Skip to content
Snippets Groups Projects
Commit 5a3364fb authored by David Sehnal's avatar David Sehnal
Browse files

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

parent d6e867e5
No related branches found
No related tags found
No related merge requests found
...@@ -55,13 +55,20 @@ function findPairLinks(unitA: Unit.Atomic, unitB: Unit.Atomic, params: LinkCompu ...@@ -55,13 +55,20 @@ function findPairLinks(unitA: Unit.Atomic, unitB: Unit.Atomic, params: LinkCompu
// the lookup queries need to happen in the "unitB space". // the lookup queries need to happen in the "unitB space".
// that means imageA = inverseOperB(operA(aI)) // that means imageA = inverseOperB(operA(aI))
const imageTransform = Mat4.mul(_imageTransform, unitB.conformation.operator.inverse, unitA.conformation.operator.matrix); const imageTransform = Mat4.mul(_imageTransform, unitB.conformation.operator.inverse, unitA.conformation.operator.matrix);
const isNotIdentity = !Mat4.isIdentity(imageTransform);
const imageA = Vec3.zero(); 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++) { 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); const structConnEntries = params.forceCompute ? void 0 : structConn && structConn.getAtomEntries(aI);
if (structConnEntries) { if (structConnEntries && structConnEntries.length) {
for (const se of structConnEntries) { for (const se of structConnEntries) {
if (se.distance < MAX_RADIUS) continue; if (se.distance < MAX_RADIUS) continue;
...@@ -74,13 +81,10 @@ function findPairLinks(unitA: Unit.Atomic, unitB: Unit.Atomic, params: LinkCompu ...@@ -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); const { indices, count, squaredDistances } = lookup3d.find(imageA[0], imageA[1], imageA[2], MAX_RADIUS);
if (count === 0) continue; if (count === 0) continue;
const aeI = getElementIdx(type_symbolA.value(aI));
const isHa = isHydrogen(aeI); const isHa = isHydrogen(aeI);
const thresholdA = getElementThreshold(aeI); const thresholdA = getElementThreshold(aeI);
const altA = label_alt_idA.value(aI); const altA = label_alt_idA.value(aI);
...@@ -154,6 +158,7 @@ function findLinks(structure: Structure, params: LinkComputationParameters) { ...@@ -154,6 +158,7 @@ function findLinks(structure: Structure, params: LinkComputationParameters) {
const lookup = structure.lookup3d; const lookup = structure.lookup3d;
const imageCenter = Vec3.zero(); const imageCenter = Vec3.zero();
for (const unit of structure.units) { for (const unit of structure.units) {
if (!Unit.isAtomic(unit)) continue; if (!Unit.isAtomic(unit)) continue;
......
...@@ -34,26 +34,26 @@ async function readData(path: string) { ...@@ -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> { // interface ProgressGenerator<T> extends AsyncIterableIterator<number | T> {
next(cont?: boolean): Promise<IteratorResult<number | T>> // next(cont?: boolean): Promise<IteratorResult<number | T>>
} // }
async function *test(): ProgressGenerator<boolean> { // async function *test(): ProgressGenerator<boolean> {
const r = yield await new Promise<number>(res => res(10)); // const r = yield await new Promise<number>(res => res(10));
return r; // return r;
} // }
async function runIt(itP: () => ProgressGenerator<boolean>) { // async function runIt(itP: () => ProgressGenerator<boolean>) {
const it = itP(); // const it = itP();
while (true) { // while (true) {
const { value, done } = await it.next(true); // const { value, done } = await it.next(true);
if (done) return value; // 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) { export async function readCIF(path: string) {
console.time('readData'); console.time('readData');
...@@ -375,6 +375,13 @@ export namespace PropertyAccess { ...@@ -375,6 +375,13 @@ export namespace PropertyAccess {
return StructureQuery.run(q, s); 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() { export async function run() {
//const { structures, models/*, mmcif*/ } = await getBcif('1cbs'); //const { structures, models/*, mmcif*/ } = await getBcif('1cbs');
// const { structures, models } = await getBcif('3j3q'); // const { structures, models } = await getBcif('3j3q');
...@@ -483,4 +490,4 @@ export namespace PropertyAccess { ...@@ -483,4 +490,4 @@ export namespace PropertyAccess {
} }
} }
PropertyAccess.run(); PropertyAccess.runLinks();
\ No newline at end of file \ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment