RipplePyADC is a source module that allows for utilization of the Ripple Grapevine and other Ripple devices within BCI2000 through BCPy2000.
- Dhruva Mehta (firstname.lastname@example.org)
- 9/22/2023 Initial Creation and Setup
Source Code Revisions
- Initial development:
- Tested under:
- Known to compile under:
- Broken since: --
Using the RipplePyADC
To use the Ripple Python ADC, you will need to have a Ripple device that works with Trellis and Ripple's Python API. You will also need a computer set up with both BCI2000 and BCPy2000, which we will go over later.
For the initial setup of your device, please follow the Ripple user manual for your specific device.
Trellis is a user interface program that has been included with your device. Please use Trellis to test your connection with the device, such as stimulating and recording, as a means of debugging any connection issues or errors.
Ripple has developed a Python interface to Trellis and the Grapevine Neural Interface Processor (NIP) called Xipppy, which is being used in this source module. If there is a functionality that is not implemented, please first check the Python API to see if Ripple has it implemented themselves. If it is missing from this source module but implemented in their API, please contact us to update the source module.
How to set up with BCPy2000
Now we will set up the research PC. First, follow the BCPy2000 installation guide found here to install BCPy2000 and compile the solution on your PC.
Creating a Batch File
Creating a batch file with BCPy2000 is very straightforward. If you followed the guide, you will already have a few python batch files in the batch folder of your BCI2000 installation since you copied them over from your BCPy2000 installation. If you don't already have a batch file related to Ripple Python, you can create one by copying the template batch file, and editing it. All you need to do is change the values of
start executable PythonSource --local --PythonSrcClassFile=BciSource.py --PythonSrcShell=0 --PythonSrcLog=Srclogger.txt start executable PythonSignalProcessing --local --PythonSigClassFile=BciSignalProcessing.py --PythonSigShell=0 --PythonSigLog=Siglogger.txt start executable PythonApplication --local --PythonAppClassFile=BciApplication.py --PythonAppShell=0 --PythonAppLog=Applogger.txt
start executable PythonSource --local --PythonSrcClassFile=ripple/ripplePC.py --PythonSrcShell=0 --PythonSrcLog=aaaaa.txt start executable DummySignalProcessing --local start executable DummyApplication --local
Here, you can also manually change the logger files for use with debugging.
Installing the Python Module
To actually be able to use the Ripple's Python API with BCPy2000, it needs to be installed with your BCPy installation. First download and unzip the whl files provided by Ripple. Depending on your operating system, right-click and copy the path to the whl file. For reference, I used version 0.16.19 on Python 3.8.
Now, open command prompt and navigate to the folder containing your BCPy2000 installation. Now, run the command
python -m pip install "YOUR_PATH_HERE"
where "YOUR_PATH_HERE" is your path in quotations.
After installing, you should be good to test the source module!
Before debugging with BCPy2000, please use Trellis to make sure a proper connection is established. Once you have done that, there are a few methods to test the functionality of both the source module and the underlying Python API.
First we will test the Python API. The following is a simple script to test connecting to a device in both UDP and TCP:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import xipppy as xp from time import sleep def connectToProcessor(): # Close connection xp._close() sleep(0.001) # Connect to processor (Try UDP then TCP). try: xp._open() except: try: xp._open(use_tcp=True) except: print("Failed to connect to processor.") else: print("Connected over TCP") else: print("Connected over UDP") sleep(0.001) if __name__ == '__main__': connectToProcessor() xp._close()
The following script can be used to test data acquisition:
import xipppy import numpy as np import time if __name__ == '__main__': with xipppy.open(use_tcp=true): i = 0 data_arrays =  while i < 10: ts = xipppy.time() time.sleep(1) array = xipppy.cont_hires(100, , ts) data_arrays.append(array) i += 1 print(data_arrays)
Most of the time, the error will be:
xipppy.exception.XippPyException: Library already open or failed to initialize
It is hard to pinpoint exactly what caused the error in this case, and even Ripple's documentation states that this error lacks any additional information. You can also manually edit the python source module and utilize print statements or write to a file within the program. The source module will print out to the designated logger file that was named in the batch file.
Running the Source Module
Now that you have installed the source module, you can begin testing to make sure that data is being acquired. Before you test the source module, you can make sure that a signal is being passed through by using the Trellis application provided by Ripple. This will eliminate any doubt about whether data is actually being acquired in the first place, since you will be able to see a signal generated in Trellis.
Next, double click on the batch file to start the source module. Here you will be able to configure parameters and even save them as a file to load in for future experiment runs.
First, you can decide the number of source channels. This is going to be the same as the number of electrodes that you would like a signal to be acquired and visualized from.
Next, you can choose the number of samples to be acquired per acquisition block with the sample block size.
Next, you must decide which data acquisition function you would like to choose. The six options are raw, lfp, hifreq, hires, emg, and status. The specifics of these data streams are covered in the Ripple manual. The important thing to note is that the choices for macro and micro are both "raw". Macro and micro depends on which front-end you are using.
Next, we must check that the sampling rate matches the sampling rate of the data acquisition function you choose. The frequencies are listed in the Parameters section of this wiki. It is important that they match otherwise you will get errors on data acquisition.
The final thing to change would be which specific electrodes to acquire data from, via the specific channel parameter. Here, you set put the electrodes in a 0-indexed list (electrode 1 is 0, electrode 2 is 1, etc.). The length of this list must match the number of source channels you put earlier. Otherwise, this list will be overwritten during preflight.
You can also change other parameters as detailed in the parameter guide.
If you would like to use stimulation with your Ripple device, there is a separate parameter tab where you can create stimulation segments, sequences, triggers, and trains. This is still currently under development.
The total number of digitized and stored channels.
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated. For example, at 1000 Hz sampling and a SampleBlockSize of 20, the system (e.g., source signal display, signal processing, and stimulus presentation) will be updated 50 times per second.
The sample rate of the system. It is important that this parameter matches the sampling rate of the data acquisition function that you want to use. Otherwise, the two frequencies will be out of sync and you will eventually get either an error or a flat line in the signal visualizer.
Offset for each channel.
Gain for each channel.
Names of each channel.
This list defines what channels will be used as reference. This list is uploaded to the device and set in hardware, effecting the raw bio-signal data that is recorded by BCI2000. If you do not want to effect the raw bio-signal data that is recorded, you can use the spatial filter. If this parameter is set to auto, no reference channels are used.
The type of data stream you would like to use for acquisition. There are six types of data streams you can use, each with different frequencies:
Before trying to use a specific data stream, test to make sure you can acquire data from Trellis with it. If you don't see a signal in Trellis, you will not be able to see data in BcPy2000 either.
Here, you can choose which channels you want to actually acquire data from, just put the number of the channel you would like in a corresponding list section. Channel numbers start with 0. You can choose any number of channels by readjusting the list matrix size. Numbers do not need to be in ascending order, however the channels will appear in order they are put in the list from top to bottom. Make sure that the number of specific channels matches the SourceCh parameter. Otherwise, you will get thrown an error and the electrode list will automatically be changed to match the value of SourchCh.