/* $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);
}
}
}
}
}
}
}