Ver Fonte

added Script namespace with helpers

Alexander Rose há 5 anos atrás
pai
commit
8b76c09559

+ 1 - 1
src/apps/state-docs/pd-to-md.ts

@@ -30,7 +30,7 @@ function paramInfo(param: PD.Any, offset: number): string {
         case 'line-graph': return `A list of 2d vectors [xi, yi][]`;
         case 'object-list': return `Array of\n${paramInfo(PD.Group(param.element), offset + 2)}`;
         // TODO: support more languages
-        case 'script-expression': return `An expression in the specified language { language: 'mol-script', expressiong: string }`;
+        case 'script': return `An expression in the specified language { language: 'mol-script', expressiong: string }`;
         default:
             const _: never = param;
             console.warn(`${_} has no associated UI component`);

+ 1 - 1
src/mol-model/structure/structure/element/loci.ts

@@ -289,7 +289,7 @@ export namespace Loci {
             : element
     }
 
-    export function toScriptExpression(loci: Loci) {
+    export function toExpression(loci: Loci) {
         if (Loci.isEmpty(loci)) return MS.struct.generator.empty();
 
         const models = loci.structure.models;

+ 1 - 1
src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts

@@ -146,7 +146,7 @@ export class StructureRepresentationInteractionBehavior extends PluginBehavior.W
             lastLoci = current;
 
             const core = MS.struct.modifier.wholeResidues([
-                StructureElement.Loci.toScriptExpression(current.loci)
+                StructureElement.Loci.toExpression(current.loci)
             ]);
 
             const surroundings = MS.struct.modifier.includeSurroundings({

+ 1 - 1
src/mol-plugin/state/actions/structure.ts

@@ -355,7 +355,7 @@ export const StructureFromSelection = StateAction.build({
     const sel = plugin.helpers.structureSelectionManager.get(a.data);
     if (sel.kind === 'empty-loci') return Task.constant('', void 0);
 
-    const expression = StructureElement.Loci.toScriptExpression(sel);
+    const expression = StructureElement.Loci.toExpression(sel);
     const root = state.build().to(ref).apply(StructureSelectionFromExpression, { expression, label: params.label });
     return state.updateTree(root);
 });

+ 7 - 11
src/mol-plugin/state/transforms/model.ts

@@ -22,11 +22,10 @@ import { stringToWords } from '../../../mol-util/string';
 import { PluginStateObject as SO, PluginStateTransform } from '../objects';
 import { trajectoryFromGRO } from '../../../mol-model-formats/structure/gro';
 import { parseGRO } from '../../../mol-io/reader/gro/parser';
-import { parseMolScript } from '../../../mol-script/language/parser';
-import { transpileMolScript } from '../../../mol-script/script/mol-script/symbols';
 import { shapeFromPly } from '../../../mol-model-formats/shape/ply';
 import { SymmetryOperator } from '../../../mol-math/geometry';
 import { ensureSecondaryStructure } from './helpers';
+import { Script } from '../../../mol-script/script';
 
 export { TrajectoryFromBlob };
 export { TrajectoryFromMmCif };
@@ -390,25 +389,22 @@ const StructureSelectionFromScript = PluginStateTransform.BuiltIn({
     from: SO.Molecule.Structure,
     to: SO.Molecule.Structure,
     params: {
-        script: PD.ScriptExpression({ language: 'mol-script', expression: '(sel.atom.atom-groups :residue-test (= atom.resname ALA))' }),
+        script: PD.Script({ language: 'mol-script', expression: '(sel.atom.atom-groups :residue-test (= atom.resname ALA))' }),
         label: PD.Optional(PD.Text(''))
     }
 })({
     apply({ a, params, cache }) {
-        const parsed = parseMolScript(params.script.expression);
-        if (parsed.length === 0) throw new Error('No query');
-        const query = transpileMolScript(parsed[0]);
-        const compiled = compile<Sel>(query);
-        (cache as { compiled: QueryFn<Sel> }).compiled = compiled;
+        const query = Script.toQuery(params.script);
+        (cache as { query: QueryFn<Sel> }).query = query;
         (cache as { source: Structure }).source = a.data;
-        const result = compiled(new QueryContext(a.data));
+        const result = query(new QueryContext(a.data));
         const s = Sel.unionStructure(result);
 
         const props = { label: `${params.label || 'Selection'}`, description: structureDesc(s) };
         return new SO.Molecule.Structure(s, props);
     },
     update: ({ a, b, oldParams, newParams, cache }) => {
-        if (oldParams.script.language !== newParams.script.language || oldParams.script.expression !== newParams.script.expression) {
+        if (Script.areEqual(oldParams.script, newParams.script)) {
             return StateTransformer.UpdateResult.Recreate;
         }
 
@@ -417,7 +413,7 @@ const StructureSelectionFromScript = PluginStateTransform.BuiltIn({
         }
         (cache as { source: Structure }).source = a.data;
 
-        updateStructureFromQuery((cache as { compiled: QueryFn<Sel> }).compiled, a.data, b, newParams.label);
+        updateStructureFromQuery((cache as { query: QueryFn<Sel> }).query, a.data, b, newParams.label);
         return StateTransformer.UpdateResult.Updated;
     }
 });

+ 2 - 2
src/mol-plugin/ui/controls/parameters.tsx

@@ -64,7 +64,7 @@ function controlFor(param: PD.Any): ParamControl | undefined {
         case 'group': return GroupControl;
         case 'mapped': return MappedControl;
         case 'line-graph': return LineGraphControl;
-        case 'script-expression': return ScriptExpressionControl;
+        case 'script': return ScriptControl;
         case 'object-list': return ObjectListControl;
         default:
             const _: never = param;
@@ -746,7 +746,7 @@ export class ConvertedControl extends React.PureComponent<ParamProps<PD.Converte
     }
 }
 
-export class ScriptExpressionControl extends SimpleParam<PD.ScriptExpression> {
+export class ScriptControl extends SimpleParam<PD.Script> {
     onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
         const value = e.target.value;
         if (value !== this.props.value.expression) {

+ 48 - 0
src/mol-script/script.ts

@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { transpileMolScript } from './script/mol-script/symbols';
+import { parseMolScript } from './language/parser';
+import Expression from './language/expression';
+import { StructureElement, QueryContext, StructureSelection, Structure, QueryFn } from '../mol-model/structure';
+import { compile } from './runtime/query/compiler';
+
+export { Script }
+
+interface Script { expression: string, language: Script.Language }
+
+function Script(expression: string, language: Script.Language): Script {
+    return { expression, language }
+}
+
+namespace Script {
+    export type Language = 'mol-script'
+
+    export function areEqual(a: Script, b: Script) {
+        return a.language === b.language && a.expression === b.expression
+    }
+
+    export function toExpression(script: Script): Expression {
+        switch (script.language) {
+            case 'mol-script':
+                const parsed = parseMolScript(script.expression)
+                if (parsed.length === 0) throw new Error('No query')
+                return transpileMolScript(parsed[0])
+        }
+        throw new Error('unsupported script language')
+    }
+
+    export function toQuery(script: Script): QueryFn<StructureSelection> {
+        const expression = toExpression(script)
+        return compile<StructureSelection>(expression);
+    }
+
+    export function toLoci(script: Script, structure: Structure): StructureElement.Loci {
+        const query = toQuery(script)
+        const result = query(new QueryContext(structure))
+        return StructureSelection.toLoci2(result)
+    }
+}

+ 8 - 7
src/mol-util/param-definition.ts

@@ -9,6 +9,7 @@ import { Color as ColorData } from './color';
 import { shallowEqual } from './index';
 import { Vec2 as Vec2Data, Vec3 as Vec3Data } from '../mol-math/linear-algebra';
 import { deepClone } from './object';
+import { Script as ScriptData } from '../mol-script/script';
 
 export namespace ParamDefinition {
     export interface Info {
@@ -233,16 +234,16 @@ export namespace ParamDefinition {
         return { type: 'conditioned', select: Select<string>(conditionForValue(defaultValue) as string, options), defaultValue, conditionParams, conditionForValue, conditionedValue };
     }
 
-    export interface ScriptExpression extends Base<{ language: 'mol-script', expression: string }> {
-        type: 'script-expression'
+    export interface Script extends Base<ScriptData> {
+        type: 'script'
     }
-    export function ScriptExpression(defaultValue: ScriptExpression['defaultValue'], info?: Info): ScriptExpression {
-        return setInfo<ScriptExpression>({ type: 'script-expression', defaultValue }, info)
+    export function Script(defaultValue: Script['defaultValue'], info?: Info): Script {
+        return setInfo<Script>({ type: 'script', defaultValue }, info)
     }
 
     export type Any =
         | Value<any> | Select<any> | MultiSelect<any> | BooleanParam | Text | Color | Vec3 | Numeric | FileParam | Interval | LineGraph
-        | ColorList<any> | Group<any> | Mapped<any> | Converted<any, any> | Conditioned<any, any, any> | ScriptExpression | ObjectList
+        | ColorList<any> | Group<any> | Mapped<any> | Converted<any, any> | Conditioned<any, any, any> | Script | ObjectList
 
     export type Params = { [k: string]: Any }
     export type Values<T extends Params> = { [k in keyof T]: T[k]['defaultValue'] }
@@ -328,8 +329,8 @@ export namespace ParamDefinition {
             return true;
         } else if (p.type === 'vec3') {
             return Vec3Data.equals(a, b);
-        } else if (p.type === 'script-expression') {
-            const u = a as ScriptExpression['defaultValue'], v = b as ScriptExpression['defaultValue'];
+        } else if (p.type === 'script') {
+            const u = a as Script['defaultValue'], v = b as Script['defaultValue'];
             return u.language === v.language && u.expression === v.expression;
         } else if (p.type === 'object-list') {
             const u = a as ObjectList['defaultValue'], v = b as ObjectList['defaultValue'];