Browse Source

seperate grid and boundary calculation

Alexander Rose 5 năm trước cách đây
mục cha
commit
f65f4f4aeb

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

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  */
@@ -7,6 +7,7 @@
 import { GridLookup3D } from '../../geometry';
 import { sortArray } from '../../../mol-data/util';
 import { OrderedSet } from '../../../mol-data/int';
+import { getBoundary } from '../boundary';
 
 const xs = [0, 0, 1];
 const ys = [0, 1, 0];
@@ -15,7 +16,9 @@ const rs = [0, 0.5, 1/3];
 
 describe('GridLookup3d', () => {
     it('basic', () => {
-        const grid = GridLookup3D({ x: xs, y: ys, z: zs, indices: OrderedSet.ofBounds(0, 3) });
+        const position = { x: xs, y: ys, z: zs, indices: OrderedSet.ofBounds(0, 3) }
+        const boundary = getBoundary(position)
+        const grid = GridLookup3D(position, boundary);
 
         let r = grid.find(0, 0, 0, 0);
         expect(r.count).toBe(1);
@@ -27,7 +30,9 @@ describe('GridLookup3d', () => {
     });
 
     it('radius', () => {
-        const grid = GridLookup3D({ x: xs, y: ys, z: zs, radius: [0, 0.5, 1 / 3], indices: OrderedSet.ofBounds(0, 3) });
+        const position = { x: xs, y: ys, z: zs, radius: [0, 0.5, 1 / 3], indices: OrderedSet.ofBounds(0, 3) }
+        const boundary = getBoundary(position)
+        const grid = GridLookup3D(position, boundary);
 
         let r = grid.find(0, 0, 0, 0);
         expect(r.count).toBe(1);
@@ -39,7 +44,9 @@ describe('GridLookup3d', () => {
     });
 
     it('indexed', () => {
-        const grid = GridLookup3D({ x: xs, y: ys, z: zs, indices: OrderedSet.ofSingleton(1), radius: rs });
+        const position = { x: xs, y: ys, z: zs, indices: OrderedSet.ofSingleton(1), radius: rs }
+        const boundary = getBoundary(position)
+        const grid = GridLookup3D(position, boundary);
 
         let r = grid.find(0, 0, 0, 0);
         expect(r.count).toBe(0);

+ 40 - 0
src/mol-math/geometry/boundary.ts

@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { PositionData } from './common';
+import { Vec3 } from '../linear-algebra';
+import { OrderedSet } from '../../mol-data/int';
+import { BoundaryHelper } from './boundary-helper';
+import { Box3D, Sphere3D } from '../geometry';
+
+const boundaryHelperCoarse = new BoundaryHelper('14');
+const boundaryHelperFine = new BoundaryHelper('98');
+function getBoundaryHelper(count: number) {
+    return count > 500_000 ? boundaryHelperCoarse : boundaryHelperFine
+}
+
+export type Boundary = { readonly box: Box3D, readonly sphere: Sphere3D }
+
+export function getBoundary(data: PositionData): Boundary {
+    const { x, y, z, radius, indices } = data;
+    const p = Vec3();
+    const boundaryHelper = getBoundaryHelper(OrderedSet.size(indices));
+    boundaryHelper.reset();
+    for (let t = 0, _t = OrderedSet.size(indices); t < _t; t++) {
+        const i = OrderedSet.getAt(indices, t);
+        Vec3.set(p, x[i], y[i], z[i]);
+        boundaryHelper.includeSphereStep(p, (radius && radius[i]) || 0);
+    }
+    boundaryHelper.finishedIncludeStep();
+    for (let t = 0, _t = OrderedSet.size(indices); t < _t; t++) {
+        const i = OrderedSet.getAt(indices, t);
+        Vec3.set(p, x[i], y[i], z[i]);
+        boundaryHelper.radiusSphereStep(p, (radius && radius[i]) || 0);
+    }
+
+    return { box: boundaryHelper.getBox(), sphere: boundaryHelper.getSphere() };
+}

+ 10 - 37
src/mol-math/geometry/lookup3d/grid.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -11,14 +11,14 @@ import { Sphere3D } from '../primitives/sphere3d';
 import { PositionData } from '../common';
 import { Vec3 } from '../../linear-algebra';
 import { OrderedSet } from '../../../mol-data/int';
-import { BoundaryHelper } from '../boundary-helper';
+import { Boundary } from '../../../mol-model/structure/structure/util/boundary';
 
 interface GridLookup3D<T = number> extends Lookup3D<T> {
     readonly buckets: { readonly offset: ArrayLike<number>, readonly count: ArrayLike<number>, readonly array: ArrayLike<number> }
 }
 
-function GridLookup3D<T extends number = number>(data: PositionData, cellSizeOrCount?: Vec3 | number): GridLookup3D<T> {
-    return new GridLookup3DImpl<T>(data, cellSizeOrCount);
+function GridLookup3D<T extends number = number>(data: PositionData, boundary: Boundary, cellSizeOrCount?: Vec3 | number): GridLookup3D<T> {
+    return new GridLookup3DImpl<T>(data, boundary, cellSizeOrCount);
 }
 
 export { GridLookup3D }
@@ -48,8 +48,8 @@ class GridLookup3DImpl<T extends number = number> implements GridLookup3D<T> {
         return query(this.ctx);
     }
 
-    constructor(data: PositionData, cellSizeOrCount?: Vec3 | number) {
-        const structure = build(data, cellSizeOrCount);
+    constructor(data: PositionData, boundary: Boundary, cellSizeOrCount?: Vec3 | number) {
+        const structure = build(data, boundary, cellSizeOrCount);
         this.ctx = createContext<T>(structure);
         this.boundary = { box: structure.boundingBox, sphere: structure.boundingSphere };
         this.buckets = { offset: structure.bucketOffset, count: structure.bucketCounts, array: structure.bucketArray };
@@ -166,36 +166,9 @@ function _build(state: BuildState): Grid3D {
     }
 }
 
-const boundaryHelperCoarse = new BoundaryHelper('14');
-const boundaryHelperFine = new BoundaryHelper('98');
-function getBoundaryHelper(count: number) {
-    return count > 500_000 ? boundaryHelperCoarse : boundaryHelperFine
-}
-
-function getBoundary(data: PositionData) {
-    const { x, y, z, radius, indices } = data;
-    const p = Vec3();
-    const boundaryHelper = getBoundaryHelper(OrderedSet.size(indices));
-    boundaryHelper.reset();
-    for (let t = 0, _t = OrderedSet.size(indices); t < _t; t++) {
-        const i = OrderedSet.getAt(indices, t);
-        Vec3.set(p, x[i], y[i], z[i]);
-        boundaryHelper.includeSphereStep(p, (radius && radius[i]) || 0);
-    }
-    boundaryHelper.finishedIncludeStep();
-    for (let t = 0, _t = OrderedSet.size(indices); t < _t; t++) {
-        const i = OrderedSet.getAt(indices, t);
-        Vec3.set(p, x[i], y[i], z[i]);
-        boundaryHelper.radiusSphereStep(p, (radius && radius[i]) || 0);
-    }
-
-    return { boundingBox: boundaryHelper.getBox(), boundingSphere: boundaryHelper.getSphere() };
-}
-
-function build(data: PositionData, cellSizeOrCount?: Vec3 | number) {
-    const { boundingBox, boundingSphere } = getBoundary(data);
+function build(data: PositionData, boundary: Boundary, cellSizeOrCount?: Vec3 | number) {
     // need to expand the grid bounds to avoid rounding errors
-    const expandedBox = Box3D.expand(Box3D.empty(), boundingBox, Vec3.create(0.5, 0.5, 0.5));
+    const expandedBox = Box3D.expand(Box3D.empty(), boundary.box, Vec3.create(0.5, 0.5, 0.5));
     const { indices } = data;
 
     const S = Box3D.size(Vec3.zero(), expandedBox);
@@ -233,8 +206,8 @@ function build(data: PositionData, cellSizeOrCount?: Vec3 | number) {
         size,
         data: inputData,
         expandedBox,
-        boundingBox,
-        boundingSphere,
+        boundingBox: boundary.box,
+        boundingSphere: boundary.sphere,
         elementCount,
         delta
     }

+ 3 - 2
src/mol-math/geometry/molecular-surface.ts

@@ -15,6 +15,7 @@ import { PositionData } from './common';
 import { Mat4 } from '../../mol-math/linear-algebra/3d';
 import { Box3D, GridLookup3D, fillGridDim } from '../../mol-math/geometry';
 import { BaseGeometry } from '../../mol-geo/geometry/base';
+import { Boundary } from '../../mol-model/structure/structure/util/boundary';
 
 function normalToLine (out: Vec3, p: Vec3) {
     out[0] = out[1] = out[2] = 1.0
@@ -54,7 +55,7 @@ export const DefaultMolecularSurfaceCalculationProps = PD.getDefaultValues(Molec
 export type MolecularSurfaceCalculationProps = typeof DefaultMolecularSurfaceCalculationProps
 
 
-export async function calcMolecularSurface(ctx: RuntimeContext, position: Required<PositionData>, maxRadius: number, box: Box3D | null, props: MolecularSurfaceCalculationProps) {
+export async function calcMolecularSurface(ctx: RuntimeContext, position: Required<PositionData>, boundary: Boundary, maxRadius: number, box: Box3D | null, props: MolecularSurfaceCalculationProps) {
     // Field generation method adapted from AstexViewer (Mike Hartshorn) by Fred Ludlow.
     // Other parts based heavily on NGL (Alexander Rose) EDT Surface class
 
@@ -320,7 +321,7 @@ export async function calcMolecularSurface(ctx: RuntimeContext, position: Requir
 
     const cellSize = Vec3.create(maxRadius, maxRadius, maxRadius)
     Vec3.scale(cellSize, cellSize, 2)
-    const lookup3d = GridLookup3D(position, cellSize)
+    const lookup3d = GridLookup3D(position, boundary, cellSize)
     const neighbours = lookup3d.result
     if (box === null) box = lookup3d.boundary.box
 

+ 12 - 3
src/mol-model-props/computed/interactions/features.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -11,6 +11,7 @@ import { OrderedSet, SortedArray } from '../../../mol-data/int';
 import { FeatureGroup, FeatureType } from './common';
 import { ValenceModelProvider } from '../valence-model';
 import { Vec3 } from '../../../mol-math/linear-algebra';
+import { getBoundary } from '../../../mol-math/geometry/boundary';
 
 export { Features }
 
@@ -105,7 +106,11 @@ namespace Features {
         return {
             ...data,
             get lookup3d() {
-                return lookup3d || (lookup3d = GridLookup3D({ x: data.x, y: data.y, z: data.z, indices: OrderedSet.ofBounds(0 as FeatureIndex, data.count as FeatureIndex) }))
+                if (!lookup3d) {
+                    const position = { x: data.x, y: data.y, z: data.z, indices: OrderedSet.ofBounds(0 as FeatureIndex, data.count as FeatureIndex) }
+                    lookup3d = GridLookup3D(position, getBoundary(position))
+                }
+                return lookup3d
             },
             get elementsIndex() {
                 return elementsIndex || (elementsIndex = createElementsIndex(data, elementsCount))
@@ -128,7 +133,11 @@ namespace Features {
         return {
             indices,
             get lookup3d() {
-                return lookup3d || (lookup3d = GridLookup3D({ x: data.x, y: data.y, z: data.z, indices }))
+                if (!lookup3d) {
+                    const position = { x: data.x, y: data.y, z: data.z, indices }
+                    lookup3d = GridLookup3D(position, getBoundary(position))
+                }
+                return lookup3d
             }
         }
     }

+ 4 - 2
src/mol-model-props/computed/secondary-structure/dssp/trace-lookup.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -8,6 +8,7 @@ import { GridLookup3D } from '../../../../mol-math/geometry';
 import { SortedArray } from '../../../../mol-data/int';
 import { Unit } from '../../../../mol-model/structure/structure';
 import { ResidueIndex } from '../../../../mol-model/structure';
+import { getBoundary } from '../../../../mol-math/geometry/boundary';
 
 export function calcUnitProteinTraceLookup3D(unit: Unit.Atomic, unitProteinResidues: SortedArray<ResidueIndex>): GridLookup3D {
     const { x, y, z } = unit.model.atomicConformation;
@@ -16,5 +17,6 @@ export function calcUnitProteinTraceLookup3D(unit: Unit.Atomic, unitProteinResid
     for (let i = 0, il = unitProteinResidues.length; i < il; ++i) {
         indices[i] = traceElementIndex[unitProteinResidues[i]]
     }
-    return GridLookup3D({ x, y, z, indices: SortedArray.ofSortedArray(indices) });
+    const position = { x, y, z, indices: SortedArray.ofSortedArray(indices) }
+    return GridLookup3D(position, getBoundary(position));
 }

+ 5 - 2
src/mol-model/structure/structure/structure.ts

@@ -28,6 +28,7 @@ import { UUID } from '../../../mol-util';
 import { CustomProperties } from '../common/custom-property';
 import { AtomicHierarchy } from '../model/properties/atomic';
 import { StructureSelection } from '../query/selection';
+import { getBoundary } from '../../../mol-math/geometry/boundary';
 
 class Structure {
     /** Maps unit.id to unit */
@@ -696,7 +697,8 @@ namespace Structure {
 
     function partitionAtomicUnitByAtom(model: Model, indices: SortedArray, builder: StructureBuilder, multiChain: boolean) {
         const { x, y, z } = model.atomicConformation;
-        const lookup = GridLookup3D({ x, y, z, indices }, 8192);
+        const position = { x, y, z, indices }
+        const lookup = GridLookup3D(position, getBoundary(position), 8192);
         const { offset, count, array } = lookup.buckets;
 
         const traits = (multiChain ? Unit.Trait.MultiChain : Unit.Trait.None) | (offset.length > 1 ? Unit.Trait.Partitioned : Unit.Trait.None);
@@ -731,7 +733,8 @@ namespace Structure {
         const gridCellCount = 512 * firstResidueAtomCount
 
         const { x, y, z } = model.atomicConformation;
-        const lookup = GridLookup3D({ x, y, z, indices: SortedArray.ofSortedArray(startIndices) }, gridCellCount);
+        const position = { x, y, z, indices: SortedArray.ofSortedArray(startIndices) }
+        const lookup = GridLookup3D(position, getBoundary(position), gridCellCount);
         const { offset, count, array } = lookup.buckets;
 
         const traits = (multiChain ? Unit.Trait.MultiChain : Unit.Trait.None) | (offset.length > 1 ? Unit.Trait.Partitioned : Unit.Trait.None);

+ 22 - 3
src/mol-model/structure/structure/unit.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -20,6 +20,7 @@ import { getAtomicPolymerElements, getCoarsePolymerElements, getAtomicGapElement
 import { mmCIF_Schema } from '../../../mol-io/reader/cif/schema/mmcif';
 import { PrincipalAxes } from '../../../mol-math/linear-algebra/matrix/principal-axes';
 import { getPrincipalAxes } from './util/principal-axes';
+import { Boundary, getBoundary } from '../../../mol-math/geometry/boundary';
 
 /**
  * A building block of a structure that corresponds to an atomic or
@@ -128,6 +129,7 @@ namespace Unit {
         getChild(elements: StructureElement.Set): Unit,
         applyOperator(id: number, operator: SymmetryOperator, dontCompose?: boolean /* = false */): Unit,
 
+        readonly boundary: Boundary
         readonly lookup3d: Lookup3D<StructureElement.UnitIndex>
         readonly polymerElements: SortedArray<ElementIndex>
         readonly gapElements: SortedArray<ElementIndex>
@@ -138,6 +140,7 @@ namespace Unit {
     }
 
     interface BaseProperties {
+        boundary: ValueRef<Boundary | undefined>,
         lookup3d: ValueRef<Lookup3D<StructureElement.UnitIndex> | undefined>,
         principalAxes: ValueRef<PrincipalAxes | undefined>,
         polymerElements: ValueRef<SortedArray<ElementIndex> | undefined>
@@ -147,6 +150,7 @@ namespace Unit {
 
     function BaseProperties(): BaseProperties {
         return {
+            boundary: ValueRef.create(void 0),
             lookup3d: ValueRef.create(void 0),
             principalAxes: ValueRef.create(void 0),
             polymerElements: ValueRef.create(void 0),
@@ -203,10 +207,17 @@ namespace Unit {
             return new Atomic(id, this.invariantId, this.chainGroupId, this.traits, this.model, this.elements, SymmetryOperator.createMapping(op, this.model.atomicConformation, this.conformation.r), this.props);
         }
 
+        get boundary() {
+            if (this.props.boundary.ref) return this.props.boundary.ref;
+            const { x, y, z } = this.model.atomicConformation;
+            this.props.boundary.ref = getBoundary({ x, y, z, indices: this.elements });
+            return this.props.boundary.ref;
+        }
+
         get lookup3d() {
             if (this.props.lookup3d.ref) return this.props.lookup3d.ref;
             const { x, y, z } = this.model.atomicConformation;
-            this.props.lookup3d.ref = GridLookup3D({ x, y, z, indices: this.elements });
+            this.props.lookup3d.ref = GridLookup3D({ x, y, z, indices: this.elements }, this.boundary);
             return this.props.lookup3d.ref;
         }
 
@@ -333,11 +344,19 @@ namespace Unit {
             return ret;
         }
 
+        get boundary() {
+            if (this.props.boundary.ref) return this.props.boundary.ref;
+            // TODO: support sphere radius?
+            const { x, y, z } = this.getCoarseConformation();
+            this.props.boundary.ref = getBoundary({ x, y, z, indices: this.elements });
+            return this.props.boundary.ref;
+        }
+
         get lookup3d() {
             if (this.props.lookup3d.ref) return this.props.lookup3d.ref;
             // TODO: support sphere radius?
             const { x, y, z } = this.getCoarseConformation();
-            this.props.lookup3d.ref = GridLookup3D({ x, y, z, indices: this.elements });
+            this.props.lookup3d.ref = GridLookup3D({ x, y, z, indices: this.elements }, this.boundary);
             return this.props.lookup3d.ref;
         }
 

+ 3 - 1
src/mol-model/structure/structure/util/lookup3d.ts

@@ -13,6 +13,7 @@ import { OrderedSet } from '../../../../mol-data/int';
 import { StructureUniqueSubsetBuilder } from './unique-subset-builder';
 import StructureElement from '../element';
 import Unit from '../unit';
+import { getBoundary } from '../../../../mol-math/geometry/boundary';
 
 export interface StructureResult extends Result<StructureElement.UnitIndex> {
     units: Unit[]
@@ -174,6 +175,7 @@ export class StructureLookup3D {
             radius[i] = s.radius;
         }
 
-        this.unitLookup = GridLookup3D({ x: xs, y: ys, z: zs, radius, indices: OrderedSet.ofBounds(0, unitCount) });
+        const position = { x: xs, y: ys, z: zs, radius, indices: OrderedSet.ofBounds(0, unitCount) }
+        this.unitLookup = GridLookup3D(position, getBoundary(position));
     }
 }

+ 4 - 2
src/mol-repr/structure/visual/util/common.ts

@@ -14,6 +14,7 @@ import { AtomicNumbers, AtomNumber } from '../../../../mol-model/structure/model
 import { fillSerial } from '../../../../mol-util/array';
 import { ParamDefinition as PD } from '../../../../mol-util/param-definition';
 import { AssignableArrayLike } from '../../../../mol-util/type-helpers';
+import { getBoundary } from '../../../../mol-math/geometry/boundary';
 
 /** Return a Loci for the elements of a whole residue the elementIndex belongs to. */
 export function getResidueLoci(structure: Structure, unit: Unit.Atomic, elementIndex: ElementIndex): Loci {
@@ -139,7 +140,7 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, p
 
     const { x, y, z } = getConformation(rootUnit)
     const { elements } = rootUnit
-    const { center, radius: sphereRadius } = unit.lookup3d.boundary.sphere
+    const { center, radius: sphereRadius } = unit.boundary.sphere
     const extraRadius = (2 + 1.5) * 2 // TODO should be twice (the max vdW/sphere radius plus the probe radius)
     const radiusSq = (sphereRadius + extraRadius) * (sphereRadius + extraRadius)
 
@@ -169,6 +170,7 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, p
     }
 
     const position = { indices, x, y, z, id }
+    const boundary = unit === rootUnit ? unit.boundary : getBoundary(position)
 
     const l = StructureElement.Location.create(structure, rootUnit)
     const sizeTheme = PhysicalSizeTheme({}, {})
@@ -177,7 +179,7 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, p
         return sizeTheme.size(l)
     }
 
-    return { position, radius }
+    return { position, boundary, radius }
 }
 
 export function getStructureConformationAndRadius(structure: Structure, ignoreHydrogens: boolean) {

+ 7 - 6
src/mol-repr/structure/visual/util/molecular-surface.ts

@@ -10,12 +10,13 @@ import { getUnitConformationAndRadius, CommonSurfaceProps } from './common';
 import { PositionData, DensityData, Box3D } from '../../../../mol-math/geometry';
 import { MolecularSurfaceCalculationProps, calcMolecularSurface } from '../../../../mol-math/geometry/molecular-surface';
 import { OrderedSet } from '../../../../mol-data/int';
+import { Boundary } from '../../../../mol-math/geometry/boundary';
 
 export type MolecularSurfaceProps = MolecularSurfaceCalculationProps & CommonSurfaceProps
 
 function getPositionDataAndMaxRadius(structure: Structure, unit: Unit, props: MolecularSurfaceProps) {
     const { probeRadius } = props
-    const { position, radius } = getUnitConformationAndRadius(structure, unit, props)
+    const { position, boundary, radius } = getUnitConformationAndRadius(structure, unit, props)
     const { indices } = position
     const n = OrderedSet.size(indices)
     const radii = new Float32Array(OrderedSet.end(indices))
@@ -28,19 +29,19 @@ function getPositionDataAndMaxRadius(structure: Structure, unit: Unit, props: Mo
         radii[j] = r + probeRadius
     }
 
-    return { position: { ...position, radius: radii }, maxRadius }
+    return { position: { ...position, radius: radii }, boundary, maxRadius }
 }
 
 export function computeUnitMolecularSurface(structure: Structure, unit: Unit, props: MolecularSurfaceProps) {
     const { box } = unit.lookup3d.boundary
-    const { position, maxRadius } = getPositionDataAndMaxRadius(structure, unit, props)
+    const { position, boundary, maxRadius } = getPositionDataAndMaxRadius(structure, unit, props)
     return Task.create('Molecular Surface', async ctx => {
-        return await MolecularSurface(ctx, position, maxRadius, box, props);
+        return await MolecularSurface(ctx, position, boundary, maxRadius, box, props);
     });
 }
 
 //
 
-async function MolecularSurface(ctx: RuntimeContext, position: Required<PositionData>, maxRadius: number, box: Box3D | null, props: MolecularSurfaceCalculationProps): Promise<DensityData> {
-    return calcMolecularSurface(ctx, position, maxRadius, box, props)
+async function MolecularSurface(ctx: RuntimeContext, position: Required<PositionData>, boundary: Boundary, maxRadius: number, box: Box3D | null, props: MolecularSurfaceCalculationProps): Promise<DensityData> {
+    return calcMolecularSurface(ctx, position, boundary, maxRadius, box, props)
 }

+ 4 - 2
src/perf-tests/lookup3d.ts

@@ -8,6 +8,7 @@ import { GridLookup3D } from '../mol-math/geometry';
 // import { sortArray } from 'mol-data/util';
 import { OrderedSet } from '../mol-data/int';
 import { trajectoryFromMmCIF, MmcifFormat } from '../mol-model-formats/structure/mmcif';
+import { getBoundary } from '../mol-math/geometry/boundary';
 
 require('util.promisify').shim();
 const readFileAsync = util.promisify(fs.readFile);
@@ -41,11 +42,12 @@ export async function readCIF(path: string) {
 export async function test() {
     const { mmcif, structures } = await readCIF('e:/test/quick/1tqn_updated.cif');
 
-    const lookup = GridLookup3D({ x: mmcif.db.atom_site.Cartn_x.toArray(), y: mmcif.db.atom_site.Cartn_y.toArray(), z: mmcif.db.atom_site.Cartn_z.toArray(),
+    const position = { x: mmcif.db.atom_site.Cartn_x.toArray(), y: mmcif.db.atom_site.Cartn_y.toArray(), z: mmcif.db.atom_site.Cartn_z.toArray(),
         indices: OrderedSet.ofBounds(0, mmcif.db.atom_site._rowCount),
         // radius: [1, 1, 1, 1]
         // indices: [1]
-    });
+    }
+    const lookup = GridLookup3D(position, getBoundary(position));
     console.log(lookup.boundary.box, lookup.boundary.sphere);
 
     const result = lookup.find(-30.07, 8.178, -13.897, 10);