Any docs on ParallelCominbation?

Forum for software developers to discuss BCI2000 software development
Locked
boulay
Posts: 382
Joined: 25 Dec 2011, 21:14

Any docs on ParallelCominbation?

Post by boulay » 22 Oct 2013, 00:37

Hi Juergen,

Are there any documents on ParallelCombination? Specifically wrt revision 4586?
(GenericFilter: ParallelCombination now supports splitting a signal into multiple subsets; new GenericFilter::Resting() overload allows idle processing by all modules if necessary.)
I found this post: http://www.bci2000.org/phpbb/viewtopic. ... ious#p4384, but it's a little old. I wonder if there is a better way now?

Thanks,
Chad

mellinger
Posts: 1163
Joined: 12 Feb 2003, 11:06

Re: Any docs on ParallelCominbation?

Post by mellinger » 22 Oct 2013, 09:23

Hi Chad,

you are right, there has been some progress in the meantime.
It is now possible to have multiple filtering chains in parallel, and to select channel subsets to be processed by each of the chains.

However, this is a very recent addition to BCI2000, and has not been documented so far. Also, its implementation is not complete with regard to multiple instances of a single filter class, i.e. it is possible to use a certain filter at multiple places within the signal processing module, but it is currently not possible set parameter values per filter instance, so all filters of the same kind will use the same parameter settings.

This makes it impossible to use the IIRFilter with different settings for different kinds of input, say for EOG channels, and EEG channels. Obviously, this is a severe restriction which will be removed in the future, but it requires rather deep changes in the Operator GUI, so it cannot be done prior to the forthcoming 3.06 release of BCI2000.

If you still want to use it, here is an example for parallel processing of EOG, and EEG:

Code: Select all

#include "FilterCombination.h"
#include "SignalStream.h"
#include "SubchainFilter.h"
#include "SpatialFilter.h"
#include "ARFilter.h"
#include "LinearClassifier.h"
#include "LPFilter.h"
#include "Normalizer.h"
#include "ExpressionFilter.h"
#include "IIRBandpass.h"

struct NormalizerInput : SignalStream<3> {};
struct NormalizerOutput : SignalStream<3> {};
struct ERDChain : SubchainFilter
{
  ERDChain()
  {
    Add<SpatialFilter>();
    Add<ARFilter>();
    Add<LinearClassifier>();
    Add<LPFilter>();
    Add<NormalizerInput>();
    Add<Normalizer>();
    Add<NormalizerOutput>();
  }
};
struct EOGOutput : SignalStream<3> {};
struct EOGChain : SubchainFilter
{
  EOGChain()
  {
    Add<IIRBandpass>();
    Add<EOGOutput>();
  }
};
struct Splitter :
  ParallelCombination<ERDChain, EOGChain>
{};

Filter( Splitter, 2.A );
Filter( ExpressionFilter, 2.E2 );
As you can see, the main filter chain consists of only two filters, a "Splitter", and the "ExpressionFilter".
Configuration of the Splitter is done by instantiating the ParallelCombination template with the desired filter chains as template parameters. Each of the two chains is a descendant of the Subchain class, and defines filter order by calling the Subchain::Add<>() method template with the desired filters as template arguments from its constructor.

In addition, you see a number of instantiations of the SignalStream<> template. This is a way to record processed data inside the data file -- each SignalStream<> object requests a fixed number of 32-bit state variables, and writes its input signal into those as 32-bit floats. The number of these state variables is given as the template parameter, and their names are derived from the template instance's class name.
When loading the resulting data file into Matlab, you may identify the states by their names, but their values will appear as 32-bit integers, so you need to apply the Matlab typecast function in order to convert them to "single" before using them.

The SignalStream<> template is a workaround until more generic means of signal routing in BCI2000 will be available.

Best regards,
Juergen

boulay
Posts: 382
Joined: 25 Dec 2011, 21:14

Re: Any docs on ParallelCominbation?

Post by boulay » 22 Oct 2013, 11:44

Hi Juergen,

Thank you for the detailed explanation. Can you explain a little further why SignalStream is necessary before Normalizer but not any other filters?

Further, can you explain a little more about SignalStream? From your description, my understanding is that each channel*sample will get written to a state variable, but I doubt the parameter passed to the SignalStream constructor in your example meant 3-channels and 1-sample-per-block. So what does the <3> mean and am I wrong that each sample gets saved to the state? (I hope so)

For my next questions I will use your example module and a contrived source of 32 EEG channels and 2 EOG channels, sampled at 512 Hz with 64 samples per block.
What are the dimensions of the inputs to SpatialFilter and IIRBandpass?
Let's say LinearClassifier is parameterized to only have one output, what dimension is the input to ExpressionFilter?

Finally, given the details below, how do I minimize the size of the added State variables? My files are already over 500 MB each, with almost 7 GB per session.

One of my experiments that I'd like to use this in has 63 EEG channels + 2 EMG channels sampled at 5 kHz. I need 3 chains: (1) My EEGChain would be similar to the ERDChain below though I usually put the ExpressionFilter before the normalizer. (2) My EMGChain1 would simply be a high-pass (10 Hz) so the application has access to the MEPs. (3) My EMGChain2 (same channels as EMGChain1) would ideally be a high-pass, then rectify, then smooth/low-pass, then average over the block, for use in calculating steady-state EMG activation. If I can't get EMGChain2 to work (due to not being able to set the parameters), then I could survive with including the EMG in the ERDFilter and using the LinearClassifier to sum the power in all EMG channel frequencies above 10Hz (up to 2500), then smooth that result.

Thanks again,
Chad

mellinger
Posts: 1163
Joined: 12 Feb 2003, 11:06

Re: Any docs on ParallelCominbation?

Post by mellinger » 25 Oct 2013, 08:45

Hi Chad,

the SignalStream<> template is really a workaround, and it _does_ write all samples that are contained in the signal it sees (which is not too much for the Normalizer).

There is no special reason at all for including SignalStream<> filters, unless you want to document intermediate signals in the data file, which you of course can recompute offline as well. In the example, the experimenter just wanted that data for convenience because he does not feel comfortable with the BCI2000 offline chain. If you don't want this, just leave out the Stream filters.

The template parameter is the maximum number of channels, and determines the number of state variables created by the filter. This is necessary because currently state variables must be requested (in Publish()) before information about signals is available (in Preflight()).
It's really just a workaround -- mid-term, the aim is to be able to route any signal in the filter chain into the data file, similar to the way how it is currently possible to route them to Operator visualization windows.

The Splitter filter has a parameter that allows you specify the channel set going into each of the two chains. Its output is basically a concatenation of the two outputs, filled with NaNs in order to get a rectangularly shaped signal.

For your EMG chain, my suggestion is that you use the IIRFilter as the first filter, and put a Splitter filter behind that. BCI2000 has a separate low pass filter, so you can use that in one of the chains without parameter clashes. If you choose a time constant in the order of a block length, you can save the additional averaging step, and use the block's central sample instead.

Regards,
Juergen

boulay
Posts: 382
Joined: 25 Dec 2011, 21:14

Re: Any docs on ParallelCominbation?

Post by boulay » 26 Nov 2015, 11:20

Hi Juergen and Peter,

Sorry to revive an old thread, but...

In the 2 years since we last talked about this, has anything changed? Are there any docs? I'm a little better at C++ now and can follow the code better. I just wanted to make sure there were no major (breaking) changes or expected changes before I dove in.

Cheers,
Chad

Locked

Who is online

Users browsing this forum: No registered users and 1 guest