private void ValidateFiguresOfMerit(FiguresOfMeritOptions options, FiguresOfMerit figuresOfMerit) { if (options.MaxLoqBias.HasValue || options.MaxLoqCv.HasValue) { double min = Math.Min(options.MaxLoqBias.GetValueOrDefault(1000), options.MaxLoqCv.GetValueOrDefault(1000)); if (min <= 0) { Assert.IsNull(figuresOfMerit.LimitOfQuantification); } if (min >= 1000) { if (!Equals(RegressionFit.NONE, options.RegressionFit) || !options.MaxLoqBias.HasValue) { Assert.IsNotNull(figuresOfMerit.LimitOfQuantification); } } } else { Assert.IsNull(figuresOfMerit.LimitOfQuantification); } if (options.LodCalculation == LodCalculation.TURNING_POINT) { if (options.RegressionFit == RegressionFit.BILINEAR) { Assert.IsNotNull(figuresOfMerit.LimitOfDetection); } else { Assert.IsNull(figuresOfMerit.LimitOfDetection); } } }
private double?GetLoq(FiguresOfMeritOptions options, Skyline.Model.Databinding.Entities.Peptide peptideEntity) { var peptideResults = peptideEntity.Results.Values .Where(result => Equals(result.ResultFile.Replicate.SampleType, SampleType.STANDARD) && result.ResultFile.Replicate.AnalyteConcentration.HasValue) .ToLookup(result => result.ResultFile.Replicate.AnalyteConcentration.Value); if (!options.MaxLoqBias.HasValue && !options.MaxLoqCv.HasValue) { return(null); } var calibrationCurve = peptideEntity.CalibrationCurve.Value; var concentrationMultiplier = peptideEntity.ConcentrationMultiplier.GetValueOrDefault(1); double?bestLoq = null; foreach (var grouping in peptideResults.OrderByDescending(g => g.Key)) { if (options.MaxLoqBias.HasValue) { var areas = grouping .Select(peptideResult => peptideResult.Quantification.Value.NormalizedArea) .Where(area => area.HasValue).Cast <double>().ToArray(); if (areas.Length == 0) { continue; } var meanArea = areas.Average(); var backCalculatedConcentration = calibrationCurve.GetFittedX(meanArea); if (!backCalculatedConcentration.HasValue) { break; } var expectedConcentration = grouping.Key * concentrationMultiplier; var error = Math.Abs(1.0 - backCalculatedConcentration.Value / expectedConcentration) * 100; if (error > options.MaxLoqBias) { break; } } if (options.MaxLoqCv.HasValue) { var stats = new Statistics(grouping.Select(peptideResult => peptideResult.Quantification.Value.NormalizedArea).OfType <double>()); if (stats.Length > 1) { var cv = stats.StdDev() / stats.Mean(); if (double.IsNaN(cv) || cv * 100 > options.MaxLoqCv.Value) { break; } } } bestLoq = grouping.Key; } return(bestLoq * concentrationMultiplier); }
private void VerifyFiguresOfMeritValues(FiguresOfMeritOptions options, Skyline.Model.Databinding.Entities.Peptide peptideEntity) { double?expectedLoq = GetLoq(options, peptideEntity); var actualLoq = peptideEntity.FiguresOfMerit.LimitOfQuantification; if (expectedLoq != actualLoq) { Assert.AreEqual(expectedLoq, actualLoq); } }
/// <summary> /// Asserts that if options1 uses less stringent criteria for calculating LOQ, then that /// must results in a lower resulting LOQ value. /// </summary> private void CompareLoq(FiguresOfMeritOptions options1, FiguresOfMerit result1, FiguresOfMeritOptions options2, FiguresOfMerit result2) { if (options1.MaxLoqCv.HasValue != options2.MaxLoqCv.HasValue) { return; } if (options1.MaxLoqBias.HasValue != options2.MaxLoqBias.HasValue) { return; } if (options1.MaxLoqCv < options2.MaxLoqCv || options1.MaxLoqBias < options2.MaxLoqBias) { return; } // we have determined that options1 is more lenient than options2 Assert.IsTrue(result1.LimitOfQuantification.GetValueOrDefault(double.MaxValue) <= result2.LimitOfQuantification.GetValueOrDefault(double.MaxValue)); }