Revision: 21556 http://sourceforge.net/p/jmol/code/21556 Author: hansonr Date: 2017-04-27 04:01:48 +0000 (Thu, 27 Apr 2017) Log Message: ----------- CIP validates for Rules 1-5 for 86 compounds
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-26 05:19:28 UTC (rev 21555) +++ trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java 2017-04-27 04:01:48 UTC (rev 21556) @@ -631,7 +631,7 @@ + Integer.toHexString(cipAtom.prevPriorities[i])); } } - if (cipAtom.aChiral) { + if (cipAtom.achiral) { isChiral = false; } else { for (int i = 0; i < cipAtom.bondCount - 1; i++) { @@ -641,6 +641,8 @@ } } } + if (currentRule == 5) + cipAtom.isPseudo = true; } if (isChiral) { rs = (!isAlkene ? cipAtom.checkHandedness() @@ -861,7 +863,7 @@ /** * Force achiral condition due to double ties. */ - boolean aChiral; + boolean achiral; /** * true atom covalent bond count @@ -1163,7 +1165,7 @@ if (prevPriorities[i] == 0 && currentRule > RULE_1) prevPriorities[i] = getBasePriority(atoms[i]); } - boolean checkRule4List = (currentRule == RULE_4 && rule4List != null); + boolean checkRule4List = (currentRule > RULE_3 && rule4List != null); for (int i = 0; i < n; i++) { CIPAtom a = atoms[i]; for (int j = i + 1; j < n; j++) { @@ -1171,8 +1173,9 @@ int score = (a.atom == null ? B_WINS : b.atom == null ? A_WINS : prevPriorities[i] == prevPriorities[j] ? TIED : prevPriorities[j] < prevPriorities[i] ? B_WINS : A_WINS); + // if this is Rule 4, then we do a check of the forward-based stereochemical path if (score == TIED) - score = (checkRule4List ? checkRule4(i, j) : a.compareTo(b)); + score = (checkRule4List ? checkRule4And5(i, j) : a.compareTo(b)); if (Logger.debuggingHigh) Logger.info("ordering " + this.id + "." + i + "." + j + " " + this + "-" + a + " vs " + b + " = " + score); @@ -1179,6 +1182,8 @@ switch (score) { case IGNORE: // just increment the index and go on to the next rule -- no breaking of the tie + if (checkRule4List && sphere == 0) + achiral = true; // two ligands for the root atom found to be equivalent in Rule 4 must be achiral indices[i]++; if (Logger.debuggingHigh) Logger.info(atom + "." + b + " ends up with tie with " + a); @@ -1259,7 +1264,7 @@ checkPseudoHandedness(ties, indices); //} } else if (sphere == 0) { - aChiral = true; + achiral = true; } } if (Logger.debugging) { @@ -1592,18 +1597,16 @@ * @param j * @return 0 (TIED), -1 (A_WINS), 1 (B_WINS), Integer.MIN_VALUE (IGNORE) */ - private int checkRule4(int i, int j) { + private int checkRule4And5(int i, int j) { // rule4List[i] = ?1[RR;;SR;;SR;;] ==> atoms[i].rule4List = [RR; SR; SR;] // rule4List[j] = ?1[SR;;RS;;RS;;] ==> atoms[j].rule4List = [SR; RS; RS;] - // note that opposites will need to generate "R" or "S" keys, which will be - // resolved as "r" or "s" - // but generally we will want to process this as "R" and "S" - // note that this analysis cannot be done ahead of time. - return (rule4List[i] == null && rule4List[j] == null ? TIED - : rule4List[i] != null && rule4List[j] != null ? compareRule4Pair(i, j) : rule4List[i] == null ? B_WINS - : A_WINS); + if (rule4List[i] == null && rule4List[j] == null) + return TIED; + if (rule4List[i] == null || rule4List[j] == null) + return rule4List[j] == null ? A_WINS : B_WINS; + return compareMataPair(i, j); } - + /** * Chapter 9 Rules 4 and 5: like vs. unlike * @@ -1614,20 +1617,28 @@ * * @param ia * @param ib + * @param isRule5 * @return 0 (TIED), -1 (A_WINS), or 1 (B_WINS), or Integer.MIN_VALUE * (IGNORE) */ - private int compareRule4Pair(int ia, int ib) { + private int compareMataPair(int ia, int ib) { + boolean isRule5 = (currentRule == RULE_5); + // note that opposites will need to generate "R" or "S" keys, which will be + // resolved as "r" or "s" + // but generally we will want to process this as "R" and "S" + // note that this analysis cannot be done ahead of time String aStr = rule4List[ia]; String bStr = rule4List[ib]; if (aStr != null && aStr.indexOf("?") == 1) { - aStr = getMataList(ia); - bStr = getMataList(ib); + aStr = getMataList(ia, isRule5); + bStr = getMataList(ib, isRule5); 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 (isRule5) + return aStr.compareTo(bStr); if (aStr.indexOf("|") >= 0 || bStr.indexOf("|") >= 0) { // Mata(2005) Figure 9 // TODO: Still some issues here.... @@ -1701,10 +1712,11 @@ * Retrieve the Mata Rule 4b list for a given atom. * * @param ia + * @param isRule5 * @return a String representation of the path through the atoms * */ - private String getMataList(int ia) { + private String getMataList(int ia, boolean isRule5) { String[] rule4List = atoms[ia].rule4List; int n = 0; for (int i = rule4List.length; --i >= 0;) @@ -1715,7 +1727,7 @@ if (rule4List[i] != null) listA[--n] = rule4List[i]; Arrays.sort(listA); - String aref = getMataRef(listA); + String aref = (isRule5 ? "R" : getMataRef(listA)); switch (aref.length()) { default: case 0: @@ -1722,53 +1734,82 @@ System.out.println("???"); return "???"; case 1: - return getMataSequence(listA, aref); + return getMataSequence(listA, aref, isRule5); case 2: - return getMataSequence(listA, "R") + "|" + getMataSequence(listA, "S"); + return getMataSequence(listA, "R", false) + "|" + getMataSequence(listA, "S", false); } } /** - * This is the key Mata method -- getting the correct sequence of atoms. + * This is the key Mata method -- getting the correct sequence of R and S + * from a set of diasteromorphic paths. Given a specific reference + * designation, the task is to sort the paths based on priority (we can't + * change the base priority already determined using Rules 1-3) and + * reference. * + * We do the sort lexicographically, simply using Array.sort(String[]) with + * our reference atom temporarily given the lowest ASCII characater "A" + * (65). + * * @param lst * @param aref + * @param isRule5 * @return one string, possibly separated by | indicating that the result * has both an R and S side to it */ - private String getMataSequence(String[] lst, String aref) { - int n = lst.length; - String[] sorted = new String[n]; - int pt = 0; + private String getMataSequence(String[] lst, String aref, boolean isRule5) { + String[] sorted = (isRule5 ? lst : getMataSortedList(lst, aref)); + int n = sorted.length; int len = 0; for (int i = 0; i < n; i++) { - String rs = lst[i]; + String rs = sorted[i]; if (rs.length() > len) len = rs.length(); - if (rs.indexOf(aref) == 1) - sorted[pt++] = rs; - } - for (int i = 0; i < n; i++) { - String rs = lst[i]; - if (rs.indexOf(aref) != 1) - sorted[pt++] = rs; } - for (int i = 0; i < n; i++) { - System.out.println("Sorted Mata list " + i + " " + sorted[i]); - } + + // Strip out all non-R/S designations String mlist = ""; char ch; 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 != ';') - mlist += ch; - } - } + for (int j = 0; j < n; j++) { + String rs = sorted[j]; + if (i < rs.length() && (ch = rs.charAt(i)) != '~' && ch != ';') + mlist += ch; + } + if (isRule5) { + // clear out this sphere and resort + for (int j = 0; j < n; j++) { + String rs = sorted[j]; + if (i < rs.length()) + sorted[j] = rs.substring(0, i) + "~" + rs.substring(i + 1); + } + Arrays.sort(sorted); + } + } return mlist; } /** + * @param lst + * @param aref + * @return + */ + private String[] getMataSortedList(String[] lst, String aref) { + int n = lst.length; + String[] sorted = new String[n]; + for (int i = 0; i < n; i++) + sorted[i] = PT.rep(lst[i], aref, "A"); + Arrays.sort(sorted); + for (int i = 0; i < n; i++) + sorted[i] = PT.rep(sorted[i], "A", aref); + + for (int i = 0; i < n; i++) { + System.out.println("Sorted Mata list " + i + " " + sorted[i]); + } + return sorted; + } + + /** * Determine the reference configuration. * * @param lst @@ -2089,9 +2130,20 @@ */ private int checkRule5(CIPAtom b) { // TODO + System.out.println("Rule 5 for " + this + " vs. " + b); int isRa = ";srSR;".indexOf(getWorkingChirality()); int isRb = ";srSR;".indexOf(b.getWorkingChirality()); - return (isRa == isRb ? TIED : isRa > isRb ? A_WINS : B_WINS); + if (isRa != isRb) + return (isRa > isRb ? A_WINS : B_WINS); + if (rule4List == null || b.rule4List == null) + return TIED; + for (int i = 0; i < 4; i++) + if (rule4List[i] != null) { + System.out.println(PT.toJSON(this + ".rule4List", rule4List)); + System.out.println(PT.toJSON(b + ".rule4List", b.rule4List)); + break; + } + return TIED; } /** 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