Reported sampling rates and observed timestamp intervals

Measurement question

Device-reported rate, source-export timestamp intervals, frame-delivery cadence, and downstream resampling frequency are distinct quantities. A declared sampling frequency should never be substituted for empirical timestamp checks; neither observed intervals nor a device specification by themselves establish synchronization accuracy, calibration quality, or the temporal accuracy of a fixation or pupil event.

This deliberately synthetic example begins with a nominal 120 Hz grid, introduces jitter, and inserts a few delayed intervals to show why mean realized rate and interval distribution should be reported separately.

set.seed(20261022)
n <- 501L
nominal_ms <- 1000 / 120
interval_ms <- pmax(0.1, stats::rnorm(n - 1L, nominal_ms, 0.55))
delays <- seq(95L, 395L, by = 60L)
interval_ms[delays] <- interval_ms[delays] * 2.6
timestamp_ms <- c(0, cumsum(interval_ms))
realized_rate_hz <- (length(timestamp_ms) - 1L) * 1000 /
  (tail(timestamp_ms, 1L) - timestamp_ms[1L])
stopifnot(length(timestamp_ms) == n,
          all(diff(timestamp_ms) > 0),
          realized_rate_hz < 120)
data.frame(declared_hz = 120, observed_mean_hz = realized_rate_hz,
           interval_q05_ms = unname(stats::quantile(interval_ms, 0.05)),
           interval_median_ms = unname(stats::median(interval_ms)),
           interval_q95_ms = unname(stats::quantile(interval_ms, 0.95)))
##   declared_hz observed_mean_hz interval_q05_ms interval_median_ms
## 1         120         117.5595        7.505306           8.339749
##   interval_q95_ms
## 1        9.276689

Figure 1. The actual interval sequence

graphics::plot(seq_along(interval_ms), interval_ms, type = "h",
               col = "#24577B", xlab = "Successive observed interval",
               ylab = "Elapsed time (milliseconds)",
               main = "Nominal sampling is not realized delivery")
graphics::abline(h = nominal_ms, lty = 2, col = "#C05B43", lwd = 2)
Synthetic timestamp differences. Dashed line shows the nominal device interval, not a measured timing-reference accuracy bound.
Synthetic timestamp differences. Dashed line shows the nominal device interval, not a measured timing-reference accuracy bound.

Figure 2. Interval distribution and delayed updates

graphics::hist(interval_ms, breaks = 28,
               col = "#CEE0ED", border = "#597087",
               xlab = "Observed timestamp interval (milliseconds)",
               main = "Interval distribution reveals long-tail delays")
graphics::abline(v = nominal_ms, col = "#C05B43", lty = 2, lwd = 2)
Original R histogram of intentionally jittered synthetic intervals with occasional delayed updates; no real device measurement or clock-ground-truth comparison.
Original R histogram of intentionally jittered synthetic intervals with occasional delayed updates; no real device measurement or clock-ground-truth comparison.

Reporting constraints

This demonstration supports an elementary acquisition audit: retain native export timestamps and source rate declarations; calculate realized intervals before interpolation, smoothing or trial aggregation; record clock changes and delayed intervals; and distinguish observed missing records from true absence of the underlying behavioral event. It does not establish whether delayed samples reflect buffering, device loss, timestamp origin, USB delivery, a host computer, or another cause. That inference needs independent reference timing and vendor-specific documentation.

The separate draft acquisition-integrity research PR #49 includes experimental certificate and plotting implementations that remain subject to empirical qualification and CI. This article does not merge those research APIs, change published stable 0.12.0 or authorize a newer CRAN release.