def plot_topo(self, i_clu=None, pos=None, **kwargs): """ Plots fmap of one or several clusters. Parameters ---------- i_clu : int cluster index Can take evoked.plot_topomap() parameters. Returns ------- fig """ from mne import find_layout from mne.viz import plot_topomap # Channel positions pos = find_layout(self.info).pos # create topomap mask from sig cluster mask, space_inds, time_inds = self._get_mask(i_clu) if pos is None: pos = find_layout(self.info).pos # plot average test statistic and mark significant sensors topo = self.T_obs_[time_inds, :].mean(axis=0) fig = plot_topomap(topo, pos, **kwargs) return fig
def test_plot_topomap_neuromag122(): """Test topomap plotting.""" res = 8 fast_test = dict(res=res, contours=0, sensors=False) evoked = read_evokeds(evoked_fname, 'Left Auditory', baseline=(None, 0)) evoked.pick_types(meg='grad') evoked.pick_channels(evoked.ch_names[:122]) ch_names = ['MEG %03d' % k for k in range(1, 123)] for c in evoked.info['chs']: c['coil_type'] = FIFF.FIFFV_COIL_NM_122 evoked.rename_channels( {c_old: c_new for (c_old, c_new) in zip(evoked.ch_names, ch_names)}) layout = find_layout(evoked.info) assert layout.kind.startswith('Neuromag_122') evoked.plot_topomap(times=[0.1], **fast_test) proj = Projection(active=False, desc="test", kind=1, data=dict(nrow=1, ncol=122, row_names=None, col_names=evoked.ch_names, data=np.ones(122)), explained_var=0.5) plot_projs_topomap([proj], evoked.info, **fast_test)
def test_plot_topomap_neuromag122(): """Test topomap plotting.""" res = 8 fast_test = dict(res=res, contours=0, sensors=False) evoked = read_evokeds(evoked_fname, 'Left Auditory', baseline=(None, 0)) evoked.pick_types(meg='grad') evoked.pick_channels(evoked.ch_names[:122]) ch_names = ['MEG %03d' % k for k in range(1, 123)] for c in evoked.info['chs']: c['coil_type'] = FIFF.FIFFV_COIL_NM_122 evoked.rename_channels({c_old: c_new for (c_old, c_new) in zip(evoked.ch_names, ch_names)}) layout = find_layout(evoked.info) assert layout.kind.startswith('Neuromag_122') evoked.plot_topomap(times=[0.1], **fast_test) proj = Projection(active=False, desc="test", kind=1, data=dict(nrow=1, ncol=122, row_names=None, col_names=evoked.ch_names, data=np.ones(122)), explained_var=0.5) plot_projs_topomap([proj], info=evoked.info, **fast_test) plot_projs_topomap([proj], layout=layout, **fast_test) pytest.raises(RuntimeError, plot_projs_topomap, [proj], **fast_test)
def plot_grads(data, info): names = [info["chs"][i]["ch_name"] for i in range(len(info["chs"]))] av_data = data.reshape(-1, 2).mean(axis=1) print(av_data.shape) av_names = [n[:-1] for n in names[::2]] layout = find_layout(info) pos = layout.pos[::2, :2] plot_topomap(av_data, pos, names=av_names, show_names=True)
def extract_info_cluster(cluster_stats, p_threshold, data, data_array_chtype, ch_type): """ This function takes the output of cluster_stats = permutation_cluster_1samp_test(...) and returns all the useful things for the plots :return: dictionnary containing all the information: - position of the sensors - number of clusters - The T-value of the cluster """ cluster_info = { 'times': data.times * 1e3, 'p_threshold': p_threshold, 'ch_type': ch_type } T_obs, clusters, p_values, _ = cluster_stats good_cluster_inds = np.where(p_values < p_threshold)[0] pos = mne.find_layout(data.info, ch_type=ch_type).pos print("We found %i positions for ch_type %s" % (len(pos), ch_type)) times = data.times * 1e3 if len(good_cluster_inds) > 0: # loop over significant clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) signals = data_array_chtype[..., ch_inds].mean( axis=-1) # is this correct ?? # signals = data_array_chtype[..., ch_inds].mean(axis=1) # is this correct ?? sig_times = times[time_inds] p_value = p_values[clu_idx] cluster_info[i_clu] = { 'sig_times': sig_times, 'time_inds': time_inds, 'signal': signals, 'channels_cluster': ch_inds, 'p_values': p_value } cluster_info['pos'] = pos cluster_info['ncluster'] = i_clu + 1 cluster_info['T_obs'] = T_obs if ch_type == 'eeg': tmp = data.copy().pick_types(meg=False, eeg=True) cluster_info['data_info'] = tmp.info else: tmp = data.copy().pick_types(meg=ch_type, eeg=False) cluster_info['data_info'] = tmp.info return cluster_info
def brain_plot(): N = 62 xlabels, ylabels, control_csv, patient_csv = readfile() raw_fname = 'jkdz_cc_01_20180430_close.vhdr' raw = mne.io.read_raw_brainvision(raw_fname, preload=True) raw.drop_channels(['Oz', 'ECG']) epoch = mne.Epochs(raw, mne.find_events(raw)) pos = mne.find_layout(epoch.info).pos print(raw.info) image, _ = mne.viz.plot_topomap(control_csv, pos) mne.viz.tight_layout() mg.imsave('test_control', image)
def cli(meg_files, save_path, flat): '''Convert fif or ds to .mat format''' common_prefix = split(cprfx(meg_files))[0] + '/' for meg_file in meg_files: # click.echo(meg_file) base, ext = splitext(meg_file) new_base = base.replace(common_prefix, '') if flat: new_base = new_base.replace('/','_') # click.echo(new_base) new_base = join(save_path, new_base) if ext == '.fif': with nostdout(): raw = Raw_fif(meg_file, preload=True, add_eeg_ref=False) elif ext == '.ds': with nostdout(): raw = Raw_ctf(meg_file, preload=True) else: click.echo('ERROR: UNKNOWN FORMAT FOR {}'.format(meg_file)) meg_raw = raw.pick_types(meg=True, ref_meg=False) data, times = meg_raw[:,:] ch_names = meg_raw.info['ch_names'] la = find_layout(meg_raw.info) pos = la.pos[:,:2] pos_filt = np.array([pos[i,:] for i in range(len(pos)) if la.names[i] in ''.join(raw.info['ch_names'])]) # click.echo(pos) new_path,_ = split(new_base) if not exists(new_path): makedirs(new_path) savemat(new_base + '.mat', {'data': data, 'times': times, 'chnames': ch_names, 'chxy': pos_filt})
def sensor_space_pac_acrossFrequencies(sensor_space_slow_epochs,sensor_space_epochs_acrossFreqs): tempdir = _TempDir() paf = params_acrossFrequencies pos = mne.find_layout(sensor_space_slow_epochs.info,exclude=[]).pos ch_names = sensor_space_slow_epochs.ch_names events = {'1':sensor_space_slow_epochs.events[:,0]/sensor_space_slow_epochs.info['sfreq']} eventnames = ['1'] neighbor_dict = {name:[] for name in ch_names} pac = spac.SensorSpacePAC('test-sens-acrossFreqs', tempdir, None, paf['slow_band'], paf['amp_bands'], paf['blnPhaseHilbert'], paf['blnAmpHilbert'], paf['Nbootstrap'], paf['swtPACmetric'], paf['swtBootstrapMethod'], 'events.xxx', tempdir, False,N=len(ch_names),pos=pos,prep=[], ch_names=ch_names,events=events, eventnames=eventnames,Nlevels=len(eventnames), neighbor_dict=neighbor_dict) pac.phase_band_epochs = sensor_space_slow_epochs pac.amp_band_epochs = sensor_space_epochs_acrossFreqs pac.run_computation(False) return pac
def plot_weights_maps(analysis_name='Standard_VS_Deviant',results_name='results.npy',suffix='',chan_types=['mag'],chance=None,vmin=None,vmax=None,font_size = 8): save_path = config.fig_path+'/localization/'+analysis_name+'/' utils.create_folder(save_path) epoch = sensor_weights_all_subj_as_epo(analysis_name=analysis_name,results_name=results_name) for chans in chan_types: fig = plt.figure(figsize=(3.,2.2)) layout = mne.find_layout(epoch.info,ch_type=chans) data_to_plot = np.squeeze(epoch.copy().pick_types(meg=chans).average()._data) if chance is None: if 'grad' in chan_types: plt.scatter(np.asarray([layout.pos[i, 0] for i in range(0,len(layout.pos),2)]), [layout.pos[i, 1] for i in range(0,len(layout.pos),2)], c=[data_to_plot[i] for i in range(0,len(layout.pos),2)], s=30, vmin=vmin, vmax=vmax) else: plt.scatter(layout.pos[:, 0], layout.pos[:, 1], c=data_to_plot, s=30, vmin=vmin, vmax=vmax) else: if 'grad' in chan_types: plt.scatter(np.asarray([layout.pos[i, 0] for i in range(0,len(layout.pos),2)]), [layout.pos[i, 1] for i in range(0,len(layout.pos),2)], c=[data_to_plot[i]-chance for i in range(0,len(layout.pos),2)], s=30, vmin=vmin, vmax=vmax) else: plt.scatter(layout.pos[:, 0], layout.pos[:, 1], c=data_to_plot - chance, s=30, vmin=vmin, vmax=vmax) # plt.title(analysis_name+chans) plt.gca().get_xaxis().set_visible(False) plt.gca().get_yaxis().set_visible(False) plt.axis('off') cbar = plt.colorbar() # Adjust as appropriate. cbar.ax.tick_params(labelsize=font_size) plt.gcf().savefig(save_path+chans+suffix+'.png') plt.gcf().savefig(save_path+chans+suffix+'.svg') plt.gcf().show() fig = plt.gcf() plt.close('all') return fig
This example shows how to display topographies of SSP projection vectors. The projections used are the ones correcting for ECG artifacts. """ # Author: Alexandre Gramfort <*****@*****.**> # Denis A. Engemann <*****@*****.**> # License: BSD (3-clause) print(__doc__) import matplotlib.pyplot as plt from mne import read_proj, find_layout from mne.io import read_evokeds from mne.datasets import sample from mne import viz data_path = sample.data_path() ecg_fname = data_path + "/MEG/sample/sample_audvis_ecg_proj.fif" ave_fname = data_path + "/MEG/sample/sample_audvis-ave.fif" evoked = read_evokeds(ave_fname, condition="Left Auditory") projs = read_proj(ecg_fname) layouts = [find_layout(evoked.info, k) for k in "meg", "eeg"] plt.figure(figsize=(12, 6)) viz.plot_projs_topomap(projs, layout=layouts) viz.tight_layout(w_pad=0.5)
eog=True, stim=False, include=include, exclude='bads') epochs = mne.Epochs(raw, events, event_id, tmin, tmax, picks=picks, baseline=(None, 0), reject=dict(grad=4000e-13, eog=150e-6)) data = epochs.get_data() # as 3D matrix layout = mne.find_layout(epochs.info, 'meg') ############################################################################### # Calculate power and phase locking value frequencies = np.arange(7, 30, 3) # define frequencies of interest n_cycles = frequencies / float(7) # different number of cycle per frequency Fs = raw.info['sfreq'] # sampling in Hz decim = 3 power, phase_lock = induced_power(data, Fs=Fs, frequencies=frequencies, n_cycles=n_cycles, n_jobs=1, use_fft=False, decim=decim,
############################################################################### # Displaying the projections from a raw object requires no extra information # since all the layout information is present in `raw.info`. # MNE is able to automatically determine the layout for some magnetometer and # gradiometer configurations but not the layout of EEG electrodes. # # Here we display the `ecg_projs` individually and we provide extra parameters # for EEG. (Notice that planar projection refers to the gradiometers and axial # refers to magnetometers.) # # Notice that the conditional is just for illustration purposes. We could # `raw.info` in all cases to avoid the guesswork in `plot_topomap` and ensure # that the right layout is always found fig, axes = plt.subplots(1, len(ecg_projs)) for proj, ax in zip(ecg_projs, axes): if proj['desc'].startswith('ECG-eeg'): proj.plot_topomap(axes=ax, info=raw.info) else: proj.plot_topomap(axes=ax) ############################################################################### # The correct layout or a list of layouts from where to choose can also be # provided. Just for illustration purposes, here we generate the # `possible_layouts` from the raw object itself, but it can come from somewhere # else. possible_layouts = [ mne.find_layout(raw.info, ch_type=ch_type) for ch_type in ('grad', 'mag', 'eeg') ] mne.viz.plot_projs_topomap(ecg_projs, layout=possible_layouts)
Plot SSP projections topographies ================================= This example shows how to display topographies of SSP projection vectors. The projections used are the ones correcting for ECG artifacts. """ # Author: Alexandre Gramfort <*****@*****.**> # Denis A. Engemann <*****@*****.**> # License: BSD (3-clause) print(__doc__) import matplotlib.pyplot as plt import mne from mne.datasets import sample data_path = sample.data_path() ecg_fname = data_path + '/MEG/sample/sample_audvis_ecg_proj.fif' ave_fname = data_path + '/MEG/sample/sample_audvis-ave.fif' evoked = mne.fiff.read_evoked(ave_fname, setno='Left Auditory') projs = mne.read_proj(ecg_fname) layouts = [mne.find_layout(evoked.info, k) for k in 'meg', 'eeg'] plt.figure(figsize=(12, 6)) mne.viz.plot_projs_topomap(projs, layout=layouts) mne.viz.tight_layout(w_pad=0.5)
================================= Plot SSP projections topographies ================================= This example shows how to display topographies of SSP projection vectors. The projections used are the ones correcting for ECG artifacts. """ # Author: Alexandre Gramfort <*****@*****.**> # Denis A. Engemann <*****@*****.**> # License: BSD (3-clause) print(__doc__) import matplotlib.pyplot as plt import mne from mne.datasets import sample data_path = sample.data_path() ecg_fname = data_path + '/MEG/sample/sample_audvis_ecg_proj.fif' ave_fname = data_path + '/MEG/sample/sample_audvis-ave.fif' evoked = mne.fiff.read_evoked(ave_fname, setno='Left Auditory') projs = mne.read_proj(ecg_fname) layouts = [mne.find_layout(evoked.info, k) for k in 'meg', 'eeg'] plt.figure(figsize=(12, 6)) mne.viz.plot_projs_topomap(projs, layout=layouts) mne.viz.tight_layout(w_pad=0.5)
connectivity=connectivity, out_type='indices', check_disjoint=True) T_obs, clusters, p_values, _ = cluster_stats good_cluster_inds = np.where(p_values < p_accept)[0] print("Good clusters: %s" % good_cluster_inds) ############################################################################## # Visualize the spatio-temporal clusters times = contrast.times * 1e3 colors = 'r', 'steelblue' linestyles = '-', '--' pos = mne.find_layout(contrast.info).pos T_obs_max = 5. T_obs_min = -T_obs_max # loop over significant clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for T0 stat T_obs_map = T_obs[time_inds, ...].mean(axis=0) # get signals at significant sensors
# In[3]: # ---------- Setup stuff for plotting ------------ # # info needed to get sensors positions # For .ds files info in a case of missing channel should # pick info_file with 271 meg channels, not 272 # | CHANGE THIS | # \/ \/ info_file = '/media/karim/SSD500/aut_gamma/K0001/K0001/K0001ec-epo.fif' # /\ /\ /\ /\ /\ /\ # | | | | | | # ----------------------------------------------------------------------- # info = read_info_custom(info_file) # <-- works both with ctf and electa layout = find_layout(info) # <-- Get sensor positions. fsize = (16, 7) mask_params = dict(marker='*', markerfacecolor='m', markersize=10) # significant sensors appearence # In[56]: # ----------- ONLY FOR ELECTA (.fif) ------------- # # --- Setup indexing for different sensor types --- # # For ctf data this should be changed # grads1 = pick_types(info, meg='planar1') grads2 = pick_types(info, meg='planar2') mags = pick_types(info, meg='mag') grads = pick_types(info, meg='grad')
# average 3 conditions for a better look at the data data_chans = mne.pick_types(epochs.info, meg=True, ref_meg=False) evokeds = [epochs[name].average() for name in conds[:3]] # also do a comparative topoplot colors = ['green', 'red', 'yellow'] title = 'Averaged data before EOG removal' mne.viz.plot_topo(evokeds, color=colors, title=title) # let's create SSP projectors for EOG: proj, eog_events = mne.preprocessing.compute_proj_eog(raw, copy=True, ch_name=eog_chan, reject=None, n_mag=5) layout = mne.find_layout(evokeds[0].info) fig = pl.figure() mne.viz.plot_projs_topomap(proj, layout=layout) comps2use = raw_input('How many components to use? ') # now we apply the recently created projections to our averaged data epochs.add_proj(proj[:int(comps2use)], remove_existing=True) # remove blocks that were crappy based on behavioral analysis # make sure the blocks are in descending order so we don't screw up the deletion delete_blocks.sort() delete_blocks = delete_blocks[::-1] for b in delete_blocks: idx = (b - 1) * 86 + np.arange(86) # 86 trails in each block epochs.drop_epochs(idx)
if operations_to_apply['PlotEoGEpochs_Auto']: # We can use a convenience function eog_epochs = mne.preprocessing.create_eog_epochs(raw.copy().filter(1, None)) eog_epochs.average().plot_joint() #raw.plot(events=eog_epochs.events); if operations_to_apply['PlotECGEpochs_Auto']: ecg_epochs = mne.preprocessing.create_ecg_epochs(raw.copy().filter(1, None)) ecg_epochs.average().plot_joint() if operations_to_apply['ProcessPCA']: layouts = [mne.find_layout(raw.info, ch_type=ch) for ch in ("eeg", "mag", "grad")] projs_eog, _ = mne.preprocessing.compute_proj_eog( raw, n_mag=3, n_grad=3, n_eeg=3, average=True) projs_ecg, _ = mne.preprocessing.compute_proj_ecg( raw, n_mag=3, n_grad=3, n_eeg=3, average=True) if operations_to_apply['PlotPCACompo']: mne.viz.plot_projs_topomap(projs_eog, layout=layouts); mne.viz.plot_projs_topomap(projs_ecg, layout=layouts); if operations_to_apply['ApplyPCA']: reject2 = dict(mag=reject['mag'], grad=reject['grad'])
def plot_topo(self, picks=None, baseline=None, mode='mean', tmin=None, tmax=None, fmin=None, fmax=None, vmin=None, vmax=None, layout=None, cmap='RdBu_r', title=None, dB=False, colorbar=True, layout_scale=0.945, show=True, border='none', fig_facecolor='k', font_color='w'): """Plot TFRs in a topography with images Parameters ---------- picks : array-like of int | None The indices of the channels to plot. If None all available channels are displayed. baseline : None (default) or tuple of length 2 The time interval to apply baseline correction. If None do not apply it. If baseline is (a, b) the interval is between "a (s)" and "b (s)". If a is None the beginning of the data is used and if b is None then b is set to the end of the interval. If baseline is equal ot (None, None) all the time interval is used. mode : None | 'logratio' | 'ratio' | 'zscore' | 'mean' | 'percent' Do baseline correction with ratio (power is divided by mean power during baseline) or zscore (power is divided by standard deviation of power during baseline after subtracting the mean, power = [power - mean(power_baseline)] / std(power_baseline)). If None no baseline correction is applied. tmin : None | float The first time instant to display. If None the first time point available is used. tmax : None | float The last time instant to display. If None the last time point available is used. fmin : None | float The first frequency to display. If None the first frequency available is used. fmax : None | float The last frequency to display. If None the last frequency available is used. vmin : float | None The mininum value an the color scale. If vmin is None, the data minimum value is used. vmax : float | None The maxinum value an the color scale. If vmax is None, the data maximum value is used. layout : Layout | None Layout instance specifying sensor positions. If possible, the correct layout is inferred from the data. cmap : matplotlib colormap | str The colormap to use. Defaults to 'RdBu_r'. title : str Title of the figure. dB : bool If True, 20*log10 is applied to the data to get dB. colorbar : bool If true, colorbar will be added to the plot layout_scale : float Scaling factor for adjusting the relative size of the layout on the canvas. show : bool Call pyplot.show() at the end. border : str matplotlib borders style to be used for each sensor plot. fig_facecolor : str | obj The figure face color. Defaults to black. font_color: str | obj The color of tick labels in the colorbar. Defaults to white. """ from ..viz.topo import _imshow_tfr, _plot_topo times = self.times.copy() freqs = self.freqs data = self.data info = self.info if picks is not None: data = data[picks] info = pick_info(info, picks) data, times, freqs, vmin, vmax = \ _preproc_tfr(data, times, freqs, tmin, tmax, fmin, fmax, mode, baseline, vmin, vmax, dB) if layout is None: from mne import find_layout layout = find_layout(self.info) imshow = partial(_imshow_tfr, tfr=data, freq=freqs, cmap=cmap) fig = _plot_topo(info=info, times=times, show_func=imshow, layout=layout, colorbar=colorbar, vmin=vmin, vmax=vmax, cmap=cmap, layout_scale=layout_scale, title=title, border=border, x_label='Time (ms)', y_label='Frequency (Hz)', fig_facecolor=fig_facecolor, font_color=font_color) if show: import matplotlib.pyplot as plt plt.show() return fig
# plotting raw data to check for any obvious noise raw.plot() # average 3 conditions for a better look at the data data_chans = mne.pick_types(epochs.info,meg=True,ref_meg=False) evokeds = [epochs[name].average() for name in conds[:3]] # also do a comparative topoplot colors = ['green', 'red', 'yellow'] title = 'Averaged data before EOG removal' mne.viz.plot_topo(evokeds, color=colors, title=title) # let's create SSP projectors for EOG: proj, eog_events = mne.preprocessing.compute_proj_eog(raw, copy=True, ch_name=eog_chan,reject=None,n_mag=5) layout = mne.find_layout(evokeds[0].info) fig = pl.figure() mne.viz.plot_projs_topomap(proj, layout=layout) comps2use = raw_input('How many components to use? ') # now we apply the recently created projections to our averaged data epochs.add_proj(proj[:int(comps2use)], remove_existing=True) # remove blocks that were crappy based on behavioral analysis # make sure the blocks are in descending order so we don't screw up the deletion delete_blocks.sort() delete_blocks = delete_blocks[::-1] for b in delete_blocks: idx = (b-1)*86 + np.arange(86) # 86 trails in each block epochs.drop_epochs(idx)
def group_stats(subjects, path, exp, filt, analysis, c_names, seed=42, threshold=1.96, p_accept=0.05, chance=.5, n_perm=10000, reg_type='rerf'): # Load the subject gats group_gat = list() group_td = list() group_reg = list() group_dict = dict() group_dev = list() for subject in subjects: subject_template = op.join(path, subject, 'mne', subject + '_%s%s.%s') fname_gat = subject_template % (exp, '_calm_' + filt + '_filt_' + analysis + '_gat', 'npy') fname_reg = subject_template % (exp, '_calm_' + filt + '_filt_' + analysis + '_%s-ave' % reg_type, 'fif') gat = np.load(fname_gat) group_gat.append(gat) group_td.append(np.diag(gat)) reg = mne.read_evokeds(fname_reg) if isinstance(c_names, list): evokeds = list() for r in reg: if r.comment == c_names[0]: evokeds.insert(0, r) elif r.comment == c_names[1]: evokeds.append(r) assert len(evokeds) == 2 reg = mne.evoked.combine_evoked([evokeds[0], evokeds[1]], weights=[1, -1]) elif isinstance(c_names, str): reg = reg[0] # transpose for the stats func group_reg.append(reg.data.T) n_subjects = len(subjects) connectivity, ch_names = read_ch_connectivity('KIT-208') ################## # Auxiliary info # ################## # define a layout layout = mne.find_layout(reg.info) group_dict['layout'] = layout group_dict['times'] = reg.times group_dict['sfreq'] = reg.info['sfreq'] group_dict['subjects'] = subjects ############################# # run a spatio-temporal REG # ############################# group_reg = np.array(group_reg) group_dict['reg_stats'] = stc_1samp_test(group_reg, n_permutations=n_perm, threshold=threshold, tail=0, connectivity=connectivity, seed=seed, n_jobs=-1) ######################### # run a GAT clustering # ######################### # remove chance from the gats group_gat = np.array(group_gat) - chance _, clusters, p_values, _ = stc_1samp_test(group_gat, n_permutations=n_perm, threshold=threshold, tail=0, seed=seed, out_type='mask', n_jobs=-1) p_values_ = np.ones_like(group_gat[0]).T for cluster, pval in zip(clusters, p_values): p_values_[cluster.T] = pval group_dict['gat_sig'] = p_values_ < p_accept ######################## # run a TD clustering # ######################## # remove chance from the gats group_td = np.array(group_td) - chance group_dict['td_stats'] = pc_1samp_test(group_td, n_permutations=n_perm, threshold=threshold, tail=0, seed=seed, n_jobs=-1) ######################### # run a GAT clustering # ######################### # determining deviation from diag group_diag = np.array([np.diag(gat)[:, np.newaxis] for gat in group_gat]) group_dev = group_gat - group_diag _, clusters, p_values, _ = stc_1samp_test(group_dev, n_permutations=n_perm, threshold=threshold, tail=0, seed=seed, out_type='mask', n_jobs=-1) p_values_ = np.ones_like(group_dev[0]).T for cluster, pval in zip(clusters, p_values): p_values_[cluster.T] = pval group_dict['gat_dev_sig'] = p_values_ < p_accept return group_dict
connectivity=connectivity) T_obs, clusters, p_values, _ = cluster_stats good_cluster_inds = np.where(p_values < p_accept)[0] # configure variables for visualization times = epochs_train.times * 1e3 colors = 'r', 'r', 'steelblue', 'steelblue' linestyles = '-', '--', '-', '--' # grand average as numpy arrray grand_ave = np.array(X).mean(axis=1) # get sensor positions via layout print(epochs_train.info) layout = mne.find_layout(epochs_train.info, 'eeg') print(layout) pos = mne.find_layout(epochs_train.info, 'eeg').pos # loop over significant clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = T_obs[time_inds, ...].mean(axis=0) # get signals at significant sensors signals = grand_ave[..., ch_inds].mean(axis=-1)
# Setup for reading the raw data raw = io.Raw(raw_fname) events = mne.read_events(event_fname) # Set up pick list: EEG + MEG - bad channels (modify to your needs) raw.info["bads"] = ["MEG 2443", "EEG 053"] picks = mne.pick_types(raw.info, meg="grad", eeg=False, stim=True, eog=True, exclude="bads") # Read epochs epochs = mne.Epochs( raw, events, event_id, tmin, tmax, proj=True, picks=picks, baseline=(None, 0), preload=True, reject=dict(grad=4000e-13, eog=150e-6), ) ############################################################################### # Show event related fields images layout = mne.find_layout(epochs.info, "meg") # use full layout title = "ERF images - MNE sample data" mne.viz.plot_topo_image_epochs(epochs, layout, sigma=0.5, vmin=-200, vmax=200, colorbar=True, title=title) plt.show()
def run_sensor_stats(): for c in np.arange(len(config.stats_params)): # organise data and analysis parameters dat0_files = config.stats_params[c]['dat0_files'] dat1_files = config.stats_params[c]['dat1_files'] condnames = config.stats_params[c]['condnames'] tmin, tmax = config.stats_params[c]['statwin'] n_permutations = config.stats_params[c]['n_permutations'] p_threshold = config.stats_params[c]['threshold'] tail = config.stats_params[c]['tail'] if tail == 0: p_threshold = p_threshold / 2 tail_x = 1 else: tail_x = tail if 'multi-subject' in config.stats_params[c] and config.stats_params[c]['multi-subject'] == True: # we will run the same analysis on each subject separately nruns = len(dat0_files) ismulti = True else: nruns = 1 ismulti = False results = [] # to store the results later for statrun in np.arange(nruns): if ismulti: # we will run the same analysis on each subject separately dat0, evokeds0, connectivity = collect_data([dat0_files[statrun]],condnames[0],tmin,tmax,ismulti) dat1, evokeds1, _ = collect_data([dat1_files[statrun]],condnames[1],tmin,tmax,ismulti) else: # collect together the data to be compared dat0, evokeds0, connectivity = collect_data(dat0_files,condnames[0],tmin,tmax,ismulti) dat1, evokeds1, _ = collect_data(dat1_files,condnames[1],tmin,tmax,ismulti) alldata = [] # fix threshold to be one-sided if requested if type(p_threshold) != 'dict': # i.e. is NOT TFCE if config.stats_params[c]['stat'] == 'indep': stat_fun = ttest_ind_no_p if len(dat0_files) == 1: # ie is single subject stats df = dat0.data.shape[0] - 1 + dat1.data.shape[0] - 1 else: df = len(dat0_files) - 1 + len(dat1_files) - 1 else: # ie is dependent data, and so is one-sample t test # this will only ever be group data... # If the length of dat0_files and dat1_files are different it'll crash later anyway stat_fun = ttest_1samp_no_p df = len(dat0_files) - 1 threshold_stat = stats.distributions.t.ppf(1. - p_threshold, df) * tail_x else: # i.e. is TFCE threshold_stat = p_threshold # run the stats if config.stats_params[c]['stat'] == 'indep': alldata = [dat0,dat1] cluster_stats = spatio_temporal_cluster_test(alldata, n_permutations=n_permutations, threshold=threshold_stat, tail=tail, stat_fun=stat_fun, n_jobs=1, buffer_size=None, connectivity=connectivity) elif config.stats_params[c]['stat'] == 'dep': # we have to use 1-sample t-tests here so also need to subtract conditions alldata = dat0 - dat1 cluster_stats = spatio_temporal_cluster_1samp_test(alldata, n_permutations=n_permutations, threshold=threshold_stat, tail=tail, stat_fun=stat_fun, n_jobs=1, buffer_size=None, connectivity=connectivity) # extract stats of interest T_obs, clusters, p_values, _ = cluster_stats good_cluster_inds = np.where(p_values < config.stats_params[c]['p_accept'])[0] # tell the user the results print('There are {} significant clusters'.format(good_cluster_inds.size)) if good_cluster_inds.size != 0: print('p-values: {}'.format(p_values[good_cluster_inds])) else: if p_values.any(): print('Minimum p-value: {}'.format(np.min(p_values))) else: print('No clusters found') # some final averaging and tidying if len(evokeds0) == 1: dat0_avg = evokeds0[0].average() dat1_avg = evokeds1[0].average() else: dat0_avg = mne.grand_average(evokeds0) dat1_avg = mne.grand_average(evokeds1) diffcond_avg = mne.combine_evoked([dat0_avg, -dat1_avg], 'equal') # get sensor positions via layout pos = mne.find_layout(evokeds0[0].info).pos ## EVENTUALLY I WILL PUT THE PLOTTING IN A SEPARATE FUNCTION... do_plot = False if do_plot: # loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = T_obs[time_inds, ...].mean(axis=0) # get topography of difference time_shift = evokeds0[0].time_as_index(tmin) # fix windowing shift print('time_shift = {}'.format(time_shift)) sig_times_idx = time_inds + time_shift diff_topo = np.mean(diffcond_avg.data[:,sig_times_idx],axis=1) sig_times = evokeds0[0].times[sig_times_idx] # create spatial mask mask = np.zeros((f_map.shape[0], 1), dtype=bool) mask[ch_inds, :] = True # initialize figure fig, ax_topo = plt.subplots(1, 1, figsize=(10, 3)) # plot average difference and mark significant sensors image, _ = plot_topomap(diff_topo, pos, mask=mask, axes=ax_topo, cmap='RdBu_r', vmin=np.min, vmax=np.max, show=False) # create additional axes (for ERF and colorbar) divider = make_axes_locatable(ax_topo) # add axes for colorbar ax_colorbar = divider.append_axes('right', size='5%', pad=0.05) plt.colorbar(image, cax=ax_colorbar) ax_topo.set_xlabel( 'Mean difference ({:0.3f} - {:0.3f} s)'.format(*sig_times[[0, -1]])) # add new axis for time courses and plot time courses ax_signals = divider.append_axes('right', size='300%', pad=1.2) title = 'Cluster #{0}, {1} sensor'.format(i_clu + 1, len(ch_inds)) if len(ch_inds) > 1: title += "s (mean)" plot_compare_evokeds([dat0_avg, dat1_avg], title=title, picks=ch_inds, axes=ax_signals, colors=None, show=False, split_legend=False, truncate_yaxis='max_ticks') # plot temporal cluster extent ymin, ymax = ax_signals.get_ylim() ax_signals.fill_betweenx((ymin, ymax), sig_times[0], sig_times[-1], color='orange', alpha=0.3) # clean up viz mne.viz.tight_layout(fig=fig) fig.subplots_adjust(bottom=.05) plt.show() results.append({ 'cluster_stats': cluster_stats, 'good_cluster_inds': good_cluster_inds, 'alldata': alldata, 'evokeds0': evokeds0, 'evokeds1': evokeds1 }) # save save_name = op.join(config.stat_path, config.stats_params[c]['analysis_name'] + '.dat') pickle_out = open(save_name,'wb') pickle.dump(results, pickle_out) pickle_out.close()
"nc_NEM_10", "nc_NEM_11", "nc_NEM_12", "nc_NEM_14", "nc_NEM_15", "nc_NEM_16", "nc_NEM_17", "nc_NEM_18", "nc_NEM_19", "nc_NEM_20", "nc_NEM_21", "nc_NEM_22", "nc_NEM_23", "nc_NEM_24", "nc_NEM_26", "nc_NEM_27", "nc_NEM_28", "nc_NEM_29", "nc_NEM_30", "nc_NEM_31", "nc_NEM_32", "nc_NEM_33", "nc_NEM_34", "nc_NEM_35", "nc_NEM_36", "nc_NEM_37" ] #subjs = ["nc_NEM_10"] A_NmP = [] for subj in subjs: #load resting state measurement of a subjects rest = mne.read_epochs(proc_dir + subj + "_1_ica-epo.fif") # produce a layout that we use for sensor plotting; same for all conditions layout = mne.find_layout(rest.info) mag_names = [rest.ch_names[p] for p in mne.pick_types(rest.info, meg=True)] layout.names = mag_names #load tone baseline (run 2) of a subject tonbas = mne.read_epochs(proc_dir + subj + "_2_ica-epo.fif") #load run 3 and 4 of a subject epo_a = mne.read_epochs(proc_dir + subj + "_3_ica-epo.fif") epo_b = mne.read_epochs(proc_dir + subj + "_4_ica-epo.fif") #interpolate bad n_channels rest.interpolate_bads() tonbas.interpolate_bads() epo_a.interpolate_bads() epo_b.interpolate_bads() #override coil positions of block b with those of block a for concatenation (sensor level only!!) epo_b.info['dev_head_t'] = epo_a.info['dev_head_t'] #concatenate data of both blocks
n_permutations = 50000 T0, p_values, H0 = permutation_t_test(data, n_permutations, n_jobs=2) significant_sensors = picks[p_values <= 0.05] significant_sensors_names = [raw.info['ch_names'][k] for k in significant_sensors] print("Number of significant sensors : %d" % len(significant_sensors)) print("Sensors names : %s" % significant_sensors_names) ############################################################################### # View location of significantly active sensors import matplotlib.pyplot as plt # load sensor layout layout = mne.find_layout(epochs.info) # Extract mask and indices of active sensors in layout idx_of_sensors = [layout.names.index(name) for name in significant_sensors_names if name in layout.names] mask_significant_sensors = np.zeros(len(layout.pos), dtype=np.bool) mask_significant_sensors[idx_of_sensors] = True mask_non_significant_sensors = mask_significant_sensors == False # plot it plt.figure(figsize=(5, 3.5), facecolor='k') plt.axis('off') plt.scatter(layout.pos[mask_significant_sensors, 0], layout.pos[mask_significant_sensors, 1], s=50, c='r') plt.scatter(layout.pos[mask_non_significant_sensors, 0],
def plot_topo(self, picks=None, baseline=None, mode='mean', tmin=None, tmax=None, fmin=None, fmax=None, vmin=None, vmax=None, layout=None, cmap='RdBu_r', title=None, dB=False, colorbar=True, layout_scale=0.945, show=True, border='none', fig_facecolor='k', font_color='w'): """Plot TFRs in a topography with images Parameters ---------- picks : array-like of int | None The indices of the channels to plot. If None all available channels are displayed. baseline : None (default) or tuple of length 2 The time interval to apply baseline correction. If None do not apply it. If baseline is (a, b) the interval is between "a (s)" and "b (s)". If a is None the beginning of the data is used and if b is None then b is set to the end of the interval. If baseline is equal ot (None, None) all the time interval is used. mode : None | 'logratio' | 'ratio' | 'zscore' | 'mean' | 'percent' Do baseline correction with ratio (power is divided by mean power during baseline) or zscore (power is divided by standard deviation of power during baseline after subtracting the mean, power = [power - mean(power_baseline)] / std(power_baseline)). If None no baseline correction is applied. tmin : None | float The first time instant to display. If None the first time point available is used. tmax : None | float The last time instant to display. If None the last time point available is used. fmin : None | float The first frequency to display. If None the first frequency available is used. fmax : None | float The last frequency to display. If None the last frequency available is used. vmin : float | None The mininum value an the color scale. If vmin is None, the data minimum value is used. vmax : float | None The maxinum value an the color scale. If vmax is None, the data maximum value is used. layout : Layout | None Layout instance specifying sensor positions. If possible, the correct layout is inferred from the data. cmap : matplotlib colormap | str The colormap to use. Defaults to 'RdBu_r'. title : str Title of the figure. dB : bool If True, 20*log10 is applied to the data to get dB. colorbar : bool If true, colorbar will be added to the plot layout_scale : float Scaling factor for adjusting the relative size of the layout on the canvas. show : bool Call pyplot.show() at the end. border : str matplotlib borders style to be used for each sensor plot. fig_facecolor : str | obj The figure face color. Defaults to black. font_color: str | obj The color of tick labels in the colorbar. Defaults to white. Returns ------- fig : matplotlib.figure.Figure The figure containing the topography. """ from ..viz.topo import _imshow_tfr, _plot_topo times = self.times.copy() freqs = self.freqs data = self.data info = self.info if picks is not None: data = data[picks] info = pick_info(info, picks) data, times, freqs, vmin, vmax = \ _preproc_tfr(data, times, freqs, tmin, tmax, fmin, fmax, mode, baseline, vmin, vmax, dB) if layout is None: from mne import find_layout layout = find_layout(self.info) imshow = partial(_imshow_tfr, tfr=data, freq=freqs, cmap=cmap) fig = _plot_topo(info=info, times=times, show_func=imshow, layout=layout, colorbar=colorbar, vmin=vmin, vmax=vmax, cmap=cmap, layout_scale=layout_scale, title=title, border=border, x_label='Time (ms)', y_label='Frequency (Hz)', fig_facecolor=fig_facecolor, font_color=font_color) if show: fig.show() return fig
# Use 'MEG 2343' as seed seed_ch = 'MEG 2343' picks_ch_names = [raw.ch_names[i] for i in picks] # Create seed-target indices for connectivity computation seed = picks_ch_names.index(seed_ch) targets = np.arange(len(picks)) indices = seed_target_indices(seed, targets) # Define wavelet frequencies and number of cycles cwt_freqs = np.arange(7, 30, 2) cwt_n_cycles = cwt_freqs / 7. # Run the connectivity analysis using 2 parallel jobs sfreq = raw.info['sfreq'] # the sampling frequency con, freqs, times, _, _ = spectral_connectivity( epochs, indices=indices, method='wpli2_debiased', mode='cwt_morlet', sfreq=sfreq, cwt_freqs=cwt_freqs, cwt_n_cycles=cwt_n_cycles, n_jobs=1) # Mark the seed channel with a value of 1.0, so we can see it in the plot con[np.where(indices[1] == seed)] = 1.0 # Show topography of connectivity from seed title = 'WPLI2 - Visual - Seed %s' % seed_ch layout = mne.find_layout(epochs.info, 'meg') # use full layout tfr = AverageTFR(epochs.info, con, times, freqs, len(epochs)) tfr.plot_topo(fig_facecolor='w', font_color='k', border='k')
# Setup for reading the raw data raw = io.Raw(raw_fname) events = mne.read_events(event_fname) include = [] raw.info['bads'] += ['MEG 2443', 'EEG 053'] # bads + 2 more # picks MEG gradiometers picks = mne.pick_types(raw.info, meg='grad', eeg=False, eog=True, stim=False, include=include, exclude='bads') epochs = mne.Epochs(raw, events, event_id, tmin, tmax, picks=picks, baseline=(None, 0), reject=dict(grad=4000e-13, eog=150e-6)) data = epochs.get_data() # as 3D matrix layout = mne.find_layout(epochs.info, 'meg') ############################################################################### # Calculate power and phase locking value frequencies = np.arange(7, 30, 3) # define frequencies of interest n_cycles = frequencies / float(7) # different number of cycle per frequency Fs = raw.info['sfreq'] # sampling in Hz decim = 3 power, phase_lock = induced_power(data, Fs=Fs, frequencies=frequencies, n_cycles=n_cycles, n_jobs=1, use_fft=False, decim=decim, zero_mean=True) ############################################################################### # Prepare topography plots, set baseline correction parameters
# Define wavelet frequencies and number of cycles cwt_freqs = np.arange(7, 30, 2) cwt_n_cycles = cwt_freqs / 7. # Run the connectivity analysis using 2 parallel jobs sfreq = raw.info['sfreq'] # the sampling frequency con, freqs, times, _, _ = spectral_connectivity(epochs, indices=indices, method='wpli2_debiased', mode='cwt_morlet', sfreq=sfreq, cwt_freqs=cwt_freqs, cwt_n_cycles=cwt_n_cycles, n_jobs=1) # Mark the seed channel with a value of 1.0, so we can see it in the plot con[np.where(indices[1] == seed)] = 1.0 # Show topography of connectivity from seed title = 'WPLI2 - Visual - Seed %s' % seed_ch layout = mne.find_layout(epochs.info, 'meg') # use full layout tfr = AverageTFR(epochs.info, con, times, freqs, len(epochs)) tfr.plot_topo(fig_facecolor='w', font_color='k', border='k') # %% # References # ---------- # .. footbibliography::
good_cluster_inds = np.where(p_values < p_accept)[0] print(good_cluster_inds) print(p_values.min()) print([np.unique(clusters[i][0]) for i in good_cluster_inds]) #%% Plot clusters sns.set(style="whitegrid", font_scale=1.5, palette="Set2") labels_plot = ['Valid Cue', 'Neutral Cue'] evs = copy.copy([C_E, N_E]) for elist in evs: for ev in elist: ev.crop(crop_time[0], crop_time[1]) colors = {labels_plot[0]: "crimson", labels_plot[1]: 'steelblue'} linestyles = {"L": '-', "R": '--'} # get sensor positions via layout pos = mne.find_layout(evs[0][0].info).pos picks, pos2, merge_channels, names, ch_type, sphere, clip_origin = \ mne.viz.topomap._prepare_topomap_plot(evs[0][0].info, sen) reg_masks = [] plot_t_offset = 2 # loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat
mask = np.zeros_like(T_obs, dtype=bool) for n, (c, p_val) in enumerate(zip(clusters, cluster_p_values)): if p_val <= 0.05: mask[c] = True good_cluster_inds.append(n) grand_average.plot_image(mask=mask.T, time_unit='s') # PLOT RESPONSES AT SENSORS CONTRIBUTING TO EACH CLUSTER (if there are any clusters...) # This is all taken from this example https://mne-tools.github.io/dev/auto_tutorials/plot_stats_spatio_temporal_cluster_sensors.html from mne.viz import plot_topomap from mpl_toolkits.axes_grid1 import make_axes_locatable from mne.viz import plot_compare_evokeds pos = mne.find_layout(grand_average.info).pos[idx, :] # loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = T_obs[time_inds, ...].mean(axis=0) # get signals at the sensors contributing to the cluster sig_times = grand_average.times[time_inds] # create spatial mask
# mask=sig_mask, xlim=(0., None), unit=False, # keep values scale scalings=dict(eeg=1), cmap='viridis', clim=dict(eeg=[0, None])) fig.axes[1].set_title('F-value') fig.axes[0].set_title('Group-level effect of phase-coherence') fig.set_size_inches(6.5, 4) ############################################################################### # visualize clusters # get sensor positions via layout pos = find_layout(epochs_info).pos # loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = f_vals[time_inds, :].mean(axis=0) # get signals at the sensors contributing to the cluster sig_times = times[time_inds] # create spatial mask
raw.plot_projs_topomap() ############################################################################### # Displaying the projections from a raw object requires no extra information # since all the layout information is present in `raw.info`. # MNE is able to automatically determine the layout for some magnetometer and # gradiometer configurations but not the layout of EEG electrodes. # # Here we display the `ecg_projs` individually and we provide extra parameters # for EEG. (Notice that planar projection refers to the gradiometers and axial # refers to magnetometers.) # # Notice that the conditional is just for illustration purposes. We could # `raw.info` in all cases to avoid the guesswork in `plot_topomap` and ensure # that the right layout is always found fig, axes = plt.subplots(1, len(ecg_projs)) for proj, ax in zip(ecg_projs, axes): if proj['desc'].startswith('ECG-eeg'): proj.plot_topomap(axes=ax, info=raw.info) else: proj.plot_topomap(axes=ax) ############################################################################### # The correct layout or a list of layouts from where to choose can also be # provided. Just for illustration purposes, here we generate the # `possible_layouts` from the raw object itself, but it can come from somewhere # else. possible_layouts = [mne.find_layout(raw.info, ch_type=ch_type) for ch_type in ('grad', 'mag', 'eeg')] mne.viz.plot_projs_topomap(ecg_projs, layout=possible_layouts)
good_cluster_inds = np.where(p_values < p_accept)[0] ############################################################################### # Note. The same functions work with source estimate. The only differences # are the origin of the data, the size, and the connectivity definition. # It can be used for single trials or for groups of subjects. # # Visualize clusters # ------------------ # configure variables for visualization colors = {"Aud": "crimson", "Vis": 'steelblue'} linestyles = {"L": '-', "R": '--'} # get sensor positions via layout pos = mne.find_layout(epochs.info).pos # organize data for plotting evokeds = {cond: epochs[cond].average() for cond in event_id} # loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = T_obs[time_inds, ...].mean(axis=0) # get signals at the sensors contributing to the cluster
# are the origin of the data, the size, and the connectivity definition. # It can be used for single trials or for groups of subjects. # # Visualize clusters # ------------------ # configure variables for visualization times = epochs.times * 1e3 colors = "r", "r", "steelblue", "steelblue" linestyles = "-", "--", "-", "--" # grand average as numpy arrray grand_ave = np.array(X).mean(axis=1) # get sensor positions via layout pos = mne.find_layout(epochs.info).pos # loop over significant clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = T_obs[time_inds, ...].mean(axis=0) # get signals at significant sensors signals = grand_ave[..., ch_inds].mean(axis=-1) sig_times = times[time_inds]
"nc_NEM_32", "nc_NEM_33", "nc_NEM_34", "nc_NEM_35", "nc_NEM_36", "nc_NEM_37" ] #subjs = ["nc_NEM_10"] NEM_data = np.zeros((2, 78, 248, 8)) for subj in subjs: #load tone baseline (run 2) of a subject #tonbas = mne.read_epochs(proc_dir+subj+"_2_ica-epo.fif") #load run 3 and 4 of a subject epo_a = mne.read_epochs(proc_dir + subj + "_3_ica-epo.fif") epo_b = mne.read_epochs(proc_dir + subj + "_4_ica-epo.fif") # produce a layout that we use for sensor plotting; same for all conditions layout = mne.find_layout(epo_a.info) mag_names = [ epo_a.ch_names[p] for p in mne.pick_types(epo_a.info, meg=True) ] layout.names = mag_names #interpolate bad n_channels #tonbas.interpolate_bads() epo_a.interpolate_bads() epo_b.interpolate_bads() #override coil positions of block b with those of block a for concatenation (sensor level only!!) epo_b.info['dev_head_t'] = epo_a.info['dev_head_t'] #concatenate data of both blocks epo = mne.concatenate_epochs([epo_a, epo_b]) # equalize event counts of experiment -- if wanted !! -- choose one or none of the following two options # epo.equalize_event_counts(event_ids=['positive','negative']) # epo.equalize_event_counts(event_ids=['positive/r1','positive/r2','positive/s1','positive/s2','negative/r1','negative/r2','negative/s1','negative/s2'])
y = x[:, mags, :].transpose((1, 0, 2)) plv, f = spectral.mtplv(y, params, verbose='DEBUG') pl.plot(f, plv.T, linewidth=2) pl.xlabel('Frequency (Hz)', fontsize=16) pl.ylabel('Intertrial PLV', fontsize=16) pl.title('MEG Magnetometers', fontsize=16) if SSSR: pl.xlim([70, 140]) else: pl.xlim([15, 90]) pl.show() figname_mag = subj + '_' + condstem + ssstag + '_mag-results.pdf' matname_mag = subj + '_' + condstem + ssstag + '_mag_results.mat' io.savemat(fpath + matname_mag, dict(f=f, plv=plv, chans=mags)) pl.savefig(fpath + figname_mag) lout = mne.find_layout(epochs.info) pos = lout.pos[mags] if SSSR: f_AM = 107.0 else: if ASSR25: f_AM = 25.0 else: f_AM = 43.0 ind_AM = np.argmin(np.abs(f - f_AM)) pl.figure() mne.viz.plot_topomap(plv[:, ind_AM], pos, sensors='ok', vmin=-0.07, vmax=0.07)
def erp_analysis(subjects): from mne.stats import spatio_temporal_cluster_test from mne.channels import read_ch_connectivity from mpl_toolkits.axes_grid1 import make_axes_locatable from scipy import stats as stats all_evo = {'off_sup_lon': list(), 'off_sup_sho': list()} all_log = list() condition_names = ['S2 Longer', 'S2 Shorter'] n_subjects = len(subjects) # Load for subj in subjects: epochs, log = load_subj(subj) epochs = epochs[['off_sup_lon', 'off_sup_sho']] log = log.loc[(log.Condition == 2.0) & (log.Ratio != 1.0)] corr_log = list() for k in all_evo.keys(): c = marks_off[k] sub_log = log[log.condition == c] sub_log['epo_ix'] = np.arange(len(sub_log)) # corr_ix = sub_log['epo_ix'].loc[(sub_log.condition == c) & (sub_log.Accuracy == 1.0)].values # sub_log = sub_log.loc[(sub_log.condition == c) & (sub_log.Accuracy == 1.0)] corr_ix = sub_log['epo_ix'] all_evo[k].append(epochs[k][corr_ix].average()) corr_log.append(sub_log) print(k, c, len(corr_ix)) all_log.append(pd.concat(corr_log)) all_log = pd.concat(all_log) all_log.groupby('condition')[['condition' ]].agg(np.count_nonzero).plot(kind='bar') # Plot evoked = { k: mne.combine_evoked(all_evo[k], weights='nave') for k in all_evo.keys() } mne.viz.plot_evoked_topo([evoked[ev] for ev in evoked.keys()]) # Stats connectivity, ch_names = read_ch_connectivity( '/Users/lpen/Documents/MATLAB/Toolbox/fieldtrip-20170628/template/neighbours/biosemi128_neighb.mat' ) #threshold = {'start': 5, 'step': 0.5} threshold = None p_threshold = 0.001 t_threshold = -stats.distributions.t.ppf(p_threshold / 2., n_subjects - 1) x = { k: np.array([all_evo[k][ix_s].data for ix_s in range(len(subjects))]) for k in sorted(all_evo.keys()) } x = [np.transpose(x[k], (0, 2, 1)) for k in sorted(x.keys())] t_obs, clusters, p_values, _ = spatio_temporal_cluster_test( x, n_permutations=1000, threshold=t_threshold, tail=0, n_jobs=2, connectivity=connectivity, ) p_val = 0.01 good_cluster_inds = np.where(p_values < p_val)[0] print(good_cluster_inds) print(len(good_cluster_inds)) # configure variables for visualization times = evoked['off_sup_lon'].times * 1e3 colors = 'r', 'b', linestyles = '-', '-', # grand average as numpy arrray grand_ave = np.array(x).mean(axis=1) # get sensor positions via layout pos = mne.find_layout(evoked['off_sup_lon'].info).pos # loop over significant clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster infomation, get unique indices time_inds, space_inds = np.squeeze(clusters[clu_idx]) ch_inds = np.unique(space_inds) time_inds = np.unique(time_inds) # get topography for F stat f_map = t_obs[time_inds, ...].mean(axis=0) # get signals at significant sensors signals = grand_ave[..., ch_inds].mean(axis=-1) sig_times = times[time_inds] # create spatial mask mask = np.zeros((f_map.shape[0], 1), dtype=bool) mask[ch_inds, :] = True # initialize figure fig, ax_topo = plt.subplots(1, 1, figsize=(10, 3)) title = 'Cluster #{0}'.format(i_clu + 1) fig.suptitle(title, fontsize=14) # plot average test statistic and mark significant sensors image, _ = mne.viz.plot_topomap(f_map, pos, mask=mask, axes=ax_topo, cmap='magma', vmin=np.min, vmax=np.max) # advanced matplotlib for showing image with figure and colorbar # in one plot divider = make_axes_locatable(ax_topo) # add axes for colorbar ax_colorbar = divider.append_axes('right', size='5%', pad=0.05) plt.colorbar(image, cax=ax_colorbar) ax_topo.set_xlabel('Averaged F-map ({:0.1f} - {:0.1f} ms)'.format( *sig_times[[0, -1]])) # add new axis for time courses and plot time courses ax_signals = divider.append_axes('right', size='300%', pad=1.5) for signal, name, col, ls in zip(signals, condition_names, colors, linestyles): ax_signals.plot(times, signal, color=col, linestyle=ls, label=name) # add information ax_signals.axvline(0, color='k', linestyle=':', label='stimulus onset') ax_signals.set_xlim([times[0], times[-1]]) ax_signals.set_ylim([-10e-7, 20e-7]) ax_signals.set_xlabel('time [ms]') ax_signals.set_ylabel('Amplitude') ax_signals.hlines(0, xmin=times[0], xmax=times[-1], linestyles='--') # plot significant time range ymin, ymax = ax_signals.get_ylim() ax_signals.fill_betweenx((ymin, ymax), sig_times[0], sig_times[-1], color='orange', alpha=0.3) ax_signals.legend(loc='lower right') ax_signals.set_ylim(ymin, ymax) # clean up viz mne.viz.tight_layout(fig=fig) fig.subplots_adjust(bottom=.05) plt.show() fig.savefig(op.join(study_path, 'figures', 'ERP_off_ckust_{}.eps'.format(i_clu)), format='eps', dpi=300) # Cluster Amplitude # t_mask = np.arange(len(times))[(times > 300) & (times < 400)] # sig_amp = {k: np.array([x[ix_c][ix_s, t_mask, :][:, ch_inds].mean() for ix_s, s in enumerate(subjects)]) for ix_c, k in enumerate(['lon', 'sho'])} sig_amp = { k: np.array([ x[ix_c][ix_s, time_inds, :][:, ch_inds].mean() for ix_s, s in enumerate(subjects) ]) for ix_c, k in enumerate(['lon', 'sho']) } subj_cond = all_log.groupby('subject')[['RT', 'Accuracy']].agg(np.mean) subj_cond['acc_lon'] = all_log[all_log.condition == 90].groupby( 'subject')[['Accuracy']].agg(np.mean) subj_cond['acc_sho'] = all_log[all_log.condition == 70].groupby( 'subject')[['Accuracy']].agg(np.mean) subj_cond['amp_lon'] = sig_amp['lon'] subj_cond['amp_sho'] = sig_amp['sho'] subj_cond['amp_dif'] = subj_cond['amp_sho'] - subj_cond['amp_lon'] subj_cond.corr(method='pearson') from seaborn import regplot from eeg_etg_fxs import permutation_pearson r_sho, p_sho = permutation_pearson(subj_cond['amp_dif'].values, subj_cond['acc_sho'].values, 10000) r_lon, p_lon = permutation_pearson(subj_cond['amp_dif'].values, subj_cond['acc_lon'].values, 10000) plt.style.use('ggplot') fig, axes = plt.subplots(1, 2, sharey=True, sharex=True) for ix, (r, p, c) in enumerate( zip([r_lon, r_sho], [p_lon, p_sho], ['acc_lon', 'acc_sho'])): regplot(subj_cond['amp_dif'], subj_cond[c], ci=None, ax=axes[ix]) axes[ix].set_title('r = %0.3f p = %0.3f' % (r, p)) fig.savefig(op.join(study_path, 'figures', 'ERP_diff_acc.eps'), format='eps', dpi=300) mne.viz.plot_compare_evokeds([evoked[ev] for ev in evoked.keys()], picks=2) plt.savefig(op.join(study_path, 'figures', 'ERP_diff_A4.eps'), format='eps', dpi=300)