Jump to content

APIs: Difference between revisions

From BCI2000 Wiki
First draft of parallel versions, not edited yet to make them exactly parallel
Mellinger (talk | contribs)
 
(2 intermediate revisions by one other user not shown)
Line 20: Line 20:
|[[User Tutorial:BCI2000Remote#C++_Tutorial|Examples]]
|[[User Tutorial:BCI2000Remote#C++_Tutorial|Examples]]
|-
|-
|'''Windows (C#, .NET, JScript)'''
|'''C# (.NET)'''
|[[Contributions:BCI2000Automation|Documentation]]
|[[Contributions:BCI2000Automation#Examples|Examples]]
|-
|'''Unity'''
|[[Contributions:BCI2000RemoteNET|Documentation]]
|[[Contributions:BCI2000RemoteNET|Documentation]]
|[[Contributions:BCI2000RemoteNET#Examples|Examples]]
|[[Contributions:BCI2000RemoteNET#Examples|Examples]]
|}
|}


=Parallel Examples=
=Rosetta Stone=
<div class="noresize">
<div class="noresize">
{|class="wikitable"
{|class="wikitable"
|'''Operator Scripting'''
|'''Operator Scripting'''
<syntaxhighlight>
<syntaxhighlight lang="bash">
#! ../prog/BCI2000Shell
#! ../prog/BCI2000Shell
@cls & ..\prog\BCI2000Shell %0 %* #! && exit /b 0 || exit /b 1\n
@cls & ..\prog\BCI2000Shell %0 %* #! && exit /b 0 || exit /b 1\n
Line 40: Line 36:
Reset system
Reset system
Startup system localhost
Startup system localhost
Start executable SignalGenerator --local --LogKeyboard=1 --SpinningWheel=1 --ShowDisplayStatistics=1
Start executable SignalGenerator --local --LogMouse=1 --LogKeyboard=1
Start executable P3SignalProcessing --local
Start executable SpectralSignalProcessing --local
Start executable StimulusPresentation --local
Start executable CursorTask --local
Wait for Connected
Wait for Connected
Load parameterfile "../parms/examples/StimulusPresentation_SignalGenerator.prm"
Load parameterfile "../parms/examples/CursorTask_SignalGenerator.prm"
 
Set Config
Start
</syntaxhighlight>
</syntaxhighlight>


|'''BCI2000RemoteNET'''
|'''C# (.NET, Unity)'''
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
using BCI2000RemoteNET;
using BCI2000RemoteNET;
Line 55: Line 54:
bci.connection.StartOperator("../prog/Operator" + isWindows ? ".exe" : ""); //Add file extension if on windows  
bci.connection.StartOperator("../prog/Operator" + isWindows ? ".exe" : ""); //Add file extension if on windows  
bci.connection.Connect();
bci.connection.Connect();
bci.LoadParameters("../parms/examples/StimulusPresentation_SignalGenerator.prm");
bci.LoadParameters("../parms/examples/CursorTask_SignalGenerator.prm");
bci.StartupModules(new Dictionary<string, IEnumerable<string>?> {
bci.StartupModules(new Dictionary<string, IEnumerable<string>?> {
{"SignalGenerator", new() {"LogKeyboard=1", "SpinningWheel=1", "ShowDisplayStatistics=1"}},
{"SignalGenerator", new() {"LogMouse=1", "LogKeyboard=1"}},
{"P3SignalProcessing", null},
{"SpectralSignalProcessing", null},
{"StimulusPresentation", null}
{"CursorTask", null}
});
});
bci.SetConfig();
bci.Start();
</syntaxhighlight>
</syntaxhighlight>


Line 71: Line 73:
bci.WindowVisible = True
bci.WindowVisible = True
bci.WindowTitle = "Python controlled"
bci.WindowTitle = "Python controlled"
bci.SubjectID = "pysub"
bci.Connect()
bci.Connect()
bci.Execute("cd ${BCI2000LAUNCHDIR}")
bci.Execute("cd ${BCI2000LAUNCHDIR}")
bci.StartupModules(("SignalGenerator", "ARSignalProcessing", "CursorTask"))
bci.StartupModules(("SignalGenerator --LogMouse=1 --LogKeyboard=1", "SpectralSignalProcessing", "CursorTask"))
bci.LoadParametersRemote("../parms/examples/CursorTask_SignalGenerator.prm")
bci.LoadParametersRemote("../parms/examples/CursorTask_SignalGenerator.prm")
bci.SetConfig()
bci.SetConfig()
print("SubjectName parameter: " + bci.GetParameter("SubjectName"))
bci.Start()
bci.Start()
bci.Execute("Wait for Suspended 5")
 
if bci.Result != "":print("Result: " + bci.Result)
bci.Stop()
del bci
del bci
</syntaxhighlight>
</syntaxhighlight>
Line 88: Line 87:
|'''Matlab'''
|'''Matlab'''
<syntaxhighlight lang="matlab">
<syntaxhighlight lang="matlab">
clc;clear;
if not(libisloaded('bci'))
if not(libisloaded('bci'))
     loadlibrary('C:\BCI2000.x64\prog\BCI2000RemoteLib64','C:\BCI2000.x64\src\core\Operator\BCI2000Remote\BCI2000RemoteLib.h', 'alias', 'bci')
     loadlibrary('C:\BCI2000.x64\prog\BCI2000RemoteLib64','C:\BCI2000.x64\src\core\Operator\BCI2000Remote\BCI2000RemoteLib.h', 'alias', 'bci')
Line 104: Line 102:


calllib('bci', 'BCI2000Remote_SetWindowVisible', bciHandle,1);
calllib('bci', 'BCI2000Remote_SetWindowVisible', bciHandle,1);
modules = libpointer('stringPtrPtr', {'SignalGenerator', 'SpectralSignalProcessing', 'CursorTask'});
modules = libpointer('stringPtrPtr', {'SignalGenerator --local --LogMouse=1 --LogKeyboard=1', 'SpectralSignalProcessing', 'CursorTask'});
calllib('bci', 'BCI2000Remote_StartupModules2', bciHandle, modules, 3);
calllib('bci', 'BCI2000Remote_StartupModules2', bciHandle, modules, 3);
calllib('bci', 'BCI2000Remote_LoadParametersRemote', bciHandle, '../parms/examples/CursorTask_SignalGenerator.prm');
calllib('bci', 'BCI2000Remote_LoadParametersRemote', bciHandle, '../parms/examples/CursorTask_SignalGenerator.prm');
%%
%add states
calllib('bci', 'BCI2000Remote_AddStateVariable', bciHandle,'matlab',8, 0);


calllib('bci', 'BCI2000Remote_SetConfig', bciHandle);
calllib('bci', 'BCI2000Remote_SetConfig', bciHandle);
calllib('bci', 'BCI2000Remote_Execute', bciHandle,'Show window watches',0);
calllib('bci', 'BCI2000Remote_Execute', bciHandle,'visualize watch matlab',0);
%start
calllib('bci', 'BCI2000Remote_Start', bciHandle);
calllib('bci', 'BCI2000Remote_Start', bciHandle);
pause(5);
%% send the behavior data to BCI2000
for i = 1:10
    calllib('bci', 'BCI2000Remote_SetStateVariable', bciHandle,'matlab', i);
    pause(1);
end


calllib('bci', 'BCI2000Remote_Delete', bciHandle);
calllib('bci', 'BCI2000Remote_Delete', bciHandle);
Line 152: Line 136:
   }
   }
   // Startup modules
   // Startup modules
   const char* modules[] = { "SignalGenerator --LogMouse=1", "ARSignalProcessing", "CursorTask" };
   std::vector<std::string> modules{ "SignalGenerator --LogMouse=1 --LogKeyboard=1", "SpectralSignalProcessing", "CursorTask" };
  std::vector<std::string> vModules( &modules[0], &modules[0] + sizeof( modules ) / sizeof( *modules ) );
   if( !bci.StartupModules( modules ) )
   if( !bci.StartupModules( vModules ) )
   {
   {
     std::cerr << bci.Result();
     std::cerr << bci.Result();
Line 161: Line 144:
   // Load a parameter file, and set subject information
   // Load a parameter file, and set subject information
   bci.LoadParametersRemote( "../parms/examples/CursorTask_SignalGenerator.prm" );
   bci.LoadParametersRemote( "../parms/examples/CursorTask_SignalGenerator.prm" );
   bci.SubjectID( "SUB" );
 
  // Start a run
   bci.SetConfig()
   if( !bci.Start() )
   bci.Start()
  {
 
    std::cerr << bci.Result();
    return -1;
  }
  // Print feedback signal
  std::string state;
  while( bci.GetSystemState( state ) && state == "Running" )
  {
    double value = 0;
    bci.GetControlSignal( 1, 1, value );
    std::cout << "Control signal: " << value << ", press Enter to proceed" << std::flush;
    std::string line;
    std::getline( std::cin, line );
  }
   return 0;
   return 0;
}
}

Latest revision as of 16:48, 21 April 2025

BCI2000 can be interacted with through external commands, called Application Program Interface (API) commands. BCI2000 provides its own extensive scripting language, called Operator Module Scripting. These commands can then be called with various languages, such as Matlab, Python, C++, JavaScript, and more.

This page provides links to each language's documentation page, with the specific commands that can be used. Examples for each language will then be linked at the bottom.

API Documentation and Examples

Operator Scripting Documentation Examples
Matlab Documentation Examples
Python Documentation Examples
C++ Documentation Examples
C# (.NET) Documentation Examples

Rosetta Stone

Operator Scripting
#! ../prog/BCI2000Shell
@cls & ..\prog\BCI2000Shell %0 %* #! && exit /b 0 || exit /b 1\n
Change directory $BCI2000LAUNCHDIR
Show window; Set title ${Extract file base $0}
Reset system
Startup system localhost
Start executable SignalGenerator --local --LogMouse=1 --LogKeyboard=1
Start executable SpectralSignalProcessing --local
Start executable CursorTask --local
Wait for Connected
Load parameterfile "../parms/examples/CursorTask_SignalGenerator.prm"

Set Config
Start
C# (.NET, Unity)
using BCI2000RemoteNET;
using System.RuntimeInformation.InteropServices;
BCI2000Remote bci = new(new BCI2000Connection());
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
bci.connection.StartOperator("../prog/Operator" + isWindows ? ".exe" : ""); //Add file extension if on windows 
bci.connection.Connect();
bci.LoadParameters("../parms/examples/CursorTask_SignalGenerator.prm");
bci.StartupModules(new Dictionary<string, IEnumerable<string>?> {
	{"SignalGenerator", new() {"LogMouse=1", "LogKeyboard=1"}},
	{"SpectralSignalProcessing", null},
	{"CursorTask", null}
	});

bci.SetConfig();
bci.Start();
Python
bci = BCI2000Remote()
print("Operator path: " + bci.OperatorPath)
bci.WindowVisible = True
bci.WindowTitle = "Python controlled"
bci.Connect()
bci.Execute("cd ${BCI2000LAUNCHDIR}")
bci.StartupModules(("SignalGenerator --LogMouse=1 --LogKeyboard=1", "SpectralSignalProcessing", "CursorTask"))
bci.LoadParametersRemote("../parms/examples/CursorTask_SignalGenerator.prm")

bci.SetConfig()
bci.Start()

del bci


Matlab
if not(libisloaded('bci'))
    loadlibrary('C:\BCI2000.x64\prog\BCI2000RemoteLib64','C:\BCI2000.x64\src\core\Operator\BCI2000Remote\BCI2000RemoteLib.h', 'alias', 'bci')
end
libfunctions('bci')
%need to call BCI2000Remote_Delete to recover the memory
bciHandle = calllib('bci', 'BCI2000Remote_New');
calllib('bci', 'BCI2000Remote_SetOperatorPath', bciHandle,'C:/BCI2000.x64/prog/Operator');
if calllib('bci', 'BCI2000Remote_Connect', bciHandle) ~= 1
    fprintf('Could not connect to BCI2000, aborting.')
    calllib('bci', 'BCI2000Remote_Delete', bciHandle);
    return
end
calllib('bci', 'BCI2000Remote_Execute', bciHandle,'Change directory $BCI2000LAUNCHDIR',0);

calllib('bci', 'BCI2000Remote_SetWindowVisible', bciHandle,1);
modules = libpointer('stringPtrPtr', {'SignalGenerator --local --LogMouse=1 --LogKeyboard=1', 'SpectralSignalProcessing', 'CursorTask'});
calllib('bci', 'BCI2000Remote_StartupModules2', bciHandle, modules, 3);
calllib('bci', 'BCI2000Remote_LoadParametersRemote', bciHandle, '../parms/examples/CursorTask_SignalGenerator.prm');

calllib('bci', 'BCI2000Remote_SetConfig', bciHandle);
calllib('bci', 'BCI2000Remote_Start', bciHandle);

calllib('bci', 'BCI2000Remote_Delete', bciHandle);
C++
#include "BCI2000Remote.h"
#include <string>
#include <vector>
#include <iostream>

int main( int argc, char* argv[] )
{
  // Instantiate a BCI2000Remote object
  BCI2000Remote bci;
  // Assume that Operator executable resides in the same directory as this program.
  std::string path = ( argc > 0 ) ? argv[0] : "";
  size_t pos = path.find_last_of( "\\/" );
  path = ( pos != std::string::npos ) ? path.substr( 0, pos + 1 ) : "";
  // Start the Operator module, and connect
  bci.OperatorPath( path + "Operator" );
  if( !bci.Connect() )
  {
    std::cerr << bci.Result();
    return -1;
  }
  // Startup modules
  std::vector<std::string> modules{ "SignalGenerator --LogMouse=1 --LogKeyboard=1", "SpectralSignalProcessing", "CursorTask" };
  if( !bci.StartupModules( modules ) )
  {
    std::cerr << bci.Result();
    return -1;
  }
  // Load a parameter file, and set subject information
  bci.LoadParametersRemote( "../parms/examples/CursorTask_SignalGenerator.prm" );

  bci.SetConfig()
  bci.Start()

  return 0;
}