Jump to content

User Reference:Operator Module Scripting: Difference between revisions

From BCI2000 Wiki
Mellinger (talk | contribs)
Mellinger (talk | contribs)
 
(244 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Operator scripts automate actions that the otherwise would be performed by the user, e.g. starting or suspending system operation.
Operator scripts automate actions that the otherwise would be performed by the user, e.g. starting or suspending system operation.
Scripts may be contained in script files, or given immediately in the operator module's preferences dialog.
Scripts may be contained in script files, or given immediately in the operator module's preferences dialog.
There is also an option to specify scripts from the [[User Reference:Module Command Line Options#Operator Module|command line]] when starting the operator module. When using the [[Technical_Reference:Operator_Library|Operator Library]] from your own application, you may execute scripts at any time.
There is also an option to specify scripts from the [[User Reference:Module Command Line Options#Operator Module|command line]] when starting the operator module. When using the [[User_Reference:BCI2000Shell|BCI2000Shell]], or the [[Technical_Reference:Operator_Library|Operator Library]] from your own application, you may execute scripts at any time.


Also, the operator scripting language is used to control an operator module over a telnet connection.
In addition, the operator scripting language may be used to control an operator module over a [[User_Reference:Module_Command_Line_Options#--Telnet|Telnet]] or [[User_Reference:Module_Command_Line_Options#--WebSocket|WebSocket]] connection.
===Syntax===
'''Command separation.''' Scripts consist of sequences of the commands listed below. A command must be terminated with either a newline, or a semicolon (;).
This allows to put multiple commands into one line, separated by semicolon characters.
Commands are case-insensitive, variables and values may be case-sensitive, depending on context.
 
'''Comments.''' Lines starting with a '#' character are ignored. Such lines may be used to hold comments. In addition, when any of the first two lines of a script contains "#!" (the Unix shell invocation sequence), it will be ignored. In conjunction with [[User Reference:BCI2000Shell|BCI2000Shell]], this may be used to write Operator scripts that may be treated as executables.
 
'''Escaping.''' In order to resolve ambiguity about command arguments that contain white space, they must be included in double quotes, or the white space must be encoded in URL-fashion, e.g. ''%20'' instead of a space character. Similarly, when an argument contains a semicolon (;), it must be included in double quotes, or the semicolon must be encoded in URL-fashion, i.e. as ''%3B''. Also, "$" characters indicate command substitution, so they should be encoded as ''%24'' if substitution is not desired.
 
'''Variable Substitution.''' When a command contains a dollar sign, alphanumeric characters following the dollar sign will be interpreted as the name of a variable: $NAME. The name will be matched against Expression variable names first, followed with Local variable names, and finally Environment variable names. When a match is found, $NAME will be replaced with the content of the matching variable. When no match is found, $NAME will be resolved to an empty string, without triggering an error.


===Events===
'''Command Substitution.''' When part of a command is enclosed with ${...}, this subexpression will be substituted with the result of its execution as a command. E.g.,
In the Operator GUI, script execution is bound to a number of events that occur during various [[Technical Reference:States of Operation|stages of BCI2000 system operation]]:
LOG "Current system state is: ${GET SYSTEM STATE}"
====OnConnect====
LOG "The path environment variable is: ${PATH}"
This event is triggered at startup, as soon as all modules are connected to the operator module.
Note that the last example uses the short form of the GET command, which will return the value of a PATH parameter or a PATH state if such exists. To make sure that only environment variables are matched, use the long form of the GET command:
====OnSetConfig====
LOG MESSAGE "The path environment variable is: ${GET VARIABLE PATH}"
This event is triggered each time a set of parameters is applied to the system. This happens when the user clicks the ''SetConfig'' button. Execution of the ''SETCONFIG'' command also triggers this event.
<!--
====OnStart, OnResume====
Substitutions may be nested, i.e. the following will work as expected:
These events correspond to the ''Start''/''Resume'' button. One of these events is also triggered when the ''Running'' state variable is set to 1 from a script. Whether ''OnStart'' or ''OnResume'' is triggered depends on whether the system has been running before with the current set of parameters.
SET MyVar "LIST STATES"; LOG "States are: ${$MyVar}"
====OnSuspend====
SET MyVar "LIST STATES"; LOG "States are: ${${GET VARIABLE MyVar}}"
Triggered when the system goes from running into suspended mode. This happens whenever the ''Running'' state variable changes from 1 to 0. This may happen when the user clicks ''Suspend'', when the application module switches the system into suspended mode, or when a script sets the ''Running'' state variable to 0.
-->
====OnShutdown====
Triggered when the operator module shuts down connections, and switches into idle state.


====OnExit====
'''Mathematical Expressions.''' A command may consist of a single [[User Reference:Expression Syntax|mathematical expression]]. This expression is then evaluated, and its result is returned as the command's result. As a special case, this allows the use of expression variables in ${...} substitutions. Consider for example
Triggered when the operator module exits. Execution of the QUIT command also triggers this event. This event is not available to the SET SCRIPT and CLEAR SCRIPT commands. Also, when both an OnShutdown and an OnExit script are defined, the OnExit script will be executed before the OnShutdown script.
x:=0; WHILE x<10; LOG ${x:=x+1}; END
There, the first command creates and initializes the expression variable x. In the WHILE condition, an expression is allowed as well as any command. In the LOG command, an expression appears in ${...}, which executes the expression in braces, and substitutes the result of the expression as an argument into the LOG command, which adds an entry to the Operator log. This results in a sequence of 10 log entries, containing the numbers from 1 to 10.


===Commands===
===Commands===
====Control commands====
These commands allow conditional execution of parts of a script. When a condition is expected, any other scripting command may be given. Its result will be considered to represent a boolean value of "true" if it is empty, a nonzero number, or the string "true". It will be taken to represent a boolean value of "false" if it contains a numeric value of zero, or any string that does not evaluate to a nonzero number. Note that identification of an empty value with "true" differs from string handling in the EVALUATE CONDITION command. This is because most scripting commands return nothing on success, but an error message on failure.
The output of the SYSTEM and START EXECUTABLE commands is handled specially. There, the result code of the created child process is translated into a boolean value in the ordinary manner, treating a result code of zero as "true", and any other result code as "false". This allows to use external commands in the same way as in a native shell.
=====IF <condition>; <if commands>; [ ELSEIF <condition>; <elseif commands>;] ... [ ELSE; <else commands>;] END=====
Executes ''if commands'' if ''condition'' evaluates to "true". Otherwise, the ''elseif commands'' of the first matching ''elseif condition'' are executed. When none of the ''elseif conditions'' evaluates to "true",  ''else commands'' are executed. ELSEIF and ELSE blocks may be omitted.
=====WHILE <condition>; <loop commands>; END=====
Executes ''loop commands'' while ''condition'' evaluates to ''true''.
=====DO; <loop commands>; UNTIL <condition>=====
Executes ''loop commands'' until ''condition'' evaluates to ''true''.
=====FOR <name> IN <item1> <item2> ... ; <loop commands>; END=====
Creates a local variable with the specified name. Then, sequentially assigns each ''item'' to that variable, and executes ''loop commands''. If an ''item'' contains newline characters, it is split up into multiple items, corresponding to the lines contained in the ''item''. E.g.,
FOR i IN top ${LIST FILES} bottom; LOG ${i}; END
will first write a log entry "top". Then, it will create a log entry for each file in the current directory, and finally, it will create a log entry "bottom".
=====RETURN [<value>]=====
Finishes execution of the current script, and optionally returns a value to the caller.
====Commands operating on Conditions====
=====EVALUATE CONDITION <left> [<op> [<right>]]=====
Evaluates a comparison between the ''left'' and ''right'' operands. As a comparison operator, the following may be specified: ==, !=, ~=, <, >, <=, >=. There, the != operator behaves identically to the ~= operator. When a test for equality is performed, the two operands are treated as strings, and compared in a case-insensitive manner. When any of the inequality tests is performed, the two operands are converted into floating-point numbers before comparison.
The ''right'' operand may be omitted, in which case it is treated as if an empty string were specified. Also, the ''op'' operator may be omitted, in which case the following rules apply regarding the remaining operand: If it is an empty string, or equal to the string "false" in case-insensitive comparison, the result is "false". If entirely consists of the text representation of a floating-point number, the result is "false" if the number is 0, and "true" if the number is not 0.
Inspired by the unix sh shells' <tt>test</tt> command, there exists a short form of the EVALUATE CONDITION command, where the arguments of EVALUATE CONDITION may appear within square brackets. This allows constructs such as
IF [ ${MyVar} == MyValue ]; LOG Is equal; ELSE; LOG Is different; END
Note that the arguments to EVALUATE CONDITION must always be separated by white space, no matter whether its long or short form is used.
Conditions may be combined logically using the operators && and ||.  These go ''outside'' the square brackets.  Note also that whitespace around the comparison operators is critical, otherwise the conditional will be treated as a single string (which will always evaluate to "true")
IF [ ${foo} == foo ] || [ ${bar} == bar ]; LOG got a match; END
====Commands operating on Local Variables====
Besides environment variables, there exist local variables in scripts. Local variables are inherited by sub-scripts executed with the EXECUTE SCRIPT command, but changes to the variable's values will not be propagated to the calling script.
=====SET VARIABLE <name> <value>=====
Sets the named variable to the specified value.
=====CLEAR VARIABLE <name>=====
Removes the named variable from memory.
=====GET VARIABLE <name>=====
Returns the variable's current value. When the variable does not exist, an empty value is returned rather than an error message generated.
====Commands operating on Environment Variables====
These scripting commands allow to read and modify environment variables. Changes to environment variables will be visible to child processes started with SYSTEM or START EXECUTABLE. Variable values are stored as strings. Variable names may not contain the equals sign.
=====SET ENVIRONMENT <name> <value>=====
Sets the named variable to the specified value.
=====CLEAR ENVIRONMENT <name>=====
Removes the named variable from memory.
=====GET ENVIRONMENT <name>=====
Returns the variable's current value. When the variable does not exist, an empty value is returned rather than an error message.
=====WRITE ENVIRONMENT <fileName> <variableName1> <variableName2> ...=====
Writes a series of SET ENVIRONMENT statements to the specified file, overwriting any previous file contents.  This saves the values of the named variables in such a way that you can later load them back by calling EXECUTE SCRIPT <filename>. The variable names may refer to either local or environment variables at the time of writing, but when you execute the script they will all be loaded as environment variables.
=====APPEND ENVIRONMENT <fileName> <variableName1> <variableName2> ...=====
This is the same as WRITE ENVIRONMENT, except that the SET ENVIRONMENT statements are appended to the named file without overwriting its previous contents.
====Commands operating on Scripts====
====Commands operating on Scripts====
=====SET SCRIPT <events> <scripting commands>=====
=====SET SCRIPT <handler names> <scripting commands>=====
Associates a sequence of scripting commands with the given events. Events are specified by names as given [[#Events|above]]. Multiple events may be specified by concatenating their names with a pipe character, e.g. "OnStart|OnResume".
Associates a sequence of scripting commands with the named handler. Handlers are specified by names as given [[#Handlers|below]]. Multiple handlers may be specified by concatenating their names with a pipe character, e.g. "OnStart|OnResume".


Scripting commands must be included in double quotes, unless they consist of a single word.
Scripting commands must be included in double quotes, unless they consist of a single word.
When specifying a sequence of scripting commands, they must be separated with a semicolon character: "SetConfig; Start". In order to use double quotes or semicolons within the commands themselves, encode these as you would in an URL, i.e. replace a double quote character with ''%22'', and a semicolon with ''%3B'': "Load Parameters %22my file%22".
When specifying a sequence of scripting commands, they must be separated with a semicolon character: "SetConfig; Start". In order to use double quotes or semicolons within the commands themselves, encode these as you would in a URL, i.e. replace a double quote character with ''%22'', and a semicolon with ''%3B'': "Load Parameters %22my file%22".


To associate an event with a script file rather than a literal script, use the EXECUTE SCRIPT command:
To use a script file rather than a literal script, use the EXECUTE SCRIPT command:
  SET SCRIPT OnConnect "EXECUTE SCRIPT myscript.txt"
  SET SCRIPT OnConnect "EXECUTE SCRIPT myscript.txt"


=====CLEAR SCRIPT <events>=====
=====GET SCRIPT <handler name>=====
Clears scripts for the given events. Equivalent to calling SET SCRIPT with an empty script.
Returns the script associated with the specified handler.
 
=====CLEAR SCRIPT <handler names>=====
Clears scripts for the given handlers. Equivalent to calling SET SCRIPT with an empty script.
 
=====EXECUTE SCRIPT <file or handler name> [<Arg1> <Arg2> ... <Arg9>]=====
Executes a script contained in a file, and optionally sets the script's local variables ''1'' to ''9'' to the specified values. To execute script commands already associated with a handler, provide a handler name rather than a file. When the script is executed successfully, the result of the last executed script command becomes the result of the EXECUTE SCRIPT command itself. Use "RETURN <value>" anywhere in a script in order to finish execution, and return a certain value.
 
When you run a script through EXECUTE SCRIPT, it will inherit copies of variables from its calling script/command line. Modifications of variables will be local to the script, and will be lost when script execution is complete.


=====EXECUTE SCRIPT <file or event>=====
The ''AbortOnError'' variable determines whether a script is aborted when any of its commands result in an error message. ''AbortOnError'' is not inherited but defaults to 1 in any script.
Executes a script contained in a file. To execute a script associated with an event, provide an event name rather than a file.


====Commands operating on Parameters====
====Commands operating on Parameters====
Line 43: Line 115:
As the parameter file name must not contain white space, please use HTML-type encoding for white space characters, such as <tt>Documents%20and%20Settings</tt> when referring to a user's "Documents and Settings" folder.
As the parameter file name must not contain white space, please use HTML-type encoding for white space characters, such as <tt>Documents%20and%20Settings</tt> when referring to a user's "Documents and Settings" folder.


=====INSERT PARAMETER <parameter definition>=====
NOTE: Only those parameters will be loaded that do exist at the time when this command is called. In idle state, no parameters exist other than created by ADD PARAMETER. After modules are connected and have published their parameters to the Operator module, a full set of parameters exists.
Adds a parameter to the system. The parameter is specified as a [[Technical_Reference:Parameter_Definition#Parameter_Lines|parameter line]]. This command may not be used after system initialization has completed, i.e. its use is restricted to the "Idle" and "Publishing" [[Technical_Reference:States_of_Operation#Publishing_Phase|phases of system operation]]. In terms of events, its use is restricted to the ''OnConnect'' event.
 
=====SET PARAMETER <name> <value>=====
=====ADD PARAMETER <parameter definition>=====
Sets the named parameter to the specified value. Values that contain special characters, or whitespace must use the [[Technical_Reference:Parameter_Definition#Special_Characters|parameter value encoding]]. Use parentheses to specify indices or labels.
Adds a parameter to the system. The parameter is specified as a [[Technical_Reference:Parameter_Definition#Parameter_Lines|parameter line]]. This command may not be used after system initialization has completed, i.e. its use is restricted to the "Idle" and "Publishing" [[Technical_Reference:States_of_Operation#Publishing_Phase|phases of system operation]]. In terms of handlers, its use is restricted to the ''OnConnect'' handler.
=====EXISTS PARAMETER <name>=====
Returns "true" when the specified parameter exists in the system, and "false" otherwise.
 
=====ISEMPTY PARAMETER <name>=====
Returns "true" when the specified parameter exists and has no values, "false" if it exists and has values.
 
=====SET PARAMETER <name>[( idx1, idx2 )] <value>=====
Sets the named parameter to the specified value. Values that contain special characters, or whitespace must use the [[Technical_Reference:Parameter_Definition#Special_Characters|parameter value encoding]]. Use parentheses to specify indices or labels. Omitted indices default to 1.


=====SET PARAMETER <parameter line>=====
=====SET PARAMETER <parameter line>=====
Replace a parameter's value and definition with the information given in the [[Technical_Reference:Parameter_Definition#Parameter_Lines|parameter line]]. The parameter must exist in the system when this command is executed.
Replace a parameter's value and definition with the information given in the [[Technical_Reference:Parameter_Definition#Parameter_Lines|parameter line]]. The parameter must exist in the system when this command is executed.
0


=====GET PARAMETER <name>=====
=====GET PARAMETER <name>[( idx1, idx2 )]=====
Prints the value of the named parameter. Use parentheses to specify indices or labels.
Prints the value of the named parameter. Use parentheses to specify indices or labels.
=====SET PARAMETERROWS <parameter name> <rows>=====
Sets the number of rows in the named parameter.
=====GET PARAMETERROWS <parameter name>=====
Prints the number of rows in the named parameter.
=====SET PARAMETERCOLS <parameter name>=====
Sets the number of columns in the named parameter.
=====GET PARAMETERCOLS <parameter name>=====
Prints the number of columns in the named parameter.
=====LIST PARAMETER <wildcard expression>, LIST PARAMETERS=====
=====LIST PARAMETER <wildcard expression>, LIST PARAMETERS=====
Prints all parameters with names matching the wildcard expression, in form of parameter lines.
Prints all parameters with names matching the wildcard expression, in form of parameter lines.
Line 60: Line 152:


====Commands operating on States====
====Commands operating on States====
=====INSERT STATE <name> <bit width> <initial value>=====
In BCI2000, there are three types of States that differ in their alignment to brain signal data (see [[Technical_Reference:State_Definition#Kinds_of_States|Kinds of States]]). This section applies to both Stream States, and normal States.
Adds a state variable to the system. State variables are defined by name, bit width, and initial value (see [[Technical Reference:State Definition]]). This command may not be used after system initialization has completed, i.e. its use is restricted to the "Idle" and "Publishing" [[Technical_Reference:States_of_Operation#Publishing_Phase|phases of system operation]]. In terms of events, its use is restricted to the ''OnConnect'' event.
For Event States, see the next section.
=====SET STATE <name> <value>=====
 
Sets the named state variable to the specified integer value. Setting the ''Running'' state to 1 will start system operation, setting it to 0 will suspend the system.
=====ADD STATE <name> <bit width> <initial value>=====
=====GET STATE <name>=====
Adds a state variable to the system. State variables are defined by name, bit width, and initial value (see [[Technical Reference:State Definition]]). This command may not be used after system initialization has completed, i.e. its use is restricted to the "Idle" and "Publishing" [[Technical_Reference:States_of_Operation#Publishing_Phase|phases of system operation]]. In terms of handlers, its use is restricted to the ''OnConnect'' handler.
=====EXISTS STATE <name>=====
Returns "true" when the specified state exists in the system, and "false" otherwise.
 
=====SET STATE <name> <value>, SET STATES <name1> <value1> <name2> <value2> ...=====
Sets the named state variable to the specified integer value by sending a state message to the source module.
Setting the ''Running'' state to 1 will start system operation, setting it to 0 will suspend the system.
 
<tt>SET STATES</tt> will atomically set the values of multiple states.
 
=====GET STATE[(<sample>)] <name>=====
Gets the value of the named state. Note that state values are not updated from the application module when the ''OperatorBackLink'' parameter is 0. In that case, GET STATE will return the state's initial value.
Gets the value of the named state. Note that state values are not updated from the application module when the ''OperatorBackLink'' parameter is 0. In that case, GET STATE will return the state's initial value.
An optional one-based sample index may be given to indicate that the state value should be retrieved at the given sample position. Sample positions range from 1 to the number of samples per block present in the state vector. The number of samples per block may be retrieved using GET STATEVECTOR SAMPLES.
By default, the state's value is retrieved for sample index 1.
=====LIST STATE <wildcard expression>, LIST STATES=====
=====LIST STATE <wildcard expression>, LIST STATES=====
Lists all states, or states with names matching the given wildcard expression, in form of state lines.
Lists all states, or states with names matching the given wildcard expression, in form of state lines.
=====CLEAR STATES=====
=====CLEAR STATES=====
Clears the list of states in the system. May only be executed in ''Idle'' and ''Publishing'' system states.
Clears the list of states in the system. May only be executed in ''Idle'' and ''Publishing'' system states.
=====FREEZE STATES, THAW STATES=====
Freezes/thaws the values of all states in the state vector, without interfering with system operation.  "Freezing" creates, and "thawing" discards, a frozen snapshot of the state vector. For the duration of its existence, GET STATE calls will be diverted to the snapshot.  This is useful for ensuring that multiple GET STATE commands actually retrieve mutually-consistent values from different state variables (i.e. values from the same sample-block).
=====GET STATEVECTOR SAMPLES=====
Returns the number of samples in the state vector per block of data. In the system's "Running" state, this matches the number of samples per block in the source data. Prior to the "Running" state, this command returns 1 because the state vector has not yet been updated from the application module.


====Commands operating on Events====
====Commands operating on Events====
Events are a special type of state, which are recorded asynchronously, at single-sample resolution. Events may only be added while the system is in "idle" state.
Events are a special type of state, which are recorded asynchronously, at single-sample resolution. Events may only be added while the system is in "idle" state. This kind of events is not related to [[#Handlers|Operator Events]] as defined below.
=====INSERT EVENT <name> <bit width> <initial value>=====
=====ADD EVENT <name> <bit width> <initial value>=====
Adds an event to the system. Like state variables, events are defined by name, bit width, and initial value (see [[Technical Reference:State Definition]]). This command may not be used after the system has started up, so it is typically executed within a telnet session before ''STARTUP'' has been called.
Adds an event to the system. Like state variables, events are defined by name, bit width, and initial value (see [[Technical Reference:State Definition]]). This command may not be used after the system has started up, so it is typically executed in a batch file before ''STARTUP'' has been called.
 
=====EXISTS EVENT <name>=====
Returns "true" when the specified event exists in the system, and "false" otherwise.
 
=====SET EVENT <name> <value>=====
=====SET EVENT <name> <value>=====
Asynchronously sets an event to the given value. Recording events requires the EventLink logger component to be present in the source module.
Asynchronously sets an event to the given value. Recording events requires the EventLink logger component to be present in the source module.
=====GET EVENT <name>=====
 
'''NOTE:''' In versions prior to BCI2000 3.06, this command behaved as described for PULSE EVENT below, rather than as advertised. If you used SET EVENT in your scripts, it is recommended to replace it with PULSE EVENT in order to retain original behavior.
 
=====PULSE EVENT <name> <value>=====
Asynchronously sets an event to the given value for a single sample duration. Recording events requires the EventLink logger component to be present in the source module.
 
=====SET EVENTS [<name> <value>] [<name2> <value2>] ... =====
Asynchronously sets given events to their specified values. Using this command, rather than multiple SET EVENT commands in a row, ensures that all event changes are recorded at exactly the same point in time. Recording events requires the EventLink logger component to be present in the source module.
 
=====PULSE EVENTS [<name> <value>] [<name2> <value2>] ... =====
Asynchronously sets given events to their specified values for a single sample duration. Using this command, rather than multiple PULSE EVENT commands in a row, ensures that all event changes are recorded at exactly the same point in time. Recording events requires the EventLink logger component to be present in the source module.
 
=====GET EVENT[(<sample>)] <name>=====
Gets the value of the named event. Note that evemt values are not updated from the application module when the ''OperatorBackLink'' parameter is 0.
Gets the value of the named event. Note that evemt values are not updated from the application module when the ''OperatorBackLink'' parameter is 0.
An optional one-based sample index may be given to indicate that the event's value should be retrieved at the given sample position. Sample positions range from 1 to the number of samples per block present in the state vector. The number of samples per block may be retrieved using GET STATEVECTOR SAMPLES.
By default, the event's value is retrieved for sample index 1.
=====LIST EVENT <wildcard expression>, LIST EVENTS=====
=====LIST EVENT <wildcard expression>, LIST EVENTS=====
Lists all events, or events with names matching the given wildcard expression, in form of state lines.
Lists all events, or events with names matching the given wildcard expression, in form of state lines.
Line 87: Line 221:
=====SET VISPROPERTY <visID>.<name> <value>=====
=====SET VISPROPERTY <visID>.<name> <value>=====
Sets the named [[Technical Reference:Visualization Properties|visualization property]] for the specified visualization ID to the given value. If the visualization ID contains a dot character, it must be encoded in [[Technical_Reference:Parameter_Definition#Special_Characters|parameter value encoding]]. E.g., setting the window width for the visualization ID "2.D1" would be written <code>SET VISPROPERTY 2%2ED1.Width 200</code>.
Sets the named [[Technical Reference:Visualization Properties|visualization property]] for the specified visualization ID to the given value. If the visualization ID contains a dot character, it must be encoded in [[Technical_Reference:Parameter_Definition#Special_Characters|parameter value encoding]]. E.g., setting the window width for the visualization ID "2.D1" would be written <code>SET VISPROPERTY 2%2ED1.Width 200</code>.
=====RESET VISPROPERTY <visID>.<name>=====
Removes the named visualization property with the specified visualization ID from the property store, effectively resetting its value to its default.
=====GET VISPROPERTY <visID>.<name>=====
=====GET VISPROPERTY <visID>.<name>=====
Prints the value of the named [[Technical Reference:Visualization Properties|visualization property]] for the specified visualization ID.
Prints the value of the named [[Technical Reference:Visualization Properties|visualization property]] for the specified visualization ID.
Line 96: Line 234:
=====GET SIGNAL( <channel index>, <element index> )=====
=====GET SIGNAL( <channel index>, <element index> )=====
Prints the value of the control signal at the given indices. Indices are 1-based.
Prints the value of the control signal at the given indices. Indices are 1-based.
=====GET SIGNAL CHANNELS=====
Prints the number of channels in the control signal.
=====GET SIGNAL ELEMENTS=====
Prints the number of elements (samples) in the control signal.
=====FREEZE SIGNAL, THAW SIGNAL=====
Freezes/thaws the contents of the control signal, without interfering with system operation. "Freezing" creates, and "thawing" discards, a frozen snapshot of the control signal. For the duration of its existence, GET SIGNAL calls will be diverted to the snapshot. This is useful for ensuring that multiple GET SIGNAL commands actually retrieve mutually-consistent values from different elements in the control signal (i.e. values from the same sample-block).
====Commands operating on Expressions====
=====EVALUATE EXPRESSION <expression>=====
This command treats the remainder of the command as a literal mathematical expression (for a description, see [[User Reference:Expression Syntax]]). An expression may contain assignments to variables; such variables may then be used in later expressions. Note that expression variables are different from local and environment variables that may be accessed by GET/SET VARIABLE/ENVIRONMENT. Expression variables hold numerical values, while local and environment variables hold string values. Also, environment variables are accessible to child processes started with SYSTEM or START EXECUTABLE, while expression variables are accessible only to scripts. When a script is executed using the EXECUTE SCRIPT command, it will inherit a copy of all expression variables present. Changes to these variables from the executed script will not be visible in the parent script.
=====CLEAR EXPRESSION VARIABLE <name>=====
Clears the named expression variable from storage.
====Commands operating on Watches====
A "Watch" is an object that consists of a set of expressions, and an action. Whenever the value of any of the expressions changes, the watch is "triggered", and the action is executed. Watches allow client applications to respond to BCI2000 state changes in a reliable manner. Rather than polling information from BCI2000, a client may create a watch to be notified about changes of interest. This avoids the problem of missing short-lived changes, which is inherent in the polling approach.
For watches created through operator scripting, the action consists of dumping values of all the expressions to a UDP port.
The intended use of a watch from a client application is to create a separate thread that reads from the watch's UDP port in a blocking mode, and calls an appropriate handler function whenever it receives data.
The data sent will consist of a single UDP packet with a single line in ASCII format, terminated with a CRLF sequence. The line consists of tab-separated data fields, which contain the current values of the expressions specified when creating the watch. In addition, the first field contains a time stamp in milliseconds. This time stamp represents the point in time where the expression value changed, with an accuracy of a single sample.
=====ADD WATCH [decimate <n>] <expression1> <expression2> ... [AT <ip:port>]=====
Adds a watch for the listed expressions. Each expression's value will be reported in a separate field. When an address is specified in <tt>ip:port</tt> format, the watch tries to open that port for output, and creation fails if that port is taken. When no address is specified, a free port is chosen automatically. In both cases, successful creation of the watch is indicated by returning the output address in ASCII format. The address is also used to uniquely identify a watch in the context of a connection.
When a ''decimate <n>'' clause is present, the watch will be created with decimation, i.e. it will only be evaluated for every ''n''th
sample of the state vector.
If a watch is created through a remote connection, it will use the remote host's external IP address for automatically chosen addresses. Otherwise, the output port will be associated with the machine's <tt>localhost</tt> address.
Watches may be created even if the system is currently running. In this case, the watch is triggered immediately at creation, and sends its current expression values to its output port.
=====ADD WATCH SYSTEM STATE [AT <address>]=====
Similar to the first variant of ADD WATCH, but will watch the system's state as reported by GET SYSTEM STATE.
=====CLEAR WATCH <address>, CLEAR WATCHES [<wildcard-expression>]=====
Removes the watches specified by address, or those with their addresses matching a wildcard expression. If CLEAR WATCHES is called without argument, all watches will be deleted.
=====TRIGGER WATCH <address>, TRIGGER WATCHES  [<wildcard-expression>]=====
Forces dumping of the watches' current expression values to their output ports. Mostly useful for testing purposes.
=====LIST WATCHES  [<wildcard-expression>]=====
Displays a list of existing watches, and their addresses.
=====COUNT WATCHES  [<wildcard-expression>]=====
Returns the number of existing watches, or the number of watches whose addresses match the optional wildcard expression.
====Commands operating on Files, Directories, and Paths====
=====EXTRACT DIRECTORY <path>, EXTRACT FILE <path>, EXTRACT FILE BASE <path>=====
Extracts the directory or file portion of a given path. When the path specifies a non-existing directory, the directory name must be followed with a separator ("/") in order to be recognized as a directory. The EXTRACT DIRECTORY command always returns its result with a trailing separator. The EXTRACT FILE BASE command returns the file portion without extension.
=====IS DIRECTORY <path>, IS FILE <path>, IS PATH <path>=====
Determines whether the specified path points to an existing directory, file, or any of the two. The result is returned as one of the strings "true" or "false".
=====PARENT DIRECTORY <path>=====
Returns the parent directory of the specified path, independently of whether the path points to a directory, or to a file.
=====CURRENT DIRECTORY=====
Returns the current working directory. Note that working directories are per-script, i.e. multiple scripts running in parallel may have different working directories.
=====CHANGE DIRECTORY <path>=====
Changes the script's working directory. Note that working directories are per-script, i.e. multiple scripts running in parallel may have different working directories. Also, this command will only affect the default directory of scripting commands, not the application-global working directory as seen by the OS.
=====MAKE DIRECTORY <path>=====
Creates a new directory with the given path. The directory's parent must exist for the command to succeed.
=====LIST DIRECTORY [<path> or <wildcard expression>]=====
Returns a listing of the specified directory, or the current working directory if no path is specified. The listing is in long form. You may use wildcard expressions in order to restrict the output.
=====LIST FILE <wildcard expression>=====
Returns a list of file names matching ''wildcard expression'' in the current directory.
=====LIST FILES [<directory> [<wildcard expression>]]=====
Returns a list of file names from the specified directory, matching ''wildcard expression''. When ''wildcard expression'' is missing, all files are listed. When ''directory'' is missing, files in the current directory are listed.
=====LIST DIRECTORIES [<directory> [<wildcard expression>]]=====
Returns a list of directory names from the specified directory, matching ''wildcard expression''. When ''wildcard expression'' is missing, all directories are listed. When ''directory'' is missing, directories in the current directory are listed.
=====RENAME FILE <current path> <new path>, RENAME DIRECTORY <current path> <new name>=====
Renames a file resp. a directory. For files, a different path may be given in the second argument, resulting in that the file is moved to the location specified by the new path. For directories, the path up to the directory's name must stay the same.
=====REMOVE FILE <path>, REMOVE DIRECTORY <path>=====
Removes the specified file or directory. This command cannot be undone. The directory must be empty for the command to succeed.
=====FORCEREMOVE DIRECTORY <path>=====
Removes the specified directory and its contents. Symbolic links are treated as ordinary files, i.e. they are not followed. This command cannot be undone.
=====NORMALIZED PATH <path>=====
Returns <path>, with the following transformations applied:
*Removes relative elements (<tt>..</tt> <tt>.</tt>) as far as possible. For absolute paths, the result will not contain any relative elements; for relative paths, double-dots may appear at the beginning of the result if necessary.
If a relative path simplifies to the empty string, <tt>./</tt> is returned. Thus, the result of NORMALIZED PATH is never empty, unless its input was empty.
*Replaces backward slashes with forward slashes to achieve uniformity across platforms.
*On case-insensitive file systems, replaces the spelling of names with the one stored in the file system.
*On Win32, replaces short (8.3) names with long ones.
=====CANONICAL PATH <path>=====
If <path> points to an existing file or directory, CANONICAL PATH returns a valid absolute file path, suitable as an unambiguous representation for the object pointed to. Especially, two non-empty canonical path strings will compare equal if and only if they refer to the same file system object.
If <path> does not point to an existing file system object, construction of a canonical path is not possible due to lack of information about the named object, and CANONICAL PATH will return an empty string.
'''NOTES:''' The need for an unambiguous, or canonical, representation arises due to ambiguities in the string representation of paths, and in file systems themselves.
*Paths may contain relative elements: <tt>/mydir/../myfile</tt> points to the same object as <tt>/myfile</tt>.
*A path that involves symbolic links will point to the same object as a path containing one or more of those links in resolved form.
*File systems may be case-insensitive, or may even provide multiple distinct names for individual directory entries (Win32 short vs. long names).
On '''Win32,''' CANONICAL PATH returns the short (8.3) representation of a path, using uppercase spelling, and backslashes as directory separators. Apart from efficiency considerations, this aesthetically unpleasing representation has been chosen to discourage its use for anything except comparing file system objects.
On '''other systems,''' CANONICAL PATH will return the result of the POSIX <tt>realpath()</tt> function.
In both cases, a CANONICAL PATH will end with a native directory separator if, and only if, the object pointed to is a directory.
=====REAL PATH <path>=====
On this command provides a work-alike for the POSIX <tt>realpath()</tt> function.
If <path> is empty, or if <path> points to a non-existing object, the result will be empty. Otherwise, an absolute path will be returned, with symbolic links resolved, using forward slashes as directory separators, and with spelling normalized as described for NORMALIZED PATH. A forward slash will be appended if the path points to a directory.
'''NOTE:''' In principle, the path returned by REAL PATH should be just as unambiguous as the result of CANONICAL PATH. However, there are a few caveats:
* On case-insensitive file systems, two independently obtained results of REAL PATH might differ in case spelling even if referring to the same file system object. This should not be the case for CANONICAL PATH.
* Determining the result of CANONICAL PATH is a fast operation. In contrast, REAL PATH may be expensive to determine, as for each directory on the path a listing needs to be obtained, and a canonical path needs to be formed, and compared, for half of the listed directory entries on average.
* On Win32, quite some amount of complexity arises from backward compatibility layers, forbidden file names, multiple filesystem roots, etc. Internally calling <tt>GetShortPathName()</tt>, CANONICAL PATH does not need to handle that complexity, and may be considered more reliable for identifying file system objects than REAL PATH.
=====READ FILE <filename>=====
Returns the text content of the file indicated by <filename>.
=====WRITE FILE <filename> <line>,  OVERWRITE FILE <filename> <line>, APPEND TO FILE <filename> <line>=====
These commands write the specified <line> of text to the file indicated by <filename>.  They behave like the <tt>echo</tt> command of a typical shell, in the sense that a line-ending will be automatically added to the <line> if it does not already end with one. To suppress the automatic line-ending, you can say WRITE FILE <filename> <content> WITHOUT LINE ENDING (or equivalently, for short, you can say WITHOUT LF or WITHOUT CRLF). Any previous content in <file> will be lost if you use WRITE or OVERWRITE (they are the same, just synonyms for each other) whereas APPEND preserves previous content and adds the new <line> to the end.
====Commands operating on executables====
=====START EXECUTABLE <command line>=====
Behaves identically to CREATE PROCESS, except that it does not report a process id for the new process. For details, see CREATE PROCESS.
=====CATEGORIZE EXECUTABLE <name or path>=====
BCI2000 keeps a list of executables/modules that have been built, and sorts them into categories. The CATEGORIZE EXECUTABLE command provides a way to retrieve that information. Given the name or path of an executable, it outputs one of the following categories:
* SignalSource,
* SignalProcessing,
* Application,
* Operator,
* Tool,
* Helper,
* Unknown.
====Commands operating on Lines of input/output====
=====WRITE LINE <line>=====
Writes a line of output. Destination depends on the context in which a script is executed. If the context is an Operator Handler, output is written as a log entry. If the context is a telnet session, output is written to the telnet connection. If the context is a [[User Reference:BCI2000Shell|BCI2000Shell]], output is written to the shell's stdout.
=====READ LINE=====
Reads a line of input from the current execution context's input. If the command is executed within an Operator Handler, it will fail. If executed within a telnet session, the other side of the connection is prompted for input. If executed from within a [[User Reference:BCI2000Shell|BCI2000Shell]], input is read from the shell's stdin.
====Commands operating on Processes in the Operating System====
=====CREATE PROCESS <command line>=====
Starts the specified executable with options. This command returns after the started program has finished initialization, i.e. it will detect load time failures such as missing DLLs on Windows. If the process is still running when CREATE PROCESS returns, its result will be an operating system process id (pid). If the process has terminated, CREATE PROCESS will report its exit code marked with an <tt>ExitCode</tt> tag to allow distinction between a pid and an exit code.
Please note that CREATE PROCESS requires quoting of arguments differently from other scripting commands. For details, see the SYSTEM command.
=====TERMINATE PROCESS <pid>=====
Tries to terminate the process with the given operating system pid, waiting for the process to terminate before returning. Will return <tt>false</tt> to indicate that a suitable process existed but could not be terminated.
=====WAIT FOR PROCESS <pid> [<timeout seconds> = infinite]=====
Waits for the process with the given operating system pid to terminate, or the timeout to expire. Returns <tt>false</tt> to indicate that the process is still executing.
=====SHOW PROCESS <pid>=====
Makes all windows visible which are associated with the process referred to by pid.
In addition, brings one of the process' top level (desktop level) windows to the front for user interaction.
=====HIDE PROCESS <pid>=====
Makes all windows invisible which are associated with the process referred to by pid.


====Global commands====
====Global commands====
=====HELP [<type>]=====
When called with a type argument, lists commands that exist for the specified type (e.g., SYSTEM, or FILE). When called without argument, lists all commands in their main form. HELP ALL will list all commands, including synonyms.
=====SET <name> <value>, GET <name>, <name>=====
Allows to set or retrieve the value of local and environment variables. The name is matched against local and environment variables. When no variable with the given name is found, SET will create a local variable, while GET will result in an error. GET may be further abbreviated to only consist of a name.
GET further allows evaluation of [[User_Reference:Expression_Syntax|mathematical expressions]]. When the expression is invalid, or contains an unknown variable, an error is triggered.
=====GET SYSTEM STATE=====
=====GET SYSTEM STATE=====
Prints the current system state. This will be one of Unavailable, Idle, Startup, Initialization, Resting, Suspended, ParamsModified, Running, Termination, Busy.
Prints the current system state. This will be one of Unavailable, Idle, Startup, Initialization, Resting, Suspended, ParamsModified, Running, Termination, Busy (for details, see the WAIT FOR command below).
 
=====GET CURRENT RUN FILE=====
Prints the full path to the current run file, or an empty string, if called outside Running state.
 
=====WAIT FOR <system state> [<timeout seconds>]=====
Waits until the system is in the specified state. This may be one of Idle, Startup, Connected, Resting, Suspended, ParamsModified, Running, Busy, or a combination of these, separated with a pipe character: "Resting|Suspended". When no timeout is given, this command waits indefinitely. If the wait is successful, i.e. system state matches one of the specified states, WAIT FOR will return a value of "true". If timeout occurred, WAIT FOR will return "false".


=====WAIT FOR <system state> <timeout seconds=5>=====
If the BCI2000 system is shut down while a script is executing a WAIT FOR command, the script will be terminated with a "wait aborted" error message.
Waits until the system is in the specified state. This may be one of Unavailable, Idle, Startup, Initialization, Resting, Suspended, ParamsModified, Running, Termination, Busy, or a combination of these, separated with a pipe character: "Resting|Suspended". When timeout occurs, an error message is returned.
 
In more detail, user visible states are:
* Idle: System is shut down and does not do other processing than executing scripts.
* Startup: System has started up and is listening for incoming connections.
* Connected: All core modules have connected to the system.
* Resting: The system has been initialized but is not running.
* Suspended: The system has ended running and is behaving like in Resting.
* ParamsModified: In Suspended mode, parameter changes have been published and will be applied at Resume.
* Running: The system is running, processing brain signals, and displaying stimuli.
* Busy: The system is performing a transition from one state to another.
 
As a synonym for "Connected," "Initialization" is valid as well since it is compatible with the nomenclature in StateMachine.h. Still, it should be avoided because it is easily confused with, but very distinct from, the actions performed in the Initialize() phase.
 
=====SLEEP &lt;time in seconds&gt;=====
Waits (sleeps) for the given amount of time. Timing resolution is 50ms. Tends to sleep a little longer than specified, with the error growing with duration.


=====GET SYSTEM VERSION=====
=====GET SYSTEM VERSION=====
Line 113: Line 434:
=====STOP=====
=====STOP=====
Stops system operation. Corresponds to the ''Stop'' button in the GUI version of the Operator.
Stops system operation. Corresponds to the ''Stop'' button in the GUI version of the Operator.
=====STARTUP=====
=====STARTUP SYSTEM=====
When in idle state, starts up the system to wait for incoming connections from core modules.
When in idle state, starts up the system to wait for incoming connections from core modules. Additionally, the following arguments may be given: 1) an IP address on which to listen (default is to listen on all addresses), and 2) a list of generic core module names with ports. The default configuration corresponds to these arguments:
=====SHUTDOWN=====
STARTUP SYSTEM * SignalSource:4000 SignalProcessing:4001 Application:4002
 
A system log file may optionally be specified on this line, by inserting the <code>--SystemLogFile</code> flag between the IP address and the module specifiers. For example:
 
STARTUP SYSTEM * --SystemLogFile=SOME_FILE.TXT SignalSource:4000 SignalProcessing:4001 Application:4002
 
The system log file will record all operator log window messages for the current launch, until the system shuts down.  It may be helpful to use the variables <code>$YYYYMMDD</code> and <code>$HHMMSS</code> to specify the filename.  Note that file name and path cannot contain spaces.
 
=====SHUTDOWN SYSTEM=====
Shuts down core modules, and enters idle system state.
Shuts down core modules, and enters idle system state.
=====RESET SYSTEM=====
Shuts down the system, and clears all parameter, state, and event information.


=====QUIT, EXIT=====
=====QUIT, EXIT [<result>]=====
Quits the operator module after terminating all BCI2000 modules.
Quits the operator module after terminating all BCI2000 modules. The optional ''result'' argument determines the result of the executed script.
 
=====CLOSE CONNECTION, TERMINATE CONNECTION=====
In the context of a telnet or websocket connection, this command will terminate the connection.
In other contexts, such as event handlers, it will be ignored.


=====SYSTEM <command line>=====
=====SYSTEM <command line>=====
Executes a shell command, redirecting any console output into the command's script result. E.g., to obtain a directory listing, under Windows, you would enter
Executes a shell command, redirecting any console output into the command's script result. E.g., to obtain a directory listing, under Windows, you would enter
  System dir
  SYSTEM DIR
=====START EXECUTABLE <command line>=====
'''NOTE:''' Arguments to the SYSTEM command are executed by the operating system's shell, and thus may require quoting different from the other scripting commands. E.g., writing
Starts the specified executable with options. This command returns immediately after the started program has finished initialization.
SET mydir ${PARENT DIRECTORY $BCI2000LAUNCHDIR}; ECHO ${LIST FILES $mydir}
will list files in the BCI2000 main directory, independently of whether the path to that directory contains space characters or not. However, to obtain a directory listing through the SYSTEM command, you would need to write
ECHO ${SYSTEM DIR "$mydir"}
to make sure the content of the variable ''mydir'' is interpreted as a single argument, independently of whether it contains space characters.


=====LOG <message>=====
=====LOG <message>=====
Line 140: Line 478:
Clears the background message buffer, and returns its previous content. Use CAPTURE MESSAGES to capture messages into the background message buffer.
Clears the background message buffer, and returns its previous content. Use CAPTURE MESSAGES to capture messages into the background message buffer.


===Syntax===
====Operator-module defined Commands====
Scripts consist of sequences of the above commands, terminated with either a DOS line ending sequence, or a semicolon (;).
=====HIDE WINDOW [<name>], SHOW WINDOW [<name>]=====
When the semicolon is used to terminate commands, a line may contain multiple commands.
Hides or shows the specified window. When called without a window name, the Operator module's main window is hidden or shown. The window name may be one of Main, Configuration, Log, Watches, and Visualizations. When "Watches" is given, the window state refers to visibility of the Watches area in the Visualizations window.
Commands are case-insensitive, values are case-sensitive.
 
=====MOVE WINDOW <name> <x> <y>, RESIZE WINDOW <name> <width> <height>=====
Moves resp. resizes the specified window with one of the above names.
Window decorations (title bar, frame) are taken into consideration such that the total size of the window matches the given width and height.
 
=====ARRANGE WINDOW <name> <rows> <cols> <row> <col> [<rowspan> <colspan>]=====
Arranges the named window in a virtual ''rows'' x ''cols'' grid at grid position ''row, col''.
 
Optional ''rowspan'' and ''colspan'' arguments may be given to specify the extension of the window across more than one row or column.
Using a ''rowspan'' of 0 will result in the window assuming its minimum height.
Likewise, a ''colspan'' of 0 will result in the window's minimum width.
 
If multiple screens are present, windows are arranged on the screen that contains the Operator window.
 
=====SET TITLE <title>=====
Sets the title of the main Operator window.
=====SET BUTTON <idx> <label> <commands>=====
Configures the function button with 1-based index ''idx'' such that it is labelled ''label'' and executes ''commands''.
 
=====VISUALIZE WATCH [decimate <n>] [range <min> <max>] <expression1> ...=====
Adds a watch for the given expressions to the operator module's Watches window, and makes the Watches window visible if it is hidden. If the ''decimate'' clause is present, the command will create a watch which will be evaluated only for every ''n''th sample in the state vector. If the ''range'' clause is present, display minimum and maximum will not be adjusted automatically but will be fixed to the values given.
 
By default, ''decimate'' has a value of "auto"; this means that there is no decimation of evaluation (i.e., all samples are evaluated) but changes that occur within 1ms will be shortened into their maximum and minimum, and thus reported as only two values.
This has proven to be efficient for avoiding sluggishness from flooding the application with events.
 
=====MOVE VISUALIZATON <visID> <x> <y>, RESIZE VISUALIZATION <visID> <width> <height>=====
Moves resp. resizes the specified visualization window.
Window decorations (title bar, frame) are taken into consideration such that the total size of the window matches the given width and height. If unknown, visualization IDs may be obtained from the Operator's ''Window->Visualizations'' menu.
 
=====ARRANGE VISUALIZATION <visID> <rows> <cols> <row> <col> [<rowspan> <colspan>]=====
Arranges the named visualization window in a virtual ''rows'' x ''cols'' grid at grid position ''row, col''.
 
Optional ''rowspan'' and ''colspan'' arguments may be given to specify the extension of the window across more than one row or column.
Using a ''rowspan'' of 0 will result in the window assuming its minimum height.
Likewise, a ''colspan'' of 0 will result in the window's minimum width.
 
If multiple screens are present, windows are arranged on the screen that contains the Operator window.
 
=====RECORD VISUALIZATION <visID> [on|off]=====
Registers the named visualization for recording. The visualization name must be the short name as displayed in the ''View->Visualizations'' menu. Switching a visualization recording to "on" is only possible in idle state (because an event for recording frame numbers must be registered in the system). When a visualization is registered for recording, its frames are stored immediately as they arrive at the operator module. Currently, only bitmap visualizations may be recorded.
 
Example: Recording the application window
RECORD VISUALIZATION ApplicationWindow on
...
# after parameters have been loaded
Set parameter VisualizeApplicationWindow 1
...
 
=====PUT NOTE <note>=====
Adds the given text to the [[User_Reference:Operator_Notes#Taking_Notes_during_recording_in_Operator|notes window]].
If the system is in ''Running'' state, the text will also be added to the current notes file as described under
[[User_Reference:Operator_Notes#Note_storage_and_file_format|"notes file"]].
 
=====START TELNET <address>, STOP TELNET <address>=====
Starts or stops a telnet server listening at the given address. The address is in <IP>:<port> format.
 
'''IMPORTANT:''' You should not use this command on global internet addresses, as there is no authentication performed. Only use addresses in the local network, such as 10.x.x.x, 172.x.x.x, or 192.168.x.x.
 
=====START WEBSOCKET <address>, STOP WEBSOCKET <address>=====
Starts or stops a websocket server listening at the given address. The address is in <IP>:<port> format.
 
'''IMPORTANT:''' You should not use this command on global internet addresses, as there is no authentication performed. Only use addresses in the local network, such as 10.x.x.x, 172.x.x.x, or 192.168.x.x.
 
====Operator-module Commands for Soliciting Input from the User====
 
 
 
=====CHOOSE [INPUT] FILE[S] [OF TYPE <.ext1> [<.ext2> ...]] [STARTING AT <dir>] [WITH PROMPT <message>]=====
Via the Qt graphical user interface, prompt the user to select an existing file (or multiple files, if the keyword FILES is used). Print the resulting file path(s).
(See the [[User_Reference:Custom_GUI_Commands|Custom GUI Commands]] page for details and examples.)
 
=====CHOOSE [OUTPUT] FILE [OF TYPE <.ext1> [<.ext2> ...]] [STARTING AT <dir>] [WITH PROMPT <message>]=====
Via the Qt graphical user interface, prompt the user to specify a file into which data can be saved (with an overwrite confirmation dialog if it already exists). Print the resulting file path.
(See the [[User_Reference:Custom_GUI_Commands|Custom GUI Commands]] page for details and examples.)
 
=====CHOOSE DIRECTORY [STARTING AT <dir>] [WITH PROMPT <message>]=====
Via the Qt graphical user interface, prompt the user to specify a directory. Print the resulting directory path.
(See the [[User_Reference:Custom_GUI_Commands|Custom GUI Commands]] page for details and examples.)
 
=====CUSTOM DIALOG [MESSAGE <msg>] [VAR <varname> <label> {[<options>]} ] [BUTTONS {<buttons>}] ... =====
Via the Qt graphical user interface, prompt the user with a modal dialog that can be flexibly customized.
(See the [[User_Reference:Custom_GUI_Commands|Custom GUI Commands]] page for details and examples.)
 
===Predefined Variables===
The following variables exist when an Operator script is executed.
Some of these variables are marked with ''local''. This means that they are not environment variables, i.e. they are invisible to child processes that are launched using the SYSTEM or START EXECUTABLE commands, and their values may be different between script invocations. In script code, they are accessed like ordinary variables.
====BCI2000LAUNCHDIR====
The full absolute path to the directory where the Operator module resides. This is also prepended to the PATH environment variable, such that executables from the current BCI2000 installation will have precedence over any other executable with the same name.
 
On macOS, this is the path where the Operator module's application bundle resides. In the default configuration, this is the BCI2000 prog directory, both on macOS and on other platforms.
 
====BCI2000BINARY====
The full absolute path to the Operator module.
====LogLevel (local)====
Determines the amount of log information written to the Operator log. This variable only affects log messages originating from the current script. May be 2 (display all log messages), 1 (display fewer log messages), or 0 (suppress all log messages). Set to 1 by default. Changes to this local variable are not propagated to any sub-scripts called. ''NOTE:'' Only log messages are controlled by this variable. Error messages originating from a script with 'LogLevel 0' will still be displayed in the Operator log. When 'AbortOnError' is set to 0, you may set 'LogLevel' to -1 in order to display error messages. When 'AbortOnError' is 1 (the default), error messages will always be displayed to indicate the reason for failure.
 
====AbortOnError (local)====
Determines if a script is aborted when an error happens, or whether the error is silently ignored. Set to 1 by default (script is aborted on error). Changes to this local variable are not propagated to any sub-scripts called.
 
====Result (local)====
The result of the last executed scripting command. When a script is executed by calling EXECUTE SCRIPT, the script's last executed command determines the result of the EXECUTE SCRIPT command itself.
 
====0, 1, ... 9 (local)====
When a script file is being executed, these variables contain the arguments of the EXECUTE SCRIPT command.
''$0'' resolves to the full absolute path to the current script file. Within scripts, all of the ''0-9'' variables are defined, and those that do not have a matching argument are empty.
 
====YYYYMMDD (local)====
Local time at execution of the current script, in YYYYMMDD format. In interactive sessions, reflects the time when the session was initiated.
 
====HHMMSS (local)====
Local time at execution of the current script, in HHMMSS format. In interactive sessions, reflects the time when the session was initiated.
 
===Abbreviated commands and synonyms===
To minimize the need of consulting documentation, as well as for backward compatibility, a number of '''synonymous commands''' are provided. E.g., states may be added by INSERT STATE as well as ADD STATE, and the existence of a file may be queried by IS FILE as well as EXISTS FILE. For an overview over all allowed forms of commands, use the HELP ALL command.
 
To simplify operation in interactive sessions, '''abbreviated commands''' exist. Currently, these are:
:'''cd''' for CHANGE DIRECTORY,
:'''pwd''' and '''cd''' without argument for CURRENT DIRECTORY,
:'''ls''' and '''dir''' for LIST DIRECTORY,
:'''mkdir''' for MAKE DIRECTORY,
:'''echo''' for WRITE LINE,
:'''realpath''' for REAL PATH,
:'''dirname''' for EXTRACT DIRECTORY,
:'''basename''' for EXTRACT FILE BASE.
 
===Handlers===
In the Operator GUI, script execution is bound to a number of Operator Events (not to be confused with Event states, above) that occur during various [[Technical Reference:States of Operation|stages of BCI2000 system operation]]:
====OnConnect====
This handler runs at startup, as soon as all modules are connected to the operator module.
====OnSetConfig====
This handler runs each time a set of parameters is applied to the system. This happens when the user clicks the ''SetConfig'' button. Execution of the ''SETCONFIG'' command also runs this handler.
 
====OnStart, OnResume====
These handlers are triggered by the ''Start''/''Resume'' button. One of these handlers is also triggered when the ''Running'' state variable is set to 1 from a script. Whether ''OnStart'' or ''OnResume'' is triggered depends on whether the system has been running before with the current set of parameters.
 
====OnStartRun====
Similarly to OnStart and OnResume, this handler is triggered by the ''Start''/''Resume'' button. Unlike other event handlers, OnStartRun has an argument, which is the current run file.
 
OnStart or OnResume are triggered immediately after ''Start''/''Resume'' has been pressed, whereas OnStartRun is deferred until modules have confirmed to be in Running state. This makes sure that the OnStartRun event handler receives a valid run file name.
 
====OnNextFilePart====
This handler is triggered during a run, whenever the ''FilePart'' event state is incremented. It allows scripts to know when a new
partial file has begun. For further information, see the [[User_Reference:BCI2000FileWriter#FileSplittingCondition|FileSplittingCondition]] parameter.
 
====OnSuspend/OnStopRun====
Triggered when the system goes from running into suspended mode. This happens whenever the ''Running'' state variable changes from 1 to 0. This may happen when the user clicks ''Suspend'', when the application module switches the system into suspended mode, or when a script sets the ''Running'' state variable to 0.
 
====OnShutdown====
Triggered when the operator module shuts down connections, and switches into idle state.


Command arguments containing white space must be included in double quotes, or the white space must be encoded in URL-fashion, e.g. ''%20'' instead of a space character. Similarly, when an argument contains a semicolon (;), it must be included in double quotes, or the semicolon must be encoded in URL-fashion, i.e. as ''%3B''.
====OnExit====
Triggered when the operator module exits. Execution of the QUIT command also triggers this handler. This handler is not available to the SET SCRIPT and CLEAR SCRIPT commands. Also, when both an OnShutdown and an OnExit script are defined, the OnExit script may be executed before the OnShutdown script.


===Associating Scripts with Events===
====Associating Scripts with Operator Events====
In the operator module's preferences dialog, scripts may be entered for each of the events listed above.
In the operator module's preferences dialog, script commands may be entered for each of the handlers listed above.
Scripts may be specified as paths to script files, or as immediate one-line scripts.
Scripts may be specified as paths to script files, or as immediate one-line scripts.
Entries that start with a minus sign (-) are treated as one-line scripts, which may contain multiple commands separated with semicolons.
Entries that start with a minus sign (-) are treated as one-line scripts, which may contain multiple commands separated with semicolons.


Scripts may also be specified from the command line used to start up the operator module. There, event names are followed with the content of the respective preference entry, enclosed in double quotes ("...").
Scripts may also be specified from the command line used to start up the operator module. There, handler names are followed with the content of the respective preference entry, enclosed in double quotes ("...").


Finally, scripts may be specified using the SET SCRIPT command of the scripting language itself.
Finally, scripts may be specified using the SET SCRIPT command of the scripting language itself.


===Examples===
===Examples===
====1====
====Making use of the Operator module's Function Buttons====
To add a state variable called "Artifact", and to set it using the operator's function buttons, do this:
To add a state variable called "Artifact", and to set it using the operator's function buttons, do this:
*Enter the following line under "After All Modules Connected" in the operator's preferences dialog (note the minus sign):
*Enter the following line under "After All Modules Connected" in the operator's preferences dialog (note the minus sign):
  -INSERT STATE Artifact 1 0
  -ADD STATE Artifact 1 0
*Under "Function Buttons", enter "Set Artifact" as the name of button 1, and as its command, enter (note there is no minus sign):
*Under "Function Buttons", enter "Set Artifact" as the name of button 1, and as its command, enter (note there is no minus sign):
  SET STATE Artifact 1
  SET STATE Artifact 1
Line 166: Line 653:
  SET STATE Artifact 0
  SET STATE Artifact 0


====2====
====A fully automated BCI2000 session====
<pre>
Echo Please enter a subject ID:
Set SubjectID ${Read line}
 
Startup system
Start executable SignalGenerator
Start executable SpectralSignalProcessing
Start executable CursorTask
Wait for Connected
Load parameterfile "../parms/examples/CursorTask_SignalGenerator.prm"
For i in 1 2 3
  Load parameterfile "../parms/MyExperiment/Session$i.prm"
  Set parameter SubjectName $SubjectID
  Set parameter SubjectSession $i
  Set config
  Wait for Resting
  Start
  Wait for Suspended 1000
End
</pre>
 
====Automating BCI2000 by Operator command line arguments====
The following example shows how to specify script commands from the command line.
The following example shows how to specify script commands from the command line.
It fully automates BCI2000 operation by loading a parameter file, applying parameters, starting the system once the parameters are applied, and quitting the system once the run is over. For better readability, the example is broken across lines; for execution, the command needs to be entered as a single line.
It fully automates BCI2000 operation by loading a parameter file, applying parameters, starting the system once the parameters are applied, and quitting the system once the run is over. For better readability, the example is broken across lines, using the ^ DOS line continuation character.


  operator.exe --OnConnect "-LOAD PARAMETERFILE ..\parms\examples\CursorTask_SignalGenerator.prm; SETCONFIG"  
  operator.exe --OnConnect "-LOAD PARAMETERFILE ../parms/examples/CursorTask_SignalGenerator.prm; SETCONFIG" ^
               --OnSetConfig "-SET STATE Running 1"   
               --OnSetConfig "-SET STATE Running 1"  ^
               --OnSuspend "-QUIT"
               --OnSuspend "-QUIT"
====Automatically arranging windows in a 4x2 grid====
The following example arranges Source and Roundtrip visualizations on the left side of the screen.
On the right side, a large area is dedicated to the Operator's log window, and the Operator's main window sits at the bottom right.
Arrange Visualization SRCD 4 2 1 1 2 1
Arrange Visualization RNDT 4 2 3 1
Arrange Window Main 4 2 4 2
Arrange Window Log  4 2 1 2 3 1
[[File:Operator_Arrangement.PNG|center|640px|border]]


==See also==
==See also==
[[User Reference:Module Command Line Options]], [[User Reference:Operator Module]], [[Technical Reference:States of Operation]]
[[User Reference:Module Command Line Options]], [[User Reference:Operator Module]], [[User Reference:BCI2000Shell]], [[Technical Reference:States of Operation]]


[[Category:User Interface]]
[[Category:User Interface]]

Latest revision as of 14:48, 20 February 2026

Operator scripts automate actions that the otherwise would be performed by the user, e.g. starting or suspending system operation. Scripts may be contained in script files, or given immediately in the operator module's preferences dialog. There is also an option to specify scripts from the command line when starting the operator module. When using the BCI2000Shell, or the Operator Library from your own application, you may execute scripts at any time.

In addition, the operator scripting language may be used to control an operator module over a Telnet or WebSocket connection.

Syntax

Command separation. Scripts consist of sequences of the commands listed below. A command must be terminated with either a newline, or a semicolon (;). This allows to put multiple commands into one line, separated by semicolon characters. Commands are case-insensitive, variables and values may be case-sensitive, depending on context.

Comments. Lines starting with a '#' character are ignored. Such lines may be used to hold comments. In addition, when any of the first two lines of a script contains "#!" (the Unix shell invocation sequence), it will be ignored. In conjunction with BCI2000Shell, this may be used to write Operator scripts that may be treated as executables.

Escaping. In order to resolve ambiguity about command arguments that contain white space, they must be included in double quotes, or the white space must be encoded in URL-fashion, e.g. %20 instead of a space character. Similarly, when an argument contains a semicolon (;), it must be included in double quotes, or the semicolon must be encoded in URL-fashion, i.e. as %3B. Also, "$" characters indicate command substitution, so they should be encoded as %24 if substitution is not desired.

Variable Substitution. When a command contains a dollar sign, alphanumeric characters following the dollar sign will be interpreted as the name of a variable: $NAME. The name will be matched against Expression variable names first, followed with Local variable names, and finally Environment variable names. When a match is found, $NAME will be replaced with the content of the matching variable. When no match is found, $NAME will be resolved to an empty string, without triggering an error.

Command Substitution. When part of a command is enclosed with ${...}, this subexpression will be substituted with the result of its execution as a command. E.g.,

LOG "Current system state is: ${GET SYSTEM STATE}"
LOG "The path environment variable is: ${PATH}"

Note that the last example uses the short form of the GET command, which will return the value of a PATH parameter or a PATH state if such exists. To make sure that only environment variables are matched, use the long form of the GET command:

LOG MESSAGE "The path environment variable is: ${GET VARIABLE PATH}"

Mathematical Expressions. A command may consist of a single mathematical expression. This expression is then evaluated, and its result is returned as the command's result. As a special case, this allows the use of expression variables in ${...} substitutions. Consider for example

x:=0; WHILE x<10; LOG ${x:=x+1}; END

There, the first command creates and initializes the expression variable x. In the WHILE condition, an expression is allowed as well as any command. In the LOG command, an expression appears in ${...}, which executes the expression in braces, and substitutes the result of the expression as an argument into the LOG command, which adds an entry to the Operator log. This results in a sequence of 10 log entries, containing the numbers from 1 to 10.

Commands

Control commands

These commands allow conditional execution of parts of a script. When a condition is expected, any other scripting command may be given. Its result will be considered to represent a boolean value of "true" if it is empty, a nonzero number, or the string "true". It will be taken to represent a boolean value of "false" if it contains a numeric value of zero, or any string that does not evaluate to a nonzero number. Note that identification of an empty value with "true" differs from string handling in the EVALUATE CONDITION command. This is because most scripting commands return nothing on success, but an error message on failure.

The output of the SYSTEM and START EXECUTABLE commands is handled specially. There, the result code of the created child process is translated into a boolean value in the ordinary manner, treating a result code of zero as "true", and any other result code as "false". This allows to use external commands in the same way as in a native shell.

IF <condition>; <if commands>; [ ELSEIF <condition>; <elseif commands>;] ... [ ELSE; <else commands>;] END

Executes if commands if condition evaluates to "true". Otherwise, the elseif commands of the first matching elseif condition are executed. When none of the elseif conditions evaluates to "true", else commands are executed. ELSEIF and ELSE blocks may be omitted.

WHILE <condition>; <loop commands>; END

Executes loop commands while condition evaluates to true.

DO; <loop commands>; UNTIL <condition>

Executes loop commands until condition evaluates to true.

FOR <name> IN <item1> <item2> ... ; <loop commands>; END

Creates a local variable with the specified name. Then, sequentially assigns each item to that variable, and executes loop commands. If an item contains newline characters, it is split up into multiple items, corresponding to the lines contained in the item. E.g.,

FOR i IN top ${LIST FILES} bottom; LOG ${i}; END

will first write a log entry "top". Then, it will create a log entry for each file in the current directory, and finally, it will create a log entry "bottom".

RETURN [<value>]

Finishes execution of the current script, and optionally returns a value to the caller.

Commands operating on Conditions

EVALUATE CONDITION <left> [<op> [<right>]]

Evaluates a comparison between the left and right operands. As a comparison operator, the following may be specified: ==, !=, ~=, <, >, <=, >=. There, the != operator behaves identically to the ~= operator. When a test for equality is performed, the two operands are treated as strings, and compared in a case-insensitive manner. When any of the inequality tests is performed, the two operands are converted into floating-point numbers before comparison.

The right operand may be omitted, in which case it is treated as if an empty string were specified. Also, the op operator may be omitted, in which case the following rules apply regarding the remaining operand: If it is an empty string, or equal to the string "false" in case-insensitive comparison, the result is "false". If entirely consists of the text representation of a floating-point number, the result is "false" if the number is 0, and "true" if the number is not 0.

Inspired by the unix sh shells' test command, there exists a short form of the EVALUATE CONDITION command, where the arguments of EVALUATE CONDITION may appear within square brackets. This allows constructs such as

IF [ ${MyVar} == MyValue ]; LOG Is equal; ELSE; LOG Is different; END

Note that the arguments to EVALUATE CONDITION must always be separated by white space, no matter whether its long or short form is used.

Conditions may be combined logically using the operators && and ||. These go outside the square brackets. Note also that whitespace around the comparison operators is critical, otherwise the conditional will be treated as a single string (which will always evaluate to "true")

IF [ ${foo} == foo ] || [ ${bar} == bar ]; LOG got a match; END

Commands operating on Local Variables

Besides environment variables, there exist local variables in scripts. Local variables are inherited by sub-scripts executed with the EXECUTE SCRIPT command, but changes to the variable's values will not be propagated to the calling script.

SET VARIABLE <name> <value>

Sets the named variable to the specified value.

CLEAR VARIABLE <name>

Removes the named variable from memory.

GET VARIABLE <name>

Returns the variable's current value. When the variable does not exist, an empty value is returned rather than an error message generated.

Commands operating on Environment Variables

These scripting commands allow to read and modify environment variables. Changes to environment variables will be visible to child processes started with SYSTEM or START EXECUTABLE. Variable values are stored as strings. Variable names may not contain the equals sign.

SET ENVIRONMENT <name> <value>

Sets the named variable to the specified value.

CLEAR ENVIRONMENT <name>

Removes the named variable from memory.

GET ENVIRONMENT <name>

Returns the variable's current value. When the variable does not exist, an empty value is returned rather than an error message.

WRITE ENVIRONMENT <fileName> <variableName1> <variableName2> ...

Writes a series of SET ENVIRONMENT statements to the specified file, overwriting any previous file contents. This saves the values of the named variables in such a way that you can later load them back by calling EXECUTE SCRIPT <filename>. The variable names may refer to either local or environment variables at the time of writing, but when you execute the script they will all be loaded as environment variables.

APPEND ENVIRONMENT <fileName> <variableName1> <variableName2> ...

This is the same as WRITE ENVIRONMENT, except that the SET ENVIRONMENT statements are appended to the named file without overwriting its previous contents.

Commands operating on Scripts

SET SCRIPT <handler names> <scripting commands>

Associates a sequence of scripting commands with the named handler. Handlers are specified by names as given below. Multiple handlers may be specified by concatenating their names with a pipe character, e.g. "OnStart|OnResume".

Scripting commands must be included in double quotes, unless they consist of a single word. When specifying a sequence of scripting commands, they must be separated with a semicolon character: "SetConfig; Start". In order to use double quotes or semicolons within the commands themselves, encode these as you would in a URL, i.e. replace a double quote character with %22, and a semicolon with %3B: "Load Parameters %22my file%22".

To use a script file rather than a literal script, use the EXECUTE SCRIPT command:

SET SCRIPT OnConnect "EXECUTE SCRIPT myscript.txt"
GET SCRIPT <handler name>

Returns the script associated with the specified handler.

CLEAR SCRIPT <handler names>

Clears scripts for the given handlers. Equivalent to calling SET SCRIPT with an empty script.

EXECUTE SCRIPT <file or handler name> [<Arg1> <Arg2> ... <Arg9>]

Executes a script contained in a file, and optionally sets the script's local variables 1 to 9 to the specified values. To execute script commands already associated with a handler, provide a handler name rather than a file. When the script is executed successfully, the result of the last executed script command becomes the result of the EXECUTE SCRIPT command itself. Use "RETURN <value>" anywhere in a script in order to finish execution, and return a certain value.

When you run a script through EXECUTE SCRIPT, it will inherit copies of variables from its calling script/command line. Modifications of variables will be local to the script, and will be lost when script execution is complete.

The AbortOnError variable determines whether a script is aborted when any of its commands result in an error message. AbortOnError is not inherited but defaults to 1 in any script.

Commands operating on Parameters

LOAD PARAMETERFILE <file>, LOAD PARAMETERS <file>

Loads a parameter file specified by its path and name. Relative paths are interpreted relative to the operator module's working directory at startup. Usually, this matches the executable's location in the prog directory. As the parameter file name must not contain white space, please use HTML-type encoding for white space characters, such as Documents%20and%20Settings when referring to a user's "Documents and Settings" folder.

NOTE: Only those parameters will be loaded that do exist at the time when this command is called. In idle state, no parameters exist other than created by ADD PARAMETER. After modules are connected and have published their parameters to the Operator module, a full set of parameters exists.

ADD PARAMETER <parameter definition>

Adds a parameter to the system. The parameter is specified as a parameter line. This command may not be used after system initialization has completed, i.e. its use is restricted to the "Idle" and "Publishing" phases of system operation. In terms of handlers, its use is restricted to the OnConnect handler.

EXISTS PARAMETER <name>

Returns "true" when the specified parameter exists in the system, and "false" otherwise.

ISEMPTY PARAMETER <name>

Returns "true" when the specified parameter exists and has no values, "false" if it exists and has values.

SET PARAMETER <name>[( idx1, idx2 )] <value>

Sets the named parameter to the specified value. Values that contain special characters, or whitespace must use the parameter value encoding. Use parentheses to specify indices or labels. Omitted indices default to 1.

SET PARAMETER <parameter line>

Replace a parameter's value and definition with the information given in the parameter line. The parameter must exist in the system when this command is executed.

GET PARAMETER <name>[( idx1, idx2 )]

Prints the value of the named parameter. Use parentheses to specify indices or labels.

SET PARAMETERROWS <parameter name> <rows>

Sets the number of rows in the named parameter.

GET PARAMETERROWS <parameter name>

Prints the number of rows in the named parameter.

SET PARAMETERCOLS <parameter name>

Sets the number of columns in the named parameter.

GET PARAMETERCOLS <parameter name>

Prints the number of columns in the named parameter.

LIST PARAMETER <wildcard expression>, LIST PARAMETERS

Prints all parameters with names matching the wildcard expression, in form of parameter lines.

CLEAR PARAMETERS

Clears the list of parameters in the system. May only be executed in Idle and Publishing system states.

Commands operating on States

In BCI2000, there are three types of States that differ in their alignment to brain signal data (see Kinds of States). This section applies to both Stream States, and normal States. For Event States, see the next section.

ADD STATE <name> <bit width> <initial value>

Adds a state variable to the system. State variables are defined by name, bit width, and initial value (see Technical Reference:State Definition). This command may not be used after system initialization has completed, i.e. its use is restricted to the "Idle" and "Publishing" phases of system operation. In terms of handlers, its use is restricted to the OnConnect handler.

EXISTS STATE <name>

Returns "true" when the specified state exists in the system, and "false" otherwise.

SET STATE <name> <value>, SET STATES <name1> <value1> <name2> <value2> ...

Sets the named state variable to the specified integer value by sending a state message to the source module. Setting the Running state to 1 will start system operation, setting it to 0 will suspend the system.

SET STATES will atomically set the values of multiple states.

GET STATE[(<sample>)] <name>

Gets the value of the named state. Note that state values are not updated from the application module when the OperatorBackLink parameter is 0. In that case, GET STATE will return the state's initial value.

An optional one-based sample index may be given to indicate that the state value should be retrieved at the given sample position. Sample positions range from 1 to the number of samples per block present in the state vector. The number of samples per block may be retrieved using GET STATEVECTOR SAMPLES.

By default, the state's value is retrieved for sample index 1.

LIST STATE <wildcard expression>, LIST STATES

Lists all states, or states with names matching the given wildcard expression, in form of state lines.

CLEAR STATES

Clears the list of states in the system. May only be executed in Idle and Publishing system states.

FREEZE STATES, THAW STATES

Freezes/thaws the values of all states in the state vector, without interfering with system operation. "Freezing" creates, and "thawing" discards, a frozen snapshot of the state vector. For the duration of its existence, GET STATE calls will be diverted to the snapshot. This is useful for ensuring that multiple GET STATE commands actually retrieve mutually-consistent values from different state variables (i.e. values from the same sample-block).

GET STATEVECTOR SAMPLES

Returns the number of samples in the state vector per block of data. In the system's "Running" state, this matches the number of samples per block in the source data. Prior to the "Running" state, this command returns 1 because the state vector has not yet been updated from the application module.

Commands operating on Events

Events are a special type of state, which are recorded asynchronously, at single-sample resolution. Events may only be added while the system is in "idle" state. This kind of events is not related to Operator Events as defined below.

ADD EVENT <name> <bit width> <initial value>

Adds an event to the system. Like state variables, events are defined by name, bit width, and initial value (see Technical Reference:State Definition). This command may not be used after the system has started up, so it is typically executed in a batch file before STARTUP has been called.

EXISTS EVENT <name>

Returns "true" when the specified event exists in the system, and "false" otherwise.

SET EVENT <name> <value>

Asynchronously sets an event to the given value. Recording events requires the EventLink logger component to be present in the source module.

NOTE: In versions prior to BCI2000 3.06, this command behaved as described for PULSE EVENT below, rather than as advertised. If you used SET EVENT in your scripts, it is recommended to replace it with PULSE EVENT in order to retain original behavior.

PULSE EVENT <name> <value>

Asynchronously sets an event to the given value for a single sample duration. Recording events requires the EventLink logger component to be present in the source module.

SET EVENTS [<name> <value>] [<name2> <value2>] ...

Asynchronously sets given events to their specified values. Using this command, rather than multiple SET EVENT commands in a row, ensures that all event changes are recorded at exactly the same point in time. Recording events requires the EventLink logger component to be present in the source module.

PULSE EVENTS [<name> <value>] [<name2> <value2>] ...

Asynchronously sets given events to their specified values for a single sample duration. Using this command, rather than multiple PULSE EVENT commands in a row, ensures that all event changes are recorded at exactly the same point in time. Recording events requires the EventLink logger component to be present in the source module.

GET EVENT[(<sample>)] <name>

Gets the value of the named event. Note that evemt values are not updated from the application module when the OperatorBackLink parameter is 0.

An optional one-based sample index may be given to indicate that the event's value should be retrieved at the given sample position. Sample positions range from 1 to the number of samples per block present in the state vector. The number of samples per block may be retrieved using GET STATEVECTOR SAMPLES.

By default, the event's value is retrieved for sample index 1.

LIST EVENT <wildcard expression>, LIST EVENTS

Lists all events, or events with names matching the given wildcard expression, in form of state lines.

CLEAR EVENTS

Clears the list of events in the system. May only be executed in Idle state.

Commands operating on VisProperties

SET VISPROPERTY <visID>.<name> <value>

Sets the named visualization property for the specified visualization ID to the given value. If the visualization ID contains a dot character, it must be encoded in parameter value encoding. E.g., setting the window width for the visualization ID "2.D1" would be written SET VISPROPERTY 2%2ED1.Width 200.

RESET VISPROPERTY <visID>.<name>

Removes the named visualization property with the specified visualization ID from the property store, effectively resetting its value to its default.

GET VISPROPERTY <visID>.<name>

Prints the value of the named visualization property for the specified visualization ID.

SET VISPROPERTIES <property set ID>

Applies a set of visualization property values as given in the VisPropertySets parameter. In that matrix-valued parameter, row labels specify visualization properties such as "SRCD.Left", and columns represent sets of property values. Column labels are IDs of the corresponding property sets.

Commands operating on the Control Signal

GET SIGNAL( <channel index>, <element index> )

Prints the value of the control signal at the given indices. Indices are 1-based.

GET SIGNAL CHANNELS

Prints the number of channels in the control signal.

GET SIGNAL ELEMENTS

Prints the number of elements (samples) in the control signal.

FREEZE SIGNAL, THAW SIGNAL

Freezes/thaws the contents of the control signal, without interfering with system operation. "Freezing" creates, and "thawing" discards, a frozen snapshot of the control signal. For the duration of its existence, GET SIGNAL calls will be diverted to the snapshot. This is useful for ensuring that multiple GET SIGNAL commands actually retrieve mutually-consistent values from different elements in the control signal (i.e. values from the same sample-block).

Commands operating on Expressions

EVALUATE EXPRESSION <expression>

This command treats the remainder of the command as a literal mathematical expression (for a description, see User Reference:Expression Syntax). An expression may contain assignments to variables; such variables may then be used in later expressions. Note that expression variables are different from local and environment variables that may be accessed by GET/SET VARIABLE/ENVIRONMENT. Expression variables hold numerical values, while local and environment variables hold string values. Also, environment variables are accessible to child processes started with SYSTEM or START EXECUTABLE, while expression variables are accessible only to scripts. When a script is executed using the EXECUTE SCRIPT command, it will inherit a copy of all expression variables present. Changes to these variables from the executed script will not be visible in the parent script.

CLEAR EXPRESSION VARIABLE <name>

Clears the named expression variable from storage.

Commands operating on Watches

A "Watch" is an object that consists of a set of expressions, and an action. Whenever the value of any of the expressions changes, the watch is "triggered", and the action is executed. Watches allow client applications to respond to BCI2000 state changes in a reliable manner. Rather than polling information from BCI2000, a client may create a watch to be notified about changes of interest. This avoids the problem of missing short-lived changes, which is inherent in the polling approach.

For watches created through operator scripting, the action consists of dumping values of all the expressions to a UDP port.

The intended use of a watch from a client application is to create a separate thread that reads from the watch's UDP port in a blocking mode, and calls an appropriate handler function whenever it receives data. The data sent will consist of a single UDP packet with a single line in ASCII format, terminated with a CRLF sequence. The line consists of tab-separated data fields, which contain the current values of the expressions specified when creating the watch. In addition, the first field contains a time stamp in milliseconds. This time stamp represents the point in time where the expression value changed, with an accuracy of a single sample.

ADD WATCH [decimate <n>] <expression1> <expression2> ... [AT <ip:port>]

Adds a watch for the listed expressions. Each expression's value will be reported in a separate field. When an address is specified in ip:port format, the watch tries to open that port for output, and creation fails if that port is taken. When no address is specified, a free port is chosen automatically. In both cases, successful creation of the watch is indicated by returning the output address in ASCII format. The address is also used to uniquely identify a watch in the context of a connection.

When a decimate <n> clause is present, the watch will be created with decimation, i.e. it will only be evaluated for every nth sample of the state vector.

If a watch is created through a remote connection, it will use the remote host's external IP address for automatically chosen addresses. Otherwise, the output port will be associated with the machine's localhost address.

Watches may be created even if the system is currently running. In this case, the watch is triggered immediately at creation, and sends its current expression values to its output port.

ADD WATCH SYSTEM STATE [AT <address>]

Similar to the first variant of ADD WATCH, but will watch the system's state as reported by GET SYSTEM STATE.

CLEAR WATCH <address>, CLEAR WATCHES [<wildcard-expression>]

Removes the watches specified by address, or those with their addresses matching a wildcard expression. If CLEAR WATCHES is called without argument, all watches will be deleted.

TRIGGER WATCH <address>, TRIGGER WATCHES [<wildcard-expression>]

Forces dumping of the watches' current expression values to their output ports. Mostly useful for testing purposes.

LIST WATCHES [<wildcard-expression>]

Displays a list of existing watches, and their addresses.

COUNT WATCHES [<wildcard-expression>]

Returns the number of existing watches, or the number of watches whose addresses match the optional wildcard expression.

Commands operating on Files, Directories, and Paths

EXTRACT DIRECTORY <path>, EXTRACT FILE <path>, EXTRACT FILE BASE <path>

Extracts the directory or file portion of a given path. When the path specifies a non-existing directory, the directory name must be followed with a separator ("/") in order to be recognized as a directory. The EXTRACT DIRECTORY command always returns its result with a trailing separator. The EXTRACT FILE BASE command returns the file portion without extension.

IS DIRECTORY <path>, IS FILE <path>, IS PATH <path>

Determines whether the specified path points to an existing directory, file, or any of the two. The result is returned as one of the strings "true" or "false".

PARENT DIRECTORY <path>

Returns the parent directory of the specified path, independently of whether the path points to a directory, or to a file.

CURRENT DIRECTORY

Returns the current working directory. Note that working directories are per-script, i.e. multiple scripts running in parallel may have different working directories.

CHANGE DIRECTORY <path>

Changes the script's working directory. Note that working directories are per-script, i.e. multiple scripts running in parallel may have different working directories. Also, this command will only affect the default directory of scripting commands, not the application-global working directory as seen by the OS.

MAKE DIRECTORY <path>

Creates a new directory with the given path. The directory's parent must exist for the command to succeed.

LIST DIRECTORY [<path> or <wildcard expression>]

Returns a listing of the specified directory, or the current working directory if no path is specified. The listing is in long form. You may use wildcard expressions in order to restrict the output.

LIST FILE <wildcard expression>

Returns a list of file names matching wildcard expression in the current directory.

LIST FILES [<directory> [<wildcard expression>]]

Returns a list of file names from the specified directory, matching wildcard expression. When wildcard expression is missing, all files are listed. When directory is missing, files in the current directory are listed.

LIST DIRECTORIES [<directory> [<wildcard expression>]]

Returns a list of directory names from the specified directory, matching wildcard expression. When wildcard expression is missing, all directories are listed. When directory is missing, directories in the current directory are listed.

RENAME FILE <current path> <new path>, RENAME DIRECTORY <current path> <new name>

Renames a file resp. a directory. For files, a different path may be given in the second argument, resulting in that the file is moved to the location specified by the new path. For directories, the path up to the directory's name must stay the same.

REMOVE FILE <path>, REMOVE DIRECTORY <path>

Removes the specified file or directory. This command cannot be undone. The directory must be empty for the command to succeed.

FORCEREMOVE DIRECTORY <path>

Removes the specified directory and its contents. Symbolic links are treated as ordinary files, i.e. they are not followed. This command cannot be undone.

NORMALIZED PATH <path>

Returns <path>, with the following transformations applied:

  • Removes relative elements (.. .) as far as possible. For absolute paths, the result will not contain any relative elements; for relative paths, double-dots may appear at the beginning of the result if necessary.

If a relative path simplifies to the empty string, ./ is returned. Thus, the result of NORMALIZED PATH is never empty, unless its input was empty.

  • Replaces backward slashes with forward slashes to achieve uniformity across platforms.
  • On case-insensitive file systems, replaces the spelling of names with the one stored in the file system.
  • On Win32, replaces short (8.3) names with long ones.
CANONICAL PATH <path>

If <path> points to an existing file or directory, CANONICAL PATH returns a valid absolute file path, suitable as an unambiguous representation for the object pointed to. Especially, two non-empty canonical path strings will compare equal if and only if they refer to the same file system object.

If <path> does not point to an existing file system object, construction of a canonical path is not possible due to lack of information about the named object, and CANONICAL PATH will return an empty string.

NOTES: The need for an unambiguous, or canonical, representation arises due to ambiguities in the string representation of paths, and in file systems themselves.

  • Paths may contain relative elements: /mydir/../myfile points to the same object as /myfile.
  • A path that involves symbolic links will point to the same object as a path containing one or more of those links in resolved form.
  • File systems may be case-insensitive, or may even provide multiple distinct names for individual directory entries (Win32 short vs. long names).

On Win32, CANONICAL PATH returns the short (8.3) representation of a path, using uppercase spelling, and backslashes as directory separators. Apart from efficiency considerations, this aesthetically unpleasing representation has been chosen to discourage its use for anything except comparing file system objects.

On other systems, CANONICAL PATH will return the result of the POSIX realpath() function.

In both cases, a CANONICAL PATH will end with a native directory separator if, and only if, the object pointed to is a directory.

REAL PATH <path>

On this command provides a work-alike for the POSIX realpath() function. If <path> is empty, or if <path> points to a non-existing object, the result will be empty. Otherwise, an absolute path will be returned, with symbolic links resolved, using forward slashes as directory separators, and with spelling normalized as described for NORMALIZED PATH. A forward slash will be appended if the path points to a directory.

NOTE: In principle, the path returned by REAL PATH should be just as unambiguous as the result of CANONICAL PATH. However, there are a few caveats:

  • On case-insensitive file systems, two independently obtained results of REAL PATH might differ in case spelling even if referring to the same file system object. This should not be the case for CANONICAL PATH.
  • Determining the result of CANONICAL PATH is a fast operation. In contrast, REAL PATH may be expensive to determine, as for each directory on the path a listing needs to be obtained, and a canonical path needs to be formed, and compared, for half of the listed directory entries on average.
  • On Win32, quite some amount of complexity arises from backward compatibility layers, forbidden file names, multiple filesystem roots, etc. Internally calling GetShortPathName(), CANONICAL PATH does not need to handle that complexity, and may be considered more reliable for identifying file system objects than REAL PATH.
READ FILE <filename>

Returns the text content of the file indicated by <filename>.

WRITE FILE <filename> <line>, OVERWRITE FILE <filename> <line>, APPEND TO FILE <filename> <line>

These commands write the specified <line> of text to the file indicated by <filename>. They behave like the echo command of a typical shell, in the sense that a line-ending will be automatically added to the <line> if it does not already end with one. To suppress the automatic line-ending, you can say WRITE FILE <filename> <content> WITHOUT LINE ENDING (or equivalently, for short, you can say WITHOUT LF or WITHOUT CRLF). Any previous content in <file> will be lost if you use WRITE or OVERWRITE (they are the same, just synonyms for each other) whereas APPEND preserves previous content and adds the new <line> to the end.

Commands operating on executables

START EXECUTABLE <command line>

Behaves identically to CREATE PROCESS, except that it does not report a process id for the new process. For details, see CREATE PROCESS.

CATEGORIZE EXECUTABLE <name or path>

BCI2000 keeps a list of executables/modules that have been built, and sorts them into categories. The CATEGORIZE EXECUTABLE command provides a way to retrieve that information. Given the name or path of an executable, it outputs one of the following categories:

  • SignalSource,
  • SignalProcessing,
  • Application,
  • Operator,
  • Tool,
  • Helper,
  • Unknown.

Commands operating on Lines of input/output

WRITE LINE <line>

Writes a line of output. Destination depends on the context in which a script is executed. If the context is an Operator Handler, output is written as a log entry. If the context is a telnet session, output is written to the telnet connection. If the context is a BCI2000Shell, output is written to the shell's stdout.

READ LINE

Reads a line of input from the current execution context's input. If the command is executed within an Operator Handler, it will fail. If executed within a telnet session, the other side of the connection is prompted for input. If executed from within a BCI2000Shell, input is read from the shell's stdin.

Commands operating on Processes in the Operating System

CREATE PROCESS <command line>

Starts the specified executable with options. This command returns after the started program has finished initialization, i.e. it will detect load time failures such as missing DLLs on Windows. If the process is still running when CREATE PROCESS returns, its result will be an operating system process id (pid). If the process has terminated, CREATE PROCESS will report its exit code marked with an ExitCode tag to allow distinction between a pid and an exit code. Please note that CREATE PROCESS requires quoting of arguments differently from other scripting commands. For details, see the SYSTEM command.

TERMINATE PROCESS <pid>

Tries to terminate the process with the given operating system pid, waiting for the process to terminate before returning. Will return false to indicate that a suitable process existed but could not be terminated.

WAIT FOR PROCESS <pid> [<timeout seconds> = infinite]

Waits for the process with the given operating system pid to terminate, or the timeout to expire. Returns false to indicate that the process is still executing.

SHOW PROCESS <pid>

Makes all windows visible which are associated with the process referred to by pid. In addition, brings one of the process' top level (desktop level) windows to the front for user interaction.

HIDE PROCESS <pid>

Makes all windows invisible which are associated with the process referred to by pid.

Global commands

HELP [<type>]

When called with a type argument, lists commands that exist for the specified type (e.g., SYSTEM, or FILE). When called without argument, lists all commands in their main form. HELP ALL will list all commands, including synonyms.

SET <name> <value>, GET <name>, <name>

Allows to set or retrieve the value of local and environment variables. The name is matched against local and environment variables. When no variable with the given name is found, SET will create a local variable, while GET will result in an error. GET may be further abbreviated to only consist of a name.

GET further allows evaluation of mathematical expressions. When the expression is invalid, or contains an unknown variable, an error is triggered.

GET SYSTEM STATE

Prints the current system state. This will be one of Unavailable, Idle, Startup, Initialization, Resting, Suspended, ParamsModified, Running, Termination, Busy (for details, see the WAIT FOR command below).

GET CURRENT RUN FILE

Prints the full path to the current run file, or an empty string, if called outside Running state.

WAIT FOR <system state> [<timeout seconds>]

Waits until the system is in the specified state. This may be one of Idle, Startup, Connected, Resting, Suspended, ParamsModified, Running, Busy, or a combination of these, separated with a pipe character: "Resting|Suspended". When no timeout is given, this command waits indefinitely. If the wait is successful, i.e. system state matches one of the specified states, WAIT FOR will return a value of "true". If timeout occurred, WAIT FOR will return "false".

If the BCI2000 system is shut down while a script is executing a WAIT FOR command, the script will be terminated with a "wait aborted" error message.

In more detail, user visible states are:

  • Idle: System is shut down and does not do other processing than executing scripts.
  • Startup: System has started up and is listening for incoming connections.
  • Connected: All core modules have connected to the system.
  • Resting: The system has been initialized but is not running.
  • Suspended: The system has ended running and is behaving like in Resting.
  • ParamsModified: In Suspended mode, parameter changes have been published and will be applied at Resume.
  • Running: The system is running, processing brain signals, and displaying stimuli.
  • Busy: The system is performing a transition from one state to another.

As a synonym for "Connected," "Initialization" is valid as well since it is compatible with the nomenclature in StateMachine.h. Still, it should be avoided because it is easily confused with, but very distinct from, the actions performed in the Initialize() phase.

SLEEP <time in seconds>

Waits (sleeps) for the given amount of time. Timing resolution is 50ms. Tends to sleep a little longer than specified, with the error growing with duration.

GET SYSTEM VERSION

Prints BCI2000 version information.

SETCONFIG, SET CONFIG

Applies current parameters to the system. Corresponds to the SetConfig button in the GUI version of the Operator module.

START

Starts or resumes system operation, corresponding to the Start/Resume button in the GUI version of the Operator module.

STOP

Stops system operation. Corresponds to the Stop button in the GUI version of the Operator.

STARTUP SYSTEM

When in idle state, starts up the system to wait for incoming connections from core modules. Additionally, the following arguments may be given: 1) an IP address on which to listen (default is to listen on all addresses), and 2) a list of generic core module names with ports. The default configuration corresponds to these arguments:

STARTUP SYSTEM * SignalSource:4000 SignalProcessing:4001 Application:4002

A system log file may optionally be specified on this line, by inserting the --SystemLogFile flag between the IP address and the module specifiers. For example:

STARTUP SYSTEM * --SystemLogFile=SOME_FILE.TXT SignalSource:4000 SignalProcessing:4001 Application:4002

The system log file will record all operator log window messages for the current launch, until the system shuts down. It may be helpful to use the variables $YYYYMMDD and $HHMMSS to specify the filename. Note that file name and path cannot contain spaces.

SHUTDOWN SYSTEM

Shuts down core modules, and enters idle system state.

RESET SYSTEM

Shuts down the system, and clears all parameter, state, and event information.

QUIT, EXIT [<result>]

Quits the operator module after terminating all BCI2000 modules. The optional result argument determines the result of the executed script.

CLOSE CONNECTION, TERMINATE CONNECTION

In the context of a telnet or websocket connection, this command will terminate the connection. In other contexts, such as event handlers, it will be ignored.

SYSTEM <command line>

Executes a shell command, redirecting any console output into the command's script result. E.g., to obtain a directory listing, under Windows, you would enter

SYSTEM DIR

NOTE: Arguments to the SYSTEM command are executed by the operating system's shell, and thus may require quoting different from the other scripting commands. E.g., writing

SET mydir ${PARENT DIRECTORY $BCI2000LAUNCHDIR}; ECHO ${LIST FILES $mydir}

will list files in the BCI2000 main directory, independently of whether the path to that directory contains space characters or not. However, to obtain a directory listing through the SYSTEM command, you would need to write

ECHO ${SYSTEM DIR "$mydir"}

to make sure the content of the variable mydir is interpreted as a single argument, independently of whether it contains space characters.

LOG <message>

Append the specified message to the system log.

WARN <message>

Append the specified message to the system log, formatted as a warning.

ERROR <message>

Append the specified message to the system log, formatted as an error message.

CAPTURE MESSAGES <message types>

Captures system log messages into a background buffer. When no message type is given, all messages are captured. When "None" is given as a message type, message capturing is disabled. Otherwise, the message type must be one of "Errors", "Warnings", "Debug", "Log". Multiple message types may be specified in a single command. When "None" appears within a single command, all preceding message types are ignored. Multiple CAPTURE MESSAGES commands are cumulative, except when "None" is specified as a message type.

FLUSH MESSAGES

Clears the background message buffer, and returns its previous content. Use CAPTURE MESSAGES to capture messages into the background message buffer.

Operator-module defined Commands

HIDE WINDOW [<name>], SHOW WINDOW [<name>]

Hides or shows the specified window. When called without a window name, the Operator module's main window is hidden or shown. The window name may be one of Main, Configuration, Log, Watches, and Visualizations. When "Watches" is given, the window state refers to visibility of the Watches area in the Visualizations window.

MOVE WINDOW <name> <x> <y>, RESIZE WINDOW <name> <width> <height>

Moves resp. resizes the specified window with one of the above names. Window decorations (title bar, frame) are taken into consideration such that the total size of the window matches the given width and height.

ARRANGE WINDOW <name> <rows> <cols> <row> <col> [<rowspan> <colspan>]

Arranges the named window in a virtual rows x cols grid at grid position row, col.

Optional rowspan and colspan arguments may be given to specify the extension of the window across more than one row or column. Using a rowspan of 0 will result in the window assuming its minimum height. Likewise, a colspan of 0 will result in the window's minimum width.

If multiple screens are present, windows are arranged on the screen that contains the Operator window.

SET TITLE <title>

Sets the title of the main Operator window.

SET BUTTON <idx> <label> <commands>

Configures the function button with 1-based index idx such that it is labelled label and executes commands.

VISUALIZE WATCH [decimate <n>] [range <min> <max>] <expression1> ...

Adds a watch for the given expressions to the operator module's Watches window, and makes the Watches window visible if it is hidden. If the decimate clause is present, the command will create a watch which will be evaluated only for every nth sample in the state vector. If the range clause is present, display minimum and maximum will not be adjusted automatically but will be fixed to the values given.

By default, decimate has a value of "auto"; this means that there is no decimation of evaluation (i.e., all samples are evaluated) but changes that occur within 1ms will be shortened into their maximum and minimum, and thus reported as only two values. This has proven to be efficient for avoiding sluggishness from flooding the application with events.

MOVE VISUALIZATON <visID> <x> <y>, RESIZE VISUALIZATION <visID> <width> <height>

Moves resp. resizes the specified visualization window. Window decorations (title bar, frame) are taken into consideration such that the total size of the window matches the given width and height. If unknown, visualization IDs may be obtained from the Operator's Window->Visualizations menu.

ARRANGE VISUALIZATION <visID> <rows> <cols> <row> <col> [<rowspan> <colspan>]

Arranges the named visualization window in a virtual rows x cols grid at grid position row, col.

Optional rowspan and colspan arguments may be given to specify the extension of the window across more than one row or column. Using a rowspan of 0 will result in the window assuming its minimum height. Likewise, a colspan of 0 will result in the window's minimum width.

If multiple screens are present, windows are arranged on the screen that contains the Operator window.

RECORD VISUALIZATION <visID> [on|off]

Registers the named visualization for recording. The visualization name must be the short name as displayed in the View->Visualizations menu. Switching a visualization recording to "on" is only possible in idle state (because an event for recording frame numbers must be registered in the system). When a visualization is registered for recording, its frames are stored immediately as they arrive at the operator module. Currently, only bitmap visualizations may be recorded.

Example: Recording the application window

RECORD VISUALIZATION ApplicationWindow on
...
# after parameters have been loaded
Set parameter VisualizeApplicationWindow 1
...
PUT NOTE <note>

Adds the given text to the notes window. If the system is in Running state, the text will also be added to the current notes file as described under "notes file".

START TELNET <address>, STOP TELNET <address>

Starts or stops a telnet server listening at the given address. The address is in <IP>:<port> format.

IMPORTANT: You should not use this command on global internet addresses, as there is no authentication performed. Only use addresses in the local network, such as 10.x.x.x, 172.x.x.x, or 192.168.x.x.

START WEBSOCKET <address>, STOP WEBSOCKET <address>

Starts or stops a websocket server listening at the given address. The address is in <IP>:<port> format.

IMPORTANT: You should not use this command on global internet addresses, as there is no authentication performed. Only use addresses in the local network, such as 10.x.x.x, 172.x.x.x, or 192.168.x.x.

Operator-module Commands for Soliciting Input from the User

CHOOSE [INPUT] FILE[S] [OF TYPE <.ext1> [<.ext2> ...]] [STARTING AT <dir>] [WITH PROMPT <message>]

Via the Qt graphical user interface, prompt the user to select an existing file (or multiple files, if the keyword FILES is used). Print the resulting file path(s). (See the Custom GUI Commands page for details and examples.)

CHOOSE [OUTPUT] FILE [OF TYPE <.ext1> [<.ext2> ...]] [STARTING AT <dir>] [WITH PROMPT <message>]

Via the Qt graphical user interface, prompt the user to specify a file into which data can be saved (with an overwrite confirmation dialog if it already exists). Print the resulting file path. (See the Custom GUI Commands page for details and examples.)

CHOOSE DIRECTORY [STARTING AT <dir>] [WITH PROMPT <message>]

Via the Qt graphical user interface, prompt the user to specify a directory. Print the resulting directory path. (See the Custom GUI Commands page for details and examples.)

CUSTOM DIALOG [MESSAGE <msg>] [VAR <varname> <label> {[<options>]} ] [BUTTONS {<buttons>}] ...

Via the Qt graphical user interface, prompt the user with a modal dialog that can be flexibly customized. (See the Custom GUI Commands page for details and examples.)

Predefined Variables

The following variables exist when an Operator script is executed. Some of these variables are marked with local. This means that they are not environment variables, i.e. they are invisible to child processes that are launched using the SYSTEM or START EXECUTABLE commands, and their values may be different between script invocations. In script code, they are accessed like ordinary variables.

BCI2000LAUNCHDIR

The full absolute path to the directory where the Operator module resides. This is also prepended to the PATH environment variable, such that executables from the current BCI2000 installation will have precedence over any other executable with the same name.

On macOS, this is the path where the Operator module's application bundle resides. In the default configuration, this is the BCI2000 prog directory, both on macOS and on other platforms.

BCI2000BINARY

The full absolute path to the Operator module.

LogLevel (local)

Determines the amount of log information written to the Operator log. This variable only affects log messages originating from the current script. May be 2 (display all log messages), 1 (display fewer log messages), or 0 (suppress all log messages). Set to 1 by default. Changes to this local variable are not propagated to any sub-scripts called. NOTE: Only log messages are controlled by this variable. Error messages originating from a script with 'LogLevel 0' will still be displayed in the Operator log. When 'AbortOnError' is set to 0, you may set 'LogLevel' to -1 in order to display error messages. When 'AbortOnError' is 1 (the default), error messages will always be displayed to indicate the reason for failure.

AbortOnError (local)

Determines if a script is aborted when an error happens, or whether the error is silently ignored. Set to 1 by default (script is aborted on error). Changes to this local variable are not propagated to any sub-scripts called.

Result (local)

The result of the last executed scripting command. When a script is executed by calling EXECUTE SCRIPT, the script's last executed command determines the result of the EXECUTE SCRIPT command itself.

0, 1, ... 9 (local)

When a script file is being executed, these variables contain the arguments of the EXECUTE SCRIPT command. $0 resolves to the full absolute path to the current script file. Within scripts, all of the 0-9 variables are defined, and those that do not have a matching argument are empty.

YYYYMMDD (local)

Local time at execution of the current script, in YYYYMMDD format. In interactive sessions, reflects the time when the session was initiated.

HHMMSS (local)

Local time at execution of the current script, in HHMMSS format. In interactive sessions, reflects the time when the session was initiated.

Abbreviated commands and synonyms

To minimize the need of consulting documentation, as well as for backward compatibility, a number of synonymous commands are provided. E.g., states may be added by INSERT STATE as well as ADD STATE, and the existence of a file may be queried by IS FILE as well as EXISTS FILE. For an overview over all allowed forms of commands, use the HELP ALL command.

To simplify operation in interactive sessions, abbreviated commands exist. Currently, these are:

cd for CHANGE DIRECTORY,
pwd and cd without argument for CURRENT DIRECTORY,
ls and dir for LIST DIRECTORY,
mkdir for MAKE DIRECTORY,
echo for WRITE LINE,
realpath for REAL PATH,
dirname for EXTRACT DIRECTORY,
basename for EXTRACT FILE BASE.

Handlers

In the Operator GUI, script execution is bound to a number of Operator Events (not to be confused with Event states, above) that occur during various stages of BCI2000 system operation:

OnConnect

This handler runs at startup, as soon as all modules are connected to the operator module.

OnSetConfig

This handler runs each time a set of parameters is applied to the system. This happens when the user clicks the SetConfig button. Execution of the SETCONFIG command also runs this handler.

OnStart, OnResume

These handlers are triggered by the Start/Resume button. One of these handlers is also triggered when the Running state variable is set to 1 from a script. Whether OnStart or OnResume is triggered depends on whether the system has been running before with the current set of parameters.

OnStartRun

Similarly to OnStart and OnResume, this handler is triggered by the Start/Resume button. Unlike other event handlers, OnStartRun has an argument, which is the current run file.

OnStart or OnResume are triggered immediately after Start/Resume has been pressed, whereas OnStartRun is deferred until modules have confirmed to be in Running state. This makes sure that the OnStartRun event handler receives a valid run file name.

OnNextFilePart

This handler is triggered during a run, whenever the FilePart event state is incremented. It allows scripts to know when a new partial file has begun. For further information, see the FileSplittingCondition parameter.

OnSuspend/OnStopRun

Triggered when the system goes from running into suspended mode. This happens whenever the Running state variable changes from 1 to 0. This may happen when the user clicks Suspend, when the application module switches the system into suspended mode, or when a script sets the Running state variable to 0.

OnShutdown

Triggered when the operator module shuts down connections, and switches into idle state.

OnExit

Triggered when the operator module exits. Execution of the QUIT command also triggers this handler. This handler is not available to the SET SCRIPT and CLEAR SCRIPT commands. Also, when both an OnShutdown and an OnExit script are defined, the OnExit script may be executed before the OnShutdown script.

Associating Scripts with Operator Events

In the operator module's preferences dialog, script commands may be entered for each of the handlers listed above. Scripts may be specified as paths to script files, or as immediate one-line scripts. Entries that start with a minus sign (-) are treated as one-line scripts, which may contain multiple commands separated with semicolons.

Scripts may also be specified from the command line used to start up the operator module. There, handler names are followed with the content of the respective preference entry, enclosed in double quotes ("...").

Finally, scripts may be specified using the SET SCRIPT command of the scripting language itself.

Examples

Making use of the Operator module's Function Buttons

To add a state variable called "Artifact", and to set it using the operator's function buttons, do this:

  • Enter the following line under "After All Modules Connected" in the operator's preferences dialog (note the minus sign):
-ADD STATE Artifact 1 0
  • Under "Function Buttons", enter "Set Artifact" as the name of button 1, and as its command, enter (note there is no minus sign):
SET STATE Artifact 1
  • Enter "Clear Artifact" as the name of button 2, and as its command, enter
SET STATE Artifact 0

A fully automated BCI2000 session

Echo Please enter a subject ID:
Set SubjectID ${Read line}

Startup system
Start executable SignalGenerator
Start executable SpectralSignalProcessing
Start executable CursorTask
Wait for Connected
Load parameterfile "../parms/examples/CursorTask_SignalGenerator.prm"
For i in 1 2 3
  Load parameterfile "../parms/MyExperiment/Session$i.prm"
  Set parameter SubjectName $SubjectID
  Set parameter SubjectSession $i
  Set config
  Wait for Resting
  Start
  Wait for Suspended 1000
End

Automating BCI2000 by Operator command line arguments

The following example shows how to specify script commands from the command line. It fully automates BCI2000 operation by loading a parameter file, applying parameters, starting the system once the parameters are applied, and quitting the system once the run is over. For better readability, the example is broken across lines, using the ^ DOS line continuation character.

operator.exe --OnConnect "-LOAD PARAMETERFILE ../parms/examples/CursorTask_SignalGenerator.prm; SETCONFIG" ^
             --OnSetConfig "-SET STATE Running 1"  ^
             --OnSuspend "-QUIT"

Automatically arranging windows in a 4x2 grid

The following example arranges Source and Roundtrip visualizations on the left side of the screen. On the right side, a large area is dedicated to the Operator's log window, and the Operator's main window sits at the bottom right.

Arrange Visualization SRCD 4 2 1 1 2 1
Arrange Visualization RNDT 4 2 3 1
Arrange Window Main 4 2 4 2
Arrange Window Log  4 2 1 2 3 1

See also

User Reference:Module Command Line Options, User Reference:Operator Module, User Reference:BCI2000Shell, Technical Reference:States of Operation