📄 smilesparser.java
字号:
bondIsAromatic = true; position++; } else if (mychar == '/' || mychar == '\\') { logger.warn("Ignoring stereo information for double bond"); position++; } else if (mychar == '@') { if (position < smiles.length() - 1 && smiles.charAt(position + 1) == '@') { position++; } logger.warn("Ignoring stereo information for atom"); position++; } else { throw new InvalidSmilesException("Unexpected character found: " + mychar); } } catch (InvalidSmilesException exc) { logger.error("InvalidSmilesException while parsing char (in parseSmiles()): " + mychar); logger.debug(exc); throw exc; } catch (Exception exception) { logger.error("Error while parsing char: " + mychar); logger.debug(exception); throw new InvalidSmilesException("Error while parsing char: " + mychar, exception); } logger.debug("Parsing next char"); } while (position < smiles.length()); return molecule; } private String getAtomString(String smiles, int pos) throws InvalidSmilesException { logger.debug("getAtomString()"); StringBuffer atomString = new StringBuffer(); try { for (int f = pos + 1; f < smiles.length(); f++) { char character = smiles.charAt(f); if (character == ']') { break; } else { atomString.append(character); } } } catch (Exception exception) { String message = "Problem parsing Atom specification given in brackets.\n"; message += "Invalid SMILES string was: " + smiles; logger.error(message); logger.debug(exception); throw new InvalidSmilesException(message, exception); } return atomString.toString(); } private int getCharge(String chargeString, int position) { logger.debug("getCharge(): Parsing charge from: ", chargeString.substring(position)); int charge = 0; if (chargeString.charAt(position) == '+') { charge = +1; position++; } else if (chargeString.charAt(position) == '-') { charge = -1; position++; } else { return charge; } StringBuffer multiplier = new StringBuffer(); while (position < chargeString.length() && Character.isDigit(chargeString.charAt(position))) { multiplier.append(chargeString.charAt(position)); position++; } if (multiplier.length() > 0) { logger.debug("Found multiplier: ", multiplier); try { charge = charge * Integer.parseInt(multiplier.toString()); } catch (Exception exception) { logger.error("Could not parse positive atomic charge!"); logger.debug(exception); } } logger.debug("Found charge: ", charge); return charge; } private int getImplicitHydrogenCount(String s, int position) { logger.debug("getImplicitHydrogenCount(): Parsing implicit hydrogens from: " + s); int count = 1; if (s.charAt(position) == 'H') { StringBuffer multiplier = new StringBuffer(); while (position < (s.length() - 1) && Character.isDigit(s.charAt(position + 1))) { multiplier.append(position + 1); position++; } if (multiplier.length() > 0) { try { count = count + Integer.parseInt(multiplier.toString()); } catch (Exception exception) { logger.error("Could not parse number of implicit hydrogens!"); logger.debug(exception); } } } return count; } private String getElementSymbol(String s, int pos) { logger.debug("getElementSymbol(): Parsing element symbol (pos=" + pos + ") from: " + s); // try to match elements not in the organic subset. // first, the two char elements if (pos < s.length() - 1) { String possibleSymbol = s.substring(pos, pos + 2); logger.debug("possibleSymbol: ", possibleSymbol); if (("HeLiBeNeNaMgAlSiClArCaScTiCrMnFeCoNiCuZnGaGeAsSe".indexOf(possibleSymbol) >= 0) || ("BrKrRbSrZrNbMoTcRuRhPdAgCdInSnSbTeXeCsBaLuHfTaRe".indexOf(possibleSymbol) >= 0) || ("OsIrPtAuHgTlPbBiPoAtRnFrRaLrRfDbSgBhHsMtDs".indexOf(possibleSymbol) >= 0)) { return possibleSymbol; } } // if that fails, the one char elements String possibleSymbol = s.substring(pos, pos + 1); logger.debug("possibleSymbol: ", possibleSymbol); if (("HKUVY".indexOf(possibleSymbol) >= 0)) { return possibleSymbol; } // if that failed too, then possibly a organic subset element return getSymbolForOrganicSubsetElement(s, pos); } /** * Gets the ElementSymbol for an element in the 'organic subset' for which * brackets may be omited. <p> * * See: <a href="http://www.daylight.com/dayhtml/smiles/smiles-atoms.html"> * http://www.daylight.com/dayhtml/smiles/smiles-atoms.html</a> . */ private String getSymbolForOrganicSubsetElement(String s, int pos) { logger.debug("getSymbolForOrganicSubsetElement(): Parsing organic subset element from: ", s); if (pos < s.length() - 1) { String possibleSymbol = s.substring(pos, pos + 2); if (("ClBr".indexOf(possibleSymbol) >= 0)) { return possibleSymbol; } } if ("BCcNnOoFPSsI".indexOf((s.charAt(pos))) >= 0) { return s.substring(pos, pos + 1); } if ("fpi".indexOf((s.charAt(pos))) >= 0) { logger.warn("Element ", s, " is normally not sp2 hybridisized!"); return s.substring(pos, pos + 1); } logger.warn("Subset element not found!"); return null; } /** * Gets the RingNumber attribute of the SmilesParser object */ private String getRingNumber(String s, int pos) throws InvalidSmilesException { logger.debug("getRingNumber()"); pos++; // Two digits impossible due to end of string if (pos >= s.length() - 1) throw new InvalidSmilesException("Percent sign ring closure numbers must be two-digit."); String retString = s.substring(pos, pos + 2); if (retString.charAt(0) < '0' || retString.charAt(0) > '9' || retString.charAt(1) < '0' || retString.charAt(1) > '9') throw new InvalidSmilesException("Percent sign ring closure numbers must be two-digit."); return retString; } private IAtom assembleAtom(String s) throws InvalidSmilesException { logger.debug("assembleAtom(): Assembling atom from: ", s); IAtom atom = null; int position = 0; String currentSymbol = null; StringBuffer isotopicNumber = new StringBuffer(); char mychar; logger.debug("Parse everythings before and including element symbol"); do { try { mychar = s.charAt(position); logger.debug("Parsing char: " + mychar); if ((mychar >= 'A' && mychar <= 'Z') || (mychar >= 'a' && mychar <= 'z')) { currentSymbol = getElementSymbol(s, position); if (currentSymbol == null) { throw new InvalidSmilesException( "Expected element symbol, found null!" ); } else { logger.debug("Found element symbol: ", currentSymbol); position = position + currentSymbol.length(); if (currentSymbol.length() == 1) { if (!(currentSymbol.toUpperCase()).equals(currentSymbol)) { currentSymbol = currentSymbol.toUpperCase(); atom = builder.newAtom(currentSymbol); atom.setHybridization(CDKConstants.HYBRIDIZATION_SP2); if (atom.getHydrogenCount() > 0) { atom.setHydrogenCount(atom.getHydrogenCount() - 1); } } else { atom = builder.newAtom(currentSymbol); } } else { atom = builder.newAtom(currentSymbol); } logger.debug("Made atom: ", atom); } break; } else if (mychar >= '0' && mychar <= '9') { isotopicNumber.append(mychar); position++; } else if (mychar == '*') { currentSymbol = "*"; atom = builder.newPseudoAtom(currentSymbol); logger.debug("Made atom: ", atom); position++; break; } else { throw new InvalidSmilesException("Found unexpected char: " + mychar); } } catch (InvalidSmilesException exc) { logger.error("InvalidSmilesException while parsing atom string: " + s); logger.debug(exc); throw exc; } catch (Exception exception) { logger.error("Could not parse atom string: ", s); logger.debug(exception); throw new InvalidSmilesException("Could not parse atom string: " + s, exception); } } while (position < s.length()); if (isotopicNumber.toString().length() > 0) { try { atom.setMassNumber(Integer.parseInt(isotopicNumber.toString())); } catch (Exception exception) { logger.error("Could not set atom's atom number."); logger.debug(exception); } } logger.debug("Parsing part after element symbol (like charge): ", s.substring(position)); int charge = 0; int implicitHydrogens = 0; while (position < s.length()) { try { mychar = s.charAt(position); logger.debug("Parsing char: " + mychar); if (mychar == 'H') { // count implicit hydrogens implicitHydrogens = getImplicitHydrogenCount(s, position); position++; if (implicitHydrogens > 1) { position++; } atom.setHydrogenCount(implicitHydrogens); } else if (mychar == '+' || mychar == '-') { charge = getCharge(s, position); position++; if (charge < -1 || charge > 1) { position++; } atom.setFormalCharge(charge); } else if (mychar == '@') { if (position < s.length() - 1 && s.charAt(position + 1) == '@') { position++; } logger.warn("Ignoring stereo information for atom"); position++; } else { throw new InvalidSmilesException("Found unexpected char: " + mychar); } } catch (InvalidSmilesException exc) { logger.error("InvalidSmilesException while parsing atom string: ", s); logger.debug(exc); throw exc; } catch (Exception exception) { logger.error("Could not parse atom string: ", s); logger.debug(exception); throw new InvalidSmilesException("Could not parse atom string: " + s, exception); } } return atom; } /** * We call this method when a ring (depicted by a number) has been found. */ private void handleRing(IAtom atom) { logger.debug("handleRing():"); double bondStat = bondStatusForRingClosure; if (ringbonds[thisRing] > bondStat) bondStat = ringbonds[thisRing]; IBond bond = null; IAtom partner = null; IAtom thisNode = rings[thisRing]; // lookup if (thisNode != null) { partner = thisNode; bond = builder.newBond(atom, partner, bondStat); if (bondIsAromatic) { bond.setFlag(CDKConstants.ISAROMATIC, true); } molecule.addBond(bond); bondIsAromatic = false; rings[thisRing] = null; ringbonds[thisRing] = -1; } else { /* * First occurence of this ring: * - add current atom to list */ rings[thisRing] = atom; ringbonds[thisRing] = bondStatusForRingClosure; } bondStatusForRingClosure = 1; } private void addImplicitHydrogens(IMolecule m) { try { logger.debug("before H-adding: ", m); hAdder.addImplicitHydrogensToSatisfyValency(m); logger.debug("after H-adding: ", m); } catch (Exception exception) { logger.error("Error while calculation Hcount for SMILES atom: ", exception.getMessage()); } } private void setupMissingBondOrders(IMolecule m) { try { valencyChecker.saturate(m); logger.debug("after adding missing bond orders: ", m); } catch (Exception exception) { logger.error("Error while calculation Hcount for SMILES atom: ", exception.getMessage()); } } private void conceiveAromaticPerception(IMolecule m) { IMoleculeSet moleculeSet = ConnectivityChecker.partitionIntoMolecules(m); logger.debug("#mols ", moleculeSet.getAtomContainerCount()); for (int i = 0; i < moleculeSet.getAtomContainerCount(); i++) { IAtomContainer molecule = moleculeSet.getAtomContainer(i); logger.debug("mol: ", molecule); try { valencyChecker.saturate(molecule); logger.debug(" after saturation: ", molecule); if (HueckelAromaticityDetector .detectAromaticity(molecule)) { logger.debug("Structure is aromatic..."); } } catch (Exception exception) { logger.error("Could not perceive aromaticity: ", exception .getMessage()); logger.debug(exception); } } } public boolean isInterrupted() { return valencyChecker.isInterrupted(); } public void setInterrupted(boolean interrupted) { valencyChecker.setInterrupted(interrupted); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -