diff --git a/src/mol-script/transpilers/pymol/properties.ts b/src/mol-script/transpilers/pymol/properties.ts index 71cc81ab50af0d734170ef2bcfce6c2a83bccc16..7b29db7bf72abc619f242b2aa5b2ed921411945b 100644 --- a/src/mol-script/transpilers/pymol/properties.ts +++ b/src/mol-script/transpilers/pymol/properties.ts @@ -16,61 +16,60 @@ function atomNameListMap(x: string) { return x.split('+').map(B.atomName); } function listMap(x: string) { return x.split('+').map(x => x.replace(/^["']|["']$/g, '')); } function listOrRangeMap(x: string) { - // cases + // cases if (x.includes('-') && x.includes('+')) { const pSplit = x.split('+').map(x => x.replace(/^["']|["']$/g, '')); const res: number[] = []; pSplit.forEach(x => { - if (x.includes('-') && !x.startsWith("-")) { + 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 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++) { + } else if (x.includes('-') && x.startsWith('-') && x.match(/[0-9]+-[-0-9]+/)) { + const min = -parseInt(x.split('-')[1]); + let 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{ + } + } 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[] = []; - if (!x.startsWith("-")) { + 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); + res.push(i); } - }else if (x.startsWith("-") && x.match(/[0-9]+-[-0-9]+/)) { + } else if (x.startsWith('-') && x.match(/[0-9]+-[-0-9]+/)) { const min = -parseInt(x.split('-')[1]); - console.log(min) - var max ; + let max; if (x.includes('--')) { - max = -parseInt(x.split('-')[3]) - }else{ - max = parseInt(x.split('-')[2]) + 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(i); + } + } else if (x.startsWith('-') && !x.match(/[0-9]+-[-0-9]+/)) { res.push(parseInt(x)); - }else{ + } else { res.push(parseInt(x)); - } - return res; + } + 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)]; } diff --git a/src/mol-script/transpilers/rasmol/parser.ts b/src/mol-script/transpilers/rasmol/parser.ts index 818ccd8f39fa199a2f86d80f069312885566c59d..ba6c74bd9bac6f4443bdf826dc93323fab546667 100644 --- a/src/mol-script/transpilers/rasmol/parser.ts +++ b/src/mol-script/transpilers/rasmol/parser.ts @@ -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 },