public QPeptide(MascotParser mp, int Index)
        {
            MascotSpectra ms = mp.Spectra[Index];
            string        buf;

            MascotMZ = ms.mz;
            if (ms.RTApex == 0.0)
            {
                MascotRT = ms.RT;
            }
            else
            {
                MascotRT = ms.RTApex;
            }
            MascotScan = ms.ScanNumber;
            IPIs       = new List <string>();
            Charge     = ms.Charge;
            if (ms.Peptides.Count > 0)
            {
                Peptide Pep = ms.Peptides[0];
                for (int j = 0; j < Pep.ProteinNames.Length; j++)
                {
                    buf = Pep.ProteinNames[j];
                    if (buf[0] == '\"')
                    {
                        buf = buf.Substring(1);
                    }
                    if (buf[buf.Length - 1] == '\"')
                    {
                        buf = buf.Substring(0, buf.Length - 1);
                    }
                    IPIs.Add(buf);
                }
                MascotScore = Pep.Score;
                Sequence    = Pep.Sequence;
                //модификации
                ModMass = 0.0;
                if (Pep.NModIndex != 0)
                {
                    ModMass += mp.VaryMods[Pep.NModIndex].Mass;
                    ModDesk += mp.VaryMods[Pep.NModIndex].Name + " on N-Terminus; ";
                }
                for (int k = 0; k < Pep.ModIndex.GetLength(0); k++)
                {
                    if (Pep.ModIndex[k] != 0)
                    {
                        ModMass += mp.VaryMods[Pep.ModIndex[k]].Mass;
                        ModDesk += mp.VaryMods[Pep.ModIndex[k]].Name + " on position " + k.ToString() + "; ";
                    }
                }
                if (Pep.CModIndex != 0)
                {
                    ModMass += mp.VaryMods[Pep.CModIndex].Mass;
                    ModDesk += mp.VaryMods[Pep.CModIndex].Name + " on C-Terminus; ";
                }
            }
            Matches         = null;
            AlreadySearched = false;
            BandID          = -1;
        }
        public QMSMSList(MascotParser mp)
        {
            Entries = new List <QMSMSEntry>();
            QMSMSEntry Entry;

            for (int i = 0; i < mp.Spectra.Count; i++)
            {
                Entry          = new QMSMSEntry();
                Entry.Approved = true;
                Entry.ms       = mp.Spectra[i];
                Entry.Match    = null;
                Entry.FSN      = mp.Spectra[i].ScanNumber;
                Entries.Add(Entry);
            }
            byFSN = new QMSMSEntrybyFSN();
            Entries.Sort(byFSN);
        }
        static public void FillMSMSLists(
            ref List <QPeptide> Mascots,
            ref List <QPeptide> MSMSList,
            ref List <QProtein> Proteins,
            MascotParser mp)
        {
            Mascots  = new List <QPeptide>();
            MSMSList = new List <QPeptide>();
            QPeptide     data;
            int          Best, i, j, k;
            SpectrabySeq comp = new SpectrabySeq();

            mp.Spectra.Sort(comp);

            for (i = 0; i < mp.Spectra.Count; i++)
            {
                //если нет пептидов
                if (mp.Spectra[i].Peptides.Count == 0)
                {
                    data      = new QPeptide(mp, i);
                    data.Case = "No peptides identified";
                    MSMSList.Add(data);
                    continue;
                }
                //если у пептидов слишком маленький Score
                if (mp.Spectra[i].Peptides[0].Score < Convert.ToDouble(Settings.Default.MascotScore))
                {
                    data      = new QPeptide(mp, i);
                    data.Case = "Peptides identified under score limit";
                    MSMSList.Add(data);
                    continue;
                }

                Best = i;
                if (Settings.Default.MascotScoreFiltering)
                {
                    for (j = i + 1; j < mp.Spectra.Count; j++)
                    {
                        if (mp.Spectra[i].Peptides[0].Sequence != mp.Spectra[j].Peptides[0].Sequence)
                        {
                            break;
                        }
                        //определяем идентичность набора модификаций
                        for (k = 0; k < mp.Spectra[i].Peptides[0].ModIndex.GetLength(0); k++)
                        {
                            if (mp.Spectra[i].Peptides[0].ModIndex[k] !=
                                mp.Spectra[j].Peptides[0].ModIndex[k])
                            {
                                break;
                            }
                        }
                        if (k < mp.Spectra[i].Peptides[0].ModIndex.GetLength(0) ||
                            mp.Spectra[i].Peptides[0].CModIndex != mp.Spectra[j].Peptides[0].CModIndex ||
                            mp.Spectra[i].Peptides[0].NModIndex != mp.Spectra[j].Peptides[0].NModIndex)
                        {
                            break;
                        }
                        //поиск лучшего по Score
                        if (mp.Spectra[j].Peptides[0].Score > mp.Spectra[Best].Peptides[0].Score)
                        {
                            Best = j;
                        }
                    }
                    //отмечаем нелучшие в списке всех MS/MS
                    for (k = i; k < j; k++)
                    {
                        if (k != Best)
                        {
                            data      = new QPeptide(mp, k);
                            data.Case = string.Format("Not the best score ({0}) for peptide {1} (Max={2})",
                                                      mp.Spectra[k].Peptides[0].Score,
                                                      mp.Spectra[k].Peptides[0].Sequence,
                                                      mp.Spectra[Best].Peptides[0].Score);
                            MSMSList.Add(data);
                        }
                    }
                    i = j - 1;
                }

                //только для лучшего по Score если пептид идентифицирован более одного раза
                data = new QPeptide(mp, Best);
                Mascots.Add(data);
            }

            //Фильтруем IPI
            //Спектр не может соответствовать нескольким IPI за исключением случая когда
            //набор спектров идентифицирующих один IPI является подмножеством (возможно полным)
            //спектров идентифицирующих другой IPI

            //собираем набор тех из них которые являются подмножествами других
            List <string> Processed = new List <string>(); //список в который откладываются
            List <string> ipiset    = new List <string>(); //список всех IPI пептида кроме проверяемого
            List <string> NotDeps   = new List <string>();

            string[] dataexipis = null;
            foreach (QPeptide dataex in Mascots)   //для каждого пептида
            {
                dataexipis = new string[dataex.IPIs.Count];
                dataex.IPIs.CopyTo(dataexipis);
                foreach (string ipi in dataexipis)
                {
                    if (!StringContains(ref Processed, ipi)) //если данный ipi еще не находится в списке обработанных
                    {
                        ipiset.Clear();                      //составляем множество всех IPI пептида кроме проверяемого
                        ipiset.AddRange(dataex.IPIs);
                        StringRemove(ref ipiset, ipi);
                        foreach (QPeptide chdata in Mascots) //составленный список будем соотносить с полным набором пептидов
                        {
                            if (dataex.MascotRT != chdata.MascotRT &&
                                StringContains(ref chdata.IPIs, ipi))
                            {
                                //в этот момент мы установили что dataex и chdata имеют общий ipi
                                foreach (string ipicheck in ipiset)
                                {
                                    //здесь мы отбираем в Nodepts идентификаторы
                                    //которые не появляются вместе с ipi
                                    //отбор такого идентификатора в NoDepts означает что существует хотя бы один пептид
                                    // относящийся к ipi но не относящийся к этому идентификатору
                                    //и следовательно ipi не является зависимым от такого идентификатора
                                    if (!StringContains(ref chdata.IPIs, ipicheck) &&
                                        !StringContains(ref NotDeps, ipicheck)) //если есть хотя бы один пептид с проверяемым IPI
                                    {
                                        NotDeps.Add(ipicheck);                  //не несущий какго-то из IPI начального списка
                                                                                //то целевой IPI не является зависимым от отсутствующего
                                    }
                                }
                            }
                        }
                        //если есть хотя бы один идентификатор который всегда встречается вместе с ipi
                        //то в список Nodepts он никогда не попадет и неполнота списка Nodepts будет признаком
                        //того что ipi зависит от другого идентификатора и должен быть исключен из списка
                        //идентификаторов во всех пептидах
                        if (ipiset.Count != NotDeps.Count)
                        {
                            foreach (QPeptide chdata in Mascots)
                            {
                                StringRemove(ref chdata.IPIs, ipi);
                            }
                        }
                        else
                        {
                            Processed.Add(ipi);
                        }
                        NotDeps.Clear();
                    }
                }
            }

            iLog.RepProgress(50);
            //и теперь переносим только непротиворечивые
            List <QPeptide> OldMascots = Mascots;

            Mascots = new List <QPeptide>();

            for (i = 0; i < OldMascots.Count; i++)
            {
                if (OldMascots[i].IPIs.Count == 1)
                {
                    QPeptide remdata = OldMascots[i];
                    remdata.IPI = remdata.IPIs[0];
                    Mascots.Add(remdata);
                }
                else
                {
                    string Mess = string.Format("This entry ambigously defined as part of {0} Proteins: ", OldMascots[i].IPIs.Count);
                    for (j = 0; j < OldMascots[i].IPIs.Count; j++)
                    {
                        Mess = Mess + OldMascots[i].IPIs[j] + ", ";
                    }
                    Mess = Mess.Substring(0, Mess.Length - 2);
                    OldMascots[i].Case = Mess;
                    MSMSList.Add(OldMascots[i]);
                }
            }
            iLog.RepProgress(60);
            //теперь сортируем по белкам
            Mascots.Sort(new QPeptide.byIPIs());

            //теперь фильтруем не набравшие достаточного количества пептидов
            iLog.RepProgress(70);

            QProtein Prot;

            Proteins = new List <QProtein>();

            int    Count  = 0;
            string preIPI = "";

            //!! здесь нет обработки последенего белка
            for (i = 0; i <= Mascots.Count; i++)
            {
                if (i < Mascots.Count && Mascots[i].IPI == preIPI)
                {
                    Count++;
                }
                else
                {
                    for (j = i - 1; i - j <= Count; j--)
                    {
                        QPeptide temp = Mascots[j];
                        temp.peptides = Count;
                        Mascots[j]    = temp;
                    }
                    if (Count >= Convert.ToInt32(Settings.Default.PeptperProt))
                    {
                        Prot          = new QProtein();
                        Prot.Peptides = new List <QPeptide>();
                        Prot.ipis     = Mascots[i - 1].IPIs;
                        Prot.ipi      = Mascots[i - 1].IPI;
                        Prot.Est      = 0.0;
                        for (j = i - 1; i - j <= Count; j--)
                        {
                            Prot.Peptides.Add(Mascots[j]);
                        }
                        //добываем из файла Маскот описания и имена белка

                        for (j = 0; j < mp.Proteins.Count; j++)
                        {
                            if (mp.Proteins[j].Name == "\"" + Mascots[i - 1].IPI + "\"")
                            {
                                break;
                            }
                        }
                        if (j < mp.Proteins.Count)
                        {
                            Prot.Name = mp.Proteins[j].Name;
                            Prot.Desc = mp.Proteins[j].Descr;
                        }
                        else
                        {
                            Prot.Name = Prot.ipi;
                            Prot.Desc = "This protein is not described in source .dat file. See initial FASTA file for protein description";
                        }
                        Proteins.Add(Prot);
                    }
                    else
                    {
                        for (j = i - 1; i - j <= Count; j--)
                        {
                            Mascots[j].Case = string.Format("This entry belongs to \"{0}\" protein which have only {1} uniquely identified peptide(s)", Mascots[j].IPI, Count);
                            MSMSList.Add(Mascots[j]);
                        }
                    }
                    Count = 1;
                    if (i < Mascots.Count)
                    {
                        preIPI = Mascots[i].IPI;
                    }
                }
            }

            iLog.RepProgress(80);

            OldMascots = Mascots;
            Mascots    = new List <QPeptide>();

            for (i = 0; i < OldMascots.Count; i++)
            {
                if (OldMascots[i].peptides >= Convert.ToInt32(Settings.Default.PeptperProt))
                {
                    QPeptide remdata = OldMascots[i];
                    remdata.Case = string.Format("This entry belongs to \"{0}\" quntified protein", remdata.IPI);
                    Mascots.Add(remdata);
                    MSMSList.Add(remdata);
                }
                else
                {
                    continue;
                }
            }
            iLog.RepProgress(90);

            //теперь сортируем по белкам и внутри них
            Mascots.Sort(new QPeptide.byMascotSN());
            //и указываем теоретические отношения первых изотопов

            iLog.RepProgress(100);
        }
 private void LoadData()
 {
     Proteins = new List<QProtein>();
     db.LoadProteins(Proteins);
     Mascots = new List<QPeptide>();
     if (Settings.Default.QuantiAll ){
         db.LoadMascots(Proteins,Mascots);
         MSMSList = new List<QPeptide>();
         db.LoadAllMSMS(MSMSList);
         //а теперь сливаем Mascots и MSMSList
         Mascots.Sort(new QPeptide.byMascotSN());
         MSMSList.Sort(new QPeptide.byMascotSN());
         int Count=0;
         for ( int i = 0 ; i< Mascots.Count ; i++){
             while( MSMSList[Count].MascotScan != Mascots[i].MascotScan) {
                 Count++;
             }
             MSMSList[Count] = Mascots[i];
         }
     }else{
         db.LoadMascots(Proteins,Mascots);
         MSMSList = Mascots;
     }
     InitMatches();
     SetProtReference();
     db.LoadQMatches(MSMSList);
     //db.LoadMSMatches(MSMSList);
     mp = null;
     Log("Loading completed");
     RepProgress(0);
 }
        //event handlers
        private void DATFileButton_Click(object sender, EventArgs e)
        {
            if(DatFileDialog.ShowDialog() != DialogResult.OK)  {
                return;
            }
            DatFileName.Text = DatFileDialog.FileName;
            if (File.Exists(Path.GetDirectoryName(DatFileDialog.FileName)+Path.DirectorySeparatorChar+Path.GetFileNameWithoutExtension(DatFileDialog.FileName)+".db3")){
                if (MessageBox.Show("There is a .db3 file for selected file. \n This file contains processing results "+
                                    "and will be overwriten.\n Are you sure you want to overwrite this file?","Result file already exsists",MessageBoxButtons.OKCancel,MessageBoxIcon.Exclamation) == DialogResult.Cancel){
                    DatFileName.Text="";
                    return;
                };
            }

            if (DatFileDialog.FilterIndex == 1){
                //Mascots files
                mp = new Mascot.MascotParser();
                try{
                    mp.ParseFile(DatFileDialog.FileName);
                }
                catch (Exception ex){
                    MessageBox.Show(ex.Message,
                        "Incorrect .Dat file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    DatFileName.Text="";
                    return ;
                }
                //меняем маскот-scan на Order - если таковой имеется
                for (int i = 0; i < mp.Spectra.Count; i++) {
                    if (mp.Spectra[i].Title.Contains("Order")) {
                        string FSN = mp.Spectra[i].Title.Substring(mp.Spectra[i].Title.IndexOf("Order")+11);
                        FSN = FSN.Substring(0, FSN.IndexOf("Finnegan")-3);
                        mp.Spectra[i].ScanNumber = Convert.ToInt32(FSN);
                    }
                }
                //проверяем  - Finnigan ScanNumber должен быть уникальным после этой процедуры
                mp.Spectra.Sort(new MascotsbyFSN());
                bool Flag = false;
                for (int i = 0 ; i < mp.Spectra.Count-1 ; i++){
                    Flag = (mp.Spectra[i].ScanNumber == mp.Spectra[i + 1].ScanNumber);
                    if (Flag) break;
                }
                if (Flag){
                    MessageBox.Show(".Dat file does not provide unique Order or ScanNumber. \n Please, Check .MGF used for Mascot Search.",
                        "Incorrect .Dat file.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    DatFileName.Text="";
                    return ;
                }

                AllCheckBox.Enabled = true;

                UseFDRCheck.Enabled = mp.IsFDRAvialable();
                UseFDRCheck.Checked = false;
                UseFDRCheck.Text = "Use FDR mascot thres.";
                FDR = 0.0;
                tabsr = null;
            }else{
                //Text files
                tabsr = new StreamReader(DatFileName.Text);
                if (!MascotProc.FillMSMSLists(ref Mascots, ref MSMSList, ref Proteins, tabsr)){
                    tabsr.Close();
                    tabsr = null;
                    return;
                }
                mp = null;

                for (int i = 0; i < Proteins.Count; i++ ){
                    if (Proteins[i].ipi.ToUpper().Contains("REVERSED")){
                        UseFDRCheck.Enabled = true;
                    }else{
                        UseFDRCheck.Enabled = false;
                    }
                    UseFDRCheck.Checked = false;
                    UseFDRCheck.Text = "Use FDR mascot thres.";
                    FDR = 0.0;

                    AllCheckBox.Checked = false;
                    AllCheckBox.Enabled = false;

                }
                tabsr.Close();
            }
            OutPathName.Text = Path.GetDirectoryName(DatFileName.Text);
            folderBrowserDialog1.SelectedPath = Path.GetDirectoryName(DatFileName.Text);
            DBFileName.Text = OutPathName.Text+Path.DirectorySeparatorChar+Path.GetFileNameWithoutExtension(DatFileName.Text)+".db3";
        }