Revision: 21489 http://sourceforge.net/p/jmol/code/21489 Author: hansonr Date: 2017-04-07 00:35:17 +0000 (Fri, 07 Apr 2017) Log Message: ----------- Jmol.___JmolVersion="14.12.0" // 2017-04-06
new feature: {atom}.chirality -- uses Cohen-Ingold-Prelog rules to assign R or S to a carbon center -- ignores sulfur chirality -- may not fully implement high symmetry cases -- not fully tested -- Checked using: function checkchiral(m) { if (m) load @m background label yellow color labels black select _C label %[atomname] refresh var b = {_C} for (var a in b) { var c = a.chirality; print _smilesString + " " + a + c if (c) { select a c = a.atomname + " " + c label @c } } select * } checkchiral("$(R)-glycidol") delay 1 checkchiral("$glucose") delay 1 checkchiral("$(2S,3R)-2,3-oxiranediol") delay 1 checkchiral("$(S)-2-butanol") delay 1 checkchiral("$(R)-2-butanol") delay 1 checkchiral("$(2S,3R)-2,3-butanediol") delay 1 checkchiral("$(2S,3S)-2,3-butanediol") delay 1 checkchiral("$(2R,3R)-2,3-butanediol") delay 1 checkchiral("$(2R,3S)-2,3-butanediol") delay 1 checkchiral("$1,4-dimethylcyclohexane") delay 1 checkchiral("$cholesterol") // (3S,8S,9S,10R,13R,14S,17R) and sidechain R 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-06 23:19:22 UTC (rev 21488) +++ trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java 2017-04-07 00:35:17 UTC (rev 21489) @@ -88,7 +88,7 @@ public String getRorS(CIPAtom a) { try { - CIPAtom[] atoms = a.sortFourAtoms(); + CIPAtom[] atoms = sortFourAtoms(a.atoms, false); if (atoms == null) return ""; SmilesMatcherInterface sm = vwr.getSmilesMatcher(); @@ -107,6 +107,104 @@ } } + /** + * The main loop that starts all the iteration of breakTie. + * + * @param atoms + * + * @return true if we have four distinct atoms in the end + */ + private static CIPAtom[] sortFourAtoms(CIPAtom[] atoms, boolean allowTie) { + int n = atoms.length; + for (int i = 0; i < n; i++) + atoms[i].isAbove = 0; + for (int i = 0; i < n; i++) { + CIPAtom a = atoms[i]; + for (int j = i + 1; j < n; j++) { + CIPAtom b = atoms[j]; + int score = (int) Math.signum(a.compareTo(b)); + if (Logger.debugging) + Logger.info("comparing " + a + " and " + b + " = " + score); + switch (score) { + case 1: + a.isAbove++; + break; + case -1: + b.isAbove++; + break; + case 0: + switch (breakTie(a, b)) { + case 1: + a.isAbove++; + break; + case -1: + b.isAbove++; + break; + case 0: + if (allowTie) + a.isAbove++; + else + return null; + } + } + } + } + CIPAtom[] ret = new CIPAtom[n]; + for (int i = 0; i < n; i++) + ret[atoms[i].isAbove] = atoms[i]; + if (Logger.debugging) + for (int i = 0; i < n; i++) + Logger.info("" + ret[i]); + return ret; + } + + /** + * Break a tie at any level in the iteration between to atoms that + * otherwise are the same by sorting heir + * + * @param a + * @param b + * @return -1 + */ + private static int breakTie(CIPAtom a, CIPAtom b) { + if (!a.set() || !b.set() || a.isTerminal || a.atom == b.atom) + return 0; + if (Logger.debugging) + Logger.info("tie for " + a + " and " + b); + // check to see if any of the three connections to a and b are different. + for (int i = 0; i < a.nAtoms; i++) { + CIPAtom ai = a.atoms[i]; + CIPAtom bi = b.atoms[i]; + int score = (int) Math.signum(compareAB(ai, bi)); + switch (score) { + case -1: + case 1: + return score; + case 0: + break; + } + } + // all are the same -- check to break tie next level + // now isDummy counts + + a.atoms = sortFourAtoms(a.atoms, true); + b.atoms = sortFourAtoms(b.atoms, true); + + for (int i = 0; i < a.nAtoms; i++) { + CIPAtom ai = a.atoms[i]; + CIPAtom bi = b.atoms[i]; + int score = (ai.isDummy == bi.isDummy ? breakTie(ai, bi) : ai.isDummy ? -1 : 1); + switch (score) { + case -1: + case 1: + return score; + case 0: + } + } + // all are the same and no tie breakers + return 0; + } + private class CIPAtom implements Comparable<CIPAtom> { /** @@ -170,7 +268,7 @@ /** * Number of substituent atoms. */ - private int nAtoms; + int nAtoms; @Override public String toString() { @@ -198,8 +296,8 @@ isDummy = true; } else { bsPath.set(iatom); - this.isDummy = isDummy; } + this.isDummy = isDummy; } /** @@ -213,6 +311,9 @@ return true; if (isSet) return true; + isSet = true; + if (isDummy) + return false; atoms = new CIPAtom[parent == null ? 4 : 3]; int nBonds = atom.getBondCount(); Edge[] bonds = atom.getEdges(); @@ -253,6 +354,7 @@ nAtoms = pt; for (; pt < atoms.length; pt++) atoms[pt] = new CIPAtom(null, null, true); + Arrays.sort(atoms); return !isTerminal; } @@ -272,94 +374,6 @@ } /** - * The main loop that starts all the iteration of breakTie. - * - * @return true if we have four distinct atoms in the end - */ - CIPAtom[] sortFourAtoms() { - for (int i = 0; i < 4; i++) { - CIPAtom a = atoms[i]; - for (int j = i + 1; j < 4; j++) { - CIPAtom b = atoms[j]; - int score = (int) Math.signum(a.compareTo(b)); - if (Logger.debugging) - Logger.info("comparing " + a + " and " + b + " = " + score); - switch (score) { - case 1: - a.isAbove++; - break; - case -1: - b.isAbove++; - break; - case 0: - switch (breakTie(a, b)) { - case 1: - a.isAbove++; - break; - case -1: - b.isAbove++; - break; - case 0: - return null; - } - } - } - } - CIPAtom[] ret = new CIPAtom[4]; - for (int i = 0; i < 4; i++) - ret[atoms[i].isAbove] = atoms[i]; - if (Logger.debugging) - for (int i = 0; i < 4; i++) - Logger.info("" + ret[i]); - return ret; - } - - /** - * Break a tie at any level in the iteration between to atoms that - * otherwise are the same by sorting heir - * - * @param a - * @param b - * @return -1 - */ - private int breakTie(CIPAtom a, CIPAtom b) { - if (!a.set() || !b.set() || a.isTerminal || a.atom == b.atom) - return 0; - if (Logger.debugging) - Logger.info("tie for " + a + " and " + b); - Arrays.sort(a.atoms); - Arrays.sort(b.atoms); - // check to see if any of the three connections to a and b are different. - for (int i = 0; i < a.nAtoms; i++) { - CIPAtom ai = a.atoms[i]; - CIPAtom bi = b.atoms[i]; - int score = (int) Math.signum(compareAB(ai, bi)); - switch (score) { - case -1: - case 1: - return score; - case 0: - break; - } - } - // all are the same -- check to break tie next level - // now isDummy counts - for (int i = 0; i < a.nAtoms; i++) { - CIPAtom ai = a.atoms[i]; - CIPAtom bi = b.atoms[i]; - int score = (ai.isDummy == bi.isDummy ? breakTie(ai, bi) : ai.isDummy ? -1 : 1); - switch (score) { - case -1: - case 1: - return score; - case 0: - } - } - // all are the same and no tie breakers - return 0; - } - - /** * used in Array.sort and sortFourAtoms; includes isDummy check */ @Override 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