public virtual void saturateRingSystems(IAtomContainer atomContainer) { IRingSet rs = new SSSRFinder(atomContainer.Builder.newMolecule(atomContainer)).findSSSR(); System.Collections.ArrayList ringSets = RingPartitioner.partitionRings(rs); IAtomContainer ac = null; IAtom atom = null; int[] temp; for (int f = 0; f < ringSets.Count; f++) { rs = (IRingSet)ringSets[f]; ac = RingSetManipulator.getAllInOneContainer(rs); temp = new int[ac.AtomCount]; for (int g = 0; g < ac.AtomCount; g++) { atom = ac.getAtomAt(g); temp[g] = atom.getHydrogenCount(); atom.setHydrogenCount(atomContainer.getBondCount(atom) - ac.getBondCount(atom) - temp[g]); } saturate(ac); for (int g = 0; g < ac.AtomCount; g++) { atom = ac.getAtomAt(g); atom.setHydrogenCount(temp[g]); } } }
/// <summary> Determines if the atom can be of type AtomType. That is, it sees if this /// AtomType only differs in bond orders, or implicit hydrogen count. /// </summary> public virtual bool couldMatchAtomType(IAtom atom, double bondOrderSum, double maxBondOrder, IAtomType type) { //logger.debug("couldMatchAtomType: ... matching atom ", atom, " vs ", type); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); if (charge == type.getFormalCharge()) { //logger.debug("couldMatchAtomType: formal charge matches..."); if (atom.Hybridization == type.Hybridization) { //logger.debug("couldMatchAtomType: hybridization is OK..."); if (bondOrderSum + hcount <= type.BondOrderSum) { //logger.debug("couldMatchAtomType: bond order sum is OK..."); if (maxBondOrder <= type.MaxBondOrder) { //logger.debug("couldMatchAtomType: max bond order is OK... We have a match!"); return(true); } } else { //logger.debug("couldMatchAtomType: no match", "" + (bondOrderSum + hcount), " > ", "" + type.BondOrderSum); } } } else { //logger.debug("couldMatchAtomType: formal charge does NOT match..."); } //logger.debug("couldMatchAtomType: No Match"); return(false); }
/// <summary> Checks if the current atom has exceeded its bond order sum value. /// /// </summary> /// <param name="atom">The Atom to check /// </param> /// <param name="ac"> The atomcontainer context /// </param> /// <returns> oversaturated or not /// </returns> public virtual bool isOverSaturated(IAtom atom, IAtomContainer ac) { IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); 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 (System.Exception exc) { } for (int f = 0; f < atomTypes.Length; f++) { if (bondOrderSum - charge + hcount > atomTypes[f].BondOrderSum) { //logger.debug("*** Good ! ***"); return(true); } } //logger.debug("*** Bad ! ***"); return(false); }
/// <summary> 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. /// </summary> public virtual bool isSaturated(IAtom atom, IAtomContainer container) { if (atom is IPseudoAtom) { //logger.debug("don't figure it out... it simply does not lack H's"); return(true); } IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); if (atomTypes.Length == 0) { //logger.warn("Missing entry in atom type list for ", atom.Symbol); 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.Symbol); //logger.debug("bondOrderSum: ", bondOrderSum); //logger.debug("maxBondOrder: ", maxBondOrder); //logger.debug("hcount: ", hcount); //logger.debug("charge: ", charge); bool elementPlusChargeMatches = false; for (int f = 0; f < atomTypes.Length; f++) { IAtomType type = atomTypes[f]; if (couldMatchAtomType(atom, bondOrderSum, maxBondOrder, type)) { if (bondOrderSum + hcount == type.BondOrderSum && maxBondOrder <= type.MaxBondOrder) { //logger.debug("We have a match: ", type); //logger.debug("Atom is saturated: ", atom.Symbol); 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.Symbol + " and charge " + charge + " is not found."); }
/// <summary> Determines if the atom can be of type AtomType.</summary> public virtual bool couldMatchAtomType(IAtomContainer atomContainer, IAtom atom, IAtomType atomType) { //logger.debug(" ... matching atom ", atom.Symbol, " vs ", atomType); if (atomContainer.getBondOrderSum(atom) + atom.getHydrogenCount() < atomType.BondOrderSum) { //logger.debug(" Match!"); return(true); } //logger.debug(" No Match"); return(false); }
/// <summary> Method that saturates an atom in a molecule by adding implicit hydrogens. /// /// </summary> /// <param name="container"> Molecule to saturate /// </param> /// <param name="atom"> Atom to satureate. /// </param> /// <cdk.keyword> hydrogen, adding </cdk.keyword> /// <cdk.keyword> implicit hydrogen </cdk.keyword> public virtual int[] addImplicitHydrogensToSatisfyValency(IAtomContainer container, IAtom atom) { int formerHydrogens = atom.getHydrogenCount(); int missingHydrogens = valencyChecker.calculateNumberOfImplicitHydrogens(atom, container); atom.setHydrogenCount(missingHydrogens); int[] hydrogens = new int[2]; hydrogens[0] = formerHydrogens; hydrogens[1] = missingHydrogens; return(hydrogens); }
/// <summary> Determines if the atom can be of type AtomType.</summary> public virtual bool couldMatchAtomType(IAtom atom, double bondOrderSum, double maxBondOrder, IAtomType type) { //logger.debug(" ... matching atom ", atom.Symbol, " vs ", type); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); if (charge == type.getFormalCharge()) { if (bondOrderSum + hcount <= type.BondOrderSum && maxBondOrder <= type.MaxBondOrder) { //logger.debug(" We have a match!"); return(true); } } //logger.debug(" No Match"); return(false); }
/// <summary> Says if an atom is the start of a double bond configuration /// /// </summary> /// <param name="a"> The atom which is the start of configuration /// </param> /// <param name="container"> The atomContainer the atom is in /// </param> /// <param name="parent"> The atom we came from /// </param> /// <param name="doubleBondConfiguration"> The array indicating where double bond /// configurations are specified (this method ensures that there is /// actually the possibility of a double bond configuration) /// </param> /// <returns> false=is not start of configuration, true=is /// </returns> private static bool isStartOfDoubleBond(IAtomContainer container, IAtom a, IAtom parent, bool[] doubleBondConfiguration) { int lengthAtom = container.getConnectedAtoms(a).Length + a.getHydrogenCount(); if (lengthAtom != 3 && (lengthAtom != 2 && (System.Object)a.Symbol != (System.Object)("N"))) { return(false); } IAtom[] atoms = container.getConnectedAtoms(a); IAtom one = null; IAtom two = null; bool doubleBond = false; IAtom nextAtom = null; for (int i = 0; i < atoms.Length; i++) { if (atoms[i] != parent && container.getBond(atoms[i], a).Order == CDKConstants.BONDORDER_DOUBLE && isEndOfDoubleBond(container, atoms[i], a, doubleBondConfiguration)) { doubleBond = true; nextAtom = atoms[i]; } if (atoms[i] != nextAtom && one == null) { one = atoms[i]; } else if (atoms[i] != nextAtom && one != null) { two = atoms[i]; } } System.String[] morgannumbers = MorganNumbersTools.getMorganNumbersWithElementSymbol(container); if (one != null && ((!a.Symbol.Equals("N") && two != null && !morgannumbers[container.getAtomNumber(one)].Equals(morgannumbers[container.getAtomNumber(two)]) && doubleBond && doubleBondConfiguration[container.getBondNumber(a, nextAtom)]) || (doubleBond && a.Symbol.Equals("N") && System.Math.Abs(giveAngleBothMethods(nextAtom, a, parent, true)) > System.Math.PI / 10))) { return(true); } else { return(false); } }
/// <summary> Says if an atom is the end of a double bond configuration /// /// </summary> /// <param name="atom"> The atom which is the end of configuration /// </param> /// <param name="container"> The atomContainer the atom is in /// </param> /// <param name="parent"> The atom we came from /// </param> /// <param name="doubleBondConfiguration"> The array indicating where double bond /// configurations are specified (this method ensures that there is /// actually the possibility of a double bond configuration) /// </param> /// <returns> false=is not end of configuration, true=is /// </returns> private static bool isEndOfDoubleBond(IAtomContainer container, IAtom atom, IAtom parent, bool[] doubleBondConfiguration) { if (container.getBondNumber(atom, parent) == -1 || doubleBondConfiguration.Length <= container.getBondNumber(atom, parent) || !doubleBondConfiguration[container.getBondNumber(atom, parent)]) { return(false); } int lengthAtom = container.getConnectedAtoms(atom).Length + atom.getHydrogenCount(); int lengthParent = container.getConnectedAtoms(parent).Length + parent.getHydrogenCount(); if (container.getBond(atom, parent) != null) { if (container.getBond(atom, parent).Order == CDKConstants.BONDORDER_DOUBLE && (lengthAtom == 3 || (lengthAtom == 2 && atom.Symbol.Equals("N"))) && (lengthParent == 3 || (lengthParent == 2 && parent.Symbol.Equals("N")))) { IAtom[] atoms = container.getConnectedAtoms(atom); IAtom one = null; IAtom two = null; for (int i = 0; i < atoms.Length; i++) { if (atoms[i] != parent && one == null) { one = atoms[i]; } else if (atoms[i] != parent && one != null) { two = atoms[i]; } } System.String[] morgannumbers = MorganNumbersTools.getMorganNumbersWithElementSymbol(container); if ((one != null && two == null && atom.Symbol.Equals("N") && System.Math.Abs(giveAngleBothMethods(parent, atom, one, true)) > System.Math.PI / 10) || (!atom.Symbol.Equals("N") && one != null && two != null && !morgannumbers[container.getAtomNumber(one)].Equals(morgannumbers[container.getAtomNumber(two)]))) { return(true); } else { return(false); } } } return(false); }
/// <summary> Returns the currently maximum formable bond order for this atom. /// /// </summary> /// <param name="atom"> The atom to be checked /// </param> /// <param name="ac"> The AtomContainer that provides the context /// </param> /// <returns> the currently maximum formable bond order for this atom /// </returns> public virtual double getCurrentMaxBondOrder(IAtom atom, IAtomContainer ac) { IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); 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].BondOrderSum - current > max) { max = atomTypes[f].BondOrderSum - current; } } return(max); }
/// <summary> Method that saturates an atom in a molecule by adding implicit hydrogens. /// /// </summary> /// <param name="container"> Molecule to saturate /// </param> /// <param name="atom"> Atom to satureate. /// </param> /// <cdk.keyword> hydrogen, adding </cdk.keyword> /// <cdk.keyword> implicit hydrogen </cdk.keyword> public virtual int[] addImplicitHydrogensToSatisfyValency(IAtomContainer container, IAtom atom) { int formerHydrogens = atom.getHydrogenCount(); int missingHydrogens = valencyChecker.calculateNumberOfImplicitHydrogens(atom, container); atom.setHydrogenCount(missingHydrogens); int[] hydrogens = new int[2]; hydrogens[0] = formerHydrogens; hydrogens[1] = missingHydrogens; return hydrogens; }
/// <summary> The method is known to fail for certain compounds. For more information, see /// cdk.test.limitations package. /// /// </summary> public virtual void saturate(IAtomContainer atomContainer) { /* newSaturate(atomContainer); * } * public void oldSaturate(AtomContainer atomContainer) throws CDKException { */ IAtom partner = null; IAtom atom = null; IAtom[] 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.AtomCount; f++) { atom = atomContainer.getAtomAt(f); //logger.debug("symbol: ", atom.Symbol); atomTypes1 = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); if (atomTypes1.Length > 0) { //logger.debug("first atom type: ", atomTypes1[0]); if (atomContainer.getBondCount(atom) == i) { if (atom.getFlag(CDKConstants.ISAROMATIC) && atomContainer.getBondOrderSum(atom) < atomTypes1[0].BondOrderSum - atom.getHydrogenCount()) { partners = atomContainer.getConnectedAtoms(atom); for (int g = 0; g < partners.Length; g++) { partner = partners[g]; //logger.debug("Atom has " + partners.Length + " partners"); atomTypes2 = getAtomTypeFactory(atom.Builder).getAtomTypes(partner.Symbol); if (atomTypes2.Length == 0) { return; } if (atomContainer.getBond(partner, atom).getFlag(CDKConstants.ISAROMATIC) && atomContainer.getBondOrderSum(partner) < atomTypes2[0].BondOrderSum - partner.getHydrogenCount()) { //logger.debug("Partner has " + atomContainer.getBondOrderSum(partner) + ", may have: " + atomTypes2[0].BondOrderSum); bond = atomContainer.getBond(atom, partner); //logger.debug("Bond order was " + bond.Order); bond.Order = bond.Order + 1; //logger.debug("Bond order now " + bond.Order); break; } } } if (atomContainer.getBondOrderSum(atom) < atomTypes1[0].BondOrderSum - atom.getHydrogenCount()) { //logger.debug("Atom has " + atomContainer.getBondOrderSum(atom) + ", may have: " + atomTypes1[0].BondOrderSum); partners = atomContainer.getConnectedAtoms(atom); for (int g = 0; g < partners.Length; g++) { partner = partners[g]; //logger.debug("Atom has " + partners.Length + " partners"); atomTypes2 = getAtomTypeFactory(atom.Builder).getAtomTypes(partner.Symbol); if (atomTypes2.Length == 0) { return; } if (atomContainer.getBondOrderSum(partner) < atomTypes2[0].BondOrderSum - partner.getHydrogenCount()) { //logger.debug("Partner has " + atomContainer.getBondOrderSum(partner) + ", may have: " + atomTypes2[0].BondOrderSum); bond = atomContainer.getBond(atom, partner); //logger.debug("Bond order was " + bond.Order); bond.Order = bond.Order + 1; //logger.debug("Bond order now " + bond.Order); break; } } } } } } } }
/// <summary> Produces an AtomContainer without explicit Hs but with H count from one with Hs. /// The new molecule is a deep copy. /// /// </summary> /// <param name="atomContainer">The AtomContainer from which to remove the hydrogens /// </param> /// <returns> The molecule without Hs. /// </returns> /// <cdk.keyword> hydrogen, removal </cdk.keyword> public static IAtomContainer removeHydrogens(IAtomContainer atomContainer) { //UPGRADE_TODO: Class 'java.util.HashMap' was converted to 'System.Collections.Hashtable' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilHashMap'" System.Collections.IDictionary map = new System.Collections.Hashtable(); // maps original atoms to clones. System.Collections.IList remove = new System.Collections.ArrayList(); // lists removed Hs. // Clone atoms except those to be removed. IMolecule mol = atomContainer.Builder.newMolecule(); int count = atomContainer.AtomCount; for (int i = 0; i < count; i++) { // Clone/remove this atom? IAtom atom = atomContainer.getAtomAt(i); if (!atom.Symbol.Equals("H")) { IAtom clonedAtom = null; try { clonedAtom = (IAtom)atom.Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" catch (System.Exception e) { // TODO Auto-generated catch block SupportClass.WriteStackTrace(e, Console.Error); } clonedAtom.setHydrogenCount(0); mol.addAtom(clonedAtom); map[atom] = clonedAtom; } else { remove.Add(atom); // maintain list of removed H. } } // Clone bonds except those involving removed atoms. count = atomContainer.getBondCount(); for (int i = 0; i < count; i++) { // Check bond. //UPGRADE_NOTE: Final was removed from the declaration of 'bond '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" IBond bond = atomContainer.getBondAt(i); IAtom[] atoms = bond.getAtoms(); bool removedBond = false; //UPGRADE_NOTE: Final was removed from the declaration of 'length '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" int length = atoms.Length; for (int k = 0; k < length; k++) { if (remove.Contains(atoms[k])) { removedBond = true; break; } } // Clone/remove this bond? if (!removedBond) // if (!remove.contains(atoms[0]) && !remove.contains(atoms[1])) { IBond clone = null; try { clone = (IBond)atomContainer.getBondAt(i).Clone(); } //UPGRADE_NOTE: Exception 'java.lang.CloneNotSupportedException' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'" catch (System.Exception e) { // TODO Auto-generated catch block SupportClass.WriteStackTrace(e, Console.Error); } clone.setAtoms(new IAtom[] { (IAtom)map[atoms[0]], (IAtom)map[atoms[1]] }); mol.addBond(clone); } } // Recompute hydrogen counts of neighbours of removed Hydrogens. //UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'" for (System.Collections.IEnumerator i = remove.GetEnumerator(); i.MoveNext();) { // Process neighbours. //UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'" //UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'" for (System.Collections.IEnumerator n = atomContainer.getConnectedAtomsVector((IAtom)i.Current).GetEnumerator(); n.MoveNext();) { //UPGRADE_NOTE: Final was removed from the declaration of 'neighb '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" //UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'" IAtom neighb = (IAtom)map[n.Current]; neighb.setHydrogenCount(neighb.getHydrogenCount() + 1); } } mol.Properties = atomContainer.Properties; mol.Flags = atomContainer.Flags; return(mol); }
/// <summary> 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. /// </summary> public virtual bool isSaturated(IAtom atom, IAtomContainer container) { if (atom is IPseudoAtom) { //logger.debug("don't figure it out... it simply does not lack H's"); return true; } IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); if (atomTypes.Length == 0) { //logger.warn("Missing entry in atom type list for ", atom.Symbol); 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.Symbol); //logger.debug("bondOrderSum: ", bondOrderSum); //logger.debug("maxBondOrder: ", maxBondOrder); //logger.debug("hcount: ", hcount); //logger.debug("charge: ", charge); bool elementPlusChargeMatches = false; for (int f = 0; f < atomTypes.Length; f++) { IAtomType type = atomTypes[f]; if (couldMatchAtomType(atom, bondOrderSum, maxBondOrder, type)) { if (bondOrderSum + hcount == type.BondOrderSum && maxBondOrder <= type.MaxBondOrder) { //logger.debug("We have a match: ", type); //logger.debug("Atom is saturated: ", atom.Symbol); 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.Symbol + " and charge " + charge + " is not found."); }
/// <summary> Determines if the atom can be of type AtomType. That is, it sees if this /// AtomType only differs in bond orders, or implicit hydrogen count. /// </summary> public virtual bool couldMatchAtomType(IAtom atom, double bondOrderSum, double maxBondOrder, IAtomType type) { //logger.debug("couldMatchAtomType: ... matching atom ", atom, " vs ", type); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); if (charge == type.getFormalCharge()) { //logger.debug("couldMatchAtomType: formal charge matches..."); if (atom.Hybridization == type.Hybridization) { //logger.debug("couldMatchAtomType: hybridization is OK..."); if (bondOrderSum + hcount <= type.BondOrderSum) { //logger.debug("couldMatchAtomType: bond order sum is OK..."); if (maxBondOrder <= type.MaxBondOrder) { //logger.debug("couldMatchAtomType: max bond order is OK... We have a match!"); return true; } } else { //logger.debug("couldMatchAtomType: no match", "" + (bondOrderSum + hcount), " > ", "" + type.BondOrderSum); } } } else { //logger.debug("couldMatchAtomType: formal charge does NOT match..."); } //logger.debug("couldMatchAtomType: No Match"); return false; }
/// <summary> Says if an atom is the start of a double bond configuration /// /// </summary> /// <param name="a"> The atom which is the start of configuration /// </param> /// <param name="container"> The atomContainer the atom is in /// </param> /// <param name="parent"> The atom we came from /// </param> /// <param name="doubleBondConfiguration"> The array indicating where double bond /// configurations are specified (this method ensures that there is /// actually the possibility of a double bond configuration) /// </param> /// <returns> false=is not start of configuration, true=is /// </returns> private bool isStartOfDoubleBond(IAtomContainer container, IAtom a, IAtom parent, bool[] doubleBondConfiguration) { int lengthAtom = container.getConnectedAtoms(a).Length + a.getHydrogenCount(); if (lengthAtom != 3 && (lengthAtom != 2 && (System.Object)a.Symbol != (System.Object)("N"))) { return (false); } IAtom[] atoms = container.getConnectedAtoms(a); IAtom one = null; IAtom two = null; bool doubleBond = false; IAtom nextAtom = null; for (int i = 0; i < atoms.Length; i++) { if (atoms[i] != parent && container.getBond(atoms[i], a).Order == CDKConstants.BONDORDER_DOUBLE && isEndOfDoubleBond(container, atoms[i], a, doubleBondConfiguration)) { doubleBond = true; nextAtom = atoms[i]; } if (atoms[i] != nextAtom && one == null) { one = atoms[i]; } else if (atoms[i] != nextAtom && one != null) { two = atoms[i]; } } System.String[] morgannumbers = MorganNumbersTools.getMorganNumbersWithElementSymbol(container); if (one != null && ((!a.Symbol.Equals("N") && two != null && !morgannumbers[container.getAtomNumber(one)].Equals(morgannumbers[container.getAtomNumber(two)]) && doubleBond && doubleBondConfiguration[container.getBondNumber(a, nextAtom)]) || (doubleBond && a.Symbol.Equals("N") && System.Math.Abs(BondTools.giveAngleBothMethods(nextAtom, a, parent, true)) > System.Math.PI / 10))) { return (true); } else { return (false); } }
/// <summary> Says if an atom is the end of a double bond configuration /// /// </summary> /// <param name="atom"> The atom which is the end of configuration /// </param> /// <param name="container"> The atomContainer the atom is in /// </param> /// <param name="parent"> The atom we came from /// </param> /// <param name="doubleBondConfiguration"> The array indicating where double bond /// configurations are specified (this method ensures that there is /// actually the possibility of a double bond configuration) /// </param> /// <returns> false=is not end of configuration, true=is /// </returns> private bool isEndOfDoubleBond(IAtomContainer container, IAtom atom, IAtom parent, bool[] doubleBondConfiguration) { if (container.getBondNumber(atom, parent) == -1 || doubleBondConfiguration.Length <= container.getBondNumber(atom, parent) || !doubleBondConfiguration[container.getBondNumber(atom, parent)]) { return false; } int lengthAtom = container.getConnectedAtoms(atom).Length + atom.getHydrogenCount(); int lengthParent = container.getConnectedAtoms(parent).Length + parent.getHydrogenCount(); if (container.getBond(atom, parent) != null) { if (container.getBond(atom, parent).Order == CDKConstants.BONDORDER_DOUBLE && (lengthAtom == 3 || (lengthAtom == 2 && atom.Symbol.Equals("N"))) && (lengthParent == 3 || (lengthParent == 2 && parent.Symbol.Equals("N")))) { IAtom[] atoms = container.getConnectedAtoms(atom); IAtom one = null; IAtom two = null; for (int i = 0; i < atoms.Length; i++) { if (atoms[i] != parent && one == null) { one = atoms[i]; } else if (atoms[i] != parent && one != null) { two = atoms[i]; } } System.String[] morgannumbers = MorganNumbersTools.getMorganNumbersWithElementSymbol(container); if ((one != null && two == null && atom.Symbol.Equals("N") && System.Math.Abs(BondTools.giveAngleBothMethods(parent, atom, one, true)) > System.Math.PI / 10) || (!atom.Symbol.Equals("N") && one != null && two != null && !morgannumbers[container.getAtomNumber(one)].Equals(morgannumbers[container.getAtomNumber(two)]))) { return (true); } else { return (false); } } } return (false); }
/// <summary> Determines if the atom can be of type AtomType.</summary> public virtual bool couldMatchAtomType(IAtomContainer atomContainer, IAtom atom, IAtomType atomType) { //logger.debug(" ... matching atom ", atom.Symbol, " vs ", atomType); if (atomContainer.getBondOrderSum(atom) + atom.getHydrogenCount() < atomType.BondOrderSum) { //logger.debug(" Match!"); return true; } //logger.debug(" No Match"); return false; }
/// <summary> Returns the currently maximum formable bond order for this atom. /// /// </summary> /// <param name="atom"> The atom to be checked /// </param> /// <param name="ac"> The AtomContainer that provides the context /// </param> /// <returns> the currently maximum formable bond order for this atom /// </returns> public virtual double getCurrentMaxBondOrder(IAtom atom, IAtomContainer ac) { IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); 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].BondOrderSum - current > max) { max = atomTypes[f].BondOrderSum - current; } } return max; }
/// <summary> Checks if the current atom has exceeded its bond order sum value. /// /// </summary> /// <param name="atom">The Atom to check /// </param> /// <param name="ac"> The atomcontainer context /// </param> /// <returns> oversaturated or not /// </returns> public virtual bool isOverSaturated(IAtom atom, IAtomContainer ac) { IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); 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 (System.Exception exc) { } for (int f = 0; f < atomTypes.Length; f++) { if (bondOrderSum - charge + hcount > atomTypes[f].BondOrderSum) { //logger.debug("*** Good ! ***"); return true; } } //logger.debug("*** Bad ! ***"); return false; }
/// <summary> Determines if the atom can be of type AtomType.</summary> public virtual bool couldMatchAtomType(IAtom atom, double bondOrderSum, double maxBondOrder, IAtomType type) { //logger.debug(" ... matching atom ", atom.Symbol, " vs ", type); int hcount = atom.getHydrogenCount(); int charge = atom.getFormalCharge(); if (charge == type.getFormalCharge()) { if (bondOrderSum + hcount <= type.BondOrderSum && maxBondOrder <= type.MaxBondOrder) { //logger.debug(" We have a match!"); return true; } } //logger.debug(" No Match"); return false; }