Skip to contents

This glassbox function (in contrast to a "black box" function where you run it and get a result but have no (or little) idea as to how you got from input to output) has a few primary benefits over calling each exported function from eyeris separately.

Usage

glassbox(
  file,
  interactive_preview = FALSE,
  preview_n = 3,
  preview_duration = 5,
  preview_window = NULL,
  verbose = TRUE,
  ...,
  confirm = deprecated(),
  num_previews = deprecated(),
  detrend_data = deprecated(),
  skip_detransient = deprecated()
)

Arguments

file

An SR Research EyeLink .asc file generated by the official EyeLink edf2asc command

interactive_preview

A flag to indicate whether to run the glassbox pipeline autonomously all the way through (set to FALSE by default), or to interactively provide a visualization after each pipeline step, where you must also indicate "(y)es" or "(n)o" to either proceed or cancel the current glassbox pipeline operation (set to TRUE)

preview_n

Number of random example "epochs" to generate for previewing the effect of each preprocessing step on the pupil time series

preview_duration

Time in seconds of each randomly selected preview

preview_window

The start and stop raw timestamps used to subset the preprocessed data from each step of the eyeris workflow for visualization. Defaults to NULL, meaning random epochs as defined by preview_n and preview_duration will be plotted. To override the random epochs, set preview_window here to a vector with relative start and stop times (in seconds), for example – c(5,6) – to indicate the raw data from 5-6 secs on data that were recorded at 1000 Hz). Note, the start/stop time values indicated here are in seconds because eyeris automatically computes the indices for the supplied range of seconds using the $info$sample.rate metadata in the eyeris S3 class object

verbose

A logical flag to indicate whether to print status messages to the console. Defaults to TRUE. Set to FALSE to suppress messages about the current processing step and run silently

...

Additional arguments to override the default, prescribed settings

confirm

(Deprecated) Use interactive_preview instead

num_previews

(Deprecated) Use preview_n instead

detrend_data

(Deprecated) A flag to indicate whether to run the detrend step (set to FALSE by default). Detrending your pupil time series can have unintended consequences; we thus recommend that users understand the implications of detrending – in addition to whether detrending is appropriate for the research design and question(s) – before using this function

skip_detransient

(Deprecated) A flag to indicate whether to skip the detransient step (set to FALSE by default). In most cases, this should remain FALSE. For a more detailed description about likely edge cases that would prompt you to set this to TRUE, see the docs for detransient()

Value

Preprocessed pupil data contained within an object of class eyeris

Details

First, this glassbox function provides a highly opinionated prescription of steps and starting parameters we believe any pupillometry researcher should use as their defaults when preprocessing pupillometry data.

Second, and not mutually exclusive from the first point, using this function should ideally reduce the probability of accidental mishaps when "reimplementing" the steps from the preprocessing pipeline both within and across projects. We hope to streamline the process in such a way that you could collect a pupillometry dataset and within a few minutes assess the quality of those data while simultaneously running a full preprocessing pipeline in 1-ish line of code!

Third, glassbox provides an "interactive" framework where you can evaluate the consequences of the parameters within each step on your data in real time, facilitating a fairly easy-to-use workflow for parameter optimization on your particular dataset. This process essentially takes each of the opinionated steps and provides a pre-/post-plot of the time series data for each step so you can adjust parameters and re-run the pipeline until you are satisfied with the choices of your parameters and their consequences on your pupil time series data.

What glassbox() does, step by step

In plain language, glassbox() runs the following eyeris steps in order on your pupil time series. Steps marked (default: on) run automatically; steps marked (default: off) are skipped unless you explicitly enable them. Any step can be turned off by passing <step> = FALSE, or customized by passing <step> = list(...) with the parameter values you want to override (for example, deblink = list(extend = 40)).

  1. Load the data (load_asc, default: on) – Reads and parses the EyeLink .asc file into an eyeris object, automatically splitting the recording into blocks and, for binocular recordings, handling each eye separately. See load_asc().

  2. Remove blinks (deblink, default: on) – Replaces the missing data around blinks with NAs, extending each gap by 50 ms on either side so that the rapid dips and spikes that surround a blink are removed too. See deblink().

  3. Remove transient artifacts (detransient, default: on) – Rejects pupil samples that change faster than is physiologically plausible, using a speed-based median absolute deviation (MAD) threshold. See detransient().

  4. Interpolate missing samples (interpolate, default: on) – Fills the NA gaps left by the deblink and detransient steps using linear interpolation, producing a continuous, gap-free time series. See interpolate().

  5. Smooth the signal (lpfilt, default: on) – Applies a low-pass filter (default 4 Hz passband) to remove high-frequency noise while preserving the slower pupil dynamics of interest. See lpfilt().

  6. Downsample (downsample, default: off) – Optionally lowers the sampling rate using an anti-aliasing filter, which preserves the temporal dynamics of the signal. Cannot be combined with bin. See downsample().

  7. Bin (bin, default: off) – Optionally lowers the sampling rate by averaging samples within equal-width time bins. Cannot be combined with downsample. See bin().

  8. Detrend (detrend, default: off) – Optionally fits a linear model of pupil ~ time and returns the residuals (along with the fitted slope and intercept) to remove slow linear drift. Use with care – see detrend() for when this is appropriate.

  9. Z-score (zscore, default: on) – Rescales the pupil time series to a mean of 0 and a standard deviation of 1, making values comparable across participants and recordings. See zscore().

Crucially, each step adds a new column to the time series rather than overwriting the previous one, so every intermediate stage is preserved inside the returned eyeris object. This is what makes the pipeline a "glass box": you can inspect, plot, and compare the data before and after each transformation (for example, plot(output, steps = c(1, 5))).

Examples

demo_data <- eyelink_asc_demo_dataset()

# (1) examples using the default prescribed parameters and pipeline recipe

## (a) run an automated pipeline with no real-time inspection of parameters
output <- eyeris::glassbox(demo_data)
#>  [2026-07-03 04:07:08] [OKAY] Running eyeris::load_asc()
#>  [2026-07-03 04:07:09] [INFO] Processing block: block_1
#>  [2026-07-03 04:07:09] [OKAY] Running eyeris::deblink() for block_1
#>  [2026-07-03 04:07:09] [OKAY] Running eyeris::detransient() for block_1
#>  [2026-07-03 04:07:09] [OKAY] Running eyeris::interpolate() for block_1
#>  [2026-07-03 04:07:09] [OKAY] Running eyeris::lpfilt() for block_1

#> ! [2026-07-03 04:07:09] [WARN] Skipping eyeris::downsample() for block_1
#> ! [2026-07-03 04:07:09] [WARN] Skipping eyeris::bin() for block_1
#> ! [2026-07-03 04:07:09] [WARN] Skipping eyeris::detrend() for block_1
#>  [2026-07-03 04:07:09] [OKAY] Running eyeris::zscore() for block_1
#>  [2026-07-03 04:07:09] [INFO] Block processing summary:
#>  [2026-07-03 04:07:09] [INFO] block_1: OK (steps: 6, latest:
#> pupil_raw_deblink_detransient_interpolate_lpfilt_z)
#>  [2026-07-03 04:07:09] [OKAY] Running eyeris::summarize_confounds()

start_time <- min(output$timeseries$block_1$time_secs)
end_time <- max(output$timeseries$block_1$time_secs)

# by default, verbose = TRUE. To suppress messages, set verbose = FALSE.
plot(
  output,
  steps = c(1, 5),
  preview_window = c(start_time, end_time),
  seed = 0
)
#>  [2026-07-03 04:07:09] [INFO] Plotting block 1 with sampling rate 1000 Hz from
#> possible blocks: 1



## (b) run a interactive workflow (with confirmation prompts after each step)
# \donttest{
output <- eyeris::glassbox(demo_data, interactive_preview = TRUE, seed = 0)
#>  [2026-07-03 04:07:09] [OKAY] Running eyeris::load_asc()
#>  [2026-07-03 04:07:09] [INFO] Plotting block 1 with sampling rate 1000 Hz from
#> possible blocks: 1

#> Continue? [Yes/No]: 
#>  [2026-07-03 04:07:10] [INFO] Process cancelled after loading data. Adjust
#> your parameters and re-run!
# }

# (2) examples of overriding the default parameters
output <- eyeris::glassbox(
  demo_data,
  interactive_preview = FALSE, # TRUE to visualize each step in real-time
  deblink = list(extend = 40),
  lpfilt = list(plot_freqz = TRUE) # overrides verbose parameter
)
#>  [2026-07-03 04:07:10] [OKAY] Running eyeris::load_asc()
#>  [2026-07-03 04:07:10] [INFO] Processing block: block_1
#>  [2026-07-03 04:07:10] [OKAY] Running eyeris::deblink() for block_1
#>  [2026-07-03 04:07:10] [OKAY] Running eyeris::detransient() for block_1
#>  [2026-07-03 04:07:10] [OKAY] Running eyeris::interpolate() for block_1
#>  [2026-07-03 04:07:10] [OKAY] Running eyeris::lpfilt() for block_1

#> ! [2026-07-03 04:07:10] [WARN] Skipping eyeris::downsample() for block_1
#> ! [2026-07-03 04:07:10] [WARN] Skipping eyeris::bin() for block_1
#> ! [2026-07-03 04:07:10] [WARN] Skipping eyeris::detrend() for block_1
#>  [2026-07-03 04:07:10] [OKAY] Running eyeris::zscore() for block_1
#>  [2026-07-03 04:07:10] [INFO] Block processing summary:
#>  [2026-07-03 04:07:10] [INFO] block_1: OK (steps: 6, latest:
#> pupil_raw_deblink_detransient_interpolate_lpfilt_z)
#>  [2026-07-03 04:07:10] [OKAY] Running eyeris::summarize_confounds()

# to suppress messages, set verbose = FALSE in plot():
plot(output, seed = 0, verbose = FALSE)







# (3) examples of disabling certain steps
output <- eyeris::glassbox(
  demo_data,
  detransient = FALSE,
  detrend = FALSE,
  zscore = FALSE
)
#>  [2026-07-03 04:07:13] [OKAY] Running eyeris::load_asc()
#>  [2026-07-03 04:07:13] [INFO] Processing block: block_1
#>  [2026-07-03 04:07:13] [OKAY] Running eyeris::deblink() for block_1
#> ! [2026-07-03 04:07:13] [WARN] Skipping eyeris::detransient() for block_1
#>  [2026-07-03 04:07:13] [OKAY] Running eyeris::interpolate() for block_1
#>  [2026-07-03 04:07:13] [OKAY] Running eyeris::lpfilt() for block_1

#> ! [2026-07-03 04:07:13] [WARN] Skipping eyeris::downsample() for block_1
#> ! [2026-07-03 04:07:13] [WARN] Skipping eyeris::bin() for block_1
#> ! [2026-07-03 04:07:13] [WARN] Skipping eyeris::detrend() for block_1
#> ! [2026-07-03 04:07:13] [WARN] Skipping eyeris::zscore() for block_1
#>  [2026-07-03 04:07:13] [INFO] Block processing summary:
#>  [2026-07-03 04:07:13] [INFO] block_1: OK (steps: 4, latest:
#> pupil_raw_deblink_interpolate_lpfilt)
#>  [2026-07-03 04:07:13] [OKAY] Running eyeris::summarize_confounds()

plot(output, seed = 0)
#>  [2026-07-03 04:07:13] [INFO] Plotting block 1 with sampling rate 1000 Hz from
#> possible blocks: 1