Browse Source

wip, assembly-symmetry preset

Alexander Rose 5 years ago
parent
commit
7b931cfb66

+ 9 - 6
src/mol-plugin-state/builder/structure/hierarchy-preset.ts

@@ -2,6 +2,7 @@
  * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import { PresetProvider } from '../preset-provider';
@@ -16,17 +17,19 @@ import { Vec3 } from '../../../mol-math/linear-algebra';
 import { Model } from '../../../mol-model/structure';
 
 export interface TrajectoryHierarchyPresetProvider<P = any, S = {}> extends PresetProvider<PluginStateObject.Molecule.Trajectory, P, S> { }
+export function TrajectoryHierarchyPresetProvider<P, S>(preset: TrajectoryHierarchyPresetProvider<P, S>) { return preset; }
 export namespace TrajectoryHierarchyPresetProvider {
     export type Params<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer T> ? T : never;
     export type State<P extends TrajectoryHierarchyPresetProvider> = P extends TrajectoryHierarchyPresetProvider<infer _, infer S> ? S : never;
+
+    export const CommonParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
+        modelProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomModelProperties, void 0, plugin))),
+        structureProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomStructureProperties, void 0, plugin))),
+        representationPreset: PD.Optional(PD.Text<keyof PresetStructureRepresentations>('auto' as const)),
+    })
 }
-export function TrajectoryHierarchyPresetProvider<P, S>(preset: TrajectoryHierarchyPresetProvider<P, S>) { return preset; }
 
-const CommonParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) => ({
-    modelProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomModelProperties, void 0, plugin))),
-    structureProperties: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.CustomStructureProperties, void 0, plugin))),
-    representationPreset: PD.Optional(PD.Text<keyof PresetStructureRepresentations>('auto' as const)),
-})
+const CommonParams = TrajectoryHierarchyPresetProvider.CommonParams
 
 const FirstModelParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) =>  ({
     model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),

+ 6 - 0
src/mol-plugin-state/builder/structure/hierarchy.ts

@@ -14,6 +14,7 @@ import { objectForEach } from '../../../mol-util/object';
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { PluginStateObject } from '../../objects';
 import { PresetTrajectoryHierarchy, TrajectoryHierarchyPresetProvider } from './hierarchy-preset';
+import { arrayRemoveInPlace } from '../../../mol-util/array';
 
 // TODO factor out code shared with StructureRepresentationBuilder?
 
@@ -80,6 +81,11 @@ export class TrajectoryHierarchyBuilder {
         this.providerMap.set(provider.id, provider);
     }
 
+    unregisterPreset(provider: TrajectoryHierarchyPresetProvider) {
+        this.providerMap.delete(provider.id)
+        arrayRemoveInPlace(this._providers, provider)
+    }
+
     applyPreset<K extends keyof PresetTrajectoryHierarchy>(parent: StateObjectRef<PluginStateObject.Molecule.Trajectory>, preset: K, params?: Partial<TrajectoryHierarchyPresetProvider.Params<PresetTrajectoryHierarchy[K]>>): Promise<TrajectoryHierarchyPresetProvider.State<PresetTrajectoryHierarchy[K]>> | undefined
     applyPreset<P = any, S = {}>(parent: StateObjectRef<PluginStateObject.Molecule.Trajectory>, provider: TrajectoryHierarchyPresetProvider<P, S>, params?: P): Promise<S> | undefined
     applyPreset(parent: StateObjectRef, providerRef: string | TrajectoryHierarchyPresetProvider, params?: any): Promise<any> | undefined {

+ 6 - 0
src/mol-plugin-state/builder/structure/representation.ts

@@ -15,6 +15,7 @@ import { createStructureRepresentationParams, StructureRepresentationBuiltInProp
 import { PluginStateObject } from '../../objects';
 import { StructureRepresentation3D } from '../../transforms/representation';
 import { PresetStructureRepresentations, StructureRepresentationPresetProvider } from './representation-preset';
+import { arrayRemoveInPlace } from '../../../mol-util/array';
 
 // TODO factor out code shared with TrajectoryHierarchyBuilder?
 
@@ -82,6 +83,11 @@ export class StructureRepresentationBuilder {
         this.providerMap.set(provider.id, provider);
     }
 
+    unregisterPreset(provider: StructureRepresentationPresetProvider) {
+        this.providerMap.delete(provider.id)
+        arrayRemoveInPlace(this._providers, provider)
+    }
+
     applyPreset<K extends keyof PresetStructureRepresentations>(parent: StateObjectRef<PluginStateObject.Molecule.Structure>, preset: K, params?: StructureRepresentationPresetProvider.Params<PresetStructureRepresentations[K]>): Promise<StructureRepresentationPresetProvider.State<PresetStructureRepresentations[K]>> | undefined
     applyPreset<P = any, S = {}>(parent: StateObjectRef<PluginStateObject.Molecule.Structure>, provider: StructureRepresentationPresetProvider<P, S>, params?: P): Promise<S> | undefined
     applyPreset(parent: StateObjectRef<PluginStateObject.Molecule.Structure>, providerId: string, params?: any): Promise<any> | undefined

+ 55 - 16
src/mol-plugin/behavior/dynamic/custom-props/rcsb/assembly-symmetry.ts

@@ -12,8 +12,11 @@ import { AssemblySymmetryClusterColorThemeProvider } from '../../../../../mol-mo
 import { PluginStateTransform, PluginStateObject } from '../../../../../mol-plugin-state/objects';
 import { Task } from '../../../../../mol-task';
 import { PluginContext } from '../../../../context';
-import { StateTransformer, StateAction, StateObject } from '../../../../../mol-state';
+import { StateTransformer, StateAction, StateObject, StateTransform, StateObjectRef } from '../../../../../mol-state';
 import { GenericRepresentationRef } from '../../../../../mol-plugin-state/manager/structure/hierarchy-state';
+import { TrajectoryHierarchyPresetProvider } from '../../../../../mol-plugin-state/builder/structure/hierarchy-preset';
+import { RootStructureDefinition } from '../../../../../mol-plugin-state/helpers/root-structure';
+import { StateTransforms } from '../../../../../mol-plugin-state/transforms';
 
 const Tag = AssemblySymmetry.Tag
 
@@ -40,20 +43,7 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
                 })
                 return [refs, 'Symmetries']
             })
-
-            // TODO this should probably be done via a hierarchy preset
-            this.subscribeObservable(this.ctx.managers.structure.hierarchy.behaviors.selection, selection => {
-                for (const structure of selection.structures) {
-                    const symmRepr = structure.genericRepresentations?.filter(r => r.cell.transform.transformer.id === AssemblySymmetry3D.id)[0]
-
-                    if (!symmRepr) {
-                        const state = this.ctx.state.data;
-                        const symmReprBuilder = state.build().to(structure.cell.transform.ref)
-                            .apply(AssemblySymmetry3D, { symmetryIndex: 0 }, { state: {} });
-                        this.ctx.updateDataState(symmReprBuilder, { revertOnError: true });
-                    }
-                }
-            })
+            this.ctx.builders.structure.hierarchy.registerPreset(assemblySymmetryPreset)
         }
 
         update(p: { autoAttach: boolean }) {
@@ -67,7 +57,9 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
             this.ctx.state.data.actions.remove(InitAssemblySymmetry3D)
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
             this.ctx.representation.structure.themes.colorThemeRegistry.remove(AssemblySymmetryClusterColorThemeProvider)
+
             this.ctx.customSourceControls.delete(Tag.Representation)
+            this.ctx.builders.structure.hierarchy.unregisterPreset(assemblySymmetryPreset)
         }
     },
     params: () => ({
@@ -148,4 +140,51 @@ const AssemblySymmetry3D = PluginStateTransform.BuiltIn({
     isApplicable(a) {
         return AssemblySymmetry.isApplicable(a.data)
     }
-});
+});
+
+//
+
+const AssemblySymmetryPresetParams = (a: PluginStateObject.Molecule.Trajectory | undefined, plugin: PluginContext) =>  ({
+    model: PD.Optional(PD.Group(StateTransformer.getParamDefinition(StateTransforms.Model.ModelFromTrajectory, a, plugin))),
+    showUnitcell: PD.Optional(PD.Boolean(false)),
+    structure: PD.Optional(RootStructureDefinition.getParams(void 0, 'assembly').type),
+    ...TrajectoryHierarchyPresetProvider.CommonParams(a, plugin)
+});
+
+const assemblySymmetryPreset = TrajectoryHierarchyPresetProvider({
+    id: 'preset-trajectory-rcsb-assembly-symmetry',
+    display: { name: 'Assembly Symmetry', group: 'Preset' },
+    isApplicable: o => {
+        return true
+    },
+    params: AssemblySymmetryPresetParams,
+    async apply(trajectory, params, plugin) {
+        const builder = plugin.builders.structure;
+
+        const model = await builder.createModel(trajectory, params.model);
+        const modelProperties = await builder.insertModelProperties(model, params.modelProperties);
+
+        const structure = await builder.createStructure(modelProperties || model, params.structure);
+        const structureProperties = await builder.insertStructureProperties(structure, params.structureProperties);
+
+        await tryCreateAssemblySymmetry(plugin, structureProperties)
+
+        const representation =  await plugin.builders.structure.representation.applyPreset(structureProperties, params.representationPreset || 'auto', { globalThemeName: Tag.Cluster });
+
+        return {
+            model,
+            modelProperties,
+            structure,
+            structureProperties,
+            representation
+        };
+    }
+});
+
+async function tryCreateAssemblySymmetry(plugin: PluginContext, structure: StateObjectRef<PluginStateObject.Molecule.Structure>, params?: StateTransformer.Params<AssemblySymmetry3D>, initialState?: Partial<StateTransform.State>) {
+    const state = plugin.state.data;
+    const assemblySymmetry = state.build().to(structure)
+        .apply(AssemblySymmetry3D, { ...params, symmetryIndex: params?.symmetryIndex ?? 0 }, { state: initialState });
+    await plugin.updateDataState(assemblySymmetry, { revertOnError: true });
+    return assemblySymmetry.selector
+}