Ejemplo n.º 1
0
        private void MainTest()
        {
            // Clean-up before running the test
            RunUI(() => SkylineWindow.ModifyDocument("Set default settings",
                                                     doc => doc.ChangeSettings(SrmSettingsList.GetDefault())));

            // Check using libkey with small molecules
            var          adduct           = Adduct.FromStringAssumeProtonated("M+3Na");
            var          z                = adduct.AdductCharge;
            const string caffeineFormula  = "C8H10N4O2";
            const string caffeineInChiKey = "RYYVLZVUVIJVGH-UHFFFAOYSA-N";
            const string caffeineHMDB     = "HMDB01847";
            const string caffeineInChi    = "InChI=1S/C8H10N4O2/c1-10-4-9-6-5(10)7(13)12(3)8(14)11(6)2/h4H,1-3H3";
            const string caffeineCAS      = "58-08-2";
            const string caffeineSMILES   = "Cn1cnc2n(C)c(=O)n(C)c(=O)c12";
            const string caffeineKEGG     = "C07481";


            var mId = new MoleculeAccessionNumbers(string.Join("\t", MoleculeAccessionNumbers.TagHMDB + ":" + caffeineHMDB,
                                                               MoleculeAccessionNumbers.TagInChI + ":" + caffeineInChi, MoleculeAccessionNumbers.TagCAS + ":" + caffeineCAS, MoleculeAccessionNumbers.TagInChiKey + ":" + caffeineInChiKey,
                                                               MoleculeAccessionNumbers.TagSMILES + ":" + caffeineSMILES, MoleculeAccessionNumbers.TagKEGG + ":" + caffeineKEGG));

            Assert.AreEqual(caffeineInChiKey, mId.GetInChiKey());
            Assert.AreEqual(caffeineCAS, mId.GetCAS());
            Assert.AreEqual(caffeineSMILES, mId.GetSMILES());
            Assert.AreEqual(caffeineKEGG, mId.GetKEGG());

            var moleculeName       = "caffeine";
            var smallMolAttributes = SmallMoleculeLibraryAttributes.Create(moleculeName, caffeineFormula, caffeineInChiKey,
                                                                           string.Join("\t", MoleculeAccessionNumbers.TagHMDB + ":" + caffeineHMDB,
                                                                                       MoleculeAccessionNumbers.TagInChI + ":" + caffeineInChi, MoleculeAccessionNumbers.TagCAS + ":" + caffeineCAS,
                                                                                       MoleculeAccessionNumbers.TagSMILES + ":" + caffeineSMILES, MoleculeAccessionNumbers.TagKEGG + ":" + caffeineKEGG));
            LibKey key;

            for (var loop = 0; loop++ < 2;)
            {
                key = new LibKey(smallMolAttributes, adduct);
                Assert.IsFalse(key.IsPrecursorKey);
                Assert.IsFalse(key.IsProteomicKey);
                Assert.IsTrue(key.IsSmallMoleculeKey);
                Assert.IsFalse(key.IsModified);
                Assert.AreEqual(0, key.ModificationCount);
                Assert.AreEqual(z, key.Charge);
                Assert.AreEqual(adduct, key.Adduct);
                Assert.AreEqual(caffeineInChiKey, key.Target.ToString());
                var viewLibPepInfo = new ViewLibraryPepInfo(key);
                Assert.AreEqual(key, viewLibPepInfo.Key);
                var smallMolInfo = viewLibPepInfo.GetSmallMoleculeLibraryAttributes();
                Assert.AreEqual(moleculeName, smallMolInfo.MoleculeName);
                Assert.AreEqual(caffeineInChiKey, smallMolInfo.InChiKey);
                Assert.AreEqual(caffeineFormula, smallMolInfo.ChemicalFormula);
                Assert.IsTrue(smallMolInfo.OtherKeys.Contains(caffeineCAS));
                Assert.IsTrue(smallMolInfo.OtherKeys.Contains(caffeineInChi));
                Assert.IsTrue(smallMolInfo.OtherKeys.Contains(caffeineHMDB));
                Assert.IsTrue(smallMolInfo.OtherKeys.Contains(caffeineSMILES));
                Assert.IsTrue(smallMolInfo.OtherKeys.Contains(caffeineKEGG));
                adduct = Adduct.FromString("M+3Si", Adduct.ADDUCT_TYPE.non_proteomic, z = -17); // Not realistic, but let's see if it's handled consistently
            }

            // Check general libkey operation
            var seq = "YTQSNSVC[+57.0]YAK";

            key = new LibKey(seq, Adduct.DOUBLY_PROTONATED);
            Assert.IsFalse(key.IsPrecursorKey);
            Assert.IsTrue(key.IsProteomicKey);
            Assert.IsFalse(key.IsSmallMoleculeKey);
            Assert.IsTrue(key.IsModified);
            Assert.AreEqual(2, key.Charge);
            Assert.AreEqual(1, key.ModificationCount);
            Assert.AreEqual(Adduct.DOUBLY_PROTONATED, key.Adduct);
            Assert.AreEqual(seq, key.Target.ToString());

            // Test error conditions
            BuildLibraryError("missing_charge.pep.XML", TestFilesDir.FullPath);
            BuildLibraryError("non_int_charge.pep.XML", null);
            BuildLibraryError("zero_charge.pep.XML", null);
            BuildLibraryError("truncated.pep.XML", null);
            BuildLibraryError("no_such_file.pep.XML", null, "Failed to open");
            BuildLibraryError("missing_mzxml.pep.XML", null, "Could not find spectrum file");

            // Check for proper handling of labeled addducts in small molecule files
            // (formerly this would throw on a null object, fixed with the use of ExplicitMods.EMPTY)
            BuildLibraryValid("heavy_adduct.ssl", true, false, false, 1);
            // Make sure explorer handles this adduct type
            var viewLibUI = ShowDialog <ViewLibraryDlg>(SkylineWindow.ViewSpectralLibraries);

            RunUI(() => AssertEx.IsTrue(viewLibUI.GraphItem.IonLabels.Any()));
            RunUI(viewLibUI.CancelDialog);

            // Barbara added code to ProteoWizard to rebuild a missing or invalid mzXML index
            // BuildLibraryError("bad_mzxml.pep.XML", "<index> not found");
            BuildLibraryValid(TestFilesDir.GetTestPath("library_errors"), new[] { "bad_mzxml.pep.XML" }, false, false, false, 1);

            string libraryBaseName = _libraryName;

            // Test mascot parser
            _libraryName = libraryBaseName + "mascot";
            string libraryMascot = _libraryName + BiblioSpecLiteSpec.EXT;

            BuildLibraryValid(TestFilesDir.GetTestPath("mascot"), new[] { "F027319.dat" },
                              true, false, false, 121, 4);
            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryMascot)));

            // Test successful builds
            _libraryName = libraryBaseName + "a";
            string libraryA          = _libraryName + BiblioSpecLiteSpec.EXT;
            string libraryARedundant = _libraryName + BiblioSpecLiteSpec.EXT_REDUNDANT;

            BuildLibraryValid("CPTAC_Set4_725_091509.pep.XML", true, false, false, 1);
            BuildLibraryValid("CPTAC_Set4_610_080509.pep.XML", true, false, true, 2);
            _libraryName = libraryBaseName + "b";
            string libraryB = _libraryName + BiblioSpecLiteSpec.EXT;

            BuildLibraryValid("CPTAC_Set4_624_072409.pep.XML", false, false, false, 6);
            _libraryName = libraryBaseName + "c";
            string libraryC = _libraryName + BiblioSpecLiteSpec.EXT;

            BuildLibraryValid(TestFilesDir.FullPath, new[] { libraryA, libraryB },
                              false, false, false, 8);

            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryA)));
            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryARedundant)));
            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryB)));
            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryC)));

            // Test peptide filter
            const string filterList = "ACARPIISVYSEK\n" +
                                      // TODO: Having the modified sequence as the first line causes an error with European number formats
                                      "ADRDESSPYAAM[+{0:F01}]IAAQDVAQR\n" +
                                      "ADAIQAGASQFETSAAK";

            PastePeptideList(string.Format(filterList, 16.0), true, 0, 3, true);

            _libraryName = libraryBaseName + "filter";
            string libraryFilter = _libraryName + BiblioSpecLiteSpec.EXT;

            BuildLibraryValid(TestFilesDir.GetTestPath("maxquant"), new[] { "test.msms.txt" },
                              false, true, false, 2);

            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryFilter)));
            RunUI(SkylineWindow.Undo);
            RunUI(SkylineWindow.Undo);

            // Test AddPathsDlg (file not found)
            EnsurePeptideSettings();
            var buildLibraryDlg = ShowDialog <BuildLibraryDlg>(PeptideSettingsUI.ShowBuildLibraryDlg);

            string[] invalidPaths =
            {
                Path.Combine(TestFilesDir.GetTestPath("maxquant"),      "test.msms.xml"),
                Path.Combine(TestFilesDir.GetTestPath("library_valid"), "CPTAC_Set4_624_072409.pep.XML")
            };
            TestAddPaths(buildLibraryDlg, invalidPaths, true);

            // Test AddPathsDlg (file invalid type)
            string[] invalidTypes =
            {
                Path.Combine(TestFilesDir.GetTestPath("maxquant"), "test.msms.txt"),
                Path.Combine(TestFilesDir.GetTestPath("maxquant"), "mqpar.xml")
            };
            TestAddPaths(buildLibraryDlg, invalidTypes, true);

            // Test AddPathsDlg (valid files)
            string[] goodPaths =
            {
                Path.Combine(TestFilesDir.GetTestPath("maxquant"),      "test.msms.txt"),
                Path.Combine(TestFilesDir.GetTestPath("library_valid"), "CPTAC_Set4_624_072409.pep.XML")
            };
            TestAddPaths(buildLibraryDlg, goodPaths, false);
            OkDialog(buildLibraryDlg, buildLibraryDlg.CancelDialog);

            const string heavyRPeptide    = "TPAQFDADELR";
            const string oxidizedMPeptide = "LVGNMHGDETVSR";
            const string peptideList      = heavyRPeptide + "\n" +
                                            oxidizedMPeptide + "\n" +
                                            "ALSIGFETCR\n" +
                                            "GNMHGDETVSR\n" +
                                            "VGNMHGDETVSR";

            PastePeptideList(peptideList, true, 0, 1);

            // Set modifications on peptides to verify they connect with library spectra.
            const LabelAtoms labelAtoms = LabelAtoms.C13 | LabelAtoms.N15;
            const string     heavyR     = "Heavy R";

            Settings.Default.HeavyModList.Add(new StaticMod(heavyR, "R", ModTerminus.C, null, labelAtoms, null, null));
            const string oMeth = "Oxidized Methionine";

            Settings.Default.StaticModList.Add(new StaticMod(oMeth, "M", null, "O"));

            var sequenceTree = SkylineWindow.SequenceTree;
            var docCurrent   = SkylineWindow.Document;
            // Select the heavyR peptide
            PeptideTreeNode nodePepTree = null;
            IdentityPath    pathPep     = docCurrent.GetPathTo((int)SrmDocument.Level.Molecules, 0);

            RunUI(() =>
            {
                sequenceTree.SelectedPath = pathPep;
                nodePepTree = sequenceTree.SelectedNode as PeptideTreeNode;
            });
            Assert.IsNotNull(nodePepTree);
            Assert.AreEqual(heavyRPeptide, nodePepTree.DocNode.Peptide.Sequence);
            // Set the Heavy R modification explicitly
            var editPepModsDlg = ShowDialog <EditPepModsDlg>(SkylineWindow.ModifyPeptide);

            RunUI(() =>
            {
                editPepModsDlg.SetModification(heavyRPeptide.Length - 1, IsotopeLabelType.heavy, heavyR);
                editPepModsDlg.OkDialog();
            });
            WaitForCondition(() => (SkylineWindow.Document.Molecules.First().TransitionGroupCount == 2));

            // The peptide should now match the spectrum in the library, and have
            // both heavy and light precursors, with ranked transitions
            PeptideDocNode nodePep = null;

            RunUI(() => nodePep = nodePepTree.DocNode);
            Assert.IsNotNull(nodePep);
            Debug.Assert(nodePep != null);
            Assert.AreEqual(2, nodePep.Children.Count, "Missing precursor for heavy R peptide.");
            docCurrent = SkylineWindow.Document;
            foreach (TransitionGroupDocNode nodeGroup in nodePep.Children)
            {
                AssertLibInfo(docCurrent, nodeGroup);
            }
            // Which means all transition groups should now have spectrum info
            foreach (var nodeGroup in docCurrent.PeptideTransitionGroups)
            {
                AssertLibInfo(docCurrent, nodeGroup);
            }

            // New document
            var docNew     = new SrmDocument(SrmSettingsList.GetDefault());
            var docNewCopy = docNew;

            RunUI(() => SkylineWindow.SwitchDocument(docNewCopy, null));

            const string idpList3 = "FHYKTDQGIK\n" +
                                    "WCAIGHQER\n" +
                                    "WCTISTHEANK";
            int idpCount3 = idpList3.Split('\n').Length;

            const string idpList = "ADVTLGGGAK\n" +
                                   "AGFAGDDAPR\n" +
                                   "ALEFAKK\n" +
                                   "CCTESLVNR\n" +
                                   "DSYVGDEAQSK\n" +
                                   "YICDNQDTISSK\n" +
                                   // charge 3 peptides all have 2 also
                                   idpList3;
            int idpCount = idpList.Split('\n').Length;

            _libraryName = libraryBaseName + "_idp";
            string libraryIdp = _libraryName + BiblioSpecLiteSpec.EXT;

            BuildLibraryValid(TestFilesDir.GetTestPath("idp_xml"), new[] { "orbi-small-eg.idpXML" },
                              false, false, false, idpCount + idpCount3);

            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryIdp)));

            // Add peptides expected to have charge 2 spectra in the library
            PastePeptideList(idpList, true, 0, 0);

            // Undo the paste
            RunUI(SkylineWindow.Undo);

            // Try filtering for only charge 3 spectra
            var transitionSettingsUI = ShowDialog <TransitionSettingsUI>(
                SkylineWindow.ShowTransitionSettingsUI);

            RunUI(() =>
            {
                transitionSettingsUI.PrecursorCharges = "3";
                transitionSettingsUI.OkDialog();
            });

            PastePeptideList(idpList, false, idpCount - idpCount3 + 1 /* missing cleavage*/, 0);

            // New document
            var docNewCopy2 = docNew;

            RunUI(() => SkylineWindow.SwitchDocument(docNewCopy2, null));

            _libraryName = libraryBaseName + "_cpas1";
            string libraryCpas1 = _libraryName + BiblioSpecLiteSpec.EXT;

            BuildLibraryValid(TestFilesDir.GetTestPath("cpas"), null,
                              false, false, false, 3);

            Assert.IsTrue(File.Exists(TestFilesDir.GetTestPath(libraryCpas1)));

            // These are very poor searches, so repeat with no filter
            Settings.Default.LibraryResultCutOff = 0;

            _libraryName = libraryBaseName + "_cpas2";
            BuildLibraryValid(TestFilesDir.GetTestPath("cpas"), null,
                              false, false, false, 100, 100);

            // And, since the spectra are really poor, allow lots of
            // possibilities for fragment ions.
            var transitionSettingsCpas = ShowDialog <TransitionSettingsUI>(
                SkylineWindow.ShowTransitionSettingsUI);

            RunUI(() =>
            {
                transitionSettingsCpas.PrecursorCharges   =
                    transitionSettingsCpas.ProductCharges = "1,2,3";
                transitionSettingsCpas.FragmentTypes      = "y,b";
                transitionSettingsCpas.InstrumentMaxMz    = 2000;
                transitionSettingsCpas.OkDialog();
            });

            EnsurePeptideSettings();

            RunUI(() =>
            {
                // Turn off carbamidomethyl cys, since not in these searches
                PeptideSettingsUI.PickedStaticMods = new string[0];
                PeptideSettingsUI.OkDialog();
            });

            // Get the set of peptides to paste from the library, since there
            // are a lot.
            var setPeptides = new HashSet <Target>();
            var library     = SkylineWindow.Document.Settings.PeptideSettings.Libraries.Libraries[0];

            foreach (var libKey in library.Keys)
            {
                if (!libKey.IsModified)
                {
                    setPeptides.Add(libKey.Target);
                }
            }

            string cpasPeptides = string.Join("\n", setPeptides.Select(p => p.ToString()).ToArray());

            var pasteFilteredPeptideDlg = ShowDialog <PasteFilteredPeptidesDlg>(
                () => SkylineWindow.Paste(cpasPeptides));

            RunUI(pasteFilteredPeptideDlg.NoDialog);
            Assert.IsTrue(WaitForCondition(() => SkylineWindow.Document.PeptideCount == setPeptides.Count),
                          string.Format("Expecting {0} peptides, found {1}.", setPeptides.Count, SkylineWindow.Document.PeptideCount));
            Assert.AreEqual(setPeptides.Count, SkylineWindow.Document.PeptideTransitionGroupCount,
                            "Expecting precursors for peptides matched to library spectrum.");

            // New document
            docNew = new SrmDocument(SrmSettingsList.GetDefault());
            RunUI(() => SkylineWindow.SwitchDocument(docNew, null));

            // Tests for adding iRTs to spectral library after building
            // 1. ask to recalibrate iRTs
            // 2. ask to add iRTs
            // 3. if added iRTs, ask to add RT predictor

            // no recalibrate, add iRTs, no add predictor
            _libraryName = libraryBaseName + "_irt1"; // library_test_irt1
            BuildLibraryIrt(true, false, false);
            RunUI(() => Assert.IsTrue(PeptideSettingsUI.Prediction.RetentionTime == null));

            // no recalibrate, add iRTs, add predictor
            _libraryName = libraryBaseName + "_irt2"; // library_test_irt2
            BuildLibraryIrt(true, false, true);
            RunUI(() => Assert.IsTrue(PeptideSettingsUI.Prediction.RetentionTime.Name.Equals(_libraryName)));
            var editIrtDlg2 = ShowDialog <EditIrtCalcDlg>(PeptideSettingsUI.EditCalculator);

            RunUI(() => Assert.IsTrue(ReferenceEquals(editIrtDlg2.IrtStandards, IrtStandard.BIOGNOSYS_10)));
            OkDialog(editIrtDlg2, editIrtDlg2.CancelDialog);

            // recalibrate, add iRTs, no add predictor
            _libraryName = libraryBaseName + "_irt3"; // library_test_irt3
            BuildLibraryIrt(true, true, false);
            RunUI(() => Assert.IsTrue(PeptideSettingsUI.Prediction.RetentionTime.Name.Equals(libraryBaseName + "_irt2")));

            // recalibrate, add iRTs, add predictor
            _libraryName = libraryBaseName + "_irt4"; // library_test_irt4
            BuildLibraryIrt(true, true, true);
            RunUI(() => Assert.IsTrue(PeptideSettingsUI.Prediction.RetentionTime.Name.Equals(_libraryName)));
            var editIrtDlg4 = ShowDialog <EditIrtCalcDlg>(PeptideSettingsUI.EditCalculator);

            RunUI(() => Assert.IsTrue(ReferenceEquals(editIrtDlg4.IrtStandards, IrtStandard.EMPTY)));
            OkDialog(editIrtDlg4, editIrtDlg4.CancelDialog);

            OkDialog(PeptideSettingsUI, PeptideSettingsUI.CancelDialog);
        }
Ejemplo n.º 2
0
        private void TestBasicFunctionality()
        {
            // Launch the Library Explorer dialog
            _viewLibUI = ShowDialog <ViewLibraryDlg>(SkylineWindow.ViewSpectralLibraries);

            // Ensure the appropriate default library is selected
            ComboBox libComboBox = null;
            ListBox  pepList     = null;
            string   libSelected = null;

            RunUI(() =>
            {
                libComboBox = (ComboBox)_viewLibUI.Controls.Find("comboLibrary", true)[0];
                Assert.IsNotNull(libComboBox);
                libSelected = libComboBox.SelectedItem.ToString();

                // Find the peptides list control
                pepList = (ListBox)_viewLibUI.Controls.Find("listPeptide", true)[0];
                Assert.IsNotNull(pepList);
            });
            Assert.AreEqual(_testLibs[0].Name, libSelected);

            // Initially, peptide with index 0 should be selected
            WaitForConditionUI(() => pepList.SelectedIndex != -1);
            var modDlg = WaitForOpenForm <MultiButtonMsgDlg>();

            RunUI(modDlg.Btn1Click);

            ViewLibraryPepInfo previousPeptide = new ViewLibraryPepInfo();
            int peptideIndex = -1;

            RunUI(() =>
            {
                previousPeptide = (ViewLibraryPepInfo)pepList.SelectedItem;
                peptideIndex    = pepList.SelectedIndex;
            });
            Assert.IsNotNull(previousPeptide);
            Assert.AreEqual(0, peptideIndex);
            Assert.AreEqual(3, previousPeptide.Charge, "Expected charge 3 on " + previousPeptide.DisplayString);

            // Now try to select a different peptide and check to see if the
            // selection changes
            const int selectPeptideIndex = 1;

            RunUI(() =>
            {
                pepList.SelectedIndex = selectPeptideIndex;
            });

            ViewLibraryPepInfo selPeptide = new ViewLibraryPepInfo();

            RunUI(() =>
            {
                Assert.AreEqual(selectPeptideIndex, pepList.SelectedIndex); // Did selection change work?

                selPeptide = (ViewLibraryPepInfo)pepList.SelectedItem;
            });
            Assert.IsNotNull(selPeptide);
            if (Equals(previousPeptide, selPeptide))
            {
                Assert.AreNotEqual(previousPeptide.DisplayString, selPeptide.DisplayString);
            }
            Assert.AreEqual(2, selPeptide.Charge, "Expected charge 2 on " + selPeptide.DisplayString);

            // Click the "Next" link
            RunUI(() =>
            {
                var nextLink = (IButtonControl)_viewLibUI.Controls.Find("NextLink", true)[0];
                Assert.IsNotNull(nextLink);

                nextLink.PerformClick();
            });
            RunUI(() =>
            {
                previousPeptide = (ViewLibraryPepInfo)pepList.SelectedItem;
            });

            // Click "Previous" link and ensure the peptide selected changes
            RunUI(() =>
            {
                var previousLink = (IButtonControl)_viewLibUI.Controls.Find("PreviousLink", true)[0];
                Assert.IsNotNull(previousLink);

                previousLink.PerformClick();
            });
            RunUI(() =>
            {
                selPeptide = (ViewLibraryPepInfo)pepList.SelectedItem;
            });
            Assert.AreNotEqual(previousPeptide, selPeptide);


            // Test valid peptide search
            TextBox pepTextBox = null;

            RunUI(() =>
            {
                pepTextBox = (TextBox)_viewLibUI.Controls.Find("textPeptide", true)[0];
                Assert.IsNotNull(pepTextBox);

                pepTextBox.Focus();
                pepTextBox.Text = _testLibs[0].UniquePeptide;
            });
            int pepsCount = 0;

            RunUI(() =>
            {
                selPeptide = (ViewLibraryPepInfo)pepList.SelectedItem;
                pepsCount  = pepList.Items.Count;
            });
            Assert.AreEqual(_testLibs[0].UniquePeptide, selPeptide.DisplayString);
            Assert.AreEqual(1, pepsCount);

            // Test invalid peptide search
            RunUI(() =>
            {
                pepTextBox.Focus();
                pepTextBox.Text = INVALID_SEARCH;
            });
            RunUI(() =>
            {
                pepsCount = pepList.Items.Count;
            });
            Assert.AreEqual(0, pepsCount);

            // Test clearing invalid peptide search
            RunUI(() =>
            {
                pepTextBox.Focus();
                pepTextBox.Text = "";
            });
            selPeptide = new ViewLibraryPepInfo();
            RunUI(() =>
            {
                selPeptide = (ViewLibraryPepInfo)pepList.SelectedItem;
                pepsCount  = pepList.Items.Count;
            });
            Assert.IsNotNull(selPeptide);
            Assert.AreNotEqual(0, pepsCount);

            // Test selecting a different library
            previousPeptide = selPeptide;
            RunDlg <MultiButtonMsgDlg>(() => libComboBox.SelectedIndex = 1, dlg => dlg.Btn1Click());
            RunUI(() =>
            {
                libComboBox.SelectedIndex = 1;
            });
            RunUI(() =>
            {
                libSelected = libComboBox.SelectedItem.ToString();
            });
            Assert.AreEqual(libSelected, _testLibs[1].Name);
            RunUI(() =>
            {
                selPeptide = (ViewLibraryPepInfo)pepList.SelectedItem;
            });
            Assert.IsNotNull(selPeptide);
            Assert.AreNotEqual(previousPeptide, selPeptide);

            // If the library is not in the document settings, offer to add the library to the settings.
            // If the user declines, add the peptides anyways, but strip them so they do not appear to be
            // connected to any library.
            RunDlg <MultiButtonMsgDlg>(_viewLibUI.AddPeptide, msgDlg => msgDlg.Btn1Click());
            Assert.AreEqual(1, SkylineWindow.Document.PeptideCount);
            Assert.IsFalse(SkylineWindow.Document.Peptides.Contains(nodePep => nodePep.HasLibInfo));
            RunUI(() =>
            {
                SkylineWindow.SelectAll();
                SkylineWindow.EditDelete();
            });

            // Test adding peptides offers to add library if not already in settings.
            // Test add single peptide.
            using (new CheckDocumentStateWithPossibleProteinMetadataBackgroundUpdate(1, 1, 1, 3))
            {
                RunDlg <MultiButtonMsgDlg>(_viewLibUI.AddPeptide, msgDlg => msgDlg.Btn0Click());
            }
            RunUI(SkylineWindow.EditDelete);

            // Test unmatched peptides are correct.
            // One unmatched because its precursor m/z is outside the instrument measurement range
            AddAllPeptides(1, 4, 3);

            // Verify that everything matches, given a wide enough mass range
            RunUI(() => SkylineWindow.ModifyDocument("Change m/z range",
                                                     doc => doc.ChangeSettings(doc.Settings.ChangeTransitionInstrument(inst =>
                                                                                                                       inst.ChangeMaxMz(TransitionInstrument.MAX_MEASURABLE_MZ)))));
            WaitForConditionUI(() => !_viewLibUI.HasUnmatchedPeptides);
            RunUI(() => SkylineWindow.ModifyDocument("Change m/z range",
                                                     doc => doc.ChangeSettings(doc.Settings.ChangeTransitionInstrument(inst =>
                                                                                                                       inst.ChangeMaxMz(1500)))));
            WaitForConditionUI(() => _viewLibUI.HasUnmatchedPeptides);

            // Test library peptides are merged without duplicates.
            TestForDuplicatePeptides();

            // Test library peptides only get added to the document once.
            var docOriginal = SkylineWindow.Document;

            RunDlg <MessageDlg>(_viewLibUI.AddPeptide, msgDlg => msgDlg.OkDialog());
            var filterMatchedPeptidesDlg5 = ShowDialog <FilterMatchedPeptidesDlg>(_viewLibUI.AddAllPeptides);

            RunDlg <MessageDlg>(filterMatchedPeptidesDlg5.OkDialog, msgDlg => msgDlg.OkDialog());
            Assert.AreSame(docOriginal, SkylineWindow.Document);

            // Test missing peptides added.
            RunUI(() =>
            {
                var sequenceTree          = SkylineWindow.SequenceTree;
                var nodePeps              = sequenceTree.Nodes[0].Nodes;
                sequenceTree.SelectedNode = nodePeps[0];
                sequenceTree.KeysOverride = Keys.Control;
                for (int i = 2; i < 10; i += 2)
                {
                    sequenceTree.SelectedNode = nodePeps[i];
                }
                sequenceTree.KeysOverride = Keys.None;
                SkylineWindow.EditDelete();
            });
            AddAllPeptides();
            var docAddBack = SkylineWindow.Document;

            // Peptides will be added back in a different order
            AssertEx.IsDocumentState(docAddBack, null,
                                     docOriginal.PeptideGroupCount, docOriginal.PeptideCount,
                                     docOriginal.PeptideTransitionGroupCount, docOriginal.PeptideTransitionCount);
            TestSamePeptides(docOriginal.Peptides);

            // Test missing transition groups added correctly.
            RunUI(() =>
            {
                var sequenceTree          = SkylineWindow.SequenceTree;
                sequenceTree.SelectedNode = sequenceTree.Nodes[0].Nodes[0].Nodes[0];
                sequenceTree.KeysOverride = Keys.Control;
                for (int x = 0; x < 5; x++)
                {
                    var nodePep    = sequenceTree.Nodes[0].Nodes[x];
                    var nodeGroups = nodePep.Nodes;
                    for (int i = 0; i < nodeGroups.Count; i += 2)
                    {
                        sequenceTree.SelectedNode = nodeGroups[i];
                    }
                }
                SkylineWindow.EditDelete();
            });
            AddAllPeptides();
            var docAddBackGroups = SkylineWindow.Document;

            // Check all precursor charges present.
            foreach (PeptideDocNode nodePep in docOriginal.Peptides)
            {
                var key = nodePep.Key;
                foreach (TransitionGroupDocNode nodeGroup in nodePep.Children)
                {
                    var charge = nodeGroup.TransitionGroup.PrecursorCharge;
                    Assert.IsTrue(docAddBackGroups.Peptides.Contains(nodePepDoc => Equals(key, nodePepDoc.Key) &&
                                                                     nodePepDoc.HasChildCharge(charge)));
                }
            }
            // Check no duplicate TransitionGroups added.
            TestForDuplicateTransitionGroups();

            // Test peptides get heavy label modifications.
            List <StaticMod> heavyMods15N =
                new List <StaticMod> {
                new StaticMod("15N", null, null, null, LabelAtoms.N15, null, null)
            };

            RunUI(() =>
            {
                SkylineWindow.SelectAll();
                SkylineWindow.EditDelete();
                var settings = SkylineWindow.Document.Settings.ChangePeptideModifications(mods => new PeptideModifications(mods.StaticModifications,
                                                                                                                           new[] { new TypedModifications(IsotopeLabelType.heavy, heavyMods15N) }));
                SkylineWindow.ModifyDocument("Change heavy modifications", doc => doc.ChangeSettings(settings));
            });
            AddAllPeptides();

            // All peptides should have a heavy label transition group.
            // There should be no peptide whose children do not contain a transition group with heavy label type.
            Assert.IsFalse(SkylineWindow.Document.Peptides.Contains(nodePep =>
                                                                    !nodePep.Children.Contains(nodeGroup =>
                                                                                               ((TransitionGroupDocNode)nodeGroup).TransitionGroup.LabelType.Equals(IsotopeLabelType.heavy))));

            // Test peptide setting changes update the library explorer.
            RunUI(() => SkylineWindow.ModifyDocument("Change static modifications",
                                                     doc => doc.ChangeSettings(SkylineWindow.Document.Settings.ChangePeptideModifications(mods =>
                                                                                                                                          mods.ChangeStaticModifications(new List <StaticMod>())))));
            AddAllPeptides(1, 8, 3);

            // Along with Heavy 15N added earlier in the test, adding this modification means that all library peptides
            // will match to the document settings.
            StaticMod varMetOxidized = new StaticMod("Methionine Oxidized", "M", null, true, "O",
                                                     LabelAtoms.None, RelativeRT.Matching, null, null, null);
            var metOxidizedSettings = SkylineWindow.Document.Settings.ChangePeptideModifications(mods =>
                                                                                                 mods.ChangeStaticModifications(new[] { varMetOxidized }));

            RunUI(() =>
            {
                SkylineWindow.SelectAll();
                SkylineWindow.EditDelete();
                SkylineWindow.ModifyDocument("Change static mods",
                                             doc => doc.ChangeSettings(metOxidizedSettings));
            });

            // Switch to ANL_Combined library
            RunDlg <MultiButtonMsgDlg>(() => { libComboBox.SelectedIndex = 2; }, msgDlg => msgDlg.BtnCancelClick());

            // User prompted to add library since not in current settings.
            RunDlg <MultiButtonMsgDlg>(() => _viewLibUI.CheckLibraryInSettings(), msgDlg => msgDlg.Btn0Click());
            // Add single peptide to the document.
            RunUI(_viewLibUI.AddPeptide);
            WaitForProteinMetadataBackgroundLoaderCompletedUI();
            var nodePepAdded = SkylineWindow.SequenceTree.Nodes[0].Nodes[0];

            // Because document settings match the library, no duplicates should be found.
            AddAllPeptides(0);

            // Even though there are two matches in the library for the the nodePep we just added
            // to the document (one with light modifications and one with heavy), the two spectrum
            // both have the same charge. In this case, both spectrum should be ignored when Add All
            // is called.
            Assert.AreEqual(nodePepAdded, SkylineWindow.SequenceTree.Nodes[0].Nodes[0]);
            Assert.AreEqual(3, SkylineWindow.Document.PeptideCount);

            // Switch to the Phospho Loss Library
            RunDlg <MultiButtonMsgDlg>(() => libComboBox.SelectedIndex = 3, msgDlg => msgDlg.Btn1Click());

            // Add modifications to the document matching the settings of the library.
            var phosphoLossMod = new StaticMod("Phospho Loss", "S, T", null, true, "HPO3",
                                               LabelAtoms.None, RelativeRT.Matching, null, null, new[] { new FragmentLoss("H3PO4"), });
            var phosphoLossSettings =
                SkylineWindow.Document.Settings.ChangePeptideModifications(mods => mods.ChangeStaticModifications(new[] { phosphoLossMod }));

            RunUI(() =>
                  SkylineWindow.ModifyDocument("Change static mods", doc => doc.ChangeSettings(phosphoLossSettings)));
            RunDlg <MultiButtonMsgDlg>(() => _viewLibUI.CheckLibraryInSettings(), msgDlg => msgDlg.Btn0Click());

            // Again, we should be able to match all peptides since the document settings match use the peptides found
            // in the library.
            RunDlg <MultiButtonMsgDlg>(_viewLibUI.AddAllPeptides, msgDlg =>
            {
                Assert.AreEqual(0, (int)msgDlg.Tag);
                msgDlg.Btn1Click();
            });
            // Test losses are being displayed in the graph, indicating that the spectrum have been matched correctly.
            WaitForConditionUI(() => _viewLibUI.GraphItem.IonLabels.Contains(str => str.Contains("98")));
            Assert.IsTrue(_viewLibUI.GraphItem.IonLabels.Contains(str => str.Contains("98")));

            // Associate yeast background proteome
            var peptideSettingsUI = ShowDialog <PeptideSettingsUI>(SkylineWindow.ShowPeptideSettingsUI);

            RunDlg <BuildBackgroundProteomeDlg>(peptideSettingsUI.ShowBuildBackgroundProteomeDlg,
                                                buildBackgroundProteomeDlg =>
            {
                buildBackgroundProteomeDlg.BackgroundProteomePath = TestFilesDir.GetTestPath("yeast_mini.protdb");
                buildBackgroundProteomeDlg.BackgroundProteomeName = "Yeast";
                buildBackgroundProteomeDlg.OkDialog();
            });
            RunUI(peptideSettingsUI.OkDialog);
            WaitForCondition(() =>
            {
                var peptideSettings    = Program.ActiveDocument.Settings.PeptideSettings;
                var backgroundProteome = peptideSettings.BackgroundProteome;
                return(backgroundProteome.HasDigestion(peptideSettings));
            });
            WaitForDocumentLoaded(); // Give background loader a chance to get the protein metadata too

            RunDlg <TransitionSettingsUI>(SkylineWindow.ShowTransitionSettingsUI, transitionSettingsUI =>
            {
                transitionSettingsUI.PrecursorCharges = "1,2,3";
                transitionSettingsUI.OkDialog();
            });

            // Test add all with the yeast background proteome connected.
            RunUI(() =>
            {
                SkylineWindow.SelectAll();
                SkylineWindow.EditDelete();
                // Switch to yeast library.
                libComboBox.SelectedIndex            = 4;
                _viewLibUI.AssociateMatchingProteins = true;
            });
            var addLibraryDlg = ShowDialog <MultiButtonMsgDlg>(_viewLibUI.AddAllPeptides);
            // Add the library to the document.
            var filterMatchedPeptidesDlg = ShowDialog <FilterMatchedPeptidesDlg>(addLibraryDlg.Btn0Click);

            RunUI(() => filterMatchedPeptidesDlg.AddUnmatched = false);
            using (new CheckDocumentStateWithPossibleProteinMetadataBackgroundUpdate(4, 10, 13, 39))
            {
                RunDlg <MultiButtonMsgDlg>(filterMatchedPeptidesDlg.OkDialog, messageDlg => messageDlg.Btn1Click());
            }
            Assert.IsFalse(SkylineWindow.Document.Peptides.Contains(nodePep => !nodePep.HasLibInfo));

            // Test adding a single peptide that matches two different proteins using keep all.
            RunUI(() =>
            {
                SkylineWindow.Undo();
                _viewLibUI.ChangeSelectedPeptide("ADTGIAVEGATDAAR+");
            });
            using (new CheckDocumentStateWithPossibleProteinMetadataBackgroundUpdate(2, 2, 2, 6))
            {
                RunDlg <FilterMatchedPeptidesDlg>(_viewLibUI.AddPeptide,
                                                  filterMatchedPeptideDlg => filterMatchedPeptideDlg.OkDialog());
            }

            // Test adding a second charge state for that peptide.
            RunUI(() => _viewLibUI.ChangeSelectedPeptide("ADTGIAVEGATDAAR++"));
            using (new CheckDocumentStateWithPossibleProteinMetadataBackgroundUpdate(2, 2, 4, 12))
            {
                RunDlg <FilterMatchedPeptidesDlg>(_viewLibUI.AddPeptide,
                                                  filterMatchedPeptideDlg => filterMatchedPeptideDlg.OkDialog());
            }
            RunDlg <FilterMatchedPeptidesDlg>(_viewLibUI.AddPeptide,
                                              filterMatchedPeptideDlg => filterMatchedPeptideDlg.OkDialog());

            // Test adding a second charge state - No Duplicates.
            RunUI(() => SkylineWindow.Undo());
            var docPrev = WaitForDocumentLoaded();

            RunDlg <FilterMatchedPeptidesDlg>(_viewLibUI.AddPeptide,
                                              filterMatchedPeptideDlg =>
            {
                filterMatchedPeptideDlg.DuplicateProteinsFilter = BackgroundProteome.DuplicateProteinsFilter.NoDuplicates;
                filterMatchedPeptideDlg.OkDialog();
            });
            Assert.AreEqual(docPrev, WaitForDocumentLoaded());

            // Test adding a second charge state - First Only.
            using (new CheckDocumentStateWithPossibleProteinMetadataBackgroundUpdate(2, 2, 3, 9))
            {
                RunDlg <FilterMatchedPeptidesDlg>(_viewLibUI.AddPeptide, filterMatchedPeptideDlg =>
                {
                    filterMatchedPeptideDlg.DuplicateProteinsFilter =
                        BackgroundProteome.DuplicateProteinsFilter.FirstOccurence;
                    filterMatchedPeptideDlg.OkDialog();
                });
            }

            RunUI(() =>
            {
                SkylineWindow.Undo();
                SkylineWindow.Undo();
                // Add doubly charged state, no protein association.
                _viewLibUI.AssociateMatchingProteins = false;
                _viewLibUI.AddPeptide();
                _viewLibUI.AssociateMatchingProteins = true;
            });

            // Add doubly charged state with protein assocation.
            RunDlg <FilterMatchedPeptidesDlg>(_viewLibUI.AddPeptide,
                                              filterMatchedPeptideDlg => filterMatchedPeptideDlg.OkDialog()); // First only
            // Select singly charged state
            RunUI(() => _viewLibUI.ChangeSelectedPeptide("ADTGIAVEGATDAAR+"));
            // Test adding peptide associated with the background proteome does not affect any matching peptides that are
            // in peptide lists.
            using (new CheckDocumentStateWithPossibleProteinMetadataBackgroundUpdate(2, 2, 3, 9))
            {
                RunDlg <FilterMatchedPeptidesDlg>(_viewLibUI.AddPeptide,
                                                  filterMatchedPeptideDlg => filterMatchedPeptideDlg.OkDialog()); // First only
            }
            var peptideGroups = SkylineWindow.Document.PeptideGroups.ToArray();
            int index         = peptideGroups.IndexOf(nodeGroup => nodeGroup.IsPeptideList);

            Assert.IsTrue(peptideGroups[index].Children.Count == 1);

            // Test selecting no duplicates prevents any peptide from appearing twice in the document.
            RunUI(() => SkylineWindow.Undo());
            RunUI(() => SkylineWindow.Undo());
            var filterMatchedPeptidesDlg1 = ShowDialog <FilterMatchedPeptidesDlg>(_viewLibUI.AddAllPeptides);

            RunUI(() => filterMatchedPeptidesDlg1.DuplicateProteinsFilter = BackgroundProteome.DuplicateProteinsFilter.NoDuplicates);
            RunDlg <MultiButtonMsgDlg>(filterMatchedPeptidesDlg1.OkDialog, messageDlg => messageDlg.Btn1Click());
            TestForDuplicatePeptides();

            // Test selecting first occurence prevents any peptide from appearing twice in the document.
            RunUI(() => SkylineWindow.Undo());
            var filterMatchedPeptidesDlg2 = ShowDialog <FilterMatchedPeptidesDlg>(_viewLibUI.AddAllPeptides);

            RunUI(() => filterMatchedPeptidesDlg2.DuplicateProteinsFilter = BackgroundProteome.DuplicateProteinsFilter.FirstOccurence);
            RunDlg <MultiButtonMsgDlg>(filterMatchedPeptidesDlg2.OkDialog, messageDlg => messageDlg.Btn1Click());
            TestForDuplicatePeptides();

            // Test peptides are added to "Library Peptides" peptide list if this peptide group already exists.
            using (new CheckDocumentStateWithPossibleProteinMetadataBackgroundUpdate(1, 2, 3, 9))
            {
                RunUI(() =>
                {
                    SkylineWindow.Undo();
                    _viewLibUI.AssociateMatchingProteins = false;
                    _viewLibUI.AddPeptide();
                    _viewLibUI.ChangeSelectedPeptide("AAAP");
                    _viewLibUI.AddPeptide();
                });
            }

            RunUI(() =>
            {
                SkylineWindow.SelectAll();
                SkylineWindow.EditDelete();
            });

            // Close the Library Explorer dialog
            OkDialog(_viewLibUI, _viewLibUI.CancelDialog);
        }