Browse Source

added element/residue/chain instances loci granularity and helpers

Alexander Rose 5 years ago
parent
commit
2a413256ed

+ 17 - 2
src/mol-model/loci.ts

@@ -12,7 +12,7 @@ import { CentroidHelper } from '../mol-math/geometry/centroid-helper';
 import { Vec3 } from '../mol-math/linear-algebra';
 import { OrderedSet } from '../mol-data/int';
 import { Structure } from './structure/structure';
-import { capitalize } from '../mol-util/string';
+import { stringToWords } from '../mol-util/string';
 import { PrincipalAxes } from '../mol-math/linear-algebra/matrix/principal-axes';
 
 /** A Loci that includes every loci */
@@ -194,6 +194,21 @@ namespace Loci {
                 ? StructureElement.Loci.extendToWholeChains(loci)
                 : loci
         },
+        'elementInstances': (loci: Loci) => {
+            return StructureElement.Loci.is(loci)
+                ? StructureElement.Loci.extendToAllInstances(loci)
+                : loci
+        },
+        'residueInstances': (loci: Loci) => {
+            return StructureElement.Loci.is(loci)
+                ? StructureElement.Loci.extendToAllInstances(StructureElement.Loci.extendToWholeResidues(loci, true))
+                : loci
+        },
+        'chainInstances': (loci: Loci) => {
+            return StructureElement.Loci.is(loci)
+                ? StructureElement.Loci.extendToAllInstances(StructureElement.Loci.extendToWholeChains(loci))
+                : loci
+        },
         'entity': (loci: Loci) => {
             return StructureElement.Loci.is(loci)
                 ? StructureElement.Loci.extendToWholeEntities(loci)
@@ -211,7 +226,7 @@ namespace Loci {
         }
     }
     export type Granularity = keyof typeof Granularity
-    export const GranularityOptions = Object.keys(Granularity).map(n => [n, capitalize(n)]) as [Granularity, string][]
+    export const GranularityOptions = Object.keys(Granularity).map(n => [n, stringToWords(n)]) as [Granularity, string][]
 
     export function applyGranularity(loci: Loci, granularity: Granularity) {
         return Granularity[granularity](loci)

+ 25 - 0
src/mol-model/structure/structure/element/loci.ts

@@ -408,6 +408,31 @@ export namespace Loci {
         return Loci(loci.structure, elements)
     }
 
+    export function extendToAllInstances(loci: Loci): Loci {
+        const elements: Loci['elements'][0][] = [];
+        const byInvariantId = new Map<number, OrderedSet<UnitIndex>>()
+        const { unitSymmetryGroups, unitSymmetryGroupsIndexMap } = loci.structure
+
+        for (let i = 0, len = loci.elements.length; i < len; i++) {
+            const e = loci.elements[i]
+            const { invariantId } = e.unit
+            if (byInvariantId.has(invariantId)) {
+                byInvariantId.set(invariantId, OrderedSet.union(e.indices, byInvariantId.get(invariantId)!))
+            } else {
+                byInvariantId.set(invariantId, e.indices)
+            }
+        }
+
+        byInvariantId.forEach((indices, invariantId) => {
+            const { units } = unitSymmetryGroups[unitSymmetryGroupsIndexMap.get(invariantId)]
+            for (let i = 0, il = units.length; i < il; ++i) {
+                elements[elements.length] = { unit: units[i], indices }
+            }
+        })
+
+        return Loci(loci.structure, elements);
+    }
+
     //
 
     const boundaryHelper = new BoundaryHelper();

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

@@ -43,6 +43,7 @@ class Structure {
         links?: InterUnitBonds,
         crossLinkRestraints?: PairRestraints<CrossLinkRestraint>,
         unitSymmetryGroups?: ReadonlyArray<Unit.SymmetryGroup>,
+        unitSymmetryGroupsIndexMap?: IntMap<number>,
         carbohydrates?: Carbohydrates,
         models?: ReadonlyArray<Model>,
         model?: Model,
@@ -217,6 +218,13 @@ class Structure {
         return this._props.unitSymmetryGroups;
     }
 
+    /** Maps unit.invariantId to index of SymmetryGroup in unitSymmetryGroups array */
+    get unitSymmetryGroupsIndexMap(): IntMap<number> {
+        if (this._props.unitSymmetryGroupsIndexMap) return this._props.unitSymmetryGroupsIndexMap;
+        this._props.unitSymmetryGroupsIndexMap = Unit.SymmetryGroup.getUnitSymmetryGroupsIndexMap(this.unitSymmetryGroups);
+        return this._props.unitSymmetryGroupsIndexMap;
+    }
+
     get carbohydrates(): Carbohydrates {
         if (this._props.carbohydrates) return this._props.carbohydrates;
         this._props.carbohydrates = computeCarbohydrates(this);

+ 8 - 0
src/mol-model/structure/structure/unit.ts

@@ -86,6 +86,14 @@ namespace Unit {
             if (a.hashCode !== b.hashCode) return false;
             return SortedArray.areEqual(a.elements, b.elements);
         }
+
+        export function getUnitSymmetryGroupsIndexMap(symmetryGroups: ReadonlyArray<Unit.SymmetryGroup>): IntMap<number> {
+            const unitSymmetryGroupsIndexMap = IntMap.Mutable<number>();
+            for (let i = 0, _i = symmetryGroups.length; i < _i; i++) {
+                unitSymmetryGroupsIndexMap.set(symmetryGroups[i].units[0].invariantId, i);
+            }
+            return unitSymmetryGroupsIndexMap
+        }
     }
 
     export function conformationId (unit: Unit) {