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