📄 saturationchecker.java
字号:
// try to leave this bond unsaturated and saturate the left bondssaturate this bond if (leftBondCount > 0) { logger.debug("Recursing with unsaturated bond with #bonds: " + leftBondCount); bondsAreFullySaturated = newSaturate(leftBonds, atomContainer) && !isUnsaturated(bond, atomContainer); } else { bondsAreFullySaturated = false; } // ok, did it work? if not, saturate this bond, and recurse if (!bondsAreFullySaturated) { logger.debug("First try did not work..."); // ok, revert saturating this bond, and recurse again boolean couldSaturate = newSaturate(bond, atomContainer); if (couldSaturate) { if (leftBondCount > 0) { logger.debug("Recursing with saturated bond with #bonds: " + leftBondCount); bondsAreFullySaturated = newSaturate(leftBonds, atomContainer); } else { bondsAreFullySaturated = true; } } else { bondsAreFullySaturated = false; // no need to recurse, because we already know that this bond // unsaturated does not work } } } else if (isSaturated(bond, atomContainer)) { logger.debug("This bond is already saturated."); if (leftBondCount > 0) { logger.debug("Recursing with #bonds: " + leftBondCount); bondsAreFullySaturated = newSaturate(leftBonds, atomContainer); } else { bondsAreFullySaturated = true; } } else { logger.debug("Cannot saturate this bond"); // but, still recurse (if possible) if (leftBondCount > 0) { logger.debug("Recursing with saturated bond with #bonds: " + leftBondCount); bondsAreFullySaturated = newSaturate(leftBonds, atomContainer) && !isUnsaturated(bond, atomContainer); } else { bondsAreFullySaturated = !isUnsaturated(bond, atomContainer); } } } logger.debug("Is bond set fully saturated?: " + bondsAreFullySaturated); logger.debug("Returning to level: " + (bonds.length + 1)); return bondsAreFullySaturated; } /** * Saturate atom by adjusting its 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 */ public boolean newSaturate(IBond bond, IAtomContainer atomContainer) throws CDKException { IAtom[] atoms = BondManipulator.getAtomArray(bond); IAtom atom = atoms[0]; IAtom partner = atoms[1]; logger.debug(" saturating bond: ", atom.getSymbol(), "-", partner.getSymbol()); IAtomType[] atomTypes1 = getAtomTypeFactory(bond.getBuilder()).getAtomTypes(atom.getSymbol()); IAtomType[] atomTypes2 = getAtomTypeFactory(bond.getBuilder()).getAtomTypes(partner.getSymbol()); boolean bondOrderIncreased = true; while (bondOrderIncreased && !isSaturated(bond, atomContainer)) { logger.debug("Can increase bond order"); bondOrderIncreased = false; for (int atCounter1=0; atCounter1<atomTypes1.length&& !bondOrderIncreased; atCounter1++) { IAtomType aType1 = atomTypes1[atCounter1]; logger.debug(" condidering atom type: ", aType1); if (couldMatchAtomType(atomContainer, atom, aType1)) { logger.debug(" trying atom type: ", aType1); for (int atCounter2=0; atCounter2<atomTypes2.length && !bondOrderIncreased; atCounter2++) { IAtomType aType2 = atomTypes2[atCounter2]; logger.debug(" condidering partner type: ", aType1); if (couldMatchAtomType(atomContainer, partner, atomTypes2[atCounter2])) { logger.debug(" with atom type: ", aType2); if (bond.getOrder() >= aType2.getMaxBondOrder() || bond.getOrder() >= aType1.getMaxBondOrder()) { logger.debug("Bond order not increased: atoms has reached (or exceeded) maximum bond order for this atom type"); } else if (bond.getOrder() < aType2.getMaxBondOrder() && bond.getOrder() < aType1.getMaxBondOrder()) { bond.setOrder(bond.getOrder() + 1); logger.debug("Bond order now " + bond.getOrder()); bondOrderIncreased = true; } } } } } } return isSaturated(bond, atomContainer); } /** * Determines if the atom can be of type AtomType. */ public boolean couldMatchAtomType(IAtomContainer atomContainer, IAtom atom, IAtomType atomType) { logger.debug(" ... matching atom ", atom.getSymbol(), " vs ", atomType); if (atomContainer.getBondOrderSum(atom) + atom.getHydrogenCount() < atomType.getBondOrderSum()) { logger.debug(" Match!"); return true; } logger.debug(" No Match"); return false; } /** * The method is known to fail for certain compounds. For more information, see * cdk.test.limitations package. * This method is known to fail, especially on pyrolle-like compounts. * Consider using import org.openscience.cdk.smiles.DeduceBondSystemTool, which should work better * */ public void saturate(IAtomContainer atomContainer) throws CDKException { /* newSaturate(atomContainer); } public void oldSaturate(AtomContainer atomContainer) throws CDKException { */ IAtom partner = null; IAtom atom = null; java.util.List partners = null; IAtomType[] atomTypes1 = null; IAtomType[] atomTypes2 = null; IBond bond = null; for (int i = 1; i < 4; i++) { // handle atoms with degree 1 first and then proceed to higher order for (int f = 0; f < atomContainer.getAtomCount(); f++) { atom = atomContainer.getAtom(f); logger.debug("symbol: ", atom.getSymbol()); atomTypes1 = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol()); if(atomTypes1.length>0){ logger.debug("first atom type: ", atomTypes1[0]); if (atomContainer.getConnectedBondsCount(atom) == i) { if (atom.getFlag(CDKConstants.ISAROMATIC) && atomContainer.getBondOrderSum(atom) < atomTypes1[0].getBondOrderSum() - atom.getHydrogenCount()){ partners = atomContainer.getConnectedAtomsList(atom); for (int g = 0; g < partners.size(); g++) { partner = (IAtom)partners.get(g); logger.debug("Atom has " + partners.size() + " partners"); atomTypes2 = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(partner.getSymbol()); if(atomTypes2.length==0) return; if (atomContainer.getBond(partner,atom).getFlag(CDKConstants.ISAROMATIC) && atomContainer.getBondOrderSum(partner) < atomTypes2[0].getBondOrderSum() - partner.getHydrogenCount()) { logger.debug("Partner has " + atomContainer.getBondOrderSum(partner) + ", may have: " + atomTypes2[0].getBondOrderSum()); bond = atomContainer.getBond(atom, partner); logger.debug("Bond order was " + bond.getOrder()); bond.setOrder(bond.getOrder() + 1); logger.debug("Bond order now " + bond.getOrder()); break; } } } if (atomContainer.getBondOrderSum(atom) < atomTypes1[0].getBondOrderSum() - atom.getHydrogenCount()) { logger.debug("Atom has " + atomContainer.getBondOrderSum(atom) + ", may have: " + atomTypes1[0].getBondOrderSum()); partners = atomContainer.getConnectedAtomsList(atom); for (int g = 0; g < partners.size(); g++) { partner = (IAtom)partners.get(g); logger.debug("Atom has " + partners.size() + " partners"); atomTypes2 = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(partner.getSymbol()); if(atomTypes2.length==0) return; if (atomContainer.getBondOrderSum(partner) < atomTypes2[0].getBondOrderSum() - partner.getHydrogenCount()) { logger.debug("Partner has " + atomContainer.getBondOrderSum(partner) + ", may have: " + atomTypes2[0].getBondOrderSum()); bond = atomContainer.getBond(atom, partner); logger.debug("Bond order was " + bond.getOrder()); bond.setOrder(bond.getOrder() + 1); logger.debug("Bond order now " + bond.getOrder()); break; } } } } } } } } public void saturateRingSystems(IAtomContainer atomContainer) throws CDKException { IRingSet rs = new SSSRFinder(atomContainer.getBuilder().newMolecule(atomContainer)).findSSSR(); List ringSets = RingPartitioner.partitionRings(rs); IAtomContainer ac = null; IAtom atom = null; int temp[]; for (int f = 0; f < ringSets.size(); f++) { rs = (IRingSet)ringSets.get(f); List containers = RingSetManipulator.getAllAtomContainers(rs); for (int counter=0; counter<containers.size(); counter++) { ac = (IAtomContainer)containers.get(counter); temp = new int[ac.getAtomCount()]; for (int g = 0; g < ac.getAtomCount(); g++) { atom = ac.getAtom(g); temp[g] = atom.getHydrogenCount(); atom.setHydrogenCount(atomContainer.getConnectedBondsCount(atom) - ac.getConnectedBondsCount(atom) - temp[g]); } saturate(ac); for (int g = 0; g < ac.getAtomCount(); g++) { atom = ac.getAtom(g); atom.setHydrogenCount(temp[g]); } } } } /* * Recursivly fixes bond orders in a molecule for * which only connectivities but no bond orders are know. * *@ param molecule The molecule to fix the bond orders for *@ param bond The number of the bond to treat in this recursion step *@ return true if the bond order which was implemented was ok. */ /*private boolean recursiveBondOrderFix(Molecule molecule, int bondNumber) { Atom partner = null; Atom atom = null; Atom[] partners = null; AtomType[] atomTypes1 = null; AtomType[] atomTypes2 = null; int maxBondOrder = 0; int oldBondOrder = 0; if (bondNumber < molecule.getBondCount()) { Bond bond = molecule.getBondAt(f); } else { return true; } atom = bond.getAtomAt(0); partner = bond.getAtomAt(1); atomTypes1 = atf.getAtomTypes(atom.getSymbol(), atf.ATOMTYPE_ID_STRUCTGEN); atomTypes2 = atf.getAtomTypes(partner.getSymbol(), atf.ATOMTYPE_ID_STRUCTGEN); maxBondOrder = Math.min(atomTypes1[0].getMaxBondOrder(), atomTypes2[0].getMaxBondOrder()); for (int f = 1; f <= maxBondOrder; f++) { oldBondOrder = bond.getOrder() bond.setOrder(f); if (!isOverSaturated(atom, molecule) && !isOverSaturated(partner, molecule)) { if (!recursiveBondOrderFix(molecule, bondNumber + 1)) break; } else { bond.setOrder(oldBondOrder); return false; } } return true; }*/ /** * 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 * @see AtomTypeFactory */ public int calculateNumberOfImplicitHydrogens(IAtom atom, IAtomContainer container) throws CDKException { return this.calculateNumberOfImplicitHydrogens(atom, container, false); } public int calculateNumberOfImplicitHydrogens(IAtom atom) throws CDKException { java.util.List bonds = new java.util.ArrayList(); return this.calculateNumberOfImplicitHydrogens(atom, 0, 0, bonds, false); } public int calculateNumberOfImplicitHydrogens(IAtom atom, IAtomContainer container, boolean throwExceptionForUnknowAtom) throws CDKException { return this.calculateNumberOfImplicitHydrogens(atom, container.getBondOrderSum(atom), container.getConnectedSingleElectronsCount(atom), container.getConnectedBondsList(atom), throwExceptionForUnknowAtom ); } /** * 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 throwExceptionForUnknowAtom Should an exception be thrown if an unknown atomtype is found or 0 returned ? * @return Description of the Return Value * @see AtomTypeFactory */ public int calculateNumberOfImplicitHydrogens(IAtom atom, double bondOrderSum, double singleElectronSum, java.util.List connectedBonds, boolean throwExceptionForUnknowAtom) throws CDKException { int missingHydrogen = 0; if (atom instanceof IPseudoAtom) { // don't figure it out... it simply does not lack H's } else if (atom.getAtomicNumber() == 1 || atom.getSymbol().equals("H")) { missingHydrogen = (int) (1 - bondOrderSum - singleElectronSum - atom.getFormalCharge()); } else { logger.info("Calculating number of missing hydrogen atoms"); // get default atom IAtomType[] atomTypes = getAtomTypeFactory(atom.getBuilder()).getAtomTypes(atom.getSymbol()); if(atomTypes.length==0 && throwExceptionForUnknowAtom) return 0; logger.debug("Found atomtypes: " + atomTypes.length); if (atomTypes.length > 0) { IAtomType defaultAtom = atomTypes[0]; logger.debug("DefAtom: ", defaultAtom); missingHydrogen = (int) (defaultAtom.getBondOrderSum() - bondOrderSum - singleElectronSum + atom.getFormalCharge()); if (atom.getFlag(CDKConstants.ISAROMATIC)){ boolean subtractOne=true; for(int i=0;i<connectedBonds.size();i++){ IBond conBond = (IBond)connectedBonds.get(i); if(conBond.getOrder()==2 || conBond.getOrder()==CDKConstants.BONDORDER_AROMATIC) subtractOne=false; } if(subtractOne) missingHydrogen--; } logger.debug("Atom: ", atom.getSymbol()); logger.debug(" max bond order: " + defaultAtom.getBondOrderSum()); logger.debug(" bond order sum: " + bondOrderSum); logger.debug(" charge : " + atom.getFormalCharge()); } else { logger.warn("Could not find atom type for ", atom.getSymbol()); } } return missingHydrogen; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -