Revision: 21609 http://sourceforge.net/p/jmol/code/21609 Author: hansonr Date: 2017-05-19 17:09:25 +0000 (Fri, 19 May 2017) Log Message: ----------- Jmol.___JmolVersion="14.16.1" // 2017.05.19
new feature: load =chebi/nnnnnn chEBI 2D molecule load, with minimal 100-step minimization bug fix: CML reader does not read 2D wedge/hash information bug fix: CIP fix for missing branch descriptors; 984 lines bug fix: CIP adds helicene M/P chirality - validated using CCDC structures HEXHEL02 HEXHEL03 HEXHEL04 ODAGOS ODAHAF - http://pubs.rsc.org/en/content/articlehtml/2017/CP/C6CP07552E code: CIP: additional simplification; code: CIP status: implementation complete, including: All subrules implemented fully: 1a, 1b, 2, 3, 4a, 4b, 4c, 5 R/S, E/Z, M/P (odd-cumulene and helicene), r/s, seqCis/seqTrans (as Z/E) fused benzenoid aromatic Mancude ring "Kekule weighted" atom number adjustments * Added logic to Rule 1b: The root distance for a Kekule-ambiguous duplicate * atom is its own sphere, not the sphere of its duplicated atom. * * Stated more precisely: * * Proposed amended Sequence Rule 1: * * (1a) higher atomic number precedes lower; * * (1b) in comparing two duplicate nodes, lower root distance precedes higher * root distance, where "root distance" is defined: * * (i) in the case of a duplicate atom for which the atomic number is averaged * over two or more atoms in applying Rule 1a, the distance from the duplicate * node itself to the root node; and * * (ii) in all other cases, the distance of its corresponding nonduplicated atom * node to the root node. * IUPAC Blue Book 2013 errors of note: ,"147":"r,,,R,,,,r,,,S" // chiral phosphine ignored in BB P-93.5.1.1.2 for S vs R { "id" : "148" "name_pname_pin" : "bis[(1r,4r)-4-methylcyclohexyl]phosphane" "ref_pname_pin" : "P-93.5.1.1.2" "stereo" : ",r,,,R,,,,r,,,R,,," } ,"148":"r,,,S,,,,r,,,R,,,,s,,,s" // r,,,S,,,,r,,,S,,,,s,,,S Jmol disagrees with BB P-93.5.1.1.2 or R and S p. 1243 { "id" : "149" "name_pname_pin" : "bis[(1r,4r)-4-methylcyclohexyl]-(1s,4s)-4-methylcyclohexylphosphane" "ref_pname_pin" : "P-93.5.1.1.2" "stereo" : ",r,,,S,,,,r,,,S,,,,s,,,S,,," } ,"202":"RR" // // p. 1265 disagrees with BB P-93.5.3.5 for RR vs. SS { "id" : "203" "name_pname_pin" : "(5S,8R,11S)-1,12-dioxatrispiro[4.2.2.4^{11}.2^{8}.2^{5}]nonadecane" "ref_pname_pin" : "P-93 5.3.5" } ,"227":"SrSEErS" // disagrees with BB P-93.5.7.2 for S vs. r { "id" : "228" "name_pname_pin" : "(1E)-1-{(1'S,1r,4s)-[1,1'-bi(cyclohexan)]-3'-en-4-yl}-N-[(1r,4r)-4-phenylcyclohexyl]methan-1-imine" "ref_pname_pin" : "P-93.5.7.2" "stereo" : "S,,,,,,,r,S,,,,,,,E,,r,r,,,,,,,,,,,," } ,"230":"@3D RrRsR" // p 1282 disagrees with BB P-93.6 { "id" : "231" "name_pname_pin" : "(2R)-1-[(1r,4R)-4-methylcyclohexyl]-3-[(1s,4S)-4-methylcyclohexyl]propan-2-ol" "ref_pname_pin" : "P-93.6" "stereo" : ",,,,r,,,R,,,,s,,,R,,," } Modified Paths: -------------- trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlCmlReader.java trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java trunk/Jmol/src/org/jmol/modelset/ModelSet.java trunk/Jmol/src/org/jmol/scriptext/CmdExt.java trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java trunk/Jmol/src/org/jmol/util/CommandHistory.java trunk/Jmol/src/org/jmol/viewer/FileManager.java trunk/Jmol/src/org/jmol/viewer/JC.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/Viewer.java Modified: trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlCmlReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlCmlReader.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlCmlReader.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -125,7 +125,7 @@ protected String moleculeID; protected Map<String, Object> htModelAtomMap; - private boolean is2d; + private boolean optimize2d; /** * state constants @@ -142,14 +142,14 @@ MOLECULE_ATOM_SCALAR = 9, MOLECULE_BOND_ARRAY = 10, MOLECULE_BOND = 11, - MOLECULE_FORMULA = 12, - MOLECULE_ATOM_BUILTIN = 13, - MOLECULE_BOND_BUILTIN = 14, - MODULE = 15, + MOLECULE_BOND_STEREO = 12, + MOLECULE_FORMULA = 13, + MOLECULE_ATOM_BUILTIN = 14, + MOLECULE_BOND_BUILTIN = 15, + MODULE = 16, SYMMETRY = 17, LATTICE_VECTOR = 18, ASSOCIATION = 19; - /** * the current state */ @@ -169,8 +169,10 @@ @Override protected void processXml(XmlReader parent, Object saxReader) throws Exception { - is2d = parent.checkFilterKey("2D"); + optimize2d = parent.checkFilterKey("2D"); processXml2(parent, saxReader); + if (optimize2d) + set2D(); } @Override @@ -306,7 +308,7 @@ for (int i = tokenCount; --i >= 0;) atomArray[i].atomName = tokens[i]; } - boolean is3d = (!is2d && (val = atts.get("x3")) != null); + boolean is3d = (!optimize2d && (val = atts.get("x3")) != null); if (is3d) { is3d = true; coords3D = true; @@ -418,8 +420,14 @@ setKeepChars(true); state = MOLECULE_BOND_BUILTIN; scalarDictValue = val; + } else if (name.equals("bondstereo")) { + state = MOLECULE_BOND_STEREO; } break; + case MOLECULE_BOND_STEREO: + setKeepChars(true); + state = MOLECULE_BOND_STEREO; + break; case MOLECULE_ATOM: if (name.equals("scalar")) { state = MOLECULE_ATOM_SCALAR; @@ -622,6 +630,13 @@ atom.elementSymbol = chars.toString(); setKeepChars(false); break; + case MOLECULE_BOND_STEREO: + String stereo = chars.toString(); + if (bond.order == 1) + bond.order = (stereo.equals("H") ? JmolAdapter.ORDER_STEREO_FAR : JmolAdapter.ORDER_STEREO_NEAR); + setKeepChars(false); + state = MOLECULE_BOND; + break; case MOLECULE_BOND_BUILTIN: // ACD Labs state = MOLECULE_BOND; if (scalarDictValue.equals("atomRef")) { @@ -690,8 +705,10 @@ parent.applySymmetryToBonds = true; a1 = fixSerialName(a1); a2 = fixSerialName(a2); - if (joinList == null || !checkBondToR(a1, a2)) + if (joinList == null || !checkBondToR(a1, a2)) { asc.addNewBondFromNames(a1, a2, order); + bond = asc.bonds[asc.bondCount - 1]; + } } private String fixSerialName(String a) { Modified: trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java =================================================================== --- trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/adapter/readers/xml/XmlReader.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -33,6 +33,7 @@ import org.jmol.adapter.smarter.Atom; import org.jmol.adapter.smarter.AtomSetCollection; import org.jmol.adapter.smarter.AtomSetCollectionReader; +import org.jmol.adapter.smarter.Bond; import org.jmol.adapter.smarter.Resolver; import org.jmol.api.Interface; import org.jmol.util.Logger; @@ -92,6 +93,7 @@ public class XmlReader extends AtomSetCollectionReader { protected Atom atom; + protected Bond bond; //protected String[] domAttributes; protected XmlReader parent; // XmlReader itself; to be assigned by the subReader public Map<String, String> atts; Modified: trunk/Jmol/src/org/jmol/modelset/ModelSet.java =================================================================== --- trunk/Jmol/src/org/jmol/modelset/ModelSet.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/modelset/ModelSet.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -2964,6 +2964,8 @@ vwr.shm.setShapeSizeBs(JC.SHAPE_BALLS, 0, vwr.rd, BSUtil.newAndSetBit(atomIndex)); setAtomName(atomIndex, type + atom.getAtomNumber(), false); + if (vwr.getBoolean(T.modelkitmode)) + am[atom.mi].isModelKit = true; if (!am[atom.mi].isModelKit) taintAtom(atomIndex, TAINT_ATOMNAME); } else if (type.equals("Pl")) { Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -5108,6 +5108,7 @@ P3 pt = (++e.iToken < slen ? centerParameter(e.iToken) : null); if (chk) return; + vwr.pushState(); switch (atomsOrBonds) { case T.atoms: e.clearDefinedVariableAtomSets(); Modified: trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java =================================================================== --- trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/symmetry/CIPChirality.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -197,7 +197,14 @@ // 4. Rule 3 requires the concept of "auxiliary" (temporary, digraph-specific) descriptors. // This concept of auxiliary descriptors is the key to not having an analysis // blow up or somehow require complex, impossible iteration. - // 5. Rule 4a needs to be addressed exhaustively prior to Rules 4b and 4c. + // 5. Rule 4a needs to be addressed exhaustively prior to Rules 4b and 4c. This involves the + // the initial generation of all auxiliary descriptors, including r/s and R/S at + // branching points. In the course of doing this, all rules, 1-5, must be employed + // at these auxiliary centers using the already-created digraph. This rule serves to + // avoid the need for Rule 4b for all except the most unusual cases, where, for example, + // there are two otherwise identical branches, but one can be identified as S and the + // other only r or no-stereo, but not R. Thus, only branches that end up as R/R, R/S, S/S, + // r/r, r/s, s/s, or nst/nst need be investigated by Rule 4b. // 6. Rule 4b Somehow missed in the discussion is that the reference descriptor is determined // once and only once for each branch from the center under scrutiny. All Rules // preceding Rule 4 can be applied to iterated subsections of a digraph. Not this one, @@ -204,7 +211,7 @@ // nor Rule 5, though. The key is to determine one single "Mata sequence" of R and S descriptors // for each pair of branches being considered. This same reference carries through all // future iterations of the algorithm for that branch. - // 7. Rule 4c Again, this rule must be invoked only after Rule 4b is completely set, and again + // 7. Rule 4c Again, this subrule must be invoked only after Rule 4b is completed, and again // it is only for the root branches, not anywhere else. // 8. Rule 5 Final setting pseudoasymmetry (r/s, m/p) can be done along the same line as Rule 4b, // but with slightly different sorting criteria. @@ -217,6 +224,7 @@ // prefilterAtoms() // checkForAlkenes() // checkForSmallRings() + // checkForHelicenes() // checkForBridgeheadNitrogens() // checkForKekuleIssues() // checkForAtropisomerism() @@ -224,6 +232,7 @@ // if (haveAlkenes) { // for(all double bonds) getBondChirality(a1, a2) // removeUnnecessaryEZDesignations() + // indicateHeliceneChirality() // } // } // @@ -307,10 +316,11 @@ static final int RULE_2 = 3; static final int RULE_3 = 4; static final int RULE_4a = 5; - static final int RULE_4bc = 6; // can be done together; no need for a separate loop - static final int RULE_5 = 7; + static final int RULE_4b = 6; + static final int RULE_4c = 7; + static final int RULE_5 = 8; - static final String[] ruleNames = {"","1a", "1b", "2", "3", "4a", "4bc", "5"}; + static final String[] ruleNames = {"","1a", "1b", "2", "3", "4a", "4b", "4c", "5"}; public String getRuleName() { return ruleNames[currentRule]; @@ -325,7 +335,7 @@ /** * maximum path to display for debugging only */ - public static final int MAX_PATH = 30; + public static final int MAX_PATH = 50; /** * maximum ring size that can have a double bond with no E/Z designation; @@ -436,32 +446,33 @@ int c = getAtomChiralityLimited(a, null, null, RULE_5); a.setCIPChirality(c == 0 ? JC.CIP_CHIRALITY_NONE : c); } + if (haveAlkenes) { - // set bond chiralities - - if (haveAlkenes) { + // set bond chiralities E/Z and M/P + Lst<int[]> lstEZ = new Lst<int[]>(); for (int i = bsToDo.nextSetBit(0); i >= 0; i = bsToDo.nextSetBit(i + 1)) getAtomBondChirality(atoms[i], lstEZ, bsToDo); if (lstSmallRings.size() > 0 && lstEZ.size() > 0) clearSmallRingEZ(atoms, lstEZ); - } - - // add helical chiralities + + // Add helicene chiralities -- predetermined using a Jmol SMARTS conformational search. + // + // M: A{a}(.t:-10,-40)a(.t:-10,-40)aaa + // P: A{a}(.t:10,40)a(.t:10,40)aaa + // + // Note that indicators are on the first and last aromatic atoms {a}. - if (bsHelixM != null) - for (int i = bsHelixM.nextSetBit(0); i >= 0; i = bsHelixM.nextSetBit(i + 1)) - atoms[i].setCIPChirality(STEREO_M); + if (bsHelixM != null) + for (int i = bsHelixM.nextSetBit(0); i >= 0; i = bsHelixM.nextSetBit(i + 1)) + atoms[i].setCIPChirality(STEREO_M); - if (bsHelixM != null) - for (int i = bsHelixM.nextSetBit(0); i >= 0; i = bsHelixM.nextSetBit(i + 1)) - atoms[i].setCIPChirality(STEREO_M); + if (bsHelixP != null) + for (int i = bsHelixP.nextSetBit(0); i >= 0; i = bsHelixP.nextSetBit(i + 1)) + atoms[i].setCIPChirality(STEREO_P); + } - if (bsHelixP != null) - for (int i = bsHelixP.nextSetBit(0); i >= 0; i = bsHelixP.nextSetBit(i + 1)) - atoms[i].setCIPChirality(STEREO_P); - if (Logger.debugging) { Logger.info("sp2-aromatic = " + bsKekuleAmbiguous); Logger.info("smallRings = " + PT.toJSON(null,lstSmallRings)); @@ -1391,13 +1402,6 @@ isTrigonalPyramidal = (bondCount == 3 && !isAlkene && (elemNo > 10 || bsAzacyclic != null && bsAzacyclic.get(atomIndex))); canBePseudo = (bondCount == 4 || isTrigonalPyramidal); - //String c = atom.getCIPChirality(false); - // What we are doing here is creating a lexigraphically sortable string - // R < S < r < s < ~ and C < T < ~ // actually, C and T are not used - // we ignore r and s here. - //if (c.equals("") || c.equals("r") || c.equals("s")) - //c = "~"; // none - //knownAtomChirality = c; if (parent != null) sphere = parent.sphere + 1; if (sphere == 1) { @@ -1577,10 +1581,6 @@ Arrays.sort(atoms); return true; - // pretty sure this next test cannot be true -// if (isTerminal) -// System.out.println("????"); -// return !isTerminal; } /** @@ -1638,7 +1638,7 @@ } // if this is Rule 4 or 5, then we do a check of the forward-based stereochemical path - boolean checkRule4List = (rule4List != null && (currentRule == RULE_4bc || currentRule == RULE_5)); + boolean checkRule4List = (rule4List != null && currentRule > RULE_4a); for (int i = 0; i < 4; i++) { CIPAtom a = atoms[i]; for (int j = i + 1; j < 4; j++) { @@ -1989,7 +1989,8 @@ return checkRule3(b); // can be IGNORE case RULE_4a: return checkRules4a(b, " sr SR PM"); - case RULE_4bc: + case RULE_4b: + case RULE_4c: case RULE_5: return TIED; // not carried out here because these need access to a full list of ligands // case RULE_4c: // taken care of by RULE_4bc @@ -2217,7 +2218,6 @@ * (IGNORE) */ 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" @@ -2224,54 +2224,60 @@ // note that this analysis cannot be done ahead of time String aStr = rule4List[ia].substring(1); String bStr = rule4List[ib].substring(1); - boolean haveRS = false; - if (atoms[ia].nextChiralBranch != null) { - String s = atoms[ia].getMataList(getFirstRef(aStr), isRule5); - haveRS = (s.indexOf("|") >= 0); - aStr = (haveRS ? s : aStr + s); - } - if (atoms[ib].nextChiralBranch != null) { - String s = atoms[ib].getMataList(getFirstRef(bStr), isRule5); - haveRS |= (s.indexOf("|") >= 0); - bStr = (s.indexOf("|") < 0 ? bStr + s : s); - } - if (Logger.debugging) - Logger.info(dots() + this + " comparing " + atoms[ia] + " " + aStr + " to " - + atoms[ib] + " " + bStr); - if (isRule5 || !haveRS && aStr.length() != bStr.length()) { - // note that these two strings can be different lengths - // if we have sXX and ~ - return sign(aStr.compareTo(bStr)); - } - if (haveRS) { - // Mata(2005) Figure 9 - // We are trying to ascertain that - // R lull R luuu - // S luuu is the same as S lull - // - // Solution is to SUM all winners. If that is 0, then they are the same - String[] aList = PT.split(aStr, "|"); - String[] bList = PT.split(bStr, "|"); - int minScore = Integer.MAX_VALUE; - int sumScore = 0; - aStr = aList[0]; - bStr = bList[0]; - for (int i = aList.length; --i >= 0;) { - for (int j = bList.length; --j >= 0;) { - int score = compareRule4PairStr(aList[i], bList[j], true); - sumScore += score; - if (score != TIED && Math.abs(score) <= minScore) { - minScore = Math.abs(score); - aStr = aList[i]; - bStr = bList[j]; + if (currentRule == RULE_4c) { + aStr = PT.rep(aStr, "~", ""); + bStr = PT.rep(bStr, "~", ""); + } else { + boolean haveRS = false; + boolean isRule5 = (currentRule == RULE_5); + if (atoms[ia].nextChiralBranch != null) { + String s = atoms[ia].getMataList(getFirstRef(aStr), isRule5); + haveRS = (s.indexOf("|") >= 0); + aStr = (haveRS ? s : aStr + s); + } + if (atoms[ib].nextChiralBranch != null) { + String s = atoms[ib].getMataList(getFirstRef(bStr), isRule5); + haveRS |= (s.indexOf("|") >= 0); + bStr = (s.indexOf("|") < 0 ? bStr + s : s); + } + if (Logger.debugging) + Logger.info(dots() + this + " comparing " + atoms[ia] + " " + aStr + + " to " + atoms[ib] + " " + bStr); + if (isRule5 || !haveRS && aStr.length() != bStr.length()) { + // note that these two strings can be different lengths + // if we have sXX and ~ + return sign(aStr.compareTo(bStr)); + } + aStr = cleanRule4Str(aStr); + bStr = cleanRule4Str(bStr); + if (haveRS) { + // Mata(2005) Figure 9 + // We are trying to ascertain that + // R lull R luuu + // S luuu is the same as S lull + // + // Solution is to SUM all winners. If that is 0, then they are the same + String[] aList = PT.split(aStr, "|"); + String[] bList = PT.split(bStr, "|"); + int minScore = Integer.MAX_VALUE; + int sumScore = 0; + aStr = aList[0]; + bStr = bList[0]; + for (int i = aList.length; --i >= 0;) { + for (int j = bList.length; --j >= 0;) { + int score = compareRule4PairStr(aList[i], bList[j], true); + sumScore += score; + if (score != TIED && Math.abs(score) <= minScore) { + minScore = Math.abs(score); + aStr = aList[i]; + bStr = bList[j]; + } } } + if (sumScore == TIED) + return TIED; } - if (sumScore == TIED) - return TIED; } - aStr = PT.rep(aStr, "~", ""); - bStr = PT.rep(bStr, "~", ""); if (aStr.length() == 1 && "RS".indexOf(aStr) < 0) { int score = checkEnantiomer(aStr, bStr, 0, aStr.length(), " rs"); switch (score) { @@ -2285,6 +2291,11 @@ return compareRule4PairStr(aStr, bStr, false); } + private String cleanRule4Str(String aStr) { + return (aStr.length() > 1 ? + PT.replaceAllCharacters(aStr, "sr~", "") : aStr); + } + /** * Just get the first R- or S-equivalent in "~~~~xxxxx" * @param aStr @@ -2412,7 +2423,7 @@ */ private int compareRule4PairStr(String aStr, String bStr, boolean isRSTest) { if (Logger.debugging) - Logger.info(dots() + this + " Rule 4b comparing " + aStr + " " + bStr); + Logger.info(dots() + this.myPath + " Rule 4b comparing " + aStr + " " + bStr); doCheckPseudo = false; int n = aStr.length(); if (n == 0 || n != bStr.length()) @@ -2655,17 +2666,18 @@ s = s.toUpperCase(); // Rule 4c or diasteriomers // AY-236.148 auxChirality = s; subRS = ""; - if (ret != null) - ret[0] = null; + //if (ret != null) + //ret[0] = null; } else { // if here, adj is TIED (0) CIPAtom atom1 = (CIPAtom) clone(); if (atom1.set()) { atom1.addReturnPath(null, this); + //System.out.println("determining " + s + " for " + atom1.myPath); atom1.sortByRule(RULE_1a); rs = atom1.checkHandedness(); s = (rs == STEREO_R ? "R" : rs == STEREO_S ? "S" : "~"); - System.out.println("determining " + s + " for " + root + "->" + atom1); + //System.out.println("determining " + s + " for " + atom1.myPath); node1.addMataRef(sphere, priority, rs); } } @@ -2738,8 +2750,13 @@ if (n != rs2.length()) return NOT_RELEVANT; // TODO: ?? this may not be true -- paths with and without O, N, C for example, that still have stereochemistry if (rs1.equals(rs2)) - return TIED; - String rs = (rs1.indexOf("R") < 0 && rs1.indexOf("S") < 0 ? "~rs" : "~RS"); + return TIED; + boolean haveRS = (rs1.indexOf("R") >= 0 || rs1.indexOf("S") >= 0); + String rs = (haveRS ? "~RS" : "~rs"); + if (haveRS) { + rs1 = PT.replaceAllCharacters(rs1, "rs", "~"); + rs2 = PT.replaceAllCharacters(rs2, "rs", "~"); + } int score = checkEnantiomer(rs1, rs2, 1, n, rs); if (score == DIASTEREOMERIC) { switch (compareMataPair(i1, i2)) { @@ -2910,6 +2927,7 @@ a.atoms = new CIPAtom[4]; a.priorities = new int[4]; a.htPathPoints = htPathPoints; + a.doCheckPseudo = false; for (int i = 0; i < 4; i++) { // a.priorities[i] = priorities[i]; if (atoms[i] != null) { @@ -2916,6 +2934,7 @@ a.atoms[i] = atoms[i]; } } + a.ties = null; if (Logger.debugging) Logger.info("cloning " + this + " as " + a); return a; Modified: trunk/Jmol/src/org/jmol/util/CommandHistory.java =================================================================== --- trunk/Jmol/src/org/jmol/util/CommandHistory.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/util/CommandHistory.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -255,4 +255,19 @@ //System.out.println("HISTORY:" + i+" "+commandList.get(i)); } + private Lst<String> lstStates; + + public void pushState(String stateInfo) { + if (lstStates == null) + lstStates = new Lst<String>(); + lstStates.addLast(stateInfo); + } + + public String popState() { + if (lstStates == null || lstStates.size() == 0) + return null; + String s = lstStates.removeItemAt(lstStates.size() - 1); + return s; + } + } Modified: trunk/Jmol/src/org/jmol/viewer/FileManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/FileManager.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/viewer/FileManager.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -210,6 +210,12 @@ && Viewer.hasDatabasePrefix(name0)) { htParams.put("dbName", name0); } + if (name.endsWith("%2D%")) { + String filter = (String) htParams.get("filter"); + htParams.put("filter", (filter == null ? "" : filter) + "2D"); + name = name.substring(0, name.length() - 4); + } + int pt = name.indexOf("::"); String nameAsGiven = (pt >= 0 ? name.substring(pt + 2) : name); String fileType = (pt >= 0 ? name.substring(0, pt) : null); Modified: trunk/Jmol/src/org/jmol/viewer/JC.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/JC.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/viewer/JC.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -129,6 +129,7 @@ // note list of RCSB access points: http://www.rcsb.org/pdb/static.do?p=download/http/index.html public static String[] databases = { + "chebi", "http://www.ebi.ac.uk/chebi/saveStructure.do?defaultImage=true&chebiId=%file%2D%", "aflowbin", "http://aflowlib.mems.duke.edu/users/jmolers/binary_new/%FILE.aflow_binary", "aflow", "http://aflowlib.mems.duke.edu/users/jmolers/binary_new/%FILE.aflow_binary", // _#DOCACHE_ flag indicates that the loaded file should be saved in any state in full Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2017-05-19 17:09:25 UTC (rev 21609) @@ -54,9 +54,12 @@ # command, and then write a PDB file, all the occupancies are listed as 1.00 # instead of the occupancies I tried to assign in jmol. +# TODO: fix UNDO -Jmol.___JmolVersion="14.15.5" +Jmol.___JmolVersion="14.16.1" // 2017.05.19 +new feature: load =chebi/nnnnnn chEBI 2D molecule load, with minimal 100-step minimization + bug fix: CML reader does not read 2D wedge/hash information bug fix: CIP fix for missing branch descriptors; 984 lines @@ -69,7 +72,7 @@ code: CIP status: implementation complete, including: All subrules implemented fully: 1a, 1b, 2, 3, 4a, 4b, 4c, 5 R/S, E/Z, M/P (odd-cumulene and helicene), r/s, seqCis/seqTrans (as Z/E) - benzenoid (including fused benzenoid heteroaromatic) Mancude ring "Kekule weighted" atom number adjustments + fused benzenoid aromatic Mancude ring "Kekule weighted" atom number adjustments * Added logic to Rule 1b: The root distance for a Kekule-ambiguous duplicate * atom is its own sphere, not the sphere of its duplicated atom. @@ -93,7 +96,7 @@ IUPAC Blue Book 2013 errors of note: -,"147":"r,,,R,,,,r,,,S" // chiral phosphine -- disagrees with BB P-93.5.1.1.2 for S vs R +,"147":"r,,,R,,,,r,,,S" // chiral phosphine ignored in BB P-93.5.1.1.2 for S vs R { "id" : "148" "name_pname_pin" : "bis[(1r,4r)-4-methylcyclohexyl]phosphane" Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Viewer.java 2017-05-18 04:50:52 UTC (rev 21608) +++ trunk/Jmol/src/org/jmol/viewer/Viewer.java 2017-05-19 17:09:25 UTC (rev 21609) @@ -7944,6 +7944,20 @@ commandHistory.addCommand(PT.replaceAllCharacters(command, "\r\n\t", " ")); } + public void pushState() { + if (autoExit || !haveDisplay || !getPreserveState()) + return; + commandHistory.pushState(getStateInfo()); + } + + public void popState() { + if (autoExit || !haveDisplay || !getPreserveState()) + return; + String state = commandHistory.popState(); + if (state != null) + evalStringQuiet(state); + } + /** * Removes one command from the command history * 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