Explorar el Código

Construction of rasmol selection command has nearly finished

yakomaxa hace 2 años
padre
commit
da6a153985

+ 22 - 208
src/mol-script/transpilers/rasmol/parser.ts

@@ -34,7 +34,7 @@ const comma = P.MonadicParser.string(',');
 const star = P.MonadicParser.string('*');
 const bra = P.MonadicParser.string('(');
 const ket = P.MonadicParser.string(')');
-const numbers = P.MonadicParser.regexp(/[0-9]/);
+
 
 /* is Parser -> MonadicParser substitution correct? */
 function orNull(rule: P.MonadicParser<any>) {
@@ -64,96 +64,6 @@ function atomSelectionQuery2(x: any) {
 }
 
 
-
-// <, <=, =, >=, >, !=, and LIKE
-const valueOperators: OperatorList = [
-    {
-        '@desc': 'value comparisons',
-        '@examples': [],
-        name: '=',
-        abbr: ['=='],
-        type: h.binaryLeft,
-        rule: P.MonadicParser.regexp(/\s*(LIKE|>=|<=|=|!=|>|<)\s*/i, 1),
-        map: (op, e1, e2) => {
-            // console.log(op, e1, e2)
-            let expr;
-	     if (e1 === 'structure') {
-                expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e2)]);
-            } else if (e2 === 'structure') {
-                expr = B.core.flags.hasAny([B.ammp('secondaryStructureFlags'), structureMap(e1)]);
-            } else if (e1.head !== undefined) {
-                if (e1.head.name === 'core.type.regex') {
-                    expr = B.core.str.match([e1, B.core.type.str([e2])]);
-                }
-            } else if (e2.head !== undefined) {
-                if (e2.head.name === 'core.type.regex') {
-                    expr = B.core.str.match([e2, B.core.type.str([e1])]);
-                }
-            } else if (op.toUpperCase() === 'LIKE') {
-                if (e1.head) {
-                    expr = B.core.str.match([
-                        B.core.type.regex([`^${e2}$`, 'i']),
-                        B.core.type.str([e1])
-                    ]);
-                } else {
-                    expr = B.core.str.match([
-                        B.core.type.regex([`^${e1}$`, 'i']),
-                        B.core.type.str([e2])
-                    ]);
-                }
-            }
-            if (!expr) {
-                if (e1.head) e2 = h.wrapValue(e1, e2);
-                if (e2.head) e1 = h.wrapValue(e2, e1);
-                switch (op) {
-                    case '=':
-                        expr = B.core.rel.eq([e1, e2]);
-                        break;
-                    case '!=':
-                        expr = B.core.rel.neq([e1, e2]);
-                        break;
-                    case '>':
-                        expr = B.core.rel.gr([e1, e2]);
-                        break;
-                    case '<':
-                        expr = B.core.rel.lt([e1, e2]);
-                        break;
-                    case '>=':
-                        expr = B.core.rel.gre([e1, e2]);
-                        break;
-                    case '<=':
-                        expr = B.core.rel.lte([e1, e2]);
-                        break;
-                    default: throw new Error(`value operator '${op}' not supported`);
-                }
-            }
-            return B.struct.generator.atomGroups({ 'atom-test': expr });
-        }
-    }
-];
-
-function atomExpressionQuery(x: any[]) {
-    const [resno, 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 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);
-}
-
 const lang = P.MonadicParser.createLanguage({
     Integer: () => P.MonadicParser.regexp(/-?[0-9]+/).map(Number).desc('integer'),
 
@@ -167,26 +77,10 @@ const lang = P.MonadicParser.createLanguage({
 
     Expression: function (r: any) {
         return P.MonadicParser.alt(
-//	    r.Keywords,
-//	    r.ValueQuery,
+	    r.Keywords,
+	    r.NamedAtomProperties,
 	    r.AtomSelectionMacro.map(atomSelectionQuery2),
-	    r.AtomSelectionMacroResi.map(atomSelectionQuery2),
-//	    r.NamedAtomProperties,
-  
-
-  //          r.Resno.lookahead(P.MonadicParser.regexp(/\s*(?!(LIKE|>=|<=|!=|[:^%/.=><]))/i)).map((x: any) => B.struct.generator.atomGroups({	
-  //              'residue-test': B.core.rel.eq([B.ammp('auth_seq_id'), x])		
-//            })),
-//	    r.Atomno.lookahead(P.MonadicParser.regexp(/\s*(?!(LIKE|>=|<=|!=|[:^%/.=><]))/i)).map((x: any) => B.struct.generator.atomGroups({	
-  //              'atom-test': B.core.rel.eq([B.ammp('id'), x])		
-//            })),
-
-//            r.Element.map((x: string) => B.struct.generator.atomGroups({
-//                'atom-test': B.core.rel.eq([B.acp('elementSymbol'), B.struct.type.elementSymbol(x)])
-//            })),
-//            r.Resname.map((x: string) => B.struct.generator.atomGroups({
-//		'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), x])
-//            })),	  
+	    r.Object
         );
     },
 
@@ -201,6 +95,7 @@ const lang = P.MonadicParser.createLanguage({
     //    :.cg -> name ca
     AtomSelectionMacro: function (r: any) {
         return P.MonadicParser.alt(
+	    // :A.CA :.CA
             colon.then(P.MonadicParser.alt(
                 P.MonadicParser.seq(                
                     orNull(propertiesDict.chain).skip(dot),
@@ -210,6 +105,7 @@ const lang = P.MonadicParser.createLanguage({
                     orNull(propertiesDict.name).skip(dot)
                 ).map(x => { return {name: x[0] }; }),
             )),
+	    // *A.CA *.CA
 	    star.then(P.MonadicParser.alt(
                 P.MonadicParser.seq(                
                     orNull(propertiesDict.chain).skip(dot),
@@ -219,13 +115,14 @@ const lang = P.MonadicParser.createLanguage({
                     orNull(propertiesDict.name).skip(dot)
                 ).map(x => { return {name: x[0] }; }),
             )),
-	    // 1-100 lys:a.ca lys:a lys lys.ca
+	    // 1-100+201
 	    bra.then(P.MonadicParser.alt(
 		P.MonadicParser.alt(
 		    P.MonadicParser.seq(
 			orNull(propertiesDict.resi).skip(ket),
 		    ).map(x => { return { resi: x[0] };})
 		))),
+	    //  lys:a.ca lys:a lys lys.ca
 	    P.MonadicParser.alt(
 		P.MonadicParser.alt(
                     P.MonadicParser.seq(
@@ -260,23 +157,20 @@ const lang = P.MonadicParser.createLanguage({
 		    
     },
 
-    AtomSelectionMacroResi: function (r: any) {
-        return P.MonadicParser.alt(
-            P.MonadicParser.alt(
-                P.MonadicParser.seq(
-                    orNull(propertiesDict.resi)
-                ).map(x => {  return { resi: x[0] };}),
-	    ),
-        );
-    },
-
     ObjectProperty: () => {
 	const w = h.getReservedWords(special_properties, special_keywords, special_operators)
               .sort(h.strLenSortFn).map(h.escapeRegExp).join('|');
         return P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i'));
     },
+
+    ObjectProperty2: () => {
+	const w = h.getReservedWords(properties, keywords, operators)
+              .sort(h.strLenSortFn).map(h.escapeRegExp).join('|');
+        return P.MonadicParser.regexp(new RegExp(`(?!(${w}))[A-Z0-9_]+`, 'i'));
+    },
+    
     Object: (r: any) => {
-        return r.ObjectProperty.notFollowedBy(slash)
+        return r.ObjectProperty2
             .map((x: any) => { throw new Error(`property 'object' not supported, value '${x}'`); });
     },
 
@@ -331,60 +225,18 @@ const lang = P.MonadicParser.createLanguage({
         });
     },
 
-    Operator: function (r: any) {
-        return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression));
-    },
-
-    AtomExpression: function (r: any) {
-        return P.MonadicParser.seq(
-            P.MonadicParser.lookahead(r.AtomPrefix),
-            P.MonadicParser.seq(
-//		r.ResnoRange.or(P.MonadicParser.of(null)),
-                r.Resno.or(P.MonadicParser.of(null)),
-		r.Atomno.or(P.MonadicParser.of(null)),
-//		r.Resno2.or(P.MonadicParser.of(null)),
-                r.Inscode.or(P.MonadicParser.of(null)),
-                r.Chainname.or(P.MonadicParser.of(null)),
-//		r.Chainname2.or(P.MonadicParser.of(null)),
-                r.Atomname.or(P.MonadicParser.of(null)),
-                r.Altloc.or(P.MonadicParser.of(null)),
-                r.Model.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'),
-//    Chainname2: () => P.MonadicParser.regexp(/\*([A-Za-z]{1,3})/, 1).desc('chainname'),
-    Model: () => P.MonadicParser.regexp(/\/([0-9]+)/, 1).map(Number).desc('model'),
-    Element: () => P.MonadicParser.regexp(/_([A-Za-z]{1,3})/, 1).desc('element'),
-    Atomname: () => P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1).map(B.atomName).desc('atomname'),
-    Resname: () => P.MonadicParser.regexp(/[a-zA-Z0-9]{1,4}/).desc('resname'),
-    Resno: (r: any) => r.Integer.desc('resno'),
-    Atomno: (r: any) => r.Integer.desc('atomno'),
-//    Resno2: (r: any) => r.split(',').Integer.desc('resno'),
-    Altloc: () => P.MonadicParser.regexp(/%([a-zA-Z0-9])/, 1).desc('altloc'),
-    Inscode: () => P.MonadicParser.regexp(/\^([a-zA-Z0-9])/, 1).desc('inscode'),
-
+//    Operator: function (r: any) {
+//        return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression));
+//    },
 
-    //    function listMap(x: string) { return x.split(',').map(x => x.replace(/^["']|["']$/g, '')); }
-
-
-
-    BracketedResname: function (r: any) {
-        return P.MonadicParser.regexp(/\.([a-zA-Z0-9]{1,4})/, 1)
-	    .desc('bracketed-resname');
-        // [0SD]
+    Operator: function (r: any) {
+        return h.combineOperators(operators, P.MonadicParser.alt(r.Parens, r.Expression, r.Operator));
     },
 
-    ResnoRange: function (r: any) {
-        return P.MonadicParser.regexp(/\.([\s]){1,3}/, 1)
-	    .desc('resno-range');
-        // 123-200
-        // -12--3
-    },
 
     Keywords: () => P.MonadicParser.alt(...h.getKeywordRules(keywords)),
 
+
     Query: function (r: any) {
         return P.MonadicParser.alt(
             r.Operator,
@@ -413,45 +265,7 @@ const lang = P.MonadicParser.createLanguage({
         return P.MonadicParser.alt(r.Number, r.String);
     },
 
-    ValueParens: function (r: any) {
-        return P.MonadicParser.alt(
-            r.ValueParens,
-            r.ValueOperator,
-            r.ValueExpressions
-        ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
-    },
-
-    ValuePropertyNames: function () {
-        return P.MonadicParser.alt(...h.getPropertyNameRules(properties, /LIKE|>=|<=|=|!=|>|<|\)|\s/i));
-    },
-
-    ValueOperator: function (r: any) {
-        return h.combineOperators(valueOperators, P.MonadicParser.alt(r.ValueParens, r.ValueExpressions));
-    },
 
-    ValueExpressions: function (r: any) {
-        return P.MonadicParser.alt(
-            r.Value,
-            r.ValuePropertyNames
-        );
-    },
-
-    ValueQuery: function (r: any) {
-        return P.MonadicParser.alt(
-            r.ValueOperator.map((x: any) => {
-                if (x.head.name) {
-                    if (x.head.name.startsWith('structure-query.generator')) return x;
-                } else {
-                    if (typeof x === 'string' && x.length <= 4) {
-                        return B.struct.generator.atomGroups({
-                            'residue-test': B.core.rel.eq([B.ammp('label_comp_id'), x])
-                        });
-                    }
-                }
-                throw new Error(`values must be part of an comparison, value '${x}'`);
-            })
-        );
-    }
 });
 
 export const transpiler: Transpiler = str => lang.Query.tryParse(str);

+ 13 - 13
src/mol-script/transpilers/rasmol/special_properties.ts

@@ -9,7 +9,7 @@ import { MolScriptBuilder } from '../../../mol-script/language/builder';
 const B = MolScriptBuilder;
 import { PropertyDict } from '../types';
 
-const reFloat = /[-+]?[0-9]*\.?[0-9]+/;
+//const reFloat = /[-+]?[0-9]*\.?[0-9]+/;
 // const rePosInt = /[0-9]+/;
 
 function atomNameListMap(x: string) { return x.split(',').map(B.atomName); }
@@ -44,18 +44,18 @@ function elementListMap(x: string) {
     return x.split('+').map(B.struct.type.elementSymbol);
 }
 
-const sstrucDict: { [k: string]: string } = {
-    H: 'helix',
-    S: 'beta',
-    L: 'none'
-};
-function sstrucListMap(x: string) {
-    return {
-        flags: B.struct.type.secondaryStructureFlags(
-            x.toUpperCase().split('+').map(ss => sstrucDict[ss] || 'none')
-        )
-    };
-}
+//const sstrucDict: { [k: string]: string } = {
+//    H: 'helix',
+//    S: 'beta',
+//    L: 'none'
+//};
+//function sstrucListMap(x: string) {
+//    return {
+//        flags: B.struct.type.secondaryStructureFlags(
+//            x.toUpperCase().split('+').map(ss => sstrucDict[ss] || 'none')
+//        )
+//    };
+//}
 
 export const special_properties: PropertyDict = {
     symbol: {