Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <summary>
        /// Is the {@code atom} a suppressible hydrogen and can be represented as
        /// implicit. A hydrogen is suppressible if it is not an ion, not the major
        /// isotope (i.e. it is a deuterium or tritium atom) and is not molecular
        /// hydrogen.
        /// </summary>
        /// <param name="container"> the structure </param>
        /// <param name="graph">     adjacent list representation </param>
        /// <param name="v">         vertex (atom index) </param>
        /// <returns> the atom is a hydrogen and it can be suppressed (implicit) </returns>
        private static bool suppressibleHydrogen(IAtomContainer container, int[][] graph, int v)
        {
            IAtom atom = container.getAtom(v);

            // is the atom a hydrogen
            if (!"H".Equals(atom.getSymbol()))
            {
                return(false);
            }
            // is the hydrogen an ion?
            if (GetFormalCharge(atom) != 0)
            {
                return(false);
            }
            // is the hydrogen deuterium / tritium?
            if (GetMassNumber(atom) != 1)
            {
                return(false);
            }
            // hydrogen is either not attached to 0 or 2 neighbors
            if (graph[v].Length != 1)
            {
                return(false);
            }

            // okay the hydrogen has one neighbor, if that neighbor is not a
            // hydrogen (i.e. molecular hydrogen) then we can suppress it
            return(!"H".Equals(container.getAtom(graph[v][0]).getSymbol()));
        }
Exemple #3
0
        /// <summary>
        /// Is the {@code atom} a suppressible hydrogen and can be represented as
        /// implicit. A hydrogen is suppressible if it is not an ion, not the major
        /// isotope (i.e. it is a deuterium or tritium atom) and is not molecular
        /// hydrogen.
        /// </summary>
        /// <param name="container"> the structure </param>
        /// <param name="atom">      an atom in the structure </param>
        /// <returns> the atom is a hydrogen and it can be suppressed (implicit) </returns>
        private static bool suppressibleHydrogen(IAtomContainer container, IAtom atom)
        {
            // is the atom a hydrogen
            if (!"H".Equals(atom.getSymbol()))
            {
                return(false);
            }
            // is the hydrogen an ion?
            if (GetFormalCharge(atom) != 0)
            {
                return(false);
            }
            // is the hydrogen deuterium / tritium?
            if (GetMassNumber(atom) != 1)
            {
                return(false);
            }
            // molecule hydrogen with implicit H?
            if (atom.getImplicitHydrogenCount() != null && atom.getImplicitHydrogenCount().intValue() != 0)
            {
                return(false);
            }
            // molecule hydrogen
            List <IAtom> neighbors = container.getConnectedAtomsList(atom) as List <IAtom>;

            if (neighbors.Count == 1 && neighbors[0].getSymbol().Equals("H"))
            {
                return(false);
            }
            // what about bridging hydrogens?
            // hydrogens with atom-atom mapping?
            return(true);
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <summary>
        /// GetHeavyAtomCount
        /// </summary>
        /// <param name="mol"></param>
        /// <returns></returns>

        public static int GetHeavyAtomCount(IAtomContainer mol)
        {
            int haCnt = 0;

            for (int ai = 0; ai < mol.getAtomCount(); ai++)
            {
                IAtom atom = mol.getAtom(ai);
                if (atom.getAtomicNumber().intValue() == 1 ||                  // do not count hydrogens
                    atom.getSymbol().Equals("H"))
                {
                    continue;
                }
                else
                {
                    haCnt++;
                }
            }

            return(haCnt);
        }
Exemple #6
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
		/**
		 * Check for the other atoms nearby in the fragment.
		 * 
		 * @param candidateOxygen
		 *            the candidate oxygen atom
		 * @param frag
		 *            the frag
		 * @param proton
		 *            the proton
		 * 
		 * @return true, if successful
		 * @throws CloneNotSupportedException
		 * @throws CDKException
		 */

		private IAtomContainer checkForCompleteNeutralLoss(IAtomContainer frag, IAtom candidateAtom, double neutralLossMass)
		{
			IAtomContainer ret = new AtomContainer();

			// create a copy from the original fragment
			var part = new List<IBond>();
			part = traverse(frag, candidateAtom, part);
			var fragCopy = makeAtomContainer(candidateAtom, part);

			// set properties again
			var properties = frag.getProperties();
			fragCopy.setProperties(properties);

			// now get the other atoms from the neutral loss
			var atomsToFind = new List<string>();
			var addHydrogen = false;
			// one hydrogen is lost with the neutral loss
			if (neutralLoss[neutralLossMass].HydrogenDifference == -1)
			{
				foreach (var isotope in neutralLoss[neutralLossMass].ElementalComposition.isotopes().ToWindowsEnumerable<IIsotope>())
				{
					var c = neutralLoss[neutralLossMass].ElementalComposition.getIsotopeCount(isotope);

					for (var i = 0; i < c; i++)
					{
						atomsToFind.Add(isotope.getSymbol());
					}
				}
			}
			else
			{
				foreach (var isotope in neutralLoss[neutralLossMass].TopoFragment.isotopes().ToWindowsEnumerable<IIsotope>())
				{
					var c = neutralLoss[neutralLossMass].ElementalComposition.getIsotopeCount(isotope);

					for (var i = 0; i < c; i++)
					{
						atomsToFind.Add(isotope.getSymbol());
					}
					addHydrogen = true;
				}
			}

			// at most 2 bonds between the oxygen and other atoms (at most 1 H and 2
			// C)
			var count = neutralLoss[neutralLossMass].Distance;
			// list storing all atoms to be removed later on if complete neutral
			// loss was found
			var foundAtoms = new List<IAtom>();
			// list storing all bonds to remove
			var foundBonds = new List<IBond>();
			// list storing all bonds already checked
			var checkedBonds = new List<IBond>();
			// list storing all checked atoms
			var checkedAtoms = new List<IAtom>();
			// queue storing all bonds to check for a particular distance
			var bondQueue = new List<IBond>();
			// List storing all bonds to be checked for the next distance
			var bondsFurther = new List<IBond>();
			// get all bonds from this atom distance = 1

			var bondList = fragCopy.getConnectedBondsList(candidateAtom);
			foreach (var bond in bondList.ToWindowsEnumerable<IBond>())
			{
				if (bond != null)
				{
					bondQueue.Add(bond);
				}
			}

			var hydrogenStartAtom = neutralLoss[neutralLossMass].HydrogenOnStartAtom;
			var firstBonds = true;

			while (count > 0)
			{
				IBond currentBond = null;
				if (bondQueue.Count > 0)
				{
					currentBond = bondQueue[bondQueue.Count - 1];
					bondQueue.RemoveAt(bondQueue.Count - 1);
				}

				// check for already tried bonds
				if (checkedBonds.Contains(currentBond) && currentBond != null)
				{
					continue;
				}
				else if (currentBond != null)
				{
					checkedBonds.Add(currentBond);
				}

				if (currentBond != null)
				{
					foreach (var atom in currentBond.atoms().ToWindowsEnumerable<IAtom>())
					{
						// check for already tried atoms
						if (checkedAtoms.Contains(atom))
						{
							continue;
						}
						else
						{
							checkedAtoms.Add(atom);
						}

						if (firstBonds && atom.getSymbol().Equals("H"))
						{
							hydrogenStartAtom--;
						}

						// thats the starting atom
						if (atom.getSymbol().Equals(candidateAtom.getSymbol()))
						{
							var removed = atomsToFind.Remove(candidateAtom.getSymbol());
							if (removed)
							{
								foundAtoms.Add(atom);
								// remove bond
								if (!foundBonds.Contains(currentBond))
								{
									foundBonds.Add(currentBond);
								}
							}
								// this bond has to be removed
							else if (!foundBonds.Contains(currentBond) && atomsToFind.Contains(atom.getSymbol()))
							{
								foundBonds.Add(currentBond);
							}

							continue;
						}
						// found atom...remove it from the atoms to find list
						// do not remove atoms from ring
						if (atomsToFind.Contains(atom.getSymbol()) && !allRings.contains(atom) && atomsToFind.Count > 0)
						{
							var removed = atomsToFind.Remove(atom.getSymbol());
							if (removed)
							{
								foundAtoms.Add(atom);
							}
							else
							{
								continue;
							}

							if (!foundBonds.Contains(currentBond))
							{
								foundBonds.Add(currentBond);
							}

							continue;
						}

						// only walk along C-Atoms!
						if (!atom.getSymbol().Equals("C"))
						{
							continue;
						}

						// get new bonds
						var bondsToAddTemp = fragCopy.getConnectedBondsList(atom);

						foreach (var bond in bondsToAddTemp.ToWindowsEnumerable<IBond>())
						{
							if (bond != null)
							{
								bondsFurther.Add(bond);
							}
						}
					}
				}

				// break condition
				if (currentBond == null && bondQueue.Count == 0 && bondsFurther.Count == 0)
				{
					break;
				}

				// now check if the queue is empty...checked all bonds in this
				// distance
				if (bondQueue.Count == 0)
				{
					count--;
					// set new queue data
					foreach (var bond in bondsFurther)
					{
						if (bond != null)
						{
							bondQueue.Add(bond);
						}
					}
					// reinitialize
					bondsFurther = new List<IBond>();
					// the initially connected bonds are all checked!
					firstBonds = false;
				}
			}

			// found complete neutral loss
			if (atomsToFind.Count == 0)
			{
				foreach (var atom in foundAtoms)
				{
					fragCopy.removeAtomAndConnectedElectronContainers(atom);
				}

				// TODO add hydrogen somewhere
				if (addHydrogen)
				{
					var props = fragCopy.getProperties();
					props.put("hydrogenAddFromNL", "1");
					fragCopy.setProperties(props);
				}

				// add fragment to return if enough H were connected and fragment is
				// still connected
				if (hydrogenStartAtom <= 0)
				{
					ret.add(fragCopy);
				}
			}

			return ret;
		}