Browse Source

added StructureSelectionQuery wrapping expr & query

Alexander Rose 5 years ago
parent
commit
989faed410

+ 8 - 8
src/mol-plugin/state/transforms/model.ts

@@ -28,7 +28,7 @@ import { ensureSecondaryStructure } from './helpers';
 import { Script } from '../../../mol-script/script';
 import { parse3DG } from '../../../mol-io/reader/3dg/parser';
 import { trajectoryFrom3DG } from '../../../mol-model-formats/structure/3dg';
-import { CompiledStructureSelectionQueries } from '../../util/structure-selection-helper';
+import { StructureSelectionQueries } from '../../util/structure-selection-helper';
 
 export { TrajectoryFromBlob };
 export { TrajectoryFromMmCif };
@@ -564,18 +564,18 @@ const StructureComplexElement = PluginStateTransform.BuiltIn({
 
         let query: StructureQuery, label: string;
         switch (params.type) {
-            case 'protein-and-nucleic': query = CompiledStructureSelectionQueries.proteinAndNucleic; label = 'Sequence'; break;
+            case 'protein-and-nucleic': query = StructureSelectionQueries.proteinAndNucleic.query; label = 'Sequence'; break;
 
-            case 'protein': query = CompiledStructureSelectionQueries.protein; label = 'Protein'; break;
-            case 'nucleic': query = CompiledStructureSelectionQueries.nucleic; label = 'Nucleic'; break;
+            case 'protein': query = StructureSelectionQueries.protein.query; label = 'Protein'; break;
+            case 'nucleic': query = StructureSelectionQueries.nucleic.query; label = 'Nucleic'; break;
             case 'water': query = Queries.internal.water(); label = 'Water'; break;
 
-            case 'branched': query = CompiledStructureSelectionQueries.branchedPlusConnected; label = 'Branched'; break;
-            case 'ligand': query = CompiledStructureSelectionQueries.ligandPlusConnected; label = 'Ligand'; break;
+            case 'branched': query = StructureSelectionQueries.branchedPlusConnected.query; label = 'Branched'; break;
+            case 'ligand': query = StructureSelectionQueries.ligandPlusConnected.query; label = 'Ligand'; break;
 
-            case 'modified': query = CompiledStructureSelectionQueries.modified; label = 'Modified'; break;
+            case 'modified': query = StructureSelectionQueries.modified.query; label = 'Modified'; break;
 
-            case 'coarse': query = CompiledStructureSelectionQueries.coarse; label = 'Coarse'; break;
+            case 'coarse': query = StructureSelectionQueries.coarse.query; label = 'Coarse'; break;
 
             case 'atomic-sequence': query = Queries.internal.atomicSequence(); label = 'Sequence'; break;
             case 'atomic-het': query = Queries.internal.atomicHet(); label = 'HET Groups/Ligands'; break;

+ 2 - 3
src/mol-plugin/ui/structure/selection.tsx

@@ -12,7 +12,6 @@ import { PluginCommands } from '../../command';
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 import { Interactivity } from '../../util/interactivity';
 import { ParameterControls } from '../controls/parameters';
-import { camelCaseToWords } from '../../../mol-util/string';
 
 const StructureSelectionParams = {
     granularity: Interactivity.Params.granularity,
@@ -66,7 +65,7 @@ export class StructureSelectionControls<P, S extends StructureSelectionControlsS
 
     set = (modifier: SelectionModifier, value: string) => {
         const query = StructureSelectionQueries[value as keyof typeof StructureSelectionQueries]
-        this.plugin.helpers.structureSelection.set(modifier, query)
+        this.plugin.helpers.structureSelection.set(modifier, query.query)
     }
 
     add = (value: string) => this.set('add', value)
@@ -86,7 +85,7 @@ export class StructureSelectionControls<P, S extends StructureSelectionControlsS
 
     renderControls() {
         const queries = Object.keys(StructureSelectionQueries).map(name => {
-            return [name, camelCaseToWords(name)] as [string, string]
+            return [name, StructureSelectionQueries[name as keyof typeof StructureSelectionQueries].label] as [string, string]
         })
 
         return <div>

+ 17 - 9
src/mol-plugin/util/structure-representation-helper.ts

@@ -199,34 +199,42 @@ export class StructureRepresentationHelper {
 
 async function polymerAndLigand(r: StructureRepresentationHelper) {
     await r.clear()
-    await r.setFromExpression('add', 'cartoon', Q.all)
-    await r.setFromExpression('add', 'carbohydrate', Q.all)
+    await r.setFromExpression('add', 'cartoon', Q.all.expression)
+    await r.setFromExpression('add', 'carbohydrate', Q.all.expression)
     await r.setFromExpression('add', 'ball-and-stick', MS.struct.modifier.union([
-        MS.struct.combinator.merge([ Q.ligandPlusConnected, Q.branchedConnectedOnly, Q.water ])
+        MS.struct.combinator.merge([
+            Q.ligandPlusConnected.expression,
+            Q.branchedConnectedOnly.expression,
+            Q.water.expression
+        ])
     ]))
 }
 
 async function proteinAndNucleic(r: StructureRepresentationHelper) {
     await r.clear()
-    await r.setFromExpression('add', 'cartoon', Q.protein)
-    await r.setFromExpression('add', 'gaussian-surface', Q.nucleic)
+    await r.setFromExpression('add', 'cartoon', Q.protein.expression)
+    await r.setFromExpression('add', 'gaussian-surface', Q.nucleic.expression)
 
-    await r.setFromExpression('add', 'carbohydrate', Q.all)
+    await r.setFromExpression('add', 'carbohydrate', Q.all.expression)
     await r.setFromExpression('add', 'ball-and-stick', MS.struct.modifier.union([
-        MS.struct.combinator.merge([ Q.ligandPlusConnected, Q.branchedConnectedOnly, Q.water ])
+        MS.struct.combinator.merge([
+            Q.ligandPlusConnected.expression,
+            Q.branchedConnectedOnly.expression,
+            Q.water.expression
+        ])
     ]))
 }
 
 async function capsid(r: StructureRepresentationHelper) {
     await r.clear()
-    await r.setFromExpression('add', 'gaussian-surface', Q.polymer, {
+    await r.setFromExpression('add', 'gaussian-surface', Q.polymer.expression, {
         smoothness: 0.5,
     })
 }
 
 async function coarseCapsid(r: StructureRepresentationHelper) {
     await r.clear()
-    await r.setFromExpression('add', 'gaussian-surface', Q.trace, {
+    await r.setFromExpression('add', 'gaussian-surface', Q.trace.expression, {
         radiusOffset: 1,
         smoothness: 0.5,
         visuals: ['structure-gaussian-surface-mesh']

+ 63 - 54
src/mol-plugin/util/structure-selection-helper.ts

@@ -13,15 +13,26 @@ import { Loci } from '../../mol-model/loci';
 import { PluginContext } from '../context';
 import Expression from '../../mol-script/language/expression';
 
-const all = MS.struct.generator.all()
+export interface StructureSelectionQuery {
+    label: string
+    query: StructureQuery
+    expression: Expression
+    description: string
+}
+
+export function StructureSelectionQuery(label: string, expression: Expression, description = ''): StructureSelectionQuery {
+    return { label, expression, query: compile<StructureSelection>(expression), description }
+}
 
-const polymer = MS.struct.modifier.union([
+const all = StructureSelectionQuery('All', MS.struct.generator.all())
+
+const polymer = StructureSelectionQuery('Polymer', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer'])
     })
-])
+]))
 
-const trace = MS.struct.modifier.union([
+const trace = StructureSelectionQuery('Trace', MS.struct.modifier.union([
     MS.struct.combinator.merge([
         MS.struct.modifier.union([
             MS.struct.generator.atomGroups({
@@ -39,9 +50,9 @@ const trace = MS.struct.modifier.union([
             })
         ])
     ])
-])
+]))
 
-const protein = MS.struct.modifier.union([
+const protein = StructureSelectionQuery('Protein', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'entity-test': MS.core.logic.and([
             MS.core.rel.eq([MS.ammp('entityType'), 'polymer']),
@@ -51,9 +62,9 @@ const protein = MS.struct.modifier.union([
             ])
         ])
     })
-])
+]))
 
-const nucleic = MS.struct.modifier.union([
+const nucleic = StructureSelectionQuery('Nucleic', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'entity-test': MS.core.logic.and([
             MS.core.rel.eq([MS.ammp('entityType'), 'polymer']),
@@ -63,9 +74,9 @@ const nucleic = MS.struct.modifier.union([
             ])
         ])
     })
-])
+]))
 
-const proteinAndNucleic = MS.struct.modifier.union([
+const proteinAndNucleic = StructureSelectionQuery('Protein | Nucleic', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'entity-test': MS.core.logic.and([
             MS.core.rel.eq([MS.ammp('entityType'), 'polymer']),
@@ -75,15 +86,15 @@ const proteinAndNucleic = MS.struct.modifier.union([
             ])
         ])
     })
-])
+]))
 
-const water = MS.struct.modifier.union([
+const water = StructureSelectionQuery('Water', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'water'])
     })
-])
+]))
 
-const branched = MS.struct.modifier.union([
+const branched = StructureSelectionQuery('Carbohydrate', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'entity-test': MS.core.logic.or([
             MS.core.rel.eq([MS.ammp('entityType'), 'branched']),
@@ -96,22 +107,22 @@ const branched = MS.struct.modifier.union([
             ])
         ])
     })
-])
+]))
 
-const branchedPlusConnected = MS.struct.modifier.union([
+const branchedPlusConnected = StructureSelectionQuery('Carbohydrate with Connected', MS.struct.modifier.union([
     MS.struct.modifier.includeConnected({
-        0: branched, 'layer-count': 1, 'as-whole-residues': true
+        0: branched.expression, 'layer-count': 1, 'as-whole-residues': true
     })
-])
+]))
 
-const branchedConnectedOnly = MS.struct.modifier.union([
+const branchedConnectedOnly = StructureSelectionQuery('Connected to Carbohydrate', MS.struct.modifier.union([
     MS.struct.modifier.exceptBy({
-        0: branchedPlusConnected,
-        by: branched
+        0: branchedPlusConnected.expression,
+        by: branched.expression
     })
-])
+]))
 
-const ligand = MS.struct.modifier.union([
+const ligand = StructureSelectionQuery('Ligand', MS.struct.modifier.union([
     MS.struct.combinator.merge([
         MS.struct.modifier.union([
             MS.struct.generator.atomGroups({
@@ -139,53 +150,53 @@ const ligand = MS.struct.modifier.union([
             })
         ])
     ]),
-])
+]))
 
 // don't include branched entities as they have their own link representation
-const ligandPlusConnected = MS.struct.modifier.union([
+const ligandPlusConnected = StructureSelectionQuery('Ligand with Connected', MS.struct.modifier.union([
     MS.struct.modifier.exceptBy({
         0: MS.struct.modifier.union([
             MS.struct.modifier.includeConnected({
-                0: ligand,
+                0: ligand.expression,
                 'layer-count': 1,
                 'as-whole-residues': true
             })
         ]),
-        by: branched
+        by: branched.expression
     })
-])
+]))
 
-const ligandConnectedOnly = MS.struct.modifier.union([
+const ligandConnectedOnly = StructureSelectionQuery('Connected to Ligand', MS.struct.modifier.union([
     MS.struct.modifier.exceptBy({
-        0: ligandPlusConnected,
-        by: ligand
+        0: ligandPlusConnected.expression,
+        by: ligand.expression
     })
-])
+]))
 
 // residues connected to ligands or branched entities
-const connectedOnly = MS.struct.modifier.union([
+const connectedOnly = StructureSelectionQuery('Connected to Ligand | Carbohydrate', MS.struct.modifier.union([
     MS.struct.combinator.merge([
-        branchedConnectedOnly,
-        ligandConnectedOnly
+        branchedConnectedOnly.expression,
+        ligandConnectedOnly.expression
     ]),
-])
+]))
 
-const modified = MS.struct.modifier.union([
+const modified = StructureSelectionQuery('Modified Residues', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
         'residue-test': MS.ammp('isModified')
     })
-])
+]))
 
-const coarse = MS.struct.modifier.union([
+const coarse = StructureSelectionQuery('Coarse Elements', MS.struct.modifier.union([
     MS.struct.generator.atomGroups({
         'chain-test': MS.core.set.has([
             MS.set('sphere', 'gaussian'), MS.ammp('objectPrimitive')
         ])
     })
-])
+]))
 
-const surroundings = MS.struct.modifier.union([
+const surroundings = StructureSelectionQuery('Surrounding Residues (5 \u212B)', MS.struct.modifier.union([
     MS.struct.modifier.exceptBy({
         0: MS.struct.modifier.includeSurroundings({
             0: MS.internal.generator.current(),
@@ -194,7 +205,14 @@ const surroundings = MS.struct.modifier.union([
         }),
         by: MS.internal.generator.current()
     })
-])
+]), 'Select residues within 5 \u212B of the current selection.')
+
+const complement = StructureSelectionQuery('Complement', MS.struct.modifier.union([
+    MS.struct.modifier.exceptBy({
+        0: MS.struct.generator.all(),
+        by: MS.internal.generator.current()
+    })
+]), 'Select everything not in the current selection.')
 
 export const StructureSelectionQueries = {
     all,
@@ -214,16 +232,9 @@ export const StructureSelectionQueries = {
     modified,
     coarse,
     surroundings,
+    complement,
 }
 
-export const CompiledStructureSelectionQueries = (function () {
-    const ret: { [K in keyof typeof StructureSelectionQueries]: StructureQuery } = Object.create(null);
-    for (const k of Object.keys(StructureSelectionQueries)) {
-        (ret as any)[k] = compile<StructureSelection>((StructureSelectionQueries as any)[k]);
-    }
-    return ret;
-})();
-
 //
 
 export type SelectionModifier = 'add' | 'remove' | 'only'
@@ -248,9 +259,7 @@ export class StructureSelectionHelper {
         }
     }
 
-    set(modifier: SelectionModifier, query: Expression) {
-        const compiled = compile<StructureSelection>(query)
-
+    set(modifier: SelectionModifier, query: StructureQuery) {
         for (const so of this.structures) {
             const s = so.obj!.data
 
@@ -259,7 +268,7 @@ export class StructureSelectionHelper {
                 ? StructureSelection.Empty(s)
                 : StructureSelection.Singletons(s, StructureElement.Loci.toStructure(current))
 
-            const result = compiled(new QueryContext(s, { currentSelection }))
+            const result = query(new QueryContext(s, { currentSelection }))
             const loci = StructureSelection.toLociWithSourceUnits(result)
             this._set(modifier, loci)
         }