Revision: 21080 http://sourceforge.net/p/jmol/code/21080 Author: hansonr Date: 2016-05-02 03:55:42 +0000 (Mon, 02 May 2016) Log Message: ----------- Jmol.___JmolVersion="14.4.4_2016.05.01"
bug fix: Jmol SMILES directive /noaromatic/ should ignore ":" bond type bug fix: Jmol SMILES directive /aromaticDouble/ not implemented for SMILES buf fix; Jmol SMARTS measurements should be required to come after branches bug fix: Jmol SMILES parser should require connection numbers to be placed prior to branches bug fix: Jmol SMILES should not allow (.t!50,60,70,80) Modified Paths: -------------- branches/v14_4/Jmol/src/org/jmol/scriptext/CmdExt.java branches/v14_4/Jmol/src/org/jmol/smiles/SmilesParser.java branches/v14_4/Jmol/src/org/jmol/smiles/SmilesSearch.java branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/scriptext/CmdExt.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 Modified: branches/v14_4/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/scriptext/CmdExt.java 2016-04-30 13:34:51 UTC (rev 21079) +++ branches/v14_4/Jmol/src/org/jmol/scriptext/CmdExt.java 2016-05-02 03:55:42 UTC (rev 21080) @@ -1217,7 +1217,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); +// System.out.println("compare:\n" + m4); if (Float.isNaN(stddev)) { showString("structures do not match"); return; @@ -4205,21 +4205,20 @@ msg = SV.getVariable(info[1]).asString(); } break; - case T.nmr: - if (eval.optParameterAsString(2).equalsIgnoreCase("1H")) { - len = 3; - if (!chk) - msg = vwr.getNMRPredict(false); - break; - } + case T.nmr: { + String type = eval.optParameterAsString(2); + // switch to "H1" and "C13" + if (type.equals("1H") || type.equals("13C")) + type = type.substring(type.length() - 1) + type.substring(0, type.length() - 1); + else if (type.equals("H")) if (!chk) - vwr.getNMRPredict(true); + vwr.getNMRPredict(type); return; + } case T.drawing: case T.chemical: case T.smiles: - - checkLength((tok == T.chemical || tok == T.smiles && tokAt(2) != T.nada ? len = 3 + checkLength((tok == T.chemical || tok == T.smiles && tokAt(2) == T.on ? len = 3 : 2) + filterLen); if (chk) @@ -4237,9 +4236,11 @@ } } else if (eval.optParameterAsString(2).equalsIgnoreCase("true")) { msg = vwr.getBioSmiles(null); + filter = null; } else if (filter != null) { msg = vwr.getSmilesOpt(null, -1, -1, JC.SMILES_TYPE_SMILES, filter + "///"); + filter = null; } if (msg == null) msg = (tok == T.smiles ? vwr.getSmiles(null) : vwr Modified: branches/v14_4/Jmol/src/org/jmol/smiles/SmilesParser.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-04-30 13:34:51 UTC (rev 21079) +++ branches/v14_4/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-05-02 03:55:42 UTC (rev 21080) @@ -403,7 +403,8 @@ int pt = 0; char ch; SmilesBond bond = null; - + boolean wasMeasure = false; + boolean wasBranch = false; while (pattern != null && pattern.length() != 0) { int index = 0; if (currentAtom == null || bond != null @@ -446,13 +447,17 @@ if (currentAtom == null) throw new InvalidSmilesException("No previous atom for " + (isMeasure ? "measure" : "branch")); + wasMeasure = wasBranch = false; if (subString.startsWith(".")) { parseMeasure(molecule, subString.substring(1), currentAtom); + wasMeasure = true; } else if (subString.length() == 0 && isBioSequence) { + // () can mean NOT crosslinked currentAtom.notCrossLinked = true; } else { branchLevel++; parseSmiles(molecule, subString, currentAtom, true); + wasBranch = true; branchLevel--; } } @@ -469,7 +474,6 @@ bond = parseBond(molecule, null, pattern.substring(pt, index), null, currentAtom, false, isBranchAtom); - if (haveOpen && bond.order != SmilesBond.TYPE_UNKNOWN) index = pt; ch = getChar(pattern, index); @@ -486,11 +490,14 @@ boolean isAtom = (!isRing && (ch == '_' || ch == '[' || ch == '*' || PT .isLetter(ch))); if (isRing) { + if (wasMeasure || wasBranch) + throw new InvalidSmilesException("connection number must immediately follow its connecting atom"); index = getRingNumber(pattern, index, ch, ret); int ringNumber = ret[0]; parseRing(molecule, ringNumber, currentAtom, bond); bond = null; } else if (isAtom) { + wasMeasure = wasBranch = false; switch (ch) { case '[': case '_': @@ -632,7 +639,7 @@ if (isNegative) strMeasure = "-" + strMeasure; String[] tokens = PT.split(strMeasure, ","); - if(tokens.length % 2 == 1) + if(tokens.length % 2 == 1 || isNot && tokens.length != 2) break; float[] vals = new float[tokens.length]; int i = tokens.length; @@ -803,10 +810,8 @@ throw new InvalidSmilesException("invalid '!'"); newAtom.not = isNot = true; } - int biopt = pattern.indexOf('.'); - int chiralpt = pattern.indexOf('@'); - if (biopt >= 0 && (chiralpt < 0 || biopt < chiralpt)) { + if (biopt >= 0) { newAtom.isBioResidue = true; String name = pattern.substring(index, biopt); pattern = pattern.substring(biopt + 1).toUpperCase(); @@ -880,19 +885,19 @@ else newAtom.elementNumber = ret[0]; break; -// does not work -// case '(': -// // JmolSMARTS, JmolSMILES reference to atom -// String name = getSubPattern(pattern, index, '('); -// index += 2 + name.length(); -// newAtom = checkReference(newAtom, name, ret); -// isNewAtom = (ret[0] == 1); // we are done here -// if (!isNewAtom) { -// if (isNot) -// index = 0; // triggers an error -// isNot = true; // flags that this must be the end -// } -// break; + // does not work + // case '(': + // // JmolSMARTS, JmolSMILES reference to atom + // String name = getSubPattern(pattern, index, '('); + // index += 2 + name.length(); + // newAtom = checkReference(newAtom, name, ret); + // isNewAtom = (ret[0] == 1); // we are done here + // if (!isNewAtom) { + // if (isNot) + // index = 0; // triggers an error + // isNot = true; // flags that this must be the end + // } + // break; case '-': case '+': index = checkCharge(pattern, index, newAtom); @@ -913,6 +918,8 @@ // "!H" is "not hydrogen" but "!H2" is "not two attached hydrogens" // [Rh] could be rhodium or "Any ring atom with at least one implicit H atom" // [Ar] could be argon or "Any aliphatic ring atom" + // however it has been pointed out by a reviewer that [Cr3] must be + // interpreted as chromium-3. // There is no ambiguity, though, with [Rh3] or [Ar6] because // in those cases the number forces the single-character property // "h3" or "r6", thus forcing "R" or "A" @@ -921,12 +928,12 @@ // the first two-letters of the expression could be interpreted // as a symbol, AND the next character is not a digit, then it WILL be interpreted as a symbol char nextChar = getChar(pattern, index + 1); - String sym2 = pattern.substring( - index + 1, - index - + (PT.isLowerCase(nextChar) - && (!isBracketed || !PT.isDigit(getChar(pattern, - index + 2))) ? 2 : 1)); + String sym2 = pattern.substring(index + 1, + index + (PT.isLowerCase(nextChar) + // 14.4.5: removed to require [C;r3] not [Cr3] for C in a 3-membered ring + // && (!isBracketed || !PT.isDigit(getChar(pattern, index + 2))) + ? 2 + : 1)); String symbol = Character.toUpperCase(ch) + sym2; boolean mustBeSymbol = true; boolean checkForPrimitive = (isBracketed && PT.isLetter(ch)); @@ -1084,7 +1091,7 @@ return newAtom; } - private Map<String, SmilesAtom> atomRefs; +// private Map<String, SmilesAtom> atomRefs; // /** // * allow for [(...)] to indicate a specific pattern atom Modified: branches/v14_4/Jmol/src/org/jmol/smiles/SmilesSearch.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-04-30 13:34:51 UTC (rev 21079) +++ branches/v14_4/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-05-02 03:55:42 UTC (rev 21080) @@ -142,13 +142,13 @@ else flags |= INVERT_STEREOCHEMISTRY; } + if (strFlags.indexOf("ATOMCOMMENT") >= 0) + flags |= JC.SMILES_GEN_ATOM_COMMENT; if ((flags & JC.SMILES_GEN_BIO) == JC.SMILES_GEN_BIO) { if (strFlags.indexOf("NOCOMMENT") >= 0) flags |= JC.SMILES_GEN_BIO_NOCOMMENTS; - if (strFlags.indexOf("ATOMCOMMENT") >= 0) - flags |= JC.SMILES_GEN_ATOM_COMMENT; if (strFlags.indexOf("UNMATCHED") >= 0) flags |= JC.SMILES_GEN_BIO_ALLOW_UNMATCHED_RINGS; if (strFlags.indexOf("COVALENT") >= 0) @@ -1191,8 +1191,9 @@ boolean isAromatic1 = (!noAromatic && bsAromatic.get(iAtom1)); boolean isAromatic2 = (!noAromatic && bsAromatic.get(iAtom2)); int order = bond.getCovalentOrder(); + int patternOrder = patternBond.order; if (isAromatic1 && isAromatic2) { - switch (patternBond.order) { + switch (patternOrder) { case SmilesBond.TYPE_AROMATIC: // : case SmilesBond.TYPE_RING: bondFound = isRingBond(ringSets, iAtom1, iAtom2); @@ -1214,7 +1215,7 @@ // distinction between single and double, as for example is necessary to distinguish // between n=cNH2 and ncNH2 (necessary for MMFF94 atom typing // - bondFound = !isSmarts || aromaticDouble && + bondFound = aromaticDouble && (order == Edge.BOND_COVALENT_DOUBLE || order == Edge.BOND_AROMATIC_DOUBLE); break; case SmilesBond.TYPE_ATROPISOMER_1: @@ -1225,7 +1226,11 @@ break; } } else { - switch (patternBond.order) { + switch (patternOrder) { + case SmilesBond.TYPE_AROMATIC: // : + if (!noAromatic) + break; + //$FALL-THROUGH$ case SmilesBond.TYPE_ANY: case SmilesBond.TYPE_UNKNOWN: bondFound = true; @@ -1253,7 +1258,7 @@ case SmilesBond.TYPE_RING: bondFound = isRingBond(ringSets, iAtom1, iAtom2); break; - } + } } return bondFound != patternBond.isNot; } Modified: branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties 2016-04-30 13:34:51 UTC (rev 21079) +++ branches/v14_4/Jmol/src/org/jmol/viewer/Jmol.properties 2016-05-02 03:55:42 UTC (rev 21080) @@ -5,6 +5,14 @@ # see also http://chemapps.stolaf.edu/jmol/zip for daily updates +Jmol.___JmolVersion="14.4.4_2016.05.01" + +bug fix: Jmol SMILES directive /noaromatic/ should ignore ":" bond type +bug fix: Jmol SMILES directive /aromaticDouble/ not implemented for SMILES +buf fix; Jmol SMARTS measurements should be required to come after branches +bug fix: Jmol SMILES parser should require connection numbers to be placed prior to branches +bug fix: Jmol SMILES should not allow (.t!50,60,70,80) + Jmol.___JmolVersion="14.4.4_2016.04.30" new feature: 13C Simulated spectra (but without correlation yet) Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2016-04-30 13:34:51 UTC (rev 21079) +++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2016-05-02 03:55:42 UTC (rev 21080) @@ -1217,7 +1217,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); +// System.out.println("compare:\n" + m4); if (Float.isNaN(stddev)) { showString("structures do not match"); return; @@ -4218,8 +4218,7 @@ case T.drawing: case T.chemical: case T.smiles: - - checkLength((tok == T.chemical || tok == T.smiles && tokAt(2) != T.nada ? len = 3 + checkLength((tok == T.chemical || tok == T.smiles && tokAt(2) == T.on ? len = 3 : 2) + filterLen); if (chk) @@ -4237,9 +4236,11 @@ } } else if (eval.optParameterAsString(2).equalsIgnoreCase("true")) { msg = vwr.getBioSmiles(null); + filter = null; } else if (filter != null) { msg = vwr.getSmilesOpt(null, -1, -1, JC.SMILES_TYPE_SMILES, filter + "///"); + filter = null; } if (msg == null) msg = (tok == T.smiles ? vwr.getSmiles(null) : vwr Modified: trunk/Jmol/src/org/jmol/smiles/SmilesParser.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-04-30 13:34:51 UTC (rev 21079) +++ trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-05-02 03:55:42 UTC (rev 21080) @@ -403,7 +403,8 @@ int pt = 0; char ch; SmilesBond bond = null; - + boolean wasMeasure = false; + boolean wasBranch = false; while (pattern != null && pattern.length() != 0) { int index = 0; if (currentAtom == null || bond != null @@ -446,13 +447,17 @@ if (currentAtom == null) throw new InvalidSmilesException("No previous atom for " + (isMeasure ? "measure" : "branch")); + wasMeasure = wasBranch = false; if (subString.startsWith(".")) { parseMeasure(molecule, subString.substring(1), currentAtom); + wasMeasure = true; } else if (subString.length() == 0 && isBioSequence) { + // () can mean NOT crosslinked currentAtom.notCrossLinked = true; } else { branchLevel++; parseSmiles(molecule, subString, currentAtom, true); + wasBranch = true; branchLevel--; } } @@ -469,7 +474,6 @@ bond = parseBond(molecule, null, pattern.substring(pt, index), null, currentAtom, false, isBranchAtom); - if (haveOpen && bond.order != SmilesBond.TYPE_UNKNOWN) index = pt; ch = getChar(pattern, index); @@ -486,11 +490,14 @@ boolean isAtom = (!isRing && (ch == '_' || ch == '[' || ch == '*' || PT .isLetter(ch))); if (isRing) { + if (wasMeasure || wasBranch) + throw new InvalidSmilesException("connection number must immediately follow its connecting atom"); index = getRingNumber(pattern, index, ch, ret); int ringNumber = ret[0]; parseRing(molecule, ringNumber, currentAtom, bond); bond = null; } else if (isAtom) { + wasMeasure = wasBranch = false; switch (ch) { case '[': case '_': @@ -632,7 +639,7 @@ if (isNegative) strMeasure = "-" + strMeasure; String[] tokens = PT.split(strMeasure, ","); - if(tokens.length % 2 == 1) + if(tokens.length % 2 == 1 || isNot && tokens.length != 2) break; float[] vals = new float[tokens.length]; int i = tokens.length; @@ -803,10 +810,8 @@ throw new InvalidSmilesException("invalid '!'"); newAtom.not = isNot = true; } - int biopt = pattern.indexOf('.'); - int chiralpt = pattern.indexOf('@'); - if (biopt >= 0 && (chiralpt < 0 || biopt < chiralpt)) { + if (biopt >= 0) { newAtom.isBioResidue = true; String name = pattern.substring(index, biopt); pattern = pattern.substring(biopt + 1).toUpperCase(); @@ -880,19 +885,19 @@ else newAtom.elementNumber = ret[0]; break; -// does not work -// case '(': -// // JmolSMARTS, JmolSMILES reference to atom -// String name = getSubPattern(pattern, index, '('); -// index += 2 + name.length(); -// newAtom = checkReference(newAtom, name, ret); -// isNewAtom = (ret[0] == 1); // we are done here -// if (!isNewAtom) { -// if (isNot) -// index = 0; // triggers an error -// isNot = true; // flags that this must be the end -// } -// break; + // does not work + // case '(': + // // JmolSMARTS, JmolSMILES reference to atom + // String name = getSubPattern(pattern, index, '('); + // index += 2 + name.length(); + // newAtom = checkReference(newAtom, name, ret); + // isNewAtom = (ret[0] == 1); // we are done here + // if (!isNewAtom) { + // if (isNot) + // index = 0; // triggers an error + // isNot = true; // flags that this must be the end + // } + // break; case '-': case '+': index = checkCharge(pattern, index, newAtom); @@ -913,6 +918,8 @@ // "!H" is "not hydrogen" but "!H2" is "not two attached hydrogens" // [Rh] could be rhodium or "Any ring atom with at least one implicit H atom" // [Ar] could be argon or "Any aliphatic ring atom" + // however it has been pointed out by a reviewer that [Cr3] must be + // interpreted as chromium-3. // There is no ambiguity, though, with [Rh3] or [Ar6] because // in those cases the number forces the single-character property // "h3" or "r6", thus forcing "R" or "A" @@ -921,12 +928,12 @@ // the first two-letters of the expression could be interpreted // as a symbol, AND the next character is not a digit, then it WILL be interpreted as a symbol char nextChar = getChar(pattern, index + 1); - String sym2 = pattern.substring( - index + 1, - index - + (PT.isLowerCase(nextChar) - && (!isBracketed || !PT.isDigit(getChar(pattern, - index + 2))) ? 2 : 1)); + String sym2 = pattern.substring(index + 1, + index + (PT.isLowerCase(nextChar) + // 14.4.5: removed to require [C;r3] not [Cr3] for C in a 3-membered ring + // && (!isBracketed || !PT.isDigit(getChar(pattern, index + 2))) + ? 2 + : 1)); String symbol = Character.toUpperCase(ch) + sym2; boolean mustBeSymbol = true; boolean checkForPrimitive = (isBracketed && PT.isLetter(ch)); @@ -1084,7 +1091,7 @@ return newAtom; } - private Map<String, SmilesAtom> atomRefs; +// private Map<String, SmilesAtom> atomRefs; // /** // * allow for [(...)] to indicate a specific pattern atom Modified: trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-04-30 13:34:51 UTC (rev 21079) +++ trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-05-02 03:55:42 UTC (rev 21080) @@ -142,13 +142,13 @@ else flags |= INVERT_STEREOCHEMISTRY; } + if (strFlags.indexOf("ATOMCOMMENT") >= 0) + flags |= JC.SMILES_GEN_ATOM_COMMENT; if ((flags & JC.SMILES_GEN_BIO) == JC.SMILES_GEN_BIO) { if (strFlags.indexOf("NOCOMMENT") >= 0) flags |= JC.SMILES_GEN_BIO_NOCOMMENTS; - if (strFlags.indexOf("ATOMCOMMENT") >= 0) - flags |= JC.SMILES_GEN_ATOM_COMMENT; if (strFlags.indexOf("UNMATCHED") >= 0) flags |= JC.SMILES_GEN_BIO_ALLOW_UNMATCHED_RINGS; if (strFlags.indexOf("COVALENT") >= 0) @@ -1191,8 +1191,9 @@ boolean isAromatic1 = (!noAromatic && bsAromatic.get(iAtom1)); boolean isAromatic2 = (!noAromatic && bsAromatic.get(iAtom2)); int order = bond.getCovalentOrder(); + int patternOrder = patternBond.order; if (isAromatic1 && isAromatic2) { - switch (patternBond.order) { + switch (patternOrder) { case SmilesBond.TYPE_AROMATIC: // : case SmilesBond.TYPE_RING: bondFound = isRingBond(ringSets, iAtom1, iAtom2); @@ -1214,7 +1215,7 @@ // distinction between single and double, as for example is necessary to distinguish // between n=cNH2 and ncNH2 (necessary for MMFF94 atom typing // - bondFound = !isSmarts || aromaticDouble && + bondFound = aromaticDouble && (order == Edge.BOND_COVALENT_DOUBLE || order == Edge.BOND_AROMATIC_DOUBLE); break; case SmilesBond.TYPE_ATROPISOMER_1: @@ -1225,7 +1226,11 @@ break; } } else { - switch (patternBond.order) { + switch (patternOrder) { + case SmilesBond.TYPE_AROMATIC: // : + if (!noAromatic) + break; + //$FALL-THROUGH$ case SmilesBond.TYPE_ANY: case SmilesBond.TYPE_UNKNOWN: bondFound = true; @@ -1253,7 +1258,7 @@ case SmilesBond.TYPE_RING: bondFound = isRingBond(ringSets, iAtom1, iAtom2); break; - } + } } return bondFound != patternBond.isNot; } Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2016-04-30 13:34:51 UTC (rev 21079) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2016-05-02 03:55:42 UTC (rev 21080) @@ -42,6 +42,15 @@ TODO: slightly stronger unitcell lines for near point? +Jmol.___JmolVersion="14.5.4_2016.05.01" + +bug fix: Jmol SMILES directive /noaromatic/ should ignore ":" bond type +bug fix: Jmol SMILES directive /aromaticDouble/ not implemented for SMILES +buf fix; Jmol SMARTS measurements should be required to come after branches +bug fix: Jmol SMILES parser should require connection numbers to be placed prior to branches +bug fix: Jmol SMILES should not allow (.t!50,60,70,80) + + Jmol.___JmolVersion="14.5.4_2016.04.30" new feature: 13C Simulated spectra (but without correlation yet) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Find and fix application performance issues faster with Applications Manager Applications Manager provides deep performance insights into multiple tiers of your business applications. It resolves application problems quickly and reduces your MTTR. Get your free trial! https://ad.doubleclick.net/ddm/clk/302982198;130105516;z _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits