Contributions:BCI2000Automation

From BCI2000 Wiki
Jump to navigation Jump to search

Synopsis

BCI2000Automation is a Windows scripting interface to the BCI2000 Operator. It allows remote control of BCI2000 from any environment that provides access to Windows automation components. These environments comprise MATLAB, VisualBasic, C#, and others. It wraps up the functionality of the BCI2000Remote C++ class. When writing C++ code, you should consider using that class directly rather than BCI2000Automation.

Before you can use it, BCI2000Automation must be installed on your system. This is possible even if your user account has no administrative privileges. For details, see the Installation section below.

Location

http://www.bci2000.org/svn/trunk/src/contrib/ExternalLinks/BCI2000Automation

Versioning

Author

juergen.mellinger@uni-tuebingen.de

Source Code Revisions

  • Initial development: 3918
  • Tested under: 3942

Functional Description

BCI2000Automation currently contains a single class called BCI2000Remote. This is an interface to the BCI2000 Operator module, and allows to start up, configure, and run BCI2000 from other applications.

To use it, instantiate an object of type "BCI2000Automation.BCI2000Remote". By default, calling the object's Connect() method will start up the Operator module residing in the same directory as BCI2000Automation. You may then use the StartupModules() method in order to start up BCI2000 core modules.

Alternatively, you may specify the path to a BCI2000 batch file in the BCI2000/batch directory. An appropriate batch file should start up Operator and core modules, and needs to forward its command line arguments to the Operator module. All batch files coming with BCI2000 fulfil this condition. When a batch file is specified, there is no need to call the StartupModules() method.

As yet another option, you may connect to an Operator module that is already running, e.g., on a remote machine on the network. In this case, set the BCI2000Remote object's OperatorPath property to an empty string, and its TelnetAddress property to the address that the remote Operator module is listening on, i.e. the remote machine's IP address, followed with a colon, and the port specified when starting up the remote Operator module. The remote Operator module must have been started with the --Telnet command line option, followed with the address to listen on. On the remote machine, this would typically be "localhost:3999". Don't use any of the ports between 4000 and 4002, as this will interfere with the communication between the Operator module, and BCI2000 core modules. Depending on whether the remote Operator module has been started up together with its core modules, or not, you may then call the StartupModules() method in order to start up BCI2000 core modules on the remote machine.

Once all BCI2000 modules are running, you may load parameter files locally or remotely using the LoadParametersLocal() and LoadParametersRemote() methods. Subject ID, Session ID, and data directory are set using the respective BCI2000Remote properties.

A recording may then be started by calling the Start() method. Depending on configuration, the recording will terminate automatically, or needs to be terminated by a call to the Stop() method.

To run BCI2000 in a different configuration (i.e., with different core modules), it is not necessary to terminate the Operator module. Rather, you may execute StartupModules() multiple times in order to terminate currently running core modules, and start different ones.

Once you are done using BCI2000, you may close the connection by calling the Disconnect() method, or by deleting the BCI2000Remote interface. Depending on whether the Operator module was started up by the previous Connect() call, this will terminate the Operator module as well. When connection was made to an already running Operator module, local or remote, the connection will be closed but the Operator module will remain running.

BCI2000Remote Members

The BCI2000Remote class has the following members:

Properties

double Timeout=5 (rw)

Timeout in seconds. Applies when establishing communication between BCI2000Remote and BCI2000.

string OperatorPath=<BCI2000Automation directory>/Operator.exe (rw)

Path to Operator module, or batch file. When empty, BCI2000Remote tries to connect to an already running Operator module which may be on a different machine. This property defaults to the Operator module located in the same directory as BCI2000Automation. You need to explicitly set it to an empty string if you want to connect to an Operator module which is already running.

string TelnetAddress=localhost:3999 (rw)

Telnet address to use for connection. Defaults to localhost:3999. When an operator path is specified, this must be a local address which will be used for communication. To connect to a remote machine, specify the machine's IP address, followed with BCI2000's listening port. You should take care to avoid specifying a port that is used by BCI2000's internal connections between Operator and core modules. By default, these are 4000, 4001, and 4002.

bool WindowVisible=2 (rw)

Visibility of the BCI2000 main window. 0: Invisible, 1: visible, 2: don't change.

string WindowTitle (rw)

The title of the BCI2000 main window.

string Result (r)

Text output of the previously executed command, or an error message when the previously executed command failed.

Recording information
string SubjectID (rw)

The subject ID for the next recording. When this property is empty, the subject ID is taken from the current value of the SubjectName parameter.

string SessionID (rw)

The session ID for the next recording. When this property is empty, the session ID is taken from the SubjectSession parameter.

string DataDirectory (rw)

The data directory for the next recording. When a relative path is given, it is taken relative to BCI2000/data. When this property is empty, the data directory is taken from the DataDirectory parameter.

Connection methods

bool Connect()

Connect to BCI2000. When OperatorPath is not empty, this starts up the operator module before connecting. Will return true on success.

bool Disconnect()

Disconnect from an existing connection. Terminates the running operator module if it was started by the previous Connect() call.

Control of operation

bool StartupModules( array(string) modules )

Start BCI2000 core modules, listed by executable name, including possible command line arguments. Each entry in the array corresponds to a single core module, given relative to the Operator module's working directory, which defaults to BCI2000/prog. You do not need to call this function if the OperatorPath property specifies a batch file rather than the Operator module itself.

bool SetConfig()

Applies the current set of parameters. Will be called from Start() automatically. Returns false if parameters could not be set, e.g. because the system was in running state, or because there was a preflight error when applying parameters. Use the Result property to obtain more error information.

bool Start()

Starts a new run (recording) with current parameters. Returns false if the run could not be started. Use the Result property to obtain more error information.

bool Stop()

Stops the current run (recording).

Parameters and system state

bool GetParameter( string name, string byRef value )

Copies the specified parameter's value into the "value" output argument. Returns false if parameter does not exist.

bool SetParameter( string name, string value )

Sets the specified parameter to the given value. The parameter must exist in the system. To add a parameter, use the Execute() method in conjunction with the INSERT PARAMETER scripting command.

bool LoadParametersLocal( string file )

Load parameters from a file, relative to the working directory of the calling application. This function returns false if the specified file was not found but will not provide information whether parameters were sent successfully. Rather, illegal parameter lines will be silently ignored.

bool LoadParametersRemote( string file )

Load parameters from a file, relative to the working directory of the Operator module connected to. Unless explicitly changed, that working directory is the BCI2000/prog directory in which the Operator module resides.

bool AddStateVariable( string name, int bitWidth, double initialValue )

Adds a state variable to the system. This is only possible before core modules have connected to the Operator module.

bool SetStateVariable( string name, double value )

Sets the value of the named BCI2000 state variable to the given value. Returns false on error.

bool GetControlSignal( int channel, int element, double byRef value )

Copies the value of the control signal at the given indices into the "value" output variable. Indices are 1-based. Typically, the control signal has only a single element, and the number of output channels corresponds to the number of feedback dimensions in feedback experiments, or is 1 in evoked potential experiments.

bool GetSystemState( string byRef state )

Gets the current system state (i.e., state of operation). If no error occurred, the "state" output variable will contain the name of the current system state, which will be one of the names listed at User Reference:Operator Module Scripting#GET_SYSTEM_STATE.

bool GetStateVariable( string name, double byRef value )

Gets the value of a named BCI2000 state variable. If no error occurred, the value will be copied into the "value" output variable.

Scripting methods

bool Execute( string command, [variant exitCode] )

Execute an arbitrary BCI2000 scripting command. A return value of "true" does not indicate successful execution of the command; rather, it indicates that the command was sent, and its result was received. In general, the Result property needs to be examined in order to determine whether the command was executed successfully.

Documentation of BCI2000 Operator scripting commands is available under User Reference:Operator Module Scripting.

Optionally, a variable of type variant may be specified as a second argument. This variable will receive the command's exit code, as described in the BCI2000Remote Class Document. Note that the exitCode variable must be declared as being of type variant in order to receive the exit code. For other types, such as int, the call may appear to succeed, but no value will be written into the variable.

bool SetScript( string event, string commands )

Associate a sequence of Operator scripting commands with an Operator module event. Operator module events are listed on the Operator scripting page. To associate a script with multiple events, concatenate event names with pipe characters: OnStart|OnResume. Calling SetScript() will replace existing script associations. SetScript() will return false if any of the specified events do not exist.

bool GetScript( string event, string byRef script )

Copies the script currently associated with the specified event into the script variable. Returns false if the specified event does not exist.

Installation

Standard installation

Before you can use BCI2000Automation, it must be made known to your Windows system. Each time when you are using BCI2000 on a different machine, or when you moved BCI2000 from its original installation location, you will need to manually install BCI2000Automation. This can be done by double-clicking the InstallAutomation.cmd batch file located in BCI2000/prog.

Deinstallation

BCI2000Automation installation adds a few registry keys to the current user's, or the machine's, "Software/Classes" key. When these keys remain on your machine after removing BCI2000, they will not do any harm, so you need not bother removing them. To remove those keys anyway, log in as the user for whom installation was performed, and execute

InstallAutomation /u

from a command prompt inside the BCI2000/prog directory.

Installation options

BCI2000Automation may be installed or deinstalled for all users of a machine, or only for the user who runs the installation script. Selection between the two is done automatically, by determining whether the user has administrator rights. If so, installation is performed per-machine; if not, installation is done per-user. To manually choose the type of installation, you will need to execute the following command from the command prompt, inside the BCI2000/prog directory:

regsvr32 /n /i:<option> BCI2000Automation.dll

There, <option> may be one of the following:

  • user to install for the current user only,
  • system to install for all users,
  • any to try installation for all users, and switch to per-user installation when that fails,
  • both to install both for all users, and the current user (this option only makes sense for deinstallation).

Note that per-user installation overrides system-wide installation. This may lead to confusing behavior of BCI2000Automation when switching between multiple users, and executing the installation program for those users, or when granting a certain user administrative privileges at one time, and later removing those privileges. To completely remove all references to BCI2000Automation from your machine under such circumstances, execute

rgsvr32 /n /u /s /i:both BCI2000Automation.dll

under all user accounts that may have executed the installation script, and make sure that at least one of those accounts has administrative privileges.

Troubleshooting

If BCI2000Automation does not work as expected, execute BCI2000/prog/InstallAutomation under the user account that is going to run your automation client.

Examples

MATLAB

% Instantiate a BCI2000Remote object
bci = actxserver( 'BCI2000Automation.BCI2000Remote' );
try
 bci.WindowVisible = 1;
  % Start the operator module, and connect to it
  ok = bci.Connect;
  if ~ok
    error( bci.Result )
  end 
  % Startup modules
  modules = { 'SignalGenerator --LogMouse=1', 'ARSignalProcessing', 'CursorTask' };
  ok = bci.StartupModules( modules );
  if ~ok
    error( bci.Result )
  end
  % Load a parameter file, and set subject information
  ok = bci.LoadParametersRemote( '../parms/examples/CursorTask_SignalGenerator.prm' );
  if ~ok
    error( bci.Result )
  end
  bci.SubjectID = 'SUB';
  % Start a run
  ok = bci.Start();
  if ~ok
    error( bci.Result )
  end

  % Display feedback signal
  state = 'Running';
  value = double( 0 );
  while( ok && strcmp( state, 'Running' ) )
    % For formal reasons, the 'value' output variable must be specified both
    % for input and output.
    [~, value] = bci.GetControlSignal( 1, 1,  value );
    fprintf( 1, '%d\n', value );
    pause( 0.5 );
    % For formal reasons, the 'state' output variable must be specified both
    % for input and output.
    [ok, state] = bci.GetSystemState( state );
  end
catch exception
  % Make sure to delete the BCI2000Remote object
  bci.delete;
  throw(exception);
end
% Deleting the BCI2000Remote object will shut down the operator module when it was started by the object
bci.delete;

Visual Basic

Before running the following example, you need to add the BCI2000Automation object library to your VB project's references (Project->References).

' Instantiate a BCI2000Remote object
Dim bci As BCI2000Remote
Set bci = New BCI2000Remote
' Show the Operator window
bci.WindowVisible = 1
' Start the Operator module, and connect to it
ok = bci.Connect
If Not ok Then MsgBox bci.Result

' Startup modules
Dim modules(0 To 2) As String
modules(0) = "SignalGenerator --LogMouse=1"
modules(1) = "DummySignalProcessing"
modules(2) = "DummyApplication"
ok = bci.StartupModules(modules)
If Not ok Then MsgBox bci.Result

' Load a parameter file, and set subject information
ok = bci.LoadParametersRemote("../parms/examples/CursorTask_SignalGenerator.prm")
If Not ok Then MsgBox bci.Result
bci.SubjectID = "SUB"
 
' Start a run
ok = bci.Start

' Display the feedback signal while BCI2000 is running
Dim state As String
Dim value As Double
state = "Running"
value = 0
While ok And state = "Running"
  ok = bci.GetControlSignal(1, 1, value)
  Debug.Print value
  Threading.Thread.Sleep (500)
  Application.DoEvents
  ok = bci.GetSystemState(state)
Wend

' Shut down BCI2000
bci.Disconnect

' Release and delete the BCI2000Remote object
Set bci = Nothing


See also

Programming Reference:BCI2000Remote Class, Contributions:BCI2000PresentationLink, Contributions:BCI2000Command, Contributions:BCI2000PythonBindings, Contributions:Applications