def fit_ica(raw, picks, reject, ecg_ch, eog_hor, eog_ver, flow_ecg, fhigh_ecg, flow_eog, fhigh_eog, ecg_thresh, eog_thresh, use_jumeg=True, random_state=42): """ author: C.Kiefer; [email protected] Fit an ICA object to the raw file. Identify cardiac and ocular components and mark them for removal. Parameters: ----------- inst : instance of Raw, Epochs or Evoked Raw measurements to be decomposed. picks : array-like of int Channels to be included. This selection remains throughout the initialized ICA solution. If None only good data channels are used. reject : dict | None Rejection parameters based on peak-to-peak amplitude. Valid keys are 'grad', 'mag', 'eeg', 'seeg', 'ecog', 'eog', 'ecg', 'hbo', 'hbr'. If reject is None then no rejection is done. Example:: reject = dict(grad=4000e-13, # T / m (gradiometers) mag=4e-12, # T (magnetometers) eeg=40e-6, # V (EEG channels) eog=250e-6 # V (EOG channels) ) It only applies if `inst` is of type Raw. ecg_ch : array-like | ch_name | None ECG channel to which the sources shall be compared. It has to be of the same shape as the sources. If some string is supplied, a routine will try to find a matching channel. If None, a score function expecting only one input-array argument must be used, for instance, scipy.stats.skew (default). eog_hor : array-like | ch_name | None Horizontal EOG channel to which the sources shall be compared. It has to be of the same shape as the sources. If some string is supplied, a routine will try to find a matching channel. If None, a score function expecting only one input-array argument must be used, for instance, scipy.stats.skew (default). eog_ver : array-like | ch_name | None Vertical EOG channel to which the sources shall be compared. It has to be of the same shape as the sources. If some string is supplied, a routine will try to find a matching channel. If None, a score function expecting only one input-array argument must be used, for instance, scipy.stats.skew (default). flow_ecg : float Low pass frequency for ECG component identification. fhigh_ecg : float High pass frequency for ECG component identification. flow_eog : float Low pass frequency for EOG component identification. fhigh_eog : float High pass frequency for EOG component identification. ecg_thresh : float Threshold for ECG component idenfication. eog_thresh : float Threshold for EOG component idenfication. use_jumeg : bool Use the JuMEG scoring method for the identification of artifact components. random_state : None | int | instance of np.random.RandomState np.random.RandomState to initialize the FastICA estimation. As the estimation is non-deterministic it can be useful to fix the seed to have reproducible results. Defaults to None. Returns: -------- ica : mne.preprocessing.ICA ICA object for raw file with ECG and EOG components marked for removal. """ # increased iteration to make it converge # fix the number of components to 40, depending on your application you # might want to raise the number # 'extended-infomax', 'fastica', 'picard' logger.info('Start ICA FIT: init ICA object') ica = ICA(method='fastica', n_components=40, random_state=random_state, max_pca_components=None, max_iter=5000, verbose=False) logger.debug('ICA FIT: apply ICA.fit\n reject: {} \n picks: {}'.format( reject, picks)) ica.fit(raw, picks=picks, decim=None, reject=reject, verbose=True) logger.info('Done ICA FIT') ####################################################################### # identify bad components ####################################################################### if use_jumeg: logger.info("JuMEG Computing scores and identifying components ...") #--- get ECG related components using JuMEG ic_ecg, sc_ecg = get_ics_cardiac(raw, ica, flow=flow_ecg, fhigh=fhigh_ecg, thresh=ecg_thresh, tmin=-0.5, tmax=0.5, name_ecg=ecg_ch, use_CTPS=True) #[0] ic_ecg = list(set(ic_ecg)) ic_ecg.sort() #--- get EOG related components using JuMEG ic_eog = get_ics_ocular(raw, ica, flow=flow_eog, fhigh=fhigh_eog, thresh=eog_thresh, name_eog_hor=eog_hor, name_eog_ver=eog_ver, score_func='pearsonr') ic_eog = list(set(ic_eog)) ic_eog.sort() #--- if necessary include components identified by correlation as well bads_list = [] bads_list.extend(ic_ecg) bads_list.extend(ic_eog) bads_list.sort() ica.exclude = bads_list msg = [ "JuMEG identified ICA components", " -> ECG components: {}".format(ic_ecg), " -> scores: {}".format(sc_ecg[ic_ecg]), " -> EOG components: {}".format(ic_eog) ] logger.debug("\n".join(msg)) else: logger.info("MNE Computing scores and identifying components ...") ecg_scores = ica.score_sources(raw, target=ecg_ch, score_func='pearsonr', l_freq=flow_ecg, h_freq=fhigh_ecg, verbose=False) # horizontal channel eog1_scores = ica.score_sources(raw, target=eog_hor, score_func='pearsonr', l_freq=flow_eog, h_freq=fhigh_eog, verbose=False) # vertical channel eog2_scores = ica.score_sources(raw, target=eog_ver, score_func='pearsonr', l_freq=flow_eog, h_freq=fhigh_eog, verbose=False) # print the top ecg, eog correlation scores ecg_inds = np.where(np.abs(ecg_scores) > ecg_thresh)[0] eog1_inds = np.where(np.abs(eog1_scores) > eog_thresh)[0] eog2_inds = np.where(np.abs(eog2_scores) > eog_thresh)[0] highly_corr = list( set(np.concatenate((ecg_inds, eog1_inds, eog2_inds)))) highly_corr.sort() highly_corr_ecg = list(set(ecg_inds)) highly_corr_eog1 = list(set(eog1_inds)) highly_corr_eog2 = list(set(eog2_inds)) highly_corr_ecg.sort() highly_corr_eog1.sort() highly_corr_eog2.sort() # if necessary include components identified by correlation as well ica.exclude = highly_corr msg = [ "MNE Highly correlated artifact components", " -> ECG : {} ".format(highly_corr_ecg), " -> EOG 1: {} ".format(highly_corr_eog1), " -> EOG 2: {} ".format(highly_corr_eog2) ] logger.debug("\n".join(msg)) logger.info("done ICA FIT\n -> excluded ICs: {}\n".format(ica.exclude)) return ica
if model_scores[idx][0] > MLICA_threshold: bads_MLICA.append(idx) # visualisation # ica.exclude = bads_MLICA # ica.plot_sources(raw_ds_chop, block=True) # compare MLICA to results from correlation and ctps analysis ica.exclude = [] print 'Identifying components..' # get ECG/EOG related components using JuMEG ic_ecg = get_ics_cardiac( raw_filtered_chop, ica, flow=flow_ecg, fhigh=fhigh_ecg, thresh=ecg_thresh, tmin=-0.5, tmax=0.5, name_ecg=ecg_ch, use_CTPS=True)[0] # returns both ICs and scores (take only ICs) ic_eog = get_ics_ocular(raw_filtered_chop, ica, flow=flow_eog, fhigh=fhigh_eog, thresh=eog_thresh, name_eog_hor=eog1_ch, name_eog_ver=eog2_ch, score_func='pearsonr') bads_corr_ctps = list(ic_ecg) + list(ic_eog) bads_corr_ctps = list(set(bads_corr_ctps)) # remove potential duplicates
# ------------------------------------------------------- #ica_method = 'fastica' ica_method = 'extended-infomax' decim = 3 ica = ICA(method=ica_method, n_components=0.99) ica.fit(raw, picks=picks_meg, decim=decim) # ------------------------------------------------------- # before visual inspection of ICA components # try the automatic version to see what we get # ------------------------------------------------------- # search for ECG artifact components (should already be removed by OCARTA) idx_ecg = get_ics_cardiac(raw, ica, flow=10, fhigh=20, tmin=-0.3, tmax=0.3, name_ecg='ECG 001', use_CTPS=True, thresh=0.3) # search for EOG artifact components idx_eog1 = get_ics_ocular(raw, ica, flow=1, fhigh=10, name_eog_hor='EOG 001', score_func='pearsonr', thresh=0.25) idx_eog2 = get_ics_ocular(raw, ica, flow=1,
verbose=False) # print the top ecg, eog correlation scores ecg_inds = np.where(np.abs(ecg_scores) > ecg_thresh)[0] eog1_inds = np.where(np.abs(eog1_scores) > eog_thresh)[0] eog2_inds = np.where(np.abs(eog2_scores) > eog_thresh)[0] highly_corr = list( set(np.concatenate((ecg_inds, eog1_inds, eog2_inds)))) print 'Highly correlated artefact components are', highly_corr # get ECG/EOG related components using JUMEG ic_ecg = get_ics_cardiac(raw_filt_chop, ica, flow=flow_ecg, fhigh=fhigh_ecg, thresh=ecg_thresh, tmin=-0.5, tmax=0.5, name_ecg=ecg_ch, score_func='pearsonr', use_CTPS=True) ic_eog = get_ics_ocular(raw_filt_chop, ica, flow=flow_eog, fhigh=fhigh_eog, thresh=eog_thresh, name_eog_hor=eog1_ch, name_eog_ver=eog2_ch, score_func='pearsonr') print 'Identified ECG components are: ', ic_ecg print 'Identified EOG components are: ', ic_eog