[![PyPI - Downloads](https://img.shields.io/pypi/dm/install-pybci)](https://pypi.org/project/install-pybci) [![PyPI - version](https://img.shields.io/pypi/v/install-pybci)](https://pypi.org/project/install-pybci) [![Documentation Status](https://readthedocs.org/projects/pybci/badge/?version=latest)](https://pybci.readthedocs.io/en/latest/?badge=latest)
[![pybci](https://raw.githubusercontent.com/LMBooth/pybci/main/docs/Images/pyBCITitle.svg)](https://github.com/LMBooth/pybci)
A Python package to create real-time Brain Computer Interfaces (BCI's). Data synchronisation and pipelining handled by the [Lab Streaming Layer](https://github.com/sccn/labstreaminglayer), machine learning with [Pytorch](https://pytorch.org/), [scikit-learn](https://scikit-learn.org/stable/#) or [TensorFlow](https://www.tensorflow.org/install), leveraging packages like [AntroPy](https://github.com/raphaelvallat/antropy), [SciPy](https://scipy.org/) and [NumPy](https://numpy.org/) for generic time and/or frequency based feature extraction or optionally have the users own custom feature extraction class used.
The goal of PyBCI is to enable quick iteration when creating pipelines for testing human machine and brain computer interfaces, namely testing applied data processing and feature extraction techniques on custom machine learning models. Training the BCI requires LSL enabled devices and an LSL marker stream for timing stimuli. (The [examples folder](https://github.com/LMBooth/pybci/tree/main/pybci/Examples) found on the github has a [Pseudo LSL data generator and marker creator](https://github.com/LMBooth/pybci/tree/main/pybci/Examples/PseudoLSLStreamGenerator) in the [mainSend.py](https://github.com/LMBooth/pybci/tree/main/pybci/Examples/PseudoLSLStreamGenerator/mainSend.py) file so the examples can run without the need of LSL capable hardware.)
# Installation
For stable releases use: ```pip install install-pybci```
For unstable dev installations and up-to-date git pushes use: ```pip install --index-url https://test.pypi.org/simple/ install-pybci```
## Prerequisite for Non-Windows Users
If you are not using windows then there is a prerequisite stipulated on the [pylsl repository](https://github.com/labstreaminglayer/pylsl) to obtain a liblsl shared library. See the [liblsl repo documentation](https://github.com/sccn/liblsl) for more information.
Once the liblsl library has been downloaded ```pip install install-pybci``` should work.
(currently using install-pybci due to pybci having name too similar with another package on pypi, [issue here.](https://github.com/pypi/support/issues/2840))
[ReadTheDocs available here!](https://pybci.readthedocs.io/en/latest/) [Examples found here!](https://github.com/LMBooth/pybci/tree/main/pybci/Examples)
[Examples of supported LSL hardware here!](https://labstreaminglayer.readthedocs.io/info/supported_devices.html)
## Python Package Dependencies Version Minimums
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.
## Basic implementation
```python
import time
from pybci import PyBCI
bci = PyBCI() # set default epoch timing, looks for first available lsl marker stream and all data streams
bci.TrainMode() # assume both marker and datastreams available to start training on received epochs
accuracy = 0
try:
while(True): # training based on couple epochs more then min threshold for classifying
currentMarkers = bci.ReceivedMarkerCount() # check to see how many received epochs, if markers sent are too close together will be ignored till done processing
time.sleep(1) # wait for marker updates
print("Markers received: " + str(currentMarkers) +" Class accuracy: " + str(accuracy), 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+1:
bci.TestMode()
break
while True: # now sufficient epochs gathered start testing
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.5)
except KeyboardInterrupt: # allow user to break while loop
pass
```
## Background Information
PyBCI is a python brain computer interface software designed to receive a varying number, be it singular or multiple, Lab Streaming Layer enabled data streams. An understanding of time-series data analysis, the lab streaming layer protocol, and machine learning techniques are a must to integrate innovative ideas with this interface. An LSL marker stream is required to train the model, where a received marker epochs the data received on the accepted datastreams based on a configurable time window around certain markers - where custom marker strings can optionally have its epoch timewindow split and overlapped to count as more then one marker, example: in training mode a baseline marker may have one marker sent for a 60 second window, whereas target actions may only be ~0.5s long, when testing the model and data is constantly analysed it would be desirable to standardise the window length, we do this by splitting the 60s window after the received baseline marker in to ~0.5s windows. PyBCI allows optional overlapping of time windows to try to account for potential missed signal patterns/aliasing - as a rule of thumb it would be advised when testing a model to have a time window overlap >= 50% (Shannon-Nyquist criterion). [See here for more information on epoch timing](https://pybci.readthedocs.io/en/latest/BackgroundInformation/Epoch_Timing.html).
Once the data has been epoched it is sent for feature extraction, there is a general feature extraction class which can be configured for general time and/or frequency analysis based features, ideal for data stream types like "EEG" and "EMG". Since data analysis, preprocessing and feature extraction trechniques can vary greatly between device data inputs, a custom feature extraction class can be created for each data stream maker type. [See here for more information on feature extraction](https://pybci.readthedocs.io/en/latest/BackgroundInformation/Feature_Selection.html).
Finally a passable pytorch, sklearn or tensorflow classifier can be given to the bci class, once a defined number of epochs have been obtained for each received epoch/marker type the classifier can begin to fit the model. It's advised to use bci.ReceivedMarkerCount() to get the number of received training epochs received, once the min num epochs received of each type is >= pybci.minimumEpochsRequired (default 10 of each epoch) the model will begin to fit. Once fit the classifier info can be queried with CurrentClassifierInfo, this returns the model used and accuracy. If enough epochs are received or high enough accuracy is obtained TestMode() can be called. Once in test mode you can query what pybci estimates the current bci epoch is(typically baseline is used for no state). [Review the examples for sklearn and model implementations](https://pybci.readthedocs.io/en/latest/BackgroundInformation/Examples.html).
## All issues, recommendations, pull-requests and suggestions are welcome and encouraged!
Raw data
{
"_id": null,
"home_page": "https://github.com/lmbooth/pybci",
"name": "install-pybci",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": "",
"keywords": "machine-learning tensorflow sklearn pytorch human-computer-interaction bci lsl brain-computer-interface labstreaminglayer",
"author": "Liam Booth",
"author_email": "liambooth123@hotmail.co.uk",
"download_url": "https://files.pythonhosted.org/packages/90/b2/f5ab3f7484d0b72d4e72db84aded6641d68ac224a0b2632af24772d61cfb/install-pybci-1.1.0.tar.gz",
"platform": null,
"description": "[![PyPI - Downloads](https://img.shields.io/pypi/dm/install-pybci)](https://pypi.org/project/install-pybci) [![PyPI - version](https://img.shields.io/pypi/v/install-pybci)](https://pypi.org/project/install-pybci) [![Documentation Status](https://readthedocs.org/projects/pybci/badge/?version=latest)](https://pybci.readthedocs.io/en/latest/?badge=latest)\n\n[![pybci](https://raw.githubusercontent.com/LMBooth/pybci/main/docs/Images/pyBCITitle.svg)](https://github.com/LMBooth/pybci)\n\nA Python package to create real-time Brain Computer Interfaces (BCI's). Data synchronisation and pipelining handled by the [Lab Streaming Layer](https://github.com/sccn/labstreaminglayer), machine learning with [Pytorch](https://pytorch.org/), [scikit-learn](https://scikit-learn.org/stable/#) or [TensorFlow](https://www.tensorflow.org/install), leveraging packages like [AntroPy](https://github.com/raphaelvallat/antropy), [SciPy](https://scipy.org/) and [NumPy](https://numpy.org/) for generic time and/or frequency based feature extraction or optionally have the users own custom feature extraction class used.\n\nThe goal of PyBCI is to enable quick iteration when creating pipelines for testing human machine and brain computer interfaces, namely testing applied data processing and feature extraction techniques on custom machine learning models. Training the BCI requires LSL enabled devices and an LSL marker stream for timing stimuli. (The [examples folder](https://github.com/LMBooth/pybci/tree/main/pybci/Examples) found on the github has a [Pseudo LSL data generator and marker creator](https://github.com/LMBooth/pybci/tree/main/pybci/Examples/PseudoLSLStreamGenerator) in the [mainSend.py](https://github.com/LMBooth/pybci/tree/main/pybci/Examples/PseudoLSLStreamGenerator/mainSend.py) file so the examples can run without the need of LSL capable hardware.)\n\n# Installation\nFor stable releases use: ```pip install install-pybci```\n\nFor unstable dev installations and up-to-date git pushes use: ```pip install --index-url https://test.pypi.org/simple/ install-pybci```\n\n## Prerequisite for Non-Windows Users\nIf you are not using windows then there is a prerequisite stipulated on the [pylsl repository](https://github.com/labstreaminglayer/pylsl) to obtain a liblsl shared library. See the [liblsl repo documentation](https://github.com/sccn/liblsl) for more information. \nOnce the liblsl library has been downloaded ```pip install install-pybci``` should work.\n\n(currently using install-pybci due to pybci having name too similar with another package on pypi, [issue here.](https://github.com/pypi/support/issues/2840))\n\n[ReadTheDocs available here!](https://pybci.readthedocs.io/en/latest/) [Examples found here!](https://github.com/LMBooth/pybci/tree/main/pybci/Examples)\n\n[Examples of supported LSL hardware here!](https://labstreaminglayer.readthedocs.io/info/supported_devices.html)\n\n## Python Package Dependencies Version Minimums\nThe following package versions define the minimum supported by PyBCI, also defined in setup.py:\n\n \"pylsl>=1.16.1\",\n \"scipy>=1.11.1\",\n \"numpy>=1.24.3\",\n \"antropy>=0.1.6\",\n \"tensorflow>=2.13.0\",\n \"scikit-learn>=1.3.0\",\n \"torch>=2.0.1\"\n \nEarlier packages may work but are not guaranteed to be supported.\n\n## Basic implementation\n```python\nimport time\nfrom pybci import PyBCI\nbci = PyBCI() # set default epoch timing, looks for first available lsl marker stream and all data streams\nbci.TrainMode() # assume both marker and datastreams available to start training on received epochs\naccuracy = 0\ntry:\n while(True): # training based on couple epochs more then min threshold for classifying\n currentMarkers = bci.ReceivedMarkerCount() # check to see how many received epochs, if markers sent are too close together will be ignored till done processing\n time.sleep(1) # wait for marker updates\n print(\"Markers received: \" + str(currentMarkers) +\" Class accuracy: \" + str(accuracy), end=\"\\r\")\n if len(currentMarkers) > 1: # check there is more then one marker type received\n if min([currentMarkers[key][1] for key in currentMarkers]) > bci.minimumEpochsRequired:\n classInfo = bci.CurrentClassifierInfo() # hangs if called too early\n accuracy = classInfo[\"accuracy\"]\n if min([currentMarkers[key][1] for key in currentMarkers]) > bci.minimumEpochsRequired+1: \n bci.TestMode()\n break\n while True: # now sufficient epochs gathered start testing\n markerGuess = bci.CurrentClassifierMarkerGuess() # when in test mode only y_pred returned\n guess = [key for key, value in currentMarkers.items() if value[0] == markerGuess]\n print(\"Current marker estimation: \" + str(guess), end=\"\\r\")\n time.sleep(0.5)\nexcept KeyboardInterrupt: # allow user to break while loop\n pass\n```\n\n## Background Information\nPyBCI is a python brain computer interface software designed to receive a varying number, be it singular or multiple, Lab Streaming Layer enabled data streams. An understanding of time-series data analysis, the lab streaming layer protocol, and machine learning techniques are a must to integrate innovative ideas with this interface. An LSL marker stream is required to train the model, where a received marker epochs the data received on the accepted datastreams based on a configurable time window around certain markers - where custom marker strings can optionally have its epoch timewindow split and overlapped to count as more then one marker, example: in training mode a baseline marker may have one marker sent for a 60 second window, whereas target actions may only be ~0.5s long, when testing the model and data is constantly analysed it would be desirable to standardise the window length, we do this by splitting the 60s window after the received baseline marker in to ~0.5s windows. PyBCI allows optional overlapping of time windows to try to account for potential missed signal patterns/aliasing - as a rule of thumb it would be advised when testing a model to have a time window overlap >= 50% (Shannon-Nyquist criterion). [See here for more information on epoch timing](https://pybci.readthedocs.io/en/latest/BackgroundInformation/Epoch_Timing.html).\n\nOnce the data has been epoched it is sent for feature extraction, there is a general feature extraction class which can be configured for general time and/or frequency analysis based features, ideal for data stream types like \"EEG\" and \"EMG\". Since data analysis, preprocessing and feature extraction trechniques can vary greatly between device data inputs, a custom feature extraction class can be created for each data stream maker type. [See here for more information on feature extraction](https://pybci.readthedocs.io/en/latest/BackgroundInformation/Feature_Selection.html).\n\nFinally a passable pytorch, sklearn or tensorflow classifier can be given to the bci class, once a defined number of epochs have been obtained for each received epoch/marker type the classifier can begin to fit the model. It's advised to use bci.ReceivedMarkerCount() to get the number of received training epochs received, once the min num epochs received of each type is >= pybci.minimumEpochsRequired (default 10 of each epoch) the model will begin to fit. Once fit the classifier info can be queried with CurrentClassifierInfo, this returns the model used and accuracy. If enough epochs are received or high enough accuracy is obtained TestMode() can be called. Once in test mode you can query what pybci estimates the current bci epoch is(typically baseline is used for no state). [Review the examples for sklearn and model implementations](https://pybci.readthedocs.io/en/latest/BackgroundInformation/Examples.html).\n\n## All issues, recommendations, pull-requests and suggestions are welcome and encouraged!\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Python interface to create a BCI with the Lab Streaming Layer, Pytorch, SciKit-Learn and Tensorflow packages",
"version": "1.1.0",
"project_urls": {
"Homepage": "https://github.com/lmbooth/pybci"
},
"split_keywords": [
"machine-learning",
"tensorflow",
"sklearn",
"pytorch",
"human-computer-interaction",
"bci",
"lsl",
"brain-computer-interface",
"labstreaminglayer"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "60e5ee015ee384166dab963c72c248580f596ffc14c6dfd5be81a870bbc5cc73",
"md5": "5527bff0f45e888f3d0108b8b97c7114",
"sha256": "2c6ccfc95217410e0acb0cef0dd5b639edd4b8118e96b22d6e0e55bc35951843"
},
"downloads": -1,
"filename": "install_pybci-1.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "5527bff0f45e888f3d0108b8b97c7114",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 32041,
"upload_time": "2023-09-03T11:38:34",
"upload_time_iso_8601": "2023-09-03T11:38:34.475308Z",
"url": "https://files.pythonhosted.org/packages/60/e5/ee015ee384166dab963c72c248580f596ffc14c6dfd5be81a870bbc5cc73/install_pybci-1.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "90b2f5ab3f7484d0b72d4e72db84aded6641d68ac224a0b2632af24772d61cfb",
"md5": "20dc9fa1e132b8b9c3ccb772e5f530a2",
"sha256": "2e06928e34e9a60c662c07859a2a08b79a4b25159bf40577af2f517afe7397ea"
},
"downloads": -1,
"filename": "install-pybci-1.1.0.tar.gz",
"has_sig": false,
"md5_digest": "20dc9fa1e132b8b9c3ccb772e5f530a2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 26576,
"upload_time": "2023-09-03T11:38:35",
"upload_time_iso_8601": "2023-09-03T11:38:35.647624Z",
"url": "https://files.pythonhosted.org/packages/90/b2/f5ab3f7484d0b72d4e72db84aded6641d68ac224a0b2632af24772d61cfb/install-pybci-1.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-03 11:38:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "lmbooth",
"github_project": "pybci",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "install-pybci"
}