/// <summary> 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. /// /// </summary> /// <param name="atom"> Description of the Parameter /// </param> /// <param name="throwExceptionForUnknowAtom"> Should an exception be thrown if an unknown atomtype is found or 0 returned ? /// </param> /// <returns> Description of the Return Value /// </returns> /// <seealso cref="AtomTypeFactory"> /// </seealso> public virtual int calculateNumberOfImplicitHydrogens(IAtom atom, double bondOrderSum, IBond[] connectedBonds, bool throwExceptionForUnknowAtom) { int missingHydrogen = 0; if (atom is IPseudoAtom) { // don't figure it out... it simply does not lack H's } else if (atom.AtomicNumber == 1 || atom.Symbol.Equals("H")) { //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" missingHydrogen = (int)(1 - bondOrderSum - atom.getFormalCharge()); } else { //logger.info("Calculating number of missing hydrogen atoms"); // get default atom IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); 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); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" missingHydrogen = (int)(defaultAtom.BondOrderSum - bondOrderSum + atom.getFormalCharge()); if (atom.getFlag(CDKConstants.ISAROMATIC)) { bool subtractOne = true; for (int i = 0; i < connectedBonds.Length; i++) { if (connectedBonds[i].Order == 2 || connectedBonds[i].Order == CDKConstants.BONDORDER_AROMATIC) { subtractOne = false; } } if (subtractOne) { missingHydrogen--; } } //logger.debug("Atom: ", atom.Symbol); //logger.debug(" max bond order: " + defaultAtom.BondOrderSum); //logger.debug(" bond order sum: " + bondOrderSum); //logger.debug(" charge : " + atom.getFormalCharge()); } else { //logger.warn("Could not find atom type for ", atom.Symbol); } } return(missingHydrogen); }
/// <summary> Generates the SMILES string for the atom /// /// </summary> /// <param name="a"> the atom to generate the SMILES for. /// </param> /// <param name="buffer"> the string buffer that the atom is to be /// apended to. /// </param> /// <param name="container"> the AtomContainer to analyze. /// </param> /// <param name="chiral"> is a chiral smiles wished? /// </param> /// <param name="parent"> the atom we came from. /// </param> /// <param name="atomsInOrderOfSmiles"> a vector containing the atoms in the order /// they are in the smiles. /// </param> /// <param name="currentChain"> The chain we currently deal with. /// </param> /// <param name="doubleBondConfiguration"> Description of Parameter /// </param> private void parseAtom(IAtom a, System.Text.StringBuilder buffer, IAtomContainer container, bool chiral, bool[] doubleBondConfiguration, IAtom parent, System.Collections.ArrayList atomsInOrderOfSmiles, System.Collections.ArrayList currentChain) { System.String symbol = a.Symbol; bool stereo = BondTools.isStereo(container, a); bool brackets = symbol.Equals("B") || symbol.Equals("C") || symbol.Equals("N") || symbol.Equals("O") || symbol.Equals("P") || symbol.Equals("S") || symbol.Equals("F") || symbol.Equals("Br") || symbol.Equals("I") || symbol.Equals("Cl"); brackets = !brackets; //System.out.println("in parseAtom()"); //Deal with the start of a double bond configuration if (isStartOfDoubleBond(container, a, parent, doubleBondConfiguration)) { buffer.Append('/'); } if (a is IPseudoAtom) { buffer.Append("[*]"); } else { System.String mass = generateMassString(a); brackets = brackets | !mass.Equals(""); System.String charge = generateChargeString(a); brackets = brackets | !charge.Equals(""); if (chiral && stereo) { brackets = true; } if (brackets) { buffer.Append('['); } buffer.Append(mass); if (a.getFlag(CDKConstants.ISAROMATIC)) { // Strictly speaking, this is wrong. Lower case is only used for sp2 atoms! buffer.Append(a.Symbol.ToLower()); } else if (a.Hybridization == CDKConstants.HYBRIDIZATION_SP2) { buffer.Append(a.Symbol.ToLower()); } else { buffer.Append(symbol); } if (a.getProperty(RING_CONFIG) != null && a.getProperty(RING_CONFIG).Equals(UP)) { buffer.Append('/'); } if (a.getProperty(RING_CONFIG) != null && a.getProperty(RING_CONFIG).Equals(DOWN)) { buffer.Append('\\'); } if (chiral && stereo && (BondTools.isTrigonalBipyramidalOrOctahedral(container, a) != 0 || BondTools.isSquarePlanar(container, a) || BondTools.isTetrahedral(container, a, false) != 0)) { buffer.Append('@'); } if (chiral && stereo && BondTools.isSquarePlanar(container, a)) { buffer.Append("SP1"); } //chiral //hcount buffer.Append(charge); if (brackets) { buffer.Append(']'); } } //System.out.println("in parseAtom() after dealing with Pseudoatom or not"); //Deal with the end of a double bond configuration if (isEndOfDoubleBond(container, a, parent, doubleBondConfiguration)) { IAtom viewFrom = null; for (int i = 0; i < currentChain.Count; i++) { if (currentChain[i] == parent) { int k = i - 1; while (k > -1) { if (currentChain[k] is IAtom) { viewFrom = (IAtom)currentChain[k]; break; } k--; } } } if (viewFrom == null) { for (int i = 0; i < atomsInOrderOfSmiles.Count; i++) { if (atomsInOrderOfSmiles[i] == parent) { viewFrom = (IAtom)atomsInOrderOfSmiles[i - 1]; } } } bool afterThisAtom = false; IAtom viewTo = null; for (int i = 0; i < currentChain.Count; i++) { if (afterThisAtom && currentChain[i] is IAtom) { viewTo = (IAtom)currentChain[i]; break; } if (afterThisAtom && currentChain[i] is System.Collections.ArrayList) { viewTo = (IAtom)((System.Collections.ArrayList)currentChain[i])[0]; break; } if (a == currentChain[i]) { afterThisAtom = true; } } try { if (BondTools.isCisTrans(viewFrom, a, parent, viewTo, container)) { buffer.Append('\\'); } else { buffer.Append('/'); } } catch (CDKException ex) { //If the user wants a double bond configuration, where there is none, we ignore this. } } System.Collections.ArrayList v = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); System.Collections.IEnumerator it = getRingOpenings(a, v).GetEnumerator(); System.Collections.IEnumerator it2 = v.GetEnumerator(); //System.out.println("in parseAtom() after checking for Ring openings"); //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'" while (it.MoveNext()) { //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'" System.Int32 integer = (System.Int32)it.Current; //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'" IBond b = container.getBond((IAtom)it2.Current, a); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" int type = (int)b.Order; if (type == 2 && !b.getFlag(CDKConstants.ISAROMATIC)) { buffer.Append("="); } else if (type == 3 && !b.getFlag(CDKConstants.ISAROMATIC)) { buffer.Append("#"); } buffer.Append(integer); } atomsInOrderOfSmiles.Add(a); //System.out.println("End of parseAtom()"); }
/// <summary> Append the symbol for the bond order between <code>a1</code> and <code>a2</code> /// to the <code>line</code>. /// /// </summary> /// <param name="line"> the StringBuffer that the bond symbol is appended to. /// </param> /// <param name="a1"> Atom participating in the bond. /// </param> /// <param name="a2"> Atom participating in the bond. /// </param> /// <param name="atomContainer"> the AtomContainer that the SMILES string is generated /// for. /// </param> private void parseBond(System.Text.StringBuilder line, IAtom a1, IAtom a2, IAtomContainer atomContainer) { //System.out.println("in parseBond()"); if (a1.getFlag(CDKConstants.ISAROMATIC) && a1.getFlag(CDKConstants.ISAROMATIC)) { return; } if (atomContainer.getBond(a1, a2) == null) { return; } int type = 0; //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" type = (int)atomContainer.getBond(a1, a2).Order; if (type == 1) { } else if (type == 2) { line.Append("="); } else if (type == 3) { line.Append("#"); } else { // //System.out.println("Unknown bond type"); } }
/// <summary> Tests the <code>ring</code> in the <code>molecule</code> for aromaticity. Uses the /// Hückle rule (4n + 2) pie electrons. sp<sup>2</sup> hybridized C contibute 1 electron non /// sp<sup>2</sup> hybridized heteroatoms contribute 2 electrons (N and O should never be sp in /// or anything else in a ring and d electron elements get to complicated) /// sp<sup>2</sup> hybridized heteroatoms contribute 1 electron hybridization is worked out by /// counting the number of bonds with order 2. Therefore sp<sup>2</sup> hybridization is assumed /// if there is one bond of order 2. Otherwise sp<sup>3</sup> hybridization is assumed. /// /// </summary> /// <param name="ring"> the ring to test /// </param> /// <param name="atomContainer"> the AtomContainer the ring is in /// </param> /// <returns> true if the ring is aromatic false otherwise. /// </returns> protected internal static bool isAromatic(IRing ring, IAtomContainer atomContainer) { IAtom[] ringAtoms = ring.Atoms; int eCount = 0; IBond[] conectedBonds; int numDoubleBond = 0; bool allConnectedBondsSingle; for (int i = 0; i < ringAtoms.Length; i++) { IAtom atom = ringAtoms[i]; numDoubleBond = 0; allConnectedBondsSingle = true; conectedBonds = atomContainer.getConnectedBonds(atom); for (int j = 0; j < conectedBonds.Length; j++) { IBond bond = conectedBonds[j]; if (bond.Order == 2 && ring.contains(bond)) { numDoubleBond++; } // Count the Electron if bond order = 1.5 else if (bond.Order == 1.5 && ring.contains(bond)) { numDoubleBond = 1; } if (bond.Order != 1) { allConnectedBondsSingle = false; } } if (numDoubleBond == 1) { //C or heteroatoms both contibute 1 electron in sp2 hybridized form eCount++; } else if (!atom.Symbol.Equals("C")) { //Heteroatom probably in sp3 hybrid therefore 2 electrons contributed. eCount = eCount + 2; } else if (atom.getFlag(CDKConstants.ISAROMATIC)) { eCount++; } else if (allConnectedBondsSingle && atom.Symbol.Equals("C") && atom.getFormalCharge() == 1.0) { // This is for tropylium and kinds. // Dependence on hybridisation would be better: // empty p-orbital is needed continue; } else { return(false); } } if (eCount - 2 != 0 && (eCount - 2) % 4 == 0) { return(true); } return(false); }
/// <summary> 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. /// /// </summary> /// <param name="atom"> Description of the Parameter /// </param> /// <param name="throwExceptionForUnknowAtom"> Should an exception be thrown if an unknown atomtype is found or 0 returned ? /// </param> /// <returns> Description of the Return Value /// </returns> /// <seealso cref="AtomTypeFactory"> /// </seealso> public virtual int calculateNumberOfImplicitHydrogens(IAtom atom, double bondOrderSum, IBond[] connectedBonds, bool throwExceptionForUnknowAtom) { int missingHydrogen = 0; if (atom is IPseudoAtom) { // don't figure it out... it simply does not lack H's } else if (atom.AtomicNumber == 1 || atom.Symbol.Equals("H")) { //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" missingHydrogen = (int) (1 - bondOrderSum - atom.getFormalCharge()); } else { //logger.info("Calculating number of missing hydrogen atoms"); // get default atom IAtomType[] atomTypes = getAtomTypeFactory(atom.Builder).getAtomTypes(atom.Symbol); 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); //UPGRADE_WARNING: Data types in Visual C# might be different. Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'" missingHydrogen = (int) (defaultAtom.BondOrderSum - bondOrderSum + atom.getFormalCharge()); if (atom.getFlag(CDKConstants.ISAROMATIC)) { bool subtractOne = true; for (int i = 0; i < connectedBonds.Length; i++) { if (connectedBonds[i].Order == 2 || connectedBonds[i].Order == CDKConstants.BONDORDER_AROMATIC) subtractOne = false; } if (subtractOne) missingHydrogen--; } //logger.debug("Atom: ", atom.Symbol); //logger.debug(" max bond order: " + defaultAtom.BondOrderSum); //logger.debug(" bond order sum: " + bondOrderSum); //logger.debug(" charge : " + atom.getFormalCharge()); } else { //logger.warn("Could not find atom type for ", atom.Symbol); } } return missingHydrogen; }
/// <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; } } } } } } } }