Module eyekit.measure

Functions for calculating common reading measures, such as gaze duration or initial landing position.

Functions

def interest_area_report(trials, measures)

Given one or more trials and one or more measures, apply each measure to all interest areas associated with each trial and return a Pandas dataframe with the collated results. The trials argument should be a list of dictionaries, where each dictionary contains minimally a fixations key that maps to a FixationSequence and an interest_areas key that maps to a list of interest areas extracted from a TextBlock. Any other keys in the dictionary (e.g., trial/subject identifiers) will be included as separate columns in the resulting dataframe. The measures argument should be a list of built-in measures from the eyekit.measure module or your own custom measurement functions. For example:

trials = [
    {
        'trial_id': 'trial1',
        'fixations': FixationSequence(...),
        'interest_areas': text_block.words()
    }
]
measures = ['total_fixation_duration', 'gaze_duration']
dataframe = eyekit.measure.interest_area_report(trials, measures)
dataframe.to_csv('path/to/output.csv') # write dateframe to CSV
def number_of_fixations(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the number of fixations on that interest area. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def initial_fixation_duration(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the duration of the initial fixation on that interest area. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def first_of_many_duration(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the duration of the initial fixation on that interest area, but only if there was more than one fixation on the interest area (otherwise return None). This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def total_fixation_duration(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the sum duration of all fixations on that interest area. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def gaze_duration(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the gaze duration on that interest area. Gaze duration is the sum duration of all fixations inside an interest area until the area is exited for the first time. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def go_past_duration(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the go-past time on that interest area. Go-past time is the sum duration of all fixations from when the interest area is first entered until when it is first exited to the right, including any regressions to the left that occur during that time period (and vice versa in the case of right-to-left text). This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def second_pass_duration(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the second pass duration on that interest area. Second pass duration is the sum duration of all fixations inside an interest area during the second pass over that interest area. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def initial_landing_position(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the initial landing position (expressed in character positions) on that interest area. Counting is from 1. If the interest area represents right-to-left text, the first character is the rightmost one. Returns None if no fixation landed on the interest area. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def initial_landing_distance(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the initial landing distance on that interest area. The initial landing distance is the pixel distance between the first fixation to land in an interest area and the left edge of that interest area (or, in the case of right-to-left text, the right edge). Technically, the distance is measured from the text onset without including any padding. Returns None if no fixation landed on the interest area. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def landing_distances(interest_area, fixation_sequence)

Deprecated in 0.5.4. Given an interest area and fixation sequence, return a list of landing distances on that interest area. Each landing distance is the pixel distance between the fixation and the left edge of the interest area(or, in the case of right-to-left text, the right edge). The distance is measured from the text onset without including any padding. Returns an empty list if no fixation landed on the interest area. This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def number_of_regressions_in(interest_area, fixation_sequence)

Given an interest area and fixation sequence, return the number of regressions back to that interest area after the interest area was read for the first time. In other words, find the first fixation to exit the interest area and then count how many times the reader returns to the interest area from the right (or from the left in the case of right-to-left text). This function may also be applied to a collection of interest areas, in which case a dictionary of results is returned.

def duration_mass(text_block, fixation_sequence, *, ngram_width=1, gamma=30)

Given a TextBlock and FixationSequence, distribute the durations of the fixations probabilistically across the TextBlock. Specifically, the duration of fixation f is distributed over all characters C in its line according to the probability that the reader is "seeing" each character (see p_characters_fixation()), and this is summed over all fixations:

\sum_{f \in F} p(C|f) \cdot f_\mathrm{dur}

For a given fixation f, we compute a Gaussian distribution over all characters in the line according to:

p(c|f) \propto \mathrm{exp} \frac{ -\mathrm{ED}(f_\mathrm{pos}, c_\mathrm{pos})^2 }{2\gamma^2}

where γ (gamma) is a free parameter controlling the rate at which probability decays with the Euclidean distance (ED) between the position of fixation f and the position of character c.

Returns a 2D Numpy array, the sum of which is equal to the total duration of all fixations. This can be passed to Image.draw_heatmap() for visualization. Duration mass reveals the parts of the text that received the most attention. Optionally, this can be performed over higher-level ngrams by setting ngram_width > 1.