Ejemplo n.º 1
0
		/**
		 * 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;
		}