2 Getting Started Guide

This Getting Started Guide explains the minimal steps required for the definition of an experiment managed by BrainStream. After BrainStream is installed, several files need to be composed before being able to run an experiment. The experiment definition table (section 2.2) is the core of your experiment. It specifies what actions need to be executed at a certain time point and which data need to be processed during the experiment. In addition, markers are added to the data stream making it possible to know the exact timepoints during the experiment at which certain actions occur. The actions can either be directly set in the table or you can add Matlab functions to your table which define the actions. There are some pre-defined plug-ins; for example, bad channel rejection, classification, etc. (see Plug-ins). If you need other functions than those, you have the possibility to write new functions yourself (section 2.3). After you defined your experiment, you need to compose a file(s) to initiate your experiment in BrainStream (section 2.4). Every block has a separate file, which contains or refers to all information needed to initiate the particular block. The Examples section of this documentation gives examples of the full set of definition tables and initialization files for several experiments. After finishing all these files, you are now ready to do your experiment! Section 2.5 explains how you have to start running BrainStream.

NB. This text is still under revision. If parts are unclear or missing, you can edit the text yourself or notifty someone else?

2.1 Start-up checklist

  1. Make sure BrainStream is installed correctly (see InstallationGuide)
  2. Compose a definition file for your experiment (section 2.2)
  3. Compose your own functions (section 2.3)
  4. Define file(s) to initialize your experiment (= block files) (section 2.4)
  5. Start BrainStream to run your experiment (section 2.5)

2.2 Compose an experiment definition file

The experiment definition file is the core of your BCI experiment. Here you can specify what actions need to be executed at what time. For this markers are used to ‘mark’ the timing of for example stimulus information or button responses of your participant.
The experiment definition file consists of several tables, which will be discussed below. Brainstream has its own internal editor for creating the tables, however, for backwards compatibility reasons it also supports excel files (.xls extensions only) where each table is put in a different sheet, or a set of separate text files (.txt), one for each table. Below, BrainStreams? internal editor will be used for explanation.

2.2.1 Tables

Actions table

BrainStream? tables contain one or more sheets, just like excel tables. A basic sheet consists of a marker, time, function and client column and can additionally contain an arbitrary number of variable columns. The first row of the table is the header and contains in the first four cells the words ‘marker’, ‘time’, ‘function’ and 'client' and in the remaining cells the variable names for the corresponding variable columns. The marker column tells Brainstream at what marker it has to execute an action. In the time column, the exact timing of the execution of the action can be specified in several ways. You can let an action be executed directly at marker onset, some time after the marker, when the data comes available or when another marker arrives. See table 1 for more information. The next column is the function column. Here you can specify a Matlab function that will be executed at the earlier specified time. See section 2.3 for more information on these user defined functions. The fourth 'client' column is optional, for more information see: Running BrainStream in parallel mode

Table 1.

a number
another mrk
Executed at marker onset
Executed as data becomes available
Executed number seconds after marker onset
Executed at onset of marker mrk

The subsequent columns can be used for user defined variables, i.e., variables that you need in user defined functions. If a function needs such a variable, you first need to get it from the global variables (with a ‘get’ statement in the corresponding cell). Then the function has access to it, and can for example change it. Saving the updated variable information to the global variables will only be executed if a ‘put’ statement is included in the corresponding cell. These 'get' and 'put' statements specify when data exchange with the global variables is necessary, or in other words for communication between event processing steps. To exchange information between the different sub-parts (blocks) of an experiment, user variables can be stored to disk using the 'save' and retrieved from disk using the 'load' statements. Click here for more information.Furthermore, the value of the variable can be updated with Matlab style assignments, which can even use it’s own value by using the '$self' statement or other user defined variables. (see Architecture; Modifying variables for more information)

An example of a user variable that will be used very often is a variable that contains the header information from the acquisition data file. It informs the user about the number of measured channels, their labels, and acquisition related information like the sample rate. The exact information delivered to the user can be found here.

The order of actions per incoming marker is fixed. First content of user defined variables is modified, then content of user defined variables is retrieved (for use in functions) after which the functions are executed, and finally the new variable content is stored. Below a simple example of an actions table is given. The first row (the header) defines two user variables; var1 and var2. When Brainstream receives the BS_INIT marker (time = EVENT; moment of incoming marker), first these variables are set to empty with the [] statement. Then the content of these variables becomes available via the get statement. Subsequently the init_all function is executed, which can for example change var1 and var2. This changed content is then saved via the put statement. When the marker stimulus arrives, Brainstream will execute actions at two different timepoints. First when the marker arrives (time = EVENT) it adds ‘1’ to the current value (specified with $self) of var1 and gets it. Then, when the data that is associated with the marker stimulus becomes available (see dataselection sheet below), also the content of var2 is retrieved (var1 was already made available at the EVENT processing step) and the functions preproc, and classify are executed in this order. Then the updated content of only var2 is saved wtih the put statement. You can see in the example that it is not necessary to copy the name of the marker (stimulus in this case) if more than one processing steps (time column) are necessary for the actions associated with that marker. Note also that the BrainStream is case-sensitive. Upper-case variables are reserved markers (see section 2.2.1).

Table 2.

marker time function var1 var2
BS_INIT EVENT init_all [],get,put [],get,put
stimulus EVENT   $self+1, get  
  DATA preproc,classify   get,put

It is recommended to only 'get' and 'put' variables when content is indeed required for that event. This assures fast and efficient processing of your experiment.


In the Actions table you can also refer to a different table by putting the name of the sheet or complete path to a different table (.edt) in the marker column preceded by a @. Brainstream will expand your first action sheet with all referred tables into one big table. If you just put a reference in the marker column without any further actions defined, all processing steps of the referenced table will be added tot the current table. Actions defined for a references table will be treated as default actions to all markers mentioned in the referenced table. This can be useful if you want to execute the same actions for a lot of different markers. Here you can find examples of referencing. Another reason to make such a reference is the possibility to use a plug-in that is used by many experiments, for example a bad channel detection Plug-in. This referred plug-in itself can also refer to other tables and in the end all corresponding definitions could have been spread out over many different tables. See the Plug-in section for more information about the available plug-ins and examples how to use them.

Table 2.3


The next important part of the experiment definition file is the dictionary. Since markers can potentially arrive from different sources in different formats (eg. numbers), they will first be converted into names. For this purpose a dictionary or lookup-table maps incoming marker information to the proper marker name. The first row of the dictionary table is the header and defines the marker, type, value and optional substitute and datasource column. In the marker column the marker name is specified. The type column specifies the marker type. The marker can be for example a stimulus or response marker. In the value column, the value of the marker is specified. The substitute column can be used to make a substitute for corresponding marker. Its purpose is to merge actions of other markers before or after corresponding marker, see Plug-in. Below a short example of such a dictionary table is given. If definitions involve usage of multiple data sources, the datasource column specifies for which data source the dictionary information is meant.If only one datasource is involved, it can be left out and BrainStream? will assume definitions are meant for the single data source used.

Table 4.

marker type value substitute datasource
tone stimulus 10    
voice stimulus 11    
button response 128    

The type and value information is delivered by the interface (between acquisition hardware, or a stimulus presentation module and Brainstream), and will translate into the marker names specified in the first marker column. Any table that is encountered - during expansion of the experiment definition table - that contains a sheet named 'Dictionary' will be added to the dictionary information that Brainstream uses to translate incoming markers into marker names (see Architecture for more information. In case only .txt files are used the same is true for any folder containing the file 'Dictionary.txt'. Off course information inside these tables should not conflict (for example, double definitions of marker names or numbers).


Each marker can specify a segment of data that should come along with the event. This can be specified in a separate table called 'DataSelection'. This table consists of a marker column, a begindata column, and an enddata column. Data selection may start before or after onset of the marker, inicated by negative and positive numbers respectively. The end of data selection can again be before or after the onset of the marker specified in the marker column, or you can use a new incoming marker by entering the name of the new marker (with or without extra timing). By specifying multiple endtimes (seperated by a comma) the one that happens first will end the dataselection. As is the case for the dictionary, all tables named 'DataSelection' encountered during the expansion, will define data for the markers specified. Also here, information inside the different tables should not conflict. As is the case for Dictionary tables, a datasource column serves to specify for which datasource data selection is meant. In case only one data source is involved, it can be left out and BrainStream? will assume definitions are meant for this single data source.

Table 5.

marker begintime endtime datasource
mrk1 -0.5 2  
mrk2 0.5 mrk3  
mrk3 0 mrk3, mrk4  

The table above shows an example of a data selection table. The data selection of mrk1 will start half a second before onset of the marker and end 2 seconds after the onset.The data selection of mrk2 will start half a second after the onset of mrk2 and will end when the new marker mrk3 arrives. mrk3 will start data selection immediately and this will end when a new marker mrk3 or the marker mrk4 arrives. For more examples of this data selection timing see Data-carrying events in the Architecture section.

More information about the tables can be found here: Architecture.
Examples of a plug-in is given here: Plug-ins.

More information about editing tables in the BrainStream Editor can be found here: BrainStream Editor.

2.2.2 Reserved markers

BrainStream defines a couple of reserved marker names that have special meaning and will be inserted by BrainStream in certain situations. Users can define their own actions for these markers:
BS_INIT : at startup, this marker is inserted by BrainStream and will always be the first processed marker. Use this marker to initialize your experiment (variables or acquisition related matter).
BS_EXIT : at shutdown, this marker is inserted by BrainStream and will always be the last processed marker. Use this marker to finalize your experiment.
BS_QUIT : marker triggers alternative shutdown, for example useful to discard certain actions defined for BS_EXIT, but still guarantee a normal closing of acquisition related items. For example, you would like to skip saving output to file and disk after quitting, but all acquisition related items should be normally closed.
BS_ABORT : marker triggers immediate shutdown. Do not define user actions for this marker.
BS_ACQFAILURE : marker triggers restart of acquisition (after possible failure) (WARNING: under construction)

2.2.3 Reserved variables

Users can define their own variables, as many as they like. The names must obey the Matlab variable naming convention rules (the first character isn't a number and symbols like !@#$%^&*(){}[]:;|\/?><~` are forbidden) and must not be equal to one of the reserved names in use by BrainStream. These reserved variables are listed below:

Table 6.

markermight get confused with marker column in exp.def.table
might get confused with marker column in exp.def.table
might get confused with marker column in exp.def.table
might get confused with marker column in exp.def.table
might get confused with marker column in exp.def.table
name of marker (and assoicated event)
time of execution referred to number of acquired samples
hdracquisition/file header info
trialinformation about selected data
datarequested raw data, trial information, samplerate
BRAINSTREAMused by BrainStream? internally
Acqinformation required for acquiring data (read-only)
trace_varsKeeps a list of traced variables (output in logfile)
brainstreamversionthe version of BrainStream? that you used to run your experiment

2.3 Compose user-defined functions

In the experiment definition table, certain actions are assigned to markers. The actions can be directly set in the table. You also have the possibility to specify actions by adding Matlab functions to your table at the marker on which you want these actions to be executed. The Plug-ins section of the documentation contains some pre-defined plug-ins; for example, bad channel rejection, classification, etc. If you need another function for your experiment than these, you have to write your own Matlab functions (i.e. user-defined functions). The new functions need to be written in the following format:
event = my_function(event,c1,c2,...)
The input and output argument 'event' is obligatory. It is a Matlab type structure variable, containing a copy of the current content of the default variables requested for in the table at the marker with the 'get' statement (copied as fields in the event structure). The additional input arguments (c1, c2, ...) are optional. You can enter constants there, if your function needs them. It is also possible to use one of your own defined global variables input argument. Note that such global variable needs to be available in the event structure by defining appropriate 'get' keywords for corresponding variables in the table. The purpose of the function is to manipulate certain variables in the event (i.e. execute certain actions with them). After changing the content, you can update modified variables to the global variables using a put action. An example of an user-defined function is

function event = classify(event)

% Classify
weight_matrix = event.wb;
dv = reshape(X,[],size(X,ndims(X)))'*weight_matrix(1:end-1)+weight_matrix((end);

% Calculate probability results
classprob = 1/(1+exp(-dv)); 

% Store results
event.classprob = classprob;

This function classifies the data in the event. The data can be found in the structure at event.data.raw. The function then classifies the data using a weight matrix which was stored in event.wb, and translates them into a class probability. The resulting variable (i.e. classprob) is stored in the event structure in the field classprob (i.e. event.classprob).

You can also opt to use constants in your function. In the following example, a function is showed that makes use of these constants:

event = classify_new(event,8, 12, 64)
which classifies the data making use of three constants (a frequency band of 8-12 Hz and 64 electrodes). The classification result is then stored in a field of the event-structure (e.g. event.classresult).

The function can be added to your experiment definition table at the marker on which you want to execute the actions specified in the function. Do not enter the obligatory 'event' argument, but suffice with my_function(c1,c2,...). The previous example of the function with the constants can be entered in the table as follows: classify_new(8,12,64). The variables needed in your function can be added as fields to the event structure via the 'get'-statement in the columns of these variables. If you want the modified variables to be stored for the following events, use the 'put'-statement in the same columns to update them to the global variables. These keywords make information exchange between repeated same or different events possible. In the example, a 'get' statement would be added in the columns of the variable wb. Note that the data are automatically included in the event structure. Furthermore, to store the class probability result of the classification, you need to enter a 'put' statement in the column of the variable classresult.

More information on how to implement functions can be found in the Function Index.

2.4 Define an experiment initialization file (block file)

To initiate your experiment in BrainStream, you need to compose an initialization run file(s), also called a block file. Every block has a separate file, which contains or refers to all information needed to initiate the particular block. For example, BrainStream needs to know to which data acquisition source it is connected, where to store output and where the experiment definition table is located. All this can be summarized in a text file with file name extension .blk. The format of the file is according to the Windows .ini file style with 'topics' enclosed in brackets and subsequent lines to define 'keys' that belong to this 'topic'. If another bracketed line is encountered, a new 'topic' is started and additional lines will add 'keys' to this new 'topic'. An example of how such a file looks like is shown below. In this example, all minimally required topics with their keys are shown.

eeg = 'buffer://localhost:1972:biosemi_active2'

% keys specific to the eeg data source 

sendMarkerFunction = 'sndMidiMarker'

BrainStream.ExperimentDefinitionFile = '/Volumes/Data/ExpDefs/SubRhythm/SubjectiveRhythm.xls'
BrainStream.OutFolder = '/Volumes/Data/Experiment/'

Block = 'subjective_rhythm'

Additional possible topics with their keys are listed here: DocsSectionsBlockFile.

The notation of the topics and keys is in Matlab style, which means that every valid Matlab statement is possible here. For example, Matlabs comment character (%) can be utilized. To check whether the block file contains correct statements and values, you can access the topics and keys in your file with the function bs_get_blockvalue(). You can enter this function in Matlab with the block file as an input argument between the brackets. Matlab will then display the information contained in the file. Another functionality of the file is that you can add your own information (constants) to them. The advantage is that these items are readily accessible for your own written Matlab user functions throughout the whole experiment (see section 2.3). You can add your own topics and keys as long as they are not used by BrainStream itself. In your own written functions, you can access the items in the block file by using the function in the following way:

item = bs_get_blockvalue(event,'topic','key',<default>)
The value of a certain key in a certain topic will be assigned to the variable item. If the topic/key combination is not present in the block file, Matlab will generate an error message. You can also give it a name in the argument 'default'. In other words, if the topic/key combination is not present in the block file, Matlab assigns the name you entered as an argument in 'default' to the variable item. The Function Index describes this function more extensively including an example.

If experiments involve execution of several blocks, references to those blocks can be put together in a single seperate 'BrainStream Project' (bsp) file (in block file format) with topics [Blocks] and [CommonBlocks]. Both topics define the 'Files' key, in which a cell array of block file names defines which block files take part in the experiment. Note that this 'experiment' text file has to be saved with the extension .bsp (i.e. experiment file), or .exp for older files. This single file then defines your whole BCI experiment. For example, if your experiment is defined by three functional blocks, namely train.blk, classifier.blk and feedback.blk, and one common block file lab1.blk, the following poject file (i.e. the .bsp file) would be sufficient to include them all at once when starting BrainStream:

Files = {'/Volumes/my_experiments/my_BCI/train.blk', ...
         '/Volumes/my_experiments/my_BCI/classifier.blk', ...
Files = {'lab1.blk'}  
If this project file is stored at the following location:
any file specified in this project file can be referenced against this folder. i.e., train.blk is located in: /Volumes/my_experiments/my_BCI/train.blk. A file '../myblock.blk' would be located: /Volumes/my_experiments/myblock.blk. A file not found in the project folder will be searched for on the Matlab path, if it is still not found, an error will be given.
Always try to prevent using absolute file names since it makes copying project definitions local dependent.
If file names can be dynamically created using one of BrainStreams? folders, it is advised to do so.
Names of BrainStreams? folders are accessedthrough the bs_folder function, like this:

See section on ... how to use this function.
All once loaded 'experiment' files can lateron be selected from a list if the function start_brainstream is executed without any input arguments.

More information about editing block files in the BrainStream Editor can be found here: BrainStream Editor.

2.5 Start BrainStream

2.5.1 Graphical User Interface (GUI)

If you finished all the necessary pieces for the experiment, you can use the Grapical User Interface (GUI) of BrainStream to run your experiment.

General start up of the GUI

To start the BrainStream GUI, you first need to open Matlab. Then, type the following in the command window: start_brainstream. This will automatically start the GUI. The function also has three optional input arguments, with which you can call it, namely:

start_brainstream(blockfile [,setmatlabpathfunction,blockfiles_startpath,commonblockfiles_startpath ]) 


  • blockfile: filename of your block initialization file (include (relative) path information or make sure it can be found in Matlab path, see section 2.4)
  • setmatlabpathfunction (optional): function that handles setting Matlab path (see [BrainStreamDocs.[DocsSectionsInstallationGuide][InstallationGuide]])
  • blockfiles_startpath (optional): starting point for browsing block files
  • commonblockfiles_startpath (optional): starting point for browsing common block files or specified common block file.

These input arguments have to be entered as type 'string'. If the setting of the proper Matlab path is taken care of beforehand (see InstallationGuide) or the proper Matlab path is defined in the block file, the argument setmatlabpathfunction can be ommitted. The arguments blockfile, blockfiles_startpath and commonblockfiles_startpath are also optional, since these options can also be selected in the GUI itself after startup. In general, it is adviced to set the Matlab path via blockfile settings and not via setmatlabpathfunction argument at startup of this function. This is only useful if all blocks would require the same Matlab path setting.

2.5.2 Command window startup (no GUI)

An alternative way to use BrainStream is without the GUI. If you want to do this, you will only use the Matlab command window. BrainStream can be started in the command window using an existing .blk file in the following way:

start_brainstream_nogui(block_file [,subject,user_folders])


  • block_file: filename of your block initialization file (include (relative) path information or make sure it can be found on Matlab path, see section 2.4). If also common block files are required, specify a cell array fo block files in order of relevance (settings of earlier mentioned block file in this list overwrite same settings specified in subsequently listed block files).
  • subject (optional): name of the subject (default = 'test')
  • user_folders (optional): cell array with paths you need for the experiment. This argument is not obligatory. If you need specific folders to be in your Matlab path, you can enter them as a cell array.

The following example shows you what to enter in the command window when you want to start BrainStream using already installed paths (see InstallationGuide): start_brainstream_nogui('bci_example1.blk','subject').
In the next example, we want to start BrainStream, but we also want to add the folders containing code for the cap montage and the artefact detection to the Matlab path: start_brainstream_nogui('bci_example1.blk','subject',{/Volumes/MyCode/CapMontage,/Volumes/MyCode/EpochArtifacts}).

A second function availabe for starting BrainStream without the GUI is brainstream_block(blocksettings). To use this the argument 'blocksettings' needs to be available in a Matlab type structure variable. Topics from the block file become fields of this structure and, sebsequently, keys become subfields of these fields. You can obtain the blocksettings in two ways:

  • Translate an existing block file into the blocksettings structure using the function:
    blocksettings = bs_get_blockvalue(blockfile), in which blockfile is the name of your block file (i.e. .blk file).
  • Generate manually in Matlab. The following example contains the minimally required items to start BrainStream without the GUI using this method:
        blocksettings.DataSources.eeg = 'buffer://localhost:1972:my_device';
        blocksettings.RunMode.Subject = 'a_subjects_name';
        blocksettings.Files.ReferenceFolder = '/Volumes/exps/defs/my_project/';
        blocksettings.Files.ExperimentDefinitionFile = '/Volumes/exps/defs/my_project/my_block.edt';
        blocksettings.Files.OutFolder = '/Volumes/data/my_project/';
        blocksettings.Experiment.Block = 'my_block';
    Note that the blocksettings when starting BrainStream without the GUI need to contain two extra items, namely RunMode.Subject and Files.Referencefolder. In contrast, when starting the experiment via the GUI these are automatically included.

After obtaining the blocksettings structure, enter brainstream_block(blocksettings) in the Matlab command window to start BrainStream.

Topic revision: r1 - 09 Nov 2009 - 18:06:19 - MarianneSeverens
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback