/* $RCSfile: $ * $Author$ * $Date$ * $Revision$ * * Copyright (C) 2006-2007 Todd Martin (Environmental Protection Agency) * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.openscience.cdk.tools; import java.util.List; import org.openscience.cdk.CDKConstants; import org.openscience.cdk.aromaticity.CDKHueckelAromaticityDetector; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IBond; import org.openscience.cdk.interfaces.IMolecule; import org.openscience.cdk.interfaces.IRing; import org.openscience.cdk.interfaces.IRingSet; import org.openscience.cdk.ringsearch.AllRingsFinder; import org.openscience.cdk.tools.manipulator.AtomContainerManipulator; import org.openscience.cdk.tools.manipulator.RingSetManipulator; /** * Utility class written by Todd Martin, for help in his QSAR descriptors and SMILES * parser. Seems to have overlap with, at least, cdk.tools.Normalizer. * * <p>TODO: merge with Normalizer. * * @author Todd Martin * @cdk.module extra * @cdk.githash * * @see org.openscience.cdk.tools.Normalizer */ public class CDKUtilities { public static String fixSmiles(String Smiles) { Smiles=Smiles.replaceAll("CL","Cl"); Smiles=Smiles.replaceAll("(H)","([H])"); // Smiles=Smiles.replace("N=N#N","N=[N+]=[N-]"); // Smiles=Smiles.replace("#N=O","#[N+][O-]"); Smiles=Smiles.trim(); return Smiles; } private static boolean fixNitroGroups(IMolecule m) { // changes nitros given by N(=O)(=O) to [N+](=O)[O-] boolean changed=false; try { for (int i=0;i<=m.getAtomCount()-1;i++) { IAtom a=m.getAtom(i); boolean nitro=false; if (a.getSymbol().equals("N")) { List ca=m.getConnectedAtomsList(a); if (ca.size()==3) { IAtom [] cao= new IAtom[2]; int count=0; for (int j=0;j<=2;j++) { if (((IAtom)ca.get(j)).getSymbol().equals("O")) { count++; } } if (count>1) { count=0; for (int j=0;j<=2;j++) { IAtom caj = (IAtom)ca.get(j); if (caj.getSymbol().equals("O")) { if (m.getConnectedAtomsCount(caj)==1) {// account for possibility of ONO2 cao[count]=caj; count++; } } } IBond.Order order1 = m.getBond(a,cao[0]).getOrder(); IBond.Order order2 = m.getBond(a,cao[1]).getOrder(); //if (totalobonds==4) { // need to fix (FIXME) if (order1 == IBond.Order.SINGLE && order2 == IBond.Order.DOUBLE) { a.setFormalCharge(1); cao[0].setFormalCharge(-1); // pick first O arbitrarily m.getBond(a,cao[0]).setOrder(IBond.Order.SINGLE); changed=true; } } //else if (count==1) {// end if count>1 }// end ca==3 if } // end symbol == N } return changed; } catch (Exception e) { return changed; } } public static boolean fixNitroGroups2(IMolecule m) { // changes nitros given by [N+](=O)[O-] to N(=O)(=O) boolean changed=false; try { for (int i=0;i<=m.getAtomCount()-1;i++) { IAtom a=m.getAtom(i); boolean nitro=false; if (a.getSymbol().equals("N")) { List ca=m.getConnectedAtomsList(a); if (ca.size()==3) { IAtom [] cao=new IAtom[2]; int count=0; for (int j=0;j<=2;j++) { IAtom caj = (IAtom)ca.get(j); if (caj.getSymbol().equals("O")) { count++; } } if (count>1) { count=0; for (int j=0;j<=2;j++) { IAtom caj = (IAtom)ca.get(j); if (caj.getSymbol().equals("O")) { if (m.getConnectedAtomsCount(caj) == 1) {// account for possibility of ONO2 cao[count]=caj; count++; } } } IBond.Order order1 = m.getBond(a,cao[0]).getOrder(); IBond.Order order2 = m.getBond(a,cao[1]).getOrder(); //int totalobonds=0; //totalobonds+=m.getBond(a,cao[0]).getOrder(); // totalobonds+=m.getBond(a,cao[1]).getOrder(); //if (totalobonds==4) { // need to fix if ((order1 == IBond.Order.SINGLE && order2 == IBond.Order.DOUBLE) || (order1 == IBond.Order.DOUBLE && order2 == IBond.Order.SINGLE) ) { a.setFormalCharge(0); cao[0].setFormalCharge(0); // pick first O arbitrarily cao[1].setFormalCharge(0); // pick first O arbitrarily m.getBond(a,cao[0]).setOrder(IBond.Order.DOUBLE); m.getBond(a,cao[1]).setOrder(IBond.Order.DOUBLE); changed=true; } } // end if count>1 }// end ca==3 if } // end symbol == N } return changed; } catch (Exception e) { return changed; } } public static void fixAromaticityForXLogP(IMolecule m) { // need to find rings and aromaticity again since added H's IRingSet rs=null; try { AllRingsFinder arf = new AllRingsFinder(); rs = arf.findAllRings(m); // SSSRFinder s = new SSSRFinder(m); // srs = s.findEssentialRings(); } catch (Exception e) { e.printStackTrace(); } try { // figure out which atoms are in aromatic rings: AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(m); CDKHueckelAromaticityDetector.detectAromaticity(m); // figure out which rings are aromatic: RingSetManipulator.markAromaticRings(rs); // figure out which simple (non cycles) rings are aromatic: // HueckelAromaticityDetector.detectAromaticity(m, srs); } catch (Exception e) { e.printStackTrace(); } // only atoms in 6 membered rings are aromatic // determine largest ring that each atom is a part of for (int i=0;i<=m.getAtomCount()-1;i++) { m.getAtom(i).setFlag(CDKConstants.ISAROMATIC,false); jloop: for (int j=0;j<=rs.getAtomContainerCount()-1;j++) { //logger.debug(i+"\t"+j); IRing r=(IRing)rs.getAtomContainer(j); if (!r.getFlag(CDKConstants.ISAROMATIC)) { continue jloop; } boolean haveatom=r.contains(m.getAtom(i)); //logger.debug("haveatom="+haveatom); if (haveatom && r.getAtomCount()==6) { m.getAtom(i).setFlag(CDKConstants.ISAROMATIC,true); } } } } public static void fixSulphurH(IMolecule m) { // removes extra H's attached to sulphurs //logger.debug("EnterFixSulphur"); for (int i = 0; i <= m.getAtomCount()-1; i++) { IAtom a=m.getAtom(i); if (a.getSymbol().equals("S")) { List connectedAtoms=m.getConnectedAtomsList(a); int bondOrderSum=0; double oldBondOrderSum = m.getBondOrderSum(a); // includes H's for (int j=0;j<connectedAtoms.size();j++) { IAtom conAtom = (IAtom)connectedAtoms.get(j); if (!conAtom.getSymbol().equals("H")) { IBond bond = m.getBond(a,conAtom); if (bond.getOrder() == IBond.Order.SINGLE) { bondOrderSum += 1; } else if (bond.getOrder() == IBond.Order.DOUBLE) { bondOrderSum += 2; } else if (bond.getOrder() == IBond.Order.TRIPLE) { bondOrderSum += 3; } else if (bond.getOrder() == IBond.Order.QUADRUPLE) { bondOrderSum += 4; } } } if (bondOrderSum>1) { for (int j=0;j<connectedAtoms.size();j++) { IAtom conAtom = (IAtom)connectedAtoms.get(j); if (conAtom.getSymbol().equals("H")) { m.removeAtomAndConnectedElectronContainers(conAtom); } } } } } } }