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