/// <summary> /// Returns a signal's Y axis minimum bound /// </summary> /// <param name="Signal"> The signal to return Y axis bounds for </param> /// <param name="woBias"> True if the returned bounds assumes 0 DC </param> /// <param name="LoadedEDFFile"> The EDF File with all the signal's values in it </param> /// <param name="sm"> The settings model containing the bounds </param> /// <returns> The min y axis bounds of a signal</returns> public static double GetMinSignalValue(string Signal, bool woBias, EDFFile LoadedEDFFile, SettingsModel sm) { // Check if the Y Bounds have already been calculated SignalYAxisExtremes find = sm.SignalsYAxisExtremes.Find(temp => temp.SignalName.Trim() == Signal.Trim()); if (find != null) // If the Y Bounds have been calculated { if (!Double.IsNaN(find.yMin) && !Double.IsNaN(find.yAvr)) // Double check if the Y Bounds have been calculated { // Remove DC bias? if (woBias) // Yes { return(find.yMin - find.yAvr); } else // No { return(find.yMin); } } else // Calculate Y Bounds { SetYBounds(Signal, LoadedEDFFile, sm); return(GetMinSignalValue(Signal, woBias, LoadedEDFFile, sm)); } } else // Calculate Y Bounds { SetYBounds(Signal, LoadedEDFFile, sm); return(GetMinSignalValue(Signal, woBias, LoadedEDFFile, sm)); } }
/// <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 }); } }