Skip to contents

Replay models a recall path as a sequence generated by local traversal of encoding fixations, occasional chunk restarts, and a candidate-independent background state. The hidden-Markov model observes each recall fixation exactly once: its position and its duration. Transition and emission parameters are fitted using training trials only by [fit_gaze_replay_model()].

Usage

gaze_replay_spec(
  max_skip = 2L,
  student_df = 4,
  scale_floor = 0.05,
  transition_grid = list(background = c(0.02, 0.08), restart = c(0.01, 0.05, 0.12),
    advance = c(0.15, 0.35), background_stay = c(0.85, 0.95)),
  temperature_bounds = c(0.05, 100),
  reliability = c("none", "effective_fixations"),
  reliability_kappa_bounds = c(0, 100),
  warp = gaze_warp_none(),
  screen = NULL,
  revision = "2026.10",
  background_by = NULL,
  background_support = c("training", "held_out"),
  calibration_control = NULL
)

Arguments

max_skip

Maximum forward encoding-state jump in a local transition.

student_df

Degrees of freedom for robust bivariate Student emissions.

scale_floor

Positive lower bound for fitted spatial scales.

transition_grid

Named list of probabilities for background entry, chunk restart, local advance, and background persistence. Their medians are the starting values of the Baum-Welch fit.

temperature_bounds

Positive lower and upper bounds for training-only calibration of candidate likelihoods. Direct one-template fits retain temperature one because no contrastive calibration set exists.

reliability

Response-blind reliability policy. `"none"` preserves the calibrated candidate posterior. `"effective_fixations"` learns a monotone shrinkage toward the declared candidate prior from the source path's duration-effective fixation count.

reliability_kappa_bounds

Non-negative bounds for the reliability half-saturation parameter. The lower bound must be zero.

warp

Cross-fitted warp specification.

screen

Optional screen geometry. Every emission density is truncated to and normalised over this rectangle. When it is `NULL`, emissions are normalised over the whole plane (a one-time message says so).

revision

Model revision, recorded in the specification and in every fit. The only supported revision is `"2026.10"`, a fixation-level HMM with one hidden-state visit per recall fixation. Each fixation emits a position and a duration. Positions follow screen-truncated Student densities for replay states and, for the background state, a participant-level screen-truncated kernel density of training recalls (excluding the candidate pool, see `background_by`) mixed with a uniform screen floor. Durations are log-normal, with log-duration mean `a + b * log(encoding duration)` for replay states and a separate log-normal for the background; these parameters are shared by every candidate. The score is the total trial log likelihood, so evidence grows with the number of recall fixations. The replay scale, duration parameters, background floor weight, and all transition probabilities are fitted by Baum-Welch (EM) on training rows, with `transition_grid` medians used only as starting values. The earlier duration-grid revision `"2026.08"` was retired in eyesim 0.3.0 because of documented defects (unnormalised screen emissions, a single-Student background, an inflated replay scale, and a duration grid under which the no-replay null was not identifiable); requesting it is an error. Install the git tag `gazeweave-2026.08-frozen` to reproduce 2026.08 results.

background_by

Optional source-table columns (for example the participant identifier) defining the level at which the background density is estimated. `NULL` pools all training recalls. Levels with fewer than three other training trials fall back to the pooled density; fitting reports this with a message and [gaze_replay_cv()] records the count in `provenance$background_fallback`. At scoring time the background excludes training rows whose exclusion key matches any candidate in the pool; it is never tied to the true candidate, so it does not depend on the label. The exclusion key is `setdiff(match_on, background_by)`. When `background_by` is not part of `match_on` (or is `NULL`), that key still contains the participant, so other participants' recalls of the candidate items stay in the background.

background_support

Background evaluation protocol. `"training"` (default) estimates every background from training recalls only: the `background_by` level when it has at least three training trials outside the candidate pool, otherwise the population (pooled) density. Under participant holdout every evaluation participant is unseen, so the population density is used and [gaze_replay_cv()] says so. `"held_out"` (opt-in, requires `background_by`) instead uses the evaluation participant's own recalls of items outside the scored row's candidate pool, available in the same evaluation fold, falling back to the training protocol when fewer than three such trials exist. It can engage only with an item-level split and a `contrast_on` that divides each participant's items into blocks, so that other-block recalls share the evaluation fold. Under participant holdout with shared items every item is a candidate, and it never engages. `"held_out"` is transductive: it reads the item labels of other evaluation rows to decide which recalls lie outside the pool, so it cannot be used on unlabelled recalls. Training fits always use the other training trials of the same level, excluding the fitted item.

calibration_control

A [gaze_calibration_control()]. `NULL` uses its defaults: an evidence-scaled temperature whose evidence count is the number of recall fixations, fitted on inner out-of-fold rows. `reliability = "effective_fixations"` then requires `method = "global"`.

Value

A frozen `gaze_replay_spec`.

Experimental

GazeWeave is experimental. Its interface, defaults and result columns may change in future releases; record the package version with any results.

Examples

gaze_replay_spec(screen = gaze_screen(30, 20, unit = "deg"))
#> $max_skip
#> [1] 2
#> 
#> $student_df
#> [1] 4
#> 
#> $scale_floor
#> [1] 0.05
#> 
#> $transition_grid
#> $transition_grid$background
#> [1] 0.02 0.08
#> 
#> $transition_grid$restart
#> [1] 0.01 0.05 0.12
#> 
#> $transition_grid$advance
#> [1] 0.15 0.35
#> 
#> $transition_grid$background_stay
#> [1] 0.85 0.95
#> 
#> 
#> $temperature_bounds
#> [1] 5e-02 1e+02
#> 
#> $reliability
#> [1] "none"
#> 
#> $reliability_kappa_bounds
#> [1]   0 100
#> 
#> $warp
#> $type
#> [1] "none"
#> 
#> $fit_by
#> NULL
#> 
#> attr(,"class")
#> [1] "gaze_warp_spec" "list"          
#> 
#> $screen
#> $width
#> [1] 30
#> 
#> $height
#> [1] 20
#> 
#> $unit
#> [1] "deg"
#> 
#> $center
#> [1] 15 10
#> 
#> $xlim
#> [1]  0 30
#> 
#> $ylim
#> [1]  0 20
#> 
#> attr(,"class")
#> [1] "gaze_screen" "list"       
#> 
#> $chronology
#> $type
#> [1] "local_order"
#> 
#> $horizon
#> [1] 0.2
#> 
#> attr(,"class")
#> [1] "gaze_chronology_spec" "list"                
#> 
#> $calibration
#> $calibration$folds
#> [1] 2
#> 
#> $calibration$seed
#> [1] 104729
#> 
#> $calibration$log_temperature_prior_sd
#> [1] 1
#> 
#> $calibration$log1p_kappa_prior_sd
#> [1] 1
#> 
#> $calibration$control
#> GazeWeave calibration control (revision 2026.10)
#>   method: evidence_scaled 
#>   gamma bounds: 0 to 1 
#>   inverse-temperature prior sd: 3 
#>   typicality offset: none 
#> 
#> 
#> $version
#> [1] 4
#> 
#> $revision
#> [1] "2026.10"
#> 
#> $background_by
#> NULL
#> 
#> $background_support
#> [1] "training"
#> 
#> attr(,"class")
#> [1] "gaze_replay_spec" "list"