From 6e36116f7681a2820e82f101d3568e9936d881af Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Wed, 8 Aug 2018 14:56:33 +0200 Subject: [PATCH] wip, mol-script --- .../model/properties/custom/descriptor.ts | 12 ++++++-- src/mol-script/language/symbol.ts | 11 +++++++ src/mol-script/runtime/query/compiler.ts | 10 ++++++- src/mol-script/runtime/query/table.ts | 14 +++------ src/perf-tests/mol-script.ts | 30 +++++++++++++++---- 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/mol-model/structure/model/properties/custom/descriptor.ts b/src/mol-model/structure/model/properties/custom/descriptor.ts index d86dd94a6..fd60c265d 100644 --- a/src/mol-model/structure/model/properties/custom/descriptor.ts +++ b/src/mol-model/structure/model/properties/custom/descriptor.ts @@ -6,14 +6,22 @@ import { CifWriter } from 'mol-io/writer/cif' import { CifExportContext } from '../../../export/mmcif'; +import { QuerySymbolRuntime } from 'mol-script/runtime/query/compiler'; -interface ModelPropertyDescriptor { +interface ModelPropertyDescriptor<Symbols extends { [name: string]: QuerySymbolRuntime } = { }> { readonly isStatic: boolean, readonly name: string, cifExport: { categories: CifWriter.Category<CifExportContext>[] - } + }, + + // TODO: add aliases when lisp-like mol-script is done + symbols?: Symbols +} + +function ModelPropertyDescriptor<Desc extends ModelPropertyDescriptor>(desc: Desc) { + return desc; } export { ModelPropertyDescriptor } \ No newline at end of file diff --git a/src/mol-script/language/symbol.ts b/src/mol-script/language/symbol.ts index de9b53665..bb935ee6f 100644 --- a/src/mol-script/language/symbol.ts +++ b/src/mol-script/language/symbol.ts @@ -74,6 +74,17 @@ export function MSymbol<A extends Arguments, T extends Type>(name: string, args: return symbol; } +export function CustomPropSymbol<T extends Type>(namespace: string, name: string, type: T, description?: string) { + const symbol: MSymbol<Arguments<{}>, T> = function(args: ExpressionArguments<Arguments<{}>['@type']>) { + return Expression.Apply(Expression.Symbol(symbol.id), args as any); + } as any; + symbol.info = { namespace, name, description }; + symbol.id = `${namespace}.${name}`; + symbol.args = Arguments.None; + symbol.type = type; + return symbol; +} + export function isSymbol(x: any): x is MSymbol { const s = x as MSymbol; return typeof s === 'function' && !!s.info && !!s.args && typeof s.info.namespace === 'string' && !!s.type; diff --git a/src/mol-script/runtime/query/compiler.ts b/src/mol-script/runtime/query/compiler.ts index 63598bb4c..aa3c6b652 100644 --- a/src/mol-script/runtime/query/compiler.ts +++ b/src/mol-script/runtime/query/compiler.ts @@ -5,7 +5,7 @@ */ import Expression from '../../language/expression'; -import { QueryContext, QueryFn, Structure } from 'mol-model/structure'; +import { QueryContext, QueryFn, Structure, ModelPropertyDescriptor } from 'mol-model/structure'; import { MSymbol } from '../../language/symbol'; export class QueryRuntimeTable { @@ -15,6 +15,14 @@ export class QueryRuntimeTable { this.map.set(runtime.symbol.id, runtime); } + addCustomProp(desc: ModelPropertyDescriptor) { + if (!desc.symbols) return; + + for (const k of Object.keys(desc.symbols)) { + this.addSymbol((desc.symbols as any)[k]); + } + } + getRuntime(id: string) { return this.map.get(id); } diff --git a/src/mol-script/runtime/query/table.ts b/src/mol-script/runtime/query/table.ts index d5c4217d7..e0d555655 100644 --- a/src/mol-script/runtime/query/table.ts +++ b/src/mol-script/runtime/query/table.ts @@ -30,6 +30,10 @@ const symbols = [ C(MolScript.core.rel.lte, (ctx, v) => v[0](ctx) <= v[1](ctx)), C(MolScript.core.rel.gr, (ctx, v) => v[0](ctx) > v[1](ctx)), C(MolScript.core.rel.gre, (ctx, v) => v[0](ctx) >= v[1](ctx)), + C(MolScript.core.rel.inRange, (ctx, v) => { + const x = v[0](ctx); + return x >= v[1](ctx) && x <= v[2](ctx); + }), // ============= TYPES ================ C(MolScript.structureQuery.type.elementSymbol, (ctx, v) => ElementSymbol(v[0](ctx))), @@ -46,16 +50,6 @@ const symbols = [ // ============= ATOM PROPERTIES ================ D(MolScript.structureQuery.atomProperty.macromolecular.label_comp_id, (ctx, _) => StructureProperties.residue.label_comp_id(ctx.element)), D(MolScript.structureQuery.atomProperty.core.elementSymbol, (ctx, _) => StructureProperties.atom.type_symbol(ctx.element)) - - // Symbol(MolQL.core.rel.neq, staticAttr)((env, v) => v[0](env) !== v[1](env)), - // Symbol(MolQL.core.rel.lt, staticAttr)((env, v) => v[0](env) < v[1](env)), - // Symbol(MolQL.core.rel.lte, staticAttr)((env, v) => v[0](env) <= v[1](env)), - // Symbol(MolQL.core.rel.gr, staticAttr)((env, v) => v[0](env) > v[1](env)), - // Symbol(MolQL.core.rel.gre, staticAttr)((env, v) => v[0](env) >= v[1](env)), - // Symbol(MolQL.core.rel.inRange, staticAttr)((env, v) => { - // const x = v[0](env); - // return x >= v[1](env) && x <= v[2](env) - // }), ]; (function () { diff --git a/src/perf-tests/mol-script.ts b/src/perf-tests/mol-script.ts index 104c6c194..5f6cfcc9e 100644 --- a/src/perf-tests/mol-script.ts +++ b/src/perf-tests/mol-script.ts @@ -1,7 +1,9 @@ import { MolScriptBuilder } from 'mol-script/language/builder'; -import { compile } from 'mol-script/runtime/query/compiler'; -import { QueryContext, Structure, StructureQuery } from 'mol-model/structure'; +import { compile, QuerySymbolRuntime, DefaultQueryRuntimeTable } from 'mol-script/runtime/query/compiler'; +import { QueryContext, Structure, StructureQuery, ModelPropertyDescriptor } from 'mol-model/structure'; import { readCifFile, getModelsAndStructure } from '../apps/structure-info/model'; +import { CustomPropSymbol } from 'mol-script/language/symbol'; +import Type from 'mol-script/language/type'; // import Examples from 'mol-script/script/mol-script/examples' // import { parseMolScript } from 'mol-script/script/mol-script/parser' @@ -27,6 +29,21 @@ const compiled = compile<number>(expr); const result = compiled(new QueryContext(Structure.Empty)); console.log(result); +const CustomProp = ModelPropertyDescriptor({ + name: 'test_prop', + isStatic: true, + cifExport: { categories: [ ]}, + symbols: { + residueIndex: QuerySymbolRuntime.Dynamic(CustomPropSymbol('custom.test-prop', 'residue-index', Type.Num), ctx => { + const e = ctx.element; + //console.log(e.element, e.unit.model.atomicHierarchy.residueAtomSegments.index[e.element]) + return e.unit.model.atomicHierarchy.residueAtomSegments.index[e.element]; + }) + } +}); + +DefaultQueryRuntimeTable.addCustomProp(CustomProp); + async function testQ() { const frame = await readCifFile('e:/test/quick/1cbs_updated.cif'); const { structure } = await getModelsAndStructure(frame); @@ -36,10 +53,11 @@ async function testQ() { MolScriptBuilder.struct.atomProperty.core.elementSymbol(), MolScriptBuilder.es('C') ]), - 'residue-test': MolScriptBuilder.core.rel.eq([ - MolScriptBuilder.struct.atomProperty.macromolecular.label_comp_id(), - 'REA' - ]) + // 'residue-test': MolScriptBuilder.core.rel.eq([ + // MolScriptBuilder.struct.atomProperty.macromolecular.label_comp_id(), + // 'REA' + // ]) + 'residue-test': MolScriptBuilder.core.rel.inRange([CustomProp.symbols.residueIndex.symbol(), 1, 5]) }); const compiled = compile<StructureQuery>(expr); -- GitLab