/// <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.Atoms.Count]; IBond[] bonds = new IBond[src.Bonds.Count]; IChemObjectBuilder builder = src.Builder; for (int i = 0; i < atoms.Length; i++) { IAtom atom = src.Atoms[i]; IAtom atom2 = builder.NewAtom(atom.Symbol); SetImplicitHydrogenCount(atom2, GetImplicitHydrogenCount(atom)); atom2.Point2D = atom.Point2D; atoms[i] = atom2; } for (int i = 0; i < bonds.Length; i++) { IBond bond = src.Bonds[i]; int u = bond.Atoms[0].Index; int v = bond.Atoms[1].Index; IBond bond2 = builder.NewBond(atoms[u], atoms[v]); bond2.IsAromatic = bond.IsAromatic; bond2.IsInRing = bond.IsInRing; bond2.Order = bond.Order; bond2.IsAromatic = bond.IsAromatic; bond2.IsSingleOrDouble = bond.IsSingleOrDouble; bonds[i] = bond2; } IAtomContainer dest = ChemObjectBuilder.Instance.NewAtomContainer(); dest.SetAtoms(atoms); dest.SetBonds(bonds); AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(dest); dest = AtomContainerManipulator.SuppressHydrogens(dest); GetHydrogenAdder().AddImplicitHydrogens(dest); return(dest); }
public void TestTraversal_Chain() { var builder = CDK.Builder; IAtom[] atoms = new IAtom[] { builder.NewAtom("C"), builder.NewAtom("C"), builder.NewAtom("C"), builder.NewAtom("C"), builder.NewAtom("C"), builder.NewAtom("C") }; IBond[] bonds = new IBond[] { builder.NewBond(atoms[0], atoms[1]), builder.NewBond(atoms[1], atoms[2]), builder.NewBond(atoms[2], atoms[3]), builder.NewBond(atoms[3], atoms[4]), builder.NewBond(atoms[4], atoms[5]) }; IAtomContainer m = builder.NewAtomContainer(); m.SetAtoms(atoms); m.SetBonds(bonds); List <IBond> accumulator = new List <IBond>(); // traverse from one end FragmentUtils.Traverse(m, atoms[0], accumulator); Assert.AreEqual(5, accumulator.Count); Assert.AreEqual(bonds[0], accumulator[0]); Assert.AreEqual(bonds[1], accumulator[1]); Assert.AreEqual(bonds[2], accumulator[2]); Assert.AreEqual(bonds[3], accumulator[3]); Assert.AreEqual(bonds[4], accumulator[4]); // traverse from the middle accumulator.Clear(); FragmentUtils.Traverse(m, atoms[3], accumulator); Assert.AreEqual(5, accumulator.Count); Assert.AreEqual(bonds[2], accumulator[0]); Assert.AreEqual(bonds[1], accumulator[1]); Assert.AreEqual(bonds[0], accumulator[2]); Assert.AreEqual(bonds[3], accumulator[3]); Assert.AreEqual(bonds[4], accumulator[4]); }
/// <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.Atoms.Count; ai++) { IAtom atom = org.Atoms[ai]; if ("H".Equals(atom.Symbol)) { 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.Atoms.Count; int nOrgBonds = org.Bonds.Count; 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.Atoms[v]; if (suppressibleHydrogen(org, graph, v)) { hydrogens.Add(atom); incrementImplHydrogenCount(org.Atoms[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.Bonds.Count; bi++) { IBond bond = org.Bonds[bi]; if (remaining > 0 && (hydrogens.Contains(bond.Atoms[0]) || hydrogens.Contains(bond.Atoms[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> /// 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.Atoms.Count; int nOrgBonds = org.Bonds.Count; // Get H atoms and their bonds to pos-charged Nitrogen, adjusting charge for (int bi = 0; bi < org.Bonds.Count; bi++) { IBond bond = org.Bonds[bi]; if (bond.Atoms.Count != 2) { continue; } IAtom a1 = bond.Atoms[0]; IAtom a2 = bond.Atoms[1]; if (a1.Symbol == "H" && a2.Symbol == "N" && GetFormalCharge(a2) > 0) { chg = GetFormalCharge(a2) - 1; SetFormalCharge(a2, chg); atomsToRemove.Add(a1); bondsToRemove.Add(bond); } else if (a2.Symbol == "H" && a1.Symbol == "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.Atoms[ai]; if (a.Symbol == "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.Atoms[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.Bonds.Count; bi++) { IBond bond = org.Bonds[bi]; if (!bondsToRemove.Contains(bond)) { cpyBonds[nCpyBonds++] = bond; } } org.SetBonds(cpyBonds); return(atomsToRemove.Count + implicitHydRemoved); }