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

wip, assembly symmetry

parent dc2b0bf3
No related branches found
No related tags found
No related merge requests found
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ParamDefinition as PD } from 'mol-util/param-definition';
import { RepresentationParamsGetter, RepresentationContext, VisualContext } from 'mol-repr/representation';
import { ThemeRegistryContext, Theme } from 'mol-theme/theme';
import { Structure } from 'mol-model/structure';
import { StructureRepresentationProvider, StructureRepresentation, ComplexRepresentation, ComplexVisual } from 'mol-repr/structure/representation';
import { AssemblySymmetry } from '../assembly-symmetry';
import { Table } from 'mol-data/db';
import { MeshBuilder } from 'mol-geo/geometry/mesh/mesh-builder';
import { Tensor } from 'mol-math/linear-algebra';
import { addSphere } from 'mol-geo/geometry/mesh/builder/sphere';
import { addCylinder } from 'mol-geo/geometry/mesh/builder/cylinder';
import { VisualUpdateState } from 'mol-repr/util';
import { ComplexMeshVisual, ComplexMeshParams } from 'mol-repr/structure/complex-visual';
import { Mesh } from 'mol-geo/geometry/mesh/mesh';
import { EmptyLoci } from 'mol-model/loci';
import { LocationIterator } from 'mol-geo/util/location-iterator';
import { NullLocation } from 'mol-model/location';
export const AssemblySymmetryAxesParams = {
...ComplexMeshParams,
sizeFactor: PD.Numeric(0.4, { min: 0, max: 3, step: 0.01 }),
radialSegments: PD.Numeric(16, { min: 3, max: 56, step: 1 }),
detail: PD.Numeric(0, { min: 0, max: 3, step: 1 }),
symmetryId: PD.Select<number>(-1, []),
}
export type AssemblySymmetryAxesParams = typeof AssemblySymmetryAxesParams
export function getAssemblySymmetryAxesParams(ctx: ThemeRegistryContext, structure: Structure) {
const params = PD.clone(AssemblySymmetryAxesParams)
if (structure.models[0].customProperties.has(AssemblySymmetry.Descriptor)) {
const assemblySymmetry = AssemblySymmetry.get(structure.models[0])!
const assemblyName = structure.assemblyName
const s = assemblySymmetry.db.rcsb_assembly_symmetry
if (s._rowCount) {
params.symmetryId.options = []
for (let i = 0, il = s._rowCount; i < il; ++i) {
if (s.assembly_id.value(i) === assemblyName) {
params.symmetryId.options.push([
s.id.value(i), `${s.symbol.value(i)} ${s.kind.value(i)}`
])
}
}
params.symmetryId.defaultValue = params.symmetryId.options[0][0]
}
}
return params
}
export type AssemblySymmetryAxesRepresentation = StructureRepresentation<AssemblySymmetryAxesParams>
export function AssemblySymmetryAxesRepresentation(ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, AssemblySymmetryAxesParams>): AssemblySymmetryAxesRepresentation {
return ComplexRepresentation('RCSB Assembly Symmetry Axes', ctx, getParams, AssemblySymmetryAxesVisual)
}
export const AssemblySymmetryAxesRepresentationProvider: StructureRepresentationProvider<AssemblySymmetryAxesParams> = {
label: 'RCSB Assembly Symmetry Axes',
description: 'Displays assembly symmetry axes.',
factory: AssemblySymmetryAxesRepresentation,
getParams: getAssemblySymmetryAxesParams,
defaultValues: PD.getDefaultValues(AssemblySymmetryAxesParams),
defaultColorTheme: 'uniform',
defaultSizeTheme: 'uniform'
}
//
export function AssemblySymmetryAxesVisual(): ComplexVisual<AssemblySymmetryAxesParams> {
return ComplexMeshVisual<AssemblySymmetryAxesParams>({
defaultProps: PD.getDefaultValues(AssemblySymmetryAxesParams),
createGeometry: createAssemblySymmetryAxesMesh,
createLocationIterator,
getLoci: () => EmptyLoci,
mark: () => false,
setUpdateState: (state: VisualUpdateState, newProps: PD.Values<AssemblySymmetryAxesParams>, currentProps: PD.Values<AssemblySymmetryAxesParams>) => {
state.createGeometry = (
newProps.sizeFactor !== currentProps.sizeFactor ||
newProps.detail !== currentProps.detail ||
newProps.symmetryId !== currentProps.symmetryId
)
}
})
}
function createLocationIterator(structure: Structure) {
let groupCount = 0
const assemblySymmetry = AssemblySymmetry.get(structure.models[0])
if (assemblySymmetry) {
const axis = assemblySymmetry.db.rcsb_assembly_symmetry_axis
groupCount = axis._rowCount
}
return LocationIterator(groupCount, 1, () => NullLocation)
}
export function createAssemblySymmetryAxesMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<AssemblySymmetryAxesParams>, mesh?: Mesh) {
const { symmetryId, sizeFactor } = props
const assemblySymmetry = AssemblySymmetry.get(structure.models[0])
if (!assemblySymmetry) return Mesh.createEmpty(mesh)
const s = assemblySymmetry.db.rcsb_assembly_symmetry
const symmetry = Table.pickRow(s, i => s.id.value(i) === symmetryId)
if (!symmetry) return Mesh.createEmpty(mesh)
// symmetry.assembly_id not available for structure.assemblyName
if (symmetry.assembly_id !== structure.assemblyName) return Mesh.createEmpty(mesh)
const axes = assemblySymmetry.getAxes(symmetryId)
if (!axes._rowCount) return Mesh.createEmpty(mesh)
const vectorSpace = AssemblySymmetry.Schema.rcsb_assembly_symmetry_axis.start.space;
// const colors: Color[] = []
// const labels: string[] = []
const radius = 1 * sizeFactor
const cylinderProps = { radiusTop: radius, radiusBottom: radius }
const builderState = MeshBuilder.createState(256, 128, mesh)
for (let i = 0, il = axes._rowCount; i < il; ++i) {
const start = Tensor.toVec3(vectorSpace, axes.start.value(i))
const end = Tensor.toVec3(vectorSpace, axes.end.value(i))
builderState.currentGroup = i
addSphere(builderState, start, radius, 2)
addSphere(builderState, end, radius, 2)
addCylinder(builderState, start, end, 1, cylinderProps)
// colors.push(Color(0xCCEE11))
// labels.push(`Axis ${i + 1} for ${symmetry.kind} ${symmetry.type.toLowerCase()} symmetry`)
}
return MeshBuilder.getMesh(builderState)
}
\ No newline at end of file
......@@ -32,7 +32,7 @@ function clusterMemberKey (asym_id: string, oper_list_ids: string[]) {
export const AssemblySymmetryClusterColorThemeParams = {
list: PD.Select<ColorListName>('Viridis', ColorListOptions),
symmetryId: PD.Select<number>(0, []),
symmetryId: PD.Select<number>(-1, []),
}
export type AssemblySymmetryClusterColorThemeParams = typeof AssemblySymmetryClusterColorThemeParams
export function getAssemblySymmetryClusterColorThemeParams(ctx: ThemeDataContext) {
......@@ -51,7 +51,7 @@ export function getAssemblySymmetryClusterColorThemeParams(ctx: ThemeDataContext
])
}
}
params.symmetryId.defaultValue = s.id.value(0)
params.symmetryId.defaultValue = params.symmetryId.options[0][0]
}
}
......
......@@ -8,7 +8,8 @@ import { PluginBehavior } from 'mol-plugin/behavior';
import { ParamDefinition as PD } from 'mol-util/param-definition'
import { AssemblySymmetry } from 'mol-model-props/rcsb/assembly-symmetry';
import { CustomPropertyRegistry } from 'mol-plugin/util/custom-prop-registry';
import { AssemblySymmetryClusterColorThemeProvider } from 'mol-model-props/rcsb/themes/assembly-symmetry';
import { AssemblySymmetryClusterColorThemeProvider } from 'mol-model-props/rcsb/themes/assembly-symmetry-cluster';
import { AssemblySymmetryAxesRepresentationProvider } from 'mol-model-props/rcsb/representations/assembly-symmetry-axes';
export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean }>({
name: 'rcsb-assembly-symmetry-prop',
......@@ -27,9 +28,10 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
register(): void {
this.ctx.customModelProperties.register(this.provider);
// TODO: support filtering of themes based on the input structure
// TODO: support filtering of themes and representations based on the input structure
// in this case, it would check structure.models[0].customProperties.has(AssemblySymmetry.Descriptor)
this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.add('rcsb-assembly-symmetry-cluster', AssemblySymmetryClusterColorThemeProvider)
this.ctx.structureRepresentation.registry.add('rcsb-assembly-symmetry-axes', AssemblySymmetryAxesRepresentationProvider)
}
update(p: { autoAttach: boolean }) {
......@@ -42,6 +44,7 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
unregister() {
this.ctx.customModelProperties.unregister(AssemblySymmetry.Descriptor.name);
this.ctx.structureRepresentation.themeCtx.colorThemeRegistry.remove('rcsb-assembly-symmetry-cluster')
this.ctx.structureRepresentation.registry.remove('rcsb-assembly-symmetry-axes')
}
},
params: () => ({
......
......@@ -43,7 +43,7 @@ export function BallAndStickRepresentation(ctx: RepresentationContext, getParams
return Representation.createMulti('Ball & Stick', ctx, getParams, BallAndStickVisuals as unknown as Representation.Def<Structure, BallAndStickParams>)
}
export const BallAndStickRepresentationProvider: StructureRepresentationProvider<typeof BallAndStickParams> = {
export const BallAndStickRepresentationProvider: StructureRepresentationProvider<BallAndStickParams> = {
label: 'Ball & Stick',
description: 'Displays atoms as spheres and bonds as cylinders.',
factory: BallAndStickRepresentation,
......
......@@ -31,7 +31,7 @@ export function DistanceRestraintRepresentation(ctx: RepresentationContext, getP
return Representation.createMulti('DistanceRestraint', ctx, getParams, DistanceRestraintVisuals as unknown as Representation.Def<Structure, DistanceRestraintParams>)
}
export const DistanceRestraintRepresentationProvider: StructureRepresentationProvider<typeof DistanceRestraintParams> = {
export const DistanceRestraintRepresentationProvider: StructureRepresentationProvider<DistanceRestraintParams> = {
label: 'Distance Restraint',
description: 'Displays cross-link distance restraints.',
factory: DistanceRestraintRepresentation,
......
......@@ -31,7 +31,7 @@ export function SpacefillRepresentation(ctx: RepresentationContext, getParams: R
return Representation.createMulti('Spacefill', ctx, getParams, SpacefillVisuals as unknown as Representation.Def<Structure, SpacefillParams>)
}
export const SpacefillRepresentationProvider: StructureRepresentationProvider<typeof SpacefillParams> = {
export const SpacefillRepresentationProvider: StructureRepresentationProvider<SpacefillParams> = {
label: 'Spacefill',
description: 'Displays atoms as spheres.',
factory: SpacefillRepresentation,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment