/// <summary> /// Get the number of proteoform sequences possible with the provided number of dynamic modifications /// </summary> /// <param name="nDynMods"></param> /// <returns></returns> public double GetNumProteoformSequencesByNumMods(int nDynMods) { if (nDynMods < 1 || nDynMods > ModificationParams.MaxNumDynModsPerSequence) { return(0); } var numModCombs = _graph[_index].Length; var nProteoforms = 0d; for (var modIndex = 0; modIndex < numModCombs; modIndex++) { var modCombs = ModificationParams.GetModificationCombination(_graph[_index][modIndex].ModificationCombinationIndex); if (modCombs.GetNumModifications() < nDynMods) { continue; } if (modCombs.GetNumModifications() > nDynMods) { break; } nProteoforms += GetNumProteoformSequences(modIndex); //if (nProteoforms > double.MaxValue) return double.MaxValue; // overflow } return(nProteoforms); }
/// <summary> /// Get the modification combinations in the current sequence graph /// </summary> /// <returns></returns> public ModificationCombination[] GetModificationCombinations() { var numModCombs = _graph[_index].Length; var modCombs = new ModificationCombination[numModCombs]; for (var modIndex = 0; modIndex < numModCombs; modIndex++) { modCombs[modIndex] = ModificationParams.GetModificationCombination(_graph[_index][modIndex].ModificationCombinationIndex); } return(modCombs); }
/// <summary> /// Generate an amino acid map with 20 standard amino acids /// </summary> public AminoAcidSet() { // Initialization _modificationParams = new ModificationParams(); SearchModifications = new List <SearchModification>(); _locationSpecificResidueMap = new Dictionary <SequenceLocation, Dictionary <char, AminoAcid> >(); _locationSpecificResidueModMap = new Dictionary <SequenceLocation, Dictionary <char, int[]> >(); foreach (var loc in AllSequenceLocations) { _locationSpecificResidueModMap[loc] = new Dictionary <char, int[]>(); } // Initialize standard amino acid set foreach (var loc in AllSequenceLocations) { var residueMap = new Dictionary <char, AminoAcid>(); switch (loc) { case SequenceLocation.PeptideNTerm: residueMap.Add(AminoAcid.PeptideNTerm.Residue, AminoAcid.PeptideNTerm); break; case SequenceLocation.PeptideCTerm: residueMap.Add(AminoAcid.PeptideCTerm.Residue, AminoAcid.PeptideCTerm); break; case SequenceLocation.ProteinNTerm: residueMap.Add(AminoAcid.ProteinNTerm.Residue, AminoAcid.ProteinNTerm); break; case SequenceLocation.ProteinCTerm: residueMap.Add(AminoAcid.ProteinCTerm.Residue, AminoAcid.ProteinCTerm); break; } // loc is SequenceLocation.Everywhere foreach (var aa in AminoAcid.StandardAminoAcidArr) { residueMap.Add(aa.Residue, aa); } _locationSpecificResidueMap[loc] = residueMap; } }
// Generate an amino acid map with 20 standard amino acids public AminoAcidSet() { // Initialization _modificationParams = new ModificationParams(); _locationSpecificResidueMap = new Dictionary<SequenceLocation, Dictionary<char, AminoAcid>>(); _locationSpecificResidueModMap = new Dictionary<SequenceLocation, Dictionary<char, int[]>>(); foreach (var loc in AllSequenceLocations) { _locationSpecificResidueModMap[loc] = new Dictionary<char, int[]>(); } // Initialize standard amino acid set foreach (var loc in AllSequenceLocations) { var residueMap = new Dictionary<char, AminoAcid>(); switch (loc) { case SequenceLocation.PeptideNTerm: residueMap.Add(AminoAcid.PeptideNTerm.Residue, AminoAcid.PeptideNTerm); break; case SequenceLocation.PeptideCTerm: residueMap.Add(AminoAcid.PeptideCTerm.Residue, AminoAcid.PeptideCTerm); break; case SequenceLocation.ProteinNTerm: residueMap.Add(AminoAcid.ProteinNTerm.Residue, AminoAcid.ProteinNTerm); break; case SequenceLocation.ProteinCTerm: residueMap.Add(AminoAcid.ProteinCTerm.Residue, AminoAcid.ProteinCTerm); break; } foreach (var aa in AminoAcid.StandardAminoAcidArr) { residueMap.Add(aa.Residue, aa); } _locationSpecificResidueMap[loc] = residueMap; } }
/// <summary> /// Add an amino acid residue to this generator. /// </summary> /// <param name="index">index to add the amino acid. 0 is C-term. 1 is the C-term amino acid.</param> /// <param name="residue">amino acid residue to add.</param> /// <returns>true if residue is a valid amino acid; false otherwise.</returns> private bool PutAminoAcid(int index, char residue) { _index = index + 1; SequenceLocation?location = null; if (_index == 1) // C-term residue { if (residue == AminoAcid.PeptideCTerm.Residue) { location = SequenceLocation.PeptideCTerm; } else if (residue == AminoAcid.ProteinCTerm.Residue) { location = SequenceLocation.ProteinCTerm; } } else if (_index == _aminoAcidSequence.Length - 1 - NumNTermCleavages) // N-term residue { if (residue == AminoAcid.PeptideNTerm.Residue) { location = SequenceLocation.PeptideNTerm; } else if (residue == AminoAcid.ProteinNTerm.Residue) { location = SequenceLocation.ProteinNTerm; } } else if (_index == 2) // Amino acid at the C-term { if (_aminoAcidSequence[1] == AminoAcid.PeptideCTerm) { location = SequenceLocation.PeptideCTerm; } else if (_aminoAcidSequence[1] == AminoAcid.ProteinCTerm) { location = SequenceLocation.ProteinCTerm; } } else if (_index == _aminoAcidSequence.Length - 2 - NumNTermCleavages) // Amino acid at the N-term { if (_aminoAcidSequence[_aminoAcidSequence.Length - 1] == AminoAcid.PeptideNTerm) { location = SequenceLocation.PeptideNTerm; } else if (_aminoAcidSequence[_aminoAcidSequence.Length - 1] == AminoAcid.ProteinNTerm) { location = SequenceLocation.ProteinNTerm; } } else { location = SequenceLocation.Everywhere; } if (location == null) { return(false); } var loc = (SequenceLocation)location; var aminoAcid = AminoAcidSet.GetAminoAcid(residue, loc); if (aminoAcid == null) // residue is not valid { return(false); } _aminoAcidSequence[_index] = aminoAcid; _suffixComposition[_index] = _suffixComposition[_index - 1] + aminoAcid.Composition; var modIndices = AminoAcidSet.GetModificationIndices(residue, loc); if (!modIndices.Any()) // No modification { _graph[_index] = new Node[_graph[_index - 1].Length]; for (var i = 0; i < _graph[_index - 1].Length; i++) { _graph[_index][i] = new Node(_graph[_index - 1][i].ModificationCombinationIndex, i); } } else { var modCombIndexToNodeMap = new Dictionary <int, Node>(); for (var i = 0; i < _graph[_index - 1].Length; i++) { var prevNodeIndex = i; var prevNode = _graph[_index - 1][i]; var prevModCombIndex = prevNode.ModificationCombinationIndex; // unmodified edge if (modCombIndexToNodeMap.TryGetValue(prevModCombIndex, out var unmodifiedEdgeNode)) { unmodifiedEdgeNode.AddPrevNodeIndex(prevNodeIndex); } else { modCombIndexToNodeMap.Add(prevModCombIndex, new Node(prevModCombIndex, prevNodeIndex)); } // modified edge foreach (var modIndex in modIndices) { var modCombIndex = ModificationParams.GetModificationCombinationIndex( prevNode.ModificationCombinationIndex, modIndex); if (modCombIndex < 0) // too many modifications { continue; } if (modCombIndexToNodeMap.TryGetValue(modCombIndex, out var modifiedEdgeNode)) { modifiedEdgeNode.AddPrevNodeIndex(prevNodeIndex); } else { modCombIndexToNodeMap.Add(modCombIndex, new Node(modCombIndex, prevNodeIndex)); } } _graph[_index] = modCombIndexToNodeMap.Values.ToArray(); } } return(true); }
private Tuple <double, string> GetFragmentScoreAndModifications(int seqIndex, int modIndex, IScorer scorer, double?[][] nodeScore, Tuple <double, string>[][] maxScoreAndMods) { var scoreAndMods = maxScoreAndMods[seqIndex][modIndex]; if (scoreAndMods != null) { return(scoreAndMods); } var node = _graph[seqIndex][modIndex]; var curNodeScore = nodeScore[seqIndex][modIndex] ?? (nodeScore[seqIndex][modIndex] = scorer.GetFragmentScore(GetComplementaryComposition(seqIndex, modIndex), GetComposition(seqIndex, modIndex))); var bestPrevNodeIndex = -1; var bestPrevNodeScore = double.NegativeInfinity; string bestPrevSequence = null; foreach (var prevNodeIndex in node.GetPrevNodeIndices()) { var prevNodeScoreAndSequence = GetFragmentScoreAndModifications(seqIndex - 1, prevNodeIndex, scorer, nodeScore, maxScoreAndMods); var prevNodeScore = prevNodeScoreAndSequence.Item1; if (prevNodeScore > bestPrevNodeScore) { bestPrevNodeIndex = prevNodeIndex; bestPrevNodeScore = prevNodeScore; bestPrevSequence = prevNodeScoreAndSequence.Item2; } } if (bestPrevNodeIndex < 0) // source { return(maxScoreAndMods[seqIndex][modIndex] = new Tuple <double, string>((double)curNodeScore, "")); } var modPos = _index - seqIndex; var aminoAcid = _aminoAcidSequence[seqIndex]; var modAa = aminoAcid as ModifiedAminoAcid; if (modAa != null) { var modificationName = modAa.Modification.Name; if (string.IsNullOrEmpty(bestPrevSequence)) { bestPrevSequence = modificationName + " " + modPos; } else { bestPrevSequence = modificationName + " " + modPos + "," + bestPrevSequence; } } var prevModCombIndex = _graph[seqIndex - 1][bestPrevNodeIndex].ModificationCombinationIndex; var curModCombIndex = node.ModificationCombinationIndex; if (prevModCombIndex != curModCombIndex) // modified { var modificationName = ModificationParams.GetModificationIndexBetween(prevModCombIndex, curModCombIndex).Name; string newModSequence; if (string.IsNullOrEmpty(bestPrevSequence)) { newModSequence = modificationName + " " + modPos; } else { newModSequence = modificationName + " " + modPos + ","; } return(maxScoreAndMods[seqIndex][modIndex] = new Tuple <double, string> ((double)curNodeScore + bestPrevNodeScore, newModSequence + bestPrevSequence)); } return(maxScoreAndMods[seqIndex][modIndex] = new Tuple <double, string> ((double)curNodeScore + bestPrevNodeScore, bestPrevSequence)); }
public AminoAcidSet(IEnumerable <SearchModification> searchModifications, int maxNumModsPerSequence) : this() { if (searchModifications == null) { return; } var modifications = searchModifications as SearchModification[] ?? searchModifications.ToArray(); // apply fixed modifications foreach (var searchModification in modifications) { if (!searchModification.IsFixedModification) { continue; } var location = searchModification.Location; var targetResidue = searchModification.TargetResidue; foreach (var loc in AffectedLocations[location]) { var appliedResidue = targetResidue != '*' ? targetResidue : SequenceLocationToLocationResidue[loc]; var residueMap = _locationSpecificResidueMap[loc]; residueMap[appliedResidue] = new ModifiedAminoAcid(residueMap[appliedResidue], searchModification.Modification); } } if (maxNumModsPerSequence <= 0) { return; } // apply dynamic modifications var dynamicModifications = new HashSet <Modification>(); var locationSpecificResidueVariableModMap = new Dictionary <SequenceLocation, Dictionary <char, List <Modification> > >(); foreach (var loc in AllSequenceLocations) { locationSpecificResidueVariableModMap[loc] = new Dictionary <char, List <Modification> >(); } foreach (var searchModification in modifications) { if (searchModification.IsFixedModification) { continue; } dynamicModifications.Add(searchModification.Modification); var location = searchModification.Location; var targetResidue = searchModification.TargetResidue; foreach (var loc in AffectedLocations[location]) { var residueModMap = locationSpecificResidueVariableModMap[loc]; var appliedResidue = targetResidue != '*' ? targetResidue : SequenceLocationToLocationResidue[loc]; List <Modification> modList; if (residueModMap.TryGetValue(appliedResidue, out modList)) { modList.Add(searchModification.Modification); } else { residueModMap.Add(appliedResidue, new List <Modification> { searchModification.Modification }); } } } var dynModArray = dynamicModifications.ToArray(); _modificationParams = new ModificationParams(dynModArray, maxNumModsPerSequence); foreach (var loc in AllSequenceLocations) { var residueModMap = locationSpecificResidueVariableModMap[loc]; foreach (var entry in residueModMap) { var residue = entry.Key; var modList = entry.Value; var modIndexArr = new int[modList.Count]; var index = -1; foreach (var mod in modList) { var modIndex = Array.IndexOf(dynModArray, mod); modIndexArr[++index] = modIndex; } _locationSpecificResidueModMap[loc].Add(residue, modIndexArr); } } }
public AminoAcidSet(IEnumerable<SearchModification> searchModifications, int maxNumModsPerSequence): this() { if (searchModifications == null) return; var modifications = searchModifications as SearchModification[] ?? searchModifications.ToArray(); // apply fixed modifications foreach (var searchModification in modifications) { if (!searchModification.IsFixedModification) continue; var location = searchModification.Location; var targetResidue = searchModification.TargetResidue; foreach (var loc in AffectedLocations[location]) { var appliedResidue = targetResidue != '*' ? targetResidue : SequenceLocationToLocationResidue[loc]; var residueMap = _locationSpecificResidueMap[loc]; residueMap[appliedResidue] = new ModifiedAminoAcid(residueMap[appliedResidue], searchModification.Modification); } } if (maxNumModsPerSequence <= 0) return; // apply dynamic modifications var dynamicModifications = new HashSet<Modification>(); var locationSpecificResidueVariableModMap = new Dictionary<SequenceLocation,Dictionary<char, List<Modification>>>(); foreach (var loc in AllSequenceLocations) { locationSpecificResidueVariableModMap[loc] = new Dictionary<char, List<Modification>>(); } foreach (var searchModification in modifications) { if (searchModification.IsFixedModification) continue; dynamicModifications.Add(searchModification.Modification); var location = searchModification.Location; var targetResidue = searchModification.TargetResidue; foreach (var loc in AffectedLocations[location]) { var residueModMap = locationSpecificResidueVariableModMap[loc]; var appliedResidue = targetResidue != '*' ? targetResidue : SequenceLocationToLocationResidue[loc]; List<Modification> modList; if (residueModMap.TryGetValue(appliedResidue, out modList)) { modList.Add(searchModification.Modification); } else { residueModMap.Add(appliedResidue, new List<Modification> { searchModification.Modification }); } } } var dynModArray = dynamicModifications.ToArray(); _modificationParams = new ModificationParams(dynModArray, maxNumModsPerSequence); foreach (var loc in AllSequenceLocations) { var residueModMap = locationSpecificResidueVariableModMap[loc]; foreach (var entry in residueModMap) { var residue = entry.Key; var modList = entry.Value; var modIndexArr = new int[modList.Count]; var index = -1; foreach (var mod in modList) { var modIndex = Array.IndexOf(dynModArray, mod); modIndexArr[++index] = modIndex; } _locationSpecificResidueModMap[loc].Add(residue, modIndexArr); } } }
/// <summary> /// Add an amino acid residue to this generator. /// </summary> /// <param name="index">index to add the amino acid. 0 is C-term. 1 is the C-term amino acid.</param> /// <param name="residue">amino acid residue to add.</param> /// <param name="loc">location of the residue</param> /// <returns>true if residue is a valid amino acid; false otherwise.</returns> private bool PutAminoAcid(int index, char residue, SequenceLocation loc) { _index = index + 1; var aminoAcid = AminoAcidSet.GetAminoAcid(residue, loc); if (aminoAcid == null) // residue is not valid { return(false); } var fragmentComposition = _fragmentComposition[_index - 1] + aminoAcid.Composition; if (fragmentComposition.Mass > _maxSequenceMass) { return(false); } _aminoAcidSequence[_index] = aminoAcid; _fragmentComposition[_index] = fragmentComposition; var modIndices = AminoAcidSet.GetModificationIndices(residue, loc); if (!modIndices.Any()) // No modification { _graph[_index] = new Node[_graph[_index - 1].Length]; for (var i = 0; i < _graph[_index - 1].Length; i++) { _graph[_index][i] = new Node(_graph[_index - 1][i].ModificationCombinationIndex, i); } } else { var modCombIndexToNodeMap = new Dictionary <int, Node>(); for (var i = 0; i < _graph[_index - 1].Length; i++) { var prevNodeIndex = i; var prevNode = _graph[_index - 1][i]; var prevModCombIndex = prevNode.ModificationCombinationIndex; // unmodified edge if (modCombIndexToNodeMap.TryGetValue(prevModCombIndex, out var unmodifiedEdgeNode)) { unmodifiedEdgeNode.AddPrevNodeIndex(prevNodeIndex); } else { modCombIndexToNodeMap.Add(prevModCombIndex, new Node(prevModCombIndex, prevNodeIndex)); } // modified edge foreach (var modIndex in modIndices) { var modCombIndex = ModificationParams.GetModificationCombinationIndex( prevNode.ModificationCombinationIndex, modIndex); if (modCombIndex < 0) // too many modifications { continue; } if (modCombIndexToNodeMap.TryGetValue(modCombIndex, out var modifiedEdgeNode)) { modifiedEdgeNode.AddPrevNodeIndex(prevNodeIndex); } else { modCombIndexToNodeMap.Add(modCombIndex, new Node(modCombIndex, prevNodeIndex)); } } _graph[_index] = modCombIndexToNodeMap.Values.ToArray(); } } return(true); }
/// <summary> /// Get the fragment score and modifications /// </summary> /// <param name="seqIndex"></param> /// <param name="modIndex"></param> /// <param name="scorer"></param> /// <param name="nodeScore"></param> /// <param name="maxScoreAndMods"></param> /// <returns></returns> private Tuple <double, LinkedList <ModificationInstance> > GetFragmentScoreAndModifications( int seqIndex, int modIndex, IScorer scorer, IReadOnlyList <double?[]> nodeScore, IReadOnlyList <Tuple <double, LinkedList <ModificationInstance> >[]> maxScoreAndMods) { var scoreAndMods = maxScoreAndMods[seqIndex][modIndex]; if (scoreAndMods != null) { return(scoreAndMods); } var node = _graph[seqIndex][modIndex]; var curNodeScore = nodeScore[seqIndex][modIndex] ?? (nodeScore[seqIndex][modIndex] = _isForward ? scorer.GetFragmentScore(GetComposition(seqIndex, modIndex), GetComplementaryComposition(seqIndex, modIndex)) : scorer.GetFragmentScore(GetComplementaryComposition(seqIndex, modIndex), GetComposition(seqIndex, modIndex)) ); var bestPrevNodeIndex = -1; var bestPrevNodeScore = double.NegativeInfinity; LinkedList <ModificationInstance> bestPrevMods = null; foreach (var prevNodeIndex in node.GetPrevNodeIndices()) { var prevNodeScoreAndSequence = GetFragmentScoreAndModifications(seqIndex - 1, prevNodeIndex, scorer, nodeScore, maxScoreAndMods); var prevNodeScore = prevNodeScoreAndSequence.Item1; if (prevNodeScore > bestPrevNodeScore) { bestPrevNodeIndex = prevNodeIndex; bestPrevNodeScore = prevNodeScore; bestPrevMods = prevNodeScoreAndSequence.Item2; } } if (bestPrevNodeIndex < 0) // source { return(maxScoreAndMods[seqIndex][modIndex] = new Tuple <double, LinkedList <ModificationInstance> >((double)curNodeScore, new LinkedList <ModificationInstance>())); } var modPos = _isForward ? seqIndex : _index - seqIndex; if (modPos <= 1) { --modPos; } var aminoAcid = _aminoAcidSequence[seqIndex]; var modAa = aminoAcid as ModifiedAminoAcid; LinkedList <ModificationInstance> newMods = null; if (modAa != null) { newMods = bestPrevMods == null ? new LinkedList <ModificationInstance>() : new LinkedList <ModificationInstance>(bestPrevMods); var modIns = new ModificationInstance(modAa.Modification, modPos); if (_isForward) { newMods.AddLast(modIns); } else { newMods.AddFirst(modIns); } } var prevModCombIndex = _graph[seqIndex - 1][bestPrevNodeIndex].ModificationCombinationIndex; var curModCombIndex = node.ModificationCombinationIndex; if (prevModCombIndex != curModCombIndex) // modified { if (newMods == null) { newMods = bestPrevMods == null ? new LinkedList <ModificationInstance>() : new LinkedList <ModificationInstance>(bestPrevMods); } var modification = ModificationParams.GetModificationIndexBetween(prevModCombIndex, curModCombIndex); var modIns = new ModificationInstance(modification, modPos); if (_isForward) { newMods.AddLast(modIns); } else { newMods.AddFirst(modIns); } } return(maxScoreAndMods[seqIndex][modIndex] = new Tuple <double, LinkedList <ModificationInstance> > ((double)curNodeScore + bestPrevNodeScore, newMods ?? bestPrevMods)); }
public void TestModificationParams() { var methodName = MethodBase.GetCurrentMethod().Name; ShowStarting(methodName); var modifications = new[] { Modification.Acetylation, Modification.Phosphorylation, Modification.Oxidation}; //, Modification.PyroGluQ }; var modParams = new ModificationParams(modifications, 3); int numCombinations = modParams.NumModificationCombinations; for (int modCombIndex = 0; modCombIndex < numCombinations; modCombIndex++) { var modCombination = modParams.GetModificationCombination(modCombIndex); Console.WriteLine("{0}: {1} {2} {3}", modCombIndex, modCombination, modCombination.Composition, modCombination.Composition.Mass); } Console.WriteLine(modParams.GetModificationCombinationIndex(8, 0)); Console.WriteLine(modParams.GetModificationCombinationIndex(19, 1)); }