Browse Source

mol-plugin: multi-source obtain structure, param definition tweaks

David Sehnal 6 years ago
parent
commit
678f788748

+ 2 - 2
src/mol-plugin/index.ts

@@ -10,7 +10,7 @@ import * as React from 'react';
 import * as ReactDOM from 'react-dom';
 import { PluginCommands } from './command';
 import { PluginSpec } from './spec';
-import { CreateStructureFromPDBe } from './state/actions/basic';
+import { ObtainAtomicStructure } from './state/actions/basic';
 import { StateTransforms } from './state/transforms';
 import { PluginBehaviors } from './behavior';
 import { LogEntry } from 'mol-util/log-entry';
@@ -22,7 +22,7 @@ function getParam(name: string, regex: string): string {
 
 const DefaultSpec: PluginSpec = {
     actions: [
-        PluginSpec.Action(CreateStructureFromPDBe),
+        PluginSpec.Action(ObtainAtomicStructure),
         PluginSpec.Action(StateTransforms.Data.Download),
         PluginSpec.Action(StateTransforms.Data.ParseCif),
         PluginSpec.Action(StateTransforms.Model.StructureAssemblyFromModel),

+ 0 - 1
src/mol-plugin/state.ts

@@ -12,7 +12,6 @@ import { CameraSnapshotManager } from './state/camera';
 import { PluginStateSnapshotManager } from './state/snapshots';
 import { RxEventHelper } from 'mol-util/rx-event-helper';
 import { Canvas3DParams } from 'mol-canvas3d/canvas3d';
-import { ParamDefinition } from 'mol-util/param-definition';
 import { PluginCommands } from './command';
 export { PluginState }
 

+ 45 - 6
src/mol-plugin/state/actions/basic.ts

@@ -11,16 +11,53 @@ import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { StateSelection } from 'mol-state/state/selection';
 import { CartoonParams } from 'mol-repr/structure/representation/cartoon';
 import { BallAndStickParams } from 'mol-repr/structure/representation/ball-and-stick';
+import { Download } from '../transforms/data';
 
-export const CreateStructureFromPDBe = StateAction.create<PluginStateObject.Root, void, { id: string }>({
+export { ObtainAtomicStructure }
+namespace ObtainAtomicStructure {
+    export type Sources = 'pdbe-updated' | 'rcsb' | 'bcif-static' | 'url' | 'file'
+    export type Source = ObtainStructureHelpers.MapParams<Sources, typeof ObtainStructureHelpers.ControlMap>
+    export interface Params {
+        source: Source
+    }
+}
+namespace ObtainStructureHelpers {
+    export const SourceOptions: [ObtainAtomicStructure.Sources, string][] = [
+        ['pdbe-updated', 'PDBe Updated'],
+        ['rcsb', 'RCSB'],
+        ['bcif-static', 'BinaryCIF (static PDBe Updated)'],
+        ['url', 'URL'],
+        // ['file', 'File']
+    ];
+    export const ControlMap = {
+        'pdbe-updated': PD.Text('1cbs', { label: 'Id' }),
+        'rcsb': PD.Text('1tqn', { label: 'Id' }),
+        'bcif-static': PD.Text('1tqn', { label: 'Id' }),
+        'url': PD.Group({ url: PD.Text(''), isBinary: PD.Boolean(false) }),
+        'file': PD.Group({ })
+    }
+    export function getControls(key: string) { return (ControlMap as any)[key]; }
+
+    export type MapParams<P extends ObtainAtomicStructure.Sources, Map extends { [K in P]: PD.Any }> = P extends ObtainAtomicStructure.Sources ? PD.NamedParams<Map[P]['defaultValue'], P> : never
+
+    export function getUrl(src: ObtainAtomicStructure.Source): Download.Params {
+        switch (src.name) {
+            case 'url': return src.params;
+            case 'pdbe-updated': return { url: `https://www.ebi.ac.uk/pdbe/static/entry/${src.params.toLowerCase()}_updated.cif`, isBinary: false, label: `PDBe: ${src.params}` };
+            case 'rcsb': return { url: `https://files.rcsb.org/download/${src.params.toUpperCase()}.cif`, isBinary: false, label: `RCSB: ${src.params}` };
+            case 'bcif-static': return { url: `https://webchem.ncbr.muni.cz/ModelServer/static/bcif/${src.params.toLowerCase()}`, isBinary: true, label: `BinaryCIF: ${src.params}` };
+            default: throw new Error(`${src.name} not supported.`);
+        }
+    }
+}
+const ObtainAtomicStructure = StateAction.create<PluginStateObject.Root, void, ObtainAtomicStructure.Params>({
     from: [PluginStateObject.Root],
     display: {
-        name: 'Entry from PDBe',
-        description: 'Download a structure from PDBe and create its default Assembly and visual'
+        name: 'Obtain Structure',
+        description: 'Load a structure from PDBe and create its default Assembly and visual'
     },
-    params: () => ({ id: PD.Text('1grm', { label: 'PDB id' }) }),
+    params: () => ({ source: PD.Mapped('bcif-static', ObtainStructureHelpers.SourceOptions, ObtainStructureHelpers.getControls) }),
     apply({ params, state }) {
-        const url = `http://www.ebi.ac.uk/pdbe/static/entry/${params.id.toLowerCase()}_updated.cif`;
         const b = state.build();
 
         // const query = MolScriptBuilder.struct.generator.atomGroups({
@@ -34,8 +71,10 @@ export const CreateStructureFromPDBe = StateAction.create<PluginStateObject.Root
         //     ])
         // });
 
+        const url = ObtainStructureHelpers.getUrl(params.source);
+
         const root = b.toRoot()
-            .apply(StateTransforms.Data.Download, { url })
+            .apply(StateTransforms.Data.Download, url)
             .apply(StateTransforms.Data.ParseCif)
             .apply(StateTransforms.Model.TrajectoryFromMmCif, {})
             .apply(StateTransforms.Model.ModelFromTrajectory, { modelIndex: 0 })

+ 5 - 8
src/mol-plugin/ui/controls/parameters.tsx

@@ -226,19 +226,17 @@ export class MultiSelectControl extends React.PureComponent<ParamProps<PD.MultiS
 export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>, { isExpanded: boolean }> {
     state = { isExpanded: false }
 
-    change(value: PD.Mapped<any>['defaultValue'] ) {
+    change(value: any ) {
         this.props.onChange({ name: this.props.name, param: this.props.param, value });
     }
 
     onChangeParam: ParamOnChange = e => {
-        const value: PD.Mapped<any>['defaultValue'] = this.props.value;
-        this.change({ ...value.params, [e.name]: e.value });
+        this.change({ ...this.props.value, [e.name]: e.value });
     }
 
     toggleExpanded = () => this.setState({ isExpanded: !this.state.isExpanded });
 
     render() {
-        const value: PD.Mapped<any>['defaultValue'] = this.props.value;
         const params = this.props.param.params;
         const label = this.props.param.label || camelCaseToWords(this.props.name);
 
@@ -250,7 +248,7 @@ export class GroupControl extends React.PureComponent<ParamProps<PD.Group<any>>,
                 </button>
             </div>
             {this.state.isExpanded && <div className='msp-control-offset' style={{ display: this.state.isExpanded ? 'block' : 'none' }}>
-                <ParameterControls params={params} onChange={this.onChangeParam} values={value.params} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} />
+                <ParameterControls params={params} onChange={this.onChangeParam} values={this.props.value} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} />
             </div>
             }
         </div>
@@ -268,8 +266,7 @@ export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any>
     }
 
     onChangeParam: ParamOnChange = e => {
-        const value: PD.Mapped<any>['defaultValue'] = this.props.value;
-        this.change({ name: value.name, params: e.value });
+        this.change({ name: this.props.value.name, params: e.value });
     }
 
     render() {
@@ -288,7 +285,7 @@ export class MappedControl extends React.PureComponent<ParamProps<PD.Mapped<any>
 
         return <div>
             {select}
-            <Mapped param={param} value={value} name={`${label} Properties`} onChange={this.onChangeParam} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} />
+            <Mapped param={param} value={value.params} name={`${label} Properties`} onChange={this.onChangeParam} onEnter={this.props.onEnter} isDisabled={this.props.isDisabled} />
         </div>
     }
 }

+ 1 - 1
src/mol-util/param-definition.ts

@@ -132,7 +132,7 @@ export namespace ParamDefinition {
         return setInfo<Group<Values<P>>>({ type: 'group', defaultValue: getDefaultValues(params) as any, params }, info);
     }
 
-    export interface NamedParams<T = any> { name: string, params: T }
+    export interface NamedParams<T = any, K = string> { name: K, params: T }
     export interface Mapped<T> extends Base<NamedParams<T>> {
         type: 'mapped',
         select: Select<string>,