inverse_operator = mne.minimum_norm.make_inverse_operator( raws[kind].info, forward=fwd[kind], noise_cov=noise_cov, verbose=True) stc_psd, sensor_psd = mne.minimum_norm.compute_source_psd( raws[kind], inverse_operator, lambda2=lambda2, n_fft=n_fft, dB=False, return_sensor=True, verbose=True) topo_norm = sensor_psd.data.sum(axis=1, keepdims=True) stc_norm = stc_psd.sum() # same operation on MNE object, sum across freqs # Normalize each source point by the total power across freqs for band, limits in freq_bands.items(): data = sensor_psd.copy().crop(*limits).data.sum(axis=1, keepdims=True) topos[kind][band] = mne.EvokedArray(100 * data / topo_norm, sensor_psd.info) stcs[kind][band] = \ 100 * stc_psd.copy().crop(*limits).sum() / stc_norm.data del inverse_operator del fwd, raws, raw_erms ############################################################################### # Now we can make some plots of each frequency band. Note that the OPM head # coverage is only over right motor cortex, so only localization # of beta is likely to be worthwhile. # # Theta # ----- def plot_band(kind, band):
# Let's do some dipole fits. We first compute the noise covariance, # then do the fits for each event_id taking the time instant that maximizes # the global field power. # here we can get away with using method='oas' for speed (faster than "shrunk") # but in general "shrunk" is usually better cov = mne.compute_covariance(epochs, tmax=bmax) mne.viz.plot_evoked_white(epochs['1'].average(), cov) data = [] t_peak = 0.036 # true for Elekta phantom for ii in event_id: # Avoid the first and last trials -- can contain dipole-switching artifacts evoked = epochs[str(ii)][1:-1].average().crop(t_peak, t_peak) data.append(evoked.data[:, 0]) evoked = mne.EvokedArray(np.array(data).T, evoked.info, tmin=0.) del epochs dip, residual = fit_dipole(evoked, cov, sphere, n_jobs=1) ############################################################################### # Do a quick visualization of how much variance we explained, putting the # data and residuals on the same scale (here the "time points" are the # 32 dipole peak values that we fit): fig, axes = plt.subplots(2, 1) evoked.plot(axes=axes) for ax in axes: ax.texts = [] for line in ax.lines: line.set_color('#98df81') residual.plot(axes=axes)
raw.plot() ############################################################################### # We can visualize this raw data on the ``fsaverage`` brain (in MNI space) as # a heatmap. This works by first creating an ``Evoked`` data structure # from the data of interest (in this example, it is just the raw LFP). # Then one should generate a ``stc`` data structure, which will be able # to visualize source activity on the brain in various different formats. # get standard fsaverage volume (5mm grid) source space fname_src = op.join(subjects_dir, 'fsaverage', 'bem', 'fsaverage-vol-5-src.fif') vol_src = mne.read_source_spaces(fname_src) evoked = mne.EvokedArray(raw.get_data(), raw.info).crop(0, 1) # shorter stc = mne.stc_near_sensors( evoked, trans, subject, subjects_dir=subjects_dir, src=vol_src, verbose='error') # ignore missing electrode warnings stc = abs(stc) # just look at magnitude clim = dict(kind='value', lims=np.percentile(abs(evoked.data), [10, 50, 75])) ############################################################################### # Plot 3D source (brain region) visualization: # # By default, `stc.plot_3d() <mne.VolSourceEstimate.plot_3d>` will show a time # course of the source with the largest absolute value across any time point.
# %% # Create fake data # ---------------- # # First we will create a simple evoked object with a single timepoint using # biosemi 10-20 channel layout. biosemi_montage = mne.channels.make_standard_montage('biosemi64') n_channels = len(biosemi_montage.ch_names) fake_info = mne.create_info(ch_names=biosemi_montage.ch_names, sfreq=250., ch_types='eeg') rng = np.random.RandomState(0) data = rng.normal(size=(n_channels, 1)) * 1e-6 fake_evoked = mne.EvokedArray(data, fake_info) fake_evoked.set_montage(biosemi_montage) # %% # Calculate sphere origin and radius # ---------------------------------- # # EEGLAB plots head outline at the level where the head circumference is # measured # in the 10-20 system (a line going through Fpz, T8/T4, Oz and T7/T3 channels). # MNE-Python places the head outline lower on the z dimension, at the level of # the anatomical landmarks :term:`LPA, RPA, and NAS <fiducial>`. # Therefore to use the EEGLAB layout we # have to move the origin of the reference sphere (a sphere that is used as a # reference when projecting channel locations to a 2d plane) a few centimeters # up.
del (glmdata) #clear from RAM as not used from now on really #contrasts = np.stack([np.arange(len(contrasts)), glmdes.contrast_names], axis=1) for iname in range(len(glmdes.contrast_names)): name = glmdes.contrast_names[iname].replace( ' ', '') #remove whitespace in the contrast name if iname in [0, 2, 4]: nave = underconf_nave elif iname in [1, 3, 5]: nave = overconf_nave else: nave = total_nave tl_betas = mne.EvokedArray(info=info, nave=nave, tmin=tmin, data=np.squeeze( model.copes[iname, :, :])) # deepcopy(tl_betas).drop_channels(['RM']).plot_joint(picks = 'eeg', topomap_args = dict(outlines = 'head', contours = 0)) tl_betas.save(fname=op.join( param['path'], 'glms', 'feedback', glm_folder, 'wmConfidence_' + param['subid'] + '_feedbacklocked_tl_' + lapstr + name + '_betas-ave.fif')) del (tl_betas) tl_tstats = mne.EvokedArray(info=info, nave=nave, tmin=tmin, data=np.squeeze( model.get_tstats()[iname, :, :])) tl_tstats.save(fname=op.join(
# 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 = epochs.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)) # plot average test statistic and mark significant sensors f_evoked = mne.EvokedArray(f_map[:, np.newaxis], epochs.info, tmin=0) f_evoked.plot_topomap(times=0, mask=mask, axes=ax_topo, cmap='Reds', vmin=np.min, vmax=np.max, show=False, colorbar=False, mask_params=dict(markersize=10)) image = ax_topo.images[0] # 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( 'Averaged F-map ({:0.3f} - {:0.3f} s)'.format(*sig_times[[0, -1]])) # add new axis for time courses and plot time courses
evokeds = mne.read_evokeds(fname, baseline=(None, 0), proj=True) print(evokeds) # Reader function returned a list of evoked instances evoked = mne.read_evokeds(fname, condition='Left Auditory') evoked.apply_baseline((None, 0)).apply_proj() print(evoked) print(evoked.info) print(evoked.times) # The evoked data structure also contains some new attributes easily accessible: print(evoked.name) # Number of averaged epochs. print(evoked.first) # First time sample. print(evoked.last) # Last time sample. print(evoked.comment) # Comment on dataset. Usually the condition. print(evoked.kind) # Type of data, either average or standard_error. # Access data data = evoked.data print(data.shape) print('Data from channel {0}:'.format(evoked.ch_names[10])) print(data[10]) # Import evoked data from some other system evoked = mne.EvokedArray(data, evoked.info, tmin=evoked.times[0]) evoked.plot(time_unit='s') # Save evoked dataset to a file # mne.Evoked.save() or save multiple categories mne.write_evokeds()
####################PCA & ICA###################### from mne.decoding import UnsupervisedSpatialFilter from sklearn.decomposition import PCA, FastICA import matplotlib.pyplot as plt X = epochs.get_data() #the number of channels == 30 print("==============PCA==================") pca = UnsupervisedSpatialFilter(PCA(30), average=False) pca_data = pca.fit_transform(X) ev = mne.EvokedArray(np.mean(pca_data, axis=0), mne.create_info(30, epochs.info['sfreq'], ch_types='eeg'), tmin=tmin) ev.plot(show=False, window_title="PCA") print("==============ICA==================") ica = UnsupervisedSpatialFilter(FastICA(30), average=False) ica_data = ica.fit_transform(X) ev1 = mne.EvokedArray(np.mean(ica_data, axis=0), mne.create_info(30, epochs.info['sfreq'], ch_types='eeg'), tmin=tmin) ev1.plot(show=False, window_title='ICA') plt.show()
epochs = mne.EpochsArray(epochs_data, info=info, events=events, event_id={'arbitrary': 1}) picks = mne.pick_types(info, meg=True, eeg=False, misc=False) epochs.plot(picks=picks, scalings='auto', show=True, block=True) ############################################################################### # EvokedArray nave = len(epochs_data) # Number of averaged epochs evoked_data = np.mean(epochs_data, axis=0) evokeds = mne.EvokedArray(evoked_data, info=info, tmin=-0.2, comment='Arbitrary', nave=nave) evokeds.plot(picks=picks, show=True, units={'mag': '-'}, titles={'mag': 'sin and cos averaged'}) ############################################################################### # Create epochs by windowing the raw data. # The events are spaced evenly every 1 second. duration = 1. # create a fixed size events array # start=0 and stop=None by default events = mne.make_fixed_length_events(raw, event_id, duration=duration) print(events) # for fixed size events no start time before and after event
# Make animation fig,anim = evokeds[0].animate_topomap(times=np.linspace(0.00, 0.79, 100),butterfly=True) # Save animation fig,anim = evokeds[0].animate_topomap(times=np.linspace(0.00, 0.79, 50),frame_rate=10,blit=False) anim.save('Brainmation.gif', writer='imagemagick', fps=10) # Sort epochs based on categories sorted_epochsarray = [allSubs_MNE[0][0][name] for name in ('scene','face')] # Plot image stable_blocksSSP_plot.plot_image() # Appending all entries in the overall epochsarray as single evoked arrays of shape (n_channels, n_times) g2 = allSubs_MNE[0][0].get_data() evoked_array = [mne.EvokedArray(entry, info_fs100,tmin=-0.1) for entry in g2] # Appending all entries in the overall epochsarray as single evoked arrays of shape (n_channels, n_times) - category info added as comments events_list = y_stable_blocks # LOAD THIS FROM SOMEWHERE!!!!! event_id = dict(scene=0, face=1) n_epochs = len(events_list) events_list = [int(i) for i in events_list] evoked_array2 = [] for idx,cat in enumerate(events_list): evoked_array2.append(mne.EvokedArray(g2[idx], info_fs100,tmin=-0.1,comment=cat)) mne.viz.plot_compare_evokeds(evoked_array2[:10],picks=[7]) # Plotting all the individual evoked arrays (up to 10) # Testing the best way to plot individual evoked arrays evoked_array2[0].plot(picks=[7])
def main(): #splitter = "\\" if platform.system().lower().startswith("win") else "/" parser = argparse.ArgumentParser() parser.add_argument("--subject", action="store", type=str, required=False, help="Name of the Patient/ Subject to process") parser.add_argument("--bidsroot", action="store", type=str, required=False, help="Specify a different BIDS root directory to use") parser.add_argument("--inputfolder", action="store", type=str, required=False, help="Specify a different data input folder") parser.add_argument( "--fsonly", action="store", type=str, required=False, help="Use --fsonly true if you only want to do a freesurfer segmentation" ) # do only freesurfer segmentation parser.add_argument("--openmp", action="store", type=str, required=False, help="Specify how many jobs/ processor cores to use") parser.add_argument("--srcspacing", action="store", type=str, required=False, help="Source spacing: \ -defaults to ico4 --> 2562 Source points \ || other options: \ oct5 --> 1026 Source points \ || oct6 --> 4098 Source points \ || ico5 --> 10242 Source points") parser.add_argument("--extras", action="store", type=str, required=False, help="Specify directory containing extras for report") args = parser.parse_args() # additional arguments if args.bidsroot: bids_root = args.bidsroot else: bids_root = os.environ.get("BIDS_ROOT") if args.openmp: n_jobs = openmp = int(args.openmp) else: n_jobs = openmp = int(os.environ.get("OPENMP")) if n_jobs == None: n_jobs = openmp = int(1) if args.inputfolder: input_folder = args.inputfolder else: input_folder = os.environ.get("INPUT_FOLDER") if args.extras: extras_directory = args.extras else: extras_directory = os.environ.get("EXTRAS_DIRECTORY") # define subject subject = args.subject if not subject: poss = [s for s in os.listdir(input_folder)] print( f"No subject specified, maybe you want to choose from those:\n {poss}" ) subject = input() if not subject.startswith("sub-"): ject = str(subject) subject = "sub-" + subject else: ject = subject.split("sub-")[-1] # create folder structure and copy dfc = Folderer.DerivativesFoldersCreator(BIDS_root=bids_root, extras_directory=extras_directory, subject=subject) dfc.make_derivatives_folders() # logging logfile = opj(dfc.freport, "SourceLocPipeline.log") logging.basicConfig(filename=logfile, filemode="w", format="\n%(levelname)s --> %(message)s") rootlog = logging.getLogger() rootlog.setLevel(logging.INFO) rootlog.info("Now running SourceLoc pipeline...") # log parameters rootlog.info(f"*" * 20) rootlog.info("Parameters") rootlog.info(f"*" * 20) rootlog.info(f"Subject name = {ject}") rootlog.info(f"Input folder is set to: {input_folder}.") rootlog.info(f"BIDS root is set to: {bids_root}.") rootlog.info(f"Extras directory is set to: {extras_directory}.") rootlog.info(f"Using {openmp} processor cores/ jobs.") rootlog.info("Folder structure has been created.") # check if freesurfer subjects_dir exists FS_SUBJECTS_DIR = str(os.environ.get("SUBJECTS_DIR")) if FS_SUBJECTS_DIR == None: print(f"It seems freesurfer is not properly set up on your computer") rootlog.warning( "No working freesurfer environment found - SUBJECTS_DIR is not set" ) # check if source spacing was set + is valid if not args.srcspacing: spacing = str(os.environ.get("SRCSPACING")) if not spacing: spacing = "oct6" else: spacing = args.srcspacing if spacing not in ["ico4", "oct5", "oct6", "ico5"]: spacing = "oct6" print('The desired spacing isn\'t allowed, typo?\n \ Options are: "ico4", "oct5", "oct6", "ico5"\n \ --> spacing was automatically set to "oct6".') rootlog.warning( "Spacing was set to \"oct6\", as input given was invalid.") rootlog.info(f"Final source spacing is {spacing}.") # MRI to nii.gz, then freesurfer, then hippocampal subfields # Naturally, this only works with a freesurfer environment # and this will take some time... anafolder = opj(input_folder, ject) if os.path.isdir(anafolder): rootlog.setLevel(logging.ERROR) rap = Anatomist.RawAnatomyProcessor(anafolder, FS_SUBJECTS_DIR, n_jobs=n_jobs) try: rap.run_anatomy_pipeline() except Exception as e: rootlog.error( f"Something went wrong while processing anatomy: {e}") rootlog.setLevel(logging.INFO) # Check if only freesurfer segmentation was desired and comply, if true if args.fsonly and args.fsonly.lower() == "true": rootlog.info( "Only freesurfer segmentation was desired - finished without errors." ) exit() # copy freesurfer files to local subjects_dir try: segmentation = opj(FS_SUBJECTS_DIR, subject) target = opj(dfc.fanat, subject) if not os.path.isdir(target): os.mkdir(target) rootlog.info( f"Copying freesurfer segmentation {segmentation} to {target}") dfc._recursive_overwrite(segmentation, target) except Exception as e: rootlog.error(f"Couldn't copy freesurfer segmentation\n--> {e}.") # create source models sourcerer = Anatomist.SourceModeler(subjects_dir=dfc.fanat, subject=subject, spacing=spacing, n_jobs=n_jobs) sourcerer.calculate_source_models() # process raw fifs raws = glob.glob(input_folder + "/*.fif") raws = [f for f in raws if ject in f] epo_filename = opj(dfc.spikes, str(subject) + "-epo.fif") concatname = opj(os.path.dirname(raws[0]), str(subject) + "_concat.fif") def raw_processing_already_done(): r = os.path.isfile(concatname) c = os.path.isfile(epo_filename) return r and c if not raw_processing_already_done(): # parse list of appropriate raws rootlog.info( f"The following raw files were found for preprocessing:\n{raws}") prepper = u.RawPreprocessor() for run, rawfile in enumerate(raws): if "tsss" in rawfile and ject in rawfile and not "-epo" in rawfile: # --> search for matching eventfile and combine rawname = rawfile.strip(".fif") + "_prep.fif" if not "_prep" in rawfile: # epochs epochs = prepper.raw_to_epoch(rawfile) if epochs is not None: epochs = epochs.load_data().filter( l_freq=l_freq, fir_design=fir_design, h_freq=h_freq, n_jobs=n_jobs) epo_filename = rawfile.strip(".fif") + "-epo.fif" epochs.save(epo_filename, overwrite=True) # preprocessing raw = mne.io.read_raw(rawfile, preload=False, on_split_missing="ignore") raw = prepper.filter_raw(raw, l_freq=l_freq, fir_design=fir_design, h_freq=h_freq, n_jobs=n_jobs) raw = prepper.resample_raw(raw, s_freq=s_freq, n_jobs=n_jobs) # # Artifacts # ECG artifacts # It's smarter to supervise this step (--> look at the topomaps!) raw.load_data() try: ecg_projs, _ = mne.preprocessing.compute_proj_ecg( raw, n_grad=n_grad, n_mag=n_mag, n_eeg=n_eeg, reject=None) raw.add_proj(ecg_projs, remove_existing=False) fig = mne.viz.plot_projs_topomap(ecg_projs, info=raw.info, show=False) savename = os.path.join(dfc.fprep, "ECG_projs_Topomap.png") fig.savefig(savename) except Exception as e: rootlog.error( f"ECG - Atrifact correction failed --> {e}") #EOG artifacts # It's a bad idea to do this in an automated step try: eog_evoked = mne.preprocessing.create_eog_epochs( raw).average() #eog_evoked.apply_baseline((None, None)) eog_projs, _ = mne.preprocessing.compute_proj_eog( raw, n_grad=n_grad, n_mag=n_mag, n_eeg=n_eeg, n_jobs=n_jobs, reject=None) raw.add_proj( eog_projs, remove_existing=False ) # --> don't do this in the early stages - see documentation figs = eog_evoked.plot_joint(show=False) for idx, fig in enumerate(figs): savename = os.path.join( dfc.fprep, "EOG Topomap_" + str(idx) + ".png") fig.savefig(savename) except Exception as e: rootlog.error( f"EOG - Atrifact correction failed --> {e}") # save raw, store projs all_projs = raw.info["projs"] raw.save(rawname, overwrite=True) del (raw) # concatenate epochs epo_filename = opj(dfc.spikes, str(subject) + "-epo.fif") if not os.path.isfile(epo_filename): epoch_files = glob.glob(input_folder + "/*-epo.fif") epoch_files = [f for f in epoch_files if ject in f] all_epochs = dict() rootlog.info("Concatenating epochs now...") for f in epoch_files: all_epochs[f] = mne.read_epochs(f) concat_epochs = mne.concatenate_epochs( [all_epochs[f] for f in epoch_files]) concat_epochs.add_proj(all_projs, remove_existing=True) concat_epochs.apply_proj() rootlog.info(f"Saving concatenated epoch file as {epo_filename}") concat_epochs.save(epo_filename) # concatenate filtered and resampled files raws = glob.glob(input_folder + "/*.fif") raws = [f for f in raws if ject in f] raws = [f for f in raws if "_prep" in f] all_raws = dict() concatname = opj(os.path.dirname(raws[0]), str(subject) + "_concat.fif") if not os.path.isfile(concatname): for r in raws: all_raws[r] = mne.io.read_raw(r, preload=False) all_raws[r].del_proj() rootlog.info( f"Concatenating the following (filtered and resampled) raw files: {raws}" ) try: raw = mne.concatenate_raws( [all_raws[r] for r in all_raws.keys()]) rootlog.info( "Rawfiles have successfully been concatenated....") except Exception as e: rootlog.error( f"Failed trying to concatenate raw file\n {r} --> {e}") #print("Loading only first raw file!") #raw = mne.io.read_raw(raws[0]) rootlog.info("Applying SSP projectors on concatenated file...") raw.add_proj(all_projs, remove_existing=True) raw.apply_proj() rootlog.info(f"Saving concatenated rawfile as {concatname}") raw.save(concatname) # Save in BIDS format derivatives_root = opj(bids_root, "derivatives") # meg bids_path = BIDSPath(subject=ject, session="resting", task="resting", root=derivatives_root, processing="concat") raw = mne.io.read_raw(concatname, preload=False) write_raw_bids(raw, bids_path, overwrite=True) # anatomy rootlog.info("Running dicom2nifti on MRI...") derivatives_root = opj(bids_root, "derivatives") # meg bids_path = BIDSPath(subject=ject, session="resting", task="resting", root=bids_root, processing="concat") nii = glob.glob(opj(input_folder, ject, "*.nii*")) try: for n in nii: write_anat(n, bids_path=bids_path, overwrite=True) except Exception as e: rootlog.error(f"Conversion of MRI to nift failed --> {e}") # Create Dataset the_roots = [bids_root, derivatives_root] rootlog.info("Creating BIDS dataset...") for r in the_roots: make_dataset_description(r, name="CDK Epilepsy Dataset", data_license="closed", authors="Rudi Kreidenhuber", overwrite=True) # Coregistration --> this doesn't work with WSLg - from here on # run on windows, if you are on a windows machine transfile = opj(dfc.ftrans, subject + "-trans.fif") rootlog.info("Starting coregistration...") if os.path.isfile(transfile): rootlog.info( f"Skipping coregistration, because a transfile ({transfile}) already exists" ) else: print(f"\n\n\n--> Transfile should be called: {transfile}\n\n\n") try: mne.gui.coregistration( subject=subject, subjects_dir=dfc.fanat, inst=bids_path, advanced_rendering=False) # BIDS: inst=raw.filenames[0]) except: print("failed with bids_derivatives folder") rawfile = opj(dfc.fbase, "ses-resting", "meg", "*concat_meg.fif") rawfile = glob.glob(rawfile)[0] rootlog.info( f"Coregistration with BIDS-file failed, Rawfile used was: {rawfile}" ) mne.gui.coregistration(subject=subject, subjects_dir=dfc.fanat, inst=rawfile, advanced_rendering=False) # frequency spectrum if do_frequencies: rootlog.info("Calculating frequency spectrum...") bem_sol = opj(dfc.fsrc, subject + "-3-layer-BEM-sol.fif") if not os.path.isfile(bem_sol) and use_single_shell_model: rootlog.warning("Working with a single shell head model") bem_sol = opj(dfc.fsrc, subject + "-single-shell-BEM-sol.fif") fwd_name = opj(dfc.fsrc, subject + "-fwd.fif") srcfilename = opj(dfc.fsrc, subject + "-" + spacing + "-src.fif") filebase = str(subject) + "_Freqs" all_stcs_filename = (filebase + '-stc-psd-MNE.pkl') all_stcs_filename = opj(dfc.freq, all_stcs_filename) sensor_psd_filename = (filebase + '-sensor-psd-MNE.pkl') sensor_psd_filename = opj(dfc.freq, sensor_psd_filename) if not os.path.isfile(all_stcs_filename) or not os.path.isfile( sensor_psd_filename ): # so this should run only on the first file.. # load again in case preprocessing didn't happen before concatname = opj(input_folder, str(subject) + "_concat.fif") raw = mne.io.read_raw(concatname, preload=True) if os.path.isfile(fwd_name): fwd = mne.read_forward_solution(fwd_name) else: fwd = mne.make_forward_solution(raw.info, src=srcfilename, bem=bem_sol, trans=transfile, meg=True, eeg=False, mindist=0.2, ignore_ref=False, n_jobs=n_jobs, verbose=True) mne.write_forward_solution(fwd_name, fwd) noise_cov = mne.compute_raw_covariance(raw, method="empirical", n_jobs=n_jobs) inv = mne.minimum_norm.make_inverse_operator(raw.info, forward=fwd, noise_cov=noise_cov, loose="auto", depth=0.8) snr = 3. stc_psd, sensor_psd = mne.minimum_norm.compute_source_psd( raw, inv, lambda2=lambda2, method='MNE', fmin=1, fmax=45, n_fft=2048, n_jobs=n_jobs, return_sensor=True, verbose=True) pickle.dump(stc_psd, open(all_stcs_filename, "wb")) pickle.dump(sensor_psd, open(sensor_psd_filename, "wb")) else: stc_psd = pickle.load(open(all_stcs_filename, "rb")) sensor_psd = pickle.load(open(sensor_psd_filename, "rb")) # Visualization topos = dict() stcs = dict() topo_norm = sensor_psd.data.sum(axis=1, keepdims=True) stc_norm = stc_psd.sum() for band, limits in freq_bands.items(): # normalize... data = sensor_psd.copy().crop(*limits).data.sum(axis=1, keepdims=True) topos[band] = mne.EvokedArray(100 * data / topo_norm, sensor_psd.info) stcs[band] = 100 * stc_psd.copy().crop( *limits).sum() / stc_norm.data brain = dict() x_hemi_freq = dict() mne.viz.set_3d_backend('pyvista') for band in freq_bands.keys(): brain[band] = u.plot_freq_band_dors(stcs[band], band=band, subject=subject, subjects_dir=dfc.fanat, filebase=filebase) freqfilename3d = (filebase + '_' + band + '_freq_topomap_3d_dors.png') freqfilename3d = os.path.join(dfc.freq, freqfilename3d) image = brain[band].save_image(freqfilename3d) brain_lh, brain_rh = u.plot_freq_band_lat(stcs[band], band=band, subject=subject, subjects_dir=dfc.fanat, filebase=filebase) freqfilename3d = (filebase + '_' + band + '_freq_topomap_3d_lat_lh.png') freqfilename3d = os.path.join(dfc.freq, freqfilename3d) image = brain_lh.save_image(freqfilename3d) freqfilename3d = (filebase + '_' + band + '_freq_topomap_3d_lat_rh.png') freqfilename3d = os.path.join(dfc.freq, freqfilename3d) image = brain_rh.save_image(freqfilename3d) brain_lh, brain_rh = u.plot_freq_band_med(stcs[band], band=band, subject=subject, subjects_dir=dfc.fanat, filebase=filebase) freqfilename3d = (filebase + '_' + band + '_freq_topomap_3d_med_lh.png') freqfilename3d = os.path.join(dfc.freq, freqfilename3d) image = brain_lh.save_image(freqfilename3d) freqfilename3d = (filebase + '_' + band + '_freq_topomap_3d_med_rh.png') freqfilename3d = os.path.join(dfc.freq, freqfilename3d) image = brain_rh.save_image(freqfilename3d) # Cross hemisphere comparison # make sure fsaverage_sym exists in local subjects dir: rootlog.info( f"Calculating cross hemisphere comparison for {band}.") target = os.path.join(dfc.fanat, "fsaverage_sym") if not os.path.isdir(target): # try to find it in $SUBJECTS_DIR and copy os_subj_dir = os.environ.get("SUBJECTS_DIR") fs_avg_sym_dir = os.path.join(os_subj_dir, "fsaverage_sym") u.recursive_overwrite(fs_avg_sym_dir, target) if not os.path.isdir(target): rootlog.error("fsaverage_sym not found - aborting") raise Exception mstc = stcs[band].copy() mstc = mne.compute_source_morph(mstc, subject, 'fsaverage_sym', smooth=5, warn=False, subjects_dir=dfc.fanat).apply(mstc) morph = mne.compute_source_morph(mstc, 'fsaverage_sym', 'fsaverage_sym', spacing=mstc.vertices, warn=False, subjects_dir=dfc.fanat, xhemi=True, verbose='error') stc_xhemi = morph.apply(mstc) diff = mstc - stc_xhemi title = ('blue = RH; ' + subject + ' -Freq-x_hemi- ' + band) x_hemi_freq[band] = diff.plot( hemi='lh', subjects_dir=dfc.fanat, size=(1200, 800), time_label=title, add_data_kwargs=dict(time_label_size=10)) freqfilename3d = (filebase + '_x_hemi_' + band + '.png') freqfilename3d = os.path.join(dfc.freq, freqfilename3d) image = x_hemi_freq[band].save_image(freqfilename3d) # Source localization rootlog.info("Now starting source localization...") epo_filename = opj(dfc.spikes, str(subject) + "-epo.fif") concat_epochs = mne.read_epochs(epo_filename) noise_cov_file = opj(dfc.spikes, "Spikes_noise_covariance.pkl") srcfilename = opj(dfc.fsrc, subject + "-" + spacing + "-src.fif") if not os.path.isfile(noise_cov_file): noise_cov = mne.compute_covariance(concat_epochs, tmax=-1., method='auto', n_jobs=n_jobs, rank="full") pickle.dump(noise_cov, open(noise_cov_file, "wb")) else: with open(noise_cov_file, 'rb') as f: noise_cov = pickle.load(f) rootlog.info( f"The following events have been found: \n{concat_epochs.event_id.keys()}" ) for event in concat_epochs.event_id.keys(): eventname = str(event) if eventname == "ignore_me" or eventname == "AAA" or eventname.startswith( "."): rootlog.info(f"Omitting event {event}") else: try: rootlog.info(f"Now localizing event: {event}") e = concat_epochs[eventname].load_data().crop( tmin=-0.5, tmax=0.5).average() e_folder = os.path.join(dfc.spikes, eventname) evoked_filename = opj(e_folder, ject + "_" + eventname + "-ave.fif") cp_folder = os.path.join(dfc.spikes, eventname, "custom_pics") cts_folder = os.path.join(dfc.spikes, eventname, "custom_time_series") gp_folder = os.path.join(dfc.spikes, eventname, "generic_pics") folders = [e_folder, cp_folder, cts_folder, gp_folder] if not os.path.isdir(e_folder): for f in folders: os.mkdir(f) e.save(evoked_filename) src = mne.read_source_spaces(srcfilename) bem_sol = opj(dfc.fsrc, subject + "-3-layer-BEM-sol.fif") if not os.path.isfile(bem_sol) and use_single_shell_model: bem_sol = opj(dfc.fsrc, subject + "-single-shell-BEM-sol.fif") fwd_name = opj(dfc.fsrc, subject + "-fwd.fif") if os.path.isfile(fwd_name): fwd = mne.read_forward_solution(fwd_name) else: fwd = mne.make_forward_solution(e.info, src=src, bem=bem_sol, trans=transfile, meg=True, eeg=False, mindist=0.2, ignore_ref=False, n_jobs=n_jobs, verbose=True) # inv for cortical surface inv = mne.minimum_norm.make_inverse_operator( e.info, forward=fwd, noise_cov=noise_cov, loose=0.2, depth=0.8) # inv with volume source space vol_srcfilename = opj(dfc.fsrc, subject + "-vol-src.fif") src_vol = mne.read_source_spaces(vol_srcfilename) fwd_vol = mne.make_forward_solution(e.info, src=src_vol, bem=bem_sol, trans=transfile, meg=True, eeg=False, mindist=0.2, ignore_ref=False, n_jobs=n_jobs, verbose=True) inv_vol = mne.minimum_norm.make_inverse_operator( e.info, forward=fwd_vol, noise_cov=noise_cov, loose=1, depth=0.8) # Distributed source models for m in source_loc_methods: stc_name = 'stc_' + m if m == 'dSPM': # calculate vector solution in volume source space try: rootlog.info( "Now calculating dSPM vector solution...") stc_name = mne.minimum_norm.apply_inverse( e, inv_vol, lambda2, method='dSPM', pick_ori='vector') surfer_kwargs = dict( subjects_dir=dfc.fanat, # hemi='split', clim=dict(kind='percent', lims=[90, 96, 99.85]), views=['lat', 'med'], colorbar=True, initial_time=0, time_unit='ms', size=(1000, 800), smoothing_steps=10) brain = stc_name.plot(**surfer_kwargs) label = str(ject + " - " + eventname + " - Vector solution") brain.add_text(0.1, 0.9, label, 'title', font_size=10) img_f_name = ('img_stc_' + ject + '_' + eventname + '_' + m + '.png') img_f_name = os.path.join(gp_folder, img_f_name) brain.save_image(img_f_name) stc_f_name = ("stc_" + ject + '_' + eventname + '_' + m + ".h5") stc_f_name = os.path.join(e_folder, stc_f_name) stc_name = stc_name.crop(tmin=stc_tmin, tmax=stc_tmax) rootlog.info("Saving dSPM vector solution.") stc_name.save(stc_f_name) except Exception as ex: rootlog.error(f"dSPM failed --> {ex}") else: stc_name = mne.minimum_norm.apply_inverse( e, inv, lambda2, method=m, pick_ori=None) surfer_kwargs = dict(hemi='split', subjects_dir=dfc.fanat, clim=dict(kind='percent', lims=[90, 96, 99.85]), views=['lat', 'med'], colorbar=True, initial_time=0, time_unit='ms', size=(1000, 800), smoothing_steps=10) brain = stc_name.plot(**surfer_kwargs) label = str(ject + " - " + eventname + " - " + m) brain.add_text(0.1, 0.9, label, 'title', font_size=10) img_f_name = ('img_stc_' + ject + '_' + eventname + '_' + m + '.png') img_f_name = os.path.join(gp_folder, img_f_name) brain.save_image(img_f_name) stc_f_name = ('stc_' + ject + '_' + eventname + '_' + m) stc_f_name = os.path.join(e_folder, stc_f_name) stc_name = stc_name.crop(tmin=stc_tmin, tmax=stc_tmax) rootlog.info("Saving eLORETA.") stc_name.save(stc_f_name) if m == "eLORETA": try: rootlog.info( "Now calculating eLORETA with peaks...") rh_peaks = u.get_peak_points( stc_name, hemi='rh', tmin=peaks_tmin, tmax=peaks_tmax, nr_points=peaks_nr_of_points, mode=peaks_mode) lh_peaks = u.get_peak_points( stc_name, hemi='lh', tmin=peaks_tmin, tmax=peaks_tmax, nr_points=peaks_nr_of_points, mode=peaks_mode) label = str(ject + " - " + eventname + " - " + m + " - max. activation points") brain.add_text(0.1, 0.9, label, font_size=10) #, 'title' for p in rh_peaks: brain.add_foci(p, color='green', coords_as_verts=True, hemi='rh', scale_factor=0.6, alpha=0.9) for p in lh_peaks: brain.add_foci(p, color='green', coords_as_verts=True, hemi='lh', scale_factor=0.6, alpha=0.9) stc_f_name = ('stc_' + ject + '_' + eventname + '_' + m + "_with_peaks-ave") stc_f_name = os.path.join(e_folder, stc_f_name) stc_name.save(stc_f_name) img_f_name = ('img_stc_' + ject + '_' + eventname + '_' + m + '_with_peaks.png') img_f_name = os.path.join( gp_folder, img_f_name) brain.save_image(img_f_name) except Exception as ex: rootlog.error( f"eLORETA with peaks failed --> {ex}") # Dipoles rootlog.info("Now calculating ECD.") try: for start, stop in dip_times.values(): dip_epoch = e.copy().crop(start, stop).pick('meg') ecd = mne.fit_dipole(dip_epoch, noise_cov, bem_sol, trans=transfile)[0] best_idx = np.argmax(ecd.gof) best_time = ecd.times[best_idx] trans = mne.read_trans(transfile) mri_pos = mne.head_to_mri(ecd.pos, mri_head_t=trans, subject=subject, subjects_dir=dfc.fanat) t1_file_name = os.path.join(dfc.fanat, subject, 'mri', 'T1.mgz') stoptime = str(abs(int(stop * int(e.info["sfreq"])))) if stoptime == "5": stoptime = "05" title = str(eventname + ' - ECD @ minus ' + stoptime + ' ms') t1_fig = plot_anat(t1_file_name, cut_coords=mri_pos[0], title=title) t1_f_name_pic = ('img_ecd_' + eventname + '_' + '_Dipol_' + stoptime + '.png') t1_f_name_pic = os.path.join(e_folder, "generic_pics", t1_f_name_pic) t1_fig.savefig(t1_f_name_pic) fig_3d = ecd.plot_locations(trans, subject, dfc.fanat, mode="orthoview") fig_3d_pic = ('img_3d_ecd_' + eventname + '_' + '_Dipol_' + stoptime + '.png') fig_3d_pic = os.path.join(e_folder, "generic_pics", fig_3d_pic) fig_3d.savefig(fig_3d_pic) plt.close("all") except Exception as ex: rootlog.error(f"ECD calculation failed --> {ex}") except Exception as ex: rootlog.error(f"Source localization failed because of:\n {ex}") # Create report if do_report: reporter = Reporter.EpilepsyReportBuilder( derivatives_root=derivatives_root, subject=subject, extras_dir=extras_directory) reporter.create_report() # Last words logging.info("Finished SourceLocPipeline.") print("SourceLocPipeline completed!")
show_power = gamma_power_t[:, sl] anim = animation.FuncAnimation(fig, animate, init_func=init, fargs=(show_power, ), frames=show_power.shape[1], interval=100, blit=True) ############################################################################### # Alternatively, we can project the sensor data to the nearest locations on # the pial surface and visualize that: # sphinx_gallery_thumbnail_number = 4 evoked = mne.EvokedArray(gamma_power_t[:, sl], raw.info, tmin=raw.times[sl][0]) stc = mne.stc_near_sensors(evoked, trans, subject, subjects_dir=subjects_dir) clim = dict(kind='value', lims=[vmin * 0.9, vmin, vmax]) brain = stc.plot(surface='pial', hemi='both', initial_time=0.68, colormap='viridis', clim=clim, views='parietal', subjects_dir=subjects_dir, size=(500, 500)) # You can save a movie like the one on our documentation website with: # brain.save_movie(time_dilation=50, interpolation='linear', framerate=10, # time_viewer=True)
fmax=40, bandwidth=1) pos_psds, pos_freqs = mne.time_frequency.psd_multitaper(pos, fmin=1, fmax=40, bandwidth=1) neg_psds, neg_freqs = mne.time_frequency.psd_multitaper(neg, fmin=1, fmax=40, bandwidth=1) #create PSD-to-Evoked objects for each condition rest_psd = np.mean(rest_psds, axis=0) rest.pick_types(meg=True) restev = rest.average() rest_fev = mne.EvokedArray(rest_psd, restev.info, comment="rest") rest_fev.times = rest_freqs ton_psd = np.mean(ton_psds, axis=0) tonbas.pick_types(meg=True) tonev = tonbas.average() ton_fev = mne.EvokedArray(ton_psd, tonev.info, comment="tonbas") ton_fev.times = ton_freqs pos_psd = np.mean(pos_psds, axis=0) pos.pick_types(meg=True) posev = pos.average() pos_fev = mne.EvokedArray(pos_psd, posev.info, comment="pos") pos_fev.times = pos_freqs neg_psd = np.mean(neg_psds, axis=0) neg.pick_types(meg=True) negev = neg.average() neg_fev = mne.EvokedArray(neg_psd, negev.info, comment="neg")
def interpolate_missing(inst, subject, data_type, hcp_path, run_index=0, mode='fast'): """Interpolate all MEG channels that are missing .. warning:: This function may require some memory. Parameters ---------- inst : MNE data containers Raw, Epochs, Evoked. subject : str, file_map The subject data_type : str The kind of data to read. The following options are supported: 'rest' 'task_motor' 'task_story_math' 'task_working_memory' 'noise_empty_room' 'noise_subject' run_index : int The run index. For the first run, use 0, for the second, use 1. Also see HCP documentation for the number of runs for a given data type. hcp_path : str The HCP directory, defaults to op.curdir. mode : str Either `'accurate'` or `'fast'`, determines the quality of the Legendre polynomial expansion used for interpolation of MEG channels. Returns ------- out : MNE data containers Raw, Epochs, Evoked but with missing channels interpolated. """ try: info = read_info( subject=subject, data_type=data_type, hcp_path=hcp_path, run_index=run_index if run_index is None else run_index) except (ValueError, IOError): raise ValueError( 'could not find config to complete info.' 'reading only channel positions without ' 'transforms.') # full BTI MEG channels bti_meg_channel_names = ['A%i' % ii for ii in range(1, 249, 1)] # figure out which channels are missing bti_meg_channel_missing_names = [ ch for ch in bti_meg_channel_names if ch not in inst.ch_names] # get meg picks picks_meg = mne.pick_types(inst.info, meg=True, ref_meg=False) # some non-contiguous block in the middle so let's try to invert picks_other = [ii for ii in range(len(inst.ch_names)) if ii not in picks_meg] other_chans = [inst.ch_names[po] for po in picks_other] # compute new n channels n_channels = (len(picks_meg) + len(bti_meg_channel_missing_names) + len(other_chans)) # restrict info to final channels # ! info read from config file is not sorted like inst.info # ! therefore picking order matters, but we don't know it. # ! so far we will rely on the consistent layout for raw files final_names = [ch for ch in _data_labels if ch in bti_meg_channel_names or ch in other_chans] info = _hcp_pick_info(info, final_names) assert len(info['ch_names']) == n_channels existing_channels_index = [ii for ii, ch in enumerate(info['ch_names']) if ch in inst.ch_names] info['sfreq'] = inst.info['sfreq'] # compute shape of data to be added is_raw = isinstance(inst, (mne.io.Raw, mne.io.RawArray, mne.io.bti.bti.RawBTi)) is_epochs = isinstance(inst, mne.BaseEpochs) is_evoked = isinstance(inst, (mne.Evoked, mne.EvokedArray)) if is_raw: shape = (n_channels, (inst.last_samp - inst.first_samp) + 1) data = inst._data elif is_epochs: shape = (n_channels, len(inst.events), len(inst.times)) data = np.transpose(inst.get_data(), (1, 0, 2)) elif is_evoked: shape = (n_channels, len(inst.times)) data = inst.data else: raise ValueError('instance must be Raw, Epochs ' 'or Evoked') out_data = np.empty(shape, dtype=data.dtype) out_data[existing_channels_index] = data if is_raw: out = mne.io.RawArray(out_data, info) if inst.annotations is not None: out.annotations = inst.annotations elif is_epochs: out = mne.EpochsArray(data=np.transpose(out_data, (1, 0, 2)), info=info, events=inst.events, tmin=inst.times.min(), event_id=inst.event_id) elif is_evoked: out = mne.EvokedArray( data=out_data, info=info, tmin=inst.times.min(), comment=inst.comment, nave=inst.nave, kind=inst.kind) else: raise ValueError('instance must be Raw, Epochs ' 'or Evoked') # set "bad" channels and interpolate. out.info['bads'] = bti_meg_channel_missing_names out.interpolate_bads(mode=mode) return out
'switch-noswitch', 'none' ]) times = np.cumsum([3, 3, 5.8, 5.8, 3, 5.8]) - 1 / 512.0 data['time'] = np.array(data.index) / 512.0 index = np.sum(data.time[:, np.newaxis] > times[np.newaxis, :], axis=1) data['condition'] = conditions[index] evokeds = {} stream_cond = ['stream1', 'stream2', 'stream2-stream1'] stream_len = data[data.condition.isin(stream_cond)].groupby( 'condition').time.count().min() for cond in stream_cond: montage = mne.channels.read_montage( op.join(data_dir, "..", "acnlbiosemi64.sfp")) evoked = mne.EvokedArray( data.ix[data.condition == cond, 0:73][0:stream_len].as_matrix().T * 10**-6, info) evoked.times -= 0.2 evoked.set_montage(montage) evoked.comment = cond evokeds[cond] = evoked # mne.viz.plot_evoked_topo([evokeds[k] for k in stream_cond]) FCz = [evokeds['stream1'].ch_names.index("FCz")] fig = mne.viz.plot_compare_evokeds( { 'stream1': evokeds['stream1'], 'stream2': evokeds['stream2'], 'stream2-stream1': evokeds['stream2-stream1'] }, styles={
# Now we can create the :class:`mne.EpochsArray` object custom_epochs = mne.EpochsArray(data, info, events, tmin, event_id) print(custom_epochs) # We can treat the epochs object as we would any other _ = custom_epochs['smiling'].average().plot() ############################################################################### # --------------------------------------------- # Creating :class:`Evoked <mne.Evoked>` Objects # --------------------------------------------- # If you already have data that is collapsed across trials, you may also # directly create an evoked array. Its constructor accepts an array of # `shape(n_chans, n_times)` in addition to some bookkeeping parameters. # The averaged data data_evoked = data.mean(0) # The number of epochs that were averaged nave = data.shape[0] # A comment to describe to evoked (usually the condition name) comment = "Smiley faces" # Create the Evoked object evoked_array = mne.EvokedArray(data_evoked, info, tmin, comment=comment, nave=nave) print(evoked_array) _ = evoked_array.plot()
# needed data form: X = array of shape observations x times/freqs x locs/chans t_obs, clusters, cluster_pv, H0 = mne.stats.spatio_temporal_cluster_1samp_test(X_alpha_diff, threshold=threshold, n_permutations=1024, tail=0, adjacency=adjacency, n_jobs=4, step_down_p=0, t_power=1, out_type='indices') # now explore and plot the clusters # get indices of good clusters good_cluster_inds = np.where(cluster_pv < .05)[0] # it's a tuple, with [0] we grab the array therein # if there are any, do more... if good_cluster_inds.any(): # then loop over clusters for i_clu, clu_idx in enumerate(good_cluster_inds): # unpack cluster information, get unique indices time_inds, ch_inds = clusters[clu_idx] ch_inds = np.unique(ch_inds) time_inds = np.unique(time_inds) # get topography for T stat (mean over cluster freqs) t_map = t_obs[time_inds, ...].mean(axis=0) # create spatial mask for plotting (setting cluster channels to "True") mask = np.zeros((t_map.shape[0], 1), dtype=bool) mask[ch_inds, :] = True # plot average test statistic and mark significant sensors t_evoked = mne.EvokedArray(t_map[:, np.newaxis], epo.info, tmin=0) fig = t_evoked.plot_topomap(times=0, mask=mask, cmap='bwr', vmin=np.min, vmax=np.max,scalings=1.0, units="T_val", time_format= "", title="Alpha Power \n{} - {} ms".format(time_inds[0]*5-105, time_inds[-1]*5-105), mask_params=dict(markersize=4), size = 6, show=True)
nave = cleft.sum() elif iname == 3: nave = nright.sum() elif iname == 4: nave = cright.sum() elif iname in [5, 11]: nave = neut_nave elif iname in [6, 10]: nave = cued_nave elif iname == 8: nave = nleft.sum() + cleft.sum() elif iname == 9: nave = nright.sum() + cright.sum() for stat in ['betas', 'tstats']: if stat == 'betas': dat = np.squeeze(model.copes[iname, :, :]) elif stat == 'tstats': dat = np.squeeze(model.get_tstats()[iname, :, :]) tl = mne.EvokedArray(info=info, nave=nave, tmin=tmin, data=dat) tl.save(fname=op.join( param['path'], 'glms', 'cuelocked', 'epochs_glm' + str(glmnum), 'wmc_' + 's%02d' % (i) + '_cuelocked_tl_' + lapstr + name + '_%s-ave.fif' % (stat))) # deepcopy(tl).plot_joint(topomap_args = dict(outlines='head', contours=0), times = np.arange(0.1, 0.8, 0.1)) #------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ del (glmdes) del (model)
def __init__(self): # DEFINE FIGURES # ------------------------------------------------------------------------------ self.AlphaFig = figure(plot_width=350, plot_height=350, title='Alpha Band (8 - 12 Hz)') self.TotalFig = figure(plot_width=350, plot_height=350, title='Total Power') # set title properties self.AlphaFig.title.align = 'center' self.AlphaFig.title.text_font_size = "22px" self.TotalFig.title.align = 'center' self.TotalFig.title.text_font_size = "22px" # remove toolbars and Bokeh logo self.AlphaFig.toolbar.logo = None self.AlphaFig.toolbar_location = None self.TotalFig.toolbar.logo = None self.TotalFig.toolbar_location = None # add border to visualizations self.AlphaFig.outline_line_width = 1 self.AlphaFig.outline_line_alpha = 1 self.AlphaFig.outline_line_color = "black" self.AlphaFig.xaxis.visible = False self.AlphaFig.yaxis.visible = False self.AlphaFig.xgrid.visible = False self.AlphaFig.ygrid.visible = False self.TotalFig.outline_line_width = 1 self.TotalFig.outline_line_alpha = 1 self.TotalFig.outline_line_color = "black" self.TotalFig.xaxis.visible = False self.TotalFig.yaxis.visible = False self.TotalFig.xgrid.visible = False self.TotalFig.ygrid.visible = False # DEFINE VARIABLES # ------------------------------------------------------------------------------ self.eeg_data = np.zeros((64, 64), float) self.global_max = 1 # variables for mne evoked structure self.ch_names = [ 'Fp1', 'Fp2', 'F3', 'F4', 'C3', 'C4', 'P3', 'P4', 'O1', 'O2', 'F7', 'F8', 'T7', 'T8', 'P7', 'P8', 'Fz', 'Cz', 'Pz', 'Oz', 'FC1', 'FC2', 'CP1', 'CP2', 'FC5', 'FC6', 'CP5', 'CP6', 'FT9', 'FT10', 'FCz', 'AFz', 'F1', 'F2', 'C1', 'C2', 'P1', 'P2', 'AF3', 'AF4', 'FC3', 'FC4', 'CP3', 'CP4', 'PO3', 'PO4', 'F5', 'F6', 'C5', 'C6', 'P5', 'P6', 'AF7', 'AF8', 'FT7', 'FT8', 'TP7', 'TP8', 'PO7', 'PO8', 'Fpz', 'CPz', 'POz', 'TP10' ] self.ch_types = ['eeg' for j in range(64)] self.info = mne.create_info(ch_names=self.ch_names, sfreq=500, ch_types=self.ch_types) self.info.set_montage("standard_1020") # for sensor locations self.evoked = mne.EvokedArray( self.eeg_data, self.info) # evoked structure for plotting topomaps # column data source for updating document self.source_images = ColumnDataSource({ 'alpha_array': [], 'total_array': [] }) self.AlphaFig.image_rgba(image='alpha_array', x=0, y=0, dw=350, dh=350, source=self.source_images) self.TotalFig.image_rgba(image='total_array', x=0, y=0, dw=350, dh=350, source=self.source_images)
clf = skl.linear_model.Ridge(alpha=.5) scaler = StandardScaler() model = mne.decoding.LinearModel(clf) labels = ds.events[:, -1] x_data = ds.get_data().reshape(len(labels), -1) x = scaler.fit_transform(x_data) model.fit(x, y) for name, coef in (('patterns', model.patterns_), ('filters', model.filters_)): coef = scaler.inverse_transform([coef])[0] coef = coef.reshape(len(ds.ch_names), -1) evoked = mne.EvokedArray(coef, ds.info, tmin=ds.tmin) evoked.plot_topomap(title='EEG %s' % name, time_unit='s') #%% ds = deepcopy(data[-2]) ds = ds.drop_channels(['VEOG', 'HEOG']) #data here is trials x channels x time time = ds.times X_all = deepcopy(ds).get_data() var = 'targinconf' #or pside if binary continuous = None if var == 'confwidth' or var == 'error': continuous = True if var == 'confwidth': y = ds.metadata.confwidth.to_numpy() elif var == 'error':
event_dict = dict(condition_A=1, condition_B=2) simulated_epochs = mne.EpochsArray(data, info, tmin=-0.5, events=events, event_id=event_dict) simulated_epochs.plot(picks='misc', show_scrollbars=False, events=events, event_id=event_dict) ############################################################################### # You could also create simulated epochs by using the normal `~mne.Epochs` # (not `~mne.EpochsArray`) constructor on the simulated `~mne.io.RawArray` # object, by creating an events array (e.g., using # `mne.make_fixed_length_events`) and extracting epochs around those events. # # # Creating `~mne.Evoked` Objects # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # # If you already have data that was averaged across trials, you can use it to # create an `~mne.Evoked` object using the `~mne.EvokedArray` class # constructor. It requires an `~mne.Info` object and a data array of shape # ``(n_channels, n_times)``, and has an optional ``tmin`` parameter like # `~mne.EpochsArray` does. It also has a parameter ``nave`` indicating how many # trials were averaged together, and a ``comment`` parameter useful for keeping # track of experimental conditions, etc. Here we'll do the averaging on our # NumPy array and use the resulting averaged data to make our `~mne.Evoked`. # Create the Evoked object evoked_array = mne.EvokedArray(data.mean(axis=0), info, tmin=-0.5, nave=data.shape[0], comment='simulated') print(evoked_array) evoked_array.plot()
def get_patterns(epochs): epochs.set_eeg_reference(ref_channels='average') sl.fit(epochs.get_data(), epochs.metadata.confdiff.to_numpy() <= 0) coef = mne.decoding.get_coef(sl, 'patterns_', inverse_transform=False) return mne.EvokedArray(-coef, epochs.info, tmin=epochs.times[0])
data = epochs.get_data() times = epochs.times temporal_mask = np.logical_and(0.04 <= times, times <= 0.06) data = np.mean(data[:, :, temporal_mask], axis=2) n_permutations = 50000 T0, p_values, H0 = permutation_t_test(data, n_permutations, n_jobs=1) significant_sensors = picks[p_values <= 0.05] significant_sensors_names = [raw.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 evoked = mne.EvokedArray(-np.log10(p_values)[:, np.newaxis], epochs.info, tmin=0.) # Extract mask and indices of active sensors in the layout stats_picks = mne.pick_channels(evoked.ch_names, significant_sensors_names) mask = p_values[:, np.newaxis] <= 0.05 evoked.plot_topomap(ch_type='grad', times=[0], scalings=1, time_format=None, cmap='Reds', vmin=0., vmax=np.max, units='-log10(p)', cbar_fmt='-%0.1f', mask=mask, size=3, show_names=lambda x: x[4:] + ' ' * 20, time_unit='s')
def apply_lap(self, evoked_data, caption, lap_type='large', tmin=-3, fs=500): channel_names = evoked_data.ch_names if lap_type == 'large': large_lap_C3_chs = [ channel_names.index('C3'), channel_names.index('T7'), channel_names.index('Cz'), channel_names.index('F3'), channel_names.index('P3') ] large_lap_Cz_chs = [ channel_names.index('Cz'), channel_names.index('C3'), channel_names.index('C4'), channel_names.index('Fz'), channel_names.index('Pz') ] large_lap_C4_chs = [ channel_names.index('C4'), channel_names.index('Cz'), channel_names.index('T8'), channel_names.index('F4'), channel_names.index('P4') ] large_lap_FC1_chs = [ channel_names.index('FC1'), channel_names.index('F3'), channel_names.index('Fz'), channel_names.index('C3'), channel_names.index('Cz') ] large_lap_FC2_chs = [ channel_names.index('FC2'), channel_names.index('Cz'), channel_names.index('Fz'), channel_names.index('F4'), channel_names.index('C4') ] C3_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_C3_chs, :]) Cz_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_Cz_chs, :]) C4_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_C4_chs, :]) FC1_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_FC1_chs, :]) FC2_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_FC2_chs, :]) large_lap_evoked = np.r_[C3_large_lap_evoked, Cz_large_lap_evoked, C4_large_lap_evoked, FC1_large_lap_evoked, FC2_large_lap_evoked] info = mne.create_info( ch_names=['C3', 'Cz', 'C4', 'FC1', 'FC2'], sfreq=fs, ch_types=['eeg', 'eeg', 'eeg', 'eeg', 'eeg']) info.set_montage('standard_1020') self.large_lap_evoked = mne.EvokedArray(large_lap_evoked, info=info, tmin=tmin, nave=evoked_data.nave) elif lap_type == 'mixed': large_lap_C3_chs = [ channel_names.index('C3'), channel_names.index('T7'), channel_names.index('Cz'), channel_names.index('F3'), channel_names.index('P3') ] large_lap_C1_chs = [ channel_names.index('C1'), channel_names.index('C3'), channel_names.index('Cz'), channel_names.index('FC1'), channel_names.index('CP1') ] large_lap_Cz_chs = [ channel_names.index('Cz'), channel_names.index('C3'), channel_names.index('C4'), channel_names.index('Fz'), channel_names.index('Pz') ] large_lap_C2_chs = [ channel_names.index('C2'), channel_names.index('C4'), channel_names.index('Cz'), channel_names.index('FC2'), channel_names.index('CP2') ] large_lap_C4_chs = [ channel_names.index('C4'), channel_names.index('Cz'), channel_names.index('T8'), channel_names.index('F4'), channel_names.index('P4') ] large_lap_FC1_chs = [ channel_names.index('FC1'), channel_names.index('F3'), channel_names.index('Fz'), channel_names.index('C3'), channel_names.index('Cz') ] large_lap_FC2_chs = [ channel_names.index('FC2'), channel_names.index('Cz'), channel_names.index('Fz'), channel_names.index('F4'), channel_names.index('C4') ] C3_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_C3_chs, :]) C1_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_C1_chs, :]) Cz_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_Cz_chs, :]) C2_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_C2_chs, :]) C4_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_C4_chs, :]) FC1_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_FC1_chs, :]) FC2_large_lap_evoked = self.lap( evoked_data.copy().data[large_lap_FC2_chs, :]) large_lap_evoked = np.r_[C3_large_lap_evoked, C1_large_lap_evoked, Cz_large_lap_evoked, C2_large_lap_evoked, C4_large_lap_evoked, FC1_large_lap_evoked, FC2_large_lap_evoked] info = mne.create_info( ch_names=['C3', 'C1', 'Cz', 'C2', 'C4', 'FC1', 'FC2'], sfreq=fs, ch_types=['eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg']) info.set_montage('standard_1020') self.large_lap_evoked = mne.EvokedArray(large_lap_evoked, info=info, tmin=tmin, nave=evoked_data.nave) elif lap_type == 'large_Cz': channels = ['Cz', 'F3', 'F4', 'Fz', 'C3', 'C4', 'P3', 'P4', 'Pz'] ch_idx = [] for ch in channels: ch_idx.append(channel_names.index(ch)) Cz_large_lap_evked = self.lap_Cz( evoked_data.copy().data[ch_idx, :]) info = mne.create_info(ch_names=['Cz'], sfreq=fs, ch_types=['eeg']) self.large_lap_evoked = mne.EvokedArray(Cz_large_lap_evked, info=info, tmin=tmin, nave=evoked_data.nave) return self.large_lap_evoked
import mne import numpy as np import scipy.io import matplotlib.pyplot as plt import numpy as np #设置通道名 biosemi_montage = mne.channels.make_standard_montage('biosemi64') #生成数据 data = np.random.randn(64, 1) #创建info对象 info = mne.create_info(ch_names=biosemi_montage.ch_names, sfreq=128., ch_types='eeg') #创建evokeds对象 evoked = mne.EvokedArray(data, info) #evokeds设置通道 evoked.set_montage(biosemi_montage) #画图 mne.viz.plot_topomap(evoked.data[:, 0], evoked.info, show=False) plt.show()
def analyzeOffline(subjID): ''' ''' # Initialize conditions for preprocessing of epochs (preproc1epoch from EEG_analysis_RT) reject_ch = 1 # Rejection of nine predefined channels reject = None # Rejection of channels, either manually defined or based on MNE analysis mne_reject = 0 flat = None # Input for MNE rejection bad_channels = None # Input for manual rejection of channels opt_detrend = 1 # Temporal EEG detrending (linear) if reject_ch == 1: n_channels = 23 if reject_ch == 0: n_channels = 32 # Initialize conditions for SSP rejection (applySSP from EEG_analysis_RT) threshold = 0.1 # SSP projection variance threshold # Initialize dictionary for saving outputs d = {} d['subjID'] = subjID plot_MNE = 0 EEGfile, markerFile, idxFile, alphaFile, n_it = findSubjectFiles( subjID, manual_n_it=None) #%% Test RT alpha per run alpha, marker = extractAlpha(alphaFile) above_chance = len(np.where((np.array(alpha) > 0.5))[0]) / len(alpha) alpha_per_run = np.zeros((n_it)) j = 0 for ii in range(n_it): alpha_per_run[ii] = len( np.where((np.array(alpha[j:j + 200]) > 0.5))[0]) / 200 j += 200 d['ALPHA_fromfile_overall'] = above_chance d['ALPHA_fromfile_run'] = alpha_per_run #%% Extract epochs from EEG data prefilter = 0 if subjID in ['07', '08', '11']: n_samples_fs500 = 550 # Number of samples to extract for each epoch, sampling frequency 500 n_samples_fs100 = int( 550 / 5) # Number of samples, sampling frequency 100 (resampled) else: n_samples_fs500 = 450 n_samples_fs100 = int(450 / 5) e = extractEpochs_tmin(EEGfile, markerFile, prefilter=prefilter, marker1=0, n_samples=n_samples_fs500) cat = extractCat(idxFile, exp_type='fused') # MNE info files info_fs500 = create_info_mne(reject_ch=0, sfreq=500) info_fs100 = create_info_mne(reject_ch=1, sfreq=100) #%% Run NF RT offline analysis stable_blocks0 = e[:600, :, :] # Fi+st run stable_blocks1 = np.zeros((600, n_channels, n_samples_fs100)) y = np.array([int(x) for x in cat]) y_run = y[:600] pred_prob_train = np.zeros((n_it * 600, 2)) pred_prob_test = np.zeros((n_it * 200, 2)) # Prediction probability pred_prob_test_corr = np.zeros( (n_it * 200, 2)) # Prediction probability, corrected for classifier bias alpha_test = np.zeros((n_it * 200)) clf_output_test = np.zeros((n_it * 200)) train_acc = np.zeros(n_it) c_test = 0 c = 0 offset = 0 y_pred_test1 = np.zeros(5 * 200) y_test_feedback = np.concatenate( (y[600:800], y[1000:1200], y[1400:1600], y[1800:2000], y[2200:2400])) Y_train = np.zeros((n_it, 600)) Y_run = np.zeros((n_it, 600)) val = 1 # Offset validation offset_pred = 0 # Offset prediction offset_Pred = [] # Score = np.zeros((n_it,3)) epochs_fb = np.zeros((200, 23, n_samples_fs100)) # Epochs feedback for b in range(n_it): for t in range(stable_blocks0.shape[0]): epoch = stable_blocks0[t, :, :] epoch = preproc1epoch(epoch, info_fs500, SSP=False, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) stable_blocks1[t + offset, :, :] = epoch c += 1 projs1, stable_blocksSSP1 = applySSP( stable_blocks1, info_fs100, threshold=threshold) # Apply SSP on stable blocks # Average training blocks after SSP stable_blocksSSP1 = average_stable(stable_blocksSSP1) if val == 1: # Test for offset classifier bias if b > 0: # Runs after first run stable_blocksSSP1_append = np.append(stable_blocksSSP1, epochs_fb, axis=0) fb_start = (b - 1) * 200 y_run_append = np.append(y_run, y_test_feedback[fb_start:fb_start + 200], axis=0) clf, offset_pred = trainLogReg_cross2(stable_blocksSSP1_append, y_run_append) else: clf, offset_pred = trainLogReg_cross(stable_blocksSSP1, y_run) # First run offset_Pred.append(offset_pred) #Score[b,:]=score print('Offset estimated to ' + str(offset_pred)) else: clf = trainLogReg(stable_blocksSSP1, y_run) Y_run[b, :] = y_run y_pred_train1 = np.zeros(len(y_run)) offset_pred = np.min([np.max([offset_pred, -0.25]), 0.25 ]) / 2 # Limit offset correction to abs(0.125) # Training accuracy based on the RT classifier for t in range(len(y_run)): epoch_t = stable_blocksSSP1[t, :, :] pred_prob_train[t, :], y_pred_train1[t] = testEpoch(clf, epoch_t) Y_train[b, :] = y_pred_train1 train_acc[b] = len( np.where(np.array(y_pred_train1[0:len(y_run)]) == np.array(y_run)) [0]) / len(y_run) stable_blocks1 = stable_blocks1[200:, :, :] stable_blocks1 = np.concatenate( (stable_blocks1, np.zeros((200, n_channels, n_samples_fs100))), axis=0) s_begin = 800 + b * 400 offset = 400 # Indexing offset for EEG data and y stable_blocks0 = e[s_begin:s_begin + 200, :, :] y_run = np.concatenate((y_run[200:], y[s_begin:s_begin + 200])) # Test accuracy of RT epochs for t in range(200): print('Testing epoch number: ', c) epoch = e[c, :, :] epoch = preproc1epoch(epoch, info_fs500, projs=projs1, SSP=True, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) if t > 0: epoch = (epoch + epoch_prev) / 2 pred_prob_test[c_test, :], y_pred_test1[c_test] = testEpoch( clf, epoch) # Correct the prediction bias offset pred_prob_test_corr[c_test, 0] = np.min( [np.max([pred_prob_test[c_test, 0] + offset_pred, 0]), 1]) pred_prob_test_corr[c_test, 1] = np.min( [np.max([pred_prob_test[c_test, 1] - offset_pred, 0]), 1]) clf_output = pred_prob_test_corr[ c_test, int(y[c])] - pred_prob_test_corr[c_test, int(y[c] - 1)] clf_output_test[ c_test] = clf_output # Save classifier output for correlation checks alpha_test[c_test] = sigmoid( clf_output ) # Convert corrected classifier output to an alpha value using a sigmoid transfer function epoch_prev = epoch epochs_fb[t, :, :] = epoch c += 1 c_test += 1 above_chance_offline = len( np.where((np.array(alpha_test[:c_test]) > 0.5))[0]) / len( alpha_test[:c_test]) print('Above chance alpha (corrected): ' + str(above_chance_offline)) score = metrics.accuracy_score(y_test_feedback[:c_test], y_pred_test1[:c_test]) print('Accuracy score (uncorrected): ' + str(score)) # Test score per run a_per_run = np.zeros((n_it)) score_per_run = np.zeros((n_it)) j = 0 for run in range(n_it): score_per_run[run] = metrics.accuracy_score( y_test_feedback[run * 200:(run + 1) * 200], y_pred_test1[run * 200:(run + 1) * 200]) a_per_run[run] = ( len(np.where((np.array(alpha_test[j:j + 200]) > 0.5))[0]) / 200) j += 200 print('Alpha, corrected, above chance per run: ' + str(a_per_run)) print('Score, uncorrected, per run: ' + str(score_per_run)) d['RT_train_acc'] = train_acc d['RT_test_acc_corr'] = above_chance_offline d['RT_test_acc_corr_run'] = a_per_run d['RT_test_acc_uncorr'] = score d['RT_test_acc_uncorr_run'] = score_per_run #%% Analyze RT session block-wise d['ALPHA_test'] = alpha_test d['CLFO_test'] = clf_output_test #%% Compare RT alpha with RT offline alpha alphan = np.asarray(alpha) alpha_corr = (np.corrcoef(alphan[1:], alpha_test[:999]))[0][1] # Shifted with one d['ALPHA_correlation'] = alpha_corr if alpha_corr >= 0.98: d['GROUP'] = 1 # 1 for NF group if alpha_corr < 0.98: d['GROUP'] = 0 # 0 for control group # Classifier output correlation has to be checked offline, because clf_output values are computed offline (RT pipeline) #np.corrcoef(clf_output_test, clf_output_test13) #plt.plot(alphan) #plt.plot(alpha_test) # ## Compare alphas from file and offline classification #plt.plot(np.arange(999),alphan[1:]) #blue, en foran #plt.plot(np.arange(1000),alpha_test) # ## Run 1 #plt.plot(np.arange(200),alphan[1:201]) #starts at 0.5 #plt.plot(np.arange(200),alpha_test[0:200]) #matches #%% Confusion matrices n_it_trials = n_it * 200 correct = (y_test_feedback[:n_it_trials] == y_pred_test1[:n_it_trials]) alpha_test_c = np.copy(alpha_test) alpha_test_c[alpha_test_c > 0.5] = True # 1 is a correctly predicted alpha_test_c[alpha_test_c < 0.5] = False alpha_predcat = np.argmax(pred_prob_test_corr, axis=1) conf_uncorr = confusion_matrix(y_test_feedback[:n_it_trials], y_pred_test1[:n_it_trials]) conf_corr = confusion_matrix(y_test_feedback[:n_it_trials], alpha_predcat[:n_it_trials]) # Separate into scenes and faces accuracy scene_acc = conf_corr[0, 0] / (conf_corr[0, 0] + conf_corr[0, 1]) face_acc = conf_corr[1, 1] / (conf_corr[1, 0] + conf_corr[1, 1]) d['RT_correct_NFtest_pred'] = correct d['RT_conf_corr'] = conf_corr d['RT_conf_uncorr'] = conf_uncorr d['RT_scene_acc'] = scene_acc d['RT_face_acc'] = face_acc # Training confusion matrices conf_train = [] for b in range(n_it): conf_train.append(confusion_matrix(Y_run[b, :], Y_train[b, :])) d['RT_conf_train'] = conf_train #%% Training on stable blocks only - leave one block out CV offset_pred_lst = [] c_test = 0 no_sb = 8 + 4 * n_it # Number stable blocks block_len = 50 pred_prob_test = np.zeros( (no_sb * block_len, 2)) # Prediction probability test. Block length of 50 trials pred_prob_test_corr = np.zeros( (no_sb * block_len, 2)) # Prediction probability test, corrected for bias alpha_test = np.zeros( (no_sb * block_len)) # Alpha values for stable blocks stable_blocks_fbrun = np.concatenate([ e[400 + n * 400:600 + n * 400] for n in range(n_it) ]) # Stable blocks feedback run y_stable_blocks_fbrun = np.concatenate( [y[400 + n * 400:600 + n * 400] for n in range(n_it)]) stable_blocks = np.concatenate((e[:400, :, :], stable_blocks_fbrun)) y_stable_blocks = np.concatenate((y[:400], y_stable_blocks_fbrun)) y_pred = np.zeros(no_sb * block_len) for sb in range(no_sb): val_indices = range(sb * block_len, (sb + 1) * block_len) # Validation block index stable_blocks_val = stable_blocks[val_indices] y_val = y_stable_blocks[val_indices] stable_blocks_train = np.delete(stable_blocks, val_indices, axis=0) y_train = np.delete(y_stable_blocks, val_indices) stable_blocks_train_prep = np.zeros( (len(y_train), 23, n_samples_fs100)) for t in range(stable_blocks_train.shape[0]): epoch = stable_blocks_train[t, :, :] epoch = preproc1epoch(epoch, info_fs500, SSP=False, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) stable_blocks_train_prep[t, :, :] = epoch projs1, stable_blocksSSP_train = applySSP(stable_blocks_train_prep, info_fs100, threshold=threshold) # Average after SSP correction stable_blocksSSP_train = average_stable(stable_blocksSSP_train) clf, offset_pred = trainLogReg_cross_offline( stable_blocksSSP_train, y_train) #cur. in EEG_classification offset_pred = np.min([np.max([offset_pred, -0.25]), 0.25]) / 2 offset_pred_lst.append(offset_pred) # Test epochs in validation block. Preprocessing and testing epoch-wise for t in range(block_len): epoch = stable_blocks_val[t, :, :] epoch = preproc1epoch(epoch, info_fs500, projs=projs1, SSP=True, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) if t > 0: epoch = (epoch + epoch_prev) / 2 pred_prob_test[c_test, :], y_pred[c_test] = testEpoch(clf, epoch) # Correct the prediction bias offset pred_prob_test_corr[c_test, 0] = np.min( [np.max([pred_prob_test[c_test, 0] + offset_pred, 0]), 1]) pred_prob_test_corr[c_test, 1] = np.min( [np.max([pred_prob_test[c_test, 1] - offset_pred, 0]), 1]) clf_output = pred_prob_test_corr[ c_test, int(y_val[t])] - pred_prob_test_corr[c_test, int(y_val[t] - 1)] alpha_test[c_test] = sigmoid(clf_output) epoch_prev = epoch c_test += 1 print('No c_test: ' + str(c_test) + 'out of ' + str(no_sb * block_len)) above_chance_train = len( np.where((np.array(alpha_test[:c_test]) > 0.5))[0]) / len( alpha_test[:c_test]) print('Above chance alpha train (corrected): ' + str(above_chance_train)) score = metrics.accuracy_score(y_stable_blocks, y_pred) d['LOBO_stable_train_offsets'] = offset_pred_lst d['LOBO_stable_train_acc_corr'] = above_chance_train d['LOBO_stable_train_acc_uncorr'] = score #%% Extract data for MNE plots # Perform preprocessing and SSP on all the stable blocks. stable_blocks_plot = np.zeros( (len(y_stable_blocks), n_channels, n_samples_fs100)) for t in range(stable_blocks.shape[0]): epoch = stable_blocks[t, :, :] epoch = preproc1epoch(epoch, info_fs500, SSP=False, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) stable_blocks_plot[t, :, :] = epoch projs1, stable_blocksSSP_plot, p_variance = applySSP_forplot( stable_blocks_plot, info_fs100, threshold=threshold, add_events=y_stable_blocks) d['MNE_stable_blocks_SSP'] = stable_blocksSSP_plot d['MNE_stable_blocks_SSP_projvariance'] = p_variance d['MNE_y_stable_blocks'] = y_stable_blocks #%% Confusion matrices - stable blocks accuracy, LOBO # y_stable_blocks has the correct y vals, y_pred has the predicted vals. For uncorrected prediction. # Uncorrected correct = (y_stable_blocks == y_pred) conf_train_stable_uncorr = confusion_matrix(y_stable_blocks, y_pred) # Separate into scenes and faces accuracy scene_acc_uncorr = conf_train_stable_uncorr[0, 0] / ( conf_train_stable_uncorr[0, 0] + conf_train_stable_uncorr[0, 1]) face_acc_uncorr = conf_train_stable_uncorr[1, 1] / ( conf_train_stable_uncorr[1, 0] + conf_train_stable_uncorr[1, 1]) # Corrected alpha_test_c = np.copy(alpha_test) alpha_test_c[alpha_test_c > 0.5] = True # 1 is a correctly predicted alpha_test_c[alpha_test_c < 0.5] = False alpha_predcat = np.argmax(pred_prob_test_corr, axis=1) conf_train_stable = confusion_matrix(y_stable_blocks, alpha_predcat) # Separate into scenes and faces accuracy scene_acc = conf_train_stable[0, 0] / (conf_train_stable[0, 0] + conf_train_stable[0, 1]) face_acc = conf_train_stable[1, 1] / (conf_train_stable[1, 0] + conf_train_stable[1, 1]) d['LOBO_stable_conf_uncorr'] = conf_train_stable_uncorr d['LOBO_stable_scene_acc_uncorr'] = scene_acc_uncorr d['LOBO_stable_face_acc_uncorr'] = face_acc_uncorr d['LOBO_stable_conf_corr'] = conf_train_stable d['LOBO_stable_scene_acc_corr'] = scene_acc d['LOBO_stable_face_acc_corr'] = face_acc #%% Training on stable blocks only - leave one run out CV. The first run is not used as test set, only for training. offset_pred_lst = [] c_test = 0 no_sb = 8 + 4 * n_it # Number stable blocks block_len = 50 pred_prob_test = np.zeros( (no_sb * block_len, 2)) # Prediction probability test. Block length of 50 trials pred_prob_test_corr = np.zeros( (no_sb * block_len, 2)) # Prediction probability test, corrected for bias alpha_test = np.zeros( (no_sb * block_len)) # Alpha values for stable blocks stable_blocks_fbrun = np.concatenate([ e[400 + n * 400:600 + n * 400] for n in range(n_it) ]) # Stable blocks feedback run y_stable_blocks_fbrun = np.concatenate( [y[400 + n * 400:600 + n * 400] for n in range(n_it)]) stable_blocks = np.concatenate((e[:400, :, :], stable_blocks_fbrun)) y_stable_blocks = np.concatenate((y[:400], y_stable_blocks_fbrun)) y_pred = np.zeros(no_sb * block_len) for r in range(n_it): # 5 runs print('Run no: ', r) val_indices = range((r + 2) * 200, ((r + 2) * 200) + 200) # Validation block index stable_blocks_val = stable_blocks[val_indices] y_val = y_stable_blocks[val_indices] stable_blocks_train = np.delete(stable_blocks, val_indices, axis=0) y_train = np.delete(y_stable_blocks, val_indices) stable_blocks_train_prep = np.zeros( (len(y_train), 23, n_samples_fs100)) for t in range(stable_blocks_train.shape[0]): epoch = stable_blocks_train[t, :, :] epoch = preproc1epoch(epoch, info_fs500, SSP=False, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) stable_blocks_train_prep[t, :, :] = epoch projs1, stable_blocksSSP_train = applySSP(stable_blocks_train_prep, info_fs100, threshold=threshold) # Average after SSP correction stable_blocksSSP_train = average_stable(stable_blocksSSP_train) clf, offset_pred = trainLogReg_cross_offline( stable_blocksSSP_train, y_train) #cur. in EEG_classification offset_pred = np.min([np.max([offset_pred, -0.25]), 0.25]) / 2 offset_pred_lst.append(offset_pred) # Test epochs in validation run. Preprocessing and testing epoch-wise for t in range(len(val_indices)): epoch = stable_blocks_val[t, :, :] epoch = preproc1epoch(epoch, info_fs500, projs=projs1, SSP=True, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) if t > 0: epoch = (epoch + epoch_prev) / 2 pred_prob_test[c_test, :], y_pred[c_test] = testEpoch(clf, epoch) # Correct the prediction bias offset pred_prob_test_corr[c_test, 0] = np.min( [np.max([pred_prob_test[c_test, 0] + offset_pred, 0]), 1]) pred_prob_test_corr[c_test, 1] = np.min( [np.max([pred_prob_test[c_test, 1] - offset_pred, 0]), 1]) clf_output = pred_prob_test_corr[ c_test, int(y_val[t])] - pred_prob_test_corr[c_test, int(y_val[t] - 1)] alpha_test[c_test] = sigmoid(clf_output) epoch_prev = epoch c_test += 1 print('No c_test: ' + str(c_test) + ' out of ' + str(no_sb * block_len)) above_chance_train = len( np.where((np.array(alpha_test[:c_test]) > 0.5))[0]) / len( alpha_test[:c_test]) print('Above chance alpha train (corrected): ' + str(above_chance_train)) score = metrics.accuracy_score(y_stable_blocks, y_pred) d['LORO_stable_train_offsets_stable'] = offset_pred_lst d['LORO_stable_acc_corr'] = above_chance_train d['LORO_stable_acc_uncorr'] = score #%% Extract RT epochs (non-averaged) for plots and analysis stable_blocks0 = e[:600, :, :] # First run + stable in run 2 stable_blocks1 = np.zeros((600, n_channels, n_samples_fs100)) y = np.array([int(x) for x in cat]) y_run = y[:600] c_test = 0 c = 0 offset = 0 y_pred_test1 = np.zeros(5 * 200) y_test_feedback = np.concatenate( (y[600:800], y[1000:1200], y[1400:1600], y[1800:2000], y[2200:2400])) epochs_fb_nonavg = np.zeros((1000, 23, n_samples_fs100)) # Epochs feedback # epochs_fb_avg = np.zeros((1000,23,n_samples_fs100)) # Epochs feedback for b in range(n_it): for t in range(stable_blocks0.shape[0]): epoch = stable_blocks0[t, :, :] epoch = preproc1epoch(epoch, info_fs500, SSP=False, reject=None, mne_reject=0, reject_ch=reject_ch, flat=None, bad_channels=None, opt_detrend=1) stable_blocks1[t + offset, :, :] = epoch c += 1 projs1, stable_blocksSSP1 = applySSP( stable_blocks1, info_fs100, threshold=threshold) # Apply SSP on stable blocks stable_blocks1 = stable_blocks1[200:, :, :] stable_blocks1 = np.concatenate( (stable_blocks1, np.zeros((200, n_channels, n_samples_fs100))), axis=0) s_begin = 800 + b * 400 offset = 400 # Indexing offset for EEG data and y stable_blocks0 = e[s_begin:s_begin + 200, :, :] y_run = np.concatenate((y_run[200:], y[s_begin:s_begin + 200])) # Append RT epochs for t in range(200): print('Epoch number: ', c) epoch1 = e[c, :, :] epoch1 = preproc1epoch(epoch1, info_fs500, projs=projs1, SSP=True, reject=reject, mne_reject=mne_reject, reject_ch=reject_ch, flat=flat, bad_channels=bad_channels, opt_detrend=opt_detrend) # For averaging epochs: # if t == 0: # epoch_avg = epoch1 # # if t > 0: # epoch_avg = (epoch1+epoch_prev)/2 # Checked again 17 April that this is legit # # epoch_prev = epoch_avg # # epochs_fb_avg[c_test,:,:] = epoch_avg epochs_fb_nonavg[c_test, :, :] = epoch1 c += 1 c_test += 1 # Create MNE objects events_list = y_test_feedback event_id = dict(scene=0, face=1) n_epochs = len(events_list) events_list = [int(i) for i in events_list] events = np.c_[np.arange(n_epochs), np.zeros(n_epochs, int), events_list] eRT_nonavg = mne.EpochsArray(epochs_fb_nonavg, info=info_fs100, events=events, event_id=event_id, tmin=-0.1, baseline=None) # eRT_avg = mne.EpochsArray(epochs_fb_avg, info=info_fs100, events=events,event_id=event_id,tmin=-0.1,baseline=None) d['MNE_RT_epochs_fb_nonavg'] = eRT_nonavg # d['MNE_RT_epochs_fb_avg'] = eRT_avg d['MNE_y_test_feedback'] = y_test_feedback if plot_MNE == True: # Creating a dict of lists: Condition 0 and condition 1 with evoked arrays. evoked_array_c0 = [] evoked_array_c1 = [] eRT_get = eRT_nonavg.get_data() for idx, cat in enumerate(events_list): if cat == 0: evoked_array_c0.append( mne.EvokedArray(eRT_get[idx], info_fs100, tmin=-0.1, comment=cat)) # Scenes 0 print if cat == 1: evoked_array_c1.append( mne.EvokedArray(eRT_get[idx], info_fs100, tmin=-0.1, comment=cat)) # Faces 1 e_dict = {} e_dict['0'] = evoked_array_c0 e_dict['1'] = evoked_array_c1 #colors = 'red', 'blue' #mne.viz.plot_compare_evokeds(e_dict,ci=0.95,picks=[7],colors=colors) #%% Save pckl file pkl_arr = [d] print('Finished running test and train analyses for subject: ' + str(subjID)) # PICKLE TIME fname = '09May_subj_' + str(subjID) + '.pkl' with open(fname, 'wb') as fout: pickle.dump(pkl_arr, fout)
ax.set_ylabel('AUC') # Area Under the Curve ax.legend() ax.axvline(.0, color='k', linestyle='-') ax.set_title('Sensor space decoding') plt.show() ############################################################################### # You can retrieve the spatial filters and spatial patterns if you explicitly # use a LinearModel clf = make_pipeline(StandardScaler(), LinearModel(LogisticRegression(solver='lbfgs'))) time_decod = SlidingEstimator(clf, n_jobs=1, scoring='roc_auc', verbose=True) time_decod.fit(X, y) coef = get_coef(time_decod, 'patterns_', inverse_transform=True) evoked = mne.EvokedArray(coef, epochs.info, tmin=epochs.times[0]) joint_kwargs = dict(ts_args=dict(time_unit='s'), topomap_args=dict(time_unit='s')) evoked.plot_joint(times=np.arange(0., .500, .100), title='patterns', **joint_kwargs) ############################################################################### # Temporal Generalization # ----------------------- # # This runs the analysis used in [1]_ and further detailed in [2]_ # # The idea is to fit the models on each time instant and see how it # generalizes to any other time point.
contrasts = list() contrasts.append(glm.design.Contrast([1, 0, 0, 0, 0], 'grand mean')) contrasts.append(glm.design.Contrast([0, 1, 0, 0, 0], 'neutral')) contrasts.append(glm.design.Contrast([0, 0, 1, 0, 0], 'cued')) contrasts.append(glm.design.Contrast([0, 0, 0, 1, 0], 'DT')) contrasts.append(glm.design.Contrast([0, -1, 1, 0, 0], 'cued vs neutral')) contrasts.append(glm.design.Contrast([0, 0, 0, 0, 1], 'DT x pside')) glmdes = glm.design.GLMDesign.initialise(regressors, contrasts) glmdes.plot_summary() model = glm.fit.OLSModel(glmdes, glmdata) #grand mean tl_betas_grandmean = mne.EvokedArray(data=np.squeeze(model.copes[0, :, :]), info=epoch.info, tmin=epoch.tmin, nave=epoch.average().nave) tl_betas_grandmean.apply_baseline((None, None)).plot_joint( picks='eeg', times=np.arange(0, 0.5, 0.1), topomap_args=dict(outlines='head', contours=0)) #this baseline demeans the entire epoch tl_betas_grandmean.plot_joint( times=np.arange(0, 0.5, 0.1), topomap_args=dict(outlines='head', contours=0) ) #can add picks=['C3', 'C4', 'C5', 'C6'] to look at lateralised motor electrodes tl_betas_grandmean.save(fname=op.join( param['path'], 'glms', 'response', 'wmConfidence_' + param['subid'] + '_resplocked_tl_grandmean_betas-ave.fif')) del (tl_betas_grandmean)
def analyzeOffline(subjID): ''' ''' # Initialize conditions for preprocessing of epochs (preproc1epoch from EEG_analysis_RT) reject_ch = 1 # Rejection of nine predefined channels reject = None # Rejection of channels, either manually defined or based on MNE analysis mne_reject = 0 flat = None # Input for MNE rejection bad_channels = None # Input for manual rejection of channels opt_detrend = 1 # Temporal EEG detrending (linear) if reject_ch == 1: n_channels = 23 if reject_ch == 0: n_channels = 32 # Initialize conditions for SSP rejection (applySSP from EEG_analysis_RT) threshold = 0.1 # SSP projection variance threshold # Initialize dictionary for saving outputs d = {} d['subjID'] = subjID plot_MNE = 0 EEGfile, markerFile, idxFile, alphaFile, n_it = findSubjectFiles(subjID,manual_n_it=None) #%% Test RT alpha per run alpha,marker = extractAlpha(alphaFile) above_chance = len(np.where((np.array(alpha)>0.5))[0])/len(alpha) alpha_per_run = np.zeros((n_it)) j = 0 for ii in range(n_it): alpha_per_run[ii] = len(np.where((np.array(alpha[j:j+200])>0.5))[0])/200 j += 200 d['ALPHA_fromfile_overall'] = above_chance d['ALPHA_fromfile_run'] = alpha_per_run #%% Extract epochs from EEG data prefilter = 0 n_samples_fs500 = 550 # Number of samples to extract for each epoch, sampling frequency 500 n_samples_fs100 = int(550/5) # Number of samples, sampling frequency 100 (resampled) e = extractEpochs_tmin(EEGfile,markerFile,prefilter=prefilter,marker1=0,n_samples=n_samples_fs500) cat = extractCat(idxFile,exp_type='fused') # MNE info files info_fs500 = create_info_mne(reject_ch=0,sfreq=500) info_fs100 = create_info_mne(reject_ch=1,sfreq=100) #%% Run NF RT offline analysis stable_blocks0 = e[:600,:,:] # First run stable_blocks1 = np.zeros((600,n_channels,n_samples_fs100)) y = np.array([int(x) for x in cat]) y_run = y[:600] pred_prob_train = np.zeros((n_it*600,2)) pred_prob_test = np.zeros((n_it*200,2)) # Prediction probability pred_prob_test_corr = np.zeros((n_it*200,2)) # Prediction probability, corrected for classifier bias alpha_test = np.zeros((n_it*200)) clf_output_test = np.zeros((n_it*200)) train_acc = np.zeros(n_it) c_test = 0 c = 0 offset = 0 y_pred_test1 = np.zeros(5*200) y_test_feedback = np.concatenate((y[600:800],y[1000:1200],y[1400:1600],y[1800:2000],y[2200:2400])) Y_train = np.zeros((n_it,600)) Y_run = np.zeros((n_it,600)) val = 1 # Offset validation offset_pred = 0 # Offset prediction offset_Pred = [] # Score = np.zeros((n_it,3)) epochs_fb = np.zeros((200,23,n_samples_fs100)) # Epochs feedback for b in range(n_it): for t in range(stable_blocks0.shape[0]): epoch = stable_blocks0[t,:,:] epoch = preproc1epoch(epoch,info_fs500,SSP=False,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) stable_blocks1[t+offset,:,:] = epoch c += 1 projs1,stable_blocksSSP1 = applySSP(stable_blocks1,info_fs100,threshold=threshold) # Apply SSP on stable blocks # Average training blocks after SSP stable_blocksSSP1 = average_stable(stable_blocksSSP1) if val == 1: # Test for offset classifier bias if b > 0: # Runs after first run stable_blocksSSP1_append = np.append(stable_blocksSSP1,epochs_fb,axis=0) fb_start = (b-1)*200 y_run_append = np.append(y_run,y_test_feedback[fb_start:fb_start+200],axis=0) clf,offset_pred = trainLogReg_cross2(stable_blocksSSP1_append,y_run_append) else: clf,offset_pred = trainLogReg_cross(stable_blocksSSP1,y_run) # First run offset_Pred.append(offset_pred) #Score[b,:]=score print('Offset estimated to '+str(offset_pred)) else: clf = trainLogReg(stable_blocksSSP1,y_run) Y_run[b,:]=y_run y_pred_train1 = np.zeros(len(y_run)) offset_pred = np.min([np.max([offset_pred,-0.25]),0.25])/2 # Limit offset correction to abs(0.125) # Training accuracy based on the RT classifier for t in range(len(y_run)): epoch_t = stable_blocksSSP1[t,:,:] pred_prob_train[t,:],y_pred_train1[t] = testEpoch(clf,epoch_t) Y_train[b,:]=y_pred_train1 train_acc[b] = len(np.where(np.array(y_pred_train1[0:len(y_run)])==np.array(y_run))[0])/len(y_run) stable_blocks1 = stable_blocks1[200:,:,:] stable_blocks1 = np.concatenate((stable_blocks1,np.zeros((200,n_channels,n_samples_fs100))),axis=0) s_begin = 800+b*400 offset = 400 # Indexing offset for EEG data and y stable_blocks0 = e[s_begin:s_begin+200,:,:] y_run = np.concatenate((y_run[200:],y[s_begin:s_begin+200])) # Test accuracy of RT epochs for t in range(200): print('Testing epoch number: ',c) epoch = e[c,:,:] epoch = preproc1epoch(epoch,info_fs500,projs=projs1,SSP=True,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) if t > 0: epoch = (epoch+epoch_prev)/2 pred_prob_test[c_test,:],y_pred_test1[c_test] = testEpoch(clf,epoch) # Correct the prediction bias offset pred_prob_test_corr[c_test,0] = np.min([np.max([pred_prob_test[c_test,0]+offset_pred,0]),1]) pred_prob_test_corr[c_test,1] = np.min([np.max([pred_prob_test[c_test,1]-offset_pred,0]),1]) clf_output = pred_prob_test_corr[c_test,int(y[c])]-pred_prob_test_corr[c_test,int(y[c]-1)] clf_output_test[c_test] = clf_output # Save classifier output for correlation checks alpha_test[c_test] = sigmoid(clf_output) # Convert corrected classifier output to an alpha value using a sigmoid transfer function epoch_prev = epoch epochs_fb[t,:,:] = epoch c += 1 c_test += 1 above_chance_offline = len(np.where((np.array(alpha_test[:c_test])>0.5))[0])/len(alpha_test[:c_test]) print('Above chance alpha (corrected): ' + str(above_chance_offline)) score = metrics.accuracy_score(y_test_feedback[:c_test], y_pred_test1[:c_test]) print('Accuracy score (uncorrected): ' + str(score)) # Test score per run a_per_run = np.zeros((n_it)) score_per_run = np.zeros((n_it)) j = 0 for run in range(n_it): score_per_run[run] = metrics.accuracy_score(y_test_feedback[run*200:(run+1)*200], y_pred_test1[run*200:(run+1)*200]) a_per_run[run] = (len(np.where((np.array(alpha_test[j:j+200])>0.5))[0])/200) j += 200 print('Alpha, corrected, above chance per run: ' + str(a_per_run)) print('Score, uncorrected, per run: ' + str(score_per_run)) d['RT_train_acc'] = train_acc d['RT_test_acc_corr'] = above_chance_offline d['RT_test_acc_corr_run'] = a_per_run d['RT_test_acc_uncorr'] = score d['RT_test_acc_uncorr_run'] = score_per_run #%% Compare RT alpha with RT offline alpha alphan = np.asarray(alpha) alpha_corr = (np.corrcoef(alphan[1:], alpha_test[:999]))[0][1] # Shifted with one d['ALPHA_correlation'] = alpha_corr if alpha_corr >= 0.98: d['GROUP'] = 1 # 1 for NF group if alpha_corr < 0.98: d['GROUP'] = 0 # 0 for control group # Classifier output correlation has to be checked offline, because clf_output values are computed offline (RT pipeline) #np.corrcoef(clf_output_test, clf_output_test13) #plt.plot(alphan) #plt.plot(alpha_test) # ## Compare alphas from file and offline classification #plt.plot(np.arange(999),alphan[1:]) #blue, en foran #plt.plot(np.arange(1000),alpha_test) # ## Run 1 #plt.plot(np.arange(200),alphan[1:201]) #starts at 0.5 #plt.plot(np.arange(200),alpha_test[0:200]) #matches #%% Confusion matrices n_it_trials = n_it*200 correct = (y_test_feedback[:n_it_trials]==y_pred_test1[:n_it_trials]) alpha_test_c = np.copy(alpha_test) alpha_test_c[alpha_test_c > 0.5] = True # 1 is a correctly predicted alpha_test_c[alpha_test_c < 0.5] = False alpha_predcat = np.argmax(pred_prob_test_corr,axis=1) conf_uncorr = confusion_matrix(y_test_feedback[:n_it_trials],y_pred_test1[:n_it_trials]) conf_corr = confusion_matrix(y_test_feedback[:n_it_trials],alpha_predcat[:n_it_trials]) # Separate into scenes and faces accuracy scene_acc = conf_corr[0,0]/(conf_corr[0,0]+conf_corr[0,1]) face_acc = conf_corr[1,1]/(conf_corr[1,0]+conf_corr[1,1]) d['RT_correct_NFtest_pred'] = correct d['RT_conf_corr'] = conf_corr d['RT_conf_uncorr'] = conf_uncorr d['RT_scene_acc'] = scene_acc d['RT_face_acc'] = face_acc # Training confusion matrices conf_train = [] for b in range(n_it): conf_train.append(confusion_matrix(Y_run[b,:], Y_train[b,:])) d['RT_conf_train'] = conf_train #%% Training on stable blocks only - leave one block out CV offset_pred_lst = [] c_test = 0 no_sb = 8+4*n_it # Number stable blocks block_len = 50 pred_prob_test = np.zeros((no_sb*block_len,2)) # Prediction probability test. Block length of 50 trials pred_prob_test_corr = np.zeros((no_sb*block_len,2)) # Prediction probability test, corrected for bias alpha_test = np.zeros((no_sb*block_len)) # Alpha values for stable blocks stable_blocks_fbrun = np.concatenate([e[400+n*400:600+n*400] for n in range(n_it)]) # Stable blocks feedback run y_stable_blocks_fbrun = np.concatenate([y[400+n*400:600+n*400] for n in range(n_it)]) stable_blocks = np.concatenate((e[:400,:,:], stable_blocks_fbrun)) y_stable_blocks = np.concatenate((y[:400], y_stable_blocks_fbrun)) y_pred = np.zeros(no_sb*block_len) for sb in range(no_sb): val_indices = range(sb*block_len,(sb+1)*block_len) # Validation block index stable_blocks_val = stable_blocks[val_indices] y_val = y_stable_blocks[val_indices] stable_blocks_train = np.delete(stable_blocks, val_indices, axis=0) y_train = np.delete(y_stable_blocks, val_indices) stable_blocks_train_prep = np.zeros((len(y_train),23,n_samples_fs100)) for t in range(stable_blocks_train.shape[0]): epoch = stable_blocks_train[t,:,:] epoch = preproc1epoch(epoch,info_fs500,SSP=False,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) stable_blocks_train_prep[t,:,:] = epoch projs1,stable_blocksSSP_train = applySSP(stable_blocks_train_prep,info_fs100,threshold=threshold) # Average after SSP correction stable_blocksSSP_train = average_stable(stable_blocksSSP_train) clf,offset_pred = trainLogReg_cross_offline(stable_blocksSSP_train,y_train) #cur. in EEG_classification offset_pred = np.min([np.max([offset_pred,-0.25]),0.25])/2 offset_pred_lst.append(offset_pred) # Test epochs in validation block. Preprocessing and testing epoch-wise for t in range(block_len): epoch = stable_blocks_val[t,:,:] epoch = preproc1epoch(epoch,info_fs500,projs=projs1,SSP=True,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) if t > 0: epoch = (epoch+epoch_prev)/2 pred_prob_test[c_test,:],y_pred[c_test] = testEpoch(clf,epoch) # Correct the prediction bias offset pred_prob_test_corr[c_test,0] = np.min([np.max([pred_prob_test[c_test,0]+offset_pred,0]),1]) pred_prob_test_corr[c_test,1] = np.min([np.max([pred_prob_test[c_test,1]-offset_pred,0]),1]) clf_output = pred_prob_test_corr[c_test,int(y_val[t])]-pred_prob_test_corr[c_test,int(y_val[t]-1)] alpha_test[c_test] = sigmoid(clf_output) epoch_prev = epoch c_test += 1 print('No c_test: ' + str(c_test) + 'out of ' + str(no_sb*block_len)) above_chance_train = len(np.where((np.array(alpha_test[:c_test])>0.5))[0])/len(alpha_test[:c_test]) print('Above chance alpha train (corrected): ' + str(above_chance_train)) score = metrics.accuracy_score(y_stable_blocks, y_pred) d['LOBO_stable_train_offsets'] = offset_pred_lst d['LOBO_stable_train_acc_corr'] = above_chance_train d['LOBO_stable_train_acc_uncorr'] = score #%% Extract data for MNE plots # Perform preprocessing and SSP on all the stable blocks. stable_blocks_plot = np.zeros((len(y_stable_blocks),n_channels,n_samples_fs100)) for t in range(stable_blocks.shape[0]): epoch = stable_blocks[t,:,:] epoch = preproc1epoch(epoch,info_fs500,SSP=False,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) stable_blocks_plot[t,:,:] = epoch projs1,stable_blocksSSP_plot,p_variance = applySSP_forplot(stable_blocks_plot,info_fs100,threshold=threshold,add_events=y_stable_blocks) d['MNE_stable_blocks_SSP'] = stable_blocksSSP_plot d['MNE_stable_blocks_SSP_projvariance'] = p_variance d['MNE_y_stable_blocks'] = y_stable_blocks if plot_MNE == True: print('Making a lot of MNE plots!') #%% Adding events manually to epochs *also implemented in applySSP_forplot* stable_blocksSSP_get = stable_blocksSSP_plot.get_data() events_list = y_stable_blocks event_id = dict(scene=0, face=1) n_epochs = len(events_list) events_list = [int(i) for i in events_list] events = np.c_[np.arange(n_epochs), np.zeros(n_epochs, int),events_list] epochs_events = mne.EpochsArray(stable_blocksSSP_get, info_fs100, events=events, tmin=-0.1, event_id=event_id,baseline=None) epochs_events['face'].average().plot() epochs_events['scene'].average().plot() #%% # Overall average plot, all channels stable_blocksSSP_plot.average().plot(spatial_colors=True, time_unit='s')#,picks=[7]) # Plot based on categories stable_blocksSSP_plot['face'].average().plot(spatial_colors=True, time_unit='s')#,picks=[7]) stable_blocksSSP_plot['scene'].average().plot(spatial_colors=True, time_unit='s') # Plot of the SSP projectors stable_blocksSSP_plot.average().plot_projs_topomap() # Consider adding p_variance values to the plot. # Plot the topomap of the power spectral density across epochs. stable_blocksSSP_plot.plot_psd_topomap(proj=True) stable_blocksSSP_plot['face'].plot_psd_topomap(proj=True) stable_blocksSSP_plot['scene'].plot_psd_topomap(proj=True) # Plot topomap (possibiity of adding specific times) stable_blocksSSP_plot.average().plot_topomap(proj=True) stable_blocksSSP_plot.average().plot_topomap(proj=True,times=np.linspace(0.05, 0.15, 5)) # Plot joint topomap and evoked ERP stable_blocksSSP_plot.average().plot_joint() # If manually adding a sensor plot stable_blocksSSP_plot.plot_sensors(show_names=True) # Noise covariance plot - not really sure what to make of this (yet) noise_cov = mne.compute_covariance(stable_blocksSSP_plot) fig = mne.viz.plot_cov(noise_cov, stable_blocksSSP_plot.info) # Generate list of evoked objects from condition names evokeds = [stable_blocksSSP_plot[name].average() for name in ('scene','face')] colors = 'blue', 'red' title = 'Subject \nscene vs face' # Plot evoked across all channels, comparing two categories mne.viz.plot_evoked_topo(evokeds, color=colors, title=title, background_color='w') # Compare two categories mne.viz.plot_compare_evokeds(evokeds,title=title,show_sensors=True,cmap='viridis')#,ci=True) # When multiple channels are passed, this function combines them all, to get one time course for each condition. mne.viz.plot_compare_evokeds(evokeds,title=title,show_sensors=True,cmap='viridis',ci=True,picks=[7]) # Make animation fig,anim = evokeds[0].animate_topomap(times=np.linspace(0.00, 0.79, 100),butterfly=True) # Save animation fig,anim = evokeds[0].animate_topomap(times=np.linspace(0.00, 0.79, 50),frame_rate=10,blit=False) anim.save('Brainmation.gif', writer='imagemagick', fps=10) # Sort epochs based on categories sorted_epochsarray = [stable_blocksSSP_plot[name] for name in ('scene','face')] # Plot image stable_blocksSSP_plot.plot_image() # Appending all entries in the overall epochsarray as single evoked arrays of shape (n_channels, n_times) g2 = stable_blocksSSP_plot.get_data() evoked_array = [mne.EvokedArray(entry, info_fs100,tmin=-0.1) for entry in g2] # Appending all entries in the overall epochsarray as single evoked arrays of shape (n_channels, n_times) - category info added as comments evoked_array2 = [] for idx,cat in enumerate(events_list): evoked_array2.append(mne.EvokedArray(g2[idx], info_fs100,tmin=-0.1,comment=cat)) mne.viz.plot_compare_evokeds(evoked_array2[:10]) # Plotting all the individual evoked arrays (up to 10) # Creating a dict of lists: Condition 0 and condition 1 with evoked arrays. evoked_array_c0 = [] evoked_array_c1 = [] for idx,cat in enumerate(events_list): if cat == 0: evoked_array_c0.append(mne.EvokedArray(g2[idx], info_fs100,tmin=-0.1,comment=cat)) # Scenes 0 print if cat == 1: evoked_array_c1.append(mne.EvokedArray(g2[idx], info_fs100,tmin=-0.1,comment=cat)) # Faces 1 e_dict={} e_dict['0'] = evoked_array_c0 e_dict['1'] = evoked_array_c1 # Could create these e_dicts for several people, and plot the means. Or create an e_dict with the evokeds for each person, and make the "overall" mean with individual evoked means across subjects. mne.viz.plot_compare_evokeds(e_dict,ci=0.4,picks=[7])#,title=title,show_sensors=True,cmap='viridis',ci=True) mne.viz.plot_compare_evokeds(e_dict,ci=0.8,picks=[7])#,title=title,show_sensors=True,cmap='viridis',ci=True) # Comparing mne.viz.plot_compare_evokeds(evokeds,title=title,show_sensors=True,picks=[7],ci=False) mne.viz.plot_compare_evokeds(e_dict,title=title,show_sensors=True,picks=[7],ci=True)#,,ci=True) # Based on categories, the correct epochs are added to the evoked_array_c0 and c1 #%% Manually check whether the MNE events correspond to the actual categories g1 = stable_blocksSSP_plot.get_data() g3 = g1[y_stable_blocks==True] # Faces = 1 g4 = g1[y_stable_blocks==False] # Scenes = 0 g3a = np.mean(g3,axis=0) g4a = np.mean(g4,axis=0) plt.figure(4) plt.plot(g3a.T[:,7]) # Corresponds to: stable_blocksSSP_plot['face'].average().plot(spatial_colors=True, time_unit='s') plt.plot(g4a.T[:,7]) epochsg3 = mne.EpochsArray(g3, info=info_fs100) epochsg4 = mne.EpochsArray(g4, info=info_fs100) plt.figure(6) epochsg3.average().plot(spatial_colors=True, time_unit='s',picks=[7]) # Corresponds to: stable_blocksSSP_plot['face'].average().plot(spatial_colors=True, time_unit='s',picks=[7]) epochsg4.average().plot(spatial_colors=True, time_unit='s',picks=[7]) # Plot topomap a3 = epochsg3.average() a3.plot_topomap(times=np.linspace(0.05, 0.15, 5)) # Plot of evoked ERP and topomaps, in one plot! a3.plot_joint() # Control the y axis a3.plot(ylim=dict(eeg=[-2000000, 2000000])) a3.plot(ylim=dict(eeg=[-2000000, 2000000])) #%% Confusion matrices - stable blocks accuracy, LOBO # y_stable_blocks has the correct y vals, y_pred has the predicted vals. For uncorrected prediction. # Uncorrected correct = (y_stable_blocks == y_pred) conf_train_stable_uncorr = confusion_matrix(y_stable_blocks,y_pred) # Separate into scenes and faces accuracy scene_acc_uncorr = conf_train_stable_uncorr[0,0]/(conf_train_stable_uncorr[0,0]+conf_train_stable_uncorr[0,1]) face_acc_uncorr = conf_train_stable_uncorr[1,1]/(conf_train_stable_uncorr[1,0]+conf_train_stable_uncorr[1,1]) # Corrected alpha_test_c = np.copy(alpha_test) alpha_test_c[alpha_test_c > 0.5] = True # 1 is a correctly predicted alpha_test_c[alpha_test_c < 0.5] = False alpha_predcat = np.argmax(pred_prob_test_corr,axis=1) conf_train_stable = confusion_matrix(y_stable_blocks,alpha_predcat) # Separate into scenes and faces accuracy scene_acc = conf_train_stable[0,0]/(conf_train_stable[0,0]+conf_train_stable[0,1]) face_acc = conf_train_stable[1,1]/(conf_train_stable[1,0]+conf_train_stable[1,1]) d['LOBO_stable_conf_uncorr'] = conf_train_stable_uncorr d['LOBO_stable_scene_acc_uncorr'] = scene_acc_uncorr d['LOBO_stable_face_acc_uncorr'] = face_acc_uncorr d['LOBO_stable_conf_corr'] = conf_train_stable d['LOBO_stable_scene_acc_corr'] = scene_acc d['LOBO_stable_face_acc_corr'] = face_acc #%% Training accuracy, training on stable and NF - leave one block out CV. Accuracy can be based on either stable+NF, only stable or only NF blocks offset_pred_lst = [] c_test = 0 no_b = 8+8*n_it # Number blocks total pred_prob_test = np.zeros((no_b*block_len,2)) pred_prob_test_corr = np.zeros((no_b*block_len,2)) alpha_test = np.zeros((no_b*block_len)) y_pred = np.zeros(no_b*block_len) for b in range(no_b): val_indices = range(b*block_len,(b+1)*block_len) blocks_val = e[val_indices] y_val = y[val_indices] blocks_train = np.delete(e, val_indices,axis=0) y_train = np.delete(y, val_indices) blocks_train_prep = np.zeros((len(y_train),23,n_samples_fs100)) for t in range(blocks_train_prep.shape[0]): epoch = blocks_train[t,:,:] epoch = preproc1epoch(epoch,info_fs500,SSP=False,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) blocks_train_prep[t,:,:] = epoch projs1,blocksSSP_train = applySSP(blocks_train_prep,info_fs100,threshold=threshold) # Average after SSP correction blocksSSP_train = average_stable(blocksSSP_train) clf,offset_pred = trainLogReg_cross_offline(blocksSSP_train,y_train) #cur. in EEG_classification offset_pred = np.min([np.max([offset_pred,-0.25]),0.25])/2 offset_pred_lst.append(offset_pred) # Test epochs in left out block for t in range(block_len): epoch = blocks_val[t,:,:] epoch = preproc1epoch(epoch,info_fs500,projs=projs1,SSP=True,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) if t > 0: epoch = (epoch+epoch_prev)/2 pred_prob_test[c_test,:],y_pred[c_test] = testEpoch(clf,epoch) # Correct the prediction bias offset pred_prob_test_corr[c_test,0] = np.min([np.max([pred_prob_test[c_test,0]+offset_pred,0]),1]) pred_prob_test_corr[c_test,1] = np.min([np.max([pred_prob_test[c_test,1]-offset_pred,0]),1]) clf_output = pred_prob_test_corr[c_test,int(y_val[t])]-pred_prob_test_corr[c_test,int(y_val[t]-1)] alpha_test[c_test] = sigmoid(clf_output) epoch_prev = epoch c_test += 1 print('No c_test: ' + str(c_test) + ' out of ' + str(no_b*block_len)) above_chance_train = len(np.where((np.array(alpha_test[:c_test])>0.5))[0])/len(alpha_test[:c_test]) print('Above chance alpha train (corrected) on both stable and NF: ' + str(above_chance_train)) # Separate in stable only, and stable + NF e_mock = np.arange((8+n_it*8)*block_len) stable_blocks_fbrun = np.concatenate([e_mock[400+n*400:600+n*400] for n in range(n_it)]) # Stable blocks feedback run stable_blocks_idx = np.concatenate((e_mock[:400],stable_blocks_fbrun)) a = alpha_test[stable_blocks_idx] above_chance_stable = len(np.where((np.array(a)>0.5))[0])/len(a) print('Above chance alpha train (corrected) on stable blocks: ' + str(above_chance_stable)) #nf_blocks_idx = np.concatenate([e_mock[600+n*400:800+n*400] for n in range(n_it)]) # Neurofeedback blocks #a2 = alpha_test[nf_blocks_idx] #above_chance_nf = len(np.where((np.array(a2)>0.5))[0])/len(a2) #print('Above chance alpha train (corrected) on NF blocks: ' + str(above_chance_nf)) d['LOBO_all_train_offsets'] = offset_pred_lst d['LOBO_all_train_acc'] = above_chance_train # All blocks included d['LOBO_all_train_acc_stable_test'] = above_chance_stable # Trained on both stable and NF, only tested on stable #d['train_acc_nf_test'] = above_chance_nf # Trained on both stable and NF, only tested on NF #%% Confusion matrices - training on stable+NF blocks, testing on stable+NF, stable or NF blocks # Uncorrected, all (stable + NF) correct = (y == y_pred) conf_train_all_uncorr = confusion_matrix(y,y_pred) # Separate into scenes and faces accuracy scene_acc_uncorr = conf_train_all_uncorr[0,0]/(conf_train_all_uncorr[0,0]+conf_train_all_uncorr[0,1]) face_acc_uncorr = conf_train_all_uncorr[1,1]/(conf_train_all_uncorr[1,0]+conf_train_all_uncorr[1,1]) # Corrected, all alpha_test_c = np.copy(alpha_test) alpha_test_c[alpha_test_c > 0.5] = True # 1 is a correctly predicted alpha_test_c[alpha_test_c < 0.5] = False alpha_predcat = np.argmax(pred_prob_test_corr,axis=1) conf_train_all = confusion_matrix(y,alpha_predcat) # Separate into scenes and faces accuracy scene_acc = conf_train_all[0,0]/(conf_train_all[0,0]+conf_train_all[0,1]) face_acc = conf_train_all[1,1]/(conf_train_all[1,0]+conf_train_all[1,1]) d['LOBO_all_conf_uncorr'] = conf_train_all_uncorr d['LOBO_all_scene_acc_uncorr'] = scene_acc_uncorr d['LOBO_all_face_acc_uncorr'] = face_acc_uncorr d['LOBO_all_conf_corr'] = conf_train_all d['LOBO_all_scene_acc_corr'] = scene_acc d['LOBO_all_face_acc_corr'] = face_acc #%% Training on stable blocks only - leave one run out CV offset_pred_lst = [] c_test = 0 no_sb = 8+4*n_it # Number stable blocks block_len = 50 pred_prob_test = np.zeros((no_sb*block_len,2)) # Prediction probability test. Block length of 50 trials pred_prob_test_corr = np.zeros((no_sb*block_len,2)) # Prediction probability test, corrected for bias alpha_test = np.zeros((no_sb*block_len)) # Alpha values for stable blocks stable_blocks_fbrun = np.concatenate([e[400+n*400:600+n*400] for n in range(n_it)]) # Stable blocks feedback run y_stable_blocks_fbrun = np.concatenate([y[400+n*400:600+n*400] for n in range(n_it)]) stable_blocks = np.concatenate((e[:400,:,:], stable_blocks_fbrun)) y_stable_blocks = np.concatenate((y[:400], y_stable_blocks_fbrun)) y_pred = np.zeros(no_sb*block_len) for r in range(n_it+1): # 6 runs print('Run no: ',r) if r == 0: # First run val_indices = range(0,400) # First run stable_blocks_val = stable_blocks[val_indices] y_val = y_stable_blocks[val_indices] if r > 0: val_indices = range((r+1)*200,((r+1)*200)+200) # Validation block index stable_blocks_val = stable_blocks[val_indices] y_val = y_stable_blocks[val_indices] stable_blocks_train = np.delete(stable_blocks, val_indices, axis=0) y_train = np.delete(y_stable_blocks, val_indices) stable_blocks_train_prep = np.zeros((len(y_train),23,n_samples_fs100)) for t in range(stable_blocks_train.shape[0]): epoch = stable_blocks_train[t,:,:] epoch = preproc1epoch(epoch,info_fs500,SSP=False,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) stable_blocks_train_prep[t,:,:] = epoch projs1,stable_blocksSSP_train = applySSP(stable_blocks_train_prep,info_fs100,threshold=threshold) # Average after SSP correction stable_blocksSSP_train = average_stable(stable_blocksSSP_train) clf,offset_pred = trainLogReg_cross_offline(stable_blocksSSP_train,y_train) #cur. in EEG_classification offset_pred = np.min([np.max([offset_pred,-0.25]),0.25])/2 offset_pred_lst.append(offset_pred) # Test epochs in validation run. Preprocessing and testing epoch-wise for t in range(len(val_indices)): epoch = stable_blocks_val[t,:,:] epoch = preproc1epoch(epoch,info_fs500,projs=projs1,SSP=True,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) if t > 0: epoch = (epoch+epoch_prev)/2 pred_prob_test[c_test,:],y_pred[c_test] = testEpoch(clf,epoch) # Correct the prediction bias offset pred_prob_test_corr[c_test,0] = np.min([np.max([pred_prob_test[c_test,0]+offset_pred,0]),1]) pred_prob_test_corr[c_test,1] = np.min([np.max([pred_prob_test[c_test,1]-offset_pred,0]),1]) clf_output = pred_prob_test_corr[c_test,int(y_val[t])]-pred_prob_test_corr[c_test,int(y_val[t]-1)] alpha_test[c_test] = sigmoid(clf_output) epoch_prev = epoch c_test += 1 print('No c_test: ' + str(c_test) + ' out of ' + str(no_sb*block_len)) above_chance_train = len(np.where((np.array(alpha_test[:c_test])>0.5))[0])/len(alpha_test[:c_test]) print('Above chance alpha train (corrected): ' + str(above_chance_train)) score = metrics.accuracy_score(y_stable_blocks, y_pred) d['LORO_stable_train_offsets_stable'] = offset_pred_lst d['LORO_stable_acc_corr'] = above_chance_train d['LORO_stable_acc_uncorr'] = score #%% Extract RT epochs (non-averaged) for plots and analysis stable_blocks0 = e[:600,:,:] # First run stable_blocks1 = np.zeros((600,n_channels,n_samples_fs100)) y = np.array([int(x) for x in cat]) y_run = y[:600] c_test = 0 c = 0 offset = 0 y_pred_test1 = np.zeros(5*200) y_test_feedback = np.concatenate((y[600:800],y[1000:1200],y[1400:1600],y[1800:2000],y[2200:2400])) epochs_fb_nonavg = np.zeros((1000,23,n_samples_fs100)) # Epochs feedback # epochs_fb_avg = np.zeros((1000,23,n_samples_fs100)) # Epochs feedback for b in range(n_it): for t in range(stable_blocks0.shape[0]): epoch = stable_blocks0[t,:,:] epoch = preproc1epoch(epoch,info_fs500,SSP=False,reject=None,mne_reject=0,reject_ch=reject_ch,flat=None,bad_channels=None,opt_detrend=1) stable_blocks1[t+offset,:,:] = epoch c += 1 projs1,stable_blocksSSP1 = applySSP(stable_blocks1,info_fs100,threshold=threshold) # Apply SSP on stable blocks stable_blocks1 = stable_blocks1[200:,:,:] stable_blocks1 = np.concatenate((stable_blocks1,np.zeros((200,n_channels,n_samples_fs100))),axis=0) s_begin = 800+b*400 offset = 400 # Indexing offset for EEG data and y stable_blocks0 = e[s_begin:s_begin+200,:,:] y_run = np.concatenate((y_run[200:],y[s_begin:s_begin+200])) # Append RT epochs for t in range(200): print('Epoch number: ',c) epoch1 = e[c,:,:] epoch1 = preproc1epoch(epoch1,info_fs500,projs=projs1,SSP=True,reject=reject,mne_reject=mne_reject,reject_ch=reject_ch,flat=flat,bad_channels=bad_channels,opt_detrend=opt_detrend) # For averaging epochs: # if t == 0: # epoch_avg = epoch1 # # if t > 0: # epoch_avg = (epoch1+epoch_prev)/2 # Checked again 17 April that this is legit # # epoch_prev = epoch_avg # # epochs_fb_avg[c_test,:,:] = epoch_avg epochs_fb_nonavg[c_test,:,:] = epoch1 c += 1 c_test += 1 # Create MNE objects events_list = y_test_feedback event_id = dict(scene=0, face=1) n_epochs = len(events_list) events_list = [int(i) for i in events_list] events = np.c_[np.arange(n_epochs), np.zeros(n_epochs, int),events_list] eRT_nonavg = mne.EpochsArray(epochs_fb_nonavg, info=info_fs100, events=events,event_id=event_id,tmin=-0.1,baseline=None) # eRT_avg = mne.EpochsArray(epochs_fb_avg, info=info_fs100, events=events,event_id=event_id,tmin=-0.1,baseline=None) d['MNE_RT_epochs_fb_nonavg'] = eRT_nonavg # d['MNE_RT_epochs_fb_avg'] = eRT_avg d['MNE_y_test_feedback'] = y_test_feedback if plot_MNE == True: # Creating a dict of lists: Condition 0 and condition 1 with evoked arrays. evoked_array_c0 = [] evoked_array_c1 = [] eRT_get = eRT_nonavg.get_data() for idx,cat in enumerate(events_list): if cat == 0: evoked_array_c0.append(mne.EvokedArray(eRT_get[idx], info_fs100,tmin=-0.1,comment=cat)) # Scenes 0 print if cat == 1: evoked_array_c1.append(mne.EvokedArray(eRT_get[idx], info_fs100,tmin=-0.1,comment=cat)) # Faces 1 e_dict={} e_dict['0'] = evoked_array_c0 e_dict['1'] = evoked_array_c1 #colors = 'red', 'blue' #mne.viz.plot_compare_evokeds(e_dict,ci=0.95,picks=[7],colors=colors) #%% Save pckl file pkl_arr = [d] print('Finished running test and train analyses for subject: ' + str(subjID)) # PICKLE TIME fname = '18April_550_subj_'+str(subjID)+'.pkl' with open(fname, 'wb') as fout: pickle.dump(pkl_arr, fout)
allow_pickle=True).item() points = EMS_results[sens]['epochs'].time_as_index(times) EMS_sens = EMS_results[sens]['EMS'] # average filters from the 4 folds meanfilt = np.average([ EMS_sens[0].filters_, EMS_sens[1].filters_, EMS_sens[2].filters_, EMS_sens[3].filters_ ], axis=0) # filter for each timepoint of interest dat = [] for mm, point_of_interest in enumerate(points): dat.append(meanfilt[:, point_of_interest]) dat = np.stack(dat) # create "fake" evo object with times corresponding to the times of the different filters meanfilt_as_evo = mne.EvokedArray(dat.T, EMS_results[sens]['epochs'].info) meanfilt_as_evo.times = np.asarray(times) all_meanfilt_as_evo.append(meanfilt_as_evo) avg = mne.grand_average(all_meanfilt_as_evo) avg.plot_topomap(times=times) save_path = op.join(config.fig_path, 'EMS', 'Full_sequence_projection', 'avg_%s_filters.png' % sens) plt.savefig(save_path, bbox_inches='tight', dpi=300) plt.close('all') ### ========================================================= ### ### PLOT GROUP AVG (item) EMS ### ========================================================= ### for sens in ['mag', 'grad', 'eeg']: # WILL LOAD THE +20Go OF DATA 3 TIMES !! (not optimal !!)