Contents

_images/logo.png

Documentation Status PyPI Package latest release PyPI Wheel Supported versions Commits since latest release Travis-CI Build Status

Explorepy overview

Explorepy is an open-source Python-based biosignal acquisition API for Mentalab’s Explore device. It provides users the following features:

  • Real-time streaming of ExG, orientation and environmental data
  • Real-time visualization
  • Data recording
  • LSL integration
  • Impedance measurement
  • Explore device configuration

Quick installation

Requirements

Please check installation page for more detailed instruction.

To install explorepy from PyPI run:

pip install explorepy

To install the latest development version run:

pip install git+https://github.com/Mentalab-hub/explorepy

Get started

CLI command

explorepy acquire -n Explore_XXXX

Enter explorepy -h for help.

Python code

The following code connects to the Explore device and prints the data.

import explorepy
explorer = explorepy.Explore()
explorer.connect(device_name="Explore_XXXX")  # Put your device Bluetooth name
explorer.acquire()

You can also visualize signal in real-time.

import explorepy
explorer = explorepy.Explore()
explorer.connect(device_name="Explore_XXXX")  # Put your device Bluetooth name
explorer.visualize(n_chan=4, bp_freq=(1, 30), notch_freq=50)  # Give the number of channels, frequencies of bandpass and notch filter

EEG:

EEG Dashboard

ECG with heart beat detection:

ECG Dashboard

Documentation

To see full documentation of the API, visit: https://explorepy.readthedocs.io/

License

This project is licensed under the MIT license.

Installation

Requirements

explorepy is using pybluez as the bluetooth backend. pybluez has different dependencies in different operating systems.

Windows

  • Visual C++ build tools
  • Visual Studio 2015 community edition (In order to build 64-bit debug and release executables)

Ubuntu 16.04 or 18.04

  • sudo apt-get install libbluetooth-dev

Mac OS

  • Xcode
  • PyObjc 3.1b or later

For more details on pybluez dependencies please see pybluez docs.

How to install (Windows)

This instructions guides you to install Explorepy API with all its dependencies on Windows.

  1. Install Python 3 on your computer. It is recommended to install Anaconda Python package. Download and install Anaconda Python 3.7 Windows installer from here.
  2. Download and install MS Visual Studio Community Edition 2015 from this link. Make sure you install Build Tools for Visual Studio 2017 (version 15.9) from this link.
  3. We recommend using a virtual environment.
  • In Conda command prompt: conda create -n myenv python=3.6
  • Activate the virtual environment: conda activate myenv
  1. Upgrade your pip: python -m pip install --upgrade pip
  1. To install explorepy from PyPI run: pip install explorepy

Quick test

  • Open Conda command prompt
  • Activate the virtual environment: conda activate myenv
  • explorepy visualize -n <YOUR-DEVICE-NAME> -c 4 (Change the number of channels if needed)
  • To stop visualization press Ctrl+c

Usage

Command Line Interface

Command structure: explorepy <command> [args]

Available Commands

find_device Scans for nearby explore-devices. Prints out Name and MAC address of the found devices.

acquire Connects to device, needs either MAC or Name of the desired device as input.

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. “Explore_12AB”).

record_data Connects to a device and records ExG and orientation data into 2 separate files. Note that in CSV mode there will be an extra file for the marker events. In EDF mode, the data is actually recorded in BDF+ format (in 24-bit resolution).

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. Explore_12AB). Note that either device name or MAC address is needed.
  • -f or --filename The prefix of the files.
  • -t or --type File type (edf and csv types are supported currently).
  • -ow or --overwrite Overwrite already existing files with the same name (optional - the default mode is False).
  • -d or --duration Recording duration in seconds

push2lsl Streams data to Lab Streaming Layer (LSL).

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. Explore_12AB). Note that either device name or MAC address is needed.

bin2csv Takes a Binary file and converts it to 3 CSV files (ExG, orientation and marker files)

  • -i or --inputfile Name of the input file
  • -ow or --overwrite Overwrite already existing files with the same name.

Note

For devices with firmware version 2.1.1 and lower, explorepy v0.5.0 has to be used to convert binary files.

bin2edf Takes a Binary file and converts it to 2 EDF files (ExG and orientation - markers will be written in ExG file). The data is actually recorded in BDF+ format (in 24-bit resolution).

  • -i or --inputfile Name of the input file
  • -ow or --overwrite Overwrite already existing files with the same name.

Note

For devices with firmware version 2.1.1 and lower, explorepy v0.5.0 has to be used to convert binary files.

visualize Visualizes real-time data in a browser-based dashboard. Currently, Chrome is the supported browser. The visualization in IE and Edge might be very slow.

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. Explore_12AB).
  • -nf or --notchfreq Frequency of applied notch filter (By default, no notch filter is applied)
  • -lf or --lowfreq Low cutoff frequency of bandpass filter (By default no bandpass filter is applied)
  • -hf or --highfreq High cutoff frequency of bandpass filter (Both -lf and -hf must be given if you want to apply a bandpass filter)
  • -cf or --calibration_file Calibration file name (e.g. “X_calibre_coef.csv”). If you pass this parameter, ORN module should be ACTIVE! To obtain this file refer to Explore.calibrate_orn module.

impedance Visualizes electrodes impedances in a browser-based dashboard. Currently, Chrome is the supported browser.

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. Explore_12AB).
  • -nf or --notchfreq Frequency of applied notch filter (By default, no notch filter is applied)

calibrate_orn Calibrate the orientation module of the specified device. After running this module, a file containing calibration data will be generated. Using this file, an extra computation block can be activated in the visualize to compute the physical orientation of the device from raw sensor data.

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. Explore_12AB).
  • -cf or --calibration_file Calibration file name. If you pass this parameter, ORN module should be ACTIVE!
  • -ow or --overwrite Overwrite already existing files with the same name.

format_memory This command formats the memory of the specified Explore device.

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. Explore_12AB).

set_sampling_rate This command sets the sampling rate of ExG on the specified Explore device. The only acceptable values for sampling rates are 250, 500 or 1000. Please note that this feature is in its alpha state. There might be some inconsistency with other modules in sampling rates except 250 Hz.

  • -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX).
  • -n or --name Device name (e.g. Explore_12AB).
  • -sr or --sampling_rate Sampling rate of ExG channels, it can be 250 or 500.

soft_reset This command does a soft reset of the device. All the settings (e.g. sampling rate, channel mask) return to the default values. * -a or --address Device MAC address (form XX:XX:XX:XX:XX:XX). * -n or --name Device name (e.g. Explore_12AB).

Example commands:

Data acquisition: explorepy acquire -n Explore_XXXX  #Put your device Bluetooth name

Record data: explorepy record_data -n Explore_XXXX -f test_file -t edf -ow

Push data to lsl: explorepy push2lsl -n Explore_XXXX

Convert a binary file to csv: explorepy bin2csv -i input_file.BIN

Convert a binary file to EDF and overwrite if files exist already: explorepy bin2edf -i input_file.BIN -ow

Visualize in real-time: explorepy visualize -n Explore_XXXX

Impedance measurement: explorepy impedance -n Explore_XXXX

Format the memory: explorepy format_memory -n Explore_XXXX

Set the sampling rate: explorepy set_sampling_rate -n Explore_XXXX -r 500

To see the full list of commands explorepy -h.

Python project

To use explorepy in a python project:

import explorepy

Initialization

Before starting a session, make sure your device is paired to your computer. The device will be shown under the following name: Explore_XXXX, with the last 4 characters being the last 4 hex numbers of the devices MAC adress

Make sure to initialize the Bluetooth connection before streaming using the following lines:

explore = explorepy.Explore()
explore.connect(device_name="Explore_XXXX") #Put your device Bluetooth name

Alternatively you can use the device’s MAC address:

explore.connect(device_addr="XX:XX:XX:XX:XX:XX")

If the device is not found it will raise an error.

Streaming

After connecting to the device you are able to stream data and print the data in the console.:

explore.acquire()

Recording

You can record data in realtime to EDF (BDF+) or CSV files:

explore.record_data(file_name='test', duration=120, file_type='csv')

This will record data in three separate files “test_ExG.csv”, “test_ORN.csv” and “test_marker.csv” which contain ExG, orientation data (accelerometer, gyroscope, magnetometer) and event markers respectively. The duration of the recording can be specified (in seconds). If you want to overwrite already existing files, change the line above:

explore.record_data(file_name='test', do_overwrite=True,file_type='csv', duration=120)

Visualization

It is possible to visualize real-time signal in a browser-based dashboard by the following code. Currently, Chrome is the supported browser. The visualization in IE and Edge might be very slow.:

explore.visualize(bp_freq=(1, 30), notch_freq=50)

Where bp_freq and notch_freq determine cut-off frequencies of bandpass filter and frequency of notch filter (either 50 or 60) respectively.

In the dashboard, you can set signal mode to EEG or ECG. EEG mode provides the spectral analysis plot of the signal. In ECG mode, the heart beats are detected and heart rate is estimated from RR-intervals.

EEG:

EEG Dashboard

ECG with heart beat detection:

ECG Dashboard

Impedance measurement

To measure electrodes impedances:

explore.impedance(notch_freq=50)
Impedance Dashboard

Note

The accuracy of measured impedances are subject to environmental conditions such as noise and temperature.

Labstreaminglayer (lsl)

You can push data directly to LSL using the following line:

explore.push2lsl()

After that you can stream data from other software such as OpenVibe or other programming languages such as MATLAB, Java, C++ and so on. (See labstreaminglayer, OpenVibe documentations for details). This function creates three LSL streams for ExG, Orientation and markers. In case of a disconnect (device loses connection), the program will try to reconnect automatically.

Converter

It is also possible to extract BIN files from the device via USB. To convert these to CSV, you can use the function bin2csv, which takes your desired BIN file and converts it to 2 CSV files (one for orientation, the other one for ExG data). Bluetooth connection is not necessary for conversion.

from explorepy.tools import bin2csv
bin2csv(bin_file)

If you want to overwrite existing files, use:

bin2csv(bin_file, do_overwrite=True)

Note

Currently, the binary files which the sampling rate or ADC mask are changed during recording are not supported. You can use python script and explorepy.Explore.record_data() function as an alternative.

Event markers

In addition to the marker event generated by pressing the button on Explore device, you can set markers in your code using explorepy.Explore.set_marker function. However, this function must be called from a different thread than the parsing thread. Please not that marker codes between 0 and 7 are reserved for hardware related markers. You can use any other (integer) code for your marker from 8 to 65535. To see an example usage of this function look at this script

Reference

explorepy

Main API

class explore.Explore(n_device=1)[source]

Bases: object

Mentalab Explore device

Parameters:n_device (int) – Number of devices to be connected
connect(device_name=None, device_addr=None, device_id=0)[source]

Connects to the nearby device. If there are more than one device, the user is asked to choose one of them.

Parameters:
  • device_name (str) – Device name in the format of “Explore_XXXX”
  • device_addr (str) – The MAC address in format “XX:XX:XX:XX:XX:XX” Either Address or name should be in the input
  • device_id (int) – device id (not needed in the current version)
disconnect(device_id=None)[source]

Disconnects from the device

Parameters:device_id (int) – device id (not needed in the current version)
acquire(device_id=0, duration=None)[source]

Start getting data from the device

Parameters:
  • device_id (int) – device id (not needed in the current version)
  • duration (float) – duration of acquiring data (if None it streams data endlessly)
record_data(file_name, do_overwrite=False, device_id=0, duration=None, file_type='csv')[source]

Records the data in real-time

Parameters:
  • file_name (str) – Output file name
  • device_id (int) – Device id (not needed in the current version)
  • do_overwrite (bool) – Overwrite if files exist already
  • duration (float) – Duration of recording in seconds (if None records endlessly).
  • file_type (str) – File type of the recorded file. Supported file types: ‘csv’, ‘edf’
push2lsl(device_id=0, duration=None)[source]

Push samples to two lsl streams

Parameters:
  • device_id (int) – device id (not needed in the current version)
  • duration (float) – duration of data acquiring (if None it streams endlessly).
visualize(device_id=0, bp_freq=(1, 30), notch_freq=50, calibre_file=None)[source]

Visualization of the signal in the dashboard :Parameters: * device_id (int) – Device ID (not needed in the current version)

  • bp_freq (tuple) – Bandpass filter cut-off frequencies (low_cutoff_freq, high_cutoff_freq), No bandpass filter
  • if it is None.
  • notch_freq (int) – Line frequency for notch filter (50 or 60 Hz), No notch filter if it is None
  • calibre_file (str) – Calibration data file name
_io_loop(device_id=0, mode='visualize')[source]
signal_handler(signal, frame)[source]
measure_imp(device_id=0, notch_freq=50)[source]

Visualization of the electrode impedances

Parameters:
  • device_id (int) – Device ID
  • notch_freq (int) – Notch frequency for filtering the line noise (50 or 60 Hz)
set_marker(code)[source]

Sets an event marker during the recording

Parameters:code (int) – Marker code. It must be an integer larger than 7 (codes from 0 to 7 are reserved for hardware markers).
change_settings(command, device_id=0)[source]

sends a message to the device :Parameters: * device_id (int) – Device ID

  • command (explorepy.command.Command) – Command object

Returns:

calibrate_orn(file_name, device_id=0, do_overwrite=False)[source]

Calibrate the orientation module of the specified device

Parameters:
  • device_id (int) – device id
  • file_name (str) – filename to be used for calibration. If you pass this parameter, ORN module should be ACTIVE!
  • do_overwrite (bool) – Overwrite if files exist already

Bluetooth API

class bt_client.BtClient[source]

Bases: object

Responsible for Connecting and reconnecting explore devices via bluetooth

init_bt(device_name=None, device_addr=None)[source]

Initialize Bluetooth connection

Parameters:
  • device_name (str) – Name of the device (either device_name or device address should be given)
  • device_addr (str) – Devices MAC address
bt_connect()[source]

Creates the socket

reconnect()[source]

tries to open the last bt socket, uses the last port and host. if after 1 minute the connection doesnt succeed, program will end

find_mac_addr(device_name)[source]
find_explore_service()[source]
static _check_mac_address(device_name, mac_address)[source]

Parser

parser.generate_packet(pid, timestamp, bin_data)[source]

Generates the packets according to the pid

Parameters:
  • pid (int) – Packet ID
  • timestamp (int) – Timestamp
  • bin_data – Binary dat
Returns:

Packet

class parser.Parser(bp_freq=None, notch_freq=None, socket=None, fid=None)[source]

Bases: object

Parser class for explore device

Parameters:
  • socket (BluetoothSocket) – Bluetooth Socket (Should be None if fid is provided)
  • fid (file object) – File object for reading data (Should be None if socket is provided)
  • bp_freq (tuple) – Tuple of cut-off frequencies of bandpass filter (low cut-off frequency, high cut-off frequency)
  • notch_freq (int) – Notch filter frequency (50 or 60 Hz)
filter
parse_packet(mode='print', recorders=None, outlets=None, dashboard=None)[source]

Reads and parses a package from a file or socket

Parameters:
  • mode (str) – Parsing mode {‘print’, ‘record’, ‘lsl’, ‘visualize’, ‘impedance’, None}
  • recorders (tuple) – Tuple of recorder objects (ExG_recorder, ORN_recorder, Marker_recorder)
  • outlets (tuple) – Tuple of lsl StreamOutlet (orientation_outlet, EEG_outlet, marker_outlet)
  • dashboard (Dashboard) – Dashboard object for visualization
Returns:

packet object

read(n_bytes)[source]

Read n_bytes from socket or file

Parameters:n_bytes (int) – number of bytes to be read
Returns:list of bytes
set_marker(marker_code)[source]
_init_filters()[source]
_compute_NED(packet)[source]
class packet.PACKET_ID[source]

Bases: enum.IntEnum

An enumeration.

ORN = 13
ENV = 19
TS = 27
DISCONNECT = 111
INFO = 99
EEG94 = 144
EEG98 = 146
EEG99S = 30
EEG99 = 62
EEG94R = 208
EEG98R = 210
CMDRCV = 192
CMDSTAT = 193
MARKER = 194
CALIBINFO = 195
class packet.Packet(timestamp, payload)[source]

Bases: object

An abstract base class for Explore packet

Gets the timestamp and payload and initializes the packet object

Parameters:payload (bytearray) – a byte array including binary data and fletcher
_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

__str__()[source]

Print the data/info

static int24to32(bin_data)[source]

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)[source]
class packet.EEG(timestamp, payload)[source]

Bases: packet.Packet

Gets the timestamp and payload and initializes the packet object

Parameters:payload (bytearray) – a byte array including binary data and fletcher
apply_bp_filter(exg_filter)[source]

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_bp_filter_noise(exg_filter)[source]

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_notch_filter(exg_filter)[source]

Band_stop filtering of ExG data

Parameters:exg_filter – Filter object
push_to_lsl(outlet)[source]

Push data to lsl socket

Parameters:outlet (lsl.StreamOutlet) – lsl stream outlet
calculate_impedance(imp_calib_info)[source]

calculate impedance with the help of impedance calibration info

Parameters:imp_calib_info (dict) – dictionary of impedance calibration info including slope, offset and noise level
push_to_dashboard(dashboard)[source]
push_to_imp_dashboard(dashboard, imp_calib_info)[source]
write_to_file(recorder)[source]
__str__()

Print the data/info

_check_fletcher(fletcher)

Checks if the fletcher is valid

_convert(bin_data)

Read the binary data and convert it to real values

static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
class packet.EEG94(timestamp, payload)[source]

Bases: packet.EEG

EEG packet for 4 channel device

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

apply_bp_filter(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_bp_filter_noise(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_notch_filter(exg_filter)

Band_stop filtering of ExG data

Parameters:exg_filter – Filter object
calculate_impedance(imp_calib_info)

calculate impedance with the help of impedance calibration info

Parameters:imp_calib_info (dict) – dictionary of impedance calibration info including slope, offset and noise level
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
push_to_imp_dashboard(dashboard, imp_calib_info)
push_to_lsl(outlet)

Push data to lsl socket

Parameters:outlet (lsl.StreamOutlet) – lsl stream outlet
write_to_file(recorder)
class packet.EEG98(timestamp, payload)[source]

Bases: packet.EEG

EEG packet for 8 channel device

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

apply_bp_filter(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_bp_filter_noise(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_notch_filter(exg_filter)

Band_stop filtering of ExG data

Parameters:exg_filter – Filter object
calculate_impedance(imp_calib_info)

calculate impedance with the help of impedance calibration info

Parameters:imp_calib_info (dict) – dictionary of impedance calibration info including slope, offset and noise level
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
push_to_imp_dashboard(dashboard, imp_calib_info)
push_to_lsl(outlet)

Push data to lsl socket

Parameters:outlet (lsl.StreamOutlet) – lsl stream outlet
write_to_file(recorder)
class packet.EEG99s(timestamp, payload)[source]

Bases: packet.EEG

EEG packet for 8 channel device

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

apply_bp_filter(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_bp_filter_noise(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_notch_filter(exg_filter)

Band_stop filtering of ExG data

Parameters:exg_filter – Filter object
calculate_impedance(imp_calib_info)

calculate impedance with the help of impedance calibration info

Parameters:imp_calib_info (dict) – dictionary of impedance calibration info including slope, offset and noise level
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
push_to_imp_dashboard(dashboard, imp_calib_info)
push_to_lsl(outlet)

Push data to lsl socket

Parameters:outlet (lsl.StreamOutlet) – lsl stream outlet
write_to_file(recorder)
class packet.EEG99(timestamp, payload)[source]

Bases: packet.EEG

EEG packet for 8 channel device

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

apply_bp_filter(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_bp_filter_noise(exg_filter)

Bandpass filtering of ExG data

Args: exg_filter: Filter object

apply_notch_filter(exg_filter)

Band_stop filtering of ExG data

Parameters:exg_filter – Filter object
calculate_impedance(imp_calib_info)

calculate impedance with the help of impedance calibration info

Parameters:imp_calib_info (dict) – dictionary of impedance calibration info including slope, offset and noise level
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
push_to_imp_dashboard(dashboard, imp_calib_info)
push_to_lsl(outlet)

Push data to lsl socket

Parameters:outlet (lsl.StreamOutlet) – lsl stream outlet
write_to_file(recorder)
class packet.Orientation(timestamp, payload)[source]

Bases: packet.Packet

Orientation data packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

write_to_file(recorder)[source]
push_to_lsl(outlet)[source]
push_to_dashboard(dashboard)[source]
compute_angle(matrix=None)[source]
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
class packet.Environment(timestamp, payload)[source]

Bases: packet.Packet

Environment data packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

push_to_dashboard(dashboard)[source]
static _volt_to_percent(voltage)[source]
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
class packet.TimeStamp(timestamp, payload)[source]

Bases: packet.Packet

Time stamp data packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

translate()[source]
push_to_lsl(outlet)[source]
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
class packet.MarkerEvent(timestamp, payload)[source]

Bases: packet.Packet

Marker packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

write_to_file(recorder)[source]
push_to_lsl(outlet)[source]
push_to_dashboard(dashboard)[source]
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
class packet.Disconnect(timestamp, payload)[source]

Bases: packet.Packet

Disconnect packet

_convert(bin_data)[source]

Disconnect packet has no data

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
class packet.DeviceInfo(timestamp, payload)[source]

Bases: packet.Packet

Device information packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

write_to_file(recorder)[source]
push_to_dashboard(dashboard)[source]
static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
class packet.CommandRCV(timestamp, payload)[source]

Bases: packet.Packet

Command Status packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
class packet.CommandStatus(timestamp, payload)[source]

Bases: packet.Packet

Command Status packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)
class packet.CalibrationInfo(timestamp, payload)[source]

Bases: packet.Packet

Calibration Info packet

_convert(bin_data)[source]

Read the binary data and convert it to real values

_check_fletcher(fletcher)[source]

Checks if the fletcher is valid

static int24to32(bin_data)

converts binary data to int32

Parameters:bin_data (list) – list of bytes with the structure of int24
Returns:np.ndarray of int values
push_to_dashboard(dashboard)

Dashboard

class dashboard.dashboard.Dashboard(n_chan, exg_fs, mode='signal', firmware_version='NA')[source]

Bases: object

Explorepy dashboard class

Parameters:
  • n_chan (int) – Number of channels
  • exg_fs (int) – Sampling rate of ExG signal
  • mode (str) – Visualization mode {‘signal’, ‘impedance’}
  • firmware_version
update_exg(self, time_vector, ExG)[source]

update_exg() Update ExG data in the visualization

Parameters:
  • time_vector (list) – time vector
  • ExG (np.ndarray) – array of new data
start_server()[source]

Start bokeh server

start_loop()[source]

Start io loop and show the dashboard

update_exg()[source]

Update ExG data in the visualization

Parameters:
  • time_vector (list) – time vector
  • ExG (np.ndarray) – array of new data
update_orn(timestamp, orn_data)[source]

Update orientation data

Parameters:
  • timestamp (float) – timestamp of the sample
  • orn_data (float vector) – Vector of orientation data with shape of (9,)
update_info(new)[source]

Update device information in the dashboard

Parameters:new (dict) – Dictionary of new values
_update_fft()[source]

Update spectral frequency analysis plot

_update_heart_rate()[source]

Detect R-peaks and update the plot and heart rate

_change_scale(attr, old, new)[source]

Change y-scale of ExG plot

_change_t_range(attr, old, new)[source]

Change time range

_change_mode(new)[source]

Set EEG or ECG mode

_init_plots()[source]

Initialize all plots in the dashboard

_init_controls()[source]

Initialize all controls in the dashboard

_set_t_range(t_length)[source]

Change time range of ExG and orientation plots

Additional tools

tools.bt_scan()[source]

“Scan for bluetooth devices Scans for available explore devices. Prints out MAC address and name of each found device

Args:

Returns:

tools.bin2csv(bin_file, do_overwrite=False, out_dir='')[source]

Binary to CSV file converter. This function converts the given binary file to ExG and ORN csv files.

Parameters:
  • bin_file (str) – Binary file full address
  • out_dir (str) – Relative output directory (if not given, it uses the current working directory.)
  • do_overwrite (bool) – Overwrite if files exist already
tools.bin2edf(bin_file, do_overwrite=False, out_dir='')[source]

Binary to EDF file converter. This function converts the given binary file to ExG and ORN csv files.

Parameters:
  • bin_file (str) – Binary file full address
  • out_dir (str) – Output directory (if None, uses the same directory as binary file)
  • do_overwrite (bool) – Overwrite if files exist already
class tools.HeartRateEstimator(fs=250, smoothing_win=20)[source]

Bases: object

Real-time heart Rate Estimator class This class provides the tools for heart rate estimation. It basically detects R-peaks in ECG signal using the method explained in Hamilton 2002 [2].

Parameters:
  • fs (int) – Sampling frequency
  • smoothing_win (int) – Length of smoothing window

References

[1] Hamilton, P. S. (2002). Open source ECG analysis software documentation. Computers in cardiology, 2002.

[2] Hamilton, P. S., & Tompkins, W. J. (1986). Quantitative investigation of QRS detection rules using the MIT/BIH arrhythmia database. IEEE transactions on biomedical engineering.

average_noise_peak
average_qrs_peak
decision_threshold
average_rr_interval
heart_rate
push_r_peak(val, time)[source]
push_noise_peak(val, peak_idx, peak_time)[source]
estimate(ecg_sig, time_vector)[source]

Detection of R-peaks

Parameters:
  • time_vector (np.array) – One-dimensional time vector
  • ecg_sig (np.array) – One-dimensional ECG signal
Returns:

List of detected peaks indices

check_missing_peak(peak_time, peak_idx, detected_peaks_idx, ecg_sig, time_vector)[source]
class tools.FileRecorder(file_name, ch_label, fs, ch_unit, ch_min=None, ch_max=None, device_name='Explore', file_type='edf', do_overwrite=False)[source]

Bases: object

Explorepy file recorder class.

This class can write ExG, orientation and environment data into (separated) EDF+ files. It can write data while streaming from Explore device. The incoming data will be stored in a buffer and after it reached fs samples, it writes the buffer in EDF file.

Attributes:

Parameters:
  • file_name (str) – File name
  • ch_label (list) – List of channel labels.
  • fs (int) – Sampling rate (must be identical for all channels)
  • ch_unit (list) – List of channels unit (e.g. ‘V’, ‘mG’, ‘s’, etc.)
  • ch_min (list) – List of minimum value of each channel. Only needed in edf mode (can be None in csv mode)
  • ch_max (list) – List of maximum value of each channel. Only needed in edf mode (can be None in csv mode)
  • device_name (str) – Recording device name
  • file_type (str) – File type. current options: ‘edf’ and ‘csv’.
  • do_overwrite (bool) – Overwrite file if a file with the same name exists already.
fs
_create_edf(do_overwrite)[source]
_create_csv(do_overwrite)[source]
stop()[source]

Stop recording

_init_edf_channels()[source]
write_data(data)[source]

writes data to the file

Notes

If file type is set to EDF, this function writes each 1 seconds of data. If the input is less than 1 second, it will be buffered in the memory and it will be written in the file when enough data is in the buffer.

Parameters:data (np.array) – Array of data to be written in the file with dimension of n_chan x n_sample
set_marker(data)[source]

Writes a marker event in the file

Parameters:data (np.array) – Array of marker data with size 2x1 ([[timestamp],[code]])

Contributing

Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.

Bug reports

When reporting a bug please include:

  • Your operating system name and version.
  • Any details about your local setup that might be helpful in troubleshooting.
  • Detailed steps to reproduce the bug.

Documentation improvements

explorepy could always use more documentation, whether as part of the official explorepy docs, in docstrings, or even on the web in blog posts, articles, and such.

Feature requests and feedback

The best way to send feedback is to file an issue at https://github.com/Mentalab-hub/explorepy/issues.

If you are proposing a feature:

  • Explain in detail how it would work.
  • Keep the scope as narrow as possible, to make it easier to implement.
  • Remember that this is a volunteer-driven project, and that code contributions are welcome :)

Development

To set up explorepy for local development:

  1. Fork explorepy (look for the “Fork” button).

  2. Clone your fork locally:

    git clone git@github.com:your_name_here/explorepy.git
    
  3. Create a branch for local development:

    git checkout -b name-of-your-bugfix-or-feature
    

    Now you can make your changes locally.

  4. When you’re done making changes, run all the checks, doc builder and spell checker with tox one command:

    tox
    
  5. Commit your changes and push your branch to GitHub:

    git add .
    git commit -m "Your detailed description of your changes."
    git push origin name-of-your-bugfix-or-feature
    
  6. Submit a pull request through the GitHub website.

Pull Request Guidelines

If you need some code review or feedback while you’re developing the code just make the pull request.

For merging, you should:

  1. Include passing tests (run tox) [1].
  2. Update documentation when there’s new API, functionality etc.
  3. Add a note to CHANGELOG.rst about the changes.
  4. Add yourself to AUTHORS.rst.
[1]

If you don’t have all the necessary python versions available locally you can rely on Travis - it will run the tests for each change you add in the pull request.

It will be slower though …

Tips

To run a subset of tests:

tox -e envname -- pytest -k test_myfeature

To run all the test environments in parallel (you need to pip install detox):

detox

Authors

  • Mohamad Atayi - mentalab.co
  • Philipp Jakovleski - mentalab.co

Changelog

0.6.0 (17-02-2020)

  • EDF (BDF+) file writer
  • Channel disable/enable feature
  • Calibration of movement sensors
  • Extraction of physical orientation (angle and rotation)
  • Soft marker event
  • Visualization performance enhancement
  • Automatic number of channel and sampling rate detection
  • Exception handling improvement
  • Command for soft reset of Explore
  • Marker visualization

0.5.0 (25-11-2019)

  • Impedance measurement
  • Send commands to device
  • Configuring device settings
  • Update push to lsl feature

0.4.0 (09-09-2019)

  • Added marker feature
  • Timer based recording
  • Fixed a bug in csv file writer
  • Fixed a bug in device reconnect
  • Improved performance of dashboard visualization

0.3.1 (28-05-2019)

  • Fixed a bug in 8-channel ExG packet conversion
  • Fixed a minor bug in the record function
  • Updated the documentation

0.3.0 (10-05-2019)

  • Explore dashboard
  • Real-time visualization of ExG and orientation signal
  • Device information in Dashboard
  • Environmental data (battery, temperature and light)
  • Real-time bandpass filter
  • New packet structures (ADS1294R & ADS1298R)
  • Heart rate estimation and R-peaks detector in dashboard

0.2.0 (2019-03-08)

  • Added real-time recording feature
  • Added Command Line Interface
  • Added lsl integration
  • Added new packet classes
  • Fixed reconnect issues
  • Removed input requests inside functions

0.1.0 (2019-01-18)

  • First release on PyPI.

Indices and tables