Troubleshooting and FAQ
6.1. Options for debugging
There are different ways to debug your BCI application:
1) Use a recorded file
The experiment is 're-played' using data and markers present in a previously recorded data file. The recorded data file has to be structured equal to the data you will acquire during a real BCI experiment. If you enter this file in your blockfile at key RunMode.DataSource (see DocsSectionsBlockFile), you can execute BrainStream using this file as data source. Running through your experiment in this way enables to debug your experiment by using Matlab debugging (i.e. placing break point in the code). For example, when Matlab encounters a break point, the experiment will stop running waiting for you to check the code. Time is now in your hand and you can easily debug your experiment.
2) Use dummy data
The second possibility is to use the InsertMarker [[BrainStreamGlossary|GUI] to execute your experiment step by step by inserting markers manually. To use this functionality, RunMode.DataSource has to be set to empty.
3) Read the log-file
Check if the log-file displays an error message or informs about something unusual.
4) Print information in the log-file
If you want to print specific information in the log-file, use the functions bs_warn or bs_msg. See the Function Index for more information about these functions.
5) Trace variables
Another functionality is tracing the content of the user-specific variables you use in your experiment definition file and/or user-defined functions. You can add or remove variables to a list of traced variables using function bs_trace. This list is stored in the variable trace_vars, which is reserved by BrainStream. To be able to use this functionality, you have to enter the variable trace_vars in your experiment definition table. Every time content of the traced variable is requested or updated (via a modifying action, a get/load or a put/save), its content will be printed in the log-file. Note that for large-sized variables only the size will be outputted in the log-file. For more information this functionality of tracing the content of variables, see the Function Index.
6) Screen level output
You can choose how many information is shown to you on the screen during the experiment or during the 're-play' of the experiment. The level of screen output can be set in two different ways: 1) In the field 'Screen output level' of the GUI or 2) In your blockfile at key RunMode.screenoutputlevel.
- 'ERROR': Only displays error messages. Warning messages and info messages are suppressed.
- 'WARNING': Error messages and warning messages are displayed. Info messages are suppressed.
- 'INFO': Displays all outputted information in the Matlab command window.
- 'DEBUG': Displays all outputted information in the Matlab command window. Compared to INFO, however, all information is also shown in the log-window of the GUI. In addition, information is provided about which actions are being executed.
All error messages BrainStream can generate are explained below:
'Missing get for ....' and BrainStream issues an error
BrainStream warns for missing 'get' statements in the [[BrainStreamGlossary|experiment definition table] in order to help you debugging your experiment. Especially during the initial setup of an experiment 'get' keywords are often missing. For example, a user function was modified and it was forgotten to update the experiment definition table with a 'get' keyword for the user state variable involved in this modification. At the moment BrainStream needs to execute actions for corresponding marker, it fails due to a missing field in the event structure (i.e. the missing user state variable) that is required in one (or more) of the user functions.
'Missing get for ....', though the experiment runs without any errors
A missing [[BrainStreamGlossary|'get' statement] will not necessarily issue an error. BrainStream verifies if all the detected event structure fields in a function have 'get' keyword specified. If not, BrainStream generates this error message. However, it only issues an error if a user-defined function uses a variable in the event structure for which the 'get' keyword is forgotten. For example, if a variable only needs to be initialized, no error will be issued.
Blockfile defined in .exp file cannot be found
Time is specified but no actions are defined (file: filename and sheet Sheetname)
Somewhere in the experiment definition file a time point is set, e.g. EVENT or DATA, but no actions have been given. This is not allowed, either add actions to the specific time point, or remove the time point from the experiment definition file. Note that this can also occur when one refers to a table with a list of markers, but no associated actions.
Frequently Asked Questions
What is BrainStream?
BrainStream is a Matlab-based toolbox that allows you to run and analyse EEG experiments in a modular way. For a more elaborate description see the introduction of the documentation.
Who is BrainStream meant for?
BrainStream offers users without programming experience the opportunity to put together their experiment in easily editable tables, in MS Excel or in simple textfiles. Alternatively, people who do have programming experience can freely use any function they want within the BrainStream framework. Brain Stream is entirely Matlab based and can therefore be used on different operating systems (it is tested on
What do I need to use BrainStream?
A Matlab license, BrainStream is tested with versions from 2007a and higher, possibly older versions would work too. At the moment, BrainStream assumes the availabilty of Matlabs' Signal Processing Toolbox.
What is the minimal required technical setup?
For BrainStream itself, there is no minimal technical requirement. This is almost fully determined by the type of the Brain-Computer Interface (BCI), (i.e., resources needed for the corresponding analyses) you are trying to execute. The acquisition source BrainStream is connecting to will have its effects on timing regarding incoming data and markers. This is mainly due to technical layers between the data source and BrainStream. The resources BrainStream requires for managing a correct execution of user defined actions are minimal.
What kind of signals are supported?
In principal there are no limits to the type of signals BrainStream is connecting to. BrainStream itself is managing and executing the actions the user has defined in the experiment definition tables. In fact it is 'blind' for the content, although off course the hardware of the data source must be supported by BrainStream. Any solution can be made to work with BrainStream if it obeys to the API described here: xxxxx. Contact the BrainStream developers in order to get it standard integrated into BrainStream.
Which equipment is supported?
Currently the following hardware devices are supported:
Biosemi, Active2, Actiview
BrainProducts, BrainAmp, Brain Vision Recorder via Fieldtrip FileIO buffer (incoming markers under construction)
Any device supported by:
BCI2000, ......, via Fieldtrip FileIO buffer (filtered marker channel needs to be resolved)
Supported data file formats for offline use:
Biosemi, biosemi data format (extended edf format)
All files supported by Fieldtrips FileIO module, see .......
Does BrainStream really need markers?
BrainStreams' concept fully relies on incoming markers. Without them nothing will be executed.
How does BrainStream handle multiple marker sources?
Currently marker information originating from one hardware data source is supported. Future developments will try to integrate a solution for multiple marker sources. Synchronization issues between the different sources then need to be resolved first.
What is the timing based on?
The BrainStream API for connected data sources instructs to return information about the number of data samples gathered after each request for new events. It is crucial to BrainStream internal processing that proper timing information is available. Therefore, interfaces between hardware and BrainStream need to prevent large buffering of information in order to keep timing accurate.
Why does BrainStream explicitly want users to define when they need access to their own variables?
One reason is that BrainStreams internal processing variable space needs to be separated from the [[BrainStreamGlossary|users variable] space (user state). Users should not be able to 'see' BrainStreams internal code processing. Another reason is that by explicitly asking for such actions, BrainStream is able to decide on which parts of the processing can be executed parallel-wise (this is an option; standard turned off). if users would like to use this feature, they are relieved from this difficult task of writing debug-free-executing parallel code.
How can I get access to constants defined in my block initialization file?
Use the value = bs_get_blockvalue(<Topic>,<Key>,<default value>) to retrieve defined constants. For example: subject = bs_get_blockvalue(event,'RunMode','Subject','no_subject');.
Does it make a difference which column I choose in the table for the markers, time or functions?
As long as they are in one of the first three columns, and before starting defining the columns with user variables, BrainStream will reorder the columns automatically.
Can I use functions to modify content of variables directly?
Yes, this is possible as long as it returns one output argument; this will then become the new content of the variable.
What does $self mean?
This is a placeholder for the actual variable it is modifying. If the name of the variable would change, you do not need to check the column for other copies of the name to be changed too.
Must I use excel to define my experiment?
No, it is also possible to define your experiment in tab-delimited text files. Although the functionality is already integrated in BrainStream, it is not yet extensively tested. Also, the column-wise presentation of information in excel files really helps to get a good overview of the actions defined per marker. This is much more cumbersome in text files. Since excel files can hold more than one sheet per file, the same functionality for text files is implemented by putting the files in the same folder.
My function updates content for a variable, but it seems to get lost. What could go wrong?
BrainStream manages an internal user workspace (the global variables) which stores all [.DocsSectionsGlossary user variables] content. If the user specifies a 'get' keyword in the experiment definition table, it will instruct BrainStream to add the content of the variable as a field to the event structure. This way, users get access to their own user variables. The other way around, if the user wants to update changed content to this user workspace, it needs to explicitly ask for this by issuing a 'put' keyword for this variable. A missing 'put' is most probably the reason why modifications are not preserved.
I defined actions at t=DATA, however nothing seems to execute?
This happens if no data selection was specified for corresponding marker. Check if the 'DataSelection' table defines data for this marker. (future versions will check the table for such failure and issue an error. For more information click here.
I get an error 'can not read data before t=0', however dataselections begintime was set to t=0 s.
If you insert a BrainStream marker with zero time-delay at the BS_INIT marker, this inserted markers timestamp will also be set to t=0. Data selection definition is interpreted relative to this timestamp. Although DataSelection begintime t=0 was specified, the extra samples required for the decimation filtering moves the start position towards values < 0. This risc exists for every marker which absolute DataSelection begintime effectual becomes a value smaller than 0.1s. Thus, inserted markers timestamp plus begintime should be larger than 0.1s, but only if data is being decimated. Data will be decimated if RunMode.SampleRateAfterDecimation is not equal to the original sample rate (either from data source or file). In case no decimation is applied, effectual DataSelection begintimes can be set to t=0 s.
I defined actions for a marker, however nothing seems to execute?
Check if the marker did pop up in the data stream. If so, check if the time point for these actions was specified in the table. (BrainStream should warn for missing time point information)
The order in which the actions are executed seems to be wrong?
Check the expanded table that is outputted in the log file and command window. If the ordering here is also wrong, check the way the [.DocsSectionsGlossary experiment definition table] will be expanded. Such error typically is caused by a wrong ordering in action definitions. For example, the main table references another table that defines user functions fnc1, fnc2, and fnc3 for marker 'analyse'. The next row in this table defines user function fnc4 for marker analyse'. The execution order will then be: fnc1, fnc2, fnc3, fnc4. However, if the definition for fnc4 is put before the reference to the other table, the execution order will be: fnc4, fnc1, fnc2, fnc3.
I use a variable to count the number of collected data epochs, however the numbers are not right, what could go wrong?
The variable responsible for counting should be modified (i.e., by a $self+1 action) and retrieved (i.e., by a 'get' keyword) both at the same time point for corresponding marker that collects the data (best practice is to do this at time point t=EVENT). It will go wrong at the moment a second marker arrives in the data stream while the first one didn't yet obtain its data, i.e., with overlapping data epochs. If the counting is done at t=EVENT and the content of the counting variable is retrieved at t=DATA, the second marker would already have increased the counting variable before the first one retrieved its content.Instead of a value equal to one it will retrieve a value equal to two.
I included a reference to another table, however, its content was not included during the table expansion.
The table can not be found on the Matlab BrainStream path or the file doesn't exist (perhaps a spelling error). References to external tables (i.e., not sheets included in the excel file) must include the extension of the file name. This tells BrainStream to search for another file instead of a local included sheet. Tables do not necessarily have to be found in the Matlab path. A full path can be included for the reference in order to directly point to its storage location; @mytable.xls (file can be found in Matlab path), or @/volumes/all_tables/mytable.xls.
Instead of specifying data epochs in time units, I would like to use samples; is that possible?
Yes, if a # symbol is placed right after the number, it will be treated as the number of samples instead of seconds. Thus 3 means three second, whereas 3# means 3 samples. The latter should be used with care since a changed sample rate will result in same length epochs (measured in samples), but different epoch lengths (measured in time). Note that for absolute time points (when actions should be executed) the same rules apply.
I inserted a marker with some time delay, however, the delay time doesn't seem to be recognized correctly.
Verify the delay time specified in the table. If this value is correct, be sure the inserted marker is not an action defined at a DATA timepoint. This will make execution time dependent of the amount of data specified if data end time exceeds the specified delay time.
Can I only use Matlab functions?
No, the functions listed in the experiment definition tables should all be Matlab functions according to the BrainStream format. Starting from these functions, the user is free to call any other Matlab functions (not restricted to BrainStream format; event=function(event)), functions implemented via mex files, java functions or any other solution standard supported by Matlab.
Can I use other user variables in expressions modifying user variables?
Yes, this is supported. Before the actual modifier expressions are executed, a copy of current content of involved user variables is preserved. This content will be used for the user variables that might pop-up in the modifier expressions.
How does !Brainstream deliver the data?
Only when a marker is associated with data (see xxx) and a timepoint t=DATA, it will get the data along with the event structure, that is: event.data.raw (channels x data).
Does BrainStream provide any standard data processing solutions?
The only supported data processing option available is decimation of the data. In the block file it can be specified which decimation factor should apply to the data (topic: RunMode, key: SampleRateAfterDecimation). In fact it is specified what the sample rate should be after decimation. BrainStream verifies if the data acquisitions' sample rate allows for decimation of the data (decimation factor should be a power of 2).
Why is the connect_brainstream_client function not connecting?
A number of actions can be taken to solve this problem. First, check the addresses or ip-addresses used. If you are trying to connect a brainstream client, it must be identified in the blockfile under the [Clients] section. Make sure it is there, and if it is, make sure the dns-name or ip-address in the blockfile matches that of the computer you are running connect_brainstream_client on. Also make sure the dns-name or ip-address you are using in the connect_brainstream_client call matches that of the machine where brainstream is running on. Second, check if there is a firewall active on the machine that is running brainstream. If there is a firewall active, make sure that ports 5001 till 5020 are open, so the client can actually connect to brainstream. You could also try to only start connecting the brainstream client after Brainstream indicates that it is listening for incoming connections.