Browse Source

Merge pull request #333 from molstar/surface-size-theme

Use size theme in molecular/gaussian surface & label representations
Alexander Rose 3 years ago
parent
commit
2c1200433c

+ 2 - 0
CHANGELOG.md

@@ -7,6 +7,8 @@ Note that since we don't clearly distinguish between a public and private interf
 ## [Unreleased]
 
 - Add ``PluginFeatureDetection`` and disable WBOIT in Safari 15.
+- [Breaking] Use size theme in molecular/gaussian surface & label representations
+    - This is breaking because it was hardcoded to ``physical`` internally but the repr size theme default was ``uniform`` (now ``physical``)
 
 ## [v3.0.0-dev.7] - 2021-12-20
 

+ 2 - 2
src/mol-plugin-state/transforms/representation.ts

@@ -120,7 +120,7 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({
             ),
             sizeTheme: PD.Mapped<any>(
                 type.defaultSizeTheme.name,
-                themeCtx.sizeThemeRegistry.types,
+                themeCtx.sizeThemeRegistry.getApplicableTypes(dataCtx),
                 name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams(dataCtx))
             )
         });
@@ -823,7 +823,7 @@ const VolumeRepresentation3D = PluginStateTransform.BuiltIn({
             ),
             sizeTheme: PD.Mapped<any>(
                 type.defaultSizeTheme.name,
-                themeCtx.sizeThemeRegistry.types,
+                themeCtx.sizeThemeRegistry.getApplicableTypes(dataCtx),
                 name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams(dataCtx))
             )
         });

+ 1 - 1
src/mol-repr/structure/representation/gaussian-surface.ts

@@ -44,6 +44,6 @@ export const GaussianSurfaceRepresentationProvider = StructureRepresentationProv
     getParams: getGaussianSurfaceParams,
     defaultValues: PD.getDefaultValues(GaussianSurfaceParams),
     defaultColorTheme: { name: 'chain-id' },
-    defaultSizeTheme: { name: 'uniform' },
+    defaultSizeTheme: { name: 'physical' },
     isApplicable: (structure: Structure) => structure.elementCount > 0
 });

+ 1 - 1
src/mol-repr/structure/representation/gaussian-volume.ts

@@ -45,6 +45,6 @@ export const GaussianVolumeRepresentationProvider = StructureRepresentationProvi
     getParams: getGaussianVolumeParams,
     defaultValues: PD.getDefaultValues(GaussianVolumeParams),
     defaultColorTheme: { name: 'chain-id' },
-    defaultSizeTheme: { name: 'uniform' },
+    defaultSizeTheme: { name: 'physical' },
     isApplicable: (structure: Structure) => structure.elementCount > 0
 });

+ 1 - 1
src/mol-repr/structure/representation/label.ts

@@ -40,6 +40,6 @@ export const LabelRepresentationProvider = StructureRepresentationProvider({
     getParams: getLabelParams,
     defaultValues: PD.getDefaultValues(LabelParams),
     defaultColorTheme: { name: 'uniform' },
-    defaultSizeTheme: { name: 'uniform' },
+    defaultSizeTheme: { name: 'physical' },
     isApplicable: (structure: Structure) => structure.elementCount > 0
 });

+ 1 - 1
src/mol-repr/structure/representation/molecular-surface.ts

@@ -43,6 +43,6 @@ export const MolecularSurfaceRepresentationProvider = StructureRepresentationPro
     getParams: getMolecularSurfaceParams,
     defaultValues: PD.getDefaultValues(MolecularSurfaceParams),
     defaultColorTheme: { name: 'chain-id' },
-    defaultSizeTheme: { name: 'uniform' },
+    defaultSizeTheme: { name: 'physical' },
     isApplicable: (structure: Structure) => structure.elementCount > 0
 });

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

@@ -25,7 +25,7 @@ async function createGaussianDensityVolume(ctx: VisualContext, structure: Struct
     }
 
     const oldTexture = directVolume ? directVolume.gridTexture.ref.value : undefined;
-    const densityTextureData = await computeStructureGaussianDensityTexture(structure, props, webgl, oldTexture).runInContext(runtime);
+    const densityTextureData = await computeStructureGaussianDensityTexture(structure, theme.size, props, webgl, oldTexture).runInContext(runtime);
     const { transform, texture, bbox, gridDim } = densityTextureData;
     const stats = { min: 0, max: 1, mean: 0.04, sigma: 0.01 };
 
@@ -81,7 +81,7 @@ async function createUnitsGaussianDensityVolume(ctx: VisualContext, unit: Unit,
     }
 
     const oldTexture = directVolume ? directVolume.gridTexture.ref.value : undefined;
-    const densityTextureData = await computeUnitGaussianDensityTexture(structure, unit, props, webgl, oldTexture).runInContext(runtime);
+    const densityTextureData = await computeUnitGaussianDensityTexture(structure, unit, theme.size, props, webgl, oldTexture).runInContext(runtime);
     const { transform, texture, bbox, gridDim } = densityTextureData;
     const stats = { min: 0, max: 1, mean: 0.04, sigma: 0.01 };
 

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

@@ -89,7 +89,7 @@ type GaussianSurfaceMeta = {
 
 async function createGaussianSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
     const { smoothness } = props;
-    const { transform, field, idField, radiusFactor, resolution } = await computeUnitGaussianDensity(structure, unit, props).runInContext(ctx.runtime);
+    const { transform, field, idField, radiusFactor, resolution } = await computeUnitGaussianDensity(structure, unit, theme.size, props).runInContext(ctx.runtime);
 
     const params = {
         isoLevel: Math.exp(-smoothness) / radiusFactor,
@@ -150,7 +150,7 @@ export function GaussianSurfaceMeshVisual(materialId: number): UnitsVisual<Gauss
 
 async function createStructureGaussianSurfaceMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: GaussianDensityProps, mesh?: Mesh): Promise<Mesh> {
     const { smoothness } = props;
-    const { transform, field, idField, radiusFactor, resolution } = await computeStructureGaussianDensity(structure, props).runInContext(ctx.runtime);
+    const { transform, field, idField, radiusFactor, resolution } = await computeStructureGaussianDensity(structure, theme.size, props).runInContext(ctx.runtime);
 
     const params = {
         isoLevel: Math.exp(-smoothness) / radiusFactor,
@@ -223,7 +223,7 @@ async function createGaussianSurfaceTextureMesh(ctx: VisualContext, unit: Unit,
     }
 
     // console.time('computeUnitGaussianDensityTexture2d');
-    const densityTextureData = await computeUnitGaussianDensityTexture2d(structure, unit, true, props, ctx.webgl, namedTextures[GaussianSurfaceName]).runInContext(ctx.runtime);
+    const densityTextureData = await computeUnitGaussianDensityTexture2d(structure, unit, theme.size, true, props, ctx.webgl, namedTextures[GaussianSurfaceName]).runInContext(ctx.runtime);
     // console.log(densityTextureData);
     // console.log('vertexGroupTexture', readTexture(ctx.webgl, densityTextureData.texture));
     // ctx.webgl.waitForGpuCommandsCompleteSync();
@@ -300,7 +300,7 @@ async function createStructureGaussianSurfaceTextureMesh(ctx: VisualContext, str
     }
 
     // console.time('computeUnitGaussianDensityTexture2d');
-    const densityTextureData = await computeStructureGaussianDensityTexture2d(structure, true, props, ctx.webgl, namedTextures[GaussianSurfaceName]).runInContext(ctx.runtime);
+    const densityTextureData = await computeStructureGaussianDensityTexture2d(structure, theme.size, true, props, ctx.webgl, namedTextures[GaussianSurfaceName]).runInContext(ctx.runtime);
     // console.log(densityTextureData);
     // console.log('vertexGroupTexture', readTexture(ctx.webgl, densityTextureData.texture));
     // ctx.webgl.waitForGpuCommandsCompleteSync();

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

@@ -19,7 +19,7 @@ import { getUnitExtraRadius } from './util/common';
 
 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 computeUnitGaussianDensity(structure, unit, props).runInContext(ctx.runtime);
+    const { transform, field, idField } = await computeUnitGaussianDensity(structure, unit, theme.size, props).runInContext(ctx.runtime);
 
     const params = {
         isoLevel: Math.exp(-smoothness),

+ 1 - 2
src/mol-repr/structure/visual/label-text.ts

@@ -16,7 +16,6 @@ import { ComplexTextVisual, ComplexTextParams, ComplexVisual } from '../complex-
 import { ElementIterator, getSerialElementLoci, eachSerialElement } from './util/element';
 import { ColorNames } from '../../../mol-util/color/names';
 import { Vec3 } from '../../../mol-math/linear-algebra';
-import { PhysicalSizeTheme } from '../../../mol-theme/size/physical';
 import { BoundaryHelper } from '../../../mol-math/geometry/boundary-helper';
 
 export const LabelTextParams = {
@@ -151,7 +150,7 @@ function createElementText(ctx: VisualContext, structure: Structure, theme: Them
     const { label_atom_id, label_alt_id } = StructureProperties.atom;
     const { cumulativeUnitElementCount } = serialMapping;
 
-    const sizeTheme = PhysicalSizeTheme({}, { scale: 1 });
+    const sizeTheme = theme.size;
 
     const count = structure.elementCount;
     const { elementScale } = props;

+ 1 - 1
src/mol-repr/structure/visual/molecular-surface-mesh.ts

@@ -40,7 +40,7 @@ type MolecularSurfaceMeta = {
 //
 
 async function createMolecularSurfaceMesh(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: MolecularSurfaceMeshProps, mesh?: Mesh): Promise<Mesh> {
-    const { transform, field, idField, resolution } = await computeUnitMolecularSurface(structure, unit, props).runInContext(ctx.runtime);
+    const { transform, field, idField, resolution } = await computeUnitMolecularSurface(structure, unit, theme.size, props).runInContext(ctx.runtime);
 
     const params = {
         isoLevel: props.probeRadius,

+ 1 - 1
src/mol-repr/structure/visual/molecular-surface-wireframe.ts

@@ -29,7 +29,7 @@ export type MolecularSurfaceWireframeParams = typeof MolecularSurfaceWireframePa
 //
 
 async function createMolecularSurfaceWireframe(ctx: VisualContext, unit: Unit, structure: Structure, theme: Theme, props: MolecularSurfaceProps, lines?: Lines): Promise<Lines> {
-    const { transform, field, idField } = await computeUnitMolecularSurface(structure, unit, props).runInContext(ctx.runtime);
+    const { transform, field, idField } = await computeUnitMolecularSurface(structure, unit, theme.size, props).runInContext(ctx.runtime);
     const params = {
         isoLevel: props.probeRadius,
         scalarField: field,

+ 3 - 5
src/mol-repr/structure/visual/util/common.ts

@@ -9,13 +9,13 @@ import { Mat4, Vec3 } from '../../../../mol-math/linear-algebra';
 import { TransformData, createTransform } from '../../../../mol-geo/geometry/transform-data';
 import { OrderedSet, SortedArray } from '../../../../mol-data/int';
 import { EmptyLoci, Loci } from '../../../../mol-model/loci';
-import { PhysicalSizeTheme } from '../../../../mol-theme/size/physical';
 import { AtomicNumbers } from '../../../../mol-model/structure/model/properties/atomic';
 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';
 import { Box3D } from '../../../../mol-math/geometry';
+import { SizeTheme } from '../../../../mol-theme/size';
 
 /** 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 {
@@ -165,7 +165,7 @@ function filterId(id: AssignableArrayLike<number>, elements: SortedArray, indice
     }
 }
 
-export function getUnitConformationAndRadius(structure: Structure, unit: Unit, props: CommonSurfaceProps) {
+export function getUnitConformationAndRadius(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: CommonSurfaceProps) {
     const { ignoreHydrogens, traceOnly, includeParent } = props;
     const rootUnit = includeParent ? structure.root.unitMap.get(unit.id) : unit;
 
@@ -205,7 +205,6 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, p
     const boundary = unit === rootUnit ? unit.boundary : getBoundary(position);
 
     const l = StructureElement.Location.create(structure, rootUnit);
-    const sizeTheme = PhysicalSizeTheme({}, { scale: 1 });
     const radius = (index: number) => {
         l.element = index as ElementIndex;
         return sizeTheme.size(l);
@@ -214,9 +213,8 @@ export function getUnitConformationAndRadius(structure: Structure, unit: Unit, p
     return { position, boundary, radius };
 }
 
-export function getStructureConformationAndRadius(structure: Structure, ignoreHydrogens: boolean, traceOnly: boolean) {
+export function getStructureConformationAndRadius(structure: Structure, sizeTheme: SizeTheme<any>, ignoreHydrogens: boolean, traceOnly: boolean) {
     const l = StructureElement.Location.create(structure);
-    const sizeTheme = PhysicalSizeTheme({}, { scale: 1 });
 
     let xs: ArrayLike<number>;
     let ys: ArrayLike<number>;

+ 13 - 12
src/mol-repr/structure/visual/util/gaussian.ts

@@ -13,6 +13,7 @@ import { WebGLContext } from '../../../../mol-gl/webgl/context';
 import { getUnitConformationAndRadius, getStructureConformationAndRadius, CommonSurfaceParams, ensureReasonableResolution } from './common';
 import { BaseGeometry } from '../../../../mol-geo/geometry/base';
 import { GaussianDensityCPU } from '../../../../mol-math/geometry/gaussian-density/cpu';
+import { SizeTheme } from '../../../../mol-theme/size';
 
 export const GaussianDensityParams = {
     resolution: PD.Numeric(1, { min: 0.1, max: 20, step: 0.1 }, { description: 'Grid resolution/cell spacing.', ...BaseGeometry.CustomQualityParamInfo }),
@@ -32,28 +33,28 @@ export function getTextureMaxCells(webgl: WebGLContext, structure?: Structure) {
 
 //
 
-export function computeUnitGaussianDensity(structure: Structure, unit: Unit, props: GaussianDensityProps) {
+export function computeUnitGaussianDensity(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: GaussianDensityProps) {
     const { box } = unit.lookup3d.boundary;
     const p = ensureReasonableResolution(box, props);
-    const { position, radius } = getUnitConformationAndRadius(structure, unit, p);
+    const { position, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, p);
     return Task.create('Gaussian Density', async ctx => {
         return await GaussianDensityCPU(ctx, position, box, radius, p);
     });
 }
 
-export function computeUnitGaussianDensityTexture(structure: Structure, unit: Unit, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
+export function computeUnitGaussianDensityTexture(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
     const { box } = unit.lookup3d.boundary;
     const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl, structure));
-    const { position, radius } = getUnitConformationAndRadius(structure, unit, p);
+    const { position, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, p);
     return Task.create('Gaussian Density', async ctx => {
         return GaussianDensityTexture(webgl, position, box, radius, p, texture);
     });
 }
 
-export function computeUnitGaussianDensityTexture2d(structure: Structure, unit: Unit, powerOfTwo: boolean, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
+export function computeUnitGaussianDensityTexture2d(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, powerOfTwo: boolean, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
     const { box } = unit.lookup3d.boundary;
     const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl, structure));
-    const { position, radius } = getUnitConformationAndRadius(structure, unit, p);
+    const { position, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, p);
     return Task.create('Gaussian Density', async ctx => {
         return GaussianDensityTexture2d(webgl, position, box, radius, powerOfTwo, p, texture);
     });
@@ -61,28 +62,28 @@ export function computeUnitGaussianDensityTexture2d(structure: Structure, unit:
 
 //
 
-export function computeStructureGaussianDensity(structure: Structure, props: GaussianDensityProps) {
+export function computeStructureGaussianDensity(structure: Structure, sizeTheme: SizeTheme<any>, props: GaussianDensityProps) {
     const { box } = structure.lookup3d.boundary;
     const p = ensureReasonableResolution(box, props);
-    const { position, radius } = getStructureConformationAndRadius(structure, props.ignoreHydrogens, props.traceOnly);
+    const { position, radius } = getStructureConformationAndRadius(structure, sizeTheme, props.ignoreHydrogens, props.traceOnly);
     return Task.create('Gaussian Density', async ctx => {
         return await GaussianDensityCPU(ctx, position, box, radius, p);
     });
 }
 
-export function computeStructureGaussianDensityTexture(structure: Structure, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
+export function computeStructureGaussianDensityTexture(structure: Structure, sizeTheme: SizeTheme<any>, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
     const { box } = structure.lookup3d.boundary;
     const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl));
-    const { position, radius } = getStructureConformationAndRadius(structure, props.ignoreHydrogens, props.traceOnly);
+    const { position, radius } = getStructureConformationAndRadius(structure, sizeTheme, props.ignoreHydrogens, props.traceOnly);
     return Task.create('Gaussian Density', async ctx => {
         return GaussianDensityTexture(webgl, position, box, radius, p, texture);
     });
 }
 
-export function computeStructureGaussianDensityTexture2d(structure: Structure, powerOfTwo: boolean, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
+export function computeStructureGaussianDensityTexture2d(structure: Structure, sizeTheme: SizeTheme<any>, powerOfTwo: boolean, props: GaussianDensityProps, webgl: WebGLContext, texture?: Texture) {
     const { box } = structure.lookup3d.boundary;
     const p = ensureReasonableResolution(box, props, getTextureMaxCells(webgl));
-    const { position, radius } = getStructureConformationAndRadius(structure, props.ignoreHydrogens, props.traceOnly);
+    const { position, radius } = getStructureConformationAndRadius(structure, sizeTheme, props.ignoreHydrogens, props.traceOnly);
     return Task.create('Gaussian Density', async ctx => {
         return GaussianDensityTexture2d(webgl, position, box, radius, powerOfTwo, p, texture);
     });

+ 5 - 4
src/mol-repr/structure/visual/util/molecular-surface.ts

@@ -11,12 +11,13 @@ 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';
+import { SizeTheme } from '../../../../mol-theme/size';
 
 export type MolecularSurfaceProps = MolecularSurfaceCalculationProps & CommonSurfaceProps
 
-function getPositionDataAndMaxRadius(structure: Structure, unit: Unit, props: MolecularSurfaceProps) {
+function getPositionDataAndMaxRadius(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: MolecularSurfaceProps) {
     const { probeRadius } = props;
-    const { position, boundary, radius } = getUnitConformationAndRadius(structure, unit, props);
+    const { position, boundary, radius } = getUnitConformationAndRadius(structure, unit, sizeTheme, props);
     const { indices } = position;
     const n = OrderedSet.size(indices);
     const radii = new Float32Array(OrderedSet.end(indices));
@@ -32,10 +33,10 @@ function getPositionDataAndMaxRadius(structure: Structure, unit: Unit, props: Mo
     return { position: { ...position, radius: radii }, boundary, maxRadius };
 }
 
-export function computeUnitMolecularSurface(structure: Structure, unit: Unit, props: MolecularSurfaceProps) {
+export function computeUnitMolecularSurface(structure: Structure, unit: Unit, sizeTheme: SizeTheme<any>, props: MolecularSurfaceProps) {
     const { box } = unit.lookup3d.boundary;
     const p = ensureReasonableResolution(box, props);
-    const { position, boundary, maxRadius } = getPositionDataAndMaxRadius(structure, unit, p);
+    const { position, boundary, maxRadius } = getPositionDataAndMaxRadius(structure, unit, sizeTheme, p);
     return Task.create('Molecular Surface', async ctx => {
         return await MolecularSurface(ctx, position, boundary, maxRadius, box, p);
     });