| carla | R Documentation |
Selects an optimal subset of channels to use as the common average reference
(CAR) for cortico-cortical evoked potential (CCEP) data, following the
CARLA (see 'Reference' and 'Citation'). Channels are ranked in
increasing order of their cross-trial covariance (or variance when only one
trial is available); subsets are then iteratively grown and the size that
yields the least anti-correlation between the candidate reference and the
remaining unreferenced channels is selected as optimal.
carla(
x,
nboot = 100L,
sensitive = FALSE,
min_size = NULL,
absolute_rank = FALSE,
virtual_reference = FALSE
)
x |
numeric array of shape |
nboot |
integer, number of bootstrapped trial resamplings used to
estimate the optimization statistic; defaults to |
sensitive |
logical; if |
min_size |
integer, minimum subset size considered when
|
absolute_rank |
logical; if |
virtual_reference |
logical; if |
The function is a faithful port of the core CARLA.m routine; it does
not perform notch filtering, time-window cropping,
or grouping by stimulation site. Those steps belong to the surrounding
preprocess pipeline (see the example below).
For each candidate subset size n = 2, \ldots, N, the
candidate reference is computed as the channel-wise mean of the n
lowest-ranked channels. Each of those n channels is then correlated,
in its unreferenced form, against every channel of the candidate
re-referenced subset. The resulting Pearson correlations are
Fisher z-transformed; the row corresponding to the most globally
anti-correlated channel is recorded as zmin. The optimal n
is the one that maximizes (i.e. makes least negative) the mean of
zmin.
Bad-channel mask. Channels whose ranking statistic is exactly
zero or NA are flagged as "bad" and excluded both from the CAR
candidate pool and from the target-channel correlation rows. This
catches flat / dead channels (constant signal, no usable variance) and
, when virtual_reference = TRUE, automatically removes the virtual
channel itself, since subtracting it from itself yields a zero trace.
All references to channel indices in the returned order,
n_optimum, and zmin_mean are with respect to the
good channels only; vars is full-length so callers can
inspect the raw scores.
A list with the following elements:
channelsinteger vector, sorted indices (1-based) of the channels chosen to construct the common average reference. Compute the reference yourself as the channel-wise mean (or median) over these channels and subtract it from the original signal to obtain the re-referenced data.
orderinteger vector, indices of the good
channels sorted in increasing order of the ranking statistic. Bad
channels (zero variance / all-NA; see Details) are excluded.
varsnumeric vector of length nchan containing the
per-channel ranking statistic (mean cross-trial covariance, or variance
for a single trial). Bad channels keep their raw value (zero or
NA) so callers can audit the mask.
n_optimuminteger, the optimal subset size selected
(indexes into order).
zmin_meannumeric matrix of shape
length(order) x nboot (or a length-length(order) vector
for a single trial / nboot = 1) holding, for each subset size
and bootstrap, the mean Fisher z-transformed correlation of the most
globally anti-correlated unreferenced channel against the candidate CAR.
Row 1 is always NA (subset size 1 is not evaluated).
bad_channelsinteger vector of channel indices that were
excluded from the analysis because their ranking statistic was zero or
NA (flat / dead channels, plus the virtual channel itself when
virtual_reference = TRUE).
virtual_channelinteger, the index (1-based) of the
channel used as the virtual reference when virtual_reference =
TRUE; NA_integer_ otherwise.
vars1numeric vector of the first-pass ranking statistic
when virtual_reference = TRUE (the post-subtraction statistic is
returned in vars); NULL otherwise.
The CARLA algorithm (virtual_reference = FALSE) is described in
\Sexpr[results=rd]{tools:::Rd_expr_doi("10.1016/j.jneumeth.2024.110153")}; the modified CARLA precursor
(virtual_reference = TRUE) is described in
\Sexpr[results=rd]{tools:::Rd_expr_doi("10.1016/j.jneumeth.2025.110461")}, with a reference implementation
at https://github.com/hharveygit/SPES_reference_contam. See
citation("ravetools") for the full bibliographic entries of
both manuscripts.
# ---- Simulate a small CCEP-like dataset --------------------------------
# 16 channels, 12 trials, sampled at 1 kHz, 0.5 s peri-stimulus epoch.
# Channels 1:4 are "responsive" (carry an evoked potential); the rest are
# noise-only and should make up the optimal CAR.
srate <- 1000
tt <- seq(-0.1, 0.4 - 1 / srate, by = 1 / srate) # time, seconds
nchan <- 16
ntrial <- 30
resp_ch <- 1:4
noise_ch <- 4:7
# Evoked potential template: damped sinusoid starting at t = 0
ep <- ifelse(tt >= 0,
80 * exp(-tt / 0.05) * sin(2 * pi * 12 * tt),
0)
# time x trials x channels
x_full <- array(rnorm(length(tt) * ntrial * nchan, sd = 5),
dim = c(length(tt), ntrial, nchan))
for (ch in resp_ch) {
for (k in seq_len(ntrial)) {
x_full[, k, ch] <- x_full[, k, ch] + ep * runif(1, -0.8, 1.2)
}
}
for (ch in noise_ch) {
for (k in seq_len(ntrial)) {
tmp <- x_full[, k, ch]
x_full[, k, ch] <- tmp + sign(ch %% 2 - 0.5) * 5 *
runif(length(tmp), 0.8, 1.2)
}
}
# Add artifacts common to all channels and trials
artifacts <- 6 * sin(2 * pi * 60 * tt) + 7 * sin(2 * pi * 24 * tt)
x_full <- sweep(x_full, 1L, artifacts, "+")
# ---- 1. Notch filter line noise (per channel, per trial) ---------------
# The CARLA paper notch-filters before ranking; the re-reference itself
# is applied to the original (unfiltered) signal.
x_clean <- x_full
for (ch in seq_len(nchan)) {
for (k in seq_len(ntrial)) {
x_clean[, k, ch] <- notch_filter(
x_full[, k, ch], sample_rate = srate,
lb = c(59, 119, 179), ub = c(61, 121, 181)
)
}
}
# ---- 2. Crop to the responsive window (0.01 s to 0.3 s post-stim) ------
resp_idx <- which(tt > 0.0 & tt <= 0.3)
x_resp <- x_clean[resp_idx, , , drop = FALSE]
# ---- 3. Run CARLA to pick reference channels ---------------------------
fit <- carla(x_resp, sensitive = TRUE, absolute_rank = TRUE,
virtual_reference = TRUE)
fit$channels # selected reference channels (should exclude 1:4)
fit$n_optimum # number of channels in the optimal CAR
# ---- 4. Re-reference the ORIGINAL (unfiltered) signal ------------------
# mean or median, your choice! (time x trials)
car_full <- apply(x_full[, , fit$channels, drop = FALSE], c(1, 2), mean)
# old-style: using all channels for CAR
car_old <- apply(x_full, c(1, 2), mean)
x_reref <- sweep(x_full, c(1, 2), car_full, "-")
x_compare <- sweep(x_full, c(1, 2), car_old, "-")
# ---- 5. Inspect: evoked potential is preserved on responsive channels --
# `plot_signals` expects channels x time, so transpose each trial-1 slice.
op <- graphics::par(mfrow = c(2, 4), mar = c(4, 4, 2, 1))
ravetools::plot_signals(
signals = t(x_full[, 1, ]),
sample_rate = srate,
main = "Trial 1 - (raw)")
ravetools::plot_signals(
signals = t(x_clean[, 1, ]),
sample_rate = srate,
main = "Notch-filtered")
ravetools::plot_signals(
signals = t(x_reref[, 1, ]),
sample_rate = srate,
main = sprintf("CARLA-ref (n=%d)", length(fit$channels)))
ravetools::plot_signals(
signals = t(x_compare[, 1, ]),
sample_rate = srate,
main = "Conventional CAR for comparison")
col <- adjustcolor(seq_len(nchan))
col[resp_ch] <- adjustcolor(col[resp_ch], alpha.f = 0.2)
# Trial-average -> time x channels, ready for `matplot(tt, .)`
graphics::matplot(tt, apply(x_full, c(1, 3), mean),
type = "l", lty = 1, xlab = "Time (s)", ylab = "uV",
main = "Trial-averaged (raw)", col = col)
graphics::matplot(tt, apply(x_clean, c(1, 3), mean),
type = "l", lty = 1, xlab = "Time (s)", ylab = "uV",
main = "Notch-filtered", col = col)
graphics::matplot(tt, apply(x_reref, c(1, 3), mean),
type = "l", lty = 1, xlab = "Time (s)", ylab = "uV",
main = "CARLA-referenced", col = col)
graphics::matplot(tt, apply(x_compare, c(1, 3), mean),
type = "l", lty = 1, xlab = "Time (s)", ylab = "uV",
main = "conventional CAR-referenced", col = col)
graphics::par(op)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.