Beispiel #1
0
        /// <summary>
        /// Get the fragment score at the provided sequence index and mod index, using the provided scorer
        /// </summary>
        /// <param name="seqIndex"></param>
        /// <param name="modIndex"></param>
        /// <param name="scorer"></param>
        /// <param name="nodeScore"></param>
        /// <param name="maxScore"></param>
        /// <returns></returns>
        protected double GetFragmentScore(int seqIndex, int modIndex, IScorer scorer, double?[][] nodeScore, double?[][] maxScore)
        {
            var score = maxScore[seqIndex][modIndex];

            if (score != null)
            {
                return((double)score);
            }

            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 prevNodeScore = 0.0;

            if (node.GetPrevNodeIndices().Any())
            {
                prevNodeScore =
                    node.GetPrevNodeIndices()
                    .Max(prevNodeIndex => GetFragmentScore(seqIndex - 1, prevNodeIndex, scorer, nodeScore, maxScore));
            }
            maxScore[seqIndex][modIndex] = curNodeScore + prevNodeScore;

            // ReSharper disable once PossibleInvalidOperationException
            return((double)maxScore[seqIndex][modIndex]);
        }
Beispiel #2
0
        /// <summary>
        /// Get the fragment score at the provided sequence index and mod index, using the provided scorer
        /// </summary>
        /// <param name="seqIndex"></param>
        /// <param name="modIndex"></param>
        /// <param name="scorer"></param>
        /// <param name="nodeScore"></param>
        /// <param name="maxScore"></param>
        /// <returns></returns>
        protected double GetFragmentScore(int seqIndex, int modIndex, IScorer scorer, double?[][] nodeScore, double?[][] maxScore)
        {
            var score = maxScore[seqIndex][modIndex];

            if (score != null)
            {
                return((double)score);
            }

            var    node = _graph[seqIndex][modIndex];
            double?curNodeScore;

            if (nodeScore[seqIndex][modIndex] != null)
            {
                curNodeScore = nodeScore[seqIndex][modIndex];
            }
            else
            {
                var prefixFragmentComposition = GetComplementaryComposition(seqIndex, modIndex);
                var suffixFragmentComposition = GetComposition(seqIndex, modIndex);

                if (scorer == null)
                {
                    Console.WriteLine("Null scorer");
                    curNodeScore = 0;
                }
                else
                {
                    nodeScore[seqIndex][modIndex] = scorer.GetFragmentScore(prefixFragmentComposition,
                                                                            suffixFragmentComposition);
                    curNodeScore = nodeScore[seqIndex][modIndex];
                }
            }

            var prevNodeScore = 0.0;

            if (node.GetPrevNodeIndices().Any())
            {
                foreach (var previousNode in node.GetPrevNodeIndices())
                {
                    if (seqIndex == 0)
                    {
                        continue;
                    }

                    var prevScore = GetFragmentScore(seqIndex - 1, previousNode, scorer, nodeScore, maxScore);
                    if (prevScore > prevNodeScore)
                    {
                        prevNodeScore = prevScore;
                    }
                }
            }
            maxScore[seqIndex][modIndex] = curNodeScore + prevNodeScore;
            // ReSharper disable PossibleInvalidOperationException
            return((double)maxScore[seqIndex][modIndex]);
            // ReSharper restore PossibleInvalidOperationException
        }
Beispiel #3
0
        /// <summary>
        /// Get the fragment score at the provided sequence index and mod index, using the provided scorer
        /// </summary>
        /// <param name="seqIndex"></param>
        /// <param name="modIndex"></param>
        /// <param name="scorer"></param>
        /// <param name="nodeScore"></param>
        /// <param name="maxScore"></param>
        /// <returns></returns>
        protected double GetFragmentScore(int seqIndex, int modIndex, IScorer scorer, double?[][] nodeScore, double?[][] maxScore)
        {
            var score = maxScore[seqIndex][modIndex];

            if (score != null)
            {
                return((double)score);
            }

            var node = _graph[seqIndex][modIndex];

            /*double? curNodeScore;
             *
             * if (nodeScore[seqIndex][modIndex] != null)
             * {
             *  curNodeScore = nodeScore[seqIndex][modIndex];
             * }
             * else
             * {
             *  var prefixFragmentComposition = GetComplementaryComposition(seqIndex, modIndex);
             *  var suffixFragmentComposition = GetComposition(seqIndex, modIndex);
             *
             *  if (scorer == null)
             *  {
             *      ConsoleMsgUtils.ShowWarning("Null scorer in GetFragmentScore");
             *      curNodeScore = 0;
             *  }
             *  else
             *  {
             *      nodeScore[seqIndex][modIndex] = scorer.GetFragmentScore(prefixFragmentComposition,
             *                                                              suffixFragmentComposition);
             *      curNodeScore = nodeScore[seqIndex][modIndex];
             *  }
             * }*/
            var curNodeScore = nodeScore[seqIndex][modIndex] ??
                               (nodeScore[seqIndex][modIndex] = scorer.GetFragmentScore(GetComplementaryComposition(seqIndex, modIndex), GetComposition(seqIndex, modIndex)));

            var prevNodeScore = 0.0;

            if (node.GetPrevNodeIndices().Any() && seqIndex > 0)
            {
                prevNodeScore = node.GetPrevNodeIndices().Max(previousNode => GetFragmentScore(seqIndex - 1, previousNode, scorer, nodeScore, maxScore));
            }
            maxScore[seqIndex][modIndex] = curNodeScore + prevNodeScore;
            // ReSharper disable PossibleInvalidOperationException
            return((double)maxScore[seqIndex][modIndex]);
            // ReSharper restore PossibleInvalidOperationException
        }
Beispiel #4
0
        /// <summary>
        /// Get the score for a protein or peptide sequence.
        /// </summary>
        /// <param name="scorer">The scorer.</param>
        /// <param name="sequence">The sequence.</param>
        /// <returns>The score calculated from the sequence.</returns>
        public static double ScoreSequence(IScorer scorer, Sequence sequence)
        {
            var prefixCompositions = GetCompositions(sequence, true);
            var suffixCompositions = GetCompositions(sequence, false);

            suffixCompositions.Reverse();

            var score = 0.0;

            for (var i = 0; i < prefixCompositions.Count; i++)
            {
                score += scorer.GetFragmentScore(prefixCompositions[i], suffixCompositions[i]);
            }

            return(score);
        }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        protected double GetFragmentScore(int seqIndex, int modIndex, IScorer scorer, double?[][] nodeScore, double?[][] maxScore)
        {
            var score = maxScore[seqIndex][modIndex];
            if (score != null) return (double)score;

            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 prevNodeScore = 0.0;
            if (node.GetPrevNodeIndices().Any())
            {
                prevNodeScore =
                    node.GetPrevNodeIndices()
                        .Max(prevNodeIndex => GetFragmentScore(seqIndex - 1, prevNodeIndex, scorer, nodeScore, maxScore));
            }
            maxScore[seqIndex][modIndex] = curNodeScore + prevNodeScore;
            // ReSharper disable PossibleInvalidOperationException
            return (double)maxScore[seqIndex][modIndex];
            // ReSharper restore PossibleInvalidOperationException
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        private IEnumerable <TagSequenceMatch> GetMatches(IEnumerable <SequenceTag.SequenceTag> tags, ProductSpectrum spec, IScorer scorer)
        {
            // Match tags against the database
            var proteinsToTags = GetProteinToMatchedTagsMap(tags, _searchableDb, _aaSet, _tolerance, _tolerance);

            //var tagSequenceMatchList = new List<TagSequenceMatch>();

            // Extend matches
            foreach (var entry in proteinsToTags)
            {
                var proteinName     = entry.Key;
                var matchedTagSet   = entry.Value;
                var proteinSequence = matchedTagSet.Sequence;

                var tagFinder = new TagMatchFinder(spec, scorer, _featureFinder, proteinSequence, _tolerance, _aaSet, _maxSequenceMass);

                foreach (var matchedTag in matchedTagSet.Tags)
                {
                    if (matchedTag.Length < _minMatchedTagLength)
                    {
                        continue;
                    }
                    if (matchedTag.NTermFlankingMass == null && matchedTag.CTermFlankingMass == null)
                    {
                        continue;
                    }

                    var matches = tagFinder.FindMatches(matchedTag).ToArray();
                    //var prevScore = double.NegativeInfinity;
                    //foreach (var match in matches.OrderByDescending(m => m.Score))
                    foreach (var match in matches)
                    {
                        var sequence = proteinSequence.Substring(match.StartIndex, match.EndIndex - match.StartIndex);
                        //re-scoring
                        var sequenceObj = Sequence.CreateSequence(sequence, match.ModificationText, _aaSet);
                        match.Score = sequenceObj.GetInternalCleavages().Sum(c => scorer.GetFragmentScore(c.PrefixComposition, c.SuffixComposition));

                        //var numMatches = matchedTag.Length * 2 + match.NTermScore + match.CTermScore;
                        //var score = match.NTermScore + match.CTermScore;
                        //score += (matchedTag.NumReliableNTermFlankingMasses > 0)
                        //  ? matchedTag.Length*CompositeScorer.ScoreParam.Prefix.ConsecutiveMatch
                        //: matchedTag.Length*CompositeScorer.ScoreParam.Suffix.ConsecutiveMatch;

                        // Poisson p-value score
                        //var n = (match.EndIndex - match.StartIndex - 1)*2;
                        //var lambda = numMatches / n;
                        //var pValue = 1 - Poisson.CDF(lambda, numMatches);
                        //var pScore = (pValue > 0) ? - Math.Log(pValue, 2) : 50.0;
                        //if (numMatches < 5) break;
                        //if (prevScore - numMatches > 2) break;
                        //prevScore = numMatches;

                        var pre  = match.StartIndex == 0 ? '-' : proteinSequence[match.StartIndex - 1];              // startIndex is inclusive
                        var post = match.EndIndex >= proteinSequence.Length ? '-' : proteinSequence[match.EndIndex]; // endIndex is Exclusive

                        yield return(new TagSequenceMatch(sequence, proteinName, match, pre, post));

                        //tagSequenceMatchList.Add(new TagSequenceMatch(sequence, proteinName, match, pre, post));
                    }
                }
            }
            //return tagSequenceMatchList;
        }
Beispiel #9
0
        /// <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));
        }
Beispiel #10
0
        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);
        }
        private IEnumerable<TagSequenceMatch> GetMatches(IEnumerable<SequenceTag> tags, ProductSpectrum spec, IScorer scorer)
        {
            // Match tags against the database
            var proteinsToTags = GetProteinToMatchedTagsMap(tags, _searchableDb, _aaSet, _tolerance, _tolerance);
            //var tagSequenceMatchList = new List<TagSequenceMatch>();

            // Extend matches
            foreach (var entry in proteinsToTags)
            {
                var proteinName = entry.Key;
                var matchedTagSet = entry.Value;
                var proteinSequence = matchedTagSet.Sequence;

                var tagFinder = new TagMatchFinder(spec, scorer, _featureFinder, proteinSequence, _tolerance, _aaSet, _maxSequenceMass);

                foreach (var matchedTag in matchedTagSet.Tags)
                {
                    if (matchedTag.Length < _minMatchedTagLength) continue;
                    if (matchedTag.NTermFlankingMass == null && matchedTag.CTermFlankingMass == null) continue;

                    var matches = tagFinder.FindMatches(matchedTag).ToArray();
                    //var prevScore = double.NegativeInfinity;
                    //foreach (var match in matches.OrderByDescending(m => m.Score))
                    foreach(var match in matches)
                    {
                        var sequence = proteinSequence.Substring(match.StartIndex, match.EndIndex - match.StartIndex);
                        //re-scoring
                        var sequenceObj = Sequence.CreateSequence(sequence, match.ModificationText, _aaSet);
                        match.Score = sequenceObj.GetInternalCleavages().Sum(c => scorer.GetFragmentScore(c.PrefixComposition, c.SuffixComposition));

                        //var numMatches = matchedTag.Length * 2 + match.NTermScore + match.CTermScore;
                        //var score = match.NTermScore + match.CTermScore;
                        //score += (matchedTag.NumReliableNTermFlankingMasses > 0)
                          //  ? matchedTag.Length*CompositeScorer.ScoreParam.Prefix.ConsecutiveMatch
                            //: matchedTag.Length*CompositeScorer.ScoreParam.Suffix.ConsecutiveMatch;
                        

                        // Poisson p-value score
                        //var n = (match.EndIndex - match.StartIndex - 1)*2;
                        //var lambda = numMatches / n;
                        //var pValue = 1 - Poisson.CDF(lambda, numMatches);
                        //var pScore = (pValue > 0) ? - Math.Log(pValue, 2) : 50.0;
                        //if (numMatches < 5) break;
                        //if (prevScore - numMatches > 2) break;
                        //prevScore = numMatches;

                        var pre = match.StartIndex == 0 ? '-' : proteinSequence[match.StartIndex - 1]; // startIndex is inclusive
                        var post = match.EndIndex >= proteinSequence.Length ? '-' : proteinSequence[match.EndIndex]; // endIndex is Exclusive

                        yield return new TagSequenceMatch(sequence, proteinName, match, pre, post);

                        //tagSequenceMatchList.Add(new TagSequenceMatch(sequence, proteinName, match, pre, post));
                    }
                }
            }
            //return tagSequenceMatchList;
        }