def events_find_events(self, raw, **param): """ some how calls <mne.find_events()> input: raw obj, e.g. parameters: {'event_id': 40, 'and_mask': 255, 'events': {'consecutive': True, 'output':'steps','stim_channel': 'STI 014', 'min_duration':0.002,'shortest_event': 2,'mask': 0} } return: pandas data-frame with epoch event structure for stimulus or response channel id : event id offset : np array with TSL event code offset onset : np array with TSL event code onset counts : number of events bads : np.array with index of bad events #=> RESPONSE MATCHING #rt_type : NAN => np array with values MISSED=0 ,TOEARLY=1,WRONG=2,HIT=3 #rt : NAN => np array with reaction time [TSL] #rt_onset: NAN => np array with response onset [TSL] #rt_id : NAN => np array with response key / id dict() with event structure for stimulus or response channel sfreq : sampling frequency => raw.info['sfreq'] duration : {mean,min,max} in TSL system_delay_is_applied : True/False --> if true <system_delay_ms> converted to TSLs and added to the TSLs in onset,offset (TSL => timeslices , your samples) """ if raw is None: print "ERROR in <get_event_structure: No raw obj \n" return None #--- import pandas as pd df = pd.DataFrame(columns=self.data_frame_stimulus_cols) #--- events = param['events'].copy() events['output'] = 'step' ev = mne.find_events(raw, **events) #-- return int64 #--- apply and mask e.g. 255 get the first 8 bits in Trigger channel if param['and_mask']: ev[:, 1:] = np.bitwise_and(ev[:, 1:], param['and_mask']) ev[:, 2:] = np.bitwise_and(ev[:, 2:], param['and_mask']) #--- search and return only events with event_id in event_id-array #--- shape =>(trials,3) => [trial idx ,tsl-onset/ tsl-offset,event id] #--- split this in onset offset ev_onset = np.squeeze(ev[np.where(ev[:, 2]), :]) # > 0 ev_offset = np.squeeze(ev[np.where(ev[:, 1]), :]) if param['event_id']: ev_id = jumeg_base.str_range_to_numpy(param['event_id'], exclude_zero=True) #ev_onset = np.squeeze( ev[np.where( np.in1d( ev[:,2],ev_id ) ), :]) #ev_offset = np.squeeze( ev[np.where( np.in1d( ev[:,1],ev_id ) ), :]) ev_id_idx = np.squeeze(np.where(np.in1d(ev_onset[:, 2], ev_id))) ev_onset = ev_onset[ev_id_idx, :] ev_offset = ev_offset[ev_id_idx, :] if (ev_onset.size == 0): return df #--- apply system delay if is defined e.g. auditory take`s 20ms to subjects ears if param['system_delay_ms']: system_delay_tsl = raw.time_as_index(param['system_delay_ms'] / 1000) # calc in sec ev_onset[:, 0] += system_delay_tsl ev_offset[:, 0] += system_delay_tsl system_delay_is_applied = True else: system_delay_is_applied = False #-- avoid invalid index/dimension error if last offset is none div = ev_offset[:, 0] - ev_onset[:ev_offset[:, 0].size, 0] df['id'] = ev_onset[:, 2] df['onset'] = ev_onset[:, 0] df['offset'] = np.zeros(ev_onset[:, 0].size, dtype=np.long) df['offset'][:ev_offset[:, 0].size] = ev_offset[:, 0] return df, dict({ 'sfreq': raw.info['sfreq'], 'duration': { 'mean': np.rint(div.mean()), 'min': div.min(), 'max': div.max() }, 'system_delay_is_applied': system_delay_is_applied })
def events_response_matching(self, raw, stim_df=None, resp_df=None, **param): """ matching correct responses with respect to <stimulus channel> <output type> (onset,offset) input: stim_df = <stimulus channel data frame> res_df = <response channel data frame> param : parameter dict e.g.:{ 'response':{'counts':1,'window':[0,0.5],'event_id':2,'include_early_ids':[1,4],'events':{'output':'onset'} }, 'stimulus':{'events':{'output'.'onset'}} } return: <stimulus data frame> pandas DataFrame obj with added cols rt_type : response type MISSED,EARLY,WRONG,HIT rt : response time as tsl (RT) rt_id : event id button press code rt_onset : response onset [tsl] rt_offset : response offset [tsl] rt_index : index in response onset / offset rt_counts : number of responses in <response time window> bads : flag for bad epochs; e.g. later use in combination with ecg/eog events """ #--- ck errors err_msg = None if raw is None: err_msg = "ERROR in <apply_response_matching> : no raw obj \n" if (stim_df is None): err_msg += "\nERROR no Stimulus-Data-Frame obj. provided\n" if (resp_df is None): err_msg += "\nERROR no Response-Data-Frame obj. provided\n" if (param is None): err_msg += "\nERROR no Parameter obj. provided\n" #--- ck RT window range if (param['response']['window'][0] >= param['response']['window'][1]): err_msg += "ERROR in parameter response windows\n" if err_msg: print "ERROR in <apply_response_matching>\n" + err_msg + "\n\n" return None #--- extend stimulus data frame for x in self.data_frame_response_cols: stim_df[x] = 0 #np.NaN #--- convert rt window [ms] into tsl (r_window_tsl_start, r_window_tsl_end) = raw.time_as_index(param['response']['window']) #--- get respose code -> event_id [int or string] as np array r_event_id = jumeg_base.str_range_to_numpy( param['response']['event_id']) #--- ck if any toearly-id is defined, returns None if not r_event_id_toearly = jumeg_base.str_range_to_numpy( param['response']['include_early_ids']) #--- get output type: onset or offset stim_output_type = param['stimulus']['events']['output'] resp_output_type = param['response']['events']['output'] #--- loop for all stim events ridx = 0 #--- get rt important part of respose df RESP_TSLs = resp_df[resp_output_type] for idx in stim_df.index: st_tsl_onset = stim_df[stim_output_type][idx] st_window_tsl0 = stim_df[stim_output_type][idx] + r_window_tsl_start st_window_tsl1 = stim_df[stim_output_type][idx] + r_window_tsl_end # st_id = stim_df['id'][idx] #--- check for to TOEARLY responses toearly_tsl0 = st_tsl_onset toearly_tsl1 = st_window_tsl0 #--- look for part of response dataframe ... res_df_early = resp_df[(toearly_tsl0 <= RESP_TSLs) & (RESP_TSLs < toearly_tsl1)] if res_df_early.index.size > 0: if not res_df_early.isin(r_event_id_toearly).all: ridx = res_df_early.index[0] stim_df.rt_counts[idx] = res_df_in.index.size stim_df.rt_onset[idx] = resp_df.onset[ridx] stim_df.rt_offset[idx] = resp_df.offset[ridx] stim_df.rt_id[idx] = resp_df.id[ridx] stim_df.rt_index[idx] = ridx stim_df.rt_type[idx] = self.idx_toearly continue #--- find index of responses from window-start till end of res_event_type array [e.g. onset / offset] # res_df_in = resp_df[ ( st_window_tsl0 <= RESP_TSLs ) & ( RESP_TSLs <= st_window_tsl1) ] resp_df_in_idx = resp_df[(st_window_tsl0 <= RESP_TSLs) & (RESP_TSLs <= st_window_tsl1)].index #--- MISSED response if not np.any(resp_df_in_idx): continue #--- WRONG or HIT; # if res_df_in.index.size > 0 : # ridx = res_df_in.index[0] if resp_df_in_idx.size > 0: ridx = resp_df_in_idx[0] stim_df.rt_counts[idx] = resp_df_in_idx.size stim_df.rt_onset[idx] = resp_df.onset[ridx] stim_df.rt_offset[idx] = resp_df.offset[ridx] stim_df.rt_type[idx] = self.idx_wrong stim_df.rt_id[idx] = resp_df.id[ridx] #stim_df.rt_id[idx] = resp_df.id[resp_df_in_idx].max() #stim_df.rt_id[idx] = np.bitwise_and(resp_df.id[resp_df_in_idx], 72).max() stim_df.rt_index[idx] = ridx #--- HIT; ck number of responses; ck pressed buttons; wrong if more than count if (stim_df.rt_counts[idx] <= param['response']['counts']): #if np.all( res_df_in.id.isin( r_event_id ) ) : if np.all(resp_df.id[resp_df_in_idx].isin(r_event_id)): stim_df.rt_type[idx] = self.idx_hit # if (stim_df.rt_id[idx] <1) and(stim_df.rt_type[idx] == self.idx_wrong): # print"!!ERROR" # print resp_df_in_idx # print resp_df.onset[resp_df_in_idx] # print resp_df.id[resp_df_in_idx] # assert "erroe rt" #--- MISSED response else: continue #--- calc reaction time (rt in tsl) if stim_output_type == 'offset': sto = stim_df.offset else: sto = stim_df.onset if resp_output_type == 'offset': rto = stim_df.rt_offset else: rto = stim_df.rt_onset stim_df.rt = rto - sto stim_df.rt[(stim_df.rt_type == self.idx_missed)] = 0 #--- if self.verbose: for kidx in range(len(self.rt_type_list)): print "\n\n---> Stimulus DataFrame Type: " + self.rt_type_list[ kidx] ddf = stim_df[stim_df.rt_type == kidx] if ddf.index.size > 0: print ddf.describe() else: print "---> EMPTY" print "---------------------------" print "\n\n" #import sys #char = sys.stdin.read(1) return stim_df
def events_find_events(self,raw,**param): """ some how calls <mne.find_events()> input: raw obj, e.g. parameters: {'event_id': 40, 'and_mask': 255, 'events': {'consecutive': True, 'output':'steps','stim_channel': 'STI 014', 'min_duration':0.002,'shortest_event': 2,'mask': 0} } return: pandas data-frame with epoch event structure for stimulus or response channel id : event id offset : np array with TSL event code offset onset : np array with TSL event code onset counts : number of events bads : np.array with index of bad events #=> RESPONSE MATCHING #rt_type : NAN => np array with values MISSED=0 ,TOEARLY=1,WRONG=2,HIT=3 #rt : NAN => np array with reaction time [TSL] #rt_onset: NAN => np array with response onset [TSL] #rt_id : NAN => np array with response key / id dict() with event structure for stimulus or response channel sfreq : sampling frequency => raw.info['sfreq'] duration : {mean,min,max} in TSL system_delay_is_applied : True/False --> if true <system_delay_ms> converted to TSLs and added to the TSLs in onset,offset (TSL => timeslices , your samples) """ if raw is None: print "ERROR in <get_event_structure: No raw obj \n" return None #--- import pandas as pd df = pd.DataFrame(columns = self.data_frame_stimulus_cols) #--- events = param['events'].copy() events['output'] = 'step' ev = mne.find_events(raw, **events) #--- apply and mask e.g. 255 get the first 8 bits in Trigger channel if param['and_mask']: ev[:, 1:] = np.bitwise_and(ev[:, 1:], param['and_mask']) ev[:, 2:] = np.bitwise_and(ev[:, 2:], param['and_mask']) #--- search and return only events with event_id in event_id-array #--- shape =>(trials,3) => [trial idx ,tsl-onset/ tsl-offset,event id] #--- split this in onset offset if param['event_id']: ev_id = jumeg_base.str_range_to_numpy(param['event_id']) ev_onset = np.squeeze( ev[np.where( np.in1d( ev[:,2],ev_id ) ), :]) ev_offset = np.squeeze( ev[np.where( np.in1d( ev[:,1],ev_id ) ), :]) #--- get all ids e.g. response for later response matching else: ev_onset = ev[0::2,] ev_offset = ev[1::2,] if ( ev_onset.size == 0 ): return df #--- apply system delay if is defined e.g. auditory take`s 20ms to subjects ears if param['system_delay_ms']: system_delay_tsl = raw.time_as_index( param['system_delay_ms']/1000 ) # calc in sec ev_onset[:, 0] += system_delay_tsl ev_offset[:, 0]+= system_delay_tsl system_delay_is_applied = True else: system_delay_is_applied = False div = ev_offset[:,0] - ev_onset[:,0] df['id'] = ev_onset[:,2] df['onset'] = ev_onset[:,0] df['offset'] = ev_offset[:,0] return df,dict( { 'sfreq' : raw.info['sfreq'], 'duration' :{'mean':np.rint(div.mean()),'min':div.min(),'max':div.max()}, 'system_delay_is_applied' : system_delay_is_applied } )
def events_response_matching(self,raw,stim_df=None,resp_df=None, **param ): """ matching correct responses with respect to <stimulus channel> <output type> (onset,offset) input: stim_df = <stimulus channel data frame> res_df = <response channel data frame> param : parameter dict e.g.:{ 'response':{'counts':1,'window':[0,0.5],'event_id':2,'include_early_ids':[1,4],'events':{'output':'onset'} }, 'stimulus':{'events':{'output'.'onset'}} } return: <stimulus data frame> pandas DataFrame obj with added cols rt_type : response type MISSED,EARLY,WRONG,HIT rt : response time as tsl (RT) rt_id : event id button press code rt_onset : response onset [tsl] rt_offset : response offset [tsl] rt_index : index in response onset / offset rt_counts : number of responses in <response time window> bads : flag for bad epochs; e.g. later use in combination with ecg/eog events """ #--- ck errors err_msg = None if raw is None: err_msg = "ERROR in <apply_response_matching> : no raw obj \n" if (stim_df is None): err_msg +="\nERROR no Stimulus-Data-Frame obj. provided\n" if (resp_df is None): err_msg +="\nERROR no Response-Data-Frame obj. provided\n" if (param is None): err_msg +="\nERROR no Parameter obj. provided\n" #--- ck RT window range if ( param['response']['window'][0] >= param['response']['window'][1] ): err_msg += "ERROR in parameter response windows\n" if err_msg: print "ERROR in <apply_response_matching>\n" + err_msg +"\n\n" return None #--- extend stimulus data frame for x in self.data_frame_response_cols : stim_df[x]= 0 #np.NaN #--- convert rt window [ms] into tsl (r_window_tsl_start, r_window_tsl_end ) = raw.time_as_index( param['response']['window'] ); #--- get respose code -> event_id [int or string] as np array r_event_id = jumeg_base.str_range_to_numpy( param['response']['event_id'] ) #--- ck if any toearly-id is defined, returns None if not r_event_id_toearly = jumeg_base.str_range_to_numpy( param['response']['include_early_ids'] ) #--- get output type: onset or offset stim_output_type = param['stimulus']['events']['output'] resp_output_type = param['response']['events']['output'] #--- loop for all stim events ridx = 0 #--- get rt important part of respose df RESP_TSLs = resp_df[resp_output_type] for idx in stim_df.index : st_tsl_onset = stim_df[stim_output_type][idx] st_window_tsl0 = stim_df[stim_output_type][idx] + r_window_tsl_start st_window_tsl1 = stim_df[stim_output_type][idx] + r_window_tsl_end st_id = stim_df['id'][idx] #--- check for to TOEARLY responses toearly_tsl0 = st_tsl_onset toearly_tsl1 = st_window_tsl0 #--- look for part of response dataframe ... res_df_early = resp_df[(toearly_tsl0 <= RESP_TSLs ) & ( RESP_TSLs < toearly_tsl1 )] if res_df_early.index.size > 0 : if not res_df_early.isin( r_event_id_toearly ).all : ridx = res_df_early.index[0] stim_df.rt_counts[idx] = res_df_in.index.size stim_df.rt_onset[idx] = resp_df.onset[ridx] stim_df.rt_offset[idx] = resp_df.offset[ridx] stim_df.rt_id[idx] = resp_df.id[ridx] stim_df.rt_index[idx] = ridx stim_df.rt_type[idx] = self.idx_toearly continue #--- find index of responses from window-start till end of res_event_type array [e.g. onset / offset] res_df_in = resp_df[ ( st_window_tsl0 <= RESP_TSLs ) & ( RESP_TSLs <= st_window_tsl1) ] #--- MISSED response if res_df_in.empty : continue #--- WRONG or HIT; if res_df_in.index.size > 0 : ridx = res_df_in.index[0] stim_df.rt_counts[idx] = res_df_in.index.size stim_df.rt_onset[idx] = resp_df.onset[ridx] stim_df.rt_offset[idx] = resp_df.offset[ridx] stim_df.rt_type[idx] = self.idx_wrong stim_df.rt_id[idx] = resp_df.id[ridx] stim_df.rt_index[idx] = ridx #--- HIT; ck number of responses; ck pressed buttons; wrong if more than count if ( stim_df.rt_counts[idx] <= param['response']['counts'] ): if res_df_in.id.isin( r_event_id ).all : stim_df.rt_type[idx] = self.idx_hit #--- calc reaction time (rt in tsl) if stim_output_type == 'offset' : sto = stim_df.offset else: sto = stim_df.onset if resp_output_type == 'offset' : rto = stim_df.rt_offset else: rto = stim_df.rt_onset stim_df.rt = rto - sto #--- if self.verbose: for kidx in range( len( self.rt_type_list ) ) : print "\n\n---> Stimulus DataFrame Type: " + self.rt_type_list[kidx] ddf = stim_df[ stim_df.rt_type == kidx ] if ddf.index.size > 0 : print ddf.describe() else : print "---> EMPTY" print"---------------------------" print "\n\n" #import sys #char = sys.stdin.read(1) return stim_df
def events_response_matching(self,raw,stim_df=None,resp_df=None, **param ): """ matching correct responses with respect to <stimulus channel> <output type> (onset,offset) input: stim_df = <stimulus channel data frame> res_df = <response channel data frame> param : parameter dict e.g.:{ 'response':{'counts':1,'window':[0,0.5],'event_id':2,'include_early_ids':[1,4],'events':{'output':'onset'} }, 'stimulus':{'events':{'output'.'onset'}} } return: <stimulus data frame> pandas DataFrame obj with added cols rt_type : response type MISSED,EARLY,WRONG,HIT rt : response time as tsl (RT) rt_id : event id button press code rt_onset : response onset [tsl] rt_offset : response offset [tsl] rt_index : index in response onset / offset rt_counts : number of responses in <response time window> bads : flag for bad epochs; e.g. later use in combination with ecg/eog events """ #--- ck errors err_msg = None if raw is None: err_msg = "ERROR in <apply_response_matching> : no raw obj \n" if (stim_df is None): err_msg +="\nERROR no Stimulus-Data-Frame obj. provided\n" if (resp_df is None): err_msg +="\nERROR no Response-Data-Frame obj. provided\n" if (param is None): err_msg +="\nERROR no Parameter obj. provided\n" #--- ck RT window range if ( param['response']['window'][0] >= param['response']['window'][1] ): err_msg += "ERROR in parameter response windows\n" if err_msg: print "ERROR in <apply_response_matching>\n" + err_msg +"\n\n" return None #--- extend stimulus data frame for x in self.data_frame_response_cols : stim_df[x]= 0 #np.NaN #--- convert rt window [ms] into tsl (r_window_tsl_start, r_window_tsl_end ) = raw.time_as_index( param['response']['window'] ); #--- get respose code -> event_id [int or string] as np array r_event_id = jumeg_base.str_range_to_numpy( param['response']['event_id'] ) #--- ck if any toearly-id is defined, returns None if not r_event_id_toearly = jumeg_base.str_range_to_numpy( param['response']['include_early_ids'] ) #--- get output type: onset or offset stim_output_type = param['stimulus']['events']['output'] resp_output_type = param['response']['events']['output'] #--- loop for all stim events ridx = 0 #--- get rt important part of respose df RESP_TSLs = resp_df[resp_output_type] for idx in stim_df.index : st_tsl_onset = stim_df[stim_output_type][idx] st_window_tsl0 = stim_df[stim_output_type][idx] + r_window_tsl_start st_window_tsl1 = stim_df[stim_output_type][idx] + r_window_tsl_end
======= ev = mne.find_events(raw, **events) #-- return int64 >>>>>>> fb_devel_03082015 #--- apply and mask e.g. 255 get the first 8 bits in Trigger channel if param['and_mask']: ev[:, 1:] = np.bitwise_and(ev[:, 1:], param['and_mask']) ev[:, 2:] = np.bitwise_and(ev[:, 2:], param['and_mask']) #--- search and return only events with event_id in event_id-array #--- shape =>(trials,3) => [trial idx ,tsl-onset/ tsl-offset,event id] #--- split this in onset offset <<<<<<< HEAD if param['event_id']: ev_id = jumeg_base.str_range_to_numpy(param['event_id']) ev_onset = np.squeeze( ev[np.where( np.in1d( ev[:,2],ev_id ) ), :]) ev_offset = np.squeeze( ev[np.where( np.in1d( ev[:,1],ev_id ) ), :]) #--- get all ids e.g. response for later response matching else: ev_onset = ev[0::2,] ev_offset = ev[1::2,] ======= ev_onset = np.squeeze( ev[np.where( ev[:,2] ),:]) # > 0 ev_offset = np.squeeze( ev[np.where( ev[:,1] ),:]) if param['event_id']: ev_id = jumeg_base.str_range_to_numpy(param['event_id'],exclude_zero=True)