Browse Source

more data model

David Sehnal 7 years ago
parent
commit
164c62e091

+ 3 - 4
src/mol-base/collections/_spec/segmentation.spec.ts

@@ -20,11 +20,10 @@ describe('segments', () => {
     });
 
     it('map', () => {
-        const segs = Segmentation.create([1, 2, 3]);
+        const segs = Segmentation.create([0, 1, 2]);
         expect(segs.segmentMap).toEqual(new Int32Array([0, 1]));
-        expect(segs.offset).toEqual(1);
-        expect(Segmentation.getSegment(segs, 1)).toBe(0);
-        expect(Segmentation.getSegment(segs, 2)).toBe(1);
+        expect(Segmentation.getSegment(segs, 0)).toBe(0);
+        expect(Segmentation.getSegment(segs, 1)).toBe(1);
     })
 
     it('iteration', () => {

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

@@ -10,22 +10,22 @@ import Interval from '../interval'
 import SortedArray from '../sorted-array'
 import Segs from '../segmentation'
 
-type Segmentation = { segments: SortedArray, segmentMap: ArrayLike<number>, offset: number, count: number }
+type Segmentation = { segments: SortedArray, segmentMap: ArrayLike<number>, count: number }
 
 export function create(values: ArrayLike<number>): Segmentation {
     const segments = SortedArray.ofSortedArray(values);
-    const min = SortedArray.min(segments), max = SortedArray.max(segments);
-    const segmentMap = new Int32Array(max - min);
+    const max = SortedArray.max(segments);
+    const segmentMap = new Int32Array(max);
     for (let i = 0, _i = values.length - 1; i < _i; i++) {
-        for (let j = values[i] - min, _j = values[i + 1] - min; j < _j; j++) {
+        for (let j = values[i], _j = values[i + 1]; j < _j; j++) {
             segmentMap[j] = i;
         }
     }
-    return { segments, segmentMap, offset: min, count: values.length - 1 };
+    return { segments, segmentMap, count: values.length - 1 };
 }
 
 export function count({ count }: Segmentation) { return count; }
-export function getSegment({ segmentMap, offset }: Segmentation, value: number) { return segmentMap[value - offset]; }
+export function getSegment({ segmentMap }: Segmentation, value: number) { return segmentMap[value]; }
 
 export function projectValue({ segments }: Segmentation, set: OrderedSet, value: number): Interval {
     const last = OrderedSet.max(segments);

+ 0 - 1
src/mol-base/collections/integer/segmentation.ts

@@ -24,7 +24,6 @@ namespace Segmentation {
 interface Segmentation {
     '@type': 'segmentation',
     readonly segmentMap: ArrayLike<number>,
-    readonly offset: number,
     readonly count: number
 }
 

+ 1 - 0
src/mol-data/atom.ts

@@ -6,6 +6,7 @@
 
 import Tuple from '../mol-base/collections/integer/tuple'
 
+/** Atom pointer */
 interface Atom { '@type': Tuple['@type'] }
 
 namespace Atom {

+ 11 - 4
src/mol-data/model.ts

@@ -5,18 +5,25 @@
  */
 
 import * as Formats from './model/formats'
-import CommonInterface from './model/interfaces/common'
-import MacromoleculeInterface from './model/interfaces/common'
+import CommonInterface from './model/common'
+import MacromoleculeInterface from './model/macromolecule'
 import Segmentation from '../mol-base/collections/integer/segmentation'
 
+/**
+ * Interface to the "source data" of the molecule.
+ *
+ * "Atoms" are integers in the range [0, atomCount).
+ */
 interface Model {
-    data: Formats.RawData,
+    sourceData: Formats.RawData,
 
     common: CommonInterface,
     macromolecule: MacromoleculeInterface
 
+    atomCount: number,
     chains: Segmentation,
-    residues: Segmentation
+    residues: Segmentation,
+    entities: Segmentation
 }
 
 export default Model

+ 23 - 15
src/mol-data/model/formats/mmcif.ts → src/mol-data/model/builders/mmcif.ts

@@ -21,10 +21,11 @@ function findModelBounds(data: mmCIF, startIndex: number) {
 
 function segment(data: mmCIF, bounds: Interval) {
     const start = Interval.start(bounds), end = Interval.end(bounds);
-    const residues = [start], chains = [start];
+    const residues = [0], chains = [0], entities = [0];
 
     const { label_entity_id, auth_asym_id, auth_seq_id, pdbx_PDB_ins_code } = data.atom_site;
 
+    let offset = 1;
     for (let i = start + 1; i < end; i++) {
         const newEntity = !label_entity_id.areValuesEqual(i - 1, i);
         const newChain = newEntity || !auth_asym_id.areValuesEqual(i - 1, i);
@@ -32,31 +33,43 @@ function segment(data: mmCIF, bounds: Interval) {
             || !auth_seq_id.areValuesEqual(i - 1, i)
             || !pdbx_PDB_ins_code.areValuesEqual(i - 1, i);
 
-        if (newResidue) residues[residues.length] = i;
-        if (newChain) chains[chains.length] = i;
+        if (newEntity) entities[entities.length] = offset;
+        if (newResidue) residues[residues.length] = offset;
+        if (newChain) chains[chains.length] = offset;
+        offset++;
     }
 
-    residues[residues.length] = end;
-    chains[chains.length] = end;
+    residues[residues.length] = offset;
+    chains[chains.length] = offset;
+    entities[entities.length] = offset;
 
-    return { residues: Segmentation.create(residues), chains: Segmentation.create(chains) };
+    return {
+        residues: Segmentation.create(residues),
+        chains: Segmentation.create(chains),
+        entities: Segmentation.create(entities)
+    };
 }
 
 function createModel(raw: RawData, data: mmCIF, bounds: Interval): Model {
     const segments = segment(data, bounds);
     return {
-        data: raw,
+        sourceData: raw,
         common: 0 as any,
         macromolecule: 0 as any,
+        atomCount: Interval.size(bounds),
         residues: segments.residues,
-        chains: segments.chains
+        chains: segments.chains,
+        entities: segments.entities
     };
 }
 
-function getModels(data: mmCIF): ArrayLike<Model> {
+function buildModels(data: mmCIF): ArrayLike<Model> {
     const raw: RawData = { source: 'mmCIF', data };
     const models: Model[] = [];
     const atomCount = data.atom_site._rowCount;
+
+    if (atomCount === 0) return models;
+
     let modelStart = 0;
     while (modelStart < atomCount) {
         const bounds = findModelBounds(data, modelStart);
@@ -67,9 +80,4 @@ function getModels(data: mmCIF): ArrayLike<Model> {
     return models;
 }
 
-export default getModels;
-
-// function createStructure() {
-
-// }
-
+export default buildModels;

+ 0 - 0
src/mol-data/model/interfaces/common.ts → src/mol-data/model/common.ts


+ 5 - 0
src/mol-data/model/common/keys.ts

@@ -0,0 +1,5 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */

+ 0 - 0
src/mol-data/model/interfaces/macromolecule.ts → src/mol-data/model/macromolecule.ts


+ 15 - 0
src/mol-data/structure/base.ts

@@ -0,0 +1,15 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import Model from '../model'
+import Structure from '../structure'
+
+//export const Empty { }
+
+export function ofModel(model: Model): Structure {
+    // TODO: create a unit for each chain in the model
+    return 0 as any;
+}

+ 2 - 2
src/script.ts

@@ -17,7 +17,7 @@ import CIF from './mol-io/reader/cif'
 
 import Computation from './mol-base/computation'
 
-import createModels from './mol-data/model/formats/mmcif'
+import buildModels from './mol-data/model/builders/mmcif'
 
 // import { toTypedFrame as applySchema } from './reader/cif/schema'
 import { generateSchema } from './mol-io/reader/cif/schema/utils'
@@ -115,7 +115,7 @@ async function runCIF(input: string | Uint8Array) {
     console.log(mmcif.pdbx_struct_oper_list.matrix.value(0));
 
     console.time('createModels');
-    const models = createModels(mmcif);
+    const models = buildModels(mmcif);
     console.timeEnd('createModels');
     console.log(models[0].common);