diff --git a/src/apps/structure-info/model.ts b/src/apps/structure-info/model.ts
index 7a9919b35299824e78876806371e3497397c96c9..d9d42709d84c9a1b4983cb919814da850b8a3206 100644
--- a/src/apps/structure-info/model.ts
+++ b/src/apps/structure-info/model.ts
@@ -198,10 +198,24 @@ export function printIHMModels(model: Model) {
     console.log(Table.formatToString(model.coarseHierarchy.models));
 }
 
+export function printModelStats(models: ReadonlyArray<Model>) {
+    console.log('\nModels\n=============');
+
+    for (const m of models) {
+        if (m.coarseHierarchy.isDefined) {
+            console.log(`${m.label} ${m.modelNum}: ${m.atomicHierarchy.atoms._rowCount} atom(s), ${m.coarseHierarchy.spheres.count} sphere(s), ${m.coarseHierarchy.gaussians.count} gaussian(s)`);
+        } else {
+            console.log(`${m.label} ${m.modelNum}: ${m.atomicHierarchy.atoms._rowCount} atom(s)`);
+        }
+    }
+    console.log();
+}
+
 async function run(frame: CifFrame, args: Args) {
     const models = await Model.create(Format.mmCIF(frame)).run();
     const structure = Structure.ofModel(models[0]);
 
+    if (args.models) printModelStats(models);
     if (args.seq) printSequence(models[0]);
     if (args.ihm) printIHMModels(models[0]);
     if (args.units) printUnits(structure);
@@ -230,6 +244,7 @@ const parser = new argparse.ArgumentParser({
 parser.addArgument(['--download', '-d'], { help: 'Pdb entry id' });
 parser.addArgument(['--file', '-f'], { help: 'filename' });
 
+parser.addArgument(['--models'], { help: 'print models info', action: 'storeTrue' });
 parser.addArgument(['--seq'], { help: 'print sequence', action: 'storeTrue' });
 parser.addArgument(['--ihm'], { help: 'print IHM', action: 'storeTrue' });
 parser.addArgument(['--units'], { help: 'print units', action: 'storeTrue' });
@@ -243,6 +258,7 @@ interface Args {
     download?: string,
     file?: string,
 
+    models?:boolean,
     seq?: boolean,
     ihm?: boolean,
     units?: boolean,
diff --git a/src/mol-data/db/table.ts b/src/mol-data/db/table.ts
index 6f0b9bcced4e182747e5031433a920be3127bb66..b68967dfc55f73985b3256beb0f122a733fa4416 100644
--- a/src/mol-data/db/table.ts
+++ b/src/mol-data/db/table.ts
@@ -101,6 +101,18 @@ namespace Table {
         return ret as Table<R>;
     }
 
+    export function window<S extends R, R extends Schema>(table: Table<S>, schema: R, start: number, end: number) {
+        const ret = Object.create(null);
+        const columns = Object.keys(schema);
+        ret._rowCount = view.length;
+        ret._columns = columns;
+        ret._schema = schema;
+        for (const k of columns) {
+            (ret as any)[k] = Column.window(table[k], start, end);
+        }
+        return ret as Table<R>;
+    }
+
     export function concat<S extends R, R extends Schema>(tables: Table<S>[], schema: R) {
         const ret = Object.create(null);
         const columns = Object.keys(schema);
diff --git a/src/mol-model/structure/model/formats/mmcif.ts b/src/mol-model/structure/model/formats/mmcif.ts
index 924fc7ba96a5dbcb74030fba2ab2eef8aebc0198..4bd2eee7bd7b4ecd40df07003e83c4a2a670c53c 100644
--- a/src/mol-model/structure/model/formats/mmcif.ts
+++ b/src/mol-model/structure/model/formats/mmcif.ts
@@ -5,89 +5,27 @@
  */
 
 import { Column, Table } from 'mol-data/db';
-import { Interval, Segmentation } from 'mol-data/int';
+import { mmCIF_Database, mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif';
 import { Spacegroup, SpacegroupCell, SymmetryOperator } from 'mol-math/geometry';
-import { Vec3, Tensor } from 'mol-math/linear-algebra';
-import { Task } from 'mol-task';
+import { Tensor, Vec3 } from 'mol-math/linear-algebra';
+import { Task, RuntimeContext } from 'mol-task';
 import UUID from 'mol-util/uuid';
 import Format from '../format';
 import Model from '../model';
-import { AtomicConformation, AtomicData, AtomicSegments, AtomsSchema, ChainsSchema, ResiduesSchema } from '../properties/atomic';
 import { Entities } from '../properties/common';
+import { CustomProperties } from '../properties/custom';
 import { ModelSymmetry } from '../properties/symmetry';
-import { getAtomicKeys } from '../properties/utils/atomic-keys';
-import { ElementSymbol } from '../types';
 import { createAssemblies } from './mmcif/assembly';
-import { getIHMCoarse } from './mmcif/ihm';
+import { getAtomicHierarchyAndConformation } from './mmcif/atomic';
+import { ComponentBond } from './mmcif/bonds';
+import { getIHMCoarse, EmptyIHMCoarse, IHMData } from './mmcif/ihm';
 import { getSecondaryStructureMmCif } from './mmcif/secondary-structure';
 import { getSequence } from './mmcif/sequence';
 import { sortAtomSite } from './mmcif/sort';
-import { mmCIF_Database, mmCIF_Schema } from 'mol-io/reader/cif/schema/mmcif';
-import { Element } from '../../../structure'
-import { CustomProperties } from '../properties/custom';
 
 import mmCIF_Format = Format.mmCIF
-import { ComponentBond } from './mmcif/bonds';
-type AtomSite = mmCIF_Database['atom_site']
-
-function findModelEnd({ data }: mmCIF_Format, startIndex: number) {
-    const num = data.atom_site.pdbx_PDB_model_num;
-    const atomCount = num.rowCount;
-    if (!num.isDefined) return atomCount;
-    let endIndex = startIndex + 1;
-    while (endIndex < atomCount && num.areValuesEqual(startIndex, endIndex)) endIndex++;
-    return endIndex;
-}
-
-function findHierarchyOffsets(atom_site: AtomSite) {
-    if (atom_site._rowCount === 0) return { residues: [], chains: [] };
 
-    const start = 0, end = atom_site._rowCount;
-    const residues = [start as Element], chains = [start as Element];
-
-    const { label_entity_id, label_asym_id, label_seq_id, auth_seq_id, pdbx_PDB_ins_code, label_comp_id } = atom_site;
-
-    for (let i = start + 1; i < end; i++) {
-        const newChain = !label_entity_id.areValuesEqual(i - 1, i) || !label_asym_id.areValuesEqual(i - 1, i);
-        const newResidue = newChain
-            || !label_seq_id.areValuesEqual(i - 1, i)
-            || !auth_seq_id.areValuesEqual(i - 1, i)
-            || !pdbx_PDB_ins_code.areValuesEqual(i - 1, i)
-            || !label_comp_id.areValuesEqual(i - 1, i);
-
-        if (newResidue) residues[residues.length] = i as Element;
-        if (newChain) chains[chains.length] = i as Element;
-    }
-    return { residues, chains };
-}
-
-function createHierarchyData(atom_site: AtomSite, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): AtomicData {
-    const atoms = Table.ofColumns(AtomsSchema, {
-        type_symbol: Column.ofArray({ array: Column.mapToArray(atom_site.type_symbol, ElementSymbol), schema: Column.Schema.Aliased<ElementSymbol>(Column.Schema.str) }),
-        label_atom_id: atom_site.label_atom_id,
-        auth_atom_id: atom_site.auth_atom_id,
-        label_alt_id: atom_site.label_alt_id,
-        pdbx_formal_charge: atom_site.pdbx_formal_charge
-    });
-    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, ChainsSchema, offsets.chains);
-    return { atoms, residues, chains };
-}
-
-function getConformation(atom_site: AtomSite): AtomicConformation {
-    return {
-        id: UUID.create(),
-        atomId: atom_site.id,
-        occupancy: atom_site.occupancy,
-        B_iso_or_equiv: atom_site.B_iso_or_equiv,
-        x: atom_site.Cartn_x.toArray({ array: Float32Array }),
-        y: atom_site.Cartn_y.toArray({ array: Float32Array }),
-        z: atom_site.Cartn_z.toArray({ array: Float32Array }),
-    }
-}
+type AtomSite = mmCIF_Database['atom_site']
 
 function getSymmetry(format: mmCIF_Format): ModelSymmetry {
     const assemblies = createAssemblies(format);
@@ -129,14 +67,6 @@ function getNcsOperators(format: mmCIF_Format) {
     }
     return opers;
 }
-
-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<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 getModifiedResidueNameMap(format: mmCIF_Format) {
     const data = format.data.pdbx_struct_mod_residue;
     const map = new Map<string, string>();
@@ -168,35 +98,13 @@ function getAsymIdSerialMap(format: mmCIF_Format) {
     return map;
 }
 
-// TODO split IHM data into models as well, atomistic ihm models have `atom_site.ihm_model_id`,
-//      how to handle it in a generic way, i.e. when there is no ihm data, use `atom_site.pdbx_PDB_model_num`
-//      but if there is use `atom_site.ihm_model_id`, `ihm_sphere_obj_site.model_id` and
-//      `ihm_gaussian_obj_site.model_id` for splitting
-//      - PDBDEV_00000002 is an example for an IHM structure with multiple models
-function createModel(format: mmCIF_Format, atom_site: AtomSite, previous?: Model): Model {
-    const hierarchyOffsets = findHierarchyOffsets(atom_site);
-    const hierarchyData = createHierarchyData(atom_site, hierarchyOffsets);
-
-    if (previous && isHierarchyDataEqual(previous.atomicHierarchy, hierarchyData)) {
-        return {
-            ...previous,
-            atomicConformation: getConformation(atom_site)
-        };
-    }
-
-    const hierarchySegments: AtomicSegments = {
-        residueSegments: Segmentation.ofOffsets(hierarchyOffsets.residues, Interval.ofBounds(0, atom_site._rowCount)),
-        chainSegments: Segmentation.ofOffsets(hierarchyOffsets.chains, Interval.ofBounds(0, atom_site._rowCount)),
+function createStandardModel(format: mmCIF_Format, atom_site: AtomSite, entities: Entities, previous?: Model): Model {
+    const atomic = getAtomicHierarchyAndConformation(format, atom_site, entities, previous);
+    if (previous && atomic.sameAsPrevious) {
+        return { ...previous, atomicConformation: atomic.conformation };
     }
 
-    const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
-
-    const hierarchyKeys = getAtomicKeys(hierarchyData, entities, hierarchySegments);
-
-    const atomicHierarchy = { ...hierarchyData, ...hierarchyKeys, ...hierarchySegments };
-
-    const coarse = getIHMCoarse(format.data, entities);
-
+    const coarse = EmptyIHMCoarse;
     const label = format.data.entry.id.valueKind(0) === Column.ValueKind.Present
         ? format.data.entry.id.value(0)
         : format.data._name;
@@ -211,13 +119,47 @@ function createModel(format: mmCIF_Format, atom_site: AtomSite, previous?: Model
         modelNum: atom_site.pdbx_PDB_model_num.value(0),
         entities,
         symmetry: getSymmetry(format),
-        atomicHierarchy,
-        sequence: getSequence(format.data, entities, atomicHierarchy, modifiedResidueNameMap),
-        atomicConformation: getConformation(atom_site),
+        sequence: getSequence(format.data, entities, atomic.hierarchy, modifiedResidueNameMap),
+        atomicHierarchy: atomic.hierarchy,
+        atomicConformation: atomic.conformation,
         coarseHierarchy: coarse.hierarchy,
         coarseConformation: coarse.conformation,
         properties: {
-            secondaryStructure: getSecondaryStructureMmCif(format.data, atomicHierarchy),
+            secondaryStructure: getSecondaryStructureMmCif(format.data, atomic.hierarchy),
+            modifiedResidueNameMap,
+            asymIdSerialMap
+        },
+        customProperties: new CustomProperties(),
+        _staticPropertyData: Object.create(null),
+        _dynamicPropertyData: Object.create(null)
+    };
+}
+
+// TODO split IHM data into models as well, atomistic ihm models have `atom_site.ihm_model_id`,
+//      how to handle it in a generic way, i.e. when there is no ihm data, use `atom_site.pdbx_PDB_model_num`
+//      but if there is use `atom_site.ihm_model_id`, `ihm_sphere_obj_site.model_id` and
+//      `ihm_gaussian_obj_site.model_id` for splitting
+//      - PDBDEV_00000002 is an example for an IHM structure with multiple models
+function createModelIHM(format: mmCIF_Format, data: IHMData): Model {
+    const atomic = getAtomicHierarchyAndConformation(format, data.atom_site, data.entities);
+    const coarse = getIHMCoarse(data);
+    const modifiedResidueNameMap = getModifiedResidueNameMap(format);
+    const asymIdSerialMap = getAsymIdSerialMap(format)
+
+    return {
+        id: UUID.create(),
+        label: data.model_name,
+        sourceData: format,
+        modelNum: data.model_id,
+        entities: data.entities,
+        symmetry: getSymmetry(format),
+        sequence: getSequence(format.data, data.entities, atomic.hierarchy, modifiedResidueNameMap),
+        atomicHierarchy: atomic.hierarchy,
+        atomicConformation: atomic.conformation,
+        coarseHierarchy: coarse.hierarchy,
+        coarseConformation: coarse.conformation,
+        properties: {
+            secondaryStructure: getSecondaryStructureMmCif(format.data, atomic.hierarchy),
             modifiedResidueNameMap,
             asymIdSerialMap
         },
@@ -231,28 +173,101 @@ function attachProps(model: Model) {
     ComponentBond.attachFromMmCif(model);
 }
 
+function findModelEnd(num: Column<number>, startIndex: number) {
+    const rowCount = num.rowCount;
+    if (!num.isDefined) return rowCount;
+    let endIndex = startIndex + 1;
+    while (endIndex < rowCount && num.areValuesEqual(startIndex, endIndex)) endIndex++;
+    return endIndex;
+}
+
+async function readStandard(ctx: RuntimeContext, format: mmCIF_Format) {
+    const atomCount = format.data.atom_site._rowCount;
+    const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
+
+    const models: Model[] = [];
+    let modelStart = 0;
+    while (modelStart < atomCount) {
+        const modelEnd = findModelEnd(format.data.atom_site.pdbx_PDB_model_num, modelStart);
+        const atom_site = await sortAtomSite(ctx, format.data.atom_site, modelStart, modelEnd);
+        const model = createStandardModel(format, atom_site, entities, models.length > 0 ? models[models.length - 1] : void 0);
+        attachProps(model);
+        models.push(model);
+        modelStart = modelEnd;
+    }
+    return models;
+}
+
+function splitTable<T extends Table<any>>(table: T, col: Column<number>) {
+    const ret = new Map<number, T>()
+    const rowCount = table._rowCount;
+    let modelStart = 0;
+    while (modelStart < rowCount) {
+        const modelEnd = findModelEnd(col, modelStart);
+        const id = col.value(modelStart);
+        const window = Table.window(table, table._schema, modelStart, modelEnd) as T;
+        ret.set(id, window);
+        modelStart = modelEnd;
+    }
+    return ret;
+}
+
+async function readIHM(ctx: RuntimeContext, format: mmCIF_Format) {
+    const { ihm_model_list } = format.data;
+    const entities: Entities = { data: format.data.entity, getEntityIndex: Column.createIndexer(format.data.entity.id) };
+
+    const atom_sites = splitTable(format.data.atom_site, format.data.atom_site.ihm_model_id);
+    const sphere_sites = splitTable(format.data.ihm_sphere_obj_site, format.data.ihm_sphere_obj_site.model_id);
+    const gauss_sites = splitTable(format.data.ihm_gaussian_obj_site, format.data.ihm_gaussian_obj_site.model_id);
+
+    const models: Model[] = [];
+
+    const { model_id, model_name } = ihm_model_list;
+    for (let i = 0; i < ihm_model_list._rowCount; i++) {
+        const id = model_id.value(i);
+        const data: IHMData = {
+            model_id: id,
+            model_name: model_name.value(i),
+            ihm_model_list,
+            entities: entities,
+            atom_site: atom_sites.has(id) ? atom_sites.get(id)! : Table.window(format.data.atom_site, format.data.atom_site._schema, 0, 0),
+            ihm_sphere_obj_site: sphere_sites.has(id) ? sphere_sites.get(id)! : Table.window(format.data.ihm_sphere_obj_site, format.data.ihm_sphere_obj_site._schema, 0, 0),
+            ihm_gaussian_obj_site: gauss_sites.has(id) ? gauss_sites.get(id)! : Table.window(format.data.ihm_gaussian_obj_site, format.data.ihm_gaussian_obj_site._schema, 0, 0)
+        };
+        const model = createModelIHM(format, data);
+        attachProps(model);
+        models.push(createModelIHM(format, data));
+    }
+
+    return models;
+
+    // const atomCount = format.data.atom_site._rowCount;
+    // const isIHM = format.data.ihm_model_list._rowCount > 0;
+
+    // if (atomCount === 0) {
+    //     return isIHM
+    //         ? [createModel(format, format.data.atom_site, void 0)]
+    //         : [];
+    // }
+
+
+    // const models: Model[] = [];
+    // let modelStart = 0;
+    // while (modelStart < atomCount) {
+    //     const modelEnd = findModelEnd(format, modelStart);
+    //     const atom_site = await sortAtomSite(ctx, format.data.atom_site, modelStart, modelEnd);
+    //     const model = createModel(format, atom_site, models.length > 0 ? models[models.length - 1] : void 0);
+    //     attachProps(model);
+    //     models.push(model);
+    //     modelStart = modelEnd;
+    // }
+    // return models;
+}
+
 function buildModels(format: mmCIF_Format): Task<ReadonlyArray<Model>> {
     return Task.create('Create mmCIF Model', async ctx => {
-        const atomCount = format.data.atom_site._rowCount;
         const isIHM = format.data.ihm_model_list._rowCount > 0;
-
-        if (atomCount === 0) {
-            return isIHM
-                ? [createModel(format, format.data.atom_site, void 0)]
-                : [];
-        }
-
-        const models: Model[] = [];
-        let modelStart = 0;
-        while (modelStart < atomCount) {
-            const modelEnd = findModelEnd(format, modelStart);
-            const atom_site = await sortAtomSite(ctx, format.data.atom_site, modelStart, modelEnd);
-            const model = createModel(format, atom_site, models.length > 0 ? models[models.length - 1] : void 0);
-            attachProps(model);
-            models.push(model);
-            modelStart = modelEnd;
-        }
-        return models;
+        return isIHM ?  await readIHM(ctx, format) : await readStandard(ctx, format);
     });
 }
 
diff --git a/src/mol-model/structure/model/formats/mmcif/atomic.ts b/src/mol-model/structure/model/formats/mmcif/atomic.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f0b0480fb2110e1f39ef422bb4a7f7534615ab67
--- /dev/null
+++ b/src/mol-model/structure/model/formats/mmcif/atomic.ts
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { Column, Table } from 'mol-data/db';
+import { Interval, Segmentation } from 'mol-data/int';
+import { mmCIF_Database } from 'mol-io/reader/cif/schema/mmcif';
+import UUID from 'mol-util/uuid';
+import { Element } from '../../../../structure';
+import Format from '../../format';
+import Model from '../../model';
+import { AtomicConformation, AtomicData, AtomicHierarchy, AtomicSegments, AtomsSchema, ChainsSchema, ResiduesSchema } from '../../properties/atomic';
+import { getAtomicKeys } from '../../properties/utils/atomic-keys';
+import { ElementSymbol } from '../../types';
+import { Entities } from '../../properties/common';
+
+import mmCIF_Format = Format.mmCIF
+type AtomSite = mmCIF_Database['atom_site']
+
+function findHierarchyOffsets(atom_site: AtomSite) {
+    if (atom_site._rowCount === 0) return { residues: [], chains: [] };
+
+    const start = 0, end = atom_site._rowCount;
+    const residues = [start as Element], chains = [start as Element];
+
+    const { label_entity_id, label_asym_id, label_seq_id, auth_seq_id, pdbx_PDB_ins_code, label_comp_id } = atom_site;
+
+    for (let i = start + 1; i < end; i++) {
+        const newChain = !label_entity_id.areValuesEqual(i - 1, i) || !label_asym_id.areValuesEqual(i - 1, i);
+        const newResidue = newChain
+            || !label_seq_id.areValuesEqual(i - 1, i)
+            || !auth_seq_id.areValuesEqual(i - 1, i)
+            || !pdbx_PDB_ins_code.areValuesEqual(i - 1, i)
+            || !label_comp_id.areValuesEqual(i - 1, i);
+
+        if (newResidue) residues[residues.length] = i as Element;
+        if (newChain) chains[chains.length] = i as Element;
+    }
+    return { residues, chains };
+}
+
+function createHierarchyData(atom_site: AtomSite, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): AtomicData {
+    const atoms = Table.ofColumns(AtomsSchema, {
+        type_symbol: Column.ofArray({ array: Column.mapToArray(atom_site.type_symbol, ElementSymbol), schema: Column.Schema.Aliased<ElementSymbol>(Column.Schema.str) }),
+        label_atom_id: atom_site.label_atom_id,
+        auth_atom_id: atom_site.auth_atom_id,
+        label_alt_id: atom_site.label_alt_id,
+        pdbx_formal_charge: atom_site.pdbx_formal_charge
+    });
+    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, ChainsSchema, offsets.chains);
+    return { atoms, residues, chains };
+}
+
+function getConformation(atom_site: AtomSite): AtomicConformation {
+    return {
+        id: UUID.create(),
+        atomId: atom_site.id,
+        occupancy: atom_site.occupancy,
+        B_iso_or_equiv: atom_site.B_iso_or_equiv,
+        x: atom_site.Cartn_x.toArray({ array: Float32Array }),
+        y: atom_site.Cartn_y.toArray({ array: Float32Array }),
+        z: atom_site.Cartn_z.toArray({ array: Float32Array }),
+    }
+}
+
+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<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>)
+}
+
+
+export function getAtomicHierarchyAndConformation(format: mmCIF_Format, atom_site: AtomSite, entities: Entities, previous?: Model) {
+    const hierarchyOffsets = findHierarchyOffsets(atom_site);
+    const hierarchyData = createHierarchyData(atom_site, hierarchyOffsets);
+
+    if (previous && isHierarchyDataEqual(previous.atomicHierarchy, hierarchyData)) {
+        return {
+            sameAsPrevious: true,
+            hierarchy: previous.atomicHierarchy,
+            conformation: getConformation(atom_site)
+        };
+    }
+
+    const hierarchySegments: AtomicSegments = {
+        residueSegments: Segmentation.ofOffsets(hierarchyOffsets.residues, Interval.ofBounds(0, atom_site._rowCount)),
+        chainSegments: Segmentation.ofOffsets(hierarchyOffsets.chains, Interval.ofBounds(0, atom_site._rowCount)),
+    }
+
+    const hierarchyKeys = getAtomicKeys(hierarchyData, entities, hierarchySegments);
+    const hierarchy: AtomicHierarchy = { ...hierarchyData, ...hierarchyKeys, ...hierarchySegments };
+    return {
+        sameAsPrevious: false,
+        hierarchy,
+        conformation: getConformation(atom_site)
+    };
+}
\ No newline at end of file
diff --git a/src/mol-model/structure/model/formats/mmcif/bonds/comp.ts b/src/mol-model/structure/model/formats/mmcif/bonds/comp.ts
index fe0c4ab4ed029eab636dd4fdd63e888ec2512a87..04d74a0a7910dc3643e785f912e1f2eba400f829 100644
--- a/src/mol-model/structure/model/formats/mmcif/bonds/comp.ts
+++ b/src/mol-model/structure/model/formats/mmcif/bonds/comp.ts
@@ -43,6 +43,7 @@ export namespace ComponentBond {
     }
 
     export function attachFromMmCif(model: Model): boolean {
+        if (model.customProperties.has(Descriptor)) return true;
         if (model.sourceData.kind !== 'mmCIF') return false;
         const { chem_comp_bond } = model.sourceData.data;
         if (chem_comp_bond._rowCount === 0) return false;
diff --git a/src/mol-model/structure/model/formats/mmcif/ihm.ts b/src/mol-model/structure/model/formats/mmcif/ihm.ts
index 8fe3b4f4aea36256e5529e47296782fb6bec975f..f3bd5ad8113a8cfcf9698e9e45cc38deb65dda9a 100644
--- a/src/mol-model/structure/model/formats/mmcif/ihm.ts
+++ b/src/mol-model/structure/model/formats/mmcif/ihm.ts
@@ -14,24 +14,39 @@ import { Segmentation, Interval } from 'mol-data/int';
 import { Mat3, Tensor } from 'mol-math/linear-algebra';
 import { Element } from '../../../structure'
 
-export function getIHMCoarse(data: mmCIF, entities: Entities): { hierarchy: CoarseHierarchy, conformation: CoarseConformation } {
-    if (data.ihm_model_list._rowCount === 0) return { hierarchy: CoarseHierarchy.Empty, conformation: void 0 as any };
+type AtomSite = mmCIF['atom_site']
+type SphereSite = mmCIF['ihm_sphere_obj_site']
+type GaussSite = mmCIF['ihm_gaussian_obj_site']
+type IHMModels = mmCIF['ihm_model_list']
 
+export interface IHMData {
+    model_id: number,
+    model_name: string,
+    ihm_model_list: IHMModels,
+    entities: Entities,
+    atom_site: AtomSite,
+    ihm_sphere_obj_site: SphereSite,
+    ihm_gaussian_obj_site: GaussSite
+}
+
+export const EmptyIHMCoarse = { hierarchy: CoarseHierarchy.Empty, conformation: void 0 as any }
+
+export function getIHMCoarse(data: IHMData): { hierarchy: CoarseHierarchy, conformation: CoarseConformation } {
     const { ihm_model_list, ihm_sphere_obj_site, ihm_gaussian_obj_site } = data;
     const modelIndex = Column.createIndexer(ihm_model_list.model_id);
 
     const sphereData = getData(ihm_sphere_obj_site);
     const sphereConformation = getSphereConformation(ihm_sphere_obj_site);
-    const sphereKeys = getCoarseKeys(sphereData, modelIndex, entities);
+    const sphereKeys = getCoarseKeys(sphereData, modelIndex, data.entities);
 
     const gaussianData = getData(ihm_gaussian_obj_site);
     const gaussianConformation = getGaussianConformation(ihm_gaussian_obj_site);
-    const gaussianKeys = getCoarseKeys(gaussianData, modelIndex, entities);
+    const gaussianKeys = getCoarseKeys(gaussianData, modelIndex, data.entities);
 
     return {
         hierarchy: {
             isDefined: true,
-            models: ihm_model_list,
+            //models: ihm_model_list,
             spheres: { ...sphereData, ...sphereKeys },
             gaussians: { ...gaussianData, ...gaussianKeys },
         },
diff --git a/src/mol-model/structure/model/properties/coarse/hierarchy.ts b/src/mol-model/structure/model/properties/coarse/hierarchy.ts
index 1b50e835de9dc560e2c42083e7843bfeb893b7c9..2bcdabbe815d39d0d62a062e9695796294d9688c 100644
--- a/src/mol-model/structure/model/properties/coarse/hierarchy.ts
+++ b/src/mol-model/structure/model/properties/coarse/hierarchy.ts
@@ -15,8 +15,9 @@ export interface CoarsedElementKeys {
     chainKey: ArrayLike<number>,
     // assign a key to each element, index to the Model.entities.data table
     entityKey: ArrayLike<number>,
-    // assign a key to each element, index to the CoarseHierarchy.models table
-    modelKey: ArrayLike<number>,
+    
+    // // assign a key to each element, index to the CoarseHierarchy.models table
+    // modelKey: ArrayLike<number>,
 
     /** find index of the residue/feature element where seq_id is included */
     findSequenceKey(entityId: string, asym_id: string, seq_id: number): number
@@ -38,7 +39,7 @@ export type CoarseElements = CoarsedElementKeys & CoarseElementData
 
 export interface CoarseHierarchy {
     isDefined: boolean,
-    models: mmCIF['ihm_model_list'],
+    //models: mmCIF['ihm_model_list'],
     spheres: CoarseElements,
     gaussians: CoarseElements
 }
diff --git a/src/mol-model/structure/model/properties/utils/coarse-keys.ts b/src/mol-model/structure/model/properties/utils/coarse-keys.ts
index 67539ec4d91a4fca937561d77913ed83f3189fb3..c18dc27ec7d72dc43b3dbab51a4f3e30f80a385f 100644
--- a/src/mol-model/structure/model/properties/utils/coarse-keys.ts
+++ b/src/mol-model/structure/model/properties/utils/coarse-keys.ts
@@ -92,5 +92,5 @@ export function getCoarseKeys(data: CoarseElementData, modelIndex: (id: number)
 
     const { findChainKey, findSequenceKey } = createLookUp(entities, chainMaps, seqMaps);
 
-    return { chainKey, entityKey, modelKey, findSequenceKey, findChainKey };
+    return { chainKey, entityKey, /*modelKey,*/ findSequenceKey, findChainKey };
 }
\ No newline at end of file