/* $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.atomtype; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openscience.cdk.CDKConstants; import org.openscience.cdk.PseudoAtom; import org.openscience.cdk.annotations.TestMethod; import org.openscience.cdk.config.AtomTypeFactory; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IAtomType; import org.openscience.cdk.interfaces.IBond; import org.openscience.cdk.tools.AtomTypeTools; import org.openscience.cdk.tools.ILoggingTool; import org.openscience.cdk.tools.LoggingToolFactory; /** * Class implements methods to assign mmff94 atom types for a specific atom in an molecule. * * @author cho * @cdk.created 2005-18-07 * @cdk.module extra * @cdk.githash */ public class MM2AtomTypeMatcher implements IAtomTypeMatcher { private static ILoggingTool logger = LoggingToolFactory.createLoggingTool(MM2AtomTypeMatcher.class); IBond.Order maxBondOrder = IBond.Order.SINGLE; private AtomTypeFactory factory = null; AtomTypeTools atomTypeTools=null; String [] atomTypeIds={"C","Csp2","C=","Csp","HC","O","O=","N","Nsp2","Nsp", "F","CL","BR","I","S","S+",">SN","SO2","Sthi","SI","LP","HO", "CR3R","HN","HOCO","P","B","BTET","HN2","C.","C+","GE", "SN","PB","SE","TE","D","-N=","CE3R","N+","NPYL","Oar", "Sthi","N2OX","HS","=N=","NO2","OM","HN+","OR","Car","HE", "NE","AR","KR","XE","MG+2","PTET","FE+2","FE+3","NI+2","NI+3","CO+2","CO+3", "OX","OK","C++","N=C","NPD+","N+=","N2OX" }; /** * Constructor for the MMFF94AtomTypeMatcher object. */ public MM2AtomTypeMatcher() { atomTypeTools=new AtomTypeTools(); } private String getSphericalMatcher(IAtomType type) throws CDKException {//NOPMD return (String)type.getProperty(CDKConstants.SPHERICAL_MATCHER); } private String getSphericalMatcher(String type) throws CDKException {//NOPMD return getSphericalMatcher(factory.getAtomType(type)); } @TestMethod("testFindMatchingAtomType_IAtomContainer") public IAtomType[] findMatchingAtomType(IAtomContainer atomContainer) throws CDKException { IAtomType[] types = new IAtomType[atomContainer.getAtomCount()]; int typeCounter = 0; for (IAtom atom : atomContainer.atoms()) { types[typeCounter] = findMatchingAtomType(atomContainer, atom); typeCounter++; } return types; } /** * Assign the mm2 atom type to a given atom. * Before this method can be called the following has to be done: * <pre> * atomContainer = (AtomContainer)atomTypeTools.assignAtomTypePropertiesToAtom( * new Molecule(atomContainer) * ); * </pre> * * @param atomContainer AtomContainer * @param atomInterface the target atom * @exception CDKException Description of the Exception * @return the matching AtomType (AtomType class) */ public IAtomType findMatchingAtomType(IAtomContainer atomContainer, IAtom atomInterface) throws CDKException { if (factory == null) { try { factory = AtomTypeFactory.getInstance("org/openscience/cdk/config/data/mm2_atomtypes.xml", atomContainer.getBuilder()); } catch (Exception ex1) { logger.error("Could not instantiate the AtomType list!", ex1.getMessage()); logger.debug(ex1); throw new CDKException("Could not instantiate the AtomType list!", ex1); } } org.openscience.cdk.Atom atom = (org.openscience.cdk.Atom)atomInterface; logger.debug("****** Configure MM2 AtomType via findMatching ******"); String atomSphericalMatcher = (String)atom.getProperty(CDKConstants.SPHERICAL_MATCHER); int atomChemicalGroupConstant = (Integer) atom.getProperty(CDKConstants.CHEMICAL_GROUP_CONSTANT); int atomRingSize = 0; // not all atom types have ring sizes define; 0 is default Object oRingSize = atom.getProperty(CDKConstants.PART_OF_RING_OF_SIZE); if (oRingSize != null) { atomRingSize = (Integer) oRingSize; } logger.debug(" Symbol:" + atom.getSymbol() +" HoseCode>" + atomSphericalMatcher + " "); if (atom instanceof PseudoAtom) { return factory.getAtomTypes("DU")[0]; } Pattern p1 = null; String ID = ""; boolean atomTypeFlag = false; Matcher mat1=null; IBond.Order tmpMaxBondOrder = IBond.Order.SINGLE; maxBondOrder = atomContainer.getMaximumBondOrder(atom); logger.debug("Atom maxBond"+maxBondOrder+" ChemicalGroupConstant "+atomChemicalGroupConstant); for (int j = 0; j < atomTypeIds.length; j++){ tmpMaxBondOrder = factory.getAtomType(atomTypeIds[j]).getMaxBondOrder(); logger.debug(j + "ATOM TYPE "+ tmpMaxBondOrder + " " +getSphericalMatcher(atomTypeIds[j])); p1 =Pattern.compile(getSphericalMatcher(atomTypeIds[j])); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID = atomTypeIds[j]; if (atomTypeIds[j].equals("C")) { if (atomChemicalGroupConstant!=-1) { if (atomRingSize==3) { ID="CR3R"; }else if (atomChemicalGroupConstant==5){ ID="Car"; }else if (maxBondOrder != IBond.Order.SINGLE) { ID="Csp2"; } } if (atom.getSymbol().equals("S")){ if (atomChemicalGroupConstant==8){ ID="Sthi"; }else{ p1 = Pattern.compile(getSphericalMatcher("S")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="S"; } } } } else if (atomTypeIds[j].equals("Csp2")) { if (atomChemicalGroupConstant!=-1) { if (atomChemicalGroupConstant==5) { ID="Car"; }else if (atomRingSize==3) { ID="CE3R"; } } p1 = Pattern.compile(getSphericalMatcher("C=")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="C="; } } else if (atomTypeIds[j].equals("O")) { //OH/Ether if (atomChemicalGroupConstant!=-1) { if (atomChemicalGroupConstant==6){ ID="Oar";//furan }else if (atomRingSize==3) { ID="OR";//epoxy } } p1 = Pattern.compile(getSphericalMatcher("OX")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches() & atomChemicalGroupConstant==-1) { ID="OX"; } } else if (atomTypeIds[j].equals("N")) {//n sp3 if (atomContainer.getMaximumBondOrder(atom) == IBond.Order.DOUBLE){ ID="Nsp2"; } if (atomChemicalGroupConstant==4) { ID="NPYL";//Pyrole }else if (atomChemicalGroupConstant==10){ ID="-N="; p1 = Pattern.compile(getSphericalMatcher("NPD+")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="NPD+"; } }else{ //Amid p1 = Pattern.compile(getSphericalMatcher("Namid")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches() & atomChemicalGroupConstant==-1) { ID="Nsp2"; }else{ p1 = Pattern.compile(getSphericalMatcher("N2OX")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches() & atomChemicalGroupConstant==-1) { ID="N2OX"; } } } } else if (atomTypeIds[j].equals("Nsp2")) { if (atomChemicalGroupConstant==12) { ID="=N-";//Pyridin } //Azo p1 = Pattern.compile(getSphericalMatcher("-N=")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches() & atomChemicalGroupConstant==-1) { ID="-N="; }else{ p1 = Pattern.compile(getSphericalMatcher("N=C")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="N=C"; } p1 = Pattern.compile(getSphericalMatcher("N2OX")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="N2OX"; } p1 = Pattern.compile(getSphericalMatcher("NO2")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="NO2"; } p1 = Pattern.compile(getSphericalMatcher("=N=")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="=N="; } } } else if (atomTypeIds[j].equals("HS")) { if (atom.getMaxBondOrder() != null && atom.getMaxBondOrder() != IBond.Order.SINGLE) { ID="HC"; } } else if (atomTypeIds[j].equals("HO")) { //Enol,amid p1 = Pattern.compile(getSphericalMatcher("HOC")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches() & atomChemicalGroupConstant==-1) { ID="HN2"; } //COOH p1 = Pattern.compile(getSphericalMatcher("HOCO")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches() & atomChemicalGroupConstant==-1) { ID="HOCO"; } } else if (atomTypeIds[j].equals("HN")) { p1 = Pattern.compile(getSphericalMatcher("HN2")); mat1 = p1.matcher(atomSphericalMatcher); if (mat1.matches()) { ID="HN2"; } } atomTypeFlag = true; logger.debug(" MATCH AtomTypeID:"+j+ " " + ID); break; }//IF }//for end if (atomTypeFlag) { atomTypeFlag = false; logger.debug("ID in factory true:"+ID); return factory.getAtomType(ID); } else { logger.debug("NoSuchAtomTypeException: Atom is unkown with Symbol:" + atom.getSymbol() + " does not MATCH AtomType. HoseCode:" + atomSphericalMatcher); logger.debug("ID in factory false:"+ID); return factory.getAtomType("DU"); } } }