public double CheckIsotope(RawData Peaks, double MZ, int Charge, int Isotope)
        {
            double TargetMass = MZ + (1.003 / (double)Charge) * (double)Isotope;

            MZData Peak = Peaks.FindNearestPeak(TargetMass, MassError);

            return(Peak.Intensity);
        }
        bool hasPreviousIsotope(RawData Peaks, MZData Peak, int Charge)
        {
            double expectedMass = Peak.Mass - (1.003 / (double)Charge);

            MZData Candidate = Peaks.FindBiggestPeak(expectedMass, MassError);

            if (Candidate.Mass != 0.0 && Candidate.Intensity > 0.5 * Peak.Intensity)
            {
                return(true);
            }
            return(false);
        }
        public MSMatch FindMatch(int Scan, double MZ, int Charge)
        {
            MSMatch ret = new MSMatch();

            ret.TimeCoeff = RTCorrection?TimeCoefs[Scan]:1;

            RawData Peaks = RawSpectra[ms2index[Scan]];

            MZData FirstPeak = Peaks.FindBiggestPeak(MZ, MassError);

            if (hasPreviousIsotope(Peaks, FirstPeak, Charge))             //skip this mass if Seq turns out Seq's a part of another peak
            {
                return(ret);
            }

            ret.FirstIsotope = FirstPeak.Intensity;
            if (Program.Processor.MetaProfile)
            {
                ret.Score         = ret.FirstIsotope;
                ret.SecondIsotope = 0.0;
            }
            else
            {
                ret.SecondIsotope = CheckIsotope(Peaks, FirstPeak.Mass, Charge, 1);
                ret.Score         = ret.FirstIsotope + ret.SecondIsotope;
                if (ret.SecondIsotope != 0.0)
                {
                    ret.Score += CheckIsotope(Peaks, FirstPeak.Mass, Charge, 2);
                }
            }

            ret.MZ = FirstPeak.Mass;
            ret.RT = Peaks.RT;

            if (RTCorrection)
            {
                ret.Score *= TimeCoefs[Scan];
            }


            if (ret.SecondIsotope == 0.0 && !Program.Processor.MetaProfile)
            {
                ret.Score = 0.0;
            }

            return(ret);
        }
        /*        public MZData[] PeakDetect(MZData[] Data ){

            PeakDetecting.PeakDetector pd = new PeakDetecting.PeakDetector();
            PeakDetecting.peakinside[] Peaks = new PeakDetecting.peakinside[1];
            pd.PeaksDetecting(ref Data, ref Peaks);
            MZData[] OutData = new MZData[Peaks.GetLength(0)];
            for (int i = 0 ; i < Peaks.GetLength(0) ; i++){
                OutData[i].Intensity = Peaks[i].Value;
                OutData[i].Mass = Peaks[i].Center;
            }
            return OutData;
        }*/
        public MZData[] Centroid(MZData[] Data,int Len, bool StickMode /* former "in" */)
        {
            int total = 0, u;
            int o = 0, i = 0, count = Len;
            double sumIi, sumI, last = 0.0;
            double du = 0.0;
            bool goingdown = false;
            MZData[] OutData;

            if (StickMode) {
                //считаем пока не начнутся нули или пока следующий не станет меньше помассе
                for ( i = 1 ; i<count ; i++){
                    if (Data[i].Mass < Data[i-1].Mass || Data[i].Mass == 0){
                        break;
                    }
                }
                OutData = new MZData[i];
                count = i;
                for (i=0; i<count ; i++){
                    OutData[i].Intensity = Data[i].Intensity;
                    OutData[i].Mass = Data[i].Mass;
                }
                return OutData;
            }

            //пропуск начальных нулей
            while(i < count && Data[i].Intensity == 0.0) ++i;

            //считает области больше нуля
            while(i < count)
            {
                while(i < count && Data[i].Intensity != 0.0)
                {
                    if(last > Data[i].Intensity) {
                        goingdown = true;
                    }else{
                        if(goingdown) {
                            ++total;
                            goingdown = false;
                        }
                    }

                    last = Data[i].Intensity;
                    ++i;
                }

                last = 0.0;
                goingdown = false;

                while(i < count && Data[i].Intensity == 0.0)
                    i++;

                total++;
            }

            //запасает память на подсчитанные области
            OutData = new MZData[total];
            i = 0; o = 0; total = 0; last = 0.0; goingdown = false;

            while(i < count && Data[i].Intensity == 0.0) i++;

            while(i < count)
            {
                sumIi = sumI = 0.0;
                o = i -1;
                while(i < count && Data[i].Intensity != 0.0){

                    //если пошло на спад
                    if(last > Data[i].Intensity) {
                        goingdown = true;
                    }else{
                        if(goingdown) {
                            u = Convert.ToInt32((sumIi / sumI)/* + 0.5*/);
                            OutData[total].Intensity = sumI;
                            OutData[total].Mass = Data[o+u].Mass;
                            ++total;

                            sumIi = sumI = 0.0;
                            o = i -1;
                            goingdown = false;
                        }
                    }

                    sumIi += Data[i].Intensity*(i-o);
                    sumI += Data[i].Intensity;

                    last = Data[i].Intensity;
                    i++;
                }

                u = Convert.ToInt32((sumIi / sumI) /*+0.5*/ );
                du = sumIi / sumI - (double)u;
                //интенсивность по интегралу
                OutData[total].Intensity = sumI;
                //сентроид - по апексу
                //OutData[total].Mass = Data[o+u].Mass;
                //центроид по центру
                OutData[total].Mass = Data[o+u].Mass*(1-du) + Data[o+u+1].Mass*du;

                last = 0.0;
                goingdown = false;

                while(i < count && Data[i].Intensity == 0.0)
                    i++;
                total++;
            }
            return OutData;
        }
/*        public MZData[] PeakDetect(MZData[] Data ){
 *
 *          PeakDetecting.PeakDetector pd = new PeakDetecting.PeakDetector();
 *          PeakDetecting.peakinside[] Peaks = new PeakDetecting.peakinside[1];
 *          pd.PeaksDetecting(ref Data, ref Peaks);
 *              MZData[] OutData = new MZData[Peaks.GetLength(0)];
 *          for (int i = 0 ; i < Peaks.GetLength(0) ; i++){
 *              OutData[i].Intensity = Peaks[i].Value;
 *              OutData[i].Mass = Peaks[i].Center;
 *          }
 *          return OutData;
 *      }*/

        public MZData[] Centroid(MZData[] Data, int Len, bool StickMode /* former "in" */)
        {
            int    total = 0, u;
            int    o = 0, i = 0, count = Len;
            double sumIi, sumI, last = 0.0;
            double du        = 0.0;
            bool   goingdown = false;

            MZData[] OutData;

            if (StickMode)
            {
                //считаем пока не начнутся нули или пока следующий не станет меньше помассе
                for (i = 1; i < count; i++)
                {
                    if (Data[i].Mass < Data[i - 1].Mass || Data[i].Mass == 0)
                    {
                        break;
                    }
                }
                OutData = new MZData[i];
                count   = i;
                for (i = 0; i < count; i++)
                {
                    OutData[i].Intensity = Data[i].Intensity;
                    OutData[i].Mass      = Data[i].Mass;
                }
                return(OutData);
            }


            //пропуск начальных нулей
            while (i < count && Data[i].Intensity == 0.0)
            {
                ++i;
            }

            //считает области больше нуля
            while (i < count)
            {
                while (i < count && Data[i].Intensity != 0.0)
                {
                    if (last > Data[i].Intensity)
                    {
                        goingdown = true;
                    }
                    else
                    {
                        if (goingdown)
                        {
                            ++total;
                            goingdown = false;
                        }
                    }

                    last = Data[i].Intensity;
                    ++i;
                }

                last      = 0.0;
                goingdown = false;

                while (i < count && Data[i].Intensity == 0.0)
                {
                    i++;
                }

                total++;
            }

            //запасает память на подсчитанные области
            OutData = new MZData[total];
            i       = 0; o = 0; total = 0; last = 0.0; goingdown = false;

            while (i < count && Data[i].Intensity == 0.0)
            {
                i++;
            }

            while (i < count)
            {
                sumIi = sumI = 0.0;
                o     = i - 1;
                while (i < count && Data[i].Intensity != 0.0)
                {
                    //если пошло на спад
                    if (last > Data[i].Intensity)
                    {
                        goingdown = true;
                    }
                    else
                    {
                        if (goingdown)
                        {
                            u = Convert.ToInt32((sumIi / sumI) /* + 0.5*/);
                            OutData[total].Intensity = sumI;
                            OutData[total].Mass      = Data[o + u].Mass;
                            ++total;

                            sumIi     = sumI = 0.0;
                            o         = i - 1;
                            goingdown = false;
                        }
                    }

                    sumIi += Data[i].Intensity * (i - o);
                    sumI  += Data[i].Intensity;

                    last = Data[i].Intensity;
                    i++;
                }

                u  = Convert.ToInt32((sumIi / sumI) /*+0.5*/);
                du = sumIi / sumI - (double)u;
                //интенсивность по интегралу
                OutData[total].Intensity = sumI;
                //сентроид - по апексу
                //OutData[total].Mass = Data[o+u].Mass;
                //центроид по центру
                OutData[total].Mass = Data[o + u].Mass * (1 - du) + Data[o + u + 1].Mass * du;

                last      = 0.0;
                goingdown = false;

                while (i < count && Data[i].Intensity == 0.0)
                {
                    i++;
                }
                total++;
            }
            return(OutData);
        }