private Tuple <double, double> CalculateBestPPMError(IEnumerable <Peptide> inputPeptides, double maximumFalseDisoveryRate = 0.01, int steps = 10, double minimumIncrement = 0.05) { List <Peptide> peptides = inputPeptides.OrderBy(pep => pep.CorrectedPrecursorErrorPPM).ToList(); double[] precursorPPMs = peptides.Select(pep => pep.CorrectedPrecursorErrorPPM).ToArray(); double bestppmError = 0; double max = peptides[peptides.Count - 1].CorrectedPrecursorErrorPPM; double maxPrecursorError = Math.Min(max, _maximumPPMError); double minPrecursorError = 0; double increment = (maxPrecursorError - minPrecursorError) / steps; increment = Math.Max(increment, minimumIncrement); double bestCount = 0; for (double ppmError = minPrecursorError; ppmError <= maxPrecursorError; ppmError += increment) { int index = Array.BinarySearch(precursorPPMs, ppmError); if (index < 0) { index = ~index; } int count = FalseDiscoveryRate <Peptide, double> .Count(peptides.Take(index).ToList(), maximumFalseDisoveryRate); if (count <= bestCount) { continue; } bestCount = count; bestppmError = ppmError; } List <Peptide> filteredPeptides = new List <Peptide>(peptides.Where(pep => pep.CorrectedPrecursorErrorPPM <= bestppmError)); // Calculate the e-value threshold for those filtered peptides double threshold = FalseDiscoveryRate <Peptide, double> .CalculateThreshold(filteredPeptides, maximumFalseDisoveryRate); return(new Tuple <double, double>(bestppmError, threshold)); }