def _compute_add_eog(p, subj, raw_orig, projs, eog_nums, kind, pca_dir, flat, extra_proj, old_kwargs, p_sl): assert kind in ('EOG', 'HEOG', 'VEOG') bk = dict(EOG='blink').get(kind, kind.lower()) eog_eve = op.join(pca_dir, f'preproc_{bk}-eve.fif') eog_epo = op.join(pca_dir, f'preproc_{bk}-epo.fif') eog_proj = op.join(pca_dir, f'preproc_{bk}-proj.fif') eog_t_lims = _handle_dict(getattr(p, f'{kind.lower()}_t_lims'), subj) eog_f_lims = _handle_dict(getattr(p, f'{kind.lower()}_f_lims'), subj) eog_channel = _handle_dict(getattr(p, f'{kind.lower()}_channel'), subj) thresh = _handle_dict(getattr(p, f'{kind.lower()}_thresh'), subj) if eog_channel is None and kind != 'EOG': eog_channel = 'EOG061' if kind == 'HEOG' else 'EOG062' if eog_nums.any(): if p.disp_files: print(f' Computing {kind} projectors...', end='') raw = raw_orig.copy() raw.filter(eog_f_lims[0], eog_f_lims[1], n_jobs=p.n_jobs_fir, method='fir', filter_length=p.filter_length, l_trans_bandwidth=0.5, h_trans_bandwidth=0.5, phase='zero-double', fir_window='hann', skip_by_annotation='edge', **old_kwargs) raw.add_proj(projs) raw.apply_proj() eog_events = find_eog_events( raw, ch_name=eog_channel, reject_by_annotation=True, thresh=thresh) use_reject, use_flat = _restrict_reject_flat( _handle_dict(p.ssp_eog_reject, subj), flat, raw) eog_epochs = Epochs( raw, eog_events, 998, eog_t_lims[0], eog_t_lims[1], baseline=None, reject=use_reject, flat=use_flat, preload=True) print(' obtained %d epochs from %d events.' % (len(eog_epochs), len(eog_events))) del eog_events if len(eog_epochs) >= 5: write_events(eog_eve, eog_epochs.events) eog_epochs.save(eog_epo, **_get_epo_kwargs()) desc_prefix = f'{kind}-%s-%s' % tuple(eog_t_lims) pr = compute_proj_wrap( eog_epochs, p.proj_ave, n_grad=eog_nums[0], n_mag=eog_nums[1], n_eeg=eog_nums[2], desc_prefix=desc_prefix, **extra_proj) assert len(pr) == np.sum(eog_nums[::p_sl]) write_proj(eog_proj, pr) projs.extend(pr) else: warnings.warn('Only %d usable EOG events!' % len(eog_epochs)) _safe_remove([eog_proj, eog_eve, eog_epo]) del raw, eog_epochs else: _safe_remove([eog_proj, eog_eve, eog_epo])
def get_ics_ocular(meg_raw, ica, flow=2, fhigh=20, name_eog='EOG 002', score_func='pearsonr', thresh=0.2, event_id=998): ''' Find Independent Components related to ocular artefacts ''' from mne.preprocessing import find_eog_events # --------------------------- # vertical EOG # --------------------------- ic_eog = [] if name_eog in meg_raw.ch_names: idx_eog = [meg_raw.ch_names.index(name_eog)] eog_filtered = mne.filter.filter_data(meg_raw[idx_eog, :][0], meg_raw.info['sfreq'], l_freq=flow, h_freq=fhigh) scores_eog = ica.score_sources(meg_raw, target=eog_filtered, score_func=score_func) ic_eog = np.where(np.abs(scores_eog) >= thresh)[0] # count from 0 # get EOG ver peaks events_eog = find_eog_events(meg_raw, ch_name=name_eog, event_id=event_id, l_freq=flow, h_freq=fhigh, verbose=False) # make sure event samples start from 0 events_eog[:, 0] -= meg_raw.first_samp else: logger.warning(">>>> Warning: Could not find EOG channel %s" % name_eog) events_eog = [] if len(ic_eog) == 0: ic_eog = np.array([-1]) scores_eog = np.zeros( ica.n_components) #scores_eog = np.array([-1]) ??? # events_eog = np.array([-1]) return [ic_eog, scores_eog, events_eog]
def findEogEvents(self, params): """ Finds events for the given id. Parameters: params - A dictionary of parameters for finding the events. """ #eog_events = find_eog_events(raw, event_id=params['event_id'], ch_name=params['ch_name'], # verbose=True, tstart=params['tstart']) try: print type(params['event_id']) eog_events = find_eog_events(self.raw, event_id=params['event_id'], l_freq=params['l_freq'], h_freq=params['h_freq'], filter_length=params['filter_length'], ch_name=params['ch_name'], verbose=True, tstart=params['tstart']) except Exception as e: print "Exception while finding events.\n" print str(e) return [] return eog_events
def plot_performance_artifact_rejection(meg_raw, ica, fnout_fig, meg_clean=None, show=False, proj=False, verbose=False, name_ecg='ECG 001', name_eog='EOG 002'): ''' Creates a performance image of the data before and after the cleaning process. ''' import matplotlib.pyplot as pl from mne.preprocessing import find_ecg_events, find_eog_events from jumeg import jumeg_math as jmath # name_ecg = 'ECG 001' # name_eog_hor = 'EOG 001' # name_eog_ver = 'EOG 002' event_id_ecg = 999 event_id_eog = 998 tmin_ecg = -0.4 tmax_ecg = 0.4 tmin_eog = -0.4 tmax_eog = 0.4 picks = mne.pick_types(meg_raw.info, meg=True, ref_meg=False, exclude='bads') # as we defined x% of the explained variance as noise (e.g. 5%) # we will remove this noise from the data if meg_clean: meg_clean_given = True else: meg_clean_given = False meg_clean = ica.apply(meg_raw.copy(), exclude=ica.exclude, n_pca_components=ica.n_components_) # plotting parameter props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) # check if ECG and EOG was recorded in addition # to the MEG data ch_names = meg_raw.info['ch_names'] # ECG if name_ecg in ch_names: nstart = 0 nrange = 1 else: nstart = 1 nrange = 1 # EOG if name_eog in ch_names: nrange = 2 y_figsize = 6 * nrange perf_art_rej = np.zeros(2) # ToDo: How can we avoid popping up the window if show=False ? pl.ioff() pl.figure('performance image', figsize=(12, y_figsize)) pl.clf() # ECG, EOG: loop over all artifact events for i in range(nstart, nrange): # get event indices if i == 0: baseline = (None, None) event_id = event_id_ecg idx_event, _, _ = find_ecg_events(meg_raw, event_id, ch_name=name_ecg, verbose=verbose) idx_ref_chan = meg_raw.ch_names.index(name_ecg) tmin = tmin_ecg tmax = tmax_ecg pl1 = nrange * 100 + 21 pl2 = nrange * 100 + 22 text1 = "CA: original data" text2 = "CA: cleaned data" elif i == 1: baseline = (None, None) event_id = event_id_eog idx_event = find_eog_events(meg_raw, event_id, ch_name=name_eog, verbose=verbose) idx_ref_chan = meg_raw.ch_names.index(name_eog) tmin = tmin_eog tmax = tmax_eog pl1 = nrange * 100 + 21 + (nrange - nstart - 1) * 2 pl2 = nrange * 100 + 22 + (nrange - nstart - 1) * 2 text1 = "OA: original data" text2 = "OA: cleaned data" # average the signals raw_epochs = mne.Epochs(meg_raw, idx_event, event_id, tmin, tmax, picks=picks, baseline=baseline, proj=proj, verbose=verbose) cleaned_epochs = mne.Epochs(meg_clean, idx_event, event_id, tmin, tmax, picks=picks, baseline=baseline, proj=proj, verbose=verbose) ref_epochs = mne.Epochs(meg_raw, idx_event, event_id, tmin, tmax, picks=[idx_ref_chan], baseline=baseline, proj=proj, verbose=verbose) raw_epochs_avg = raw_epochs.average() cleaned_epochs_avg = cleaned_epochs.average() ref_epochs_avg = np.average(ref_epochs.get_data(), axis=0).flatten() * -1.0 times = raw_epochs_avg.times * 1e3 if np.max(raw_epochs_avg.data) < 1: factor = 1e15 else: factor = 1 ymin = np.min(raw_epochs_avg.data) * factor ymax = np.max(raw_epochs_avg.data) * factor # plotting data before cleaning pl.subplot(pl1) pl.plot(times, raw_epochs_avg.data.T * factor, 'k') pl.title(text1) # plotting reference signal pl.plot(times, jmath.rescale(ref_epochs_avg, ymin, ymax), 'r') pl.xlim(times[0], times[len(times) - 1]) pl.ylim(1.1 * ymin, 1.1 * ymax) # print some info textstr1 = 'num_events=%d\nEpochs: tmin, tmax = %0.1f, %0.1f' \ % (len(idx_event), tmin, tmax) pl.text(times[10], 1.09 * ymax, textstr1, fontsize=10, verticalalignment='top', bbox=props) # plotting data after cleaning pl.subplot(pl2) pl.plot(times, cleaned_epochs_avg.data.T * factor, 'k') pl.title(text2) # plotting reference signal again pl.plot(times, jmath.rescale(ref_epochs_avg, ymin, ymax), 'r') pl.xlim(times[0], times[len(times) - 1]) pl.ylim(1.1 * ymin, 1.1 * ymax) # print some info perf_art_rej[i] = calc_performance(raw_epochs_avg, cleaned_epochs_avg) # ToDo: would be nice to add info about ica.excluded if meg_clean_given: textstr1 = 'Performance: %d\nFrequency Correlation: %d'\ % (perf_art_rej[i], calc_frequency_correlation(raw_epochs_avg, cleaned_epochs_avg)) else: textstr1 = 'Performance: %d\nFrequency Correlation: %d\n# ICs: %d\nExplained Var.: %d'\ % (perf_art_rej[i], calc_frequency_correlation(raw_epochs_avg, cleaned_epochs_avg), ica.n_components_, ica.n_components * 100) pl.text(times[10], 1.09 * ymax, textstr1, fontsize=10, verticalalignment='top', bbox=props) if show: pl.show() # save image pl.savefig(fnout_fig + '.png', format='png') pl.close('performance image') pl.ion() return perf_art_rej
def plot_performance_artifact_rejection(meg_raw, ica, fnout_fig, meg_clean=None, show=False, proj=False, verbose=False, name_ecg='ECG 001', name_eog='EOG 002'): ''' Creates a performance image of the data before and after the cleaning process. ''' from mne.preprocessing import find_ecg_events, find_eog_events from jumeg import jumeg_math as jmath # name_ecg = 'ECG 001' # name_eog_hor = 'EOG 001' # name_eog_ver = 'EOG 002' event_id_ecg = 999 event_id_eog = 998 tmin_ecg = -0.4 tmax_ecg = 0.4 tmin_eog = -0.4 tmax_eog = 0.4 picks = mne.pick_types(meg_raw.info, meg=True, ref_meg=False, exclude='bads') # as we defined x% of the explained variance as noise (e.g. 5%) # we will remove this noise from the data if meg_clean: meg_clean_given = True else: meg_clean_given = False meg_clean = ica.apply(meg_raw.copy(), exclude=ica.exclude, n_pca_components=ica.n_components_) # plotting parameter props = dict(boxstyle='round', facecolor='wheat', alpha=0.5) # check if ECG and EOG was recorded in addition # to the MEG data ch_names = meg_raw.info['ch_names'] # ECG if name_ecg in ch_names: nstart = 0 nrange = 1 else: nstart = 1 nrange = 1 # EOG if name_eog in ch_names: nrange = 2 y_figsize = 6 * nrange perf_art_rej = np.zeros(2) # ToDo: How can we avoid popping up the window if show=False ? pl.ioff() pl.figure('performance image', figsize=(12, y_figsize)) pl.clf() # ECG, EOG: loop over all artifact events for i in range(nstart, nrange): # get event indices if i == 0: baseline = (None, None) event_id = event_id_ecg idx_event, _, _ = find_ecg_events(meg_raw, event_id, ch_name=name_ecg, verbose=verbose) idx_ref_chan = meg_raw.ch_names.index(name_ecg) tmin = tmin_ecg tmax = tmax_ecg pl1 = nrange * 100 + 21 pl2 = nrange * 100 + 22 text1 = "CA: original data" text2 = "CA: cleaned data" elif i == 1: baseline = (None, None) event_id = event_id_eog idx_event = find_eog_events(meg_raw, event_id, ch_name=name_eog, verbose=verbose) idx_ref_chan = meg_raw.ch_names.index(name_eog) tmin = tmin_eog tmax = tmax_eog pl1 = nrange * 100 + 21 + (nrange - nstart - 1) * 2 pl2 = nrange * 100 + 22 + (nrange - nstart - 1) * 2 text1 = "OA: original data" text2 = "OA: cleaned data" # average the signals raw_epochs = mne.Epochs(meg_raw, idx_event, event_id, tmin, tmax, picks=picks, baseline=baseline, proj=proj, verbose=verbose) cleaned_epochs = mne.Epochs(meg_clean, idx_event, event_id, tmin, tmax, picks=picks, baseline=baseline, proj=proj, verbose=verbose) ref_epochs = mne.Epochs(meg_raw, idx_event, event_id, tmin, tmax, picks=[idx_ref_chan], baseline=baseline, proj=proj, verbose=verbose) raw_epochs_avg = raw_epochs.average() cleaned_epochs_avg = cleaned_epochs.average() ref_epochs_avg = np.average(ref_epochs.get_data(), axis=0).flatten() * -1.0 times = raw_epochs_avg.times * 1e3 if np.max(raw_epochs_avg.data) < 1: factor = 1e15 else: factor = 1 ymin = np.min(raw_epochs_avg.data) * factor ymax = np.max(raw_epochs_avg.data) * factor # plotting data before cleaning pl.subplot(pl1) pl.plot(times, raw_epochs_avg.data.T * factor, 'k') pl.title(text1) # plotting reference signal pl.plot(times, jmath.rescale(ref_epochs_avg, ymin, ymax), 'r') pl.xlim(times[0], times[len(times) - 1]) pl.ylim(1.1 * ymin, 1.1 * ymax) # print some info textstr1 = 'num_events=%d\nEpochs: tmin, tmax = %0.1f, %0.1f' \ % (len(idx_event), tmin, tmax) pl.text(times[10], 1.09 * ymax, textstr1, fontsize=10, verticalalignment='top', bbox=props) # plotting data after cleaning pl.subplot(pl2) pl.plot(times, cleaned_epochs_avg.data.T * factor, 'k') pl.title(text2) # plotting reference signal again pl.plot(times, jmath.rescale(ref_epochs_avg, ymin, ymax), 'r') pl.xlim(times[0], times[len(times) - 1]) pl.ylim(1.1 * ymin, 1.1 * ymax) # print some info perf_art_rej[i] = calc_performance(raw_epochs_avg, cleaned_epochs_avg) # ToDo: would be nice to add info about ica.excluded if meg_clean_given: textstr1 = 'Performance: %d\nFrequency Correlation: %d'\ % (perf_art_rej[i], calc_frequency_correlation(raw_epochs_avg, cleaned_epochs_avg)) else: textstr1 = 'Performance: %d\nFrequency Correlation: %d\n# ICs: %d\nExplained Var.: %d'\ % (perf_art_rej[i], calc_frequency_correlation(raw_epochs_avg, cleaned_epochs_avg), ica.n_components_, ica.n_components * 100) pl.text(times[10], 1.09 * ymax, textstr1, fontsize=10, verticalalignment='top', bbox=props) if show: pl.show() # save image pl.savefig(fnout_fig + '.png', format='png') pl.close('performance image') pl.ion() return perf_art_rej
raw_new_ref_show = raw_new_ref.copy().crop(tmin=tmin, tmax=tmax) raw_new_ref_show.plot(duration=6) raw_reconst_show = raw_reconst.copy().crop(tmin=tmin, tmax=tmax) raw_reconst_show.plot(duration=6) raw_reconst.save(datapath + str(subID) + '_reconst_newRef_raw.fif', overwrite=True) # raw_reconst = mne.io.read_raw_fif(datapath + str(subID) + '_reconst_newRef_raw.fif', preload=True) # make sure two different artifact method have the same variable name raw_artifact = raw_reconst # -------------------------Reject bad data spans------------------------- # # Annotate bad spans of data # Annotate EOG programmatically, annotate from [-0.25, 0.25] eog_events = find_eog_events(raw_new_ref) onsets = eog_events[:, 0] / raw_new_ref.info['sfreq'] - 0.25 durations = [0.5] * len(eog_events) descriptions = ['bad blink'] * len(eog_events) blink_annot = mne.Annotations(onsets, durations, descriptions, orig_time=raw_new_ref.info['meas_date']) # visualize the bad blinks # raw_new_ref_badBlink = raw_new_ref.copy().set_annotations(blink_annot) # raw_new_ref_show = raw_new_ref_badBlink.copy().crop(tmin=tmin, tmax=tmax) # raw_new_ref_show.plot(duration=6) # get raw data annotations raw_new_ref_annot = raw_new_ref.annotations