public void TestClone_Isotopes() { MolecularFormulaRange mfRange = new MolecularFormulaRange(); IIsotope carb = builder.NewIsotope("C"); IIsotope flu = builder.NewIsotope("F"); IIsotope h1 = builder.NewIsotope("H"); mfRange.AddIsotope(carb, 0, 5); mfRange.AddIsotope(flu, 2, 8); mfRange.AddIsotope(h1, 4, 10); Assert.AreEqual(3, mfRange.Count); Assert.AreEqual(0, mfRange.GetIsotopeCountMin(carb)); Assert.AreEqual(2, mfRange.GetIsotopeCountMin(flu)); Assert.AreEqual(4, mfRange.GetIsotopeCountMin(h1)); Assert.AreEqual(5, mfRange.GetIsotopeCountMax(carb)); Assert.AreEqual(8, mfRange.GetIsotopeCountMax(flu)); Assert.AreEqual(10, mfRange.GetIsotopeCountMax(h1)); object clone = mfRange.Clone(); Assert.IsTrue(clone is MolecularFormulaRange); Assert.AreEqual(mfRange.Count, ((MolecularFormulaRange)clone).Count); Assert.AreEqual(3, ((MolecularFormulaRange)clone).Count); Assert.AreEqual(3, ((MolecularFormulaRange)clone).Count); Assert.AreEqual(0, ((MolecularFormulaRange)clone).GetIsotopeCountMin(carb)); Assert.AreEqual(2, ((MolecularFormulaRange)clone).GetIsotopeCountMin(flu)); Assert.AreEqual(4, ((MolecularFormulaRange)clone).GetIsotopeCountMin(h1)); Assert.AreEqual(5, ((MolecularFormulaRange)clone).GetIsotopeCountMax(carb)); Assert.AreEqual(8, ((MolecularFormulaRange)clone).GetIsotopeCountMax(flu)); Assert.AreEqual(10, ((MolecularFormulaRange)clone).GetIsotopeCountMax(h1)); }
public void TestGetIsotopeCountMax_IIsotope() { MolecularFormulaRange mfRange = new MolecularFormulaRange(); IIsotope carb = builder.NewIsotope("C"); IIsotope h1 = builder.NewIsotope("H"); mfRange.AddIsotope(carb, 0, 10); mfRange.AddIsotope(h1, 0, 10); Assert.AreEqual(2, mfRange.Count); Assert.AreEqual(10, mfRange.GetIsotopeCountMax(carb)); Assert.AreEqual(10, mfRange.GetIsotopeCountMax(h1)); }
/// <summary> /// Initiate the MolecularFormulaGenerator. /// </summary> /// <param name="minMass">Lower boundary of the target mass range</param> /// <param name="maxMass">Upper boundary of the target mass range</param> /// <param name="mfRange">A range of elemental compositions defining the search space</param> /// <exception cref="ArgumentOutOfRangeException">In case some of the isotopes in mfRange has undefined exact mass or in case illegal parameters are provided (e.g., negative mass values or empty MolecularFormulaRange)</exception> /// <seealso cref="MolecularFormulaRange"/> internal RoundRobinFormulaGenerator(IChemObjectBuilder builder, double minMass, double maxMass, MolecularFormulaRange mfRange) { this.builder = builder; var isotopes = new List <IIsotope>(mfRange.GetIsotopes().Count()); foreach (IIsotope iso in mfRange.GetIsotopes()) { if (mfRange.GetIsotopeCountMin(iso) >= 0 && mfRange.GetIsotopeCountMax(iso) > 0) { isotopes.Add(iso); } } this.decomposer = DecomposerFactory.Instance.GetDecomposerFor(isotopes.ToArray()).DecomposeIterator(minMass, maxMass, mfRange); this.done = false; this.mfRange = mfRange; }
/// <summary> /// Returns an iterator over all decompositons of this mass range /// </summary> /// <param name="from">lowest mass to decompose</param> /// <param name="to">(inclusive) largest mass to decompose</param> /// <param name="boundaries">defines lowerbounds and upperbounds for the number of elements</param> internal DecompIterator DecomposeIterator(double from, double to, MolecularFormulaRange boundaries) { Init(); if (to < 0d || from < 0d) { throw new ArgumentException("Expect positive mass for decomposition: [" + from + ", " + to + "]"); } if (to < from) { throw new ArgumentException("Negative range given: [" + from + ", " + to + "]"); } int[] minValues = new int[weights.Count]; int[] boundsarray = new int[weights.Count]; double cfrom = from, cto = to; Arrays.Fill(boundsarray, int.MaxValue); if (boundaries != null) { for (int i = 0; i < boundsarray.Length; i++) { IIsotope el = weights[i].GetOwner(); int max = boundaries.GetIsotopeCountMax(el); int min = boundaries.GetIsotopeCountMin(el); if (min >= 0 || max >= 0) { boundsarray[i] = max - min; minValues[i] = min; if (minValues[i] > 0) { double reduceWeightBy = weights[i].GetMass() * min; cfrom -= reduceWeightBy; cto -= reduceWeightBy; } } } } int[] minmax = new int[2]; IntegerBound(cfrom, cto, minmax); int deviation = minmax[1] - minmax[0]; //calculate the required ERTs if ((1 << (ERTs.Length - 1)) <= deviation) { CalcERT(deviation); } { int[][][] ERTs = this.ERTs; //take ERT with required deviation int[][] currentERT; if (deviation == 0) { currentERT = ERTs[0]; } else { currentERT = ERTs[32 - Ints.NumberOfLeadingZeros(deviation)]; } return(new DecompIterator(currentERT, minmax[0], minmax[1], from, to, minValues, boundsarray, weights)); } }
/// <summary> /// Initiate the MolecularFormulaGenerator. /// </summary> /// <param name="minMass">Lower boundary of the target mass range</param> /// <param name="maxMass">Upper boundary of the target mass range</param> /// <param name="mfRange">A range of elemental compositions defining the search space</param> /// <exception cref="ArgumentOutOfRangeException">In case some of the isotopes in mfRange has undefined exact mass or in case illegal parameters are provided (e.g., negative mass values or empty MolecularFormulaRange)</exception> /// <seealso cref="MolecularFormulaRange"/> public FullEnumerationFormulaGenerator(IChemObjectBuilder builder, double minMass, double maxMass, MolecularFormulaRange mfRange) { Trace.TraceInformation("Initiate MolecularFormulaGenerator, mass range " + minMass + "-" + maxMass); // Check parameter values if (minMass < 0.0) { throw (new ArgumentOutOfRangeException(nameof(minMass), "The minimum and maximum mass values must be >=0")); } if (maxMass < 0.0) { throw (new ArgumentOutOfRangeException(nameof(maxMass), "The minimum and maximum mass values must be >=0")); } if ((minMass > maxMass)) { throw (new ArgumentException("Minimum mass must be <= maximum mass")); } if ((mfRange == null) || (mfRange.GetIsotopes().Count() == 0)) { throw (new ArgumentException("The MolecularFormulaRange parameter must be non-null and must contain at least one isotope")); } // Save the parameters this.builder = builder; this.minMass = minMass; this.maxMass = maxMass; // Sort the elements by mass in ascending order. That speeds up // the search. var isotopesSet = new SortedSet <IIsotope>( new IIsotopeSorterByMass()); foreach (IIsotope isotope in mfRange.GetIsotopes()) { // Check if exact mass of each isotope is set if (isotope.ExactMass == null) { throw new ArgumentException($"The exact mass value of isotope {isotope} is not set"); } isotopesSet.Add(isotope); } isotopes = isotopesSet.ToArray(); // Save the element counts from the provided MolecularFormulaRange minCounts = new int[isotopes.Length]; maxCounts = new int[isotopes.Length]; for (int i = 0; i < isotopes.Length; i++) { minCounts[i] = mfRange.GetIsotopeCountMin(isotopes[i]); maxCounts[i] = mfRange.GetIsotopeCountMax(isotopes[i]); // Update the maximum count according to the mass limit int maxCountAccordingToMass = (int)Math.Floor(maxMass / isotopes[i].ExactMass.Value); if (maxCounts[i] > maxCountAccordingToMass) { maxCounts[i] = maxCountAccordingToMass; } } // Set the current counters to minimal values, initially currentCounts = Arrays.CopyOf(minCounts, minCounts.Length); }