↑↓ move↵ open[] previous / next lesson? all shortcuts
Appearance
Theme
Type size
Reading

Focus mode hides the sidebars. Press f to toggle it anywhere.

Keyboard shortcuts
/
Search
[ ]
Previous / next lesson
t
Jump to the table of contents
r
Review queue
f
Focus mode
?
This panel
ProjectOne evening$0Tier 0

Project E: The zero-dollar version

Real EEG from 109 people, downloaded free, opened in Python. Find alpha, find a blink, find the heartbeat leaking in. Everything in Phase 1 without buying a part.

SpineDecoding / signal processing / ML
On this pageOne evening
  1. Setup
  2. Find alpha
  3. Find a blink
  4. Find the heartbeat
  5. Draw the map
  6. Going further

If you have no parts yet, or you want to see what a properly recorded 64-channel looks like before you build a one-channel version, this is the project. hosts the Motor Movement/Imagery dataset: 109 people, 64 , sampled at 160 Hz, with two one-minute baseline recordings for each person, one with eyes open and one with eyes closed. will download it for you. In an hour you will have found alpha in a stranger’s brain and know what a blink and a heartbeat look like on a real recording.

Predict before you look

On a 64-channel recording, in which channel will a blink be biggest?

Fp1, the frontal-polar just above the eye. Blinks are eye movement, and the eyeball is a battery whose field is strongest right next to it. At Oz the same blink is a tenth the size.

Setup

pip install mne matplotlib

has a loader for this dataset that fetches only the files you ask for. Run 1 is eyes open, run 2 is eyes closed.

import mne
from mne.datasets import eegbci

paths = eegbci.load_data(subject=1, runs=[1, 2])      # downloads ~2 MB per run
open_eyes  = mne.io.read_raw_edf(paths[0], preload=True)
closed     = mne.io.read_raw_edf(paths[1], preload=True)
for raw in (open_eyes, closed):
    eegbci.standardize(raw)                             # clean up channel names
    raw.set_montage('standard_1005')                    # tell MNE where the electrodes are
    raw.filter(0.5, 40.)                                # the same band-pass as Project B

Find alpha

Real alpha from the same dataset
This interactive needs JavaScript. If you are reading a printout, the caption describes what it shows.
Figure 1. This is the dataset you are about to load, subject S001, channel O1, and this is what you are looking for: the bump near 10 Hz that is there with the eyes closed (green) and mostly gone with them open (yellow line). When your own plot looks like this, you have found it.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
for raw, label in ((open_eyes, 'eyes open'), (closed, 'eyes closed')):
    spec = raw.compute_psd(picks=['O1'], fmax=40)
    freqs = spec.freqs; psd = spec.get_data()[0]
    ax.semilogy(freqs, psd, label=label)
ax.set(xlabel='Hz', ylabel='power (V²/Hz)', title='Subject 1, O1'); ax.legend(); plt.show()

Two curves. The eyes-closed one has a peak somewhere between 8 and 12 Hz that the eyes-open one does not. That is alpha, in a person you have never met, recorded with a research amplifier. Note the peak frequency; it differs by a hertz or two between people, and it is stable within a person for years.

Try a few subjects. Some have enormous alpha; a few have almost none. Both are normal.

open_eyes.plot(start=0, duration=10, n_channels=8, scalings=dict(eeg=100e-6))

Look at Fp1 and Fp2 at the top. Blinks are the big, slow, paired deflections, a few hundred microvolts, about a third of a second wide, that show up in both frontal channels and fade as you go back. Now look at Oz at the same moment. Small or absent. You have just seen how a source’s location shows up as a pattern across , which is the physics that Phase 4’s head model is about.

Find the heartbeat

Pick a channel near an ear, such as T7 or TP7, and plot ten seconds with a smaller scaling. Look for a small sharp about once a second. That is the heart’s electrical activity, a millivolt on the chest, leaking to the head as a few microvolts. It is in almost every and most people never notice it until it shows up in their average.

Draw the map

closed.compute_psd(fmax=40).plot_topomap(bands={'alpha (8-12 Hz)': (8, 12)})

A head, coloured by alpha power. It should be brightest at the back. This single picture is why Project B puts the where it does.

  1. Install and run the loader for subject 1, runs 1 and 2.
  2. Plot the O1 for both runs and identify the alpha peak. Write down its frequency.
  3. Plot ten seconds of the eyes-open run and find two blinks in Fp1. Measure their amplitude and width from the plot.
  4. Find the heartbeat in a temporal channel.
  5. Plot the alpha topography for eyes closed.
  6. Repeat step 2 for three more subjects. Save the four spectra as one figure with a legend, axes labelled.

Going further

Load run 3 (a motor task: open and close the left or right fist) and plot the C3 and C4 spectra while the subject moves versus rests. You will see the mu rhythm drop over the hemisphere opposite the moving hand. That is the phenomenon that motor imagery BCIs try to decode, and you have just seen it in a minute of data. Then go to the software pipeline project, which turns tonight’s script into a proper analysis.

Recall
Which two runs of the PhysioNet motor imagery dataset let you see alpha appear and disappear?
Run 1 (eyes open baseline) and run 2 (eyes closed baseline). The eyes-closed spectrum at O1 has an 8 to 12 Hz peak the eyes-open one lacks.
Recall
Why is a blink biggest at Fp1 and small at Oz, and what larger idea does that illustrate?
The eye is a dipole-like source and its field falls off with distance, so nearby frontal electrodes see it most. It illustrates that a source's location shows up as a pattern across electrodes, which is the basis of topographic maps and source localization.