public void TestCrosslinkModSerialization() { var settings = SrmSettingsList.GetDefault(); var crosslinkerDef = new StaticMod("disulfide", null, null, "-H2") .ChangeCrosslinkerSettings(CrosslinkerSettings.EMPTY); settings = settings.ChangePeptideSettings(settings.PeptideSettings.ChangeModifications( settings.PeptideSettings.Modifications.ChangeStaticModifications(new[] { crosslinkerDef }))); settings = settings.ChangeTransitionSettings(settings.TransitionSettings.ChangeFilter( settings.TransitionSettings.Filter .ChangeFragmentRangeFirstName(TransitionFilter.StartFragmentFinder.ION_1.Name) .ChangeFragmentRangeLastName(@"last ion") .ChangePeptideIonTypes(new[] { IonType.precursor, IonType.y, IonType.b }) )); var mainPeptide = new Peptide("MERCURY"); var transitionGroup = new TransitionGroup(mainPeptide, Adduct.DOUBLY_PROTONATED, IsotopeLabelType.light); var linkedPeptide = new LinkedPeptide(new Peptide("ARSENIC"), 2, null); var crosslinkMod = new ExplicitMod(3, crosslinkerDef).ChangeLinkedPeptide(linkedPeptide); var explicitModsWithCrosslink = new ExplicitMods(mainPeptide, new[] { crosslinkMod }, new TypedExplicitModifications[0]); var transitionGroupDocNode = new TransitionGroupDocNode(transitionGroup, Annotations.EMPTY, settings, explicitModsWithCrosslink, null, ExplicitTransitionGroupValues.EMPTY, null, null, true); var peptideDocNode = new PeptideDocNode(mainPeptide, settings, explicitModsWithCrosslink, null, ExplicitRetentionTimeInfo.EMPTY, new [] { transitionGroupDocNode }, false); peptideDocNode = peptideDocNode.ChangeSettings(settings, SrmSettingsDiff.ALL); Assert.AreNotEqual(0, peptideDocNode.TransitionCount); var peptideGroupDocNode = new PeptideGroupDocNode(new PeptideGroup(), Annotations.EMPTY, "Peptides", null, new [] { peptideDocNode }); var srmDocument = (SrmDocument) new SrmDocument(settings).ChangeChildren(new[] { peptideGroupDocNode }); AssertEx.Serializable(srmDocument); string docXML = null; AssertEx.RoundTrip(srmDocument, ref docXML); Assert.IsNotNull(docXML); }
private PeptideDocNode CreateDocNodeFromSettings(Target seq, PeptideDocNode nodePep, SrmSettingsDiff diff, out TransitionGroupDocNode nodeGroupMatched) { PeptideDocNode nodePepMod = nodePep.ChangeSettings(Settings, diff ?? SrmSettingsDiff.ALL, false); TransitionGroupDocNode nodeGroupMatchedFound; if (IsMatch(seq, nodePepMod, out nodeGroupMatchedFound)) { nodeGroupMatched = nodeGroupMatchedFound; return(nodePepMod); } nodeGroupMatched = null; return(null); }
public PeptideDocNode ChangeFastaSequence(SrmSettings srmSettings, PeptideDocNode peptideDocNode, FastaSequence newSequence) { int begin = newSequence.Sequence.IndexOf(peptideDocNode.Peptide.Target.Sequence, StringComparison.Ordinal); int end = begin + peptideDocNode.Peptide.Target.Sequence.Length; var newPeptide = new Peptide(newSequence, peptideDocNode.Peptide.Target.Sequence, begin, end, peptideDocNode.Peptide.MissedCleavages); var newPeptideDocNode = new PeptideDocNode(newPeptide, srmSettings, peptideDocNode.ExplicitMods, peptideDocNode.SourceKey, peptideDocNode.GlobalStandardType, peptideDocNode.Rank, peptideDocNode.ExplicitRetentionTime, peptideDocNode.Annotations, peptideDocNode.Results, peptideDocNode.TransitionGroups.ToArray(), false); // Don't automanage this peptide newPeptideDocNode = newPeptideDocNode.ChangeSettings(srmSettings, SrmSettingsDiff.ALL); return(newPeptideDocNode); }
public PeptideGroupDocNode ChangeSettings(SrmSettings settingsNew, SrmSettingsDiff diff) { if (diff.Monitor != null) { diff.Monitor.ProcessGroup(this); } if (diff.DiffPeptides && settingsNew.PeptideSettings.Filter.AutoSelect && AutoManageChildren) { IList <DocNode> childrenNew = new List <DocNode>(); int countPeptides = 0; int countIons = 0; Dictionary <int, DocNode> mapIndexToChild = CreateGlobalIndexToChildMap(); Dictionary <PeptideModKey, DocNode> mapIdToChild = CreatePeptideModToChildMap(); foreach (PeptideDocNode nodePep in GetPeptideNodes(settingsNew, true)) { PeptideDocNode nodePepResult = nodePep; SrmSettingsDiff diffNode = SrmSettingsDiff.ALL; DocNode existing; // Add values that existed before the change. First check for exact match by // global index, which will happen when explicit modifications are added, // and then by content identity. if (mapIndexToChild.TryGetValue(nodePep.Id.GlobalIndex, out existing) || mapIdToChild.TryGetValue(nodePep.Key, out existing)) { nodePepResult = (PeptideDocNode)existing; diffNode = diff; } if (nodePepResult != null) { // Materialize children of the peptide. nodePepResult = nodePepResult.ChangeSettings(settingsNew, diffNode); childrenNew.Add(nodePepResult); // Make sure a single peptide group does not exceed document limits. countPeptides++; countIons += nodePepResult.TransitionCount; if (countIons > SrmDocument.MAX_TRANSITION_COUNT) { throw new InvalidDataException(String.Format( Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_targeted_transitions_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_, SrmDocument.MAX_TRANSITION_COUNT)); } if (countPeptides > SrmDocument.MAX_PEPTIDE_COUNT) { throw new InvalidDataException(String.Format( Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_peptides_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_, SrmDocument.MAX_PEPTIDE_COUNT)); } } } if (PeptideGroup.Sequence != null) { childrenNew = PeptideGroup.RankPeptides(childrenNew, settingsNew, true); } return((PeptideGroupDocNode)ChangeChildrenChecked(childrenNew)); } else { var nodeResult = this; if (diff.DiffPeptides && diff.SettingsOld != null) { // If variable modifications changed, remove all peptides with variable // modifications which are no longer possible. var modsNew = settingsNew.PeptideSettings.Modifications; var modsVarNew = modsNew.VariableModifications.ToArray(); var modsOld = diff.SettingsOld.PeptideSettings.Modifications; var modsVarOld = modsOld.VariableModifications.ToArray(); if (modsNew.MaxVariableMods < modsOld.MaxVariableMods || !ArrayUtil.EqualsDeep(modsVarNew, modsVarOld)) { IList <DocNode> childrenNew = new List <DocNode>(); foreach (PeptideDocNode nodePeptide in nodeResult.Children) { if (nodePeptide.AreVariableModsPossible(modsNew.MaxVariableMods, modsVarNew)) { childrenNew.Add(nodePeptide); } } nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew); } } // Check for changes affecting children if (diff.DiffPeptideProps || diff.DiffExplicit || diff.DiffTransitionGroups || diff.DiffTransitionGroupProps || diff.DiffTransitions || diff.DiffTransitionProps || diff.DiffResults) { IList <DocNode> childrenNew = new List <DocNode>(); // Enumerate the nodes making necessary changes. foreach (PeptideDocNode nodePeptide in nodeResult.Children) { childrenNew.Add(nodePeptide.ChangeSettings(settingsNew, diff)); } childrenNew = RankChildren(settingsNew, childrenNew); nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew); } return(nodeResult); } }
public PeptideGroupDocNode ChangeSettings(SrmSettings settingsNew, SrmSettingsDiff diff, DocumentSettingsContext context = null) { if (diff.Monitor != null) { diff.Monitor.ProcessGroup(this); } if (diff.DiffPeptides && settingsNew.PeptideSettings.Filter.AutoSelect && AutoManageChildren) { IList <DocNode> childrenNew = new List <DocNode>(); int countPeptides = 0; int countIons = 0; Dictionary <int, DocNode> mapIndexToChild = CreateGlobalIndexToChildMap(); Dictionary <PeptideModKey, DocNode> mapIdToChild = CreatePeptideModToChildMap(); IEnumerable <PeptideDocNode> peptideDocNodes; if (settingsNew.PeptideSettings.Filter.PeptideUniqueness == PeptideFilter.PeptideUniquenessConstraint.none || settingsNew.PeptideSettings.NeedsBackgroundProteomeUniquenessCheckProcessing) { peptideDocNodes = GetPeptideNodes(settingsNew, true).ToList(); } else { // Checking peptide uniqueness against the background proteome can be expensive. // Do all the regular processing, then filter those results at the end when we // can do it in aggregate for best speed. IEnumerable <PeptideDocNode> peptideDocNodesUnique; var peptideDocNodesPrecalculatedForUniquenessCheck = context == null ? null : context.PeptideDocNodesPrecalculatedForUniquenessCheck; var uniquenessDict = context == null ? null : context.UniquenessDict; if (peptideDocNodesPrecalculatedForUniquenessCheck != null) { // Already processed, and a global list of peptides provided Assume.IsNotNull(uniquenessDict); peptideDocNodesUnique = peptideDocNodesPrecalculatedForUniquenessCheck; } else { // We'll have to do the processing for this node, and work with // just the peptides on this node. With luck the background proteome // will already have those cached for uniqueness checks. var settingsNoUniquenessFilter = settingsNew.ChangePeptideFilter(f => f.ChangePeptideUniqueness(PeptideFilter.PeptideUniquenessConstraint.none)); var nodes = GetPeptideNodes(settingsNoUniquenessFilter, true).ToList(); var sequences = new List <string>(from p in nodes select p.Peptide.Sequence); peptideDocNodesUnique = nodes; // Avoid ReSharper multiple enumeration warning uniquenessDict = settingsNew.PeptideSettings.Filter.CheckPeptideUniqueness(settingsNew, sequences, diff.Monitor); } // ReSharper disable once PossibleNullReferenceException peptideDocNodes = peptideDocNodesUnique.Where(p => { // It's possible during document load for uniqueness dict to get out of synch, so be // cautious with lookup and just return false of not found. Final document change will clean that up. bool isUnique; return(uniquenessDict.TryGetValue(p.Peptide.Sequence, out isUnique) && isUnique); }); } foreach (var nodePep in peptideDocNodes) { PeptideDocNode nodePepResult = nodePep; SrmSettingsDiff diffNode = SrmSettingsDiff.ALL; DocNode existing; // Add values that existed before the change. First check for exact match by // global index, which will happen when explicit modifications are added, // and then by content identity. if (mapIndexToChild.TryGetValue(nodePep.Id.GlobalIndex, out existing) || mapIdToChild.TryGetValue(nodePep.Key, out existing)) { nodePepResult = (PeptideDocNode)existing; diffNode = diff; } if (nodePepResult != null) { // Materialize children of the peptide. nodePepResult = nodePepResult.ChangeSettings(settingsNew, diffNode); childrenNew.Add(nodePepResult); // Make sure a single peptide group does not exceed document limits. countPeptides++; countIons += nodePepResult.TransitionCount; if (countIons > SrmDocument.MAX_TRANSITION_COUNT) { throw new InvalidDataException(String.Format( Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_targeted_transitions_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_, SrmDocument.MAX_TRANSITION_COUNT)); } if (countPeptides > SrmDocument.MAX_PEPTIDE_COUNT) { throw new InvalidDataException(String.Format( Resources.PeptideGroupDocNode_ChangeSettings_The_current_document_settings_would_cause_the_number_of_peptides_to_exceed__0_n0___The_document_settings_must_be_more_restrictive_or_add_fewer_proteins_, SrmDocument.MAX_PEPTIDE_COUNT)); } } } if (PeptideGroup.Sequence != null) { childrenNew = PeptideGroup.RankPeptides(childrenNew, settingsNew, true); } return((PeptideGroupDocNode)ChangeChildrenChecked(childrenNew)); } else { var nodeResult = this; if (diff.DiffPeptides && diff.SettingsOld != null) { // If variable modifications changed, remove all peptides with variable // modifications which are no longer possible. var modsNew = settingsNew.PeptideSettings.Modifications; var modsVarNew = modsNew.VariableModifications.ToArray(); var modsOld = diff.SettingsOld.PeptideSettings.Modifications; var modsVarOld = modsOld.VariableModifications.ToArray(); if (modsNew.MaxVariableMods < modsOld.MaxVariableMods || !ArrayUtil.EqualsDeep(modsVarNew, modsVarOld)) { IList <DocNode> childrenNew = new List <DocNode>(); foreach (PeptideDocNode nodePeptide in nodeResult.Children) { if (nodePeptide.AreVariableModsPossible(modsNew.MaxVariableMods, modsVarNew)) { childrenNew.Add(nodePeptide); } } nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew); } } // Check for changes affecting children if (diff.DiffPeptideProps || diff.DiffExplicit || diff.DiffTransitionGroups || diff.DiffTransitionGroupProps || diff.DiffTransitions || diff.DiffTransitionProps || diff.DiffResults) { IList <DocNode> childrenNew = new List <DocNode>(); // Enumerate the nodes making necessary changes. foreach (PeptideDocNode nodePeptide in nodeResult.Children) { childrenNew.Add(nodePeptide.ChangeSettings(settingsNew, diff)); } childrenNew = RankChildren(settingsNew, childrenNew); nodeResult = (PeptideGroupDocNode)nodeResult.ChangeChildrenChecked(childrenNew); } return(nodeResult); } }
/// <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)); }