def createNewProject(self, file_name, pen_data): PenDataSegmentCategory.clearSegmentCache() self._project_settings = None self._name = file_name # Normalize pen sample times so first sample starts at 0.0 sec. self._original_timebase_offset=pen_data[0]['time'] pen_data['time']-=self._original_timebase_offset pen_data['time']=pen_data['time']/1000.0 # to flip data vertically by changing y pos values... # Maybe better to see if pyqtgraph has a built in option # to flip a plot vertically. # # pmax = pen_data['y'].max() # pmin = pen_data['y'].min() # pen_data['y'] = pmax-pen_data['y']+pmin self._pendata = pen_data self.nonzero_pressure_mask=self._pendata['pressure']>0 # nonzero_regions_ix will be a tuple of (starts, stops, lengths) arrays self.nonzero_region_ix=contiguous_regions(self.nonzero_pressure_mask) self._segmentset=PenDataSegmentCategory(name=self.name,project=self) self._pendata['segment_id']=self._segmentset.id if self._selectedtimeregion is None: MarkWriteProject._selectedtimeregion = SelectedTimePeriodItem(project=self) else: MarkWriteProject._selectedtimeregion.project = self MarkWriteProject._selectedtimeregion.setBounds(bounds=(self.pendata['time'][0], self.pendata['time'][-1])) MarkWriteProject._selectedtimeregion.setRegion([self.pendata['time'][0], self.pendata['time'][0] + 1.0])
def createNewProject(self, file_name, pen_data, condvars=None, stime_var=None, etime_var=None, file_type=None): PenDataSegmentCategory.clearSegmentCache() self._project_settings = None self._name = file_name self._filetype = file_type self._expcondvars = condvars self._stimevar = stime_var self._etimevar = etime_var # go through each trial, select only the samples within # the trial period, add the trials sample array to list of trial # sample data. samples_by_trial = [] trial_times = None if self._expcondvars is not None and self._stimevar is not None and self._etimevar is not None: trial_times = [] for t in self._expcondvars: try: trialstart = float(t[self._stimevar]) trialend = float(t[self._etimevar]) trial_times.append((trialstart,trialend)) trial_samples = pen_data[(pen_data['time'] >= trialstart) & (pen_data['time'] <= trialend)] samples_by_trial.append(trial_samples) #print "trial samples:",trial_samples.shape except: print("Error getting trial time period:") import traceback traceback.print_exc() if samples_by_trial: # make pen_data == concat'ed samples_by_trial pen_data = np.concatenate(samples_by_trial) # turn trial start, stop time list into np array trial_times = np.asarray(trial_times) # Normalize pen sample times so first sample starts at 0.0 sec. self._original_timebase_offset=pen_data[0]['time'] pen_data['time']-=self._original_timebase_offset if trial_times is not None: trial_times-=self._original_timebase_offset self._trialtimes = trial_times # Change time stamps to sec.msec format, if needed if file_type != 'hdf5': # data from iohub hdf5 file is already in sec.msec format pen_data['time']=pen_data['time']/1000.0 self._pendata = pen_data self.nonzero_pressure_mask=self._pendata['pressure']>0 # nonzero_regions_ix will be a tuple of (starts, stops, lengths) arrays self.nonzero_region_ix=contiguous_regions(self.nonzero_pressure_mask) self._segmentset=PenDataSegmentCategory(name=self.name,project=self) self._pendata['segment_id']=self._segmentset.id if self._selectedtimeregion is None: MarkWriteProject._selectedtimeregion = SelectedTimePeriodItem(project=self) else: MarkWriteProject._selectedtimeregion.project = self
def postprocess(cls,pendata): # Set initial sample state to HOVERING or PRESSED based on pressure pendata['state'][pendata['pressure']==0]=SAMPLE_STATES["HOVERING"] pendata['state'][pendata['pressure']>0]=SAMPLE_STATES["PRESSED"] # Calculate ISI value for samples 1-N sample_dts = pendata['time'][1:]-pendata['time'][:-1] # Handle non monotonic time stamped samples non_mono_ix = (sample_dts < 0.0).nonzero()[0] if len(non_mono_ix)>0: non_mono_ix = non_mono_ix + 1 print ">>>>>>>" print "WARNING: Non-monotonic Timestamps Detected." print " Removing %d sample(s) with negative ISIs...."%(len(non_mono_ix)) print " Sample Indices:",non_mono_ix print "<<<<<<<" print # TODO: This code needs updating, it is a quick and dirty fix. # Simply removes samples with negative ISI. In Guidos files, # this seems to only occur within the first few samples # of the file, if at all. pendata = np.delete(pendata,non_mono_ix) sample_dts = pendata['time'][1:]-pendata['time'][:-1] # # Detect Series Boundaries Using an ISI Threshold alg. # # Determine ISI threshold value to use if SETTINGS['series_detect_max_isi_msec'] > 0: series_isi_thresh = SETTINGS['series_detect_max_isi_msec']/1000.0 else: try: series_isi_thresh = np.percentile(sample_dts,99.0,interpolation='nearest')*2.5 except TypeError: series_isi_thresh = np.percentile(sample_dts,99.0)*2.5 print "series_isi_thresh:",series_isi_thresh print # Find sample array ix where ISI threshold is exceeded. # These are the series start ix series_start_ixs = (sample_dts > series_isi_thresh).nonzero()[0] if len(series_start_ixs)>0: series_start_ixs=series_start_ixs+1 # First sample in data file is always a series start. series_start_ixs = np.insert(series_start_ixs, 0, 0) # Create list of series_start, series_end indexs for slicing series_bounds = [] # holds (series_start_ix, series_end_ix, # series_len, stime, etime, series_dur, series_dur/series_len) for i, start_ix in enumerate(series_start_ixs[:-1]): end_ix = series_start_ixs[i+1] stime, etime = pendata['time'][[start_ix,end_ix-1]] sdur = etime - stime slen = end_ix-start_ix series_bounds.append((start_ix,end_ix, slen,stime, etime,sdur,sdur/slen)) start_ix, end_ix = series_start_ixs[-1], len(pendata) stime, etime = pendata['time'][[start_ix,end_ix-1]] sdur = etime - stime slen = end_ix-start_ix series_bounds.append((start_ix,end_ix, slen,stime, etime,sdur,sdur/(slen-1))) # For each Sample Series in the data file, # 1) handle duplicate sample timestamps # 2) set FIRST_PRESS and FIRST_HOVER sample status as needed. for i, sb in enumerate(series_bounds): # Cleanup duplicate timestamps after series bounds have been found # TODO: This code needs updating, it is a quick and dirty fix. # A constant ISI across all series should really be used. dup_ix = (sample_dts[sb[0]:sb[1]] == 0.0).nonzero()[0]# + sb[0] if len(dup_ix)>0: start_ix, end_ix, slen, stime, etime, sdur, sampling_interval = sb calc_sample_times, calc_isi = np.linspace(etime-slen*sampling_interval,etime,slen,retstep=True) print ">>>>>>>" print "Warning: Duplicate timestamps found in series", i+1, (stime, etime) print " Sample / Duplicate Count:",slen,'/',len(dup_ix) print " Calc. Series ISI:",calc_isi print " Updating Series sample times......." print "<<<<<<<" print pendata['time'][start_ix:end_ix] = calc_sample_times[:] # Update sample state field to include FIRST_PRESS as needed run_start_ixs, _, _ = contiguous_regions(pendata['state'][sb[0]:sb[1]] == SAMPLE_STATES["PRESSED"]) if len(run_start_ixs): run_start_ixs = np.array(run_start_ixs, dtype=np.uint32) + sb[0] pendata['state'][run_start_ixs]+= SAMPLE_STATES['FIRST_PRESS'] # Update sample state field to include FIRST_HOVER as needed hover_start_ixs, _, _ = contiguous_regions(pendata['state'][sb[0]:sb[1]] == SAMPLE_STATES["HOVERING"]) if len(hover_start_ixs): hover_start_ixs = np.array(hover_start_ixs, dtype=np.uint32) + sb[0] pendata['state'][hover_start_ixs]+= SAMPLE_STATES['FIRST_HOVER'] # For whole sample array, update series start sample's status # with FIRST_ENTER value. if len(series_start_ixs): pendata['state'][series_start_ixs] += SAMPLE_STATES['FIRST_ENTER'] # Return pendata array with sample state field populated. return pendata
def postprocess(cls, pendata): # Set initial sample state to HOVERING or PRESSED based on pressure pendata['state'][pendata['pressure'] == 0] = SAMPLE_STATES["HOVERING"] pendata['state'][pendata['pressure'] > 0] = SAMPLE_STATES["PRESSED"] # Calculate ISI value for samples 1-N sample_dts = pendata['time'][1:] - pendata['time'][:-1] # Handle non monotonic time stamped samples non_mono_ix = (sample_dts < 0.0).nonzero()[0] if len(non_mono_ix) > 0: non_mono_ix = non_mono_ix + 1 print ">>>>>>>" print "WARNING: Non-monotonic Timestamps Detected." print " Removing %d sample(s) with negative ISIs...." % ( len(non_mono_ix)) print " Sample Indices:", non_mono_ix print "<<<<<<<" print # TODO: This code needs updating, it is a quick and dirty fix. # Simply removes samples with negative ISI. In Guidos files, # this seems to only occur within the first few samples # of the file, if at all. pendata = np.delete(pendata, non_mono_ix) sample_dts = pendata['time'][1:] - pendata['time'][:-1] # # Detect Series Boundaries Using an ISI Threshold alg. # # Determine ISI threshold value to use if SETTINGS['series_detect_max_isi_msec'] > 0: series_isi_thresh = SETTINGS['series_detect_max_isi_msec'] / 1000.0 else: try: series_isi_thresh = np.percentile( sample_dts, 99.0, interpolation='nearest') * 2.5 except TypeError: series_isi_thresh = np.percentile(sample_dts, 99.0) * 2.5 print "series_isi_thresh:", series_isi_thresh print # Find sample array ix where ISI threshold is exceeded. # These are the series start ix series_start_ixs = (sample_dts > series_isi_thresh).nonzero()[0] if len(series_start_ixs) > 0: series_start_ixs = series_start_ixs + 1 # First sample in data file is always a series start. series_start_ixs = np.insert(series_start_ixs, 0, 0) # Create list of series_start, series_end indexs for slicing series_bounds = [] # holds (series_start_ix, series_end_ix, # series_len, stime, etime, series_dur, series_dur/series_len) for i, start_ix in enumerate(series_start_ixs[:-1]): end_ix = series_start_ixs[i + 1] stime, etime = pendata['time'][[start_ix, end_ix - 1]] sdur = etime - stime slen = end_ix - start_ix series_bounds.append( (start_ix, end_ix, slen, stime, etime, sdur, sdur / slen)) start_ix, end_ix = series_start_ixs[-1], len(pendata) stime, etime = pendata['time'][[start_ix, end_ix - 1]] sdur = etime - stime slen = end_ix - start_ix series_bounds.append( (start_ix, end_ix, slen, stime, etime, sdur, sdur / (slen - 1))) # For each Sample Series in the data file, # 1) handle duplicate sample timestamps # 2) set FIRST_PRESS and FIRST_HOVER sample status as needed. for i, sb in enumerate(series_bounds): # Cleanup duplicate timestamps after series bounds have been found # TODO: This code needs updating, it is a quick and dirty fix. # A constant ISI across all series should really be used. dup_ix = (sample_dts[sb[0]:sb[1]] == 0.0).nonzero()[0] # + sb[0] if len(dup_ix) > 0: start_ix, end_ix, slen, stime, etime, sdur, sampling_interval = sb calc_sample_times, calc_isi = np.linspace( etime - slen * sampling_interval, etime, slen, retstep=True) print ">>>>>>>" print "Warning: Duplicate timestamps found in series", i + 1, ( stime, etime) print " Sample / Duplicate Count:", slen, '/', len( dup_ix) print " Calc. Series ISI:", calc_isi print " Updating Series sample times......." print "<<<<<<<" print pendata['time'][start_ix:end_ix] = calc_sample_times[:] # Update sample state field to include FIRST_PRESS as needed run_start_ixs, _, _ = contiguous_regions( pendata['state'][sb[0]:sb[1]] == SAMPLE_STATES["PRESSED"]) if len(run_start_ixs): run_start_ixs = np.array(run_start_ixs, dtype=np.uint32) + sb[0] pendata['state'][run_start_ixs] += SAMPLE_STATES['FIRST_PRESS'] # Update sample state field to include FIRST_HOVER as needed hover_start_ixs, _, _ = contiguous_regions( pendata['state'][sb[0]:sb[1]] == SAMPLE_STATES["HOVERING"]) if len(hover_start_ixs): hover_start_ixs = np.array(hover_start_ixs, dtype=np.uint32) + sb[0] pendata['state'][hover_start_ixs] += SAMPLE_STATES[ 'FIRST_HOVER'] # For whole sample array, update series start sample's status # with FIRST_ENTER value. if len(series_start_ixs): pendata['state'][series_start_ixs] += SAMPLE_STATES['FIRST_ENTER'] # Return pendata array with sample state field populated. return pendata