From 9c046b808c295f20614c1bfce60d103528f7a0c8 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Wed, 16 Oct 2019 13:26:05 +0200 Subject: [PATCH] mol-script: added Bundle support --- .../structure/query/queries/internal.ts | 23 +++++++++++++- .../structure/structure/element/bundle.ts | 19 +++++++++++- src/mol-script/language/builder.ts | 1 + src/mol-script/language/symbol-table.ts | 3 +- .../language/symbol-table/internal.ts | 30 +++++++++++++++++++ src/mol-script/runtime/query/table.ts | 7 +++++ 6 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 src/mol-script/language/symbol-table/internal.ts diff --git a/src/mol-model/structure/query/queries/internal.ts b/src/mol-model/structure/query/queries/internal.ts index 23b495f72..fecbf7d10 100644 --- a/src/mol-model/structure/query/queries/internal.ts +++ b/src/mol-model/structure/query/queries/internal.ts @@ -4,7 +4,7 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { Segmentation } from '../../../../mol-data/int'; +import { Segmentation, SortedArray } from '../../../../mol-data/int'; import StructureElement from '../../../../mol-model/structure/structure/element'; import { StructureProperties as P, Unit } from '../../structure'; import Structure from '../../structure/structure'; @@ -12,6 +12,8 @@ import { StructureQuery } from '../query'; import { StructureSelection } from '../selection'; import { QueryContext } from '../context'; import { LinkType } from '../../model/types'; +import { BundleElement, Bundle } from '../../structure/element/bundle'; +import { UnitIndex } from '../../structure/element/element'; export function defaultLinkTest(ctx: QueryContext) { return LinkType.isCovalent(ctx.atomicLink.type); @@ -105,4 +107,23 @@ export function spheres(): StructureQuery { } return StructureSelection.Singletons(inputStructure, new Structure(units, { parent: inputStructure })); }; +} + +export function bundleElementImpl(groupedUnits: number[][], ranges: number[], set: number[]): BundleElement { + return { + groupedUnits: groupedUnits as any as SortedArray<number>[], + ranges: ranges as any as SortedArray<UnitIndex>, + set: set as any as SortedArray<UnitIndex> + }; +} + +export function bundleGenerator(elements: BundleElement[]): StructureQuery { + return ctx => { + const bundle: Bundle = { + hash: ctx.inputStructure.hashCode, + elements + }; + + return StructureSelection.Sequence(ctx.inputStructure, [Bundle.toStructure(bundle, ctx.inputStructure)]); + }; } \ No newline at end of file diff --git a/src/mol-model/structure/structure/element/bundle.ts b/src/mol-model/structure/structure/element/bundle.ts index b750308df..b22289426 100644 --- a/src/mol-model/structure/structure/element/bundle.ts +++ b/src/mol-model/structure/structure/element/bundle.ts @@ -12,8 +12,10 @@ import { hashFnv32a, hash2 } from '../../../../mol-data/util'; import SortedRanges from '../../../../mol-data/int/sorted-ranges'; import { UnitIndex } from './element'; import { Loci } from './loci'; +import Expression from '../../../../mol-script/language/expression'; +import { MolScriptBuilder as MS } from '../../../../mol-script/language/builder'; -interface BundleElement { +export interface BundleElement { /** * Array (sorted by first element in sub-array) of * arrays of `Unit.id`s that share the same `Unit.invariantId` @@ -192,6 +194,21 @@ export namespace Bundle { return Structure.create(units, { parent }) } + + function elementToExpression(e: BundleElement): Expression { + return MS.internal.generator.bundleElement({ + groupedUnits: MS.core.type.list(e.groupedUnits.map(u => MS.core.type.list(u))), + ranges: MS.core.type.list(e.ranges), + set: MS.core.type.list(e.set), + }) + } + + export function toExpression(bundle: Bundle): Expression { + return MS.internal.generator.bundle({ + elements: MS.core.type.list(bundle.elements.map(elementToExpression)) + }); + } + export function areEqual(a: Bundle, b: Bundle) { if (a.elements.length !== b.elements.length) return false for (let i = 0, il = a.elements.length; i < il; ++i) { diff --git a/src/mol-script/language/builder.ts b/src/mol-script/language/builder.ts index c114c0ff6..16038e383 100644 --- a/src/mol-script/language/builder.ts +++ b/src/mol-script/language/builder.ts @@ -11,6 +11,7 @@ import { MolScriptSymbolTable as SymbolTable } from './symbol-table' export namespace MolScriptBuilder { export const core = SymbolTable.core; export const struct = SymbolTable.structureQuery; + export const internal = SymbolTable.internal; /** Atom-name constructor */ export function atomName(s: string) { return struct.type.atomName([s]); } diff --git a/src/mol-script/language/symbol-table.ts b/src/mol-script/language/symbol-table.ts index 3dec8616f..b8fde22ab 100644 --- a/src/mol-script/language/symbol-table.ts +++ b/src/mol-script/language/symbol-table.ts @@ -6,10 +6,11 @@ import core from './symbol-table/core' import structureQuery from './symbol-table/structure-query' +import internal from './symbol-table/internal' import { normalizeTable, symbolList } from './helpers' import { MSymbol } from './symbol' -const MolScriptSymbolTable = { core, structureQuery }; +const MolScriptSymbolTable = { core, structureQuery, internal }; normalizeTable(MolScriptSymbolTable); diff --git a/src/mol-script/language/symbol-table/internal.ts b/src/mol-script/language/symbol-table/internal.ts new file mode 100644 index 000000000..d03433484 --- /dev/null +++ b/src/mol-script/language/symbol-table/internal.ts @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2019 Mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + */ + +import Type from '../type' +import * as Struct from './structure-query' +import { Arguments, Argument } from '../symbol' +import { symbol } from '../helpers' + +const generator = { + '@header': 'Generators', + + bundleElement: symbol(Arguments.Dictionary({ + // TODO: should we use more universal unit keys? (i.e. based on chain and "operator name") + groupedUnits: Argument(Type.Any), // SortedArray<number>[], + set: Argument(Type.Any), // SortedArray<UnitIndex> + ranges: Argument(Type.Any) // SortedArray<UnitIndex> + }), Type.Any), // returns BundleElement + + bundle: symbol(Arguments.Dictionary({ + elements: Argument(Type.Any) // BundleElement[] + }), Struct.Types.ElementSelectionQuery, 'A selection with single structure containing represented by the bundle.'), +} + +export default { + '@header': 'Internal Queries', + generator +} \ No newline at end of file diff --git a/src/mol-script/runtime/query/table.ts b/src/mol-script/runtime/query/table.ts index bf45a8836..6c1bcf441 100644 --- a/src/mol-script/runtime/query/table.ts +++ b/src/mol-script/runtime/query/table.ts @@ -15,6 +15,7 @@ import { VdwRadius, AtomWeight, AtomNumber } from '../../../mol-model/structure/ import { cantorPairing } from '../../../mol-data/util'; import C = QuerySymbolRuntime.Const import D = QuerySymbolRuntime.Dynamic +import { bundleElementImpl, bundleGenerator } from '../../../mol-model/structure/query/queries/internal'; const symbols = [ // ============= TYPES ============= @@ -320,6 +321,12 @@ const symbols = [ // ============= BOND PROPERTIES ================ D(MolScript.structureQuery.linkProperty.order, (ctx, xs) => ctx.atomicLink.order), D(MolScript.structureQuery.linkProperty.flags, (ctx, xs) => ctx.atomicLink.type), + + + //////////////////////////////////// + // Internal + D(MolScript.internal.generator.bundleElement, (ctx, xs) => bundleElementImpl(xs.groupedUnits(ctx), xs.ranges(ctx), xs.set(ctx))), + D(MolScript.internal.generator.bundle, (ctx, xs) => bundleGenerator(xs.elements(ctx))), ]; function atomProp(p: (e: StructureElement.Location) => any): (ctx: QueryContext, _: any) => any { -- GitLab