Ver Fonte

add maxDistance prop to IndexPairBonds

Alexander Rose há 3 anos atrás
pai
commit
44308fa1fd

+ 10 - 6
src/mol-model-formats/structure/property/bonds/index-pair.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 Mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2021 Mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -11,14 +11,15 @@ import { FormatPropertyProvider } from '../../common/property';
 import { BondType } from '../../../../mol-model/structure/model/types';
 import { ElementIndex } from '../../../../mol-model/structure';
 
-export type IndexPairBondsProps = {
+export type IndexPairsProps = {
     readonly order: ArrayLike<number>
     readonly distance: ArrayLike<number>
     readonly flag: ArrayLike<BondType.Flag>
 }
-export type IndexPairBonds = IntAdjacencyGraph<ElementIndex, IndexPairBondsProps>
+export type IndexPairs = IntAdjacencyGraph<ElementIndex, IndexPairsProps>
+export type IndexPairBonds = { bonds: IndexPairs, maxDistance: number }
 
-function getGraph(indexA: ArrayLike<ElementIndex>, indexB: ArrayLike<ElementIndex>, props: Partial<IndexPairBondsProps>, count: number): IndexPairBonds {
+function getGraph(indexA: ArrayLike<ElementIndex>, indexB: ArrayLike<ElementIndex>, props: Partial<IndexPairsProps>, count: number): IndexPairs {
     const builder = new IntAdjacencyGraph.EdgeBuilder(count, indexA, indexB);
     const order = new Int8Array(builder.slotCount);
     const distance = new Array(builder.slotCount);
@@ -51,13 +52,16 @@ export namespace IndexPairBonds {
         count: number
     }
 
-    export function fromData(data: Data) {
+    export function fromData(data: Data, maxDistance = 4): IndexPairBonds {
         const { pairs, count } = data;
         const indexA = pairs.indexA.toArray() as ArrayLike<ElementIndex>;
         const indexB = pairs.indexB.toArray() as ArrayLike<ElementIndex>;
         const order = pairs.order && pairs.order.toArray();
         const distance = pairs.distance && pairs.distance.toArray();
         const flag = pairs.flag && pairs.flag.toArray();
-        return getGraph(indexA, indexB, { order, distance, flag }, count);
+        return {
+            bonds: getGraph(indexA, indexB, { order, distance, flag }, count),
+            maxDistance
+        };
     }
 }

+ 8 - 6
src/mol-model/structure/structure/unit/bonds/inter-compute.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2020 Mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2021 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>
@@ -73,11 +73,12 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
         if (Vec3.squaredDistance(_imageA, bCenter) > testDistanceSq) continue;
 
         if (!props.forceCompute && indexPairs) {
-            const { order, distance, flag } = indexPairs.edgeProps;
+            const { maxDistance } = indexPairs;
+            const { offset, b, edgeProps: { order, distance, flag } } = indexPairs.bonds;
 
             const srcA = sourceIndex.value(aI);
-            for (let i = indexPairs.offset[srcA], il = indexPairs.offset[srcA + 1]; i < il; ++i) {
-                const bI = invertedIndex![indexPairs.b[i]];
+            for (let i = offset[srcA], il = offset[srcA + 1]; i < il; ++i) {
+                const bI = invertedIndex![b[i]];
 
                 const _bI = SortedArray.indexOf(unitB.elements, bI) as StructureElement.UnitIndex;
                 if (_bI < 0) continue;
@@ -85,7 +86,7 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
 
                 const d = distance[i];
                 const dist = getDistance(unitA, aI, unitB, bI);
-                if ((d !== -1 && equalEps(dist, d, 0.5)) || dist < maxRadius) {
+                if ((d !== -1 && equalEps(dist, d, 0.5)) || dist < maxDistance) {
                     builder.add(_aI, _bI, { order: order[i], flag: flag[i] });
                 }
             }
@@ -187,8 +188,9 @@ const DefaultInterBondComputationProps = {
 
 function findBonds(structure: Structure, props: InterBondComputationProps) {
     const builder = new InterUnitGraph.Builder<number, StructureElement.UnitIndex, InterUnitEdgeProps>();
+    const hasIndexPairBonds = structure.models.some(m => IndexPairBonds.Provider.get(m));
 
-    if (props.noCompute || structure.isCoarseGrained) {
+    if (props.noCompute || (structure.isCoarseGrained && !hasIndexPairBonds)) {
         // TODO add function that only adds bonds defined in structConn and avoids using
         //      structure.lookup and unit.lookup (expensive for large structure and not
         //      needed for archival files or files with an MD topology)

+ 14 - 15
src/mol-model/structure/structure/unit/bonds/intra-compute.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2020 Mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2021 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>
@@ -44,14 +44,13 @@ function getDistance(unit: Unit.Atomic, indexA: ElementIndex, indexB: ElementInd
 
 const __structConnAdded = new Set<StructureElement.UnitIndex>();
 
-function findIndexPairBonds(unit: Unit.Atomic, props: BondComputationProps) {
-    const { maxRadius } = props;
-
+function findIndexPairBonds(unit: Unit.Atomic) {
     const indexPairs = IndexPairBonds.Provider.get(unit.model)!;
     const { elements: atoms } = unit;
     const { type_symbol } = unit.model.atomicHierarchy.atoms;
     const atomCount = unit.elements.length;
-    const { edgeProps } = indexPairs;
+    const { maxDistance } = indexPairs;
+    const { offset, b, edgeProps: { order, distance, flag } } = indexPairs.bonds;
 
     const { atomSourceIndex: sourceIndex } = unit.model.atomicHierarchy;
     const { invertedIndex } = Model.getInvertedAtomSourceIndex(unit.model);
@@ -59,7 +58,7 @@ function findIndexPairBonds(unit: Unit.Atomic, props: BondComputationProps) {
     const atomA: StructureElement.UnitIndex[] = [];
     const atomB: StructureElement.UnitIndex[] = [];
     const flags: number[] = [];
-    const order: number[] = [];
+    const orders: number[] = [];
 
     for (let _aI = 0 as StructureElement.UnitIndex; _aI < atomCount; _aI++) {
         const aI =  atoms[_aI];
@@ -67,26 +66,26 @@ function findIndexPairBonds(unit: Unit.Atomic, props: BondComputationProps) {
 
         const srcA = sourceIndex.value(aI);
 
-        for (let i = indexPairs.offset[srcA], il = indexPairs.offset[srcA + 1]; i < il; ++i) {
-            const bI = invertedIndex[indexPairs.b[i]];
+        for (let i = offset[srcA], il = offset[srcA + 1]; i < il; ++i) {
+            const bI = invertedIndex[b[i]];
             if (aI >= bI) continue;
 
             const _bI = SortedArray.indexOf(unit.elements, bI) as StructureElement.UnitIndex;
             if (_bI < 0) continue;
             if (isHa && type_symbol.value(bI) === 'H') continue;
 
-            const d = edgeProps.distance[i];
+            const d = distance[i];
             const dist = getDistance(unit, aI, bI);
-            if ((d !== -1 && equalEps(dist, d, 0.5)) || dist < maxRadius) {
+            if ((d !== -1 && equalEps(dist, d, 0.5)) || dist < maxDistance) {
                 atomA[atomA.length] = _aI;
                 atomB[atomB.length] = _bI;
-                order[order.length] = edgeProps.order[i];
-                flags[flags.length] = edgeProps.flag[i];
+                orders[order.length] = order[i];
+                flags[flags.length] = flag[i];
             }
         }
     }
 
-    return getGraph(atomA, atomB, order, flags, atomCount, false);
+    return getGraph(atomA, atomB, orders, flags, atomCount, false);
 }
 
 function findBonds(unit: Unit.Atomic, props: BondComputationProps): IntraUnitBonds {
@@ -248,8 +247,8 @@ function computeIntraUnitBonds(unit: Unit.Atomic, props?: Partial<BondComputatio
         return IntraUnitBonds.Empty;
     }
 
-    if (!p.forceCompute && IndexPairBonds.Provider.get(unit.model)!) {
-        return findIndexPairBonds(unit, p);
+    if (!p.forceCompute && IndexPairBonds.Provider.get(unit.model)) {
+        return findIndexPairBonds(unit);
     } else {
         return findBonds(unit, p);
     }