Beispiel #1
0
 /// <summary>
 /// Adds Informations about the recording and the patient to the edfFile
 /// </summary>
 /// <param name="recDescription">Description of the recording</param>
 /// <param name="patientInfo">Information about the patient</param>
 /// <param name="birthDate">BirthDate of the patient</param>
 /// <param name="gender">Gender of patient</param>
 /// <param name="name">Name of patient</param>
 public void addInformation(string recDescription, string patientInfo, DateTime birthDate, char gender, string name)
 {
     //Copy header info from the original signal
     edfFile.FileInfo.Recording        = recDescription;
     edfFile.FileInfo.Patient          = patientInfo;
     edfFile.FileInfo.PatientBirthDate = DateTime.Today;
     edfFile.FileInfo.PatientGender    = gender;
     edfFile.FileInfo.PatientName      = name;
     edfFile.FileInfo.StartDate        = DateTime.Today;
     edfFile.FileInfo.StartTime        = DateTime.Now.TimeOfDay;
     saveStart = DateTime.Now;
     edfFile.CommitChanges();
 }
        /// <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>
        /// 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);
        }