Browse Source

refactoring and tweaks

David Sehnal 5 years ago
parent
commit
428187ad81

+ 4 - 0
src/mol-model/structure/structure/element/bundle.ts

@@ -40,6 +40,10 @@ export namespace Bundle {
         return fromLoci(StructureSelection.toLociWithSourceUnits(StructureSelection.Singletons(parent, structure)))
     }
 
+    export function fromSelection(selection: StructureSelection) {
+        return fromLoci(StructureSelection.toLociWithSourceUnits(selection));
+    }
+
     export function fromLoci(loci: Loci): Bundle {
         const _elements: {
             unit: Unit

+ 11 - 50
src/mol-plugin-state/actions/structure.ts

@@ -5,22 +5,19 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Loci } from '../../mol-model/loci';
-import { StructureElement } from '../../mol-model/structure';
 import { PluginContext } from '../../mol-plugin/context';
 import { StateAction, StateBuilder, StateSelection, StateTransformer } from '../../mol-state';
 import { Task } from '../../mol-task';
-import { UUID } from '../../mol-util';
 import { FileInfo } from '../../mol-util/file-info';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
+import { TrajectoryFormat } from '../builder/structure';
+import { BuildInTrajectoryFormat } from '../formats/trajectory';
 import { RootStructureDefinition } from '../helpers/root-structure';
 import { PluginStateObject } from '../objects';
 import { StateTransforms } from '../transforms';
 import { Download, ParsePsf } from '../transforms/data';
 import { CoordinatesFromDcd, CustomModelProperties, CustomStructureProperties, TopologyFromPsf, TrajectoryFromModelAndCoordinates } from '../transforms/model';
 import { DataFormatProvider, guessCifVariant } from './data-format';
-import { TrajectoryFormat } from '../builder/structure';
-import { BuildInTrajectoryFormat } from '../formats/trajectory';
 
 export const MmcifProvider: DataFormatProvider<PluginStateObject.Data.String | PluginStateObject.Data.Binary> = {
     label: 'mmCIF',
@@ -37,7 +34,7 @@ export const MmcifProvider: DataFormatProvider<PluginStateObject.Data.String | P
         return Task.create('mmCIF default builder', async taskCtx => {
             const { structure } = await ctx.builders.structure.parseStructure({ data, dataFormat: 'mmcif' });
             if (options.visuals) {
-                await ctx.builders.structure.representation.structurePreset(structure, 'auto');
+                await ctx.builders.structure.representation.applyPreset(structure, 'auto');
             }
         })
     }
@@ -55,7 +52,7 @@ export const PdbProvider: DataFormatProvider<any> = {
         return Task.create('PDB default builder', async () => {
             const { structure } = await ctx.builders.structure.parseStructure({ data, dataFormat: 'pdb' });
             if (options.visuals) {
-                await ctx.builders.structure.representation.structurePreset(structure, 'auto');
+                await ctx.builders.structure.representation.applyPreset(structure, 'auto');
             }
         })
     }
@@ -73,7 +70,7 @@ export const GroProvider: DataFormatProvider<any> = {
         return Task.create('GRO default builder', async () => {
             const { structure } = await ctx.builders.structure.parseStructure({ data, dataFormat: 'gro' });
             if (options.visuals) {
-                await ctx.builders.structure.representation.structurePreset(structure, 'auto');
+                await ctx.builders.structure.representation.applyPreset(structure, 'auto');
             }
         })
     }
@@ -91,7 +88,7 @@ export const Provider3dg: DataFormatProvider<any> = {
         return Task.create('3DG default builder', async () => {
             const { structure } = await ctx.builders.structure.parseStructure({ data, dataFormat: '3dg' });
             if (options.visuals) {
-                await ctx.builders.structure.representation.structurePreset(structure, 'auto');
+                await ctx.builders.structure.representation.applyPreset(structure, 'auto');
             }
         })
     }
@@ -249,7 +246,7 @@ const DownloadStructure = StateAction.build({
                 structureProperties: supportProps
             });
             if (createRepr) {
-                await plugin.builders.structure.representation.structurePreset(structure, 'auto');
+                await plugin.builders.structure.representation.applyPreset(structure, 'auto');
             }
         } else {
             for (const download of downloadParams) {
@@ -261,7 +258,7 @@ const DownloadStructure = StateAction.build({
                     structureProperties: supportProps
                 });
                 if (createRepr) {
-                    await plugin.builders.structure.representation.structurePreset(structure, 'auto');
+                    await plugin.builders.structure.representation.applyPreset(structure, 'auto');
                 }
             }
         }
@@ -306,25 +303,11 @@ export const Create3DRepresentationPreset = StateAction.build({
     isApplicable(a, _, plugin: PluginContext) { return plugin.builders.structure.representation.hasPreset(a.data); },
     params(a, plugin: PluginContext) {
         return {
-            type: plugin.builders.structure.representation.getPresets(a.data)
+            type: plugin.builders.structure.representation.getPresetsWithOptions(a.data)
         };
     }
 })(({ ref, params }, plugin: PluginContext) => {
-    plugin.builders.structure.representation.structurePreset(ref, params.type.name, params.type.params);
-});
-
-export const Remove3DRepresentationPreset = StateAction.build({
-    display: { name: 'Remove 3D Representation Preset', description: 'Remove 3D representations.' },
-    from: PluginStateObject.Molecule.Structure,
-    isApplicable(_, t, plugin: PluginContext) { return plugin.builders.structure.representation.hasPresetRepresentation(t.ref); },
-    params(a, plugin: PluginContext) {
-        return {
-            type: plugin.builders.structure.representation.getPresets(a.data).select
-        };
-    }
-})(({ ref, params }, plugin: PluginContext) => {
-    // TODO: this will be completely handled by the managed and is just for testing purposes
-    plugin.builders.structure.representation.removePreset(params.type, ref);
+    return plugin.builders.structure.representation.applyPreset(ref, params.type.name, params.type.params);
 });
 
 export const UpdateTrajectory = StateAction.build({
@@ -389,28 +372,6 @@ export const TransformStructureConformation = StateAction.build({
     return state.updateTree(root);
 });
 
-export const StructureFromSelection = StateAction.build({
-    display: { name: 'Structure from Current Selection', description: 'Create a new Structure from the current selection.' },
-    from: PluginStateObject.Molecule.Structure,
-    params: {
-        label: PD.Text()
-    }
-    // isApplicable(a, t, ctx: PluginContext) {
-    //     return t.transformer !== CustomModelProperties;
-    // }
-})(async ({ a, ref, params, state }, plugin: PluginContext) => {
-    const sel = plugin.managers.structure.selection.getLoci(a.data);
-    if (Loci.isEmpty(sel)) return;
-
-    const bundle = StructureElement.Bundle.fromLoci(sel);
-
-    await plugin.builders.structure.tryCreateComponent(ref, {
-        type: { name: 'bundle', params: bundle },
-        nullIfEmpty: true,
-        label: params.label
-    }, UUID.create22());
-});
-
 export const AddTrajectory = StateAction.build({
     display: { name: 'Add Trajectory', description: 'Add trajectory from existing model/topology and coordinates.' },
     from: PluginStateObject.Root,
@@ -440,6 +401,6 @@ export const AddTrajectory = StateAction.build({
 
         await state.updateTree(model).runInContext(taskCtx);
         const structure = await ctx.builders.structure.createStructure(model.selector);
-        await ctx.builders.structure.representation.structurePreset(structure, 'auto');
+        await ctx.builders.structure.representation.applyPreset(structure, 'auto');
     }).runInContext(taskCtx)
 }));

+ 4 - 1
src/mol-plugin-state/builder/structure.ts

@@ -14,6 +14,7 @@ import { BuildInTrajectoryFormat, TrajectoryFormatProvider } from '../formats/tr
 import { StructureRepresentationBuilder } from './structure/representation';
 import { StructureSelectionQuery } from '../helpers/structure-selection-query';
 import { Task } from '../../mol-task';
+import { StructureElement } from '../../mol-model/structure';
 
 export type TrajectoryFormat = 'pdb' | 'cif' | 'gro' | '3dg'
 
@@ -172,7 +173,9 @@ export class StructureBuilder {
     
             const transformParams: StructureComponentParams = query.referencesCurrent
                 ? {
-                    type: { name: 'bundle', params: await StructureSelectionQuery.getBundle(this.plugin, taskCtx, query, structureData) },
+                    type: {
+                        name: 'bundle',
+                        params: StructureElement.Bundle.fromSelection(await query.getSelection(this.plugin, taskCtx, structureData)) },
                     nullIfEmpty: true,
                     label: label || query.label
                 } : {

+ 22 - 66
src/mol-plugin-state/builder/structure/representation.ts

@@ -4,11 +4,10 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { UniqueArray } from '../../../mol-data/generic';
 import { arrayFind } from '../../../mol-data/util';
 import { Structure } from '../../../mol-model/structure';
 import { PluginContext } from '../../../mol-plugin/context';
-import { StateBuilder, StateObjectRef, StateObjectSelector, StateSelection, StateTransform, StateTree } from '../../../mol-state';
+import { StateBuilder, StateObjectRef, StateObjectSelector } from '../../../mol-state';
 import { Task } from '../../../mol-task';
 import { isProductionMode } from '../../../mol-util/debug';
 import { objectForEach } from '../../../mol-util/object';
@@ -22,7 +21,7 @@ import { RepresentationProviderTags, StructureRepresentationProvider } from './p
 export type StructureRepresentationProviderRef = keyof PresetStructureReprentations | StructureRepresentationProvider | string
 
 export class StructureRepresentationBuilder {
-    private providers: StructureRepresentationProvider[] = [];
+    private _providers: StructureRepresentationProvider[] = [];
     private providerMap: Map<string, StructureRepresentationProvider> = new Map();
     private get dataState() { return this.plugin.state.dataState; }
 
@@ -30,23 +29,33 @@ export class StructureRepresentationBuilder {
 
     private resolveProvider(ref: StructureRepresentationProviderRef) {
         return typeof ref === 'string'
-            ? PresetStructureReprentations[ref as keyof PresetStructureReprentations] ?? arrayFind(this.providers, p => p.id === ref)
+            ? PresetStructureReprentations[ref as keyof PresetStructureReprentations] ?? arrayFind(this._providers, p => p.id === ref)
             : ref;
     }
 
     hasPreset(s: Structure) {
-        for (const p of this.providers) {
+        for (const p of this._providers) {
             if (!p.isApplicable || p.isApplicable(s, this.plugin)) return true;
         }
         return false;
     }
 
-    get providerList(): ReadonlyArray<StructureRepresentationProvider> { return this.providers; }
+    get providers(): ReadonlyArray<StructureRepresentationProvider> { return this._providers; }
 
-    getPresets(s: Structure) {
+    getPresets(s?: Structure) {
+        if (!s) return this.providers;
+        const ret = [];
+        for (const p of this._providers) {
+            if (p.isApplicable && !p.isApplicable(s, this.plugin)) continue;
+            ret.push(p);
+        }
+        return ret;
+    }
+
+    getPresetsWithOptions(s: Structure) {
         const options: [string, string][] = [];
         const map: { [K in string]: PD.Any } = Object.create(null);
-        for (const p of this.providers) {
+        for (const p of this._providers) {
             if (p.isApplicable && !p.isApplicable(s, this.plugin)) continue;
 
             options.push([p.id, p.display.name]);
@@ -56,71 +65,18 @@ export class StructureRepresentationBuilder {
         return PD.MappedStatic(options[0][0], map, { options });
     }
 
-    hasPresetRepresentation(ref: StateObjectRef) {
-        // TODO: make this state selection function?
-        const tree = this.plugin.state.dataState.tree;
-        const root = StateObjectRef.resolve(this.plugin.state.dataState, ref);
-        if (!root) return false;
-        return StateTree.doPreOrder(tree, root.transform,  { found: false, map: this.providerMap }, (n, _, s) => {
-            if (!n.tags) return;
-            for (const t of n.tags) {
-                if (s.map.has(t)) {
-                    s.found = true;
-                    return false;
-                }
-            }
-        }).found;
-    }
-
-    getPresetRepresentations(ref: StateObjectRef) {
-        const tree = this.plugin.state.dataState.tree;
-        const root = StateObjectRef.resolve(this.plugin.state.dataState, ref);
-        if (!root) return [];
-        return StateTree.doPreOrder(tree, root.transform, { found: UniqueArray.create<string, StructureRepresentationProvider>(), map: this.providerMap }, (n, _, s) => {
-            if (!n.tags) return;
-            for (const t of n.tags) {
-                if (s.map.has(t)) UniqueArray.add(s.found, t, s.map.get(t)!);
-            }
-        }).found.array;
-    }
-
     registerPreset(provider: StructureRepresentationProvider) {
         if (this.providerMap.has(provider.id)) {
             throw new Error(`Repr. provider with id '${provider.id}' already registered.`);
         }
-        // TODO: sort by group
-        this.providers.push(provider);
+        this._providers.push(provider);
         this.providerMap.set(provider.id, provider);
     }
 
-    removePreset(providerRef: StructureRepresentationProviderRef, structureRoot?: StateObjectRef) {
-        const id = this.resolveProvider(providerRef)?.id;
-        if (!id) return;
-
-        const state = this.plugin.state.dataState;
-        const root = StateObjectRef.resolveRef(structureRoot) || StateTransform.RootRef;
-        const reprs = StateSelection.findWithAllTags(state.tree, root, new Set([id, RepresentationProviderTags.Representation]));
-
-        const builder = state.build();
-        for (const r of reprs) {
-            builder.delete(r.ref);
-        }
-
-        const tree = builder.currentTree;
-        const selections = StateSelection.findWithAllTags(tree, root, new Set([RepresentationProviderTags.Component]));
-
-        for (const s of selections) {
-            if (!tree.children.has(s.ref) || tree.children.get(s.ref).size === 0) builder.delete(s.ref);
-        }
-
-        if (builder.editInfo.count === 0) return;
-        return this.plugin.runTask(state.updateTree(builder));
-    }
-
-    structurePreset<K extends keyof PresetStructureReprentations>(parent: StateObjectRef, preset: K, params?: StructureRepresentationProvider.Params<PresetStructureReprentations[K]>): Promise<StructureRepresentationProvider.State<PresetStructureReprentations[K]>> | undefined
-    structurePreset<P = any, S = {}>(parent: StateObjectRef, providers: StructureRepresentationProvider<P, S>, params?: P): Promise<S> | undefined
-    structurePreset(parent: StateObjectRef, providerId: string, params?: any): Promise<any> | undefined
-    structurePreset(parent: StateObjectRef, providerRef: string | StructureRepresentationProvider, params?: any): Promise<any> | undefined {
+    applyPreset<K extends keyof PresetStructureReprentations>(parent: StateObjectRef, preset: K, params?: StructureRepresentationProvider.Params<PresetStructureReprentations[K]>): Promise<StructureRepresentationProvider.State<PresetStructureReprentations[K]>> | undefined
+    applyPreset<P = any, S = {}>(parent: StateObjectRef, providers: StructureRepresentationProvider<P, S>, params?: P): Promise<S> | undefined
+    applyPreset(parent: StateObjectRef, providerId: string, params?: any): Promise<any> | undefined
+    applyPreset(parent: StateObjectRef, providerRef: string | StructureRepresentationProvider, params?: any): Promise<any> | undefined {
         const provider = this.resolveProvider(providerRef);
         if (!provider) return;
 

+ 38 - 29
src/mol-plugin-state/helpers/structure-selection-query.ts

@@ -8,10 +8,9 @@
 import { CustomProperty } from '../../mol-model-props/common/custom-property';
 import { AccessibleSurfaceAreaProvider, AccessibleSurfaceAreaSymbols } from '../../mol-model-props/computed/accessible-surface-area';
 import { ValidationReport, ValidationReportProvider } from '../../mol-model-props/rcsb/validation-report';
-import { QueryContext, Structure, StructureQuery, StructureSelection, StructureElement } from '../../mol-model/structure';
+import { QueryContext, Structure, StructureQuery, StructureSelection } from '../../mol-model/structure';
 import { BondType, NucleicBackboneAtoms, ProteinBackboneAtoms, SecondaryStructureType } from '../../mol-model/structure/model/types';
-import { PluginStateObject } from '../objects';
-import { StateTransforms } from '../transforms';
+import { PluginContext } from '../../mol-plugin/context';
 import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
 import Expression from '../../mol-script/language/expression';
 import { compile } from '../../mol-script/runtime/query/compiler';
@@ -19,7 +18,8 @@ import { StateBuilder } from '../../mol-state';
 import { RuntimeContext } from '../../mol-task';
 import { SetUtils } from '../../mol-util/set';
 import { stringToWords } from '../../mol-util/string';
-import { PluginContext } from '../../mol-plugin/context';
+import { PluginStateObject } from '../objects';
+import { StateTransforms } from '../transforms';
 
 export enum StructureSelectionCategory {
     Type = 'Type',
@@ -46,6 +46,7 @@ interface StructureSelectionQuery {
     readonly referencesCurrent: boolean
     readonly query: StructureQuery
     readonly ensureCustomProperties?: (ctx: CustomProperty.Context, structure: Structure) => Promise<void>
+    getSelection(plugin: PluginContext, runtime: RuntimeContext, structure: Structure): Promise<StructureSelection>
 }
 
 interface StructureSelectionQueryProps {
@@ -69,7 +70,16 @@ function StructureSelectionQuery(label: string, expression: Expression, props: S
             if (!_query) _query = compile<StructureSelection>(expression)
             return _query
         },
-        ensureCustomProperties: props.ensureCustomProperties
+        ensureCustomProperties: props.ensureCustomProperties,
+        async getSelection(plugin, runtime, structure) {
+            const current = plugin.managers.structure.selection.getStructure(structure)
+            const currentSelection = current ? StructureSelection.Singletons(structure, current) : StructureSelection.Empty(structure);
+            if (props.ensureCustomProperties) {
+                await props.ensureCustomProperties({ fetch: plugin.fetch, runtime }, structure)
+            }
+            if (!_query) _query = compile<StructureSelection>(expression)    
+            return _query(new QueryContext(structure, { currentSelection }));
+        }
     }
 }
 
@@ -510,33 +520,32 @@ export function applyBuiltInSelection(to: StateBuilder.To<PluginStateObject.Mole
         { tags: customTag ? [query, customTag] : [query] });
 }
 
-namespace StructureSelectionQuery {
-    export async function getStructure(plugin: PluginContext, runtime: RuntimeContext, selectionQuery: StructureSelectionQuery, structure: Structure) {
-        const current = plugin.managers.structure.selection.getStructure(structure)
-        const currentSelection = current ? StructureSelection.Singletons(structure, current) : StructureSelection.Empty(structure);
+// namespace StructureSelectionQuery {
+//     // export async function getStructure(plugin: PluginContext, runtime: RuntimeContext, selectionQuery: StructureSelectionQuery, structure: Structure) {
+//     //     const current = plugin.managers.structure.selection.getStructure(structure)
+//     //     const currentSelection = current ? StructureSelection.Singletons(structure, current) : StructureSelection.Empty(structure);
 
-        if (selectionQuery.ensureCustomProperties) {
-            await selectionQuery.ensureCustomProperties({ fetch: plugin.fetch, runtime }, structure)
-        }
+//     //     if (selectionQuery.ensureCustomProperties) {
+//     //         await selectionQuery.ensureCustomProperties({ fetch: plugin.fetch, runtime }, structure)
+//     //     }
 
-        const result = selectionQuery.query(new QueryContext(structure, { currentSelection }))
-        return StructureSelection.unionStructure(result)
-    }
+//     //     const result = selectionQuery.query(new QueryContext(structure, { currentSelection }))
+//     //     return StructureSelection.unionStructure(result)
+//     // }
 
-    export async function getLoci(plugin: PluginContext, runtime: RuntimeContext, selectionQuery: StructureSelectionQuery, structure: Structure) {
-        const current = plugin.managers.structure.selection.getStructure(structure)
-        const currentSelection = current ? StructureSelection.Singletons(structure, current) : StructureSelection.Empty(structure);
+//     // export async function getSelection(plugin: PluginContext, runtime: RuntimeContext, selectionQuery: StructureSelectionQuery, structure: Structure) {
+//     //     const current = plugin.managers.structure.selection.getStructure(structure)
+//     //     const currentSelection = current ? StructureSelection.Singletons(structure, current) : StructureSelection.Empty(structure);
 
-        if (selectionQuery.ensureCustomProperties) {
-            await selectionQuery.ensureCustomProperties({ fetch: plugin.fetch, runtime }, structure)
-        }
+//     //     if (selectionQuery.ensureCustomProperties) {
+//     //         await selectionQuery.ensureCustomProperties({ fetch: plugin.fetch, runtime }, structure)
+//     //     }
 
-        const result = selectionQuery.query(new QueryContext(structure, { currentSelection }))
-        return StructureSelection.toLociWithSourceUnits(result)
-    }
+//     //     return selectionQuery.query(new QueryContext(structure, { currentSelection }));
+//     // }
 
-    export async function getBundle(plugin: PluginContext, runtime: RuntimeContext, selectionQuery: StructureSelectionQuery, structure: Structure) {
-        const loci = await getLoci(plugin, runtime, selectionQuery, structure);
-        return StructureElement.Bundle.fromLoci(loci);
-    }
-}
+//     // export async function getBundle(plugin: PluginContext, runtime: RuntimeContext, selectionQuery: StructureSelectionQuery, structure: Structure) {
+//     //     const loci = await getLoci(plugin, runtime, selectionQuery, structure);
+//     //     return StructureElement.Bundle.fromLoci(loci);
+//     // }
+// }

+ 1 - 3
src/mol-plugin-state/manager/structure/component.ts

@@ -31,8 +31,6 @@ interface StructureComponentManagerState {
     options: StructureComponentManager.Options
 }
 
-// TODO: add/update representation in all selected components
-
 class StructureComponentManager extends PluginComponent<StructureComponentManagerState> {
     readonly events = {
         optionsUpdated: this.ev<undefined>()
@@ -113,7 +111,7 @@ class StructureComponentManager extends PluginComponent<StructureComponentManage
         return this.plugin.dataTransaction(async () => {
             await this.clearComponents(structures);
             for (const s of structures) {
-                await this.plugin.builders.structure.representation.structurePreset(s.cell, provider, params);
+                await this.plugin.builders.structure.representation.applyPreset(s.cell, provider, params);
             }
         });
     }

+ 1 - 1
src/mol-plugin-state/manager/structure/hierarchy.ts

@@ -129,7 +129,7 @@ export class StructureHierarchyManager extends PluginComponent<StructureHierarch
             for (let i = 0; i < tr.length; i++) {
                 const model = await this.plugin.builders.structure.createModel(trajectory.cell, { modelIndex: i }, { isCollapsed: true });
                 const structure = await this.plugin.builders.structure.createStructure(model, { name: 'deposited', params: { } });
-                await this.plugin.builders.structure.representation.structurePreset(structure, 'auto', { globalThemeName: 'model-index' });
+                await this.plugin.builders.structure.representation.applyPreset(structure, 'auto', { globalThemeName: 'model-index' });
             }
         })
     }

+ 4 - 4
src/mol-plugin-state/manager/structure/selection.ts

@@ -10,7 +10,7 @@ import { BoundaryHelper } from '../../../mol-math/geometry/boundary-helper';
 import { Vec3 } from '../../../mol-math/linear-algebra';
 import { PrincipalAxes } from '../../../mol-math/linear-algebra/matrix/principal-axes';
 import { EmptyLoci, Loci } from '../../../mol-model/loci';
-import { Structure, StructureElement } from '../../../mol-model/structure';
+import { Structure, StructureElement, StructureSelection } from '../../../mol-model/structure';
 import { Boundary } from '../../../mol-model/structure/structure/util/boundary';
 import { PluginContext } from '../../../mol-plugin/context';
 import { StateObject } from '../../../mol-state';
@@ -362,11 +362,11 @@ export class StructureSelectionManager extends PluginComponent<StructureSelectio
         this.triggerInteraction(modifier, loci, applyGranularity);
     }
 
-    fromSelectionQuery(modifier: StructureSelectionModifier, selectionQuery: StructureSelectionQuery, applyGranularity = true) {
+    fromSelectionQuery(modifier: StructureSelectionModifier, query: StructureSelectionQuery, applyGranularity = true) {
         this.plugin.runTask(Task.create('Structure Selection', async runtime => {
             for (const s of this.applicableStructures) {
-                const loci = await StructureSelectionQuery.getLoci(this.plugin, runtime, selectionQuery, s);
-                this.triggerInteraction(modifier, loci, applyGranularity);
+                const loci = await query.getSelection(this.plugin, runtime, s);
+                this.triggerInteraction(modifier, StructureSelection.toLociWithSourceUnits(loci), applyGranularity);
             }
         }))
     }

+ 3 - 2
src/mol-plugin-ui/structure/components.tsx

@@ -84,8 +84,9 @@ class ComponentEditorControls extends PurePluginUIComponent<{}, ComponentEditorC
         const actions = [
             ActionMenu.Item('Clear', null),
         ];
-        // TODO: filter by applicable??
-        for (const p of this.plugin.builders.structure.representation.providerList) {
+        const pivot = this.plugin.managers.structure.component.pivotStructure;
+        const providers = this.plugin.builders.structure.representation.getPresets(pivot?.cell.obj?.data)
+        for (const p of providers) {
             actions.push(ActionMenu.Item(p.display.name, p));
         }
         return actions;

+ 0 - 3
src/mol-plugin/index.ts

@@ -27,7 +27,6 @@ export const DefaultPluginSpec: PluginSpec = {
         PluginSpec.Action(StateActions.Volume.DownloadDensity),
         PluginSpec.Action(StateActions.DataFormat.OpenFiles),
         PluginSpec.Action(StateActions.Structure.Create3DRepresentationPreset),
-        PluginSpec.Action(StateActions.Structure.Remove3DRepresentationPreset),
         PluginSpec.Action(StateActions.Structure.EnableModelCustomProps),
         PluginSpec.Action(StateActions.Structure.EnableStructureCustomProps),
 
@@ -62,8 +61,6 @@ export const DefaultPluginSpec: PluginSpec = {
 
         PluginSpec.Action(StateTransforms.Volume.VolumeFromCcp4),
         PluginSpec.Action(StateTransforms.Representation.VolumeRepresentation3D),
-
-        PluginSpec.Action(StateActions.Structure.StructureFromSelection),
     ],
     behaviors: [
         PluginSpec.Behavior(PluginBehaviors.Representation.HighlightLoci),