Revision: 20734 http://sourceforge.net/p/jmol/code/20734 Author: hansonr Date: 2015-08-25 05:56:29 +0000 (Tue, 25 Aug 2015) Log Message: ----------- Jmol.___JmolVersion="14.3.16_2015.08.24"
new feature: JmolSMILES $(.x:1,2,3,4,5,6,7,8) -- x is oen of d,a,t -- up to four ranges per measurement new feature: print {2.1}.find("SMILES",{1.1}) bug fix: compare() function returning matrix with translation about center, not origin bug fix: print compare({1.1},{2.1}, "SMILES", "stddev") broken bug fix: select search("[$(select atomno < 5)]") broken bug fix: select search("[$(select atomno < 5) or @5]") broken new feature: _hoverLabel -- reports general hover label set by hover command new feature: _hoverEnabled -- reports if hover is enabled or not bug fix: calculate partialCharge does not store result if all values are 0 (Otis Rothenberger) bug fix: still problems with aTest = "testing"; x = [aTest:aTest] or a = [property_MYINFO:aTest] (Rolf Huehne) bug fix: cross(a,b) broken bug fix: write PDB broken; works without "PDB" keyword broken in 14.3.15_2015.06.18 new feature: /invertStereo/ flag for SMARTS search -- allows quick check for enantiomers -- example: select search("/invertStereo/C[C@H](Br)CC") will match (R)-2-bromobutane even though it is for (S)-2-bromobutane FEATURE CHANGE: Definitions of dna, rna, purine, and pyrimidine were ambiguous and not particularly viable for group fragments. This is much clearer now: Fragments and P-only and N-only monomers are identified by name only: // These masks are only used for P-only and N-only polymers // or cases where there are so few atoms that a monomer's type // cannot be determined by checking actual atoms and connections. // They are used for NucleicMonomer or AminoMonomer classes only as // a last resort. // // I A G // purine: 100101 = 0x25 // UT C // pyrimidine: 011010 = 0x1A // // +IUTACGDIUTACG IUTACG // rna: 110000 000000 110111 = 0x30037 // +IUTACGDIUTACG IUTACG // dna: 001111 111111 001000 = 0x0FFC8 bug fix: SMILES recognizes atom name [*.CA] but not residue name [ALA.*] bug fix: Jmol BioSMILES broken bug fix: set cartoonLadders with phosphorus-only polymers crashes Jmol bug fix: protein and nucleic are not set properly for non-monomer groups (Eric Martz) -- broken in Jmol 14.3.11 (12/13/2014) -- general definition of protein is from having CA, C, and N. But there are situations where we know it is protein from its group name (ALA,LEU..) despite the fact that it is just one atom. Same for nucleic. -- note that non-canonical (HETERO) amino acids or nucleic bases that do not have the requisite atoms to identify them as such will still not test positive for "protein" or "nucleic". Modified Paths: -------------- trunk/Jmol/src/org/jmol/render/FrankRenderer.java trunk/Jmol/src/org/jmol/script/ScriptEval.java trunk/Jmol/src/org/jmol/script/ScriptExpr.java trunk/Jmol/src/org/jmol/scriptext/CmdExt.java trunk/Jmol/src/org/jmol/scriptext/MathExt.java trunk/Jmol/src/org/jmol/scriptext/SmilesExt.java trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java trunk/Jmol/src/org/jmol/smiles/SmilesMeasure.java trunk/Jmol/src/org/jmol/smiles/SmilesParser.java trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/Viewer.java Modified: trunk/Jmol/src/org/jmol/render/FrankRenderer.java =================================================================== --- trunk/Jmol/src/org/jmol/render/FrankRenderer.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/render/FrankRenderer.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -43,8 +43,7 @@ : C.GRAY); if (isExport || !vwr.getShowFrank() - || !g3d.setC(C.getColixTranslucent3(colix, - g3d.haveTranslucentObjects(), 0.5f))) + || !g3d.setC(colix)) return false; if (vwr.frankOn && !vwr.noFrankEcho) return vwr.noFrankEcho; Modified: trunk/Jmol/src/org/jmol/script/ScriptEval.java =================================================================== --- trunk/Jmol/src/org/jmol/script/ScriptEval.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/script/ScriptEval.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -821,7 +821,7 @@ if (compileScript(null, "e_x_p_r_e_s_s_i_o_n = " + expr, false)) { if (compileOnly) return aatoken[0]; - setStatement(aatoken[0]); + setStatement(aatoken[0], 1); return (asVariable ? parameterExpressionList(2, -1, false).get(0) : parameterExpressionString(2, 0)); } @@ -875,6 +875,7 @@ scr = PT.rep(scr, "()", "(none)"); if (compileScript(null, scr, false)) { st = aatoken[0]; + setStatement(st, 0); bs = atomExpression(st, 1, 0, false, false, true, true); } popContext(false, false); @@ -2183,7 +2184,7 @@ if (!"".equals(script)) runScript(script); } - if (!setStatement(aatoken[pc])) { + if (!setStatement(aatoken[pc], 1)) { Logger.info(getCommand(pc, true, false) + " -- STATEMENT CONTAINING @{} SKIPPED"); continue; @@ -4041,7 +4042,7 @@ private void cmdHover() throws ScriptException { if (chk) return; - String strLabel = paramAsStr(1); + String strLabel = (slen == 1 ? "on" : paramAsStr(1)); if (strLabel.equalsIgnoreCase("on")) strLabel = "%U"; else if (strLabel.equalsIgnoreCase("off")) @@ -7555,6 +7556,7 @@ BS bs = null; if (!chk) vwr.slm.setSelectionSubset(null); + // hover none --> subset exprbeg "off" exprend if (slen != 1 && (slen != 4 || !getToken(2).value.equals("off"))) bs = atomExpressionAt(1); if (!chk) Modified: trunk/Jmol/src/org/jmol/script/ScriptExpr.java =================================================================== --- trunk/Jmol/src/org/jmol/script/ScriptExpr.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/script/ScriptExpr.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -2347,7 +2347,7 @@ * @throws ScriptException */ @SuppressWarnings("unchecked") - protected boolean setStatement(T[] st0) throws ScriptException { + protected boolean setStatement(T[] st0, int pt0) throws ScriptException { st = st0; slen = st.length; if (slen == 0) @@ -2355,7 +2355,7 @@ T[] fixed; int i; int tok; - for (i = 1; i < slen; i++) { + for (i = pt0; i < slen; i++) { if (st[i] == null) { slen = i; return true; @@ -2375,8 +2375,8 @@ fixed = new T[slen]; fixed[0] = st[0]; boolean isExpression = false; - int j = 1; - for (i = 1; i < slen; i++) { + int j = pt0; + for (i = pt0; i < slen; i++) { if (st[i] == null) continue; switch (tok = getToken(i).tok) { @@ -2400,7 +2400,7 @@ String s; String var = paramAsStr(i); boolean isClauseDefine = (tokAt(i) == T.expressionBegin); - boolean isSetAt = (j == 1 && st[0] == T.tokenSetCmd); + boolean isSetAt = (pt0 == 1 && j == 1 && st[0] == T.tokenSetCmd); if (isClauseDefine) { SV vt = parameterExpressionToken(++i); v = (vt.tok == T.varray ? vt : SV.oValue(vt)); Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -1190,6 +1190,7 @@ float stddev = eval.getSmilesExt().getSmilesCorrelation(bsFrom, bsTo, strSmiles, null, null, m4, null, false, null, center, false, isSmiles ? JC.SMILES_TYPE_SMILES : JC.SMILES_TYPE_SMARTS); + System.out.println("compare:\n" + m4); if (Float.isNaN(stddev)) { showString("structures do not match"); return; Modified: trunk/Jmol/src/org/jmol/scriptext/MathExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -378,6 +378,7 @@ boolean isStdDev = sOpt.equalsIgnoreCase("stddev"); boolean isIsomer = sOpt.equalsIgnoreCase("ISOMER"); boolean isBonds = sOpt.equalsIgnoreCase("BONDS"); + boolean isSmiles = (!isIsomer && args.length > (isStdDev ? 3 : 2)); BS bs1 = (args[0].tok == T.bitset ? (BS) args[0].value : null); BS bs2 = (args[1].tok == T.bitset ? (BS) args[1].value : null); @@ -386,29 +387,35 @@ M4 m = new M4(); stddev = Float.NaN; Lst<P3> ptsA, ptsB; - if (isSmiles) { - if (bs1 == null || bs2 == null) - return false; - } - if (isBonds) { - if (args.length != 4) - return false; - smiles1 = SV.sValue(args[2]); - isSmiles = smiles1.equalsIgnoreCase("SMILES"); - try { - if (isSmiles) - smiles1 = vwr.getSmiles(bs1); - } catch (Exception ex) { - e.evalError(ex.getMessage(), null); + try { + if (isSmiles) { + if (bs1 == null || bs2 == null) + return false; } - float[] data = e.getSmilesExt().getFlexFitList(bs1, bs2, smiles1, - !isSmiles); - return (data == null ? mp.addXStr("") : mp.addXAF(data)); - } - try { + if (isBonds) { + if (args.length != 4) + return false; + // A, B, ........................BONDS + // A, B, SMILES,...................BONDS + smiles1 = SV.sValue(args[2]); + isSmiles = smiles1.equalsIgnoreCase("SMILES"); + try { + if (isSmiles) + smiles1 = vwr.getSmiles(bs1); + } catch (Exception ex) { + e.evalError(ex.getMessage(), null); + } + float[] data = e.getSmilesExt().getFlexFitList(bs1, bs2, smiles1, + !isSmiles); + return (data == null ? mp.addXStr("") : mp.addXAF(data)); + } if (isIsomer) { if (args.length != 3) return false; + + // A, B, ISOMER + + if (bs1 == null && bs2 == null) return mp.addXStr(vwr.getSmilesMatcher() .getRelationship(smiles1, smiles2).toUpperCase()); @@ -438,8 +445,8 @@ || s.indexOf("@") >= 0) { if (smiles1.indexOf("@") >= 0 && (bs2 != null || smiles2.indexOf("@") >= 0)) { - // reverse chirality centers - smiles1 = vwr.getSmilesMatcher().reverseChirality(smiles1); + // reverse chirality centers + smiles1 = "/invertstereo/" + smiles1;//vwr.getSmilesMatcher().reverseChirality(smiles1); if (bs2 == null) { check = (vwr.getSmilesMatcher().areEqual(smiles1, smiles2) > 0); } else { @@ -471,37 +478,61 @@ null, null, null, false, null, null, false, JC.SMILES_TYPE_SMILES); return mp.addXStr(stddev < 0.2f ? "IDENTICAL" : "IDENTICAL or CONFORMATIONAL ISOMERS (RMSD=" + stddev + ")"); - } else if (isSmiles) { + } + if (isSmiles) { + // A, B, MAP + // A, B, MAP, [pattern "H" "allH" "bestH"], ["stddev"] + // A, B, SMILES, [pattern "H" "allH" "bestH"], ["stddev"] + // A, B, SMARTS, pattern, ["stddev"] + // A, B, SMILES, "polyhedron", [pattern "all" "best"], ["stddev"] + // A, B, SMARTS, "polyhedron", pattern, ["all" "best"], ["stddev"] ptsA = new Lst<P3>(); ptsB = new Lst<P3>(); sOpt = SV.sValue(args[2]); boolean isMap = sOpt.equalsIgnoreCase("MAP"); - isSmiles = (sOpt.equalsIgnoreCase("SMILES")); + isSmiles = sOpt.equalsIgnoreCase("SMILES"); boolean isSearch = (isMap || sOpt.equalsIgnoreCase("SMARTS")); if (isSmiles || isSearch) - sOpt = (args.length > 3 ? SV.sValue(args[3]) : null); - boolean hMaps = (("H".equalsIgnoreCase(sOpt) || "allH".equalsIgnoreCase(sOpt) || "bestH" - .equalsIgnoreCase(sOpt))); + sOpt = (args.length > (isStdDev ? 4 : 3) ? SV.sValue(args[3]) : null); + + // sOpts = "H", "allH", "bestH", "polyhedra", pattern, or null + boolean hMaps = (("H".equalsIgnoreCase(sOpt) + || "allH".equalsIgnoreCase(sOpt) || "bestH".equalsIgnoreCase(sOpt))); boolean isPolyhedron = ("polyhedra".equalsIgnoreCase(sOpt)); if (isPolyhedron) - sOpt = (args.length > 4 ? SV.sValue(args[4]) : null); - boolean allMaps = (("all".equalsIgnoreCase(sOpt) || "allH".equalsIgnoreCase(sOpt))); - boolean bestMap = (("best".equalsIgnoreCase(sOpt) || "bestH".equalsIgnoreCase(sOpt))); + sOpt = (args.length > (isStdDev ? 5 : 4) ? SV.sValue(args[4]) : null); + boolean allMaps = (("all".equalsIgnoreCase(sOpt) || "allH" + .equalsIgnoreCase(sOpt))); + boolean bestMap = (("best".equalsIgnoreCase(sOpt) || "bestH" + .equalsIgnoreCase(sOpt))); + if ("stddev".equals(sOpt)) + sOpt = null; + String pattern = sOpt; if (sOpt == null || hMaps || allMaps || bestMap) { // with explicitH we set to find only the first match. - if (!isMap && !isSmiles) + if (!isMap && !isSmiles || hMaps && isPolyhedron) return false; - sOpt = "/noaromatic" + pattern = "/noaromatic" + (allMaps || bestMap ? "/" : " nostereo/") + e.getSmilesExt().getSmilesMatches((hMaps ? "H" : ""), null, bs1, null, false, true, false); } else { allMaps = true; } - stddev = e.getSmilesExt().getSmilesCorrelation(bs1, bs2, sOpt, ptsA, - ptsB, m, null, isMap, null, null, bestMap, - (isSmiles ? JC.SMILES_TYPE_SMILES : JC.SMILES_TYPE_SMARTS) - | (!allMaps && !bestMap ? JC.SMILES_RETURN_FIRST : 0)); + stddev = e.getSmilesExt().getSmilesCorrelation( + bs1, + bs2, + pattern, + ptsA, + ptsB, + m, + null, + isMap, + null, + null, + bestMap, + (isSmiles ? JC.SMILES_TYPE_SMILES : JC.SMILES_TYPE_SMARTS) + | (!allMaps && !bestMap ? JC.SMILES_RETURN_FIRST : 0)); if (isMap) { int nAtoms = ptsA.size(); if (nAtoms == 0) @@ -516,9 +547,21 @@ ((Atom) ptsB.get(pt)).i }; } return (allMaps ? mp.addXList(ret) : ret.size() > 0 ? mp.addXAII(ret - .get(0)) : mp.addXStr("")); + .get(0)) : mp.addXStr("")); } } else { + switch (args.length) { + case 2: + break; + case 3: + if (isStdDev) + break; + //$FALL-THROUGH$ + default: + return false; + } + // A, B + // A, B, stddev ptsA = e.getPointVector(args[0], 0); ptsB = e.getPointVector(args[1], 0); if (ptsA != null && ptsB != null) { @@ -1008,6 +1051,8 @@ // {*}.find("ccCCN","BONDS") // {*}.find("SMILES","H") // {*}.find("chemical",type) + // {1.1}.find("SMILES", {2.1}) + // {1.1}.find("SMARTS", {2.1}) SV x1 = mp.getX(); boolean isList = (x1.tok == T.varray); @@ -1021,7 +1066,8 @@ boolean isChemical = !isList && sFind.equalsIgnoreCase("CHEMICAL"); boolean isMF = !isList && sFind.equalsIgnoreCase("MF"); boolean isCF = !isList && sFind.equalsIgnoreCase("CELLFORMULA"); - boolean isON = !isList && (args[args.length - 1].tok == T.on); + boolean isON = !isList && args.length > 0 + && (args[args.length - 1].tok == T.on); try { if (isChemical) { String data = (x1.tok == T.bitset ? vwr.getSmiles(SV.getBitSet(x1, @@ -1062,9 +1108,9 @@ asMap = SV.bValue(args[2]); break; } - try { - ret = e.getSmilesExt().getSmilesMatches(pattern, smiles, null, null, - isSMARTS, !asMap, !allMappings); + try { + ret = e.getSmilesExt().getSmilesMatches(pattern, smiles, null, + null, isSMARTS, !asMap, !allMappings); } catch (Exception e) { return mp.addXInt(-1); } @@ -1087,8 +1133,10 @@ JC.SMILES_BIO | (isAll ? JC.SMILES_BIO_ALLOW_UNMACHED_RINGS | JC.SMILES_BIO_CROSSLINK : 0))); - if (isSmiles || isSMARTS) - sFind = flags; + if (isSmiles || isSMARTS) { + sFind = (args.length > 1 && args[1].tok == T.bitset ? vwr + .getSmilesOpt((BS) args[1].value, 0, 0, 0) : flags); + } BS bsMatch3D = bs2; if (asBonds) { // this will return a single match Modified: trunk/Jmol/src/org/jmol/scriptext/SmilesExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/SmilesExt.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/scriptext/SmilesExt.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -121,7 +121,7 @@ for (int j = 0; j < maps[i].length; j++) ptsB.addLast(atoms[maps[i][j]]); Interface.getInterface("javajs.util.Eigen", e.vwr, "script"); - float stddev = Measure.getTransformMatrix4(ptsA, ptsB, m, c); + float stddev = (ptsB.size() == 1 ? 0 : Measure.getTransformMatrix4(ptsA, ptsB, m, null)); Logger.info("getSmilesCorrelation stddev=" + stddev); if (vReturn != null) { if (stddev < tolerance) { Modified: trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -263,6 +263,9 @@ return "identical"; } + /** + * Note, this may be incompatible with [$(select(..))] + */ @Override public String reverseChirality(String smiles) { smiles = PT.rep(smiles, "@@", "!@"); Modified: trunk/Jmol/src/org/jmol/smiles/SmilesMeasure.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesMeasure.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/smiles/SmilesMeasure.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -26,6 +26,7 @@ import javajs.util.P3; +import javajs.util.PT; public class SmilesMeasure { @@ -40,21 +41,27 @@ private int[] indices = new int[4]; static final String TYPES = "__dat"; - private float min; - private float max; + private float[] min = new float[4]; + private float[] max = new float[4]; + private int n = 0; - SmilesMeasure(SmilesSearch search, int index, int type, float min, float max, boolean isNot) { + SmilesMeasure(SmilesSearch search, int index, int type, boolean isNot) { this.search = search; this.type = Math.min(4, Math.max(type, 2)); this.index = index; - this.min = Math.min(min, max); - this.max = Math.max(min, max); this.isNot = isNot; } - + + void addRange(float min, float max) { + if (n >= 4) + return; + this.min[n] = Math.min(min, max); + this.max[n] = Math.max(min, max); + n++; + } @Override public String toString() { - String s = "(." + TYPES.charAt(type) + index + ":" + min + "," + max + ") for"; + String s = "(." + TYPES.charAt(type) + index + ":" + PT.toJSON(null, min) + "," + PT.toJSON(null, max) + ") for"; for (int i = 0; i < type; i++) s+= " " + (i >= nPoints ? "?" : "" + indices[i]); return s; @@ -90,13 +97,16 @@ search.v.vB.sub2(points[2], points[1]); d = search.v.vA.angle(search.v.vB) / radiansPerDegree; break; - case 4: + case 4: setTorsionData(points[0], points[1], points[2], points[3], search.v, true); - d = search.v.vTemp1.angle(search.v.vTemp2) / radiansPerDegree * (search.v.vNorm1.dot(search.v.vNorm2) < 0 ? 1 : -1); + d = search.v.vTemp1.angle(search.v.vTemp2) / radiansPerDegree + * (search.v.vNorm1.dot(search.v.vNorm2) < 0 ? 1 : -1); break; } - //System.out.println(type + " " + min + " " + max + " " + d + " " + isNot); - return ((d < min || d > max) == isNot); + for (int i = 0; i < n; i++) + if (d >= min[i] && d <= max[i]) + return !isNot; + return isNot; } public static void setTorsionData(P3 pt1a, P3 pt1, Modified: trunk/Jmol/src/org/jmol/smiles/SmilesParser.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -341,7 +341,7 @@ for (int i = molecule.ac; --i >= 0;) { SmilesAtom atom = molecule.patternAtoms[i]; if (molecule.isTopology && - (atom.hasSubpattern || atom.isBioAtom || atom.elementNumber != -2 || atom.nAtomsOr > 0 || atom.nPrimitives > 0)) + (atom.hasSubpattern || atom.iNested != 0 || atom.isBioAtom || atom.elementNumber != -2 || atom.nAtomsOr > 0 || atom.nPrimitives > 0)) molecule.isTopology = false; atom.setBondArray(); if (!isSmarts && atom.bioType == '\0' && !atom.setHydrogenCount(molecule)) @@ -621,14 +621,13 @@ // or C(.d1:1.5-1.6)C(.d1) // or C(.d1:!1.5-1.6)C(.d1) int pt = strMeasure.indexOf(":"); - boolean isNot = false; String id = (pt < 0 ? strMeasure : strMeasure.substring(0, pt)); while (pt != 0) { // no real repeat here -- just an enclosure for break int len = id.length(); if (len == 1) id += "0"; SmilesMeasure m = htMeasures.get(id); - if ((m == null) == (pt < 0)) + if ((m == null) == (pt < 0) || len == 0) break; try { if (pt > 0) { @@ -636,22 +635,33 @@ if (type < 2) break; int[] ret = new int[1]; - int index = getDigits(id, 1, ret); - int pt2 = strMeasure.indexOf(",", pt); - if (pt2 < 0) - pt2 = strMeasure.indexOf("-", pt + 1); - if (pt2 < 0) + getDigits(id, 1, ret); + int index = ret[0]; + strMeasure = strMeasure.substring(pt + 1); + boolean isNot = strMeasure.startsWith("!"); + if (isNot) + strMeasure = strMeasure.substring(1); + boolean isNegative = (strMeasure.startsWith("-")); + if (isNegative) + strMeasure = strMeasure.substring(1); + strMeasure = PT.rep(strMeasure, "-", ","); + strMeasure = PT.rep(strMeasure, ",,", ",-"); + if (isNegative) + strMeasure = "-" + strMeasure; + String[] tokens = PT.split(strMeasure, ","); + if(tokens.length % 2 == 1 || tokens.length > 8) break; - String s = strMeasure.substring(pt + 1, pt2); - if (s.startsWith("!")) { - isNot = true; - s = s.substring(1); - } - float min = (pt + 1 == pt2 ? 0 : PT.fVal(s)); - s = strMeasure.substring(pt2 + 1); - float max = (s.length() == 0 ? Float.MAX_VALUE : PT.fVal(s)); - m = new SmilesMeasure(molecule, index, type, min, max, isNot); + float[] vals = new float[tokens.length]; + int i = tokens.length; + for (; --i >= 0;) + if (Float.isNaN(vals[i] = PT.fVal(tokens[i]))) + break; + if (i >= 0) + break; + m = new SmilesMeasure(molecule, index, type, isNot); molecule.measures.addLast(m); + for (i = 0; i < vals.length; i += 2) + m.addRange(vals[i], vals[i+1]); if (index > 0) htMeasures.put(id, m); else if (index == 0 && Logger.debugging) Modified: trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -70,7 +70,6 @@ String pattern; Node[] jmolAtoms; - Node[] smartsAtoms; BNode[] bioAtoms; int jmolAtomCount; @@ -1928,7 +1927,7 @@ String key = entry.getValue().toString(); if (key.startsWith("select")) { BS bs = (htNew.containsKey(key) ? (BS) htNew.get(key) - : smartsAtoms[0].findAtomsLike(key.substring(6))); + : jmolAtoms[0].findAtomsLike(key.substring(6))); if (bs == null) bs = new BS(); htNew.put(key, bs); Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-08-25 05:56:29 UTC (rev 20734) @@ -58,7 +58,24 @@ Jmol.___JmolVersion="14.3.16_2015.08.24" -bug fix: still problems with aTest = "testing"; x = [aTest:aTest] or a = [property_MYINFO:aTest] +new feature: JmolSMILES $(.x:1,2,3,4,5,6,7,8) + -- x is oen of d,a,t + -- up to four ranges per measurement +new feature: print {2.1}.find("SMILES",{1.1}) + +bug fix: compare() function returning matrix with translation about center, not origin +bug fix: print compare({1.1},{2.1}, "SMILES", "stddev") broken +bug fix: select search("[$(select atomno < 5)]") broken +bug fix: select search("[$(select atomno < 5) or @5]") broken + +new feature: _hoverLabel + -- reports general hover label set by hover command + +new feature: _hoverEnabled + -- reports if hover is enabled or not + +bug fix: calculate partialCharge does not store result if all values are 0 (Otis Rothenberger) +bug fix: still problems with aTest = "testing"; x = [aTest:aTest] or a = [property_MYINFO:aTest] (Rolf Huehne) bug fix: cross(a,b) broken bug fix: write PDB broken; works without "PDB" keyword broken in 14.3.15_2015.06.18 Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Viewer.java 2015-08-24 16:41:15 UTC (rev 20733) +++ trunk/Jmol/src/org/jmol/viewer/Viewer.java 2015-08-25 05:56:29 UTC (rev 20734) @@ -1,4 +1,4 @@ - /* $RCSfile$ +/* $RCSfile$ * $Author: hansonr $ * $Date: 2014-02-02 22:24:37 -0600 (Sun, 02 Feb 2014) $ * $Revision: 19253 $ @@ -628,6 +628,7 @@ getScriptManager(); zap(false, true, false); // here to allow echos g.setO("language", GT.getLanguage()); + g.setO("_hoverLabel", hoverLabel); stm.setJmolDefaults(); // this code will be shared between Jmol 14.0 and 14.1 Elements.covalentVersion = Elements.RAD_COV_BODR_2014_02_22; @@ -2529,7 +2530,7 @@ rotatePrev1 = rotateBondIndex = -1; movingSelected = false; slm.noneSelected = Boolean.FALSE; - hoverEnabled = true; + setHoverEnabled(true); setSelectionHalosEnabled(false); tm.setCenter(); am.initializePointers(1); @@ -4063,17 +4064,23 @@ setShapeSize(JC.SHAPE_STICKS, marBond * 2, BSUtil.setAll(ms.ac)); } - int hoverAtomIndex = -1; - String hoverText; - public boolean hoverEnabled = true; + private int hoverAtomIndex = -1; + private String hoverText, hoverLabel = "%U"; + private boolean hoverEnabled = true; public void setHoverLabel(String strLabel) { shm.loadShape(JC.SHAPE_HOVER); setShapeProperty(JC.SHAPE_HOVER, "label", strLabel); - hoverEnabled = (strLabel != null); + setHoverEnabled(strLabel != null); + g.setO("_hoverLabel", hoverLabel = strLabel); if (!hoverEnabled && !sm.haveHoverCallback()) startHoverWatcher(false); } + + private void setHoverEnabled(boolean tf) { + hoverEnabled = tf; + g.setB("_hoverEnabled", tf); + } /* * hoverCallback reports information about the atom being hovered over. @@ -4090,6 +4097,7 @@ void hoverOn(int atomIndex, boolean isLabel) { g.removeParam("_objecthovered"); g.setI("_atomhovered", atomIndex); + g.setO("_hoverLabel", hoverLabel); g.setUserVariable("hovered", SV.getVariable(BSUtil.newAndSetBit(atomIndex))); if (sm.haveHoverCallback()) sm.setStatusAtomHovered(atomIndex, getAtomInfoXYZ(atomIndex, false)); @@ -4122,6 +4130,7 @@ // from draw for drawhover on if (eval != null && isScriptExecuting()) return; + g.setO("_hoverLabel", hoverLabel); if (id != null && pt != null) { g.setO("_objecthovered", id); g.setI("_atomhovered", -1); @@ -8833,6 +8842,11 @@ public void calculatePartialCharges(BS bsSelected) throws JmolAsyncException { if (bsSelected == null || bsSelected.cardinality() == 0) bsSelected = getModelUndeletedAtomsBitSetBs(getVisibleFramesBitSet()); + int pt = bsSelected.nextSetBit(0); + if (pt < 0) + return; + // this forces an array if it does not exist + setAtomProperty(BSUtil.newAndSetBit(pt), T.partialcharge, 0, 1f, null, null, null); getMinimizer(true).calculatePartialCharges(ms.bo, ms.bondCount, ms.at, bsSelected); } 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