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)
Example #2
0
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
Example #4
0
    # Get the needed left eye sample arrays
    #
    left_gaze_x = trial_samples.left_gaze_x
    left_gaze_y = trial_samples.left_gaze_y
    left_pupil_size = trial_samples.left_pupil_measure1
    # Process the left 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, but providing a list where each element is the (start, stop)
    # index for a given period of valid data.
    #
    left_valid_data_periods = processSampleEventGaps(
        left_gaze_x, left_gaze_y, left_pupil_size, left_eye_invalid_data_masks,
        'clear')

    # Get the needed right eye sample field arrays
    #
    right_gaze_x = trial_samples.right_gaze_x
    right_gaze_y = trial_samples.right_gaze_y
    right_pupil_size = trial_samples.right_pupil_measure1

    # Process the right eye fields
    #
    right_valid_data_periods = processSampleEventGaps(
        right_gaze_x, right_gaze_y, right_pupil_size,
        right_eye_invalid_data_masks, 'clear')

    # get the array of sample times for the current trial
Example #5
0
#                            
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')
#### STEP C. ####
# Create a plot of eye position in pixels and visual degrees
#                                          
fig = plt.figure(figsize=(12,8))
fig.suptitle("Eye Sample Data For Trial Index %d"%(TRIAL_INDEX+1),fontsize=14)

# Get the range to use for the x axis
# 
tmin=time.min()//1
tmax=time.max()//1+1

# Create the y axis (time)
ax=plt.gca()
px=ax.plot(time, pix_x,label='X Position (Pixels)',color=(.5,.5,1))
py=ax.plot(time, pix_y,label='Y Position (Pixels)',color=(1,.5,.5))
#
dataAccessUtil.close()

# 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. 
#
valid_data_periods=processSampleEventGaps(degree_x,degree_y,pupil,invalid_data_mask,
                                          'clear')

# calculate unfiltered velocity and accelleration streams
#
velocity=np.abs(calculateVelocity(time,degree_x,degree_y))
accelleration=calculateAccelleration(time,degree_x,degree_y)

pix_x[invalid_data_mask]=np.NaN
pix_y[invalid_data_mask]=np.NaN
degree_x[invalid_data_mask]=np.NaN
degree_y[invalid_data_mask]=np.NaN

# Get the range to use for the x axis
# 
tmin=time.min()//1
tmax=time.max()//1+1
Example #7
0
    # Get the needed left eye sample arrays
    #
    gaze_x = trial_data.gaze_x
    gaze_y = trial_data.gaze_y
    pupil_size = trial_data.pupil_measure1

    # Process the eye fields using the processSampleEventGaps function defined
    # in the common_workshop_functions.py file. The last arguement 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, but providing a list where each element is the (start, stop)
    # index for a given period of valid data.
    #
    valid_data_periods = processSampleEventGaps(gaze_x, gaze_y, pupil_size,
                                                invalid_data_mask, 'clear')

    # get the array of sample times for the current trial
    #
    time = trial_data.time

    # Start plotting for the trial
    plt.figure(figsize=(12, 8))

    ##### STEP C. #####
    # Create Image background for each trial scanpath
    # Get the condition variable set used for the current trial
    #
    condition_set = trial_data.condition_set
    # Get the image name and trial_id from the condition data for
    # the trial.
Example #8
0
    # Get the needed left eye sample arrays
    #
    left_gaze_x=trial_samples.left_gaze_x
    left_gaze_y=trial_samples.left_gaze_y
    left_pupil_size=trial_samples.left_pupil_measure1
    # Process the left 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, but providing a list where each element is the (start, stop)
    # index for a given period of valid data.
    #
    left_valid_data_periods=processSampleEventGaps(left_gaze_x,left_gaze_y,
        left_pupil_size,
        left_eye_invalid_data_masks,
        'clear')

    # Get the needed right eye sample field arrays
    #
    right_gaze_x=trial_samples.right_gaze_x
    right_gaze_y=trial_samples.right_gaze_y
    right_pupil_size=trial_samples.right_pupil_measure1

    # Process the right eye fields
    #
    right_valid_data_periods=processSampleEventGaps(right_gaze_x,right_gaze_y,
        right_pupil_size,
        right_eye_invalid_data_masks,
        'clear')
Example #9
0
#
dataAccessUtil.close()

# 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.
#
valid_data_periods = processSampleEventGaps(degree_x, degree_y, pupil,
                                            invalid_data_mask, 'clear')

# calculate unfiltered velocity and accelleration streams
#
velocity = np.abs(calculateVelocity(time, degree_x, degree_y))
accelleration = calculateAccelleration(time, degree_x, degree_y)

pix_x[invalid_data_mask] = np.NaN
pix_y[invalid_data_mask] = np.NaN
degree_x[invalid_data_mask] = np.NaN
degree_y[invalid_data_mask] = np.NaN

# Get the range to use for the x axis
#
tmin = time.min() // 1
tmax = time.max() // 1 + 1
Example #10
0
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
Example #11
0
    #
    gaze_x=trial_data.gaze_x
    gaze_y=trial_data.gaze_y
    pupil_size=trial_data.pupil_measure1
    
    # Process the eye fields using the processSampleEventGaps function defined
    # in the common_workshop_functions.py file. The last arguement 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, but providing a list where each element is the (start, stop)
    # index for a given period of valid data.
    #
    valid_data_periods=processSampleEventGaps(gaze_x,gaze_y,
                                                   pupil_size,
                                                   invalid_data_mask,
                                                   'clear')
                                                   
    # get the array of sample times for the current trial
    #
    time=trial_data.time

    # Start plotting for the trial
    plt.figure(figsize=(12,8))

    ##### STEP C. #####
    # Create Image background for each trial scanpath
    # Get the condition variable set used for the current trial
    #
    condition_set=trial_data.condition_set    
    # Get the image name and trial_id from the condition data for