Compute band power¶
This example pipeline, Bandpower.pyp, preprocesses and cleans an EEG stream, then computes the power in the standard frequency bands (delta, theta, alpha, beta and gamma), averaged across channels, in a moving window. The band power is plotted, and is also sent out over the network (via LSL) for pickup by another application, such as a game or a neurofeedback display. It also demonstrates a way of computing the spectral power in multiple bands at once.

The pipeline is set up for live (streaming) data, as it is shown here, but it can also be used with offline (recorded) data, as discussed at the end of this page. It can be divided into five parts, which we discuss in the following: data acquisition, preprocessing, artifact cleaning, band power computation, and output.
Data Acquisition¶
Includes: LSL Input, and (for the example only) Import XDF, Stream Data and LSL Output
This pipeline is designed to run out of the box by restreaming recorded data. For use with live data, you would remove the playback branch and change the query property of the LSL Input node so that it finds your live EEG stream, for instance type='EEG', or the name of your device's LSL stream. For use with recorded data, change the Import File path, wire it directly into Dejitter Timestamps and drop the LSL and Stream Data nodes. See Data input in the example pipelines for details.
Preprocessing¶
Includes: Dejitter Timestamps, FIR Filter, Assign Channel Locations, Remove Unlocalized Channels and Re-referencing

The preprocessing nodes prepare the data for the cleaning nodes:
Dejitter Timestampsmakes sure that the time stamps of the incoming samples are monotonically increasing, by smoothing out their irregularities. You should generally always run this, unless the time stamps are generated by the EEG hardware itself. It is particularly necessary if the signal is acquired wirelessly (e.g., over Bluetooth), where samples tend to arrive in irregular bursts, which makes their time stamps jittery.- The
FIR Filter(named 1Hz highpass filter) is an initial high-pass filter (frequenciesof 0.5 and 1 Hz) that removes slow drifts. This is required, since theBad Channel RemovalandArtifact Removalnodes assume that the data has already been high-passed. Depending on your headset and your use case, you may want to use a lower cutoff here (e.g., 0.5 Hz or even 0.1 Hz). Assign Channel Locationsautomatically assigns a position on the scalp to each EEG channel, looking up the default locations for channel labels in the international 10-20 system (or using a custom montage provided in itsmontageproperty). Downstream nodes need these locations.Remove Unlocalized Channelsremoves the channels that did not get a location, which are non-EEG channels such as triggers or accelerometers, since these have no position in a head montage.- The first
Re-referencingnode, which works along thetimeaxis, removes the mean of each channel in the time domain, i.e., any constant offset.
Artifact Cleaning¶
Includes: Bad Channel Removal, Artifact Removal, Extract Channel Names, Interpolate Missing Channels, Re-referencing and Remove Bad Time Windows

The data is then cleaned with the same chain of nodes as in the Artifact removal example, to which we refer for a detailed discussion of these nodes and of their properties. In short:
Bad Channel Removaldrops channels that are outliers (noisy or broken electrodes), andArtifact Removalremoves high-amplitude artifacts such as blinks and movement artifacts using the Artifact Subspace Reconstruction (ASR) algorithm.Interpolate Missing Channelsthen restores the channels that were dropped, so that the output has the same channels as the input. The list of channels it should produce comes from theExtract Channel Namesnode, which reads the channel names before any channels were removed.- The second
Re-referencingnode, which works along thespaceaxis, performs common average referencing: the average of all channels (itsreference_rangeis:) is subtracted from each channel. If you want to use a different reference, specify the reference channels in this property. Remove Bad Time Windowsdrops time segments that are still outliers after the cleaning. Note that this only works on recorded data, not live data, so this node has no effect when the pipeline is run on a live stream.
Bad Channel Removal and Artifact Removal calibrate their algorithms on the first few seconds of the stream (the calib_seconds property of each node, 30 seconds by default), so the cleaned data, and therefore the band power, only appears after this initial period.
Simplifying the preprocessing chain
For recorded data (see Using Offline Data), the nodes of the preprocessing and the artifact cleaning, from Dejitter Timestamps to Remove Bad Time Windows, can be replaced by a single PreprocessEEG node, if you prefer. It is a "meta-node" that runs a standard preprocessing chain of the same kind of nodes, in order, with their settings as its properties. This keeps a pipeline simpler, which is useful in a large pipeline. The Flanker ERP analysis example uses it. Note that PreprocessEEG only works on recorded data, not on a live stream.
Band Power Computation¶
Includes: Moving Window, Power Spectrum (Welch) and Power Bands

A power spectrum must be computed over windows of a certain length, not over continuous data. The Moving Window node therefore segments the stream into windows of window_length 2 seconds, and outputs the most recent window on every update. This node only works on streaming data, so it must be dropped when processing offline data (see the last section). The Power Spectrum (Welch) node then computes the power spectral density of each window.
The Power Bands node groups and averages the power spectrum into frequency bands. By default, these are the following bands (given in Hz, where the upper limit is not included):
| Property | Band | Range |
|---|---|---|
delta |
Delta | 1-3 |
theta |
Theta | 4-7 |
alpha |
Alpha | 8-15 |
beta |
Beta | 16-31 |
gamma |
Gamma | 32-40 |
You can change the range of each band by editing these properties, or define your own bands in the custom_bands property (for example {'theta2': [6, 7], 'beta3': [25, 31]}). If custom_bands is set, only those bands are computed, and the standard ones are ignored. Further settings used here are:
average_across_channelsis enabled, so there is only one value per band, which is the average over all channels. Disable it to get the band power for each channel separately.correct_for_falloffis enabled, which corrects the spectrum for the 1/f fall-off of EEG power.unitis set todB, so that the band power is expressed in decibels.
Output¶

The band power is sent to three outputs:
- A
Time Series Plotshows the band power over time (the last 20 seconds, itstime_rangeproperty), with one line per band. - A
Bar Plotshows the current band power as one bar per band (itsy_limitsare 0 to 50 dB). - An
LSL Outputnode sends the band power out as an LSL stream namedmy-relaxation-1(itsstream_nameproperty, ofstream_typeControl), so that it can be picked up by another pipeline or application, for example to control a game. Change the name and type to suit your application.
Using Offline Data¶
This pipeline can be adapted to use with offline (recorded) data. To do so:
- Wire the
Import XDFnode directly intoDejitter Timestamps, and drop the LSL nodes (LSL Input, and the playback branch'sStream DataandLSL Output). - Drop the
Moving Windownode, since it only works on streaming data. - Drop the
LSL Outputnode that sends out the band power. - The
Remove Bad Time Windowsnode, which has no effect on live data, now becomes active.
The Bar Plot would still work and would show the average band power for the entire session, but the band power needs to be averaged over time first, which can be done by adding a Mean node (averaging along the time axis) in front of the Bar Plot.