Browse Source

properties

David Sehnal 7 years ago
parent
commit
c131d7b942

+ 12 - 0
src/mol-base/collections/column.ts

@@ -81,6 +81,18 @@ namespace Column {
         return arrayColumn(spec);
     }
 
+    export function ofIntArray(array: ArrayLike<number>) {
+        return arrayColumn({ array, type: Type.int });
+    }
+
+    export function ofFloatArray(array: ArrayLike<number>) {
+        return arrayColumn({ array, type: Type.float });
+    }
+
+    export function ofStringArray(array: ArrayLike<string>) {
+        return arrayColumn({ array, type: Type.str });
+    }
+
     export function window<T>(column: Column<T>, start: number, end: number) {
         return windowColumn(column, start, end);
     }

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

@@ -9,6 +9,11 @@ import HierarchyProperties from './model/properties/hierarchy'
 import ConformationProperties from './model/properties/conformation'
 import UUID from '../mol-base/utils/uuid'
 
+export interface Version {
+    hierarchy: UUID,
+    conformation: UUID
+}
+
 /**
  * Interface to the "source data" of the molecule.
  *
@@ -25,10 +30,7 @@ interface Model extends Readonly<{
     conformation: ConformationProperties,
 
     // used for diffing.
-    version: {
-        data: UUID,
-        conformation: UUID
-    },
+    version: Version,
 
     atomCount: number
 }> { }

+ 2 - 2
src/mol-data/model/builders/mmcif.ts

@@ -88,7 +88,7 @@ function createModel(raw: RawData, data: mmCIF, bounds: Interval, previous?: Mod
         return {
             ...previous,
             conformation: getConformation(data, bounds),
-            version: { data: previous.version.data, conformation: newUUID() }
+            version: { hierarchy: previous.version.hierarchy, conformation: newUUID() }
         };
     }
 
@@ -104,7 +104,7 @@ function createModel(raw: RawData, data: mmCIF, bounds: Interval, previous?: Mod
         model_num: data.atom_site.pdbx_PDB_model_num.value(Interval.start(bounds)),
         hierarchy: { ...hierarchyData, ...hierarchyKeys, ...hierarchySegments },
         conformation: getConformation(data, bounds),
-        version: { data: newUUID(), conformation: newUUID() },
+        version: { hierarchy: newUUID(), conformation: newUUID() },
         atomCount: Interval.size(bounds)
     };
 }

+ 3 - 3
src/mol-data/model/properties/hierarchy.ts

@@ -70,12 +70,12 @@ export interface Keys {
     isMonotonous: boolean,
 
     // assign a key to each residue index.
-    residueKey: ArrayLike<number>,
+    residueKey: Column<number>,
     // assign a key to each chain index
-    chainKey: ArrayLike<number>,
+    chainKey: Column<number>,
     // assigne a key to each chain index
     // also index to the Entities table.
-    entityKey: ArrayLike<number>,
+    entityKey: Column<number>,
 
     findEntityKey(id: string): number,
     findChainKey(entityId: string, label_asym_id: string): number,

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

@@ -104,9 +104,9 @@ function create(data: Data, segments: Segments): Keys {
 
     return {
         isMonotonous: isMonotonous && checkMonotonous(entityKey) && checkMonotonous(chainKey) && checkMonotonous(residueKey),
-        residueKey: residueKey,
-        chainKey: chainKey,
-        entityKey: entityKey,
+        residueKey: Column.ofIntArray(residueKey),
+        chainKey: Column.ofIntArray(chainKey),
+        entityKey: Column.ofIntArray(entityKey),
         findEntityKey,
         findChainKey,
         findResidueKey

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

@@ -13,7 +13,7 @@ import * as Base from './structure/base'
 
 // TODO: do "single model" version of the structure?
 export interface Structure extends Readonly<{
-    units: Readonly<{ [id: number]: Unit }>,
+    units: { readonly [id: number]: Unit },
     atoms: AtomSet
 }> { }
 

+ 0 - 16
src/mol-data/structure/atom.ts

@@ -5,9 +5,6 @@
  */
 
 import Tuple from '../../mol-base/collections/integer/tuple'
-import Structure from '../structure'
-import Unit from './unit'
-import Model from '../model'
 
 /** Atom pointer */
 interface Atom { '@type': Tuple['@type'] }
@@ -20,19 +17,6 @@ namespace Atom {
     export const index: (a: Atom) => number = Tuple.snd;
     export const areEqual: (a: Atom, b: Atom) => boolean = Tuple.areEqual;
     export const hashCode: (a: Atom) => number = Tuple.hashCode;
-
-    /** All the information required to access atom properties */
-    export interface Location {
-        structure: Structure,
-        unit: Unit,
-        model: Model,
-        atomIndex: number,
-        residueIndex: number,
-        chainIndex: number
-    }
-
-    export interface Property<T> { (location: Atom): T }
-    export interface Predicate extends Property<boolean> { }
 }
 
 export default Atom

+ 62 - 0
src/mol-data/structure/property.ts

@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import Structure from '../structure'
+import Atom from './atom'
+import Unit from './unit'
+import Model from '../model'
+import Column from '../../mol-base/collections/column'
+
+/** Atom pointer */
+interface Property<T> { (location: Property.Location): T }
+
+namespace Property {
+    export interface Predicate extends Property<boolean> { }
+
+    /** All the information required to access atom properties */
+    export interface Location {
+        structure: Structure,
+        unit: Unit,
+        atomIndex: number,
+        residueIndex: number,
+        chainIndex: number
+    }
+
+    export function create(structure?: Structure, unit?: Unit): Location {
+        return {
+            structure: structure!,
+            unit: unit!,
+            atomIndex: 0,
+            residueIndex: 0,
+            chainIndex: 0
+        };
+    }
+
+    export function update(l: Location, structure: Structure, atom: Atom) {
+        const u = structure.units[Atom.unit(atom)];
+        const i = Atom.index(atom);
+        l.structure = structure;
+        l.unit = u;
+        l.atomIndex = i;
+        l.residueIndex = u.residueIndex[i];
+        l.chainIndex = u.chainIndex[i];
+    }
+
+    export function cachedAtomColumn<T>(col: (model: Model) => Column<T>): Property<T> {
+        let lastUnit: Unit | undefined = void 0;
+        let cached: ((row: number) => T) | undefined = void 0;
+        return function (location) {
+            if (location.unit === lastUnit && !!cached) return cached(location.atomIndex);
+            lastUnit = location.unit;
+            cached = col(lastUnit.model).value;
+            return cached(location.atomIndex);
+        };
+    }
+
+    // TODO: cached versions of other properties.
+}
+
+export default Property

+ 7 - 2
src/mol-data/structure/unit.ts

@@ -16,7 +16,11 @@ interface Unit extends Readonly<{
 
     // Determines the operation applied to this unit.
     // The transform and and inverse are baked into the "getPosition" function
-    operator: Operator
+    operator: Operator,
+
+    // Cache residue and chain indices for fast access.
+    residueIndex: ArrayLike<number>,
+    chainIndex: ArrayLike<number>
 }> {
     // // returns the untransformed position. Used for spatial queries.
     // getInvariantPosition(atom: number, slot: Vec3): Vec3
@@ -27,7 +31,8 @@ interface Unit extends Readonly<{
 
 namespace Unit {
     export function create(model: Model, operator: Operator): Unit {
-        return { id: nextUnitId(), model, operator };
+        const h = model.hierarchy;
+        return { id: nextUnitId(), model, operator, residueIndex: h.residueSegments.segmentMap, chainIndex: h.chainSegments.segmentMap };
     }
 }