Kaynağa Gözat

structure data model 1st somewhat working version

David Sehnal 7 yıl önce
ebeveyn
işleme
530a86dc92

+ 12 - 0
src/mol-base/collections/_spec/table.spec.ts

@@ -96,6 +96,18 @@ describe('table', () => {
         expect(picked.y.toArray()).toEqual([3, 4]);
         expect(picked.y.toArray()).toEqual([3, 4]);
     });
     });
 
 
+    it('view', () => {
+        const t = Table.ofColumns<typeof schema>({
+            x: Column.ofArray({ array: [10, -1], type: Column.Type.int }),
+            n: Column.ofArray({ array: ['row1', 'row2'], type: Column.Type.str }),
+        });
+        const s = { x: Column.Type.int };
+        const view = Table.view(t, s, [1]);
+        expect(view._columns).toEqual(['x']);
+        expect(view._rowCount).toEqual(1);
+        expect(view.x.toArray()).toEqual([-1]);
+    });
+
     it('sort', () => {
     it('sort', () => {
         const t = Table.ofColumns<typeof schema>({
         const t = Table.ofColumns<typeof schema>({
             x: Column.ofArray({ array: [10, -1], type: Column.Type.int }),
             x: Column.ofArray({ array: [10, -1], type: Column.Type.int }),

+ 4 - 4
src/mol-base/collections/column.ts

@@ -87,7 +87,7 @@ namespace Column {
     }
     }
 
 
     export function view<T>(column: Column<T>, indices: ArrayLike<number>, checkIndentity = true) {
     export function view<T>(column: Column<T>, indices: ArrayLike<number>, checkIndentity = true) {
-        return columnPermutation(column, indices, checkIndentity);
+        return columnView(column, indices, checkIndentity);
     }
     }
 
 
     /** A map of the 1st occurence of each value. */
     /** A map of the 1st occurence of each value. */
@@ -192,7 +192,7 @@ function arrayColumn<T extends Column.Type>({ array, type, valueKind }: Column.A
 
 
 function windowColumn<T>(column: Column<T>, start: number, end: number) {
 function windowColumn<T>(column: Column<T>, start: number, end: number) {
     if (!column.isDefined) return Column.Undefined(end - start, column['@type']);
     if (!column.isDefined) return Column.Undefined(end - start, column['@type']);
-    if (column['@array'] && ColumnHelpers.isTypedArray(column['@array'])) return windowTyped(column, start, end);
+    if (!!column['@array'] && ColumnHelpers.isTypedArray(column['@array'])) return windowTyped(column, start, end);
     return windowFull(column, start, end);
     return windowFull(column, start, end);
 }
 }
 
 
@@ -229,10 +229,10 @@ function isIdentity(map: ArrayLike<number>, rowCount: number) {
     return true;
     return true;
 }
 }
 
 
-function columnPermutation<T>(c: Column<T>, map: ArrayLike<number>, checkIdentity: boolean): Column<T> {
+function columnView<T>(c: Column<T>, map: ArrayLike<number>, checkIdentity: boolean): Column<T> {
     if (!c.isDefined) return c;
     if (!c.isDefined) return c;
     if (checkIdentity && isIdentity(map, c.rowCount)) return c;
     if (checkIdentity && isIdentity(map, c.rowCount)) return c;
-    if (!c['@array']) return arrayView(c, map);
+    if (!!c['@array']) return arrayView(c, map);
     return viewFull(c, map);
     return viewFull(c, map);
 }
 }
 
 

+ 48 - 2
src/mol-base/collections/integer/_spec/segmentation.spec.ts

@@ -11,7 +11,7 @@ import Segmentation from '../segmentation'
 describe('segments', () => {
 describe('segments', () => {
     const data = OrderedSet.ofSortedArray([4, 9, 10, 11, 14, 15, 16]);
     const data = OrderedSet.ofSortedArray([4, 9, 10, 11, 14, 15, 16]);
     const segs = Segmentation.create([0, 4, 10, 12, 13, 15, 25]);
     const segs = Segmentation.create([0, 4, 10, 12, 13, 15, 25]);
-
+    
     it('size', () => expect(Segmentation.count(segs)).toBe(6));
     it('size', () => expect(Segmentation.count(segs)).toBe(6));
 
 
     it('project', () => {
     it('project', () => {
@@ -35,7 +35,9 @@ describe('segments', () => {
         const it = Segmentation.transientSegments(segs, data);
         const it = Segmentation.transientSegments(segs, data);
 
 
         const t = Object.create(null);
         const t = Object.create(null);
+        let count = 0;
         while (it.hasNext) {
         while (it.hasNext) {
+            count++;
             const s = it.move();
             const s = it.move();
             for (let j = s.start; j < s.end; j++) {
             for (let j = s.start; j < s.end; j++) {
                 const x = t[s.index];
                 const x = t[s.index];
@@ -44,7 +46,51 @@ describe('segments', () => {
                 else x[x.length] = v;
                 else x[x.length] = v;
             }
             }
         }
         }
-
+        expect(count).toBe(4);
         expect(t).toEqual({ 1: [4, 9], 2: [10, 11], 4: [14], 5: [15, 16] });
         expect(t).toEqual({ 1: [4, 9], 2: [10, 11], 4: [14], 5: [15, 16] });
     });
     });
+
+    it('iteration range', () => {
+        const segs = Segmentation.create([0, 2, 4]);
+        const dataRange = OrderedSet.ofBounds(0, 4);
+
+        const it = Segmentation.transientSegments(segs, dataRange);
+
+        const t = Object.create(null);
+        let count = 0;
+        while (it.hasNext) {
+            count++;
+            const s = it.move();
+            for (let j = s.start; j < s.end; j++) {
+                const x = t[s.index];
+                const v = OrderedSet.getAt(dataRange, j);
+                if (!x) t[s.index] = [v];
+                else x[x.length] = v;
+            }
+        }
+        expect(count).toBe(2);
+        expect(t).toEqual({ 0: [0, 1], 1: [2, 3] });
+    });
+
+    it('iteration range 1', () => {
+        const segs = Segmentation.create([0, 2, 4]);
+        const dataRange = OrderedSet.ofBounds(0, 4);
+
+        const it = Segmentation.transientSegments(segs, dataRange, { index: 0, start: 2, end: 4 });
+
+        const t = Object.create(null);
+        let count = 0;
+        while (it.hasNext) {
+            count++;
+            const s = it.move();
+            for (let j = s.start; j < s.end; j++) {
+                const x = t[s.index];
+                const v = OrderedSet.getAt(dataRange, j);
+                if (!x) t[s.index] = [v];
+                else x[x.length] = v;
+            }
+        }
+        expect(count).toBe(1);
+        expect(t).toEqual({ 1: [2, 3] });
+    });
 });
 });

+ 14 - 6
src/mol-base/collections/integer/impl/segmentation.ts

@@ -54,12 +54,12 @@ class SegmentIterator implements Iterator<Segs.Segment> {
 
 
     move() {
     move() {
         while (this.hasNext) {
         while (this.hasNext) {
-            if (!this.updateValue()) {
-                this.updateSegmentRange();
-            } else {
+            if (this.updateValue()) {
                 this.value.index = this.segmentStart++;
                 this.value.index = this.segmentStart++;
-                this.hasNext = this.segmentEnd > this.segmentStart;
+                this.hasNext = this.segmentEnd >= this.segmentStart && Interval.size(this.setRange) > 0;
                 break;
                 break;
+            } else {
+                this.updateSegmentRange();
             }
             }
         }
         }
         return this.value;
         return this.value;
@@ -75,16 +75,24 @@ class SegmentIterator implements Iterator<Segs.Segment> {
         const setEnd = OrderedSet.findPredecessorIndexInRange(this.set, segmentEnd, this.setRange);
         const setEnd = OrderedSet.findPredecessorIndexInRange(this.set, segmentEnd, this.setRange);
         this.value.start = Interval.start(this.setRange);
         this.value.start = Interval.start(this.setRange);
         this.value.end = setEnd;
         this.value.end = setEnd;
-        this.setRange = Interval.ofBounds(setEnd, Interval.end(this.setRange))
+        const rEnd = Interval.end(this.setRange);
+        this.setRange = Interval.ofBounds(setEnd, rEnd);
         return setEnd > this.value.start;
         return setEnd > this.value.start;
     }
     }
 
 
     private updateSegmentRange() {
     private updateSegmentRange() {
+        const sMin = Interval.min(this.setRange), sMax = Interval.max(this.setRange);
+        if (sMax < sMin) {
+            this.hasNext = false;
+            return;
+        }
+
         const min = OrderedSet.getAt(this.set, Interval.min(this.setRange));
         const min = OrderedSet.getAt(this.set, Interval.min(this.setRange));
         const max = OrderedSet.getAt(this.set, Interval.max(this.setRange));
         const max = OrderedSet.getAt(this.set, Interval.max(this.setRange));
+
         this.segmentStart = this.getSegmentIndex(min);
         this.segmentStart = this.getSegmentIndex(min);
         this.segmentEnd = this.getSegmentIndex(max) + 1;
         this.segmentEnd = this.getSegmentIndex(max) + 1;
-        this.hasNext = this.segmentEnd > this.segmentStart;
+        this.hasNext = this.segmentEnd >= this.segmentStart && Interval.size(this.setRange) > 0;
     }
     }
 
 
     constructor(private segments: OrderedSet, private set: OrderedSet, inputRange: Interval) {
     constructor(private segments: OrderedSet, private set: OrderedSet, inputRange: Interval) {

+ 12 - 1
src/mol-base/collections/table.ts

@@ -58,12 +58,23 @@ namespace Table {
         const columns = Object.keys(schema);
         const columns = Object.keys(schema);
         ret._rowCount = arrays[columns[0]].length;
         ret._rowCount = arrays[columns[0]].length;
         ret._columns = columns;
         ret._columns = columns;
-        for (const k of Object.keys(schema)) {
+        for (const k of columns) {
             (ret as any)[k] = Column.ofArray({ array: arrays[k], type: schema[k] })
             (ret as any)[k] = Column.ofArray({ array: arrays[k], type: schema[k] })
         }
         }
         return ret as R;
         return ret as R;
     }
     }
 
 
+    export function view<S extends Schema, R extends Schema>(table: Table<S>, schema: R, view: ArrayLike<number>) {
+        const ret = Object.create(null);
+        const columns = Object.keys(schema);
+        ret._rowCount = view.length;
+        ret._columns = columns;
+        for (const k of columns) {
+            (ret as any)[k] = Column.view(table[k], view);
+        }
+        return ret as Table<R>;
+    }
+
     /** Sort and return a new table */
     /** Sort and return a new table */
     export function sort<T extends Table<S>, S extends Schema>(table: T, cmp: (i: number, j: number) => number) {
     export function sort<T extends Table<S>, S extends Schema>(table: T, cmp: (i: number, j: number) => number) {
         const indices = new Int32Array(table._rowCount);
         const indices = new Int32Array(table._rowCount);

+ 1 - 6
src/mol-data/model.ts

@@ -7,7 +7,6 @@
 import * as Formats from './model/formats'
 import * as Formats from './model/formats'
 import HierarchyProperties from './model/properties/hierarchy'
 import HierarchyProperties from './model/properties/hierarchy'
 import ConformationProperties from './model/properties/conformation'
 import ConformationProperties from './model/properties/conformation'
-import Segmentation from '../mol-base/collections/integer/segmentation'
 
 
 /**
 /**
  * Interface to the "source data" of the molecule.
  * Interface to the "source data" of the molecule.
@@ -30,11 +29,7 @@ interface Model extends Readonly<{
         conformation: number
         conformation: number
     },
     },
 
 
-    atomCount: number,
-    segments: Readonly<{
-        chains: Segmentation,
-        residues: Segmentation
-    }>
+    atomCount: number
 }> { }
 }> { }
 
 
 export default Model
 export default Model

+ 35 - 11
src/mol-data/model/builders/mmcif.ts

@@ -7,10 +7,13 @@
 import { RawData } from '../formats'
 import { RawData } from '../formats'
 import { Frame as mmCIF } from '../../../mol-io/reader/cif/schema/mmcif'
 import { Frame as mmCIF } from '../../../mol-io/reader/cif/schema/mmcif'
 import Model from '../../model'
 import Model from '../../model'
-//import Column from '../../../mol-base/collections/column'
+import Column from '../../../mol-base/collections/column'
+import Table from '../../../mol-base/collections/table'
 import Interval from '../../../mol-base/collections/integer/interval'
 import Interval from '../../../mol-base/collections/integer/interval'
 import Segmentation from '../../../mol-base/collections/integer/segmentation'
 import Segmentation from '../../../mol-base/collections/integer/segmentation'
 import uuId from '../../../mol-base/utils/uuid'
 import uuId from '../../../mol-base/utils/uuid'
+import * as Hierarchy from '../properties/hierarchy'
+import findHierarchyKeys from '../utils/hierarchy-keys'
 
 
 function findModelBounds(data: mmCIF, startIndex: number) {
 function findModelBounds(data: mmCIF, startIndex: number) {
     const num = data.atom_site.pdbx_PDB_model_num;
     const num = data.atom_site.pdbx_PDB_model_num;
@@ -21,7 +24,7 @@ function findModelBounds(data: mmCIF, startIndex: number) {
     return Interval.ofBounds(startIndex, endIndex);
     return Interval.ofBounds(startIndex, endIndex);
 }
 }
 
 
-function segmentOffsets(data: mmCIF, bounds: Interval) {
+function findHierarchyOffsets(data: mmCIF, bounds: Interval) {
     const start = Interval.start(bounds), end = Interval.end(bounds);
     const start = Interval.start(bounds), end = Interval.end(bounds);
     const residues = [start], chains = [start];
     const residues = [start], chains = [start];
 
 
@@ -41,21 +44,42 @@ function segmentOffsets(data: mmCIF, bounds: Interval) {
     return { residues, chains };
     return { residues, chains };
 }
 }
 
 
+function createHierarchyData(data: mmCIF, bounds: Interval, offsets: { residues: ArrayLike<number>, chains: ArrayLike<number> }): Hierarchy.HierarchyData {
+    const { atom_site } = data;
+    const start = Interval.start(bounds), end = Interval.end(bounds);
+    const atoms = Table.ofColumns<Hierarchy.AtomsSchema>({
+        id: Column.window(atom_site.id, start, end),
+        type_symbol: Column.ofArray({ array: Column.mapToArray(Column.window(atom_site.type_symbol, start, end), Hierarchy.ElementSymbol), type: Column.Type.aliased<Hierarchy.ElementSymbol>(Column.Type.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),
+        occupancy: Column.window(atom_site.occupancy, start, end),
+        B_iso_or_equiv: Column.window(atom_site.B_iso_or_equiv, start, end),
+    });
+    const residues = Table.view(atom_site, Hierarchy.ResiduesSchema, offsets.residues);
+    const chains = Table.view(atom_site, Hierarchy.ChainsSchema, offsets.chains);
+    return { atoms, residues, chains, entities: data.entity };
+}
+
 function createModel(raw: RawData, data: mmCIF, bounds: Interval): Model {
 function createModel(raw: RawData, data: mmCIF, bounds: Interval): Model {
-    const segments = segmentOffsets(data, bounds);
+    const hierarchyOffsets = findHierarchyOffsets(data, bounds);
+
+    const hierarchySegments: Hierarchy.HierarchySegmentation = {
+        residueSegments: Segmentation.ofOffsets(hierarchyOffsets.residues, bounds),
+        chainSegments: Segmentation.ofOffsets(hierarchyOffsets.chains, bounds),
+    }
+    const hierarchyData = createHierarchyData(data, bounds, hierarchyOffsets);
+    const hierarchyKeys = findHierarchyKeys(hierarchyData, hierarchySegments);
+
     return {
     return {
         id: uuId(),
         id: uuId(),
         sourceData: raw,
         sourceData: raw,
-        model_num: 0, // TODO: fix
-        //common: 0 as any,
-        hierarchy: 0 as any,
+        model_num: data.atom_site.pdbx_PDB_model_num.value(Interval.start(bounds)),
+        hierarchy: { ...hierarchyData, ...hierarchyKeys, ...hierarchySegments },
         conformation: 0 as any,
         conformation: 0 as any,
         version: { data: 0, conformation: 0 },
         version: { data: 0, conformation: 0 },
-        atomCount: Interval.size(bounds),
-        segments: {
-            residues: Segmentation.ofOffsets(segments.residues, bounds),
-            chains: Segmentation.ofOffsets(segments.chains, bounds),
-        }
+        atomCount: Interval.size(bounds)
     };
     };
 }
 }
 
 

+ 12 - 11
src/mol-data/model/properties/hierarchy.ts

@@ -16,6 +16,7 @@ export function ElementSymbol(s: string): ElementSymbol {
 }
 }
 
 
 export const AtomsSchema = {
 export const AtomsSchema = {
+    id: mmCIF.atom_site.id,
     type_symbol: Column.Type.aliased<ElementSymbol>(mmCIF.atom_site.type_symbol),
     type_symbol: Column.Type.aliased<ElementSymbol>(mmCIF.atom_site.type_symbol),
     label_atom_id: mmCIF.atom_site.label_atom_id,
     label_atom_id: mmCIF.atom_site.label_atom_id,
     auth_atom_id: mmCIF.atom_site.auth_atom_id,
     auth_atom_id: mmCIF.atom_site.auth_atom_id,
@@ -25,6 +26,7 @@ export const AtomsSchema = {
     B_iso_or_equiv: mmCIF.atom_site.B_iso_or_equiv
     B_iso_or_equiv: mmCIF.atom_site.B_iso_or_equiv
 };
 };
 
 
+export type AtomsSchema = typeof AtomsSchema
 export interface Atoms extends Table<typeof AtomsSchema> { }
 export interface Atoms extends Table<typeof AtomsSchema> { }
 
 
 export const ResiduesSchema = {
 export const ResiduesSchema = {
@@ -59,8 +61,8 @@ export interface HierarchyData {
 }
 }
 
 
 export interface HierarchySegmentation {
 export interface HierarchySegmentation {
-    residues: Segmentation,
-    chains: Segmentation
+    residueSegments: Segmentation,
+    chainSegments: Segmentation
 }
 }
 
 
 export interface HierarchyKeys {
 export interface HierarchyKeys {
@@ -69,20 +71,19 @@ export interface HierarchyKeys {
     isMonotonous: boolean,
     isMonotonous: boolean,
 
 
     // assign a key to each residue index.
     // assign a key to each residue index.
-    residue: ArrayLike<number>,
+    residueKey: ArrayLike<number>,
     // assign a key to each chain index
     // assign a key to each chain index
-    chain: ArrayLike<number>,
+    chainKey: ArrayLike<number>,
     // assigne a key to each chain index
     // assigne a key to each chain index
     // also index to the Entities table.
     // also index to the Entities table.
-    entity: ArrayLike<number>,
+    entityKey: ArrayLike<number>,
 
 
-    findEntity(id: string): number,
-    findChain(entityId: string, auth_asym_id: string): number,
-    findResidue(entityId: string, auth_asym_id: string, auth_comp_id: string, auth_seq_id: number, pdbx_PDB_ins_code: string): number
+    findEntityKey(id: string): 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
 }
 }
 
 
-export interface Hierarchy extends HierarchyData {
-    keys: HierarchyKeys
-}
+type _Hierarchy = HierarchyData & HierarchySegmentation & HierarchyKeys
+export interface Hierarchy extends _Hierarchy { }
 
 
 export default Hierarchy
 export default Hierarchy

+ 25 - 19
src/mol-data/model/utils/hierarchy-keys.ts

@@ -28,14 +28,14 @@ function getElementSubstructureKeyMap(map: Map<number, Map<string, number>>, key
 }
 }
 
 
 function createLookUp(entity: Map<string, number>, chain: Map<number, Map<string, number>>, residue: Map<number, Map<string, number>>) {
 function createLookUp(entity: Map<string, number>, chain: Map<number, Map<string, number>>, residue: Map<number, Map<string, number>>) {
-    const findEntity: HierarchyKeys['findEntity'] = (id) => entity.has(id) ? entity.get(id)! : -1;
-    const findChain: HierarchyKeys['findChain'] = (e, c) => {
+    const findEntityKey: HierarchyKeys['findEntityKey'] = (id) => entity.has(id) ? entity.get(id)! : -1;
+    const findChainKey: HierarchyKeys['findChainKey'] = (e, c) => {
         if (!entity.has(e)) return -1;
         if (!entity.has(e)) return -1;
         const cm = chain.get(entity.get(e)!)!;
         const cm = chain.get(entity.get(e)!)!;
         if (!cm.has(c)) return -1;
         if (!cm.has(c)) return -1;
         return cm.get(c)!;
         return cm.get(c)!;
     }
     }
-    const findResidue: HierarchyKeys['findResidue'] = (e, c, name, seq, ins) => {
+    const findResidueKey: HierarchyKeys['findResidueKey'] = (e, c, name, seq, ins) => {
         if (!entity.has(e)) return -1;
         if (!entity.has(e)) return -1;
         const cm = chain.get(entity.get(e)!)!;
         const cm = chain.get(entity.get(e)!)!;
         if (!cm.has(c)) return -1;
         if (!cm.has(c)) return -1;
@@ -44,12 +44,14 @@ function createLookUp(entity: Map<string, number>, chain: Map<number, Map<string
         if (!rm.has(id)) return -1;
         if (!rm.has(id)) return -1;
         return rm.get(id)!;
         return rm.get(id)!;
     }
     }
-    return { findEntity, findChain, findResidue };
+    return { findEntityKey, findChainKey, findResidueKey };
 }
 }
 
 
 function isMonotonous(xs: ArrayLike<number>) {
 function isMonotonous(xs: ArrayLike<number>) {
     for (let i = 1, _i = xs.length; i < _i; i++) {
     for (let i = 1, _i = xs.length; i < _i; i++) {
-        if (xs[i] < xs[i - 1]) return false;
+        if (xs[i] < xs[i - 1]) {
+            return false;
+        }
     }
     }
     return true;
     return true;
 }
 }
@@ -65,40 +67,44 @@ function create(data: HierarchyData, segments: HierarchySegmentation): Hierarchy
     const chainKey = new Int32Array(chains._rowCount);
     const chainKey = new Int32Array(chains._rowCount);
     const entityKey = new Int32Array(chains._rowCount);
     const entityKey = new Int32Array(chains._rowCount);
 
 
-    const { auth_comp_id, auth_seq_id, pdbx_PDB_ins_code } = data.residues;
-    const { label_entity_id, auth_asym_id } = data.chains;
+    const { label_comp_id, auth_seq_id, pdbx_PDB_ins_code } = data.residues;
+    const { label_entity_id, label_asym_id } = data.chains;
+
+    const atomSet = Interval.ofBounds(0, data.atoms._rowCount);
+
+    const chainsIt = Segmentation.transientSegments(segments.chainSegments,atomSet);
 
 
-    const chainsIt = Segmentation.transientSegments(segments.chains, Interval.ofBounds(0, data.atoms._rowCount));
     while (chainsIt.hasNext) {
     while (chainsIt.hasNext) {
         const chainSegment = chainsIt.move();
         const chainSegment = chainsIt.move();
-        const residuesIt = Segmentation.transientSegments(segments.residues, Interval.ofBounds(chainSegment.start, chainSegment.end));
         const cI = chainSegment.index;
         const cI = chainSegment.index;
 
 
         const eKey = entityMap.get(label_entity_id.value(cI)) || 0;
         const eKey = entityMap.get(label_entity_id.value(cI)) || 0;
         const chainMap = getElementSubstructureKeyMap(chainMaps, eKey);
         const chainMap = getElementSubstructureKeyMap(chainMaps, eKey);
-        const cKey = getElementKey(chainMap, auth_asym_id.value(cI), chainCounter);
+        const cKey = getElementKey(chainMap, label_asym_id.value(cI), chainCounter);
 
 
         chainKey[cI] = cKey;
         chainKey[cI] = cKey;
         entityKey[cI] = eKey;
         entityKey[cI] = eKey;
 
 
         const residueMap = getElementSubstructureKeyMap(residueMaps, cKey);
         const residueMap = getElementSubstructureKeyMap(residueMaps, cKey);
+        const residuesIt = Segmentation.transientSegments(segments.residueSegments, atomSet, chainSegment);
         while (residuesIt.hasNext) {
         while (residuesIt.hasNext) {
-            const rI = residuesIt.move().index;
-            const residueId = getResidueId(auth_comp_id.value(rI), auth_seq_id.value(rI), pdbx_PDB_ins_code.value(rI));
+            const residueSegment = residuesIt.move();
+            const rI = residueSegment.index;
+            const residueId = getResidueId(label_comp_id.value(rI), auth_seq_id.value(rI), pdbx_PDB_ins_code.value(rI));
             residueKey[rI] = getElementKey(residueMap, residueId, residueCounter);
             residueKey[rI] = getElementKey(residueMap, residueId, residueCounter);
         }
         }
     }
     }
 
 
-    const { findEntity, findChain, findResidue } = createLookUp(entityMap, chainMaps, residueMaps);
+    const { findEntityKey, findChainKey, findResidueKey } = createLookUp(entityMap, chainMaps, residueMaps);
 
 
     return {
     return {
         isMonotonous: isMonotonous(entityKey) && isMonotonous(chainKey) && isMonotonous(residueKey),
         isMonotonous: isMonotonous(entityKey) && isMonotonous(chainKey) && isMonotonous(residueKey),
-        residue: residueKey,
-        chain: chainKey,
-        entity: entityKey,
-        findEntity,
-        findChain,
-        findResidue
+        residueKey: residueKey,
+        chainKey: chainKey,
+        entityKey: entityKey,
+        findEntityKey,
+        findChainKey,
+        findResidueKey
     };
     };
 }
 }
 
 

+ 1 - 1
src/mol-data/structure/base.ts

@@ -24,7 +24,7 @@ class Builder {
 export const Empty: Structure = { units: {}, atoms: AtomSet.Empty };
 export const Empty: Structure = { units: {}, atoms: AtomSet.Empty };
 
 
 export function ofModel(model: Model): Structure {
 export function ofModel(model: Model): Structure {
-    const chains = model.segments.chains;
+    const chains = model.hierarchy.chainSegments;
     const builder = new Builder();
     const builder = new Builder();
 
 
     for (let c = 0; c < chains.count; c++) {
     for (let c = 0; c < chains.count; c++) {

+ 9 - 1
src/script.ts

@@ -117,7 +117,15 @@ async function runCIF(input: string | Uint8Array) {
     console.time('createModels');
     console.time('createModels');
     const models = buildModels(mmcif);
     const models = buildModels(mmcif);
     console.timeEnd('createModels');
     console.timeEnd('createModels');
-    console.log(models[0].id);
+
+    console.log(models[0].hierarchy.isMonotonous);
+    console.log(models[0].hierarchy.atoms.type_symbol.value(0));
+    console.log(models[0].hierarchy.atoms.id.value(1));
+    console.log(models[0].hierarchy.residues.auth_comp_id.value(0));
+    console.log(models[0].hierarchy.residues.auth_comp_id.value(1));
+    console.log(models[0].hierarchy.chains.auth_asym_id.value(0));
+    console.log(models[0].hierarchy.chains.auth_asym_id.value(1));
+    console.log(models[0].hierarchy.chains.label_asym_id.value(1));
 
 
     // const schema = await _dic()
     // const schema = await _dic()
     // if (schema) {
     // if (schema) {