Skip to content
Snippets Groups Projects
Commit 40b5605e authored by JonStargaryen's avatar JonStargaryen
Browse files

local Vec3 methods

parent 609654b6
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment