?? saturationchecker.java
字號:
/* $RCSfile$ * $Author: egonw $ * $Date: 2007-03-14 18:33:52 +0100 (Wed, 14 Mar 2007) $ * $Revision: 8121 $ * * Copyright (C) 2001-2007 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.tools;import java.io.IOException;import java.util.Iterator;import java.util.List;import org.openscience.cdk.CDKConstants;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.interfaces.IChemObjectBuilder;import org.openscience.cdk.interfaces.IPseudoAtom;import org.openscience.cdk.interfaces.IRingSet;import org.openscience.cdk.ringsearch.RingPartitioner;import org.openscience.cdk.ringsearch.SSSRFinder;import org.openscience.cdk.tools.manipulator.BondManipulator;import org.openscience.cdk.tools.manipulator.RingSetManipulator;/** * Provides methods for checking whether an atoms valences are saturated with * respect to a particular atom type. * * <p>Important: this class does not deal with hybridization states, which makes * it fail, for example, for situations where bonds are marked as aromatic (either * 1.5 or single an AROMATIC). * * @author steinbeck * @author Egon Willighagen * @cdk.created 2001-09-04 * * @cdk.keyword saturation * @cdk.keyword atom, valency * * @cdk.module valencycheck */public class SaturationChecker implements IValencyChecker, IDeduceBondOrderTool { AtomTypeFactory structgenATF; private LoggingTool logger; public SaturationChecker() throws IOException, ClassNotFoundException { logger = new LoggingTool(this); } /** * @param builder the ChemObjectBuilder implementation used to construct the AtomType's. */ protected AtomTypeFactory getAtomTypeFactory(IChemObjectBuilder builder) throws CDKException { if (structgenATF == null) { try { structgenATF = AtomTypeFactory.getInstance( "org/openscience/cdk/config/data/structgen_atomtypes.xml", builder ); } catch (Exception exception) { logger.debug(exception); throw new CDKException("Could not instantiate AtomTypeFactory!", exception); } } return structgenATF; } public boolean hasPerfectConfiguration(IAtom atom, IAtomContainer ac) throws CDKException { double bondOrderSum = ac.getBondOrderSum(atom); double maxBondOrder = ac.getMaximumBondOrder(atom); IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol()); if(atomTypes.length==0) return true; logger.debug("*** Checking for perfect configuration ***"); try { logger.debug("Checking configuration of atom " + ac.getAtomNumber(atom)); logger.debug("Atom has bondOrderSum = " + bondOrderSum); logger.debug("Atom has max = " + bondOrderSum); } catch (Exception exc) { } for (int f = 0; f < atomTypes.length; f++) { if (bondOrderSum == atomTypes[f].getBondOrderSum() && maxBondOrder == atomTypes[f].getMaxBondOrder()) { try { logger.debug("Atom " + ac.getAtomNumber(atom) + " has perfect configuration"); } catch (Exception exc) { } return true; } } try { logger.debug("*** Atom " + ac.getAtomNumber(atom) + " has imperfect configuration ***"); } catch (Exception exc) { } return false; } /** * Determines of all atoms on the AtomContainer are saturated. */ public boolean isSaturated(IAtomContainer container) throws CDKException { return allSaturated(container); } public boolean allSaturated(IAtomContainer ac) throws CDKException { logger.debug("Are all atoms saturated?"); for (int f = 0; f < ac.getAtomCount(); f++) { if (!isSaturated(ac.getAtom(f), ac)) { return false; } } return true; } /** * Returns wether a bond is unsaturated. A bond is unsaturated if * <b>both</b> Atoms in the bond are unsaturated. */ public boolean isUnsaturated(IBond bond, IAtomContainer atomContainer) throws CDKException { IAtom[] atoms = BondManipulator.getAtomArray(bond); boolean isUnsaturated = true; for (int i=0; i<atoms.length; i++) { isUnsaturated = isUnsaturated && !isSaturated(atoms[i], atomContainer); } return isUnsaturated; } /** * Returns wether a bond is saturated. A bond is saturated if * <b>both</b> Atoms in the bond are saturated. */ public boolean isSaturated(IBond bond, IAtomContainer atomContainer) throws CDKException { IAtom[] atoms = BondManipulator.getAtomArray(bond); boolean isSaturated = true; for (int i=0; i<atoms.length; i++) { isSaturated = isSaturated && isSaturated(atoms[i], atomContainer); } return isSaturated; } /** * Checks wether an Atom is saturated by comparing it with known AtomTypes. */ IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol()); if(atomTypes.length==0) return true; double bondOrderSum = ac.getBondOrderSum(atom); double maxBondOrder = ac.getMaximumBondOrder(atom); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); try { logger.debug("*** Checking saturation of atom ", atom.getSymbol(), "" + ac.getAtomNumber(atom) + " ***"); logger.debug("bondOrderSum: " + bondOrderSum); logger.debug("maxBondOrder: " + maxBondOrder); logger.debug("hcount: " + hcount); } catch (Exception exc) { logger.debug(exc); } for (int f = 0; f < atomTypes.length; f++) { if (bondOrderSum - charge + hcount == atomTypes[f].getBondOrderSum() && maxBondOrder <= atomTypes[f].getMaxBondOrder()) { logger.debug("*** Good ! ***"); return true; } } logger.debug("*** Bad ! ***"); return false; } /** * Checks if the current atom has exceeded its bond order sum value. * * @param atom The Atom to check * @param ac The atomcontainer context * @return oversaturated or not */ public boolean isOverSaturated(IAtom atom, IAtomContainer ac) throws CDKException { IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol()); if(atomTypes.length==0) return false; double bondOrderSum = ac.getBondOrderSum(atom); double maxBondOrder = ac.getMaximumBondOrder(atom); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); try { logger.debug("*** Checking saturation of atom " + ac.getAtomNumber(atom) + " ***"); logger.debug("bondOrderSum: " + bondOrderSum); logger.debug("maxBondOrder: " + maxBondOrder); logger.debug("hcount: " + hcount); } catch (Exception exc) { } for (int f = 0; f < atomTypes.length; f++) { if (bondOrderSum - charge + hcount > atomTypes[f].getBondOrderSum()) { logger.debug("*** Good ! ***"); return true; } } logger.debug("*** Bad ! ***"); return false; } /** * Returns the currently maximum formable bond order for this atom. * * @param atom The atom to be checked * @param ac The AtomContainer that provides the context * @return the currently maximum formable bond order for this atom */ public double getCurrentMaxBondOrder(IAtom atom, IAtomContainer ac) throws CDKException { IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol()); if(atomTypes.length==0) return 0; double bondOrderSum = ac.getBondOrderSum(atom); int hcount = atom.getHydrogenCount(); double max = 0; double current = 0; for (int f = 0; f < atomTypes.length; f++) { current = hcount + bondOrderSum; if (atomTypes[f].getBondOrderSum() - current > max) { max = atomTypes[f].getBondOrderSum() - current; } } return max; } /** * Resets the bond orders of all atoms to 1.0. */ public void unsaturate(IAtomContainer atomContainer) { Iterator bonds = atomContainer.bonds(); while (bonds.hasNext()) { ((IBond)bonds.next()).setOrder(CDKConstants.BONDORDER_SINGLE); } } /** * Resets the bond order of the Bond to 1.0. */ public void unsaturateBonds(IAtomContainer container) { Iterator bonds = container.bonds(); while (bonds.hasNext()) ((IBond)bonds.next()).setOrder(1.0); } /** * Saturates a molecule by setting appropriate bond orders. * This method is known to fail, especially on pyrolle-like compounts. * Consider using import org.openscience.cdk.smiles.DeduceBondSystemTool, which should work better * * @cdk.keyword bond order, calculation * @cdk.created 2003-10-03 */ public void newSaturate(IAtomContainer atomContainer) throws CDKException { logger.info("Saturating atomContainer by adjusting bond orders..."); boolean allSaturated = allSaturated(atomContainer); if (!allSaturated) { IBond[] bonds = new IBond[atomContainer.getBondCount()]; for (int i=0; i<bonds.length; i++) bonds[i] = atomContainer.getBond(i); boolean succeeded = newSaturate(bonds, atomContainer); for(int i=0;i<bonds.length;i++){ if(bonds[i].getOrder()==2 && bonds[i].getFlag(CDKConstants.ISAROMATIC) && (bonds[i].getAtom(0).getSymbol().equals("N") && bonds[i].getAtom(1).getSymbol().equals("N"))){ int atomtohandle=0; if(bonds[i].getAtom(0).getSymbol().equals("N")) atomtohandle=1; java.util.List bondstohandle=atomContainer.getConnectedBondsList(bonds[i].getAtom(atomtohandle)); for(int k=0;k<bondstohandle.size();k++){ IBond bond = (IBond)bondstohandle.get(k); if(bond.getOrder()==1 && bond.getFlag(CDKConstants.ISAROMATIC)){ bond.setOrder(2); bonds[i].setOrder(1); break; } } } } if (!succeeded) { throw new CDKException("Could not saturate this atomContainer!"); } } } /** * Saturates a set of Bonds in an AtomContainer. * This method is known to fail, especially on pyrolle-like compounts. * Consider using import org.openscience.cdk.smiles.DeduceBondSystemTool, which should work better */ public boolean newSaturate(IBond[] bonds, IAtomContainer atomContainer) throws CDKException { logger.debug("Saturating bond set of size: " + bonds.length); boolean bondsAreFullySaturated = true; if (bonds.length > 0) { IBond bond = bonds[0]; // determine bonds left int leftBondCount = bonds.length-1; IBond[] leftBonds = new IBond[leftBondCount]; System.arraycopy(bonds, 1, leftBonds, 0, leftBondCount); // examine this bond if (isUnsaturated(bond, atomContainer)) { // either this bonds should be saturated or not
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -