Revision: 20731 http://sourceforge.net/p/jmol/code/20731 Author: hansonr Date: 2015-08-24 09:20:06 +0000 (Mon, 24 Aug 2015) Log Message: ----------- Jmol.___JmolVersion="14.3.16_2015.08.24"
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/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/viewer/Jmol.properties Modified: trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2015-08-23 21:34:50 UTC (rev 20730) +++ trunk/Jmol/src/org/jmol/smiles/SmilesMatcher.java 2015-08-24 09:20:06 UTC (rev 20731) @@ -248,8 +248,7 @@ if (s.indexOf("/") >= 0 || s.indexOf("\\") >= 0 || s.indexOf("@") >= 0) { if (n1 == n2 && n1 > 0) { // reverse chirality centers - smiles1 = reverseChirality(smiles1); - check = (areEqual(smiles1, smiles2) > 0); + check = (areEqual("/invertstereo/" + smiles2, smiles1) > 0); if (check) return "enantiomers"; } Modified: trunk/Jmol/src/org/jmol/smiles/SmilesParser.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2015-08-23 21:34:50 UTC (rev 20730) +++ trunk/Jmol/src/org/jmol/smiles/SmilesParser.java 2015-08-24 09:20:06 UTC (rev 20731) @@ -168,6 +168,8 @@ flags |= Edge.FLAG_AROMATIC_DOUBLE; if (strFlags.indexOf("NOSTEREO") >= 0) flags |= Edge.FLAG_IGNORE_STEREOCHEMISTRY; + if (strFlags.indexOf("INVERTSTEREO") >= 0) + flags |= Edge.FLAG_INVERT_STEREOCHEMISTRY; } if (pattern.indexOf("$") >= 0) pattern = parseVariables(pattern); @@ -339,7 +341,7 @@ for (int i = molecule.ac; --i >= 0;) { SmilesAtom atom = molecule.patternAtoms[i]; if (molecule.isTopology && - (atom.hasSubpattern || atom.elementNumber != -2 || atom.nAtomsOr > 0 || atom.nPrimitives > 0)) + (atom.hasSubpattern || atom.isBioAtom || atom.elementNumber != -2 || atom.nAtomsOr > 0 || atom.nPrimitives > 0)) molecule.isTopology = false; atom.setBondArray(); if (!isSmarts && atom.bioType == '\0' && !atom.setHydrogenCount(molecule)) @@ -712,12 +714,28 @@ return pattern; } + /** + * variables can be defined, as in + * + * select within(SMARTS,'$R1="[CH3, NH2]";$R2="[$([$R1]),OH]"; {a}[$R2]') + * + * select within(SMARTS,'$R1="[CH3,NH2]";$R2="[OH]"; {a}[$([$R1]),$([$R2])]') + * + * "select aromatic atoms bearing CH3, NH2, or OH" + * + * + * @param pattern + * @return substituted pattern + * @throws InvalidSmilesException + */ private String parseVariables(String pattern) throws InvalidSmilesException { Lst<String> keys = new Lst<String>(); Lst<String> values = new Lst<String>(); int index; int ipt = 0; int iptLast = -1; + if (Logger.debugging) + Logger.info(pattern); while ((index = pattern.indexOf("$", ipt)) >= 0) { if (getChar(pattern, ipt + 1) == '(') break; @@ -736,7 +754,16 @@ } if (iptLast < 0) return pattern; - return PT.replaceStrings(pattern.substring(iptLast), keys, values); + pattern = pattern.substring(iptLast); + for (int i = keys.size(); --i >= 0;) { + String k = keys.get(i); + String v = values.get(i); + if (!v.equals(k)) + pattern = PT.rep(pattern, k, v); + } + if (Logger.debugging) + Logger.info(pattern); + return pattern; } /** Modified: trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java =================================================================== --- trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2015-08-23 21:34:50 UTC (rev 20730) +++ trunk/Jmol/src/org/jmol/smiles/SmilesSearch.java 2015-08-24 09:20:06 UTC (rev 20731) @@ -51,6 +51,9 @@ */ public class SmilesSearch extends JmolMolecule { + public SmilesSearch() { + } + @Override public String toString() { SB sb = new SB().append(pattern); @@ -124,7 +127,7 @@ private Lst<Object> vReturn; BS bsReturn = new BS(); - private boolean ignoreStereochemistry; + private boolean ignoreStereochemistry, invertStereochemistry; private boolean noAromatic; private boolean aromaticDouble; @@ -304,6 +307,7 @@ boolean isRingCheck) throws InvalidSmilesException { search.ringSets = ringSets; search.jmolAtoms = jmolAtoms; + search.bioAtoms = bioAtoms; search.jmolAtomCount = jmolAtomCount; search.bsSelected = bsSelected; search.htNested = htNested; @@ -391,6 +395,7 @@ */ ignoreStereochemistry = ((flags & Edge.FLAG_IGNORE_STEREOCHEMISTRY) != 0); + invertStereochemistry = ((flags & Edge.FLAG_INVERT_STEREOCHEMISTRY) != 0); noAromatic = ((flags & Edge.FLAG_NO_AROMATIC) != 0); aromaticDouble = ((flags & Edge.FLAG_AROMATIC_DOUBLE) != 0); @@ -822,9 +827,20 @@ foundAtom = (patternAtom.not != (((BS) o).get(iAtom))); break; } + // all types + if (patternAtom.residueName != null + && !patternAtom.residueName + .equals(((BNode)atom).getGroup3(false).toUpperCase())) + break; + // # <n> or Symbol Check atomic number + if (patternAtom.elementNumber >= 0 + && patternAtom.elementNumber != atom.getElementNumber()) + break; + if (patternAtom.jmolIndex >= 0 + && atom.getIndex() != patternAtom.jmolIndex) + break; if (patternAtom.isBioAtom) { BNode a = (BNode) atom; - // BIOSMARTS if (patternAtom.atomName != null && (patternAtom.isLeadAtom() ? !a.isLeadAtom() @@ -832,10 +848,6 @@ break; if (patternAtom.notCrossLinked && a.getCrossLinkLeadAtomIndexes(null)) break; - if (patternAtom.residueName != null - && !patternAtom.residueName - .equals(a.getGroup3(false).toUpperCase())) - break; if (patternAtom.residueChar != null) { if (patternAtom.isDna() && !a.isDna() || patternAtom.isRna() && !a.isRna() || patternAtom.isProtein() && !a.isProtein() @@ -857,10 +869,6 @@ if (!isOK) break; } - // # <n> or Symbol Check atomic number - if (patternAtom.elementNumber >= 0 - && patternAtom.elementNumber != atom.getElementNumber()) - break; } else { if (patternAtom.atomName != null @@ -868,19 +876,10 @@ break; // "=" <n> Jmol index - if (patternAtom.jmolIndex >= 0 - && atom.getIndex() != patternAtom.jmolIndex) - break; - if (patternAtom.atomType != null && !patternAtom.atomType.equals(atom.getAtomType())) break; - // # <n> or Symbol Check atomic number - if (patternAtom.elementNumber >= 0 - && patternAtom.elementNumber != atom.getElementNumber()) - break; - // Check aromatic boolean isAromatic = patternAtom.isAromatic(); if (!noAromatic && !patternAtom.aromaticAmbiguous @@ -1206,7 +1205,7 @@ getX(sAtom, jn, 1, true, false); if (jn[3] == null) getX(sAtom2, jn, 3, true, false); - if (!checkStereochemistryAll(sAtom.not, atom0, chiralClass, order, + if (!checkStereochemistryAll(sAtom.not != invertStereochemistry, atom0, chiralClass, order, jn[0], jn[1], jn[2], jn[3], null, null, v)) return false; continue; @@ -1247,7 +1246,7 @@ && !setSmilesCoordinates(atom0, sAtom, sAtom2, new Node[] { atom1, atom2, atom3, atom4, atom5, atom6 })) return false; - if (!checkStereochemistryAll(sAtom.not, atom0, chiralClass, order, + if (!checkStereochemistryAll(sAtom.not != invertStereochemistry, atom0, chiralClass, order, atom1, atom2, atom3, atom4, atom5, atom6, v)) return false; continue; Modified: trunk/Jmol/src/org/jmol/util/Edge.java =================================================================== --- trunk/Jmol/src/org/jmol/util/Edge.java 2015-08-23 21:34:50 UTC (rev 20730) +++ trunk/Jmol/src/org/jmol/util/Edge.java 2015-08-24 09:20:06 UTC (rev 20731) @@ -104,9 +104,10 @@ public int index = -1; public int order; - final public static int FLAG_AROMATIC_DOUBLE = 16; - final public static int FLAG_AROMATIC_DEFINED = 8; - final public static int FLAG_AROMATIC_STRICT = 4; + 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; Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-08-23 21:34:50 UTC (rev 20730) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-08-24 09:20:06 UTC (rev 20731) @@ -56,8 +56,13 @@ appear at a different location. An interesting challenge to figure out the algorithm that still places it in the "proper" place even when perspective is on. (Daniele Tomerini) -Jmol.___JmolVersion="14.3.16_2015.08.23" +Jmol.___JmolVersion="14.3.16_2015.08.24" +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 @@ -81,7 +86,10 @@ // +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) 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