- 1 Synopsis
- 2 Location
- 3 Versioning
- 4 Parameters
- 5 States
BCPy2000 takes the C++ out of BCI2000 programming. It is aimed at developers of new applications and new signal processing methods, providing a platform for rapid, flexible development of experimental Brain-Computer Interface systems in Python. It takes advantage of various high-level Python packages: VisionEgg for stimulus presentation, NumPy and SciPy for signal processing and classification, and IPython for interactive debugging.
You can program a python-based application module, signal processing module, or even a signal source module for generating custom test signals and playing back data files. You can slow the system right down or even step through packet-by-packet, while interactively debugging your python code with pdb.
BCPy2000 implements a lot of infrastructure that allows you to get an application module running quickly. It also contains a set of optional tools, which are still a work in progress, but which are rapidly turning into a kind of "standard library" of Pythonic signal-processing algorithms and stimulus widgets.
The source code is available under the terms of the GNU General Public License v3.
Thomas Schreiner, Jeremy Hill, Christian Puzicha, Jason Farquhar
BCPy2000 1.0 will be uploaded on 30.09.2008
Source Code Revisions
(TODO: In this section, indicate the BCI2000 source code revisions (changesets) that you used when developing your contribution, and information about testing/compilation. Adapt the list to your own needs. Hint: You obtain the revision of a source code repository by right-clicking its top level directory, and choosing "show log" from the TortoiseSVN submenu.)
- Initial development: XXXX
- Tested under: YYYY
- Known to compile under: ZZZZ
- Broken since: UUUU
BCPy2000 have whatever parameters you want to define in your own python module implementations. There are a few that it implements in the framework already, however:
This boolean, defined by the application framework, determines whether a signal-packet clock should be shown in the bottom right corner of the screen.
Your experiment need not be trial-based, but there's a flexible and automatic way of keeping track of trials within blocks, and blocks within runs, if you choose to design it that way. The self.design() application API method helps you set this up, and this parameter, defined by the application module, specifies the number of trials in a block.
This defaults to 1, so we usually consider a "block" to be the same thing as a "run". However, we once designed an experiment where multiple blocks of trials where recorded continuously in one file, along with the inter-block rest periods. So that had multiple BlocksPerRun. The self.design() application API method allows you to configure this.
The default speed at which the Python source module sends its artificial signals through the system. The default value of this parameter, 1.0, means real time.
An arbitrary string describing your Python application module's behaviour, filled in by the self.Description() hook in your BciApplication class implementation.
An arbitrary string describing your Python signal-processing module's behaviour, filled in by the self.Description() hook in your BciSignalProcessing class implementation.
An arbitrary string describing your Python source module's behaviour, filled in by the self.Description() hook in your BciSource class implementation.
BCPy2000 modules have whatever states you want to define for them in your Python implementation. However, the application module framework defines one or two already:
This is used as a poor substitute for stimulus timing information when a physical synchronization signal is not available. It is set automatically whenever a phase transition occurs, and its value lets you localize that event in the data stream with reasonable precision. Type self.doc('Timing') at one of the BCPy2000 modules' shell prompts for more info.
If you have chosen to implement a trial-based experimental design, this state variable keeps track of the trial number.
If you have chosen to implement multiple blocks per run in your experimetnal design (see the parameter BlocksPerRun) then this keeps track of the block number.
A clock stamp that tells you when phase transitions occur (probably superceded by the simpler-to-use EventOffset mechanism, but let's see).