/* Copyright (C) 2004-2010 The Chemistry Development Kit (CDK) project * * 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. * All we ask is that proper credit is given for our work, which includes * - but is not limited to - adding the above copyright notice to the beginning * of your source code files, and to any copyright notice that you may distribute * with programs based on this work. * * 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.normalize; import java.util.Iterator; import java.util.List; import org.openscience.cdk.DefaultChemObjectBuilder; import org.openscience.cdk.annotations.TestClass; import org.openscience.cdk.annotations.TestMethod; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.exception.InvalidSmilesException; import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IBond; import org.openscience.cdk.isomorphism.UniversalIsomorphismTester; import org.openscience.cdk.isomorphism.mcss.RMap; import org.openscience.cdk.smiles.SmilesParser; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * Adjusts parts of an AtomContainer to the congiguratin of a fragment. * * @author shk3 * @cdk.created 2004-03-04 * @cdk.module smiles * @cdk.githash */ @TestClass("org.openscience.cdk.tools.NormalizerTest") public class Normalizer { /** * The method takes an xml files like the following:<br> * <replace-set><br> * <replace>O=N=O</replace><br> * <replacement>[O-][N+]=O</replacement><br> * </replace-set><br> * All parts in ac which are the same as replace will be changed according to replacement. * Currently the following changes are done: BondOrder, FormalCharge. * For detection of fragments like replace, we rely on UniversalIsomorphismTester. * doc may contain several replace-sets and a replace-set may contain several replace fragments, which will all be normalized according to replacement. * * @param ac The atomcontainer to normalize. * @param doc The configuration file. * @return Did a replacement take place? * @exception InvalidSmilesException doc contains an invalid smiles. */ @TestMethod("testNormalize") public static boolean normalize(IAtomContainer ac, Document doc) throws InvalidSmilesException, CDKException { NodeList nl = doc.getElementsByTagName("replace-set"); SmilesParser sp = new SmilesParser(DefaultChemObjectBuilder.getInstance()); boolean change=false; for (int i = 0; i < nl.getLength(); i++) { Element child = (Element) nl.item(i); NodeList replaces = child.getElementsByTagName("replace"); NodeList replacement = child.getElementsByTagName("replacement"); String replacementstring = replacement.item(0).getFirstChild().getNodeValue(); if (replacementstring.indexOf("\n") > -1 || replacementstring.length() < 1) { replacementstring = replacement.item(0).getFirstChild().getNextSibling().getNodeValue(); } IAtomContainer replacementStructure = sp.parseSmiles(replacementstring); for (int k = 0; k < replaces.getLength(); k++) { Element replace = (Element) replaces.item(k); String replacestring = replace.getFirstChild().getNodeValue(); if (replacestring.indexOf("\n") > -1 || replacestring.length() < 1) { replacestring = replace.getFirstChild().getNextSibling().getNodeValue(); } IAtomContainer replaceStructure = sp.parseSmiles(replacestring); List l = null; while ((l = UniversalIsomorphismTester.getSubgraphMap(ac, replaceStructure)) != null) { List l2 = UniversalIsomorphismTester.makeAtomsMapOfBondsMap(l, ac, replaceStructure); Iterator bondit = l.iterator(); while (bondit.hasNext()) { RMap rmap = (RMap) bondit.next(); IBond acbond = ac.getBond(rmap.getId1()); IBond replacebond = replacementStructure.getBond(rmap.getId2()); acbond.setOrder(replacebond.getOrder()); change=true; } Iterator atomit = l2.iterator(); while (atomit.hasNext()) { RMap rmap = (RMap) atomit.next(); IAtom acatom = ac.getAtom(rmap.getId1()); IAtom replaceatom = replacementStructure.getAtom(rmap.getId2()); acatom.setFormalCharge(replaceatom.getFormalCharge()); change=true; } } } } return (change); } }