From b1ceb0c7d0858ef0f9c0442a8052ef8a05248460 Mon Sep 17 00:00:00 2001
From: David Sehnal <david.sehnal@gmail.com>
Date: Thu, 10 May 2018 11:46:52 +0200
Subject: [PATCH] Refactoring mol-model

---
 src/mol-model/structure/model/formats/gro.ts  | 30 +++++++++----------
 .../structure/model/formats/mmcif.ts          | 24 +++++++--------
 .../structure/model/formats/mmcif/ihm.ts      | 10 +++----
 .../structure/model/formats/mmcif/sequence.ts |  6 ++--
 src/mol-model/structure/model/model.ts        | 14 ++++-----
 .../conformation.ts}                          |  6 ++--
 .../properties/{ => atomic}/hierarchy.ts      | 27 +++++------------
 .../{atomic.ts => atomic/measures.ts}         |  2 +-
 .../properties/coarse-grained/conformation.ts |  0
 .../hierarchy.ts}                             | 12 ++++----
 .../structure/model/properties/common.ts      | 18 +++++++++--
 .../structure/model/properties/sequence.ts    |  4 +--
 .../structure/model/utils/hierarchy-keys.ts   |  8 ++---
 src/mol-model/structure/query/properties.ts   |  2 +-
 src/mol-model/structure/structure/unit.ts     | 12 ++++----
 15 files changed, 87 insertions(+), 88 deletions(-)
 rename src/mol-model/structure/model/properties/{atom-site-conformation.ts => atomic/conformation.ts} (93%)
 rename src/mol-model/structure/model/properties/{ => atomic}/hierarchy.ts (71%)
 rename src/mol-model/structure/model/properties/{atomic.ts => atomic/measures.ts} (99%)
 create mode 100644 src/mol-model/structure/model/properties/coarse-grained/conformation.ts
 rename src/mol-model/structure/model/properties/{coarse-grained.ts => coarse-grained/hierarchy.ts} (82%)

diff --git a/src/mol-model/structure/model/formats/gro.ts b/src/mol-model/structure/model/formats/gro.ts
index cb868ff96..d2348b120 100644
--- a/src/mol-model/structure/model/formats/gro.ts
+++ b/src/mol-model/structure/model/formats/gro.ts
@@ -10,9 +10,9 @@ import { Interval, Segmentation } from 'mol-data/int'
 import { Atoms } from 'mol-io/reader/gro/schema'
 import Format from '../format'
 import Model from '../model'
-import * as Hierarchy from '../properties/hierarchy'
-import AtomSiteConformation from '../properties/atom-site-conformation'
-import CoarseGrained from '../properties/coarse-grained'
+import * as AtomicHierarchy from '../properties/atomic/hierarchy'
+import { AtomicConformation } from '../properties/atomic/conformation'
+import { CoarseGrainedHierarchy } from '../properties/coarse-grained/hierarchy'
 import findHierarchyKeys from '../utils/hierarchy-keys'
 import { guessElement } from '../utils/guess-element'
 import { ElementSymbol} from '../types'
@@ -44,9 +44,9 @@ function guessElementSymbol (value: string) {
     return ElementSymbol(guessElement(value));
 }
 
-function createHierarchyData(atomsData: Atoms, offsets: HierarchyOffsets): Hierarchy.Data {
+function createHierarchyData(atomsData: Atoms, offsets: HierarchyOffsets): AtomicHierarchy.AtomicData {
     console.log(atomsData.atomName)
-    const atoms = Table.ofColumns(Hierarchy.AtomsSchema, {
+    const atoms = Table.ofColumns(AtomicHierarchy.AtomsSchema, {
         type_symbol: Column.ofArray({ array: Column.mapToArray(atomsData.atomName, guessElementSymbol), schema: Column.Schema.Aliased<ElementSymbol>(Column.Schema.str) }),
         label_atom_id: atomsData.atomName,
         auth_atom_id: atomsData.atomName,
@@ -54,14 +54,14 @@ function createHierarchyData(atomsData: Atoms, offsets: HierarchyOffsets): Hiera
         pdbx_formal_charge: Column.Undefined(atomsData.count, Column.Schema.int)
     });
 
-    const residues = Table.view(Table.ofColumns(Hierarchy.ResiduesSchema, {
+    const residues = Table.view(Table.ofColumns(AtomicHierarchy.ResiduesSchema, {
         group_PDB: Column.Undefined(atomsData.count, Column.Schema.Aliased<'ATOM' | 'HETATM'>(Column.Schema.str)),
         label_comp_id: atomsData.residueName,
         auth_comp_id: atomsData.residueName,
         label_seq_id: atomsData.residueNumber,
         auth_seq_id: atomsData.residueNumber,
         pdbx_PDB_ins_code: Column.Undefined(atomsData.count, Column.Schema.str),
-    }), Hierarchy.ResiduesSchema, offsets.residues);
+    }), AtomicHierarchy.ResiduesSchema, offsets.residues);
     // Optimize the numeric columns
     Table.columnToArray(residues, 'label_seq_id', Int32Array);
     Table.columnToArray(residues, 'auth_seq_id', Int32Array);
@@ -72,12 +72,12 @@ function createHierarchyData(atomsData: Atoms, offsets: HierarchyOffsets): Hiera
     //     label_entity_id: Column.Undefined(atomsData.count, Column.Schema.str)
     // });
 
-    const chains = Table.ofUndefinedColumns(Hierarchy.ChainsSchema, 0);
+    const chains = Table.ofUndefinedColumns(AtomicHierarchy.ChainsSchema, 0);
 
     return { atoms, residues, chains };
 }
 
-function getConformation(atoms: Atoms): AtomSiteConformation {
+function getConformation(atoms: Atoms): AtomicConformation {
     return {
         id: UUID.create(),
         atomId: atoms.atomNumber,
@@ -89,10 +89,10 @@ function getConformation(atoms: Atoms): AtomSiteConformation {
     }
 }
 
-function isHierarchyDataEqual(a: Hierarchy.Hierarchy, b: Hierarchy.Data) {
+function isHierarchyDataEqual(a: AtomicHierarchy.AtomicData, b: AtomicHierarchy.AtomicData) {
     // need to cast because of how TS handles type resolution for interfaces https://github.com/Microsoft/TypeScript/issues/15300
-    return Table.areEqual(a.residues as Table<Hierarchy.ResiduesSchema>, b.residues as Table<Hierarchy.ResiduesSchema>)
-        && Table.areEqual(a.atoms as Table<Hierarchy.AtomsSchema>, b.atoms as Table<Hierarchy.AtomsSchema>)
+    return Table.areEqual(a.residues as Table<AtomicHierarchy.ResiduesSchema>, b.residues as Table<AtomicHierarchy.ResiduesSchema>)
+        && Table.areEqual(a.atoms as Table<AtomicHierarchy.AtomsSchema>, b.atoms as Table<AtomicHierarchy.AtomsSchema>)
 }
 
 function createModel(format: gro_Format, modelNum: number, previous?: Model): Model {
@@ -109,7 +109,7 @@ function createModel(format: gro_Format, modelNum: number, previous?: Model): Mo
         };
     }
 
-    const hierarchySegments: Hierarchy.Segments = {
+    const hierarchySegments: AtomicHierarchy.AtomicSegments = {
         residueSegments: Segmentation.ofOffsets(hierarchyOffsets.residues, bounds),
         chainSegments: Segmentation.ofOffsets(hierarchyOffsets.chains, bounds),
     }
@@ -132,9 +132,9 @@ function createModel(format: gro_Format, modelNum: number, previous?: Model): Mo
         modelNum,
         hierarchy,
         entities,
-        sequence: Sequence.fromHierarchy(hierarchy),
+        sequence: Sequence.fromAtomicHierarchy(hierarchy),
         atomSiteConformation: getConformation(structure.atoms),
-        coarseGrained: CoarseGrained.Empty,
+        coarseGrained: CoarseGrainedHierarchy.Empty,
         symmetry: { assemblies: [] },
         atomCount: structure.atoms.count
     };
diff --git a/src/mol-model/structure/model/formats/mmcif.ts b/src/mol-model/structure/model/formats/mmcif.ts
index 33c09a598..c9a962266 100644
--- a/src/mol-model/structure/model/formats/mmcif.ts
+++ b/src/mol-model/structure/model/formats/mmcif.ts
@@ -9,8 +9,8 @@ import { Column, Table } from 'mol-data/db'
 import { Interval, Segmentation } from 'mol-data/int'
 import Format from '../format'
 import Model from '../model'
-import * as Hierarchy from '../properties/hierarchy'
-import AtomSiteConformation from '../properties/atom-site-conformation'
+import { AtomsSchema, ResiduesSchema, ChainsSchema, AtomicData, AtomicSegments } from '../properties/atomic/hierarchy'
+import { AtomicConformation } from '../properties/atomic/conformation'
 import Symmetry from '../properties/symmetry'
 import findHierarchyKeys from '../utils/hierarchy-keys'
 import { ElementSymbol} from '../types'
@@ -51,25 +51,25 @@ function findHierarchyOffsets({ data }: mmCIF_Format, bounds: Interval) {
     return { residues, chains };
 }
 
-function createHierarchyData({ data }: mmCIF_Format, bounds: Interval, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): Hierarchy.Data {
+function createHierarchyData({ data }: mmCIF_Format, bounds: Interval, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): AtomicData {
     const { atom_site } = data;
     const start = Interval.start(bounds), end = Interval.end(bounds);
-    const atoms = Table.ofColumns(Hierarchy.AtomsSchema, {
+    const atoms = Table.ofColumns(AtomsSchema, {
         type_symbol: Column.ofArray({ array: Column.mapToArray(Column.window(atom_site.type_symbol, start, end), ElementSymbol), schema: Column.Schema.Aliased<ElementSymbol>(Column.Schema.str) }),
         label_atom_id: Column.window(atom_site.label_atom_id, start, end),
         auth_atom_id: Column.window(atom_site.auth_atom_id, start, end),
         label_alt_id: Column.window(atom_site.label_alt_id, start, end),
         pdbx_formal_charge: Column.window(atom_site.pdbx_formal_charge, start, end)
     });
-    const residues = Table.view(atom_site, Hierarchy.ResiduesSchema, offsets.residues);
+    const residues = Table.view(atom_site, ResiduesSchema, offsets.residues);
     // Optimize the numeric columns
     Table.columnToArray(residues, 'label_seq_id', Int32Array);
     Table.columnToArray(residues, 'auth_seq_id', Int32Array);
-    const chains = Table.view(atom_site, Hierarchy.ChainsSchema, offsets.chains);
+    const chains = Table.view(atom_site, ChainsSchema, offsets.chains);
     return { atoms, residues, chains };
 }
 
-function getConformation({ data }: mmCIF_Format, bounds: Interval): AtomSiteConformation {
+function getConformation({ data }: mmCIF_Format, bounds: Interval): AtomicConformation {
     const start = Interval.start(bounds), end = Interval.end(bounds);
     const { atom_site } = data;
     return {
@@ -87,11 +87,11 @@ function getSymmetry(format: mmCIF_Format): Symmetry {
     return { assemblies: createAssemblies(format) };
 }
 
-function isHierarchyDataEqual(a: Hierarchy.Hierarchy, b: Hierarchy.Data) {
+function isHierarchyDataEqual(a: AtomicData, b: AtomicData) {
     // need to cast because of how TS handles type resolution for interfaces https://github.com/Microsoft/TypeScript/issues/15300
-    return Table.areEqual(a.chains as Table<Hierarchy.ChainsSchema>, b.chains as Table<Hierarchy.ChainsSchema>)
-        && Table.areEqual(a.residues as Table<Hierarchy.ResiduesSchema>, b.residues as Table<Hierarchy.ResiduesSchema>)
-        && Table.areEqual(a.atoms as Table<Hierarchy.AtomsSchema>, b.atoms as Table<Hierarchy.AtomsSchema>)
+    return Table.areEqual(a.chains as Table<ChainsSchema>, b.chains as Table<ChainsSchema>)
+        && Table.areEqual(a.residues as Table<ResiduesSchema>, b.residues as Table<ResiduesSchema>)
+        && Table.areEqual(a.atoms as Table<AtomsSchema>, b.atoms as Table<AtomsSchema>)
 }
 
 function createModel(format: mmCIF_Format, bounds: Interval, previous?: Model): Model {
@@ -105,7 +105,7 @@ function createModel(format: mmCIF_Format, bounds: Interval, previous?: Model):
         };
     }
 
-    const hierarchySegments: Hierarchy.Segments = {
+    const hierarchySegments: AtomicSegments = {
         residueSegments: Segmentation.ofOffsets(hierarchyOffsets.residues, bounds),
         chainSegments: Segmentation.ofOffsets(hierarchyOffsets.chains, bounds),
     }
diff --git a/src/mol-model/structure/model/formats/mmcif/ihm.ts b/src/mol-model/structure/model/formats/mmcif/ihm.ts
index d85906571..5eab89ab0 100644
--- a/src/mol-model/structure/model/formats/mmcif/ihm.ts
+++ b/src/mol-model/structure/model/formats/mmcif/ihm.ts
@@ -5,12 +5,12 @@
  */
 
 import { mmCIF_Database as mmCIF, mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif'
-import CoarseGrained from '../../properties/coarse-grained'
+import { CoarseGrainedHierarchy } from '../../properties/coarse-grained/hierarchy'
 import { Entities } from '../../properties/common';
 import { Column } from 'mol-data/db';
 
-function coarseGrainedFromIHM(data: mmCIF, entities: Entities): CoarseGrained {
-    if (data.ihm_model_list._rowCount === 0) return CoarseGrained.Empty;
+function coarseGrainedFromIHM(data: mmCIF, entities: Entities): CoarseGrainedHierarchy {
+    if (data.ihm_model_list._rowCount === 0) return CoarseGrainedHierarchy.Empty;
 
     const { ihm_model_list, ihm_sphere_obj_site, ihm_gaussian_obj_site } = data;
     const modelIndex = Column.createIndexer(ihm_model_list.model_id);
@@ -23,7 +23,7 @@ function coarseGrainedFromIHM(data: mmCIF, entities: Entities): CoarseGrained {
     };
 }
 
-function getSpheres(data: mmCIF['ihm_sphere_obj_site'], entities: Entities, modelIndex: (id: number) => number): CoarseGrained.Spheres {
+function getSpheres(data: mmCIF['ihm_sphere_obj_site'], entities: Entities, modelIndex: (id: number) => number): CoarseGrainedHierarchy.Spheres {
     const { Cartn_x, Cartn_y, Cartn_z, object_radius: radius, rmsf } = data;
     const x = Cartn_x.toArray({ array: Float32Array });
     const y = Cartn_y.toArray({ array: Float32Array });
@@ -31,7 +31,7 @@ function getSpheres(data: mmCIF['ihm_sphere_obj_site'], entities: Entities, mode
     return { count: x.length, ...getCommonColumns(data, entities, modelIndex), x, y, z, radius, rmsf };
 }
 
-function getGaussians(data: mmCIF['ihm_gaussian_obj_site'], entities: Entities, modelIndex: (id: number) => number): CoarseGrained.Gaussians {
+function getGaussians(data: mmCIF['ihm_gaussian_obj_site'], entities: Entities, modelIndex: (id: number) => number): CoarseGrainedHierarchy.Gaussians {
     const { mean_Cartn_x, mean_Cartn_y, mean_Cartn_z, weight, covariance_matrix  } = data;
     const x = mean_Cartn_x.toArray({ array: Float32Array });
     const y = mean_Cartn_y.toArray({ array: Float32Array });
diff --git a/src/mol-model/structure/model/formats/mmcif/sequence.ts b/src/mol-model/structure/model/formats/mmcif/sequence.ts
index ccba6849b..88da71446 100644
--- a/src/mol-model/structure/model/formats/mmcif/sequence.ts
+++ b/src/mol-model/structure/model/formats/mmcif/sequence.ts
@@ -7,11 +7,11 @@
 import { mmCIF_Database as mmCIF } from 'mol-io/reader/cif/schema/mmcif'
 import Sequence from '../../properties/sequence'
 import { Column } from 'mol-data/db';
-import { Hierarchy } from '../../properties/hierarchy';
+import { AtomicHierarchy } from '../../properties/atomic/hierarchy';
 import { Entities } from '../../properties/common';
 
-export function getSequence(cif: mmCIF, entities: Entities, hierarchy: Hierarchy): Sequence {
-    if (!cif.entity_poly_seq._rowCount) return Sequence.fromHierarchy(hierarchy);
+export function getSequence(cif: mmCIF, entities: Entities, hierarchy: AtomicHierarchy): Sequence {
+    if (!cif.entity_poly_seq._rowCount) return Sequence.fromAtomicHierarchy(hierarchy);
 
     const { entity_id, num, mon_id } = cif.entity_poly_seq;
 
diff --git a/src/mol-model/structure/model/model.ts b/src/mol-model/structure/model/model.ts
index e685af863..8a0f009c2 100644
--- a/src/mol-model/structure/model/model.ts
+++ b/src/mol-model/structure/model/model.ts
@@ -7,10 +7,10 @@
 import UUID from 'mol-util/uuid'
 import Format from './format'
 import Sequence from './properties/sequence'
-import Hierarchy from './properties/hierarchy'
-import AtomSiteConformation from './properties/atom-site-conformation'
+import { AtomicHierarchy } from './properties/atomic/hierarchy'
+import { AtomicConformation } from './properties/atomic/conformation'
 import Symmetry from './properties/symmetry'
-import CoarseGrained from './properties/coarse-grained'
+import { CoarseGrainedHierarchy } from './properties/coarse-grained/hierarchy'
 import { Entities } from './properties/common';
 
 import from_gro from './formats/gro'
@@ -28,13 +28,13 @@ interface Model extends Readonly<{
 
     sourceData: Format,
 
+    symmetry: Symmetry,
     entities: Entities,
     sequence: Sequence,
 
-    hierarchy: Hierarchy,
-    atomSiteConformation: AtomSiteConformation,
-    symmetry: Symmetry,
-    coarseGrained: CoarseGrained,
+    hierarchy: AtomicHierarchy,
+    atomSiteConformation: AtomicConformation,
+    coarseGrained: CoarseGrainedHierarchy,
 
     atomCount: number,
 }> {
diff --git a/src/mol-model/structure/model/properties/atom-site-conformation.ts b/src/mol-model/structure/model/properties/atomic/conformation.ts
similarity index 93%
rename from src/mol-model/structure/model/properties/atom-site-conformation.ts
rename to src/mol-model/structure/model/properties/atomic/conformation.ts
index ce94b8597..fd99511a4 100644
--- a/src/mol-model/structure/model/properties/atom-site-conformation.ts
+++ b/src/mol-model/structure/model/properties/atomic/conformation.ts
@@ -7,7 +7,7 @@
 import { Column } from 'mol-data/db'
 import UUID from 'mol-util/uuid'
 
-interface Conformation {
+export interface AtomicConformation {
     id: UUID,
 
     // ID is part of conformation because mmCIF is a leaky abstraction
@@ -23,6 +23,4 @@ interface Conformation {
     x: ArrayLike<number>,
     y: ArrayLike<number>,
     z: ArrayLike<number>
-}
-
-export default Conformation
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/mol-model/structure/model/properties/hierarchy.ts b/src/mol-model/structure/model/properties/atomic/hierarchy.ts
similarity index 71%
rename from src/mol-model/structure/model/properties/hierarchy.ts
rename to src/mol-model/structure/model/properties/atomic/hierarchy.ts
index d25903d95..02ef4dd5d 100644
--- a/src/mol-model/structure/model/properties/hierarchy.ts
+++ b/src/mol-model/structure/model/properties/atomic/hierarchy.ts
@@ -7,7 +7,8 @@
 import { Column, Table } from 'mol-data/db'
 import { Segmentation } from 'mol-data/int'
 import { mmCIF_Schema as mmCIF } from 'mol-io/reader/cif/schema/mmcif'
-import { ElementSymbol} from '../types'
+import { ElementSymbol} from '../../types'
+import { Keys } from '../common';
 
 export const AtomsSchema = {
     type_symbol: Column.Schema.Aliased<ElementSymbol>(mmCIF.atom_site.type_symbol),
@@ -40,36 +41,22 @@ export const ChainsSchema = {
 export type ChainsSchema = typeof ChainsSchema
 export interface Chains extends Table<ChainsSchema> { }
 
-export interface Data {
+export interface AtomicData {
     atoms: Atoms,
     residues: Residues,
     chains: Chains
 }
 
-export interface Segments {
+export interface AtomicSegments {
     residueSegments: Segmentation,
     chainSegments: Segmentation
 }
 
-export interface Keys {
-    // indicate whether the keys form an increasing sequence and within each chain, sequence numbers
-    // are in increasing order.
-    // monotonous sequences enable for example faster secondary structure assignment.
-    isMonotonous: boolean,
-
+export interface AtomicKeys extends Keys {
     // assign a key to each residue index.
     residueKey: Column<number>,
-    // assign a key to each chain index
-    chainKey: Column<number>,
-    // assigne a key to each chain index
-    // also index to the Entities table.
-    entityKey: Column<number>,
-
-    findChainKey(entityId: string, label_asym_id: string): number,
     findResidueKey(entityId: string, label_asym_id: string, label_comp_id: string, auth_seq_id: number, pdbx_PDB_ins_code: string): number
 }
 
-type _Hierarchy = Data & Segments & Keys
-export interface Hierarchy extends _Hierarchy { }
-
-export default Hierarchy
\ No newline at end of file
+type _Hierarchy = AtomicData & AtomicSegments & AtomicKeys
+export interface AtomicHierarchy extends _Hierarchy { }
\ No newline at end of file
diff --git a/src/mol-model/structure/model/properties/atomic.ts b/src/mol-model/structure/model/properties/atomic/measures.ts
similarity index 99%
rename from src/mol-model/structure/model/properties/atomic.ts
rename to src/mol-model/structure/model/properties/atomic/measures.ts
index 38550af27..05aad28a9 100644
--- a/src/mol-model/structure/model/properties/atomic.ts
+++ b/src/mol-model/structure/model/properties/atomic/measures.ts
@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { ElementSymbol } from '../types';
+import { ElementSymbol } from '../../types';
 
 export const AtomicNumbers: { [e: string]: number | undefined } = { 'H': 1, 'D': 1, 'T': 1, 'HE': 2, 'LI': 3, 'BE': 4, 'B': 5, 'C': 6, 'N': 7, 'O': 8, 'F': 9, 'NE': 10, 'NA': 11, 'MG': 12, 'AL': 13, 'SI': 14, 'P': 15, 'S': 16, 'CL': 17, 'AR': 18, 'K': 19, 'CA': 20, 'SC': 21, 'TI': 22, 'V': 23, 'CR': 24, 'MN': 25, 'FE': 26, 'CO': 27, 'NI': 28, 'CU': 29, 'ZN': 30, 'GA': 31, 'GE': 32, 'AS': 33, 'SE': 34, 'BR': 35, 'KR': 36, 'RB': 37, 'SR': 38, 'Y': 39, 'ZR': 40, 'NB': 41, 'MO': 42, 'TC': 43, 'RU': 44, 'RH': 45, 'PD': 46, 'AG': 47, 'CD': 48, 'IN': 49, 'SN': 50, 'SB': 51, 'TE': 52, 'I': 53, 'XE': 54, 'CS': 55, 'BA': 56, 'LA': 57, 'CE': 58, 'PR': 59, 'ND': 60, 'PM': 61, 'SM': 62, 'EU': 63, 'GD': 64, 'TB': 65, 'DY': 66, 'HO': 67, 'ER': 68, 'TM': 69, 'YB': 70, 'LU': 71, 'HF': 72, 'TA': 73, 'W': 74, 'RE': 75, 'OS': 76, 'IR': 77, 'PT': 78, 'AU': 79, 'HG': 80, 'TL': 81, 'PB': 82, 'BI': 83, 'PO': 84, 'AT': 85, 'RN': 86, 'FR': 87, 'RA': 88, 'AC': 89, 'TH': 90, 'PA': 91, 'U': 92, 'NP': 93, 'PU': 94, 'AM': 95, 'CM': 96, 'BK': 97, 'CF': 98, 'ES': 99, 'FM': 100, 'MD': 101, 'NO': 102, 'LR': 103, 'RF': 104, 'DB': 105, 'SG': 106, 'BH': 107, 'HS': 108, 'MT': 109 };
 
diff --git a/src/mol-model/structure/model/properties/coarse-grained/conformation.ts b/src/mol-model/structure/model/properties/coarse-grained/conformation.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/mol-model/structure/model/properties/coarse-grained.ts b/src/mol-model/structure/model/properties/coarse-grained/hierarchy.ts
similarity index 82%
rename from src/mol-model/structure/model/properties/coarse-grained.ts
rename to src/mol-model/structure/model/properties/coarse-grained/hierarchy.ts
index ac5ba1084..12dd042cd 100644
--- a/src/mol-model/structure/model/properties/coarse-grained.ts
+++ b/src/mol-model/structure/model/properties/coarse-grained/hierarchy.ts
@@ -8,15 +8,15 @@ import { mmCIF_Database as mmCIF } from 'mol-io/reader/cif/schema/mmcif'
 import { Tensor } from 'mol-math/linear-algebra';
 import { Column } from 'mol-data/db';
 
-interface CoarseGrained {
+interface CoarseGrainedHierarchy {
     isDefined: boolean,
     modelList: mmCIF['ihm_model_list'],
-    spheres: CoarseGrained.Spheres,
-    gaussians: CoarseGrained.Gaussians
+    spheres: CoarseGrainedHierarchy.Spheres,
+    gaussians: CoarseGrainedHierarchy.Gaussians
 }
 
-namespace CoarseGrained {
-    export const Empty: CoarseGrained = { isDefined: false } as any;
+namespace CoarseGrainedHierarchy {
+    export const Empty: CoarseGrainedHierarchy = { isDefined: false } as any;
 
     export const enum ElementType { Sphere, Gaussian }
 
@@ -50,4 +50,4 @@ namespace CoarseGrained {
     export type Gaussians = Common & { matrix_space: Tensor.Space } & { [P in keyof Gaussian]: Column<Gaussian[P]> }
 }
 
-export default CoarseGrained;
\ No newline at end of file
+export { CoarseGrainedHierarchy }
\ No newline at end of file
diff --git a/src/mol-model/structure/model/properties/common.ts b/src/mol-model/structure/model/properties/common.ts
index aa5d93aae..e70712cbb 100644
--- a/src/mol-model/structure/model/properties/common.ts
+++ b/src/mol-model/structure/model/properties/common.ts
@@ -5,10 +5,24 @@
  */
 
 import { mmCIF_Database as mmCIF } from 'mol-io/reader/cif/schema/mmcif'
+import { Column } from 'mol-data/db';
 
-interface Entities {
+export interface Entities {
     data: mmCIF['entity'],
     getEntityIndex(id: string): number
 }
 
-export { Entities }
\ No newline at end of file
+export interface Keys {
+    // indicate whether the keys form an increasing sequence and within each chain, sequence numbers
+    // are in increasing order.
+    // monotonous sequences enable for example faster secondary structure assignment.
+    isMonotonous: boolean,
+
+    // assign a key to each chain index
+    chainKey: Column<number>,
+    // assigne a key to each chain index
+    // also index to the Entities table.
+    entityKey: Column<number>,
+
+    findChainKey(entityId: string, label_asym_id: string): number
+}
\ No newline at end of file
diff --git a/src/mol-model/structure/model/properties/sequence.ts b/src/mol-model/structure/model/properties/sequence.ts
index d7aa43951..b34b1ef61 100644
--- a/src/mol-model/structure/model/properties/sequence.ts
+++ b/src/mol-model/structure/model/properties/sequence.ts
@@ -5,7 +5,7 @@
  */
 
 import { Column } from 'mol-data/db'
-import { Hierarchy } from './hierarchy';
+import { AtomicHierarchy } from './atomic/hierarchy';
 
 interface Sequence {
     readonly byEntityKey: { [key: number]: Sequence.Entity }
@@ -19,7 +19,7 @@ namespace Sequence {
         readonly compId: Column<string>
     }
 
-    export function fromHierarchy(hierarchy: Hierarchy): Sequence {
+    export function fromAtomicHierarchy(hierarchy: AtomicHierarchy): Sequence {
         // const { label_comp_id } = hierarchy.residues;
 
         throw 'not implemented';
diff --git a/src/mol-model/structure/model/utils/hierarchy-keys.ts b/src/mol-model/structure/model/utils/hierarchy-keys.ts
index d70a26a94..e825df9dd 100644
--- a/src/mol-model/structure/model/utils/hierarchy-keys.ts
+++ b/src/mol-model/structure/model/utils/hierarchy-keys.ts
@@ -5,7 +5,7 @@
  */
 
 import { Column } from 'mol-data/db'
-import { Data, Segments, Keys } from '../properties/hierarchy'
+import { AtomicData, AtomicSegments, AtomicKeys } from '../properties/atomic/hierarchy'
 import { Interval, Segmentation } from 'mol-data/int'
 import { Entities } from '../properties/common';
 
@@ -29,14 +29,14 @@ function getElementSubstructureKeyMap(map: Map<number, Map<string, number>>, key
 
 function createLookUp(entities: Entities, chain: Map<number, Map<string, number>>, residue: Map<number, Map<string, number>>) {
     const getEntKey = entities.getEntityIndex;
-    const findChainKey: Keys['findChainKey'] = (e, c) => {
+    const findChainKey: AtomicKeys['findChainKey'] = (e, c) => {
         let eKey = getEntKey(e);
         if (eKey < 0) return -1;
         const cm = chain.get(eKey)!;
         if (!cm.has(c)) return -1;
         return cm.get(c)!;
     }
-    const findResidueKey: Keys['findResidueKey'] = (e, c, name, seq, ins) => {
+    const findResidueKey: AtomicKeys['findResidueKey'] = (e, c, name, seq, ins) => {
         let eKey = getEntKey(e);
         if (eKey < 0) return -1;
         const cm = chain.get(eKey)!;
@@ -62,7 +62,7 @@ function missingEntity(k: string) {
     throw new Error(`Missing entity entry for entity id '${k}'.`);
 }
 
-function create(data: Data, entities: Entities, segments: Segments): Keys {
+function create(data: AtomicData, entities: Entities, segments: AtomicSegments): AtomicKeys {
     const { chains, residues } = data;
 
     const chainMaps = new Map<number, Map<string, number>>(), chainCounter = { index: 0 };
diff --git a/src/mol-model/structure/query/properties.ts b/src/mol-model/structure/query/properties.ts
index fc2a066ad..6fe1eed35 100644
--- a/src/mol-model/structure/query/properties.ts
+++ b/src/mol-model/structure/query/properties.ts
@@ -5,7 +5,7 @@
  */
 
 import { Element, Unit } from '../structure'
-import { VdwRadius } from '../model/properties/atomic';
+import { VdwRadius } from '../model/properties/atomic/measures';
 
 const constant = {
     true: Element.property(l => true),
diff --git a/src/mol-model/structure/structure/unit.ts b/src/mol-model/structure/structure/unit.ts
index 15a85c646..7ede3f8a7 100644
--- a/src/mol-model/structure/structure/unit.ts
+++ b/src/mol-model/structure/structure/unit.ts
@@ -7,7 +7,7 @@
 import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
 import { Model } from '../model'
 import { GridLookup3D, Lookup3D } from 'mol-math/geometry'
-import CoarseGrained from '../model/properties/coarse-grained';
+import { CoarseGrainedHierarchy } from '../model/properties/coarse-grained/hierarchy';
 import { SortedArray } from 'mol-data/int';
 import { idFactory } from 'mol-util/id-factory';
 import { IntraUnitBonds, computeIntraUnitBonds } from './unit/bonds'
@@ -109,11 +109,11 @@ namespace Unit {
     }
 
     // Coarse grained representations.
-    export interface CoarseBase<S extends CoarseGrained.SitesBase> extends Base  {
+    export interface CoarseBase<S extends CoarseGrainedHierarchy.SitesBase> extends Base  {
         readonly sites: S
     }
 
-    class Coarse<S extends CoarseGrained.SitesBase> implements CoarseBase<S> {
+    class Coarse<S extends CoarseGrainedHierarchy.SitesBase> implements CoarseBase<S> {
         readonly kind: Kind;
 
         readonly id: number;
@@ -153,12 +153,12 @@ namespace Unit {
         }
     }
 
-    function createCoarse<S extends CoarseGrained.SitesBase>(id: number, invariantId: number, model: Model, kind: Kind, sites: S, elements: SortedArray, conformation: SymmetryOperator.ArrayMapping): Unit {
+    function createCoarse<S extends CoarseGrainedHierarchy.SitesBase>(id: number, invariantId: number, model: Model, kind: Kind, sites: S, elements: SortedArray, conformation: SymmetryOperator.ArrayMapping): Unit {
         return new Coarse(id, invariantId, model, kind, sites, elements, conformation) as any as Unit /** lets call this an ugly temporary hack */;
     }
 
-    export interface Spheres extends CoarseBase<CoarseGrained.Spheres> { kind: Kind.Spheres }
-    export interface Gaussians extends CoarseBase<CoarseGrained.Gaussians> { kind: Kind.Gaussians }
+    export interface Spheres extends CoarseBase<CoarseGrainedHierarchy.Spheres> { kind: Kind.Spheres }
+    export interface Gaussians extends CoarseBase<CoarseGrainedHierarchy.Gaussians> { kind: Kind.Gaussians }
 }
 
 export default Unit;
\ No newline at end of file
-- 
GitLab