Пример #1
0
        } //End redrawChannels

        void markChannelRegions(ChannelCanvas cc)
        {
            cc.offScaleRegions.Children.Clear();
            cc.offScaleRegions.Height = ChannelCanvas.nominalCanvasHeight;

            double upperThr = ChannelCanvas.ChannelYScale / 2D;
            double lowerThr = -upperThr;
            bool InBadRegion = false;
            double rectLeft = 0;
            foreach (PointListPoint pt in cc.PointList)
            {
                if (pt.Y > upperThr || pt.Y < lowerThr)
                {
                    if (!InBadRegion) //start new region
                    {
                        InBadRegion = true;
                        rectLeft = pt.X;
                    }
                }
                else
                    if (InBadRegion) //end current region
                    {
                        addNewCCRect(cc, rectLeft, pt.X);
                        InBadRegion = false;
                    }
            }

            Canvas.SetTop(cc.offScaleRegions, currentChannelLocation(cc._channel) * ChannelCanvas.nominalCanvasHeight);
            cc.offScaleRegions.Visibility = Visibility.Visible;
        }
Пример #2
0
 void addNewCCRect(ChannelCanvas cc, double left, double right)
 {
     if (left >= right) return; //can't mark single value -- unlikely to occur
     Rectangle r = new Rectangle();
     r.Opacity = 0.4;
     r.Fill = Brushes.Green;
     r.Width = right - left;
     r.Height = ChannelCanvas.nominalCanvasHeight;
     Canvas.SetTop(r, 0);
     Canvas.SetLeft(r, left);
     cc.offScaleRegions.Children.Add(r);
 }
Пример #3
0
        public MainWindow()
        {
            bool r;
            do //first get HDR file and open BDF file
            {
                OpenFileDialog dlg = new OpenFileDialog();
                dlg.Title = "Open Header of dataset to be edited...";
                dlg.DefaultExt = ".hdr"; // Default file extension
                dlg.Filter = "HDR Files (.hdr)|*.hdr"; // Filter files by extension
                Nullable<bool> result = dlg.ShowDialog();
                if (result == null || result == false) Environment.Exit(0); 

                directory = System.IO.Path.GetDirectoryName(dlg.FileName); //will use to find other files in dataset
                headerFileName = System.IO.Path.GetFileNameWithoutExtension(dlg.FileName);

                header = (new HeaderFileReader(dlg.OpenFile())).read();
                updateFlag = header.Events.ContainsKey("**ArtifactBegin"); //indicates that we are editing a dataset that has already been edited for artifacts

                bdf = new BDFEDFFileReader(new FileStream(System.IO.Path.Combine(directory, header.BDFFile),
                        FileMode.Open, FileAccess.Read));

                //make list of candidate EEG channels, so that channel selection window can use it
                BDFLength = (double)bdf.NumberOfRecords * bdf.RecordDuration;
                string trans = bdf.transducer(0); //here we assumne that channel 0 is an EEG channel
                for (int i = 0; i < bdf.NumberOfChannels - 1; i++) //exclude Status channel
                    if (bdf.transducer(i) == trans) EEGChannels.Add(i);

                Window1 w = new Window1(this); //open channel selection and file approval window
                r = (bool)w.ShowDialog();

            } while (r == false);

            InitializeComponent();

            Log.writeToLog("Starting EEGArtifactEditor " + Assembly.GetExecutingAssembly().GetName().Version.ToString() +
                " on dataset " + headerFileName);
            ViewerGrid.Width = BDFLength;

            try
            {
                //process Events in current dataset; we have to do this now in case this is an update situation, but don't have to when we finish
                Event.EventFactory.Instance(header.Events); // set up the factory, based on this Event dictionary
                //and read them in
                EventFileReader efr = new EventFileReader(
                    new FileStream(System.IO.Path.Combine(directory, header.EventFile),
                        FileMode.Open, FileAccess.Read)); // open Event file

                foreach (InputEvent ie in efr)// read in all Events into list
                    events.Add(new OutputEvent(ie));
                efr.Close(); //now events is list of Events in the dataset

                //now set zeroTime for this BDF file, after finding an appropriate (non-"naked") Event
                bool ok = false;
                foreach (OutputEvent ev in events)
                    if (header.Events[ev.Name].IsCovered)
                    {
                        bdf.setZeroTime(ev);
                        ok = true;
                        break;
                    }
                if (!ok)
                {
                    ErrorWindow ew = new ErrorWindow();
                    ew.Message = "Unable to find a covered Event in this dataset on which to synchronize clocks. Exiting.";
                    ew.ShowDialog();
                    Log.writeToLog("Unable to synchronize clocks.");
                    this.Close();
                }

                if (updateFlag) //re-editing this dataset for artifacts
                {
                    Event.EventFactory.Instance(header.Events); // set up the factory, based on this Event dictionary
                    //and read them in
                    OutputEvent ev;
                    int i = 0;
                    double left;
                    while (i < events.Count)
                    {
                        ev = events[i];
                        if (ev.Name == "**ArtifactBegin")
                        {
                            left = bdf.timeFromBeginningOfFileTo(ev);
                            events.Remove(ev);
                            while (i < events.Count)
                            {
                                ev = events[i];
                                if (ev.Name == "**ArtifactEnd")
                                {
                                    MarkerCanvas.createMarkRegion(left, bdf.timeFromBeginningOfFileTo(ev));
                                    events.Remove(ev);
                                    break;
                                }
                                if (ev.Name == "**ArtifactBegin")
                                    throw (new Exception("Unmatched artifact Event in Event file " +
                                        System.IO.Path.Combine(directory, header.EventFile)));
                                i++;
                            }
                        }
                        else
                            i++;
                    }
                }

                //initialize the individual channel canvases

                foreach (int chan in selectedEEGChannels)
                {
                    ChannelCanvas cc = new ChannelCanvas(this, chan);
                    currentChannelList.Add(cc);
                    ViewerCanvas.Children.Add(cc);
                    ViewerCanvas.Children.Add(cc.offScaleRegions);
                }


                Title = headerFileName; //set window title
                BDFFileInfo.Content = bdf.ToString();
                HDRFileInfo.Content = header.ToString();

                ElectrodeInputFileStream eif = new ElectrodeInputFileStream(
                    new FileStream(System.IO.Path.Combine(directory, header.ElectrodeFile),
                        FileMode.Open, FileAccess.Read)); //open Electrode file
                electrodes = eif.etrPositions;

                //initialize vertical gridline array; never more than 18
                for (int i = 0; i < 18; i++)
                {
                    Line l = new Line();
                    Grid.SetRow(l, 0);
                    Grid.SetColumn(l, 0);
                    l.Y1 = 0D;
                    l.HorizontalAlignment = HorizontalAlignment.Left;
                    l.VerticalAlignment = VerticalAlignment.Stretch;
                    l.IsHitTestVisible = false;
                    l.Stroke = Brushes.LightBlue;
                    l.Visibility = Visibility.Hidden;
                    Panel.SetZIndex(l, int.MaxValue);
                    VerticalGrid.Children.Add(l);
                    gridlines[i] = l;
                }

                //Initialize timer
                timer.AutoReset = true;
                timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);

                //Initialize channel information popup
                Color c1 = Color.FromArgb(0xFF, 0xF8, 0xF8, 0xF8);
                Color c2 = Color.FromArgb(0xFF, 0xC8, 0xC8, 0xC8);
                popupTB.Background = new LinearGradientBrush(c1, c2, 45D);
                popupTB.Foreground = Brushes.Black;
                popupTB.Padding = new Thickness(4D);
                Border b = new Border();
                b.BorderThickness = new Thickness(1);
                b.CornerRadius = new CornerRadius(4);
                b.BorderBrush = Brushes.Tomato;
                b.Margin = new Thickness(0, 0, 24, 24); //allows drop shadow to show up
                b.Effect = new DropShadowEffect();
                b.Child = popupTB;
                channelPopup.Placement = PlacementMode.MousePoint;
                channelPopup.AllowsTransparency = true;
                channelPopup.Child = b;

                //Initialize FOV slider
                FOV.Maximum = Math.Log10(BDFLength);
                FOV.Value = 1D;
                FOVMax.Text = BDFLength.ToString("0");

                //Note file always uses the "main" orginal dataset name, which should be the BDFFile name; this keeps notes from all levels of
                //processing in the same place
                noteFilePath = System.IO.Path.Combine(directory, System.IO.Path.GetFileNameWithoutExtension(header.BDFFile) + ".notes.txt");
            }
            catch (Exception ex)
            {
                ErrorWindow ew = new ErrorWindow();
                ew.Message = "Error in EEGArtifactEditor initialization" + ex.Message;
                ew.ShowDialog();
                this.Close(); //exit
            }

            //from here on the program is GUI-event driven
        }