Переглянути джерело

StructureElement.Loci.toScriptExpression, mol-script fixes

David Sehnal 6 роки тому
батько
коміт
118daa2b25

+ 1 - 2
src/mol-model/structure/query/queries/modifiers.ts

@@ -279,11 +279,10 @@ export function expandProperty(query: StructureQuery, property: QueryFn): Struct
                 ctx.element.element = elements[i];
                 const p = property(ctx);
                 if (!propertyToStructureIndexMap.has(p)) continue;
-
                 const indices = propertyToStructureIndexMap.get(p)!.array;
 
                 for (let _sI = 0, __sI = indices.length; _sI < __sI; _sI++) {
-                    builders[indices[i]].addToUnit(unit.id, elements[i]);
+                    builders[indices[_sI]].addToUnit(unit.id, elements[i]);
                 }
             }
         }

+ 34 - 7
src/mol-model/structure/structure/element.ts

@@ -4,14 +4,17 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-import { OrderedSet, SortedArray } from 'mol-data/int'
-import Unit from './unit'
+import { UniqueArray } from 'mol-data/generic';
+import { OrderedSet, SortedArray } from 'mol-data/int';
+import { BoundaryHelper } from 'mol-math/geometry/boundary-helper';
+import { Vec3 } from 'mol-math/linear-algebra';
+import { MolScriptBuilder as MS } from 'mol-script/language/builder';
 import { ElementIndex } from '../model';
-import { ResidueIndex, ChainIndex } from '../model/indexing';
+import { ChainIndex, ResidueIndex } from '../model/indexing';
 import Structure from './structure';
+import Unit from './unit';
 import { Boundary } from './util/boundary';
-import { BoundaryHelper } from 'mol-math/geometry/boundary-helper';
-import { Vec3 } from 'mol-math/linear-algebra';
+import { StructureProperties } from '../structure';
 
 interface StructureElement<U = Unit> {
     readonly kind: 'element-location',
@@ -38,11 +41,11 @@ namespace StructureElement {
 
     function _wrongUnitKind(kind: string) { throw new Error(`Property only available for ${kind} models.`); }
     export function atomicProperty<T>(p: (location: StructureElement<Unit.Atomic>) => T) {
-        return property(l => Unit.isAtomic(l.unit) ? p(l as StructureElement<Unit.Atomic>) : _wrongUnitKind('atomic') );
+        return property(l => Unit.isAtomic(l.unit) ? p(l as StructureElement<Unit.Atomic>) : _wrongUnitKind('atomic'));
     }
 
     export function coarseProperty<T>(p: (location: StructureElement<Unit.Spheres | Unit.Gaussians>) => T) {
-        return property(l => Unit.isCoarse(l.unit) ? p(l as StructureElement<Unit.Spheres | Unit.Gaussians>) : _wrongUnitKind('coarse') );
+        return property(l => Unit.isCoarse(l.unit) ? p(l as StructureElement<Unit.Spheres | Unit.Gaussians>) : _wrongUnitKind('coarse'));
     }
 
     /** Represents multiple element index locations */
@@ -240,6 +243,30 @@ namespace StructureElement {
 
             return { box: boundaryHelper.getBox(), sphere: boundaryHelper.getSphere() };
         }
+
+        export function toScriptExpression(loci: Loci) {
+            if (loci.structure.models.length > 1) {
+                console.warn('toScriptExpression is only supported for Structure with single model, returning empty expression.');
+                return MS.struct.generator.empty();
+            }
+            const sourceIndices = UniqueArray.create<number, number>();
+            const el = StructureElement.create(), p = StructureProperties.atom.sourceIndex;
+            for (const e of loci.elements) {
+                const { indices } = e;
+                const { elements } = e.unit;
+
+                el.unit = e.unit;
+                for (let i = 0, _i = OrderedSet.size(indices); i < _i; i++) {
+                    el.element = elements[OrderedSet.getAt(indices, i)];
+                    const idx = p(el);
+                    UniqueArray.add(sourceIndices, idx, idx);
+                }
+            }
+            return MS.struct.generator.atomGroups({
+                'atom-test': MS.core.set.has([MS.set.apply(null, sourceIndices.array), MS.struct.atomProperty.core.sourceIndex()]),
+                'group-by': 0
+            });
+        }
     }
 }
 

+ 13 - 12
src/mol-plugin/behavior/dynamic/volume-streaming/behavior.ts

@@ -4,22 +4,23 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
+import CIF from 'mol-io/reader/cif';
+import { Box3D } from 'mol-math/geometry';
+import { Vec3 } from 'mol-math/linear-algebra';
+import { volumeFromDensityServerData } from 'mol-model-formats/volume/density-server';
+import { StructureElement } from 'mol-model/structure';
+import { VolumeData, VolumeIsoValue } from 'mol-model/volume';
 import { PluginBehavior } from 'mol-plugin/behavior';
+import { PluginContext } from 'mol-plugin/context';
 import { PluginStateObject } from 'mol-plugin/state/objects';
-import { ParamDefinition as PD } from 'mol-util/param-definition';
-import { VolumeServerInfo, VolumeServerHeader } from './model';
 import { createIsoValueParam } from 'mol-repr/volume/isosurface';
-import { VolumeIsoValue, VolumeData } from 'mol-model/volume';
 import { Color } from 'mol-util/color';
-import { Vec3 } from 'mol-math/linear-algebra';
-import { PluginContext } from 'mol-plugin/context';
 import { LRUCache } from 'mol-util/lru-cache';
-import CIF from 'mol-io/reader/cif';
-import { Box3D } from 'mol-math/geometry';
+import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { urlCombine } from 'mol-util/url';
-import { volumeFromDensityServerData } from 'mol-model-formats/volume/density-server';
-import { StructureElement } from 'mol-model/structure';
+import { VolumeServerHeader, VolumeServerInfo } from './model';
 import { CreateVolumeStreamingBehavior } from './transformers';
+import { ButtonsType } from 'mol-util/input/input-observer';
 
 export class VolumeStreaming extends PluginStateObject.CreateBehavior<VolumeStreaming.Behavior>({ name: 'Volume Streaming' }) { }
 
@@ -147,8 +148,8 @@ export namespace VolumeStreaming {
         register(ref: string): void {
             // this.ref = ref;
 
-            this.subscribeObservable(this.plugin.events.canvas3d.click, ({ current }) => {
-                if (this.params.view.name !== 'selection-box') return;
+            this.subscribeObservable(this.plugin.events.canvas3d.click, ({ current, buttons }) => {
+                if (buttons !== ButtonsType.Flag.Secondary || this.params.view.name !== 'selection-box') return;
                 // TODO: support link loci as well?
                 // Perhaps structure loci too?
                 if (!StructureElement.isLoci(current.loci)) return;
@@ -198,7 +199,7 @@ export namespace VolumeStreaming {
                     break;
             }
 
-            const data = emptyData ? { } : await this.queryData(box);
+            const data = emptyData ? {} : await this.queryData(box);
 
             if (!data) return false;
 

+ 4 - 0
src/mol-script/language/symbol-table/structure-query.ts

@@ -150,6 +150,10 @@ const modifier = {
         'as-whole-residues': Argument(Type.Bool, { isOptional: true })
     }), Types.ElementSelectionQuery, 'Pick all atom sets that are connected to the target.'),
 
+    wholeResidues: symbol(Arguments.Dictionary({
+        0: Argument(Types.ElementSelectionQuery),
+    }), Types.ElementSelectionQuery, 'Expand the selection to whole residues.'),
+
     expandProperty: symbol(Arguments.Dictionary({
         0: Argument(Types.ElementSelectionQuery),
         property: Argument(Type.AnyValue)

+ 13 - 0
src/mol-script/runtime/query/table.ts

@@ -195,6 +195,19 @@ const symbols = [
         groupBy: xs['group-by']
     })(ctx)),
 
+    D(MolScript.structureQuery.generator.all, (ctx) => Queries.generators.all(ctx)),
+    D(MolScript.structureQuery.generator.empty, (ctx) => Queries.generators.none(ctx)),
+
+    // ============= MODIFIERS ================
+
+    D(MolScript.structureQuery.modifier.includeSurroundings, (ctx, xs) => Queries.modifiers.includeSurroundings(xs[0] as any, {
+        radius: xs['radius'](ctx),
+        wholeResidues: !!(xs['as-whole-residues'] && xs['as-whole-residues'](ctx)),
+        elementRadius: xs['atom-radius']
+    })(ctx)),
+    D(MolScript.structureQuery.modifier.wholeResidues, (ctx, xs) => Queries.modifiers.wholeResidues(xs[0] as any)(ctx)),
+    D(MolScript.structureQuery.modifier.expandProperty, (ctx, xs) => Queries.modifiers.expandProperty(xs[0] as any, xs['property'])(ctx)),
+
     // ============= ATOM PROPERTIES ================
 
     // ~~~ CORE ~~~