|
@@ -20,29 +20,63 @@ import { Transpiler } from '../transpiler';
|
|
|
function listMap(x: string) { return x.split(',').map(x => x.replace(/^["']|["']$/g, '')); }
|
|
|
|
|
|
function listOrRangeMap(x: string) {
|
|
|
+ // cases
|
|
|
+ // case1: 1-100,200
|
|
|
+ console.log(x)
|
|
|
if (x.includes('-') && x.includes(',')) {
|
|
|
const pSplit = x.split(',').map(x => x.replace(/^["']|["']$/g, ''));
|
|
|
const res: number[] = [];
|
|
|
pSplit.forEach(x => {
|
|
|
- if (x.includes('-')) {
|
|
|
+ if (x.includes('-') && !x.startsWith("-")) {
|
|
|
const [min, max] = x.split('-').map(x=>parseInt(x));
|
|
|
for (let i = min; i <= max; i++) {
|
|
|
res.push(i);
|
|
|
}
|
|
|
- } else {
|
|
|
+ }else if (x.includes('-') && x.startsWith("-") && x.match(/[0-9]+-[-0-9]+/)) {
|
|
|
+ const min = -parseInt(x.split('-')[1]);
|
|
|
+ var max ;
|
|
|
+ if (x.includes('--')) {
|
|
|
+ max = -parseInt(x.split('-')[3])
|
|
|
+ }else{
|
|
|
+ max = parseInt(x.split('-')[2])
|
|
|
+ }
|
|
|
+ for (let i = min; i <= max; i++) {
|
|
|
+ res.push(i);
|
|
|
+ }
|
|
|
+ }else if (x.includes('-') && x.startsWith("-") && !x.match(/[0-9]+-[-0-9]+/)) {
|
|
|
+ res.push(parseInt(x));
|
|
|
+ }else{
|
|
|
res.push(parseInt(x));
|
|
|
}
|
|
|
});
|
|
|
return res;
|
|
|
} else if (x.includes('-') && !x.includes(',')) {
|
|
|
- const res: number[] = [];
|
|
|
- const [min, max] = x.split('-').map(x=>parseInt(x));
|
|
|
- for (let i = min; i <= max; i++) {
|
|
|
- res.push(i);
|
|
|
- }
|
|
|
- return res;
|
|
|
+ const res: number[] = [];
|
|
|
+ if (!x.startsWith("-")) {
|
|
|
+ const [min, max] = x.split('-').map(x=>parseInt(x));
|
|
|
+ for (let i = min; i <= max; i++) {
|
|
|
+ res.push(i);
|
|
|
+ }
|
|
|
+ }else if (x.startsWith("-") && x.match(/[0-9]+-[-0-9]+/)) {
|
|
|
+ const min = -parseInt(x.split('-')[1]);
|
|
|
+ console.log(min)
|
|
|
+ var max ;
|
|
|
+ if (x.includes('--')) {
|
|
|
+ max = -parseInt(x.split('-')[3])
|
|
|
+ }else{
|
|
|
+ max = parseInt(x.split('-')[2])
|
|
|
+ }
|
|
|
+ for (let i = min; i <= max; i++) {
|
|
|
+ res.push(i);
|
|
|
+ }
|
|
|
+ }else if (x.startsWith("-") && !x.match(/[0-9]+-[-0-9]+/)) {
|
|
|
+ res.push(parseInt(x));
|
|
|
+ }else{
|
|
|
+ res.push(parseInt(x));
|
|
|
+ }
|
|
|
+ return res;
|
|
|
} else if (!x.includes('-') && x.includes(',')) {
|
|
|
- return listMap(x).map(x => parseInt(x));
|
|
|
+ return listMap(x).map(x => parseInt(x));
|
|
|
} else {
|
|
|
return [parseInt(x)];
|
|
|
}
|
|
@@ -84,6 +118,7 @@ function atomSelectionQuery2(x: any) {
|
|
|
|
|
|
function atomExpressionQuery(x: any[]) {
|
|
|
const [resnorange, resno, inscode, chainname, atomname, altloc] = x[1];
|
|
|
+ //const [resnorange, inscode, chainname, atomname, altloc] = x[1];
|
|
|
const tests: AtomGroupArgs = {};
|
|
|
|
|
|
if (chainname) {
|
|
@@ -101,7 +136,7 @@ function atomExpressionQuery(x: any[]) {
|
|
|
|
|
|
const resProps: any = [];
|
|
|
if (resno) {
|
|
|
- console.log(resno);
|
|
|
+ console.log(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]));
|
|
@@ -115,6 +150,28 @@ function atomExpressionQuery(x: any[]) {
|
|
|
return B.struct.generator.atomGroups(tests);
|
|
|
}
|
|
|
|
|
|
+function resnorangeExpressionQuery(x: any[]) {
|
|
|
+ const [resnorange, chainname] = x;
|
|
|
+ //const [resnorange, inscode, chainname, atomname, altloc] = x[1];
|
|
|
+ const tests: AtomGroupArgs = {};
|
|
|
+
|
|
|
+ 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 resnoRangeProps: any = [];
|
|
|
+ if (resnorange) {
|
|
|
+ resnorange.forEach((x: number) =>{
|
|
|
+ resnoRangeProps.push(B.core.rel.eq([B.ammp('auth_seq_id'), x]));
|
|
|
+ });
|
|
|
+ };
|
|
|
+ if (resnoRangeProps.length) tests['residue-test'] = h.orExpr(resnoRangeProps);
|
|
|
+
|
|
|
+ return B.struct.generator.atomGroups(tests);
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
const lang = P.MonadicParser.createLanguage({
|
|
|
|
|
@@ -134,7 +191,21 @@ const lang = P.MonadicParser.createLanguage({
|
|
|
r.Keywords,
|
|
|
r.NamedAtomProperties,
|
|
|
r.AtomSelectionMacro.map(atomSelectionQuery2),
|
|
|
+/* r.ResnoRange.map((x:string) => {
|
|
|
+ const resnorange=listOrRangeMap(x);
|
|
|
+ const resnoRangeProps: any = [];
|
|
|
+ const tests: AtomGroupArgs = {};
|
|
|
+ console.log(resnorange)
|
|
|
+ resnorange.forEach((a: number) =>{
|
|
|
+ resnoRangeProps.push(B.core.rel.eq([B.ammp('auth_seq_id'), a]));
|
|
|
+ });
|
|
|
+ console.log(resnoRangeProps)
|
|
|
+ tests['residue-test'] = h.orExpr(resnoRangeProps);
|
|
|
+ return B.struct.generator.atomGroups(tests);
|
|
|
+ }),
|
|
|
+*/
|
|
|
r.AtomExpression.map(atomExpressionQuery),
|
|
|
+ r.ResnoRangeExpression.map(resnorangeExpressionQuery),
|
|
|
r.Element.map((x: string) => B.struct.generator.atomGroups({
|
|
|
'atom-test': B.core.rel.eq([B.acp('elementSymbol'), B.struct.type.elementSymbol(x)])
|
|
|
})),
|
|
@@ -272,7 +343,7 @@ const lang = P.MonadicParser.createLanguage({
|
|
|
},
|
|
|
|
|
|
Operator: function (r: any) {
|
|
|
- return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression, r.Operator));
|
|
|
+ return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression,r.Operator));
|
|
|
},
|
|
|
|
|
|
AtomExpression: function (r: any) {
|
|
@@ -280,7 +351,7 @@ const lang = P.MonadicParser.createLanguage({
|
|
|
P.MonadicParser.lookahead(r.AtomPrefix),
|
|
|
P.MonadicParser.seq(
|
|
|
r.ResnoRange.or(P.MonadicParser.of(null)),
|
|
|
- r.Resno.or(P.MonadicParser.of(null)),
|
|
|
+ r.Resno.or(P.MonadicParser.of(null)),
|
|
|
r.Inscode.or(P.MonadicParser.of(null)),
|
|
|
r.Chainname.or(P.MonadicParser.of(null)),
|
|
|
r.Atomname.or(P.MonadicParser.of(null)),
|
|
@@ -290,6 +361,13 @@ const lang = P.MonadicParser.createLanguage({
|
|
|
);
|
|
|
},
|
|
|
|
|
|
+ ResnoRangeExpression: function (r: any) {
|
|
|
+ return P.MonadicParser.seq(
|
|
|
+ r.ResnoRange.or(P.MonadicParser.of(null)),
|
|
|
+ r.Chainname.or(P.MonadicParser.of(null)),
|
|
|
+ )
|
|
|
+ },
|
|
|
+
|
|
|
AtomPrefix: () => P.MonadicParser.regexp(/[0-9:^%/.]/).desc('atom-prefix'),
|
|
|
Chainname: () => P.MonadicParser.regexp(/:([A-Za-z]{1,3})/, 1).desc('chainname'),
|
|
|
Model: () => P.MonadicParser.regexp(/\/([0-9]+)/, 1).map(Number).desc('model'),
|
|
@@ -300,9 +378,15 @@ const lang = P.MonadicParser.createLanguage({
|
|
|
Altloc: () => P.MonadicParser.regexp(/%([a-zA-Z0-9])/, 1).desc('altloc'),
|
|
|
Inscode: () => P.MonadicParser.regexp(/\^([a-zA-Z0-9])/, 1).desc('inscode'),
|
|
|
|
|
|
+ Number: function () {
|
|
|
+ return P.MonadicParser.regexp(/-?(0|[1-9][0-9]*)([.][0-9]+)?([eE][+-]?[0-9]+)?/)
|
|
|
+ .map(Number)
|
|
|
+ .desc('number');
|
|
|
+ },
|
|
|
+
|
|
|
|
|
|
ResnoRange: function (r: any) {
|
|
|
- return P.MonadicParser.regex(/[0-9,-]+/).map(listOrRangeMap).desc('resnorange');
|
|
|
+ return P.MonadicParser.regex(/-?[0-9,-]+/).map(listOrRangeMap).desc('resnorange');
|
|
|
// // 123-200
|
|
|
// // -12--3
|
|
|
},
|