Skip to content

Commit 88ed91e

Browse files
salman2135andrea-escartinArnoLib
authored
Rc 1.7.0 (#240)
* Add parser for new device info and 32 channel packets (#227) * Add parser for new device info and 32 channel packets Added new device info with ID-97 and EEG32 class ID- 148 * Create settings_manager.py add settings class for changing channels * add set channel mask functionality * Add mac address retrieval in yaml settings filefile * Update binary file conversion code * add software and hardware channel mask * remove debug log * use settings manager for filters * add setter methods * add chan count to all devices Co-authored-by: Andrea Escartin <[email protected]> * Refactor integrate ch 32 (#228) * Add parser for new device info and 32 channel packets Added new device info with ID-97 and EEG32 class ID- 148 * Create settings_manager.py add settings class for changing channels * add set channel mask functionality * Add mac address retrieval in yaml settings filefile * Update binary file conversion code * add software and hardware channel mask * remove debug log * use settings manager for filters * add setter methods * add chan count to all devices * adjust vref for EEG98_USBC packet to 2.4 * update settings manager with channel mask * add adc mask functionality for recording * add software channel mask setter * fix typo * remove sampling rate check for 32 ch * Change multiplier for new calibration info packet * reformat * fix bug in write_data function * remove redundant lines * add time vector data in record * remove debug message * Feature desktop compatible (#232) * custom path for binary conversion * add custom chan names in recording * fix filters * fix filters * add recorded data sort feature for CSV * Update LSL with new ADC mask system * updated-filter (#223) * corrected butterworth filter Butterworth filters require the Nyquist frequency to be used for calculation when the sampling frequency is not provided * corrected butterworth filters * add test script * APIS-665 test script and comment of packet class * APIS-689 fix BDF recording with mask based indices Co-authored-by: Andrea Escartin <[email protected]> Co-authored-by: Andrea Escartin <[email protected]> Co-authored-by: ArnoLib <[email protected]> * Refactor integrate ch 32 (#233) * Add parser for new device info and 32 channel packets Added new device info with ID-97 and EEG32 class ID- 148 * Create settings_manager.py add settings class for changing channels * add set channel mask functionality * Add mac address retrieval in yaml settings filefile * Update binary file conversion code * add software and hardware channel mask * remove debug log * use settings manager for filters * add setter methods * add chan count to all devices * adjust vref for EEG98_USBC packet to 2.4 * update settings manager with channel mask * add adc mask functionality for recording * add software channel mask setter * fix typo * remove sampling rate check for 32 ch * Change multiplier for new calibration info packet * reformat * fix bug in write_data function * remove redundant lines * add time vector data in record * remove debug message * Feature desktop compatible (#232) * custom path for binary conversion * add custom chan names in recording * fix filters * fix filters * add recorded data sort feature for CSV * Update LSL with new ADC mask system * updated-filter (#223) * corrected butterworth filter Butterworth filters require the Nyquist frequency to be used for calculation when the sampling frequency is not provided * corrected butterworth filters * add test script * APIS-665 test script and comment of packet class * APIS-689 fix BDF recording with mask based indices * adjust binary conversion with new 32 ch bin file * remove adc mask from function arg Co-authored-by: Andrea Escartin <[email protected]> Co-authored-by: Andrea Escartin <[email protected]> Co-authored-by: ArnoLib <[email protected]> * Ignore UTF conversion error * Use only virtual mask for channels set command * Update docs, remove data vis command * APIS-665: fix typo * APIS-665: fix flake8 error (#236) * Update docs (#237) * APIS-665: fix flake8 error * APIS-665: add pandas in setup.py * Update docs (#238) * APIS-665: fix flake8 error * APIS-665: add pandas in setup.py * fix typo * bumpversion minor * fix lint errors * remove whitespace * Update tools.py * remove whitespace * apply isort * Update tools.py * APIS-665: revert changes on recorder and setup.py with flake8 * fix flake8 errors * fix numpy version to 1.21.4 * APS-665: changelog update for release * revert commit d571e79 Co-authored-by: Andrea Escartin <[email protected]> Co-authored-by: Andrea Escartin <[email protected]> Co-authored-by: ArnoLib <[email protected]>
1 parent ce205a3 commit 88ed91e

26 files changed

+380
-157
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 1.6.3
2+
current_version = 1.7.0
33
commit = False
44
tag = False
55

.cookiecutterrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,4 @@ default_context:
5353
version: '0.1.0'
5454
website: 'https://mentalab.co/'
5555
year_from: '2018'
56-
year_to: '2019'
56+
year_to: '2022'

AUTHORS.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ Authors
55
* Mohamad Atayi - mentalab.com
66
* Masooma Fazelian - mentalab.com
77
* Salman Rahman - mentalab.com
8+
* Andrea Escartin - mentalab.com
9+
* Alex Platt - mentalab.com

CHANGELOG.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11

22
Changelog
33
=========
4+
1.7.0 (21.12.2022)
5+
------------------
6+
* Add suppport for new explore+ 32 ch device
7+
* Sorted timestamps in CSV
8+
* Settings file to preserve experiment settings
9+
10+
11+
1.6.3 (25.10.2022)
12+
------------------
13+
* Add new 8 channel Explore+ device
14+
15+
416
1.6.2 (7.09.2022)
517
------------------
618
* Change EDF file extension

README.rst

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
:target: https://pypi.org/project/explorepy
1818

1919

20-
.. |commits-since| image:: https://img.shields.io/github/commits-since/Mentalab-hub/explorepy/v1.6.3.svg
20+
.. |commits-since| image:: https://img.shields.io/github/commits-since/Mentalab-hub/explorepy/v1.7.0.svg
2121
:alt: Commits since latest release
22-
:target: https://github.com/Mentalab-hub/explorepy/compare/v1.6.3...master
22+
:target: https://github.com/Mentalab-hub/explorepy/compare/v1.7.0...master
2323

2424

2525
.. |wheel| image:: https://img.shields.io/pypi/wheel/explorepy.svg
@@ -54,13 +54,13 @@ Quick installation
5454
==================
5555
For Windows users, the best way to install ``explorepy`` is to download the latest ``explorepy`` version from the `release page <https://github.com/Mentalab-hub/explorepy/releases>`_. Please note that dependencies will install automatically from the release page.
5656

57-
For other operating systems, or to build the package manually on Windows, please refer to the information below.
57+
For other operating systems, or to build the package manually on Windows, please refer to the information below. MAC OSX is currently not supported.
5858

5959

6060
Requirements
6161
------------
6262

63-
* Python 3.6 to Python 3.9.
63+
* Python 3.7 to Python 3.10.
6464
* Visual Studio 2015 community edition (Windows only. For package building).
6565
* Bluetooth header files (Linux only. Use: ``sudo apt-get install libbluetooth-dev``).
6666

@@ -112,19 +112,6 @@ You can also visualize the data in real-time.
112112
import explorepy
113113
explorer = explorepy.Explore()
114114
explorer.connect(device_name="Explore_XXXX") # Put your device Bluetooth name
115-
explorer.visualize(bp_freq=(.5, 30), notch_freq=50)
116-
117-
EEG:
118-
119-
.. image:: /images/Dashboard_EEG.jpg
120-
:width: 800
121-
:alt: EEG Dashboard
122-
123-
ECG with heart beat detection:
124-
125-
.. image:: /images/Dashboard_ECG.jpg
126-
:width: 800
127-
:alt: ECG Dashboard
128115

129116
Documentation
130117
=============
@@ -149,6 +136,8 @@ Authors
149136
=======
150137
- `Mohamad Atayi`_
151138
- `Salman Rahman`_
139+
- `Andrea Escartin`_
140+
- `Alex Platt`_
152141
- `Andreas Gutsche`_
153142
- `Masooma Fazelian`_
154143
- `Philipp Jakovleski`_
@@ -158,6 +147,8 @@ Authors
158147

159148
.. _Mohamad Atayi: https://github.com/bmeatayi
160149
.. _Salman Rahman: https://github.com/salman2135
150+
.. _Andrea Escartin: https://github.com/andrea-escartin
151+
.. _Alex Platt: https://github.com/Nujanauss
161152
.. _Andreas Gutsche: https://github.com/andyman410
162153
.. _Masooma Fazelian: https://github.com/fazelian
163154
.. _Philipp Jakovleski: https://github.com/philippjak

docs/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
source_suffix = '.rst'
2727
master_doc = 'index'
2828
project = 'explorepy'
29-
year = '2018-2020'
29+
year = '2018-2022'
3030
author = 'Mentalab GmbH.'
3131
copyright = '{0}, {1}'.format(year, author)
32-
version = release = '1.6.3'
32+
version = release = '1.7.0'
3333

3434
pygments_style = 'trac'
3535
templates_path = ['.']

docs/images/Dashboard_ECG.jpg

-218 KB
Binary file not shown.

docs/images/Dashboard_EEG.jpg

-223 KB
Binary file not shown.

docs/images/Dashboard_imp.jpg

-51.8 KB
Binary file not shown.

docs/installation.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Ubuntu
6868

6969
Mac
7070
^^^
71+
Please note that Mac OSX is not supported at the moment due to some bluetooth bug from Apple OS updates.
7172
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/>`_.
7273
2. Accept the license agreement: ``sudo xcodebuild -license``
7374
3. It is best to install Anaconda. Download and install the `Anaconda Python 3.7 Mac installer <https://www.anaconda.com/distribution/#download-section>`_. 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>`_.
@@ -84,8 +85,8 @@ Quick test
8485

8586
* Open the Conda command prompt (if you used pip) or Windows command prompt (if you used the installable file).
8687
* Activate the virtual environment (this step is only necessary in the Conda command prompt): ``conda activate myenv``
87-
* Run ``explorepy visualize -n DEVICE-NAME -lf 1 -hf 40``
88-
* To stop visualization press ``Ctrl+C``
88+
* Run ``explorepy acquire -n DEVICE-NAME``
89+
* To stop the command execution, press ``Ctrl+C``
8990

9091
Troubleshooting
9192
---------------

docs/usage.rst

Lines changed: 7 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,18 @@ Command Line Interface
1010
Get help for a specific command using
1111
::
1212
explorepy <command> -h
13-
For example to get help about the visualize command, run: ``explorepy visualize -h``
13+
For example to get help about the visualize command, run: ``explorepy push2lsl -h``
1414
::
1515

16-
Usage: explorepy visualize [OPTIONS]
16+
Usage: explorepy push2lsl [OPTIONS]
1717

18-
Visualizing signal in a browser-based dashboard
18+
Push data to lsl
1919

2020
Options:
21-
-a, --address TEXT Explore device's MAC address
22-
-n, --name TEXT Name of the device
23-
-nf, --notchfreq [50|60] Frequency of notch filter.
24-
-lf, --lowfreq FLOAT Low cutoff frequency of bandpass/highpass
25-
filter.
26-
-hf, --highfreq FLOAT High cutoff frequency of bandpass/lowpass
27-
filter.
28-
-h, --help Show this message and exit.
21+
-a, --address TEXT Explore device's MAC address
22+
-n, --name TEXT Name of the device
23+
-d, --duration <integer> Streaming duration in seconds
24+
-h, --help Show this message and exit.
2925

3026

3127
Available Commands
@@ -144,8 +140,6 @@ Takes a binary file and converts it to two EDF files (ExG and orientation - mark
144140

145141
EEGLAB's BIOSIG plugin has problems with some EDF files (see this `issue <https://github.com/sccn/eeglab/issues/103>`_). To resolve this, download a precompiled MATLAB file (mexSLOAD.mex) from BIOSIG `here <https://pub.ist.ac.at/~schloegl/src/mexbiosig/>`_. Documentation is `here <http://biosig.sourceforge.net/help/biosig/t200/sload.html>`_.
146142

147-
.. note:: If you change your device's sampling rate or channel mask during recording, ``explorepy`` will create a new CSV file for ExG data with the given file name plus the time the setting changed.
148-
149143
.. note:: Because environmental factors, like temperature, can affect your device's sampling rate, we recommend computing the sampling rate of recorded data. If you find a deviation between the recorded sampling rate and ``explorepy``'s sampling rate, resample your signal to correct for drifts. The timestamps in the CSV/EDF file can be used to compute the resampling factor.
150144

151145
If you are setting markers, use CSV. Alternatively, push data to LSL and record with `LabRecorder <https://github.com/labstreaminglayer/App-labrecorder/tree/master>`_. Avoid EDF files here, as they cannot guarantee precise timing.
@@ -154,24 +148,6 @@ Example (overwrite):
154148
::
155149
explorepy bin2edf -f input_file.BIN -ow
156150

157-
visualize
158-
%%%%
159-
160-
Visualizes real-time data in a browser-based dashboard. Currently, Google Chrome is supported. Visualization in IE and Edge can be slow.
161-
::
162-
163-
Options:
164-
-a, --address TEXT Explore device's MAC address
165-
-n, --name TEXT Name of the device
166-
-nf, --notchfreq [50|60] Frequency of notch filter.
167-
-lf, --lowfreq FLOAT Low cutoff frequency of bandpass/highpass filter.
168-
-hf, --highfreq FLOAT High cutoff frequency of bandpass/lowpass filter.
169-
-h, --help Show this message and exit.
170-
171-
Example:
172-
::
173-
explorepy visualize -n Explore_XXXX -lf .5 -hf 40 -nf 50
174-
175151
impedance
176152
%%%%
177153

@@ -363,29 +339,6 @@ This will record data in three separate files: "``test_ExG.csv``", "``test_ORN.c
363339

364340
If you are setting markers, use CSV. Alternatively, push data to LSL and record with `LabRecorder <https://github.com/labstreaminglayer/App-labrecorder/tree/master>`_. Avoid EDF, as it cannot guarantee precise timing.
365341

366-
Visualization
367-
""""""""""""""
368-
369-
You can visualize real-time data in a browser-based dashboard using the following code. Currently, Google Chrome is supported. Visualization in IE and Edge can be slow.
370-
::
371-
explore.visualize(bp_freq=(1, 30), notch_freq=50)
372-
373-
``bp_freq`` specifies the cut-off frequencies of bandpass/lowpass/highpass filters. ``notch_freq`` sets the notch filter (either 50 or 60).
374-
375-
In the dashboard, you can set the signal visualization mode to either EEG or ECG. EEG mode provides the spectral analysis plot of the signal. ECG mode detects heartbeats and calculates heart rate using RR-intervals.
376-
377-
EEG:
378-
379-
.. image:: /images/Dashboard_EEG.jpg
380-
:width: 800
381-
:alt: EEG Dashboard
382-
383-
ECG with heart beat detection:
384-
385-
.. image:: /images/Dashboard_ECG.jpg
386-
:width: 800
387-
:alt: ECG Dashboard
388-
389342

390343
Impedance measurement
391344
"""""""""""""""""""""
@@ -394,10 +347,6 @@ You can measure electrodes impedances using:
394347
::
395348
explore.measure_imp()
396349

397-
.. image:: /images/Dashboard_imp.jpg
398-
:width: 800
399-
:alt: Impedance Dashboard
400-
401350
.. note:: Impedance values depend on the impedance of the reference electrode. The value shown for each electrode is the average of the ground and ExG electrodes' impedances.
402351

403352
If all channel impedances are high, try cleaning the skin under the reference electrode more thoroughly using, e.g., alcohol, abrasive gel, or EEG.

examples/p300_demo/analysis_csv_4_channel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def custom_filter(exg, lf, hf, fs, type):
5555
(numpy ndarray): Filtered signal (N_chan, N_sample)
5656
"""
5757
N = 4
58-
b, a = signal.butter(N, [lf / fs, hf / fs], type)
58+
b, a = signal.butter(N, [lf / (fs/2), hf / (fs/2)], type)
5959
return signal.filtfilt(b, a, exg)
6060

6161

examples/p300_demo/analysis_csv_8_channel.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def custom_filter(exg, lf, hf, fs, type):
5555
(numpy ndarray): Filtered signal (N_chan, N_sample)
5656
"""
5757
N = 4
58-
b, a = signal.butter(N, [lf / fs, hf / fs], type)
58+
b, a = signal.butter(N, [lf / (fs/2), hf / (fs/2)], type)
5959
return signal.filtfilt(b, a, exg)
6060

6161

examples/ssvep_demo/offline_analysis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def custom_filter(exg, lf, hf, fs, type):
2121
(numpy ndarray): Filtered signal (N_chan, N_sample)
2222
"""
2323
N = 4
24-
b, a = signal.butter(N, [lf / fs, hf / fs], type)
24+
b, a = signal.butter(N, [lf / (fs/2), hf / (fs/2)], type)
2525
return signal.filtfilt(b, a, exg)
2626

2727

installer/windows/installer.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[Application]
22
name=MentaLab ExplorePy
3-
version=1.6.3
3+
version=1.7.0
44
entry_point=explorepy.cli:cli
55
console=true
66
icon=mentalab.ico
@@ -16,7 +16,7 @@ entry_point=explorepy.cli:cli
1616

1717
[Include]
1818
pypi_wheels =
19-
explorepy==1.6.3
19+
explorepy==1.7.0
2020
appdirs==1.4.3
2121
# bokeh==2.2.3 # No wheel available
2222
certifi==2020.12.5

lib/windows/test.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
import exploresdk
2-
3-
dummy = exploresdk.ExploreSDK_Create()
4-
5-
list = dummy.PerformDeviceSearch()
6-
for p in list:
7-
print(p.name)
8-
9-
bt_serial_port_manager = exploresdk.BTSerialPortBinding_Create("00:13:43:80:14:3A", 5)
10-
11-
bt_serial_port_manager.Connect()
12-
13-
14-
bt_serial_port_manager.Send()
15-
1+
import numpy as np
2+
3+
import explorepy
4+
from explorepy import settings_manager
5+
e = explorepy.Explore()
6+
name = "Explore_844A"
7+
e.connect(name)
8+
#s = settings_manager.SettingsManager(name)
9+
#s.set_adc_mask([1] + [0] * 31)
10+
#e.push2lsl()
11+
#e.set_channels("1010")
12+
e.record_data(do_overwrite=True, duration=10, file_type="csv", file_name="test1")
13+
import time
14+
import os
15+
#time.sleep(15)
16+
#e.acquire(30)
1617

1718

licenses/LICENSE_explorepy.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2018-2019, Mentalab GmbH
3+
Copyright (c) 2018-2022, Mentalab GmbH
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
66

setup.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ def read(*names, **kwargs):
3232
return fh.read()
3333

3434

35-
my_req = [
36-
'numpy', 'scipy', 'pyedflib==0.1.25', 'click==7.1.2', 'appdirs==1.4.3', 'sentry_sdk==1.0.0', 'mne', 'eeglabio'
37-
]
38-
35+
my_req = ['numpy==1.21.4', 'scipy', 'pyedflib==0.1.25', 'click==7.1.2', 'appdirs==1.4.3', 'sentry_sdk==1.0.0', 'mne', 'eeglabio', 'pandas'] # noqa: E501
3936
test_requirements = ["pytest==6.2.5",
4037
"flake8==4.0.1",
4138
"isort==5.10.1"]
@@ -83,7 +80,7 @@ def read(*names, **kwargs):
8380
os.system('cp lib/mac/exploresdk.py src/explorepy')
8481
setup(
8582
name='explorepy',
86-
version='1.6.3',
83+
version='1.7.0',
8784
license='MIT license',
8885
description='Python API for Mentalab biosignal aquisition devices',
8986
long_description_content_type="text/markdown",
@@ -109,9 +106,10 @@ def read(*names, **kwargs):
109106
'Operating System :: POSIX',
110107
'Operating System :: Microsoft :: Windows',
111108
'Programming Language :: Python',
112-
'Programming Language :: Python :: 3.5',
113-
'Programming Language :: Python :: 3.6',
114109
'Programming Language :: Python :: 3.7',
110+
'Programming Language :: Python :: 3.8',
111+
'Programming Language :: Python :: 3.9',
112+
'Programming Language :: Python :: 3.10',
115113
'Topic :: Education',
116114
'Topic :: Scientific/Engineering :: Medical Science Apps.',
117115
'Topic :: Scientific/Engineering :: Visualization'

src/explorepy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323

2424
__all__ = ["Explore", "Dashboard", "command", "exploresdk", "tools", "log_config"]
25-
__version__ = '1.6.3'
25+
__version__ = '1.7.0'
2626

2727
this = sys.modules[__name__]
2828
this._bt_interface = 'sdk'

src/explorepy/btcpp.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
import logging
44
import time
55

6-
from explorepy import exploresdk
6+
from explorepy import (
7+
exploresdk,
8+
settings_manager
9+
)
710
from explorepy._exceptions import (
811
DeviceNotFoundError,
912
InputError
@@ -36,10 +39,14 @@ def connect(self):
3639
Returns:
3740
socket (bluetooth.socket)
3841
"""
42+
config_manager = settings_manager.SettingsManager(self.device_name)
43+
mac_address = config_manager.get_mac_address()
3944

40-
if self.mac_address is None:
45+
if mac_address is None:
4146
self._find_mac_address()
47+
config_manager.set_mac_address(self.mac_address)
4248
else:
49+
self.mac_address = mac_address
4350
self.device_name = "Explore_" + str(self.mac_address[-5:-3]) + str(self.mac_address[-2:])
4451

4552
for _ in range(5):

0 commit comments

Comments
 (0)