示例#1
0
        //  Implementation
        #region Implementation

        /// <summary>
        /// Constructor
        /// </summary>
        public BrainflowDataProcessor(string name, int boardId, int sampleRate)
        {
            BoardId          = boardId;
            NumberOfChannels = BrainhatBoardShim.GetNumberOfExgChannels(boardId);
            SampleRate       = sampleRate;
            Name             = name;

            CreateChannelStdDevRunningCollection();

            UnfilteredData  = new List <IBFSample>();
            DataToProcess   = new ConcurrentQueue <IBFSample>();
            NotifyAddedData = new SemaphoreSlim(0);

            BandPowers             = new BandPowerMonitor(Name, BoardId, SampleRate);
            BandPowers.GetRawChunk = GetRawChunk;
            BandPowers.Log        += OnComponentLog;

            RealTimeBufferLengthSeconds = 5 * 60;


            ActiveFilters = new Dictionary <string, RealTimeSignalProcessing>();

            //  default periods for periodic loops
            PeriodMsUpdateData           = 200;  //  5Hz for update data message
            PeriodMsUpdateProcessorStats = 5000; //  every five seconds update processor stats

            PeriodMsUpdateStdDev     = 100;      //  10Hz std deviation update
            PeriodMsUpdateDataFilter = 200;      // 5 Hz data filter update
            PeriodMsFlushOldData     = 2000;     // Flush old every two seconds

            ProcessingTimesQueue = new ConcurrentQueue <double>();
        }
示例#2
0
        /// <summary>
        /// Set the file properties from the header information
        /// </summary>
        bool SetFilePropertiesFromHeader(EdfHeaderStruct header)
        {
            BoardId = header.recording_additional.Trim().GetBoardId();

            switch ((BrainhatBoardIds)BoardId)
            {
            case BrainhatBoardIds.CYTON_BOARD:
            case BrainhatBoardIds.CYTON_DAISY_BOARD:
            case BrainhatBoardIds.MENTALIUM:
                break;

            default:
                return(false);
            }

            SampleRate         = (int)(header.signalparam[0].smp_in_datarecord / (header.datarecord_duration * 1.0E-7));
            DataRecordDuration = header.datarecord_duration * 1.0E-7;

            NumberOfChannels = BrainhatBoardShim.GetNumberOfExgChannels(BoardId);

            var date = new DateTime(header.startdate_year, header.startdate_month, header.startdate_day, header.starttime_hour, header.starttime_minute, header.starttime_second);

            date      = date.AddMilliseconds(header.starttime_subsecond / 10_000);
            StartTime = new DateTimeOffset(date.ToUniversalTime(), TimeSpan.FromHours(0)).ToUnixTimeInDoubleSeconds();

            EndTime = StartTime + (header.datarecords_in_file * (header.datarecord_duration * 1.0E-7));

            return(true);
        }
        /// <summary>
        /// Setup LSL outlet for the board
        /// </summary>
        void SetupLslOutletForBoard()
        {
            var numChannels       = BrainhatBoardShim.GetNumberOfExgChannels(BoardId);
            var numAccelChannels  = BrainhatBoardShim.GetNumberOfAccelChannels(BoardId);
            var numOtherChannels  = BrainhatBoardShim.GetNumberOfOtherChannels(BoardId);
            var numAnalogChannels = BrainhatBoardShim.GetNumberOfAnalogChannels(BoardId);

            SampleSize = 2 + numChannels + numAccelChannels + numOtherChannels + numAnalogChannels;

            StreamInfo = new liblsl.StreamInfo(BoardId.GetSampleName(), "BFSample", SampleSize, SampleRate, liblsl.channel_format_t.cf_double64, BrainHatNetwork.NetworkUtilities.GetHostName());

            StreamInfo.desc().append_child_value("manufacturer", "OpenBCI");
            StreamInfo.desc().append_child_value("boardId", $"{BoardId}");
            liblsl.XMLElement chns = StreamInfo.desc().append_child("channels");

            chns.append_child("channel")
            .append_child_value("label", "SampleIndex")
            .append_child_value("unit", "0-255")
            .append_child_value("type", "index");

            for (int k = 0; k < numChannels; k++)
            {
                chns.append_child("channel")
                .append_child_value("label", $"ExgCh{k}")
                .append_child_value("unit", "uV")
                .append_child_value("type", "EEG");
            }

            for (int k = 0; k < numAccelChannels; k++)
            {
                chns.append_child("channel")
                .append_child_value("label", $"AcelCh{k}")
                .append_child_value("unit", "1.0")
                .append_child_value("type", "Accelerometer");
            }

            for (int k = 0; k < numOtherChannels; k++)
            {
                chns.append_child("channel")
                .append_child_value("label", $"Other{k}");
            }

            for (int k = 0; k < numAnalogChannels; k++)
            {
                chns.append_child("channel")
                .append_child_value("label", $"AngCh{k}");
            }

            chns.append_child("channel")
            .append_child_value("label", "TimeStamp")
            .append_child_value("unit", "s");
        }
示例#4
0
        //  Implementation
        #region Implementation

        /// <summary>
        /// Constructor
        /// </summary>
        public BandPowerMonitor(string name, int boardId, int sampleRate)
        {
            BoardId          = boardId;
            NumberOfChannels = BrainhatBoardShim.GetNumberOfExgChannels(boardId);
            SampleRate       = sampleRate;
            Name             = name;

            PeriodMilliseconds = 200;   //  default 5 Hz

            ProcessingTimes      = new ConcurrentQueue <double>();
            BandPowersCollection = new ConcurrentDictionary <string, IBFSample>();
            BandPowerCalc        = new BandPowerCalculator(BoardId, NumberOfChannels, SampleRate);
            InitializeMonitorForBandPowerRangeList();
        }
示例#5
0
        //  Implementation
        #region Implementation


        /// <summary>
        /// Constructor
        /// </summary>
        public RealTimeSignalProcessing(int boardId, int sampleRate, SignalFilter filter, ISignalMontage montage)
        {
            BoardId          = boardId;
            NumberOfChannels = BrainhatBoardShim.GetNumberOfExgChannels(BoardId);
            SampleRate       = sampleRate;

            Filter  = filter;
            Montage = montage;

            Name = KeyName((Filter == null ? "" : Filter.Name), Montage.Name);

            PeriodMilliseconds = 33;

            FilterBufferLength = 10;

            ProcessingTimes = new ConcurrentQueue <double>();


            FilteredData = new ConcurrentQueue <IBFSample>();
        }
示例#6
0
        /// <summary>
        /// Write the file header
        /// </summary>
        void WriteFileHeader(StreamWriter file)
        {
            //  write header
            file.WriteLine("%OpenBCI Raw EEG Data");
            file.WriteLine($"%Number of channels = {BrainhatBoardShim.GetNumberOfExgChannels(BoardId)}");
            file.WriteLine($"%Sample Rate = {SampleRate} Hz");
            file.WriteLine($"%Board = {FileBoardDescription()}");

            switch ((BrainhatBoardIds)BoardId)
            {
            case BrainhatBoardIds.MENTALIUM:
                file.WriteLine($"%ExtraBoardId = {BoardId}");
                break;
            }

            file.WriteLine("%Logger = brainHat");
            file.WriteLine($"%SubjectName = {Info.SubjectName}");
            file.WriteLine($"%SubjectCode = {Info.SubjectCode}");
            file.WriteLine($"%SubjectAdditional = {Info.SubjectAdditional}");
            file.WriteLine($"%SubjectGender = {(Info.SubjectGender == 0 ? "XX" : "XY")}");
            file.WriteLine($"%SubjectBirthday = {Info.SubjectBirthday.ToString("yyyy-MM-dd")}");
            file.WriteLine($"%AdminCode = {Info.AdminCode}");
            file.WriteLine($"%Technician = {Info.Technician}");
        }
示例#7
0
        /// <summary>
        /// Init the board session
        /// </summary>
        private async Task InitializeBoardAsync()
        {
            try
            {
                Log?.Invoke(this, new LogEventArgs(this, "InitializeBoardAsync", $"Initializaing board", LogLevel.DEBUG));

                await ReleaseBoardAsync();

                RequestToggleStreamingMode = false;

                var useBoardId = BoardId;
                switch ((BrainhatBoardIds)BoardId)
                {
                case BrainhatBoardIds.MENTALIUM:
                    useBoardId = 0;
                    break;
                }

                TheBoard = new BoardShim(useBoardId, InputParams);

                SampleRate     = BrainhatBoardShim.GetSampleRate(BoardId);
                TimeStampIndex = BrainhatBoardShim.GetTimestampChannel(BoardId);

                TheBoard.prepare_session();
                await Task.Delay(TimeSpan.FromSeconds(1));

                TheBoard.config_board("s");


                BoardSettings = new CytonBoardsImplementation();
                if (!await LoadBoardRegistersSettings(1))
                {
                    throw new Exception("Unable to get board register settings");
                }

                //  TODO - clean up SRB1 start setting
                if (StartSrb1CytonSet)
                {
                    await SetSrb1Async(BoardSettings.Boards[0].Channels[0], true);

                    if (StartSrb1DaisySet && (BrainhatBoardIds)BoardId == BrainhatBoardIds.CYTON_DAISY_BOARD && BoardSettings.Boards.Count() > 1)
                    {
                        await SetSrb1Async(BoardSettings.Boards[1].Channels[0], true);
                    }

                    BoardSettings = new CytonBoardsImplementation();
                    if (!await LoadBoardRegistersSettings(1))
                    {
                        throw new Exception("Unable to get board register settings");
                    }
                }

                await StartStreamingAsync();

                await Task.Delay(TimeSpan.FromSeconds(5));

                ConnectToBoard?.Invoke(this, new ConnectToBoardEventArgs(BoardId, SampleRate));
            }
            catch (Exception e)
            {
                Log?.Invoke(this, new LogEventArgs(this, "InitializeBoardAsync", e, LogLevel.ERROR));

                if (TheBoard != null && TheBoard.is_prepared())
                {
                    TheBoard.release_session();
                }
                TheBoard = null;
            }
        }