--- title: "AOI, fixation, transition, and time-course workflow" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{AOI, fixation, transition, and time-course workflow} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} ------------------------- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", eval = FALSE ) ``` # 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. ```{r} 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: ```{r} 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 ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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: ```{r} 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 ```