Skip to content

Commit a255fcf

Browse files
committed
1st draft of mne example
1 parent a66a39b commit a255fcf

File tree

1 file changed

+223
-0
lines changed

1 file changed

+223
-0
lines changed

examples/plot_mne_example.py

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
"""
2+
Using fooof with MNE
3+
=================
4+
5+
This examples illustrates how to use fooof with `MNE
6+
<https://mne-tools.github.io/>`_ and create topographical plots
7+
8+
This tutorial does require that you have MNE installed. If you don't already have
9+
MNE, you can follow instructions to get it `here
10+
<https://mne-tools.github.io/stable/getting_started.html>`_.
11+
"""
12+
13+
###################################################################################################
14+
15+
16+
#General imports
17+
import numpy as np
18+
import pandas as pd
19+
from matplotlib import cm, colors, colorbar
20+
import matplotlib.pyplot as plt
21+
22+
# Import MNE, as well as the MNE sample dataset
23+
import mne
24+
from mne import io
25+
from mne.datasets import sample
26+
from mne.viz import plot_topomap
27+
28+
# FOOOF imports
29+
from fooof import FOOOF, FOOOFGroup
30+
from fooof.analysis import *
31+
32+
33+
###################################################################################################
34+
# Load & Check MNE Data
35+
# ---------------------
36+
#
37+
# First, we will load the example dataset from MNE, and have a quick look at the data.
38+
#
39+
# The MNE sample dataset is a combined MEG/EEG recording with an audiovisual task, as
40+
# described `here <https://martinos.org/mne/stable/manual/sample_dataset.html>`_.
41+
#
42+
# For the current example, we are going to sub-select only the EEG data,
43+
# and analyze it as continuous (non-epoched) data.
44+
#
45+
46+
###################################################################################################
47+
48+
# Get the data path for the MNE example data
49+
raw_fname = sample.data_path() + '/MEG/sample/sample_audvis_filt-0-40_raw.fif'
50+
event_fname = sample.data_path() + '/MEG/sample/sample_audvis_filt-0-40_raw-eve.fif'
51+
52+
# Load the file of example MNE data
53+
raw = mne.io.read_raw_fif(raw_fname, preload=True)
54+
55+
###################################################################################################
56+
57+
# Select EEG channels from the dataset
58+
raw = raw.pick_types(meg=False, eeg=True, eog=False, exclude='bads')
59+
60+
###################################################################################################
61+
62+
# Explicitly adding a default EEG average reference required for source localization
63+
raw.set_eeg_reference()
64+
65+
###################################################################################################
66+
67+
# Explore the data
68+
raw.info()
69+
70+
###################################################################################################
71+
72+
# Plot the channel locations and labels
73+
raw.plot_sensors(show_names=True)
74+
75+
###################################################################################################
76+
77+
# Creating epochs
78+
reject = dict(eeg=180e-6)
79+
event_id, tmin, tmax = {'left/auditory': 1}, -0.2, 0.5
80+
events = mne.read_events(event_fname)
81+
epochs = mne.Epochs(raw, events=events, event_id=event_id,
82+
tmin=5, tmax=125, baseline=None, preload=True)
83+
84+
###################################################################################################
85+
86+
# Creating Power Spectra Densities
87+
psd, freqs = mne.time_frequency.psd_welch(epochs, fmin=1., fmax=50., n_fft=2000, n_overlap=250, n_per_seg=500)
88+
89+
###################################################################################################
90+
# fooofgroup
91+
# ------------------
92+
#
93+
# The FOOOFGroup object is used to fit
94+
# FOOOF models across the power spectra. A list of FOOOFGroup objects is returned.
95+
#
96+
97+
###################################################################################################
98+
99+
# Initialize a FOOOF group object, with desired settings
100+
fg = FOOOFGroup(peak_width_limits=[1, 6], min_peak_amplitude=0.075,
101+
max_n_peaks=6, peak_threshold=1, verbose=False)
102+
103+
###################################################################################################
104+
105+
# Shaping the PSDs so that we can run fooofgroup
106+
fooof_psd = np.squeeze(psd[4,:,:])
107+
n_channels, n_freq = fooof_psd.shape
108+
num_blocks = len(mne.read_events(event_fname))
109+
110+
# Setting frequency range
111+
freq_range = [3, 32]
112+
113+
# This returns a list of FOOOFGRoup objects
114+
fg.fit(freqs, fooof_psd, freq_range)
115+
fg.plot()
116+
117+
###################################################################################################
118+
119+
# Define bands of interest
120+
bands = {'theta': [2,7],
121+
'alpha': [8,14],
122+
'beta': [15,30]}
123+
124+
# Creating dictionaries to store all the aperiodic properties across frequencies
125+
results = {}
126+
for band_name in bands.keys():
127+
results[band_name] = np.zeros(shape=[ num_blocks, n_channels, n_feats])
128+
129+
# Creating dictionaries to store all the periodic properties across frequencies
130+
slope_results = np.zeros(shape=[num_blocks, n_channels, 2])
131+
132+
###################################################################################################
133+
134+
# Populating periodic and aperiodic values
135+
for block in range(0, num_blocks):
136+
for ind, res in enumerate(fg):
137+
slope_results[block, ind, :] = res.background_params
138+
for band_label, band_range in bands.items():
139+
results[band_label][block, ind, :] = get_band_peak(res.peak_params, band_range, True)
140+
141+
###################################################################################################
142+
# Plotting topologies
143+
# --------------
144+
#
145+
# The following will illustrate the process of exploring the previoulsy generated
146+
# oscillatory values
147+
148+
###################################################################################################
149+
# This is the function required to create color bars for topographies
150+
def plot_topo_colorbar(vmin, vmax, label):
151+
"""
152+
Create a colorbar for the topography plots
153+
vmin: int
154+
vmax: int
155+
label: str
156+
"""
157+
fig = plt.figure(figsize=(2, 3))
158+
ax1 = fig.add_axes([0.9, 0.25, 0.15, 0.9])
159+
160+
cmap = cm.viridis
161+
norm = colors.Normalize(vmin=vmin, vmax=vmax)
162+
163+
cb1 = colorbar.ColorbarBase(plt.gca(), cmap=cmap,
164+
norm=norm, orientation='vertical')all_fg.plot()
165+
166+
###################################################################################################
167+
168+
# Settings: In this example, we will be plotting the Alpha Central Frequency
169+
# and oscillatory slope
170+
band = 'alpha'
171+
cur_data = results[band]
172+
feats = ["CFS", "AMPS", "BWS"]
173+
topo_dat = np.mean(cur_data,0)
174+
175+
###################################################################################################
176+
177+
# Looking at the alpha Central Frequeuncy
178+
print('CURRENT FEATURE:', feats[0])
179+
disp_dat = topo_dat[:,0]
180+
181+
inds = np.where(np.isnan(disp_dat))
182+
disp_dat[inds] = np.nanmean(disp_dat)
183+
184+
vbuffer = 0.1 * (disp_dat.max() - disp_dat.min())
185+
vmin, vmax, = disp_dat.min() - vbuffer, disp_dat.max() + vbuffer
186+
187+
fig, ax = plt.subplots()
188+
plot_topo_colorbar(vmin, vmax, feats[0])
189+
mne.viz.plot_topomap(disp_dat, raw.info, vmin=vmin, vmax=vmax, cmap=cm.viridis, contours=0, axes=ax)
190+
191+
###################################################################################################
192+
193+
# Looking at the Oscillatory
194+
cur_data = slope_results
195+
196+
topo_dat = np.mean(cur_data,0)
197+
198+
print('CURRENT FEATURE:', slope_feat[1])
199+
disp_dat = topo_dat[:,1]
200+
201+
inds = np.where(np.isnan(disp_dat))
202+
disp_dat[inds] = np.nanmean(disp_dat)
203+
204+
vbuffer = 0.1 * (disp_dat.max() - disp_dat.min())
205+
vmin, vmax, = disp_dat.min() - vbuffer, disp_dat.max() + vbuffer
206+
207+
fig, ax = plt.subplots()
208+
plot_topo_colorbar(vmin, vmax, slope_feat[1])
209+
mne.viz.plot_topomap(disp_dat, raw.info, vmin=vmin, vmax=vmax, cmap=cm.viridis, contours=0, axes=ax)
210+
211+
212+
###################################################################################################
213+
# Alternative epoching methods
214+
# --------------
215+
#
216+
# Antother way to epoch your data based on time by avaeraging across events as suppose to
217+
# selecting specifc time sections
218+
219+
###################################################################################################
220+
221+
epochs_params = dict(events=events, event_id=event_id, tmin=tmin, tmax=tmax,
222+
reject=reject)
223+
epochs = mne.Epochs(raw_no_ref, **epochs_params).average()

0 commit comments

Comments
 (0)