public Pattern Calculate(FormMap fm, double limit, long charge) { Pattern tmp = new Pattern(); Pattern result = new Pattern(); result.Add(new Peak() { Mz = 0.0, Intensity = 1.0 }); foreach (var i in fm) { int atom_index = i.Key; SuperAtomList sal = sad[atom_index]; int n = i.Value; int j = 0; while (n > 0) { int sz = sal.Count; if (j == sz) { sal.Add(new Pattern()); convolute_basic(sal[j], sal[j - 1], sal[j - 1]); Prune(sal[j], limit); } if ((n & 1) == 1) { // digit is 1, convolute result convolute_basic(tmp, result, sal[j]); Prune(tmp, limit); result.Clear(); result.AddRange(tmp); } n >>= 1; j++; } } // take charge into account foreach (var p in result) { if (charge > 0) { p.Mz = p.Mz / Math.Abs(charge) - ELECTRON_MASS; } else if (charge < 0) { p.Mz = p.Mz / Math.Abs(charge) + ELECTRON_MASS; } } if (result.Count == 0) { throw new Exception("Calculate profile failed"); } return(result); }