Skip to content
Snippets Groups Projects
Commit 181646f0 authored by Alexander Rose's avatar Alexander Rose
Browse files

membrane orientation tweaks

- registered custom repr so it shows up in components
- some renames to make it more in line with the other extensions
- fix shapes to reuse existing geometries (fails to update on prop changes otherwise)
- added label to repr visuals on hover/highlight
- ignore light forbilayer planes mesh
- TODO: layer spheres seem to be broken (e.g. 3pqr)
parent ea5a9458
No related branches found
No related tags found
No related merge requests found
...@@ -24,7 +24,7 @@ import { PluginState } from '../../mol-plugin/state'; ...@@ -24,7 +24,7 @@ import { PluginState } from '../../mol-plugin/state';
import { DownloadDensity } from '../../mol-plugin-state/actions/volume'; import { DownloadDensity } from '../../mol-plugin-state/actions/volume';
import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout'; import { PluginLayoutControlsDisplay } from '../../mol-plugin/layout';
import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory'; import { BuiltInTrajectoryFormat } from '../../mol-plugin-state/formats/trajectory';
import { MembraneOrientationData } from '../../extensions/membrane-orientation/behavior'; import { ANVILMembraneOrientation } from '../../extensions/anvil/behavior';
import { DnatcoConfalPyramids } from '../../extensions/dnatco'; import { DnatcoConfalPyramids } from '../../extensions/dnatco';
require('mol-plugin-ui/skin/light.scss'); require('mol-plugin-ui/skin/light.scss');
...@@ -38,7 +38,7 @@ const Extensions = { ...@@ -38,7 +38,7 @@ const Extensions = {
'pdbe-structure-quality-report': PluginSpec.Behavior(PDBeStructureQualityReport), 'pdbe-structure-quality-report': PluginSpec.Behavior(PDBeStructureQualityReport),
'rcsb-assembly-symmetry': PluginSpec.Behavior(RCSBAssemblySymmetry), 'rcsb-assembly-symmetry': PluginSpec.Behavior(RCSBAssemblySymmetry),
'rcsb-validation-report': PluginSpec.Behavior(RCSBValidationReport), 'rcsb-validation-report': PluginSpec.Behavior(RCSBValidationReport),
'membrane-orientation': PluginSpec.Behavior(MembraneOrientationData) 'anvil-membrane-orientation': PluginSpec.Behavior(ANVILMembraneOrientation)
}; };
const DefaultViewerOptions = { const DefaultViewerOptions = {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { ANVILContext } from './anvil/common';
import { Structure, StructureElement, StructureProperties } from '../../mol-model/structure'; import { Structure, StructureElement, StructureProperties } from '../../mol-model/structure';
import { Task, RuntimeContext } from '../../mol-task'; import { Task, RuntimeContext } from '../../mol-task';
import { CentroidHelper } from '../../mol-math/geometry/centroid-helper'; import { CentroidHelper } from '../../mol-math/geometry/centroid-helper';
...@@ -15,7 +14,22 @@ import { getElementMoleculeType } from '../../mol-model/structure/util'; ...@@ -15,7 +14,22 @@ import { getElementMoleculeType } from '../../mol-model/structure/util';
import { MoleculeType } from '../../mol-model/structure/model/types'; import { MoleculeType } from '../../mol-model/structure/model/types';
import { AccessibleSurfaceArea } from '../../mol-model-props/computed/accessible-surface-area/shrake-rupley'; import { AccessibleSurfaceArea } from '../../mol-model-props/computed/accessible-surface-area/shrake-rupley';
import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { MembraneOrientation } from './membrane-orientation'; import { MembraneOrientation } from './prop';
interface ANVILContext {
structure: Structure,
numberOfSpherePoints: number,
stepSize: number,
minThickness: number,
maxThickness: number,
asaCutoff: number,
offsets: ArrayLike<number>,
exposed: ArrayLike<boolean>,
centroid: Vec3,
extent: number
};
export const ANVILParams = { export const ANVILParams = {
numberOfSpherePoints: PD.Numeric(120, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }), numberOfSpherePoints: PD.Numeric(120, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }),
......
/** /**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org> * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../mol-plugin-state/builder/structure/representation-preset'; import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../mol-plugin-state/builder/structure/representation-preset';
import { MembraneOrientationProvider, isTransmembrane } from './membrane-orientation'; import { MembraneOrientationProvider, MembraneOrientation } from './prop';
import { StateObjectRef, StateAction, StateTransformer, StateTransform } from '../../mol-state'; import { StateObjectRef, StateTransformer, StateTransform } from '../../mol-state';
import { Task } from '../../mol-task'; import { Task } from '../../mol-task';
import { PluginBehavior } from '../../mol-plugin/behavior'; import { PluginBehavior } from '../../mol-plugin/behavior';
import { MembraneOrientationRepresentationProvider, MembraneOrientationParams, MembraneOrientationRepresentation } from './representation'; import { MembraneOrientationRepresentationProvider, MembraneOrientationParams, MembraneOrientationRepresentation } from './representation';
...@@ -16,13 +16,18 @@ import { HydrophobicityColorThemeProvider } from '../../mol-theme/color/hydropho ...@@ -16,13 +16,18 @@ import { HydrophobicityColorThemeProvider } from '../../mol-theme/color/hydropho
import { PluginStateObject, PluginStateTransform } from '../../mol-plugin-state/objects'; import { PluginStateObject, PluginStateTransform } from '../../mol-plugin-state/objects';
import { PluginContext } from '../../mol-plugin/context'; import { PluginContext } from '../../mol-plugin/context';
import { DefaultQueryRuntimeTable } from '../../mol-script/runtime/query/compiler'; import { DefaultQueryRuntimeTable } from '../../mol-script/runtime/query/compiler';
import { StructureSelectionQuery, StructureSelectionCategory } from '../../mol-plugin-state/helpers/structure-selection-query';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
import { GenericRepresentationRef } from '../../mol-plugin-state/manager/structure/hierarchy-state';
export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boolean }>({ const Tag = MembraneOrientation.Tag;
name: 'membrane-orientation-prop',
export const ANVILMembraneOrientation = PluginBehavior.create<{ autoAttach: boolean }>({
name: 'anvil-membrane-orientation-prop',
category: 'custom-props', category: 'custom-props',
display: { display: {
name: 'Membrane Orientation', name: 'Membrane Orientation',
description: 'Initialize orientation of membrane layers. Data calculated with ANVIL algorithm.' // TODO add ' or obtained via RCSB PDB' description: 'Data calculated with ANVIL algorithm.'
}, },
ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean }> { ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean }> {
private provider = MembraneOrientationProvider private provider = MembraneOrientationProvider
...@@ -30,12 +35,19 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole ...@@ -30,12 +35,19 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole
register(): void { register(): void {
DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor); DefaultQueryRuntimeTable.addCustomProp(this.provider.descriptor);
this.ctx.state.data.actions.add(InitMembraneOrientation3D);
this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach); this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
this.ctx.representation.structure.registry.add(MembraneOrientationRepresentationProvider); this.ctx.representation.structure.registry.add(MembraneOrientationRepresentationProvider);
this.ctx.query.structure.registry.add(isTransmembrane); this.ctx.query.structure.registry.add(isTransmembrane);
this.ctx.genericRepresentationControls.set(Tag.Representation, selection => {
const refs: GenericRepresentationRef[] = [];
selection.structures.forEach(structure => {
const memRepr = structure.genericRepresentations?.filter(r => r.cell.transform.transformer.id === MembraneOrientation3D.id)[0];
if (memRepr) refs.push(memRepr);
});
return [refs, 'Membrane Orientation'];
});
this.ctx.builders.structure.representation.registerPreset(MembraneOrientationPreset); this.ctx.builders.structure.representation.registerPreset(MembraneOrientationPreset);
} }
...@@ -49,12 +61,12 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole ...@@ -49,12 +61,12 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole
unregister() { unregister() {
DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor); DefaultQueryRuntimeTable.removeCustomProp(this.provider.descriptor);
this.ctx.state.data.actions.remove(InitMembraneOrientation3D);
this.ctx.customStructureProperties.unregister(this.provider.descriptor.name); this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
this.ctx.representation.structure.registry.remove(MembraneOrientationRepresentationProvider); this.ctx.representation.structure.registry.remove(MembraneOrientationRepresentationProvider);
this.ctx.query.structure.registry.remove(isTransmembrane); this.ctx.query.structure.registry.remove(isTransmembrane);
this.ctx.genericRepresentationControls.delete(Tag.Representation);
this.ctx.builders.structure.representation.unregisterPreset(MembraneOrientationPreset); this.ctx.builders.structure.representation.unregisterPreset(MembraneOrientationPreset);
} }
}, },
...@@ -63,25 +75,26 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole ...@@ -63,25 +75,26 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole
}) })
}); });
export const InitMembraneOrientation3D = StateAction.build({ //
display: {
name: 'Membrane Orientation', export const isTransmembrane = StructureSelectionQuery('Residues Embedded in Membrane', MS.struct.modifier.union([
description: 'Initialize Membrane Orientation planes and rims. Data calculated with ANVIL algorithm.' MS.struct.modifier.wholeResidues([
}, MS.struct.modifier.union([
from: PluginStateObject.Molecule.Structure, MS.struct.generator.atomGroups({
isApplicable: (a) => MembraneOrientationProvider.isApplicable(a.data) 'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
})(({ a, ref, state }, plugin: PluginContext) => Task.create('Init Membrane Orientation', async ctx => { 'atom-test': MembraneOrientation.symbols.isTransmembrane.symbol(),
try { })
const propCtx = { runtime: ctx, assetManager: plugin.managers.asset }; ])
await MembraneOrientationProvider.attach(propCtx, a.data); ])
} catch(e) { ]), {
plugin.log.error(`Membrane Orientation: ${e}`); description: 'Select residues that are embedded between the membrane layers.',
return; category: StructureSelectionCategory.Residue,
ensureCustomProperties: (ctx, structure) => {
return MembraneOrientationProvider.attach(ctx, structure);
} }
const tree = state.build().to(ref) });
.applyOrUpdateTagged('membrane-orientation-3d', MembraneOrientation3D);
await state.updateTree(tree).runInContext(ctx); //
}));
export { MembraneOrientation3D }; export { MembraneOrientation3D };
......
/** /**
* Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org> * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { ParamDefinition as PD } from '../../mol-util/param-definition';
import { Structure, StructureProperties, Unit } from '../../mol-model/structure'; import { Structure, StructureProperties, Unit } from '../../mol-model/structure';
import { CustomPropertyDescriptor } from '../../mol-model/custom-property'; import { CustomPropertyDescriptor } from '../../mol-model/custom-property';
import { ANVILParams, ANVILProps, computeANVIL, isInMembranePlane } from './ANVIL'; import { ANVILParams, ANVILProps, computeANVIL, isInMembranePlane } from './algorithm';
import { CustomStructureProperty } from '../../mol-model-props/common/custom-structure-property'; import { CustomStructureProperty } from '../../mol-model-props/common/custom-structure-property';
import { CustomProperty } from '../../mol-model-props/common/custom-property'; import { CustomProperty } from '../../mol-model-props/common/custom-property';
import { AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/accessible-surface-area'; import { AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/accessible-surface-area';
...@@ -16,8 +16,6 @@ import { Vec3 } from '../../mol-math/linear-algebra'; ...@@ -16,8 +16,6 @@ import { Vec3 } from '../../mol-math/linear-algebra';
import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base'; import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base';
import { CustomPropSymbol } from '../../mol-script/language/symbol'; import { CustomPropSymbol } from '../../mol-script/language/symbol';
import Type from '../../mol-script/language/type'; import Type from '../../mol-script/language/type';
import { StructureSelectionQuery, StructureSelectionCategory } from '../../mol-plugin-state/helpers/structure-selection-query';
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
export const MembraneOrientationParams = { export const MembraneOrientationParams = {
...ANVILParams ...ANVILParams
...@@ -25,6 +23,8 @@ export const MembraneOrientationParams = { ...@@ -25,6 +23,8 @@ export const MembraneOrientationParams = {
export type MembraneOrientationParams = typeof MembraneOrientationParams export type MembraneOrientationParams = typeof MembraneOrientationParams
export type MembraneOrientationProps = PD.Values<MembraneOrientationParams> export type MembraneOrientationProps = PD.Values<MembraneOrientationParams>
export { MembraneOrientation };
interface MembraneOrientation { interface MembraneOrientation {
// point in membrane boundary // point in membrane boundary
readonly planePoint1: Vec3, readonly planePoint1: Vec3,
...@@ -37,8 +37,13 @@ interface MembraneOrientation { ...@@ -37,8 +37,13 @@ interface MembraneOrientation {
readonly centroid: Vec3 readonly centroid: Vec3
} }
namespace MembraneOrientation {
export enum Tag {
Representation = 'membrane-orientation-3d'
}
const pos = Vec3(); const pos = Vec3();
export const MembraneOrientationSymbols = { export const symbols = {
isTransmembrane: QuerySymbolRuntime.Dynamic(CustomPropSymbol('computed', 'membrane-orientation.is-transmembrane', Type.Bool), isTransmembrane: QuerySymbolRuntime.Dynamic(CustomPropSymbol('computed', 'membrane-orientation.is-transmembrane', Type.Bool),
ctx => { ctx => {
const { unit, structure } = ctx.element; const { unit, structure } = ctx.element;
...@@ -50,32 +55,14 @@ export const MembraneOrientationSymbols = { ...@@ -50,32 +55,14 @@ export const MembraneOrientationSymbols = {
const { normalVector, planePoint1, planePoint2 } = membraneOrientation!; const { normalVector, planePoint1, planePoint2 } = membraneOrientation!;
return isInMembranePlane(pos, normalVector, planePoint1, planePoint2); return isInMembranePlane(pos, normalVector, planePoint1, planePoint2);
}) })
};
} }
export const isTransmembrane = StructureSelectionQuery('Residues Embedded in Membrane', MS.struct.modifier.union([
MS.struct.modifier.wholeResidues([
MS.struct.modifier.union([
MS.struct.generator.atomGroups({
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
'atom-test': MembraneOrientationSymbols.isTransmembrane.symbol(),
})
])
])
]), {
description: 'Select residues that are embedded between the membrane layers.',
category: StructureSelectionCategory.Residue,
ensureCustomProperties: (ctx, structure) => {
return MembraneOrientationProvider.attach(ctx, structure);
}
});
export { MembraneOrientation };
export const MembraneOrientationProvider: CustomStructureProperty.Provider<MembraneOrientationParams, MembraneOrientation> = CustomStructureProperty.createProvider({ export const MembraneOrientationProvider: CustomStructureProperty.Provider<MembraneOrientationParams, MembraneOrientation> = CustomStructureProperty.createProvider({
label: 'Membrane Orientation', label: 'Membrane Orientation',
descriptor: CustomPropertyDescriptor({ descriptor: CustomPropertyDescriptor({
name: 'molstar_computed_membrane_orientation', name: 'anvil_computed_membrane_orientation',
symbols: MembraneOrientationSymbols, symbols: MembraneOrientation.symbols,
// TODO `cifExport` // TODO `cifExport`
}), }),
type: 'root', type: 'root',
......
/** /**
* Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
* *
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org> * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
...@@ -12,11 +12,10 @@ import { Structure } from '../../mol-model/structure'; ...@@ -12,11 +12,10 @@ import { Structure } from '../../mol-model/structure';
import { Spheres } from '../../mol-geo/geometry/spheres/spheres'; import { Spheres } from '../../mol-geo/geometry/spheres/spheres';
import { SpheresBuilder } from '../../mol-geo/geometry/spheres/spheres-builder'; import { SpheresBuilder } from '../../mol-geo/geometry/spheres/spheres-builder';
import { StructureRepresentationProvider, StructureRepresentation, StructureRepresentationStateBuilder } from '../../mol-repr/structure/representation'; import { StructureRepresentationProvider, StructureRepresentation, StructureRepresentationStateBuilder } from '../../mol-repr/structure/representation';
import { MembraneOrientation } from './membrane-orientation'; import { MembraneOrientation } from './prop';
import { ThemeRegistryContext } from '../../mol-theme/theme'; import { ThemeRegistryContext } from '../../mol-theme/theme';
import { ShapeRepresentation } from '../../mol-repr/shape/representation'; import { ShapeRepresentation } from '../../mol-repr/shape/representation';
import { Shape } from '../../mol-model/shape'; import { Shape } from '../../mol-model/shape';
import { ColorNames } from '../../mol-util/color/names';
import { RuntimeContext } from '../../mol-task'; import { RuntimeContext } from '../../mol-task';
import { Lines } from '../../mol-geo/geometry/lines/lines'; import { Lines } from '../../mol-geo/geometry/lines/lines';
import { Mesh } from '../../mol-geo/geometry/mesh/mesh'; import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
...@@ -24,7 +23,10 @@ import { LinesBuilder } from '../../mol-geo/geometry/lines/lines-builder'; ...@@ -24,7 +23,10 @@ import { LinesBuilder } from '../../mol-geo/geometry/lines/lines-builder';
import { Circle } from '../../mol-geo/primitive/circle'; import { Circle } from '../../mol-geo/primitive/circle';
import { transformPrimitive } from '../../mol-geo/primitive/primitive'; import { transformPrimitive } from '../../mol-geo/primitive/primitive';
import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder'; import { MeshBuilder } from '../../mol-geo/geometry/mesh/mesh-builder';
import { MembraneOrientationProvider } from './membrane-orientation'; import { MembraneOrientationProvider } from './prop';
import { MarkerActions } from '../../mol-util/marker-action';
import { lociLabel } from '../../mol-theme/label';
import { ColorNames } from '../../mol-util/color/names';
const SharedParams = { const SharedParams = {
color: PD.Color(ColorNames.lightgrey), color: PD.Color(ColorNames.lightgrey),
...@@ -32,8 +34,8 @@ const SharedParams = { ...@@ -32,8 +34,8 @@ const SharedParams = {
}; };
const BilayerSpheresParams = { const BilayerSpheresParams = {
...SharedParams,
...Spheres.Params, ...Spheres.Params,
...SharedParams,
sphereSize: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }, { description: 'Size of spheres that represent membrane planes' }), sphereSize: PD.Numeric(1, { min: 0.1, max: 10, step: 0.1 }, { description: 'Size of spheres that represent membrane planes' }),
density: PD.Numeric(1, { min: 0.25, max: 10, step: 0.25 }, { description: 'Distance between spheres'}) density: PD.Numeric(1, { min: 0.25, max: 10, step: 0.25 }, { description: 'Distance between spheres'})
}; };
...@@ -41,27 +43,27 @@ export type BilayerSpheresParams = typeof BilayerSpheresParams ...@@ -41,27 +43,27 @@ export type BilayerSpheresParams = typeof BilayerSpheresParams
export type BilayerSpheresProps = PD.Values<BilayerSpheresParams> export type BilayerSpheresProps = PD.Values<BilayerSpheresParams>
const BilayerPlanesParams = { const BilayerPlanesParams = {
...SharedParams,
...Mesh.Params, ...Mesh.Params,
sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }) ...SharedParams,
sectorOpacity: PD.Numeric(0.5, { min: 0, max: 1, step: 0.01 }),
}; };
export type BilayerPlanesParams = typeof BilayerPlanesParams export type BilayerPlanesParams = typeof BilayerPlanesParams
export type BilayerPlanesProps = PD.Values<BilayerPlanesParams> export type BilayerPlanesProps = PD.Values<BilayerPlanesParams>
const BilayerRimsParams = { const BilayerRimsParams = {
...SharedParams,
...Lines.Params, ...Lines.Params,
...SharedParams,
lineSizeAttenuation: PD.Boolean(true), lineSizeAttenuation: PD.Boolean(true),
linesSize: PD.Numeric(0.5, { min: 0.01, max: 50, step: 0.01 }), linesSize: PD.Numeric(0.3, { min: 0.01, max: 50, step: 0.01 }),
dashedLines: PD.Boolean(true) dashedLines: PD.Boolean(true),
}; };
export type BilayerRimsParams = typeof BilayerRimsParams export type BilayerRimsParams = typeof BilayerRimsParams
export type BilayerRimsProps = PD.Values<BilayerRimsParams> export type BilayerRimsProps = PD.Values<BilayerRimsParams>
const MembraneOrientationVisuals = { const MembraneOrientationVisuals = {
'bilayer-spheres': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerSpheresParams>) => ShapeRepresentation(getBilayerSpheres, Spheres.Utils, { modifyState: s => ({ ...s, pickable: false }) }), 'bilayer-spheres': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerSpheresParams>) => ShapeRepresentation(getBilayerSpheres, Spheres.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) }),
'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyProps: p => ({ ...p, alpha: p.sectorOpacity }), modifyState: s => ({ ...s, pickable: false }) }), 'bilayer-planes': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerPlanesParams>) => ShapeRepresentation(getBilayerPlanes, Mesh.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }), modifyProps: p => ({ ...p, alpha: p.sectorOpacity, ignoreLight: true, doubleSided: false }) }),
'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, pickable: false }) }) 'bilayer-rims': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<MembraneOrientation, BilayerRimsParams>) => ShapeRepresentation(getBilayerRims, Lines.Utils, { modifyState: s => ({ ...s, markerActions: MarkerActions.Highlighting }) })
}; };
export const MembraneOrientationParams = { export const MembraneOrientationParams = {
...@@ -94,16 +96,20 @@ export const MembraneOrientationRepresentationProvider = StructureRepresentation ...@@ -94,16 +96,20 @@ export const MembraneOrientationRepresentationProvider = StructureRepresentation
isApplicable: (structure: Structure) => structure.elementCount > 0 isApplicable: (structure: Structure) => structure.elementCount > 0
}); });
function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps): Shape<Lines> { function membraneLabel(data: Structure) {
return `${lociLabel(Structure.Loci(data))} | Membrane Orientation`;
}
function getBilayerRims(ctx: RuntimeContext, data: Structure, props: BilayerRimsProps, shape?: Shape<Lines>): Shape<Lines> {
const { planePoint1: p1, planePoint2: p2, centroid, normalVector: normal, radius } = MembraneOrientationProvider.get(data).value!; const { planePoint1: p1, planePoint2: p2, centroid, normalVector: normal, radius } = MembraneOrientationProvider.get(data).value!;
const scaledRadius = props.radiusFactor * radius; const scaledRadius = props.radiusFactor * radius;
const builder = LinesBuilder.create(128, 64); const builder = LinesBuilder.create(128, 64, shape?.geometry);
getLayerCircle(builder, p1, centroid, normal, scaledRadius, props); getLayerCircle(builder, p1, centroid, normal, scaledRadius, props);
getLayerCircle(builder, p2, centroid, normal, scaledRadius, props); getLayerCircle(builder, p2, centroid, normal, scaledRadius, props);
return Shape.create(name, data, builder.getLines(), () => props.color, () => props.linesSize, () => ''); return Shape.create(name, data, builder.getLines(), () => props.color, () => props.linesSize, () => membraneLabel(data));
} }
function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, normal: Vec3, radius: number, props: BilayerRimsProps) { function getLayerCircle(builder: LinesBuilder, p: Vec3, centroid: Vec3, normal: Vec3, radius: number, props: BilayerRimsProps, shape?: Shape<Lines>) {
const circle = getCircle(p, centroid, normal, radius); const circle = getCircle(p, centroid, normal, radius);
const { indices, vertices } = circle; const { indices, vertices } = circle;
for (let j = 0, jl = indices.length; j < jl; j += 3) { for (let j = 0, jl = indices.length; j < jl; j += 3) {
...@@ -126,7 +132,7 @@ function getCircle(p: Vec3, centroid: Vec3, normal: Vec3, radius: number) { ...@@ -126,7 +132,7 @@ function getCircle(p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
Mat4.setTranslation(tmpMat, p); Mat4.setTranslation(tmpMat, p);
Mat4.mul(tmpMat, tmpMat, Mat4.rotX90); Mat4.mul(tmpMat, tmpMat, Mat4.rotX90);
const circle = Circle({ radius }); const circle = Circle({ radius, segments: 64 });
return transformPrimitive(circle, tmpMat); return transformPrimitive(circle, tmpMat);
} }
...@@ -136,7 +142,7 @@ function getBilayerPlanes(ctx: RuntimeContext, data: Structure, props: BilayerPl ...@@ -136,7 +142,7 @@ function getBilayerPlanes(ctx: RuntimeContext, data: Structure, props: BilayerPl
const scaledRadius = props.radiusFactor * radius; const scaledRadius = props.radiusFactor * radius;
getLayerPlane(state, p1, centroid, normal, scaledRadius); getLayerPlane(state, p1, centroid, normal, scaledRadius);
getLayerPlane(state, p2, centroid, normal, scaledRadius); getLayerPlane(state, p2, centroid, normal, scaledRadius);
return Shape.create(name, data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => ''); return Shape.create(name, data, MeshBuilder.getMesh(state), () => props.color, () => 1, () => membraneLabel(data));
} }
function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal: Vec3, radius: number) { function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal: Vec3, radius: number) {
...@@ -146,15 +152,15 @@ function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal ...@@ -146,15 +152,15 @@ function getLayerPlane(state: MeshBuilder.State, p: Vec3, centroid: Vec3, normal
MeshBuilder.addPrimitiveFlipped(state, Mat4.id, circle); MeshBuilder.addPrimitiveFlipped(state, Mat4.id, circle);
} }
function getBilayerSpheres(ctx: RuntimeContext, data: Structure, props: BilayerSpheresProps): Shape<Spheres> { function getBilayerSpheres(ctx: RuntimeContext, data: Structure, props: BilayerSpheresProps, shape?: Shape<Spheres>): Shape<Spheres> {
const { density } = props; const { density } = props;
const { radius, planePoint1, planePoint2, normalVector } = MembraneOrientationProvider.get(data).value!; const { radius, planePoint1, planePoint2, normalVector } = MembraneOrientationProvider.get(data).value!;
const scaledRadius = (props.radiusFactor * radius) * (props.radiusFactor * radius); const scaledRadius = (props.radiusFactor * radius) * (props.radiusFactor * radius);
const spheresBuilder = SpheresBuilder.create(); const spheresBuilder = SpheresBuilder.create(256, 128, shape?.geometry);
getLayerSpheres(spheresBuilder, planePoint1, normalVector, density, scaledRadius); getLayerSpheres(spheresBuilder, planePoint1, normalVector, density, scaledRadius);
getLayerSpheres(spheresBuilder, planePoint2, normalVector, density, scaledRadius); getLayerSpheres(spheresBuilder, planePoint2, normalVector, density, scaledRadius);
return Shape.create(name, data, spheresBuilder.getSpheres(), () => props.color, () => props.sphereSize, () => ''); return Shape.create(name, data, spheresBuilder.getSpheres(), () => props.color, () => props.sphereSize, () => membraneLabel(data));
} }
function getLayerSpheres(spheresBuilder: SpheresBuilder, point: Vec3, normalVector: Vec3, density: number, sqRadius: number) { function getLayerSpheres(spheresBuilder: SpheresBuilder, point: Vec3, normalVector: Vec3, density: number, sqRadius: number) {
......
/**
* Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Sebastian Bittrich <sebastian.bittrich@rcsb.org>
*/
import { Structure } from '../../../mol-model/structure';
import { Vec3 } from '../../../mol-math/linear-algebra';
export interface ANVILContext {
structure: Structure,
numberOfSpherePoints: number,
stepSize: number,
minThickness: number,
maxThickness: number,
asaCutoff: number,
offsets: ArrayLike<number>,
exposed: ArrayLike<boolean>,
centroid: Vec3,
extent: number
};
\ No newline at end of file
...@@ -26,8 +26,8 @@ import { InteractionsProvider } from '../../mol-model-props/computed/interaction ...@@ -26,8 +26,8 @@ import { InteractionsProvider } from '../../mol-model-props/computed/interaction
import { SecondaryStructureProvider } from '../../mol-model-props/computed/secondary-structure'; import { SecondaryStructureProvider } from '../../mol-model-props/computed/secondary-structure';
import { SyncRuntimeContext } from '../../mol-task/execution/synchronous'; import { SyncRuntimeContext } from '../../mol-task/execution/synchronous';
import { AssetManager } from '../../mol-util/assets'; import { AssetManager } from '../../mol-util/assets';
import { MembraneOrientationProvider } from '../../extensions/membrane-orientation/membrane-orientation'; import { MembraneOrientationProvider } from '../../extensions/anvil/prop';
import { MembraneOrientationRepresentationProvider } from '../../extensions/membrane-orientation/representation'; import { MembraneOrientationRepresentationProvider } from '../../extensions/anvil/representation';
const parent = document.getElementById('app')!; const parent = document.getElementById('app')!;
parent.style.width = '100%'; parent.style.width = '100%';
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment