The MatlabFilter implements a mechanism for using Matlab scripts within the BCI2000 pipeline. The MatlabFilter calls Matlab to act upon signals, parameters, and states. It provides the full BCI2000 filter interface to a Matlab filter implementation. In earlier versions of BCI2000, the MatlabFilter was using the MatlabEngine library to start up and interact with an instance of Matlab. This is no longer the case. Rather, Matlab is now started up executing a client program that receives commands from BCI2000 through a local TCP socket. This has the advantage of greater transparency regarding which Matlab executable is started up in case of multiple parallel installations, and that it works no matter whether BCI2000's bitness matches that of Matlab or not. Also, this is faster than the Matlab engine on Windows, because the Matlab engine utilizes COM marshaling mechanisms to translate data forth and back, whereas data is transmitted in text form through the socket connection.
While BCI2000 is running, each block of data is provided to Matlab via shared memory, and a well-specified Matlab function (i.e. *.m file) is executed. As explained in more detail in the Programming reference for the GenericFilter Class, all BCI2000 filters consist of a set of functions. The MatlabFilter will, upon execution of each of these functions, contact Matlab and execute the corresponding Matlab function equivalent. Furthermore, the MatlabFilter copies the input signal, states and events to Matlab, and copies the output signal and states from Matlab after processing the signal.
|BCI2000 function||Matlab equivalent||Purpose|
|Constructor()||bci_Construct||define parameters and states|
|Preflight()||bci_Preflight||test for valid and consistent parameter values|
|Initialize()||bci_Initialize||apply parameter values|
|StartRun()||bci_StartRun||produce a consistent state at the beginning of a run|
|Process()||bci_Process||process a portion of data (data block)|
|StopRun()||bci_StopRun||produce a consistent state at the end of a run|
|Resting()||bci_Resting||set any adapted parameter values after the end of a run|
|Halt()||bci_Halt||stop any asynchronous activity between runs, and before shutdown|
|Destructor()||bci_Destruct||deallocate any resources allocated while executing any of the previous functions|
Existence of the above-listed Matlab functions is not mandatory, the Matlab 'exist' command will be used to determine whether a given function is available, and will not call Matlab when this is not the case. If either of the bci_Preflight, bci_Initialize, or bci_Process functions is not available, a warning will be displayed to the user.
Most of these Matlab functions do not take arguments, except for
function [parameters, states] = bci_Construct; function [out_signal_dim] = bci_Preflight( in_signal_dim ); function bci_Initialize( in_signal_dim, out_signal_dim ); function [out_signal] = bci_Process( in_signal );
The most important functions is bci_Process, which is executed every time a new block of data is passed through the pipeline. The bci_Construct function is executed at the beginning and determines the parameters and states. The bci_Initialize function determines whether all requirements are met. The bci_StartRun function prepares the computation that is done during processing (e.g. computing filter parameters). Communication between these Matlab functions is done using global variables.
Parameters and States
Parameters and states are accessible via global Matlab structs called 'bci_Parameters' and 'bci_States'. Parameters may be changed from bci_StopRun and bci_Resting, and will automatically be propagated to the other modules. State values may be modified from the bci_Process function.
To add parameters and states to the BCI2000 list of states, the bci_Construct function may return non-empty cell arrays of strings in its parameters and states return values. The strings constituting these cell arrays are parameter and state definitions.
Your added parameters will appear in the operator module's parameter configuration dialog. Your parameter definition's section name will be used to direct its position in the configuration dialog's register cards:
MyFilter int MyParam= 2 0 0 2 // ...
will display the MyParam parameter on separate register card named MyFilter.
Filtering:MyFilter int MyParam= 2 0 0 2 // ...
will display the parameter on the Filtering register card, inside a group called MyFilter.
Input and Output Signal Format
BCI2000 signals are mapped to Matlab matrices with channel index first, and sample (element) index second. The signal dimension arguments of bci_Preflight and bci_Initialize are integer vectors of size 1x2 with [n_channels n_elements].
To report errors from Matlab functions, use Matlab's error command. Your error messages will be displayed to the user from the operator module.
Combining the MatlabFilter with other Signal Processing Filters
In the BCI2000 binary distribution, the MatlabFilter is shipped inside the MatlabSignalProcessing executable. There, the signal processing chain consists of the SpatialFilter and the MatlabFilter. However, by editing src/core/SignalProcessing/Matlab/PipeDefinition.cpp, you may add as many signal processing filters as you wish.
See Programming Reference:Filter Chain for information about defining a filter chain. Modification of the filter chain requires access to the BCI2000 source code. You will need to rebuild the MatlabSignalProcessing executable.
Command Line Options
Full path to the Matlab executable that should be started up. If none is given, Matlab is searched at %PROGRAM FILES%/Matlab/<Release>/bin/matlab.exe on Windows, and as matlab on the search path for other operating systems. If you have installed Matlab to a non-default location, you will need to provide a path because it will not be found automatically. Similarly, if you have installed multiple versions of Matlab in parallel, you will need to provide a path to select which one to use. When specifying the path from the command line or in a batch file, you need to use an URL-like notation for space characters and special characters:
start executable MatlabSignalProcessing.exe --local --MatlabExecutable=C:/Program%20Files/Matlab/R2020a/bin/matlab.exe
This parameter must be set from the command line (batch file). Later changes to this parameter have no effect.
By default, Matlab's working directory is set to the signal processing module's working directory at startup. When using the Matlab filter for signal processing, your filter's code will be contained in the bci_Process and associated Matlab functions, which will typically be located inside a dedicated directory. Thus, you may switch between Matlab-based filter implementations by selecting a Matlab working directory at startup. This may be done by specifying the MatlabWD parameter from the command line when starting the MatlabSignalProcessing module:
start executable MatlabSignalProcessing.exe --local --MatlabWD="./matlab" 127.0.0.1
will change Matlab's working directory to a directory called "matlab" inside the BCI2000 "prog" directory at startup, and execute bci_Process and associated functions from there.
This parameter must be set from the command line; later changes will have no effect.
Using the --MatlabWD command line option, you may easily switch between multiple Matlab-based BCI2000 configurations. Simply create a separate startup batch file for each configuration, and specify the respective configuration's path on the command line that starts up the MatlabFilter.
The MatlabFilter will open a new instance of Matlab when it starts. By default, this instance will be closed when BCI2000 quits. Generally, this behavior is desired to ensure a well-defined BCI2000 system state after each startup. For debugging purposes, though, it is sometimes useful to have Matlab's command window available even after BCI2000 has been quit. This behavior is controlled by another command-line parameter, MatlabStayOpen, which may take the following values:
- 0 is the default (no change in behavior),
- 1 keeps Matlab open but clears variables used to transmit information forth and back between BCI2000 and Matlab,
- 2 also preserves intermediate variables (such as bci_Parameters and bci_States) in Matlab's workspace.
To set this parameter to 2, use this command to start up the signal processing module:
start executable MatlabSignalProcessing.exe --local --MatlabStayOpen=2
Once the MatlabStayOpen parameter has been set from the command line, it will be listed on the Operator Module's parameter configuration dialog's "system" tab, and may be modified from there. The change will be applied when clicking Set Config.
Debugging Matlab functions
Start BCI2000. The MatlabFilter will open a Matlab instance in its own window. Switch to the Matlab instance. Open, e.g.,bci_Process.m in a Matlab editor window using the Matlab GUI. In the editor window, set breakpoints as you would normally. Execution will be paused, and you may examine variables hovering the mouse over them.
NOTE: In some versions of Matlab, you cannot open Matlab editor windows/tabs when Matlab has been started by BCI2000. As a workaround, open Matlab without BCI2000 first, open the desired files in the editor, and quit Matlab. Then start Matlab again through BCI2000. Your editor tabs will be available as before, and you can switch to a file and set breakpoints as desired.
Matlab doesn't find your functions
Make sure to
- either set Matlab's working directory to the directory containing your functions, using the --MatlabWD command line option described above,
- or add the respective directory to your Matlab path.
Generally, the first option is recommended over the second one.
There is no Matlab instance started up
If you have installed Matlab in an unusual location, it won't be found automatically. Make sure to set the --MatlabExecutable command line option as described above.
If you get linker errors after editing PipeDefinition.cpp, make sure that all filters' cpp files are part of the MatlabSignalProcessing project.
Technical Reference:Core Modules#Signal Processing Module, Technical Reference:Parameter Definition, Technical Reference:State Definition, Programming Reference:GenericFilter Class, Programming Reference:Filter Chain, Contributions:FieldTripBuffer