Beispiel #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);
        }
 /// <summary>
 /// Add a function to the filter
 /// will determine if this function has dynamic parameters of data[] only, or data[] and sampling_rate
 /// </summary>
 static void AddSignalFilterFunction(SignalFilter filter, MethodInfo mi, Dictionary <string, string> paramDict, object[] parameters)
 {
     if (paramDict.ContainsKey("sampling_rate"))
     {
         filter.AddFunction(new SignalFilterFunctionDataSampleRate(typeof(DataFilter).Assembly, mi, parameters));
     }
     else
     {
         filter.AddFunction(new SignalFilterFunctionData(typeof(DataFilter).Assembly, mi, parameters));
     }
 }
        /// <summary>
        /// Create a default filter for 60Hz mains noise
        /// </summary>
        static void CreateDefaultFilterNotch50()
        {
            var newFilter = new SignalFilter("default50");

            MethodInfo mi        = typeof(DataFilter).GetMethod("perform_bandstop", BindingFlags.Public | BindingFlags.Static);
            var        paramDict = new Dictionary <string, string>
            {
                ["data"]          = "",
                ["sampling_rate"] = "0",
                ["center_freq"]   = "50.0",
                ["band_width"]    = "2.0",
                ["order"]         = "6",
                ["filter_type"]   = "1",
                ["ripple"]        = "1.0"
            };

            //  create object array from parameters, casting to proper type
            object[] parameters = mi.GetParameters().Select(p => paramDict[p.Name].Length > 0 ? Convert.ChangeType(paramDict[p.Name], p.ParameterType) : null).ToArray();
            newFilter.AddFunction(new SignalFilterFunctionDataSampleRate(typeof(DataFilter).Assembly, mi, parameters));

            mi        = typeof(DataFilter).GetMethod("perform_bandpass", BindingFlags.Public | BindingFlags.Static);
            paramDict = new Dictionary <string, string>
            {
                ["data"]          = "",
                ["sampling_rate"] = "0",
                ["center_freq"]   = "25.5",
                ["band_width"]    = "47",
                ["order"]         = "2",
                ["filter_type"]   = "0",
                ["ripple"]        = "0.0"
            };

            //  create object array from parameters, casting to proper type
            parameters = mi.GetParameters().Select(p => paramDict[p.Name].Length > 0 ? Convert.ChangeType(paramDict[p.Name], p.ParameterType) : null).ToArray();
            newFilter.AddFunction(new SignalFilterFunctionDataSampleRate(typeof(DataFilter).Assembly, mi, parameters));

            mi        = typeof(DataFilter).GetMethod("perform_wavelet_denoising", BindingFlags.Public | BindingFlags.Static);
            paramDict = new Dictionary <string, string>
            {
                ["data"]                = "",
                ["wavelet"]             = "db12",
                ["decomposition_level"] = "3",
            };

            //  create object array from parameters, casting to proper type
            parameters = mi.GetParameters().Select(p => paramDict[p.Name].Length > 0 ? Convert.ChangeType(paramDict[p.Name], p.ParameterType) : null).ToArray();
            newFilter.AddFunction(new SignalFilterFunctionData(typeof(DataFilter).Assembly, mi, parameters));

            Filters.Add(newFilter.Name, newFilter);
        }
Beispiel #4
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>();
        }
        public static IBFSample[] FilterChunk(SignalFilter filter, IEnumerable <IBFSample> chunk, int boardId, int numberOfChannels, int sampleRate)
        {
            try
            {
                if (chunk == null || chunk.Count() == 0)
                {
                    throw new ArgumentException("Invalid chunk");
                }

                //  copy the data for filtering
                var filteredSamples = new List <IBFSample>(chunk.Select(x => new BFSampleImplementation(x)));

                for (int i = 0; i < numberOfChannels; i++)
                {
                    var filtered = filter.ApplyFilter(chunk.GetExgDataForChannel(i), sampleRate);

                    for (int j = 0; j < chunk.Count(); j++)
                    {
                        filteredSamples[j].SetExgDataForChannel(i, filtered[j]);
                    }
                }

                var lastTimeStamp   = chunk.First().TimeStamp;
                int lastSampleIndex = (int)chunk.First().SampleIndex;
                for (int i = 0; i < filteredSamples.Count; i++)
                {
                    filteredSamples[i].TimeStamp = lastTimeStamp + filteredSamples[i].SampleIndex.TimeBetweenSamples(lastSampleIndex, boardId, sampleRate);
                    lastTimeStamp   = filteredSamples[i].TimeStamp;
                    lastSampleIndex = (int)filteredSamples[i].SampleIndex;
                }

                return(filteredSamples.ToArray());
            }
            catch (Exception e)
            {
                throw e;
            }
        }
Beispiel #6
0
        //public async Task<SignalFiltering> StartSignalFilteringAsync()
        //{
        //    var filterName = ActiveFilters.FirstOrDefault().Key;
        //    if (filterName != null)
        //        return await StartSignalFilteringAsync(filterName);

        //    return null;
        //}

        /// <summary>
        /// Start the signal filtering task
        /// </summary>
        public async Task <RealTimeSignalProcessing> StartRealTimeSignalProcessingAsync(SignalFilter filter, ISignalMontage montage)
        {
            var useMontage = montage;

            if (useMontage == null)
            {
                useMontage = SignalMontages.MakeDefaultMontage(NumberOfChannels);
            }

            var montageName = useMontage.Name;
            var filterName  = filter == null ? "XXXDEFAULTXXX" : filter.Name;

            if (CancelTokenSource == null)
            {
                Log?.Invoke(this, new LogEventArgs(Name, this, "StartSignalFiltering", $"You must start the processor first.", LogLevel.ERROR));
                return(null);
            }


            if (ActiveFilters.ContainsKey(RealTimeSignalProcessing.KeyName(filterName, montageName)))
            {
                return(ActiveFilters[RealTimeSignalProcessing.KeyName(filterName, montageName)]);
            }



            var newFilter = new RealTimeSignalProcessing(BoardId, SampleRate, filter, useMontage)
            {
                FilterBufferLength = 30,
            };

            newFilter.GetRawChunk = GetRawChunk;
            newFilter.Log        += OnComponentLog;

            ActiveFilters.Add(RealTimeSignalProcessing.KeyName(filterName, montageName), newFilter);
            await newFilter.StartRealTimeProcessingAsync();

            return(newFilter);
        }
        /// <summary>
        /// Load filter definitions from XML file
        /// </summary>
        public void LoadSignalFilters(string xmlFilePath)
        {
            try
            {
                Filters.Clear();

                using (var reader = new StreamReader(xmlFilePath))
                {
                    var doc = XDocument.Load(reader);

                    var filters = doc.Element("brainHatSignalFilters")?.Element("Filters")?.Elements("Filter");
                    if (filters == null)
                    {
                        throw new Exception("Document does not hae a <Filters> element.");
                    }

                    foreach (var nextFilter in filters)
                    {
                        var filterName = nextFilter.Element("Name")?.Value;
                        if (filterName == null || Filters.ContainsKey(filterName))
                        {
                            throw new Exception("Filter does not have a name or name is duplicated.");
                        }

                        var newFilter = new SignalFilter(filterName);

                        var functions = nextFilter.Element("Functions")?.Elements("Function");
                        if (functions == null)
                        {
                            throw new Exception($"Filter {filterName} does not have any functions.");
                        }

                        foreach (var nextFunction in nextFilter.Element("Functions")?.Elements("Function"))
                        {
                            //  get function name from XML
                            var functionName = nextFunction.Attribute("Name")?.Value;
                            //  get method from DataFilter class
                            MethodInfo mi = typeof(DataFilter).GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);

                            if (mi == null)
                            {
                                throw new Exception($"Filter {filterName} specifies an invalid function");
                            }

                            //  get dictionary of parameters from XML
                            var paramDict = nextFunction.Elements("Parameter").ToDictionary(d => d.Attribute("Name").Value, d => d.Attribute("Value").Value);
                            //  create object array from parameters, casting to proper type
                            object[] parameters = mi.GetParameters().Select(p => paramDict[p.Name].Length > 0 ? Convert.ChangeType(paramDict[p.Name], p.ParameterType) : null).ToArray();

                            AddSignalFilterFunction(newFilter, mi, paramDict, parameters);
                        }

                        Filters.Add(filterName, newFilter);
                    }
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }