Artifact Correction#
MNE-RT provides five real-time artifact correction methods that can be selected
via RTStream (artifact_correction= parameter) or the
CLI (--artifact-correction). All methods expose a common
fit / transform interface and operate sample-by-sample (or
chunk-by-chunk) during the closed-loop session.
Adaptive LMS filter#
Class: mne_rt.tools.AdaptiveLMSFilter
The Least Mean Squares (LMS) algorithm [1] is a stochastic gradient-descent adaptive filter designed to cancel a reference signal (e.g., an EOG or ECG channel) from the M/EEG data channels.
Model. For channel \(i\) at time \(t\), the cleaned signal is:
where \(x_i(t)\) is the raw sample, \(\mathbf{r}(t) \in \mathbb{R}^q\) is the reference signal vector (possibly delayed copies of the artefact channel), and \(\mathbf{w}_i(t)\) is the adaptive weight vector.
Weight update (Widrow–Hoff rule):
where \(\mu > 0\) is the step size (learning rate). The algorithm converges when the cross-correlation between \(\mathbf{r}(t)\) and the residual \(y_i(t)\) reaches zero — i.e., when the filter has learned to predict the artifact contribution in channel \(i\) from the reference.
Stability condition. The step size must satisfy \(0 < \mu < 2/(\lambda_{\max}\, q)\), where \(\lambda_{\max}\) is the largest eigenvalue of the reference autocorrelation matrix. MNE-RT uses a normalised variant (NLMS) that adapts \(\mu\) automatically:
When to use. Best suited for ocular (EOG) or cardiac (ECG) artifacts when a clean reference channel is available. Requires no calibration baseline — the filter adapts online from sample 1.
ORICA — Online Recursive ICA#
Class: mne_rt.tools.ORICA
ORICA [2] is an online (sample-recursive) variant of Independent Component Analysis (ICA) [3] that continuously updates the unmixing matrix \(\mathbf{W}\) as new data arrive.
ICA model. EEG is assumed to be a linear mixture of independent sources:
where \(\mathbf{A} \in \mathbb{R}^{p \times p}\) is the mixing matrix, \(\mathbf{W} = \mathbf{A}^{-1}\) is the unmixing matrix, and \(\mathbf{s}(t)\) are the independent components (ICs).
Recursive update. ORICA updates \(\mathbf{W}\) with each new sample using an exponentially weighted natural-gradient rule:
where \(\mathbf{f}(\cdot)\) is a nonlinear score function (e.g., \(f(s) = \tanh(s)\) for super-Gaussian sources) and \(\lambda(t)\) is a decreasing forgetting factor that controls how fast old data are discarded.
Artifact removal. ICs whose kurtosis, focal power, or spatial map match known artifact signatures (blinks, muscle, ECG) are identified and zeroed before back-projection:
where the subscript “clean” denotes the subsets of columns / rows with artifact ICs removed.
When to use. Suitable for EEG with diverse artifact types. No reference channel is required. Because \(\mathbf{W}\) adapts continuously, ORICA tracks slow non-stationarities (electrode drift, changing impedances).
GEDAI — GED-based Artifact Isolation#
Class: mne_rt.tools.GEDAIDenoiser
GEDAI uses Generalized Eigendecomposition (GED) [4] to find spatial filters that maximally separate brain signal from broadband activity, optionally anchored to a leadfield-derived forward model [5].
GED formulation. MNE-RT uses a band-vs-broadband formulation. Let \(\mathbf{R}_\text{band}\) be the covariance of the band-limited signal (e.g. 8–30 Hz for alpha/beta) and \(\mathbf{R}_\text{broad}\) be the broadband covariance. The GED solves:
The columns of \(\mathbf{W}\) are spatial filters and the eigenvalues \(\lambda_k = \mathbf{w}_k^\top \mathbf{R}_\text{band}\, \mathbf{w}_k \;/\; \mathbf{w}_k^\top \mathbf{R}_\text{broad}\, \mathbf{w}_k\) express the band-to-broadband power ratio along each filter direction.
Eigenvalue interpretation. Filters are sorted by \(\lambda_k\) in descending order:
Large \(\lambda_k\) — high band/broadband ratio → brain-like (targeted oscillation dominant).
Small \(\lambda_k\) — low band/broadband ratio → non-brain (broadband, artifact-like).
Artifact isolation. find_noise_components()
returns the \(n_\text{noise}\) components with the smallest eigenvalues
(least band-specific), which are then zeroed before back-projection:
where \(\mathbf{W}_{\text{brain}}\) is the subset of \(\mathbf{W}\) with the largest eigenvalues (brain-like directions retained).
Leadfield incorporation. When a forward model is available
(fit_from_leadfield()), GEDAI replaces
\(\mathbf{R}_\text{band}\) with the leadfield outer product
\(\mathbf{L}\mathbf{L}^\top\), directly constraining filters to be
consistent with neural generators.
When to use. Most powerful when a resting-state baseline is available
and the artifact has a stable spatial signature (cardiac, powerline).
Requires a calibration recording (fit_from_raw() uses the first N seconds).
ASR — Artifact Subspace Reconstruction#
Class: mne_rt.tools.ASRDenoiser
ASR [6] [7] learns the covariance statistics of a clean baseline segment, then projects out components that deviate beyond a threshold in subsequent data windows.
Calibration. The baseline recording is divided into overlapping windows of length \(T_{\mathrm{win}}\). The sample covariance per window is:
Windows with the highest total power (top max_dropout_fraction fraction
by \(\operatorname{tr}(\mathbf{C}_j)\)) are discarded as likely artifactual.
The mean of the remaining clean covariances is eigendecomposed:
Per-component RMS thresholds are set as:
where \(\sigma\) = cutoff (default 5).
Cleaning (online). For each incoming window \(\mathbf{X} \in \mathbb{R}^{p \times n}\):
Project to calibration-component space: \(\mathbf{Z} = \mathbf{U}^\top(\mathbf{X} - \bar{\mathbf{x}})\).
Compute per-component RMS: \(r_k = \sqrt{\operatorname{mean}(Z_k^2)}\).
Zero artifact-dominated components: \(Z_k \leftarrow 0\) if \(r_k > T_k\).
Back-project and restore the mean: \(\hat{\mathbf{X}} = \mathbf{U}\mathbf{Z} + \bar{\mathbf{x}}\).
Because steps 1–4 reduce to two matrix multiplies, the per-chunk runtime is \(\mathcal{O}(p^2 n)\).
When to use. General-purpose EEG artifact suppressor. Robust to
transient high-amplitude artifacts (muscle bursts, electrode pops).
Requires a brief clean baseline (fit_asr() records 60 s by default).
RTMaxwellFilter — Real-Time SSS / tSSS#
Class: mne_rt.tools.RTMaxwellFilter
The Signal Space Separation (SSS) method [8] and its temporal extension (tSSS) [9] exploit the physics of quasi-static magnetic fields to separate brain-origin signals from external interference in MEG recordings.
Physical basis. Inside the sensor array the magnetic field satisfies the Laplace equation \(\nabla^2 \phi = 0\). Solutions are decomposed into a basis of spherical harmonic multipoles:
where \(\phi^{\mathrm{in}}_{\ell m}\) are the internal basis functions (sources inside the array — brain signals) and \(\phi^{\mathrm{ex}}_{\ell m}\) are the external basis functions (sources outside — environmental noise).
SSS projector. Let \(\mathbf{S}_{\mathrm{in}}\) and \(\mathbf{S}_{\mathrm{ex}}\) be the basis matrices evaluated at all sensor positions. The SSS projector onto the internal subspace is:
where \((\cdot)^\dagger\) denotes the Moore–Penrose pseudoinverse. Applied to raw MEG data \(\mathbf{X}\):
This single matrix multiply (cached at calibration time) suppresses all signal components that cannot originate inside the sensor array.
tSSS — temporal extension. Internal components that correlate with external ones over a sliding time window indicate that interference has “leaked” into the internal space (e.g., due to a nearby ferromagnetic object). tSSS [9] removes these correlated components by projecting the internal coefficients onto the subspace orthogonal to the external ones:
where \(\Pi_{\mathrm{corr}}\) is the projector onto the directions of \(\boldsymbol{\alpha}\) that correlate above threshold with the external coefficient matrix over the buffer.
Real-time implementation in MNE-RT.
RTMaxwellFilter caches \(\mathbf{P}_{\mathrm{SSS}}\)
once during fit() using mne.preprocessing.compute_maxwell_basis(),
then applies it as a matrix multiply per incoming chunk. This gives:
Zero additional latency beyond a matrix multiply per chunk.
Numerical equivalence with offline MNE
maxwell_filter()(verified to machine-epsilon level).
tSSS runs periodically on a rolling buffer with
maxwell_filter() (st_only=True, skipping the
already-applied spatial step).
Empty-room noise covariance. When an empty-room recording is provided,
RTMaxwellFilter uses a system-identification approach:
MNE’s full Maxwell filter (with noise-informed regularisation) is applied to a
Gaussian test signal, and the effective operator is recovered by least squares:
where \(\mathbf{X}\) is the test input (good-channel MEG) and \(\mathbf{Y}\) is the filtered output. This transparently incorporates fine calibration, cross-talk compensation, and noise-informed regularisation into the single cached matrix — no re-implementation of SSS is required.
Baseline requirement. Unlike ASR or GEDAI, RTMaxwellFilter
requires no baseline recording — \(\mathbf{P}_{\mathrm{SSS}}\) depends
only on sensor geometry, which is fixed at scanner installation.
When to use. MEG data only. Mandatory first denoising step in any MEG pipeline. Use SSS mode for environmental noise suppression; add tSSS when nearby ferromagnetic objects or implants are present.
Bad Channel Detection#
Class: mne_rt.tools.BadChannelDetector
Artifact correction assumes all channels are functional. A disconnected or
noisy electrode contaminating adjacent channels can degrade every downstream
method. BadChannelDetector evaluates each incoming data
window against up to four independent criteria and uses a rolling-window
majority vote to flag persistently bad channels.
Criteria
"flat"Channels whose RMS amplitude falls below
flat_threshold. Catches disconnected leads and dead electrodes."variance"Channels whose RMS is a robust outlier across all channels, measured by a MAD-based z-score: \(z = (\text{RMS} - \text{median})\;/\;(\text{MAD} \times 1.4826)\). Flags both excessively noisy and suspiciously quiet channels.
"correlation"Channels whose mean Pearson correlation with their \(K\) nearest spatial neighbours falls below
corr_threshold. Requires channel positions to be set ininfo(montage applied)."hf_noise"Channels with an abnormally high ratio of HF power (>
hf_cutoffHz) to broadband power, using the same MAD z-score. Catches EMG, loose cable noise, and intermittent contacts.
Rolling-window vote. A channel is declared bad only when it is flagged
by at least one criterion in ≥ min_bad_frac of the last
history_windows windows. With the default min_bad_frac=0.5 this
is a majority vote over the past 30 windows, suppressing false positives
from transient artifacts.
Usage example:
detector = BadChannelDetector(raw.info, method="all")
while streaming:
window = stream.get_data(1.0) # 1-second chunk
bad_channels = detector.update(window)
raw.info["bads"] = bad_channels
Riemannian Potato — Online Artifact Detection#
Class: mne_rt.tools.RiemannianPotatoDetector
The Riemannian Potato [10][11] is a covariance-based method for detecting — rather than correcting — artifactual data windows in real time. It operates on the manifold of symmetric positive-definite (SPD) matrices by computing the Riemannian distance from each incoming covariance matrix to the geometric mean of a clean calibration set. When this distance exceeds a z-score threshold, the window is flagged as an artifact and can be discarded or buffered for later ICA clean-up.
Why Riemannian geometry? Standard Euclidean distances on covariance matrices are sensitive to the arbitrary scaling of individual channels. The Riemannian (affine-invariant) metric is scale-invariant: multiplying all channels by any positive constant leaves the distance unchanged. This makes the potato robust to amplitude drift and electrode-impedance changes across sessions.
Algorithm. Let \(\Sigma_t\) be the sample covariance matrix of window \(t\) and \(\bar{\Sigma}\) be the geometric mean of calibration covariances. The z-score is:
where \(\delta\) is the Riemannian distance and \(\mu_\delta\), \(\sigma_\delta\) are the mean and standard deviation of distances computed over the calibration set. Window \(t\) is declared an artifact when \(z_t > \theta\) (default \(\theta = 3\)).
Note
The Riemannian Potato is a detection method, not a correction method.
It identifies and rejects artifactual windows; it does not reconstruct
clean signal from contaminated data. Pair it with
ORICA or ASRDenoiser when online
correction is needed.
Usage example:
from mne_rt.tools import RiemannianPotatoDetector
# Calibrate on 60 clean 1-second windows
detector = RiemannianPotatoDetector(threshold=3.0)
detector.fit(clean_windows) # shape (n_windows, n_ch, n_samples)
while streaming:
window = stream.get_data(1.0)
is_clean, z_score = detector.detect(window)
if is_clean:
compute_nf_feature(window)
else:
logger.debug("Artifact detected (z=%.2f) — window skipped", z_score)
When to use. Any EEG or MEG setup where transient artifacts (blinks, muscle bursts, electrode pops) need to be excluded from the feature computation. Particularly effective when reliable reference channels for LMS are unavailable. Requires a short clean calibration phase (≥ 30 windows recommended) before streaming begins.
Method comparison#
Method |
Modality |
Baseline needed |
Reference ch. |
Adapts online |
Primary target |
|---|---|---|---|---|---|
LMS |
EEG / MEG |
No |
Yes (EOG/ECG) |
Yes |
Ocular, cardiac |
ORICA |
EEG / MEG |
No |
No |
Yes |
Mixed artifacts |
GEDAI |
EEG / MEG |
Yes (N s) |
No |
No |
Cardiac, powerline |
ASR |
EEG / MEG |
Yes (N s) |
No |
No |
Transient high-amplitude |
RTMaxwellFilter |
MEG only |
No |
No |
No (periodic tSSS) |
Environmental noise |
BadChannelDetector |
EEG / MEG |
No |
No |
Yes (rolling) |
Disconnected / noisy channels |
RiemannianPotatoDetector |
EEG / MEG |
Yes (N windows) |
No |
No (detection only) |
Transient artifacts (blinks, muscle, pops) |
See also the artifact comparison example for a quantitative benchmark of LMS, ASR, and GEDAI on simulated EEG, and the RTMaxwell example for a demonstration of real-time SSS on the MNE sample MEG dataset.