コード例 #1
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)
コード例 #2
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
コード例 #3
0
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')