Ver Fonte

removed Unit.findUnitById, added Unit.SymmetryGroup.unitIndexMap

Alexander Rose há 6 anos atrás
pai
commit
ed2ca8ae66

+ 4 - 0
src/mol-geo/representation/structure/units-representation.ts

@@ -34,6 +34,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
             if (!_structure && !structure) {
                 throw new Error('missing structure')
             } else if (structure && !_structure) {
+                // console.log('initial structure')
                 // First call with a structure, create visuals for each group.
                 _groups = structure.unitSymmetryGroups;
                 for (let i = 0; i < _groups.length; i++) {
@@ -43,6 +44,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
                     visuals.set(group.hashCode, { visual, group })
                 }
             } else if (structure && _structure.hashCode !== structure.hashCode) {
+                // console.log('_structure.hashCode !== structure.hashCode')
                 // Tries to re-use existing visuals for the groups of the new structure.
                 // Creates additional visuals if needed, destroys left-over visuals.
                 _groups = structure.unitSymmetryGroups;
@@ -77,6 +79,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
                 // })
                 // unusedVisuals.forEach(visual => visual.destroy())
             } else if (structure && _structure.hashCode === structure.hashCode) {
+                // console.log('_structure.hashCode === structure.hashCode')
                 // Expects that for structures with the same hashCode,
                 // the unitSymmetryGroups are the same as well.
                 // Re-uses existing visuals for the groups of the new structure.
@@ -92,6 +95,7 @@ export function UnitsRepresentation<P extends StructureProps>(label: string, vis
                     }
                 }
             } else {
+                // console.log('no new structure')
                 // No new structure given, just update all visuals with new props.
                 visuals.forEach(async ({ visual, group }) => {
                     await visual.createOrUpdate(ctx, _props, { group, structure: _structure })

+ 2 - 2
src/mol-geo/representation/structure/visual/intra-unit-link-cylinder.ts

@@ -103,8 +103,8 @@ function markLink(loci: Loci, group: Unit.SymmetryGroup, apply: (interval: Inter
     let changed = false
     if (Unit.isAtomic(unit) && Link.isLoci(loci)) {
         for (const b of loci.links) {
-            const unitIdx = Unit.findUnitById(b.aUnit.id, group.units)
-            if (unitIdx !== -1) {
+            const unitIdx = group.unitIndexMap.get(b.aUnit.id)
+            if (unitIdx !== undefined) {
                 const idx = unit.links.getDirectedEdgeIndex(b.aIndex, b.bIndex)
                 if (idx !== -1) {
                     if (apply(Interval.ofSingleton(idx))) changed = true

+ 2 - 2
src/mol-geo/representation/structure/visual/util/element.ts

@@ -57,8 +57,8 @@ export function markElement(loci: Loci, group: Unit.SymmetryGroup, apply: (inter
     let changed = false
     if (StructureElement.isLoci(loci)) {
         for (const e of loci.elements) {
-            const unitIdx = Unit.findUnitById(e.unit.id, group.units)
-            if (unitIdx !== -1) {
+            const unitIdx = group.unitIndexMap.get(e.unit.id)
+            if (unitIdx !== undefined) {
                 if (Interval.is(e.indices)) {
                     const start = unitIdx * elementCount + Interval.start(e.indices);
                     const end = unitIdx * elementCount + Interval.end(e.indices);

+ 4 - 0
src/mol-geo/representation/structure/visual/util/polymer.ts

@@ -32,6 +32,8 @@ export function getGapRanges(unit: Unit): SortedRanges<ElementIndex> {
     }
 }
 
+// polymer element
+
 export function getPolymerElementCount(unit: Unit) {
     let count = 0
     const { elements } = unit
@@ -108,6 +110,8 @@ export namespace PolymerLocationIterator {
     }
 }
 
+// polymer gap
+
 export function getPolymerGapCount(unit: Unit) {
     let count = 0
     const { elements } = unit

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

@@ -25,7 +25,9 @@ import { Vec3 } from 'mol-math/linear-algebra';
 import { idFactory } from 'mol-util/id-factory';
 
 class Structure {
+    /** Maps unit.id to unit */
     readonly unitMap: IntMap<Unit>;
+    /** Array of all units in the structure, sorted by unit.id */
     readonly units: ReadonlyArray<Unit>;
 
     private _props: {
@@ -67,6 +69,7 @@ class Structure {
         return hash;
     }
 
+    /** Returns a new element location iterator */
     elementLocations(): Iterator<StructureElement> {
         return new Structure.ElementLocationIterator(this);
     }

+ 5 - 13
src/mol-model/structure/structure/symmetry.ts

@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import Structure from './structure'
@@ -10,7 +11,7 @@ import { ModelSymmetry } from '../model'
 import { Task, RuntimeContext } from 'mol-task';
 import { SortedArray } from 'mol-data/int';
 import Unit from './unit';
-import { EquivalenceClasses, hash2 } from 'mol-data/util';
+import { EquivalenceClasses } from 'mol-data/util';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { SymmetryOperator, Spacegroup, SpacegroupCell } from 'mol-math/geometry';
 
@@ -58,16 +59,12 @@ namespace StructureSymmetry {
         return Task.create('Build NCS', ctx => _buildNCS(ctx, structure));
     }
 
-    function hashUnit(u: Unit) {
-        return hash2(u.invariantId, SortedArray.hashCode(u.elements));
-    }
-
     export function areUnitsEquivalent(a: Unit, b: Unit) {
         return a.invariantId === b.invariantId && a.model.id === b.model.id && SortedArray.areEqual(a.elements, b.elements);
     }
 
     export function UnitEquivalenceBuilder() {
-        return EquivalenceClasses<number, Unit>(hashUnit, areUnitsEquivalent);
+        return EquivalenceClasses<number, Unit>(Unit.hashUnit, areUnitsEquivalent);
     }
 
     export function computeTransformGroups(s: Structure): ReadonlyArray<Unit.SymmetryGroup> {
@@ -76,12 +73,7 @@ namespace StructureSymmetry {
 
         const ret: Unit.SymmetryGroup[] = [];
         for (const eqUnits of groups.groups) {
-            const first = s.unitMap.get(eqUnits[0]);
-            ret.push({
-                elements: first.elements,
-                units: eqUnits.map(id => s.unitMap.get(id)),
-                hashCode: hashUnit(first)
-            });
+            ret.push(Unit.SymmetryGroup(eqUnits.map(id => s.unitMap.get(id))))
         }
 
         return ret;

+ 33 - 7
src/mol-model/structure/structure/unit.ts

@@ -2,6 +2,7 @@
  * Copyright (c) 2017-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
@@ -13,6 +14,8 @@ import { ValueRef } from 'mol-util';
 import { UnitRings } from './unit/rings';
 import StructureElement from './element'
 import { ChainIndex, ResidueIndex } from '../model/indexing';
+import { IntMap, SortedArray } from 'mol-data/int';
+import { hash2 } from 'mol-data/util';
 
 // A building block of a structure that corresponds to an atomic or a coarse grained representation
 // 'conveniently grouped together'.
@@ -36,21 +39,44 @@ namespace Unit {
 
     /** A group of units that differ only by symmetry operators. */
     export type SymmetryGroup = {
-        readonly elements: StructureElement.Set,
+        readonly elements: StructureElement.Set
         readonly units: ReadonlyArray<Unit>
+        /** Maps unit.id to index of unit in units array */
+        readonly unitIndexMap: IntMap<number>
         readonly hashCode: number
     }
 
+    function getUnitIndexMap(units: Unit[]) {
+        const unitIndexMap = IntMap.Mutable<number>();
+        for (let i = 0, _i = units.length; i < _i; i++) {
+            unitIndexMap.set(units[i].id, i);
+        }
+        return unitIndexMap
+    }
+
+    export function SymmetryGroup(units: Unit[]) {
+        const props: {
+            unitIndexMap?: IntMap<number>
+        } = {}
+
+        return {
+            elements: units[0].elements,
+            units,
+            get unitIndexMap () {
+                if (props.unitIndexMap) return props.unitIndexMap
+                props.unitIndexMap = getUnitIndexMap(units)
+                return props.unitIndexMap
+            },
+            hashCode: hashUnit(units[0])
+        }
+    }
+
     export function conformationId (unit: Unit) {
         return Unit.isAtomic(unit) ? unit.model.atomicConformation.id : unit.model.coarseConformation.id
     }
 
-    /** Find index of unit with given id, returns -1 if not found */
-    export function findUnitById(id: number, units: ReadonlyArray<Unit>) {
-        for (let i = 0, il = units.length; i < il; ++i) {
-            if (units[i].id === id) return i
-        }
-        return -1
+    export function hashUnit(u: Unit) {
+        return hash2(u.invariantId, SortedArray.hashCode(u.elements));
     }
 
     export interface Base {