/// <summary> /// Sets the information that should be displayed by the chart. /// </summary> /// <param name="histogramInfo">The histogram info.</param> public void SetHistogramInfo(HistogramInfo histogramInfo) { // Fill configuration information labelFileName.Text = histogramInfo.FileName; labelSignalLabel.Text = histogramInfo.SignalLabel; labelF0.Text = histogramInfo.F0 + @" Hz"; labelFC.Text = histogramInfo.FC + @" Hz"; labelB.Text = histogramInfo.B + @" Hz"; labelSmoothRate.Text = histogramInfo.SmoothRate.ToString(); labelSmoothTime.Text = histogramInfo.SmoothTime + @" s"; if (histogramInfo.UnderSampling != 1) { labelUndersample.Text = histogramInfo.UnderSampling.ToString(); } // Filling the histogram for SS_SU double ymax = double.MinValue; double ymin = double.MaxValue; for (int k = 0; k < histogramInfo.SU_SS.Length; k++) { chartHistogram.Series.ElementAt(0).Points.AddXY(k + histogramInfo.SS_SUmin, histogramInfo.SU_SS.ElementAt(k)); chartHistogram.Series.ElementAt(1).Points.AddXY(k + histogramInfo.SS_SUmin, histogramInfo.SU_SSsmoothed.ElementAt(k)); double tmp = Math.Max(histogramInfo.SU_SS.ElementAt(k), histogramInfo.SU_SSsmoothed.ElementAt(k)); if (ymax < tmp) { ymax = tmp; } tmp = Math.Min(histogramInfo.SU_SS.ElementAt(k), histogramInfo.SU_SSsmoothed.ElementAt(k)); if (ymin > tmp) { ymin = tmp; } } // Representing correlation double scaleFactor = ymax / histogramInfo.SU_SSmatch.ElementAt(histogramInfo.PiBvalueLog - histogramInfo.SS_SUmin); for (int k = 0; k < histogramInfo.SU_SS.Length; k++) { chartHistogram.Series.ElementAt(2).Points.AddXY(k + histogramInfo.SS_SUmin, histogramInfo.SU_SSmatch.ElementAt(k) * scaleFactor); } // Representing PiB value chartHistogram.Series.ElementAt(3).Points.AddXY(histogramInfo.PiBvalueLog, 0); chartHistogram.Series.ElementAt(3).Points.AddXY(histogramInfo.PiBvalueLog, histogramInfo.SU_SS.ElementAt(histogramInfo.PiBvalueLog - histogramInfo.SS_SUmin)); chartHistogram.Titles.Add("PiB value title"); //chartHistogram.Titles.ElementAt(1).Text = String.Format("PiB value = {0} (Log-converted) / {1} (Digital) / {2} (Physical)", histogramInfo.PiBvalueLog, histogramInfo.PiBvalueDigi, histogramInfo.PiBvaluePhysi); chartHistogram.Titles.ElementAt(1).Text = String.Format("PiB value = {0} (Log-converted) / {1:#.00} (Physical)", histogramInfo.PiBvalueLog, histogramInfo.PiBvaluePhysi); chartHistogram.ChartAreas.ElementAt(0).AxisY.Minimum = ymin - 1; chartHistogram.ChartAreas.ElementAt(0).AxisY.Maximum = ymax + 1; }
/// <summary> /// Sets the information that should be displayed by the chart. /// </summary> /// <param name="histogramInfo">The histogram info.</param> public void SetHistogramInfo(HistogramInfo histogramInfo) { // Fill configuration information labelFileName.Text = histogramInfo.FileName; labelSignalLabel.Text = histogramInfo.SignalLabel; labelF0.Text = histogramInfo.F0 + @" Hz"; labelFC.Text = histogramInfo.FC + @" Hz"; labelB.Text = histogramInfo.B + @" Hz"; labelSmoothRate.Text = histogramInfo.SmoothRate.ToString(); labelSmoothTime.Text = histogramInfo.SmoothTime + @" s"; if (histogramInfo.UnderSampling != 1) labelUndersample.Text = histogramInfo.UnderSampling.ToString(); // Filling the histogram for SS_SU double ymax = double.MinValue; double ymin = double.MaxValue; for (int k = 0; k < histogramInfo.SU_SS.Length; k++) { chartHistogram.Series.ElementAt(0).Points.AddXY(k + histogramInfo.SS_SUmin, histogramInfo.SU_SS.ElementAt(k)); chartHistogram.Series.ElementAt(1).Points.AddXY(k + histogramInfo.SS_SUmin, histogramInfo.SU_SSsmoothed.ElementAt(k)); double tmp = Math.Max(histogramInfo.SU_SS.ElementAt(k), histogramInfo.SU_SSsmoothed.ElementAt(k)); if (ymax < tmp) ymax = tmp; tmp = Math.Min(histogramInfo.SU_SS.ElementAt(k), histogramInfo.SU_SSsmoothed.ElementAt(k)); if (ymin > tmp) ymin = tmp; } // Representing correlation double scaleFactor = ymax / histogramInfo.SU_SSmatch.ElementAt(histogramInfo.PiBvalueLog - histogramInfo.SS_SUmin); for (int k = 0; k < histogramInfo.SU_SS.Length; k++) { chartHistogram.Series.ElementAt(2).Points.AddXY(k + histogramInfo.SS_SUmin, histogramInfo.SU_SSmatch.ElementAt(k) * scaleFactor); } // Representing PiB value chartHistogram.Series.ElementAt(3).Points.AddXY(histogramInfo.PiBvalueLog, 0); chartHistogram.Series.ElementAt(3).Points.AddXY(histogramInfo.PiBvalueLog, histogramInfo.SU_SS.ElementAt(histogramInfo.PiBvalueLog - histogramInfo.SS_SUmin)); chartHistogram.Titles.Add("PiB value title"); //chartHistogram.Titles.ElementAt(1).Text = String.Format("PiB value = {0} (Log-converted) / {1} (Digital) / {2} (Physical)", histogramInfo.PiBvalueLog, histogramInfo.PiBvalueDigi, histogramInfo.PiBvaluePhysi); chartHistogram.Titles.ElementAt(1).Text = String.Format("PiB value = {0} (Log-converted) / {1:#.00} (Physical)", histogramInfo.PiBvalueLog, histogramInfo.PiBvaluePhysi); chartHistogram.ChartAreas.ElementAt(0).AxisY.Minimum = ymin - 1; chartHistogram.ChartAreas.ElementAt(0).AxisY.Maximum = ymax + 1; }
/// <summary> /// Detects the piB value. /// </summary> /// <returns><c>true</c> if successful</returns> private bool DoDetectPiB() { short[] sssu = new short[AppConf.SS_SUmax - AppConf.SS_SUmin + 1]; double[] sssuSmoothed = new double[AppConf.SS_SUmax - AppConf.SS_SUmin + 1]; double[] sssuTemplate = new double[AppConf.piBCorrelationFunctionBufferSize]; double[] sssuMatch = new double[AppConf.SS_SUmax - AppConf.SS_SUmin + 1]; double x; double value; sssuSmoothed.Fill(0); sssuTemplate.Fill(0); sssuMatch.Fill(0); int dataBlockSamples = OutputEDFFile.SignalInfo[1].NrSamples; for (int k = 0; k < OutputEDFFile.FileInfo.NrDataRecords; k++) { OutputEDFFile.ReadDataBlock(k); for (int k1 = 0; k1 < dataBlockSamples; k1++) { double su = MathEx.ExpInteger(OutputEDFFile.DataBuffer[OutputBufferOffsets[1] + k1], AppConf.LogFloatY0, AppConf.LogFloatA); double ss = MathEx.ExpInteger(OutputEDFFile.DataBuffer[OutputBufferOffsets[2] + k1], AppConf.LogFloatY0, AppConf.LogFloatA); // Do not add zeros from unrecorded end of file if ((Math.Abs(su) >= AppConf.LogFloatY0) || (Math.Abs(ss) >= AppConf.LogFloatY0)) { short j = MathEx.LogFloat(ss - su, AppConf.LogFloatY0, AppConf.LogFloatA); //Watch it! SS_SUmin and SS_SUmax now refer to log-transformed values if (Range.InRange(j, AppConf.SS_SUmin, AppConf.SS_SUmax) && (sssu[j - AppConf.SS_SUmin] < short.MaxValue) && (j != 0)) sssu[j - AppConf.SS_SUmin]++; } } } /* * 2*SS_SUsmoother applied to the logarithmic converted values in the histogram * corresponds to the original values of piBPeakWidth */ int sssuSmootherWidth = (int)Range.EnsureRange(Math.Truncate(Math.Log(1.0 + AppConf.piBPeakWidth) / AppConf.LogFloatA / 2), -int.MaxValue, int.MaxValue); // Apply the smoothing (mean filter) to the histogram for (int k = sssuSmootherWidth; k <= AppConf.SS_SUmax - AppConf.SS_SUmin - sssuSmootherWidth; k++) { for (int k1 = k - sssuSmootherWidth; k1 <= k + sssuSmootherWidth; k1++) { sssuSmoothed[k] += sssu[k1]; } sssuSmoothed[k] = sssuSmoothed[k] / (2 * sssuSmootherWidth + 1); } // Construct the template to detect desired piB value peak in the smoothed histogram for (int k = 1; k < sssuTemplate.Length - 1; k++) { x = ((double)k / (sssuTemplate.Length - 1)) * 3 * Math.PI - 2 * Math.PI; value = 2.0 / 3 * (-0.5894) * (MathEx.Heav(x + 2 * Math.PI) - MathEx.Heav(x + (Math.PI / 2))) + (MathEx.Heav(x + (Math.PI / 2)) - MathEx.Heav(x)) * (Math.Sin(2 * x) / (2 * x)) + (MathEx.Heav(x) - MathEx.Heav(x - Math.PI / 2)) * (Math.Sin(2 * x) / (2 * x)); sssuTemplate[k] = value; } // Calculate and substract template mean value and calculate resulting template's peak index x = MathEx.Average(sssuTemplate); value = 0; int templatePeakIdx = 0; for (int k = 0; k < sssuTemplate.Length - 1; k++) { sssuTemplate[k] -= x; if (sssuTemplate[k] > value) { templatePeakIdx = k; value = sssuTemplate[k]; } } // Calculate correlation coefficients by shifting the template over the histogram for (int k = 0; k < (sssuSmoothed.Length - sssuTemplate.Length); k++) { value = 0; for (int k1 = 0; k1 < sssuTemplate.Length; k1++) value += sssuTemplate[k1] * sssuSmoothed[k + k1]; sssuMatch[k + templatePeakIdx] = value; } piB = 0; double peak = 0; // We'll take Pi*B as the x-value for the maximum correlation point for (int k = 0; k < sssuMatch.Length; k++) { if (sssuMatch[k] > peak) { peak = sssuMatch[k]; //piB = (short)Range.EnsureRange(k + appConf.SS_SUmin, -short.MaxValue, short.MaxValue); piB = (short)(k + AppConf.SS_SUmin); } } // Show histogram if (AppConf.ShowPiBHistogram) { HistogramInfo histogramInfo = new HistogramInfo { FileName = InputEDFFileName, SignalLabel = InputEDFFile.SignalInfo[InputSignalSelected].SignalLabel, SS_SUmax = AppConf.SS_SUmax, SS_SUmin = AppConf.SS_SUmin, SU_SS = sssu, SU_SSsmoothed = sssuSmoothed, UnderSampling = AppConf.IIRUnderSampler, SU_SSmatch = sssuMatch, F0 = AppConf.F0, FC = AppConf.FC, B = AppConf.BandWidth, PiBvalueLog = piB, PiBvaluePhysi = PiBExpInt, SmoothRate = AppConf.SmoothRate, SmoothTime = AppConf.SmoothTime }; //histogramInfo.PiBvalueDigi = (short)PiBExpInt; //histogramInfo.PiBvalueDigi = PiBExpInt; //histogramInfo.PiBvaluePhysi = PiBExpInt / PowGain; FormPiBHistogram formHistogram = new FormPiBHistogram(); formHistogram.SetHistogramInfo(histogramInfo); formHistogram.Show(); } return !AppError.Signaled; }