private static IEnumerable <MatchedWith> GetBestReconstructedPath(TrackRegion trackRegion, IEnumerable <MatchedWith> matches) { // matches are already sorted by `TrackMatchAt` return(matches.Skip(trackRegion.StartAt) .Take(trackRegion.Count) .GroupBy(m => m.TrackSequenceNumber) .Aggregate(new { List = new List <MatchedWith>(), Used = new HashSet <uint>() }, (acc, group) => { var bestByScore = group .OrderByDescending(m => m.Score) .ThenBy(m => m.QueryMatchAt) .ToList(); foreach (var match in bestByScore.Where(match => !acc.Used.Contains(match.QuerySequenceNumber))) { acc.List.Add(match); acc.Used.Add(match.QuerySequenceNumber); return acc; } return acc; }, acc => acc.List) .OrderBy(m => m.TrackSequenceNumber)); }
private static double GetNotCoveredLength(List <MatchedWith> orderedByResultAt, TrackRegion trackRegion, double fingerprintLengthInSeconds, out MatchedWith bestMatch) { double notCovered = 0d; bestMatch = orderedByResultAt[trackRegion.StartAt]; for (int i = trackRegion.StartAt + 1; i <= trackRegion.EndAt; ++i) { if (orderedByResultAt[i].ResultAt - orderedByResultAt[i - 1].ResultAt > fingerprintLengthInSeconds) { notCovered += orderedByResultAt[i].ResultAt - (orderedByResultAt[i - 1].ResultAt + fingerprintLengthInSeconds); } if (bestMatch.HammingSimilarity < orderedByResultAt[i].HammingSimilarity) { bestMatch = orderedByResultAt[i]; } } return(notCovered); }