|
@@ -1,5 +1,5 @@
|
|
/**
|
|
/**
|
|
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
|
|
|
+ * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
*
|
|
*
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
* @author David Sehnal <david.sehnal@gmail.com>
|
|
* @author David Sehnal <david.sehnal@gmail.com>
|
|
@@ -8,32 +8,76 @@
|
|
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
|
|
import { MolScriptBuilder as MS } from '../../mol-script/language/builder';
|
|
import { StateSelection, StateBuilder } from '../../mol-state';
|
|
import { StateSelection, StateBuilder } from '../../mol-state';
|
|
import { PluginStateObject } from '../state/objects';
|
|
import { PluginStateObject } from '../state/objects';
|
|
-import { QueryContext, StructureSelection, StructureQuery, StructureElement } from '../../mol-model/structure';
|
|
|
|
|
|
+import { QueryContext, StructureSelection, StructureQuery, StructureElement, Structure } from '../../mol-model/structure';
|
|
import { compile } from '../../mol-script/runtime/query/compiler';
|
|
import { compile } from '../../mol-script/runtime/query/compiler';
|
|
import { Loci } from '../../mol-model/loci';
|
|
import { Loci } from '../../mol-model/loci';
|
|
import { PluginContext } from '../context';
|
|
import { PluginContext } from '../context';
|
|
import Expression from '../../mol-script/language/expression';
|
|
import Expression from '../../mol-script/language/expression';
|
|
import { BondType, ProteinBackboneAtoms, NucleicBackboneAtoms, SecondaryStructureType } from '../../mol-model/structure/model/types';
|
|
import { BondType, ProteinBackboneAtoms, NucleicBackboneAtoms, SecondaryStructureType } from '../../mol-model/structure/model/types';
|
|
import { StateTransforms } from '../state/transforms';
|
|
import { StateTransforms } from '../state/transforms';
|
|
|
|
+import { SetUtils } from '../../mol-util/set';
|
|
|
|
+import { ValidationReport, ValidationReportProvider } from '../../mol-model-props/rcsb/validation-report';
|
|
|
|
+import { CustomProperty } from '../../mol-model-props/common/custom-property';
|
|
|
|
+import { Task } from '../../mol-task';
|
|
|
|
+import { AccessibleSurfaceAreaSymbols, AccessibleSurfaceAreaProvider } from '../../mol-model-props/computed/accessible-surface-area';
|
|
|
|
+import { stringToWords } from '../../mol-util/string';
|
|
|
|
+
|
|
|
|
+export enum StructureSelectionCategory {
|
|
|
|
+ Type = 'Type',
|
|
|
|
+ Structure = 'Structure Property',
|
|
|
|
+ Atom = 'Atom Property',
|
|
|
|
+ Bond = 'Bond Property',
|
|
|
|
+ Residue = 'Residue Property',
|
|
|
|
+ AminoAcid = 'Amino Acid',
|
|
|
|
+ NucleicBase = 'Nucleic Base',
|
|
|
|
+ Manipulate = 'Manipulate Selection',
|
|
|
|
+ Validation = 'Validation',
|
|
|
|
+ Misc = 'Miscellaneous',
|
|
|
|
+ Internal = 'Internal',
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export { StructureSelectionQuery }
|
|
|
|
+
|
|
|
|
+interface StructureSelectionQuery {
|
|
|
|
+ readonly label: string
|
|
|
|
+ readonly expression: Expression
|
|
|
|
+ readonly description: string
|
|
|
|
+ readonly category: string
|
|
|
|
+ readonly isHidden: boolean
|
|
|
|
+ readonly query: StructureQuery
|
|
|
|
+ readonly ensureCustomProperties?: (ctx: CustomProperty.Context, structure: Structure) => Promise<void>
|
|
|
|
+}
|
|
|
|
|
|
-export interface StructureSelectionQuery {
|
|
|
|
- label: string
|
|
|
|
- query: StructureQuery
|
|
|
|
- expression: Expression
|
|
|
|
- description: string
|
|
|
|
|
|
+interface StructureSelectionQueryProps {
|
|
|
|
+ description?: string,
|
|
|
|
+ category?: string
|
|
|
|
+ isHidden?: boolean
|
|
|
|
+ ensureCustomProperties?: (ctx: CustomProperty.Context, structure: Structure) => Promise<void>
|
|
}
|
|
}
|
|
|
|
|
|
-export function StructureSelectionQuery(label: string, expression: Expression, description = ''): StructureSelectionQuery {
|
|
|
|
- return { label, expression, query: compile<StructureSelection>(expression), description }
|
|
|
|
|
|
+function StructureSelectionQuery(label: string, expression: Expression, props: StructureSelectionQueryProps = {}): StructureSelectionQuery {
|
|
|
|
+ let _query: StructureQuery
|
|
|
|
+ return {
|
|
|
|
+ label,
|
|
|
|
+ expression,
|
|
|
|
+ description: props.description || '',
|
|
|
|
+ category: props.category ?? StructureSelectionCategory.Misc,
|
|
|
|
+ isHidden: !!props.isHidden,
|
|
|
|
+ get query() {
|
|
|
|
+ if (!_query) _query = compile<StructureSelection>(expression)
|
|
|
|
+ return _query
|
|
|
|
+ },
|
|
|
|
+ ensureCustomProperties: props.ensureCustomProperties
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
-const all = StructureSelectionQuery('All', MS.struct.generator.all())
|
|
|
|
|
|
+const all = StructureSelectionQuery('All', MS.struct.generator.all(), { category: '' })
|
|
|
|
|
|
const polymer = StructureSelectionQuery('Polymer', MS.struct.modifier.union([
|
|
const polymer = StructureSelectionQuery('Polymer', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer'])
|
|
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'polymer'])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Type })
|
|
|
|
|
|
const trace = StructureSelectionQuery('Trace', MS.struct.modifier.union([
|
|
const trace = StructureSelectionQuery('Trace', MS.struct.modifier.union([
|
|
MS.struct.combinator.merge([
|
|
MS.struct.combinator.merge([
|
|
@@ -53,7 +97,7 @@ const trace = StructureSelectionQuery('Trace', MS.struct.modifier.union([
|
|
})
|
|
})
|
|
])
|
|
])
|
|
])
|
|
])
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Structure })
|
|
|
|
|
|
// TODO maybe pre-calculate atom properties like backbone/sidechain
|
|
// TODO maybe pre-calculate atom properties like backbone/sidechain
|
|
const backbone = StructureSelectionQuery('Backbone', MS.struct.modifier.union([
|
|
const backbone = StructureSelectionQuery('Backbone', MS.struct.modifier.union([
|
|
@@ -68,7 +112,7 @@ const backbone = StructureSelectionQuery('Backbone', MS.struct.modifier.union([
|
|
])
|
|
])
|
|
]),
|
|
]),
|
|
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
- 'atom-test': MS.core.set.has([MS.set(...Array.from(ProteinBackboneAtoms.values())), MS.ammp('label_atom_id')])
|
|
|
|
|
|
+ 'atom-test': MS.core.set.has([MS.set(...SetUtils.toArray(ProteinBackboneAtoms)), MS.ammp('label_atom_id')])
|
|
})
|
|
})
|
|
]),
|
|
]),
|
|
MS.struct.modifier.union([
|
|
MS.struct.modifier.union([
|
|
@@ -81,11 +125,11 @@ const backbone = StructureSelectionQuery('Backbone', MS.struct.modifier.union([
|
|
])
|
|
])
|
|
]),
|
|
]),
|
|
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
- 'atom-test': MS.core.set.has([MS.set(...Array.from(NucleicBackboneAtoms.values())), MS.ammp('label_atom_id')])
|
|
|
|
|
|
+ 'atom-test': MS.core.set.has([MS.set(...SetUtils.toArray(NucleicBackboneAtoms)), MS.ammp('label_atom_id')])
|
|
})
|
|
})
|
|
])
|
|
])
|
|
])
|
|
])
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Structure })
|
|
|
|
|
|
const protein = StructureSelectionQuery('Protein', MS.struct.modifier.union([
|
|
const protein = StructureSelectionQuery('Protein', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -97,7 +141,7 @@ const protein = StructureSelectionQuery('Protein', MS.struct.modifier.union([
|
|
])
|
|
])
|
|
])
|
|
])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Type })
|
|
|
|
|
|
const nucleic = StructureSelectionQuery('Nucleic', MS.struct.modifier.union([
|
|
const nucleic = StructureSelectionQuery('Nucleic', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -109,7 +153,7 @@ const nucleic = StructureSelectionQuery('Nucleic', MS.struct.modifier.union([
|
|
])
|
|
])
|
|
])
|
|
])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Type })
|
|
|
|
|
|
const proteinOrNucleic = StructureSelectionQuery('Protein or Nucleic', MS.struct.modifier.union([
|
|
const proteinOrNucleic = StructureSelectionQuery('Protein or Nucleic', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -121,7 +165,7 @@ const proteinOrNucleic = StructureSelectionQuery('Protein or Nucleic', MS.struct
|
|
])
|
|
])
|
|
])
|
|
])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Type })
|
|
|
|
|
|
const helix = StructureSelectionQuery('Helix', MS.struct.modifier.union([
|
|
const helix = StructureSelectionQuery('Helix', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -137,7 +181,7 @@ const helix = StructureSelectionQuery('Helix', MS.struct.modifier.union([
|
|
MS.core.type.bitflags([SecondaryStructureType.Flag.Helix])
|
|
MS.core.type.bitflags([SecondaryStructureType.Flag.Helix])
|
|
])
|
|
])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Residue })
|
|
|
|
|
|
const beta = StructureSelectionQuery('Beta Strand/Sheet', MS.struct.modifier.union([
|
|
const beta = StructureSelectionQuery('Beta Strand/Sheet', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -153,13 +197,13 @@ const beta = StructureSelectionQuery('Beta Strand/Sheet', MS.struct.modifier.uni
|
|
MS.core.type.bitflags([SecondaryStructureType.Flag.Beta])
|
|
MS.core.type.bitflags([SecondaryStructureType.Flag.Beta])
|
|
])
|
|
])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Residue })
|
|
|
|
|
|
const water = StructureSelectionQuery('Water', MS.struct.modifier.union([
|
|
const water = StructureSelectionQuery('Water', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'water'])
|
|
'entity-test': MS.core.rel.eq([MS.ammp('entityType'), 'water'])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Type })
|
|
|
|
|
|
const branched = StructureSelectionQuery('Carbohydrate', MS.struct.modifier.union([
|
|
const branched = StructureSelectionQuery('Carbohydrate', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -174,20 +218,20 @@ const branched = StructureSelectionQuery('Carbohydrate', MS.struct.modifier.unio
|
|
])
|
|
])
|
|
])
|
|
])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Type })
|
|
|
|
|
|
const branchedPlusConnected = StructureSelectionQuery('Carbohydrate with Connected', MS.struct.modifier.union([
|
|
const branchedPlusConnected = StructureSelectionQuery('Carbohydrate with Connected', MS.struct.modifier.union([
|
|
MS.struct.modifier.includeConnected({
|
|
MS.struct.modifier.includeConnected({
|
|
0: branched.expression, 'layer-count': 1, 'as-whole-residues': true
|
|
0: branched.expression, 'layer-count': 1, 'as-whole-residues': true
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Internal })
|
|
|
|
|
|
const branchedConnectedOnly = StructureSelectionQuery('Connected to Carbohydrate', MS.struct.modifier.union([
|
|
const branchedConnectedOnly = StructureSelectionQuery('Connected to Carbohydrate', MS.struct.modifier.union([
|
|
MS.struct.modifier.exceptBy({
|
|
MS.struct.modifier.exceptBy({
|
|
0: branchedPlusConnected.expression,
|
|
0: branchedPlusConnected.expression,
|
|
by: branched.expression
|
|
by: branched.expression
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Internal })
|
|
|
|
|
|
const ligand = StructureSelectionQuery('Ligand', MS.struct.modifier.union([
|
|
const ligand = StructureSelectionQuery('Ligand', MS.struct.modifier.union([
|
|
MS.struct.combinator.merge([
|
|
MS.struct.combinator.merge([
|
|
@@ -221,7 +265,7 @@ const ligand = StructureSelectionQuery('Ligand', MS.struct.modifier.union([
|
|
})
|
|
})
|
|
])
|
|
])
|
|
]),
|
|
]),
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Residue })
|
|
|
|
|
|
// don't include branched entities as they have their own link representation
|
|
// don't include branched entities as they have their own link representation
|
|
const ligandPlusConnected = StructureSelectionQuery('Ligand with Connected', MS.struct.modifier.union([
|
|
const ligandPlusConnected = StructureSelectionQuery('Ligand with Connected', MS.struct.modifier.union([
|
|
@@ -241,14 +285,14 @@ const ligandPlusConnected = StructureSelectionQuery('Ligand with Connected', MS.
|
|
]),
|
|
]),
|
|
by: branched.expression
|
|
by: branched.expression
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Internal })
|
|
|
|
|
|
const ligandConnectedOnly = StructureSelectionQuery('Connected to Ligand', MS.struct.modifier.union([
|
|
const ligandConnectedOnly = StructureSelectionQuery('Connected to Ligand', MS.struct.modifier.union([
|
|
MS.struct.modifier.exceptBy({
|
|
MS.struct.modifier.exceptBy({
|
|
0: ligandPlusConnected.expression,
|
|
0: ligandPlusConnected.expression,
|
|
by: ligand.expression
|
|
by: ligand.expression
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Internal })
|
|
|
|
|
|
// residues connected to ligands or branched entities
|
|
// residues connected to ligands or branched entities
|
|
const connectedOnly = StructureSelectionQuery('Connected to Ligand or Carbohydrate', MS.struct.modifier.union([
|
|
const connectedOnly = StructureSelectionQuery('Connected to Ligand or Carbohydrate', MS.struct.modifier.union([
|
|
@@ -256,7 +300,7 @@ const connectedOnly = StructureSelectionQuery('Connected to Ligand or Carbohydra
|
|
branchedConnectedOnly.expression,
|
|
branchedConnectedOnly.expression,
|
|
ligandConnectedOnly.expression
|
|
ligandConnectedOnly.expression
|
|
]),
|
|
]),
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Internal })
|
|
|
|
|
|
const disulfideBridges = StructureSelectionQuery('Disulfide Bridges', MS.struct.modifier.union([
|
|
const disulfideBridges = StructureSelectionQuery('Disulfide Bridges', MS.struct.modifier.union([
|
|
MS.struct.modifier.wholeResidues([
|
|
MS.struct.modifier.wholeResidues([
|
|
@@ -269,14 +313,7 @@ const disulfideBridges = StructureSelectionQuery('Disulfide Bridges', MS.struct.
|
|
})
|
|
})
|
|
])
|
|
])
|
|
])
|
|
])
|
|
-]))
|
|
|
|
-
|
|
|
|
-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')
|
|
|
|
- })
|
|
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Bond })
|
|
|
|
|
|
const nonStandardPolymer = StructureSelectionQuery('Non-standard Residues in Polymers', MS.struct.modifier.union([
|
|
const nonStandardPolymer = StructureSelectionQuery('Non-standard Residues in Polymers', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -284,7 +321,7 @@ const nonStandardPolymer = StructureSelectionQuery('Non-standard Residues in Pol
|
|
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
'residue-test': MS.ammp('isNonStandard')
|
|
'residue-test': MS.ammp('isNonStandard')
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Residue })
|
|
|
|
|
|
const coarse = StructureSelectionQuery('Coarse Elements', MS.struct.modifier.union([
|
|
const coarse = StructureSelectionQuery('Coarse Elements', MS.struct.modifier.union([
|
|
MS.struct.generator.atomGroups({
|
|
MS.struct.generator.atomGroups({
|
|
@@ -292,15 +329,15 @@ const coarse = StructureSelectionQuery('Coarse Elements', MS.struct.modifier.uni
|
|
MS.set('sphere', 'gaussian'), MS.ammp('objectPrimitive')
|
|
MS.set('sphere', 'gaussian'), MS.ammp('objectPrimitive')
|
|
])
|
|
])
|
|
})
|
|
})
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Residue })
|
|
|
|
|
|
const ring = StructureSelectionQuery('Rings in Residues', MS.struct.modifier.union([
|
|
const ring = StructureSelectionQuery('Rings in Residues', MS.struct.modifier.union([
|
|
MS.struct.generator.rings()
|
|
MS.struct.generator.rings()
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Residue })
|
|
|
|
|
|
const aromaticRing = StructureSelectionQuery('Aromatic Rings in Residues', MS.struct.modifier.union([
|
|
const aromaticRing = StructureSelectionQuery('Aromatic Rings in Residues', MS.struct.modifier.union([
|
|
MS.struct.generator.rings({ 'only-aromatic': true })
|
|
MS.struct.generator.rings({ 'only-aromatic': true })
|
|
-]))
|
|
|
|
|
|
+]), { category: StructureSelectionCategory.Residue })
|
|
|
|
|
|
const surroundings = StructureSelectionQuery('Surrounding Residues (5 \u212B) of Selection', MS.struct.modifier.union([
|
|
const surroundings = StructureSelectionQuery('Surrounding Residues (5 \u212B) of Selection', MS.struct.modifier.union([
|
|
MS.struct.modifier.exceptBy({
|
|
MS.struct.modifier.exceptBy({
|
|
@@ -311,20 +348,121 @@ const surroundings = StructureSelectionQuery('Surrounding Residues (5 \u212B) of
|
|
}),
|
|
}),
|
|
by: MS.internal.generator.current()
|
|
by: MS.internal.generator.current()
|
|
})
|
|
})
|
|
-]), 'Select residues within 5 \u212B of the current selection.')
|
|
|
|
|
|
+]), {
|
|
|
|
+ description: 'Select residues within 5 \u212B of the current selection.',
|
|
|
|
+ category: StructureSelectionCategory.Manipulate
|
|
|
|
+})
|
|
|
|
|
|
const complement = StructureSelectionQuery('Inverse / Complement of Selection', MS.struct.modifier.union([
|
|
const complement = StructureSelectionQuery('Inverse / Complement of Selection', MS.struct.modifier.union([
|
|
MS.struct.modifier.exceptBy({
|
|
MS.struct.modifier.exceptBy({
|
|
0: MS.struct.generator.all(),
|
|
0: MS.struct.generator.all(),
|
|
by: MS.internal.generator.current()
|
|
by: MS.internal.generator.current()
|
|
})
|
|
})
|
|
-]), 'Select everything not in the current selection.')
|
|
|
|
|
|
+]), {
|
|
|
|
+ description: 'Select everything not in the current selection.',
|
|
|
|
+ category: StructureSelectionCategory.Manipulate
|
|
|
|
+})
|
|
|
|
|
|
const bonded = StructureSelectionQuery('Residues Bonded to Selection', MS.struct.modifier.union([
|
|
const bonded = StructureSelectionQuery('Residues Bonded to Selection', MS.struct.modifier.union([
|
|
MS.struct.modifier.includeConnected({
|
|
MS.struct.modifier.includeConnected({
|
|
0: MS.internal.generator.current(), 'layer-count': 1, 'as-whole-residues': true
|
|
0: MS.internal.generator.current(), 'layer-count': 1, 'as-whole-residues': true
|
|
})
|
|
})
|
|
-]), 'Select residues covalently bonded to current selection.')
|
|
|
|
|
|
+]), {
|
|
|
|
+ description: 'Select residues covalently bonded to current selection.',
|
|
|
|
+ category: StructureSelectionCategory.Manipulate
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const hasClash = StructureSelectionQuery('Residues with Clashes', MS.struct.modifier.union([
|
|
|
|
+ MS.struct.modifier.wholeResidues([
|
|
|
|
+ MS.struct.modifier.union([
|
|
|
|
+ MS.struct.generator.atomGroups({
|
|
|
|
+ 'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
|
|
+ 'atom-test': ValidationReport.symbols.hasClash.symbol(),
|
|
|
|
+ })
|
|
|
|
+ ])
|
|
|
|
+ ])
|
|
|
|
+]), {
|
|
|
|
+ description: 'Select residues with clashes in the wwPDB validation report.',
|
|
|
|
+ category: StructureSelectionCategory.Residue,
|
|
|
|
+ ensureCustomProperties: (ctx, structure) => {
|
|
|
|
+ return ValidationReportProvider.attach(ctx, structure.models[0])
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const isBuried = StructureSelectionQuery('Buried Protein Residues', MS.struct.modifier.union([
|
|
|
|
+ MS.struct.modifier.wholeResidues([
|
|
|
|
+ MS.struct.modifier.union([
|
|
|
|
+ MS.struct.generator.atomGroups({
|
|
|
|
+ 'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
|
|
+ 'residue-test': AccessibleSurfaceAreaSymbols.isBuried.symbol(),
|
|
|
|
+ })
|
|
|
|
+ ])
|
|
|
|
+ ])
|
|
|
|
+]), {
|
|
|
|
+ description: 'Select buried protein residues.',
|
|
|
|
+ category: StructureSelectionCategory.Residue,
|
|
|
|
+ ensureCustomProperties: (ctx, structure) => {
|
|
|
|
+ return AccessibleSurfaceAreaProvider.attach(ctx, structure)
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const isAccessible = StructureSelectionQuery('Accessible Protein Residues', MS.struct.modifier.union([
|
|
|
|
+ MS.struct.modifier.wholeResidues([
|
|
|
|
+ MS.struct.modifier.union([
|
|
|
|
+ MS.struct.generator.atomGroups({
|
|
|
|
+ 'chain-test': MS.core.rel.eq([MS.ammp('objectPrimitive'), 'atomistic']),
|
|
|
|
+ 'residue-test': AccessibleSurfaceAreaSymbols.isAccessible.symbol(),
|
|
|
|
+ })
|
|
|
|
+ ])
|
|
|
|
+ ])
|
|
|
|
+]), {
|
|
|
|
+ description: 'Select accessible protein residues.',
|
|
|
|
+ category: StructureSelectionCategory.Residue,
|
|
|
|
+ ensureCustomProperties: (ctx, structure) => {
|
|
|
|
+ return AccessibleSurfaceAreaProvider.attach(ctx, structure)
|
|
|
|
+ }
|
|
|
|
+})
|
|
|
|
+
|
|
|
|
+const StandardAminoAcids = [
|
|
|
|
+ [['HIS'], 'HISTIDINE'],
|
|
|
|
+ [['ARG'], 'ARGININE'],
|
|
|
|
+ [['LYS'], 'LYSINE'],
|
|
|
|
+ [['ILE'], 'ISOLEUCINE'],
|
|
|
|
+ [['PHE'], 'PHENYLALANINE'],
|
|
|
|
+ [['LEU'], 'LEUCINE'],
|
|
|
|
+ [['TRP'], 'TRYPTOPHAN'],
|
|
|
|
+ [['ALA'], 'ALANINE'],
|
|
|
|
+ [['MET'], 'METHIONINE'],
|
|
|
|
+ [['CYS'], 'CYSTEINE'],
|
|
|
|
+ [['ASN'], 'ASPARAGINE'],
|
|
|
|
+ [['VAL'], 'VALINE'],
|
|
|
|
+ [['GLY'], 'GLYCINE'],
|
|
|
|
+ [['SER'], 'SERINE'],
|
|
|
|
+ [['GLN'], 'GLUTAMINE'],
|
|
|
|
+ [['TYR'], 'TYROSINE'],
|
|
|
|
+ [['ASP'], 'ASPARTIC ACID'],
|
|
|
|
+ [['GLU'], 'GLUTAMIC ACID'],
|
|
|
|
+ [['THR'], 'THREONINE'],
|
|
|
|
+ [['SEC'], 'SELENOCYSTEINE'],
|
|
|
|
+ [['PYL'], 'PYRROLYSINE'],
|
|
|
|
+].sort((a, b) => a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0) as [string[], string][]
|
|
|
|
+
|
|
|
|
+const StandardNucleicBases = [
|
|
|
|
+ [['A', 'DA'], 'ADENOSINE'],
|
|
|
|
+ [['C', 'DC'], 'CYTIDINE'],
|
|
|
|
+ [['T', 'DT'], 'THYMIDINE'],
|
|
|
|
+ [['G', 'DG'], 'GUANOSINE'],
|
|
|
|
+ [['I', 'DI'], 'INOSINE'],
|
|
|
|
+ [['U', 'DU'], 'URIDINE'],
|
|
|
|
+].sort((a, b) => a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0) as [string[], string][]
|
|
|
|
+
|
|
|
|
+function ResidueQuery([names, label]: [string[], string], category: string) {
|
|
|
|
+ return StructureSelectionQuery(`${stringToWords(label)} (${names.join(', ')})`, MS.struct.modifier.union([
|
|
|
|
+ MS.struct.generator.atomGroups({
|
|
|
|
+ 'residue-test': MS.core.set.has([MS.set(...names), MS.ammp('auth_comp_id')])
|
|
|
|
+ })
|
|
|
|
+ ]), { category })
|
|
|
|
+}
|
|
|
|
|
|
export const StructureSelectionQueries = {
|
|
export const StructureSelectionQueries = {
|
|
all,
|
|
all,
|
|
@@ -345,7 +483,6 @@ export const StructureSelectionQueries = {
|
|
ligandConnectedOnly,
|
|
ligandConnectedOnly,
|
|
connectedOnly,
|
|
connectedOnly,
|
|
disulfideBridges,
|
|
disulfideBridges,
|
|
- modified,
|
|
|
|
nonStandardPolymer,
|
|
nonStandardPolymer,
|
|
coarse,
|
|
coarse,
|
|
ring,
|
|
ring,
|
|
@@ -353,8 +490,18 @@ export const StructureSelectionQueries = {
|
|
surroundings,
|
|
surroundings,
|
|
complement,
|
|
complement,
|
|
bonded,
|
|
bonded,
|
|
|
|
+
|
|
|
|
+ hasClash,
|
|
|
|
+ isBuried,
|
|
|
|
+ isAccessible
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+export const StructureSelectionQueryList = [
|
|
|
|
+ ...Object.values(StructureSelectionQueries),
|
|
|
|
+ ...StandardAminoAcids.map(v => ResidueQuery(v, StructureSelectionCategory.AminoAcid)),
|
|
|
|
+ ...StandardNucleicBases.map(v => ResidueQuery(v, StructureSelectionCategory.NucleicBase)),
|
|
|
|
+]
|
|
|
|
+
|
|
export function applyBuiltInSelection(to: StateBuilder.To<PluginStateObject.Molecule.Structure>, query: keyof typeof StructureSelectionQueries, customTag?: string) {
|
|
export function applyBuiltInSelection(to: StateBuilder.To<PluginStateObject.Molecule.Structure>, query: keyof typeof StructureSelectionQueries, customTag?: string) {
|
|
return to.apply(StateTransforms.Model.StructureSelectionFromExpression,
|
|
return to.apply(StateTransforms.Model.StructureSelectionFromExpression,
|
|
{ expression: StructureSelectionQueries[query].expression, label: StructureSelectionQueries[query].label },
|
|
{ expression: StructureSelectionQueries[query].expression, label: StructureSelectionQueries[query].label },
|
|
@@ -384,17 +531,24 @@ export class StructureSelectionHelper {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- set(modifier: SelectionModifier, query: StructureQuery, applyGranularity = true) {
|
|
|
|
- for (const s of this.structures) {
|
|
|
|
- const current = this.plugin.helpers.structureSelectionManager.get(s)
|
|
|
|
- const currentSelection = Loci.isEmpty(current)
|
|
|
|
- ? StructureSelection.Empty(s)
|
|
|
|
- : StructureSelection.Singletons(s, StructureElement.Loci.toStructure(current))
|
|
|
|
-
|
|
|
|
- const result = query(new QueryContext(s, { currentSelection }))
|
|
|
|
- const loci = StructureSelection.toLociWithSourceUnits(result)
|
|
|
|
- this._set(modifier, loci, applyGranularity)
|
|
|
|
- }
|
|
|
|
|
|
+ async set(modifier: SelectionModifier, selectionQuery: StructureSelectionQuery, applyGranularity = true) {
|
|
|
|
+ this.plugin.runTask(Task.create('Structure Selection', async runtime => {
|
|
|
|
+ const ctx = { fetch: this.plugin.fetch, runtime }
|
|
|
|
+ for (const s of this.structures) {
|
|
|
|
+ const current = this.plugin.helpers.structureSelectionManager.get(s)
|
|
|
|
+ const currentSelection = Loci.isEmpty(current)
|
|
|
|
+ ? StructureSelection.Empty(s)
|
|
|
|
+ : StructureSelection.Singletons(s, StructureElement.Loci.toStructure(current))
|
|
|
|
+
|
|
|
|
+ if (selectionQuery.ensureCustomProperties) {
|
|
|
|
+ await selectionQuery.ensureCustomProperties(ctx, s)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const result = selectionQuery.query(new QueryContext(s, { currentSelection }))
|
|
|
|
+ const loci = StructureSelection.toLociWithSourceUnits(result)
|
|
|
|
+ this._set(modifier, loci, applyGranularity)
|
|
|
|
+ }
|
|
|
|
+ }))
|
|
}
|
|
}
|
|
|
|
|
|
constructor(private plugin: PluginContext) {
|
|
constructor(private plugin: PluginContext) {
|