Revision: 20982 http://sourceforge.net/p/jmol/code/20982 Author: hansonr Date: 2016-03-07 04:22:42 +0000 (Mon, 07 Mar 2016) Log Message: ----------- Jmol.___JmolVersion="14.5.3_2016.03.06"
new feature: optional processing of OpenSMILES [CH2:002] ":<n>" atom class. -- positive integer value only -- checks the atom property property_osclass -- for SMARTS, [:0] means "without an osclass" -- for SMARTS, [!:0] means "any non-zero osclass" -- for SMARTS, same as [$(select property_osclass=n)] -- only enabled with Jmol SMILES directive "/opensmiles/"; otherwise ignored new feature: {*}.find("OPENSMILES") -- adds atom class if property_osclass is nonzero bug fix: Inconsistent use of "DIASTEREOMERS" (preferred) and "DIASTERIOMERS" (incorrect) Modified Paths: -------------- branches/v14_4/Jmol/src/org/jmol/api/SmilesMatcherInterface.java branches/v14_4/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java branches/v14_4/Jmol/src/org/jmol/modelset/Atom.java branches/v14_4/Jmol/src/org/jmol/scriptext/MathExt.java branches/v14_4/Jmol/src/org/jmol/smiles/SmilesAtom.java branches/v14_4/Jmol/src/org/jmol/smiles/SmilesGenerator.java branches/v14_4/Jmol/src/org/jmol/smiles/SmilesMatcher.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/util/Edge.java branches/v14_4/Jmol/src/org/jmol/util/Node.java branches/v14_4/Jmol/src/org/jmol/viewer/JC.java trunk/Jmol/src/org/jmol/api/SmilesMatcherInterface.java trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java trunk/Jmol/src/org/jmol/modelset/Atom.java trunk/Jmol/src/org/jmol/scriptext/MathExt.java trunk/Jmol/src/org/jmol/smiles/SmilesAtom.java trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java trunk/Jmol/src/org/jmol/smiles/SmilesParser.java trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java trunk/Jmol/src/org/jmol/util/Edge.java trunk/Jmol/src/org/jmol/util/Node.java trunk/Jmol/src/org/jmol/viewer/JC.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties Modified: branches/v14_4/Jmol/src/org/jmol/api/SmilesMatcherInterface.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/api/SmilesMatcherInterface.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/api/SmilesMatcherInterface.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -45,9 +45,8 @@ int ac, BS bsSelected, int flags) throws Exception; - public abstract void getSubstructureSets(String[] smarts, Node[] atoms, int ac, - int flags, - BS bsSelected, Lst<BS> bitSets, Lst<BS>[] vRings) throws Exception; + public abstract void getMMFF94AtomTypes(String[] smarts, Node[] atoms, int ac, + BS bsSelected, Lst<BS> bitSets, Lst<BS>[] vRings) throws Exception; public abstract String getSmiles(Node[] atoms, int ac, BS bsSelected, String bioComment, int flags) throws Exception; Modified: branches/v14_4/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -870,8 +870,7 @@ // identifies that atom's MMFF94 type. try { - smartsMatcher.getSubstructureSets(smarts, atoms, atoms.length, - Edge.FLAG_AROMATIC_STRICT | Edge.FLAG_AROMATIC_DOUBLE, + smartsMatcher.getMMFF94AtomTypes(smarts, atoms, atoms.length, bsConnected, bitSets, vRings); } catch (Exception e) { Logger.error(e.toString()); Modified: branches/v14_4/Jmol/src/org/jmol/modelset/Atom.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/modelset/Atom.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/modelset/Atom.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -33,6 +33,7 @@ import javajs.util.T3; import javajs.util.V3; +import org.jmol.api.JmolDataManager; import org.jmol.api.JmolModulationSet; import org.jmol.api.SymmetryInterface; import org.jmol.atomdata.RadiusData; @@ -1420,4 +1421,18 @@ return (m.isBioModel ? ((BioModel) m).getUnitID(this, flags) : ""); } + @Override + public float getFloatProperty(String property) { + Object data = group.chain.model.ms.vwr.getDataObj(property, null, + JmolDataManager.DATA_TYPE_AF); + float f = 0; + if (data != null) { + try { + f = ((float[]) data)[i]; + } catch (Exception e) { + } + } + return f; + } + } Modified: branches/v14_4/Jmol/src/org/jmol/scriptext/MathExt.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/scriptext/MathExt.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/scriptext/MathExt.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -1272,7 +1272,8 @@ && args[1].tok != T.off ? SV.sValue(args[1]) : ""); boolean isSequence = !isList && sFind.equalsIgnoreCase("SEQUENCE"); boolean isSeq = !isList && sFind.equalsIgnoreCase("SEQ"); - boolean isSmiles = !isList && sFind.equalsIgnoreCase("SMILES"); + boolean isOpenSmiles = !isList && sFind.equalsIgnoreCase("OPENSMILES"); + boolean isSmiles = isOpenSmiles || !isList && sFind.equalsIgnoreCase("SMILES"); boolean isSMARTS = !isList && sFind.equalsIgnoreCase("SMARTS"); boolean isChemical = !isList && sFind.equalsIgnoreCase("CHEMICAL"); boolean isMF = !isList && sFind.equalsIgnoreCase("MF"); @@ -1365,7 +1366,8 @@ | JC.SMILES_RETURN_FIRST); ret = (map.length > 0 ? vwr.ms.getDihedralMap(map[0]) : new int[0]); } else { - int smilesFlags = (isSmiles ? JC.SMILES_TYPE_SMILES + int smilesFlags = (isOpenSmiles ? JC.SMILES_TYPE_OPENSMILES + : isSmiles ? JC.SMILES_TYPE_SMILES : JC.SMILES_TYPE_SMARTS) | (isON && sFind.length() == 0 ? JC.SMILES_BIO_COV_CROSSLINK | JC.SMILES_BIO_COMMENT : 0); Modified: branches/v14_4/Jmol/src/org/jmol/smiles/SmilesAtom.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/smiles/SmilesAtom.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/smiles/SmilesAtom.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -180,6 +180,7 @@ private Node matchingNode; public boolean hasSubpattern; public int mapIndex = -1; // in CCC we have atoms 0, 1, and 2 + public float osClass = Float.NaN; // OpenSMILES atom class is an integer public SmilesAtom setAll(int iComponent, int ptAtom, int atomicNumber, int charge) { @@ -716,18 +717,21 @@ } /** + * + * called from SmilesGenerator * * @param atomicNumber * @param isotopeNumber * @param valence set -1 to force brackets * @param charge + * @param osclass OpenSMILES value * @param nH * @param isAromatic * @param stereo * @return label */ static String getAtomLabel(int atomicNumber, int isotopeNumber, int valence, - int charge, int nH, boolean isAromatic, + int charge, float osclass, int nH, boolean isAromatic, String stereo) { String sym = Elements.elementSymbolFromNumber(atomicNumber); if (isAromatic) { @@ -735,15 +739,20 @@ if (atomicNumber != 6) valence = Integer.MAX_VALUE; // force [n] } - int count = (stereo == null || stereo.length() > 0 || isotopeNumber != 0 || charge != 0 ? -1 + int count = (isotopeNumber != 0 + || stereo != null && stereo.length() > 0 + || charge != 0 || osclass != 0 ? -1 : getDefaultCount(atomicNumber, false)); return (count == valence ? sym : + // rearranged 14.5.3_2016.03.06 to "[" - + (isotopeNumber <= 0 ? "" : "" + isotopeNumber) + sym + + (isotopeNumber <= 0 ? "" : "" + isotopeNumber) + + sym + + (stereo == null ? "" : stereo) + + (nH > 1 ? "H" + nH : nH == 1 ? "H" : "") + (charge < 0 && charge != Integer.MIN_VALUE ? "" + charge : charge > 0 ? "+" + charge : "") - + (stereo == null ? "" : stereo) - + (nH > 1 ? "H" + nH : nH == 1 ? "H" : "") + + (osclass == 0 ? "" : ":" + (int) osclass) + "]"); } @@ -807,4 +816,11 @@ + "]"; } + @Override + public float getFloatProperty(String property) { + if (property == "property_osclass") // == is OK here. + return osClass; + return Float.NaN; + } + } Modified: branches/v14_4/Jmol/src/org/jmol/smiles/SmilesGenerator.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/smiles/SmilesGenerator.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/smiles/SmilesGenerator.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -86,6 +86,7 @@ private boolean addAtomComment; private boolean noBioComment; private boolean noStereo; + private boolean openSMILES; public P3 stereoReference; private SmilesStereo smilesStereo; private boolean isPolyhedral; @@ -99,13 +100,15 @@ return ""; this.atoms = atoms; this.ac = ac; - addAtomComment = ((flags & JC.SMILES_ATOM_COMMENT) == JC.SMILES_ATOM_COMMENT); bsSelected = BSUtil.copy(bsSelected); - + + // note -- some of these are 2-bit flags, so we need to use (flags & X) == X if ((flags & JC.SMILES_BIO) == JC.SMILES_BIO) return getBioSmiles(bsSelected, comment, flags); this.bsSelected = bsSelected; + openSMILES = ((flags & JC.SMILES_TYPE_OPENSMILES) == JC.SMILES_TYPE_OPENSMILES); + addAtomComment = ((flags & JC.SMILES_ATOM_COMMENT) == JC.SMILES_ATOM_COMMENT); explicitH = ((flags & JC.SMILES_EXPLICIT_H) == JC.SMILES_EXPLICIT_H); topologyOnly = ((flags & JC.SMILES_TOPOLOGY) == JC.SMILES_TOPOLOGY); getAromatic = !((flags & JC.SMILES_NOAROMATIC) == JC.SMILES_NOAROMATIC); @@ -704,6 +707,7 @@ int charge = atom.getFormalCharge(); int isotope = atom.getIsotopeNumber(); int valence = atom.getValence(); + float osclass = (openSMILES ? atom.getFloatProperty("property_osclass") : 0); String atomName = atom.getAtomName(); String groupType = (atom instanceof BNode ? ((BNode)atom).getBioStructureTypeName() : ""); // for bioSMARTS we provide the connecting atom if @@ -717,7 +721,7 @@ addBracketedBioName(sb, atom, "." + atomName, false); else sb.append(SmilesAtom - .getAtomLabel(atomicNumber, isotope, (forceBrackets ? -1 : valence), charge, nH, isAromatic, + .getAtomLabel(atomicNumber, isotope, (forceBrackets ? -1 : valence), charge, osclass, nH, isAromatic, atat != null ? atat : noStereo ? null : checkStereoPairs(atom, atomIndex, stereo, stereoFlag))); sb.appendSB(sMore); Modified: branches/v14_4/Jmol/src/org/jmol/smiles/SmilesMatcher.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -285,16 +285,17 @@ } /** - * called by ForceFieldMMFF.setAtomTypes + * called by ForceFieldMMFF.setAtomTypes only * */ @Override - public void getSubstructureSets(String[] smarts, Node[] atoms, int ac, - int flags, BS bsSelected, Lst<BS> ret, + public void getMMFF94AtomTypes(String[] smarts, Node[] atoms, int ac, + BS bsSelected, Lst<BS> ret, Lst<BS>[] vRings) throws Exception { InvalidSmilesException.clear(); SmilesParser sp = new SmilesParser(true); SmilesSearch search = null; + int flags = (SmilesSearch.FLAG_AROMATIC_STRICT | SmilesSearch.FLAG_AROMATIC_DOUBLE); search = sp.parse(""); search.firstMatchOnly = false; search.matchAllAtoms = false; Modified: branches/v14_4/Jmol/src/org/jmol/smiles/SmilesParser.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -25,16 +25,16 @@ package org.jmol.smiles; +import java.util.Hashtable; +import java.util.Map; + import javajs.util.Lst; import javajs.util.PT; import javajs.util.SB; -import java.util.Hashtable; -import java.util.Map; - import org.jmol.util.Elements; -import org.jmol.util.Edge; import org.jmol.util.Logger; +import org.jmol.viewer.JC; /** * Parses a SMILES String to create a <code>SmilesMolecule</code>. @@ -121,6 +121,7 @@ private int braceCount; private int branchLevel; private boolean ignoreStereochemistry; + private boolean openSMILES; public static SmilesSearch getMolecule(String pattern, boolean isSmarts) throws InvalidSmilesException { @@ -160,23 +161,27 @@ String strFlags = getSubPattern(pattern, 0, '/').toUpperCase(); pattern = pattern.substring(strFlags.length() + 2); if (strFlags.indexOf("NONCANONICAL") >= 0) - flags |= Edge.FLAG_AROMATIC_NONCANONICAL; + flags |= SmilesSearch.FLAG_AROMATIC_NONCANONICAL; + if (strFlags.indexOf("OPENSMILES") >= 0) { + flags |= JC.SMILES_TYPE_OPENSMILES; + openSMILES = true; + } if (strFlags.indexOf("NOAROMATIC") >= 0) - flags |= Edge.FLAG_NO_AROMATIC; + flags |= SmilesSearch.FLAG_NO_AROMATIC; if (strFlags.indexOf("AROMATICSTRICT") >= 0) - flags |= Edge.FLAG_AROMATIC_STRICT; + flags |= SmilesSearch.FLAG_AROMATIC_STRICT; if (strFlags.indexOf("AROMATICDEFINED") >= 0) - flags |= Edge.FLAG_AROMATIC_DEFINED; + flags |= SmilesSearch.FLAG_AROMATIC_DEFINED; if (strFlags.indexOf("AROMATICDOUBLE") >= 0) - flags |= Edge.FLAG_AROMATIC_DOUBLE; + flags |= SmilesSearch.FLAG_AROMATIC_DOUBLE; if (strFlags.indexOf("NOSTEREO") >= 0) { - flags |= Edge.FLAG_IGNORE_STEREOCHEMISTRY; + flags |= SmilesSearch.FLAG_IGNORE_STEREOCHEMISTRY; ignoreStereochemistry = true; } else if (strFlags.indexOf("INVERTSTEREO") >= 0) { - if ((flags & Edge.FLAG_INVERT_STEREOCHEMISTRY) != 0) - flags &= ~Edge.FLAG_INVERT_STEREOCHEMISTRY; + if ((flags & SmilesSearch.FLAG_INVERT_STEREOCHEMISTRY) != 0) + flags &= ~SmilesSearch.FLAG_INVERT_STEREOCHEMISTRY; else - flags |= Edge.FLAG_INVERT_STEREOCHEMISTRY; + flags |= SmilesSearch.FLAG_INVERT_STEREOCHEMISTRY; } } if (pattern.indexOf("$") >= 0) @@ -920,6 +925,11 @@ index = SmilesStereo.checkChirality(pattern, index, molecule.patternAtoms[newAtom.index]); break; + case ':': //openSmiles application-dependent atom class + index = getDigits(pattern, index + 1, ret); + if (openSMILES) + newAtom.osClass = ret[0]; + break; default: // SMARTS has ambiguities in terms of chaining without &. // H alone is "one H atom" Modified: branches/v14_4/Jmol/src/org/jmol/smiles/SmilesSearch.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -40,6 +40,7 @@ import org.jmol.util.JmolMolecule; import org.jmol.util.Logger; import org.jmol.util.Node; +import org.jmol.viewer.JC; /** * -- was SmilesMolecule, @@ -58,7 +59,16 @@ sb.append("\nmolecular formula: " + getMolecularFormula(true, null, false)); return sb.toString(); } + + final static int FLAG_AROMATIC_NONCANONICAL = 0x400; + final static int FLAG_AROMATIC_DOUBLE = 0x200; + final static int FLAG_AROMATIC_DEFINED = 0x100; + final static int FLAG_AROMATIC_STRICT = 0x080; + final static int FLAG_INVERT_STEREOCHEMISTRY = 0x040; + final static int FLAG_IGNORE_STEREOCHEMISTRY = 0x020; + final static int FLAG_NO_AROMATIC = 0x010; + private final static int INITIAL_ATOMS = 16; SmilesAtom[] patternAtoms = new SmilesAtom[INITIAL_ATOMS]; @@ -131,6 +141,7 @@ private boolean noAromatic; private boolean aromaticDouble; private boolean noncanonical; + private boolean openSMILES; void setAtomArray() { @@ -186,7 +197,7 @@ needAromatic = false; if (needAromatic) needRingData = true; - boolean noAromatic = ((flags & Edge.FLAG_NO_AROMATIC) != 0); + boolean noAromatic = ((flags & FLAG_NO_AROMATIC) != 0); needAromatic &= (bsA == null) & !noAromatic; // when using "xxx".find("search","....") // or $(...), the aromatic set has already been determined @@ -203,8 +214,8 @@ @SuppressWarnings("unchecked") void getRingData(boolean needRingData, int flags, Lst<BS>[] vRings) throws InvalidSmilesException { - boolean aromaticStrict = ((flags & Edge.FLAG_AROMATIC_STRICT) != 0); - boolean aromaticDefined = ((flags & Edge.FLAG_AROMATIC_DEFINED) != 0); + boolean aromaticStrict = ((flags & FLAG_AROMATIC_STRICT) != 0); + boolean aromaticDefined = ((flags & FLAG_AROMATIC_DEFINED) != 0); if (aromaticStrict && vRings == null) vRings = AU.createArrayOfArrayList(4); if (aromaticDefined && needAromatic) { @@ -406,11 +417,13 @@ * */ - ignoreStereochemistry = ((flags & Edge.FLAG_IGNORE_STEREOCHEMISTRY) != 0); - invertStereochemistry = ((flags & Edge.FLAG_INVERT_STEREOCHEMISTRY) != 0); - noAromatic = ((flags & Edge.FLAG_NO_AROMATIC) != 0); - noncanonical = ((flags & Edge.FLAG_AROMATIC_NONCANONICAL) != 0); - aromaticDouble = ((flags & Edge.FLAG_AROMATIC_DOUBLE) != 0); + // flags are passed on from SmilesParser + aromaticDouble = ((flags & FLAG_AROMATIC_DOUBLE) != 0); + ignoreStereochemistry = ((flags & FLAG_IGNORE_STEREOCHEMISTRY) != 0); + invertStereochemistry = ((flags & FLAG_INVERT_STEREOCHEMISTRY) != 0); + noAromatic = ((flags & FLAG_NO_AROMATIC) != 0); + noncanonical = ((flags & FLAG_AROMATIC_NONCANONICAL) != 0); + openSMILES = ((flags & JC.SMILES_TYPE_OPENSMILES) == JC.SMILES_TYPE_OPENSMILES); if (Logger.debugging && !isSilent) Logger.debug("SmilesSearch processing " + pattern); @@ -928,8 +941,8 @@ if (!noAromatic && !patternAtom.aromaticAmbiguous && isAromatic != bsAromatic.get(iAtom)) { if (!noncanonical - || patternAtom.getExplicitHydrogenCount() != - atom.getCovalentHydrogenCount()) + || patternAtom.getExplicitHydrogenCount() != atom + .getCovalentHydrogenCount()) break; } @@ -985,33 +998,41 @@ + atom.getImplicitHydrogenCount()) break; - // r <n> ring of a given size - if (ringData != null && patternAtom.ringSize >= -1) { - if (patternAtom.ringSize <= 0) { - if ((ringCounts[iAtom] == 0) != (patternAtom.ringSize == 0)) - break; - } else { - BS rd = ringData[patternAtom.ringSize == 500 ? 5 - : patternAtom.ringSize == 600 ? 6 : patternAtom.ringSize]; - if (rd == null || !rd.get(iAtom)) - break; - if (!noAromatic) - if (patternAtom.ringSize == 500) { - if (!bsAromatic5.get(iAtom)) - break; - } else if (patternAtom.ringSize == 600) { - if (!bsAromatic6.get(iAtom)) - break; - } + if (openSMILES) { + if (!Float.isNaN(patternAtom.osClass) + && patternAtom.osClass != atom.getFloatProperty("property_osclass")) + break; + } + + if (ringData != null) { + // r <n> ring of a given size + if (patternAtom.ringSize >= -1) { + if (patternAtom.ringSize <= 0) { + if ((ringCounts[iAtom] == 0) != (patternAtom.ringSize == 0)) + break; + } else { + BS rd = ringData[patternAtom.ringSize == 500 ? 5 + : patternAtom.ringSize == 600 ? 6 : patternAtom.ringSize]; + if (rd == null || !rd.get(iAtom)) + break; + if (!noAromatic) + if (patternAtom.ringSize == 500) { + if (!bsAromatic5.get(iAtom)) + break; + } else if (patternAtom.ringSize == 600) { + if (!bsAromatic6.get(iAtom)) + break; + } + } + // R <n> a certain number of rings + if (patternAtom.ringMembership >= -1) { + // R --> -1 implies "!R0" + if (patternAtom.ringMembership == -1 ? ringCounts[iAtom] == 0 + : ringCounts[iAtom] != patternAtom.ringMembership) + break; + } } } - // R <n> a certain number of rings - if (ringData != null && patternAtom.ringMembership >= -1) { - // R --> -1 implies "!R0" - if (patternAtom.ringMembership == -1 ? ringCounts[iAtom] == 0 - : ringCounts[iAtom] != patternAtom.ringMembership) - break; - } // x <n> if (patternAtom.ringConnectivity >= 0) { // default > 0 Modified: branches/v14_4/Jmol/src/org/jmol/util/Edge.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/util/Edge.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/util/Edge.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -104,13 +104,6 @@ public int index = -1; public int order; - final public static int FLAG_AROMATIC_NONCANONICAL = 64; - final public static int FLAG_AROMATIC_DOUBLE = 32; - final public static int FLAG_AROMATIC_DEFINED = 16; - final public static int FLAG_AROMATIC_STRICT = 8; - final public static int FLAG_INVERT_STEREOCHEMISTRY = 4; - final public static int FLAG_IGNORE_STEREOCHEMISTRY = 2; - public final static int FLAG_NO_AROMATIC = 1; abstract public int getAtomIndex1(); Modified: branches/v14_4/Jmol/src/org/jmol/util/Node.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/util/Node.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/util/Node.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -43,7 +43,14 @@ public int getIsotopeNumber(); public int getValence(); public void set(float x, float y, float z); + + /** + * @param property "property_xxxx" + * @return value or Float.NaN + */ + public float getFloatProperty(String property); + // abstracts out the essential pieces for SMARTS processing public BS findAtomsLike(String substring); Modified: branches/v14_4/Jmol/src/org/jmol/viewer/JC.java =================================================================== --- branches/v14_4/Jmol/src/org/jmol/viewer/JC.java 2016-03-06 18:23:15 UTC (rev 20981) +++ branches/v14_4/Jmol/src/org/jmol/viewer/JC.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -1067,6 +1067,7 @@ public static final int SMILES_TYPE_SMILES = 0x1; public static final int SMILES_TYPE_SMARTS = 0x2; + public static final int SMILES_TYPE_OPENSMILES = 0x5; public static final int SMILES_MATCH_ALL = 0x10; public static final int SMILES_MATCH_ONE = 0x20; Modified: trunk/Jmol/src/org/jmol/api/SmilesMatcherInterface.java =================================================================== --- trunk/Jmol/src/org/jmol/api/SmilesMatcherInterface.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/api/SmilesMatcherInterface.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -45,9 +45,8 @@ int ac, BS bsSelected, int flags) throws Exception; - public abstract void getSubstructureSets(String[] smarts, Node[] atoms, int ac, - int flags, - BS bsSelected, Lst<BS> bitSets, Lst<BS>[] vRings) throws Exception; + public abstract void getMMFF94AtomTypes(String[] smarts, Node[] atoms, int ac, + BS bsSelected, Lst<BS> bitSets, Lst<BS>[] vRings) throws Exception; public abstract String getSmiles(Node[] atoms, int ac, BS bsSelected, String bioComment, int flags) throws Exception; Modified: trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java =================================================================== --- trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/minimize/forcefield/ForceFieldMMFF.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -25,15 +25,13 @@ package org.jmol.minimize.forcefield; import java.io.BufferedReader; +import java.util.Hashtable; +import java.util.Map; import javajs.util.AU; import javajs.util.Lst; import javajs.util.PT; -import java.util.Hashtable; - -import java.util.Map; - import org.jmol.api.SmilesMatcherInterface; import org.jmol.java.BS; import org.jmol.minimize.MinAngle; @@ -47,7 +45,6 @@ import org.jmol.util.BSUtil; import org.jmol.util.Elements; import org.jmol.util.Escape; -import org.jmol.util.Edge; import org.jmol.util.Logger; import org.jmol.viewer.JmolAsyncException; @@ -870,8 +867,7 @@ // identifies that atom's MMFF94 type. try { - smartsMatcher.getSubstructureSets(smarts, atoms, atoms.length, - Edge.FLAG_AROMATIC_STRICT | Edge.FLAG_AROMATIC_DOUBLE, + smartsMatcher.getMMFF94AtomTypes(smarts, atoms, atoms.length, bsConnected, bitSets, vRings); } catch (Exception e) { Logger.error(e.toString()); Modified: trunk/Jmol/src/org/jmol/modelset/Atom.java =================================================================== --- trunk/Jmol/src/org/jmol/modelset/Atom.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/modelset/Atom.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -33,6 +33,7 @@ import javajs.util.T3; import javajs.util.V3; +import org.jmol.api.JmolDataManager; import org.jmol.api.JmolModulationSet; import org.jmol.api.SymmetryInterface; import org.jmol.atomdata.RadiusData; @@ -1420,4 +1421,18 @@ return (m.isBioModel ? ((BioModel) m).getUnitID(this, flags) : ""); } + @Override + public float getFloatProperty(String property) { + Object data = group.chain.model.ms.vwr.getDataObj(property, null, + JmolDataManager.DATA_TYPE_AF); + float f = 0; + if (data != null) { + try { + f = ((float[]) data)[i]; + } catch (Exception e) { + } + } + return f; + } + } Modified: trunk/Jmol/src/org/jmol/scriptext/MathExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/scriptext/MathExt.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -1272,7 +1272,8 @@ && args[1].tok != T.off ? SV.sValue(args[1]) : ""); boolean isSequence = !isList && sFind.equalsIgnoreCase("SEQUENCE"); boolean isSeq = !isList && sFind.equalsIgnoreCase("SEQ"); - boolean isSmiles = !isList && sFind.equalsIgnoreCase("SMILES"); + boolean isOpenSmiles = !isList && sFind.equalsIgnoreCase("OPENSMILES"); + boolean isSmiles = isOpenSmiles || !isList && sFind.equalsIgnoreCase("SMILES"); boolean isSMARTS = !isList && sFind.equalsIgnoreCase("SMARTS"); boolean isChemical = !isList && sFind.equalsIgnoreCase("CHEMICAL"); boolean isMF = !isList && sFind.equalsIgnoreCase("MF"); @@ -1365,7 +1366,8 @@ | JC.SMILES_RETURN_FIRST); ret = (map.length > 0 ? vwr.ms.getDihedralMap(map[0]) : new int[0]); } else { - int smilesFlags = (isSmiles ? JC.SMILES_TYPE_SMILES + int smilesFlags = (isOpenSmiles ? JC.SMILES_TYPE_OPENSMILES + : isSmiles ? JC.SMILES_TYPE_SMILES : JC.SMILES_TYPE_SMARTS) | (isON && sFind.length() == 0 ? JC.SMILES_BIO_COV_CROSSLINK | JC.SMILES_BIO_COMMENT : 0); Modified: trunk/Jmol/src/org/jmol/smiles/SmilesAtom.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesAtom.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/smiles/SmilesAtom.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -180,6 +180,7 @@ private Node matchingNode; public boolean hasSubpattern; public int mapIndex = -1; // in CCC we have atoms 0, 1, and 2 + public float osClass = Float.NaN; // OpenSMILES atom class is an integer public SmilesAtom setAll(int iComponent, int ptAtom, int atomicNumber, int charge) { @@ -716,18 +717,21 @@ } /** + * + * called from SmilesGenerator * * @param atomicNumber * @param isotopeNumber * @param valence set -1 to force brackets * @param charge + * @param osclass OpenSMILES value * @param nH * @param isAromatic * @param stereo * @return label */ static String getAtomLabel(int atomicNumber, int isotopeNumber, int valence, - int charge, int nH, boolean isAromatic, + int charge, float osclass, int nH, boolean isAromatic, String stereo) { String sym = Elements.elementSymbolFromNumber(atomicNumber); if (isAromatic) { @@ -735,15 +739,20 @@ if (atomicNumber != 6) valence = Integer.MAX_VALUE; // force [n] } - int count = (stereo == null || stereo.length() > 0 || isotopeNumber != 0 || charge != 0 ? -1 + int count = (isotopeNumber != 0 + || stereo != null && stereo.length() > 0 + || charge != 0 || osclass != 0 ? -1 : getDefaultCount(atomicNumber, false)); return (count == valence ? sym : + // rearranged 14.5.3_2016.03.06 to "[" - + (isotopeNumber <= 0 ? "" : "" + isotopeNumber) + sym + + (isotopeNumber <= 0 ? "" : "" + isotopeNumber) + + sym + + (stereo == null ? "" : stereo) + + (nH > 1 ? "H" + nH : nH == 1 ? "H" : "") + (charge < 0 && charge != Integer.MIN_VALUE ? "" + charge : charge > 0 ? "+" + charge : "") - + (stereo == null ? "" : stereo) - + (nH > 1 ? "H" + nH : nH == 1 ? "H" : "") + + (osclass == 0 ? "" : ":" + (int) osclass) + "]"); } @@ -807,4 +816,11 @@ + "]"; } + @Override + public float getFloatProperty(String property) { + if (property == "property_osclass") // == is OK here. + return osClass; + return Float.NaN; + } + } Modified: trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/smiles/SmilesGenerator.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -86,6 +86,7 @@ private boolean addAtomComment; private boolean noBioComment; private boolean noStereo; + private boolean openSMILES; public P3 stereoReference; private SmilesStereo smilesStereo; private boolean isPolyhedral; @@ -99,13 +100,15 @@ return ""; this.atoms = atoms; this.ac = ac; - addAtomComment = ((flags & JC.SMILES_ATOM_COMMENT) == JC.SMILES_ATOM_COMMENT); bsSelected = BSUtil.copy(bsSelected); - + + // note -- some of these are 2-bit flags, so we need to use (flags & X) == X if ((flags & JC.SMILES_BIO) == JC.SMILES_BIO) return getBioSmiles(bsSelected, comment, flags); this.bsSelected = bsSelected; + openSMILES = ((flags & JC.SMILES_TYPE_OPENSMILES) == JC.SMILES_TYPE_OPENSMILES); + addAtomComment = ((flags & JC.SMILES_ATOM_COMMENT) == JC.SMILES_ATOM_COMMENT); explicitH = ((flags & JC.SMILES_EXPLICIT_H) == JC.SMILES_EXPLICIT_H); topologyOnly = ((flags & JC.SMILES_TOPOLOGY) == JC.SMILES_TOPOLOGY); getAromatic = !((flags & JC.SMILES_NOAROMATIC) == JC.SMILES_NOAROMATIC); @@ -704,6 +707,7 @@ int charge = atom.getFormalCharge(); int isotope = atom.getIsotopeNumber(); int valence = atom.getValence(); + float osclass = (openSMILES ? atom.getFloatProperty("property_osclass") : 0); String atomName = atom.getAtomName(); String groupType = (atom instanceof BNode ? ((BNode)atom).getBioStructureTypeName() : ""); // for bioSMARTS we provide the connecting atom if @@ -717,7 +721,7 @@ addBracketedBioName(sb, atom, "." + atomName, false); else sb.append(SmilesAtom - .getAtomLabel(atomicNumber, isotope, (forceBrackets ? -1 : valence), charge, nH, isAromatic, + .getAtomLabel(atomicNumber, isotope, (forceBrackets ? -1 : valence), charge, osclass, nH, isAromatic, atat != null ? atat : noStereo ? null : checkStereoPairs(atom, atomIndex, stereo, stereoFlag))); sb.appendSB(sMore); Modified: trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -285,16 +285,17 @@ } /** - * called by ForceFieldMMFF.setAtomTypes + * called by ForceFieldMMFF.setAtomTypes only * */ @Override - public void getSubstructureSets(String[] smarts, Node[] atoms, int ac, - int flags, BS bsSelected, Lst<BS> ret, + public void getMMFF94AtomTypes(String[] smarts, Node[] atoms, int ac, + BS bsSelected, Lst<BS> ret, Lst<BS>[] vRings) throws Exception { InvalidSmilesException.clear(); SmilesParser sp = new SmilesParser(true); SmilesSearch search = null; + int flags = (SmilesSearch.FLAG_AROMATIC_STRICT | SmilesSearch.FLAG_AROMATIC_DOUBLE); search = sp.parse(""); search.firstMatchOnly = false; search.matchAllAtoms = false; Modified: trunk/Jmol/src/org/jmol/smiles/SmilesParser.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -25,16 +25,16 @@ package org.jmol.smiles; +import java.util.Hashtable; +import java.util.Map; + import javajs.util.Lst; import javajs.util.PT; import javajs.util.SB; -import java.util.Hashtable; -import java.util.Map; - import org.jmol.util.Elements; -import org.jmol.util.Edge; import org.jmol.util.Logger; +import org.jmol.viewer.JC; /** * Parses a SMILES String to create a <code>SmilesMolecule</code>. @@ -121,6 +121,7 @@ private int braceCount; private int branchLevel; private boolean ignoreStereochemistry; + private boolean openSMILES; public static SmilesSearch getMolecule(String pattern, boolean isSmarts) throws InvalidSmilesException { @@ -160,23 +161,27 @@ String strFlags = getSubPattern(pattern, 0, '/').toUpperCase(); pattern = pattern.substring(strFlags.length() + 2); if (strFlags.indexOf("NONCANONICAL") >= 0) - flags |= Edge.FLAG_AROMATIC_NONCANONICAL; + flags |= SmilesSearch.FLAG_AROMATIC_NONCANONICAL; + if (strFlags.indexOf("OPENSMILES") >= 0) { + flags |= JC.SMILES_TYPE_OPENSMILES; + openSMILES = true; + } if (strFlags.indexOf("NOAROMATIC") >= 0) - flags |= Edge.FLAG_NO_AROMATIC; + flags |= SmilesSearch.FLAG_NO_AROMATIC; if (strFlags.indexOf("AROMATICSTRICT") >= 0) - flags |= Edge.FLAG_AROMATIC_STRICT; + flags |= SmilesSearch.FLAG_AROMATIC_STRICT; if (strFlags.indexOf("AROMATICDEFINED") >= 0) - flags |= Edge.FLAG_AROMATIC_DEFINED; + flags |= SmilesSearch.FLAG_AROMATIC_DEFINED; if (strFlags.indexOf("AROMATICDOUBLE") >= 0) - flags |= Edge.FLAG_AROMATIC_DOUBLE; + flags |= SmilesSearch.FLAG_AROMATIC_DOUBLE; if (strFlags.indexOf("NOSTEREO") >= 0) { - flags |= Edge.FLAG_IGNORE_STEREOCHEMISTRY; + flags |= SmilesSearch.FLAG_IGNORE_STEREOCHEMISTRY; ignoreStereochemistry = true; } else if (strFlags.indexOf("INVERTSTEREO") >= 0) { - if ((flags & Edge.FLAG_INVERT_STEREOCHEMISTRY) != 0) - flags &= ~Edge.FLAG_INVERT_STEREOCHEMISTRY; + if ((flags & SmilesSearch.FLAG_INVERT_STEREOCHEMISTRY) != 0) + flags &= ~SmilesSearch.FLAG_INVERT_STEREOCHEMISTRY; else - flags |= Edge.FLAG_INVERT_STEREOCHEMISTRY; + flags |= SmilesSearch.FLAG_INVERT_STEREOCHEMISTRY; } } if (pattern.indexOf("$") >= 0) @@ -920,6 +925,11 @@ index = SmilesStereo.checkChirality(pattern, index, molecule.patternAtoms[newAtom.index]); break; + case ':': //openSmiles application-dependent atom class + index = getDigits(pattern, index + 1, ret); + if (openSMILES) + newAtom.osClass = ret[0]; + break; default: // SMARTS has ambiguities in terms of chaining without &. // H alone is "one H atom" Modified: trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -40,6 +40,7 @@ import org.jmol.util.JmolMolecule; import org.jmol.util.Logger; import org.jmol.util.Node; +import org.jmol.viewer.JC; /** * -- was SmilesMolecule, @@ -58,7 +59,16 @@ sb.append("\nmolecular formula: " + getMolecularFormula(true, null, false)); return sb.toString(); } + + final static int FLAG_AROMATIC_NONCANONICAL = 0x400; + final static int FLAG_AROMATIC_DOUBLE = 0x200; + final static int FLAG_AROMATIC_DEFINED = 0x100; + final static int FLAG_AROMATIC_STRICT = 0x080; + final static int FLAG_INVERT_STEREOCHEMISTRY = 0x040; + final static int FLAG_IGNORE_STEREOCHEMISTRY = 0x020; + final static int FLAG_NO_AROMATIC = 0x010; + private final static int INITIAL_ATOMS = 16; SmilesAtom[] patternAtoms = new SmilesAtom[INITIAL_ATOMS]; @@ -131,6 +141,7 @@ private boolean noAromatic; private boolean aromaticDouble; private boolean noncanonical; + private boolean openSMILES; void setAtomArray() { @@ -186,7 +197,7 @@ needAromatic = false; if (needAromatic) needRingData = true; - boolean noAromatic = ((flags & Edge.FLAG_NO_AROMATIC) != 0); + boolean noAromatic = ((flags & FLAG_NO_AROMATIC) != 0); needAromatic &= (bsA == null) & !noAromatic; // when using "xxx".find("search","....") // or $(...), the aromatic set has already been determined @@ -203,8 +214,8 @@ @SuppressWarnings("unchecked") void getRingData(boolean needRingData, int flags, Lst<BS>[] vRings) throws InvalidSmilesException { - boolean aromaticStrict = ((flags & Edge.FLAG_AROMATIC_STRICT) != 0); - boolean aromaticDefined = ((flags & Edge.FLAG_AROMATIC_DEFINED) != 0); + boolean aromaticStrict = ((flags & FLAG_AROMATIC_STRICT) != 0); + boolean aromaticDefined = ((flags & FLAG_AROMATIC_DEFINED) != 0); if (aromaticStrict && vRings == null) vRings = AU.createArrayOfArrayList(4); if (aromaticDefined && needAromatic) { @@ -406,11 +417,13 @@ * */ - ignoreStereochemistry = ((flags & Edge.FLAG_IGNORE_STEREOCHEMISTRY) != 0); - invertStereochemistry = ((flags & Edge.FLAG_INVERT_STEREOCHEMISTRY) != 0); - noAromatic = ((flags & Edge.FLAG_NO_AROMATIC) != 0); - noncanonical = ((flags & Edge.FLAG_AROMATIC_NONCANONICAL) != 0); - aromaticDouble = ((flags & Edge.FLAG_AROMATIC_DOUBLE) != 0); + // flags are passed on from SmilesParser + aromaticDouble = ((flags & FLAG_AROMATIC_DOUBLE) != 0); + ignoreStereochemistry = ((flags & FLAG_IGNORE_STEREOCHEMISTRY) != 0); + invertStereochemistry = ((flags & FLAG_INVERT_STEREOCHEMISTRY) != 0); + noAromatic = ((flags & FLAG_NO_AROMATIC) != 0); + noncanonical = ((flags & FLAG_AROMATIC_NONCANONICAL) != 0); + openSMILES = ((flags & JC.SMILES_TYPE_OPENSMILES) == JC.SMILES_TYPE_OPENSMILES); if (Logger.debugging && !isSilent) Logger.debug("SmilesSearch processing " + pattern); @@ -928,8 +941,8 @@ if (!noAromatic && !patternAtom.aromaticAmbiguous && isAromatic != bsAromatic.get(iAtom)) { if (!noncanonical - || patternAtom.getExplicitHydrogenCount() != - atom.getCovalentHydrogenCount()) + || patternAtom.getExplicitHydrogenCount() != atom + .getCovalentHydrogenCount()) break; } @@ -985,33 +998,41 @@ + atom.getImplicitHydrogenCount()) break; - // r <n> ring of a given size - if (ringData != null && patternAtom.ringSize >= -1) { - if (patternAtom.ringSize <= 0) { - if ((ringCounts[iAtom] == 0) != (patternAtom.ringSize == 0)) - break; - } else { - BS rd = ringData[patternAtom.ringSize == 500 ? 5 - : patternAtom.ringSize == 600 ? 6 : patternAtom.ringSize]; - if (rd == null || !rd.get(iAtom)) - break; - if (!noAromatic) - if (patternAtom.ringSize == 500) { - if (!bsAromatic5.get(iAtom)) - break; - } else if (patternAtom.ringSize == 600) { - if (!bsAromatic6.get(iAtom)) - break; - } + if (openSMILES) { + if (!Float.isNaN(patternAtom.osClass) + && patternAtom.osClass != atom.getFloatProperty("property_osclass")) + break; + } + + if (ringData != null) { + // r <n> ring of a given size + if (patternAtom.ringSize >= -1) { + if (patternAtom.ringSize <= 0) { + if ((ringCounts[iAtom] == 0) != (patternAtom.ringSize == 0)) + break; + } else { + BS rd = ringData[patternAtom.ringSize == 500 ? 5 + : patternAtom.ringSize == 600 ? 6 : patternAtom.ringSize]; + if (rd == null || !rd.get(iAtom)) + break; + if (!noAromatic) + if (patternAtom.ringSize == 500) { + if (!bsAromatic5.get(iAtom)) + break; + } else if (patternAtom.ringSize == 600) { + if (!bsAromatic6.get(iAtom)) + break; + } + } + // R <n> a certain number of rings + if (patternAtom.ringMembership >= -1) { + // R --> -1 implies "!R0" + if (patternAtom.ringMembership == -1 ? ringCounts[iAtom] == 0 + : ringCounts[iAtom] != patternAtom.ringMembership) + break; + } } } - // R <n> a certain number of rings - if (ringData != null && patternAtom.ringMembership >= -1) { - // R --> -1 implies "!R0" - if (patternAtom.ringMembership == -1 ? ringCounts[iAtom] == 0 - : ringCounts[iAtom] != patternAtom.ringMembership) - break; - } // x <n> if (patternAtom.ringConnectivity >= 0) { // default > 0 Modified: trunk/Jmol/src/org/jmol/util/Edge.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Edge.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/util/Edge.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -104,13 +104,6 @@ public int index = -1; public int order; - final public static int FLAG_AROMATIC_NONCANONICAL = 64; - final public static int FLAG_AROMATIC_DOUBLE = 32; - final public static int FLAG_AROMATIC_DEFINED = 16; - final public static int FLAG_AROMATIC_STRICT = 8; - final public static int FLAG_INVERT_STEREOCHEMISTRY = 4; - final public static int FLAG_IGNORE_STEREOCHEMISTRY = 2; - public final static int FLAG_NO_AROMATIC = 1; abstract public int getAtomIndex1(); Modified: trunk/Jmol/src/org/jmol/util/Node.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Node.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/util/Node.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -43,7 +43,14 @@ public int getIsotopeNumber(); public int getValence(); public void set(float x, float y, float z); + + /** + * @param property "property_xxxx" + * @return value or Float.NaN + */ + public float getFloatProperty(String property); + // abstracts out the essential pieces for SMARTS processing public BS findAtomsLike(String substring); Modified: trunk/Jmol/src/org/jmol/viewer/JC.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/JC.java 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/viewer/JC.java 2016-03-07 04:22:42 UTC (rev 20982) @@ -1067,23 +1067,24 @@ public static final int SMILES_TYPE_SMILES = 0x1; public static final int SMILES_TYPE_SMARTS = 0x2; + public static final int SMILES_TYPE_OPENSMILES = 0x5; public static final int SMILES_MATCH_ALL = 0x10; public static final int SMILES_MATCH_ONE = 0x20; public static final int SMILES_RETURN_FIRST = 0x40; - public static final int SMILES_EXPLICIT_H = 0x00100; - public static final int SMILES_TOPOLOGY = 0x00200; - public static final int SMILES_NOAROMATIC = 0x00400; - public static final int SMILES_NOSTEREO = 0x00800; - public static final int SMILES_POLYHEDRAL = 0x01000; - public static final int SMILES_BIO = 0x10000; - public static final int SMILES_BIO_ALLOW_UNMATCHED_RINGS = 0x11000; - public static final int SMILES_BIO_COV_CROSSLINK = 0x12000; - public static final int SMILES_BIO_HH_CROSSLINK = 0x16000; - public static final int SMILES_BIO_COMMENT = 0x30000; - public static final int SMILES_BIO_NOCOMMENTS = 0x50000; - public static final int SMILES_ATOM_COMMENT = 0x80000; + public static final int SMILES_EXPLICIT_H = 0x000100; + public static final int SMILES_TOPOLOGY = 0x000200; + public static final int SMILES_NOAROMATIC = 0x000400; + public static final int SMILES_NOSTEREO = 0x000800; + public static final int SMILES_POLYHEDRAL = 0x001000; + public static final int SMILES_ATOM_COMMENT = 0x002000; + public static final int SMILES_BIO = 0x010000; + public static final int SMILES_BIO_ALLOW_UNMATCHED_RINGS = 0x030000; + public static final int SMILES_BIO_COV_CROSSLINK = 0x050000; + public static final int SMILES_BIO_HH_CROSSLINK = 0x090000; + public static final int SMILES_BIO_COMMENT = 0x110000; + public static final int SMILES_BIO_NOCOMMENTS = 0x210000; public static final int JSV_NOT = -1; Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2016-03-06 18:23:15 UTC (rev 20981) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2016-03-07 04:22:42 UTC (rev 20982) @@ -67,6 +67,17 @@ Jmol.___JmolVersion="14.5.3_2016.03.06" +new feature: optional processing of OpenSMILES [CH2:002] ":<n>" atom class. + -- positive integer value only + -- checks the atom property property_osclass + -- for SMARTS, [:0] means "without an osclass" + -- for SMARTS, [!:0] means "any non-zero osclass" + -- for SMARTS, same as [$(select property_osclass=n)] + -- only enabled with Jmol SMILES directive "/opensmiles/"; otherwise ignored + +new feature: {*}.find("OPENSMILES") + -- adds atom class if property_osclass is nonzero + bug fix: Inconsistent use of "DIASTEREOMERS" (preferred) and "DIASTERIOMERS" (incorrect) JmolVersion="14.5.3_2016.03.05" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Transform Data into Opportunity. Accelerate data analysis in your applications with Intel Data Analytics Acceleration Library. Click to learn more. http://makebettercode.com/inteldaal-eval _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits