Revision: 20749
          http://sourceforge.net/p/jmol/code/20749
Author:   hansonr
Date:     2015-08-31 18:04:43 +0000 (Mon, 31 Aug 2015)
Log Message:
-----------
Jmol.___JmolVersion="14.3.16_2015.08.31"

new feature: Jmol SMILES/SMARTS generic stereoSMILES polyhedron option 
@PHn(....)
 -- totally generic; will work with any number of connected atoms
 -- suitable replacement for all TP, OH, etc. 
 -- standard equivalence to [C@] is [C@PH4(234)]
 -- standard equivalence to [C@@] is [C@PH4(432)]
 -- "reverse" option via "!": [C@PH4(!234)]
 -- designation around any or all of the attached atoms is possible. For 
tetrahedra, this is
    redundant, but for higher number of vertices, it may not be. This 
designation is 
    done using "." to separate atoms. 
 -- so [C@] is [C@PH4(234)] or [C@PH4(!432)] or [C@PH4(.134)]
 -- implied H as in [CH@] will be atom 1 if this is the first atom; 2 if not -- 
Br[CH@]....
    (same as in standard tetrahedral)

 -- not implemented yet for SMARTS searching of SMILES strings
    
                $ load $2-bromobutane
                $ show smiles
                Br[C@@H](C)CC
                $ print {*}.find("Br[C@](C)(H)CC")
                ({0:5})
                $ print {*}.find("Br[C@PH4(234)](C)(H)CC")
                ({0:5})
                $ print {*}.find("Br[C@PH4(234)](H)(C)CC")
                ({})
                $ print {*}.find("Br[C@PH4(432)](H)(C)CC")
                ({0:5})
                $ print {*}.find("Br[CH@@](C)CC")
                ({0:4})
                $ print {*}.find("Br[CH@PH4(.134)](C)CC")
                ({0:4})
                $ print {*}.find("Br[CH@PH4(!.134)](C)CC") 
                ({})
                
 -- :)
 

Modified Paths:
--------------
    trunk/Jmol/src/javajs/util/PT.java
    trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java
    trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java
    trunk/Jmol/src/org/jmol/viewer/Jmol.properties

Modified: trunk/Jmol/src/javajs/util/PT.java
===================================================================
--- trunk/Jmol/src/javajs/util/PT.java  2015-08-31 14:19:11 UTC (rev 20748)
+++ trunk/Jmol/src/javajs/util/PT.java  2015-08-31 18:04:43 UTC (rev 20749)
@@ -367,11 +367,11 @@
   }
 
   public static int countChar(String line, char c) {
-    int tokenCount = 0;
-    int pt = -1;
-    while ((pt = line.indexOf(c, pt + 1)) >= 0)
-      tokenCount++;
-    return  tokenCount;
+    int n = 0;
+    for (int i = line.lastIndexOf(c) + 1; --i >= 0;)
+      if (line.charAt(i) == '@')
+        n++;
+    return n;
   }
   
   public static int countTokens(String line, int ich) {

Modified: trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java
===================================================================
--- trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java   2015-08-31 14:19:11 UTC 
(rev 20748)
+++ trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java   2015-08-31 18:04:43 UTC 
(rev 20749)
@@ -224,8 +224,8 @@
       return "none";
     boolean check;
     // note: find smiles1 IN smiles2 here
-    int n1 = countStereo(smiles1);
-    int n2 = countStereo(smiles2);
+    int n1 = PT.countChar(PT.rep(smiles1, "@@", "@"), '@');
+    int n2 = PT.countChar(PT.rep(smiles2, "@@", "@"), '@');
     check = (n1 == n2 && areEqual(smiles2, smiles1) > 0);
     if (!check) {
       // MF matched, but didn't match SMILES
@@ -250,15 +250,18 @@
 
   /**
    * Note, this may be incompatible with [$(select(..))]
+   * 
+   * THIS IS NOT DEPENDABLE. USE /invertStereo/ INSTEAD
    */
   @Override
   public String reverseChirality(String smiles) {
     smiles = PT.rep(smiles, "@@", "!@");
     smiles = PT.rep(smiles, "@", "@@");
     smiles = PT.rep(smiles, "!@@", "@");
-    smiles = PT.rep(smiles, "@@SP", "@SP");
-    smiles = PT.rep(smiles, "@@OH", "@OH");
-    smiles = PT.rep(smiles, "@@TB", "@TB");
+    // note -- @@SP does not exist
+//    smiles = PT.rep(smiles, "@@SP", "@SP");
+//    smiles = PT.rep(smiles, "@@OH", "@OH");
+//    smiles = PT.rep(smiles, "@@TP", "@TP");
     return smiles;
   }
 
@@ -494,16 +497,6 @@
     return null;
   }
 
-  private static int countStereo(String s) {
-    s = PT.rep(s, "@@", "@");
-    int i = s.lastIndexOf('@') + 1;
-    int n = 0;
-    for (; --i >= 0;)
-      if (s.charAt(i) == '@')
-        n++;
-    return n;
-  }
-
   @Override
   public String cleanSmiles(String smiles) {
     return SmilesParser.cleanPattern(smiles);

Modified: trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java
===================================================================
--- trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java    2015-08-31 14:19:11 UTC 
(rev 20748)
+++ trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java    2015-08-31 18:04:43 UTC 
(rev 20749)
@@ -53,7 +53,6 @@
   private SmilesSearch search;
   private Node[] jmolAtoms;
   private String directives;
-  final static int STEREOCHEMISTRY_MASK = 0xF;
   final static int STEREOCHEMISTRY_SQUARE_PLANAR = 8;
   final static int STEREOCHEMISTRY_OCTAHEDRAL = 6;
   final static int STEREOCHEMISTRY_TRIGONAL_BIPYRAMIDAL = 5;
@@ -84,6 +83,7 @@
   }
 
   private int[][] polyhedralOrders;
+  private boolean isNot;
   static PolyhedronStereoSorter polyhedronStereoSorter;
   
   private void getPolyhedralOrders() throws InvalidSmilesException {
@@ -102,10 +102,14 @@
     do {
       char ch = s.charAt(index);
       switch (ch) {
+      case '!':
+        isNot = true;
+        index++;
+        break;
       case '/':
       case '.':
         if ((pt = atomPt) >= atomCount) {
-          msg = "Too many descriptors.";
+          msg = "Too many descriptors";
           break;
         }
         int[] a = po[atomPt] = new int[n];
@@ -123,13 +127,17 @@
       default:
         index = SmilesParser.getRingNumber(s, index, ch, ret);
         pt = temp[n++] = ret[0] - 1;
-        if (pt < 0 || pt >= atomCount)
+        if (pt == atomPt) 
+          msg = "Atom cannot connect to itself"; 
+        else if (pt < 0 || pt >= atomCount)
           msg = "Connection number outside of range (1-" + atomCount + ")";
         else if (n >= atomCount)
           msg = "Too many connections indicated";
       }
-      if (msg != null)
+      if (msg != null) {
+        msg += ": " + s.substring(0, index) + "<<";
         throw new InvalidSmilesException(msg);
+      }
     } while (index < len);
   }
 
@@ -452,38 +460,63 @@
       int nH = Math.max(sAtom.missingHydrogenCount, 0);
       int order = sAtom.stereo.chiralOrder;
       int chiralClass = sAtom.stereo.chiralClass;
-      if (isSmilesFind && ((SmilesAtom) atom0).getChiralClass() != chiralClass)
+      // SMILES string must match pattern for chiral class.
+      // but we could do something about changing those if desired.
+      if (isSmilesFind && sAtom0.getChiralClass() != chiralClass)
         return false;
       if (Logger.debugging)
         Logger.debug("...type " + chiralClass + " for pattern atom " + sAtom
             + " " + atom0);
       switch (chiralClass) {
       case STEREOCHEMISTRY_POLYHEDRAL:
+        if (sAtom.stereo.isNot)
+          isNot = !isNot;
         if (nH > 1)
-          continue;
-        if (nH == 1) {
-          // must create this atom temporarily
-          // TODO
-          continue;
-        }
+          continue; // no chirality for [CH2@]
         if (isSmilesFind) {
           // TODO
           continue;
         }
+        SmilesBond[] bonds = sAtom.bonds;
+        int jHpt = -1;
+        if (nH == 1) {
+          jHpt = (sAtom.isFirst ? 0 : 1);
+          // can't process this unless it is tetrahedral or perhaps square 
planar
+          if (sAtom.getBondCount() != 3)
+            return false;
+          v.vA.set(0,  0,  0);
+          for (int j = 0; j < 3; j++)
+            v.vA.add((T3)bonds[j].getOtherAtom(sAtom0).getMatchingAtom());
+          v.vA.scale(0.3333f);
+          v.vA.sub2((T3) atom0, v.vA);
+          v.vA.add((T3) atom0);
+        }
         int[][] po = sAtom.stereo.polyhedralOrders;
-        SmilesBond[] bonds = sAtom.bonds;
+        int pt;
         for (int j = po.length; --j >= 0;) {
           int[] orders = po[j];
           if (orders == null || orders.length < 2)
             continue;
-          sAtom1 = bonds[j - nH].getOtherAtom(sAtom);
-          atom1 = sAtom1.getMatchingAtom(); // the atom we are looking down
-          sAtom2 = bonds[orders[0] - nH].getOtherAtom(sAtom);
-          atom2 = sAtom2.getMatchingAtom();
+          // the atom we are looking down
+          pt = (j > jHpt ? j - nH: j);
+          T3 ta1 = (j == jHpt ? v.vA : (T3) 
bonds[pt].getOtherAtom(sAtom).getMatchingAtom()); 
           float flast = (isNot ? Float.MAX_VALUE : 0);
-          for (int k = 1; k < orders.length; k++) {
-            atom3 = bonds[orders[k] - 
nH].getOtherAtom(sAtom).getMatchingAtom();
-            float f = Measure.computeTorsion((T3) atom3, (T3)atom1, (T3) 
atom0, (T3) atom2, true);
+          T3 ta2 = null;
+          for (int k = 0; k < orders.length; k++) {
+            pt = orders[k];
+            T3 ta3;
+            if (pt == jHpt) { // attached H
+              ta3 = v.vA;
+            } else {
+              if (pt > jHpt)
+                pt--;
+              ta3 = (T3) bonds[pt].getOtherAtom(sAtom).getMatchingAtom();
+            }
+            if (k == 0) {
+              ta2 = ta3;
+              continue;
+            }
+            float f = Measure.computeTorsion(ta3, ta1, (T3) atom0, ta2, true);
             if (Float.isNaN(f))
               f = 180; // directly across the center from the previous atom
             if (orders.length == 2)

Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-08-31 14:19:11 UTC 
(rev 20748)
+++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties      2015-08-31 18:04:43 UTC 
(rev 20749)
@@ -66,11 +66,16 @@
  -- suitable replacement for all TP, OH, etc. 
  -- standard equivalence to [C@] is [C@PH4(234)]
  -- standard equivalence to [C@@] is [C@PH4(432)]
+ -- "reverse" option via "!": [C@PH4(!234)]
+ -- designation around any or all of the attached atoms is possible. For 
tetrahedra, this is
+    redundant, but for higher number of vertices, it may not be. This 
designation is 
+    done using "." to separate atoms. 
+ -- so [C@] is [C@PH4(234)] or [C@PH4(!432)] or [C@PH4(.134)]
+ -- implied H as in [CH@] will be atom 1 if this is the first atom; 2 if not 
-- Br[CH@]....
+    (same as in standard tetrahedral)
 
- -- not implemented yet for implied H
  -- not implemented yet for SMARTS searching of SMILES strings
-  
-  
+    
                $ load $2-bromobutane
                $ show smiles
                Br[C@@H](C)CC
@@ -82,6 +87,12 @@
                ({})
                $ print {*}.find("Br[C@PH4(432)](H)(C)CC")
                ({0:5})
+               $ print {*}.find("Br[CH@@](C)CC")
+               ({0:4})
+               $ print {*}.find("Br[CH@PH4(.134)](C)CC")
+               ({0:4})
+               $ print {*}.find("Br[CH@PH4(!.134)](C)CC") 
+               ({})
                
  -- :)
  

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to