def filterEyeSamples(filter_type, xpix, ypix, pupil, invalid_data_mask, **kwargs): processSampleEventGaps(xpix, ypix, pupil, invalid_data_mask, 'linear') vac = VisualAngleCalc(**calibration_area_info) xdeg, ydeg = vac.pix2deg(xpix, ypix) if filter_type == 'butter': wn = kwargs.get('wn', 0.2) order = kwargs.get('order', 2) b, a = butter(order, wn, 'low') x_filtered = filtfilt(b, a, xdeg) y_filtered = filtfilt(b, a, ydeg) elif filter_type == 'gauss': sigma = kwargs.get('sigma', 2) x_filtered = gaussian_filter1d(xdeg, sigma) y_filtered = gaussian_filter1d(ydeg, sigma) elif filter_type == 'median': size = kwargs.get('size', 5) x_filtered = medfilt(xdeg, size) y_filtered = medfilt(ydeg, size) elif filter_type == 'sg': size = kwargs.get('size', 7) order = kwargs.get('order', 2) x_filtered = savitzky_golay(xdeg, window_size=size, order=order) y_filtered = savitzky_golay(ydeg, window_size=size, order=order) elif filter_type == 'average': weights = np.asarray(kwargs.get('weights', [1., 2., 3., 2., 1.])) weights = weights / np.sum(weights) x_filtered = np.convolve(xdeg, weights, 'same') y_filtered = np.convolve(ydeg, weights, 'same') else: raise ValueError( 'Unknown Filter Type: %s. Must be one of %s' % (filter_type, str(['sg', 'butter', 'gauss', 'median']))) xdeg[invalid_data_mask] = np.NaN ydeg[invalid_data_mask] = np.NaN x_filtered[invalid_data_mask] = np.NaN y_filtered[invalid_data_mask] = np.NaN return (xdeg, ydeg), (x_filtered, y_filtered)
def filterEyeSamples(filter_type,xpix,ypix,pupil,invalid_data_mask,**kwargs): processSampleEventGaps(xpix,ypix,pupil,invalid_data_mask,'linear') vac=VisualAngleCalc(**calibration_area_info) xdeg,ydeg=vac.pix2deg(xpix,ypix) if filter_type=='butter': wn=kwargs.get('wn',0.2) order=kwargs.get('order',2) b, a = butter(order, wn, 'low') x_filtered = filtfilt(b, a, xdeg) y_filtered = filtfilt(b, a, ydeg) elif filter_type=='gauss': sigma=kwargs.get('sigma',2) x_filtered = gaussian_filter1d(xdeg,sigma) y_filtered = gaussian_filter1d(ydeg,sigma) elif filter_type=='median': size=kwargs.get('size',5) x_filtered=medfilt(xdeg,size) y_filtered=medfilt(ydeg,size) elif filter_type=='sg': size=kwargs.get('size',7) order=kwargs.get('order',2) x_filtered=savitzky_golay(xdeg,window_size=size, order=order) y_filtered=savitzky_golay(ydeg,window_size=size, order=order) elif filter_type=='average': weights=np.asarray(kwargs.get('weights',[1.,2.,3.,2.,1.])) weights=weights/np.sum(weights) x_filtered=np.convolve(xdeg, weights,'same') y_filtered=np.convolve(ydeg, weights,'same') else: raise ValueError('Unknown Filter Type: %s. Must be one of %s'%(filter_type,str(['sg','butter','gauss','median']))) xdeg[invalid_data_mask]=np.NaN ydeg[invalid_data_mask]=np.NaN x_filtered[invalid_data_mask]=np.NaN y_filtered[invalid_data_mask]=np.NaN return (xdeg,ydeg),(x_filtered,y_filtered)
def createTrialDataStreams(): trial_data_streams=[] # Get the filtered event data. # We will use right eye data only for the testing.. # dataAccessUtil=ExperimentDataAccessUtility('../hdf5_files','remote_data.hdf5', experimentCode=None,sessionCodes=[]) event_type=EventConstants.BINOCULAR_EYE_SAMPLE retrieve_attributes=('time','right_gaze_x','right_gaze_y','right_pupil_measure1','status') trial_event_data=dataAccessUtil.getEventAttributeValues(event_type, retrieve_attributes, conditionVariablesFilter=None, startConditions={'time':('>=','@TRIAL_START@')}, endConditions={'time':('<=','@TRIAL_END@')}, ) dataAccessUtil.close() for t,trial_data in enumerate(trial_event_data): #Create a mask to be used to define periods of missing data in a data trace (eye tracker dependent) # invalid_data_mask=trial_data.status%10>=2 time=trial_data.time pupil=trial_data.right_pupil_measure1 # Get x, y eye position traces (in pixels), setting sample positions where there is track loss # to NaN. xpix_cleared=trial_data.right_gaze_x.copy() ypix_cleared=trial_data.right_gaze_y.copy() processSampleEventGaps(xpix_cleared,ypix_cleared,pupil,invalid_data_mask,'clear') # Get x, y eye position traces (in pixels), setting sample positions # where there is track loss to be linearly interpolated using each # missing_sample_start-1 and missing_sample_end+1 as the points to # interpolate between. # xpix_linear=trial_data.right_gaze_x.copy() ypix_linear=trial_data.right_gaze_y.copy() # valid_data_periods is a list of array slice objects giving the start,end index of each non missing # period of in the data stream. # valid_data_periods=processSampleEventGaps(xpix_linear,ypix_linear,pupil,invalid_data_mask,'linear') # Convert from pixels to visual angle coordinates calibration_area_info=dict(display_size_mm=(340,280.0), display_res_pix=(1280.0,1024.0), eye_distance_mm=590.0) vac=VisualAngleCalc(**calibration_area_info) xdeg,ydeg=vac.pix2deg(xpix_linear,ypix_linear) # Create Filtered versions of the x and y degree data traces # We'll use the Median Filter... # xdeg_filtered = scipy.signal.medfilt(xdeg,SPATIAL_FILTER_WINDOW_SIZE) ydeg_filtered = scipy.signal.medfilt(ydeg,SPATIAL_FILTER_WINDOW_SIZE) # Create the velocity stream # xvel=calculateVelocity(time,xdeg_filtered) yvel=calculateVelocity(time,ydeg_filtered) # Filter the velocity data # FILTER_ORDER=2 Wn=0.3 b, a = scipy.signal.butter(FILTER_ORDER, Wn, 'low') ffunc=scipy.signal.filtfilt xvel_filtered = ffunc(b, a, xvel) yvel_filtered = ffunc(b, a, yvel) # xvel_filtered=savitzky_golay(xvel,window_size=VELOCITY_FILTER_WINDOW_SIZE,order=2) # yvel_filtered=savitzky_golay(yvel,window_size=VELOCITY_FILTER_WINDOW_SIZE,order=2) # xvel_filtered=gaussian_filter1d(xvel,VELOCITY_FILTER_WINDOW_SIZE) # yvel_filtered=gaussian_filter1d(yvel,VELOCITY_FILTER_WINDOW_SIZE) # xvel_filtered=scipy.signal.medfilt(xvel,VELOCITY_FILTER_WINDOW_SIZE) # yvel_filtered=scipy.signal.medfilt(yvel,VELOCITY_FILTER_WINDOW_SIZE) velocity=np.sqrt(xvel*xvel+yvel*yvel) velocity_filtered=np.sqrt(xvel_filtered*xvel_filtered+yvel_filtered*yvel_filtered) # Create a data trace dictionary for all the different types # of data traces created for the trial # trial_data={} trial_data['time']=time trial_data['xpix_cleared']=xpix_cleared trial_data['ypix_cleared']=ypix_cleared trial_data['xpix_linear']=xpix_linear trial_data['xpix_linear']=xpix_linear trial_data['xdeg']=xdeg trial_data['ydeg']=ydeg trial_data['xdeg_filtered']=xdeg_filtered trial_data['ydeg_filtered']=ydeg_filtered trial_data['pupil']=pupil trial_data['velocity']=velocity trial_data['velocity_filtered']=velocity_filtered trial_data['valid_data_periods']=valid_data_periods trial_data['missing_data_mask']=invalid_data_mask # Add the data trace dictionary to a list # trial_data_streams.append(trial_data) return trial_data_streams
else: pix_x=trial_data.left_gaze_x pix_y=trial_data.left_gaze_y pupil=trial_data.left_pupil_measure1 invalid_data_mask=trial_data.status//10>=2 # No need to keep the hdf5 file open anymore... # dataAccessUtil.close() ##### STEP B. ##### # Use the VisualAngleCalc class defined in the common_workshop_functions to # generate an object that can convert data from pixels to visual angles based # on the supplied calibration / display surface geometry and eye distance. # vac=VisualAngleCalc(**calibration_area_info) # Calculate the visual degree position in x and y for the given pixel position arrays. # degree_x,degree_y=vac.pix2deg(pix_x,pix_y) # Process the eye fields using the processSampleEventGaps function defined # in the common_workshop_functions.py file. The last argument of 'clear' # tells the function to set any x or y position missing data samples to NaN # and to set the pupil size field to 0. The operations are preformed in-place # on the numpy arrays passed to the function. # The returned valid_data_periods is a list of each group of temporally adjacent # samples that are valid, each element of the list is the (start, stop) # index for a given period of valid data. # valid_data_periods=processSampleEventGaps(pix_x,pix_y,pupil,invalid_data_mask, 'clear')
def createTrialDataStreams(): trial_data_streams = [] # Get the filtered event data. # We will use right eye data only for the testing.. # dataAccessUtil = ExperimentDataAccessUtility( "../hdf5_files", "remote_data.hdf5", experimentCode=None, sessionCodes=[] ) event_type = EventConstants.BINOCULAR_EYE_SAMPLE retrieve_attributes = ("time", "right_gaze_x", "right_gaze_y", "right_pupil_measure1", "status") trial_event_data = dataAccessUtil.getEventAttributeValues( event_type, retrieve_attributes, conditionVariablesFilter=None, startConditions={"time": (">=", "@TRIAL_START@")}, endConditions={"time": ("<=", "@TRIAL_END@")}, ) dataAccessUtil.close() for t, trial_data in enumerate(trial_event_data): # Create a mask to be used to define periods of missing data in a data trace (eye tracker dependent) # invalid_data_mask = trial_data.status % 10 >= 2 time = trial_data.time pupil = trial_data.right_pupil_measure1 # Get x, y eye position traces (in pixels), setting sample positions where there is track loss # to NaN. xpix_cleared = trial_data.right_gaze_x.copy() ypix_cleared = trial_data.right_gaze_y.copy() processSampleEventGaps(xpix_cleared, ypix_cleared, pupil, invalid_data_mask, "clear") # Get x, y eye position traces (in pixels), setting sample positions # where there is track loss to be linearly interpolated using each # missing_sample_start-1 and missing_sample_end+1 as the points to # interpolate between. # xpix_linear = trial_data.right_gaze_x.copy() ypix_linear = trial_data.right_gaze_y.copy() # valid_data_periods is a list of array slice objects giving the start,end index of each non missing # period of in the data stream. # valid_data_periods = processSampleEventGaps(xpix_linear, ypix_linear, pupil, invalid_data_mask, "linear") # Convert from pixels to visual angle coordinates calibration_area_info = dict( display_size_mm=(340, 280.0), display_res_pix=(1280.0, 1024.0), eye_distance_mm=590.0 ) vac = VisualAngleCalc(**calibration_area_info) xdeg, ydeg = vac.pix2deg(xpix_linear, ypix_linear) # Create Filtered versions of the x and y degree data traces # We'll use the Median Filter... # xdeg_filtered = scipy.signal.medfilt(xdeg, SPATIAL_FILTER_WINDOW_SIZE) ydeg_filtered = scipy.signal.medfilt(ydeg, SPATIAL_FILTER_WINDOW_SIZE) # Create the velocity stream # xvel = calculateVelocity(time, xdeg_filtered) yvel = calculateVelocity(time, ydeg_filtered) # Filter the velocity data # FILTER_ORDER = 2 Wn = 0.3 b, a = scipy.signal.butter(FILTER_ORDER, Wn, "low") ffunc = scipy.signal.filtfilt xvel_filtered = ffunc(b, a, xvel) yvel_filtered = ffunc(b, a, yvel) # xvel_filtered=savitzky_golay(xvel,window_size=VELOCITY_FILTER_WINDOW_SIZE,order=2) # yvel_filtered=savitzky_golay(yvel,window_size=VELOCITY_FILTER_WINDOW_SIZE,order=2) # xvel_filtered=gaussian_filter1d(xvel,VELOCITY_FILTER_WINDOW_SIZE) # yvel_filtered=gaussian_filter1d(yvel,VELOCITY_FILTER_WINDOW_SIZE) # xvel_filtered=scipy.signal.medfilt(xvel,VELOCITY_FILTER_WINDOW_SIZE) # yvel_filtered=scipy.signal.medfilt(yvel,VELOCITY_FILTER_WINDOW_SIZE) velocity = np.sqrt(xvel * xvel + yvel * yvel) velocity_filtered = np.sqrt(xvel_filtered * xvel_filtered + yvel_filtered * yvel_filtered) # Create a data trace dictionary for all the different types # of data traces created for the trial # trial_data = {} trial_data["time"] = time trial_data["xpix_cleared"] = xpix_cleared trial_data["ypix_cleared"] = ypix_cleared trial_data["xpix_linear"] = xpix_linear trial_data["xpix_linear"] = xpix_linear trial_data["xdeg"] = xdeg trial_data["ydeg"] = ydeg trial_data["xdeg_filtered"] = xdeg_filtered trial_data["ydeg_filtered"] = ydeg_filtered trial_data["pupil"] = pupil trial_data["velocity"] = velocity trial_data["velocity_filtered"] = velocity_filtered trial_data["valid_data_periods"] = valid_data_periods trial_data["missing_data_mask"] = invalid_data_mask # Add the data trace dictionary to a list # trial_data_streams.append(trial_data) return trial_data_streams