diff --git a/src/extensions/membrane-orientation/ANVIL.ts b/src/extensions/membrane-orientation/ANVIL.ts index db0e7250182c725faaef5775df0d13e558c2a63c..db61ee2b8e10cc11c3ba6a5df273aa77ea549a08 100644 --- a/src/extensions/membrane-orientation/ANVIL.ts +++ b/src/extensions/membrane-orientation/ANVIL.ts @@ -14,8 +14,8 @@ import { Vec3 } from '../../mol-math/linear-algebra'; import { getElementMoleculeType } from '../../mol-model/structure/util'; import { MoleculeType } from '../../mol-model/structure/model/types'; import { AccessibleSurfaceArea } from '../../mol-model-props/computed/accessible-surface-area/shrake-rupley'; -import { MembraneOrientation } from '../../mol-model/structure/model/properties/membrane-orientation'; import { ParamDefinition as PD } from '../../mol-util/param-definition'; +import { MembraneOrientation } from './membrane-orientation'; 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.' }), @@ -123,7 +123,13 @@ export async function calculate(runtime: RuntimeContext, structure: Structure, p const membrane = initialMembrane.qmax! > alternativeMembrane.qmax! ? initialMembrane : alternativeMembrane; - return MembraneOrientation(membrane.planePoint1, membrane.planePoint2, membrane.normalVector!, ctx.extent, ctx.centroid); + return { + p1: membrane.planePoint1, + p2: membrane.planePoint2, + normal: membrane.normalVector!, + radius: ctx.extent, + centroid: ctx.centroid + }; } interface MembraneCandidate { diff --git a/src/extensions/membrane-orientation/behavior.ts b/src/extensions/membrane-orientation/behavior.ts index bff75c6b282fbf3de319fb59f132d2438a0e4357..ea097071964839ba4777248bff2ec894acbe3220 100644 --- a/src/extensions/membrane-orientation/behavior.ts +++ b/src/extensions/membrane-orientation/behavior.ts @@ -7,19 +7,11 @@ import { ParamDefinition as PD } from '../../mol-util/param-definition'; import { StructureRepresentationPresetProvider, PresetStructureRepresentations } from '../../mol-plugin-state/builder/structure/representation-preset'; -import { MembraneOrientationProvider } from './membrane-orientation'; +import { MembraneOrientationProvider, MembraneOrientation } from './membrane-orientation'; import { StateObjectRef } from '../../mol-state'; import { Task } from '../../mol-task'; import { PluginBehavior } from '../../mol-plugin/behavior'; -import { StructureSelectionQuery, StructureSelectionCategory } from '../../mol-plugin-state/helpers/structure-selection-query'; -import { MolScriptBuilder as MS } from '../../mol-script/language/builder'; -import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base'; import { MembraneOrientationRepresentationProvider } from './representation'; -import { CustomPropSymbol } from '../../mol-script/language/symbol'; -import Type from '../../mol-script/language/type'; -import { isInMembranePlane } from './ANVIL'; -import { StructureProperties } from '../../mol-model/structure'; -import { Vec3 } from '../../mol-math/linear-algebra'; import { HydrophobicityColorThemeProvider } from '../../mol-theme/color/hydrophobicity'; export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boolean }>({ @@ -38,7 +30,7 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole this.ctx.representation.structure.themes.colorThemeRegistry.add(HydrophobicityColorThemeProvider); this.ctx.representation.structure.registry.add(MembraneOrientationRepresentationProvider); - this.ctx.query.structure.registry.add(isTransmembrane); + this.ctx.query.structure.registry.add(MembraneOrientation.isTransmembrane); this.ctx.builders.structure.representation.registerPreset(MembraneOrientationPreset); } @@ -56,7 +48,7 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole this.ctx.representation.structure.themes.colorThemeRegistry.remove(HydrophobicityColorThemeProvider); this.ctx.representation.structure.registry.remove(MembraneOrientationRepresentationProvider); - this.ctx.query.structure.registry.remove(isTransmembrane); + this.ctx.query.structure.registry.remove(MembraneOrientation.isTransmembrane); this.ctx.builders.structure.representation.unregisterPreset(MembraneOrientationPreset); } @@ -66,36 +58,6 @@ export const MembraneOrientationData = PluginBehavior.create<{ autoAttach: boole }) }); -const pos = Vec3(); -const isTransmembraneSymbol = QuerySymbolRuntime.Dynamic(CustomPropSymbol('membrane-orientation', 'is-transmembrane', Type.Bool), - ctx => { - const structure = ctx.currentStructure; - const { x, y, z } = StructureProperties.atom; - if (!structure.isAtomic) return false; - const membraneOrientation = MembraneOrientationProvider.get(structure).value; - if (!membraneOrientation) return false; - Vec3.set(pos, x(ctx.element), y(ctx.element), z(ctx.element)); - const { normal, p1, p2 } = membraneOrientation!; - return isInMembranePlane(pos, normal, p1, p2); - }); - -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': isTransmembraneSymbol.symbol(), - }) - ]) - ]) -]), { - description: 'Select residues that are embedded between the membrane layers.', - category: StructureSelectionCategory.Residue, - ensureCustomProperties: (ctx, structure) => { - return MembraneOrientationProvider.attach(ctx, structure); - } -}); - export const MembraneOrientationPreset = StructureRepresentationPresetProvider({ id: 'preset-membrane-orientation', display: { diff --git a/src/extensions/membrane-orientation/membrane-orientation.ts b/src/extensions/membrane-orientation/membrane-orientation.ts index 759ebab796ed942fbc1d3bda1fc55d167e50e3c6..3abba9d1ea98e2746905a32b804aec93e3f5500c 100644 --- a/src/extensions/membrane-orientation/membrane-orientation.ts +++ b/src/extensions/membrane-orientation/membrane-orientation.ts @@ -6,13 +6,18 @@ */ import { ParamDefinition as PD } from '../../mol-util/param-definition'; -import { Structure } from '../../mol-model/structure'; +import { Structure, StructureProperties } from '../../mol-model/structure'; import { CustomPropertyDescriptor } from '../../mol-model/custom-property'; -import { ANVILParams, ANVILProps, computeANVIL } from './ANVIL'; -import { MembraneOrientation } from '../../mol-model/structure/model/properties/membrane-orientation'; +import { ANVILParams, ANVILProps, computeANVIL, isInMembranePlane } from './ANVIL'; import { CustomStructureProperty } from '../../mol-model-props/common/custom-structure-property'; import { CustomProperty } from '../../mol-model-props/common/custom-property'; import { AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/accessible-surface-area'; +import { Vec3 } from '../../mol-math/linear-algebra'; +import { QuerySymbolRuntime } from '../../mol-script/runtime/query/base'; +import { CustomPropSymbol } from '../../mol-script/language/symbol'; +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 = { ...ANVILParams @@ -20,10 +25,59 @@ export const MembraneOrientationParams = { export type MembraneOrientationParams = typeof MembraneOrientationParams export type MembraneOrientationProps = PD.Values<MembraneOrientationParams> +interface MembraneOrientation { + // point in membrane boundary + readonly p1: Vec3, + // point in opposite side of membrane boundary + readonly p2: Vec3, + // normal vector of membrane layer + readonly normal: Vec3, + // the radius of the membrane layer + readonly radius: number, + readonly centroid: Vec3 +} + +namespace MembraneOrientation { + const pos = Vec3(); + export const symbols = { + isTransmembrane: QuerySymbolRuntime.Dynamic(CustomPropSymbol('membrane-orientation', 'is-transmembrane', Type.Bool), + ctx => { + const structure = ctx.currentStructure; + const { x, y, z } = StructureProperties.atom; + if (!structure.isAtomic) return false; + const membraneOrientation = MembraneOrientationProvider.get(structure).value; + if (!membraneOrientation) return false; + Vec3.set(pos, x(ctx.element), y(ctx.element), z(ctx.element)); + const { normal, p1, p2 } = membraneOrientation!; + return isInMembranePlane(pos, normal, p1, p2); + }) + }; + + 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': symbols.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({ label: 'Membrane Orientation', descriptor: CustomPropertyDescriptor({ name: 'molstar_computed_membrane_orientation', + symbols: MembraneOrientation.symbols // TODO `cifExport` }), type: 'root', diff --git a/src/extensions/membrane-orientation/representation.ts b/src/extensions/membrane-orientation/representation.ts index 741af39cda27ede2630662c481d8da126e57d76a..76b4cba0cf56ec0546ed92a1d25727f2651a753b 100644 --- a/src/extensions/membrane-orientation/representation.ts +++ b/src/extensions/membrane-orientation/representation.ts @@ -12,7 +12,7 @@ import { Structure } from '../../mol-model/structure'; import { Spheres } from '../../mol-geo/geometry/spheres/spheres'; import { SpheresBuilder } from '../../mol-geo/geometry/spheres/spheres-builder'; import { StructureRepresentationProvider, StructureRepresentation, StructureRepresentationStateBuilder } from '../../mol-repr/structure/representation'; -import { MembraneOrientation } from '../../mol-model/structure/model/properties/membrane-orientation'; +import { MembraneOrientation } from './membrane-orientation'; import { ThemeRegistryContext } from '../../mol-theme/theme'; import { ShapeRepresentation } from '../../mol-repr/shape/representation'; import { Shape } from '../../mol-model/shape'; diff --git a/src/mol-model/structure/model/properties/membrane-orientation.ts b/src/mol-model/structure/model/properties/membrane-orientation.ts deleted file mode 100644 index 72a8d0313820b9978600eef50b6842def2aad510..0000000000000000000000000000000000000000 --- a/src/mol-model/structure/model/properties/membrane-orientation.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. - * - * @author Sebastian Bittrich <sebastian.bittrich@rcsb.org> - */ - -import { Vec3 } from '../../../../mol-math/linear-algebra'; - -interface MembraneOrientation { - // point in membrane boundary - readonly p1: Vec3, - // point in opposite side of membrane boundary - readonly p2: Vec3, - // normal vector of membrane layer - readonly normal: Vec3, - // the radius of the membrane layer - readonly radius: number, - readonly centroid: Vec3 -} - -function MembraneOrientation(p1: Vec3, p2: Vec3, normal: Vec3, radius: number, centroid: Vec3): MembraneOrientation { - return { p1, p2, normal, radius, centroid }; -} - -export { MembraneOrientation }; \ No newline at end of file