JonStargaryen 3 years ago
parent
commit
6ad09c60c0

+ 23 - 29
src/mol-model-props/computed/accessible-surface-area/shrake-rupley/area.ts

@@ -8,7 +8,6 @@
 import { ShrakeRupleyContext, VdWLookup } from './common';
 import { Vec3 } from '../../../../mol-math/linear-algebra';
 import { RuntimeContext } from '../../../../mol-task';
-import { StructureProperties, StructureElement, Structure } from '../../../../mol-model/structure/structure';
 
 // TODO
 // - iterate over units and elements
@@ -28,35 +27,27 @@ export async function computeArea(runtime: RuntimeContext, ctx: ShrakeRupleyCont
     }
 }
 
+const v3set = Vec3.set;
 const aPos = Vec3();
 
-function setLocation(l: StructureElement.Location, structure: Structure, serialIndex: number) {
-    l.structure = structure;
-    l.unit = structure.units[structure.serialMapping.unitIndices[serialIndex]];
-    l.element = structure.serialMapping.elementIndices[serialIndex];
-    return l;
-}
-
 function computeRange(ctx: ShrakeRupleyContext, begin: number, end: number) {
     const { structure, atomRadiusType, serialResidueIndex, area, spherePoints, scalingConstant, maxLookupRadius, probeSize } = ctx;
-    const aLoc = StructureElement.Location.create(structure);
-    const bLoc = StructureElement.Location.create(structure);
-    const { x, y, z } = StructureProperties.atom;
-    const { lookup3d, serialMapping, unitIndexMap } = structure;
-    const { cumulativeUnitElementCount } = serialMapping;
+    const { lookup3d, serialMapping, unitIndexMap, units } = structure;
+    const { cumulativeUnitElementCount, elementIndices, unitIndices } = serialMapping;
 
     for (let aI = begin; aI < end; ++aI) {
         const vdw1 = VdWLookup[atomRadiusType[aI]];
         if (vdw1 === VdWLookup[0]) continue;
 
-        setLocation(aLoc, structure, aI);
-        const aX = x(aLoc);
-        const aY = y(aLoc);
-        const aZ = z(aLoc);
-        Vec3.set(aPos, x(aLoc), y(aLoc), z(aLoc));
+        const aUnit = units[unitIndices[aI]];
+        const aElementIndex = elementIndices[aI];
+        const aX = aUnit.conformation.x(aElementIndex);
+        const aY = aUnit.conformation.y(aElementIndex);
+        const aZ = aUnit.conformation.z(aElementIndex);
+        v3set(aPos, aX, aY, aZ);
 
         // pre-filter by lookup3d (provides >10x speed-up compared to naive evaluation)
-        const { count, units, indices, squaredDistances } = lookup3d.find(aX, aY, aZ, maxLookupRadius);
+        const { count, units: lUnits, indices, squaredDistances } = lookup3d.find(aX, aY, aZ, maxLookupRadius);
 
         // see optimizations proposed in Eisenhaber et al., 1995 (https://doi.org/10.1002/jcc.540160303)
         // collect neighbors for each atom
@@ -64,23 +55,26 @@ function computeRange(ctx: ShrakeRupleyContext, begin: number, end: number) {
         const cutoff1 = probeSize + radius1;
         let neighbors = []; // TODO reuse
         for (let iI = 0; iI < count; ++iI) {
-            const bUnit = units[iI];
-            StructureElement.Location.set(bLoc, ctx.structure, bUnit, bUnit.elements[indices[iI]]);
+            const bUnit = lUnits[iI];
             const bI = cumulativeUnitElementCount[unitIndexMap.get(bUnit.id)] + indices[iI];
+            const bElementIndex = elementIndices[bI];
 
             const vdw2 = VdWLookup[atomRadiusType[bI]];
-            if (StructureElement.Location.areEqual(aLoc, bLoc) || vdw2 === VdWLookup[0]) continue;
+            if ((aUnit === bUnit && aElementIndex === bElementIndex) || vdw2 === VdWLookup[0]) continue;
 
             const cutoff2 = (cutoff1 + vdw2) * (cutoff1 + vdw2);
             const radius2 = probeSize + vdw2;
             if (squaredDistances[iI] < cutoff2) {
-                setLocation(bLoc, structure, bI);
+                const bElementIndex = elementIndices[bI];
+                const bX = bUnit.conformation.x(bElementIndex);
+                const bY = bUnit.conformation.y(bElementIndex);
+                const bZ = bUnit.conformation.z(bElementIndex);
                 // while here: compute values for later lookup
                 neighbors[neighbors.length] = [squaredDistances[iI],
                     (squaredDistances[iI] + radius1 * radius1 - radius2 * radius2) / (2 * radius1),
-                    x(bLoc) - aPos[0],
-                    y(bLoc) - aPos[1],
-                    z(bLoc) - aPos[2]];
+                    bX - aPos[0],
+                    bY - aPos[1],
+                    bZ - aPos[2]];
             }
         }
 
@@ -89,10 +83,10 @@ function computeRange(ctx: ShrakeRupleyContext, begin: number, end: number) {
 
         let accessiblePointCount = 0;
         sl: for (let sI = 0; sI < spherePoints.length; ++sI) {
-            const [sx, sy, sz] = spherePoints[sI];
+            const [sX, sY, sZ] = spherePoints[sI];
             for (let nI = 0; nI < neighbors.length; ++nI) {
-                const [, sqRadius, nx, ny, nz] = neighbors[nI];
-                const dot = sx * nx + sy * ny + sz * nz;
+                const [, sqRadius, nX, nY, nZ] = neighbors[nI];
+                const dot = sX * nX + sY * nY + sZ * nZ;
                 if (dot > sqRadius) {
                     continue sl;
                 }