public GVSectionViewModel(NavigationController controller, LegSectionViewModel prev, int number) : base(controller, prev)
 {
     ListNumber      = number;
     StructureSource = new ObservableCollection <LegPartDbStructure>(Data.GV.LevelStructures(number).ToList());
     foreach (var structure in StructureSource)
     {
         structure.Metrics = Data.Metrics.GetStr(structure.Size);
     }
     AddCustomObject(typeof(GVStructure));
     AddNextPartObject(typeof(GVStructure));
     AddEmpty(typeof(GVStructure));
     CurrentEntry = new GVEntry();
 }
Exemplo n.º 2
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();
        }
Exemplo n.º 3
0
 /// <summary>
 /// Add a new GV to the Header or return previously entered one
 /// </summary>
 /// <param name="name">Name of the GV</param>
 /// <param name="description">Description of the GV</param>
 /// <param name="valueName"></param>
 /// <param name="val"></param>
 /// <returns></returns>
 public GVEntry AddOrGetGroupVar(string name, string description = "", string[] valueName = null, int[] val = null)
 {
     if (!GroupVars.ContainsKey(name))
     {
         GVEntry gve = new GVEntry();
         gve.Description = description;
         if (valueName != null && valueName.Length > 0)
         {
             gve.GVValueDictionary = new Dictionary<string, int>(valueName.Length);
             for (int i = 0; i < valueName.Length; i++)
                 gve.GVValueDictionary.Add(valueName[i], val == null ? i + 1 : val[i]);
         }
         GroupVars.Add(name, gve);
         return gve;
     }
     else
         return GroupVars[name];
 }
Exemplo n.º 4
0
        public Header.Header read()
        {
            Header.Header header = new Header.Header();
            try
            {
                xr.ReadStartElement("ExperimentDescription", nameSpace);
                xr.ReadStartElement("SoftwareVersion", nameSpace);
                header.SoftwareVersion = xr.ReadContentAsString();
                xr.ReadEndElement(/* SoftwareVersion */);
                xr.ReadStartElement("Title", nameSpace);
                header.Title = xr.ReadContentAsString();
                xr.ReadEndElement(/* Title */);
                xr.ReadStartElement("LongDescription", nameSpace);
                header.LongDescription = xr.ReadContentAsString();
                xr.ReadEndElement(/* LongDescription */);

                header.Experimenter = new List<string>();
                while (xr.Name == "Experimenter")
                {
                    xr.ReadStartElement(/* Experimenter */);
                    header.Experimenter.Add(xr.ReadContentAsString());
                    xr.ReadEndElement(/* Experimenter */);
                }
                xr.ReadStartElement("Status", nameSpace);
                header.Status = xr.ReadContentAsInt();
                xr.ReadEndElement(/* Status */);

                if (xr.Name == "Other")
                {
                    header.OtherExperimentInfo = new Dictionary<string, string>();
                    do
                    {
                        string name = xr["Name"];
                        xr.ReadStartElement(/* Other */);
                        string value = xr.ReadContentAsString();
                        header.OtherExperimentInfo.Add(name, value);
                        xr.ReadEndElement(/* Other */);
                    } while (xr.Name == "Other");
                }

                if (xr.Name == "GroupVar")
                {
                    header.GroupVars = new GroupVarDictionary.GroupVarDictionary();
                    do {
                        xr.ReadStartElement(/* GroupVar */);
                        GroupVarDictionary.GVEntry gve = new GVEntry();
                        xr.ReadStartElement("Name", nameSpace);
                        string name = xr.ReadContentAsString();
                        if (name.Length > 24)
                            throw new Exception("name too long for GV " + name);
                        xr.ReadEndElement(/* Name */);
                        xr.ReadStartElement("Description", nameSpace);
                        gve.Description = xr.ReadContentAsString();
                        xr.ReadEndElement(/* Description */);
                        if (xr.Name == "GV")
                        {
                            gve.GVValueDictionary = new Dictionary<string, int>();
                            do
                            {
                                string key = xr["Desc", nameSpace];
                                xr.ReadStartElement(/* GV */);
                                int val = xr.ReadContentAsInt();
                                if (val > 0)
                                    gve.GVValueDictionary.Add(key, val);
                                else
                                    throw new Exception("invalid value for GV "+ name);
                                xr.ReadEndElement(/* GV */);
                            }
                            while (xr.Name == "GV");
                        }
                        header.GroupVars.Add(name, gve);
                        xr.ReadEndElement(/* GroupVar */);
                    } while (xr.Name == "GroupVar");
                }

                if (xr.Name == "Event")
                {
                    header.Events = new EventDictionary.EventDictionary(header.Status);
                    do {
                        EventDictionaryEntry ede = new EventDictionaryEntry();
                        if (xr.MoveToAttribute("Type"))
                        {
                            string s = xr.ReadContentAsString();
                            if (s == "*")
                                ede.intrinsic = null;
                            else
                                ede.intrinsic = s != "extrinsic";
                        } //else Type is intrinsic by default
                        if (xr.MoveToAttribute("Clock")) //is there a Clock attribute?
                        {
                            string s = xr.ReadContentAsString();
                            if (s == "Absolute")
                                ede.BDFBased = false;
                            else if (s == "BDF-based")
                            {
                                if (ede.IsCovered) throw new Exception("Incompatible Type and Clock attributes in Event");
                                ede.BDFBased = true;
                            }
                            else throw new Exception("Invalid Clock attribute in Event");
                        } //else clock is Absolute by default
                        xr.ReadStartElement(/* Event */);
                        xr.ReadStartElement("Name", nameSpace);
                        string name = xr.ReadContentAsString();
                        xr.ReadEndElement(/* Event */);
                        xr.ReadStartElement("Description", nameSpace);
                        ede.Description = xr.ReadContentAsString();
                        xr.ReadEndElement(/* Description */);
                        if (ede.IsCovered && !(bool)ede.intrinsic)
                        {
                            xr.ReadStartElement("Channel", nameSpace);
                            ede.channelName = xr.ReadContentAsString();
                            xr.ReadEndElement(/* Channel */);
                            xr.ReadStartElement("Edge", nameSpace);
                            ede.rise = xr.ReadContentAsString() == "rising";
                            xr.ReadEndElement(/* Edge */);
                            ede.location = (xr.Name == "Location" ? (xr.ReadElementContentAsString() == "after") : false); //leads by default
                            ede.channelMax = xr.Name == "Max" ? xr.ReadElementContentAsDouble() : 0D; //zero by default
                            ede.channelMin = xr.Name == "Min" ? xr.ReadElementContentAsDouble() : 0D; //zero by default
                            if (ede.channelMax < ede.channelMin)
                                throw new Exception("invalid max/min signal values in extrinsic Event " + name);
                            //Note: Max and Min are optional; if neither is specified, 0.0 will always be used as threshold
                        }
                        if (xr.Name == "Ancillary")
                        {
                            xr.ReadStartElement(/* Ancillary */);
                            ede.ancillarySize = xr.ReadContentAsInt();
                            xr.ReadEndElement(/* Ancillary */);
                        }
                        if (xr.Name == "GroupVar")
                        {
                            ede.GroupVars = new List<GVEntry>();
                            do {
                                string gvName = xr["Name", nameSpace];
                                bool isEmpty = xr.IsEmptyElement;
                                xr.ReadStartElement(/* GroupVar */);
                                GVEntry gve;
                                if (header.GroupVars.TryGetValue(gvName, out gve))
                                    ede.GroupVars.Add(gve);
                                else throw new Exception("invalid GroupVar " + gvName + " in Event " + name);
                                if(!isEmpty) xr.ReadEndElement(/* GroupVar */);
                            } while (xr.Name == "GroupVar");
                        }
                        header.Events.Add(name, ede);
                        xr.ReadEndElement(/* Event */);
                    } while (xr.Name == "Event");
                }
                xr.ReadEndElement(/* ExperimentDescription */);
                xr.ReadStartElement("SessionDescription", nameSpace);
                xr.ReadStartElement("Date", nameSpace);
                header.Date = xr.ReadContentAsString();
                xr.ReadEndElement(/* Date */);
                xr.ReadStartElement("Time", nameSpace);
                header.Time = xr.ReadContentAsString();
                xr.ReadEndElement(/* Time */);
                xr.ReadStartElement("Subject", nameSpace);
                header.Subject = xr.ReadContentAsInt();
                xr.ReadEndElement(/* Subject */);
                if (xr.Name == "Agent")
                {
                    xr.ReadStartElement(/* Agent */);
                    header.Agent = xr.ReadContentAsInt();
                    xr.ReadEndElement(/* Agent */);
                }
                header.Technician = new List<string>();
                while (xr.Name == "Technician")
                {
                    xr.ReadStartElement(/* Technician */);
                    header.Technician.Add(xr.ReadContentAsString());
                    xr.ReadEndElement(/* Technician */);
                }
                if (xr.Name == "Other") {
                    header.OtherSessionInfo = new Dictionary<string, string>();
                    do
                    {
                        string name = xr["Name"];
                        xr.ReadStartElement(/* Other */);
                        string value = xr.ReadContentAsString();
                        xr.ReadEndElement(/* Other */);
                        header.OtherSessionInfo.Add(name, value);
                    } while (xr.Name == "Other");
                }
                xr.ReadStartElement("BDFFile", nameSpace);
                header.BDFFile = xr.ReadContentAsString();
                xr.ReadEndElement(/* BDFFile */);
                xr.ReadStartElement("EventFile", nameSpace);
                header.EventFile = xr.ReadContentAsString();
                xr.ReadEndElement(/* EventFile */);
                xr.ReadStartElement("ElectrodeFile", nameSpace);
                header.ElectrodeFile = xr.ReadContentAsString();
                xr.ReadEndElement(/* ElectrodeFile */);
                if (xr.Name == "Comment")
                {
                    xr.ReadStartElement(/* Comment */);
                    header.Comment = xr.ReadContentAsString(); //Optional comment
                    xr.ReadEndElement(/* Comment */);
                }
                xr.ReadEndElement(/* SessionDescription */);
                return header;
            }
            catch (Exception e)
            {
                XmlNodeType nodeType = xr.NodeType;
                string name = xr.Name;
                throw new Exception("HeaderFileReader.read: Error processing " + nodeType.ToString() +
                    " named " + name + ": " + e.Message);
            }
        }
Exemplo n.º 5
0
        //Process the PK events found: returns true if files succesfully written
        private bool ProcessEvents()
        {
            //GV 1
            if (!head.GroupVars.ContainsKey("Source channel"))
            {
                GVEntry gve = new GVEntry();
                gve.GVValueDictionary = new Dictionary<string, int>();
                gve.Description = "Source channel for this Event";
                foreach (ChannelItem ci in ChannelEntries.Items)
                {   //create GV Value entry for each channel name
                    channelOptions co = channels[ci.Channel.SelectedIndex];
                    int i;
                    gve.GVValueDictionary.TryGetValue(co.name, out i);
                    if (i == 0)
                        gve.GVValueDictionary.Add(co.name, co.channel + 1); //Use "external" (1-based) channel numbering
                }
                head.GroupVars.Add("Source channel", gve); //Channel name: add to GV list in HDR
                newGVList[0] = gve;
            }
            else
                newGVList[0] = head.GroupVars["Source channel"];

            //GV 2
            newGVList[1] = head.AddOrGetGroupVar("Found fit", "Found satisfactory fit to PK signal",
                new string[] { "Found", "Not found" });

            //GV 3
                newGVList[2] = head.AddOrGetGroupVar("Magnitude",
                    "Estimate of the magnitude of PK signal in scale of channel");

            //GV 4
                newGVList[3] = head.AddOrGetGroupVar("Direction", "Direction of PK signal",
                    new string[] { "Positive", "Negative" });

            //GV 5
                newGVList[4] = head.AddOrGetGroupVar("Alpha TC",
                    "Estimate of the time constant (in millisecs) for the rising edge of the PK signal");

            //GV 6
                newGVList[5] = head.AddOrGetGroupVar("Chi square",
                    "Chi square estimate of goodness of fit to the PK signal");

            //GV 7
                newGVList[6] = head.AddOrGetGroupVar("Serial number",
                    "Serial number for this channel/filter combination");

            //GV 8
                newGVList[7] = head.AddOrGetGroupVar("Trend degree",
                    "Degree of trend removal of original PK signal plus 2");

            //GV 9
                newGVList[8] = head.AddOrGetGroupVar("Filter length", "Length of filter in points");

            //GV 10
                newGVList[9] = head.AddOrGetGroupVar("Threshold", "Capturing threshold in microV/sec");

            //GV 11
                newGVList[10] = head.AddOrGetGroupVar("Minimum length",
                    "Minimum length of above-threshold filter signal in points");

            //Create Event Dictionary entry for each new PK event/ChannelItem
            foreach (ChannelItem ci in ChannelEntries.Items)
            {
                EventDictionaryEntry ede = head.AddNewEvent(ci.ImpliedEventName,
                    "PK detector events from PKDetectorAnalyzer based on channel " + ci.Channel.Text, newGVList);
                ede.BDFBased = true; //naked Event with clock BDF-based
            }

            head.Comment += (head.Comment == "" ? "" : Environment.NewLine) +
                "PK source Events added on " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss") + " by " + Environment.UserName;

            //Now read old Event file
            events = new List<Event.OutputEvent>();
            Event.EventFactory.Instance(head.Events); // set up Event factory, based on EventDictionary in HDR
            EventFileReader efr = new EventFileReader(
                new FileStream(System.IO.Path.Combine(directory, head.EventFile),
                    FileMode.Open, FileAccess.Read)); // open Event file

            bool zeroSet = false;
            foreach (Event.InputEvent ie in efr) // read in all Events into dictionary
            {
                events.Add(new Event.OutputEvent(ie)); //make list of all current Events
                if (!zeroSet && ie.IsCovered) //set zeroTime based on first encounter covered Event
                {
                    bdf.setZeroTime(ie);
                    zeroSet = true;
                }
            }

            efr.Close();

            //write out new HDR file
            FileStream fs = null;
            bool OK = false;
            while (!OK)
            {
                try
                {
                    head.EventFile = newFileName + ".evt"; //now we can change Event file name and write out new HDR
                    fs = new FileStream(System.IO.Path.Combine(directory, newFileName + ".hdr"), FileMode.CreateNew, FileAccess.Write);
                    OK = true;
                }
                catch (IOException) //force only a new
                {
                    Replace_dataset rd = new Replace_dataset(newFileName, this.FNExtension.Text);
                    rd.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                    rd.Owner = this;
                    rd.ShowDialog();
                    if (rd.Result > 0)
                    {
                        if (rd.Result == 3) //Exit
                        {
                            Status.Text = "Cancelled writing new dataset";
                            return false;
                        }
                        if (rd.Result == 1) //Yes
                        {
                            OK = true;
                            fs = new FileStream(System.IO.Path.Combine(directory, newFileName + ".hdr"), FileMode.Create, FileAccess.Write);
                        }
                        else //N0: new extension, try again
                        {
                            this.FNExtension.Text = rd.NewExtension.Text; //this will also change newFileName
                        }
                    }
                }
            }
            new HeaderFileWriter(fs, head);

            foreach (eventTime et in eventTimeList)
            {
                double ST =  bdf.SampleTime(et.channelNumber);
                //create a naked Event at this time
                Event.OutputEvent newEvent = new Event.OutputEvent(head.Events[et.channelItem.ImpliedEventName], (double)(et.t0 + et.startTime) * ST);
                //assign GV values to new event
                newEvent.GVValue = new string[11];
                newEvent.GVValue[0] = bdf.channelLabel(et.channelNumber);
                newEvent.GVValue[1] = et.foundFit ? "Found" : "Not found";
                newEvent.GVValue[2] = ((int)Math.Abs(et.A)).ToString("0");
                newEvent.GVValue[3] = et.sign > 0 ? "Positive" : "Negative";
                newEvent.GVValue[4] = ((int)(1000D / et.a)).ToString("0");
                if (et.chiSquare < 2E9)
                    newEvent.GVValue[5] = ((int)et.chiSquare).ToString("0");
                else
                    newEvent.GVValue[5] = "0";
                newEvent.GVValue[6] = et.serialNumber.ToString("0");
                newEvent.GVValue[7] = (et.trendDegree + 2).ToString("0");
                newEvent.GVValue[8] = et.filterLength.ToString("0");
                newEvent.GVValue[9] = ((int)(et.threshold / ST)).ToString("0");
                newEvent.GVValue[10] = et.minimumLength.ToString("0");
                events.Add(newEvent);
            }

            events = events.OrderBy(ev => bdf.timeFromBeginningOfFileTo(ev)).ToList(); //sort Events into time order

            fs = new FileStream(System.IO.Path.Combine(directory,head.EventFile), FileMode.Create, FileAccess.Write);
            EventFileWriter efw = new EventFileWriter(fs);
            foreach (Event.OutputEvent ev in events)
                efw.writeRecord(ev);
            efw.Close();
            lf.Close(); //close out log file
            //and copy out to file
            logStream.WriteTo(new FileStream(System.IO.Path.Combine(directory, newFileName + ".pkda.log.xml"), FileMode.Create, FileAccess.Write));
            return true;
        }