Alpha/TMS Closed Loop
A BLOG POST BY DAVID MEDINE
The alpha rhythm (8-12Hz) is a prominent feature of adult human brain activity. Transcranial magnetic stimulation (TMS) is a technique for noninvasive, direct stimulation of the cortex. Recent research has pointed to a number of applications for the synchronization of TMS with different EEG features, including the alpha rhythm. For this reason, it is often a parameter of experimental design that stimulation from the TMS device aligns with a particular phase of a subject’s alpha rhythms. For example, a researcher may want to investigate the effects of applying TMS at the peak of an alpha wave.
Shown in Figure 1 is an idealized result.
The EEG in the occipital region (particularly in O2) shows a large alpha wave. Our goal is to have an algorithm that can determine the amplitude and period of this wave so that it can predict the precise time of an upcoming peak. From an engineering perspective, this presents a number of interesting challenges.
- To reliably detect alpha rhythms without filtering (which causes phase and group delay)
- To detect alpha rhythms quickly enough so that the upcoming predicted peak has not yet occured
- To control the TMS device in a timely manner
- To assess the performance of the system
We demonstrate how Brain Products hardware, used in conjunction with LabStreamingLayer (LSL)-enabled software can address these issues and provide a platform for conducting research in this field.
As noted above, this is a fairly complicated system with a number of hardware and software components. The crux of the system lies within the C++ code that compiles into the application TMSClosedLoop.exe. Therein is demonstrated how to connect with and retrieve data from an actiCHamp streaming via LSL, how to analyze the data in real-time, and how to use the results of the analysis to trigger an event at a specified point in the future. As a bonus, it also demonstrates how to use the Brain Products TriggerBox SDK to control that hardware from a C/C++ application.
3. Some Notes on the Code for TMSClosedLoop.exe
The file main.cpp controls the User Interface (UI) and the flow of this application. The file lsl.h (by Norbert Hauser) is used to interface LSL with an incoming EEG stream (which comes from the actiCHamp/LSL connector). The class IAmplifier does the work. You can also see the C++ examples that come with the LSL source code to understand how to use LSL in a C++ application (https://github.com/labstreaminglayer/App-Examples).
A lot of the code in main.cpp deals with controlling the console based user-interface and is not of much interest. The user must choose a single channel to use for alpha detection as well as an optional reference channel. By monitoring the EEG through a special LSL-enabled version of PyCorder, we can quickly inspect the data and visually select the best channel for alpha detection.
Once the TriggerBox and amplifier objects have been established (main.cpp lines 315-323) the peak detection object is constructed and started. Then, until the user cues the application to stop, it simply pulls the latest EEG data from the LSL stream and runs the selected channel through the detection algorithm. If alpha is present and the amplitude is above the adjustable threshold, the application will schedule an event in the future. This trigger should coincide with an upcoming peak in the alpha wave (main.cpp lines 42-58). This event is in the form of an instruction to the TriggerBox. The trigger goes directly through to the TMS device’s trigger output, and because that is plugged into the trigger port of the actiCHamp, this trigger will be present in the data coming from the amplifier in PyCorder.
Of prime importance in such a system is the reliable detection of alpha activity without using software filters. IIR filters have non-linear phase responses, so even though only a few taps are needed in order to reject frequencies outside of the alpha-band, the phase of the signal is distorted in a complicated way. Since the system needs to predict precisely when the next peak occurs in the wave, such phase-distortion is very undesirable. FIR filters can be used to filter a signal with a linear phase-response, but require more taps to effectively filter out frequencies beyond the edges of the pass-band. This is undesirable because each tap delays the signal by one sample. Thus, if too many taps are used, by the time the digitally filtered version of the wave arrives for analysis, the actual brain wave is already long gone. This means that the predicted forth-coming peak is already in the past.
To address this issue, we must choose a peak-picking algorithm that is robust and somewhat insensitive to noise. peakdet (http://www.billauer.co.il/peakdet.html) is a well-established example of such an algorithm, and this is what is implemented in the files PeakDet.cpp/h. The original MATLAB® code had to be significantly altered to adapt the algorithm to a real-time (online) application. The peakdet algorithm gives us the peak-to-peak amplitude of the wave as well as its frequency. This is exactly what we need to know: whether the amplitude is above a certain (settable) threshold and what the estimated period of the wave is.
At the hardware level, we chose actiCHamp for this application because it can operate at very high sampling rates (up to 100kHz!) and because we can access the data from the amplifier very quickly in software (as quickly as 2ms under ideal circumstances). This is important because peakdet requires a little time to judge whether a peak is a true peak or not. Please consult the original author’s explanation (again: http://www.billauer.co.il/peakdet.html) for the precise details. This means that there isn’t a lot of time before the next peak (which is when we want to stimulate) comes around again.
3.3 Timing Accuracy
We can never be completely accurate because the actual shape of the EEG (i.e. the emergence and precise period of the alpha waves) is noisy, and unpredictable. However, to be as accurate as possible, we lean heavily on LSL. Not only does LSL serve as a means to pipe signals and send messages between different software applications, it is both fast and accurate to within 1ms. These properties of LSL were long ago confirmed and you can read the reports here: https://sccn.ucsd.edu/~mgrivich/LSL_Validation.html.
The files PortEnumerator.cpp and PortEnumerator.h are written by Norbert Hauser and are used in order to automate connection with the Brain Products TriggerBox. The class which interfaces with the TriggerBox itself (TriggerBox.c/h) is also by Norbert. Norbert also authored Console.cpp/h (which deal with the command line user interface).