Browse Source

always use root topology for valence model

Alexander Rose 5 years ago
parent
commit
7a2e85b856

+ 10 - 0
src/mol-data/int/_spec/sorted-array.spec.ts

@@ -63,6 +63,16 @@ describe('sortedArray', () => {
         compareArrays(SortedArray.indicesOf(SortedArray.ofSortedArray([10, 11, 12]), SortedArray.ofSortedArray([10, 12, 14])), [0, 2]);
     })
 
+    it('indicesOf 2', () => {
+        compareArrays(
+            SortedArray.indicesOf(
+                SortedArray.ofSortedArray([0, 1, 2, 3, 4, 8, 9, 10]),
+                SortedArray.ofSortedArray([1, 3, 4, 9, 10])
+            ),
+            [1, 3, 4, 6, 7]
+        );
+    })
+
     test('intersectionSize', SortedArray.intersectionSize(a1234, a2468), 2);
 
     it('union1', () => {

+ 17 - 2
src/mol-model-props/computed/chemistry/valence-model.ts

@@ -12,6 +12,7 @@ import { bondCount, typeSymbol, formalCharge, bondToElementCount } from './util'
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { RuntimeContext } from '../../../mol-task';
 import { isDebugMode } from '../../../mol-util/debug';
+import { SortedArray } from '../../../mol-data/int';
 
 /**
  * TODO:
@@ -287,8 +288,22 @@ function calcUnitValenceModel(structure: Structure, unit: Unit.Atomic, props: Va
     const totalH = new Int8Array(n)
     const idealGeometry = new Int8Array(n)
 
-    for (let i = 0 as StructureElement.UnitIndex; i < n; ++i) {
-        const [ chg, implH, totH, geom ] = calculateHydrogensCharge(structure, unit, i, props)
+    // always use root UnitIndex to take the topology of the whole structure in account
+    const hasParent = !!structure.parent
+    let mapping: SortedArray
+    if (hasParent) {
+        const rootUnit = structure.root.unitMap.get(unit.id) as Unit.Atomic
+        mapping = SortedArray.indicesOf(rootUnit.elements, unit.elements)
+        if (mapping.length !== unit.elements.length) {
+            throw new Error('expected to find an index for every element')
+        }
+        unit = rootUnit
+        structure = structure.root
+    }
+
+    for (let i = 0; i < n; ++i) {
+        const j = (hasParent ? mapping![i] : i) as StructureElement.UnitIndex
+        const [ chg, implH, totH, geom ] = calculateHydrogensCharge(structure, unit, j, props)
         charge[i] = chg
         implicitH[i] = implH
         totalH[i] = totH