Getting Started
Python Package Dependencies Version Minimums
PyBCI is tested on Python versions 3.9, 3.10 and 3.11 (defined via appveyor.yml)
The following package versions define the minimum supported by PyBCI, also defined in setup.py
:
pylsl>=1.16.1,
scipy>=1.11.1,
numpy>=1.24.3,
antropy>=0.1.6,
tensorflow>=2.13.0,
scikit-learn>=1.3.0,
torch>=2.0.1
Earlier packages may work but are not guaranteed to be supported.
Prerequisite for Non-Windows Users
If you are not using windows then there is a prerequisite stipulated on the pylsl repository to obtain a liblsl shared library. See the liblsl repo documentation for more information. Once the liblsl library has been downloaded pip install pybci-package should work.
Installation
For stable releases use: pip install pybci-package
For development versions use: pip install git+https://github.com/LMBooth/pybci.git
or
git clone https://github.com/LMBooth/pybci.git
cd pybci
pip install -e .
Optional: Virtual Environment
Or optionally, install and run in a virtual environment:
Windows:
python -m venv my_env
.\my_env\Scripts\Activate
pip install pybci-package # For stable releases
# OR
pip install git+https://github.com/LMBooth/pybci.git # For development version
Linux/MaxOS:
python3 -m venv my_env
source my_env/bin/activate
pip install pybci-package # For stable releases
# OR
pip install git+https://github.com/LMBooth/pybci.git # For development version
There has been issues raised with Linux successfully running all pytests and examples, there is a dockerfile included in the root repository outlining what should be a successful build of ubuntu 22:04.
Dockerfile
There is an Ubuntu 22.04 setup found in the Dockerfile in the root of the directory which can be used in conjunction with docker .
Once docker is installed call the following in the root directory:
sudo docker build -t pybci .
sudo docker run -it -p 4000:8080 pybci
Then either run the pybci
CLI command or run pytest Tests
.
Download the Dockerfile and run
Running Pytest Locally
After installing pybci and downloading and extracting the pybci git repository, navigate to the extracted location and run pip install requirements-devel.txt
to install pytest, then call pytest -vv -s Tests\
to run all the automated tests and ensure all 10 tests pass (should take approximately 15 mins to complete), this will ensure pybci functionality is as desired.
Simple Implementation
PyBCI requires an LSL marker stream for defining when time series data should be attributed to an action/marker/epoch and an LSL data stream to create time-series data.
If the user has no available LSL hardware to hand they can set createPseudoDevice=True
when instantiating the PyBCI object to enable a pseudo LSL data stream to generate time-series data and LSL marker stream for epoching the data. More information on PyBCI’s Pseudo Device class can be found here: What is the Pseudo Device?.
The example scripts illustrate various applied ML libraries (SKLearn, Tensorflow, PyTorch) or provide examples of how to integrate LSL hardware.
The code snippet can be used below to run a simple classification task using the Pseudo Device, alternatively call pybci in the command line to get a list of CLI commands and tests:
from pybci import PyBCI
import time
if __name__ == '__main__': # Note: this line is needed when calling pseudoDevice as by default runs in a multiprocessed operation
bci = PyBCI(minimumEpochsRequired = 5, createPseudoDevice=True)
while not bci.connected: # check to see if lsl marker and datastream are available
bci.Connect()
time.sleep(1)
bci.TrainMode() # now both marker and datastreams available start training on received epochs
accuracy = 0
try:
while(True):
currentMarkers = bci.ReceivedMarkerCount() # check to see how many received epochs, if markers sent to close together will be ignored till done processing
time.sleep(0.5) # wait for marker updates
print("Markers received: " + str(currentMarkers) +" Accuracy: " + str(round(accuracy,2)), end=" \r")
if len(currentMarkers) > 1: # check there is more then one marker type received
if min([currentMarkers[key][1] for key in currentMarkers]) > bci.minimumEpochsRequired:
classInfo = bci.CurrentClassifierInfo() # hangs if called too early
accuracy = classInfo["accuracy"]
if min([currentMarkers[key][1] for key in currentMarkers]) > bci.minimumEpochsRequired+10:
bci.TestMode()
break
while True:
markerGuess = bci.CurrentClassifierMarkerGuess() # when in test mode only y_pred returned
guess = [key for key, value in currentMarkers.items() if value[0] == markerGuess]
print("Current marker estimation: " + str(guess), end=" \r")
time.sleep(0.2)
except KeyboardInterrupt: # allow user to break while loop
print("\nLoop interrupted by user.")