Ver Fonte

Merge branch 'master' into gl-geo

# Conflicts:
#	src/apps/render-test/state.ts
#	src/mol-geo/representation/structure/index.ts
Alexander Rose há 7 anos atrás
pai
commit
2f8bdd6fb4
29 ficheiros alterados com 262 adições e 201 exclusões
  1. 1 1
      src/apps/render-test/state.ts
  2. 32 14
      src/apps/structure-info/index.ts
  3. 6 16
      src/mol-geo/representation/structure/index.ts
  4. 1 1
      src/mol-math/geometry.ts
  5. 5 5
      src/mol-math/geometry/_spec/lookup3d.spec.ts
  6. 5 5
      src/mol-math/geometry/common.ts
  7. 1 1
      src/mol-math/geometry/lookup3d/common.ts
  8. 1 1
      src/mol-math/geometry/lookup3d/grid.ts
  9. 1 1
      src/mol-math/geometry/primitives/box3d.ts
  10. 1 1
      src/mol-math/geometry/primitives/sphere3d.ts
  11. 11 11
      src/mol-model/structure/_spec/atom-set.spec.ts
  12. 3 3
      src/mol-model/structure/model/formats/mmcif/assembly.ts
  13. 5 5
      src/mol-model/structure/model/formats/mmcif/bonds.ts
  14. 0 1
      src/mol-model/structure/model/model.ts
  15. 0 18
      src/mol-model/structure/model/utils/compute-bonds.ts
  16. 20 14
      src/mol-model/structure/query/generators.ts
  17. 12 1
      src/mol-model/structure/query/query.ts
  18. 1 1
      src/mol-model/structure/query/selection.ts
  19. 4 13
      src/mol-model/structure/structure/element/group.ts
  20. 17 1
      src/mol-model/structure/structure/element/impl/set.ts
  21. 18 0
      src/mol-model/structure/structure/element/properties/bonds/group-compute.ts
  22. 5 7
      src/mol-model/structure/structure/element/properties/bonds/group-data.ts
  23. 17 10
      src/mol-model/structure/structure/element/set.ts
  24. 3 8
      src/mol-model/structure/structure/structure.ts
  25. 20 17
      src/mol-model/structure/structure/symmetry.ts
  26. 23 0
      src/mol-model/structure/structure/unit.ts
  27. 6 6
      src/mol-model/structure/structure/util/boundary.ts
  28. 16 16
      src/mol-model/structure/structure/util/lookup3d.ts
  29. 27 23
      src/perf-tests/structure.ts

+ 1 - 1
src/apps/render-test/state.ts

@@ -45,7 +45,7 @@ export default class State {
         this.loading.next(true)
 
         const structures = await getStructuresFromPdbId(pdbId)
-        const struct = Symmetry.buildAssembly(structures[0], '1')
+        const struct = await Run(Symmetry.buildAssembly(structures[0], '1'))
 
         // const structPointRepr = StructureRepresentation(Point)
         // await Run(structPointRepr.create(struct))

+ 32 - 14
src/apps/structure-info/index.ts

@@ -10,8 +10,9 @@ require('util.promisify').shim();
 
 // import { Table } from 'mol-data/db'
 import CIF from 'mol-io/reader/cif'
-import { Model } from 'mol-model/structure'
+import { Model, Structure, ElementSet, Unit, ElementGroup } from 'mol-model/structure'
 import { Run, Progress } from 'mol-task'
+import { OrderedSet } from 'mol-data/int';
 
 async function parseCif(data: string|Uint8Array) {
     const comp = CIF.parse(data);
@@ -21,7 +22,8 @@ async function parseCif(data: string|Uint8Array) {
 }
 
 async function getPdb(pdb: string) {
-    const data = await fetch(`https://files.rcsb.org/download/${pdb}.cif`)
+    //const data = await fetch(`https://files.rcsb.org/download/${pdb}.cif`)
+    const data = await fetch(`http://www.ebi.ac.uk/pdbe/static/entry/${pdb}_updated.cif`);
     const parsed = await parseCif(await data.text())
     return CIF.schema.mmCIF(parsed.result.blocks[0])
 }
@@ -37,24 +39,40 @@ export function atomLabel(model: Model, aI: number) {
 }
 
 
-function printBonds(model: Model) {
-    // TODO: do bonds again
-    // const { count, offset, neighbor } = Model.bonds(model)
-    // for (let i = 0; i < count; ++i) {
-    //     const start = offset[i];
-    //     const end = offset[i + 1];
-    //     for (let bI = start; bI < end; bI++) {
-    //         console.log(`${atomLabel(model, i)} -- ${atomLabel(model, neighbor[bI])}`)
-    //     }
-    // }
+function printBonds(structure: Structure) {
+    const { units, elements } = structure;
+    const unitIds = ElementSet.unitIndices(elements);
+
+    for (let i = 0, _i = OrderedSet.size(unitIds); i < _i; i++) {
+        const unit = units[OrderedSet.getAt(unitIds, i)];
+        const group = ElementSet.groupFromUnitIndex(elements, OrderedSet.getAt(unitIds, i));
+
+        const { count, offset, neighbor } = Unit.getGroupBonds(unit, group);
+        const { model }  = unit;
+
+        if (!count) continue;
+
+        for (let j = 0; j < offset.length - 1; ++j) {
+            const start = offset[j];
+            const end = offset[j + 1];
+
+            if (end <= start) continue;
+
+            const aI = ElementGroup.getAt(group, j);
+            for (let _bI = start; _bI < end; _bI++) {
+                const bI = ElementGroup.getAt(group, neighbor[_bI])
+                console.log(`${atomLabel(model, aI)} -- ${atomLabel(model, bI)}`);
+            }
+        }
+    }
 }
 
 async function run(pdb: string) {
     const mmcif = await getPdb(pdb)
     const models = Model.create({ kind: 'mmCIF', data: mmcif });
-    // const structure = Structure.ofModel(models[0])
+    const structure = Structure.ofModel(models[0])
     // console.log(structure)
-    printBonds(models[0])
+    printBonds(structure)
 }
 
 const parser = new argparse.ArgumentParser({

+ 6 - 16
src/mol-geo/representation/structure/index.ts

@@ -40,10 +40,11 @@ export function StructureRepresentation<Props>(reprCtor: () => UnitsRepresentati
                     (a, b) => a.unit.model.id === b.unit.model.id && OrderedSet.areEqual(a.group.elements, b.group.elements)
                 );
 
-                for (let i = 0, _i = ElementSet.unitCount(elements); i < _i; i++) {
-                    const group = ElementSet.unitGetByIndex(elements, i);
-                    const unitId = ElementSet.unitGetId(elements, i);
-                    uniqueGroups.add(unitId, { unit: units[unitId], group });
+                const unitIndices = ElementSet.unitIndices(elements);
+                for (let i = 0, _i = unitIndices.length; i < _i; i++) {
+                    const unitIndex = unitIndices[i];
+                    const group = ElementSet.groupFromUnitIndex(elements, unitIndex);
+                    uniqueGroups.add(unitIndex, { unit: units[unitIndex], group });
                 }
 
                 for (let i = 0, _i = uniqueGroups.groups.length; i < _i; i++) {
@@ -53,24 +54,13 @@ export function StructureRepresentation<Props>(reprCtor: () => UnitsRepresentati
                     for (let j = 0, _j = group.length; j < _j; j++) {
                         groupUnits.push(units[group[j]])
                     }
-                    const elementGroup = ElementSet.unitGetByIndex(elements, group[0])
+                    const elementGroup = ElementSet.groupFromUnitIndex(elements, group[0])
                     const repr = reprCtor()
                     unitReprs.push(repr)
                     await ctx.update({ message: 'Building units...', current: i, max: _i });
                     await ctx.runChild(repr.create(groupUnits, elementGroup, props));
                     renderObjects.push(...repr.renderObjects)
                 }
-
-                // console.log(ElementSet.unitCount(elements))
-                // console.log(uniqueGroups)
-
-                // console.log({ elements, units })
-
-                // const repr = reprCtor()
-                // unitReprs.push(repr)
-                // await ctx.update('Building units...');
-                // await ctx.runChild(repr.create(units, elements, props));
-                // renderObjects.push(...repr.renderObjects)
             });
         },
         update(elements: ElementSet, props: RepresentationProps) {

+ 1 - 1
src/mol-math/geometry.ts

@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>

+ 5 - 5
src/mol-math/geometry/_spec/lookup3d.spec.ts

@@ -1,8 +1,8 @@
-/*
-* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
-*
-* @author David Sehnal <david.sehnal@gmail.com>
-*/
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
 
 import { GridLookup3D } from '../../geometry';
 import { sortArray } from 'mol-data/util';

+ 5 - 5
src/mol-math/geometry/common.ts

@@ -1,8 +1,8 @@
-/*
-* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
-*
-* @author David Sehnal <david.sehnal@gmail.com>
-*/
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
 
 import { OrderedSet } from 'mol-data/int'
 

+ 1 - 1
src/mol-math/geometry/lookup3d/common.ts

@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>

+ 1 - 1
src/mol-math/geometry/lookup3d/grid.ts

@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>

+ 1 - 1
src/mol-math/geometry/primitives/box3d.ts

@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>

+ 1 - 1
src/mol-math/geometry/primitives/sphere3d.ts

@@ -1,4 +1,4 @@
-/*
+/**
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>

+ 11 - 11
src/mol-model/structure/_spec/atom-set.spec.ts

@@ -26,7 +26,7 @@ describe('atom set', () => {
         expect(setToPairs(set)).toEqual([p(10, 11)]);
         expect(ElementSet.elementHas(set, p(10, 11))).toBe(true);
         expect(ElementSet.elementHas(set, p(11, 11))).toBe(false);
-        expect(ElementSet.elementGetAt(set, 0)).toBe(p(10, 11));
+        expect(ElementSet.elementAt(set, 0)).toBe(p(10, 11));
         expect(ElementSet.elementCount(set)).toBe(1);
     });
 
@@ -35,7 +35,7 @@ describe('atom set', () => {
         expect(setToPairs(set)).toEqual([p(10, 11)]);
         expect(ElementSet.elementHas(set, p(10, 11))).toBe(true);
         expect(ElementSet.elementHas(set, p(11, 11))).toBe(false);
-        expect(ElementSet.elementGetAt(set, 0)).toBe(p(10, 11));
+        expect(ElementSet.elementAt(set, 0)).toBe(p(10, 11));
         expect(ElementSet.elementCount(set)).toBe(1);
     });
 
@@ -51,7 +51,7 @@ describe('atom set', () => {
         expect(ElementSet.elementHas(set, p(3, 0))).toBe(true);
         expect(ElementSet.elementHas(set, p(1, 7))).toBe(true);
         for (let i = 0; i < ElementSet.elementCount(set); i++) {
-            expect(Element.areEqual(ElementSet.elementGetAt(set, i), ret[i])).toBe(true);
+            expect(Element.areEqual(ElementSet.elementAt(set, i), ret[i])).toBe(true);
         }
     });
 
@@ -62,8 +62,8 @@ describe('atom set', () => {
         gen.add(1, OrderedSet.ofSingleton(3));
         const set = gen.getSet();
 
-        expect(ElementSet.unitGetById(set, 0)).toBe(ElementSet.unitGetById(template, 0));
-        expect(ElementSet.unitGetById(set, 1)).toBe(ElementSet.unitGetById(template, 1));
+        expect(ElementSet.groupFromUnitIndex(set, 0)).toBe(ElementSet.groupFromUnitIndex(template, 0));
+        expect(ElementSet.groupFromUnitIndex(set, 1)).toBe(ElementSet.groupFromUnitIndex(template, 1));
         expect(set).toBe(template);
     });
 
@@ -74,8 +74,8 @@ describe('atom set', () => {
         gen.add(1, OrderedSet.ofSingleton(4));
         const set = gen.getSet();
 
-        expect(ElementSet.unitGetById(set, 0)).toBe(ElementSet.unitGetById(template, 0));
-        expect(ElementSet.unitGetById(set, 1) === ElementSet.unitGetById(template, 1)).toBe(false);
+        expect(ElementSet.groupFromUnitIndex(set, 0)).toBe(ElementSet.groupFromUnitIndex(template, 0));
+        expect(ElementSet.groupFromUnitIndex(set, 1) === ElementSet.groupFromUnitIndex(template, 1)).toBe(false);
         expect(set === template).toBe(false);
     });
 
@@ -89,9 +89,9 @@ describe('atom set', () => {
 
         const u0 = ElementSet.union([p01, p02, p06], template);
         const u1 = ElementSet.union([p01, p02, p06, p13], template);
-        expect(ElementSet.unitGetById(u0, 0)).toBe(ElementSet.unitGetById(template, 0));
-        expect(ElementSet.unitGetById(u1, 0)).toBe(ElementSet.unitGetById(template, 0));
-        expect(ElementSet.unitGetById(u1, 1)).toBe(ElementSet.unitGetById(template, 1));
+        expect(ElementSet.groupFromUnitIndex(u0, 0)).toBe(ElementSet.groupFromUnitIndex(template, 0));
+        expect(ElementSet.groupFromUnitIndex(u1, 0)).toBe(ElementSet.groupFromUnitIndex(template, 0));
+        expect(ElementSet.groupFromUnitIndex(u1, 1)).toBe(ElementSet.groupFromUnitIndex(template, 1));
         expect(u1).toBe(template);
     });
 
@@ -108,7 +108,7 @@ describe('atom set', () => {
         }
         const ms = gen.getSet();
         for (let i = 0; i < control.length; i++) {
-            expect(Element.areEqual(ElementSet.elementGetAt(ms, i), control[i])).toBe(true);
+            expect(Element.areEqual(ElementSet.elementAt(ms, i), control[i])).toBe(true);
         }
 
         for (let i = 0; i < control.length; i++) {

+ 3 - 3
src/mol-model/structure/model/formats/mmcif/assembly.ts

@@ -8,7 +8,7 @@ import { Mat4, Tensor } from 'mol-math/linear-algebra'
 import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
 import Format from '../../format'
 import { Assembly, OperatorGroup, OperatorGroups } from '../../properties/symmetry'
-import { Queries as Q } from '../../../query'
+import { Queries as Q, Query } from '../../../query'
 
 import mmCIF_Format = Format.mmCIF
 
@@ -57,10 +57,10 @@ function operatorGroupsProvider(generators: Generator[], matrices: Matrices): ()
             const operatorList = parseOperatorList(gen.expression);
             const operatorNames = expandOperators(operatorList);
             const operators = getAssemblyOperators(matrices, operatorNames, operatorOffset);
-            const selector = Q.generators.atoms({ chainTest: Q.pred.and(
+            const selector = Query(Q.generators.atoms({ chainTest: Q.pred.and(
                 Q.pred.eq(Q.props.unit.operator_name, SymmetryOperator.DefaultName),
                 Q.pred.inSet(Q.props.chain.label_asym_id, gen.asymIds)
-            )});
+            )}));
             groups[groups.length] = { selector, operators };
             operatorOffset += operators.length;
         }

+ 5 - 5
src/mol-model/structure/model/formats/mmcif/bonds.ts

@@ -6,12 +6,12 @@
  */
 
 import Model from '../../model'
-import Bonds from '../../properties/bonds'
 import { BondType } from '../../types'
 import { findEntityIdByAsymId, findAtomIndexByLabelName } from './util'
 import { Column } from 'mol-data/db'
+import { GroupBonds } from '../../../structure/element/properties/bonds/group-data';
 
-export class StructConn implements Bonds.StructConn {
+export class StructConn implements GroupBonds.StructConn {
     private _residuePairIndex: Map<string, StructConn.Entry[]> | undefined = void 0;
     private _atomIndex: Map<number, StructConn.Entry[]> | undefined = void 0;
 
@@ -71,7 +71,7 @@ export class StructConn implements Bonds.StructConn {
 }
 
 export namespace StructConn {
-    export interface Entry extends Bonds.StructConnEntry {
+    export interface Entry extends GroupBonds.StructConnEntry {
         distance: number,
         order: number,
         flags: number,
@@ -181,7 +181,7 @@ export namespace StructConn {
     }
 }
 
-export class ComponentBondInfo implements Bonds.ComponentBondInfo {
+export class ComponentBondInfo implements GroupBonds.ComponentBondInfo {
     entries: Map<string, ComponentBondInfo.Entry> = new Map();
 
     newEntry(id: string) {
@@ -192,7 +192,7 @@ export class ComponentBondInfo implements Bonds.ComponentBondInfo {
 }
 
 export namespace ComponentBondInfo {
-    export class Entry implements Bonds.ComponentBondInfoEntry {
+    export class Entry implements GroupBonds.ComponentBondInfoEntry {
         map: Map<string, Map<string, { order: number, flags: number }>> = new Map();
 
         add(a: string, b: string, order: number, flags: number, swap = true) {

+ 0 - 1
src/mol-model/structure/model/model.ts

@@ -14,7 +14,6 @@ import CoarseGrained from './properties/coarse-grained'
 import from_gro from './formats/gro'
 import from_mmCIF from './formats/mmcif'
 
-
 /**
  * Interface to the "source data" of the molecule.
  *

Diff do ficheiro suprimidas por serem muito extensas
+ 0 - 18
src/mol-model/structure/model/utils/compute-bonds.ts


+ 20 - 14
src/mol-model/structure/query/generators.ts

@@ -10,7 +10,7 @@ import P from './properties'
 import { Structure, ElementSet, Element } from '../structure'
 import { OrderedSet, Segmentation } from 'mol-data/int'
 
-export const all: Query = s => Selection.Singletons(s, s.elements);
+export const all: Query.Provider = async (s, ctx) => Selection.Singletons(s, s.elements);
 
 export interface AtomQueryParams {
     entityTest: Element.Predicate,
@@ -27,7 +27,7 @@ export interface AtomGroupsQueryParams extends AtomQueryParams {
 export function residues(params?: Partial<AtomQueryParams>) { return atoms({ ...params, groupBy: P.residue.key }); }
 export function chains(params?: Partial<AtomQueryParams>) { return atoms({ ...params, groupBy: P.chain.key }); }
 
-export function atoms(params?: Partial<AtomGroupsQueryParams>): Query {
+export function atoms(params?: Partial<AtomGroupsQueryParams>): Query.Provider {
     if (!params || (!params.atomTest && !params.residueTest && !params.chainTest && !params.entityTest && !params.groupBy)) return all;
     if (!!params.atomTest && !params.residueTest && !params.chainTest && !params.entityTest && !params.groupBy) return atomGroupsLinear(params.atomTest);
 
@@ -43,17 +43,17 @@ export function atoms(params?: Partial<AtomGroupsQueryParams>): Query {
     return atomGroupsGrouped(normalized);
 }
 
-function atomGroupsLinear(atomTest: Element.Predicate): Query {
-    return structure => {
+function atomGroupsLinear(atomTest: Element.Predicate): Query.Provider {
+    return async (structure, ctx) => {
         const { elements, units } = structure;
-        const unitIds = ElementSet.unitIds(elements);
+        const unitIds = ElementSet.unitIndices(elements);
         const l = Element.Location();
         const builder = ElementSet.LinearBuilder(elements);
 
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             const unitId = unitIds[i];
             l.unit = units[unitId];
-            const set = ElementSet.unitGetByIndex(elements, i).elements;
+            const set = ElementSet.groupAt(elements, i).elements;
 
             builder.beginUnit();
             for (let j = 0, _j = OrderedSet.size(set); j < _j; j++) {
@@ -61,16 +61,18 @@ function atomGroupsLinear(atomTest: Element.Predicate): Query {
                 if (atomTest(l)) builder.addToUnit(l.element);
             }
             builder.commitUnit(unitId);
+
+            if (ctx.shouldUpdate) await ctx.update({ message: 'Atom Groups', current: 0, max: unitIds.length });
         }
 
         return Selection.Singletons(structure, builder.getSet());
     };
 }
 
-function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: AtomGroupsQueryParams): Query {
-    return structure => {
+function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: AtomGroupsQueryParams): Query.Provider {
+    return async (structure, ctx) => {
         const { elements, units } = structure;
-        const unitIds = ElementSet.unitIds(elements);
+        const unitIds = ElementSet.unitIndices(elements);
         const l = Element.Location();
         const builder = ElementSet.LinearBuilder(elements);
 
@@ -78,7 +80,7 @@ function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: A
             const unitId = unitIds[i];
             const unit = units[unitId];
             l.unit = unit;
-            const set = ElementSet.unitGetByIndex(elements, i).elements;
+            const set = ElementSet.groupAt(elements, i).elements;
 
             builder.beginUnit();
             const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set);
@@ -104,6 +106,8 @@ function atomGroupsSegmented({ entityTest, chainTest, residueTest, atomTest }: A
                 }
             }
             builder.commitUnit(unitId);
+
+            if (ctx.shouldUpdate) await ctx.update({ message: 'Atom Groups', current: 0, max: unitIds.length });
         }
 
         return Selection.Singletons(structure, builder.getSet());
@@ -157,10 +161,10 @@ class LinearGroupingBuilder {
     constructor(private structure: Structure) { }
 }
 
-function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, groupBy }: AtomGroupsQueryParams): Query {
-    return structure => {
+function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, groupBy }: AtomGroupsQueryParams): Query.Provider {
+    return async (structure, ctx) => {
         const { elements, units } = structure;
-        const unitIds = ElementSet.unitIds(elements);
+        const unitIds = ElementSet.unitIndices(elements);
         const l = Element.Location();
         const builder = new LinearGroupingBuilder(structure);
 
@@ -168,7 +172,7 @@ function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, group
             const unitId = unitIds[i];
             const unit = units[unitId];
             l.unit = unit;
-            const set = ElementSet.unitGetByIndex(elements, i).elements;
+            const set = ElementSet.groupAt(elements, i).elements;
 
             const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set);
             const residuesIt = Segmentation.transientSegments(unit.hierarchy.residueSegments, set);
@@ -192,6 +196,8 @@ function atomGroupsGrouped({ entityTest, chainTest, residueTest, atomTest, group
                     }
                 }
             }
+
+            if (ctx.shouldUpdate) await ctx.update({ message: 'Atom Groups', current: 0, max: unitIds.length });
         }
 
         return builder.getSelection();

+ 12 - 1
src/mol-model/structure/query/query.ts

@@ -4,10 +4,21 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
+import { Task, RuntimeContext } from 'mol-task'
 import { Structure } from '../structure'
 import Selection from './selection'
 
 // TODO: Query { (s: Structure): Computation<Selection> }
 
-interface Query { (s: Structure): Selection }
+interface Query { (s: Structure): Task<Selection>, provider: Query.Provider }
+function Query(q: Query.Provider): Query {
+    const ret = (s => Task.create('Query', ctx => q(s, ctx))) as Query;
+    ret.provider = q;
+    return ret;
+}
+
+namespace Query {
+    export interface Provider { (s: Structure, ctx: RuntimeContext): Promise<Selection> }
+}
+
 export default Query

+ 1 - 1
src/mol-model/structure/query/selection.ts

@@ -35,7 +35,7 @@ namespace Selection {
 
     export function getAt(sel: Selection, i: number): Structure {
         if (isSingleton(sel)) {
-            const atom = ElementSet.elementGetAt(sel.set, i);
+            const atom = ElementSet.elementAt(sel.set, i);
             return Structure.create(sel.structure.units, ElementSet.singleton(atom, sel.structure.elements));
         }
         return Structure.create(sel.structure.units, sel.sets[i]);

+ 4 - 13
src/mol-model/structure/structure/element/group.ts

@@ -5,15 +5,17 @@
  */
 
 import { OrderedSet } from 'mol-data/int'
-import { Lookup3D, GridLookup3D } from 'mol-math/geometry';
+import { Lookup3D } from 'mol-math/geometry'
 import Unit from '../unit'
+import { GroupBonds } from './properties/bonds/group-data';
 
 interface ElementGroup {
     elements: OrderedSet,
     // Unique identifier of the group, usable as partial key for various "caches".
     key: number,
 
-    __lookup3d__?: Lookup3D
+    __lookup3d__?: Lookup3D,
+    __bonds__?: GroupBonds
 }
 
 namespace ElementGroup {
@@ -64,17 +66,6 @@ namespace ElementGroup {
         return createNew(set);
     }
 
-    export function getLookup3d(unit: Unit, group: ElementGroup) {
-        if (group.__lookup3d__)  return group.__lookup3d__;
-        if (Unit.isAtomic(unit)) {
-            const { x, y, z } = unit.model.conformation;
-            group.__lookup3d__ = GridLookup3D({ x, y, z, indices: group.elements });
-            return group.__lookup3d__;
-        }
-
-        throw 'not implemented';
-    }
-
     let _id = 0;
     function nextKey() {
         const ret = _id;

+ 17 - 1
src/mol-model/structure/structure/element/impl/set.ts

@@ -9,10 +9,19 @@ import { sortArray } from 'mol-data/util/sort'
 import { hash1 } from 'mol-data/util/hash-functions'
 import Element from '../../element'
 import ElementGroup from '../group'
+import { ElementSetLookup3D } from '../../util/lookup3d'
+import Structure from '../../structure';
 
 /** Long and painful implementation starts here */
 
-export type ElementSetImpl = { groups: IntMap<ElementGroup>, offsets: Int32Array, hashCode: number, keys: SortedArray }
+export type ElementSetImpl = {
+    groups: IntMap<ElementGroup>,
+    offsets: Int32Array,
+    hashCode: number,
+    keys: SortedArray,
+
+    __lookup3d__?: ElementSetLookup3D
+}
 
 export const Empty: ElementSetImpl = { groups: IntMap.Empty, offsets: new Int32Array(1), hashCode: 0, keys: SortedArray.Empty };
 
@@ -270,6 +279,13 @@ export function Generator() {
     return new AtomSetGenerator();
 }
 
+export function getLookup3d(s: Structure) {
+    const set = s.elements as any as ElementSetImpl;
+    if (set.__lookup3d__) return set.__lookup3d__;
+    set.__lookup3d__ = ElementSetLookup3D.create(s);
+    return set.__lookup3d__;
+}
+
 /** When adding groups, compare them to existing ones. If they all match, return the whole original set. */
 class ChildGenerator {
     private keys: number[] = [];

Diff do ficheiro suprimidas por serem muito extensas
+ 18 - 0
src/mol-model/structure/structure/element/properties/bonds/group-compute.ts


+ 5 - 7
src/mol-model/structure/model/properties/bonds.ts → src/mol-model/structure/structure/element/properties/bonds/group-data.ts

@@ -5,9 +5,9 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { BondType } from '../types'
+import { BondType } from '../../../../model/types'
 
-interface Bonds {
+interface GroupBonds {
     /**
      * Where bonds for atom A start and end.
      * Start offset at idx, end at idx + 1
@@ -21,8 +21,8 @@ interface Bonds {
     count: number
 }
 
-namespace Bonds {
-    export function createEmpty(): Bonds {
+namespace GroupBonds {
+    export function createEmpty(): GroupBonds {
         return { offset: [], neighbor: [], order: [], flags: [], count: 0 }
     }
     export function isCovalent(flags: number) {
@@ -46,6 +46,4 @@ namespace Bonds {
     }
 }
 
-
-
-export default Bonds
+export { GroupBonds }

+ 17 - 10
src/mol-model/structure/structure/element/set.ts

@@ -9,26 +9,32 @@ import Element from '../element'
 import ElementGroup from './group'
 import * as Impl from './impl/set'
 import * as Builders from './impl/set-builder'
+import { ElementSetLookup3D } from '../util/lookup3d';
+import Structure from '../structure';
 
-/** A map-like representation of grouped atom set */
+/**
+ * A map-like representation of grouped atom set
+ *
+ * Essentially corresponds to the type { [unitId: number]: ElementGroup }.
+ */
 namespace ElementSet {
     export const Empty: ElementSet = Impl.Empty as any;
 
     export const ofAtoms: (elements: ArrayLike<Element>, template: ElementSet) => ElementSet = Impl.ofElements as any;
     export const singleton: (element: Element, template: ElementSet) => ElementSet = Impl.singleton as any;
 
-    export const unitCount: (set: ElementSet) => number = Impl.keyCount as any;
-    export const unitIds: (set: ElementSet) => SortedArray = Impl.getKeys as any;
-    export const unitHas: (set: ElementSet, id: number) => boolean = Impl.hasKey as any;
-    export const unitGetId: (set: ElementSet, i: number) => number = Impl.getKey as any;
+    export const unitIndices: (set: ElementSet) => SortedArray = Impl.getKeys as any;
+    export const unitHas: (set: ElementSet, index: number) => boolean = Impl.hasKey as any;
 
-    export const unitGetById: (set: ElementSet, key: number) => ElementGroup = Impl.getByKey as any;
-    export const unitGetByIndex: (set: ElementSet, i: number) => ElementGroup = Impl.getByIndex as any;
+    export const groupCount: (set: ElementSet) => number = Impl.keyCount as any;
+    export const groupUnitIndex: (set: ElementSet, index: number) => number = Impl.getKey as any;
+    export const groupFromUnitIndex: (set: ElementSet, unitId: number) => ElementGroup = Impl.getByKey as any;
+    export const groupAt: (set: ElementSet, index: number) => ElementGroup = Impl.getByIndex as any;
 
     export const elementCount: (set: ElementSet) => number = Impl.size as any;
     export const elementHas: (set: ElementSet, x: Element) => boolean = Impl.hasAtom as any;
     export const elementIndexOf: (set: ElementSet, x: Element) => number = Impl.indexOf as any;
-    export const elementGetAt: (set: ElementSet, i: number) => Element = Impl.getAt as any;
+    export const elementAt: (set: ElementSet, i: number) => Element = Impl.getAt as any;
     export const elements: (set: ElementSet) => Iterator<Element> = Impl.values as any;
 
     export const hashCode: (set: ElementSet) => number = Impl.hashCode as any;
@@ -49,12 +55,13 @@ namespace ElementSet {
     export interface TemplateGenerator { add(unit: number, set: OrderedSet): void, getSet(): ElementSet }
     export const TemplateGenerator: (template: ElementSet) => TemplateGenerator = Impl.TemplateGenerator as any
 
-    // TODO: bounding sphere
+    export const getLookup3d: (s: Structure) => ElementSetLookup3D = Impl.getLookup3d;
+
     // TODO: distance, areWithIn?
     // TODO: check connected
     // TODO: add "parent" property? how to avoid using too much memory? Transitive parents? Parent unlinking?
 }
 
-interface ElementSet { '@type': 'element-set' | Element['@type'] }
+interface ElementSet { '@type': 'element-set' }
 
 export default ElementSet

+ 3 - 8
src/mol-model/structure/structure/structure.ts

@@ -12,15 +12,12 @@ import Unit from './unit'
 import ElementSet from './element/set'
 import ElementGroup from './element/group'
 import Element from './element'
-import { StructureLookup3D } from './util/lookup3d';
 
 // A structure is a pair of "units" and an element set.
 // Each unit contains the data and transformation of its corresponding elements.
 interface Structure {
     readonly units: ReadonlyArray<Unit>,
-    readonly elements: ElementSet,
-
-    __lookup3d__?: StructureLookup3D
+    readonly elements: ElementSet
 }
 
 namespace Structure {
@@ -77,7 +74,7 @@ namespace Structure {
     export function getModels(s: Structure) {
         const { units, elements } = s;
         const arr = UniqueArray.create<Model['id'], Model>();
-        const ids = ElementSet.unitIds(elements);
+        const ids = ElementSet.unitIndices(elements);
         for (let i = 0; i < ids.length; i++) {
             const u = units[ids[i]];
             UniqueArray.add(arr, u.model.id, u.model);
@@ -86,9 +83,7 @@ namespace Structure {
     }
 
     export function getLookup3d(s: Structure) {
-        if (s.__lookup3d__) return s.__lookup3d__;
-        s.__lookup3d__ = StructureLookup3D.create(s);
-        return s.__lookup3d__;
+        return ElementSet.getLookup3d(s);
     }
 
     export function getBoundary(s: Structure) {

+ 20 - 17
src/mol-model/structure/structure/symmetry.ts

@@ -9,36 +9,39 @@ import ElementSet from './element/set'
 import Unit from './unit'
 import { Selection } from '../query'
 import { ModelSymmetry } from '../model'
+import { Task } from 'mol-task';
 
 namespace Symmetry {
-    export const  buildAssembly = buildAssemblyImpl;
+    export const buildAssembly = buildAssemblyImpl;
 }
 
 export default Symmetry;
 
 function buildAssemblyImpl(structure: Structure, name: string) {
-    const models = Structure.getModels(structure);
-    if (models.length !== 1) throw new Error('Can only build assemblies from structures based on 1 model.');
+    return Task.create('Build Symmetry', async ctx => {
+        const models = Structure.getModels(structure);
+        if (models.length !== 1) throw new Error('Can only build assemblies from structures based on 1 model.');
 
-    const assembly = ModelSymmetry.findAssembly(models[0], name);
-    if (!assembly) throw new Error(`Assembly '${name}' is not defined.`);
+        const assembly = ModelSymmetry.findAssembly(models[0], name);
+        if (!assembly) throw new Error(`Assembly '${name}' is not defined.`);
 
-    const assembler = Structure.Builder();
+        const assembler = Structure.Builder();
 
-    for (const g of assembly.operatorGroups) {
-        const selection = g.selector(structure);
-        if (Selection.structureCount(selection) === 0) continue;
-        const { units, elements } = Selection.unionStructure(selection);
+        for (const g of assembly.operatorGroups) {
+            const selection = await ctx.runChild(g.selector(structure));
+            if (Selection.structureCount(selection) === 0) continue;
+            const { units, elements } = Selection.unionStructure(selection);
 
-        const unitIds = ElementSet.unitIds(elements);
+            const unitIds = ElementSet.unitIndices(elements);
 
-        for (const oper of g.operators) {
-            for (let uI = 0, _uI = unitIds.length; uI < _uI; uI++) {
-                const unit = units[unitIds[uI]];
-                assembler.add(Unit.withOperator(unit, oper), ElementSet.unitGetByIndex(elements, uI));
+            for (const oper of g.operators) {
+                for (let uI = 0, _uI = unitIds.length; uI < _uI; uI++) {
+                    const unit = units[unitIds[uI]];
+                    assembler.add(Unit.withOperator(unit, oper), ElementSet.groupAt(elements, uI));
+                }
             }
         }
-    }
 
-    return assembler.getStructure();
+        return assembler.getStructure();
+    });
 }

+ 23 - 0
src/mol-model/structure/structure/unit.ts

@@ -7,6 +7,8 @@
 import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
 import ElementGroup from './element/group'
 import { Model } from '../model'
+import { GridLookup3D } from 'mol-math/geometry'
+import { computeUnitBonds } from './element/properties/bonds/group-compute';
 
 // A building block of a structure that corresponds to an atomic or a coarse grained representation
 // 'conveniently grouped together'.
@@ -83,6 +85,27 @@ namespace Unit {
             case Kind.Coarse: return createCoarse(unit.model, SymmetryOperator.compose(unit.operator, operator), unit.fullGroup);
         }
     }
+
+    export function getLookup3d(unit: Unit, group: ElementGroup) {
+        if (group.__lookup3d__)  return group.__lookup3d__;
+        if (Unit.isAtomic(unit)) {
+            const { x, y, z } = unit.model.conformation;
+            group.__lookup3d__ = GridLookup3D({ x, y, z, indices: group.elements });
+            return group.__lookup3d__;
+        }
+
+        throw 'not implemented';
+    }
+
+    export function getGroupBonds(unit: Unit, group: ElementGroup) {
+        if (group.__bonds__) return group.__bonds__;
+        if (Unit.isAtomic(unit)) {
+            group.__bonds__ = computeUnitBonds(unit, group);
+            return group.__bonds__;
+        }
+
+        throw 'not implemented';
+    }
 }
 
 export default Unit;

+ 6 - 6
src/mol-model/structure/structure/util/boundary.ts

@@ -20,9 +20,9 @@ function computeStructureBoundary(s: Structure): { box: Box3D, sphere: Sphere3D
     let radiusSq = 0;
     let size = 0;
 
-    for (let i = 0, _i = ElementSet.unitCount(elements); i < _i; i++) {
-        const group = ElementSet.unitGetByIndex(elements, i);
-        const { x, y, z } = units[ElementSet.unitGetId(elements, i)];
+    for (let i = 0, _i = ElementSet.groupCount(elements); i < _i; i++) {
+        const group = ElementSet.groupAt(elements, i);
+        const { x, y, z } = units[ElementSet.groupUnitIndex(elements, i)];
 
         size += ElementGroup.size(group);
         for (let j = 0, _j = ElementGroup.size(group); j < _j; j++) {
@@ -48,9 +48,9 @@ function computeStructureBoundary(s: Structure): { box: Box3D, sphere: Sphere3D
         cz /= size;
     }
 
-    for (let i = 0, _i = ElementSet.unitCount(elements); i < _i; i++) {
-        const group = ElementSet.unitGetByIndex(elements, i);
-        const { x, y, z } = units[ElementSet.unitGetId(elements, i)];
+    for (let i = 0, _i = ElementSet.groupCount(elements); i < _i; i++) {
+        const group = ElementSet.groupAt(elements, i);
+        const { x, y, z } = units[ElementSet.groupUnitIndex(elements, i)];
 
         size += ElementGroup.size(group);
         for (let j = 0, _j = ElementGroup.size(group); j < _j; j++) {

+ 16 - 16
src/mol-model/structure/structure/util/lookup3d.ts

@@ -7,15 +7,15 @@
 import Structure from '../structure'
 import Element from '../element'
 import { Lookup3D, GridLookup3D, Result, Box3D, Sphere3D } from 'mol-math/geometry';
-import { ElementGroup, ElementSet } from '../../structure';
+import { ElementSet, Unit } from '../../structure';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { OrderedSet } from 'mol-data/int';
 import { computeStructureBoundary } from './boundary';
 
-interface StructureLookup3D extends Lookup3D<Element> {}
+interface ElementSetLookup3D extends Lookup3D<Element> {}
 
-namespace StructureLookup3D {
-    class Impl implements StructureLookup3D {
+namespace ElementSetLookup3D {
+    class Impl implements ElementSetLookup3D {
         private unitLookup: Lookup3D;
         private result = Result.create<Element>();
         private pivot = Vec3.zero();
@@ -28,14 +28,14 @@ namespace StructureLookup3D {
 
             for (let t = 0, _t = closeUnits.count; t < _t; t++) {
                 const i = closeUnits.indices[t];
-                const unitId = ElementSet.unitGetId(elements, i);
-                const group = ElementSet.unitGetByIndex(elements, i);
+                const unitId = ElementSet.groupUnitIndex(elements, i);
+                const group = ElementSet.groupAt(elements, i);
                 const unit = units[unitId];
                 Vec3.set(this.pivot, x, y, z);
                 if (!unit.operator.isIdentity) {
                     Vec3.transformMat4(this.pivot, this.pivot, unit.operator.inverse);
                 }
-                const groupLookup = ElementGroup.getLookup3d(unit, group);
+                const groupLookup = Unit.getLookup3d(unit, group);
                 const groupResult = groupLookup.find(this.pivot[0], this.pivot[1], this.pivot[2], radius);
                 for (let j = 0, _j = groupResult.count; j < _j; j++) {
                     Result.add(this.result, Element.create(unitId, groupResult.indices[j]), groupResult.squaredDistances[j]);
@@ -52,14 +52,14 @@ namespace StructureLookup3D {
 
             for (let t = 0, _t = closeUnits.count; t < _t; t++) {
                 const i = closeUnits.indices[t];
-                const unitId = ElementSet.unitGetId(elements, i);
-                const group = ElementSet.unitGetByIndex(elements, i);
+                const unitId = ElementSet.groupUnitIndex(elements, i);
+                const group = ElementSet.groupAt(elements, i);
                 const unit = units[unitId];
                 Vec3.set(this.pivot, x, y, z);
                 if (!unit.operator.isIdentity) {
                     Vec3.transformMat4(this.pivot, this.pivot, unit.operator.inverse);
                 }
-                const groupLookup = ElementGroup.getLookup3d(unit, group);
+                const groupLookup = Unit.getLookup3d(unit, group);
                 if (groupLookup.check(this.pivot[0], this.pivot[1], this.pivot[2], radius)) return true;
             }
 
@@ -70,7 +70,7 @@ namespace StructureLookup3D {
 
         constructor(private structure: Structure) {
             const { units, elements } = structure;
-            const unitCount = ElementSet.unitCount(elements);
+            const unitCount = ElementSet.groupCount(elements);
             const xs = new Float32Array(unitCount);
             const ys = new Float32Array(unitCount);
             const zs = new Float32Array(unitCount);
@@ -78,9 +78,9 @@ namespace StructureLookup3D {
 
             const center = Vec3.zero();
             for (let i = 0; i < unitCount; i++) {
-                const group = ElementSet.unitGetByIndex(elements, i);
-                const unit = units[ElementSet.unitGetId(elements, i)];
-                const lookup = ElementGroup.getLookup3d(unit, group);
+                const group = ElementSet.groupAt(elements, i);
+                const unit = units[ElementSet.groupUnitIndex(elements, i)];
+                const lookup = Unit.getLookup3d(unit, group);
                 const s = lookup.boundary.sphere;
 
                 Vec3.transformMat4(center, s.center, unit.operator.matrix);
@@ -96,9 +96,9 @@ namespace StructureLookup3D {
         }
     }
 
-    export function create(s: Structure): StructureLookup3D {
+    export function create(s: Structure): ElementSetLookup3D {
         return new Impl(s);
     }
 }
 
-export { StructureLookup3D }
+export { ElementSetLookup3D }

+ 27 - 23
src/perf-tests/structure.ts

@@ -11,7 +11,7 @@ import * as fs from 'fs'
 import fetch from 'node-fetch'
 import CIF from 'mol-io/reader/cif'
 
-import { Structure, Model, Queries as Q, Element, ElementGroup, ElementSet, Selection, Symmetry, Unit } from 'mol-model/structure'
+import { Structure, Model, Queries as Q, Element, ElementGroup, ElementSet, Selection, Symmetry, Unit, Query } from 'mol-model/structure'
 import { Segmentation, OrderedSet } from 'mol-data/int'
 
 import to_mmCIF from 'mol-model/structure/export/mmcif'
@@ -120,14 +120,14 @@ export namespace PropertyAccess {
 
     function sumProperty(structure: Structure, p: Element.Property<number>) {
         const { elements, units } = structure;
-        const unitIds = ElementSet.unitIds(elements);
+        const unitIds = ElementSet.unitIndices(elements);
         const l = Element.Location();
 
         let s = 0;
 
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             l.unit = units[unitIds[i]];
-            const set = ElementSet.unitGetByIndex(elements, i);
+            const set = ElementSet.groupAt(elements, i);
 
 
             for (let j = 0, _j = ElementGroup.size(set); j < _j; j++) {
@@ -141,7 +141,7 @@ export namespace PropertyAccess {
 
     function sumPropertySegmented(structure: Structure, p: Element.Property<number>) {
         const { elements, units } = structure;
-        const unitIds = ElementSet.unitIds(elements);
+        const unitIds = ElementSet.unitIndices(elements);
         const l = Element.Location();
 
         let s = 0;
@@ -150,7 +150,7 @@ export namespace PropertyAccess {
         for (let i = 0, _i = unitIds.length; i < _i; i++) {
             const unit = units[unitIds[i]];
             l.unit = unit;
-            const set = ElementSet.unitGetByIndex(elements, i);
+            const set = ElementSet.groupAt(elements, i);
 
             const chainsIt = Segmentation.transientSegments(unit.hierarchy.chainSegments, set.elements);
             const residues = unit.hierarchy.residueSegments;
@@ -294,16 +294,16 @@ export namespace PropertyAccess {
         console.log(to_mmCIF('test', s));
     }
 
-    export function testAssembly(id: string, s: Structure) {
+    export async function testAssembly(id: string, s: Structure) {
         console.time('assembly')
-        const a = Symmetry.buildAssembly(s, '1');
+        const a = await Run(Symmetry.buildAssembly(s, '1'));
         console.timeEnd('assembly')
         fs.writeFileSync(`${DATA_DIR}/${id}_assembly.bcif`, to_mmCIF(id, a, true));
         console.log('exported');
     }
 
-    export function testGrouping(structure: Structure) {
-        const { elements, units } = Symmetry.buildAssembly(structure, '1');
+    export async function testGrouping(structure: Structure) {
+        const { elements, units } = await Run(Symmetry.buildAssembly(structure, '1'));
         console.log('grouping', units.length);
         console.log('built asm');
 
@@ -312,15 +312,19 @@ export namespace PropertyAccess {
             (a, b) => a.unit.model.id === b.unit.model.id && (a.group.key === b.group.key && OrderedSet.areEqual(a.group.elements, b.group.elements))
         );
 
-        for (let i = 0, _i = ElementSet.unitCount(elements); i < _i; i++) {
-            const group = ElementSet.unitGetByIndex(elements, i);
-            const unitId = ElementSet.unitGetId(elements, i);
+        for (let i = 0, _i = ElementSet.groupCount(elements); i < _i; i++) {
+            const group = ElementSet.groupAt(elements, i);
+            const unitId = ElementSet.groupUnitIndex(elements, i);
             uniqueGroups.add(unitId, { unit: units[unitId], group });
         }
 
         console.log('group count', uniqueGroups.groups.length);
     }
 
+    function query(q: Query, s: Structure) {
+        return Run((q(s)));
+    }
+
     export async function run() {
         //const { structures, models/*, mmcif*/ } = await getBcif('1cbs');
         // const { structures, models } = await getBcif('3j3q');
@@ -375,26 +379,26 @@ export namespace PropertyAccess {
         //const auth_asym_id = Q.props.chain.auth_asym_id;
         //const set =  new Set(['A', 'B', 'C', 'D']);
         //const q = Q.generators.atomGroups({ atomTest: l => auth_seq_id(l) < 3 });
-        const q = Q.generators.atoms({ atomTest: Q.pred.eq(Q.props.residue.auth_comp_id, 'ALA') });
+        const q = Query(Q.generators.atoms({ atomTest: Q.pred.eq(Q.props.residue.auth_comp_id, 'ALA') }));
         const P = Q.props
         //const q0 = Q.generators.atoms({ atomTest: l => auth_comp_id(l) === 'ALA' });
-        const q1 = Q.generators.atoms({ residueTest: l => auth_comp_id(l) === 'ALA' });
-        const q2 = Q.generators.atoms({ residueTest: l => auth_comp_id(l) === 'ALA', groupBy: Q.props.residue.key });
-        const q3 = Q.generators.atoms({
+        const q1 = Query(Q.generators.atoms({ residueTest: l => auth_comp_id(l) === 'ALA' }));
+        const q2 = Query(Q.generators.atoms({ residueTest: l => auth_comp_id(l) === 'ALA', groupBy: Q.props.residue.key }));
+        const q3 = Query(Q.generators.atoms({
             chainTest: Q.pred.inSet(P.chain.auth_asym_id, ['A', 'B', 'C', 'D']),
             residueTest: Q.pred.eq(P.residue.auth_comp_id, 'ALA')
-        });
-        q(structures[0]);
+        }));
+        await query(q, structures[0]);
         //console.log(to_mmCIF('test', Selection.union(q0r)));
 
         console.time('q1')
-        q1(structures[0]);
+        await query(q1, structures[0]);
         console.timeEnd('q1')
         console.time('q1')
-        q1(structures[0]);
+        await query(q1, structures[0]);
         console.timeEnd('q1')
         console.time('q2')
-        const q2r = q2(structures[0]);
+        const q2r = await query(q2, structures[0]);
         console.timeEnd('q2')
         console.log(Selection.structureCount(q2r));
         //console.log(q1(structures[0]));
@@ -404,8 +408,8 @@ export namespace PropertyAccess {
         suite
             //.add('test q', () => q1(structures[0]))
             //.add('test q', () => q(structures[0]))
-            .add('test q1', () => q1(structures[0]))
-            .add('test q3', () => q3(structures[0]))
+            .add('test q1', async () => await q1(structures[0]))
+            .add('test q3', async () => await q3(structures[0]))
             //.add('test int', () => sumProperty(structures[0], l => col(l.element))
             // .add('sum residue', () => sumPropertyResidue(structures[0], l => l.unit.hierarchy.residues.auth_seq_id.value(l.unit.residueIndex[l.atom])))
 

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff