Skip to content
Snippets Groups Projects
Commit 10cf0db0 authored by yakomaxa's avatar yakomaxa
Browse files

Within operator was implemented in RasMol

parent 08f1a1dc
No related branches found
No related tags found
No related merge requests found
...@@ -29,6 +29,16 @@ export function prefix(opParser: P.MonadicParser<any>, nextParser: P.MonadicPars ...@@ -29,6 +29,16 @@ export function prefix(opParser: P.MonadicParser<any>, nextParser: P.MonadicPars
return parser; return parser;
} }
export function prefixRemoveKet(opParser: P.MonadicParser<any>, nextParser: P.MonadicParser<any>, mapFn: any) {
const parser: P.MonadicParser<any> = P.MonadicParser.lazy(() => {
return P.MonadicParser.seq(opParser, parser.skip(P.MonadicParser.string(")")))
.map(x => mapFn(...x))
.or(nextParser);
});
return parser;
}
// Ideally this function would be just like `PREFIX` but reordered like // Ideally this function would be just like `PREFIX` but reordered like
// `P.seq(parser, opParser).or(nextParser)`, but that doesn't work. The // `P.seq(parser, opParser).or(nextParser)`, but that doesn't work. The
// reason for that is that Parsimmon will get stuck in infinite recursion, since // reason for that is that Parsimmon will get stuck in infinite recursion, since
...@@ -129,6 +139,11 @@ export function prefixOp(re: RegExp, group: number = 0) { ...@@ -129,6 +139,11 @@ export function prefixOp(re: RegExp, group: number = 0) {
return P.MonadicParser.regexp(re, group).skip(P.MonadicParser.whitespace); return P.MonadicParser.regexp(re, group).skip(P.MonadicParser.whitespace);
} }
export function prefixOpNoWhiteSpace(re: RegExp, group: number = 0) {
// return P.MonadicParser.regexp(re, group).skip(P.MonadicParser.regexp(/\s*/));
return P.MonadicParser.regexp(re, group).skip(P.MonadicParser.regexp(/\s*/));
}
export function postfixOp(re: RegExp, group: number = 0) { export function postfixOp(re: RegExp, group: number = 0) {
return P.MonadicParser.whitespace.then(P.MonadicParser.regexp(re, group)); return P.MonadicParser.whitespace.then(P.MonadicParser.regexp(re, group));
} }
......
\[/** /**
* Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. * Copyright (c) 2017-2021 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>
...@@ -60,7 +60,7 @@ function elementListMap(x: string) { ...@@ -60,7 +60,7 @@ function elementListMap(x: string) {
// }; // };
// } // }
export const special_properties: PropertyDict = { export const macroproperties: PropertyDict = {
symbol: { symbol: {
'@desc': 'chemical-symbol-list: list of 1- or 2-letter chemical symbols from the periodic table', '@desc': 'chemical-symbol-list: list of 1- or 2-letter chemical symbols from the periodic table',
'@examples': ['symbol O+N'], '@examples': ['symbol O+N'],
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com> * @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
* *
* @author Koya Sakuma * @author Koya Sakuma
* This module is based on jmol transpiler from MolQL and modified in similar manner as pymol and vmd tranpilers. \ * This module is based on jmol transpiler from MolQL and modified in similar manner as pymol and vmd tranpilers
*/ */
...@@ -14,6 +14,10 @@ import { MolScriptBuilder } from '../../../mol-script/language/builder'; ...@@ -14,6 +14,10 @@ import { MolScriptBuilder } from '../../../mol-script/language/builder';
const B = MolScriptBuilder; const B = MolScriptBuilder;
import { OperatorList } from '../types'; import { OperatorList } from '../types';
import { Expression } from '../../language/expression'; import { Expression } from '../../language/expression';
import { macroproperties } from './macroproperties'
const propNames = Object.keys(macroproperties).sort(h.strLenSortFn)
.filter(name => !macroproperties[name].isUnsupported).join('|');
export const operators: OperatorList = [ export const operators: OperatorList = [
...@@ -30,7 +34,8 @@ export const operators: OperatorList = [ ...@@ -30,7 +34,8 @@ export const operators: OperatorList = [
'@examples': ['ASP and .CA'], '@examples': ['ASP and .CA'],
name: 'and', name: 'and',
type: h.binaryLeft, type: h.binaryLeft,
rule: h.infixOp(/AND|&/i), rule: P.MonadicParser.alt(h.infixOp(/AND|&/i), P.MonadicParser.whitespace),
//rule: h.infixOp(/AND|&/i),
map: (op, selection, by) => B.struct.modifier.intersectBy({ 0: selection, by }) map: (op, selection, by) => B.struct.modifier.intersectBy({ 0: selection, by })
}, },
{ {
...@@ -41,15 +46,70 @@ export const operators: OperatorList = [ ...@@ -41,15 +46,70 @@ export const operators: OperatorList = [
rule: h.infixOp(/OR|\||\|\|/i), rule: h.infixOp(/OR|\||\|\|/i),
map: (op, s1, s2) => B.struct.combinator.merge([s1, s2]) map: (op, s1, s2) => B.struct.combinator.merge([s1, s2])
}, },
/*
{ {
'@desc': 'Selects atoms within a specified distance of a selection', '@desc': 'Selects atoms within a specified distance of a selection',
'@examples': ['within 5 of name FE'], '@examples': ['within (5.0, LYS:A.CA)'],
name: 'within', name: 'aaa',
type: h.prefix, type: h.prefixRemoveKet,
rule: h.prefixOp(/within\s+([-+]?[0-9]*\.?[0-9]+)\s+of/, 1).map((x: any) => parseFloat(x)), rule: h.prefixOpNoWhiteSpace(/within\s*\(\s*([-+]?[0-9]*\.?[0-9]+)\s*,/, 1).map((x: any) => {
console.log(x)
return parseFloat(x)}),
map: (radius: number, selection: Expression) => { map: (radius: number, selection: Expression) => {
return B.struct.modifier.includeSurroundings({ 0: selection, radius }); return B.struct.modifier.includeSurroundings({ 0: selection, radius });
} }
}, },
*/
{
'@desc':'Selects atoms in s1 that are within X Angstroms of any atom in s2.',
'@examples': ['chain A WITHIN 3 OF chain B'],
name: 'within',
abbr: ['w2.'],
// type: h.binaryLeft,
type: h.prefixRemoveKet,
rule: h.prefixOpNoWhiteSpace(/within\s*\(\s*([-+]?[0-9]*\.?[0-9]+)\s*,/i, 1).map((x: any) => {
console.log(x)
return parseFloat(x)}),
map: (radius: number, target: Expression) => {
return B.struct.filter.within({
0: B.struct.generator.all(),
target,
'max-radius': radius,
});
},
},
{
'@desc': 'Selects atoms which have the same keyword as the atoms in a given selection',
'@examples': ['same resid as name FE'],
name: 'same',
type: h.prefix,
rule: h.prefixOp(new RegExp(`SAME\\s+(${propNames})\\s+AS`, 'i'), 1).map((x: any) => macroproperties[x].property),
map: (property: Expression, source: Expression) => {
return B.struct.filter.withSameAtomProperties({
'0': B.struct.generator.all(),
source,
property
});
}
},
{
'@desc':
'Selects atoms in s1 whose identifiers name and resi match atoms in s2.',
'@examples': ['chain A LIKE chain B'],
name: 'like',
type: h.binaryLeft,
rule: h.infixOp(/LIKE|l\./i),
map: (op: string, selection: Expression, source: Expression) => {
return B.struct.filter.withSameAtomProperties({
0: selection,
source,
property: B.core.type.compositeKey([
B.ammp('label_atom_id'),
B.ammp('label_seq_id'),
]),
});
},
},
]; ];
...@@ -12,9 +12,9 @@ import * as h from '../helper'; ...@@ -12,9 +12,9 @@ import * as h from '../helper';
import { MolScriptBuilder } from '../../../mol-script/language/builder'; import { MolScriptBuilder } from '../../../mol-script/language/builder';
const B = MolScriptBuilder; const B = MolScriptBuilder;
import { properties } from './properties'; import { properties } from './properties';
import { special_properties } from './special_properties'; import { macroproperties } from './macroproperties';
import { special_keywords } from './special_keywords'; //import { macrokeywords } from './macrokeywords';
import { special_operators } from './special_operators'; //import { macrooperators } from './macrooperators';
import { operators } from './operators'; import { operators } from './operators';
import { keywords } from './keywords'; import { keywords } from './keywords';
import { AtomGroupArgs } from '../types'; import { AtomGroupArgs } from '../types';
...@@ -25,7 +25,7 @@ import { Transpiler } from '../transpiler'; ...@@ -25,7 +25,7 @@ import { Transpiler } from '../transpiler';
// const slash = P.MonadicParser.string('/'); // const slash = P.MonadicParser.string('/');
const propertiesDict = h.getPropertyRules(special_properties); const propertiesDict = h.getPropertyRules(macroproperties);
// const slash = P.MonadicParser.string('/'); // const slash = P.MonadicParser.string('/');
const dot = P.MonadicParser.string('.'); const dot = P.MonadicParser.string('.');
...@@ -49,7 +49,7 @@ function atomSelectionQuery2(x: any) { ...@@ -49,7 +49,7 @@ function atomSelectionQuery2(x: any) {
const props: { [k: string]: any[] } = {}; const props: { [k: string]: any[] } = {};
for (const k in x) { for (const k in x) {
const ps = special_properties[k]; const ps = macroproperties[k];
if (!ps) { if (!ps) {
throw new Error(`property '${k}' not supported, value '${x[k]}'`); throw new Error(`property '${k}' not supported, value '${x[k]}'`);
} }
...@@ -65,33 +65,12 @@ function atomSelectionQuery2(x: any) { ...@@ -65,33 +65,12 @@ function atomSelectionQuery2(x: any) {
return B.struct.generator.atomGroups(tests); return B.struct.generator.atomGroups(tests);
} }
function atomExpressionQuery(x: any[]) { //function atomExpressionQuery(x: any[]) {
const resname = x[0]; // const resname = x[0];
// const tests: AtomGroupArgs = {}; // if (resname){
// return B.struct.generator.atomGroups({'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), resname])})
/* if (chainname) { // }
// should be configurable, there is an option in Jmol to use auth or label //}
tests['chain-test'] = B.core.rel.eq([B.ammp('auth_asym_id'), chainname]);
}
const resProps = [];
if (resno) resProps.push(B.core.rel.eq([B.ammp('auth_seq_id'), resno]));
if (inscode) resProps.push(B.core.rel.eq([B.ammp('pdbx_PDB_ins_code'), inscode]));
if (resProps.length) tests['residue-test'] = h.andExpr(resProps);
const atomProps = [];
if (atomname) atomProps.push(B.core.rel.eq([B.ammp('auth_atom_id'), atomname]));
if (altloc) atomProps.push(B.core.rel.eq([B.ammp('label_alt_id'), altloc]));
if (atomProps.length) tests['atom-test'] = h.andExpr(atomProps);
return B.struct.generator.atomGroups(tests);
*/
if (resname){
return B.struct.generator.atomGroups({'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), resname])})
}
}
const lang = P.MonadicParser.createLanguage({ const lang = P.MonadicParser.createLanguage({
...@@ -109,11 +88,17 @@ const lang = P.MonadicParser.createLanguage({ ...@@ -109,11 +88,17 @@ const lang = P.MonadicParser.createLanguage({
r.Keywords, r.Keywords,
r.NamedAtomProperties, r.NamedAtomProperties,
r.AtomSelectionMacro.map(atomSelectionQuery2), r.AtomSelectionMacro.map(atomSelectionQuery2),
// r.AtomExpression.map(atomExpressionQuery), // r.AtomExparession.map(atomExpressionQuery),
r.Object r.Object,
r.Object2,
); );
}, },
// AtomExpression: function (r: any) {
// return P.MonadicParser.seq(r.Resname.or(P.MonadicParser.of(null)));
// },
// lys:a.ca -> resn lys and chain A and name ca // lys:a.ca -> resn lys and chain A and name ca
// lys*a.ca -> resn lys and chain A and name ca // lys*a.ca -> resn lys and chain A and name ca
...@@ -200,29 +185,32 @@ const lang = P.MonadicParser.createLanguage({ ...@@ -200,29 +185,32 @@ const lang = P.MonadicParser.createLanguage({
}, },
ObjectProperty: () => { ObjectProperty: () => {
const w = h.getReservedWords(special_properties, special_keywords, special_operators) const w = h.getReservedWords(macroproperties, keywords, operators)
.sort(h.strLenSortFn).map(h.escapeRegExp).join('|'); .sort(h.strLenSortFn).map(h.escapeRegExp).join('|');
return P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i')); return P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i'));
}, },
Object: (r: any) => {
return r.ObjectProperty
.map((x: any) => { throw new Error(`property 'object' not supported, value '${x}'`); });
},
ObjectProperty2: () => { ObjectProperty2: () => {
const w = h.getReservedWords(properties, keywords, operators) const w = h.getReservedWords(properties, keywords, operators)
.sort(h.strLenSortFn).map(h.escapeRegExp).join('|'); .sort(h.strLenSortFn).map(h.escapeRegExp).join('|');
return P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i')); return P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i'));
}, },
Object: (r: any) => { Object2: (r: any) => {
return r.ObjectProperty2 return r.ObjectProperty2
.map((x: any) => { throw new Error(`property 'object' not supported, value '${x}'`); }); .map((x: any) => { throw new Error(`property 'object' not supported, value '${x}'`); });
}, },
AtomExpression: function (r: any) {
return P.MonadicParser.seq(r.Resname.or(P.MonadicParser.of(null)));
},
// Resname: () => P.MonadicParser.regexp(s/[a-zA-Z0-9]{1,4}/).desc('resname'), // Resname: () => P.MonadicParser.regexp(s/[a-zA-Z0-9]{1,4}/).desc('resname'),
Resname: () => P.MonadicParser.regexp(/\[[A-Z0-9]{1,4}\]/).desc('resname'), // Resname: () => P.MonadicParser.regexp(/\[[A-Z0-9]{1,4}\]/).desc('resname'),
NamedAtomProperties: function () { NamedAtomProperties: function () {
return P.MonadicParser.alt(...h.getNamedPropertyRules(properties)); return P.MonadicParser.alt(...h.getNamedPropertyRules(properties));
......
/**
* Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
*/
import { MolScriptBuilder } from '../../../mol-script/language/builder';
const B = MolScriptBuilder;
import * as h from '../helper';
import { KeywordDict } from '../types';
const ResDict = {
nucleic: ['A', 'C', 'T', 'G', 'U', 'DA', 'DC', 'DT', 'DG', 'DU'],
protein: ['ALA', 'ARG', 'ASN', 'ASP', 'CYS', 'CYX', 'GLN', 'GLU', 'GLY', 'HIS', 'HID', 'HIE', 'HIP', 'ILE', 'LEU', 'LYS', 'MET', 'MSE', 'PHE', 'PRO', 'SER', 'THR', 'TRP', 'TYR', 'VAL'],
solvent: ['HOH', 'WAT', 'H20', 'TIP', 'SOL']
};
const Backbone = {
nucleic: ['P', "O3'", "O5'", "C5'", "C4'", "C3'", 'OP1', 'OP2', 'O3*', 'O5*', 'C5*', 'C4*', 'C3*'],
protein: ['C', 'N', 'CA', 'O']
};
export const special_keywords: KeywordDict = {
all: {
'@desc': 'All atoms currently loaded into PyMOL',
abbr: ['*'],
map: () => B.struct.generator.all()
},
none: {
'@desc': 'No atoms (empty selection)',
map: () => B.struct.generator.empty()
},
hydrogens: {
'@desc': 'All hydrogen atoms currently loaded into PyMOL',
abbr: ['hydro', 'h.'],
map: () => B.struct.generator.atomGroups({
'atom-test': B.core.rel.eq([
B.acp('elementSymbol'),
B.es('H')
])
})
},
hetatm: {
'@desc': 'All atoms loaded from Protein Data Bank HETATM records',
abbr: ['het'],
map: () => B.struct.generator.atomGroups({
'atom-test': B.core.rel.eq([B.ammp('isHet'), true])
})
},
visible: {
'@desc': 'All atoms in enabled objects with at least one visible representation',
abbr: ['v.']
},
polymer: {
'@desc': 'All atoms on the polymer (not het). Finds atoms with residue identifiers matching a known polymer, such a peptide and DNA.',
abbr: ['pol.'],
map: () => B.struct.generator.atomGroups({
'residue-test': B.core.set.has([
B.core.type.set(ResDict.nucleic.concat(ResDict.protein)),
B.ammp('label_comp_id')
])
})
},
sidechain: {
'@desc': 'Polymer non-backbone atoms (new in PyMOL 1.6.1)',
},
present: {
'@desc': 'All atoms with defined coordinates in the current state (used in creating movies)',
abbr: ['pr.']
},
center: {
'@desc': 'Pseudo-atom at the center of the scene'
},
origin: {
'@desc': 'Pseudo-atom at the origin of rotation',
},
enabled: {
'@desc': 'All enabled objects or selections from the object list.',
},
masked: {
'@desc': 'All masked atoms.',
abbr: ['msk.']
},
protected: {
'@desc': 'All protected atoms.',
abbr: ['pr.']
},
bonded: {
'@desc': 'All bonded atoms',
map: () => B.struct.generator.atomGroups({
'atom-test': B.core.rel.gr([B.struct.atomProperty.core.bondCount({
flags: B.struct.type.bondFlags(['covalent', 'metallic', 'sulfide'])
}), 0])
})
},
donors: {
'@desc': 'All hydrogen bond donor atoms.',
abbr: ['don.']
},
acceptors: {
'@desc': 'All hydrogen bond acceptor atoms.',
abbr: ['acc.']
},
fixed: {
'@desc': 'All fixed atoms.',
abbr: ['fxd.']
},
restrained: {
'@desc': 'All restrained atoms.',
abbr: ['rst.']
},
organic: {
'@desc': 'All atoms in non-polymer organic compounds (e.g. ligands, buffers). Finds carbon-containing molecules that do not match known polymers.',
abbr: ['org.'],
map: () => h.asAtoms(B.struct.modifier.expandProperty({
'0': B.struct.modifier.union([
B.struct.generator.queryInSelection({
'0': B.struct.generator.atomGroups({
'residue-test': B.core.logic.not([
B.core.set.has([
B.core.type.set(ResDict.nucleic.concat(ResDict.protein)),
B.ammp('label_comp_id')
])
])
}),
query: B.struct.generator.atomGroups({
'atom-test': B.core.rel.eq([
B.es('C'),
B.acp('elementSymbol')
])
})
})
]),
property: B.ammp('residueKey')
}))
},
inorganic: {
'@desc': 'All non-polymer inorganic atoms/ions. Finds atoms in molecules that do not contain carbon and do not match any known solvent residues.',
abbr: ['ino.'],
map: () => h.asAtoms(B.struct.modifier.expandProperty({
'0': B.struct.modifier.union([
B.struct.filter.pick({
'0': B.struct.generator.atomGroups({
'residue-test': B.core.logic.not([
B.core.set.has([
B.core.type.set(ResDict.nucleic.concat(ResDict.protein).concat(ResDict.solvent)),
B.ammp('label_comp_id')
])
]),
'group-by': B.ammp('residueKey')
}),
test: B.core.logic.not([
B.core.set.has([
B.struct.atomSet.propertySet([B.acp('elementSymbol')]),
B.es('C')
])
])
})
]),
property: B.ammp('residueKey')
}))
},
solvent: {
'@desc': 'All water molecules. The hardcoded solvent residue identifiers are currently: HOH, WAT, H20, TIP, SOL.',
abbr: ['sol.'],
map: () => B.struct.generator.atomGroups({
'residue-test': B.core.set.has([
B.core.type.set(ResDict.solvent),
B.ammp('label_comp_id')
])
})
},
guide: {
'@desc': 'All protein CA and nucleic acid C4*/C4',
map: () => B.struct.combinator.merge([
B.struct.generator.atomGroups({
'atom-test': B.core.rel.eq([
B.atomName('CA'),
B.ammp('label_atom_id')
]),
'residue-test': B.core.set.has([
B.core.type.set(ResDict.protein),
B.ammp('label_comp_id')
])
}),
B.struct.generator.atomGroups({
'atom-test': B.core.set.has([
h.atomNameSet(['C4*', 'C4']),
B.ammp('label_atom_id')
]),
'residue-test': B.core.set.has([
B.core.type.set(ResDict.nucleic),
B.ammp('label_comp_id')
])
})
]),
},
metals: {
'@desc': 'All metal atoms (new in PyMOL 1.6.1)'
},
backbone: {
'@desc': 'the C, N, CA, and O atoms of a protein and the equivalent atoms in a nucleic acid.',
map: () => B.struct.generator.atomGroups({
'atom-test': B.core.set.has([
B.core.type.set(Backbone.protein.concat(ResDict.protein)),
B.ammp('label_atom_id')
])
}),
},
proteinxxxxxx: {
'@desc': 'protein................',
abbr: ['polymer.protein'],
map: () => B.struct.generator.atomGroups({
'residue-test': B.core.set.has([
B.core.type.set(ResDict.protein),
B.ammp('label_comp_id')
])
})
},
nucleicxxxxx: {
'@desc': 'protein................',
abbr: ['polymer.nucleic'],
map: () => B.struct.generator.atomGroups({
'residue-test': B.core.set.has([
B.core.type.set(ResDict.nucleic),
B.ammp('label_comp_id')
])
})
}
};
/**
* Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
* @author Panagiotis Tourlas <panagiot_tourlov@hotmail.com>
*/
import * as P from '../../../mol-util/monadic-parser';
import * as h from '../helper';
import { MolScriptBuilder } from '../../../mol-script/language/builder';
const B = MolScriptBuilder;
import { OperatorList } from '../types';
import { Expression } from '../../language/expression';
export const special_operators: OperatorList = [
{
'@desc': 'Selects atoms that are not included in s1.',
'@examples': [
'NOT resn ALA',
'not (resi 42 or chain A)',
'!resi 42 or chain A',
],
name: 'not',
type: h.prefix,
rule: P.MonadicParser.alt(
P.MonadicParser.regexp(/NOT/i).skip(P.MonadicParser.whitespace),
P.MonadicParser.string('!').skip(P.MonadicParser.optWhitespace)
),
map: (op, selection) => h.invertExpr(selection),
},
{
'@desc': 'Selects atoms included in both s1 and s2.',
'@examples': ['chain A AND name CA'],
name: 'and',
type: h.binaryLeft,
rule: h.infixOp(/AND|&/i),
map: (op, selection, by) =>
B.struct.modifier.intersectBy({ 0: selection, by }),
},
{
'@desc': 'Selects atoms included in either s1 or s2.',
'@examples': ['chain A OR chain B'],
name: 'or',
type: h.binaryLeft,
rule: h.infixOp(/OR|\|/i),
map: (op: string, s1: Expression, s2: Expression) => B.struct.combinator.merge([s1, s2]),
},
{
'@desc':
'Selects atoms in s1 whose identifiers name, resi, resn, chain and segi all match atoms in s2.',
'@examples': ['chain A IN chain B'],
name: 'in',
type: h.binaryLeft,
rule: h.infixOp(/IN/i),
map: (op: string, selection: Expression, source: Expression) => {
return B.struct.filter.withSameAtomProperties({
0: selection,
source,
property: B.core.type.compositeKey([
B.ammp('label_atom_id'),
B.ammp('label_seq_id'),
B.ammp('label_comp_id'),
B.ammp('auth_asym_id'),
B.ammp('label_asym_id'),
]),
});
},
},
{
'@desc':
'Selects atoms in s1 whose identifiers name and resi match atoms in s2.',
'@examples': ['chain A LIKE chain B'],
name: 'like',
type: h.binaryLeft,
rule: h.infixOp(/LIKE|l\./i),
map: (op: string, selection: Expression, source: Expression) => {
return B.struct.filter.withSameAtomProperties({
0: selection,
source,
property: B.core.type.compositeKey([
B.ammp('label_atom_id'),
B.ammp('label_seq_id'),
]),
});
},
},
{
'@desc':
'Selects all atoms whose van der Waals radii are separated from the van der Waals radii of s1 by a minimum of X Angstroms.',
'@examples': ['solvent GAP 2'],
name: 'gap',
type: h.postfix,
rule: h
.postfixOp(/GAP\s+([-+]?[0-9]*\.?[0-9]+)/i, 1)
.map((x: any) => parseFloat(x)),
map: (distance: number, target: Expression) => {
return B.struct.filter.within({
'0': B.struct.generator.all(),
target,
'atom-radius': B.acp('vdw'),
'max-radius': distance,
invert: true,
});
},
},
{
'@desc':
'Selects atoms with centers within X Angstroms of the center of any atom in s1.',
'@examples': ['resname LIG AROUND 1'],
name: 'around',
abbr: ['a.'],
type: h.postfix,
rule: h
.postfixOp(/(AROUND|a\.)\s+([-+]?[0-9]*\.?[0-9]+)/i, 2)
.map((x: any) => parseFloat(x)),
map: (radius: number, target: Expression) => {
return B.struct.modifier.exceptBy({
'0': B.struct.filter.within({
'0': B.struct.generator.all(),
target,
'max-radius': radius,
}),
by: target,
});
},
},
{
'@desc':
'Expands s1 by all atoms within X Angstroms of the center of any atom in s1.',
'@examples': ['chain A EXPAND 3'],
name: 'expand',
abbr: ['x.'],
type: h.postfix,
rule: h
.postfixOp(/(EXPAND|x\.)\s+([-+]?[0-9]*\.?[0-9]+)/i, 2)
.map((x: any) => parseFloat(x)),
map: (radius: number, selection: Expression) => {
return B.struct.modifier.includeSurroundings({ 0: selection, radius });
},
},
{
'@desc':
'Selects atoms in s1 that are within X Angstroms of any atom in s2.',
'@examples': ['chain A WITHIN 3 OF chain B'],
name: 'within',
abbr: ['w.'],
type: h.binaryLeft,
rule: h.ofOp('WITHIN', 'w.'),
map: (radius: number, selection: Expression, target: Expression) => {
return B.struct.filter.within({
0: selection,
target,
'max-radius': radius,
});
},
},
{
'@desc':
'Same as within, but excludes s2 from the selection (and thus is identical to s1 and s2 around X).',
'@examples': ['chain A NEAR_TO 3 OF chain B'],
name: 'near_to',
abbr: ['nto.'],
type: h.binaryLeft,
rule: h.ofOp('NEAR_TO', 'nto.'),
map: (radius: number, selection: Expression, target: Expression) => {
return B.struct.modifier.exceptBy({
'0': B.struct.filter.within({
'0': selection,
target,
'max-radius': radius,
}),
by: target,
});
},
},
{
'@desc': 'Selects atoms in s1 that are at least X Anstroms away from s2.',
'@examples': ['solvent BEYOND 2 OF chain A'],
name: 'beyond',
abbr: ['be.'],
type: h.binaryLeft,
rule: h.ofOp('BEYOND', 'be.'),
map: (radius: number, selection: Expression, target: Expression) => {
return B.struct.modifier.exceptBy({
'0': B.struct.filter.within({
'0': selection,
target,
'max-radius': radius,
invert: true,
}),
by: target,
});
},
},
{
'@desc': 'Expands selection to complete residues.',
'@examples': ['BYRESIDUE name N'],
name: 'byresidue',
abbr: ['byresi', 'byres', 'br.'],
type: h.prefix,
rule: h.prefixOp(/BYRESIDUE|byresi|byres|br\./i),
map: (op: string, selection: Expression) => {
return h.asAtoms(
B.struct.modifier.expandProperty({
'0': B.struct.modifier.union({ 0: selection }),
property: B.ammp('residueKey'),
})
);
},
},
{
'@desc':
'Completely selects all alpha carbons in all residues covered by a selection.',
'@examples': ['BYCALPHA chain A'],
name: 'bycalpha',
abbr: ['bca.'],
type: h.prefix,
rule: h.prefixOp(/BYCALPHA|bca\./i),
map: (op: string, selection: Expression) => {
return B.struct.generator.queryInSelection({
'0': B.struct.modifier.expandProperty({
'0': B.struct.modifier.union({ 0: selection }),
property: B.ammp('residueKey'),
}),
query: B.struct.generator.atomGroups({
'atom-test': B.core.rel.eq([
B.atomName('CA'),
B.ammp('label_atom_id'),
]),
}),
});
},
},
{
'@desc': 'Expands selection to complete molecules.',
'@examples': ['BYMOLECULE resi 20-30'],
name: 'bymolecule',
isUnsupported: true, // structure-query.atom-property.topology.connected-component-key' is not implemented
abbr: ['bymol', 'bm.'],
type: h.prefix,
rule: h.prefixOp(/BYMOLECULE|bymol|bm\./i),
map: (op: string, selection: Expression) => {
return h.asAtoms(
B.struct.modifier.expandProperty({
'0': B.struct.modifier.union({ 0: selection }),
property: B.atp('connectedComponentKey'),
})
);
},
},
{
'@desc': 'Expands selection to complete fragments.',
'@examples': ['BYFRAGMENT resi 10'],
name: 'byfragment',
abbr: ['byfrag', 'bf.'],
isUnsupported: true,
type: h.prefix,
rule: h.prefixOp(/BYFRAGMENT|byfrag|bf\./i),
map: (op: string, selection: Expression) => [op, selection],
},
{
'@desc': 'Expands selection to complete segments.',
'@examples': ['BYSEGMENT resn CYS'],
name: 'bysegment',
abbr: ['bysegi', 'byseg', 'bs.'],
type: h.prefix,
rule: h.prefixOp(/BYSEGMENT|bysegi|byseg|bs\./i),
map: (op: string, selection: Expression) => {
return h.asAtoms(
B.struct.modifier.expandProperty({
'0': B.struct.modifier.union({ 0: selection }),
property: B.ammp('chainKey'),
})
);
},
},
{
'@desc': 'Expands selection to complete objects.',
'@examples': ['BYOBJECT chain A'],
name: 'byobject',
abbr: ['byobj', 'bo.'],
isUnsupported: true,
type: h.prefix,
rule: h.prefixOp(/BYOBJECT|byobj|bo\./i),
map: (op: string, selection: Expression) => [op, selection],
},
{
'@desc': 'Expands selection to unit cell.',
'@examples': ['BYCELL chain A'],
name: 'bycell',
isUnsupported: true,
type: h.prefix,
rule: h.prefixOp(/BYCELL/i),
map: (op: string, selection: Expression) => [op, selection],
},
{
'@desc': 'All rings of size ≤ 7 which have at least one atom in s1.',
'@examples': ['BYRING resn HEM'],
name: 'byring',
// isUnsupported: true, // structure-query.atom-set.atom-count' is not implemented.
type: h.prefix,
rule: h.prefixOp(/BYRING/i),
map: (op: string, selection: Expression) => {
return h.asAtoms(
B.struct.modifier.intersectBy({
'0': B.struct.filter.pick({
'0': B.struct.generator.rings(),
test: B.core.logic.and([
B.core.rel.lte([B.struct.atomSet.atomCount(), 7]),
B.core.rel.gr([B.struct.atomSet.countQuery([selection]), 1]),
]),
}),
by: selection,
})
);
},
},
{
'@desc': 'Selects atoms directly bonded to s1, excludes s1.',
'@examples': ['NEIGHBOR resn CYS'],
name: 'neighbor',
type: h.prefix,
abbr: ['nbr.'],
rule: h.prefixOp(/NEIGHBOR|nbr\./i),
map: (op: string, selection: Expression) => {
return B.struct.modifier.exceptBy({
'0': h.asAtoms(
B.struct.modifier.includeConnected({
'0': B.struct.modifier.union({ 0: selection }),
'bond-test': true,
})
),
by: selection,
});
},
},
{
'@desc': 'Selects atoms directly bonded to s1, may include s1.',
'@examples': ['BOUND_TO name CA'],
name: 'bound_to',
abbr: ['bto.'],
type: h.prefix,
rule: h.prefixOp(/BOUND_TO|bto\./i),
map: (op: string, selection: Expression) => {
return h.asAtoms(
B.struct.modifier.includeConnected({
'0': B.struct.modifier.union({ 0: selection }),
})
);
},
},
{
'@desc': 'Extends s1 by X bonds connected to atoms in s1.',
'@examples': ['resname LIG EXTEND 3'],
name: 'extend',
abbr: ['xt.'],
type: h.postfix,
rule: h.postfixOp(/(EXTEND|xt\.)\s+([0-9]+)/i, 2).map((x: any) => parseInt(x)),
map: (count: number, selection: Expression) => {
return h.asAtoms(
B.struct.modifier.includeConnected({
'0': B.struct.modifier.union({ 0: selection }),
'bond-test': true,
'layer-count': count,
})
);
},
},
];
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*/ */
import { properties } from './properties'; import { properties } from './properties';
import { macroproperties } from './macroproperties';
import { operators } from './operators'; import { operators } from './operators';
import { keywords } from './keywords'; import { keywords } from './keywords';
...@@ -17,6 +18,11 @@ for (const name in properties) { ...@@ -17,6 +18,11 @@ for (const name in properties) {
Properties.push(name); Properties.push(name);
if (properties[name].abbr) Properties.push(...properties[name].abbr!); if (properties[name].abbr) Properties.push(...properties[name].abbr!);
} }
for (const name in macroproperties) {
if (macroproperties[name].isUnsupported) continue;
Properties.push(name);
if (macroproperties[name].abbr) Properties.push(...macroproperties[name].abbr!);
}
export const Operators: string[] = []; export const Operators: string[] = [];
operators.forEach(o => { operators.forEach(o => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment