Revision: 21552
          http://sourceforge.net/p/jmol/code/21552
Author:   hansonr
Date:     2017-04-25 21:39:12 +0000 (Tue, 25 Apr 2017)
Log Message:
-----------
CIP -- very close to complete for Rule 4; just working on Example 6

Modified Paths:
--------------
    trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java

Modified: trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java
===================================================================
--- trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java  2017-04-25 15:57:35 UTC 
(rev 21551)
+++ trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java  2017-04-25 21:39:12 UTC 
(rev 21552)
@@ -1621,21 +1621,47 @@
       String aStr = rule4List[ia];
       String bStr = rule4List[ib];
 
-      if (aStr != null && aStr.indexOf("?") == 0) {
-        aStr = getMataList(atoms[ia].rule4List);
-        bStr = getMataList(atoms[ib].rule4List);
+      if (aStr != null && aStr.indexOf("?") == 1) {
+        aStr = getMataList(ia);
+        bStr = getMataList(ib);
         if (aStr.length() != bStr.length()) {
           // bStr must have R and S options, but aStr does not
           return (aStr.length() < bStr.length() ? A_WINS : B_WINS);
         }
-        if (aStr.indexOf("|") >= 0 || bStr.indexOf("|") >= 0)
-          return TIED; // TODO!
+        if (aStr.indexOf("|") >= 0 || bStr.indexOf("|") >= 0) {
+          // Mata(2005) Figure 9
+          // TODO: Still some issues here....
+          // We are trying to ascertain that
+          // R lull                  R luuu
+          // S luuu   is the same as S lull
+          // maybe "min for one is the same as min for the other?"
+          // 
+          String[] aList = PT.split(aStr, "|");
+          String[] bList = PT.split(bStr, "|");
+          int minScore = Integer.MAX_VALUE;
+          aStr = aList[0];
+          bStr = bList[0];
+          for (int i = 0; i < 2; i++) {
+            for (int j = 0; j < 2; j++) {
+              int score = compareRule4PairStr(aList[i], bList[j], true);
+              if (score <= minScore) {
+                minScore = score;
+                aStr = aList[i];
+                bStr = bList[j];
+              }
+            }
+          }
+        }
+      } else {
+        // trim off priority numbers
+        aStr = PT.rep(aStr.substring(1), "~", "");
+        bStr = PT.rep(bStr.substring(1), "~", "");
       }
+      return compareRule4PairStr(aStr, bStr, false);
+    }
 
-      // TODO: preliminary only. The challenge is to get these strings lined 
up right.
-      aStr = PT.rep(aStr, "~", "");
-      bStr = PT.rep(bStr, "~", "");
-      System.out.println("Rule 4b comparing " + aStr + " " + bStr);
+    private int compareRule4PairStr(String aStr, String bStr, boolean 
isRSTest) {
+      System.out.println(this + " Rule 4b comparing " + aStr + " " + bStr);
       doCheckPseudo = false;
       int n = aStr.length();
       if (n == 0 || n != bStr.length())
@@ -1646,8 +1672,10 @@
         boolean alike = (aref == aStr.charAt(c));
         boolean blike = (bref == bStr.charAt(c));
         if (alike != blike)
-          return (alike ? A_WINS : B_WINS);
+          return (isRSTest ? c : alike ? A_WINS : B_WINS);
       }
+      if (isRSTest)
+        return TIED;
       if (aref == bref)
         return IGNORE;
       doCheckPseudo = (aref == 'R' || aref == 'S');
@@ -1654,8 +1682,16 @@
       return aref < bref ? A_WINS : B_WINS;
     }
 
-    private String getMataList(String[] rule4List) {
-      String[] listA = condenseList(rule4List);
+    private String getMataList(int ia) {
+      String[] rule4List = atoms[ia].rule4List;
+      int n = 0;
+      for (int i = rule4List.length; --i >= 0;)
+        if (rule4List[i] != null)
+          n++;
+      String[] listA = new String[n];
+      for (int i = rule4List.length; --i >= 0;)
+        if (rule4List[i] != null)
+          listA[--n] = rule4List[i];
       Arrays.sort(listA);
       String aref = getMataRef(listA);
       switch (aref.length()) {
@@ -1679,17 +1715,21 @@
         String rs = lst[i];
         if (rs.length() > len)
           len = rs.length();
-        if (rs.startsWith(aref))
+        if (rs.indexOf(aref) == 1)
           sorted[pt++] = rs;
       }         
       for (int i = 0; i < n; i++) {
         String rs = lst[i];
-        if (!rs.startsWith(aref))
+        if (rs.indexOf(aref) != 1)
           sorted[pt++] = rs;
       }
+      
+      for (int i = 0; i < n; i++) {
+        System.out.println("Sorted Mata list " + i + " " + sorted[i]);  
+      }
       String mlist = "";
       char ch;
-      for (int i = 0; i < len; i++) {
+      for (int i = 1; i < len; i++) {
          for (int j = 0; j < n; j++) {
            String rs = sorted[j];
            if (i < rs.length() &&  (ch = rs.charAt(i)) != '~' && ch != ';')    
         
@@ -1700,113 +1740,58 @@
     }
 
     private String getMataRef(String[] lst) {
-      // TODO: does not take into consideration initial ~~ 
-      switch  (lst.length) {
+      // get highest-ranking chiral unit
+      int pt = Integer.MAX_VALUE;
+      for (int i = 0; i < lst.length; i++) {
+        String s = lst[i];
+        int j = 1;
+        for (int n = s.length(); j < n; j++)
+          if (s.charAt(j) != '~')
+            break;
+        if (j < pt)
+          pt = j;
+      }
+      switch (lst.length) {
       case 1:
         // R or S
-        return lst[0].substring(0, 1);
+        return lst[0].substring(pt, pt + 1);
       case 2:
-        // RR RS SR SS
-        return (lst[0].charAt(0) == lst[1].charAt(0) ? 
-            lst[0].substring(0, 1) : "RS");           
+        // 1R2R 1R2S 1S2R 1S2S
+        // 1R1R 1R1S 1S1R 1S1S
+        // 1R1~ 1S1~ 1R2~ 1S2~
+        // 1~2R 1~2S
+        char pa = lst[0].charAt(0);
+        char pb = lst[1].charAt(0);
+        char ca = lst[0].charAt(pt);
+        char cb = lst[1].charAt(pt);
+        return (ca == cb || cb == '~' || pa < pb && ca != '~' ? "" + ca
+            : pa == pb ? "RS" : "" + cb);
       case 3:
-        return lst[1].substring(0, 1);
+        char p1 = lst[0].charAt(0);
+        char p2 = lst[1].charAt(0);
+        char p3 = lst[2].charAt(0);
+        char c1 = lst[0].charAt(pt);
+        char c2 = lst[1].charAt(pt);
+        char c3 = lst[2].charAt(pt);
+        // 1 1 1
+        if (p1 == p2 && p2 == p3)
+          return (c1 == c2 || c2 == '~' ? "" + c1 // RRR RRS SSS RR~ SS~ R~~ 
S~~
+          : c2 == c3 ? "" + c3 // RSS SSS 
+          : "RS" // RS~
+          );
+        // 1 1 2
+        if (p1 == p2)
+          return (p1 == '~' ? "" + c3 : c1 == c2 || c2 == '~' ? "" + c1 : 
"RS");
+        // 1 2 2
+        if (p2 == p3)
+          return (p1 != '~' ? "" + c1 : c2 == c3 || c3 == '~' ? "" + c2 : 
"RS");
+        // 1 2 3 
+        return "" + (c1 != '~' ? c1 : c2 != '~'  ? c2 : c3);
       }
       return "";
     }
 
     /**
-     * remove unnecessary nulls
-     * @param a
-     * @return trimmed array
-     */
-    private String[] condenseList(String[] a) {
-      int n = 0;
-      for (int i = a.length; --i >= 0;)
-        if (a[i] != null)
-          n++;
-      String[] b = new String[n];
-      for (int i = a.length; --i >= 0;)
-        if (a[i] != null)
-          b[--n] = a[i];
-      return b;
-    }
-
-    /**
-     * Reverse the path to the parent and check r/s chirality
-     * 
-     * @param ties
-     * @param indices
-     * 
-     */
-    private void checkPseudoHandedness(BS ties, int[] indices) {
-      int ia = ties.nextSetBit(0);
-      int ib = ties.nextSetBit(ia + 1);
-      CIPAtom atom1;
-      if (auxPseudo == null) {
-        // critical here that we do NOT include the tied branches
-        atom1 = (CIPAtom) clone();
-        atom1.atoms[indices[ia]] = new CIPAtom(null, atom1, false, isAlkene);
-        atom1.atoms[indices[ib]] = new CIPAtom(null, atom1, false, isAlkene);
-        atom1.addReturnPath(null, this);
-      } else {
-        atom1 = auxPseudo;
-      }
-      int thisRule = currentRule;
-      currentRule = RULE_1;
-      atom1.sortSubstituents();
-      currentRule = thisRule;
-      // Now add the tied branches at the end; it doesn't matter where they 
-      // go as long as they are together and in order.
-      atom1.atoms[bondCount - 2] = atoms[Math.min(indices[ia], indices[ib])];
-      atom1.atoms[bondCount - 1] = atoms[Math.max(indices[ia], indices[ib])];
-      int rs = atom1.checkHandedness();
-      if (Logger.debugging) {
-        for (int i = 0; i < 4; i++)
-          Logger.info("pseudo " + rs + " " + priorities[i] + " "
-              + atoms[i].myPath);
-      }
-      if (rs == STEREO_R || rs == STEREO_S) {
-        isPseudo = true;
-      }
-    }
-
-
-    /**
-     * 
-     * Create a priority key that matches elemNo and massNo.
-     * 
-     * We can skip the duplicate flag, because all these have substituents.
-     * 
-     * @param a
-     * @return a shifted key based on elemNo and massNo
-     */
-    private int getBasePriority(CIPAtom a) {
-      int code = 0;
-      if (a.atom == null) {
-        code = 0x7FFFF << PRIORITY_SHIFT[2];
-      } else {
-        code = ((127 - a.elemNo) << PRIORITY_SHIFT[0])
-            | ((255 - a.massNo) << PRIORITY_SHIFT[2]);
-      }
-      return code;
-    }
-    
-
-    /**
-     * reset auxEZ chirality to "undetermined"
-     */
-    void resetAuxiliaryChirality() {
-      auxEZ = STEREO_UNDETERMINED;
-      for (int i = 0; i < 4; i++)
-        if (atoms[i] != null && atoms[i].atom != null)
-          atoms[i].resetAuxiliaryChirality();
-      if (auxParentReversed != null)
-        auxParentReversed.resetAuxiliaryChirality();
-      if (auxPseudo != null)
-        auxPseudo.resetAuxiliaryChirality();
-    }
-    /**
      * This method creates a list of downstream (higher-sphere) auxiliary 
chirality designators
      * R, S, r, and s that are passed upstream ultimately to the Sphere-1 root 
substituent.
      * 
@@ -1832,8 +1817,8 @@
         for (int i = 0; i < 4; i++) {
           CIPAtom a = atoms[i];
           if (a != null && !a.isDuplicate && !a.isTerminal) {
-            String ssub = rule4List[i] = a
-                .createAuxiliaryRSCenters(false);
+            String ssub = a.createAuxiliaryRSCenters(false);
+            rule4List[i] = priorities[i] + ssub;
             if ("sr".indexOf(ssub) >= 0 || ssub.indexOf("R") >= 0 || 
ssub.indexOf("S") >= 0) {
               mataList[nRS] = i;
               nRS++;
@@ -1840,7 +1825,7 @@
               subRS += ssub + ";";
             } else {
               rule4List[i] = null;
-              subRS += "~";
+//              subRS += "~";
             }
           }
         }
@@ -1860,6 +1845,7 @@
               break;
             case NOT_RELEVANT:
               // create a ?<sphere>[....] object ?
+              done = false;
               adj = TIED;
               break;
             case TIED:
@@ -1899,8 +1885,7 @@
         }
       }
       s += subRS;
-      if (sphere < 2 && !done)
-        System.out.println(this + " creating aux " + s);
+      System.out.println(this + " creating aux " + s);
       return s;
     }
 
@@ -1915,7 +1900,9 @@
      *         if diastereomeric
      */
     private int compareRule4aEnantiomers(String rs1, String rs2) {
-      if (rs1.indexOf("R") < 0 && rs1.indexOf("S") < 0)
+      
+      if (rs1.indexOf("R") < 0 && rs1.indexOf("S") < 0
+          || rs1.charAt(0) != rs2.charAt(0))
         return NOT_RELEVANT;
       int n = rs1.length(); 
       if (n != rs2.length())
@@ -1935,6 +1922,81 @@
     }
 
     /**
+     * Reverse the path to the parent and check r/s chirality
+     * 
+     * @param ties
+     * @param indices
+     * 
+     */
+    private void checkPseudoHandedness(BS ties, int[] indices) {
+      int ia = ties.nextSetBit(0);
+      int ib = ties.nextSetBit(ia + 1);
+      CIPAtom atom1;
+      if (auxPseudo == null) {
+        // critical here that we do NOT include the tied branches
+        atom1 = (CIPAtom) clone();
+        atom1.atoms[indices[ia]] = new CIPAtom(null, atom1, false, isAlkene);
+        atom1.atoms[indices[ib]] = new CIPAtom(null, atom1, false, isAlkene);
+        atom1.addReturnPath(null, this);
+      } else {
+        atom1 = auxPseudo;
+      }
+      int thisRule = currentRule;
+      currentRule = RULE_1;
+      atom1.sortSubstituents();
+      currentRule = thisRule;
+      // Now add the tied branches at the end; it doesn't matter where they 
+      // go as long as they are together and in order.
+      atom1.atoms[bondCount - 2] = atoms[Math.min(indices[ia], indices[ib])];
+      atom1.atoms[bondCount - 1] = atoms[Math.max(indices[ia], indices[ib])];
+      int rs = atom1.checkHandedness();
+      if (Logger.debugging) {
+        for (int i = 0; i < 4; i++)
+          Logger.info("pseudo " + rs + " " + priorities[i] + " "
+              + atoms[i].myPath);
+      }
+      if (rs == STEREO_R || rs == STEREO_S) {
+        isPseudo = true;
+      }
+    }
+
+
+    /**
+     * 
+     * Create a priority key that matches elemNo and massNo.
+     * 
+     * We can skip the duplicate flag, because all these have substituents.
+     * 
+     * @param a
+     * @return a shifted key based on elemNo and massNo
+     */
+    private int getBasePriority(CIPAtom a) {
+      int code = 0;
+      if (a.atom == null) {
+        code = 0x7FFFF << PRIORITY_SHIFT[2];
+      } else {
+        code = ((127 - a.elemNo) << PRIORITY_SHIFT[0])
+            | ((255 - a.massNo) << PRIORITY_SHIFT[2]);
+      }
+      return code;
+    }
+    
+
+    /**
+     * reset auxEZ chirality to "undetermined"
+     */
+    void resetAuxiliaryChirality() {
+      auxEZ = STEREO_UNDETERMINED;
+      for (int i = 0; i < 4; i++)
+        if (atoms[i] != null && atoms[i].atom != null)
+          atoms[i].resetAuxiliaryChirality();
+      if (auxParentReversed != null)
+        auxParentReversed.resetAuxiliaryChirality();
+      if (auxPseudo != null)
+        auxPseudo.resetAuxiliaryChirality();
+    }
+
+    /**
      * Swap a substituent and the parent in preparation for reverse traversal 
of
      * this path
      * 

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


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to