/* $RCSfile$ * $Author$ * $Date$ * $Revision$ * * Copyright (C) 2005-2007 Christian Hoppe <chhoppe@users.sf.net> * * 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 org.openscience.cdk.CDKConstants; import org.openscience.cdk.aromaticity.CDKHueckelAromaticityDetector; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IMolecule; import org.openscience.cdk.interfaces.IRing; import org.openscience.cdk.interfaces.IRingSet; import org.openscience.cdk.ringsearch.SSSRFinder; import org.openscience.cdk.smiles.SmilesGenerator; import org.openscience.cdk.tools.manipulator.RingSetManipulator; /** * AtomTypeTools is a helper class for assigning atom types to an atom. * * @author cho * @cdk.created 2005-18-07 * @cdk.module extra * @cdk.githash */ public class AtomTypeTools { private static ILoggingTool logger = LoggingToolFactory.createLoggingTool(AtomTypeTools.class); HOSECodeGenerator hcg=null; SmilesGenerator sg=null; /** * Constructor for the MMFF94AtomTypeMatcher object. */ public AtomTypeTools() { hcg = new HOSECodeGenerator(); } public IRingSet assignAtomTypePropertiesToAtom(IMolecule molecule) throws Exception{ return assignAtomTypePropertiesToAtom(molecule, true); } /** * Method assigns certain properties to an atom. Necessary for the atom type matching * Properties: * <ul> * <li>aromaticity) * <li>ChemicalGroup (CDKChemicalRingGroupConstant) * <li>SSSR * <li>Ring/Group, ringSize, aromaticity * <li>SphericalMatcher (HoSe Code) * </ul> * *@param aromaticity booelan true/false true if aromaticity should be calculated *@return sssrf ringSetofTheMolecule *@exception Exception Description of the Exception */ public IRingSet assignAtomTypePropertiesToAtom(IMolecule molecule, boolean aromaticity) throws Exception{ SmilesGenerator sg = new SmilesGenerator(); //logger.debug("assignAtomTypePropertiesToAtom Start ..."); logger.debug("assignAtomTypePropertiesToAtom Start ..."); String hoseCode = ""; IRingSet ringSetA = null; IRingSet ringSetMolecule = new SSSRFinder(molecule).findSSSR(); logger.debug(ringSetMolecule); if (aromaticity){ try { CDKHueckelAromaticityDetector.detectAromaticity(molecule); } catch (Exception cdk1) { //logger.debug("AROMATICITYError: Cannot determine aromaticity due to: " + cdk1.toString()); logger.error("AROMATICITYError: Cannot determine aromaticity due to: " + cdk1.toString()); } } for (int i = 0; i < molecule.getAtomCount(); i++) { // FIXME: remove casting org.openscience.cdk.Atom atom2 = (org.openscience.cdk.Atom)molecule.getAtom(i); //Atom aromatic is set by HueckelAromaticityDetector //Atom in ring? if (ringSetMolecule.contains((org.openscience.cdk.interfaces.IAtom)atom2)) { ringSetA = ringSetMolecule.getRings(atom2); RingSetManipulator.sort(ringSetA); IRing sring = (IRing) ringSetA.getAtomContainer(ringSetA.getAtomContainerCount()-1); atom2.setProperty(CDKConstants.PART_OF_RING_OF_SIZE, Integer.valueOf(sring.getRingSize())); atom2.setProperty(CDKConstants.CHEMICAL_GROUP_CONSTANT, Integer.valueOf(ringSystemClassifier( sring, sg.createSMILES(atom2.getBuilder().newMolecule(sring))) )); atom2.setFlag(CDKConstants.ISINRING, true); atom2.setFlag(CDKConstants.ISALIPHATIC, false); }else{ atom2.setProperty(CDKConstants.CHEMICAL_GROUP_CONSTANT, Integer.valueOf(CDKConstants.ISNOTINRING) ); atom2.setFlag(CDKConstants.ISINRING, false); atom2.setFlag(CDKConstants.ISALIPHATIC,true); } try { hoseCode = hcg.getHOSECode(molecule, atom2, 3); hoseCode=removeAromaticityFlagsFromHoseCode(hoseCode); atom2.setProperty(CDKConstants.SPHERICAL_MATCHER, hoseCode); } catch (CDKException ex1) { throw new CDKException("Could not build HOSECode from atom "+ i + " due to " + ex1.toString(), ex1); } } return ringSetMolecule; } /** * Identifies ringSystem and returns a number which corresponds to * CDKChemicalRingConstant * *@param ring Ring class with the ring system *@param smile smile of the ring system *@return chemicalRingConstant */ private int ringSystemClassifier(IRing ring, String smile) { /*System.out.println("IN AtomTypeTools Smile:"+smile);*/ logger.debug("Comparing ring systems: SMILES=", smile); if (smile.equals("c1ccnc1"))return 4; else if (smile.equals("c1ccoc1"))return 6; else if (smile.equals("c1ccsc1"))return 8; else if (smile.equals("c1ccncc1"))return 10; else if (smile.equals("c1cncnc1"))return 12; else if (smile.equals("c1ccccc1"))return 5; int ncount=0; for (int i=0; i<ring.getAtomCount();i++){ if (ring.getAtom(i).getSymbol().equals("N")){ ncount=ncount+1; } } if (ring.getAtomCount()==6 & ncount==1){ return 10; }else if (ring.getAtomCount()==5 & ncount==1){ return 4; } if (ncount==0){ return 3; }else{ return 0; } } private String removeAromaticityFlagsFromHoseCode(String hoseCode){ String hosecode=""; for (int i=0;i<hoseCode.length();i++){ if (hoseCode.charAt(i)!= '*'){ hosecode=hosecode+hoseCode.charAt(i); } } return hosecode; } }