/// <summary> /// Enumerate all document peptides. If a library peptide already exists in the /// current document, update the transition groups for that document peptide and /// remove the peptide from the list to add. /// </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="toPath">Currently selected path.</param> /// <param name="selectedPath">Selected path after the nodes have been added</param> /// <returns>A new document with precursors for existing petides added</returns> private SrmDocument UpdateExistingPeptides(SrmDocument document, Dictionary <PeptideSequenceModKey, PeptideMatch> dictCopy, IdentityPath toPath, out IdentityPath selectedPath) { selectedPath = toPath; IList <DocNode> nodePepGroups = new List <DocNode>(); var keysAddedWithoutMatch = new SortedDictionary <PeptideSequenceModKey, PeptideMatch>(); foreach (PeptideGroupDocNode nodePepGroup in document.MoleculeGroups) { IList <DocNode> nodePeps = new List <DocNode>(); foreach (PeptideDocNode nodePep in nodePepGroup.Children) { var key = nodePep.SequenceKey; PeptideMatch peptideMatch; // If this peptide is not in our list of peptides to add, // or if we are in a peptide list and this peptide has been matched to protein(s), // then we don't touch this particular node. if (!dictCopy.TryGetValue(key, out peptideMatch) || (nodePepGroup.IsPeptideList && (peptideMatch.Proteins != null && peptideMatch.Proteins.Any()))) { nodePeps.Add(nodePep); if (keysAddedWithoutMatch.ContainsKey(key)) { keysAddedWithoutMatch.Add(key, new PeptideMatch(null, null, false)); } } else { var proteinName = nodePepGroup.PeptideGroup.Name; int indexProtein = -1; if (peptideMatch.Proteins != null) { indexProtein = peptideMatch.Proteins.IndexOf(protein => Equals(protein.ProteinMetadata.Name, proteinName)); // If the user has opted to filter duplicate peptides, remove this peptide from the list to // add and continue. if (FilterMultipleProteinMatches == BackgroundProteome.DuplicateProteinsFilter.NoDuplicates && peptideMatch.Proteins.Count > 1) { dictCopy.Remove(key); nodePeps.Add(nodePep); continue; } // [1] If this protein is not the first match, and the user has opted to add only the first occurence, // [2] or if this protein is not one of the matches, and [2a] we are either not in a peptide list // [2b] or the user has opted to filter unmatched peptides, ignore this particular node. if ((indexProtein > 0 && FilterMultipleProteinMatches == BackgroundProteome.DuplicateProteinsFilter.FirstOccurence) || (indexProtein == -1 && (!nodePepGroup.IsPeptideList || !Properties.Settings.Default.LibraryPeptidesAddUnmatched))) { nodePeps.Add(nodePep); continue; } } // Update the children of the peptide in the document to include the charge state of the peptide we are adding. PeptideDocNode nodePepMatch = peptideMatch.NodePep; PeptideDocNode nodePepSettings = null; var newChildren = nodePep.Children.ToList(); Identity nodeGroupChargeId = newChildren.Count > 0 ? newChildren[0].Id : null; foreach (TransitionGroupDocNode nodeGroup in nodePepMatch.Children) { var chargeGroup = nodeGroup.TransitionGroup.PrecursorAdduct; if (nodePep.HasChildCharge(chargeGroup)) { SkippedPeptideCount++; } else { if (nodePepSettings == null) { nodePepSettings = nodePepMatch.ChangeSettings(document.Settings, SrmSettingsDiff.ALL); } TransitionGroupDocNode nodeGroupCharge = (TransitionGroupDocNode)nodePepSettings.FindNode(nodeGroup.TransitionGroup); if (nodeGroupCharge == null) { continue; } if (peptideMatch.Proteins != null && peptideMatch.Proteins.Count > 1) { // If we may be adding this specific node to the document more than once, create a copy of it so that // we don't have two nodes with the same global id. nodeGroupCharge = (TransitionGroupDocNode)nodeGroupCharge.CopyId(); nodeGroupCharge = (TransitionGroupDocNode)nodeGroupCharge.ChangeChildren( nodeGroupCharge.Children.ToList().ConvertAll(child => child.CopyId())); } nodeGroupChargeId = nodeGroupCharge.Id; newChildren.Add(nodeGroupCharge); } } // Sort the new peptide children. newChildren.Sort(Peptide.CompareGroups); var nodePepAdd = nodePep.ChangeChildrenChecked(newChildren); // If we have changed the children, need to set automanage children to false. if (nodePep.AutoManageChildren && !ReferenceEquals(nodePep, nodePepAdd)) { nodePepAdd = nodePepAdd.ChangeAutoManageChildren(false); } // Change the selected path. if (PeptideMatches.Count == 1) { selectedPath = nodeGroupChargeId == null ? new IdentityPath(new[] { nodePepGroup.Id, nodePepAdd.Id }) : new IdentityPath(new[] { nodePepGroup.Id, nodePepAdd.Id, nodeGroupChargeId }); } nodePeps.Add(nodePepAdd); // Remove this peptide from the list of peptides we need to add to the document dictCopy.Remove(key); if (peptideMatch.Proteins != null) { if (indexProtein != -1) { // Remove this protein from the list of proteins associated with the peptide. peptideMatch.Proteins.RemoveAt(indexProtein); } // If this peptide has not yet been added to all matched proteins, // put it back in the list of peptides to add. if (peptideMatch.Proteins.Count != 0 && FilterMultipleProteinMatches != BackgroundProteome.DuplicateProteinsFilter.FirstOccurence) { dictCopy.Add(key, peptideMatch); } } } } nodePepGroups.Add(nodePepGroup.ChangeChildrenChecked(nodePeps)); } return((SrmDocument)document.ChangeChildrenChecked(nodePepGroups)); }