Пример #1
0
        /*	Disable this constructor -- there is no way right now to set file path & name in
         * another way!
         *
         * /// <summary>
         * /// Minimal constructor.  Note that if you use this constructor, you must
         * /// set filePath and fileName before calling init(), otherwise an exception
         * /// will be raised.
         * /// Also loads header from file.
         * /// </summary>
         * /// <param name="secondsPerStep">Interval between samples, in seconds or fraction thereof,
         * ///					e.g. 1 KHz = 1 ms per sample would have secondsPerStep = 0.001.  If
         * ///					autoOutput is TRUE and the file header has its own sample period value,
         * ///					then this param is ignored and the value in the file header is used
         * ///					instead.</param>
         * /// <param name="autoOutput">If TRUE, then we push data out to the Followers AND try to
         * ///					use the sample period value from the file header; if FALSE, we wait
         * ///					for whoever to pull out the data.</param>
         * public FileReader ( double secondsPerStep, bool autoOutput )
         *      : base ( secondsPerStep, autoOutput )
         * {
         * }
         * //		*/

        /// <summary>
        /// Full constructor:  requires file path and file name.
        /// Also loads header from file.
        /// </summary>
        /// <param name="secondsPerStep">Interval between samples, in seconds or fraction thereof,
        ///					e.g. 1 KHz = 1 ms per sample would have secondsPerStep = 0.001.  If
        ///					autoOutput is TRUE and the file header has its own sample period value,
        ///					then this param is ignored and the value in the file header is used
        ///					instead.</param>
        /// <param name="autoOutput">If TRUE, then we push data out to the Followers AND try to
        ///					use the sample period value from the file header; if FALSE, we wait
        ///					for whoever to pull out the data.</param>
        /// <param name="filePath">Must be an existing file path, with or without trailing slash</param>
        /// <param name="fileName">Must be an existing file name</param>
        public FileReader(double secondsPerStep, bool autoOutput,
                          string filePath, string fileName)
            : base(secondsPerStep, autoOutput)
        {
            // Save values:
            fPath     = FileHandler.cleanPath(filePath);
            fName     = FileHandler.cleanFileName(fileName);
            fPathName = fPath + fName;

            // Check for existing path:
            FileHandler.validatePath(fPath);

            // Make sure file does exist:
            FileHandler.fileExists(fPathName);

            // Try opening the new file for reading:
            FileStream fs = File.OpenRead(fPathName);

            fs.Close();

            // Some inits:
            // Create the appropriate data structure:
            initValues             = new ChainInfo();
            initValues.patientInfo = new PatientInfo("", "", "");
            initValues.dataInfo    = new DataInfo();
            initValues.fileInfo    = new FileHandler();

            // Read the header from the input file:
            curReadStartPos = 0;
            readHeader();

            // Update the sampling period:
            stepSize = initValues.samplingPeriodSec;
            // Note, we now discard the header data and read it again at Init() time
        }
Пример #2
0
        /// <summary>
        /// Override default behavior to:
        /// - Save a local copy
        /// - Get file header info
        /// - Update iData accordingly
        /// - Allow using header info to drive the output rates
        /// </summary>
        public override void init(ChainInfo iData)
        {
            // Save a local handle:
            // - If we're AutoSending, we're the authority on the data, so we can override the
            //		contents of iData.  That means we point to iData and modify that.
            // - If we're not AutoSending, we can tell anyone downstream what the actual data
            //		params are, but we shouldn't mess with the original iData to avoid affecting
            //		the source.
            if (autoSend)
            {                   // Point to the input data structure:
                initValues = iData;
            }
            else
            {                   // Make our own data structure:
                initValues = new ChainInfo();
                initValues.samplingPeriodSec = iData.samplingPeriodSec;
            }

            if (autoSend && doneReading)                // We terminated the timer earlier - restart it:
            {
                // Init the TimerThread:
                sendTimer = new TimerThread(
                    new System.Threading.ThreadStart(this.next),
                    false);
            }

            // Init. what needs it:
            curReadStartPos = 0;
            doneReading     = false;
            dataFinished    = false;            // in case it was set to true previously
            if (initValues.patientInfo == null)
            {
                initValues.patientInfo = new PatientInfo("", "", "");
            }
            if (initValues.dataInfo == null)
            {
                initValues.dataInfo = new DataInfo( );
            }
            if (initValues.fileInfo == null)
            {
                initValues.fileInfo = new FileHandler( );
            }

            // Read the header from the input file:
            readHeader();

            // Init. the sampling period:
            this.stepSize = initValues.samplingPeriodSec;

            // Init output buffer:
            initBuffer();

            // Apply values and propagate downstream:
            base.init(iData);                   // iData may have been changed or not
        }
Пример #3
0
        /// <summary>
        /// Creates a duplicate copy of this object and all its data.
        /// </summary>
        /// <returns>A new ChainInfo object identical to this one</returns>
        public ChainInfo clone()
        {
            ChainInfo newData = new ChainInfo();

            newData.samplingPeriodSec = this.samplingPeriodSec;
            newData.patientInfo       = this.pInfo.clone();
            newData.dataInfo          = this.dInfo.clone();
            newData.fileInfo          = this.fInfo.clone();

            return(newData);
        }
Пример #4
0
        /// <summary>
        /// Initializes the current object with whatever params it needs, and
        /// propagates the initialization to all its followers.
        /// </summary>
        /// <param name="iData">number of seconds between data samples, e.g. 1 millisec = 0.001</param>
        public virtual void init(ChainInfo iData)
        {
            // Throw exception if null:
            if (iData == null)
            {
                throw new ArgumentNullException("iData", "iData cannot be null!");
            }
            // Throw exception if samplingPeriod is not reasonable:
            if (iData.samplingPeriodSec <= 0.0)                 // Must be > 0!
            {
                throw new ArgumentOutOfRangeException("iData", iData,
                                                      "iData.samplingPeriodSec (the number of seconds between data samples) "
                                                      + "must be greater than zero!");
            }

            // Retrieve what we need:
            stepPeriod = iData.samplingPeriodSec;
            // Save (a handle to) the whole thing:
            initVals = iData;                   // NOTE:  THE TARGET DATA IS SUBJECT TO BEING CHANGED ELSEWHERE!

            IReceiver follower;

            for (int i = 0; i < followers.Count; i++)
            {
                try
                {
                    follower = (IReceiver)followers[i];
                }
                catch
                {   // An exception means, followers got changed at just the wrong time
                    // AND it no longer has an i(th) element
                    follower = null;
                }
                if (follower != null)
                {
                    follower.init(iData);
                }
            }
            //lock ( followers )
            //{
            //	foreach ( object cur in followers )
            //	{
            //		follower = (IReceiver) cur;
            //		follower.init ( iData );
            //	}
            //}
        }
Пример #5
0
        /// <summary>
        /// Initialize the data run with the appropriate info/parameters.
        /// Note that a class should tolerate multiple init(...) calls without being destroyed
        /// then re-instantiated, and there should be nothing carried over from a previous run
        /// after init(...) has returned.
        /// </summary>
        /// <param name="iData">An object containing all necessary/relevant data for this
        /// data run.</param>
        public override void init(ChainInfo iData)
        {
            base.init(iData);
            // Re-Init the two progress indicators:
            lastStep   = 0;
            lastOutput = DateTime.Now;

            if (autoSend)
            {
                // Start the TimerThread now:
                // - If the step period is less than 0.02 seconds, then only execute
                //	every 0.02 seconds, to avoid overloading the system:
                if ((stepPeriod * 1000.0) < minTimerIntervalMSec)
                {
                    sendTimer.Start(minTimerIntervalMSec);                              // 20 ms. = 0.02 sec. = 50 Hz
                }
                else
                {
                    sendTimer.Start((long)(this.stepPeriod * 1000));
                }
            }
        }
Пример #6
0
        private void setInitValueByTag(ChainInfo initSet, ChainInfo.tagValuePair tagVal)
        {
            // Get the tag:
            ChainInfo.varTags tag = ChainInfo.getTagFromValue(tagVal.tagName);
            // Set appropriately -- try ChainInfo first:
            bool matched = initSet.setByTag(tag, tagVal.tagValue);

            if (!matched)               // It was not an ChainInfo, try DataInfo:
            {
                matched = initSet.dataInfo.setByTag(tag, tagVal.tagValue);
            }
            if (!matched)               // Not a DataInfo, try a PatientInfo
            {
                matched = initSet.patientInfo.setByTag(tag, tagVal.tagValue);
            }
            if (!matched)
            {
                matched = initSet.fileInfo.setByTag(tag, tagVal.tagValue);
            }
            if (!matched)
            {
                // None of the above -- ????
            }
        }
Пример #7
0
 /// <summary>
 /// Initialize the object;  if this is .
 /// </summary>
 /// <param name="iData">Passed up only</param>
 public override void init(ChainInfo iData)
 {
     iData.samplingPeriodSec = stepSize;                         // Init. the sampling period
     base.init(iData);
 }
Пример #8
0
        /// <summary>
        /// Override default behavior to:
        /// - Save a local copy
        /// - Get file header info
        /// - Update iData accordingly
        /// - Allow using header info to drive the output rates.
        /// <para>NOTE:  This method call GC.Collect() to force garbage collection on the
        /// managed-code environment.  If you are running unmanaged code, before calling
        /// this method you must ensure that your unmanaged storage allocations are properly
        /// protected or released.</para>
        /// </summary>
        public override void init(ChainInfo iData)
        {
            string errMsg = null;

            // Reset THOROUGHLY:
            GC.Collect();
            GC.WaitForPendingFinalizers();
            WfdbAccess.CloseWfdb();
            GC.Collect();
            GC.WaitForPendingFinalizers();
            // Read record header:
            siArray = WfdbAccess.GetSigInfoArray(numSignals, ref errMsg);
            bool result = WfdbAccess.GetSignalInfo(recordName, siArray, numSignals, ref errMsg);

            if (!result)
            {
                //System.Windows.Forms.MessageBox("Unable to access header for record '" + recordName + "' in path '" + searchPath + "'!");
                Exception ex = new ArgumentException("Unable to access header for record '" + recordName + "' in path '" + searchPath + "'.");
                throw ex;
            }
            // Read useful info from header:
            WFDB_Siginfo sigInfo = siArray.getitem(0);

            buffSize    = sigInfo.spf;
            frameBuffer = new int[buffSize];
            numSamples  = sigInfo.nsamp * sigInfo.spf;
            sigName     = sigInfo.desc;
            //sampFreq = WfdbAccess.GetSamplingFrequency(recordName);
            //if (sampFreq < 1)
            //{	// Problem reading header!
            //    //System.Windows.Forms.MessageBox("Unable to access record '" + recordName + "' in path '" + searchPath + "'!");
            //    Exception ex = new ArgumentException("Unable to access header for record '" + recordName + "' in path '" + searchPath + "'.");
            //    throw ex;
            //}
            adcZeroRef  = sigInfo.adczero;
            adcResBits  = sigInfo.adcres;
            adcMaxValue = (int)Math.Pow(2, adcResBits);
            baseline    = sigInfo.baseline;
            ampGain     = sigInfo.gain;
            if (ampGain == 0)
            {                   // Use default:
                ampGain = 200;
            }
            dataUnits = sigInfo.units;
            if ((dataUnits == null) || (dataUnits.Length == 0))
            {                   // Assign arbitrarily?
                dataUnits = "mV";
            }

            // Save a local handle:
            if (autoSend)
            {                   // Point to the input data structure:
                initValues = iData;
            }
            else
            {                   // Make our own data structure:
                initValues = new ChainInfo();
                initValues.samplingPeriodSec = iData.samplingPeriodSec;
            }

            if (autoSend && doneReading) // We previously terminated the timer - restart it:
            {                            // Init the TimerThread:
                sendTimer = new TimerThread(
                    new System.Threading.ThreadStart(this.next),
                    true);
            }

            // Init. what needs it:
            dispSamples = 0;                            // just started, nothing retrieved yet
            doneReading = false;
            if (initValues.patientInfo == null)
            {
                initValues.patientInfo = new PatientInfo("", "", "");
            }
            if (initValues.dataInfo == null)
            {
                initValues.dataInfo = new DataInfo(sigInfo.desc, DateTime.Now.ToString());
            }
            // And, apply the REAL values:
            initValues.dataInfo.BitsPerSample   = adcResBits;
            initValues.dataInfo.ScaleMultiplier = ampGain.ToString();
            if (adcResBits == 0)
            {                   // Missing some info -- go with a default:
                initValues.dataInfo.FullScaleReferenceVoltage = "2.0";
                initValues.dataInfo.ZeroOffset           = "0.0";
                initValues.dataInfo.ZeroReferenceVoltage = "-2.0";
            }
            else
            {
                initValues.dataInfo.FullScaleReferenceVoltage = ((adcMaxValue - baseline) / ampGain).ToString();
                initValues.dataInfo.ZeroOffset           = baseline.ToString();
                initValues.dataInfo.ZeroReferenceVoltage = (-baseline / ampGain).ToString();
            }
            initValues.dataInfo.ValueUnits = dataUnits;

            if (initValues.fileInfo == null)
            {
                initValues.fileInfo = new FileHandler();
            }
            if (initValues.samplingPeriodSec != stepSize)
            {
                // Update the sampling period:
                initValues.samplingPeriodSec = stepSize;
            }

            //// Init. the sampling period:
            //this.stepSize = initValues.samplingPeriodSec;

            // Init output buffer:
            ReadBuffer();

            // Apply values and propagate downstream:
            base.init(iData);                   // iData may have been changed or not
        }
Пример #9
0
 /// <summary>
 /// Returns the tag that the given value corresponds to, or throws an
 /// exception if there is no match.
 /// Note that the match must be exact and case-sensitive!
 /// </summary>
 /// <param name="tagValue">Tag Value to match to varTags tags</param>
 /// <returns>The appropriate tag;  throws an exception if no match.
 ///		Note that the match must be exact and case-sensitive!</returns>
 public static ChainInfo.varTags getTagFromLabel(string tagValue)
 {
     return(ChainInfo.getTagFromValue(tagValue));
 }
Пример #10
0
 /// <summary>
 /// Initialize myself.
 /// </summary>
 /// <param name="iData"></param>
 public void init(ChainInfo iData)
 {
     lastRefresh = DateTime.Now;
 }