public SaveData(int sampleDuration, string fileName, bool complex, Controller controller) { this.controller = controller; if (complex) nrSignals = 9; else nrSignals = 3; edfFile = new EdfFile(fileName, false, false, false, false); edfFile.CreateNewFile(nrSignals, true); edfFile.FileInfo.SampleRecDuration = sampleDuration; buffer = new List<short>[nrSignals]; for (int i = 0; i < nrSignals; i++) buffer[i]=new List<short>(); addSignal(0, "Audio", "Amplitude", Statics.FS, 1024, 0); addSignal(1, "Aktivitaet", "Aktivitaet", Statics.FS /20, 100, 0); addSignal(2, "Position", "Position", Statics.FS / 20, 3, 0); if (complex) { addSignal(3, "Gyro X", "Winkelgeschwindigkeit", Statics.FS / 20, 255, 0); addSignal(4, "Gyro Y", "Winkelgeschwindigkeit", Statics.FS / 20, 255, 0); addSignal(5, "Gyro Z", "Winkelgeschwindigkeit", Statics.FS / 20, 255, 0); addSignal(6, "Acc X", "Beschleunigung", Statics.FS / 20, 255, 0); addSignal(7, "Acc Y", "Beschleunigung", Statics.FS / 20, 255, 0); addSignal(8, "Acc Z", "Beschleunigung", Statics.FS / 20, 255, 0); } }
/// <summary> /// Handles the change of the input file name. Opens the file and sets the available signal labels. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void EdfInputFileNameChange(object sender, EventArgs e) { signalsComboBox.Items.Clear(); signalsComboBox.ResetText(); signalsComboBox.Enabled = false; buttonStart.Enabled = false; if (File.Exists(textBoxInputFilename.Text)) { EdfFile edfFile = new EdfFile(textBoxInputFilename.Text, true, false, false, false); if (edfFile.ValidFormat) { _edfFile = edfFile; textBox.AppendText(Environment.NewLine + "Number of signals: " + _edfFile.FileInfo.NrSignals.ToString()); for (int k = 0; k < _edfFile.FileInfo.NrSignals; k++) { signalsComboBox.Items.Add(string.Format("{0} - {1} ({2}Hz)", k + 1, _edfFile.SignalInfo[k].SignalLabel, _edfFile.SignalInfo[k].NrSamples / _edfFile.FileInfo.SampleRecDuration)); } if (signalsComboBox.Items.Count > 0) { signalsComboBox.SelectedIndex = 0; } signalsComboBox.Enabled = true; buttonStart.Enabled = true; } } }
public SaveData(int sampleDuration, string fileName, bool complex, Controller controller) { this.controller = controller; if (complex) { nrSignals = 9; } else { nrSignals = 3; } edfFile = new EdfFile(fileName, false, false, false, false); edfFile.CreateNewFile(nrSignals, true); edfFile.FileInfo.SampleRecDuration = sampleDuration; buffer = new List <short> [nrSignals]; for (int i = 0; i < nrSignals; i++) { buffer[i] = new List <short>(); } addSignal(0, "Audio", "Amplitude", Statics.FS, 1024, 0); addSignal(1, "Aktivitaet", "Aktivitaet", Statics.FS / 20, 100, 0); addSignal(2, "Position", "Position", Statics.FS / 20, 3, 0); if (complex) { addSignal(3, "Gyro X", "Winkelgeschwindigkeit", Statics.FS / 20, 255, 0); addSignal(4, "Gyro Y", "Winkelgeschwindigkeit", Statics.FS / 20, 255, 0); addSignal(5, "Gyro Z", "Winkelgeschwindigkeit", Statics.FS / 20, 255, 0); addSignal(6, "Acc X", "Beschleunigung", Statics.FS / 20, 255, 0); addSignal(7, "Acc Y", "Beschleunigung", Statics.FS / 20, 255, 0); addSignal(8, "Acc Z", "Beschleunigung", Statics.FS / 20, 255, 0); } }
/// <summary> /// Prepares the EDF files. /// Opens the input file, creates a new ouput file and sets the header information. /// </summary> /// <returns></returns> private bool PrepareEDFFiles() { if (AppConf.CopyInputSignal) { _neuroLoopGain.NumOutputSignals = 15; } else { _neuroLoopGain.NumOutputSignals = 14; } double[] sFrecs = new double[_neuroLoopGain.NumOutputSignals]; // Calculate best value for output EDF datablock duration according to analysis parameters try { //OPEN INPUT FILENAME _neuroLoopGain.InputEDFFile = new EdfFile(InputEDFFileName, true, false, false, true); _neuroLoopGain.InputSignalSelected = InputSignalSelected; int numInputSignals = _neuroLoopGain.InputEDFFile.FileInfo.NrSignals; _neuroLoopGain.InputBufferOffsets = new int[numInputSignals]; for (int k = 0; k < numInputSignals; k++) _neuroLoopGain.InputBufferOffsets[k] = _neuroLoopGain.InputEDFFile.SignalInfo[k].BufferOffset; //OUTPUT EDF EdfFile outputEDF = new EdfFile(AppConf.OutputFileName, false, false, false, false); //EdfFile outputEDF = new EdfFile(AppConf.OutputFileName, false, true, false, false); EdfSignalInfoBase edfSignalInfo = _neuroLoopGain.InputEDFFile.SignalInfo[InputSignalSelected]; outputEDF.CreateNewFile(_neuroLoopGain.NumOutputSignals); //PreCondition checked before: (1 / AppConf.SmoothTime) is between 1 and sFrecs[0] double doubleValue = MathEx.RoundNearest(1 / AppConf.SmoothTime); Range.EnsureRange(doubleValue, 0, _neuroLoopGain.InputSampleFrequency); for (int k = 0; k < _neuroLoopGain.NumOutputSignals; k++) { sFrecs[k] = doubleValue; } if (AppConf.CopyInputSignal) sFrecs[0] = _neuroLoopGain.InputSampleFrequency; //TODO: check this List<EdfDataBlockSizeCalculatorResult> results = new List<EdfDataBlockSizeCalculatorResult>(); double dataBlockDuration = EdfDataBlockSizeCalculator.Calculate(sFrecs, MaxEdFblockSize, results); if (!MathEx.SameValue(dataBlockDuration, -1)) { // Look for minimun possible error double bestError = results[0].MaxRelativeError; int bestIdx = 0; for (int k = 1; k < results.Count; k++) if (results[k].MaxRelativeError < bestError) { bestError = results[k].MaxRelativeError; bestIdx = k; } else if (MathEx.SameValue(results[k].MaxRelativeError, bestError) && (results[k].Duration > results[bestIdx].Duration) && (results[k].Duration <= MaxBlockDuration)) { // Try to get block durations as much as possible to avoid excesive disk reads bestIdx = k; } if (!MathEx.SameValue(bestError, 0)) { //TODO: error??, not valid SUSSsmoothingTime parameter (we're gonna miss some samples) ApplicationError.Add("not valid SmoothTime parameter (we're gonna miss some samples)", DefaultErrorMessageId); ErrorLogger.WriteErrorLog("not valid SmoothTime parameter (we're gonna miss some samples). Error = " + bestError.ToString()); outputEDF.FileInfo.SampleRecDuration = results[bestIdx].Duration; } else { outputEDF.FileInfo.SampleRecDuration = results[bestIdx].Duration; // Duration in seconds of block record AppConf.SmoothTime = 1.0 / sFrecs[1]; // Reset the value of SmoothTime to the one actually used by the system } } else { ApplicationError.Add("failed to assign a data block duration for output EDF", DefaultErrorMessageId); ErrorLogger.WriteErrorLog("failed to assign a data block duration for output EDF"); } _neuroLoopGain.OutputBufferOffsets = new int[15]; _neuroLoopGain.OutputBufferOffsets[0] = 0; for (int k = 0; k < _neuroLoopGain.NumOutputSignals; k++) { outputEDF.SignalInfo[k].PreFilter = edfSignalInfo.PreFilter; double nsamples = outputEDF.FileInfo.SampleRecDuration * sFrecs[k]; if (Math.Truncate(nsamples) < nsamples) { //TODO: Error?? the number of samples in a data block should be an integer number ApplicationError.Add("not valid SmoothTime parameter: we are going miss some samples", DefaultErrorMessageId); ErrorLogger.WriteErrorLog("not valid SmoothTime parameter: we are going miss some samples"); /* It should effectively be an integer number, but if we admit some error to happen * (bestError != 0), then we can work with the truncated value => we're gonna miss some * sample during the process */ nsamples = Math.Truncate(nsamples); } outputEDF.SignalInfo[k].NrSamples = (int)nsamples; //if (k == 0) if ((k == 0) && AppConf.CopyInputSignal) { outputEDF.SignalInfo[k].DigiMax = edfSignalInfo.DigiMax; outputEDF.SignalInfo[k].DigiMin = edfSignalInfo.DigiMin; outputEDF.SignalInfo[k].PhysiMax = edfSignalInfo.PhysiMax; outputEDF.SignalInfo[k].PhysiMin = edfSignalInfo.PhysiMin; outputEDF.SignalInfo[k].PhysiDim = edfSignalInfo.PhysiDim; } else { outputEDF.SignalInfo[k].DigiMax = short.MaxValue; outputEDF.SignalInfo[k].DigiMin = -short.MaxValue; //if (k < 9) if (k < _neuroLoopGain.NumOutputSignals - 6) { outputEDF.SignalInfo[k].PhysiDim = "Filtered"; outputEDF.SignalInfo[k].PhysiMax = short.MaxValue; outputEDF.SignalInfo[k].PhysiMin = -short.MaxValue; } else //if ((k >= 9) && (k < 12)) if ((k >= _neuroLoopGain.NumOutputSignals - 6) && (k < _neuroLoopGain.NumOutputSignals - 3)) { outputEDF.SignalInfo[k].PhysiMax = short.MaxValue; outputEDF.SignalInfo[k].PhysiMin = -short.MaxValue; } else { outputEDF.SignalInfo[k].PhysiDim = "%"; outputEDF.SignalInfo[k].PhysiMax = short.MaxValue / AppConf.MicGain; outputEDF.SignalInfo[k].PhysiMin = -short.MaxValue / AppConf.MicGain; } if (k > 0) { if (AppConf.CopyInputSignal) _neuroLoopGain.OutputBufferOffsets[k] = _neuroLoopGain.OutputBufferOffsets[k - 1] + outputEDF.SignalInfo[k - 1].NrSamples; else _neuroLoopGain.OutputBufferOffsets[k + 1] = _neuroLoopGain.OutputBufferOffsets[k] + outputEDF.SignalInfo[k].NrSamples; } } outputEDF.SignalInfo[k].Reserved = edfSignalInfo.Reserved; //if ((k > 0) && (k < 9)) if ((k >= _neuroLoopGain.NumOutputSignals - 14) && (k < _neuroLoopGain.NumOutputSignals - 6)) if (AppConf.CopyInputSignal) outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k] + " " + edfSignalInfo.PhysiDim + "**2/x"; else outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k + 1] + " " + edfSignalInfo.PhysiDim + "**2/x"; else if (AppConf.CopyInputSignal) outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k]; else outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k + 1]; outputEDF.SignalInfo[k].TransducerType = edfSignalInfo.TransducerType; outputEDF.SignalInfo[k].ThousandSeparator = edfSignalInfo.ThousandSeparator; } // Info for MC analysis outputEDF.FileInfo.Recording = string.Format(CultureInfo.InvariantCulture, "Startdate {0} NeuroLoop-gain analysis at {1:#.#}Hz of {2} in {3}", _neuroLoopGain.InputEDFFile.FileInfo.StartDate.HasValue ? _neuroLoopGain.InputEDFFile.FileInfo.StartDate.Value.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture) : "X", sFrecs[1], _neuroLoopGain.InputEDFFile.SignalInfo[InputSignalSelected].SignalLabel, Path.GetFileName(InputEDFFileName)); //Copy header info from the original signal outputEDF.FileInfo.Patient = _neuroLoopGain.InputEDFFile.FileInfo.Patient; outputEDF.FileInfo.StartDate = _neuroLoopGain.InputEDFFile.FileInfo.StartDate; outputEDF.FileInfo.StartTime = _neuroLoopGain.InputEDFFile.FileInfo.StartTime; outputEDF.CommitChanges(); _neuroLoopGain.MCsignalsBlockSamples = outputEDF.SignalInfo[1].NrSamples; _neuroLoopGain.OutputEDFFile = outputEDF; } catch (Exception e) { ApplicationError.Add("Error opening input and/or ouput files: " + e.Message, DefaultErrorMessageId); ErrorLogger.WriteErrorLog("Error opening input and/or ouput files: " + e.Message); } return !ApplicationError.Signaled; }
/// <summary> /// Handles the change of the input file name. Opens the file and sets the available signal labels. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> private void EdfInputFileNameChange(object sender, EventArgs e) { signalsComboBox.Items.Clear(); signalsComboBox.ResetText(); signalsComboBox.Enabled = false; buttonStart.Enabled = false; if (File.Exists(textBoxInputFilename.Text)) { EdfFile edfFile = new EdfFile(textBoxInputFilename.Text, true, false, false, false); if (edfFile.ValidFormat) { _edfFile = edfFile; textBox.AppendText(Environment.NewLine + "Number of signals: " + _edfFile.FileInfo.NrSignals.ToString()); for (int k = 0; k < _edfFile.FileInfo.NrSignals; k++) { signalsComboBox.Items.Add(string.Format("{0} - {1} ({2}Hz)", k + 1, _edfFile.SignalInfo[k].SignalLabel, _edfFile.SignalInfo[k].NrSamples / _edfFile.FileInfo.SampleRecDuration)); } if (signalsComboBox.Items.Count > 0) signalsComboBox.SelectedIndex = 0; signalsComboBox.Enabled = true; buttonStart.Enabled = true; } } }
/// <summary> /// Prepares the EDF files. /// Opens the input file, creates a new ouput file and sets the header information. /// </summary> /// <returns></returns> private bool PrepareEDFFiles() { if (AppConf.CopyInputSignal) { _neuroLoopGain.NumOutputSignals = 15; } else { _neuroLoopGain.NumOutputSignals = 14; } double[] sFrecs = new double[_neuroLoopGain.NumOutputSignals]; // Calculate best value for output EDF datablock duration according to analysis parameters try { //OPEN INPUT FILENAME _neuroLoopGain.InputEDFFile = new EdfFile(InputEDFFileName, true, false, false, true); _neuroLoopGain.InputSignalSelected = InputSignalSelected; int numInputSignals = _neuroLoopGain.InputEDFFile.FileInfo.NrSignals; _neuroLoopGain.InputBufferOffsets = new int[numInputSignals]; for (int k = 0; k < numInputSignals; k++) { _neuroLoopGain.InputBufferOffsets[k] = _neuroLoopGain.InputEDFFile.SignalInfo[k].BufferOffset; } //OUTPUT EDF EdfFile outputEDF = new EdfFile(AppConf.OutputFileName, false, false, false, false); //EdfFile outputEDF = new EdfFile(AppConf.OutputFileName, false, true, false, false); EdfSignalInfoBase edfSignalInfo = _neuroLoopGain.InputEDFFile.SignalInfo[InputSignalSelected]; outputEDF.CreateNewFile(_neuroLoopGain.NumOutputSignals); //PreCondition checked before: (1 / AppConf.SmoothTime) is between 1 and sFrecs[0] double doubleValue = MathEx.RoundNearest(1 / AppConf.SmoothTime); Range.EnsureRange(doubleValue, 0, _neuroLoopGain.InputSampleFrequency); for (int k = 0; k < _neuroLoopGain.NumOutputSignals; k++) { sFrecs[k] = doubleValue; } if (AppConf.CopyInputSignal) { sFrecs[0] = _neuroLoopGain.InputSampleFrequency; } //TODO: check this List <EdfDataBlockSizeCalculatorResult> results = new List <EdfDataBlockSizeCalculatorResult>(); double dataBlockDuration = EdfDataBlockSizeCalculator.Calculate(sFrecs, MaxEdFblockSize, results); if (!MathEx.SameValue(dataBlockDuration, -1)) { // Look for minimun possible error double bestError = results[0].MaxRelativeError; int bestIdx = 0; for (int k = 1; k < results.Count; k++) { if (results[k].MaxRelativeError < bestError) { bestError = results[k].MaxRelativeError; bestIdx = k; } else if (MathEx.SameValue(results[k].MaxRelativeError, bestError) && (results[k].Duration > results[bestIdx].Duration) && (results[k].Duration <= MaxBlockDuration)) { // Try to get block durations as much as possible to avoid excesive disk reads bestIdx = k; } } if (!MathEx.SameValue(bestError, 0)) { //TODO: error??, not valid SUSSsmoothingTime parameter (we're gonna miss some samples) ApplicationError.Add("not valid SmoothTime parameter (we're gonna miss some samples)", DefaultErrorMessageId); ErrorLogger.WriteErrorLog("not valid SmoothTime parameter (we're gonna miss some samples). Error = " + bestError.ToString()); outputEDF.FileInfo.SampleRecDuration = results[bestIdx].Duration; } else { outputEDF.FileInfo.SampleRecDuration = results[bestIdx].Duration; // Duration in seconds of block record AppConf.SmoothTime = 1.0 / sFrecs[1]; // Reset the value of SmoothTime to the one actually used by the system } } else { ApplicationError.Add("failed to assign a data block duration for output EDF", DefaultErrorMessageId); ErrorLogger.WriteErrorLog("failed to assign a data block duration for output EDF"); } _neuroLoopGain.OutputBufferOffsets = new int[15]; _neuroLoopGain.OutputBufferOffsets[0] = 0; for (int k = 0; k < _neuroLoopGain.NumOutputSignals; k++) { outputEDF.SignalInfo[k].PreFilter = edfSignalInfo.PreFilter; double nsamples = outputEDF.FileInfo.SampleRecDuration * sFrecs[k]; if (Math.Truncate(nsamples) < nsamples) { //TODO: Error?? the number of samples in a data block should be an integer number ApplicationError.Add("not valid SmoothTime parameter: we are going miss some samples", DefaultErrorMessageId); ErrorLogger.WriteErrorLog("not valid SmoothTime parameter: we are going miss some samples"); /* It should effectively be an integer number, but if we admit some error to happen * (bestError != 0), then we can work with the truncated value => we're gonna miss some * sample during the process */ nsamples = Math.Truncate(nsamples); } outputEDF.SignalInfo[k].NrSamples = (int)nsamples; //if (k == 0) if ((k == 0) && AppConf.CopyInputSignal) { outputEDF.SignalInfo[k].DigiMax = edfSignalInfo.DigiMax; outputEDF.SignalInfo[k].DigiMin = edfSignalInfo.DigiMin; outputEDF.SignalInfo[k].PhysiMax = edfSignalInfo.PhysiMax; outputEDF.SignalInfo[k].PhysiMin = edfSignalInfo.PhysiMin; outputEDF.SignalInfo[k].PhysiDim = edfSignalInfo.PhysiDim; } else { outputEDF.SignalInfo[k].DigiMax = short.MaxValue; outputEDF.SignalInfo[k].DigiMin = -short.MaxValue; //if (k < 9) if (k < _neuroLoopGain.NumOutputSignals - 6) { outputEDF.SignalInfo[k].PhysiDim = "Filtered"; outputEDF.SignalInfo[k].PhysiMax = short.MaxValue; outputEDF.SignalInfo[k].PhysiMin = -short.MaxValue; } else //if ((k >= 9) && (k < 12)) if ((k >= _neuroLoopGain.NumOutputSignals - 6) && (k < _neuroLoopGain.NumOutputSignals - 3)) { outputEDF.SignalInfo[k].PhysiMax = short.MaxValue; outputEDF.SignalInfo[k].PhysiMin = -short.MaxValue; } else { outputEDF.SignalInfo[k].PhysiDim = "%"; outputEDF.SignalInfo[k].PhysiMax = short.MaxValue / AppConf.MicGain; outputEDF.SignalInfo[k].PhysiMin = -short.MaxValue / AppConf.MicGain; } if (k > 0) { if (AppConf.CopyInputSignal) { _neuroLoopGain.OutputBufferOffsets[k] = _neuroLoopGain.OutputBufferOffsets[k - 1] + outputEDF.SignalInfo[k - 1].NrSamples; } else { _neuroLoopGain.OutputBufferOffsets[k + 1] = _neuroLoopGain.OutputBufferOffsets[k] + outputEDF.SignalInfo[k].NrSamples; } } } outputEDF.SignalInfo[k].Reserved = edfSignalInfo.Reserved; //if ((k > 0) && (k < 9)) if ((k >= _neuroLoopGain.NumOutputSignals - 14) && (k < _neuroLoopGain.NumOutputSignals - 6)) { if (AppConf.CopyInputSignal) { outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k] + " " + edfSignalInfo.PhysiDim + "**2/x"; } else { outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k + 1] + " " + edfSignalInfo.PhysiDim + "**2/x"; } } else if (AppConf.CopyInputSignal) { outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k]; } else { outputEDF.SignalInfo[k].SignalLabel = _signalOutputLabels[k + 1]; } outputEDF.SignalInfo[k].TransducerType = edfSignalInfo.TransducerType; outputEDF.SignalInfo[k].ThousandSeparator = edfSignalInfo.ThousandSeparator; } // Info for MC analysis outputEDF.FileInfo.Recording = string.Format(CultureInfo.InvariantCulture, "Startdate {0} NeuroLoop-gain analysis at {1:#.#}Hz of {2} in {3}", _neuroLoopGain.InputEDFFile.FileInfo.StartDate.HasValue ? _neuroLoopGain.InputEDFFile.FileInfo.StartDate.Value.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture) : "X", sFrecs[1], _neuroLoopGain.InputEDFFile.SignalInfo[InputSignalSelected].SignalLabel, Path.GetFileName(InputEDFFileName)); //Copy header info from the original signal outputEDF.FileInfo.Patient = _neuroLoopGain.InputEDFFile.FileInfo.Patient; outputEDF.FileInfo.StartDate = _neuroLoopGain.InputEDFFile.FileInfo.StartDate; outputEDF.FileInfo.StartTime = _neuroLoopGain.InputEDFFile.FileInfo.StartTime; outputEDF.CommitChanges(); _neuroLoopGain.MCsignalsBlockSamples = outputEDF.SignalInfo[1].NrSamples; _neuroLoopGain.OutputEDFFile = outputEDF; } catch (Exception e) { ApplicationError.Add("Error opening input and/or ouput files: " + e.Message, DefaultErrorMessageId); ErrorLogger.WriteErrorLog("Error opening input and/or ouput files: " + e.Message); } return(!ApplicationError.Signaled); }