Measures

Trial Measures

Trial-based eye-tracking measures. These measures are calculated for each trial of an experiment.

sideeye.measures.trial.average_backward_saccade(trial: sideeye.data.trial.Trial)

Average saccade duration between fixations moving backward through the sentence, or the average duration of a regression saccade.

backward_saccades = 0
total_time = 0

for saccade in trial:
    if saccade is regression:
        backward_saccades += 1
        total_time += saccade.duration

if backward_saccades is 0:
    return 0
else:
    return total_time / backward_saccades
sideeye.measures.trial.average_forward_saccade(trial: sideeye.data.trial.Trial)

Average saccade duration between fixations moving forward through the sentence.

forward_saccades = 0
total_time = 0

for saccade in trial:
    if saccade is not regression:
        forward_saccades += 1
        total_time += saccade.duration

if forward_saccades is 0:
    return 0
else:
    return total_time / forward_saccades
sideeye.measures.trial.fixation_count(trial: sideeye.data.trial.Trial)

Total number of non-excluded fixations in a trial.

return length of [non-excluded fixations in trial]
sideeye.measures.trial.latency_first_regression(trial: sideeye.data.trial.Trial)

Time until the end of the fixation before the first regression saccade in the trial, where a regression is defined as a saccade where the position of the fixation at the beginning of the saccade is later in the item than the position of the fixation at the end of the saccade. None if there are no regressions.

for saccade in trial:
    if saccade is regression:
        return saccade.start_fixation.end_time
    else:
        return None
sideeye.measures.trial.location_first_regression(trial: sideeye.data.trial.Trial)

(x, y) character position of the last fixation before the first regression saccade in the trial, where a regression is defined as a saccade where the position of the fixation at the beginning of the saccade is later in the item than the position of the fixation at the end of the saccade. None if there are no regressions.

for saccade in trial:
    if saccade is regression:
        return (saccade.start_fixation.char, saccade.start_fixation.line)
    else:
        return None
sideeye.measures.trial.percent_regressions(trial: sideeye.data.trial.Trial)

Proportion of saccades that are regressions from the location of the previous fixation, where a regression is defined as a saccade where the position of the fixation at the beginning of the saccade is later in the item than the position of the fixation at the end of the saccade. None if there are no saccades.

regressions = 0

for saccade in trial:
    if saccade is regression:
        regressions += 1

return regressions / (length of [trial.saccades])
sideeye.measures.trial.trial_total_time(trial: sideeye.data.trial.Trial)

Total time in the trial.

return total trial time from .DA1 file OR end time of last non-excluded fixation

Region Measures

Region-based eye-tracking measures. These measures are calculated for each region of each trial in an experiment.

Many of these measures use a list of first pass fixations in the region in calculating the measure. First pass fixations are defined as:

def get_first_pass_fixations(trial, region_number):
    first_pass_fixations = []

    for fixation in trial:
        if fixation.region_number > region_number:
            break
        if length of first_pass_fixations > 0 and fixation.region_number is not region_number:
            break
        if fixation.region_number is region_number and fixation is not excluded:
            first_pass_fixations += [fixation]

    return first_pass_fixations
sideeye.measures.region.skip(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

True if the reader fixates a region beyond the target region before fixating the target region or the target region is never fixated, False otherwise.

if length of get_first_pass_fixations(trial, region_number) is 0:
    return True
else return False
sideeye.measures.region.first_pass_regressions_in(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

This measure is True if the reader made a fixation in the region after fixating on any region to the right of it, False if they only fixated on the region after fixating on regions to the left, and None if the region was never fixated.

region_fixations = [all non-excluded fixations in region]

if length of region_fixations is 0:
    return None

for fixation in region_fixations:
    if previous_fixation.region_number > region_number:
        return True

return False
sideeye.measures.region.first_pass_regressions_out(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

This measure is True if the reader made a regression out of the region on the first pass - that is, exited a region to the left after the first pass. The measure is False if they exited to the right, and None if the region was not fixated during first pass reading.

fp_fixations = get_first_pass_fixations(trial, region_number)

if length of fp_fixations is 0:
    return None

next_fixation = next non-excluded fixation after last fixation in fp_fixations

if next_fixation.region_number < region_number:
    return True
else:
    return False
sideeye.measures.region.landing_position(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The location relative to the beginning of the region (in number of characters) of the first fixation during the first pass, where the first character in the region is at position (0, 0). If the region was skipped, this measure is None.

fp_fixations = get_first_pass_fixations(trial, region_number)

if (length of fp_fixations is not 0
        and fp_fixations[0].char is not None
        and fp_fixations[0].line is not None):
    return (fp_fixations[0].char - region.start.char,
            fp_fixations[0].line - region.start.line)

else:
    return None
sideeye.measures.region.launch_site(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The location of the last fixation prior to the first fixation in the region. This measure returns an (x, y) tuple, where x is either the number of characters from the the beginning of the target region and y is the number of lines from the beginning of the region. -1 indicates the last character of the region preceding the target region, or the preceding line, and increasing negative numbers indicate further launch sites. If the region was skipped this measure is None.

fixations = [fixation for fixation in trial if fixation is not excluded]

for (index, fixation) in enumerate(fixations):
    if fixation.region_number > region_number:
        break
    if fixation.region_number == region_number:
        if index == 0:
            break

        if fixations[index - 1].char is None:
            launch_char = fixations[index - 1].char
        else:
            launch_char = fixations[index - 1].char - fixation.region.start.char

        if fixations[index - 1].line is None:
            launch_line = fixations[index - 1].line
        else:
            launch_line = fixations[index - 1].line - fixation.region.start.line

        return (launch_char, launch_line)

return None
sideeye.measures.region.first_pass_fixation_count(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The number of fixations made in a region before leaving it during first pass. If the region was skipped this measure is None.

fp_fixations = get_first_pass_fixations(trial, region_number)

if length of fp_fixations is 0:
    return None
else:
    return length of fp_fixations
sideeye.measures.region.first_fixation_duration(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The duration of the first fixation in a region during first pass reading (i.e., before the reader fixates areas beyond the region). If this region is skipped during first pass, this measure is None.

fp_fixations = get_first_pass_fixations(trial, region_number)

if length of fp_fixations is 0:
    return None
else:
    return duration of first fixation in fp_fixations
sideeye.measures.region.single_fixation_duration(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

If there is only one fixation on the region during first pass reading, this measure is the duration of that fixation. If the region is skipped during first pass, the measure is None.

fp_fixations = get_first_pass_fixations(trial, region_number)

if length of fp_fixations is 1:
    return duration of fixation in fp_fixations
else:
    return None
sideeye.measures.region.first_pass(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The summed duration of all fixations in a region during first pass (i.e., before the reader fixates areas beyond the region). If this region is skipped during first pass, this measure is None.

fp_fixations = get_first_pass_fixations(trial, region_number)

if length of fp_fixations is 0:
    return None

total = 0

for fixation in fp_fixations:
    total += fixation.duration()

return total
sideeye.measures.region.go_past(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

Also known as regression path duration. The summed duration of all fixations starting from the first fixation in the region, including any fixations in prior regions until the reader goes past the region (i.e., before the reader fixates areas beyond the region). If this region is skipped during first pass, this measure is None.

if length of get_first_pass_fixations(trial, region_number) is 0:
    return None

total = 0

for fixation in trial:
    if fixation is not excluded:
        if fixation.region_number > region_number:
            break
        if total is not 0 or fixation.region_number is region_number:
            total += fixation.duration()

return total
sideeye.measures.region.total_time(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The summed duration of all fixations in the region that occur at any time during the trial. If this region is never fixated this measure is 0.

total = 0

for fixation in trial:
    if fixation.region_number is region_number and fixation is not excluded:
        total += fixation.duration()

return total
sideeye.measures.region.right_bounded_time(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The summed duration of all fixations starting from the first fixation in the region, excluding any fixations in prior regions until the reader goes past the region (i.e., until the reader fixates areas beyond the region). If this region is skipped during first pass, this measure is None.

if length of get_first_pass_fixations(trial, region_number) is 0:
    return None

total = 0

for fixation in trial:
    if fixation is not excluded:
        if fixation.region_number > region_number:
            break
        if fixation.region_number is region_number:
            total += fixation.duration()

return total
sideeye.measures.region.reread_time(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The summed duration of all fixations in the region that occur after a region to the right has been fixated. If this region is never fixated this measure is 0.

total = 0
reread = False

for fixation in trial:
    if fixation is not excluded:
        if fixation.region_number > region_number:
            reread = True
        if reread and fixation.region_number is region_number:
            total += fixation.duration()

return total
sideeye.measures.region.second_pass(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The summed duration of all fixations in the region that occur on a region after that region has been exited in either direction for the first time. If this region is never fixated this measure is 0.

total = 0
first_pass = False
exited = False

for fixation in trial:
    if fixation is not excluded:
        if fixation.region_number is region_number:
            first_pass = True
        if first_pass and fixation.region_number is not region_number:
            exited = True
        if first_pass and exited and fixation.region_number is region_number:
            total += fixation.duration()

return total
sideeye.measures.region.spillover_time(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The duration of fixations on the region immediately following the region of interest, where the previous fixation was on the region of interest. If there are no such fixations, the measure is None.

total = 0
visited_region = False

for fixation in trial:
    if fixation is not excluded:
        if visited_region and fixation.region_number is not region_number + 1:
            visited_region = False
        if fixation.region_number is region_number:
            visited_region = True
        if visited_region and fixation.region_number is region_number + 1:
            total += fixation.duration()

if total is 0:
    return None

return total
sideeye.measures.region.refixation_time(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

The sum of all first-pass fixations excluding the first fixation. If there was a single fixation in the region or it was skipped this measure is None.

fp_fixations = get_first_pass_fixations(trial, region_number)

if length of fp_fixations is 0 or 1:
    return None

total = 0

for fixation in fp_fixations[1:]:
    total += fixation.duration()

return total
sideeye.measures.region.go_back_time_char(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

Go-back time is the time (in ms) until the first regression is made after encountering a region. For the purposes of go-back time, any fixation which lands to the left of the preceding fixation is considered a regression; the landing site regression does not need to precede the critical region. If a region was fixated, it is measured from the onset of the first fixation in that regreion. If a region was skipped, it is measured from the offset of the preceding fixation. The end point is the end of the fixation that precedes the regression. If no regression is made after the critical region, this measure is ‘None.’

go_back_time_char defines a regression character by character: any fixation which lands on a character to the left of the preceding fixation counts as a regression.

sideeye.measures.region.go_back_time_region(trial: sideeye.data.trial.Trial, region_number: int) → sideeye.types.RegionMeasure

Go-back time is the time (in ms) until the first regression is made after encountering a region. For the purposes of go-back time, any fixation which lands to the left of the preceding fixation is considered a regression; the landing site regression does not need to precede the critical region. If a region was fixated, it is measured from the onset of the first fixation in that regreion. If a region was skipped, it is measured from the offset of the preceding fixation. The end point is the end of the fixation that precedes the regression. If no regression is made after the critical region, this measure is ‘None.’

go_back_time_region defines a regression region by region: any fixation which lands on a region to the left of the preceding fixation counts as a regression.