Skip to content

Commit

Permalink
ExplorePy Version 3.2.0 (#328)
Browse files Browse the repository at this point in the history
* change unstable bt threshold to .5s (#295)

* Hotfix unstable imp (#296)

* change unstable bt threshold to .5s

* add hint for disabled BT

* Hotfix unstable imp (#297)

* change unstable bt threshold to .5s

* add hint for disabled BT

* apply changes for v3.1.0

* delete redundant files

* add shared libraries

* add .pyd file

* add mac libraries

* add files to public repo

* fix flake8 error

* apply isort

* add files to public repo (#311)

* add files to public repo

* fix flake8 error

* apply isort

* Bump sentry-sdk from 1.19.1 to 2.8.0 in /docs (#304)

Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.19.1 to 2.8.0.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](getsentry/sentry-python@1.19.1...2.8.0)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Salman Rahman <salman2135@gmail.com>

* Bump tornado from 6.3.2 to 6.4.1 in /docs (#303)

Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.3.2 to 6.4.1.
- [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst)
- [Commits](tornadoweb/tornado@v6.3.2...v6.4.1)

---
updated-dependencies:
- dependency-name: tornado
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Salman Rahman <salman2135@gmail.com>

* delete shared lib

* add byte calculator

* update sentry sdk version to 2.8.0 (#314)

* APIS-1081 Added testing for available EEG service in btcpp and unpair for OS other than Mac

* APIS-1081 Changed call to get services, removed debug messages

* APIS-1081 Removed reconnection attempts (on Maziar's recommendation)

* APIS-1081 Removed execution of service discovery for MacOS

* APIS-1081 Added async wait and replaced check for Mac with check for Windows

* APIS-1081 Added UUID normalization, fixed linter

* APIS-1081 Made wait only necessary for Windows, added checks to prevent getting new client and connecting if already done

* Froze pylsl version to 1.16.2 (for now)

* discard corrupt yaml file on load (#319)

* discard corrupt yaml file on load

* fix isort error

* no reconnect on ble disconnection (#320)

* no reconnect on ble disconnect

* Set correct log messsage on disconnection callback

* APIS-1036 Added Miniconda installation to macOS runner, updated upload action, updated Python version

* Apis 930 reconnect problem at higher sampling rates (#317)

* break parser loop on usb disconnect

* APIS-1115 Replaced function to calculate notch coefficients with iirnotch

* change baud rate & do sanity check on usb disconnect

* read USB data in chunks

* increase usb read timeout

* check device name before usb connection (#318)

* add comment

* fix flake8 error

* add whitespace before inline

* read all available bytes from serial port in one go

* wait 10ms in read method when data is not enough

* set bt flag to false on usb

* handle value error or recording stop

* remove backslash from string

* use lower order filter for higher SPS

* add lock on data write

* fix flake8 error

* continue usb connection when name query fails

* change core usb buffer to deque, add usb conditional in bt drop calc

* restore debug message on usb read

* APIS-930 Added catching yaml.parser.ParserError

---------

Co-authored-by: SonjaSt <sonja.stefani@tum.de>

* Apis 935 explore desktop loses track of impedance mode being enabled disabled (#321)

* break parser loop on usb disconnect

* APIS-1115 Replaced function to calculate notch coefficients with iirnotch

* change baud rate & do sanity check on usb disconnect

* read USB data in chunks

* increase usb read timeout

* check device name before usb connection (#318)

* add comment

* fix flake8 error

* add whitespace before inline

* read all available bytes from serial port in one go

* wait 10ms in read method when data is not enough

* set bt flag to false on usb

* handle value error or recording stop

* remove backslash from string

* use lower order filter for higher SPS

* add lock on data write

* fix flake8 error

* continue usb connection when name query fails

* disable imp on fresh connection

* check device info with specific key for imp mode

* fix isort and flake8 errors

---------

Co-authored-by: SonjaSt <sonja.stefani@tum.de>

* Apis 1131 fix name connect issue in mac (#323)

* stop stream and clear stream buffer before name query

* remove unused method and import

* remove print statement

* isort fix

* APIS-1131 Added lock to prevent simultaneous read/write to settings yaml

* Linter (E302) settings_manager.py

---------

Co-authored-by: SonjaSt <sonja.stefani@tum.de>

* Froze bleak version (0.22.3)

* Update tools.py (#325)

* Bugfix command thread (#327)

* move disable imp command on fresh connection to top level file

* remove disable imp command from stream processor, update thread variable

* separate notch filters for impedance (#326)

* simplify-mac-intel-connection

* Revert "simplify-mac-intel-connection"

This reverts commit f2a1a86.

* Remove acquiring serial port instance on BLE connect (#329)

* remove acquiring serial port instance on BLE connect

* APIS-1193 remove unused import for pr submission

* Revert "APIS-1193 remove unused import for pr submission"

This reverts commit 845b801.

* APIS-1193 remove unused import for pr submission

* Merge master into develop (#330)

* Release 3.1.0 (#307)

* change unstable bt threshold to .5s (#295)

* Hotfix unstable imp (#296)

* change unstable bt threshold to .5s

* add hint for disabled BT

* Hotfix unstable imp (#297)

* change unstable bt threshold to .5s

* add hint for disabled BT

* apply changes for v3.1.0

* delete redundant files

* add shared libraries

* add .pyd file

* add mac libraries

* Updated the P300 oddball paradigm to work with Explore Pro devices (#310)

* delete dynamic lib files

---------

Co-authored-by: Kyotikk <63866051+Kyotikk@users.noreply.github.com>

* delete dynamic lib files

* Removed macOS from unit testing

* Update docs (#333)

* Added email to authors, removed duplicate section in stallation rst

* Updated installation rst

* Removed blueutil requirement for Mac

* bumpversion minor

* add changelog

---------

Co-authored-by: Salman Rahman <salman2135@gmail.com>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nayan Sharma <51515645+rednayan@users.noreply.github.com>
Co-authored-by: SonjaSt <sonja.stefani@tum.de>
Co-authored-by: Sonja Stefani <35492857+SonjaSt@users.noreply.github.com>
Co-authored-by: Kyotikk <63866051+Kyotikk@users.noreply.github.com>
  • Loading branch information
6 people authored Jan 31, 2025
1 parent 31048f3 commit 9f05b8d
Show file tree
Hide file tree
Showing 38 changed files with 2,552 additions and 159 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 3.1.0
current_version = 3.2.0
commit = False
tag = False

Expand Down
25 changes: 19 additions & 6 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python: [3.9.12]
os: [ubuntu-latest, windows-latest]
python: [3.12]
runs-on: ${{ matrix.os }}
timeout-minutes: 10
steps:
Expand All @@ -21,23 +21,36 @@ jobs:
run: git checkout ${{ env.BRANCH }}

- name: Install non-python dependencies on Ubuntu
if: runner.os == 'Linux'
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update -y
sudo apt-get install libbluetooth-dev -y
- name: Set up Python ${{ matrix.python }}
- name: Set up Miniconda for Linux and Windows with ${{ matrix.python }}
if: matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest'
uses: s-weigand/setup-conda@v1
with:
python-version: ${{ matrix.python }}
conda-channels: anaconda, conda-forge
- name: Set up Miniconda for macOS with ${{ matrix.python }}
if: matrix.os == 'macos-latest'
shell: bash
run: |
mkdir -p ${{ github.workspace }}/miniconda3
curl "https://repo.anaconda.com/miniconda/Miniconda3-py312_24.9.2-0-MacOSX-arm64.sh" -o "${{ github.workspace }}/miniconda3/miniconda.sh"
bash ${{ github.workspace }}/miniconda3/miniconda.sh -b -u -p ${{ github.workspace }}/miniconda3
rm ${{ github.workspace }}/miniconda3/miniconda.sh
source ${{ github.workspace }}/miniconda3/bin/activate
conda init bash
conda config --prepend channels conda-forge
echo "${{ github.workspace }}/miniconda3/bin/" >> $GITHUB_PATH
- name: Install liblsl from conda-forge
run: |
conda install -c conda-forge liblsl
pip install -e .[test]
python -m pytest --import-mode=append --html=pytest_report.html --self-contained-html
- name: Archive test results
if: success() || failure()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: pytest-results
name: pytest-results-${{ matrix.runs-on }}
path: pytest_report.html
12 changes: 6 additions & 6 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Authors
=======


* Salman Rahman - mentalab.com
* Andrea Escartin - mentalab.com
* Sonja Stefani - mentalab.com
* Mohamad Atayi - mentalab.com
* Masoome Fazelian - mentalab.com
* Alex Platt - mentalab.com
* Salman Rahman - `salman@mentalab.com <mailto:salman@mentalab.com>`_
* Andrea Escartin
* Sonja Stefani - `sonja@mentalab.com <mailto:sonja@mentalab.com>`_
* Mohamad Atayi
* Masoome Fazelian
* Alex Platt
14 changes: 12 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,33 @@
Changelog
=========

3.2.0 (31.1.2025)
------------------
* Fix critical bug in settings file modification
* Improve BT communication
* Disable impedance on fresh connection
* Introduce new sampling rates


3.1.0 (8.11.2024)
------------------
* Add USB streaming support
* Improve BT communication


3.0.1 (28.08.2024)
------------------
* Improve device connectivity
* Add text marker support


3.0.0 (7.6.2024)
------------------
* Improve Mac OSX support
* Add Support for Explore Pro
* Robust data parsing


2.0.0 (5.1.2024)
------------------
* Add Mac OSX support
Expand All @@ -31,7 +42,6 @@ Changelog
* Add yaml file for RTD build



1.8.1 (11.7.2023)
------------------
* Bugfix record data
Expand All @@ -50,7 +60,7 @@ Changelog

1.7.0 (21.12.2022)
------------------
* Add suppport for new explore+ 32 ch device
* Add support for new explore+ 32 ch device
* Sorted timestamps in CSV
* Settings file to preserve experiment settings

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
:target: https://pypi.org/project/explorepy


.. |commits-since| image:: https://img.shields.io/github/commits-since/Mentalab-hub/explorepy/v3.1.0.svg
.. |commits-since| image:: https://img.shields.io/github/commits-since/Mentalab-hub/explorepy/v3.2.0.svg
:alt: Commits since latest release
:target: https://github.com/Mentalab-hub/explorepy/compare/v3.1.0...master
:target: https://github.com/Mentalab-hub/explorepy/compare/v3.2.0...master


.. |wheel| image:: https://img.shields.io/pypi/wheel/explorepy.svg
Expand Down
3 changes: 1 addition & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
year = '2018-2024'
author = 'Mentalab GmbH.'
copyright = '{0}, {1}'.format(year, author)
version = release = '3.1.0'

version = release = '3.2.0'
pygments_style = 'trac'
templates_path = ['.']
extlinks = {
Expand Down
91 changes: 51 additions & 40 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,80 @@ Installation
============

Minimal Requirements
------------
* Python 3.10 to Python 3.12. We recommend Python 3.10.
--------------------
* Python 3.10 to Python 3.12. We recommend Python 3.12.
* Microsoft Build Tools for Visual Studio 2019 (only Windows)
* 6GB RAM (minimum 1GB *free* RAM during the session)
* Intel i5 or higher (2x2.5GHz) CPU

Recommended Requirements
------------
* Python 3.10
------------------------
* Python 3.12
* Microsoft Build Tools for Visual Studio 2019 (only Windows)
* 8GB RAM
* Intel i7 or higher CPU

How to install
--------------

Windows
^^^^^^^

Option 1: Installing via installer file (basic)
""""""""
"""""""""""""""""""""""""""""""""""""""""""""""

*This option is best for users who only intend to use* ``explorepy`` *via graphical user interface*
Windows and Mac
^^^^^^^^^^^^^^^

For example, if you want to quickly visualize and record data, use Option 1.
If you intend to add ``explorepy`` commands to a Python script
(e.g. an experiment script), install ``explorepy`` via Anaconda instead.
*This option is best for users who only intend to use functionalities offered by* ``explorepy`` *via a graphical user interface*

For an overview of ``explorepy`` commands, click `here <https://explorepy.readthedocs.io/en/latest/usage.html#command-line-interface>`_.
For example, if you want to quickly visualize and record data and don't need the command line interface or to use it in your own Python script, use this option.

On a Windows and Mac operating systems, standalone desktop software ``explorepy-desktop`` can be installed using the .exe installable file uploaded to
`release page <https://github.com/Mentalab-hub/explore-desktop-release/releases/latest/>`_. Please note that the dependencies will be installed automatically.
If you intend to call ``explorepy`` from the command line or a Python script (e.g. from an experiment script), install ``explorepy`` via Anaconda/pip instead.

For Windows and Mac, the standalone desktop software ExploreDesktop can be installed using the installer files uploaded to the
`release page <https://github.com/Mentalab-hub/explore-desktop-release/releases/latest/>`_. Please note that the dependencies will be installed automatically and bundled locally with the installed software.


Option 2: Installing from Python Package Index (PyPI) and pip (advanced)
""""""""
*To install explorepy for any python version except 3.10, please contact support@mentalab.com.*
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
*To install explorepy for any Python version below 3.10, please contact support@mentalab.com.*

*This option is best for users who intend to include* ``explorepy`` *functionalities in their own Python scripts or use it from the command line.*

For an overview of ``explorepy`` commands, click `here <https://explorepy.readthedocs.io/en/latest/usage.html#command-line-interface>`_.

Windows
^^^^^^^

*This option is best for users who intend to include* ``explorepy`` *functionalities in their own Python scripts.*
To install the ``explorepy`` API and all its dependencies using pip on Windows:

1. Install Anaconda (or any other Python distribution; these instructions pertain to Anaconda only). Download and install the `Anaconda Windows installer <https://www.anaconda.com/distribution/#download-section>`_.
1. Install Anaconda (or any other Python distribution; these instructions pertain to Anaconda only). Download and run the `Anaconda installer for windows <https://www.anaconda.com/download/success>`_.
2. Install `Microsoft Build Tools for Visual Studio 2019 <https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16>`_. Select *Desktop development with C++* in the workloads tab. Make sure that *MSVCv142 - VS 2019 C++ x64/x86 build tools* and the latest version of *Windows 10 SDK* are checked.
3. Open the Conda command prompt.
4. We recommend using a virtual environment. To do this:
3. Open the Anaconda command prompt.
4. We recommend using a conda environment. To do this:

a. In Conda command prompt: ``conda create -n myenv python=3.10``
b. Activate the virtual environment: ``conda activate myenv``
a. In the Anaconda command prompt: ``conda create -n myenv python=3.12``
b. Activate the conda environment: ``conda activate myenv``

5. Upgrade your pip: ``python -m pip install --upgrade pip``
6. Run: ``pip install explorepy``, to install ``explorepy`` from PyPI.
6. Install liblsl: ``conda install -c conda-forge liblsl``
7. Run ``pip install explorepy`` to install ``explorepy`` from PyPI.

Ubuntu
^^^^^^
1. From Linux Terminal, run these commands one by one: ``sudo apt-get install libbluetooth-dev`` and ``sudo apt-get install build-essential`` and ``conda install -c conda-forge liblsl``.
1. From the terminal, run these commands one by one: ``sudo apt-get install libbluetooth-dev`` and ``sudo apt-get install build-essential``.
2. We recommend installing Anaconda. Download and installer `Anaconda<https://www.anaconda.com/download>`/Miniconda/.
3. We recommend using a virtual environment in Conda. To do this:

a. In Conda command prompt: ``conda create -n myenv python=3.10``
b. Activate the virtual environment: ``conda activate myenv``
a. In the Anaconda command prompt: ``conda create -n myenv python=3.12``
b. Activate the conda environment: ``conda activate myenv``

4. Upgrade your pip: ``python -m pip install --upgrade pip``
5. Run: ``pip install explorepy``, to install ``explorepy`` from PyPI.
6. From Linux Terminal, run: ``sudo apt install libxcb-cursor0``
5. Install liblsl: ``conda install -c conda-forge liblsl``
6. Run ``pip install explorepy`` to install ``explorepy`` from PyPI.
7. From the terminal, run: ``sudo apt install libxcb-cursor0``

Set up USB streaming in Linux
"""""""""""""""""""""""""""""
+++++++++++++++++++++++++++++

a. Set up ``udev`` rules for appropiate permission to ``/dev/ttyACM*`` in Linux

*Steps to Execute the Udev Script Manually*
Expand Down Expand Up @@ -108,29 +115,33 @@ b. Alternate method: Temporarily granting appropriate permissions to ``/dev/ttyA
1. Identify the device (ttyACM0, ttyACM1, ttyACM2, etc) in ``/dev`` directory


2. Execute this command in the terminal (replcae * with appropiate id) ::
2. Execute this command in the terminal (replace * with appropiate id) ::

chmod 666 /dev/ttyACM*

Mac
^^^
1. Install ``XCode`` from the Mac App store. For this, you may need to upgrade to the latest version of MacOS. For older versions of MacOS, find compatible versions of ``XCode`` `here <https://en.wikipedia.org/wiki/Xcode>`_. All old ``XCode`` versions are available `here <https://developer.apple.com/download/more/>`_.
2. Accept the license agreement: ``sudo xcodebuild -license``
3. Download and installer `Anaconda<https://www.anaconda.com/download>`/Miniconda/.
4. We recommend using a virtual environment in Conda.
2. Accept the license agreement: ``sudo xcodebuild -license``.
3. It is best to install Anaconda. Download and run the `Anaconda installer for Mac <https://www.anaconda.com/download/success>`_. For older versions of MacOS, compatible version of Anaconda can be found in `this table <https://docs.continuum.io/anaconda/install/#old-os>`_ and downloaded `here <https://repo.anaconda.com/archive/index.html>`_.
4. We recommend using a conda environment.

a. In Conda command prompt: ``conda create -n myenv python=3.10``
b. Activate the virtual environment: ``conda activate myenv``
a. In the Anaconda command prompt: ``conda create -n myenv python=3.10``
b. Activate the conda environment: ``conda activate myenv``

5. Upgrade your pip: ``python -m pip install --upgrade pip``
6. Run: ``pip install explorepy``, to install ``explorepy`` from PyPI.
7. Connect your Explore device from Mac Bluetooth menu and run your Python script.
6. Install liblsl: ``conda install -c conda-forge liblsl``
7. Run ``pip install explorepy`` to install ``explorepy`` from PyPI.
8. Connect your Explore device from the Bluetooth menu and run your Python script.


Quick test
----------

* Open the Conda command prompt (if you used pip) or Windows command prompt (if you used the installable file).
* Activate the virtual environment (this step is only necessary in the Conda command prompt): ``conda activate myenv``
*Note: If you installed the graphical user interface ExploreDesktop as outlined above, explorepy won't be available from the command line.*

* Open the Anaconda command prompt.
* Activate the virtual environment that you made before installing explorepy: ``conda activate myenv``
* Run ``explorepy acquire -n DEVICE-NAME``
* To stop the command execution, press ``Ctrl+C``

Expand Down
3 changes: 2 additions & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pylsl==1.16.1
PyYAML==6.0.1
PyYAML==6.0.1
scipy==1.11.1
sentry_sdk==1.19.1
tornado==6.4.1
sentry_sdk==2.8.0
sphinx-rtd-theme==1.3.0
sphinx==7.2.4
2 changes: 1 addition & 1 deletion examples/marker_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def main():
interval = 2

for i in range(n_markers):
explore.set_marker(code=i)
explore.set_marker(str(i))
time.sleep(interval)

explore.stop_recording()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import explorepy
import time

# at first, set correct bt interface! Possible interface options are 'ble' and 'usb'
explorepy.set_bt_interface('ble')

exp_device = explorepy.Explore()
exp_device.connect('Explore_AAAC')
exp_device.record_data(file_name='AAAC', duration=30, file_type='csv')
n_markers = 20
interval = 2
for i in range(n_markers):
exp_device.send_8_bit_trigger(i)
time.sleep(2)

12 changes: 12 additions & 0 deletions examples/markers_examples/send_8_bit_marker_independently.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import explorepy
import time

# for independent markers to be stored only in binary file, we only need to instantiate Explore class!
exp_device = explorepy.Explore()

n_markers = 20
interval = 2
for i in range(n_markers):
exp_device.send_8_bit_trigger(i)
time.sleep(2)

34 changes: 34 additions & 0 deletions examples/mne_raw_format_from_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import pandas as pd
import mne
import matplotlib.pyplot as plt
from mne import export


def create_mne_raw_format(file_name, channel_number):
file_name_root = file_name.split('.')[0][:-4]

sampling_freq = pd.read_csv(file_name_root + '_Meta.csv', delimiter=',')['sr'][0]

# Create some dummy metadata
n_channels = channel_number
ch_types = ["eeg"] * n_channels
info = mne.create_info(len(ch_types), sfreq=sampling_freq, ch_types=ch_types)

data_frame = pd.read_csv(file_name, delimiter=',')
data_frame = data_frame.drop('TimeStamp', axis = 1)
# convert to volt, because MNE expects data in Volt unit
data_frame = data_frame.div(1e6)
data_frame = data_frame.transpose()
raw_data = mne.io.RawArray(data_frame, info).notch_filter(freqs=50)
raw_data.plot(show_scrollbars=True, show_scalebars=True, remove_dc=True, highpass=1, lowpass=40)
plt.show()
return raw_data

def explort_eeglab_format(raw_input_df, output_file_name):
export.export_raw(output_file_name, raw_input_df,
fmt='eeglab',
overwrite=True, physical_range=[-400000, 400000])


raw_df = create_mne_raw_format(file_name='chr180924_ExG.csv', channel_number=8)
explort_eeglab_format(output_file_name='output_edf.edf', raw_input_df=raw_df)
Loading

0 comments on commit 9f05b8d

Please sign in to comment.