// var poissonDist = new MathNet.Numerics.Distributions.Poisson(errorRate * coverage); public static double AssignRawPoissonQScore(int callCount, int coverage, int estimatedBaseCallQuality) // ReSharper restore InconsistentNaming { double errorRate = MathOperations.QtoP(estimatedBaseCallQuality); double callCountMinusOne = callCount - 1; double callCountDouble = callCount; var lambda = errorRate * coverage; var poissonDist = new MathNet.Numerics.Distributions.Poisson(lambda); var pValue = 1 - poissonDist.CumulativeDistribution(callCountMinusOne); if (pValue > 0) { return(MathOperations.PtoQ(pValue)); } else { //Approximation to get around precision issues. double A = poissonDist.ProbabilityLn((int)callCountMinusOne); double correction = (callCountDouble - lambda) / callCountDouble; var qScore = -10.0 * (A - Math.Log(2.0 * correction)) / Math.Log(10.0); return(qScore); } }
// Poisson.Cdf(observedCallCount - 1.0, coverage* errorRate)); public double[] Triangle_AssignQValue(double depth, double noise, double callCounts) { var poissonDist = new MathNet.Numerics.Distributions.Poisson(noise * depth); double rawCDF = poissonDist.CumulativeDistribution(callCounts - 1.0); double P = 1 - rawCDF; //Approximation to get around precision issues. double A = poissonDist.ProbabilityLn((int)callCounts - 1); double correction = (callCounts - noise * depth) / callCounts; double Qnew = -10.0 * (A - Math.Log(2.0 * correction)) / Math.Log(10.0); return(new double[] { P, Qnew }); }