Skip to main content

Eye Tracking Metrics

In [14]:
%run prelude.ipy
The autoreload extension is already loaded. To reload it, use:
  %reload_ext autoreload

In [23]:
all_fixes = data.hansen_2012.all_fixations()
all_saccs = data.hansen_2012.all_saccades()
aois = data.hansen_2012.areas_of_interest()
In [41]:
rows = []
i = 10
for (exp_id, trial_id), t_fixes in all_fixes.groupby(["exp_id", "trial_id"]):
    num_fixes = len(t_fixes)
    avg_fix_duration = metrics.avg_fixation_duration(t_fixes)
    
    # AOIs
    t_aois = aois[(aois.exp_id == exp_id) & (aois.trial_id == trial_id)]
    t_aois = aoi.combine_aois(t_aois, "line", new_kind="codebbox")
    code_bbox = t_aois[t_aois.kind == "codebbox"]    
    spatial_density = metrics.spatial_density(t_fixes, code_bbox)
    
    convex_hull_area = metrics.convex_hull_area(t_fixes)
    
    # Saccades
    t_saccs = all_saccs[(all_saccs.exp_id == exp_id) &
                        (all_saccs.trial_id == trial_id)]
    fix_sacc_proportion = metrics.fixation_saccade_proportion(t_fixes, t_saccs)
    
    # Scanpaths
    line_sp = aoi.scanpath_from_fixations(t_fixes, "line", repeats=False)
    line_tm = aoi.transition_matrix(line_sp, norm=False)
    line_trans_density = metrics.transition_density(line_tm)
    
    block_sp = aoi.scanpath_from_fixations(t_fixes, "block", repeats=False)
    block_tm = aoi.transition_matrix(block_sp, norm=False)
    block_trans_density = metrics.transition_density(block_tm)
    
    code_out_sp = aoi.scanpath_from_fixations(t_fixes,
            { "interface": ["code box", "output box"] }, repeats=False)
    code_out_tm = aoi.transition_matrix(code_out_sp, norm=False)
    #code_out_trans_density = metrics.transition_density(code_out_tm)
    code_out_transitions = code_out_tm.flatten().sum()
    
    sp_length = metrics.scanpath_length(t_fixes)
    
    rows.append([exp_id, trial_id, num_fixes, avg_fix_duration,
                 spatial_density, convex_hull_area, fix_sacc_proportion,
                 line_trans_density, block_trans_density,
                 code_out_transitions, sp_length])
    i = i - 1
    if i == 0:
        break
    
cols = ["exp_id", "trial_id", "fix_count", "avg_fix_duration",
        "spatial_density", "convex_hull_area", "fix_sacc_proportion",
        "line_trans_density", "block_trans_density",
        "code_out_transitions", "sp_length"]

trial_metrics = pandas.DataFrame(rows, columns=cols)
trial_metrics[:10]
Out[41]:
exp_id trial_id fix_count avg_fix_duration spatial_density convex_hull_area fix_sacc_proportion line_trans_density block_trans_density code_out_transitions sp_length
0 1 1 103 282.436893 0.35 342744.5 8.466531 0.428571 0.500000 8 2302704.279126
1 1 2 57 304.929825 0.29 326982.0 8.429195 0.209877 0.444444 12 685788.335793
2 1 3 50 240.740000 0.26 397507.0 8.116655 0.204082 0.312500 5 548842.186113
3 1 4 258 258.837209 0.65 474234.0 8.924228 0.187500 0.333333 15 13492374.526810
4 1 5 69 249.362319 0.34 287790.0 7.606543 0.527778 0.500000 8 660268.975694
5 1 6 107 266.009346 0.45 383984.5 9.280404 0.350000 0.666667 6 1574548.686646
6 1 7 92 244.086957 0.42 205967.5 6.039806 0.560000 0.000000 21 1680081.009733
7 1 8 227 268.264317 0.56 363327.5 7.895242 0.413223 0.750000 23 8839025.658249
8 1 9 156 263.596154 0.54 371890.5 10.522262 0.243056 0.333333 7 3565190.661654
9 1 10 109 306.330275 0.27 259462.5 7.860169 0.444444 0.500000 31 2682398.849289

In [10]:
base, version = "between", "functions"
fixes = util.filter_program(all_fixations, base, version)
num_lines = len(data.hansen_2012.program_code(base, version))
aoi_names = {
    "line" : ["line {0}".format(i) for i in range(1, num_lines+1)],
    "interface" : ["output box"]
}

scanpaths = []
for trial_id, t_fixes in fixes.groupby("trial_id"):
    t_scanpath, _ = aoi.aoi_scanpath(t_fixes, aoi_names, mixed=True, repeats=False)
    scanpaths.append(t_scanpath.values)
In [12]:
results = util.all_pairs(scanpaths, aoi.scanpath_edit_distance)
In [2]:
pandas.Series(results.flatten()).hist().figure
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-53cbc97ea512> in <module>()
----> 1 pandas.Series(results.flatten()).hist().figure

NameError: name 'results' is not defined
In [30]:
rows = []

for base, version in programs[["base", "version"]].values:
    fixes = util.filter_program(all_fixations, base, version)
    lines_with_code = data.hansen_2012.program_lines_with_code(base, version)
    line_aois = ["line {0}".format(i) for i in lines_with_code]
    
    for trial_id, t_fixes in fixes.groupby("trial_id"):
        trial = trials[trials.trial_id == trial_id].iloc[0]
        duration_30_percent = trial["duration_ms"] / 3.0
        t_fixes = t_fixes[t_fixes.start_ms < duration_30_percent]
        percent_fixated = 0.0
        if len(t_fixes) > 0:
            aoi_names = metrics.first_fixation_ms(t_fixes)
            if "line" in aoi_names.index.get_level_values("kind"):
                lines_fixated = [name for name in aoi_names.loc["line"].index if name in line_aois]
                percent_fixated = len(lines_fixated) / float(len(line_aois))
        rows.append([base, version, trial_id, percent_fixated])
        
df = pandas.DataFrame(rows, columns=["base", "version", "trial_id", "percent_fixated30"])
In [37]:
df.percent_fixated30.mean()
Out[37]:
0.74854106480627747
In [45]:
def base_fun(b_frame, ax):
    ax.set_title("{0} ({1} trials)".format(b_frame.iloc[0]["base"], len(b_frame)))
    ax.set_xlim(0, 1)
    ax.set_xlabel("Percent Lines Fixated")
    
axes = plot.misc.hist_by_base(df, "percent_fixated30", title="Percent Lines Fixated by Program (30%)",
                              base_fun=base_fun, figsize=(20, 10))
axes[0].figure
Out[45]:

Other

In [7]:
per_trial = metrics.fixation_ms_per_trial(all_fixations)
print "Mean", per_trial.mean()
print "STD", per_trial.std()
Mean 280.413137964
STD 48.6831911018