Ejemplo n.º 1
0
 public PeptideQuantifier(PeptideGroupDocNode peptideGroup, PeptideDocNode peptideDocNode,
     QuantificationSettings quantificationSettings)
 {
     PeptideGroupDocNode = peptideGroup;
     PeptideDocNode = peptideDocNode;
     QuantificationSettings = quantificationSettings;
 }
Ejemplo n.º 2
0
 public GroupComparisonSelector(PeptideGroupDocNode protein, PeptideDocNode peptide, IsotopeLabelType labelType, 
     int? msLevel, GroupIdentifier groupIdentifier)
 {
     Protein = protein;
     Peptide = peptide;
     LabelType = labelType;
     MsLevel = msLevel;
     GroupIdentifier = groupIdentifier;
 }
Ejemplo n.º 3
0
 public static PeptideQuantifier GetPeptideQuantifier(SrmSettings srmSettings, PeptideGroupDocNode peptideGroup, PeptideDocNode peptide)
 {
     var mods = srmSettings.PeptideSettings.Modifications;
     // Quantify on all label types which are not internal standards.
     ICollection<IsotopeLabelType> labelTypes = ImmutableList.ValueOf(mods.GetModificationTypes()
         .Except(mods.InternalStandardTypes));
     return new PeptideQuantifier(peptideGroup, peptide, srmSettings.PeptideSettings.Quantification)
     {
         MeasuredLabelTypes = labelTypes
     };
 }
Ejemplo n.º 4
0
 public void ProcessGroup(PeptideGroupDocNode nodeGroup)
 {
     bool messageChange = _formatString != null;
     if (messageChange)
         _status = _status.ChangeMessage(string.Format(_formatString, nodeGroup.Name));
     int? percentComplete = ProgressStatus.ThreadsafeIncementPercent(ref _seenGroupCount, GroupCount);
     UpdateProgress(percentComplete, messageChange);
 }
Ejemplo n.º 5
0
 protected virtual bool IsMatch(PeptideGroupDocNode nodePepGroup)
 {
     return false;
 }
Ejemplo n.º 6
0
        protected override void DoTest()
        {
            const string firstPeptideSequence  = "PEPTIDEA";
            const string secondPeptideSequence = "PEPTIDEC";
            const string thirdPeptideSequence  = "PEPTIDED";
            var          peptideSettingsUi     = ShowDialog <PeptideSettingsUI>(SkylineWindow.ShowPeptideSettingsUI);

            RunUI(() =>
            {
                peptideSettingsUi.SelectedTab    = PeptideSettingsUI.TABS.Filter;
                peptideSettingsUi.TextExcludeAAs = 0;
                peptideSettingsUi.SelectedTab    = PeptideSettingsUI.TABS.Library;
            });
            var libListDlg =
                ShowDialog <EditListDlg <SettingsListBase <LibrarySpec>, LibrarySpec> >(peptideSettingsUi.EditLibraryList);
            var addLibDlg = ShowDialog <EditLibraryDlg>(libListDlg.AddItem);

            RunUI(() =>
            {
                addLibDlg.LibraryName = "peptides";
                addLibDlg.LibraryPath = TestFilesDir.GetTestPath("peptides.blib");
            });
            OkDialog(addLibDlg, addLibDlg.OkDialog);

            addLibDlg = ShowDialog <EditLibraryDlg>(libListDlg.AddItem);
            RunUI(() =>
            {
                addLibDlg.LibraryName = "peptided";
                addLibDlg.LibraryPath = TestFilesDir.GetTestPath("peptided.blib");
            });
            OkDialog(addLibDlg, addLibDlg.OkDialog);

            OkDialog(libListDlg, libListDlg.OkDialog);
            RunUI(() =>
            {
                peptideSettingsUi.SetLibraryChecked(0, true);
                peptideSettingsUi.SetLibraryChecked(1, true);
                peptideSettingsUi.SelectedTab = PeptideSettingsUI.TABS.Digest;
                peptideSettingsUi.PeptidePick = PeptidePick.either;
            });

            // Create a background proteome with protein "MyProtein" whose sequence contains both "PEPTIDEA" and "PEPTIDEC".
            var buildBackgroundProteomeDlg = ShowDialog <BuildBackgroundProteomeDlg>(
                peptideSettingsUi.ShowBuildBackgroundProteomeDlg);

            RunUI(() =>
            {
                buildBackgroundProteomeDlg.BackgroundProteomeName = "MyBackgroundProteome";
                buildBackgroundProteomeDlg.BackgroundProteomePath = TestFilesDir.GetTestPath("MyBackgroundProteome.protdb");
                buildBackgroundProteomeDlg.AddFastaFile(TestFilesDir.GetTestPath("PEPTIDEC.fasta"));
            });
            OkDialog(buildBackgroundProteomeDlg, buildBackgroundProteomeDlg.OkDialog);
            OkDialog(peptideSettingsUi, peptideSettingsUi.OkDialog);
            WaitForDocumentLoaded();

            Assert.AreEqual(0, SkylineWindow.Document.MoleculeGroupCount);
            // Add a protein to the document whose name is "MyProtein" and whose sequence contains "PEPTIDEA" but does not
            // contain "PEPTIDEC".
            SetClipboardTextUI(">MyProtein\r\nKAAAPEPTIDEAAAKKK");
            RunUI(() => SkylineWindow.Paste());
            Assert.AreEqual(1, SkylineWindow.Document.MoleculeGroupCount);
            var firstProtein = SkylineWindow.Document.PeptideGroups.FirstOrDefault();

            Assert.IsNotNull(firstProtein);
            StringAssert.Contains(firstProtein.PeptideGroup.Sequence, firstPeptideSequence);
            Assert.IsFalse(firstProtein.PeptideGroup.Sequence.Contains(secondPeptideSequence));

            // Add the peptides "PEPTIDEA" and "PEPTIDEC" to the document, and associate proteins.
            var libraryViewer = ShowDialog <ViewLibraryDlg>(SkylineWindow.ViewSpectralLibraries);

            RunUI(() =>
            {
                libraryViewer.ChangeSelectedLibrary("peptides");
                libraryViewer.AssociateMatchingProteins = true;
            });
            RunDlg <AlertDlg>(libraryViewer.AddAllPeptides, alertDlg => alertDlg.DialogResult = DialogResult.Yes);

            // Verify that "PEPTIDEA" got added to the first protein, and that a new protein had to be created for "PEPTIDEC" since
            // the first protein's sequence did not contain it.
            var doc = SkylineWindow.Document;

            Assert.AreEqual(2, doc.Children.Count);
            firstProtein = (PeptideGroupDocNode)doc.Children[0];
            PeptideGroupDocNode secondProtein = (PeptideGroupDocNode)doc.Children[1];

            Assert.AreEqual(1, secondProtein.Children.Count);

            StringAssert.Contains(firstProtein.PeptideGroup.Sequence, firstPeptideSequence);
            Assert.IsFalse(firstProtein.PeptideGroup.Sequence.Contains(secondPeptideSequence));
            StringAssert.Contains(secondProtein.PeptideGroup.Sequence, secondPeptideSequence);

            var firstPeptide = firstProtein.Peptides.FirstOrDefault(pep => firstPeptideSequence.Equals(pep.Peptide.Sequence));

            Assert.IsNotNull(firstPeptide);
            StringAssert.Contains(secondProtein.PeptideGroup.Sequence, secondPeptideSequence);
            var secondPeptide = secondProtein.Peptides.FirstOrDefault(pep => secondPeptideSequence.Equals(pep.Peptide.Sequence));

            Assert.IsNotNull(secondPeptide);
            Assert.IsNull(firstProtein.Peptides.FirstOrDefault(pep => pep.Peptide.Sequence == secondPeptide.Peptide.Sequence));

            // Now add just the peptide "PEPTIDED" and make sure it gets added to the second protein in the document.
            RunUI(() => libraryViewer.ChangeSelectedLibrary("peptided"));
            RunDlg <AlertDlg>(libraryViewer.AddAllPeptides, alertDlg => alertDlg.DialogResult = DialogResult.Yes);
            secondProtein = (PeptideGroupDocNode)SkylineWindow.Document.Children[1];
            Assert.AreEqual(2, secondProtein.Children.Count);
            var thirdPeptide = (PeptideDocNode)secondProtein.Children[1];

            Assert.AreEqual(thirdPeptideSequence, thirdPeptide.Peptide.Sequence);

            OkDialog(libraryViewer, libraryViewer.Close);
        }
Ejemplo n.º 7
0
 private static Tuple <IdentityPath, PeptideGroupDocNode> ToIdentityPathTuple(PeptideGroupDocNode peptideGroupDocNode)
 {
     return(Tuple.Create(new IdentityPath(peptideGroupDocNode.Id), peptideGroupDocNode));
 }
Ejemplo n.º 8
0
 public static CalibrationCurveFitter GetCalibrationCurveFitter(SrmSettings srmSettings,
                                                                PeptideGroupDocNode peptideGroup, PeptideDocNode peptide)
 {
     return(new CalibrationCurveFitter(PeptideQuantifier.GetPeptideQuantifier(null, srmSettings, peptideGroup, peptide), srmSettings));
 }
Ejemplo n.º 9
0
 public static CalibrationCurveFitter GetCalibrationCurveFitter(SrmSettings srmSettings,
     PeptideGroupDocNode peptideGroup, PeptideDocNode peptide)
 {
     return new CalibrationCurveFitter(PeptideQuantifier.GetPeptideQuantifier(srmSettings, peptideGroup, peptide), srmSettings);
 }
Ejemplo n.º 10
0
 public static string ProteinModalDisplayText(PeptideGroupDocNode node)
 {
     return(ProteinModalDisplayText(node.ProteinMetadata, Settings.Default.ShowPeptidesDisplayMode));
 }
Ejemplo n.º 11
0
        public static OptimizationDb ConvertFromOldFormat(string path, IProgressMonitor loadMonitor, ProgressStatus status, SrmDocument document)
        {
            // Try to open assuming old format (Id, PeptideModSeq, Charge, Mz, Value, Type)
            var precursors    = new Dictionary <string, HashSet <int> >();    // PeptideModSeq -> charges
            var optimizations = new List <Tuple <DbOptimization, double> >(); // DbOptimization, product m/z
            int maxCharge     = 1;

            using (SQLiteConnection connection = new SQLiteConnection("Data Source = " + path)) // Not L10N
                using (SQLiteCommand command = new SQLiteCommand(connection))
                {
                    connection.Open();
                    command.CommandText = "SELECT PeptideModSeq, Charge, Mz, Value, Type FROM OptimizationLibrary"; // Not L10N
                    using (SQLiteDataReader reader = command.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var type             = (OptimizationType)reader["Type"];   // Not L10N
                            var modifiedSequence = reader["PeptideModSeq"].ToString(); // Not L10N
                            var charge           = (int)reader["Charge"];              // Not L10N
                            var productMz        = (double)reader["Mz"];               // Not L10N
                            var value            = (double)reader["Value"];            // Not L10N
                            optimizations.Add(new Tuple <DbOptimization, double>(new DbOptimization(type, modifiedSequence, charge, string.Empty, -1, value), productMz));

                            if (!precursors.ContainsKey(modifiedSequence))
                            {
                                precursors[modifiedSequence] = new HashSet <int>();
                            }
                            precursors[modifiedSequence].Add(charge);
                            if (charge > maxCharge)
                            {
                                maxCharge = charge;
                            }
                        }
                    }
                }

            var peptideList = (from precursor in precursors
                               from charge in precursor.Value
                               select string.Format("{0}{1}", precursor.Key, Transition.GetChargeIndicator(charge)) // Not L10N
                               ).ToList();

            var newDoc = new SrmDocument(document != null ? document.Settings : SrmSettingsList.GetDefault());

            newDoc = newDoc.ChangeSettings(newDoc.Settings
                                           .ChangePeptideLibraries(libs => libs.ChangePick(PeptidePick.filter))
                                           .ChangeTransitionFilter(filter =>
                                                                   filter.ChangeFragmentRangeFirstName("ion 1") // Not L10N
                                                                   .ChangeFragmentRangeLastName("last ion")     // Not L10N
                                                                   .ChangeProductCharges(Enumerable.Range(1, maxCharge).ToList())
                                                                   .ChangeIonTypes(new [] { IonType.y, IonType.b }))
                                           .ChangeTransitionLibraries(libs => libs.ChangePick(TransitionLibraryPick.none))
                                           );
            var matcher = new ModificationMatcher {
                FormatProvider = NumberFormatInfo.InvariantInfo
            };

            matcher.CreateMatches(newDoc.Settings, peptideList, Settings.Default.StaticModList, Settings.Default.HeavyModList);
            FastaImporter       importer = new FastaImporter(newDoc, matcher);
            string              text     = string.Format(">>{0}\r\n{1}", newDoc.GetPeptideGroupId(true), TextUtil.LineSeparate(peptideList)); // Not L10N
            PeptideGroupDocNode imported = importer.Import(new StringReader(text), null, Helpers.CountLinesInString(text)).First();

            int optimizationsUpdated = 0;

            foreach (PeptideDocNode nodePep in imported.Children)
            {
                string sequence = newDoc.Settings.GetSourceTextId(nodePep);
                foreach (var nodeGroup in nodePep.TransitionGroups)
                {
                    int charge = nodeGroup.PrecursorCharge;
                    foreach (var nodeTran in nodeGroup.Transitions)
                    {
                        double productMz = nodeTran.Mz;
                        foreach (var optimization in optimizations.Where(opt =>
                                                                         string.IsNullOrEmpty(opt.Item1.FragmentIon) &&
                                                                         opt.Item1.ProductCharge == -1 &&
                                                                         opt.Item1.PeptideModSeq == sequence &&
                                                                         opt.Item1.Charge == charge &&
                                                                         Math.Abs(opt.Item2 - productMz) < 0.00001))
                        {
                            optimization.Item1.FragmentIon   = nodeTran.FragmentIonName;
                            optimization.Item1.ProductCharge = nodeTran.Transition.Charge;
                            ++optimizationsUpdated;
                        }
                    }
                }
            }

            if (optimizations.Count > optimizationsUpdated)
            {
                throw new OptimizationsOpeningException(string.Format(Resources.OptimizationDb_ConvertFromOldFormat_Failed_to_convert__0__optimizations_to_new_format_,
                                                                      optimizations.Count - optimizationsUpdated));
            }

            using (var fs = new FileSaver(path))
            {
                OptimizationDb db = CreateOptimizationDb(fs.SafeName);
                db.UpdateOptimizations(optimizations.Select(opt => opt.Item1).ToArray(), new DbOptimization[0]);
                fs.Commit();

                if (loadMonitor != null)
                {
                    loadMonitor.UpdateProgress(status.ChangePercentComplete(100));
                }
                return(GetOptimizationDb(fs.RealName, null, null));
            }
        }
Ejemplo n.º 12
0
        private static SrmDocument AddPeptidesToLibraryGroup(SrmDocument document,
                                                             ICollection <PeptideMatch> listMatches,
                                                             ILongWaitBroker broker,
                                                             IdentityPath toPath,
                                                             out IdentityPath selectedPath)
        {
            // Get starting progress values
            int startPercent     = (broker != null ? broker.ProgressValue : 0);
            int processedPercent = 0;
            int processedCount   = 0;
            int totalMatches     = listMatches.Count;

            selectedPath = null;

            // Some .blib files provide protein accessions (understood as Molecule List Names fro small molecules).
            // If those are provided we will use them as node names.
            // TODO(bspratt) for now we will do this only for small molecules since it might be a surprise to proteomics users. We should revisit that decision.
            foreach (var proteinName in listMatches.Select(m => m.LibInfo.Protein).Distinct())
            {
                var listPeptides      = new List <PeptideDocNode>();
                var hasSmallMolecules = false;
                foreach (var match in listMatches.Where(m => Equals(proteinName, m.LibInfo.Protein)))
                {
                    // Show progress, if in a long wait
                    if (broker != null)
                    {
                        if (broker.IsCanceled)
                        {
                            selectedPath = null;
                            return(document);
                        }
                        processedCount++;
                        int processPercentNow = processedCount * (100 - startPercent) / totalMatches;
                        if (processedPercent != processPercentNow)
                        {
                            processedPercent     = processPercentNow;
                            broker.ProgressValue = startPercent + processedPercent;
                        }
                    }

                    listPeptides.Add(match.NodePep.ChangeSettings(document.Settings, SrmSettingsDiff.ALL));
                    hasSmallMolecules |= !match.NodePep.IsProteomic;
                }

                bool hasVariable =
                    listPeptides.Contains(nodePep => nodePep.HasExplicitMods && nodePep.ExplicitMods.IsVariableStaticMods);

                // Use existing group by this name, if present.
                // If library provides a RefSpectraProteins table, use that to name the group
                // TODO(bspratt) for now we will use RefSpectraProteins names only for small molecules
                var genericLibraryPeptidesGroupName = hasSmallMolecules
                    ? Resources.ViewLibraryPepMatching_AddPeptidesToLibraryGroup_Library_Molecules
                    : Resources.ViewLibraryPepMatching_AddPeptidesToLibraryGroup_Library_Peptides;
                var nodeName = string.IsNullOrEmpty(proteinName) ||
                               listPeptides.Any(p => p.IsProteomic) // TODO(bspratt) revisit this caution-driven decision
                    ? genericLibraryPeptidesGroupName
                    : proteinName;
                var nodePepGroupNew = FindPeptideGroupDocNode(document, nodeName, null);
                if (nodePepGroupNew != null)
                {
                    var newChildren = nodePepGroupNew.Children.ToList();
                    newChildren.AddRange(listPeptides.ConvertAll(nodePep => (DocNode)nodePep));
                    selectedPath    = (listPeptides.Count == 1 ? new IdentityPath(nodePepGroupNew.Id, listPeptides[0].Id) : toPath);
                    nodePepGroupNew = (PeptideGroupDocNode)nodePepGroupNew.ChangeChildren(newChildren);
                    if (hasVariable)
                    {
                        nodePepGroupNew = (PeptideGroupDocNode)nodePepGroupNew.ChangeAutoManageChildren(false);
                    }
                    document = (SrmDocument)document.ReplaceChild(nodePepGroupNew);
                }
                else
                {
                    nodePepGroupNew = new PeptideGroupDocNode(new PeptideGroup(),
                                                              nodeName,
                                                              string.Empty, listPeptides.ToArray());
                    if (hasVariable)
                    {
                        nodePepGroupNew = (PeptideGroupDocNode)nodePepGroupNew.ChangeAutoManageChildren(false);
                    }
                    IdentityPath nextAdd;
                    document = document.AddPeptideGroups(new[] { nodePepGroupNew }, true,
                                                         toPath, out selectedPath, out nextAdd);
                    selectedPath = new IdentityPath(selectedPath, nodePepGroupNew.Children[0].Id);
                }
            }
            return(document);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Adds all peptides which can be matched to a background proteome to the
        /// proteins in the background proteins, and returns a new document with those
        /// proteins and peptides added.
        /// </summary>
        /// <param name="document">The starting document</param>
        /// <param name="dictCopy">A dictionary of peptides to peptide matches. All added
        /// peptides are removed</param>
        /// <param name="broker">For reporting long wait status</param>
        /// <param name="toPath">Path to the location in the document to add new items</param>
        /// <param name="selectedPath">Path to item in the document that should be selected
        /// after this operation is complete</param>
        /// <returns>A new document with matching peptides and their proteins addded</returns>
        private SrmDocument AddProteomePeptides(SrmDocument document,
                                                Dictionary <PeptideSequenceModKey, PeptideMatch> dictCopy,
                                                ILongWaitBroker broker,
                                                IdentityPath toPath,
                                                out IdentityPath selectedPath)
        {
            // Build a list of new PeptideGroupDocNodes to add to the document.
            var dictPeptideGroupsNew = new Dictionary <string, PeptideGroupDocNode>();

            // Get starting progress values
            int startPercent     = (broker != null ? broker.ProgressValue : 0);
            int processedPercent = 0;
            int processedCount   = 0;
            int totalMatches     = dictCopy.Count;

            // Just to make sure this is set
            selectedPath = toPath;

            foreach (PeptideMatch pepMatch in dictCopy.Values)
            {
                // Show progress, if in a long wait
                if (broker != null)
                {
                    if (broker.IsCanceled)
                    {
                        selectedPath = toPath;
                        return(document);
                    }
                    // All peptides with protein get processed in this loop.  Peptides
                    // without proteins get added later.
                    if (pepMatch.Proteins != null)
                    {
                        processedCount++;
                    }
                    int processPercentNow = processedCount * (100 - startPercent) / totalMatches;
                    if (processedPercent != processPercentNow)
                    {
                        processedPercent     = processPercentNow;
                        broker.ProgressValue = startPercent + processedPercent;
                    }
                }
                // Peptide should be added to the document,
                // unless the NoDuplicates radio was selected and the peptide has more than 1 protein associated with it.
                if (pepMatch.Proteins == null ||
                    (FilterMultipleProteinMatches == BackgroundProteome.DuplicateProteinsFilter.NoDuplicates && pepMatch.Proteins.Count > 1))
                {
                    continue;
                }


                foreach (ProteinInfo protein in pepMatch.Proteins)
                {
                    // Look for the protein in the document.
                    string name = protein.ProteinMetadata.Name;
                    var    peptideGroupDocNode = FindPeptideGroupDocNode(document, name, pepMatch.NodePep.Peptide.Sequence);
                    bool   foundInDoc          = peptideGroupDocNode != null;
                    bool   foundInList         = false;
                    if (!foundInDoc)
                    {
                        // If the protein is not already in the document,
                        // check to see if we have already created a PeptideGroupDocNode for it.
                        if (name != null && dictPeptideGroupsNew.TryGetValue(name, out peptideGroupDocNode))
                        {
                            foundInList = true;
                        }
                        // If not, create a new PeptideGroupDocNode.
                        else
                        {
                            List <ProteinMetadata> alternativeProteins = new List <ProteinMetadata>(protein.Alternatives);
                            peptideGroupDocNode = new PeptideGroupDocNode(
                                new FastaSequence(name, protein.ProteinMetadata.Description, alternativeProteins, protein.Sequence),
                                null, null, new PeptideDocNode[0]);
                        }
                    }
                    // Create a new peptide that matches this protein.
                    var fastaSequence   = peptideGroupDocNode.PeptideGroup as FastaSequence;
                    var peptideSequence = pepMatch.NodePep.Peptide.Target.Sequence;
                    // ReSharper disable PossibleNullReferenceException
                    var begin = fastaSequence.Sequence.IndexOf(peptideSequence, StringComparison.Ordinal);
                    // ReSharper restore PossibleNullReferenceException
                    // Create a new PeptideDocNode using this peptide.
                    var newPeptide = new Peptide(fastaSequence, peptideSequence, begin, begin + peptideSequence.Length,
                                                 Settings.PeptideSettings.Enzyme.CountCleavagePoints(peptideSequence));
                    // Make sure we keep the same children.
                    PeptideMatch match      = pepMatch;
                    var          newNodePep = ((PeptideDocNode) new PeptideDocNode(newPeptide, pepMatch.NodePep.ExplicitMods, pepMatch.NodePep.ExplicitRetentionTime)
                                               .ChangeChildren(pepMatch.NodePep.Children.ToList().ConvertAll(nodeGroup =>
                    {
                        // Create copies of the children in order to prevent transition groups with the same
                        // global indices.
                        var nodeTranGroup = (TransitionGroupDocNode)nodeGroup;
                        if (match.Proteins != null && match.Proteins.Count > 1)
                        {
                            nodeTranGroup = (TransitionGroupDocNode)nodeTranGroup.CopyId();
                            nodeTranGroup = (TransitionGroupDocNode)nodeTranGroup.ChangeChildren(
                                nodeTranGroup.Children.ToList().ConvertAll(nodeTran => nodeTran.CopyId()));
                        }
                        return((DocNode)nodeTranGroup);
                    })).ChangeAutoManageChildren(false)).ChangeSettings(document.Settings, SrmSettingsDiff.ALL);
                    // If this PeptideDocNode is already a child of the PeptideGroupDocNode,
                    // ignore it.
                    if (peptideGroupDocNode.Children.Contains(nodePep => Equals(((PeptideDocNode)nodePep).Key, newNodePep.Key)))
                    {
                        Console.WriteLine(Resources.ViewLibraryPepMatching_AddProteomePeptides_Skipping__0__already_present, newNodePep.Peptide.Target);
                        continue;
                    }
                    // Otherwise, add it to the list of children for the PeptideGroupNode.
                    var newChildren = peptideGroupDocNode.Children.Cast <PeptideDocNode>().ToList();
                    newChildren.Add(newNodePep);
                    newChildren.Sort(FastaSequence.ComparePeptides);

                    // Store modified proteins by global index in a HashSet for second pass.
                    var newPeptideGroupDocNode = peptideGroupDocNode.ChangeChildren(newChildren.Cast <DocNode>().ToArray())
                                                 .ChangeAutoManageChildren(false);
                    // If the protein was already in the document, replace with the new PeptideGroupDocNode.
                    if (foundInDoc)
                    {
                        document = (SrmDocument)document.ReplaceChild(newPeptideGroupDocNode);
                    }
                    // Otherwise, update the list of new PeptideGroupDocNodes to add.
                    else
                    {
                        if (foundInList)
                        {
                            dictPeptideGroupsNew.Remove(peptideGroupDocNode.Name);
                        }
                        dictPeptideGroupsNew.Add(peptideGroupDocNode.Name, (PeptideGroupDocNode)newPeptideGroupDocNode);
                    }
                    // If we are only adding a single node, select it.
                    if (PeptideMatches.Count == 1)
                    {
                        selectedPath = new IdentityPath(new[] { peptideGroupDocNode.Id, newNodePep.Peptide });
                    }
                    // If the user only wants to add the first protein found,
                    // we break the foreach loop after peptide has been added to its first protein.)
                    if (FilterMultipleProteinMatches == BackgroundProteome.DuplicateProteinsFilter.FirstOccurence)
                    {
                        break;
                    }
                }
            }

            if (dictPeptideGroupsNew.Count == 0)
            {
                return(document);
            }

            // Sort the peptides.
            var nodePepGroupsSortedChildren = new List <PeptideGroupDocNode>();

            foreach (PeptideGroupDocNode nodePepGroup in dictPeptideGroupsNew.Values)
            {
                var newChildren = nodePepGroup.Children.ToList();
                // Have to cast all children to PeptideDocNodes in order to sort.
                var newChildrenNodePeps = newChildren.Cast <PeptideDocNode>().ToList();
                newChildrenNodePeps.Sort(FastaSequence.ComparePeptides);
                nodePepGroupsSortedChildren.Add((PeptideGroupDocNode)
                                                nodePepGroup.ChangeChildren(newChildrenNodePeps.Cast <DocNode>().ToArray()));
            }
            // Sort the proteins.
            nodePepGroupsSortedChildren.Sort((node1, node2) => Comparer <string> .Default.Compare(node1.Name, node2.Name));
            IdentityPath selPathTemp = selectedPath, nextAdd;

            document = document.AddPeptideGroups(nodePepGroupsSortedChildren, false,
                                                 toPath, out selectedPath, out nextAdd);
            selectedPath = PeptideMatches.Count == 1 ? selPathTemp : selectedPath;
            return(document);
        }