Пример #1
0
        public virtual IBFSample[] ApplyMontage(IBFSample[] samples, SignalFilter filter, int boardId, int numberOfChannels, int sampleRate)
        {
            var montagedSignal = new List <IBFSample>();

            foreach (var nextSample in samples)
            {
                var newSample = new BFSampleImplementation(nextSample, NumberOfDerivations, 0, 0, 0);

                for (int i = 0; i < Derivations.Count; i++)
                {
                    var result = 0.0;
                    foreach (var nextChannel in Derivations[i].Channels)
                    {
                        result += nextSample.GetExgDataForChannel(nextChannel.RawChannelNumber) * nextChannel.Factor;
                    }

                    newSample.SetExgDataForChannel(i, result);
                }

                montagedSignal.Add(newSample);
            }

            samples = montagedSignal.ToArray();

            if (filter != null)
            {
                samples = FilterBrainflowSample.FilterChunk(filter, samples, boardId, numberOfChannels, sampleRate);
            }

            return(samples);
        }
Пример #2
0
        public void BlinkDetectorRisingAndFalling()
        {
            LeftCount  = 0;
            RightCount = 0;

            BlinkDetector detector = new BlinkDetector();

            detector.DetectedBlink += Detector_DetectedBlink;

            BFSampleImplementation data = new BFSampleImplementation(0)
            {
                TimeStamp = 1.00100,
            };

            //  this looks like rising edge
            detector.DetectBlinks(data, 31.0, 10.0, 31.0, 10.0);

            //  no blinks on rising edge alone
            Assert.AreEqual(0, LeftCount);
            Assert.AreEqual(0, RightCount);

            data = new BFSampleImplementation(0)
            {
                TimeStamp = 1.25,
            };

            // this looks like falling edge
            detector.DetectBlinks(data, 11.0, 10.0, 11.0, 10.0);

            //  should be one blink
            Assert.AreEqual(1, LeftCount);
            Assert.AreEqual(1, RightCount);
        }
Пример #3
0
 /// <summary>
 /// Process chunk read
 /// </summary>
 void ProcessChunk(double[,] buffer, int num)
 {
     for (int s = 0; s < num; s++)
     {
         IBFSample nextSample = new BFSampleImplementation(BoardId);
         nextSample.InitializeFromSample(buffer.GetRow(s));
         RawDataReceived?.Invoke(this, new BFSampleEventArgs(nextSample));
         LogRawDataProcessingPerformance(nextSample);
     }
 }
Пример #4
0
        /// <summary>
        /// Calculate the median for each Exg channel using specified seconds worth of data
        /// </summary>
        IBFSample GenerateMedianReport(double seconds)
        {
            var medianReport = new BFSampleImplementation(BoardId);
            var data         = GetUnfilteredData(seconds);

            for (int i = 0; i < NumberOfChannels; i++)
            {
                medianReport.SetExgDataForChannel(i, data.GetExgDataForChannel(i).Median());
            }

            return(medianReport);
        }
Пример #5
0
        //  Public Methods
        #region PublicMethods

        /// <summary>
        /// Setup the band powers range lists
        /// </summary>
        public void InitializeMonitorForBandPowerRangeList()
        {
            BandPowers = new IBFSample[BandPowerCalc.NumberOfBands];

            //  create a dictionary for the results of the band power calculation
            //  must match the number of frequency ranges list above
            BandPowersCollection = new ConcurrentDictionary <string, IBFSample>();
            for (int j = 0; j < BandPowerCalc.NumberOfBands; j++)
            {
                BandPowers[j] = new BFSampleImplementation(BoardId);

                var key = (BandPowerCalc.BandPowerCalcRangeList[j].Item1 + (BandPowerCalc.BandPowerCalcRangeList[j].Item2 - BandPowerCalc.BandPowerCalcRangeList[j].Item1) / 2).BandPowerKey();
                BandPowersCollection.TryAdd(key, BandPowers[j]);
            }
        }
Пример #6
0
        /// <summary>
        /// Create samples from a single data record (chunk of signals per sample)
        /// </summary>
        void CreateSamples(double[,] chunk)
        {
            double dataRecordTime = StartTime.Value + (ReadDataRecordsCount * DataRecordDuration);

            for (int i = 0; i < chunk.GetRow(0).Length; i++)
            {
                IBFSample newSample = null;
                newSample = new BFSampleImplementation(BoardId);
                if (newSample != null)
                {
                    newSample.InitializeFromSample(chunk.GetColumn(i));
                    newSample.TimeStamp = StartTime.Value + newSample.TimeStamp;
                    _Samples.Add(newSample);
                }
            }
        }
        /// <summary>
        /// Calculate band powers for the range list
        /// </summary>
        public IBFSample[] CalculateBandPowers(IEnumerable <IBFSample> samples)
        {
            var bandPowers = new IBFSample[BandPowerCalcRangeList.Count];

            for (int i = 0; i < BandPowerCalcRangeList.Count; i++)
            {
                bandPowers[i] = new BFSampleImplementation(BoardId);
            }

            for (int i = 0; i < NumberOfChannels; i++)
            {
                var bandPower = CalculateBandPower(samples, SampleRate, i, BandPowerCalcRangeList);

                int j = 0;
                foreach (var nextBandPower in bandPower)
                {
                    bandPowers[j++].SetExgDataForChannel(i, nextBandPower);
                }
            }

            return(bandPowers);
        }
Пример #8
0
        /// <summary>
        /// Create a sample from a single line of ascii text
        /// </summary>
        IBFSample CreateSample(string nextLine)
        {
            IBFSample newSample = null;

            newSample = new BFSampleImplementation(BoardId);
            newSample.InitializeFromText(nextLine);

            //  check the timestamp for valid data, this indicates we read a partial line for example the file is actively being written
            if (Math.Abs(newSample.TimeStamp - 0) < 0.0000001)
            {
                return(null);
            }

            //  cache the start time of the first record
            if (!StartTime.HasValue)
            {
                StartTime = newSample.TimeStamp;
            }
            //  cahce the end time
            EndTime = newSample.TimeStamp;

            return(newSample);
        }
Пример #9
0
        /// <summary>
        /// Read data from the board, and return collection of data
        /// </summary>
        private List <IBFSample> ReadDataFromBoard()
        {
            var data = new List <IBFSample>();

            try
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                var rawData = TheBoard.get_board_data();

                sw.Stop();
                var timeReadData = sw.Elapsed.TotalSeconds;
                sw.Restart();

                if (rawData.GetLength(1) == 0)
                {
                    InvalidReadCounter++;
                }
                else
                {
                    InvalidReadCounter = 0;

                    if (rawData.GetLength(1) > 255)
                    {
                        return(data);    //  this is the first connection surge, flush these readings
                    }
                    //Log?.Invoke(this, new LogEventArgs(this, "ReadDataFromBoard", $"Read {rawData.Columns()}.", LogLevel.VERBOSE));

                    double oldestReadingTime, period;
                    CalculateReadingPeriod(rawData, out oldestReadingTime, out period);

                    for (int i = 0; i < rawData.GetLength(1); i++)
                    {
                        IBFSample nextSample = new BFSampleImplementation(BoardId);
                        nextSample.InitializeFromSample(rawData.GetColumn(i));

                        nextSample.TimeStamp = oldestReadingTime + ((i + 1) * period);
                        data.Add(nextSample);
                        InspectSampleIndex(nextSample);
                    }

                    sw.Stop();
                    var timeParseData = sw.Elapsed.TotalSeconds;

                    ReadCounter += data.Count;
                    var since = (DateTimeOffset.UtcNow - LastReportTime);
                    if (since.TotalMilliseconds > 5000)
                    {
                        Log?.Invoke(this, new LogEventArgs(this, "ReadDataFromBoard", $"Read {ReadCounter - ReadCounterLastReport} in {since.TotalSeconds.ToString("F3")} s. { (int)(((ReadCounter - ReadCounterLastReport) / since.TotalSeconds) + 0.5)} SPS.  Read time {timeReadData.ToString("F4")} Parse Time {timeParseData.ToString("F4")}.", LogLevel.TRACE));
                        LastReportTime        = DateTimeOffset.UtcNow;
                        ReadCounterLastReport = ReadCounter;

                        if (CountMissingIndex > 1)
                        {
                            Log?.Invoke(this, new LogEventArgs(this, "ReadDataFromBoard", $"Missed {CountMissingIndex} samples in the past {since.TotalSeconds.ToString("F3")} seconds.", LogLevel.WARN));
                        }
                        CountMissingIndex = 0;
                    }
                }
            }
            catch (Exception e)
            {
                Log?.Invoke(this, new LogEventArgs(this, "ReadDataFromBoard", e, LogLevel.ERROR));
            }

            return(data);
        }