Bladeren bron

Working on structure data model

David Sehnal 7 jaren geleden
bovenliggende
commit
b4aab810ad

+ 4 - 2
src/mol-model/structure/query/selection.ts

@@ -16,8 +16,10 @@ type Selection =
 // TODO: Do not allow to change unit set in the middle of a query, create a differnt language to control assemblies etc.
 /*
 type Selection =
-  | { kind: 'sequence', units: UnitCollection, sets: AtomSet[] }
-  | { kind: 'atom-set', units: UnitCollection, set: AtomSet }
+  | { kind: 'sequence', structure: Structure, sets: AtomSet[] }
+  | { kind: 'atom-set', structure: Structure, set: AtomSet }
+
+  structure allows for good unions.
 */
 
 namespace Selection {

+ 2 - 1
src/mol-model/structure/structure.ts

@@ -6,8 +6,9 @@
 
 import Atom from './structure/atom'
 import AtomSet from './structure/atom/set'
+import AtomGroup from './structure/atom/group'
 import Structure from './structure/structure'
 import Unit from './structure/unit'
 import Symmetry from './structure/symmetry'
 
-export { Atom, AtomSet, Structure, Unit, Symmetry }
+export { Atom, AtomSet, AtomGroup, Structure, Unit, Symmetry }

+ 46 - 0
src/mol-model/structure/structure/atom/group.ts

@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import { OrderedSet } from 'mol-data/int'
+import Unit from '../unit'
+
+interface AtomGroup {
+    set: OrderedSet,
+    id: number
+}
+
+namespace AtomGroup {
+    export const Empty = createNew(OrderedSet.Empty)
+
+    // export function singleton(idx: number) {
+    //     return create(OrderedSet.ofSingleton(idx));
+    // }
+
+    export function createNew(set: OrderedSet) {
+        return { id: nextId(), set };
+    }
+
+    export function create(unit: Unit, set: OrderedSet): AtomGroup {
+        if (OrderedSet.areEqual(set, unit.naturalGroup.set)) return unit.naturalGroup;
+        return createNew(set);
+    }
+
+    // export function size(group: AtomGroup) { return OrderedSet.size(group.set); }
+    // export function has(group: AtomGroup, atom: number) { return OrderedSet.has(group.set, atom); }
+    // export function getAt(group: AtomGroup, i: number) { return OrderedSet.getAt(group.set, i); }
+    // export function indexOf(group: AtomGroup, atom: number) { return OrderedSet.indexOf(group.set, atom); }
+    // export function hashCode(group: AtomGroup) { return OrderedSet.hashCode(group.set); }
+    // export function areEqual(a: AtomGroup, b: AtomGroup) { return OrderedSet.areEqual(a.set, b.set); }
+
+    let _id = 0;
+    function nextId() {
+        const ret = _id;
+        _id = (_id + 1) % 0x3fffffff;
+        return ret;
+    }
+}
+
+export default AtomGroup

+ 0 - 34
src/mol-model/structure/structure/atom/unit.ts

@@ -1,34 +0,0 @@
-/**
- * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author David Sehnal <david.sehnal@gmail.com>
- */
-
-// TODO : wrap OrderedSet with and include "id" to identify unique (sub)sets in AtomSet and the ability to cache data (also include "ancestor" field for effictient subsets).
-
-import { OrderedSet } from 'mol-data/int'
-
-interface AtomUnit {
-    set: OrderedSet,
-    id: number,
-    ancestor?: AtomUnit
-}
-
-namespace AtomUnit {
-    export function create(set: OrderedSet, ancestor?: AtomUnit): AtomUnit {
-        if (!ancestor) {
-            return { id: nextId(), set };
-        }
-        if (OrderedSet.areEqual(set, ancestor.set)) return ancestor;
-        return { id: nextId(), set, ancestor: ancestor.ancestor || ancestor };
-    }
-
-    let _id = 0;
-    function nextId() {
-        const ret = _id;
-        _id = (_id + 1) % 0x3fffffff;
-        return ret;
-    }
-}
-
-export default AtomUnit

+ 3 - 1
src/mol-model/structure/structure/structure.ts

@@ -10,6 +10,7 @@ import SymmetryOperator from 'mol-math/geometry/symmetry-operator'
 import { Model, Format } from '../model'
 import Unit from './unit'
 import AtomSet from './atom/set'
+import AtomGroup from './atom/group'
 import Atom from './atom'
 
 
@@ -35,7 +36,8 @@ namespace Structure {
         const builder = Builder();
 
         for (let c = 0; c < chains.count; c++) {
-            const unit = Unit.create(c, model, SymmetryOperator.Default);
+            const group = AtomGroup.createNew(OrderedSet.ofBounds(chains.segments[c], chains.segments[c + 1]));
+            const unit = Unit.create(c, model, SymmetryOperator.Default, group);
             builder.add(unit, OrderedSet.ofBounds(chains.segments[c], chains.segments[c + 1]));
         }
 

+ 1 - 1
src/mol-model/structure/structure/symmetry.ts

@@ -36,7 +36,7 @@ function buildAssemblyImpl(structure: Structure, name: string) {
         for (const oper of g.operators) {
             for (let uI = 0, _uI = unitIds.length; uI < _uI; uI++) {
                 const unit = units.get(unitIds[uI]);
-                assembler.add(Unit.create(unitId++, unit.model, oper), AtomSet.unitGetByIndex(atoms, uI));
+                assembler.add(Unit.create(unitId++, unit.model, oper, unit.naturalGroup), AtomSet.unitGetByIndex(atoms, uI));
             }
         }
     }

+ 6 - 1
src/mol-model/structure/structure/unit.ts

@@ -5,6 +5,7 @@
  */
 
 import SymmetryOperator from 'mol-math/geometry/symmetry-operator'
+import AtomGroup from './atom/group'
 import { Model } from '../model'
 
 interface Unit extends SymmetryOperator.ArrayMapping {
@@ -18,6 +19,9 @@ interface Unit extends SymmetryOperator.ArrayMapping {
     // The transform and and inverse are baked into the "getPosition" function
     readonly operator: SymmetryOperator,
 
+    // The "full" atom group corresponding to this unit.
+    readonly naturalGroup: AtomGroup,
+
     // Reference some commonly accessed things for faster access.
     readonly residueIndex: ArrayLike<number>,
     readonly chainIndex: ArrayLike<number>,
@@ -28,7 +32,7 @@ interface Unit extends SymmetryOperator.ArrayMapping {
 }
 
 namespace Unit {
-    export function create(id: number, model: Model, operator: SymmetryOperator): Unit {
+    export function create(id: number, model: Model, operator: SymmetryOperator, naturalGroup: AtomGroup): Unit {
         const h = model.hierarchy;
         const { invariantPosition, position, x, y, z } = SymmetryOperator.createMapping(operator, model.conformation);
 
@@ -36,6 +40,7 @@ namespace Unit {
             id,
             model,
             operator,
+            naturalGroup,
             residueIndex: h.residueSegments.segmentMap,
             chainIndex: h.chainSegments.segmentMap,
             hierarchy: model.hierarchy,