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);
        }
        public object Clone()
        {
            FormMap result = new FormMap();

            foreach (var key in this.Keys)
            {
                result[key] = this[key];
            }
            return(result);
        }
 public void Add(FormMap add)
 {
     foreach (var key in add.Keys)
     {
         if (this.ContainsKey(key))
         {
             this[key] = this[key] + add[key];
         }
         else
         {
             this[key] = add[key];
         }
     }
     CleanUp();
 }
 public void Subtract(FormMap sub)
 {
     foreach (var key in sub.Keys)
     {
         if (this.ContainsKey(key))
         {
             this[key] = this[key] - sub[key];
         }
         else
         {
             this[key] = -sub[key];
         }
     }
     CleanUp();
 }
        public Pattern Calculate(AtomComposition ac, double limit, long charge)
        {
            FormMap fm = new FormMap();

            foreach (var key in ac.Keys)
            {
                if (IsotopicMap.ContainsKey(key.Symbol))
                {
                    fm[IsotopicMap[key.Symbol]] = ac[key];
                }
                else
                {
                    throw new Exception(MyConvert.Format("Atom {0} is not defined in EmassCalculator", key.Symbol));
                }
            }

            return(Calculate(fm, limit, charge));
        }