public static List <List <PointD> > GetSparkles(List <double> input) { #region PreProcess // Dispersion List <double> disp = CurveProcessingTools.WindowDispersion(input, 50); //PlotData(disp, "DISPERSION", "DISPERSION"); // Average of dispersion List <double> dispAVGC = new List <double>(); dispAVGC = CurveProcessingTools.WindowAVGC(disp, 650); //PlotData(dispAVGC, "DISPERSION + AVGC", "DISPERSION_AvgC"); List <double> test = CurveProcessingTools.WindowAVGC(dispAVGC, 650); for (int i = 0; i < test.Count; i++) { test[i] = dispAVGC[i] - test[i]; } //PlotData(dispAVGC, test, "Comparison dispAVGC[i] - dispAVGC[i].Windows[800]", "Test"); //PlotData(disp, test, "Comparison disp and dispAVGC[i] - dispAVGC[i].Windows[800]", "Test2"); //PlotData(disp, dispAVGC, "Comparison disp and disp+avgc", "Disp_vs_dispavgc"); #endregion List <Point> SeparationPoints = GetSparkleSeparationPoints(disp, dispAVGC, input); List <List <PointD> > RawSparkles = GetSeparatedWords(SeparationPoints, input); List <List <PointD> > GoodSparkles = new List <List <PointD> >(); List <List <PointD> > BadSparkles = new List <List <PointD> >(); FiltrateSparkles(RawSparkles, input, out GoodSparkles, out BadSparkles); return(GoodSparkles); }
public void AnalyseSignal() { SparkleIndexes = new List <double[]>(); double[] raw = _IntensityCleanData.ToArray(); _Average = new double[raw.Length]; _Sigma = new double[raw.Length]; _AveragePlusSigma = new double[raw.Length]; //1. Построим среднее _Average = CurveProcessingTools.WindowAVGC(_IntensityCleanData, windowWidth).ToArray(); //2. Построим сигму _Sigma = CurveProcessingTools.WindowDispersion(_Average.ToList(), windowWidth).ToArray(); //3. Построим среднее + 3.5 * сигма for (int i = 0; i < raw.Length; i++) { _AveragePlusSigma[i] = _Average[i] + 3.0 * _Sigma[i]; } //4. Найдем вспышки SparkleIndexes.Clear(); for (int i = 0; i < raw.Length;) { //идем по всему сигналу, если среднее + 3.5 сигма меньше основной кривой //начинамем поиск максимума, начальной и конечной точки if (_AveragePlusSigma[i] < raw[i]) { int left = i, right = i; // идем в право до уровня сигма while (right < raw.Length && _AveragePlusSigma[right] < raw[right]) { right++; } #region Уточнение границ // теперь left и right показывают индексные координаты точек на уровне пересечения с кривой уровня неслучайности. // найдем истинную левую граицу while (left > 5) { // будем сдвигаться влево //пока среднее от 4 точек до текущей не превысит её double sum = 0; for (int j = left - 5; j < left; j++) { sum += raw[j]; } sum /= 5; if (sum > raw[left]) { break; } else { left--; } } // найдем истинную правую границу while (right + 6 < raw.Length) { // будем сдвигаться вправо //пока среднее от 4 точек после текущей не превысит её List <double> sum = new List <double>();; for (int j = right + 1; j < right + 5; j++) { sum.Add(raw[j]); } if (sum.Average() > raw[right]) { break; } else { right++; } } // к этому моменту у нас есть координаты начала и конца события вспышки #endregion //найдем максимум светимости события вспышки. double max = double.MinValue; for (int j = left; j < right; j++) { if (raw[j] > max) { max = raw[j]; } } //если разница между уровнем отсечения в момент первого пересечения и максимумом существенна, добавим событие в список if (max > _AveragePlusSigma[i] + SigmaLevel[left]) { //if (max > 250) SparkleIndexes.Add(new double[2] { left, right }); } i = right + 1; continue; } i++; } // finish }