mne_rt.tools.RiemannianPotatoDetector#
- class mne_rt.tools.RiemannianPotatoDetector(threshold: float = 3.0, estimator: str = 'oas', metric: str = 'riemann', verbose: bool | str | None = None)[source]#
Bases:
objectOnline EEG/MEG artifact detector based on the Riemannian Potato.
The Riemannian Potato detects artifactual epochs by measuring how far each incoming covariance matrix is from the geometric mean of a clean calibration set — distance is computed in the Riemannian metric on the manifold of symmetric positive-definite (SPD) matrices. A window is declared artifactual when this distance (expressed as a z-score) exceeds
threshold.Unlike threshold-based or ICA-based methods, this approach requires no reference channel and is robust to gradual amplitude drift (because the geometric mean adapts to the signal statistics during calibration rather than using a fixed absolute threshold).
- Parameters:
- threshold
float, default 3.0 Z-score cutoff (Riemannian distance units). Windows with a distance z-score above this value are flagged as artifacts. Typical range: 2.5–4.0. Lower = more aggressive rejection.
- estimator
str, default “oas” Covariance estimator passed to
pyriemann.estimation.Covariances."oas"(Oracle Approximating Shrinkage) is robust at low sample-to-channel ratios;"scm"gives the raw sample covariance.- metric
str, default “riemann” Riemannian metric used for the potato.
"riemann"(affine-invariant) is the canonical choice;"logeuclid"is faster but less robust.- verbosebool |
str|None, defaultNone Verbosity level. See
set_log_level().
- threshold
- Attributes:
- Raises:
ImportErrorIf
pyriemannis not installed.RuntimeError
Examples
Calibrate on 60 s of clean data, then detect online:
detector = RiemannianPotatoDetector(threshold=3.0) detector.fit(clean_windows) # shape (n_windows, n_ch, n_samples) while streaming: window = stream.get_data(1.0) # shape (n_ch, n_samples) is_clean, z_score = detector.detect(window) if is_clean: process_for_nf(window)
Added in version 1.0.0.
- __init__(threshold: float = 3.0, estimator: str = 'oas', metric: str = 'riemann', verbose: bool | str | None = None) None[source]#
Methods
__init__([threshold, estimator, metric, verbose])detect(window)Test a single window for artifacts.
fit(windows)Calibrate the potato on clean data windows.
- fit(windows: ndarray) RiemannianPotatoDetector[source]#
Calibrate the potato on clean data windows.
Computes covariance matrices for each window and fits the geometric mean and variance used as the potato centre and spread.
- Parameters:
- windows
ndarray,shape(n_windows,n_channels,n_samples) Calibration data. Should contain clean (artifact-free) segments. At least 10 windows are recommended; 30–60 is typical for a 1-second window length at standard EEG sampling rates.
- windows
- Returns:
- Raises:
ValueErrorIf
windows.ndim != 3or fewer than 2 windows are provided.
- detect(window: ndarray) tuple[bool, float][source]#
Test a single window for artifacts.
- Parameters:
- window
ndarray,shape(n_channels,n_samples) One data window to evaluate.
- window
- Returns:
- Raises:
RuntimeErrorIf called before
fit().ValueErrorIf the channel count does not match the calibration set.