Sfoglia il codice sorgente

removed gaussian density calc from unit

Alexander Rose 6 anni fa
parent
commit
bd1b07ad86

+ 1 - 16
src/mol-model/structure/structure/unit.ts

@@ -7,7 +7,7 @@
 
 import { SymmetryOperator } from 'mol-math/geometry/symmetry-operator'
 import { Model } from '../model'
-import { GridLookup3D, Lookup3D, DensityData } from 'mol-math/geometry'
+import { GridLookup3D, Lookup3D } from 'mol-math/geometry'
 import { IntraUnitLinks, computeIntraUnitBonds } from './unit/links'
 import { CoarseElements, CoarseSphereConformation, CoarseGaussianConformation } from '../model/properties/coarse';
 import { ValueRef } from 'mol-util';
@@ -18,9 +18,6 @@ import { IntMap, SortedArray } from 'mol-data/int';
 import { hash2, hashFnv32a } from 'mol-data/util';
 import { getAtomicPolymerElements, getCoarsePolymerElements, getAtomicGapElements, getCoarseGapElements } from './util/polymer';
 import { getNucleotideElements } from './util/nucleotide';
-import { GaussianDensityProps, computeUnitGaussianDensityCached } from './unit/gaussian-density';
-import { RuntimeContext } from 'mol-task';
-import { WebGLContext } from 'mol-gl/webgl/context';
 
 /**
  * A building block of a structure that corresponds to an atomic or
@@ -191,10 +188,6 @@ namespace Unit {
             return this.model.atomicHierarchy.residueAtomSegments.index[this.elements[elementIndex]];
         }
 
-        async computeGaussianDensity(props: GaussianDensityProps, ctx: RuntimeContext, webgl?: WebGLContext) {
-            return computeUnitGaussianDensityCached(this, props, this.props.gaussianDensities, ctx, webgl);
-        }
-
         constructor(id: number, invariantId: number, model: Model, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping<ElementIndex>, props: AtomicProperties) {
             this.id = id;
             this.invariantId = invariantId;
@@ -215,7 +208,6 @@ namespace Unit {
         polymerElements: ValueRef<SortedArray<ElementIndex> | undefined>
         gapElements: ValueRef<SortedArray<ElementIndex> | undefined>
         nucleotideElements: ValueRef<SortedArray<ElementIndex> | undefined>
-        gaussianDensities: Map<string, DensityData>
     }
 
     function AtomicProperties(): AtomicProperties {
@@ -226,7 +218,6 @@ namespace Unit {
             polymerElements: ValueRef.create(void 0),
             gapElements: ValueRef.create(void 0),
             nucleotideElements: ValueRef.create(void 0),
-            gaussianDensities: new Map()
         };
     }
 
@@ -280,10 +271,6 @@ namespace Unit {
             return this.kind === Kind.Spheres ? this.model.coarseConformation.spheres : this.model.coarseConformation.gaussians;
         }
 
-        async computeGaussianDensity(props: GaussianDensityProps, ctx: RuntimeContext, webgl?: WebGLContext): Promise<DensityData> {
-            return computeUnitGaussianDensityCached(this as Unit.Spheres | Unit.Gaussians, props, this.props.gaussianDensities, ctx, webgl); // TODO get rid of casting
-        }
-
         constructor(id: number, invariantId: number, model: Model, kind: K, elements: StructureElement.Set, conformation: SymmetryOperator.ArrayMapping<ElementIndex>, props: CoarseProperties) {
             this.kind = kind;
             this.id = id;
@@ -299,7 +286,6 @@ namespace Unit {
 
     interface CoarseProperties {
         lookup3d: ValueRef<Lookup3D | undefined>,
-        gaussianDensities: Map<string, DensityData>
         polymerElements: ValueRef<SortedArray<ElementIndex> | undefined>
         gapElements: ValueRef<SortedArray<ElementIndex> | undefined>
     }
@@ -307,7 +293,6 @@ namespace Unit {
     function CoarseProperties(): CoarseProperties {
         return {
             lookup3d: ValueRef.create(void 0),
-            gaussianDensities: new Map(),
             polymerElements: ValueRef.create(void 0),
             gapElements: ValueRef.create(void 0),
         };

+ 0 - 76
src/mol-model/structure/structure/unit/gaussian-density.ts

@@ -1,76 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import { Unit, StructureElement, ElementIndex } from 'mol-model/structure';
-import { GaussianDensity } from 'mol-math/geometry/gaussian-density';
-import { Task, RuntimeContext } from 'mol-task';
-import { DensityData } from 'mol-math/geometry';
-import { ParamDefinition as PD } from 'mol-util/param-definition';
-import { GaussianDensityTexture } from 'mol-math/geometry/gaussian-density/gpu';
-import { Texture } from 'mol-gl/webgl/texture';
-import { WebGLContext } from 'mol-gl/webgl/context';
-import { PhysicalSizeTheme } from 'mol-theme/size/physical';
-
-export const GaussianDensityParams = {
-    resolution: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }),
-    radiusOffset: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }),
-    smoothness: PD.Numeric(1.5, { min: 0.5, max: 2.5, step: 0.1 }),
-    useGpu: PD.Boolean(false),
-    ignoreCache: PD.Boolean(false),
-}
-export const DefaultGaussianDensityProps = PD.getDefaultValues(GaussianDensityParams)
-export type GaussianDensityProps = typeof DefaultGaussianDensityProps
-
-function getConformation(unit: Unit) {
-    switch (unit.kind) {
-        case Unit.Kind.Atomic: return unit.model.atomicConformation
-        case Unit.Kind.Spheres: return unit.model.coarseConformation.spheres
-        case Unit.Kind.Gaussians: return unit.model.coarseConformation.gaussians
-    }
-}
-
-function getConformationAndRadius(unit: Unit) {
-    const conformation = getConformation(unit)
-    const { elements } = unit
-    const position = {
-        indices: elements,
-        x: conformation.x,
-        y: conformation.y,
-        z: conformation.z
-    }
-
-    const l = StructureElement.create(unit)
-    const sizeTheme = PhysicalSizeTheme({}, {})
-    const radius = (index: number) => {
-        l.element = index as ElementIndex
-        return sizeTheme.size(l)
-    }
-
-    return { position, radius }
-}
-
-export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityProps, webgl?: WebGLContext) {
-    const { position, radius } = getConformationAndRadius(unit)
-    return Task.create('Gaussian Density', async ctx => {
-        return await GaussianDensity(ctx, position, unit.lookup3d.boundary.box, radius, props, webgl);
-    });
-}
-
-export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
-    const { position, radius } = getConformationAndRadius(unit)
-    return Task.create('Gaussian Density', async ctx => {
-        return await GaussianDensityTexture(ctx, webgl, position, unit.lookup3d.boundary.box, radius, props, texture);
-    });
-}
-
-export async function computeUnitGaussianDensityCached(unit: Unit, props: GaussianDensityProps, cache: Map<string, DensityData>, ctx: RuntimeContext, webgl?: WebGLContext) {
-    const key = `${props.radiusOffset}|${props.resolution}|${props.smoothness}`
-    let density = cache.get(key)
-    if (density && !props.ignoreCache) return density
-    density = await computeUnitGaussianDensity(unit, props, webgl).runInContext(ctx)
-    if (!props.ignoreCache) cache.set(key, density)
-    return density
-}

+ 2 - 2
src/mol-repr/structure/visual/gaussian-density-point.ts

@@ -11,12 +11,12 @@ import { StructureElementIterator } from './util/element';
 import { EmptyLoci } from 'mol-model/loci';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { UnitsPointsVisual, UnitsPointsParams } from '../units-visual';
-import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { Points } from 'mol-geo/geometry/points/points';
 import { PointsBuilder } from 'mol-geo/geometry/points/points-builder';
 import { VisualContext } from 'mol-repr/visual';
 import { Theme } from 'mol-theme/theme';
+import { computeUnitGaussianDensity, GaussianDensityParams, GaussianDensityProps } from './util/gaussian';
 
 export const GaussianDensityPointParams = {
     ...UnitsPointsParams,
@@ -26,7 +26,7 @@ export const GaussianDensityPointParams = {
 export type GaussianDensityPointParams = typeof GaussianDensityPointParams
 
 export async function createGaussianDensityPoint(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, points?: Points) {
-    const { transform, field: { space, data } } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
+    const { transform, field: { space, data } } = await computeUnitGaussianDensity(unit, props, ctx.webgl).runInContext(ctx.runtime)
 
     const { dimensions, get } = space
     const [ xn, yn, zn ] = dimensions

+ 4 - 53
src/mol-repr/structure/visual/gaussian-density-volume.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Structure, StructureElement } from 'mol-model/structure';
+import { Structure } from 'mol-model/structure';
 import { VisualUpdateState } from '../../util';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { DirectVolume } from 'mol-geo/geometry/direct-volume/direct-volume';
@@ -14,56 +14,9 @@ import { ComplexVisual, ComplexDirectVolumeVisual, ComplexDirectVolumeParams } f
 import { EmptyLoci } from 'mol-model/loci';
 import { NullLocation } from 'mol-model/location';
 import { LocationIterator } from 'mol-geo/util/location-iterator';
-import { WebGLContext } from 'mol-gl/webgl/context';
-import { Texture } from 'mol-gl/webgl/texture';
-import { GaussianDensityTexture } from 'mol-math/geometry/gaussian-density/gpu';
-import { Task } from 'mol-task';
-import { OrderedSet } from 'mol-data/int';
-import { PhysicalSizeTheme } from 'mol-theme/size/physical';
+import { computeStructureGaussianDensityTexture, GaussianDensityTextureProps, GaussianDensityTextureParams } from './util/gaussian';
 
-function getConformationAndRadius(structure: Structure) {
-    const n = structure.elementCount
-
-    const xs = new Float32Array(n)
-    const ys = new Float32Array(n)
-    const zs = new Float32Array(n)
-    const rs = new Float32Array(n)
-
-    const l = StructureElement.create()
-    const sizeTheme = PhysicalSizeTheme({}, {})
-
-    let m = 0
-    for (let i = 0, il = structure.units.length; i < il; ++i) {
-        const unit = structure.units[i]
-        const { elements } = unit
-        const { x, y, z } = unit.conformation
-        l.unit = unit
-        for (let j = 0, jl = elements.length; j < jl; ++j) {
-            const eI = elements[j]
-            xs[m + j] = x(eI)
-            ys[m + j] = y(eI)
-            zs[m + j] = z(eI)
-            l.element = eI
-            rs[m + j] = sizeTheme.size(l)
-        }
-        m += elements.length
-    }
-
-    const position = { indices: OrderedSet.ofRange(0, n), x: xs, y: ys, z: zs }
-    const radius = (index: number) => rs[index]
-
-    return { position, radius }
-}
-
-// TODO calculate by combining unit volumes
-function computeStructureGaussianDensityTexture(structure: Structure, props: PD.Values<GaussianDensityVolumeParams>, webgl: WebGLContext, texture?: Texture) {
-    const { position, radius } = getConformationAndRadius(structure)
-    return Task.create('Gaussian Density', async ctx => {
-        return await GaussianDensityTexture(ctx, webgl, position, structure.lookup3d.boundary.box, radius, props, texture);
-    });
-}
-
-async function createGaussianDensityVolume(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<GaussianDensityVolumeParams>, directVolume?: DirectVolume): Promise<DirectVolume> {
+async function createGaussianDensityVolume(ctx: VisualContext, structure: Structure, theme: Theme, props: GaussianDensityTextureProps, directVolume?: DirectVolume): Promise<DirectVolume> {
     const { runtime, webgl } = ctx
     if (webgl === undefined) throw new Error('createGaussianDensityVolume requires `webgl` object in VisualContext')
 
@@ -77,9 +30,7 @@ async function createGaussianDensityVolume(ctx: VisualContext, structure: Struct
 
 export const GaussianDensityVolumeParams = {
     ...ComplexDirectVolumeParams,
-    resolution: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }),
-    radiusOffset: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }),
-    smoothness: PD.Numeric(1.5, { min: 0.5, max: 2.5, step: 0.1 }),
+    ...GaussianDensityTextureParams
 }
 export type GaussianDensityVolumeParams = typeof GaussianDensityVolumeParams
 

+ 2 - 2
src/mol-repr/structure/visual/gaussian-surface-mesh.ts

@@ -9,16 +9,16 @@ import { UnitsVisual } from '../representation';
 import { VisualUpdateState } from '../../util';
 import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual';
 import { StructureElementIterator, getElementLoci, markElement } from './util/element';
-import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { Mesh } from 'mol-geo/geometry/mesh/mesh';
 import { computeMarchingCubesMesh } from 'mol-geo/util/marching-cubes/algorithm';
 import { VisualContext } from 'mol-repr/visual';
 import { Theme } from 'mol-theme/theme';
+import { GaussianDensityProps, computeUnitGaussianDensity, GaussianDensityParams } from './util/gaussian';
 
 async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
     const { smoothness } = props
-    const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime, ctx.webgl)
+    const { transform, field, idField } = await computeUnitGaussianDensity(unit, props, ctx.webgl).runInContext(ctx.runtime)
 
     const params = {
         isoLevel: Math.exp(-smoothness),

+ 2 - 2
src/mol-repr/structure/visual/gaussian-surface-wireframe.ts

@@ -9,16 +9,16 @@ import { UnitsVisual } from '../representation';
 import { VisualUpdateState } from '../../util';
 import { UnitsLinesVisual, UnitsLinesParams } from '../units-visual';
 import { StructureElementIterator, getElementLoci, markElement } from './util/element';
-import { GaussianDensityProps, GaussianDensityParams } from 'mol-model/structure/structure/unit/gaussian-density';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { Lines } from 'mol-geo/geometry/lines/lines';
 import { computeMarchingCubesLines } from 'mol-geo/util/marching-cubes/algorithm';
 import { VisualContext } from 'mol-repr/visual';
 import { Theme } from 'mol-theme/theme';
+import { GaussianDensityProps, GaussianDensityParams, computeUnitGaussianDensity } from './util/gaussian';
 
 async function createGaussianWireframe(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, lines?: Lines): Promise<Lines> {
     const { smoothness } = props
-    const { transform, field, idField } = await unit.computeGaussianDensity(props, ctx.runtime)
+    const { transform, field, idField } = await computeUnitGaussianDensity(unit, props, ctx.webgl).runInContext(ctx.runtime)
 
     const params = {
         isoLevel: Math.exp(-smoothness),

+ 124 - 0
src/mol-repr/structure/visual/util/gaussian.ts

@@ -3,3 +3,127 @@
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
+
+import { Unit, StructureElement, ElementIndex, Structure } from 'mol-model/structure';
+import { GaussianDensity } from 'mol-math/geometry/gaussian-density';
+import { Task, RuntimeContext } from 'mol-task';
+import { DensityData } from 'mol-math/geometry';
+import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { GaussianDensityTexture } from 'mol-math/geometry/gaussian-density/gpu';
+import { Texture } from 'mol-gl/webgl/texture';
+import { WebGLContext } from 'mol-gl/webgl/context';
+import { PhysicalSizeTheme } from 'mol-theme/size/physical';
+import { OrderedSet } from 'mol-data/int';
+
+export const GaussianDensityParams = {
+    resolution: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }),
+    radiusOffset: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }),
+    smoothness: PD.Numeric(1.5, { min: 0.5, max: 2.5, step: 0.1 }),
+    useGpu: PD.Boolean(false),
+    ignoreCache: PD.Boolean(false),
+}
+export const DefaultGaussianDensityProps = PD.getDefaultValues(GaussianDensityParams)
+export type GaussianDensityProps = typeof DefaultGaussianDensityProps
+
+function getConformation(unit: Unit) {
+    switch (unit.kind) {
+        case Unit.Kind.Atomic: return unit.model.atomicConformation
+        case Unit.Kind.Spheres: return unit.model.coarseConformation.spheres
+        case Unit.Kind.Gaussians: return unit.model.coarseConformation.gaussians
+    }
+}
+
+function getUnitConformationAndRadius(unit: Unit) {
+    const conformation = getConformation(unit)
+    const { elements } = unit
+    const position = {
+        indices: elements,
+        x: conformation.x,
+        y: conformation.y,
+        z: conformation.z
+    }
+
+    const l = StructureElement.create(unit)
+    const sizeTheme = PhysicalSizeTheme({}, {})
+    const radius = (index: number) => {
+        l.element = index as ElementIndex
+        return sizeTheme.size(l)
+    }
+
+    return { position, radius }
+}
+
+export function computeUnitGaussianDensity(unit: Unit, props: GaussianDensityProps, webgl?: WebGLContext) {
+    const { position, radius } = getUnitConformationAndRadius(unit)
+    return Task.create('Gaussian Density', async ctx => {
+        return await GaussianDensity(ctx, position, unit.lookup3d.boundary.box, radius, props, webgl);
+    });
+}
+
+export function computeUnitGaussianDensityTexture(unit: Unit, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
+    const { position, radius } = getUnitConformationAndRadius(unit)
+    return Task.create('Gaussian Density', async ctx => {
+        return await GaussianDensityTexture(ctx, webgl, position, unit.lookup3d.boundary.box, radius, props, texture);
+    });
+}
+
+export async function computeUnitGaussianDensityCached(unit: Unit, props: GaussianDensityProps, cache: Map<string, DensityData>, ctx: RuntimeContext, webgl?: WebGLContext) {
+    const key = `${props.radiusOffset}|${props.resolution}|${props.smoothness}`
+    let density = cache.get(key)
+    if (density && !props.ignoreCache) return density
+    density = await computeUnitGaussianDensity(unit, props, webgl).runInContext(ctx)
+    if (!props.ignoreCache) cache.set(key, density)
+    return density
+}
+
+//
+
+function getStructureConformationAndRadius(structure: Structure) {
+    const n = structure.elementCount
+
+    const xs = new Float32Array(n)
+    const ys = new Float32Array(n)
+    const zs = new Float32Array(n)
+    const rs = new Float32Array(n)
+
+    const l = StructureElement.create()
+    const sizeTheme = PhysicalSizeTheme({}, {})
+
+    let m = 0
+    for (let i = 0, il = structure.units.length; i < il; ++i) {
+        const unit = structure.units[i]
+        const { elements } = unit
+        const { x, y, z } = unit.conformation
+        l.unit = unit
+        for (let j = 0, jl = elements.length; j < jl; ++j) {
+            const eI = elements[j]
+            xs[m + j] = x(eI)
+            ys[m + j] = y(eI)
+            zs[m + j] = z(eI)
+            l.element = eI
+            rs[m + j] = sizeTheme.size(l)
+        }
+        m += elements.length
+    }
+
+    const position = { indices: OrderedSet.ofRange(0, n), x: xs, y: ys, z: zs }
+    const radius = (index: number) => rs[index]
+
+    return { position, radius }
+}
+
+export const GaussianDensityTextureParams = {
+    resolution: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }),
+    radiusOffset: PD.Numeric(0, { min: 0, max: 10, step: 0.1 }),
+    smoothness: PD.Numeric(1.5, { min: 0.5, max: 2.5, step: 0.1 }),
+}
+export const DefaultGaussianDensityTextureProps = PD.getDefaultValues(GaussianDensityTextureParams)
+export type GaussianDensityTextureProps = typeof DefaultGaussianDensityTextureProps
+
+// TODO calculate by combining unit volumes
+export function computeStructureGaussianDensityTexture(structure: Structure, props: GaussianDensityTextureProps, webgl: WebGLContext, texture?: Texture) {
+    const { position, radius } = getStructureConformationAndRadius(structure)
+    return Task.create('Gaussian Density', async ctx => {
+        return await GaussianDensityTexture(ctx, webgl, position, structure.lookup3d.boundary.box, radius, props, texture);
+    });
+}