title: “AOI, fixation, transition, and time-course workflow” output: rmarkdown::html_vignette vignette: > % % % ————————-

Overview

This vignette shows a practical AOI workflow for Gazepoint GP3 / Gazepoint Analysis exports using gp3tools.

The workflow covers:

  1. creating and validating a master table;
  2. checking AOI geometry and coding;
  3. creating AOI-entry and AOI-window summaries;
  4. fitting AOI-window GLMMs;
  5. extracting fixation, AOI, and transition features;
  6. fitting AOI time-course GAMMs;
  7. running model diagnostics and reporting checks.

The vignette chunks are not evaluated during package checks, so the file can serve as a readable workflow template.

The first section uses built-in example data; the optional import chunk shows how to replace those objects with data from a private Gazepoint export folder.

When adapting the code, replace the placeholder paths, AOI labels, time windows, and column names with those used in your own study.

1. Load example data or import your own exports

For a quick read-through, start with the lightweight synthetic example data included in the package.

These objects make the later workflow easier to follow because they already use the column names expected by the examples.

library(gp3tools)

data("gazepoint_example_master")
data("gazepoint_example_fixations")
data("gazepoint_example_aoi_geometry")
data("gazepoint_example_aoi_windows")

master <- gazepoint_example_master
all_fix <- gazepoint_example_fixations
aoi_geometry <- gazepoint_example_aoi_geometry
aoi_windows <- gazepoint_example_aoi_windows

For a real study, replace the example objects above by importing a Gazepoint export folder.

This optional chunk creates all_gaze and all_fix, then rebuilds master from the imported gaze rows:

export_dir <- system.file(
  "extdata",
  "gazepoint_realistic_demo_exports",
  package = "gp3tools"
)
output_dir <- "C:/Users/YourName/Desktop/gp3_outputs"

results <- run_gazepoint_workflow(
  export_dir = export_dir,
  output_dir = output_dir,
  prefix = "study1",
  save_plots = TRUE,
  create_report = TRUE
)

all_gaze <- results$all_gaze
all_fix <- results$all_fix
master <- create_gazepoint_master(all_gaze)

2. Validate the master table

master_audit <- audit_gazepoint_master(master)

validation <- validate_gazepoint_master(master)

master_audit$overview
validation$summary
validation$checks

Use the validation output before continuing to AOI coding, AOI-window summaries, and model fitting. If you imported real Gazepoint exports, this is the point where you should confirm that the expected participant, trial, time, gaze, fixation, and AOI-related columns were created correctly.

3. AOI geometry and coding checks

The example data already includes an aoi_geometry object.

For a real study, create or import a geometry table with one row per AOI and stimulus.

A minimal geometry template looks like this:

aoi_geometry_template <- tibble::tibble(
  media_id = c("stim1", "stim1"),
  aoi = c("logo", "product"),
  x_min = c(0.10, 0.50),
  y_min = c(0.10, 0.50),
  x_max = c(0.30, 0.70),
  y_max = c(0.30, 0.70)
)

aoi_geometry_template

Audit AOI geometry:

aoi_geometry_audit <- audit_gazepoint_aoi_geometry(
  aoi_geometry,
  aoi_col = "aoi",
  stimulus_col = "media_id",
  x_min_col = "x_min",
  y_min_col = "y_min",
  x_max_col = "x_max",
  y_max_col = "y_max",
  screen_x_range = c(0, 1),
  screen_y_range = c(0, 1)
)

aoi_geometry_audit$overview
aoi_geometry_audit$flagged_aois

Audit AOI overlap:

aoi_overlap_audit <- audit_gazepoint_aoi_overlap(
  aoi_geometry,
  aoi_col = "aoi",
  stimulus_col = "media_id",
  x_min_col = "x_min",
  y_min_col = "y_min",
  x_max_col = "x_max",
  y_max_col = "y_max",
  min_overlap_area = 0,
  min_overlap_prop = 0
)

aoi_overlap_audit$overview
aoi_overlap_audit$flagged_overlaps

Validate observed AOI labels against geometry-derived labels:

aoi_coding_audit <- audit_gazepoint_aoi_coding_matrix(
  gaze_data = master,
  aoi_geometry = aoi_geometry,
  observed_aoi_col = "aoi_current",
  gaze_x_col = "x",
  gaze_y_col = "y",
  gaze_stimulus_col = "MEDIA_ID",
  sample_id_cols = c("subject", "MEDIA_ID", "trial_global"),
  geometry_aoi_col = "aoi",
  geometry_stimulus_col = "media_id",
  x_min_col = "x_min",
  y_min_col = "y_min",
  x_max_col = "x_max",
  y_max_col = "y_max"
)

aoi_coding_audit$overview
aoi_coding_audit$coding_matrix

Create a visual AOI verification plot:

aoi_verification_plot <- plot_gazepoint_aoi_verification(
  aoi_geometry = aoi_geometry,
  gaze_data = master,
  geometry_aoi_col = "aoi",
  geometry_stimulus_col = "media_id",
  x_min_col = "x_min",
  y_min_col = "y_min",
  x_max_col = "x_max",
  y_max_col = "y_max",
  gaze_x_col = "x",
  gaze_y_col = "y",
  gaze_stimulus_col = "MEDIA_ID"
)

aoi_verification_plot

4. AOI entries and AOI-window summaries

The examples assume that each gaze sample has already been assigned to an AOI-state column called aoi_current. For your own data, check that the AOI labels used in target_aoi_values and distractor_aoi_values match your coding scheme.

Create ordered AOI-entry episodes:

aoi_entries <- summarise_gazepoint_aoi_entries(
  master,
  time_col = "time",
  aoi_col = "aoi_current",
  group_cols = c("subject", "MEDIA_ID", "trial_global")
)

dplyr::glimpse(aoi_entries)

Create AOI-window summaries:

aoi_windows <- summarise_gazepoint_aoi_windows(
  master,
  windows = c(0, 500, 1000, 2000, 5000, 10000),
  time_col = "time",
  aoi_col = "aoi_current",
  subject_col = "subject",
  condition_col = "condition",
  group_cols = c("subject", "MEDIA_ID", "trial_global"),
  target_aoi_values = "AOI 2",
  distractor_aoi_values = c("AOI 0", "AOI 1")
)

dplyr::glimpse(aoi_windows)

Inspect target-looking proportions:

dplyr::select(
  aoi_windows,
  subject,
  condition,
  MEDIA_ID,
  trial_global,
  window_label,
  n_window_samples,
  n_target_samples,
  n_distractor_samples,
  n_valid_denominator_samples,
  target_sample_prop_valid,
  aoi_window_status
)

5. AOI-window GLMM

Use the AOI-window GLMM for predefined confirmatory windows. Before fitting the model, check the AOI-window denominators so that sparse or imbalanced windows are visible.

Audit denominator adequacy:

aoi_window_denominator_audit <- audit_gazepoint_aoi_window_denominators(
  aoi_windows,
  min_denominator_samples = 5,
  min_valid_denominator_prop = 0.70,
  max_denominator_cv = 0.25,
  max_condition_ratio = 2
)

aoi_window_denominator_audit$overview
aoi_window_denominator_audit$window_summary
aoi_window_denominator_audit$condition_window_summary

Prepare binomial success/failure data:

aoi_glmm_data <- prepare_gazepoint_aoi_glmm_data(
  aoi_windows,
  success_col = "n_target_samples",
  denominator = "valid",
  subject_col = "subject",
  condition_col = "condition",
  window_col = "window_label",
  window_start_col = "window_start_ms",
  window_end_col = "window_end_ms",
  min_denominator_samples = 5,
  outcome_label = "target"
)

dplyr::count(
  aoi_glmm_data,
  aoi_glmm_condition,
  aoi_glmm_window,
  aoi_glmm_status
)

Fit the main AOI-window GLMM:

aoi_glmm_fit <- fit_gazepoint_aoi_window_glmm(
  aoi_glmm_data,
  random_window_slopes = FALSE
)

aoi_glmm_fit$model_status
aoi_glmm_fit$formula
aoi_glmm_fit$comparison
aoi_glmm_fit$fixed_effects

Transform AOI proportions into empirical logits for sensitivity models:

aoi_emp_logit <- transform_gazepoint_aoi_empirical_logit(
  aoi_glmm_data,
  numerator_col = "aoi_glmm_success",
  denominator_col = "aoi_glmm_denominator",
  correction = 0.5
)

attr(aoi_emp_logit, "gp3_empirical_logit_overview")

Run model-family sensitivity checks:

aoi_sensitivity <- fit_gazepoint_aoi_model_sensitivity(
  aoi_glmm_data,
  model_types = c(
    "binomial_glmm",
    "empirical_logit_lmm",
    "proportion_lmm",
    "quasibinomial_glm"
  ),
  include_condition = TRUE,
  include_window = TRUE,
  include_interaction = TRUE,
  random_intercept = TRUE
)

aoi_sensitivity$comparison
aoi_sensitivity$fixed_effects

6. AOI, fixation, and transition features

The next helpers create descriptive trial-level and sequence-level features. You do not need every feature for every study; select the summaries that match your research question.

Create transition-ready AOI sequences:

aoi_sequences <- prepare_gazepoint_aoi_sequences(
  master,
  time_col = "time",
  aoi_col = "aoi_current",
  group_cols = c("subject", "MEDIA_ID", "trial_global")
)

dplyr::glimpse(aoi_sequences)

Summarise AOI transitions:

aoi_transition_summary <- summarise_gazepoint_aoi_transitions(
  master,
  time_col = "time",
  aoi_col = "aoi_current",
  group_cols = c("subject", "MEDIA_ID", "trial_global"),
  target_aoi_values = "AOI 2",
  distractor_aoi_values = c("AOI 0", "AOI 1")
)

aoi_transition_summary

Create transition matrices:

aoi_transition_matrix <- compute_gazepoint_aoi_transition_matrix(
  master,
  time_col = "time",
  aoi_col = "aoi_current",
  group_cols = c("subject", "MEDIA_ID", "trial_global"),
  target_aoi_values = "AOI 2",
  distractor_aoi_values = c("AOI 0", "AOI 1")
)

aoi_transition_matrix$count_matrix
aoi_transition_matrix$probability_matrix
aoi_transition_matrix$long_table

Create time-varying transition matrices:

time_varying_transition_matrix <- compute_gazepoint_time_varying_transition_matrix(
  master,
  time_col = "time",
  state_col = "aoi_current",
  group_cols = c("subject", "MEDIA_ID", "trial_global"),
  windows = c(0, 500, 1000, 2000, 5000)
)

time_varying_transition_matrix$overview
time_varying_transition_matrix$transition_summary

Create trial-level AOI features:

aoi_trial_features <- summarise_gazepoint_aoi_trial_features(
  master,
  time_col = "time",
  aoi_col = "aoi_current",
  group_cols = c("subject", "MEDIA_ID", "trial_global"),
  target_aoi_values = "AOI 2",
  distractor_aoi_values = c("AOI 0", "AOI 1")
)

aoi_trial_features

Create trial-level fixation features from Gazepoint fixation exports:

fixation_trial_features <- summarise_gazepoint_fixation_trials(
  all_fix,
  target_aoi_values = "AOI 2",
  distractor_aoi_values = c("AOI 0", "AOI 1")
)

fixation_trial_features

Create fixation-, saccade-, or AOI-contingent aligned data:

fixation_aligned <- prepare_gazepoint_fixation_aligned_data(
  master,
  time_col = "time",
  participant_col = "subject",
  trial_col = "trial_global",
  aoi_col = "aoi_current",
  target_aoi = "AOI 2",
  fixation_col = "is_fixation",
  alignment_event = "first_fixation_to_target",
  baseline_window = c(-200, 0),
  analysis_window = c(0, 800)
)

fixation_aligned$overview
fixation_aligned$event_table
fixation_aligned$trial_summary

7. Advanced sequence-model preparation

These preparation helpers are optional. Use them when you plan Markov-chain, semi-Markov, or HMM-style sequence analyses; otherwise, this section can be skipped.

Prepare dependency-free sequence-model objects:

markov_obj <- create_gazepoint_markovchain_object(
  aoi_sequences,
  state_col = "aoi"
)

semimarkov_data <- prepare_gazepoint_semimarkov_data(
  aoi_sequences,
  state_col = "aoi",
  time_col = "time"
)

hmm_data <- prepare_gazepoint_hmm_data(
  aoi_sequences,
  state_col = "aoi",
  observation_cols = c("x", "y", "pupil")
)

markov_obj$overview
semimarkov_data$overview
hmm_data$overview

These helpers prepare sequence and transition data for inspection, reporting, export, or specialist modelling packages. They do not directly fit Markov-chain, semi-Markov, or hidden Markov models.

8. AOI time-course GAMM

Prepare AOI-GAMM data from an AOI-state column:

aoi_gamm_data <- prepare_gazepoint_aoi_gamm_data(
  master,
  aoi_col = "aoi_current",
  target_aoi_values = "AOI 2",
  subject_col = "subject",
  condition_col = "condition",
  time_col = "time",
  trial_col = "trial_global",
  time_window = c(0, 2000),
  bin_size_ms = 50,
  denominator = "valid",
  min_denominator_samples = 1,
  outcome_label = "target_aoi"
)

dplyr::count(
  aoi_gamm_data,
  .gp3_aoi_gamm_condition,
  .gp3_aoi_gamm_condition_status,
  .gp3_aoi_gamm_status
)

Fit the AOI time-course GAMM:

aoi_gamm_fit <- fit_gazepoint_aoi_gamm(
  aoi_gamm_data,
  include_condition = TRUE,
  condition_smooths = TRUE,
  random_subject = TRUE,
  random_subject_time = FALSE,
  time_k = 10
)

aoi_gamm_fit$model_status
aoi_gamm_fit$condition_status
aoi_gamm_fit$formula_text
aoi_gamm_fit$diagnostics
aoi_gamm_fit$smooth_table

Plot observed and fitted AOI trajectories:

aoi_gamm_plot <- plot_gazepoint_aoi_gamm(
  aoi_gamm_fit,
  n_time_points = 100,
  include_observed = TRUE,
  include_fitted = TRUE,
  show_ci = TRUE
)

aoi_gamm_plot

AOI time-course GAMMs are complementary to AOI-window GLMMs. Use AOI-window GLMMs for predefined confirmatory windows and AOI-GAMMs when the research question concerns smooth target-looking trajectories.

9. Diagnostics and reporting

Finish by checking the fitted model and collecting reporting-ready summaries. These outputs are intended to support manuscript reporting rather than replace statistical interpretation.

Run model diagnostics:

aoi_diagnostics <- diagnose_gazepoint_glmm(
  aoi_glmm_fit,
  model_name = "aoi_window_glmm",
  use_dharma = FALSE
)

aoi_diagnostics$overview
aoi_diagnostics$convergence
aoi_diagnostics$singularity
aoi_diagnostics$overdispersion

Create model-summary tables:

aoi_model_summary <- tidy_gazepoint_model_summary(
  aoi_glmm_fit,
  model_name = "aoi_window_glmm",
  exponentiate = TRUE,
  use_dharma = FALSE
)

aoi_model_summary$overview
aoi_model_summary$fixed_effects

Estimate marginal means when emmeans is installed:

aoi_emmeans <- summarise_gazepoint_emmeans(
  aoi_glmm_fit,
  specs = "aoi_glmm_condition",
  by = "aoi_glmm_window",
  model_name = "aoi_window_glmm",
  type = "response"
)

aoi_emmeans$overview
aoi_emmeans$emmeans
aoi_emmeans$contrasts

Export manuscript-ready tables:

model_table_files <- export_gazepoint_model_tables(
  model_summary = aoi_model_summary,
  emmeans_summary = aoi_emmeans,
  output_dir = output_dir,
  prefix = "aoi_window_glmm"
)

model_table_files

Create a reporting checklist:

reporting <- create_gazepoint_reporting_checklist(
  data = master,
  objects = list(
    validation = validation,
    aoi_geometry_audit = aoi_geometry_audit,
    aoi_denominator_audit = aoi_window_denominator_audit,
    aoi_model = aoi_glmm_fit,
    diagnostics = aoi_diagnostics
  ),
  analysis_type = "aoi",
  study_title = "Gazepoint AOI study"
)

reporting$overview
reporting$checklist