def __init__(self,adjust_size=True,save=True,startcode=128,copy_eeg_events_to_trigger=False,filter_meg=False,filter_eeg=True,check_ids=True, meg={'stim_channel':'STI 014','min_duration':0.002,'shortest_event':3 }, eeg={'stim_channel':'STI 014','response_shift':1000,'stim_type':'STIMULUS','and_mask':None} ): # meg={'stim_channel':'STI 013'},eeg={'stim_channel':'STI 014','response_shift':1000,'stim_type':'RESPONSE','and_mask':None} super(JuMEG_MergeMEEG,self).__init__() self.meg = JuMEG_MergeMEEG_HiLoRate(system='MEG') self.meg.stim_channel = meg['stim_channel'] self.meg.shortest_event = meg['shortest_event'] self.meg.min_duration = meg['min_duration'] self.eeg = JuMEG_MergeMEEG_HiLoRate(system='EEG') self.eeg.stim_channel = eeg["stim_channel"] self.eeg.response_shift = eeg["response_shift"] # brainvision_response_shift to mark response bits to higher 8bit in STI channel self.eeg.stim_type = eeg["stim_type"] self.eeg.and_mask = eeg['and_mask'] #self.eeg.startcode = startcode self.brainvision_response_shift = self.eeg.response_shift self.copy_eeg_events_to_trigger = copy_eeg_events_to_trigger self.match_first_event = False # flag , if no startcode found try match with first event code #--- output self.meeg_fname = None self.meeg_extention = ",meeg-raw.fif" #--- change channel names and group # self.channel_types = {'EEG 001': u'ecg', 'EEG 002': u'eog', 'EEG 003': u'eog'} # self.channel_names = {'EEG 001': u'ECG 001', 'EEG 002': u'EOG hor', 'EEG 003': u'EOG ver'} #--- filter obj self.filter = jumeg_filter( filter_method="bw",filter_type='lp',fcut1=None,fcut2=None,remove_dcoffset=False,notch=[] ) self.__event_id = 128 self.verbose = False self.debug = False self.do_adjust_data_size = adjust_size self.do_save = save self.do_filter_meg = filter_meg self.do_filter_eeg = filter_eeg self.do_check_ids = check_ids #self.do_check_data_drift = check_data_drift self.startcode = startcode self.__default_event_id = 128 self.bads_list = []
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
"parameter": { "event_extention": ".eve", "save_condition": { "events": True, "epochs": True, "evoked": True }, "weights": { "mode": "equal", "method": "median", "skipp_first": None } # "time":{"time_pre":null,"time_post":null,"baseline":null}, # "exclude_events":{"eog_events":{"tmin":-0.4,"tmax":0.6} } }, } } #--- if DO_FILTER: from jumeg.filter.jumeg_filter import jumeg_filter jf = jumeg_filter() jb.picks.exclude_trigger jf.vebose = verbose jf.apply_filter(raw._data, picks=jb.picks.exclude_trigger(raw)) # inplace #--- print "---> EPOCHER Epochs" print " -> File : " + fname print " -> Epocher Template: " + template_name + "\n" raw, fname = jumeg_epocher.apply_epochs(fname=fname, raw=raw, **ep_param)
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)): ''' Applies CTPS to a list of ICA files. ''' import mne, ctps, os import numpy as np from jumeg.filter import jumeg_filter fiws = jumeg_filter.jumeg_filter(filter_method="ws") fiws.filter_type = 'bp' # bp, lp, hp fiws.dcoffset = True fiws.filter_attenuation_factor = 1 nfreq = len(freqs) print freqs print nfreq # 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' # check list of filenames if isinstance(fname_ica, list): fnlist = fname_ica else: if isinstance(fname_ica, str): fnlist = list([fname_ica]) else: fnlist = 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.strip('-ica.fif') fnraw = basename+'-raw.fif' #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, 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) 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) # compute CTPS _, pk, pt = ctps.compute_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'] = pkarr dctps['pt'] = ptarr dctps['pkmax'] = pkmax_arr dctps['nsamp'] = len(times) dctps['times'] = times dctps['tmin'] = ica_epochs.tmin dctps['tmax'] = ica_epochs.tmax fnctps = basename + ',ctps-'+trig_name np.save(fnctps, dctps) # Note; loading example: dctps = np.load(fnctps).items() else: event_id=None
def __init__(self, adjust_size=True, save=True, startcode=128, copy_eeg_events_to_trigger=False, meg={'stim_channel': 'STI 014'}, eeg={ 'stim_channel': 'STI 014', 'response_shift': 1000, 'stim_type': 'STIMULUS', 'and_mask': None }): # meg={'stim_channel':'STI 013'},eeg={'stim_channel':'STI 014','response_shift':1000,'stim_type':'RESPONSE','and_mask':None} ''' Class JuMEG_MergeMEEG -> merge BrainVision ECG/EOG signals into MEG Fif file -> finding common onset via startcode in TRIGGER channel e.g <STI 014> <STI 013> -> filter data FIR lp butter 200Hz / 400Hz -> downsampling eeg data, srate sould be igher than meg e.g. eeg:5kHz meg:1017.25Hz -> rename groups and channel names dynamic & automatic !!! meg EEG 0001 -> ECG group ecg meg EEG 0002 -> EOG_xxx group eog meg EEG 0003 -> EOG_xxx group ecg input adjust= True : ajust raw-obj data size to startcode-onset and last common sample beween MEG and EEG data save = True : save merged raw-obj parameter set via obj: meg_fname = None <full file name> eeg_fname = None <eeg brainvision vhdr full file name> with extention <.vhdr> meeg_extention = ",meeg-raw.fif" output extention stim_channel = 'STI 014' startcode = 128 start code for common onset in <stim_channel> brainvision_channel_type = 'STIMULUS' brainvision_stim_channel = 'STI 014' brainvision_response_shift = 1000 used for mne.io.read_raw_brainvision will be added to the response value flags: verbose = False do_adjust_size = True do_save = True do_filter_meg = True do_filter_eeg = True filter option: can be canged via <obj.filter> filter.filter_method = "bw" filter.filter_type ='lp' filter.fcut1 = None -> automatic selected 200Hz or 400Hz return: raw obj; new meeg file name ''' super(JuMEG_MergeMEEG, self).__init__() self.meg = JuMEG_MergeMEEG_HiLoRate(system='MEG') self.meg.stim_channel = meg['stim_channel'] #self.meg.startcode = startcode self.eeg = JuMEG_MergeMEEG_HiLoRate(system='EEG') self.eeg.stim_channel = eeg["stim_channel"] self.eeg.response_shift = eeg[ "response_shift"] # brainvision_response_shift to mark response bits to higher 8bit in STI channel self.eeg.stim_type = eeg["stim_type"] self.eeg.and_mask = eeg['and_mask'] #self.eeg.startcode = startcode self.brainvision_response_shift = self.eeg.response_shift self.copy_eeg_events_to_trigger = copy_eeg_events_to_trigger #--- output self.meeg_fname = None self.meeg_extention = ",meeg-raw.fif" #--- change channel names and group # self.channel_types = {'EEG 001': u'ecg', 'EEG 002': u'eog', 'EEG 003': u'eog'} # self.channel_names = {'EEG 001': u'ECG 001', 'EEG 002': u'EOG hor', 'EEG 003': u'EOG ver'} #--- filter obj self.filter = jumeg_filter(filter_method="bw", filter_type='lp', fcut1=None, fcut2=None, remove_dcoffset=False, notch=[]) self.__event_id = 128 self.verbose = False self.debug = False self.do_adjust_data_size = adjust_size self.do_save = save self.do_filter_meg = True self.do_filter_eeg = True self.startcode = startcode self.bads_list = []