Browse Source

tweak bond assignment from IndexPairBonds

- fix & clarify logic
Alexander Rose 3 years ago
parent
commit
17a18d5fea

+ 7 - 3
src/mol-model-formats/structure/property/bonds/index-pair.ts

@@ -53,7 +53,8 @@ export namespace IndexPairBonds {
             /**
              * Useful for bonds in periodic cells. That is, only bonds within the given
              * distance are added. This allows for bond between periodic image but
-             * avoids unwanted bonds with wrong distances.
+             * avoids unwanted bonds with wrong distances. If negative, test using the
+             * `maxDistance` option from `Props`.
              */
             distance?: Column<number>,
             flag?: Column<BondType.Flag>,
@@ -63,10 +64,13 @@ export namespace IndexPairBonds {
 
     export const DefaultProps = {
         /**
-         * If -1, test using element-based threshold, otherwise distance in Angstrom.
+         * If negative, test using element-based threshold, otherwise distance in Angstrom.
          *
          * This option exists to handle bonds in periodic cells. For systems that are
-         * made from beads (as opposed to atomic elements), set to a spicific distance.
+         * made from beads (as opposed to atomic elements), set to a specific distance.
+         *
+         * Note that `Data` has a `distance` field which allows specifying a distance
+         * for each bond individually which takes precedence over this option.
          */
         maxDistance: -1
     };

+ 19 - 10
src/mol-model/structure/structure/unit/bonds/inter-compute.ts

@@ -85,19 +85,28 @@ function findPairBonds(unitA: Unit.Atomic, unitB: Unit.Atomic, props: BondComput
 
                 const aeI = getElementIdx(type_symbolA.value(aI));
                 const beI = getElementIdx(type_symbolA.value(bI));
-                // only element-based test when maxDistance !== -1
-                if (maxDistance !== -1 && isHydrogen(aeI) && isHydrogen(beI)) continue;
 
                 const d = distance[i];
                 const dist = getDistance(unitA, aI, unitB, bI);
-                const pairingThreshold = getPairingThreshold(
-                    aeI, beI, getElementThreshold(aeI), getElementThreshold(beI)
-                );
-
-                if ((d !== -1 && equalEps(dist, d, 0.5)) ||
-                    (maxDistance !== -1 && dist < maxDistance) ||
-                    dist < pairingThreshold
-                ) {
+
+                let add = false;
+                if (d >= 0) {
+                    add = equalEps(dist, d, 0.3);
+                } else if (maxDistance >= 0) {
+                    add = dist < maxDistance;
+                } else {
+                    const pairingThreshold = getPairingThreshold(
+                        aeI, beI, getElementThreshold(aeI), getElementThreshold(beI)
+                    );
+                    add = dist < pairingThreshold;
+
+                    if (isHydrogen(aeI) && isHydrogen(beI)) {
+                        // TODO handle molecular hydrogen
+                        add = false;
+                    }
+                }
+
+                if (add) {
                     builder.add(_aI, _bI, { order: order[i], flag: flag[i] });
                 }
             }

+ 19 - 10
src/mol-model/structure/structure/unit/bonds/intra-compute.ts

@@ -75,19 +75,28 @@ function findIndexPairBonds(unit: Unit.Atomic) {
             if (_bI < 0) continue;
 
             const beI = getElementIdx(type_symbol.value(bI));
-            // only element-based test when maxDistance !== -1
-            if (maxDistance !== -1 && isHa && isHydrogen(beI)) continue;
 
             const d = distance[i];
             const dist = getDistance(unit, aI, bI);
-            const pairingThreshold = getPairingThreshold(
-                aeI, beI, getElementThreshold(aeI), getElementThreshold(beI)
-            );
-
-            if ((d !== -1 && equalEps(dist, d, 0.5)) ||
-                (maxDistance !== -1 && dist < maxDistance) ||
-                dist < pairingThreshold
-            ) {
+
+            let add = false;
+            if (d >= 0) {
+                add = equalEps(dist, d, 0.3);
+            } else if (maxDistance >= 0) {
+                add = dist < maxDistance;
+            } else {
+                const pairingThreshold = getPairingThreshold(
+                    aeI, beI, getElementThreshold(aeI), getElementThreshold(beI)
+                );
+                add = dist < pairingThreshold;
+
+                if (isHa && isHydrogen(beI)) {
+                    // TODO handle molecular hydrogen
+                    add = false;
+                }
+            }
+
+            if (add) {
                 atomA[atomA.length] = _aI;
                 atomB[atomB.length] = _bI;
                 orders[orders.length] = order[i];