ソースを参照

mol-plugin: Transform and Action tweaks

David Sehnal 5 年 前
コミット
18befade7f

+ 39 - 19
src/mol-plugin/state/actions/structure.ts

@@ -33,7 +33,7 @@ export const MmcifProvider: DataFormatProvider<any> = {
     getDefaultBuilder: (ctx: PluginContext, data: StateBuilder.To<PluginStateObject.Data.Binary | PluginStateObject.Data.String>, options: DataFormatBuilderOptions, state: State) => {
         return Task.create('mmCIF default builder', async taskCtx => {
             const traj = createModelTree(data, 'cif');
-            await state.updateTree(options.visuals ? createStructureTree(ctx, traj, false) : traj).runInContext(taskCtx)
+            await state.updateTree(options.visuals ? createStructureAndVisuals(ctx, traj, false) : traj).runInContext(taskCtx)
         })
     }
 }
@@ -49,7 +49,7 @@ export const PdbProvider: DataFormatProvider<any> = {
     getDefaultBuilder: (ctx: PluginContext, data: StateBuilder.To<PluginStateObject.Data.String>, options: DataFormatBuilderOptions, state: State) => {
         return Task.create('PDB default builder', async taskCtx => {
             const traj = createModelTree(data, 'pdb');
-            await state.updateTree(options.visuals ? createStructureTree(ctx, traj, false) : traj).runInContext(taskCtx)
+            await state.updateTree(options.visuals ? createStructureAndVisuals(ctx, traj, false) : traj).runInContext(taskCtx)
         })
     }
 }
@@ -65,7 +65,7 @@ export const GroProvider: DataFormatProvider<any> = {
     getDefaultBuilder: (ctx: PluginContext, data: StateBuilder.To<PluginStateObject.Data.String>, options: DataFormatBuilderOptions, state: State) => {
         return Task.create('GRO default builder', async taskCtx => {
             const traj = createModelTree(data, 'gro');
-            await state.updateTree(options.visuals ? createStructureTree(ctx, traj, false) : traj).runInContext(taskCtx)
+            await state.updateTree(options.visuals ? createStructureAndVisuals(ctx, traj, false) : traj).runInContext(taskCtx)
         })
     }
 }
@@ -81,7 +81,7 @@ export const Provider3dg: DataFormatProvider<any> = {
     getDefaultBuilder: (ctx: PluginContext, data: StateBuilder.To<PluginStateObject.Data.String>, options: DataFormatBuilderOptions, state: State) => {
         return Task.create('3DG default builder', async taskCtx => {
             const traj = createModelTree(data, '3dg');
-            await state.updateTree(options.visuals ? createStructureTree(ctx, traj, false) : traj).runInContext(taskCtx)
+            await state.updateTree(options.visuals ? createStructureAndVisuals(ctx, traj, false) : traj).runInContext(taskCtx)
         })
     }
 }
@@ -90,15 +90,16 @@ type StructureFormat = 'pdb' | 'cif' | 'gro' | '3dg'
 
 //
 
-const DownloadModelRepresentationOptions = ModelStructureRepresentation.getParams(void 0, 'assembly').type;
+const DownloadModelRepresentationOptions = PD.Group({
+    type: ModelStructureRepresentation.getParams(void 0, 'assembly').type,
+    noRepresentation: PD.Optional(PD.Boolean(false, { description: 'Omit creating default representation.' }))
+}, { isExpanded: false });
 
 const DownloadStructurePdbIdSourceOptions = PD.Group({
-    structure: DownloadModelRepresentationOptions,
     supportProps: PD.Optional(PD.Boolean(false)),
     asTrajectory: PD.Optional(PD.Boolean(false, { description: 'Load all entries into a single trajectory.' }))
 });
 
-
 export { DownloadStructure };
 type DownloadStructure = typeof DownloadStructure
 const DownloadStructure = StateAction.build({
@@ -108,31 +109,37 @@ const DownloadStructure = StateAction.build({
         source: PD.MappedStatic('bcif-static', {
             'pdbe-updated': PD.Group({
                 id: PD.Text('1cbs', { label: 'PDB Id(s)', description: 'One or more comma separated PDB ids.' }),
+                structure: DownloadModelRepresentationOptions,
                 options: DownloadStructurePdbIdSourceOptions
             }, { isFlat: true }),
             'rcsb': PD.Group({
                 id: PD.Text('1tqn', { label: 'PDB Id(s)', description: 'One or more comma separated PDB ids.' }),
+                structure: DownloadModelRepresentationOptions,
                 options: DownloadStructurePdbIdSourceOptions
             }, { isFlat: true }),
             'pdb-dev': PD.Group({
                 id: PD.Text('PDBDEV_00000001', { label: 'PDBDev Id(s)', description: 'One or more comma separated ids.' }),
+                structure: DownloadModelRepresentationOptions,
                 options: DownloadStructurePdbIdSourceOptions
             }, { isFlat: true }),
             'bcif-static': PD.Group({
                 id: PD.Text('1tqn', { label: 'PDB Id(s)', description: 'One or more comma separated PDB ids.' }),
+                structure: DownloadModelRepresentationOptions,
                 options: DownloadStructurePdbIdSourceOptions
             }, { isFlat: true }),
             'swissmodel': PD.Group({
                 id: PD.Text('Q9Y2I8', { label: 'UniProtKB AC(s)', description: 'One or more comma separated ACs.' }),
+                structure: DownloadModelRepresentationOptions,
                 options: DownloadStructurePdbIdSourceOptions
             }, { isFlat: true, description: 'Loads the best homology model or experimental structure' }),
             'url': PD.Group({
                 url: PD.Text(''),
                 format: PD.Select('cif', [['cif', 'CIF'], ['pdb', 'PDB']] as ['cif' | 'pdb', string][]),
                 isBinary: PD.Boolean(false),
+                structure: DownloadModelRepresentationOptions,
                 options: PD.Group({
-                    structure: DownloadModelRepresentationOptions,
-                    supportProps: PD.Optional(PD.Boolean(false))
+                    supportProps: PD.Optional(PD.Boolean(false)),
+                    createRepresentation: PD.Optional(PD.Boolean(true))
                 })
             }, { isFlat: true })
         }, {
@@ -146,7 +153,7 @@ const DownloadStructure = StateAction.build({
                 ]
             })
     }
-})(({ params, state }, ctx: PluginContext) => {
+})(({ params, state }, plugin: PluginContext) => Task.create('Download Structure', async ctx => {
     const b = state.build();
     const src = params.source;
     let downloadParams: StateTransformer.Params<Download>[];
@@ -194,18 +201,28 @@ const DownloadStructure = StateAction.build({
         default: throw new Error(`${(src as any).name} not supported.`);
     }
 
+    const createRepr = !params.source.params.structure.noRepresentation;
+
     if (downloadParams.length > 0 && asTrajectory) {
         const traj = createSingleTrajectoryModel(downloadParams, b);
-        createStructureTree(ctx, traj, supportProps, src.params.options.structure);
+        const struct = createStructure(traj, supportProps, src.params.structure.type);
+        await state.updateTree(struct, { revertIfAborted: true }).runInContext(ctx);
+        if (createRepr) {
+            await plugin.structureRepresentation.manager.apply(struct.ref, plugin.structureRepresentation.manager.defaultProvider);
+        }
     } else {
         for (const download of downloadParams) {
             const data = b.toRoot().apply(StateTransforms.Data.Download, download, { state: { isGhost: true } });
             const traj = createModelTree(data, format);
-            createStructureTree(ctx, traj, supportProps, src.params.options.structure)
+
+            const struct = createStructure(traj, supportProps, src.params.structure.type);
+            await state.updateTree(struct, { revertIfAborted: true }).runInContext(ctx);
+            if (createRepr) {
+                await plugin.structureRepresentation.manager.apply(struct.ref, plugin.structureRepresentation.manager.defaultProvider);
+            }
         }
     }
-    return state.updateTree(b, { revertIfAborted: true });
-});
+}));
 
 function getDownloadParams(src: string, url: (id: string) => string, label: (id: string) => string, isBinary: boolean): StateTransformer.Params<Download>[] {
     const ids = src.split(',').map(id => id.trim()).filter(id => !!id && (id.length >= 4 || /^[1-9][0-9]*$/.test(id)));
@@ -251,15 +268,18 @@ export function createModelTree(b: StateBuilder.To<PluginStateObject.Data.Binary
     return parsed.apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: 0 });
 }
 
-function createStructureTree(ctx: PluginContext, b: StateBuilder.To<PluginStateObject.Molecule.Model>, supportProps: boolean, params?: ModelStructureRepresentation.Params) {
+function createStructure(b: StateBuilder.To<PluginStateObject.Molecule.Model>, supportProps: boolean, params?: ModelStructureRepresentation.Params) {
     let root = b;
     if (supportProps) {
         root = root.apply(StateTransforms.Model.CustomModelProperties);
     }
-    const structure = root.apply(StateTransforms.Model.StructureFromModel, { type: params || { name: 'assembly', params: { } } });
-    createDefaultStructureComplex(ctx, structure);
+    return root.apply(StateTransforms.Model.StructureFromModel, { type: params || { name: 'assembly', params: { } } });
+}
 
-    return root;
+function createStructureAndVisuals(ctx: PluginContext, b: StateBuilder.To<PluginStateObject.Molecule.Model>, supportProps: boolean, params?: ModelStructureRepresentation.Params) {
+    const structure = createStructure(b, supportProps, params);
+    createDefaultStructureComplex(ctx, structure);
+    return b;
 }
 
 export const Create3DRepresentationPreset = StateAction.build({
@@ -346,7 +366,7 @@ export const TransformStructureConformation = StateAction.build({
 });
 
 export const StructureFromSelection = StateAction.build({
-    display: { name: 'Selection Structure', description: 'Create a new Structure from the current selection.' },
+    display: { name: 'Structure from Current Selection', description: 'Create a new Structure from the current selection.' },
     from: PluginStateObject.Molecule.Structure,
     params: {
         label: PD.Text()

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

@@ -18,6 +18,8 @@ import { StructureRepresentationProvider } from './structure/providers';
 export class StructureRepresentationManager {
     private providers: StructureRepresentationProvider[] = [];
 
+    readonly defaultProvider = PresetStructureReprentations.default;
+
     hasProvider(s: Structure) {
         for (const p of this.providers) {
             if (!p.isApplicable || p.isApplicable(s, this.plugin)) return true;

+ 3 - 3
src/mol-plugin/state/transforms/model.ts

@@ -308,7 +308,7 @@ const TransformStructureConformationByMatrix = PluginStateTransform.BuiltIn({
 type StructureSelectionFromExpression = typeof StructureSelectionFromExpression
 const StructureSelectionFromExpression = PluginStateTransform.BuiltIn({
     name: 'structure-selection-from-expression',
-    display: { name: 'Structure Selection', description: 'Create a molecular structure from the specified expression.' },
+    display: { name: 'Selection', description: 'Create a molecular structure from the specified expression.' },
     from: SO.Molecule.Structure,
     to: SO.Molecule.Structure,
     params: {
@@ -469,7 +469,7 @@ const MultiStructureSelectionFromExpression = PluginStateTransform.BuiltIn({
 type StructureSelectionFromScript = typeof StructureSelectionFromScript
 const StructureSelectionFromScript = PluginStateTransform.BuiltIn({
     name: 'structure-selection-from-script',
-    display: { name: 'Structure Selection', description: 'Create a molecular structure from the specified script.' },
+    display: { name: 'Selection', description: 'Create a molecular structure from the specified script.' },
     from: SO.Molecule.Structure,
     to: SO.Molecule.Structure,
     params: {
@@ -505,7 +505,7 @@ const StructureSelectionFromScript = PluginStateTransform.BuiltIn({
 type StructureSelectionFromBundle = typeof StructureSelectionFromBundle
 const StructureSelectionFromBundle = PluginStateTransform.BuiltIn({
     name: 'structure-selection-from-bundle',
-    display: { name: 'Structure Selection', description: 'Create a molecular structure from the specified structure-element bundle.' },
+    display: { name: 'Selection', description: 'Create a molecular structure from the specified structure-element bundle.' },
     from: SO.Molecule.Structure,
     to: SO.Molecule.Structure,
     params: {

+ 1 - 1
src/mol-plugin/state/transforms/representation.ts

@@ -705,7 +705,7 @@ export { StructureOrientation3D }
 type StructureOrientation3D = typeof StructureOrientation3D
 const StructureOrientation3D = PluginStateTransform.BuiltIn({
     name: 'structure-orientation-3d',
-    display: 'Structure Orientation',
+    display: '3D Orientation Box',
     from: SO.Molecule.Structure,
     to: SO.Shape.Representation3D,
     params: {