EEG speech envelope TRF

Analyze continuous speech data from the mTRF dataset 1: use the boosting algorithm for estimating temporal response functions (TRFs) to the acoustic envelope.

# Author: Christian Brodbeck <christianbrodbeck@nyu.edu>
# sphinx_gallery_thumbnail_number = 4
import os

from scipy.io import loadmat
import mne
from eelbrain import *

# Load the mTRF speech dataset and convert data to NDVars
root = mne.datasets.mtrf.data_path()
speech_path = os.path.join(root, 'speech_data.mat')
mdata = loadmat(speech_path)

# Time axis
tstep = 1. / mdata['Fs'][0, 0]
n_times = mdata['envelope'].shape[0]
time = UTS(0, tstep, n_times)
# Load the EEG sensor coordinates (drop fiducials coordinates, which are stored
# after sensor 128)
sensor = Sensor.from_montage('biosemi128')[:128]
# Frequency dimension for the spectrogram
band = Scalar('frequency', range(16))
# Create variables
envelope = NDVar(mdata['envelope'][:, 0], (time,), name='envelope')
eeg = NDVar(mdata['EEG'], (time, sensor), name='EEG', info={'unit': 'µV'})
spectrogram = NDVar(mdata['spectrogram'], (time, band), name='spectrogram')
# Exclude a bad channel
eeg = eeg[sensor.index(exclude='A13')]

Data

Plot the spectrogram of the speech stimulus:

plot.Array(spectrogram, xlim=5, w=6, h=2)
mtrf

Out:

<Array: spectrogram>

Plot the envelope used as stimulus representation for reverse correlation:

plot.UTS(envelope, xlim=5, w=6, h=2)
mtrf

Out:

<UTS: envelope>

Plot the corresponding EEG data:

p = plot.TopoButterfly(eeg, xlim=5, w=7, h=2)
p.set_time(1.200)
mtrf

Reverse correlation

TRF for the envelope using boosting:

  • TRF from -100 to 400 ms

  • Basis of 100 ms Hamming windows

  • Use 4 partitionings of the data for cross-validation based early stopping

res = boosting(eeg, envelope, -0.100, 0.400, basis=0.100, partitions=4)
p = plot.TopoButterfly(res.h_scaled, w=6, h=2)
p.set_time(.180)
mtrf

Out:

Fitting models:   0%|          | 0/508 [00:00<?, ?it/s]
Fitting models:   0%|          | 1/508 [00:00<03:27,  2.44it/s]
Fitting models:   2%|1         | 9/508 [00:00<00:23, 21.64it/s]
Fitting models:   3%|3         | 17/508 [00:00<00:13, 35.47it/s]
Fitting models:   5%|4         | 25/508 [00:00<00:10, 44.75it/s]
Fitting models:   6%|6         | 33/508 [00:00<00:09, 50.36it/s]
Fitting models:   8%|7         | 40/508 [00:01<00:08, 53.32it/s]
Fitting models:   9%|9         | 48/508 [00:01<00:07, 58.92it/s]
Fitting models:  11%|#         | 55/508 [00:01<00:07, 60.75it/s]
Fitting models:  12%|#2        | 62/508 [00:01<00:07, 58.62it/s]
Fitting models:  14%|#3        | 69/508 [00:01<00:07, 58.18it/s]
Fitting models:  15%|#4        | 76/508 [00:01<00:07, 60.87it/s]
Fitting models:  16%|#6        | 83/508 [00:01<00:07, 60.60it/s]
Fitting models:  18%|#7        | 90/508 [00:01<00:06, 60.64it/s]
Fitting models:  19%|#9        | 98/508 [00:01<00:06, 64.32it/s]
Fitting models:  21%|##        | 105/508 [00:02<00:06, 64.95it/s]
Fitting models:  22%|##2       | 112/508 [00:02<00:06, 63.97it/s]
Fitting models:  23%|##3       | 119/508 [00:02<00:07, 55.04it/s]
Fitting models:  25%|##4       | 126/508 [00:02<00:06, 58.47it/s]
Fitting models:  26%|##6       | 133/508 [00:02<00:06, 59.72it/s]
Fitting models:  28%|##7       | 141/508 [00:02<00:06, 59.56it/s]
Fitting models:  29%|##9       | 148/508 [00:02<00:06, 59.85it/s]
Fitting models:  31%|###       | 155/508 [00:02<00:05, 60.50it/s]
Fitting models:  32%|###2      | 163/508 [00:02<00:05, 63.50it/s]
Fitting models:  34%|###3      | 171/508 [00:03<00:05, 64.68it/s]
Fitting models:  35%|###5      | 179/508 [00:03<00:04, 66.85it/s]
Fitting models:  37%|###6      | 187/508 [00:03<00:04, 68.24it/s]
Fitting models:  38%|###8      | 195/508 [00:03<00:04, 69.42it/s]
Fitting models:  40%|###9      | 203/508 [00:03<00:04, 70.23it/s]
Fitting models:  42%|####1     | 211/508 [00:03<00:04, 69.51it/s]
Fitting models:  43%|####3     | 219/508 [00:03<00:04, 71.07it/s]
Fitting models:  45%|####4     | 227/508 [00:03<00:03, 72.07it/s]
Fitting models:  46%|####6     | 235/508 [00:04<00:03, 68.68it/s]
Fitting models:  48%|####7     | 242/508 [00:04<00:04, 64.40it/s]
Fitting models:  49%|####9     | 250/508 [00:04<00:03, 66.48it/s]
Fitting models:  51%|#####     | 258/508 [00:04<00:03, 66.68it/s]
Fitting models:  52%|#####2    | 265/508 [00:04<00:03, 66.55it/s]
Fitting models:  54%|#####3    | 272/508 [00:04<00:03, 66.54it/s]
Fitting models:  55%|#####4    | 279/508 [00:04<00:03, 66.98it/s]
Fitting models:  56%|#####6    | 286/508 [00:04<00:03, 66.65it/s]
Fitting models:  58%|#####7    | 293/508 [00:04<00:03, 64.33it/s]
Fitting models:  59%|#####9    | 301/508 [00:05<00:03, 65.52it/s]
Fitting models:  61%|######    | 308/508 [00:05<00:03, 62.61it/s]
Fitting models:  62%|######2   | 315/508 [00:05<00:03, 59.57it/s]
Fitting models:  63%|######3   | 321/508 [00:05<00:03, 58.24it/s]
Fitting models:  64%|######4   | 327/508 [00:05<00:03, 52.51it/s]
Fitting models:  66%|######5   | 333/508 [00:05<00:03, 52.64it/s]
Fitting models:  67%|######6   | 340/508 [00:05<00:03, 55.63it/s]
Fitting models:  69%|######8   | 348/508 [00:05<00:02, 59.78it/s]
Fitting models:  70%|######9   | 355/508 [00:06<00:02, 58.32it/s]
Fitting models:  71%|#######1  | 361/508 [00:06<00:02, 58.76it/s]
Fitting models:  72%|#######2  | 367/508 [00:06<00:02, 54.25it/s]
Fitting models:  74%|#######3  | 374/508 [00:06<00:02, 56.21it/s]
Fitting models:  75%|#######4  | 380/508 [00:06<00:02, 50.64it/s]
Fitting models:  76%|#######6  | 388/508 [00:06<00:02, 55.58it/s]
Fitting models:  78%|#######7  | 395/508 [00:06<00:02, 56.28it/s]
Fitting models:  79%|#######8  | 401/508 [00:06<00:02, 52.83it/s]
Fitting models:  80%|########  | 407/508 [00:06<00:01, 53.27it/s]
Fitting models:  81%|########1 | 413/508 [00:07<00:01, 47.88it/s]
Fitting models:  82%|########2 | 418/508 [00:07<00:01, 46.83it/s]
Fitting models:  83%|########3 | 423/508 [00:07<00:01, 46.31it/s]
Fitting models:  84%|########4 | 428/508 [00:07<00:01, 46.38it/s]
Fitting models:  85%|########5 | 434/508 [00:07<00:01, 49.99it/s]
Fitting models:  87%|########6 | 440/508 [00:07<00:01, 51.58it/s]
Fitting models:  88%|########7 | 447/508 [00:07<00:01, 54.66it/s]
Fitting models:  89%|########9 | 454/508 [00:07<00:00, 54.76it/s]
Fitting models:  91%|######### | 460/508 [00:08<00:00, 50.99it/s]
Fitting models:  92%|#########1| 466/508 [00:08<00:00, 50.21it/s]
Fitting models:  93%|#########2| 472/508 [00:08<00:00, 48.50it/s]
Fitting models:  94%|#########4| 479/508 [00:08<00:00, 52.51it/s]
Fitting models:  95%|#########5| 485/508 [00:08<00:00, 51.22it/s]
Fitting models:  97%|#########6| 491/508 [00:08<00:00, 50.47it/s]
Fitting models:  98%|#########8| 499/508 [00:08<00:00, 56.29it/s]
Fitting models:  99%|#########9| 505/508 [00:08<00:00, 52.88it/s]

/home/docs/checkouts/readthedocs.org/user_builds/eelbrain/envs/r-0.34/lib/python3.7/site-packages/scipy/stats/stats.py:4264: SpearmanRConstantInputWarning: An input array is constant; the correlation coefficent is not defined.
  warnings.warn(SpearmanRConstantInputWarning())

Multiple predictors

Multiple predictors additively explain the signal:

# Derive acoustic onsets from the envelope
onset = envelope.diff('time', name='onset').clip(0)
onset *= envelope.max() / onset.max()
plot.UTS([[envelope, onset]], xlim=5, w=6, h=2)
mtrf

Out:

<UTS: envelope, onset>
res_onset = boosting(eeg, [onset, envelope], -0.100, 0.400, basis=0.100, partitions=4)
p = plot.TopoButterfly(res_onset.h_scaled, w=6, h=3)
p.set_time(.150)
mtrf

Out:

Fitting models:   0%|          | 0/508 [00:00<?, ?it/s]
Fitting models:   0%|          | 1/508 [00:00<03:12,  2.63it/s]
Fitting models:   1%|          | 5/508 [00:00<00:39, 12.79it/s]
Fitting models:   2%|1         | 9/508 [00:00<00:25, 19.80it/s]
Fitting models:   3%|2         | 13/508 [00:00<00:19, 24.88it/s]
Fitting models:   3%|3         | 17/508 [00:00<00:17, 28.75it/s]
Fitting models:   4%|4         | 21/508 [00:00<00:15, 30.53it/s]
Fitting models:   5%|4         | 25/508 [00:01<00:15, 30.32it/s]
Fitting models:   6%|5         | 29/508 [00:01<00:15, 31.47it/s]
Fitting models:   6%|6         | 33/508 [00:01<00:15, 31.13it/s]
Fitting models:   7%|7         | 37/508 [00:01<00:14, 32.54it/s]
Fitting models:   8%|8         | 41/508 [00:01<00:13, 33.50it/s]
Fitting models:   9%|8         | 45/508 [00:01<00:13, 34.61it/s]
Fitting models:  10%|9         | 49/508 [00:01<00:12, 35.63it/s]
Fitting models:  10%|#         | 53/508 [00:01<00:12, 36.11it/s]
Fitting models:  11%|#1        | 57/508 [00:01<00:13, 33.41it/s]
Fitting models:  12%|#2        | 61/508 [00:02<00:13, 33.26it/s]
Fitting models:  13%|#2        | 65/508 [00:02<00:13, 32.44it/s]
Fitting models:  14%|#3        | 69/508 [00:02<00:13, 33.34it/s]
Fitting models:  14%|#4        | 73/508 [00:02<00:13, 32.52it/s]
Fitting models:  15%|#5        | 77/508 [00:02<00:12, 33.23it/s]
Fitting models:  16%|#5        | 81/508 [00:02<00:12, 33.83it/s]
Fitting models:  17%|#6        | 85/508 [00:02<00:12, 34.44it/s]
Fitting models:  18%|#7        | 89/508 [00:02<00:11, 35.73it/s]
Fitting models:  18%|#8        | 93/508 [00:03<00:11, 35.65it/s]
Fitting models:  19%|#9        | 97/508 [00:03<00:11, 35.44it/s]
Fitting models:  20%|#9        | 101/508 [00:03<00:11, 36.03it/s]
Fitting models:  21%|##        | 105/508 [00:03<00:12, 33.14it/s]
Fitting models:  21%|##1       | 109/508 [00:03<00:12, 32.16it/s]
Fitting models:  22%|##2       | 113/508 [00:03<00:12, 32.75it/s]
Fitting models:  23%|##3       | 117/508 [00:03<00:11, 33.20it/s]
Fitting models:  24%|##3       | 121/508 [00:03<00:11, 34.36it/s]
Fitting models:  25%|##4       | 125/508 [00:03<00:10, 35.03it/s]
Fitting models:  25%|##5       | 129/508 [00:04<00:10, 35.38it/s]
Fitting models:  26%|##6       | 133/508 [00:04<00:10, 36.26it/s]
Fitting models:  27%|##6       | 137/508 [00:04<00:11, 33.49it/s]
Fitting models:  28%|##7       | 141/508 [00:04<00:10, 34.01it/s]
Fitting models:  29%|##8       | 145/508 [00:04<00:11, 30.41it/s]
Fitting models:  29%|##9       | 149/508 [00:04<00:12, 29.64it/s]
Fitting models:  30%|###       | 153/508 [00:04<00:11, 31.77it/s]
Fitting models:  31%|###       | 157/508 [00:04<00:10, 33.26it/s]
Fitting models:  32%|###1      | 161/508 [00:05<00:10, 34.12it/s]
Fitting models:  32%|###2      | 165/508 [00:05<00:09, 34.66it/s]
Fitting models:  33%|###3      | 169/508 [00:05<00:09, 35.39it/s]
Fitting models:  34%|###4      | 173/508 [00:05<00:09, 36.02it/s]
Fitting models:  35%|###4      | 177/508 [00:05<00:09, 34.75it/s]
Fitting models:  36%|###5      | 181/508 [00:05<00:09, 34.85it/s]
Fitting models:  36%|###6      | 185/508 [00:05<00:09, 35.51it/s]
Fitting models:  37%|###7      | 189/508 [00:05<00:08, 36.25it/s]
Fitting models:  38%|###7      | 193/508 [00:05<00:08, 36.22it/s]
Fitting models:  39%|###8      | 197/508 [00:06<00:09, 33.00it/s]
Fitting models:  40%|###9      | 201/508 [00:06<00:09, 32.96it/s]
Fitting models:  40%|####      | 205/508 [00:06<00:09, 33.43it/s]
Fitting models:  41%|####1     | 209/508 [00:06<00:08, 34.18it/s]
Fitting models:  42%|####1     | 213/508 [00:06<00:08, 35.17it/s]
Fitting models:  43%|####2     | 217/508 [00:06<00:08, 36.35it/s]
Fitting models:  44%|####3     | 221/508 [00:06<00:07, 37.22it/s]
Fitting models:  44%|####4     | 225/508 [00:06<00:07, 37.09it/s]
Fitting models:  45%|####5     | 229/508 [00:06<00:07, 36.57it/s]
Fitting models:  46%|####5     | 233/508 [00:07<00:07, 35.72it/s]
Fitting models:  47%|####6     | 237/508 [00:07<00:07, 34.35it/s]
Fitting models:  47%|####7     | 241/508 [00:07<00:07, 34.40it/s]
Fitting models:  48%|####8     | 245/508 [00:07<00:07, 35.32it/s]
Fitting models:  49%|####9     | 249/508 [00:07<00:07, 34.31it/s]
Fitting models:  50%|####9     | 253/508 [00:07<00:07, 34.84it/s]
Fitting models:  51%|#####     | 257/508 [00:07<00:07, 35.19it/s]
Fitting models:  51%|#####1    | 261/508 [00:07<00:06, 35.89it/s]
Fitting models:  52%|#####2    | 265/508 [00:08<00:06, 35.82it/s]
Fitting models:  53%|#####2    | 269/508 [00:08<00:06, 34.21it/s]
Fitting models:  54%|#####3    | 273/508 [00:08<00:07, 32.71it/s]
Fitting models:  55%|#####4    | 277/508 [00:08<00:07, 31.20it/s]
Fitting models:  55%|#####5    | 281/508 [00:08<00:07, 31.28it/s]
Fitting models:  56%|#####6    | 285/508 [00:08<00:06, 31.97it/s]
Fitting models:  57%|#####6    | 289/508 [00:08<00:06, 32.31it/s]
Fitting models:  58%|#####7    | 293/508 [00:08<00:06, 33.10it/s]
Fitting models:  58%|#####8    | 297/508 [00:09<00:06, 34.28it/s]
Fitting models:  59%|#####9    | 301/508 [00:09<00:05, 34.94it/s]
Fitting models:  60%|######    | 305/508 [00:09<00:06, 33.04it/s]
Fitting models:  61%|######    | 309/508 [00:09<00:06, 33.16it/s]
Fitting models:  62%|######1   | 313/508 [00:09<00:05, 34.46it/s]
Fitting models:  62%|######2   | 317/508 [00:09<00:05, 34.16it/s]
Fitting models:  63%|######3   | 321/508 [00:09<00:05, 33.54it/s]
Fitting models:  64%|######3   | 325/508 [00:09<00:05, 31.60it/s]
Fitting models:  65%|######4   | 329/508 [00:10<00:05, 30.90it/s]
Fitting models:  66%|######5   | 333/508 [00:10<00:05, 29.84it/s]
Fitting models:  66%|######6   | 337/508 [00:10<00:05, 31.66it/s]
Fitting models:  67%|######7   | 341/508 [00:10<00:05, 30.70it/s]
Fitting models:  68%|######7   | 345/508 [00:10<00:05, 31.46it/s]
Fitting models:  69%|######8   | 349/508 [00:10<00:05, 30.36it/s]
Fitting models:  69%|######9   | 353/508 [00:10<00:05, 30.04it/s]
Fitting models:  70%|#######   | 357/508 [00:10<00:04, 32.17it/s]
Fitting models:  71%|#######1  | 361/508 [00:11<00:04, 31.56it/s]
Fitting models:  72%|#######1  | 365/508 [00:11<00:04, 29.89it/s]
Fitting models:  73%|#######2  | 369/508 [00:11<00:04, 29.67it/s]
Fitting models:  73%|#######3  | 373/508 [00:11<00:04, 31.31it/s]
Fitting models:  74%|#######4  | 377/508 [00:11<00:04, 30.60it/s]
Fitting models:  75%|#######5  | 381/508 [00:11<00:04, 27.30it/s]
Fitting models:  76%|#######5  | 385/508 [00:11<00:04, 28.91it/s]
Fitting models:  76%|#######6  | 388/508 [00:12<00:04, 27.38it/s]
Fitting models:  77%|#######6  | 391/508 [00:12<00:04, 26.01it/s]
Fitting models:  78%|#######7  | 395/508 [00:12<00:04, 24.86it/s]
Fitting models:  78%|#######8  | 398/508 [00:12<00:04, 25.62it/s]
Fitting models:  79%|#######8  | 401/508 [00:12<00:04, 23.73it/s]
Fitting models:  80%|#######9  | 404/508 [00:12<00:04, 21.22it/s]
Fitting models:  80%|########  | 407/508 [00:12<00:04, 21.17it/s]
Fitting models:  81%|########  | 410/508 [00:12<00:04, 23.01it/s]
Fitting models:  81%|########1 | 413/508 [00:13<00:04, 19.97it/s]
Fitting models:  82%|########1 | 416/508 [00:13<00:04, 20.61it/s]
Fitting models:  82%|########2 | 419/508 [00:13<00:04, 21.10it/s]
Fitting models:  83%|########3 | 422/508 [00:13<00:03, 22.71it/s]
Fitting models:  84%|########3 | 425/508 [00:13<00:03, 22.95it/s]
Fitting models:  84%|########4 | 428/508 [00:13<00:04, 19.96it/s]
Fitting models:  85%|########4 | 431/508 [00:13<00:03, 22.06it/s]
Fitting models:  86%|########5 | 435/508 [00:14<00:02, 24.96it/s]
Fitting models:  86%|########6 | 439/508 [00:14<00:02, 27.86it/s]
Fitting models:  87%|########7 | 443/508 [00:14<00:02, 29.46it/s]
Fitting models:  88%|########7 | 447/508 [00:14<00:02, 30.03it/s]
Fitting models:  89%|########8 | 451/508 [00:14<00:01, 30.17it/s]
Fitting models:  90%|########9 | 455/508 [00:14<00:01, 29.81it/s]
Fitting models:  90%|######### | 459/508 [00:14<00:01, 28.52it/s]
Fitting models:  91%|#########1| 463/508 [00:15<00:01, 28.58it/s]
Fitting models:  92%|#########1| 467/508 [00:15<00:01, 28.12it/s]
Fitting models:  93%|#########2| 470/508 [00:15<00:01, 26.26it/s]
Fitting models:  93%|#########3| 474/508 [00:15<00:01, 28.05it/s]
Fitting models:  94%|#########3| 477/508 [00:15<00:01, 27.76it/s]
Fitting models:  94%|#########4| 480/508 [00:15<00:01, 27.89it/s]
Fitting models:  95%|#########5| 483/508 [00:15<00:00, 27.78it/s]
Fitting models:  96%|#########5| 487/508 [00:15<00:00, 27.08it/s]
Fitting models:  96%|#########6| 490/508 [00:16<00:00, 27.58it/s]
Fitting models:  97%|#########7| 493/508 [00:16<00:00, 27.39it/s]
Fitting models:  98%|#########7| 497/508 [00:16<00:00, 29.47it/s]
Fitting models:  99%|#########8| 501/508 [00:16<00:00, 31.38it/s]
Fitting models:  99%|#########9| 505/508 [00:16<00:00, 28.59it/s]

Compare models

Compare model quality through the correlation between measured and predicted responses:

plot.Topomap([res.r, res_onset.r], w=4, h=2, ncol=2, axtitle=['envelope', 'envelope + onset'])
envelope, envelope + onset

Out:

<Topomap: Correlation>

References

1

Crosse, M. J., Liberto, D., M, G., Bednar, A., & Lalor, E. C. (2016). The Multivariate Temporal Response Function (mTRF) Toolbox: A MATLAB Toolbox for Relating Neural Signals to Continuous Stimuli. Frontiers in Human Neuroscience, 10. https://doi.org/10.3389/fnhum.2016.00604

Total running time of the script: ( 0 minutes 31.413 seconds)

Gallery generated by Sphinx-Gallery