فهرست منبع

refined VMD: RangeListProperty in vmd/parser.ts is not working for unknown reasons, so it was substituted by NamedAtomProperties: This limits the selection like 'residue 10 to 50' and 'residue 10'

yakomaxa 2 سال پیش
والد
کامیت
0665524b11
3فایلهای تغییر یافته به همراه139 افزوده شده و 62 حذف شده
  1. 101 8
      src/mol-script/transpilers/vmd/parser.ts
  2. 2 12
      src/mol-script/transpilers/vmd/properties.ts
  3. 36 42
      src/mol-util/monadic-parser.ts

+ 101 - 8
src/mol-script/transpilers/vmd/parser.ts

@@ -15,8 +15,37 @@ import { keywords } from './keywords';
 import { functions } from './functions';
 import { OperatorList } from '../types';
 import { Transpiler } from '../transpiler';
+//import { AtomGroupArgs } from '../types';
 
-// const propertiesDict = h.getPropertyRules(properties)
+//const slash = P.MonadicParser.string('/');
+
+//function orNull(rule: P.MonadicParser<any>) {
+//    return rule.or(P.MonadicParser.of(null));
+//}
+
+/**function atomSelectionQuery(x: any) {
+   const tests: AtomGroupArgs = {};
+    const props: { [k: string]: any[] } = {};
+
+    for (let k in x) {
+        const ps = properties[k];
+        if (!ps) {
+            throw new Error(`property '${k}' not supported, value '${x[k]}'`);
+        }
+        if (x[k] === null) continue;
+        if (!props[ps.level]) props[ps.level] = [];
+        props[ps.level].push(x[k]);
+    }
+
+    for (let p in props) {
+        tests[p] = h.andExpr(props[p]);
+    }
+
+    return B.struct.generator.atomGroups(tests);
+}
+*/
+
+//const propertiesDict = h.getPropertyRules(properties)
 
 // <, <=, = or ==, >=, >, and !=
 // lt, le, eq, ge, gt, and ne, =~
@@ -119,20 +148,84 @@ const lang = P.MonadicParser.createLanguage({
         ).wrap(P.MonadicParser.string('('), P.MonadicParser.string(')'));
     },
 
-    Expression: function (r:any) {
+    Expression: function (r : any) {
         return P.MonadicParser.alt(
-	    r.NamedAtomProperties,
-	    r.RangeListProperty,
-            r.ValueQuery,
-            r.Keywords,
-	    r.ValueRange,
+	    r.Keywords,
+            r.NamedAtomProperties,
+	    r.ValueQuery
         );
     },
+    
+//    Expression: function (r:any) {
+//        return P.MonadicParser.alt(
+//	    r.NamedAtomProperties,
+//	    r.AtomSelectionMacro.map(atomSelectionQuery),
+//	    r.Keywords,
+ //           r.ValueQuery, 
+ //       );
+  //  },
 
     NamedAtomProperties: function () {
-        return P.MonadicParser.alt(...h.getNamedPropertyRules(properties));
+	return P.MonadicParser.alt(...h.getNamedPropertyRules(properties));                                                                                 
     },
 
+/*        AtomSelectionMacro: function (r : any) {
+        return P.MonadicParser.alt(
+            slash.then(P.MonadicParser.alt(
+                P.MonadicParser.seq(
+                    orNull(r.ObjectProperty).skip(slash),
+                    orNull(propertiesDict.segi).skip(slash),
+                    orNull(propertiesDict.chain).skip(slash),
+                    orNull(propertiesDict.resi).skip(slash),
+                    orNull(propertiesDict.name)
+                ).map(x => { return { object: x[0], segi: x[1], chain: x[2], resi: x[3], name: x[4] }; }),
+                P.MonadicParser.seq(
+                    orNull(r.ObjectProperty).skip(slash),
+                    orNull(propertiesDict.segi).skip(slash),
+                    orNull(propertiesDict.chain).skip(slash),
+                    orNull(propertiesDict.resi)
+                ).map(x => { return { object: x[0], segi: x[1], chain: x[2], resi: x[3] }; }),
+                P.MonadicParser.seq(
+                    orNull(r.ObjectProperty).skip(slash),
+                    orNull(propertiesDict.segi).skip(slash),
+                    orNull(propertiesDict.chain)
+                ).map(x => { return { object: x[0], segi: x[1], chain: x[2] }; }),
+                P.MonadicParser.seq(
+                    orNull(r.ObjectProperty).skip(slash),
+                    orNull(propertiesDict.segi)
+                ).map(x => { return { object: x[0], segi: x[1] }; }),
+                P.MonadicParser.seq(
+                    orNull(r.ObjectProperty)
+                ).map(x => { return { object: x[0] }; }),
+            )),
+            P.MonadicParser.alt(
+                P.MonadicParser.seq(
+                    orNull(r.ObjectProperty).skip(slash),
+                    orNull(propertiesDict.segi).skip(slash),
+                    orNull(propertiesDict.chain).skip(slash),
+                    orNull(propertiesDict.resi).skip(slash),
+                    orNull(propertiesDict.name)
+                ).map(x => { return { object: x[0], segi: x[1], chain: x[2], resi: x[3], name: x[4] }; }),
+                P.MonadicParser.seq(
+                    orNull(propertiesDict.segi).skip(slash),
+                    orNull(propertiesDict.chain).skip(slash),
+                    orNull(propertiesDict.resi).skip(slash),
+                    orNull(propertiesDict.name)
+                ).map(x => { return { segi: x[0], chain: x[1], resi: x[2], name: x[3] }; }),
+                P.MonadicParser.seq(
+                    orNull(propertiesDict.chain).skip(slash),
+                    orNull(propertiesDict.resi).skip(slash),
+                    orNull(propertiesDict.name)
+                ).map(x => { return { chain: x[0], resi: x[1], name: x[2] }; }),
+                P.MonadicParser.seq(
+                    orNull(propertiesDict.resi).skip(slash),
+                    orNull(propertiesDict.name)
+                ).map(x => { return { resi: x[0], name: x[1] }; }),
+            )
+        );
+    },
+*/
+    
     Keywords: () => P.MonadicParser.alt(...h.getKeywordRules(keywords)),
 
     ValueRange: function (r:any) {

+ 2 - 12
src/mol-script/transpilers/vmd/properties.ts

@@ -11,20 +11,10 @@ import { PropertyDict } from '../types';
 
 const reFloat = /[-+]?[0-9]*\.?[0-9]+/;
 const rePosInt = /[+]?[0-9]+/;
-const reInt = /[-+]?[0-9] +/;
+const reInt = /[-+]?[0-9]+/;
 
 function atomNameListMapVMD(x: string) { return x.split(' ').map(B.atomName); };
 function listMapVMD(x: string) { return x.split(' ').map(x => x.replace(/^["']|["']$/g, '')); }
-function rangeMapVMD(x: string) {
-    const [min, max] = x.split('\sto\s').map(x => parseInt(x));
-    return { min, max };
-}
-function listOrRangeMapVMD(x: string) {
-    return x.includes('to') ? rangeMapVMD(x) : listMapVMD(x).map(x => parseInt(x));
-}
-//function elementListMap(x: string) {
-//    return x.split('+').map(B.struct.type.elementSymbol); 
-//}
 
 function str(x: string) { return x; }
 
@@ -100,7 +90,7 @@ export const properties: PropertyDict = {
         '@desc': 'num  a set of connected atoms with the same residue number',
         '@examples': ['residue < 11', 'residue 11'],
         isNumeric: true,
-        regex: reInt, map: x => listOrRangeMapVMD,
+        regex: reInt, map: x => parseInt(x),
         level: 'residue-test', property: B.ammp('auth_seq_id')
     },
     resid: {

+ 36 - 42
src/mol-util/monadic-parser.ts

@@ -2,7 +2,6 @@
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
- * @author Koya Sakuma
  */
 
 /**
@@ -237,6 +236,15 @@ export namespace MonadicParser {
 
     export type Result<T> = Success<T> | Failure
 
+    //export function lookahead<A>(x: MonadicParser<A> | string | RegExp): MonadicParser<null> {
+    //export function seq(...parsers: MonadicParser<any>[]): MonadicParser<any[]> {
+    //export function seq<A, B, C>(a: MonadicParser<A>, b: MonadicParser<B>, c: MonadicParser<C>): MonadicParser<[A, B, C]>
+//        export function alt(...parsers: MonadicParser<any>[]): MonadicParser<any> {
+ //       const numParsers = parsers.length;
+  //      if (numParsers === 0) {
+  //          return fail('zero alternates');
+//        }
+
     export function seqMap( a: MonadicParser<any>,b:MonadicParser<any>,c:any) {
 	var args = [].slice.call(arguments);
 	if (args.length === 0) {
@@ -259,6 +267,28 @@ export namespace MonadicParser {
         return language;
     }
 
+   
+    //    function seq() {
+    //var parsers = [].slice.call(arguments);
+//	var numParsers = parsers.length;
+//	for (var j = 0; j < numParsers; j += 1) {
+//	    assertParser(parsers[j]);
+//	}
+//	return Parsimmon(function(input, i) {
+//	    var result;
+//	    var accum = new Array(numParsers);
+//	    for (var j = 0; j < numParsers; j += 1) {
+    //		result = mergeReplies(parsers[j]._(input, i), result);
+    //if (!result.status) {
+//		    return result;
+//		}
+//		accum[j] = result.value;
+//		i = result.index;
+//	    }
+//	    return mergeReplies(makeSuccess(i, accum), result);
+//	});
+  //  }
+
     export function seq<A>(a: MonadicParser<A>): MonadicParser<[A]>
     export function seq<A, B>(a: MonadicParser<A>, b: MonadicParser<B>): MonadicParser<[A, B]>
     export function seq<A, B, C>(a: MonadicParser<A>, b: MonadicParser<B>, c: MonadicParser<C>): MonadicParser<[A, B, C]>
@@ -339,13 +369,9 @@ export namespace MonadicParser {
     }
 
    
-    export function regexp(re: RegExp, group=0) {
-	assertRegexp(re);
-	if (arguments.length >= 2) {
-	    assertNumber(group);
-	} else {
-	    group = 0;
-	}
+
+    //return new MonadicParser<any[]>((input, index) => {
+    export function regexp(re: RegExp, group = 0) {
         const anchored = anchoredRegexp(re);
         const expected = '' + re;
         return new MonadicParser<any>( function (input:any, i:any){
@@ -492,6 +518,8 @@ export namespace MonadicParser {
     MonadicParser.of = succeed;
     MonadicParser.regex = regexp;
     MonadicParser.regexp = regexp;
+//    MonadicParser.regexp.lookahead = lookahead;
+    //MonadicParser.RegExp = regexp;
 }
 
 function seqPick(idx: number, ...parsers: MonadicParser<any>[]): MonadicParser<any> {
@@ -595,38 +623,4 @@ function assertFunction(x:any) {
     }
 }
 
-function assertNumber(x:any) {
-  if (typeof x !== "number") {
-    throw new Error("not a number: " + x);
-  }
-}
-
-function assertRegexp(x:any) {
-  if (!(x instanceof RegExp)) {
-    throw new Error("not a regexp: " + x);
-  }
-  var f = flags(x);
-  for (var i = 0; i < f.length; i++) {
-    var c = f.charAt(i);
-    // Only allow regexp flags [imus] for now, since [g] and [y] specifically
-    // mess up Parsimmon. If more non-stateful regexp flags are added in the
-    // future, this will need to be revisited.
-    if (c !== "i" && c !== "m" && c !== "u" && c !== "s") {
-      throw new Error('unsupported regexp flag "' + c + '": ' + x);
-    }
-  }
-}
 
-function flags(re:RegExp) {
-  if (re.flags !== undefined) {
-    return re.flags;
-  }
-  // legacy browser support
-  return [
-    re.global ? "g" : "",
-    re.ignoreCase ? "i" : "",
-    re.multiline ? "m" : "",
-    re.unicode ? "u" : "",
-    re.sticky ? "y" : ""
-  ].join("");
-}