/// <summary> /// Calculates standard deviance and mean value and writes to peak detection data /// </summary> public PeakDetectionData Compute(PeakDetectionData peakDetectionData) { // initialize default values peakDetectionData.Mean = 0; peakDetectionData.StandardDeviance = 0; // Compute mean and std of peak function int counter = 0; double M2 = 0; double delta; // process data foreach (double functionValue in peakDetectionData.PeakFunctionValues) { counter++; delta = functionValue - peakDetectionData.Mean; peakDetectionData.Mean = peakDetectionData.Mean + delta / counter; M2 = M2 + delta * (functionValue - peakDetectionData.Mean); } // calculate deviance double variance = M2 / (counter - 1); peakDetectionData.StandardDeviance = Math.Sqrt(variance); return(peakDetectionData); }
/// <summary> /// Computes the values checking points in specific window. Gets the min and max value in that window and result is average of that. /// </summary> public PeakDetectionData Compute(IEnumerable <IPoint> points, DetectionSettings detectionSettings) { PeakDetectionData peakDetectionData = new PeakDetectionData(); // initialize min/max values peakDetectionData.MinValue = peakDetectionData.MaxValue = 0; // Compute peak function values double[] S = new double[points.Count()]; double maxLeft, maxRight; for (int i = detectionSettings.WindowSize; i < S.Length - detectionSettings.WindowSize; i++) { IPoint currentChartPoint = points.ElementAt(i); IPoint leftChartPoint = points.ElementAt(i - 1); IPoint rightChartPoint = points.ElementAt(i + 1); // used to remember min and max value if (currentChartPoint.Y > peakDetectionData.MaxValue) { peakDetectionData.MaxValue = currentChartPoint.Y; } if (currentChartPoint.Y < peakDetectionData.MinValue || peakDetectionData.MinValue == 0) { peakDetectionData.MinValue = currentChartPoint.Y; } // get difference between point and its left neighbor maxLeft = currentChartPoint.Y - leftChartPoint.Y; maxRight = currentChartPoint.Y - rightChartPoint.Y; // get the max difference for left and right neighbors for (int j = 2; j <= detectionSettings.WindowSize; j++) { leftChartPoint = points.ElementAt(i - j); rightChartPoint = points.ElementAt(i + j); if (currentChartPoint.Y - leftChartPoint.Y > maxLeft) { maxLeft = currentChartPoint.Y - leftChartPoint.Y; } if (currentChartPoint.Y - rightChartPoint.Y > maxRight) { maxRight = currentChartPoint.Y - rightChartPoint.Y; } } S[i] = 0.5f * (maxRight + maxLeft); } // set the peak function values and return peakDetectionData.PeakFunctionValues = S; return(peakDetectionData); }
/// <summary> /// Sets IsPeak to peaks in points list. Also returns all peaks in a single list. /// </summary> public List <IPoint> Detect(IEnumerable <IPoint> points) { // list of peaks to be returned List <IPoint> peaks = new List <IPoint>(); // initialize detection data PeakDetectionData peakDetectionData = new PeakDetectionData(); // Compute peak function values peakDetectionData = _peakFunctionComputor.Compute(points, _detectionSettings); // calculate if min and max value are too near each other // this means that graph made of points is too flat if (peakDetectionData.MaxValue != 0 && peakDetectionData.MinValue != 0) { if (((peakDetectionData.MaxValue - peakDetectionData.MinValue) / peakDetectionData.MaxValue) < 0.25) { return(new List <IPoint>()); } } // calculate mean value and standard deviance peakDetectionData = _mathzComputor.Compute(peakDetectionData); // Collect only large peaks List <int> peakLocations = new List <int>(); int counter = 0; foreach (double peakValue in peakDetectionData.PeakFunctionValues) { // get point IPoint point = points.ElementAt(counter); // check if peak if (_mathzComputor.IsPeak(peakValue, peakDetectionData, _detectionSettings)) { point.IsPeak = true; peaks.Add(point); } counter++; } // dilute peaks so the ones too near are excluded and return return(_dilluter.Dillute(points, _detectionSettings)); }
/// <summary> /// Checks for peak conditions /// </summary> public bool IsPeak(double peakValue, PeakDetectionData peakDetectionData, DetectionSettings detectionSettings) { // if peak function value minus mean is greater than Stringency * StandardDeviance then point is a peak return(peakValue > 0 && (peakValue - peakDetectionData.Mean) > detectionSettings.Stringency * peakDetectionData.StandardDeviance); }