Browse Source

mol-state: allow Transformer.Params to accept undefined source StateObject to be able to auto-generate docs

David Sehnal 6 years ago
parent
commit
7fe8234cbd

+ 7 - 0
src/mol-model/volume/data.ts

@@ -21,6 +21,13 @@ interface VolumeData {
 }
 
 namespace VolumeData {
+    export const Empty: VolumeData = {
+        cell: SpacegroupCell.Zero,
+        fractionalBox: Box3D.empty(),
+        data: Tensor.create(Tensor.Space([0, 0, 0], [0, 1, 2]), Tensor.Data1([])),
+        dataStats: { min: 0, max: 0, mean: 0, sigma: 0 }
+    }
+
     const _scale = Mat4.zero(), _translate = Mat4.zero();
     export function getGridToCartesianTransform(volume: VolumeData) {
         const { data: { space } } = volume;

+ 0 - 8
src/mol-plugin/behavior/static/state.ts

@@ -156,13 +156,5 @@ export function Snapshots(ctx: PluginContext) {
         } catch (e) {
             ctx.log.error(`Reading JSON state: ${e}`);
         }
-        // const element = document.createElement('a');
-        // const json = JSON.stringify(ctx.state.getSnapshot(), null, 2);
-        // element.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(json));
-        // element.setAttribute('download', `mol-star_state_${(name || getFormattedTime())}.json`);
-        // element.style.display = 'none';
-        // document.body.appendChild(element);
-        // element.click();
-        // document.body.removeChild(element);
     });
 }

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

@@ -27,6 +27,11 @@ const TrajectoryFromMmCif = PluginStateTransform.BuiltIn({
     from: SO.Format.Cif,
     to: SO.Molecule.Trajectory,
     params(a) {
+        if (!a) {
+            return {
+                blockHeader: PD.makeOptional(PD.Text(void 0, { description: 'Header of the block to parse. If none is specifed, the 1st data block in the file is used.' }))
+            };
+        }
         const { blocks } = a.data;
         return {
             blockHeader: PD.makeOptional(PD.Select(blocks[0] && blocks[0].header, blocks.map(b => [b.header, b.header] as [string, string]), { description: 'Header of the block to parse' }))
@@ -55,7 +60,12 @@ const ModelFromTrajectory = PluginStateTransform.BuiltIn({
     display: { name: 'Model from Trajectory', description: 'Create a molecular structure from the specified model.' },
     from: SO.Molecule.Trajectory,
     to: SO.Molecule.Model,
-    params: a => ({ modelIndex: PD.Converted(plus1, minus1, PD.Numeric(1, { min: 1, max: a.data.length, step: 1 }, { description: 'Model Index' })) })
+    params: a => {
+        if (!a) {
+            return { modelIndex: PD.Numeric(0, {}, { description: 'Zero-based index of the model' }) };
+        }
+        return { modelIndex: PD.Converted(plus1, minus1, PD.Numeric(1, { min: 1, max: a.data.length, step: 1 }, { description: 'Model Index' })) }
+    }
 })({
     isApplicable: a => a.data.length > 0,
     apply({ a, params }) {
@@ -93,6 +103,9 @@ const StructureAssemblyFromModel = PluginStateTransform.BuiltIn({
     from: SO.Molecule.Model,
     to: SO.Molecule.Structure,
     params(a) {
+        if (!a) {
+            return { id: PD.Text('', { label: 'Assembly Id', description: 'Assembly Id. If none specified (undefined or empty string), the asymmetric unit is used.' }) };
+        }
         const model = a.data;
         const ids = model.symmetry.assemblies.map(a => [a.id, `${a.id}: ${stringToWords(a.details)}`] as [string, string]);
         if (!ids.length) ids.push(['deposited', 'Deposited'])
@@ -104,7 +117,7 @@ const StructureAssemblyFromModel = PluginStateTransform.BuiltIn({
             const model = a.data;
             const id = params.id;
             const asm = ModelSymmetry.findAssembly(model, id);
-            if (id !== 'deposited' && !asm) throw new Error(`Assembly '${id}' not found`);
+            if (!!id && id !== 'deposited' && !asm) throw new Error(`Assembly '${id}' not found`);
 
             const base = Structure.ofModel(model);
             if (!asm) {
@@ -179,7 +192,10 @@ const CustomModelProperties = PluginStateTransform.BuiltIn({
     display: { name: 'Custom Model Properties' },
     from: SO.Molecule.Model,
     to: SO.Molecule.Model,
-    params: (a, ctx: PluginContext) => ({ properties: ctx.customModelProperties.getSelect(a.data) })
+    params: (a, ctx: PluginContext) => {
+        if (!a) return { properties: PD.MultiSelect([], [], { description: 'A list of property descriptor ids.' }) };
+        return { properties: ctx.customModelProperties.getSelect(a.data) };
+    }
 })({
     apply({ a, params }, ctx: PluginContext) {
         return Task.create('Custom Props', async taskCtx => {

+ 40 - 0
src/mol-plugin/state/transforms/representation.ts

@@ -56,6 +56,26 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({
     params: (a, ctx: PluginContext) => {
         const { registry, themeCtx } = ctx.structureRepresentation
         const type = registry.get(registry.default.name);
+
+        if (!a) {
+            return {
+                type: PD.Mapped<any>(
+                    registry.default.name,
+                    registry.types,
+                    name => PD.Group<any>(registry.get(name).getParams(themeCtx, Structure.Empty))),
+                colorTheme: PD.Mapped<any>(
+                    type.defaultColorTheme,
+                    themeCtx.colorThemeRegistry.types,
+                    name => PD.Group<any>(themeCtx.colorThemeRegistry.get(name).getParams({ structure: Structure.Empty }))
+                ),
+                sizeTheme: PD.Mapped<any>(
+                    type.defaultSizeTheme,
+                    themeCtx.sizeThemeRegistry.types,
+                    name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams({ structure: Structure.Empty }))
+                )
+            }
+        }
+
         const dataCtx = { structure: a.data }
         return ({
             type: PD.Mapped<any>(
@@ -163,6 +183,26 @@ const VolumeRepresentation3D = PluginStateTransform.BuiltIn({
     params: (a, ctx: PluginContext) => {
         const { registry, themeCtx } = ctx.volumeRepresentation
         const type = registry.get(registry.default.name);
+
+        if (!a) {
+            return {
+                type: PD.Mapped<any>(
+                    registry.default.name,
+                    registry.types,
+                    name => PD.Group<any>(registry.get(name).getParams(themeCtx, VolumeData.Empty ))),
+                colorTheme: PD.Mapped<any>(
+                    type.defaultColorTheme,
+                    themeCtx.colorThemeRegistry.types,
+                    name => PD.Group<any>(themeCtx.colorThemeRegistry.get(name).getParams({ volume: VolumeData.Empty }))
+                ),
+                sizeTheme: PD.Mapped<any>(
+                    type.defaultSizeTheme,
+                    themeCtx.sizeThemeRegistry.types,
+                    name => PD.Group<any>(themeCtx.sizeThemeRegistry.get(name).getParams({ volume: VolumeData.Empty }))
+                )
+            }
+        }
+
         const dataCtx = { volume: a.data }
         return ({
             type: PD.Mapped<any>(

+ 2 - 1
src/mol-state/transformer.ts

@@ -151,7 +151,8 @@ export namespace Transformer {
             name: string,
             from: A | A[],
             to: B | B[],
-            params?: PD.For<P> | ((a: StateObject.From<A>, globalCtx: any) => PD.For<P>),
+            /** The source StateObject can be undefined: used for generating docs. */
+            params?: PD.For<P> | ((a: StateObject.From<A> | undefined, globalCtx: any) => PD.For<P>),
             display?: string | { name: string, description?: string }
         }