Пример #1
0
 public void registerError(string message, InputEvent ie)
 {
     logStream.WriteStartElement("Error");
     logStream.WriteAttributeString("Index", ie.Index.ToString("0"));
     logStream.WriteValue(message);
     logStream.WriteEndElement(/*Error*/);
 }
Пример #2
0
 public void registerEpochSet(double epoch, InputEvent ie)
 {
     logStream.WriteStartElement("EpochSet");
     logStream.WriteAttributeString("EventIndex", ie.Index.ToString("0"));
     logStream.WriteValue(epoch.ToString("00000000000.0000000"));
     logStream.WriteEndElement(/*EpochSet*/);
 }
Пример #3
0
 /// <summary>
 /// Calculates the time of start of file (record 0, point 0) based on the InputEvent.
 /// After this, value may be accessed via property <code>zeroTime</code>
 /// </summary>
 /// <param name="IE">InputEvent to use as index</param>
 /// <returns>True if GC found, false if not</returns>
 public bool setZeroTime(InputEvent IE)
 {
     int[] statusBuffer = new int[NSamp];
     int rec = 0;
     uint mask = 0xFFFFFFFF >> (32 - EventFactory.Instance().statusBits);
     while (this.read(rec++) != null)
     {
         statusBuffer = getStatus();
         for (int i = 0; i < NSamp; i++)
             if ((mask & statusBuffer[i]) == IE.GC)
             {
                 _zeroTime = IE.Time - this.RecordDuration * (--rec + (double)i / NSamp);
                 return true;
             }
     }
     return false;
 }
Пример #4
0
        private bool findNextMark(EpisodeMark eventCriterium, IEnumerator<InputEvent> Events, bool startEvent, out double time, out InputEvent ie)
        {
            if (eventCriterium._Event.GetType() == typeof(string)) //handle special cases first
            {
                string str = (string)eventCriterium._Event;
                if (str == "Beginning of file") //may occur as start- or endEvent
                {
                    time = 0D;
                    ie = null; //only one with no additional GVs possible
                    return true;
                }
                else if (str == "Same Event") //only occurs as endEvent
                { //will only be called if there has been a previous match
                    ie = Events.Current;
                    time = Events.Current.relativeTime;
                    sameEventFlag = true;
                    return true;
                }
            } //end special cases

            time = -1D; //default returns
            ie = null;

            bool more = true;
            //this allows a start Event to match the previously matched Event except in case of Same Event
            if (!startEvent || Events.Current == null || sameEventFlag)
                more = Events.MoveNext();
            sameEventFlag = false;

            while(more) // loop through Events beginning at .Current to find one meeting eventCriterium
            {
                ie = Events.Current;
                if (eventCriterium._Event.GetType() == typeof(EventDictionaryEntry)) //if named Event, simply check it
                {
                    if (eventCriterium.Match(ie)) //found matching Event
                    {
                        time = Events.Current.relativeTime;
                        return true;
                    }
                }
                else //anonymous Event
                {
                    string str = eventCriterium.EventName();
                    if (str == "Any Event" || str.Substring(11) == "(all)" || ie.EDE.IsCovered) //make sure Any Event or
                        if (eventCriterium.MatchGV(ie))
                        {
                            time = Events.Current.relativeTime;
                            return true;
                        }
                }
                more = Events.MoveNext(); //move on to next Event
            } //while loop
            if (!startEvent) //if endEvent time is end of BDF file
                time = bdf.RecordDurationDouble * bdf.NumberOfRecords;
            return false;
        }
Пример #5
0
 /// <summary>
 /// Copy constructor converting an InputEvent to OutputEvent to permit copying
 /// of Event file entries to create a new Event file
 /// </summary>
 /// <param name="ie">InputEvent to be copied</param>
 public OutputEvent(InputEvent ie)
     : base(ie.EDE)
 {
     m_time = ie.Time;
     m_index = ie.m_index;
     m_gc = ie.m_gc;
     if (ie.GVValue != null)
     {//do a full copy to protect values
         GVValue = new string[ie.EDE.GroupVars.Count]; //go back to HDR definition
         int i = 0;
         foreach (string v in ie.GVValue)
              GVValue[i++] = v;
     }
     else
         GVValue = null;
 }
Пример #6
0
 public InputEvent CreateInputEvent(string name)
 {
     EventDictionaryEntry ede;
     if (name == null || !ed.TryGetValue(name, out ede))
         throw new Exception("No entry in EventDictionary for \"" + name + "\"");
     InputEvent e = new InputEvent(ede);
     return e;
 }
Пример #7
0
        private void runBDFtoEvent(BDFLoc lastEventLocation, ref BDFLoc nextEventLocation, InputEvent evt)
        {
            nextEventLocation += decimation - 1; //correct location so we know where to stop; warning: it's tricky!
            nextEventLocation.Pt /= decimation; //location should be next after actual Event to keep decimation on track
            nextEventLocation.Pt *= decimation; //this also works because decimation must be a factor of the record length
            int pt = lastEventLocation.Pt / decimation;
            int j = lastEventLocation.Pt;
            int k;
            int p = 0;
            double[] buff = new double[BDF.NumberOfChannels-1];
            double[] references = null;
            if (referenceChannels != null) references = new double[referenceChannels.Count];
            for (int rec = lastEventLocation.Rec; rec <= nextEventLocation.Rec; rec++)
            {
                if (BDF.read(rec) == null) return; // only happen on last call to fill out record
                if (rec == nextEventLocation.Rec) k = nextEventLocation.Pt;
                else k = BDF.NSamp;
                for (p = j; p < k; p += decimation, pt++)
                {
                    for (int c = 0; c < BDF.NumberOfChannels - 1; c++)
                        buff[c] = BDF.getSample(c, p);
                    if (referenceChannels != null) // then some channels need reference correction
                    {
                        //First calculate all needed references for this point
                        for (int i1 = 0; i1 < referenceChannels.Count; i1++)
                        {
                            references[i1] = 0.0D; //zero them out
                            foreach (int chan in referenceChannels[i1]) references[i1] += buff[chan]; //add them up
                            references[i1] /= (double)referenceChannels[i1].Count; //divide to get average
                        }

                        //Then, subtract them from each channel in each channel group
                        float refer;
                        for (int i1 = 0; i1 < referenceGroups.Count; i1++)
                        {
                            refer = (float)references[i1];
                            for (int i2 = 0; i2 < referenceGroups[i1].Count; i2++) buff[referenceGroups[i1][i2]] -= refer;
                        }
                    }
                    for (int c = 0; c < BDFWriter.NumberOfChannels - 1; c++)
                        BDFWriter.putSample(c, pt, (float)(buff[channels[c]]));
                    newStatus[pt] = lastStatus;
                }
                if (rec != nextEventLocation.Rec)
                {
                    BDFWriter.putStatus(newStatus);
                    BDFWriter.write();
                }
                j = 0; // OK because decimation has to be integer divisor of the sampling rate
                pt = 0; // so that these two remain in lock-step => no offset to calculate
            }

            /***** Get group variable for this record *****/
            string s = evt.GVValue[EDE.GroupVars.FindIndex(n => n.Equals(GV0))]; //Find value for this GV
            if (GV0.GVValueDictionary != null)
                lastStatus = GV0.GVValueDictionary[s]; //Lookup in GV value dictionary to convert to integer
            else
                lastStatus = Convert.ToInt32(s); //Or not; value of GV numnber representing itself
        }
Пример #8
0
        private void createBDFRecord(BDFLoc eventLocation, InputEvent evt)
        {
            BDFLoc startingPt = eventLocation + oldOffsetInPts; //calculate starting point
            if (startingPt.Rec < 0) return; //start of record outside of file coverage; so skip it
            BDFLoc endPt = startingPt + newRecordLength * decimation; //calculate ending point
            if (endPt.Rec >= BDF.NumberOfRecords) return; //end of record outside of file coverage

            /***** Read correct portion of BDF file and decimate *****/
            int pt = 0;
            int j;
            int k;
            int p = 0; //set to avoid compiler complaining about uninitialized variable!
            for (int rec = startingPt.Rec; rec <= endPt.Rec; rec++)
            {
                if (BDF.read(rec) == null) throw new Exception("Unable to read BDF record #" + rec.ToString("0"));
                if (rec == startingPt.Rec) j = startingPt.Pt;
                else j = p - BDF.NSamp; // calculate point offset at beginning of new record, taking into account left over from decimation
                if (rec == endPt.Rec) k = endPt.Pt;
                else k = BDF.NSamp;
                for (p = j; p < k; p += decimation, pt++)
                    for (int c = 0; c < BDF.NumberOfChannels - 1; c++)
                        bigBuff[c, pt] = (float)BDF.getSample(c, p);
            }

            /***** Get group variable for this record and set Status channel values *****/
            string s = evt.GVValue[EDE.GroupVars.FindIndex(n => n.Equals(GV0))]; //Find value for this GV
            newStatus[StatusMarkerType == 1 ? 0 : -newOffsetInPts] = GV0.ConvertGVValueStringToInteger(s);
            // then propagate throughout Status channel
            for (int i = (StatusMarkerType == 1 ? 1 : 1 - newOffsetInPts); i < newRecordLength; i++) newStatus[i] = newStatus[i - 1];
            BDFWriter.putStatus(newStatus);

            /***** Calculate referenced data *****/
            calculateReferencedData();

            /***** Write out record after loading appropriate data *****/
            for (int iChan = 0; iChan < BDFWriter.NumberOfChannels - 1; iChan++)
            {
                int channel = channels[iChan]; // translate channel numbers
                double ave = 0.0;
                double beta = 0.0;
                double fn = (double)newRecordLength;
                if (radinOffset) //calculate Radin offset for this channel, based on a segment of the data specified by radinLow and radinHigh
                {
                    for (int i = radinLow; i < radinHigh; i++) ave += bigBuff[channel, i];
                    ave = ave / (double)(radinHigh - radinLow);
                }
                if (removeOffsets || removeTrends) //calculate average for this channel
                {
                    for (int i = 0; i < newRecordLength; i++) ave += bigBuff[channel, i];
                    ave = ave / fn;
                }
                double t = 0D;
                if (removeTrends) //calculate linear trend for this channel; see Bloomfield p. 115
                //NOTE: this technique works only for "centered" data: if there are N points, covering NT seconds, it is assumed that
                // these points are located at (2i-N-1)T/2 seconds, for i = 1 to N; in other words, the samples are in the center of
                // each sample time and are symetrically distributed about a central zero time in the record. Then one can separately
                // calculate the mean and the slope and apply them together to remove a linear trend. This doesn't work for quadratic
                // or higher order trend removal however.
                {
                    t = (fn - 1.0D) / 2.0D;
                    fn *= fn * fn - 1D;
                    for (int i = 0; i < newRecordLength; i++) beta += bigBuff[channel, i] * ((double)i - t);
                    beta = 12.0D * beta / fn;
                }
                for (int i = 0; i < newRecordLength; i++) BDFWriter.putSample(iChan, i,
                    bigBuff[channel, i] - (float)(ave + beta * ((double)i - t)));
            }
            BDFWriter.write();
        }
Пример #9
0
        private void createFILMANRecord(BDFLoc stp, InputEvent evt)
        {
            BDFLoc startingPt = stp + offsetInPts; //calculate starting point
            if (startingPt.Rec < 0) return; //start of record outside of file coverage; so skip it
            BDFLoc endPt = startingPt + Convert.ToInt32(length * samplingRate); //calculate ending point
            if (endPt.Rec >= BDF.NumberOfRecords) return; //end of record outside of file coverage

            /***** Read correct portion of BDF file and decimate *****/
            int pt = 0;
            int j;
            int k;
            int p = 0; //set to avoid compiler complaining about uninitialized variable!
            for (int rec = startingPt.Rec; rec <= endPt.Rec; rec++)
            {
                if (BDF.read(rec) == null) throw new Exception("Unable to read BDF record #" + rec.ToString("0"));
                if (rec == startingPt.Rec) j = startingPt.Pt;
                else j = p - BDF.NSamp; // calculate point offset at beginning of new record
                if (rec == endPt.Rec) k = endPt.Pt;
                else k = BDF.NSamp;
                for (p = j; p < k; p += decimation, pt++)
                    for (int c = 0; c < BDF.NumberOfChannels - 1; c++)
                        bigBuff[c, pt] = (float)BDF.getSample(c, p);
            }

            //NOTE: after this point bigBuff containes all channels in BDF file,
            // includes all BDF records that contribute to this output record,
            // but has been decimated to include only those points that will actually be written out!!!
            // This is necessary because referencing channels may not be actually included in the recordSet.

            /***** Get group variable for this record *****/
            int GrVar = 2; //Load up group variables
            foreach (GVEntry gve in GV)
            {
                string s = evt.GVValue[EDE.GroupVars.FindIndex(n => n.Equals(gve))]; //Find value for this GV
                FMStream.record.GV[GrVar++] = gve.ConvertGVValueStringToInteger(s); //Lookup in dictionary
            }

            /***** Include any ancillary data *****/
            if (anc)
            {
                int w = 0;
                for (int i = 0; i < EDE.ancillarySize; i += 4)
                    FMStream.record.ancillary[w++] = (((evt.ancillary[i] << 8)
                        + evt.ancillary[i + 1] << 8)
                        + evt.ancillary[i + 2] << 8)
                        + evt.ancillary[i + 3]; //NOTE: does not change endian; works for little endian to little endian
            }

            /***** Update bigBuff to referenced data *****/
            calculateReferencedData();

            /***** Write out channel after loading appropriate data *****/
            for (int iChan = 0; iChan < FMStream.NC; iChan++)
            {
                int channel = channels[iChan]; // translate channel numbers
                double ave = 0.0;
                double beta = 0.0;
                double fn = (double)FMStream.ND;
                if (radinOffset) //calculate Radin offset for this channel, based on a segment of the data specified by radinLow and radinHigh
                {
                    for (int i = radinLow; i < radinHigh; i++) ave += bigBuff[channel, i];
                    ave = ave / (double)(radinHigh - radinLow);
                }
                if (removeOffsets || removeTrends) //calculate average for this channel; this will always be true if removeTrends true
                {
                    for (int i = 0; i < FMStream.ND; i++) ave += bigBuff[channel, i];
                    ave = ave / fn;
                }
                double t = 0D;
                if (removeTrends) //calculate linear trend for this channel; see Bloomfield p. 115
                //NOTE: this technique works only for "centered" data: if there are N points, covering NT seconds, it is assumed that
                // these points are located at (2i-N-1)T/2 seconds, for i = 1 to N; in other words, the samples are in the center of
                // each sample time and are symetrically distributed about a central zero time in the record. Then one can separately
                // calculate the mean and the slope and apply them together to remove a linear trend. This doesn't work for quadratic
                // or higher order trend removal however.
                {
                    t = (fn - 1.0D) / 2.0D;
                    fn *= fn * fn - 1D;
                    for (int i = 0; i < FMStream.ND; i++) beta += bigBuff[channel, i] * ((double)i - t);
                    beta = 12.0D * beta / fn;
                }
                for (int i = 0; i < FMStream.ND; i++)
                    FMStream.record[i] = (double)bigBuff[channel, i] - (ave + beta * ((double)i - t));
                FMStream.write(); //Channel number group variable taken care of here
            }
        }
Пример #10
0
        protected bool findEvent(ref BDFLoc stp, InputEvent ie)
        {
            if (!setEpoch) //First Event of this type: calculate start time (epoch) of the first point in the BDF file
            {
                if (!findEvent(ie.GC, ref stp))
                {
                    log.registerError("No Status found for Event named " + EDE.Name, ie);
                    stp.Rec = 0; stp.Pt = 0; //reset
                    return false;
                }
                nominalT.Rec = actualT.Rec = stp.Rec;
                nominalT.Pt = actualT.Pt = stp.Pt;
                epoch = ie.Time - ((double)stp.Rec + (double)stp.Pt / (double)BDF.NSamp)
                    * (double)BDF.RecordDuration;
                log.registerEpochSet(epoch, ie);
                setEpoch = true;
            }
            else //calculate Status search starting point
            {
                double t = ie.Time - epoch; //Calculate seconds from starting epoch
                nominalT.Rec = (int)(t / (double)BDF.RecordDuration); //Record number
                nominalT.Pt = (int)((t - (double)(nominalT.Rec * BDF.RecordDuration)) * (double)samplingRate); //Sample number
                if (continuousSearch)
                {
                    stp.Rec = actualT.Rec; //start at last found Event
                    stp.Pt = actualT.Pt;
                }
                else // find next Event by jumping near to it
                {
                    stp.Rec = nominalT.Rec;
                    stp.Pt = nominalT.Pt;
                    stp -= samplingRate / 16 + 1; //start 1/16sec before estimated time of the event
                }
                if (!findEvent(ie.GC, ref stp)) // find the next Status event in BDF; returns with stp set to event location
                {
                    log.registerError("Unable to locate Status for Event " + EDE.Name, ie);
                    stp.Rec = actualT.Rec; //return to last previous found Event
                    stp.Pt = actualT.Pt;
                    return false;
                }
                actualT.Rec = stp.Rec;
                actualT.Pt = stp.Pt;
            }

            if (!EDE.intrinsic)
                if (!findExtrinsicEvent(ref stp, maxSearch))
                {
                    log.registerError("No extrinsic event found for Event " + EDE.Name, ie);
                    return false;
                }
                else
                    log.registerExtrinsicEvent(nominalT, actualT, stp, ie);
            else
                log.registerIntrinsicEvent(nominalT, actualT, ie);
            return true;
        }
Пример #11
0
 public void registerExtrinsicEvent(BDFLoc nominal, BDFLoc actual, BDFLoc ext, InputEvent ie)
 {
     logStream.WriteStartElement("Event");
     logStream.WriteAttributeString("Index", ie.Index.ToString("0"));
     double t0 = actual.ToSecs();
     double nominalOffset = nominal.ToSecs() - t0;
     logStream.WriteElementString("ActualStatus", t0.ToString("0.000000"));
     logStream.WriteElementString("EventFileDiff", (nominal.ToSecs() - t0).ToString("0.000000"));
     logStream.WriteElementString("ExtrinsicEventDiff", (ext.ToSecs() - t0).ToString("0.000000"));
     logStream.WriteEndElement(/*Event*/);
     gatherStats(t0, nominalOffset);
 }
Пример #12
0
 internal bool Match(InputEvent ev)
 {
     if (ev.Name == this.EventName()) //event type matches
         return (_GV == null || this.MatchGV(ev));
     return false;
 }
Пример #13
0
 /// <summary>
 /// Convenience method that looks up the value of the correct GV in an InputEvent
 /// </summary>
 /// <param name="ev">The InputEvent to compare GV fors</param>
 /// <returns></returns>
 internal bool MatchGV(InputEvent ev)
 {
     return (_GV == null || MatchGV(ev.GetIntValueForGVName(_GV.Name)));
 }