Browse Source

Optimized inter-unit link computation (~2.5x faster)

David Sehnal 6 years ago
parent
commit
5a3364fb46

+ 11 - 6
src/mol-model/structure/structure/unit/links/inter-compute.ts

@@ -55,13 +55,20 @@ function findPairLinks(unitA: Unit.Atomic, unitB: Unit.Atomic, params: LinkCompu
     // the lookup queries need to happen in the "unitB space".
     // that means imageA = inverseOperB(operA(aI))
     const imageTransform = Mat4.mul(_imageTransform, unitB.conformation.operator.inverse, unitA.conformation.operator.matrix);
+    const isNotIdentity = !Mat4.isIdentity(imageTransform);
     const imageA = Vec3.zero();
 
+    const { center: bCenter, radius: bRadius } = lookup3d.boundary.sphere;
+    const testDistanceSq = (bRadius + MAX_RADIUS) * (bRadius + MAX_RADIUS);
+
     for (let _aI = 0; _aI < atomCount; _aI++) {
-        const aI =  atomsA[_aI];
+        const aI = atomsA[_aI];
+        Vec3.set(imageA, xA[aI], yA[aI], zA[aI]);
+        if (isNotIdentity) Vec3.transformMat4(imageA, imageA, imageTransform);
+        if (Vec3.squaredDistance(imageA, bCenter) > testDistanceSq) continue;
 
         const structConnEntries = params.forceCompute ? void 0 : structConn && structConn.getAtomEntries(aI);
-        if (structConnEntries) {
+        if (structConnEntries && structConnEntries.length) {
             for (const se of structConnEntries) {
                 if (se.distance < MAX_RADIUS) continue;
 
@@ -74,13 +81,10 @@ function findPairLinks(unitA: Unit.Atomic, unitB: Unit.Atomic, params: LinkCompu
             }
         }
 
-        const aeI = getElementIdx(type_symbolA.value(aI));
-
-        Vec3.set(imageA, xA[aI], yA[aI], zA[aI]);
-        Vec3.transformMat4(imageA, imageA, imageTransform);
         const { indices, count, squaredDistances } = lookup3d.find(imageA[0], imageA[1], imageA[2], MAX_RADIUS);
         if (count === 0) continue;
 
+        const aeI = getElementIdx(type_symbolA.value(aI));
         const isHa = isHydrogen(aeI);
         const thresholdA = getElementThreshold(aeI);
         const altA = label_alt_idA.value(aI);
@@ -154,6 +158,7 @@ function findLinks(structure: Structure, params: LinkComputationParameters) {
 
     const lookup = structure.lookup3d;
     const imageCenter = Vec3.zero();
+
     for (const unit of structure.units) {
         if (!Unit.isAtomic(unit)) continue;
 

+ 24 - 17
src/perf-tests/structure.ts

@@ -34,26 +34,26 @@ async function readData(path: string) {
     }
 }
 
-(Symbol as any).asyncIterator = (Symbol as any).asyncIterator || Symbol.for('Symbol.asyncIterator');
+// (Symbol as any).asyncIterator = (Symbol as any).asyncIterator || Symbol.for('Symbol.asyncIterator');
 
-interface ProgressGenerator<T> extends AsyncIterableIterator<number | T> {
-    next(cont?: boolean): Promise<IteratorResult<number | T>>
-}
+// interface ProgressGenerator<T> extends AsyncIterableIterator<number | T> {
+//     next(cont?: boolean): Promise<IteratorResult<number | T>>
+// }
 
-async function *test(): ProgressGenerator<boolean> {
-    const r = yield await new Promise<number>(res => res(10));
-    return r;
-}
+// async function *test(): ProgressGenerator<boolean> {
+//     const r = yield await new Promise<number>(res => res(10));
+//     return r;
+// }
 
-async function runIt(itP: () => ProgressGenerator<boolean>) {
-    const it = itP();
-    while (true) {
-        const { value, done } = await it.next(true);
-        if (done) return value;
-    }
-}
+// async function runIt(itP: () => ProgressGenerator<boolean>) {
+//     const it = itP();
+//     while (true) {
+//         const { value, done } = await it.next(true);
+//         if (done) return value;
+//     }
+// }
 
-runIt(test).then(r => console.log('rerdasdasda', r))
+// runIt(test).then(r => console.log('rerdasdasda', r))
 
 export async function readCIF(path: string) {
     console.time('readData');
@@ -375,6 +375,13 @@ export namespace PropertyAccess {
         return StructureQuery.run(q, s);
     }
 
+    export async function runLinks() {
+        const { structures } = await readCIF('e:/test/quick/3j3q_full.bcif');
+        console.time('links');
+        structures[0].links
+        console.timeEnd('links');
+    }
+
     export async function run() {
         //const { structures, models/*, mmcif*/ } = await getBcif('1cbs');
         // const { structures, models } = await getBcif('3j3q');
@@ -483,4 +490,4 @@ export namespace PropertyAccess {
     }
 }
 
-PropertyAccess.run();
+PropertyAccess.runLinks();