/// <summary> /// The Add Filtered Signal Wizard calls this function to return user input /// </summary> public void AddFilterOutput(FilteredSignal filteredSignal) { sm.FilteredSignals.Add(filteredSignal); PreviewList_Updated(); OnPropertyChanged(nameof(AllNonHiddenSignals)); }
/// <summary> /// Loads the filtered signal definitions into memory /// </summary> /// <param name="AllSignals"> All signals loaded from the EDF file or specified as derivatives or filtered signals </param> /// <returns> The filtered signal definitions </returns> public static FilteredSignal[] LoadFilteredSignalsFile(string[] AllSignals) { if (!Directory.Exists(settings_folder)) { Directory.CreateDirectory(settings_folder); } List <FilteredSignal> filteredSignals = new List <FilteredSignal>(); if (File.Exists(settings_folder + "\\filtered.txt")) { StreamReader sr = new StreamReader(settings_folder + "\\filtered.txt"); string[] lines = sr.ReadToEnd().Replace("\r\n", "\n").Split('\n'); for (int x = 0; x < lines.Length; x++) { string[] curr = lines[x].Split(','); if (curr.Length == 6) { FilteredSignal fr = new FilteredSignal(); fr.SignalName = curr[0]; fr.OriginalName = curr[1]; fr.LowPass_Enabled = bool.Parse(curr[2]); fr.LowPassCutoff = float.Parse(curr[3]); fr.Average_Enabled = bool.Parse(curr[4]); fr.Average_Length = float.Parse(curr[5]); if (AllSignals == null || AllSignals.Contains(fr.OriginalName)) { filteredSignals.Add(fr); } } } sr.Close(); } return(filteredSignals.ToArray()); }
/// <summary> /// From a signal, returns a series of X,Y values for use with a PlotModel /// Also returns y axis information and the sample_period of the signal /// </summary> /// <param name="sample_period"> Variable to contain the sample period of the signal </param> /// <param name="Signal"> The input signal name </param> /// <param name="StartTime"> The input start time to be contained in the series </param> /// <param name="EndTime"> The input end time to be contained in the series </param> /// <returns> The series of X,Y values to draw on the plot </returns> public LineSeries GetSeriesFromSignalName(out float sample_period, string Signal, DateTime StartTime, DateTime EndTime) { // Variable To Return LineSeries series = new LineSeries(); // Check if this signal needs filtering bool filter = false; FilteredSignal filteredSignal = sm.FilteredSignals.Find(temp => temp.SignalName == Signal); if (filteredSignal != null) { filter = true; Signal = sm.FilteredSignals.Find(temp => temp.SignalName == Signal).OriginalName; } // Get Signal if (EDFAllSignals.Contains(Signal)) { // Get Signal EDFSignal edfsignal = LoadedEDFFile.Header.Signals.Find(temp => temp.Label.Trim() == Signal); // Determine Array Portion sample_period = (float)LoadedEDFFile.Header.DurationOfDataRecordInSeconds / (float)edfsignal.NumberOfSamplesPerDataRecord; // Get Array List <float> values = Utils.retrieveSignalSampleValuesMod(LoadedEDFFile, edfsignal, StartTime, EndTime); // Add Points to Series for (int y = 0; y < values.Count; y++) { series.Points.Add(new DataPoint(DateTimeAxis.ToDouble(StartTime + new TimeSpan(0, 0, 0, 0, (int)(sample_period * (float)y * 1000))), values[y])); } } else // Derivative Signal { // Get Signals DerivativeSignal deriv_info = sm.DerivedSignals.Find(temp => temp.DerivativeName == Signal); EDFSignal edfsignal1 = LoadedEDFFile.Header.Signals.Find(temp => temp.Label.Trim() == deriv_info.Signal1Name.Trim()); EDFSignal edfsignal2 = LoadedEDFFile.Header.Signals.Find(temp => temp.Label.Trim() == deriv_info.Signal2Name.Trim()); // Get Arrays and Perform Resampling if needed List <float> values1; List <float> values2; if (edfsignal1.NumberOfSamplesPerDataRecord == edfsignal2.NumberOfSamplesPerDataRecord) // No resampling { values1 = Utils.retrieveSignalSampleValuesMod(LoadedEDFFile, edfsignal1, StartTime, EndTime); values2 = Utils.retrieveSignalSampleValuesMod(LoadedEDFFile, edfsignal2, StartTime, EndTime); sample_period = (float)LoadedEDFFile.Header.DurationOfDataRecordInSeconds / (float)edfsignal1.NumberOfSamplesPerDataRecord; } else if (edfsignal1.NumberOfSamplesPerDataRecord > edfsignal2.NumberOfSamplesPerDataRecord) // Upsample signal 2 { values1 = Utils.retrieveSignalSampleValuesMod(LoadedEDFFile, edfsignal1, StartTime, EndTime); values2 = Utils.retrieveSignalSampleValuesMod(LoadedEDFFile, edfsignal2, StartTime, EndTime); values2 = Utils.MATLAB_Resample(values2.ToArray(), edfsignal1.NumberOfSamplesPerDataRecord / edfsignal2.NumberOfSamplesPerDataRecord); sample_period = (float)LoadedEDFFile.Header.DurationOfDataRecordInSeconds / (float)edfsignal1.NumberOfSamplesPerDataRecord; } else // Upsample signal 1 { values1 = Utils.retrieveSignalSampleValuesMod(LoadedEDFFile, edfsignal1, StartTime, EndTime); values2 = Utils.retrieveSignalSampleValuesMod(LoadedEDFFile, edfsignal2, StartTime, EndTime); values1 = Utils.MATLAB_Resample(values1.ToArray(), edfsignal2.NumberOfSamplesPerDataRecord / edfsignal1.NumberOfSamplesPerDataRecord); sample_period = (float)LoadedEDFFile.Header.DurationOfDataRecordInSeconds / (float)edfsignal2.NumberOfSamplesPerDataRecord; } // Add Points to Series for (int y = 0; y < Math.Min(values1.Count, values2.Count); y++) { series.Points.Add(new DataPoint(DateTimeAxis.ToDouble(StartTime + new TimeSpan(0, 0, 0, 0, (int)(sample_period * (float)y * 1000))), values1[y] - values2[y])); } } if (filter == true) { if (filteredSignal.LowPass_Enabled) { series = Utils.ApplyLowPassFilter(series, filteredSignal.LowPassCutoff, sample_period); } if (filteredSignal.Average_Enabled) { float LENGTH; LENGTH = Math.Max(filteredSignal.Average_Length / (sample_period * 1000), 1); series = Utils.ApplyAverageFilter(series, (int)LENGTH); } } return(series); }
/// <summary> /// Given a settings model and edf file, sets the Y axis bounds of a given signal /// </summary> /// <param name="Signal"> The signal to set the bounds for </param> /// <param name="LoadedEDFFile"> The EDF file with the signal's values </param> /// <param name="sm"> The settings model that bounds are stored in </param> public static void SetYBounds(string Signal, EDFFile LoadedEDFFile, SettingsModel sm) { // Save Signal Name string OrigName = Signal; // Check to see if the Signal Y Bounds have already been calculated SignalYAxisExtremes find = sm.SignalsYAxisExtremes.Find(temp => temp.SignalName.Trim() == Signal.Trim()); // If the Signal Y Bounds have not been calculated if (find == null) { List <float> values = new List <float>(); // Check if this signal needs filtering FilteredSignal filteredSignal = sm.FilteredSignals.Find(temp => temp.SignalName == Signal); if (filteredSignal != null) { Signal = sm.FilteredSignals.Find(temp => temp.SignalName == Signal).OriginalName; } if (LoadedEDFFile.Header.Signals.Find(temp => temp.Label.Trim() == Signal) != null) // Regular Signal { // Get the EDF Signal Values EDFSignal edfsignal = LoadedEDFFile.Header.Signals.Find(temp => temp.Label.Trim() == Signal); values = LoadedEDFFile.retrieveSignalSampleValues(edfsignal); } else // Derivative Signal { // Get Signals DerivativeSignal deriv_info = sm.DerivedSignals.Find(temp => temp.DerivativeName == Signal); EDFSignal edfsignal1 = LoadedEDFFile.Header.Signals.Find(temp => temp.Label.Trim() == deriv_info.Signal1Name.Trim()); EDFSignal edfsignal2 = LoadedEDFFile.Header.Signals.Find(temp => temp.Label.Trim() == deriv_info.Signal2Name.Trim()); // Get Arrays and Perform Resampling if needed List <float> values1; List <float> values2; if (edfsignal1.NumberOfSamplesPerDataRecord == edfsignal2.NumberOfSamplesPerDataRecord) // No resampling { values1 = LoadedEDFFile.retrieveSignalSampleValues(edfsignal1); values2 = LoadedEDFFile.retrieveSignalSampleValues(edfsignal2); } else if (edfsignal1.NumberOfSamplesPerDataRecord > edfsignal2.NumberOfSamplesPerDataRecord) // Upsample signal 2 { values1 = LoadedEDFFile.retrieveSignalSampleValues(edfsignal1); values2 = LoadedEDFFile.retrieveSignalSampleValues(edfsignal2); values2 = Utils.MATLAB_Resample(values2.ToArray(), edfsignal1.NumberOfSamplesPerDataRecord / edfsignal2.NumberOfSamplesPerDataRecord); } else // Upsample signal 1 { values1 = LoadedEDFFile.retrieveSignalSampleValues(edfsignal1); values2 = LoadedEDFFile.retrieveSignalSampleValues(edfsignal2); values1 = Utils.MATLAB_Resample(values1.ToArray(), edfsignal2.NumberOfSamplesPerDataRecord / edfsignal1.NumberOfSamplesPerDataRecord); } for (int x = 0; x < Math.Min(values1.Count, values2.Count); x += 1) { values.Add(values1[x] - values2[x]); } } // Remove repeated values int last_unique = 0; for (int x = 0; x < values.Count; x++) { if (x > 0 && values[x] == values[last_unique]) { values[x] = float.NaN; } else { last_unique = x; } } values.RemoveAll(temp => float.IsNaN(temp)); // Find the high and low percentiles of the signal and the average value of the signal values.Sort(); int high_index = (int)(percent_high / 100 * (values.Count - 1)); int low_index = (int)(percent_low / 100 * (values.Count - 1)); float range = values[high_index] - values[low_index]; float high_value = values[high_index] + range * (100 - (float)percent_high) / 100; float low_value = values[low_index] - range * ((float)percent_low) / 100; float av_value = values.Average(); // Save the values so that they do not have to be recalculated sm.SignalsYAxisExtremes.Add(new SignalYAxisExtremes(OrigName) { yMax = high_value, yMin = low_value, yAvr = av_value }); } }