Detrend pupil data by fitting a model of pupil_data ~ time and returning
the fitted values (the estimated trend) together with the residuals
(pupil_data - fitted_values). Two trend models are supported via the
method argument: "linear" (the default) removes a straight-line drift by
fitting an ordinary linear model, while "spline" removes a smooth,
potentially nonlinear drift by fitting a natural cubic spline basis of time
(splines::ns(time, df = spline_df)).
Usage
detrend(
eyeris,
method = c("linear", "spline"),
spline_df = 5,
call_info = NULL
)Arguments
- eyeris
An object of class
eyerisderived fromload_asc()- method
A string indicating the detrending model to fit. Either
"linear"(the default) to remove a straight-line trend by regressing pupil size on time, or"spline"to remove a smooth, potentially nonlinear trend by fitting a natural cubic spline basis of time (splines::ns(time, df = spline_df))- spline_df
The degrees of freedom for the natural cubic spline basis used when
method = "spline". Higher values allow the fitted trend to follow more rapid, nonlinear drift; lower values enforce a smoother trend. Must be a single whole number>= 1. Defaults to5. Ignored whenmethod = "linear"- call_info
A list of call information and parameters. If not provided, it will be generated from the function call. Defaults to
NULL
Value
An eyeris object with two new columns in time series:
detrend_fitted_values, and pupil_raw_{...}_detrend
Details
This function is automatically called by glassbox() if detrend = TRUE.
Users should prefer using glassbox() rather than invoking this function
directly unless they have a specific reason to customize the pipeline
manually.
Note
This function is part of the glassbox() preprocessing pipeline and is not
intended for direct use in most cases. Use glassbox(detrend = TRUE) for
linear detrending, or glassbox(detrend = list(method = "spline")) for
spline detrending.
Advanced users may call it directly if needed.
See also
glassbox() for the recommended way to run this step as
part of the full eyeris glassbox preprocessing pipeline
For a complete, end-to-end reference pipeline that demonstrates how all
eyeris preprocessing functions are chained together in practice, see the
"Building Blocks Under the Hood" section of the Anatomy of an eyeris
Object vignette — vignette("anatomy", package = "eyeris") — as
well as the Complete Pupillometry Pipeline Walkthrough vignette:
vignette("complete-pipeline", package = "eyeris").
Examples
demo_data <- eyelink_asc_demo_dataset()
# (a) linear detrending (the default)
demo_data |>
eyeris::glassbox(detrend = TRUE) |> # set to FALSE to skip step (default)
plot(seed = 0)
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::load_asc()
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::resample()
#> ℹ [2026-07-19 07:14:53] [INFO] Processing block: block_1
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::deblink() for block_1
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::detransient() for block_1
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::interpolate() for block_1
#> ! [2026-07-19 07:14:53] [WARN] Interpolation now leaves gaps longer than 250 ms
#> as `NA` instead of interpolating across them (following Kret & Sjak-Shie,
#> 2018). This is a change in default behavior from eyeris <= 3.2.0 and may affect
#> your results. To restore the previous behavior, set `interpolate =
#> list(max_gap_ms = Inf)` in `glassbox()` (or `max_gap_ms = Inf` in
#> `interpolate()`).
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::lpfilt() for block_1
#> ! [2026-07-19 07:14:53] [WARN] Skipping eyeris::downsample() for block_1
#> ! [2026-07-19 07:14:53] [WARN] Skipping eyeris::bin() for block_1
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::detrend() for block_1
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::zscore() for block_1
#> ℹ [2026-07-19 07:14:53] [INFO] Block processing summary:
#> ℹ [2026-07-19 07:14:53] [INFO] block_1: OK (steps: 7, latest:
#> pupil_raw_deblink_detransient_interpolate_lpfilt_detrend_z)
#> ✔ [2026-07-19 07:14:53] [OKAY] Running eyeris::summarize_confounds()
#> ℹ [2026-07-19 07:14:53] [INFO] Plotting block 1 with sampling rate 1000 Hz from
#> possible blocks: 1
# (b) spline detrending (removes a smooth, nonlinear trend)
demo_data |>
eyeris::glassbox(detrend = list(method = "spline", spline_df = 5)) |>
plot(seed = 0)
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::load_asc()
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::resample()
#> ℹ [2026-07-19 07:14:57] [INFO] Processing block: block_1
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::deblink() for block_1
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::detransient() for block_1
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::interpolate() for block_1
#> ! [2026-07-19 07:14:57] [WARN] Interpolation now leaves gaps longer than 250 ms
#> as `NA` instead of interpolating across them (following Kret & Sjak-Shie,
#> 2018). This is a change in default behavior from eyeris <= 3.2.0 and may affect
#> your results. To restore the previous behavior, set `interpolate =
#> list(max_gap_ms = Inf)` in `glassbox()` (or `max_gap_ms = Inf` in
#> `interpolate()`).
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::lpfilt() for block_1
#> ! [2026-07-19 07:14:57] [WARN] Skipping eyeris::downsample() for block_1
#> ! [2026-07-19 07:14:57] [WARN] Skipping eyeris::bin() for block_1
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::detrend() for block_1
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::zscore() for block_1
#> ℹ [2026-07-19 07:14:57] [INFO] Block processing summary:
#> ℹ [2026-07-19 07:14:57] [INFO] block_1: OK (steps: 7, latest:
#> pupil_raw_deblink_detransient_interpolate_lpfilt_detrend_z)
#> ✔ [2026-07-19 07:14:57] [OKAY] Running eyeris::summarize_confounds()
#> ℹ [2026-07-19 07:14:57] [INFO] Plotting block 1 with sampling rate 1000 Hz from
#> possible blocks: 1
