private Tuple<double, LinkedList<ModificationInstance>> GetFragmentScoreAndModifications(int seqIndex, int modIndex, IScorer scorer, double?[][] nodeScore, 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); }
/// <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)); }