top of page

Finding Out What Does and Doesn't Work for EEG Data Processing

Complications with using Python on MacOS to Receive and Process EEG data

As a somewhat new student to the neurotech field and specifically EEG data manipulation, my first task seemed simple - connect the OpenBCI hardware with my Mac via Bluetooth, and then attempt to manipulate the EEG data using Python. Python, arguably one of the easier programming

Image from: http://forrestbao.blogspot.com/2009/10/eeg-signal-processing-in-python-and.html

languages, would be a perfect option for making EEG data more comprehensible by filtering unwanted frequencies, setting minimum and maximum ranges, and extracting only useful data.

My resources included:

  • a comprehensive OpenBCI website with an entire Python Software section explaining how to connect hardware to software

  • Multiple GitHub repositories, digital file storages, to clone and build for my system.

  • The world wide web

The start, I must say, was quite exciting and hopeful. The first steps included an installation of the OpenBCI GUI provided by the OpenBci website. With only slight confusion about which directory, or folder, to put this application, the GUI was quickly functional.

According to the OpenBci website, I needed to download a few (or so I thought) dependencies, such as programming languages and computing packages, to get the bluetooth connection working. The dependencies included the latest version of Python, NumPy (supports data in large, multi-dimensional arrays/matrices), pySerial (connects data streaming from different devices), and Yapsy (builds a plug-in system that adds specific features to existing programs).

Let’s Begin.

 

Luckily, my Mac came with the python 2.7.10 already installed. Wonderful. Installing numpy involved simply cloning a Github repository.

Sashas-MacBook-Air:bci sashaschtein$ git clone

https://github.com/numpy/numpy.git numpy

Installing pyserial required a bit more effort. As there was no GitHub repository to clone, I installed a python installation platform, pip. My Mac already had easy_install making pip ‘easy’ to ‘install’.

Installing pip:

sudo easy_install pip

Installing pyserial:

sudo pip install pyserial

Similar to the process I used for pyserial, I used pip to install Yapsy:

sudo pip install Yapsy

All the dependencies that were indicated on the website were now installed without any complications. Now, on to downloading and installing the OpenBCI-Python GitHub repository.

Making sure that all tools are located in the correct directory, (I created a directory, ‘bci’ to place all my bci libraries and files into), I cloned the GitHub repository for OpenBCI-Python from terminal into the bci folder. From first glance it seemed like this repository needed to be built. I built the repository using the setup.py file provided:

sudo python setup.py install

Time to run the application. Running the user.py file from the repository (python user.py -l) produced this unexpected error:

WARNING: no plugin selected, you will only be able to communicate with the board. You should select at least one plugin with '--add [plugin_name]'. Use '--list' to show available plugins or '--info [plugin_name]' to get more information.

Board type: OpenBCI Cyton (v3 API)

Traceback (most recent call last):

File "user.py", line 62, in <module>

from openbci import cyton as bci

File "/Users/sashaschtein/bci/OpenBCI_Python/openbci/__init__.py", line 3, in <module>

from .ganglion import OpenBCIGanglion

File "/Users/sashaschtein/bci/OpenBCI_Python/openbci/ganglion.py", line 26, in <module>

from bluepy.btle import Scanner, DefaultDelegate, Peripheral

ImportError: No module named bluepy.btle

Upon some inspection, the first problem I noted right off the bat was that the board type was incorrect. My team and I purchased a Ganglion motherboard, while the user.py file was programmed in such a way that defaulted to a Cyton motherboard. After opening the user.py file and scanning through complex code that seemed far too advanced for me, I eventually found how this runtime error could be fixed: changing to a ganglion board by running (python user.py -- board ganglion). This, however, was a wasted effort, as the real error (compilation error) was not in the board type, but in the lacking bluepy.btle library, a library that my laptop did not possess. (ImportError: No module named bluepy.btle)

The task now was to install bluepy.btle.

Installing bluepy using pip (sudo pip install bluepy) produced quite a few errors. In order to even begin compilation of bluepy, another class, bluepyhelper, needed to compile first. On top of this, bluepyhelper was dependent on glib, endian, and byteswap system softwares. As if things couldn’t get more difficult, my MacOS did not have any of those libraries, so the new task was now to simply download and install the dependencies. Right? This task however was anything but simple. Even if these libraries are downloaded, the bluepy Makefile required access to these directories when compiling bluepyhelper (and ultimately bluepy). Yet again, I downloaded the bluepy directory and placed it the bci directory I created earlier:

mkdir bluepy_src

cd bluepy_src

git clone https://github.com/IanHarvey/bluepy.git

cd bluepy/bluepy

Make

Now that the bluepy directory was downloaded, the missing libraries could be linked, and bluepy Makefile could point to their .h files. A certain installation platform, homebrew was required for these library installations.

Homebrew Installation:

/usr/bin/ruby -e "$(curl -fsSL

https://raw.githubusercontent.com/Homebrew/install/master/install)"

And with the help of homebrew, the glib library is now easy to setup:

brew install glib

(while making sure to be in the bluepy directory).

To allow bluepy to link the glib library, I added the location of the glib.h file in the bluepy Makefile. Unsure of where this file was located, I included flags to all the glib.h files on my Mac.

-I$(BLUEZ_PATH)/btio -I$(BLUEZ_PATH)/sys -I/usr/lib/glib-2.0/include -I/usr/local/Cellar/glib/2.58.2/glib-2.0 -I/usr/local/Cellar/glib/2.58.2/lib -I/usr/local/Cellar/glib/2.58.2/include

-I/usr/local/Cellar/glib/2.58.2/include/glib-2.0

-I/usr/local/Cellar/glib/2.58.2/lib/glib-2.0

-I/usr/local/Cellar/glib/2.58.2/lib/glib-2.0/include

-I/usr/local/include/glib-2.0/glib

(this is added to the CPPFLAGS of the bluepy Makefile.)

 

Next dependency : endian.

The endian library was simple to install, as my laptop had Xcode, and Xcode uses the endian library. All that was left was to point to the endian.h file from the bluepy Makefile.

-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.

platform/Developer/SDKs/MacOSX.sdk/usr/include/machine

(this is also added to the CPPFLAGS of the bluepy Makefile.)

 

Next dependency: byteswap.

Ummm... immediate problem.

Vigorously searching through the various libraries on my laptop, I found that my Mac OS did not appear to have the byteswap.h file or any library with the byteswap file. Looking online, all my search showed no byteswap library (or anything similar) to be available for MacOS.

I attempted to create my own byteswap file. However, this manual execution caused many, MANY compilation errors. Searching for a byteswap file online took far too much time with no concrete results. There was only one thing left to do - start over.

Let’s see where the error is occurring, and try to find an alternative python bluetooth library. Following the error message, bluepy.btle imported a few classes in the file where the error occurs (ganglion.py):

from bluepy.btle import Scanner, DefaultDelegate, Peripheral.

So, if an alternative python bluetooth library is the only option, it must contain all 3 classes from import and through all my searching, I am nearly convinced that it does not exist! The last few days of my break was spoiled with annoying questions of why I put myself through this torture, whether anyone has ever manipulated EEG data using python on MacOS, and, if yes, how I can contact them.

On the last day of break, and 12 hours before my flight back to LA, I decided to drastically change my approach. You see, the “Python” path was a straightforward attempt to intercept the Ganglion board communication on a low level by reading the bluetooth input port of my Mac. Since that was not working for me, I thought why not to use BCI gui application to do what it already does, receive data. I downloaded the Processing IDE, imported a few libraries that my Mac was missing, and… within an hour I was able to manipulate EEG data from my laptop using the Processing language.

 

The takeaway? DO NOT attempt to use Python when working with OpenBci data manipulation on MacOS.

bottom of page