📄 valencychecker.java
字号:
/* $RCSfile$ * $Author: egonw $ * $Date: 2007-01-04 18:46:10 +0100 (Thu, 04 Jan 2007) $ * $Revision: 7636 $ * * Copyright (C) 2004-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 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.tools.manipulator.BondManipulator;/** * This class is an experimental alternative to the SaturationChecker. * The main difference is that this checker uses a different atom type * list and takes formal charges into account: it first matches against * element and charge, and then browses the list for possible matching * types. * * <p>The atoms are matched against the valency_atomtype.xml list. * * @author Egon Willighagen * @cdk.created 2004-01-07 * * @cdk.keyword atom, valency * * @cdk.module valencycheck */public class ValencyChecker implements IValencyChecker, IDeduceBondOrderTool { private String atomTypeList = null; protected AtomTypeFactory structgenATF; protected LoggingTool logger; public ValencyChecker() throws IOException, ClassNotFoundException { this("org/openscience/cdk/config/data/valency_atomtypes.xml"); } public ValencyChecker(String atomTypeList) throws IOException, ClassNotFoundException { this.atomTypeList = atomTypeList; logger = new LoggingTool(this); logger.info("Using configuration file: ", atomTypeList); } /** * @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(atomTypeList, builder); } catch (Exception exception) { logger.debug(exception); throw new CDKException("Could not instantiate AtomTypeFactory!", exception); } } return structgenATF; } /** * Checks wether an Atom is saturated by comparing it with known AtomTypes. * It returns true if the atom is an PseudoAtom and when the element is not in the list. */ public boolean isSaturated(IAtom atom, IAtomContainer container) throws CDKException { if (atom instanceof IPseudoAtom) { logger.debug("don't figure it out... it simply does not lack H's"); return true; } IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol()); if (atomTypes.length == 0) { logger.warn("Missing entry in atom type list for ", atom.getSymbol()); return true; } double bondOrderSum = container.getBondOrderSum(atom); double maxBondOrder = container.getMaximumBondOrder(atom); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); logger.debug("Checking saturation of atom ", atom.getSymbol()); logger.debug("bondOrderSum: ", bondOrderSum); logger.debug("maxBondOrder: ", maxBondOrder); logger.debug("hcount: ", hcount); logger.debug("charge: ", charge); boolean elementPlusChargeMatches = false; for (int f = 0; f < atomTypes.length; f++) { IAtomType type = atomTypes[f]; if (couldMatchAtomType(atom, bondOrderSum, maxBondOrder, type)) { if (bondOrderSum + hcount == type.getBondOrderSum() && maxBondOrder <= type.getMaxBondOrder()) { logger.debug("We have a match: ", type); logger.debug("Atom is saturated: ", atom.getSymbol()); return true; } else { // ok, the element and charge matche, but unfulfilled elementPlusChargeMatches = true; } } // else: formal charges don't match } if (elementPlusChargeMatches) { logger.debug("No, atom is not saturated."); return false; } // ok, the found atom was not in the list throw new CDKException("The atom with element " + atom.getSymbol() + " and charge " + charge + " is not found."); } /** * Determines if the atom can be of type AtomType. */ public boolean couldMatchAtomType(IAtomContainer container, IAtom atom, IAtomType type) { double bondOrderSum = container.getBondOrderSum(atom); double maxBondOrder = container.getMaximumBondOrder(atom); return couldMatchAtomType(atom, bondOrderSum, maxBondOrder, type); } /** * Determines if the atom can be of type AtomType. */ public boolean couldMatchAtomType(IAtom atom, double bondOrderSum, double maxBondOrder, IAtomType type) { logger.debug(" ... matching atom ", atom.getSymbol(), " vs ", type); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); if (charge == type.getFormalCharge()) { if (bondOrderSum + hcount <= type.getBondOrderSum() && maxBondOrder <= type.getMaxBondOrder()) { logger.debug(" We have a match!"); return true; } } logger.debug(" No Match"); return false; } /** * Calculate the number of missing hydrogens by substracting the number of * bonds for the atom from the expected number of bonds. Charges are included * in the calculation. The number of expected bonds is defined by the AtomType * generated with the AtomTypeFactory. * * @param atom Description of the Parameter * @param container Description of the Parameter * @return Description of the Return Value */ public int calculateNumberOfImplicitHydrogens(IAtom atom, IAtomContainer container) throws CDKException { return this.calculateNumberOfImplicitHydrogens(atom, container.getBondOrderSum(atom), container.getConnectedSingleElectronsCount(atom), container.getMaximumBondOrder(atom), container.getConnectedAtomsCount(atom) ); } public int calculateNumberOfImplicitHydrogens(IAtom atom) throws CDKException { return this.calculateNumberOfImplicitHydrogens(atom, 0.0, 0.0, 0.0, 0); } /** * Calculates the number of hydrogens that can be added to the given atom to fullfil * the atom's valency. It will return 0 for PseudoAtoms, and for atoms for which it * does not have an entry in the configuration file. */ public int calculateNumberOfImplicitHydrogens(IAtom atom, double bondOrderSum, double singleElectronSum, double maxBondOrder, int neighbourCount) throws CDKException { int missingHydrogen = 0; if (atom instanceof IPseudoAtom) { logger.debug("don't figure it out... it simply does not lack H's"); return 0; } logger.debug("Calculating number of missing hydrogen atoms"); // get default atom
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -