Author : Alexandre Gramfort
date : Jan. 2014
DISCLAIMER : This tutorial is for illustration purposes. The function to perform the TFR analysis is likely to change over the next few months. Objective is to simplify the code required.
# add plot inline in the page
%matplotlib inline
First, load the mne package:
import mne
We set the log-level to 'WARNING' so the output is less verbose
mne.set_log_level('WARNING')
Now we import the sample dataset. If you don't already have it, it will be downloaded automatically (but be patient approx. 2GB)
data_path = '/Users/alex/Sync/karolinska_teaching/'
raw_fname = data_path + '/meg/workshop_visual_sss.fif'
print raw_fname
Read data from file:
raw = mne.fiff.Raw(raw_fname)
print raw
!!! we need to fix now tiny acquisition problems
def fix_info(raw):
raw.info['chs'][raw.ch_names.index('BIO001')]['kind'] = mne.fiff.constants.FIFF.FIFFV_EOG_CH
raw.info['chs'][raw.ch_names.index('BIO002')]['kind'] = mne.fiff.constants.FIFF.FIFFV_EOG_CH
raw.info['chs'][raw.ch_names.index('BIO003')]['kind'] = mne.fiff.constants.FIFF.FIFFV_ECG_CH
fix_info(raw)
print raw.info
print raw.info['bads']
First extract events:
events = mne.find_events(raw, stim_channel='STI101', verbose=True)
print events[:5] # events is a 2d array
Look at the design in a graphical way:
plt.plot((events[:, 0] - raw.first_samp) / raw.info['sfreq'], events[:, 2], '.');
plt.xlabel('time (s)')
plt.axis([0.1168, 41.4003, 9.7295, 17.3887])
Define epochs parameters:
event_id = dict(cue_left=10, cue_right=20) # event trigger and conditions
tmin = -0.3 # start of each epoch
tmax = 1.6 # end of each epoch
event_id
Pick the good channels:
picks = mne.fiff.pick_types(raw.info, meg=True, eeg=False, eog=True,
stim=False, exclude='bads')
Define the baseline period:
baseline = (None, 0) # means from the first instant to t = 0
Define peak-to-peak rejection parameters for gradiometers, magnetometers and EOG:
reject = dict(grad=4000e-13, mag=4e-12, eog=150e-6)
Read epochs:
epochs = mne.Epochs(raw, events, event_id, tmin, tmax, proj=True,
picks=picks, baseline=baseline, reject=reject,
preload=True) # with preload
print epochs
epochs.plot_drop_log()
Create trialinfo array like Fieldtrip
def make_trialinfo(epochs, events):
trialinfo = []
n_epochs = len(epochs.selection)
sfreq = epochs.info['sfreq']
for ii in epochs.selection:
this_trialinfo = []
for jj in range(ii + 1, ii + 5):
if jj >= len(events):
continue
dt = (events[jj, 0] - events[ii, 0]) / sfreq
if dt < epochs.tmax:
this_trialinfo.append(dt)
trialinfo.append(this_trialinfo)
return np.array(trialinfo)
trialinfo = make_trialinfo(epochs, events)
Plot ERF on gradiometers and average latencies
fig = mne.fiff.pick_types_evoked(epochs.average(), meg='grad').plot(show=False)
ax = plt.gca()
ax.axvline(0., color='b')
ax.axvline(1000. * np.mean(trialinfo[:, 0]), color='g')
ax.axvline(1000. * np.mean(trialinfo[:, 1]), color='r')
plt.show()
evoked_left = epochs['cue_left'].average()
print evoked_left
evoked_right = epochs['cue_right'].average()
print evoked_right
Plot ERFs for both and then each conditions:
fig = (evoked_right + evoked_left).plot() # left and right
import numpy as np
times = np.linspace(0.07, 0.25, 5)
fig = evoked_left.plot_topomap(times=times, ch_type='mag')
fig = evoked_right.plot_topomap(times=times, ch_type='mag')
fig = evoked_left.plot_topomap(times=times, ch_type='grad')
fig = evoked_right.plot_topomap(times=times, ch_type='grad')
event_id = dict(stim_left=12, stim_right=22) # event trigger and conditions
tmin = -0.75 # start of each epoch
tmax = 0.8 # end of each epoch
baseline = (-0.5, 0)
# Restrict the analysis to occipital sensors for speed
selection = mne.read_selection('occipital')
selection = [s.replace(' ', '') for s in selection] # remove empty spaces
picks = mne.fiff.pick_types(raw.info, meg=True, eeg=False, eog=True,
stim=False, exclude='bads', selection=None)
epochs_stim = mne.Epochs(raw, events, event_id, tmin, tmax, proj=True,
picks=picks, baseline=baseline, reject=reject,
preload=True) # with preload
print epochs_stim
Let's look at the ERF on gradiometers only
fig = epochs_stim.average().plot()
Let's not run TF on EOG channels:
print epochs_stim.ch_names[:5]
epochs_stim.drop_channels(['BIO001', 'BIO002'])
print epochs_stim.ch_names[:5] # EOGs are gone...
Define paramters for time-frequency analysis
frequencies = np.arange(5., 120., 2.5) # define frequencies of interest
n_cycles = frequencies / 5. # different number of cycle per frequency
Fs = raw.info['sfreq'] # sampling in Hz
decim = 5
data = epochs_stim.get_data()
print data.shape
Let's compute
from mne.time_frequency import induced_power
power, phase_lock = induced_power(data, Fs=Fs, frequencies=frequencies,
n_cycles=n_cycles, n_jobs=4, use_fft=False,
decim=decim, zero_mean=True)
Let's look at some shapes to understand what we manipulate
power.shape, data.shape, frequencies.shape
Let's visualize
from mne.viz import plot_topo_power
baseline = (-0.4, -0.) # set the baseline for induced power
mode = 'percent' # set mode for baseline rescaling
layout = mne.find_layout(epochs_stim.info)
power_viz = power.copy()
baseline = None
mode = None
mask = (epochs_stim.times[::decim] < -0.1) & (epochs_stim.times[::decim] > -0.5)
power_viz = power_viz / np.mean(power_viz[:,:,mask], axis=-1)[:, :, None] - 1.
title = 'Induced power - Stim ON'
plot_topo_power(epochs_stim, power_viz, frequencies, layout, baseline=baseline,
mode=mode, decim=decim, title=title,
dB=False, vmin=-.3, vmax=0.3)
plt.show()
ch_idx = epochs_stim.ch_names.index('MEG1922')
times = 1e3 * epochs_stim.times[::decim]
extent = (times[0], times[-1], frequencies[0], frequencies[-1])
plt.imshow(power_viz[ch_idx], extent=extent, aspect="auto", origin="lower",
vmin=-0.3, vmax=0.3, picker=True)
plt.xlim([-300., 700.])
plt.xlabel('Time (ms)')
plt.ylabel('Freq. (Hz)')
plt.title('Power ' + epochs.ch_names[ch_idx])
plt.colorbar()
%matplotlib inline
plt.imshow(phase_lock[ch_idx], extent=extent, aspect="auto", origin="lower",
vmin=0, vmax=0.8, picker=True)
plt.xlim([-300., 700.])
plt.xlabel('Time (ms)')
plt.ylabel('Freq. (Hz)')
plt.title('Phase Lock ' + epochs.ch_names[ch_idx])
plt.colorbar()