private static IRingSet toRingSet(IAtomContainer ac, System.Collections.ICollection cycles) { IRingSet ringSet = ac.Builder.newRingSet(); System.Collections.IEnumerator cycleIterator = cycles.GetEnumerator(); while (cycleIterator.MoveNext()) { SimpleCycle cycle = (SimpleCycle)cycleIterator.Current; IRing ring = ac.Builder.newRing(); System.Collections.IList vertices = cycle.vertexList(); IAtom[] atoms = new IAtom[vertices.Count]; atoms[0] = (IAtom)vertices[0]; for (int i = 1; i < vertices.Count; i++) { atoms[i] = (IAtom)vertices[i]; ring.addElectronContainer(ac.getBond(atoms[i - 1], atoms[i])); } ring.addElectronContainer(ac.getBond(atoms[vertices.Count - 1], atoms[0])); ring.Atoms = atoms; ringSet.addAtomContainer(ring); } return(ringSet); }
/// <summary> /// Count bonds connecting two heavy atoms /// </summary> /// <param name="mol"></param> /// <returns></returns> public static int GetHeavyBondCount(IAtomContainer mol) { int hbCnt = 0; for (int bi = 0; bi < mol.getBondCount(); bi++) { IBond b = mol.getBond(bi); if (b.getAtomCount() != 2) { continue; } IAtom a = b.getAtom(0); // first atom if (a.getAtomicNumber().intValue() == 1 || // do not count hydrogens a.getSymbol().Equals("H")) { a = b.getAtom(1); // second atom } if (a.getAtomicNumber().intValue() == 1 || // do not count hydrogens a.getSymbol().Equals("H")) { continue; } hbCnt++; } return(hbCnt); }
/// <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); }
public static void makeUpDownBonds(IAtomContainer container) { for (int i = 0; i < container.AtomCount; i++) { IAtom a = container.getAtomAt(i); if (container.getConnectedAtoms(a).Length == 4) { int up = 0; int down = 0; int hs = 0; IAtom h = null; for (int k = 0; k < 4; k++) { if (container.getBond(a, container.getConnectedAtoms(a)[k]).Stereo == CDKConstants.STEREO_BOND_UP) { up++; } if (container.getBond(a, container.getConnectedAtoms(a)[k]).Stereo == CDKConstants.STEREO_BOND_DOWN) { down++; } if (container.getBond(a, container.getConnectedAtoms(a)[k]).Stereo == CDKConstants.STEREO_BOND_NONE && container.getConnectedAtoms(a)[k].Symbol.Equals("H")) { h = container.getConnectedAtoms(a)[k]; hs++; } } if (up == 0 && down == 1 && h != null && hs == 1) { container.getBond(a, h).Stereo = CDKConstants.STEREO_BOND_UP; } if (up == 1 && down == 0 && h != null && hs == 1) { container.getBond(a, h).Stereo = CDKConstants.STEREO_BOND_DOWN; } } } }
/// <summary> Says if of four atoms connected two one atom the up and down bonds are /// opposite or not, i. e.if it's tetrehedral or square planar. The method /// doesnot check if there are four atoms and if two or up and two are down /// /// </summary> /// <param name="a"> The atom which is the center /// </param> /// <param name="container"> The atomContainer the atom is in /// </param> /// <returns> true=are opposite, false=are not /// </returns> public static bool stereosAreOpposite(IAtomContainer container, IAtom a) { System.Collections.IList atoms = container.getConnectedAtomsVector(a); //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.TreeMap' and 'System.Collections.SortedList' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" //UPGRADE_TODO: Constructor 'java.util.TreeMap.TreeMap' was converted to 'System.Collections.SortedList' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapTreeMap'" System.Collections.SortedList hm = new System.Collections.SortedList(); for (int i = 1; i < atoms.Count; i++) { hm[(double)giveAngle(a, (IAtom)atoms[0], ((IAtom)atoms[i]))] = (System.Int32)i; } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); int stereoOne = container.getBond(a, (IAtom)atoms[0]).Stereo; int stereoOpposite = container.getBond(a, (IAtom)atoms[(((System.Int32)ohere[1]))]).Stereo; if (stereoOpposite == stereoOne) { return(true); } else { return(false); } }
/// <summary> /// Remove the following features from a molecule /// - Atom non-standard mass /// - Stereo chemistry /// - explicit hydrogens /// </summary> /// <param name="src"></param> /// <returns>Modified mol</returns> public static IAtomContainer RemoveIsotopesStereoExplicitHydrogens( IAtomContainer src) { IAtom[] atoms = new IAtom[src.getAtomCount()]; IBond[] bonds = new IBond[src.getBondCount()]; IChemObjectBuilder builder = src.getBuilder(); for (int i = 0; i < atoms.Length; i++) { IAtom atom = src.getAtom(i); IAtom atom2 = (IAtom)builder.newInstance(typeof(IAtom), atom.getSymbol()); SetImplicitHydrogenCount(atom2, GetImplicitHydrogenCount(atom)); atom2.setPoint2d(atom.getPoint2d()); atoms[i] = atom2; } for (int i = 0; i < bonds.Length; i++) { IBond bond = src.getBond(i); int u = src.getAtomNumber(bond.getAtom(0)); int v = src.getAtomNumber(bond.getAtom(1)); IBond bond2 = (IBond)builder.newInstance(typeof(IBond), atoms[u], atoms[v]); bond2.setIsAromatic(bond.isAromatic()); bond2.setIsInRing(bond.isInRing()); bond2.setOrder(bond.getOrder()); bond2.setFlag(CDKConstants.ISAROMATIC, bond.getFlag(CDKConstants.ISAROMATIC)); bond2.setFlag(CDKConstants.SINGLE_OR_DOUBLE, bond.getFlag(CDKConstants.SINGLE_OR_DOUBLE)); bonds[i] = bond2; } IAtomContainer dest = (IAtomContainer)builder.newInstance(typeof(IAtomContainer)); dest.setAtoms(atoms); dest.setBonds(bonds); AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(dest); dest = AtomContainerManipulator.suppressHydrogens(dest); GetHydrogenAdder().addImplicitHydrogens(dest); return(dest); }
/// <summary> Says if two atoms are in cis or trans position around a double bond. /// The atoms have to be given to the method like this: firstOuterAtom - firstInnerAtom = secondInnterAtom - secondOuterAtom /// /// </summary> /// <param name="firstOuterAtom"> See above. /// </param> /// <param name="firstInnerAtom"> See above. /// </param> /// <param name="secondInnerAtom"> See above. /// </param> /// <param name="secondOuterAtom"> See above. /// </param> /// <param name="ac"> The atom container the atoms are in. /// </param> /// <returns> true=trans, false=cis. /// </returns> /// <exception cref="CDKException"> The atoms are not in a double bond configuration (no double bond in the middle, same atoms on one side) /// </exception> public static bool isCisTrans(IAtom firstOuterAtom, IAtom firstInnerAtom, IAtom secondInnerAtom, IAtom secondOuterAtom, IAtomContainer ac) { if (!isValidDoubleBondConfiguration(ac, ac.getBond(firstInnerAtom, secondInnerAtom))) { throw new CDKException("There is no valid double bond configuration between your inner atoms!"); } bool firstDirection = isLeft(firstOuterAtom, firstInnerAtom, secondInnerAtom); bool secondDirection = isLeft(secondOuterAtom, secondInnerAtom, firstInnerAtom); if (firstDirection == secondDirection) { return(true); } else { return(false); } }
/// <summary> /// Rebonds one atom by looking up nearby atom using the binary space partition tree. /// </summary> private void bondAtom(IAtomContainer container, IAtom atom) { double myCovalentRadius = atom.CovalentRadius; double searchRadius = myCovalentRadius + maxCovalentRadius + bondTolerance; Point tupleAtom = new Point(atom.X3d, atom.Y3d, atom.Z3d); Bspt.EnumerateSphere e = bspt.enumHemiSphere(tupleAtom, searchRadius); while (e.MoveNext()) { IAtom atomNear = ((TupleAtom)e.Current).Atom; if (atomNear != atom && container.getBond(atom, atomNear) == null) { bool isBonded_ = isBonded(myCovalentRadius, atomNear.CovalentRadius, e.foundDistance2()); if (isBonded_) { IBond bond = atom.Builder.newBond(atom, atomNear, 1.0); container.addBond(bond); } } } }
/// <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> Description of the Method /// /// </summary> /// <param name="ac"> Description of the Parameter /// </param> /// <param name="a"> Description of the Parameter /// </param> /// <returns> Description of the Return Value /// </returns> private IAtom hasWedges(IAtomContainer ac, IAtom a) { IAtom[] atoms = ac.getConnectedAtoms(a); for (int i = 0; i < atoms.Length; i++) { if (ac.getBond(a, atoms[i]).Stereo != CDKConstants.STEREO_BOND_NONE && !atoms[i].Symbol.Equals("H")) { return (atoms[i]); } } for (int i = 0; i < atoms.Length; i++) { if (ac.getBond(a, atoms[i]).Stereo != CDKConstants.STEREO_BOND_NONE) { return (atoms[i]); } } return (null); }
/// <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> Says if of four atoms connected two one atom the up and down bonds are /// opposite or not, i. e.if it's tetrehedral or square planar. The method /// doesnot check if there are four atoms and if two or up and two are down /// /// </summary> /// <param name="a"> The atom which is the center /// </param> /// <param name="container"> The atomContainer the atom is in /// </param> /// <returns> true=are opposite, false=are not /// </returns> public static bool stereosAreOpposite(IAtomContainer container, IAtom a) { System.Collections.IList atoms = container.getConnectedAtomsVector(a); //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.TreeMap' and 'System.Collections.SortedList' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" //UPGRADE_TODO: Constructor 'java.util.TreeMap.TreeMap' was converted to 'System.Collections.SortedList' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapTreeMap'" System.Collections.SortedList hm = new System.Collections.SortedList(); for (int i = 1; i < atoms.Count; i++) { hm[(double)giveAngle(a, (IAtom)atoms[0], ((IAtom)atoms[i]))] = (System.Int32)i; } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); int stereoOne = container.getBond(a, (IAtom)atoms[0]).Stereo; int stereoOpposite = container.getBond(a, (IAtom)atoms[(((System.Int32)ohere[1]))]).Stereo; if (stereoOpposite == stereoOne) { return true; } else { return false; } }
/// <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> /// (Converted from Java to C# for possible later modification) /// Suppress any explicit hydrogens in the provided container. Only hydrogens /// that can be represented as a hydrogen count value on the atom are /// suppressed. The container is updated and no elements are copied, please /// use either <seealso cref="#copyAndSuppressedHydrogens"/> if you would to preserve /// the old instance. /// </summary> /// <param name="org"> the container from which to remove hydrogens </param> /// <returns> the input for convenience </returns> /// <seealso cref= #copyAndSuppressedHydrogens </seealso> public IAtomContainer suppressHydrogens(IAtomContainer org) { bool anyHydrogenPresent = false; for (int ai = 0; ai < org.getAtomCount(); ai++) { IAtom atom = org.getAtom(ai); if ("H".Equals(atom.getSymbol())) { anyHydrogenPresent = true; break; } } if (!anyHydrogenPresent) { return(org); } // we need fast adjacency checks (to check for suppression and // update hydrogen counts) int[][] graph = GraphUtil.toAdjList(org); int nOrgAtoms = org.getAtomCount(); int nOrgBonds = org.getBondCount(); int nCpyAtoms = 0; int nCpyBonds = 0; ISet <IAtom> hydrogens = new HashSet <IAtom>(); IAtom[] cpyAtoms = new IAtom[nOrgAtoms]; // filter the original container atoms for those that can/can't // be suppressed for (int v = 0; v < nOrgAtoms; v++) { IAtom atom = org.getAtom(v); if (suppressibleHydrogen(org, graph, v)) { hydrogens.Add(atom); incrementImplHydrogenCount(org.getAtom(graph[v][0])); } else { cpyAtoms[nCpyAtoms++] = atom; } } // none of the hydrogens could be suppressed - no changes need to be made if (hydrogens.Count == 0) { return(org); } org.setAtoms(cpyAtoms); // we now update the bonds - we have auxiliary variable remaining that // bypasses the set membership checks if all suppressed bonds are found IBond[] cpyBonds = new IBond[nOrgBonds - hydrogens.Count]; int remaining = hydrogens.Count; for (int bi = 0; bi < org.getBondCount(); bi++) { IBond bond = org.getBond(bi); if (remaining > 0 && (hydrogens.Contains(bond.getAtom(0)) || hydrogens.Contains(bond.getAtom(1)))) { remaining--; continue; } cpyBonds[nCpyBonds++] = bond; } // we know how many hydrogens we removed and we should have removed the // same number of bonds otherwise the container is strange if (nCpyBonds != cpyBonds.Length) { throw new System.ArgumentException("number of removed bonds was less than the number of removed hydrogens"); } org.setBonds(cpyBonds); return(org); }
/// <summary> /// Convert isotope labels to hilighting. /// </summary> /// <param name="mol"></param> /// <returns></returns> public string ConvertIsotopeValuesToHilighting( IAtomContainer mol) { bool hilight; string molfile2 = ""; bool clearAttachmentPointLabels = true; bool hilightAttachmentBond = true; List <int> atomSet = new List <int>(); List <int> bondSet = new List <int>(); for (int bi = 0; bi < mol.getBondCount(); bi++) { IBond b = mol.getBond(bi); if (b.getAtomCount() != 2) { continue; } IAtom a1 = b.getAtom(0); IAtom a2 = b.getAtom(1); if (hilightAttachmentBond) { hilight = (GetMassNumber(a1) != 0 && GetMassNumber(a2) != 0); } else { hilight = (GetMassNumber(a1) < 0 && GetMassNumber(a2) < 0); } if (hilight) { bondSet.Add(bi); } } //String posMap = ""; // debug (note that hydrogens can get repositioned) for (int ai = 0; ai < mol.getAtomCount(); ai++) // scan atoms for hilighting and reset isotope values { IAtom a = mol.getAtom(ai); hilight = GetMassNumber(a) < 0; if (hilight) { atomSet.Add(ai); } //posMap += ai.ToString() + ", " + a.getSymbol() + ", " + hilight + "\r\n"; // debug int massNo = GetMassNumber(a); if (massNo == hilightIsotopeValue) { a.setMassNumber(null); // set back to original value } else if (massNo < 0) { if (clearAttachmentPointLabels) { a.setMassNumber(null); } else { SetMassNumber(a, -massNo); // set back to positive } } } //mol = GenerateCoordinates(mol); // (should already be done) try { molfile2 = AtomContainerToMolFileV3000(mol); } catch (Exception ex) { ex = ex; } if (Lex.IsUndefined(molfile2)) // couldn't convert to v3000, just return unhilighted v2000 file { molfile2 = AtomContainerToMolfile(mol); return(molfile2); } string txt = "MDLV30/HILITE"; if (atomSet.Count > 0) { txt += " " + BuildV3000KeywordList("ATOMS", atomSet); } if (bondSet.Count > 0) { txt += " " + BuildV3000KeywordList("BONDS", bondSet); } txt = BuildV3000Lines(txt); bool hasCollection = Lex.Contains(molfile2, "M V30 END COLLECTION"); if (hasCollection) // already have collection begin and end { txt = txt + "M V30 END COLLECTION"; molfile2 = Lex.Replace(molfile2, "M V30 END COLLECTION", txt); } else // add collection begin & end { txt = "M V30 BEGIN COLLECTION\n" + txt + "M V30 END COLLECTION\n" + "M V30 END CTAB"; molfile2 = Lex.Replace(molfile2, "M V30 END CTAB", txt); } return(molfile2); }
/// <summary> Says if two atoms are in cis or trans position around a double bond. /// The atoms have to be given to the method like this: firstOuterAtom - firstInnerAtom = secondInnterAtom - secondOuterAtom /// /// </summary> /// <param name="firstOuterAtom"> See above. /// </param> /// <param name="firstInnerAtom"> See above. /// </param> /// <param name="secondInnerAtom"> See above. /// </param> /// <param name="secondOuterAtom"> See above. /// </param> /// <param name="ac"> The atom container the atoms are in. /// </param> /// <returns> true=trans, false=cis. /// </returns> /// <exception cref="CDKException"> The atoms are not in a double bond configuration (no double bond in the middle, same atoms on one side) /// </exception> public static bool isCisTrans(IAtom firstOuterAtom, IAtom firstInnerAtom, IAtom secondInnerAtom, IAtom secondOuterAtom, IAtomContainer ac) { if (!isValidDoubleBondConfiguration(ac, ac.getBond(firstInnerAtom, secondInnerAtom))) { throw new CDKException("There is no valid double bond configuration between your inner atoms!"); } bool firstDirection = isLeft(firstOuterAtom, firstInnerAtom, secondInnerAtom); bool secondDirection = isLeft(secondOuterAtom, secondInnerAtom, firstInnerAtom); if (firstDirection == secondDirection) { return true; } else { return false; } }
/// <summary> Parse a branch /// /// </summary> /// <param name="v"> Description of Parameter /// </param> /// <param name="buffer"> Description of Parameter /// </param> /// <param name="container"> Description of Parameter /// </param> /// <param name="parent"> Description of Parameter /// </param> /// <param name="chiral"> Description of Parameter /// </param> /// <param name="doubleBondConfiguration"> Description of Parameter /// </param> /// <param name="atomsInOrderOfSmiles"> Description of Parameter /// </param> private void parseChain(System.Collections.ArrayList v, System.Text.StringBuilder buffer, IAtomContainer container, IAtom parent, bool chiral, bool[] doubleBondConfiguration, System.Collections.ArrayList atomsInOrderOfSmiles) { int positionInVector = 0; IAtom atom; //System.out.println("in parse chain. Size of tree: " + v.size()); for (int h = 0; h < v.Count; h++) { System.Object o = v[h]; if (o is IAtom) { atom = (IAtom)o; if (parent != null) { parseBond(buffer, atom, parent, container); } else { if (chiral && BondTools.isStereo(container, atom)) { parent = (IAtom)((System.Collections.ArrayList)v[1])[0]; } } parseAtom(atom, buffer, container, chiral, doubleBondConfiguration, parent, atomsInOrderOfSmiles, v); //System.out.println("in parseChain after parseAtom()"); /* * The principle of making chiral smiles is quite simple, although the code is * pretty uggly. The Atoms connected to the chiral center are put in sorted[] in the * order they have to appear in the smiles. Then the Vector v is rearranged according * to sorted[] */ if (chiral && BondTools.isStereo(container, atom) && container.getBond(parent, atom) != null) { //System.out.println("in parseChain in isChiral"); IAtom[] sorted = null; System.Collections.IList chiralNeighbours = container.getConnectedAtomsVector(atom); if (BondTools.isTetrahedral(container, atom, false) > 0) { sorted = new IAtom[3]; } if (BondTools.isTetrahedral(container, atom, false) == 1) { if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0 && BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0 && !BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[1] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } } } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UP) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0 && BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[1] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0 && !BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } } } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UNDEFINED || container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_NONE) { bool normalBindingIsLeft = false; for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0) { if (BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom)) { normalBindingIsLeft = true; break; } } } } for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (normalBindingIsLeft) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { sorted[1] = (IAtom)chiralNeighbours[i]; } } else { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP) { sorted[1] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { sorted[2] = (IAtom)chiralNeighbours[i]; } } } } } } if (BondTools.isTetrahedral(container, atom, false) == 2) { if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UP) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[1] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && !BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } } } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { double angle1 = 0; double angle2 = 0; IAtom atom1 = null; IAtom atom2 = null; for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { if (angle1 == 0) { angle1 = BondTools.giveAngle(atom, parent, (IAtom)chiralNeighbours[i]); atom1 = (IAtom)chiralNeighbours[i]; } else { angle2 = BondTools.giveAngle(atom, parent, (IAtom)chiralNeighbours[i]); atom2 = (IAtom)chiralNeighbours[i]; } } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[1] = (IAtom)chiralNeighbours[i]; } } } if (angle1 < angle2) { sorted[0] = atom2; sorted[2] = atom1; } else { sorted[0] = atom1; sorted[2] = atom2; } } } if (BondTools.isTetrahedral(container, atom, false) == 3) { if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UP) { //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.TreeMap' and 'System.Collections.SortedList' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" //UPGRADE_TODO: Constructor 'java.util.TreeMap.TreeMap' was converted to 'System.Collections.SortedList' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapTreeMap'" System.Collections.SortedList hm = new System.Collections.SortedList(); for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { hm[(double)BondTools.giveAngle(atom, parent, ((IAtom)chiralNeighbours[i]))] = (System.Int32)i; } } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); for (int i = ohere.Length - 1; i > -1; i--) { sorted[i] = ((IAtom)chiralNeighbours[((System.Int32)ohere[i])]); } } if (container.getBond(parent, atom).Stereo == 0) { double angle1 = 0; double angle2 = 0; IAtom atom1 = null; IAtom atom2 = null; for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0 && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { if (angle1 == 0) { angle1 = BondTools.giveAngle(atom, parent, (IAtom)chiralNeighbours[i]); atom1 = (IAtom)chiralNeighbours[i]; } else { angle2 = BondTools.giveAngle(atom, parent, (IAtom)chiralNeighbours[i]); atom2 = (IAtom)chiralNeighbours[i]; } } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } } } if (angle1 < angle2) { sorted[1] = atom2; sorted[2] = atom1; } else { sorted[1] = atom1; sorted[2] = atom2; } } } if (BondTools.isTetrahedral(container, atom, false) == 4) { if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.TreeMap' and 'System.Collections.SortedList' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" //UPGRADE_TODO: Constructor 'java.util.TreeMap.TreeMap' was converted to 'System.Collections.SortedList' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapTreeMap'" System.Collections.SortedList hm = new System.Collections.SortedList(); for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { hm[(double)BondTools.giveAngle(atom, parent, ((IAtom)chiralNeighbours[i]))] = (System.Int32)i; } } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); for (int i = ohere.Length - 1; i > -1; i--) { sorted[i] = ((IAtom)chiralNeighbours[((System.Int32)ohere[i])]); } } if (container.getBond(parent, atom).Stereo == 0) { double angle1 = 0; double angle2 = 0; IAtom atom1 = null; IAtom atom2 = null; for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0 && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { if (angle1 == 0) { angle1 = BondTools.giveAngle(atom, parent, (IAtom)chiralNeighbours[i]); atom1 = (IAtom)chiralNeighbours[i]; } else { angle2 = BondTools.giveAngle(atom, parent, (IAtom)chiralNeighbours[i]); atom2 = (IAtom)chiralNeighbours[i]; } } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } } } if (angle1 < angle2) { sorted[1] = atom2; sorted[0] = atom1; } else { sorted[1] = atom1; sorted[0] = atom2; } } } if (BondTools.isTetrahedral(container, atom, false) == 5) { if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { sorted[1] = (IAtom)chiralNeighbours[i]; } } } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UP) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && !BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0) { sorted[1] = (IAtom)chiralNeighbours[i]; } } } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UNDEFINED || container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_NONE) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN && !BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP) { sorted[1] = (IAtom)chiralNeighbours[i]; } } } } } if (BondTools.isTetrahedral(container, atom, false) == 6) { if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UP) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { sorted[1] = (IAtom)chiralNeighbours[i]; } } } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && !BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == 0) { sorted[1] = (IAtom)chiralNeighbours[i]; } } } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UNDEFINED || container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_NONE) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[2] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_UP && !BondTools.isLeft(((IAtom)chiralNeighbours[i]), parent, atom) && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond((IAtom)chiralNeighbours[i], atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { sorted[1] = (IAtom)chiralNeighbours[i]; } } } } } if (BondTools.isSquarePlanar(container, atom)) { sorted = new IAtom[3]; //This produces a U=SP1 order in every case //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.TreeMap' and 'System.Collections.SortedList' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" //UPGRADE_TODO: Constructor 'java.util.TreeMap.TreeMap' was converted to 'System.Collections.SortedList' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapTreeMap'" System.Collections.SortedList hm = new System.Collections.SortedList(); for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent && !isBondBroken((IAtom)chiralNeighbours[i], atom)) { hm[(double)BondTools.giveAngle(atom, parent, ((IAtom)chiralNeighbours[i]))] = (System.Int32)i; } } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); for (int i = 0; i < ohere.Length; i++) { sorted[i] = ((IAtom)chiralNeighbours[((System.Int32)ohere[i])]); } } if (BondTools.isTrigonalBipyramidalOrOctahedral(container, atom) != 0) { sorted = new IAtom[container.getConnectedAtoms(atom).Length - 1]; //UPGRADE_ISSUE: Class hierarchy differences between 'java.util.TreeMap' and 'System.Collections.SortedList' may cause compilation errors. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1186'" //UPGRADE_TODO: Constructor 'java.util.TreeMap.TreeMap' was converted to 'System.Collections.SortedList' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapTreeMap'" System.Collections.SortedList hm = new System.Collections.SortedList(); if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_UP) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (container.getBond(atom, (IAtom)chiralNeighbours[i]).Stereo == 0) { hm[(double)BondTools.giveAngle(atom, parent, ((IAtom)chiralNeighbours[i]))] = (System.Int32)i; } if (container.getBond(atom, (IAtom)chiralNeighbours[i]).Stereo == CDKConstants.STEREO_BOND_DOWN) { sorted[sorted.Length - 1] = (IAtom)chiralNeighbours[i]; } } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); for (int i = 0; i < ohere.Length; i++) { sorted[i] = ((IAtom)chiralNeighbours[((System.Int32)ohere[i])]); } } if (container.getBond(parent, atom).Stereo == CDKConstants.STEREO_BOND_DOWN) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (container.getBond(atom, (IAtom)chiralNeighbours[i]).Stereo == 0) { hm[(double)BondTools.giveAngle(atom, parent, ((IAtom)chiralNeighbours[i]))] = (System.Int32)i; } if (container.getBond(atom, (IAtom)chiralNeighbours[i]).Stereo == CDKConstants.STEREO_BOND_UP) { sorted[sorted.Length - 1] = (IAtom)chiralNeighbours[i]; } } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); for (int i = 0; i < ohere.Length; i++) { sorted[i] = ((IAtom)chiralNeighbours[((System.Int32)ohere[i])]); } } if (container.getBond(parent, atom).Stereo == 0) { for (int i = 0; i < chiralNeighbours.Count; i++) { if (chiralNeighbours[i] != parent) { if (container.getBond(atom, (IAtom)chiralNeighbours[i]).Stereo == 0) { hm[(double)(BondTools.giveAngleFromMiddle(atom, parent, ((IAtom)chiralNeighbours[i])))] = (System.Int32)i; } if (container.getBond(atom, (IAtom)chiralNeighbours[i]).Stereo == CDKConstants.STEREO_BOND_UP) { sorted[0] = (IAtom)chiralNeighbours[i]; } if (container.getBond(atom, (IAtom)chiralNeighbours[i]).Stereo == CDKConstants.STEREO_BOND_DOWN) { sorted[sorted.Length - 2] = (IAtom)chiralNeighbours[i]; } } } //UPGRADE_TODO: Method 'java.util.TreeMap.values' was converted to 'System.Collections.SortedList.Values' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilTreeMapvalues'" System.Object[] ohere = SupportClass.ICollectionSupport.ToArray(hm.Values); sorted[sorted.Length - 1] = ((IAtom)chiralNeighbours[((System.Int32)ohere[ohere.Length - 1])]); if (ohere.Length == 2) { sorted[sorted.Length - 3] = ((IAtom)chiralNeighbours[((System.Int32)ohere[0])]); if (BondTools.giveAngleFromMiddle(atom, parent, ((IAtom)chiralNeighbours[((System.Int32)ohere[1])])) < 0) { IAtom dummy = sorted[sorted.Length - 2]; sorted[sorted.Length - 2] = sorted[0]; sorted[0] = dummy; } } if (ohere.Length == 3) { sorted[sorted.Length - 3] = sorted[sorted.Length - 2]; sorted[sorted.Length - 2] = ((IAtom)chiralNeighbours[((System.Int32)ohere[ohere.Length - 2])]); sorted[sorted.Length - 4] = ((IAtom)chiralNeighbours[((System.Int32)ohere[ohere.Length - 3])]); } } } //This builds an onew[] containing the objects after the center of the chirality in the order given by sorted[] if (sorted != null) { int numberOfAtoms = 3; if (BondTools.isTrigonalBipyramidalOrOctahedral(container, atom) != 0) { numberOfAtoms = container.getConnectedAtoms(atom).Length - 1; } System.Object[] omy = new System.Object[numberOfAtoms]; System.Object[] onew = new System.Object[numberOfAtoms]; for (int k = getRingOpenings(atom, null).Count; k < numberOfAtoms; k++) { if (positionInVector + 1 + k - getRingOpenings(atom, null).Count < v.Count) { omy[k] = v[positionInVector + 1 + k - getRingOpenings(atom, null).Count]; } } for (int k = 0; k < sorted.Length; k++) { if (sorted[k] != null) { for (int m = 0; m < omy.Length; m++) { if (omy[m] is IAtom) { if (omy[m] == sorted[k]) { onew[k] = omy[m]; } } else { if (omy[m] == null) { onew[k] = null; } else { if (((System.Collections.ArrayList)omy[m])[0] == sorted[k]) { onew[k] = omy[m]; } } } } } else { onew[k] = null; } } //This is a workaround for 3624.MOL.2 I don't have a better solution currently bool doubleentry = false; for (int m = 0; m < onew.Length; m++) { for (int k = 0; k < onew.Length; k++) { if (m != k && onew[k] == onew[m]) { doubleentry = true; } } } if (!doubleentry) { //Make sure that the first atom in onew is the first one in the original smiles order. This is important to have a canonical smiles. if (positionInVector + 1 < v.Count) { System.Object atomAfterCenterInOriginalSmiles = v[positionInVector + 1]; int l = 0; while (onew[0] != atomAfterCenterInOriginalSmiles) { System.Object placeholder = onew[onew.Length - 1]; for (int k = onew.Length - 2; k > -1; k--) { onew[k + 1] = onew[k]; } onew[0] = placeholder; l++; if (l > onew.Length) { break; } } } //This cares about ring openings. Here the ring closure (represendted by a figure) must be the first atom. In onew the closure is null. if (getRingOpenings(atom, null).Count > 0) { int l = 0; while (onew[0] != null) { System.Object placeholder = onew[0]; for (int k = 1; k < onew.Length; k++) { onew[k - 1] = onew[k]; } onew[onew.Length - 1] = placeholder; l++; if (l > onew.Length) { break; } } } //The last in onew is a vector: This means we need to exchange the rest of the original smiles with the rest of this vector. if (onew[numberOfAtoms - 1] is System.Collections.ArrayList) { for (int i = 0; i < numberOfAtoms; i++) { if (onew[i] is IAtom) { System.Collections.ArrayList vtemp = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); vtemp.Add(onew[i]); for (int k = positionInVector + 1 + numberOfAtoms; k < v.Count; k++) { vtemp.Add(v[k]); } onew[i] = vtemp; for (int k = v.Count - 1; k > positionInVector + 1 + numberOfAtoms - 1; k--) { v.RemoveAt(k); } for (int k = 1; k < ((System.Collections.ArrayList)onew[numberOfAtoms - 1]).Count; k++) { v.Add(((System.Collections.ArrayList)onew[numberOfAtoms - 1])[k]); } onew[numberOfAtoms - 1] = ((System.Collections.ArrayList)onew[numberOfAtoms - 1])[0]; break; } } } //Put the onew objects in the original Vector int k2 = 0; for (int m = 0; m < onew.Length; m++) { if (onew[m] != null) { v[positionInVector + 1 + k2] = onew[m]; k2++; } } } } } parent = atom; } else { //Have Vector //System.out.println("in parseChain after else"); bool brackets = true; System.Collections.ArrayList result = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList(10)); addAtoms((System.Collections.ArrayList)o, result); if (isRingOpening(parent, result) && container.getBondCount(parent) < 4) { brackets = false; } if (brackets) { buffer.Append('('); } parseChain((System.Collections.ArrayList)o, buffer, container, parent, chiral, doubleBondConfiguration, atomsInOrderOfSmiles); if (brackets) { buffer.Append(')'); } } positionInVector++; //System.out.println("in parseChain after positionVector++"); } }
/// <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); }
private static IRingSet toRingSet(IAtomContainer ac, System.Collections.ICollection cycles) { IRingSet ringSet = ac.Builder.newRingSet(); System.Collections.IEnumerator cycleIterator = cycles.GetEnumerator(); while (cycleIterator.MoveNext()) { SimpleCycle cycle = (SimpleCycle)cycleIterator.Current; IRing ring = ac.Builder.newRing(); System.Collections.IList vertices = cycle.vertexList(); IAtom[] atoms = new IAtom[vertices.Count]; atoms[0] = (IAtom)vertices[0]; for (int i = 1; i < vertices.Count; i++) { atoms[i] = (IAtom)vertices[i]; ring.addElectronContainer(ac.getBond(atoms[i - 1], atoms[i])); } ring.addElectronContainer(ac.getBond(atoms[vertices.Count - 1], atoms[0])); ring.Atoms = atoms; ringSet.addAtomContainer(ring); } return ringSet; }
/// <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> /// Remove explicit and implicit hydrogens bonded to positive nitrogens /// </summary> /// <param name="org"></param> /// <returns></returns> public int RemoveHydrogensBondedToPositiveNitrogens(IAtomContainer org) { int chg, impHydCnt; int implicitHydRemoved = 0; HashSet <IAtom> atomsToRemove = new HashSet <IAtom>(); HashSet <IBond> bondsToRemove = new HashSet <IBond>(); int nOrgAtoms = org.getAtomCount(); int nOrgBonds = org.getBondCount(); // Get H atoms and their bonds to pos-charged Nitrogen, adjusting charge for (int bi = 0; bi < org.getBondCount(); bi++) { IBond bond = org.getBond(bi); if (bond.getAtomCount() != 2) { continue; } IAtom a1 = bond.getAtom(0); IAtom a2 = bond.getAtom(1); if (a1.getSymbol() == "H" && a2.getSymbol() == "N" && GetFormalCharge(a2) > 0) { chg = GetFormalCharge(a2) - 1; SetFormalCharge(a2, chg); atomsToRemove.Add(a1); bondsToRemove.Add(bond); } else if (a2.getSymbol() == "H" && a1.getSymbol() == "N" && GetFormalCharge(a1) > 0) { chg = GetFormalCharge(a1) - 1; SetFormalCharge(a1, chg); atomsToRemove.Add(a2); bondsToRemove.Add(bond); } } // Check for implicit H attached to pos-charged N for (int ai = 0; ai < nOrgAtoms; ai++) { IAtom a = org.getAtom(ai); if (a.getSymbol() == "N" && GetFormalCharge(a) > 0 && GetImplicitHydrogenCount(a) > 0) { chg = GetFormalCharge(a) - 1; SetFormalCharge(a, chg); impHydCnt = GetImplicitHydrogenCount(a) - 1; SetImplicitHydrogenCount(a, impHydCnt); implicitHydRemoved++; } } if (implicitHydRemoved > 0) { implicitHydRemoved = implicitHydRemoved; // debug } if (atomsToRemove.Count == 0) { return(implicitHydRemoved); // just return if no explicit H to remove } // Get list of atoms to keep IAtom[] cpyAtoms = new IAtom[nOrgAtoms - atomsToRemove.Count]; int nCpyAtoms = 0; for (int ai = 0; ai < nOrgAtoms; ai++) { IAtom atom = org.getAtom(ai); if (!atomsToRemove.Contains(atom)) { cpyAtoms[nCpyAtoms++] = atom; } } org.setAtoms(cpyAtoms); // Get list of bonds to keep IBond[] cpyBonds = new IBond[nOrgBonds - bondsToRemove.Count]; int nCpyBonds = 0; for (int bi = 0; bi < org.getBondCount(); bi++) { IBond bond = org.getBond(bi); if (!bondsToRemove.Contains(bond)) { cpyBonds[nCpyBonds++] = bond; } } org.setBonds(cpyBonds); return(atomsToRemove.Count + implicitHydRemoved); }
/// <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; } } } } } } } }