Пример #1
0
        public void Execute(object sender, DoWorkEventArgs e)
        {
            bw = (BackgroundWorker)sender;

            bw.ReportProgress(0, "Starting BDFConverter");
            CCIUtilities.Log.writeToLog("Starting BDFConverter on records in " + directory);

            /***** Read electrode file *****/
            ElectrodeInputFileStream etrFile = new ElectrodeInputFileStream(
                new FileStream(Path.Combine(directory, eventHeader.ElectrodeFile), FileMode.Open, FileAccess.Read));

            /***** Open BDF file *****/
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.Title = "Save as BDF file ...";
            dlg.AddExtension = true;
            dlg.DefaultExt = ".bdf"; // Default file extension
            dlg.Filter = "BDF Files (.bdf)|*.bdf"; // Filter files by extension
            dlg.FileName = Path.GetFileNameWithoutExtension(eventHeader.BDFFile);
            bool? result = dlg.ShowDialog();
            if (result == false)
            {
                e.Result = new int[] { 0, 0 };
                return;
            }
            samplingRate = BDF.NSamp / BDF.RecordDuration; //Old sampling rate; exact as number of samples and duration are always an exact multiple
            oldOffsetInPts = Convert.ToInt32(offset * samplingRate);
            int newSamplingRate = (int)((double)samplingRate / (double)decimation + 0.5); //Make best estimate possible with integers
            newOffsetInPts = Convert.ToInt32(offset * newSamplingRate);
            newRecordLength = length * newSamplingRate; //new record length must be exact multiple of the sampling rate in BDF
            newStatus = new int[newRecordLength];
            status = new int[BDF.NSamp];
            GV0 = GV[0];

            BDFWriter = new BDFEDFFileWriter(File.Open(dlg.FileName, FileMode.Create, FileAccess.ReadWrite),
                channels.Count + 1, /* Extra channel will have group variable value in it */
                length, /* Record length in seconds, must be integer */
                newSamplingRate,
                true);

            log = new LogFile(dlg.FileName + ".log.xml");
            bigBuff = new float[BDF.NumberOfChannels - 1, newRecordLength];   //have to dimension to old channels rather than new
                                                                                //in case we need for reference calculations later
            /***** Create BDF header record *****/
            BDFWriter.LocalRecordingId = BDF.LocalRecordingId;
            BDFWriter.LocalSubjectId = BDF.LocalSubjectId;
            int chan;
            for (int i = 0; i < channels.Count; i++)
            {
                chan = channels[i];
                BDFWriter.channelLabel(i, BDF.channelLabel(chan));
                BDFWriter.transducer(i, BDF.transducer(chan));
                BDFWriter.dimension(i, BDF.dimension(chan));
                BDFWriter.pMax(i, BDF.pMax(chan));
                BDFWriter.pMin(i, BDF.pMin(chan));
                BDFWriter.dMax(i, BDF.dMax(chan));
                BDFWriter.dMin(i, BDF.dMin(chan));
                BDFWriter.prefilter(i, BDF.prefilter(chan));
            }
            chan = channels.Count;
            BDFWriter.channelLabel(chan, GV0.Name); //Make entries for old Status channel
            BDFWriter.transducer(chan, "None");
            BDFWriter.dimension(chan, "");
            BDFWriter.pMax(chan, 262143);
            BDFWriter.pMin(chan, -262144);
            BDFWriter.dMax(chan, 262143);
            BDFWriter.dMin(chan, -262144);
            BDFWriter.prefilter(chan, "None");

            log.registerHeader(this);

            /***** Open Event file for reading *****/
            EventFactory.Instance(eventHeader.Events); // set up the factory
            EventFileReader EventFR = new EventFileReader(
                new FileStream(Path.Combine(directory, eventHeader.EventFile), FileMode.Open, FileAccess.Read));

            BDFLoc stp = BDF.LocationFactory.New();
            BDFLoc lastEvent = BDF.LocationFactory.New();
            if (!EDE.intrinsic) //set threshold
                if (risingEdge) threshold = EDE.channelMin + (EDE.channelMax - EDE.channelMin) * threshold;
                else threshold = EDE.channelMax - (EDE.channelMax - EDE.channelMin) * threshold;

            nominalT = BDF.LocationFactory.New(); //nominal Event time based on Event.Time
            actualT = BDF.LocationFactory.New(); //actual Event time in Status channel
            //Note: these should be the same if the two clocks run the same rate (DAQ and computer)
            /***** MAIN LOOP *****/
            foreach (InputEvent ie in EventFR) //Loop through Event file
            {
                bw.ReportProgress(0, "Processing event " + ie.Index.ToString("0")); //Report progress

                if (ie.Name == EDE.Name) // Event match found in Event file
                {
                    if(findEvent(ref stp, ie))
                        if (allSamps) //this is a continuous copy, not Event generated episodic conversion
                        {
                            runBDFtoEvent(lastEvent, ref stp, ie);
                            lastEvent = BDF.LocationFactory.New();
                        }
                        else createBDFRecord(stp, ie); //Create BDF recordset around this point; i.e. Event generated episodic conversion
                }
            }
            if (allSamps) //copy out to end of file
            {
                stp.Rec = BDF.NumberOfRecords;
                stp.Pt = 0;
                runBDFtoEvent(lastEvent, ref stp, null);
            }
            e.Result = new int[] { BDFWriter.NumberOfRecords, BDFWriter.NumberOfRecords };
            BDFWriter.Close();
            EventFR.Close();
            log.Close();
        }
Пример #2
0
        public void Execute(object sender, DoWorkEventArgs e)
        {
            bw = (BackgroundWorker)sender;

            bw.ReportProgress(0, "Starting FMConverter");
            CCIUtilities.Log.writeToLog("Starting FMConverter on records in " + directory);

            /***** Read electrode file *****/
            ElectrodeInputFileStream etrFile = new ElectrodeInputFileStream(
                new FileStream(Path.Combine(directory, eventHeader.ElectrodeFile), FileMode.Open, FileAccess.Read));

            /***** Open FILMAN file *****/
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Title = "Save as FILMAN file ...";
            dlg.AddExtension = true;
            dlg.DefaultExt = ".fmn"; // Default file extension
            dlg.Filter = "FILMAN Files (.fmn)|*.fmn"; // Filter files by extension
            dlg.FileName=Path.GetFileNameWithoutExtension(eventHeader.BDFFile);
            Nullable<bool> result = dlg.ShowDialog();
            if (result == null || !(bool)result)
            {
                e.Result = new int[] { 0, 0 };
                return;
            }
            samplingRate = BDF.NSamp / BDF.RecordDuration;
            offsetInPts = Convert.ToInt32(offset * samplingRate);
            newRecordLength = Convert.ToInt32(Math.Ceiling(length * samplingRate / (float)decimation));

            FMStream = new FILMANOutputStream(
                File.Open(dlg.FileName, FileMode.Create, FileAccess.ReadWrite),
                GV.Count + 2, EDE.ancillarySize, channels.Count,
                newRecordLength,
                FILMANFileStream.FILMANFileStream.Format.Real);
            log = new LogFile(dlg.FileName + ".log.xml");
            FMStream.IS = Convert.ToInt32( (double)samplingRate/(double)decimation);
            bigBuff = new float[BDF.NumberOfChannels - 1, FMStream.ND]; //have to dimension to BDF rather than FMStream
                                                                        //in case we need for reference calculations

            /***** Create FILMAN header records *****/
            FMStream.GVNames(0, "Channel");
            FMStream.GVNames(1, "Montage");
            int i = 2;
            foreach (GVEntry gv in GV) FMStream.GVNames(i++, gv.Name); //generate group variable names

            for (i = 0; i < FMStream.NC; i++) //generate channel labels
            {
                string s = BDF.channelLabel(channels[i]);
                ElectrodeFileStream.ElectrodeRecord p;
                if (etrFile.etrPositions.TryGetValue(s, out p))   //add electrode location information, if available
                    FMStream.ChannelNames(i, s.PadRight(16, ' ') + p.projectPhiTheta().ToString("0"));
                else
                    FMStream.ChannelNames(i, s);
            }

            FMStream.Description(0, eventHeader.Title + " Date: " + eventHeader.Date + " " + eventHeader.Time);

            FMStream.Description(1, "File: " + Path.Combine(directory, Path.GetFileNameWithoutExtension(eventHeader.BDFFile)));

            StringBuilder sb = new StringBuilder("Subject: " + eventHeader.Subject.ToString());
            if (eventHeader.Agent != 0) sb.Append(" Agent: " + eventHeader.Agent);
            sb.Append(" Tech:");
            foreach (string s in eventHeader.Technician) sb.Append(" "  + s);
            FMStream.Description(2, sb.ToString());

            sb = new StringBuilder("Event="+EDE.Name);
            sb.Append(" Offset=" + offset.ToString("0.00"));
            sb.Append(" Length=" + length.ToString("0.00"));
            if (referenceGroups == null || referenceGroups.Count == 0) sb.Append(" No reference");
            else if (referenceGroups.Count == 1)
            {
                sb.Append(" Single ref group with");
                if (referenceGroups[0].Count >= FMStream.NC)
                    if (referenceChannels[0].Count == BDF.NumberOfChannels) sb.Append(" common average ref");
                    else if (referenceChannels[0].Count == 1)
                        sb.Append(" ref channel " + referenceChannels[0][0].ToString("0") + "=" + BDF.channelLabel(referenceChannels[0][0]));
                    else sb.Append(" multiple ref channels=" + referenceChannels[0].Count.ToString("0"));
            }
            else // complex reference expression
            {
                sb.Append(" Multiple reference groups=" + referenceGroups.Count.ToString("0"));
            }
            FMStream.Description(3, sb.ToString());

            sb = new StringBuilder("#Group vars=" + GV.Count.ToString("0"));
            if (anc) sb.Append(" Ancillary=" + FMStream.NA.ToString("0"));
            sb.Append(" #Channels=" + FMStream.NC.ToString("0"));
            sb.Append(" #Samples=" + FMStream.ND.ToString("0"));
            sb.Append(" Samp rate=" + FMStream.IS.ToString("0"));
            FMStream.Description(4, sb.ToString());

            FMStream.Description(5, BDF.LocalRecordingId);

            FMStream.writeHeader();

            log.registerHeader(this);

            /***** Open Event file for reading *****/
            EventFactory.Instance(eventHeader.Events); // set up the factory
            EventFileReader EventFR = new EventFileReader(
                new FileStream(Path.Combine(directory, eventHeader.EventFile), FileMode.Open, FileAccess.Read));

            BDFLoc stp = BDF.LocationFactory.New();
            if (!EDE.intrinsic)
                if (risingEdge) threshold = EDE.channelMin + (EDE.channelMax - EDE.channelMin) * threshold;
                else threshold = EDE.channelMax - (EDE.channelMax - EDE.channelMin) * threshold;

            nominalT = BDF.LocationFactory.New(); //nominal Event time based on Event.Time
            actualT = BDF.LocationFactory.New(); //actual Event time in Status channel
            //Note: these should be the same if the two clocks run the same rate (BioSemi DAQ and computer)
            /***** MAIN LOOP *****/
            foreach (InputEvent ie in EventFR) //Loop through Event file
            {
                bw.ReportProgress(0, "Processing event " + ie.Index.ToString("0")); //Report progress

                if (ie.Name == EDE.Name) // Event match found in Event file
                {
                    if (findEvent(ref stp, ie))
                        createFILMANRecord(stp, ie); //Create FILMAN recordset around this found point
                }
            }
            e.Result = new int[] { FMStream.NR, FMStream.NR / FMStream.NC };
            FMStream.Close();
            EventFR.Close();
            log.Close();
        }