Revision: 20759 http://sourceforge.net/p/jmol/code/20759 Author: hansonr Date: 2015-09-06 20:54:56 +0000 (Sun, 06 Sep 2015) Log Message: ----------- Jmol.___JmolVersion="14.3.16_2015.09.06"
bug fix: after atom deletion, atom iterator still finds atoms. -- was not reinitializing the binary search after atom deletion -- affects polyhedra, within() $ load $caffeine $ delete _N 4 atoms deleted $ print {*}.count 20 $ print within(14.0, {c6}).count 24 Modified Paths: -------------- trunk/Jmol/src/org/jmol/modelset/ModelSet.java trunk/Jmol/src/org/jmol/scriptext/MathExt.java trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java trunk/Jmol/src/org/jmol/smiles/SmilesParser.java trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties Added Paths: ----------- trunk/Jmol/src/org/jmol/smiles/PolyhedronStereoSorter.java Modified: trunk/Jmol/src/org/jmol/modelset/ModelSet.java =================================================================== --- trunk/Jmol/src/org/jmol/modelset/ModelSet.java 2015-09-06 04:11:42 UTC (rev 20758) +++ trunk/Jmol/src/org/jmol/modelset/ModelSet.java 2015-09-06 20:54:56 UTC (rev 20759) @@ -3047,6 +3047,7 @@ am[i].dssrCache = null; } deleteBonds(bsBonds, false); + validateBspf(false); } // atom addition // Modified: trunk/Jmol/src/org/jmol/scriptext/MathExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2015-09-06 04:11:42 UTC (rev 20758) +++ trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2015-09-06 20:54:56 UTC (rev 20759) @@ -193,7 +193,7 @@ case T.search: case T.smiles: case T.substructure: - return evaluateSubstructure(mp, args, tok); + return evaluateSubstructure(mp, args, tok, op.tok == T.propselector); case T.sort: case T.count: return evaluateSort(mp, args, tok); @@ -2624,19 +2624,21 @@ } private boolean evaluateSubstructure(ScriptMathProcessor mp, SV[] args, - int tok) throws ScriptException { + int tok, boolean isSelector) + throws ScriptException { // select substucture(....) legacy - was same as smiles(), now search() // select smiles(...) // select search(...) now same as substructure - if (args.length == 0) + // print {*}.search(...) + if (args.length == 0 || isSelector && args.length != 1) return false; BS bs = new BS(); String pattern = SV.sValue(args[0]); if (pattern.length() > 0) try { - BS bsSelected = (args.length == 2 && args[1].tok == T.bitset ? SV - .bsSelectVar(args[1]) : null); - // BS bsSelected, boolean isSmarts, boolean firstMatchOnly + BS bsSelected = (isSelector ? SV.bsSelectVar(mp.getX()) + : args.length == 2 && args[1].tok == T.bitset ? SV + .bsSelectVar(args[1]) : null); bs = vwr.getSmilesMatcher().getSubstructureSet(pattern, vwr.ms.at, vwr.ms.ac, bsSelected, (tok == T.smiles ? JC.SMILES_TYPE_SMILES : JC.SMILES_TYPE_SMARTS)); Modified: trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java =================================================================== --- trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java 2015-09-06 04:11:42 UTC (rev 20758) +++ trunk/Jmol/src/org/jmol/shapespecial/Polyhedra.java 2015-09-06 20:54:56 UTC (rev 20759) @@ -86,7 +86,7 @@ private int nVertices; float faceCenterOffset; - float distanceFactor = Float.NaN; +// float distanceFactor = Float.NaN; boolean isCollapsed; private boolean iHaveCenterBitSet; @@ -109,7 +109,8 @@ if ("init" == propertyName) { faceCenterOffset = DEFAULT_FACECENTEROFFSET; - distanceFactor = planarParam = Float.NaN; + //distanceFactor = + planarParam = Float.NaN; radius = 0.0f; nVertices = 0; nPoints = 0; @@ -190,7 +191,8 @@ if ("distanceFactor" == propertyName) { // not a general user option - distanceFactor = ((Float) value).floatValue(); + // ignore + //distanceFactor = ((Float) value).floatValue(); return; } @@ -588,9 +590,9 @@ int nj = vertexCount - 1; float planarParam = (Float.isNaN(this.planarParam) ? DEFAULT_PLANAR_PARAM : this.planarParam); - float factor = (!Float.isNaN(distanceFactor) ? distanceFactor - : DEFAULT_DISTANCE_FACTOR); - BS bs = BS.newN(vertexCount); +// float factor = (!Float.isNaN(distanceFactor) ? distanceFactor +// : DEFAULT_DISTANCE_FACTOR); +// BS bs = BS.newN(vertexCount); // here we are assuring that at least ONE face is drawn to // all matching vertices -- skip this for BOND polyhedra @@ -600,43 +602,43 @@ for (int i = 0; i < vertexCount; i++) ptAve.add(points[i]); ptAve.scale(1f / vertexCount); - float distMax = 0; - if (checkDist) { - float dAverage = 0; - for (int i = 0; i < vertexCount; i++) - dAverage += points[vertexCount].distance(points[i]); - dAverage /= vertexCount; - boolean isOK = (dAverage == 0); - while (!isOK && factor < 10.0f) { - distMax = dAverage * factor; - bs.setBits(0, vertexCount); - for (int i = 0; i < ni; i++) - for (int j = i + 1; j < nj; j++) { - if (points[i].distance(points[j]) > distMax) - continue; - for (int k = j + 1; k < vertexCount; k++) { - if (points[i].distance(points[k]) > distMax - || points[j].distance(points[k]) > distMax) - continue; - bs.clear(i); - bs.clear(j); - bs.clear(k); - } - } - isOK = true; - for (int i = 0; i < vertexCount; i++) - if (bs.get(i)) { - isOK = false; - factor *= 1.05f; - if (Logger.debugging) { - Logger.debug("Polyhedra distanceFactor for " + vertexCount - + " atoms increased to " + factor + " in order to include " - + points[i]); - } - break; - } - } - } +// float distMax = 0; +// if (checkDist) { +// float dAverage = 0; +// for (int i = 0; i < vertexCount; i++) +// dAverage += points[vertexCount].distance(points[i]); +// dAverage /= vertexCount; +// boolean isOK = (dAverage == 0); +// while (!isOK && factor < 10.0f) { +// distMax = dAverage * factor; +// bs.setBits(0, vertexCount); +// for (int i = 0; i < ni; i++) +// for (int j = i + 1; j < nj; j++) { +// if (points[i].distance(points[j]) > distMax) +// continue; +// for (int k = j + 1; k < vertexCount; k++) { +// if (points[i].distance(points[k]) > distMax +// || points[j].distance(points[k]) > distMax) +// continue; +// bs.clear(i); +// bs.clear(j); +// bs.clear(k); +// } +// } +// isOK = true; +// for (int i = 0; i < vertexCount; i++) +// if (bs.get(i)) { +// isOK = false; +// factor *= 1.05f; +// if (Logger.debugging) { +// Logger.debug("Polyhedra distanceFactor for " + vertexCount +// + " atoms increased to " + factor + " in order to include " +// + points[i]); +// } +// break; +// } +// } +// } /* Start by defining a face to be when all three distances * are < distanceFactor * (longest central) but if a vertex is missed, * then expand the range. The collapsed trick is to introduce @@ -676,15 +678,15 @@ V3 vTemp = vAC; for (int i = 0, pt = 0; i < ni; i++) for (int j = i + 1; j < nj; j++) { - if (checkDist && points[i].distance(points[j]) > distMax) { - pt += vertexCount - j - 1; - continue; - } +// if (checkDist && points[i].distance(points[j]) > distMax) { +// pt += vertexCount - j - 1; +// continue; +// } for (int k = j + 1; k < vertexCount; k++, pt++) { - if (checkDist - && (points[i].distance(points[k]) > distMax || points[j] - .distance(points[k]) > distMax)) - continue; +// if (checkDist +// && (points[i].distance(points[k]) > distMax || points[j] +// .distance(points[k]) > distMax)) +// continue; if (planeCount >= fmax) { Logger.error("Polyhedron error: maximum face(" + fmax + ") -- reduce RADIUS"); Added: trunk/Jmol/src/org/jmol/smiles/PolyhedronStereoSorter.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/PolyhedronStereoSorter.java (rev 0) +++ trunk/Jmol/src/org/jmol/smiles/PolyhedronStereoSorter.java 2015-09-06 20:54:56 UTC (rev 20759) @@ -0,0 +1,59 @@ +package org.jmol.smiles; + +import java.util.Comparator; + +import javajs.util.P3; +import javajs.util.T3; +import javajs.util.V3; + +class PolyhedronStereoSorter implements Comparator<Object[]> { + + private V3 vTemp = new V3(); + private V3 vRef; + + PolyhedronStereoSorter() { + } + + void setRef(V3 vRef) { + this.vRef = vRef; + } + + /** + * Comparison is by torsion angle, as set previously and passed in as Float a[1] and b[1]. + * If these two are within 1 degree of each other, then we compare the dot product of + * the reference vector and the vector from a to b, from points stored as a[2] and b[2]. + */ + @Override + public int compare(Object[] a, Object[] b) { + float torA = ((Float) a[1]).floatValue(); + float torB = ((Float) b[1]).floatValue(); + if (Math.abs(torA - torB) < 1f) { + torA = 0; + vTemp.sub2((P3) b[2], (P3) a[2]); + torB = vRef.dot(vTemp); + } + return (torA < torB ? 1 : torA > torB ? -1 : 0); + } + + private V3 align1 = new V3(); + private V3 align2 = new V3(); + + private static final float MIN_ALIGNED = (float) (10f/180*Math.PI); + + /** + * check alignment, within 10 degrees is considered aligned. + * + * @param pt1 + * @param pt2 + * @param pt3 + * @return true if within 10 degrees + */ + boolean isAligned(T3 pt1, T3 pt2, T3 pt3) { + align1.sub2(pt1, pt2); + align2.sub2(pt2, pt3); + float angle = align1.angle(align2); + return (angle < MIN_ALIGNED); + } + + +} \ No newline at end of file Property changes on: trunk/Jmol/src/org/jmol/smiles/PolyhedronStereoSorter.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Modified: trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java 2015-09-06 04:11:42 UTC (rev 20758) +++ trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java 2015-09-06 20:54:56 UTC (rev 20759) @@ -24,25 +24,22 @@ package org.jmol.smiles; -import java.util.Comparator; +import java.util.Hashtable; import java.util.Iterator; -import java.util.Hashtable; import java.util.Map; import javajs.util.Lst; +import javajs.util.P3; import javajs.util.SB; -import javajs.util.P3; import org.jmol.java.BS; - - +import org.jmol.util.BNode; import org.jmol.util.BSUtil; +import org.jmol.util.Edge; import org.jmol.util.Elements; -import org.jmol.util.Edge; import org.jmol.util.JmolMolecule; -import org.jmol.util.BNode; +import org.jmol.util.Logger; import org.jmol.util.Node; -import org.jmol.util.Logger; import org.jmol.viewer.JC; /** @@ -90,6 +87,7 @@ private boolean noBioComment; private boolean noStereo; public P3 stereoReference; + private SmilesStereo smilesStereo; // generation of SMILES strings @@ -510,7 +508,13 @@ Edge[] bonds = atom.getEdges(); if (stereoReference != null) { allowBranches = false; - SmilesStereo.sortBondsByStereo(atom, prevAtom, stereoReference, bonds, aTemp); + if (smilesStereo == null) + try { + smilesStereo = SmilesStereo.newStereo(null); + } catch (InvalidSmilesException e) { + // not possible + } + smilesStereo.sortBondsByStereo(atom, prevAtom, stereoReference, bonds, vTemp.vA); } Node aH = null; int stereoFlag = (isAromatic ? 10 : 0); @@ -663,7 +667,7 @@ String atat = null; if (!allowBranches && !noStereo && stereoReference == null && (v.size() == 5 || v.size() == 6)) - atat = sortInorganic(atom, v); + atat = sortInorganic(atom, v, vTemp); for (int i = 0; i < v.size(); i++) { Edge bond = v.get(i); if (bond == bond0) @@ -744,8 +748,6 @@ return atomNext; } - private Object[] aTemp; - /** * We must sort the bond vector such that a diaxial pair is * first and last. Then we assign stereochemistry based on what @@ -755,9 +757,10 @@ * * @param atom * @param v + * @param vTemp * @return "@" or "@@" or "" */ - private String sortInorganic(Node atom, Lst<Edge> v) { + private String sortInorganic(Node atom, Lst<Edge> v, VTemp vTemp) { int atomIndex = atom.getIndex(); int n = v.size(); Lst<Edge[]> axialPairs = new Lst<Edge[]>(); @@ -929,18 +932,6 @@ return Math.min(i0, i1) + "_" + Math.max(i0, i1); } - class PolyhedronStereoSorter implements Comparator<Object> { - - protected PolyhedronStereoSorter() { } - - @Override - public int compare(Object a, Object b) { - float torA = ((Float) ((Object[]) a)[1]).floatValue(); - float torB = ((Float) ((Object[]) b)[1]).floatValue(); - return (torA < torB ? 1 : torA > torB ? -1 : 0); - } - } - //static { // T3 atom = P3.new3(0, 0.0001f, -1); // T3 atomPrev = P3.new3(0, 0 , 1); Modified: trunk/Jmol/src/org/jmol/smiles/SmilesParser.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2015-09-06 04:11:42 UTC (rev 20758) +++ trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2015-09-06 20:54:56 UTC (rev 20759) @@ -898,7 +898,7 @@ break; case '@': if (molecule.stereo == null) - molecule.stereo = new SmilesStereo(0, 0, 0, null, null); + molecule.stereo = SmilesStereo.newStereo(null); index = SmilesStereo.checkChirality(pattern, index, molecule.patternAtoms[newAtom.index]); break; default: Modified: trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java 2015-09-06 04:11:42 UTC (rev 20758) +++ trunk/Jmol/src/org/jmol/smiles/SmilesStereo.java 2015-09-06 20:54:56 UTC (rev 20759) @@ -33,7 +33,6 @@ import javajs.util.T3; import javajs.util.V3; -import org.jmol.smiles.SmilesGenerator.PolyhedronStereoSorter; import org.jmol.util.Edge; import org.jmol.util.Escape; import org.jmol.util.Logger; @@ -42,7 +41,7 @@ //import org.jmol.util.Logger; /** - * This class relates to stereochemical issues. + * This class relates to stereochemical issues. */ public class SmilesStereo { @@ -66,13 +65,15 @@ return ("0;PH;AL;33;TH;TP;OH;77;SP;".indexOf(xx) + 1) / 3; } - public static SmilesStereo newStereo(SmilesStereo stereo) throws InvalidSmilesException { - SmilesStereo s = new SmilesStereo(stereo.chiralClass, stereo.chiralOrder, - stereo.atomCount, stereo.details, stereo.directives); - return s; + public static SmilesStereo newStereo(SmilesStereo stereo) + throws InvalidSmilesException { + return (stereo == null ? new SmilesStereo(0, 0, 0, null, null) + : new SmilesStereo(stereo.chiralClass, stereo.chiralOrder, + stereo.atomCount, stereo.details, stereo.directives)); } - SmilesStereo(int chiralClass, int chiralOrder, int atomCount, String details, String directives) throws InvalidSmilesException { + SmilesStereo(int chiralClass, int chiralOrder, int atomCount, String details, + String directives) throws InvalidSmilesException { this.chiralClass = chiralClass; this.chiralOrder = chiralOrder; this.atomCount = atomCount; @@ -84,8 +85,8 @@ private int[][] polyhedralOrders; private boolean isNot; - static PolyhedronStereoSorter polyhedronStereoSorter; - + private PolyhedronStereoSorter sorter; + private void getPolyhedralOrders() throws InvalidSmilesException { int[][] po = polyhedralOrders = AU.newInt2(atomCount); if (details == null) @@ -127,8 +128,8 @@ default: index = SmilesParser.getRingNumber(s, index, ch, ret); pt = temp[n++] = ret[0] - 1; - if (pt == atomPt) - msg = "Atom cannot connect to itself"; + 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) @@ -234,9 +235,8 @@ return false; int chiralClass = atom.stereo.chiralClass; int chiralOrder = atom.stereo.chiralOrder; - Node a2 = (chiralClass == STEREOCHEMISTRY_ALLENE - || chiralClass == 3 ? a2 = jmolAtoms[sAtom2.getMatchingAtomIndex()] - : null); + Node a2 = (chiralClass == STEREOCHEMISTRY_ALLENE || chiralClass == 3 ? a2 = jmolAtoms[sAtom2 + .getMatchingAtomIndex()] : null); // set the chirality center at the origin atom.set(0, 0, 0); @@ -349,11 +349,11 @@ v.sub((P3) jn[i]); } if (v.length() == 0) { - v.setT(((P3)jn[4])); + v.setT(((P3) jn[4])); doSwitch = false; } else { - v.scaleAdd2(n + 1,(P3) getJmolAtom(sAtom.getMatchingAtomIndex()), v); - doSwitch = search.isSmilesFind || doSwitch ; + v.scaleAdd2(n + 1, (P3) getJmolAtom(sAtom.getMatchingAtomIndex()), v); + doSwitch = search.isSmilesFind || doSwitch; } jn[pt] = new SmilesAtom().setIndex(-1); ((P3) jn[pt]).setT(v); @@ -377,50 +377,52 @@ jn[pt - 1] = a; } } - private Node getJmolAtom(int i) { return (i < 0 || i >= jmolAtoms.length ? null : jmolAtoms[i]); } /** - * Sort bond array as ccw rotation around the axis connecting the - * atom and the reference point (polyhedron center) as seen from - * outside the polyhedron looking in. + * Sort bond array as ccw rotation around the axis connecting the atom and the + * reference point (polyhedron center) as seen from outside the polyhedron + * looking in. * * Since we are allowing no branching, all atoms will appear as separate * components with only numbers after them. These numbers will be processed - * and listed in this order. + * and listed in this order. * * @param atom * @param atomPrev * @param ref * @param bonds - * @param aTemp + * @param vTemp */ - static void sortBondsByStereo(Node atom, Node atomPrev, T3 ref, Edge[] bonds, Object[] aTemp) { + void sortBondsByStereo(Node atom, Node atomPrev, T3 ref, Edge[] bonds, + V3 vTemp) { if (bonds.length < 2 || !(atom instanceof T3)) return; if (atomPrev == null) atomPrev = bonds[0].getOtherAtomNode(atom); - if (aTemp == null || aTemp.length != bonds.length) - aTemp = new Object[bonds.length]; + Object[][] aTemp = new Object[bonds.length][0]; + if (sorter == null) + sorter = new PolyhedronStereoSorter(); + vTemp.sub2((T3)atomPrev, ref); + sorter.setRef(vTemp); for (int i = bonds.length; --i >= 0;) { Node a = bonds[i].getOtherAtomNode(atom); - float f = (a == atomPrev ? 0 : Measure.computeTorsion((T3) atom, (T3)atomPrev, ref, (T3) a, true)); - if (Float.isNaN(f)) - f = 180; // directly across the center from the previous atom + float f = (a == atomPrev ? 0 : + sorter.isAligned((T3) a, ref, (T3) atomPrev) ? -999 : + Measure.computeTorsion((T3) atom, + (T3) atomPrev, ref, (T3) a, true)); if (bonds.length > 2) f += 360; - aTemp[i] = new Object[] {bonds[i], Float.valueOf(f) }; + aTemp[i] = new Object[] { bonds[i], Float.valueOf(f), a }; } - if (polyhedronStereoSorter == null) - polyhedronStereoSorter = new SmilesGenerator().new PolyhedronStereoSorter(); - Arrays.sort(aTemp, polyhedronStereoSorter); + Arrays.sort(aTemp, sorter); if (Logger.debugging) - Logger.info(Escape.e(aTemp)) ; + Logger.info(Escape.e(aTemp)); for (int i = bonds.length; --i >= 0;) - bonds[i] = (Edge) ((Object[]) aTemp[i])[0]; + bonds[i] = (Edge) aTemp[i][0]; } public boolean checkStereoChemistry(SmilesSearch smilesSearch, VTemp v) { @@ -430,7 +432,7 @@ boolean invertStereochemistry = smilesSearch.invertStereochemistry; if (Logger.debugging) - Logger.debug("checking stereochemistry..."); + Logger.debug("checking sstereochemistry..."); //for debugging, first try SET DEBUG //for (int i = 0; i < ac; i++) { @@ -484,9 +486,9 @@ // can't process this unless it is tetrahedral or perhaps square planar if (sAtom.getBondCount() != 3) return false; - v.vA.set(0, 0, 0); + v.vA.set(0, 0, 0); for (int j = 0; j < 3; j++) - v.vA.add((T3)bonds[j].getOtherAtom(sAtom0).getMatchingAtom()); + 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); @@ -498,8 +500,9 @@ if (orders == null || orders.length < 2) continue; // the atom we are looking down - pt = (j > jHpt ? j - nH: j); - T3 ta1 = (j == jHpt ? v.vA : (T3) bonds[pt].getOtherAtom(sAtom).getMatchingAtom()); + 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); T3 ta2 = null; for (int k = 0; k < orders.length; k++) { @@ -633,8 +636,8 @@ && !setSmilesCoordinates(sAtom0, sAtom, sAtom2, new Node[] { atom1, atom2, atom3, atom4, atom5, atom6 })) return false; - if (!checkStereochemistryAll(isNot, atom0, - chiralClass, order, atom1, atom2, atom3, atom4, atom5, atom6, v)) + if (!checkStereochemistryAll(isNot, atom0, chiralClass, order, atom1, + atom2, atom3, atom4, atom5, atom6, v)) return false; continue; @@ -652,7 +655,7 @@ * @param atoms * @param nAtoms * @param v - * @return String + * @return String */ static String getStereoFlag(Node atom0, Node[] atoms, int nAtoms, VTemp v) { Node atom1 = atoms[0]; @@ -668,23 +671,29 @@ case 5: case 6: // like tetrahedral - return (checkStereochemistryAll(false, atom0, chiralClass, 1, atom1, atom2, atom3, atom4, atom5, atom6, v)? "@" : "@@"); + return (checkStereochemistryAll(false, atom0, chiralClass, 1, atom1, + atom2, atom3, atom4, atom5, atom6, v) ? "@" : "@@"); case 2: // allene case 4: // tetrahedral, square planar if (atom3 == null || atom4 == null) return ""; - float d = SmilesAromatic.getNormalThroughPoints(atom1, atom2, atom3, v.vTemp, v.vA, v.vB); + float d = SmilesAromatic.getNormalThroughPoints(atom1, atom2, atom3, + v.vTemp, v.vA, v.vB); if (Math.abs(distanceToPlane(v.vTemp, d, (P3) atom4)) < 0.2f) { chiralClass = STEREOCHEMISTRY_SQUARE_PLANAR; - if (checkStereochemistryAll(false, atom0, chiralClass, 1, atom1, atom2, atom3, atom4, atom5, atom6, v)) + if (checkStereochemistryAll(false, atom0, chiralClass, 1, atom1, atom2, + atom3, atom4, atom5, atom6, v)) return "@SP1"; - if (checkStereochemistryAll(false, atom0, chiralClass, 2, atom1, atom2, atom3, atom4, atom5, atom6, v)) + if (checkStereochemistryAll(false, atom0, chiralClass, 2, atom1, atom2, + atom3, atom4, atom5, atom6, v)) return "@SP2"; - if (checkStereochemistryAll(false, atom0, chiralClass, 3, atom1, atom2, atom3, atom4, atom5, atom6, v)) - return "@SP3"; + if (checkStereochemistryAll(false, atom0, chiralClass, 3, atom1, atom2, + atom3, atom4, atom5, atom6, v)) + return "@SP3"; } else { - return (checkStereochemistryAll(false, atom0, chiralClass, 1, atom1, atom2, atom3, atom4, atom5, atom6, v)? "@" : "@@"); - } + return (checkStereochemistryAll(false, atom0, chiralClass, 1, atom1, + atom2, atom3, atom4, atom5, atom6, v) ? "@" : "@@"); + } } return ""; } @@ -817,8 +826,8 @@ case 'O': //OH case 'S': //SP case 'T': //TH, TP - stereoClass = (index + 1 < len ? getChiralityClass(pattern - .substring(index, index + 2)) : -1); + stereoClass = (index + 1 < len ? getChiralityClass(pattern.substring( + index, index + 2)) : -1); index += 2; break; default: @@ -838,8 +847,7 @@ details = SmilesParser.getSubPattern(pattern, pt, '('); pt += details.length() + 2; } - } - else { + } else { order = n; } } catch (NumberFormatException e) { @@ -851,7 +859,8 @@ if (order < 1 || stereoClass < 0) throw new InvalidSmilesException("Invalid stereochemistry descriptor"); } - newAtom.stereo = new SmilesStereo(stereoClass, order, atomCount, details, directives); + newAtom.stereo = new SmilesStereo(stereoClass, order, atomCount, details, + directives); if (SmilesParser.getChar(pattern, index) == '?') { Logger.info("Ignoring '?' in stereochemistry"); index++; @@ -859,5 +868,4 @@ return index; } - } Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-09-06 04:11:42 UTC (rev 20758) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-09-06 20:54:56 UTC (rev 20759) @@ -59,8 +59,21 @@ TODO: image off stops JSmol TODO: Rolf's errors in Safari due to move + zoomto -Jmol.___JmolVersion="14.3.16_2015.09.05" +Jmol.___JmolVersion="14.3.16_2015.09.06" +bug fix: after atom deletion, atom iterator still finds atoms. + -- was not reinitializing the binary search after atom deletion + -- affects polyhedra, within() + $ load $caffeine + $ delete _N + 4 atoms deleted + $ print {*}.count + 20 + $ print within(14.0, {c6}).count + 24 + +JmolVersion="14.3.16_2015.09.05" + new feature: POLYHEDRA -- same as POLYHEDRA BONDS {selected} new feature: POLYHEDRA 4 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