def test_ctps(): """Test basic ctps functionality.""" for ii, (n_trials, j_extent, pk_max) in iter_test_ctps: data = get_data(n_trials, j_extent) ks_dyn, pk_dyn, phase_trial = ctps(data) data2 = _compute_normalized_phase(data) ks_dyn2, pk_dyn2, phase_trial2 = ctps(data2, is_raw=False) for a, b in zip([ks_dyn, pk_dyn, phase_trial], [ks_dyn2, pk_dyn2, data2]): assert_array_equal(a, b) assert (a.min() >= 0) assert (a.max() <= 1) assert (b.min() >= 0) assert (b.max() <= 1) # test for normalization assert ((pk_dyn.min() > 0.0) or (pk_dyn.max() < 1.0)) # test shapes assert (phase_trial.shape == data.shape) assert (pk_dyn.shape == data.shape[1:]) # tets ground_truth + random + jittered case assert (pk_dyn[0].max() == 1.0) assert (len(np.unique(pk_dyn[0])) == 1.0) assert (pk_dyn[1].max() < pk_max) assert (pk_dyn[2].max() > 0.3) if ii < 1: pytest.raises(ValueError, ctps, data[:, :, :, None]) assert (_prob_kuiper(1.0, 400) == 1.0) # test vecrosization assert_array_equal(_prob_kuiper(np.array([1.0, 1.0]), 400), _prob_kuiper(np.array([1.0, 1.0]), 400)) assert (_prob_kuiper(0.1, 400) < 0.1)
def test_ctps(): """ Test basic ctps functionality """ for ii, (n_trials, j_extent, pk_max) in iter_test_ctps: data = get_data(n_trials, j_extent) ks_dyn, pk_dyn, phase_trial = ctps(data) data2 = _compute_normalized_phase(data) ks_dyn2, pk_dyn2, phase_trial2 = ctps(data2, is_raw=False) for a, b in zip([ks_dyn, pk_dyn, phase_trial], [ks_dyn2, pk_dyn2, data2]): assert_array_equal(a, b) assert_true(a.min() >= 0) assert_true(a.max() <= 1) assert_true(b.min() >= 0) assert_true(b.max() <= 1) # test for normalization assert_true((pk_dyn.min() > 0.0) or (pk_dyn.max() < 1.0)) # test shapes assert_true(phase_trial.shape == data.shape) assert_true(pk_dyn.shape == data.shape[1:]) # tets ground_truth + random + jittered case assert_true(pk_dyn[0].max() == 1.0) assert_true(len(np.unique(pk_dyn[0])) == 1.0) assert_true(pk_dyn[1].max() < pk_max) assert_true(pk_dyn[2].max() > 0.3) if ii < 1: assert_raises(ValueError, ctps, data[:, :, :, None]) assert_true(_prob_kuiper(1.0, 400) == 1.0) # test vecrosization assert_array_equal(_prob_kuiper(np.array([1.0, 1.0]), 400), _prob_kuiper(np.array([1.0, 1.0]), 400)) assert_true(_prob_kuiper(0.1, 400) < 0.1)
def get_temporal_envelope(self, origdata, W_orig, average=True): """ Returns the temporal envelope of the independent components after FourierICA decomposition. Note, the 'fit()' function must be applied before this routine can be used (to get W_orig). Parameters ---------- origdata: array of data to be decomposed [nchan, ntsl]. W_orig: estimated de-mixing matrix average: if set the temporal envelopes are averaged over all epochs default: average=True Returns ------- temporal_envelope: temporal envelop of the independent components pk_max: pk-values of the independent component """ # chop data into epochs and apply short-time Fourier transform (STFT) X, _ = apply_stft(origdata, events=self.events, tpre=self.tpre, sfreq=self.sfreq, flow=self.flow, fhigh=self.fhigh, win_length_sec=self.win_length_sec, overlap_fac=self.overlap_fac, hamming_data=self.hamming_data, remove_outliers=False, fcnoutliers=self.fcnoutliers, verbose=False) # get some size information from data fftsize, nwindows, nchan = X.shape ntsl = int(np.floor(self.win_length_sec*self.sfreq)) ncomp = W_orig.shape[0] temporal_envelope = np.zeros((nwindows, ncomp, ntsl)) startfftind = int(np.floor(self.flow*self.win_length_sec)) endfftind = int(startfftind+fftsize) fft_act = np.zeros((ncomp, ntsl), dtype=np.complex) act = np.zeros((ncomp, nwindows, fftsize), dtype=np.complex) # loop over all windows for iwin in range(0, nwindows): # transform data into FourierICA-space X_norm = (X[:, iwin, :] - np.dot(np.ones((fftsize, 1)), self.dmean)) / \ np.dot(np.ones((fftsize, 1)), self.dstd) act[:, iwin, :] = np.dot(W_orig, X_norm.transpose()) # act = np.dot(W_orig, X[:, iwin, :].transpose()) # apply inverse STFT to get temporal envelope fft_act[:, startfftind:endfftind] = act[:, iwin, :] temporal_envelope[iwin, :, :] = sc.fftpack.ifft(fft_act, n=ntsl, axis=1).real from mne.preprocessing.ctps_ import ctps ks_dynamics_orig, pk_dynamics_orig, _ = ctps(temporal_envelope) pk_max = np.max(pk_dynamics_orig, axis=1) # average data if required if average: temporal_envelope = np.mean(temporal_envelope, axis=0) return temporal_envelope, pk_max
def get_temporal_envelope(self, origdata, W_orig, average=True): """ Returns the temporal envelope of the independent components after FourierICA decomposition. Note, the 'fit()' function must be applied before this routine can be used (to get W_orig). Parameters ---------- origdata: array of data to be decomposed [nchan, ntsl]. W_orig: estimated de-mixing matrix average: if set the temporal envelopes are averaged over all epochs default: average=True Returns ------- temporal_envelope: temporal envelop of the independent components pk_max: pk-values of the independent component """ # import necessary modules from mne.preprocessing import ctps_ as ctps # chop data into epochs and apply short-time Fourier transform (STFT) X, _ = apply_stft(origdata, events=self.events, tpre=self.tpre, sfreq=self.sfreq, flow=self.flow, fhigh=self.fhigh, win_length_sec=self.win_length_sec, overlap_fac=self.overlap_fac, hamming_data=self.hamming_data, remove_outliers=False, fcnoutliers=self.fcnoutliers, verbose=False) # get some size information from data fftsize, nwindows, nchan = X.shape ntsl = int(np.floor(self.win_length_sec*self.sfreq)) ncomp = W_orig.shape[0] temporal_envelope = np.zeros((nwindows, ncomp, ntsl)) startfftind = int(np.floor(self.flow*self.win_length_sec)) endfftind = int(startfftind+fftsize) fft_act = np.zeros((ncomp, ntsl), dtype=np.complex) # loop over all windows for iwin in range(0, nwindows): # transform data into FourierICA-space act = np.dot(W_orig, X[:, iwin, :].transpose()) # apply inverse STFT to get temporal envelope fft_act[:, startfftind:endfftind] = act temporal_envelope[iwin, :, :] = sc.fftpack.ifft(fft_act, n=ntsl, axis=1).real # estimate pk-values _, pk, _ = ctps.ctps(temporal_envelope) pk_max = np.max(pk, axis=1) # average data if required if average: temporal_envelope = np.mean(temporal_envelope, axis=0) return temporal_envelope, pk_max
def get_ics_cardiac(meg_raw, ica, flow=10, fhigh=20, tmin=-0.3, tmax=0.3, name_ecg='ECG 001', use_CTPS=True, proj=False, score_func='pearsonr', thresh=0.3): ''' Identify components with cardiac artefacts ''' from mne.preprocessing import find_ecg_events event_id_ecg = 999 if name_ecg in meg_raw.ch_names: # get and filter ICA signals ica_raw = ica.get_sources(meg_raw) ica_raw.filter(l_freq=flow, h_freq=fhigh, n_jobs=2, method='fft') # get R-peak indices in ECG signal idx_R_peak, _, _ = find_ecg_events(meg_raw, ch_name=name_ecg, event_id=event_id_ecg, l_freq=flow, h_freq=fhigh, verbose=False) # ----------------------------------- # default method: CTPS # else: correlation # ----------------------------------- if use_CTPS: # create epochs picks = np.arange(ica.n_components_) ica_epochs = mne.Epochs(ica_raw, events=idx_R_peak, event_id=event_id_ecg, tmin=tmin, tmax=tmax, baseline=None, proj=False, picks=picks, verbose=False) # compute CTPS _, pk, _ = ctps.ctps(ica_epochs.get_data()) pk_max = np.max(pk, axis=1) idx_ecg = np.where(pk_max >= thresh)[0] else: # use correlation idx_ecg = [meg_raw.ch_names.index(name_ecg)] ecg_filtered = mne.filter.band_pass_filter(meg_raw[idx_ecg, :][0], meg_raw.info['sfreq'], Fp1=flow, Fp2=fhigh) ecg_scores = ica.score_sources(meg_raw, target=ecg_filtered, score_func=score_func) idx_ecg = np.where(np.abs(ecg_scores) >= thresh)[0] else: print ">>>> NOTE: No ECG channel found!" idx_ecg = np.array([0]) return idx_ecg
def apply_ctps(fname_ica, freqs=[(1, 4), (4, 8), (8, 12), (12, 16), (16, 20)], tmin=-0.2, tmax=0.4, name_stim='STI 014', event_id=None, baseline=(None, 0), proj=False): ''' Applies CTPS to a list of ICA files. ''' from jumeg.filter import jumeg_filter fiws = jumeg_filter(filter_method="bw") fiws.filter_type = 'bp' # bp, lp, hp fiws.dcoffset = True fiws.filter_attenuation_factor = 1 nfreq = len(freqs) print '>>> CTPS calculation on: ', freqs # Trigger or Response ? if name_stim == 'STI 014': # trigger trig_name = 'trigger' else: if name_stim == 'STI 013': # response trig_name = 'response' else: trig_name = 'auxillary' fnlist = get_files_from_list(fname_ica) # loop across all filenames for fnica in fnlist: name = os.path.split(fnica)[1] #fname = fnica[0:len(fnica)-4] basename = fnica[:fnica.rfind(ext_ica)] fnraw = basename + ext_raw #basename = os.path.splitext(os.path.basename(fnica))[0] # load cleaned data raw = mne.io.Raw(fnraw, preload=True) picks = mne.pick_types(raw.info, meg=True, ref_meg=False, exclude='bads') # read (second) ICA print ">>>> working on: " + basename ica = mne.preprocessing.read_ica(fnica) ica_picks = np.arange(ica.n_components_) ncomp = len(ica_picks) # stim events stim_events = mne.find_events(raw, stim_channel=name_stim, consecutive=True) nevents = len(stim_events) if (nevents > 0): # for a specific event ID if event_id: ix = np.where(stim_events[:, 2] == event_id)[0] stim_events = stim_events[ix, :] else: event_id = stim_events[0, 2] # create ctps dictionary dctps = {'fnica': fnica, 'basename': basename, 'stim_channel': name_stim, 'trig_name': trig_name, 'ncomp': ncomp, 'nevent': nevents, 'event_id': event_id, 'nfreq': nfreq, 'freqs': freqs, } # loop across all filenames pkarr = [] ptarr = [] pkmax_arr = [] for ifreq in range(nfreq): ica_raw = ica.get_sources(raw) flow, fhigh = freqs[ifreq][0], freqs[ifreq][1] bp = str(flow) + '_' + str(fhigh) # filter ICA data and create epochs #tw=0.1 # ica_raw.filter(l_freq=flow, h_freq=fhigh, picks=ica_picks, # method='fft',l_trans_bandwidth=tw, h_trans_bandwidth=tw) # ica_raw.filter(l_freq=flow, h_freq=fhigh, picks=ica_picks, # method='fft') # filter ws settings # later we will make this as a one line call data_length = raw._data[0, :].size fiws.sampling_frequency = raw.info['sfreq'] fiws.fcut1 = flow fiws.fcut2 = fhigh #fiws.init_filter_kernel(data_length) #fiws.init_filter(data_length) for ichan in ica_picks: fiws.apply_filter(ica_raw._data[ichan, :]) ica_epochs = mne.Epochs(ica_raw, events=stim_events, event_id=event_id, tmin=tmin, tmax=tmax, verbose=False, picks=ica_picks, baseline=baseline, proj=proj) # compute CTPS _, pk, pt = ctps.ctps(ica_epochs.get_data()) pkmax = pk.max(1) times = ica_epochs.times * 1e3 pkarr.append(pk) ptarr.append(pt) pkmax_arr.append(pkmax) pkarr = np.array(pkarr) ptarr = np.array(ptarr) pkmax_arr = np.array(pkmax_arr) dctps['pk'] = np.float32(pkarr) dctps['pt'] = np.float32(ptarr) dctps['pkmax'] = np.float32(pkmax_arr) dctps['nsamp'] = len(times) dctps['times'] = np.float32(times) dctps['tmin'] = np.float32(ica_epochs.tmin) dctps['tmax'] = np.float32(ica_epochs.tmax) fnctps = basename + prefix_ctps + trig_name np.save(fnctps, dctps) # Note; loading example: dctps = np.load(fnctps).items() else: event_id = None
def ctps_ica_brain_responses_update(self,fname,raw=None,fname_ica=None,ica_raw=None,template_name=None,condition_list=None, filter_method="bw",remove_dcoffset=False,njobs=None, freq_ctps=np.array([]),fmin=4,fmax=32,fstep=8,proj=False,exclude_events=None, ctps_parameter = {'time_pre':None,'time_post':None,'baseline':None}, save_phase_angles=False,fif_extention=".fif",fif_postfix="ctps"): """ :param fname: :param raw: :param fname_ica: :param ica_raw: :param template_name: :param condition_list: :param filter_method: :param remove_dcoffset: :param njobs: :param freq_ctps: :param fmin: :param fmax: :param fstep: :param proj: :param exclude_events: :param ctps_parameter: :param save_phase_angles: :param fif_extention: :param fif_postfix: :return: """ self.ctps_init_brain_response_data(fname,raw=raw,fname_ica=fname_ica,ica_raw=ica_raw,template_name=template_name) self.ctps_init_freq_bands(freq_ctps=freq_ctps,fmin=fmin,fmax=fmax,fstep=fstep) artifact_events = self.ctps_update_artifact_time_window(aev=exclude_events) #--- init/define bw-bp-filter-obj for ctps to filter ica_raw data within freq bands jfi_bw = jumeg_filter(filter_method=filter_method,filter_type='bp',fcut1=None,fcut2=None,remove_dcoffset=remove_dcoffset,njobs=njobs) jfi_bw.sampling_frequency = self.ica_raw.info['sfreq'] epocher_condition_list = self.ctps_update_hdf_condition_list(condition_list) for condi in epocher_condition_list: self.hdf_obj_reset_key('/ctps/'+ condi) #--- get fresh IC's data & filter inplace print " ---> get ica sources ...\n" ica_orig = self.ica_raw.get_sources(self.raw) #---for filter bands for idx_freq in range( self.ctps_freq_bands.shape[0] ): print " ---> START CTPS Filter Band ==> %d / %d\n" % (idx_freq+1, self.ctps_freq_bands.shape[0]+1 ) print self.ctps_freq_bands[idx_freq] #--- get fresh IC's data & filter inplace print " ---> copy ica sources ...\n" ica = ica_orig.copy() # self.ica_raw.get_sources(self.raw) print " ---> apply filter ...\n" jfi_bw.fcut1 = self.ctps_freq_bands[idx_freq][0] jfi_bw.fcut2 = self.ctps_freq_bands[idx_freq][1] jfi_bw.verbose = self.verbose jfi_bw.apply_filter(ica._data) #--- for epocher condition for condi in epocher_condition_list: print " ---> START condition : " + condi + " CTPS Filter Band ==> %d / %d \n" % (idx_freq+1, self.ctps_freq_bands.shape[0] ) ctps_key = '/ctps/' + condi #stim,ep_param,info_param = self.ctps_update_condition_parameter(condi,artifact_events) #self.ctps_update_ctps_hdf_parameter_time(ctps_parameter=ctps_parameter,ep_param=ep_param) if not( ctps_key in self.HDFobj.keys() ): print"---> NEW HDF key: " + ctps_key stim,ep_param,info_param = self.ctps_update_condition_parameter(condi,artifact_events) self.ctps_update_ctps_hdf_parameter_time(ctps_parameter=ctps_parameter,ep_param=ep_param) self.HDFobj[ctps_key] = pd.DataFrame( self.ctps_freq_bands ).astype(np.int16) Hstorer = self.HDFobj.get_storer(ctps_key) Hstorer.attrs['ctps_hdf_parameter'] = self.ctps_hdf_parameter self.HDFobj[ctps_key+'/events'] = pd.Series( stim['events'][:,0] ).astype(np.int32) # d=np.zeros( [ len(self.ctps_freq_bands_list ),248,1000 ] ).astype(np.int16) self.HDFobj.flush() print"--->done update storer: " + ctps_key else: ev = self.HDFobj.get(ctps_key+'/events') Hstorer = self.HDFobj.get_storer(ctps_key) self.ctps_hdf_parameter = Hstorer.attrs.ctps_hdf_parameter stim['events'] = np.zeros(( ev.size, 3), dtype=np.float64) stim['events'][:,0]= ev stim['events'][:,2]= self.idx_hit #pk_dynamics_key = ctps_key +'/pk_dynamics' pk_dynamics_key = ctps_key +'/pk_dynamics/'+ self.ctps_freq_bands_list[idx_freq] #--- make epochs # print self.ctps_hdf_parameter ica_epochs = mne.Epochs(ica,events=stim['events'],picks=self.ica_picks, event_id=self.ctps_hdf_parameter['event_id'], tmin=self.ctps_hdf_parameter['time_pre'], tmax=self.ctps_hdf_parameter['time_post'], baseline=self.ctps_hdf_parameter['baseline'],verbose=self.verbose,proj=proj) #--- compute CTPS #------- #--- ks_dynamics : ndarray, shape (n_sources, n_times) # The kuiper statistics. #--- pk_dynamics : ndarray, shape (n_sources, n_times) # The normalized kuiper index for ICA sources and # time slices. #--- phase_angles : ndarray, (n_epochs, n_sources, n_times) | None # The phase values for epochs, sources and time slices. If ``assume_raw`` # is False, None is returned. print " ---> apply compute_ctps ...\n" if save_phase_angles : phase_angles_key = ctps_key +'/phase_angle/'+ self.ctps_freq_bands_list[idx_freq] _,pk_dynamics_f64,phase_angles_f64 = ctps( ica_epochs.get_data() ) #_,pk_dynamics_f64,phase_angles_f64 = ctps.compute_ctps( ica_epochs.get_data() ) self.HDFobj[ phase_angles_key ]= pd.Panel( (phase_angles_f64 * self.ctps_hdf_parameter['scale_factor'])).astype( np.int16 ) else : _,pk_dynamics_f64,_ = ctps( ica_epochs.get_data() ) #_,pk_dynamics_f64,_ = ctps.compute_ctps( ica_epochs.get_data() ) self.HDFobj[pk_dynamics_key] = pd.DataFrame( (pk_dynamics_f64 * self.ctps_hdf_parameter['scale_factor']) ).astype( np.int16 ) self.HDFobj.flush() # print self.HDFobj[pk_dynamics_key].transpose().max() fhdr = self.HDFobj.filename self.HDFobj.close() return fhdr
def ctps_ica_steady_state_artifacts_update(self,fname,raw=None,fname_ica=None,ica_raw=None,template_name=None,condition_list=None, filter_method="bw",remove_dcoffset=False,jobs=4, freq_ctps=None,proj=False,njobs=None, ctps_parameter = {'time_pre':-1.0,'time_post':1.0,'baseline':None}, save_phase_angles=False,verbose=False): self.ctps_init_brain_response_data(fname,raw=raw,fname_ica=fname_ica,ica_raw=ica_raw,template_name=template_name) if not freq_ctps: self.ctps_init_freq_bands(freq_ctps=self.steady_state_artifact_bands) else: self.ctps_init_freq_bands(freq_ctps=freq_ctps) #--- init/define bw-bp-filter-obj for ctps to filter ica_raw data within freq bands jfi_bw = jumeg_filter(filter_method=filter_method,filter_type='bp',fcut1=None,fcut2=None,remove_dcoffset=remove_dcoffset,njobs=njobs) jfi_bw.sampling_frequency = self.ica_raw.info['sfreq'] #--- init ctps_hdf_parameter ctps_parameter['dt'] = 4 # ~every 4 sec ctps_parameter['t0'] = 1 ctps_parameter['t1'] = int ( self.raw.index_as_time( self.raw.n_times)[0] ) self.ctps_update_ctps_hdf_parameter_time(ctps_parameter=ctps_parameter) #--- make evs ev_id = 2048 tpoints = np.linspace(ctps_parameter['t0'],ctps_parameter['t1'],int(ctps_parameter['t1']/ctps_parameter['dt']),endpoint=False) # dtp= tp[1:]-tp[0:-1] ev = np.zeros(( tpoints.size, 3), dtype=np.float64) ev[:,0]= self.raw.time_as_index(tpoints) ev[:,2]= ev_id # dtsls=tsls[1:]-tsls[0:-1] #--- make HDF node for steady-state artifacsts storer_attrs = {'ctps_parameter': self.ctps_hdf_parameter} stst_key='/artifacts/steady-state' self.hdf_obj_update_dataframe(pd.DataFrame( self.ctps_freq_bands ).astype(np.int16),key=stst_key,**storer_attrs ) #--- get fresh IC's data & filter inplace print " ---> get ica sources ...\n" ica_orig = self.ica_raw.get_sources(self.raw) #---for filter bands for idx_freq in range( self.ctps_freq_bands.shape[0] ): print " ---> START CTPS Steady-State Artifact Detection Filter Band ==> %d / %d\n" % (idx_freq+1, self.ctps_freq_bands.shape[0]+1 ) print self.ctps_freq_bands[idx_freq] #--- get fresh IC's data & filter inplace print " ---> copy ica sources ...\n" ica = ica_orig.copy() # self.ica_raw.get_sources(self.raw) print " ---> apply filter ...\n" jfi_bw.fcut1 = self.ctps_freq_bands[idx_freq][0] jfi_bw.fcut2 = self.ctps_freq_bands[idx_freq][1] jfi_bw.verbose = self.verbose jfi_bw.apply_filter(ica._data) pk_dynamics_key = stst_key +'/pk_dynamics/'+ self.ctps_freq_bands_list[idx_freq] ica_epochs = mne.Epochs(ica,events=ev,event_id=ev_id, tmin=self.ctps_hdf_parameter['time_pre'], tmax=self.ctps_hdf_parameter['time_post'], baseline=self.ctps_hdf_parameter['baseline'], verbose=self.verbose,proj=proj) print " ---> Steady-State Artifact -> apply compute_ ctps ...\n" #--- compute CTPS #------- #--- ks_dynamics : ndarray, shape (n_sources, n_times) # The kuiper statistics. #--- pk_dynamics : ndarray, shape (n_sources, n_times) # The normalized kuiper index for ICA sources and # time slices. #--- phase_angles : ndarray, (n_epochs, n_sources, n_times) | None # The phase values for epochs, sources and time slices. If ``assume_raw`` # is False, None is returned. if save_phase_angles : phase_angles_key = stst_key +'/phase_angle/'+ self.ctps_freq_bands_list[idx_freq] _,pk_dynamics_f64,phase_angles_f64 = ctps( ica_epochs.get_data() ) self.HDFobj[ phase_angles_key ]= pd.Panel( (phase_angles_f64 * self.ctps_hdf_parameter['scale_factor'])).astype( np.int16 ) else : _,pk_dynamics_f64,_ = ctps( ica_epochs.get_data() ) self.HDFobj[pk_dynamics_key] = pd.DataFrame( (pk_dynamics_f64 * self.ctps_hdf_parameter['scale_factor']) ).astype( np.int16 ) print " ---> done Steady-State Artifact -> "+ pk_dynamics_key print "Max : %f" % ( pk_dynamics_f64.max() ) print "\n" self.HDFobj.flush() fhdr = self.HDFobj.filename self.HDFobj.close() return fhdr
def get_ics_cardiac(meg_raw, ica, flow=8, fhigh=25, tmin=-0.4, tmax=0.4, name_ecg='ECG 001', use_CTPS=True, event_id=999, score_func='pearsonr', thresh=0.25): ''' Identify components with cardiac artefacts ''' from mne.preprocessing import find_ecg_events idx_ecg = [] if name_ecg in meg_raw.ch_names: # get and filter ICA signals ica_raw = ica.get_sources(meg_raw) ica_raw.filter(l_freq=flow, h_freq=fhigh, n_jobs=2, method='fft') # get ECG events events_ecg, _, _ = find_ecg_events(meg_raw, ch_name=name_ecg, event_id=event_id, l_freq=flow, h_freq=fhigh, verbose=False) # CTPS if use_CTPS: # create epochs picks = np.arange(ica.n_components_) ica_epochs = mne.Epochs(ica_raw, events=events_ecg, event_id=event_id, tmin=tmin, tmax=tmax, baseline=None, proj=False, picks=picks, verbose=False) # compute CTPS _, pk, _ = ctps.ctps(ica_epochs.get_data()) pk_max = np.max(pk, axis=1) scores_ecg = pk_max ic_ecg = np.where(pk_max >= thresh)[0] else: # use correlation idx_ecg = [meg_raw.ch_names.index(name_ecg)] ecg_filtered = mne.filter.filter_data(meg_raw[idx_ecg, :][0], meg_raw.info['sfreq'], l_freq=flow, h_freq=fhigh) scores_ecg = ica.score_sources(meg_raw, target=ecg_filtered, score_func=score_func) ic_ecg = np.where(np.abs(scores_ecg) >= thresh)[0] else: logger.warning(">>>> Warning: Could not find ECG channel %s" % name_ecg) events_ecg = [] if len(ic_ecg) == 0: ic_ecg = np.array([-1]) scores_ecg = np.zeros( ica.n_components) #scores_ecg = np.array([-1]) ??? events_ecg = np.array([-1]) else: events_ecg[:, 0] -= meg_raw.first_samp # make sure event samples start from 0 return [ic_ecg, scores_ecg, events_ecg]