Browse Source

local Vec3 methods

JonStargaryen 3 years ago
parent
commit
40b5605e10
1 changed files with 58 additions and 43 deletions
  1. 58 43
      src/extensions/anvil/algorithm.ts

+ 58 - 43
src/extensions/anvil/algorithm.ts

@@ -59,6 +59,21 @@ export function computeANVIL(structure: Structure, props: ANVILProps) {
     });
 }
 
+// avoiding namespace lookup improved performance in Chrome (Aug 2020)
+const v3add = Vec3.add;
+const v3clone = Vec3.clone;
+const v3create = Vec3.create;
+const v3distance = Vec3.distance;
+const v3dot = Vec3.dot;
+const v3magnitude = Vec3.magnitude;
+const v3normalize = Vec3.normalize;
+const v3scale = Vec3.scale;
+const v3scaleAndAdd = Vec3.scaleAndAdd;
+const v3set = Vec3.set;
+const v3squaredDistance = Vec3.squaredDistance;
+const v3sub = Vec3.sub;
+const v3zero = Vec3.zero;
+
 const centroidHelper = new CentroidHelper();
 async function initialize(runtime: RuntimeContext, structure: Structure, props: ANVILProps): Promise<ANVILContext> {
     const l = StructureElement.Location.create(structure);
@@ -74,7 +89,7 @@ async function initialize(runtime: RuntimeContext, structure: Structure, props:
     const accessibleSurfaceArea = await AccessibleSurfaceArea.compute(structure, p).runInContext(runtime);
     const asaCutoff = props.asaCutoff / 100;
 
-    const vec = Vec3();
+    const vec = v3zero();
     let m = 0;
     let n = 0;
     for (let i = 0, il = structure.units.length; i < il; ++i) {
@@ -102,7 +117,7 @@ async function initialize(runtime: RuntimeContext, structure: Structure, props:
             }
 
             // while iterating use first pass to compute centroid
-            Vec3.set(vec, x(l), y(l), z(l));
+            v3set(vec, x(l), y(l), z(l));
             centroidHelper.includeStep(vec);
 
             // keep track of offsets and exposed state to reuse
@@ -119,10 +134,10 @@ async function initialize(runtime: RuntimeContext, structure: Structure, props:
 
     // calculate centroid and extent
     centroidHelper.finishedIncludeStep();
-    const centroid = Vec3.clone(centroidHelper.center);
+    const centroid = v3clone(centroidHelper.center);
     for (let k = 0, kl = offsets.length; k < kl; k++) {
         setLocation(l, structure, offsets[k]);
-        Vec3.set(vec, x(l), y(l), z(l));
+        v3set(vec, x(l), y(l), z(l));
         centroidHelper.radiusStep(vec);
     }
     const extent = 1.2 * Math.sqrt(centroidHelper.radiusSq);
@@ -150,13 +165,13 @@ export async function calculate(runtime: RuntimeContext, structure: Structure, p
         membrane = await adjustThickness(runtime, 'Adjusting membrane thickness...', ctx, membrane, initialHphobHphil);
     }
 
-    const normalVector = Vec3.zero();
-    const center =  Vec3.zero();
-    Vec3.sub(normalVector, membrane.planePoint1, membrane.planePoint2);
-    Vec3.normalize(normalVector, normalVector);
+    const normalVector = v3zero();
+    const center =  v3zero();
+    v3sub(normalVector, membrane.planePoint1, membrane.planePoint2);
+    v3normalize(normalVector, normalVector);
 
-    Vec3.add(center, membrane.planePoint1, membrane.planePoint2);
-    Vec3.scale(center, center, 0.5);
+    v3add(center, membrane.planePoint1, membrane.planePoint2);
+    v3scale(center, center, 0.5);
     const extent = adjustExtent(ctx, membrane, center);
 
     return {
@@ -187,8 +202,8 @@ namespace MembraneCandidate {
     }
 
     export function scored(spherePoint: Vec3, planePoint1: Vec3, planePoint2: Vec3, stats: HphobHphil, qmax: number, centroid: Vec3): MembraneCandidate {
-        const normalVector = Vec3();
-        Vec3.sub(normalVector, centroid, spherePoint);
+        const normalVector = v3zero();
+        v3sub(normalVector, centroid, spherePoint);
         return {
             planePoint1,
             planePoint2,
@@ -208,25 +223,25 @@ async function findMembrane(runtime: RuntimeContext, message: string | undefined
     let qmax = 0;
 
     // construct slices of thickness 1.0 along the axis connecting the centroid and the spherePoint
-    const diam = Vec3();
+    const diam = v3zero();
     for (let n = 0, nl = spherePoints.length; n < nl; n++) {
         if (runtime?.shouldUpdate && message && (n + 1) % UPDATE_INTERVAL === 0) {
             await runtime.update({ message, current: (n + 1), max: nl });
         }
 
         const spherePoint = spherePoints[n];
-        Vec3.sub(diam, centroid, spherePoint);
-        Vec3.scale(diam, diam, 2);
-        const diamNorm = Vec3.magnitude(diam);
+        v3sub(diam, centroid, spherePoint);
+        v3scale(diam, diam, 2);
+        const diamNorm = v3magnitude(diam);
         const qvartemp = [];
 
         for (let i = 0, il = diamNorm - stepSize; i < il; i += stepSize) {
-            const c1 = Vec3();
-            const c2 = Vec3();
-            Vec3.scaleAndAdd(c1, spherePoint, diam, i / diamNorm);
-            Vec3.scaleAndAdd(c2, spherePoint, diam, (i + stepSize) / diamNorm);
-            const d1 = -Vec3.dot(diam, c1);
-            const d2 = -Vec3.dot(diam, c2);
+            const c1 = v3zero();
+            const c2 = v3zero();
+            v3scaleAndAdd(c1, spherePoint, diam, i / diamNorm);
+            v3scaleAndAdd(c2, spherePoint, diam, (i + stepSize) / diamNorm);
+            const d1 = -v3dot(diam, c1);
+            const d2 = -v3dot(diam, c2);
             const dMin = Math.min(d1, d2);
             const dMax = Math.max(d1, d2);
 
@@ -273,7 +288,7 @@ async function findMembrane(runtime: RuntimeContext, message: string | undefined
 async function adjustThickness(runtime: RuntimeContext, message: string | undefined, ctx: ANVILContext, membrane: MembraneCandidate, initialHphobHphil: HphobHphil): Promise<MembraneCandidate> {
     const { minThickness } = ctx;
     const step = 0.3;
-    let maxThickness = Vec3.distance(membrane.planePoint1, membrane.planePoint2);
+    let maxThickness = v3distance(membrane.planePoint1, membrane.planePoint2);
 
     let maxNos = membraneSegments(ctx, membrane).length;
     let optimalThickness = membrane;
@@ -310,12 +325,12 @@ function membraneSegments(ctx: ANVILContext, membrane: MembraneCandidate): Array
     const { offsets, structure, adjust } = ctx;
     const { normalVector, planePoint1, planePoint2 } = membrane;
     const l = StructureElement.Location.create(structure);
-    const testPoint = Vec3();
+    const testPoint = v3zero();
     const { auth_asym_id } = StructureProperties.chain;
     const { auth_seq_id } = StructureProperties.residue;
 
-    const d1 = -Vec3.dot(normalVector!, planePoint1);
-    const d2 = -Vec3.dot(normalVector!, planePoint2);
+    const d1 = -v3dot(normalVector!, planePoint1);
+    const d2 = -v3dot(normalVector!, planePoint2);
     const dMin = Math.min(d1, d2);
     const dMax = Math.max(d1, d2);
 
@@ -341,7 +356,7 @@ function membraneSegments(ctx: ANVILContext, membrane: MembraneCandidate): Array
         }
 
         authSeqId = auth_seq_id(l);
-        Vec3.set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
+        v3set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
         if (_isInMembranePlane(testPoint, normalVector!, dMin, dMax)) {
             inMembrane[authAsymId].add(authSeqId);
         } else {
@@ -387,12 +402,12 @@ function membraneSegments(ctx: ANVILContext, membrane: MembraneCandidate): Array
 
         // evaluate residues 1 pos outside of membrane
         setLocation(l, structure, offsets[start - 1]);
-        Vec3.set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
-        const d3 = -Vec3.dot(normalVector!, testPoint);
+        v3set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
+        const d3 = -v3dot(normalVector!, testPoint);
 
         setLocation(l, structure, offsets[end + 1]);
-        Vec3.set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
-        const d4 = -Vec3.dot(normalVector!, testPoint);
+        v3set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
+        const d4 = -v3dot(normalVector!, testPoint);
 
         if (Math.min(d3, d4) < dMin && Math.max(d3, d4) > dMax) {
             // reject this refinement
@@ -415,20 +430,20 @@ function adjustExtent(ctx: ANVILContext, membrane: MembraneCandidate, centroid:
     const { offsets, structure } = ctx;
     const { normalVector, planePoint1, planePoint2 } = membrane;
     const l = StructureElement.Location.create(structure);
-    const testPoint = Vec3();
+    const testPoint = v3zero();
     const { x, y, z } = StructureProperties.atom;
 
-    const d1 = -Vec3.dot(normalVector!, planePoint1);
-    const d2 = -Vec3.dot(normalVector!, planePoint2);
+    const d1 = -v3dot(normalVector!, planePoint1);
+    const d2 = -v3dot(normalVector!, planePoint2);
     const dMin = Math.min(d1, d2);
     const dMax = Math.max(d1, d2);
     let extent = 0;
 
     for (let k = 0, kl = offsets.length; k < kl; k++) {
         setLocation(l, structure, offsets[k]);
-        Vec3.set(testPoint, x(l), y(l), z(l));
+        v3set(testPoint, x(l), y(l), z(l));
         if (_isInMembranePlane(testPoint, normalVector!, dMin, dMax)) {
-            const dsq = Vec3.squaredDistance(testPoint, centroid);
+            const dsq = v3squaredDistance(testPoint, centroid);
             if (dsq > extent) extent = dsq;
         }
     }
@@ -451,13 +466,13 @@ function qValue(currentStats: HphobHphil, initialStats: HphobHphil): number {
 }
 
 export function isInMembranePlane(testPoint: Vec3, normalVector: Vec3, planePoint1: Vec3, planePoint2: Vec3): boolean {
-    const d1 = -Vec3.dot(normalVector, planePoint1);
-    const d2 = -Vec3.dot(normalVector, planePoint2);
+    const d1 = -v3dot(normalVector, planePoint1);
+    const d2 = -v3dot(normalVector, planePoint2);
     return _isInMembranePlane(testPoint, normalVector, Math.min(d1, d2), Math.max(d1, d2));
 }
 
 function _isInMembranePlane(testPoint: Vec3, normalVector: Vec3, min: number, max: number): boolean {
-    const d = -Vec3.dot(normalVector, testPoint);
+    const d = -v3dot(normalVector, testPoint);
     return d > min && d < max;
 }
 
@@ -471,7 +486,7 @@ function generateSpherePoints(ctx: ANVILContext, numberOfSpherePoints: number):
         theta = Math.acos(h);
         phi = (k === 1 || k === numberOfSpherePoints) ? 0 : (oldPhi + 3.6 / Math.sqrt(numberOfSpherePoints * (1 - h * h))) % (2 * Math.PI);
 
-        const point = Vec3.create(
+        const point = v3create(
             extent * Math.sin(phi) * Math.sin(theta) + centroid[0],
             extent * Math.cos(theta) + centroid[1],
             extent * Math.cos(phi) * Math.sin(theta) + centroid[2]
@@ -494,7 +509,7 @@ function findProximateAxes(ctx: ANVILContext, membrane: MembraneCandidate): Vec3
         const dsq = (s + j) * (s + j);
         sphere_pts2 = [];
         for (let i = 0, il = points.length; i < il; i++) {
-            if (Vec3.squaredDistance(points[i], membrane.spherePoint!) < dsq) {
+            if (v3squaredDistance(points[i], membrane.spherePoint!) < dsq) {
                 sphere_pts2.push(points[i]);
             }
         }
@@ -516,7 +531,7 @@ namespace HphobHphil {
         };
     }
 
-    const testPoint = Vec3();
+    const testPoint = v3zero();
     export function filtered(ctx: ANVILContext, filter?: { normalVector: Vec3, dMin: number, dMax: number }): HphobHphil {
         const { exposed, structure } = ctx;
         const { label_comp_id } = StructureProperties.atom;
@@ -528,7 +543,7 @@ namespace HphobHphil {
 
             // testPoints have to be in putative membrane layer
             if (filter) {
-                Vec3.set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
+                v3set(testPoint, l.unit.conformation.x(l.element), l.unit.conformation.y(l.element), l.unit.conformation.z(l.element));
                 if (!_isInMembranePlane(testPoint, filter.normalVector, filter.dMin, filter.dMax)) {
                     continue;
                 }