AnnotateArtifact
Namespace: RTPROCESSINGLIB · Library: DSP Library
This page documents a header-level module — a collection of free functions that share an algorithmic topic. There is no enclosing C++ class; the functions live directly in the library namespace.
mne.preprocessing.annotate_muscle_zscore / annotate_amplitude in MNE-Python.
#include <dsp/annotate_artifact.h>
SPDX-License-Identifier: BSD-3-Clause Copyright (c) 2026 MNE-CPP Authors.
The detectors in this header scan continuous MEG / EEG data and emit FiffAnnotation intervals marking time segments that should be excluded from downstream averaging, ICA fitting or PSD estimation. annotateMusclZscore band-pass filters the signal in the 110–140 Hz range (typical EMG band), z-scores the Hilbert envelope of every channel, combines and smooths the scores and marks samples above a threshold as BAD_muscle. annotateAmplitude marks spans where consecutive samples jump by more than a "peak" threshold or change by less than a "flat" one, and returns channels for which that holds too often as bad.
Both routines reproduce their MNE-Python counterparts mne.preprocessing.annotate_muscle_zscore and mne.preprocessing.annotate_amplitude onset for onset.
AnnotateAmplitudeParams amplitude;
amplitude.flat = 1e-12; // consecutive samples within 1 pV of each other
QStringList flatChannels;
const FiffAnnotations flatSpans = annotateAmplitude(loose, info, kSFreq, amplitude, &flatChannels);
AnnotateMusclParams muscle; // mne defaults: z > 4 in the 110-140 Hz envelope, gaps < 0.1 s filled
const FiffAnnotations emgBad = annotateMusclZscore(emgData, info.pick_info(RowVectorXi::LinSpaced(kEeg, 0, kEeg - 1)), emgSFreq, muscle);
Functions
annotateMusclZscore(data, info, sfreq, params, scores)
[FiffAnnotations](/docs/api/fiff/fiff-annotations) annotateMusclZscore(const Eigen::MatrixXd & data, const [FiffInfo](/docs/api/fiff/fiff-info) & info, double sfreq, const [AnnotateMusclParams](/docs/api/dsp/annotate-muscl-params) & params, Eigen::RowVectorXd * scores);
Detect muscle artifacts via high-frequency z-score and annotate bad segments.
Algorithm of mne.preprocessing.annotate_muscle_zscore with ch_type None:
Pick the magnetometers, else the gradiometers, else the EEG channels.
Band-pass them with mne's default FIR filter (FirFilter::filterData).
Take the Hilbert envelope (FFT length padded to the next 5-smooth size).
Z-score every channel over time, sum over channels and divide by sqrt(n_channels).
Low-pass the score at 4 Hz with the same FIR filter.
Mark samples above the threshold; good stretches shorter than dMinLengthGood become bad.
Parameters:
-
data : const Eigen::MatrixXd & Raw data matrix (n_channels × n_times).
-
info : const FiffInfo & Measurement info.
-
sfreq : double Sampling frequency in Hz.
-
params : const AnnotateMusclParams & Detection parameters.
-
scores : *Eigen::RowVectorXd ** If not null, receives the smoothed score per sample (mne's scores_muscle).
Returns:
- FiffAnnotations — FiffAnnotations with "BAD_muscle" entries.
annotateAmplitude(data, info, sfreq, params, bads)
[FiffAnnotations](/docs/api/fiff/fiff-annotations) annotateAmplitude(const Eigen::MatrixXd & data, const [FiffInfo](/docs/api/fiff/fiff-info) & info, double sfreq, const [AnnotateAmplitudeParams](/docs/api/dsp/annotate-amplitude-params) & params, QStringList * bads);
Annotate spans where consecutive samples jump or stay flat, as mne.preprocessing.annotate_amplitude.
For every data channel that is not bad, the absolute differences between consecutive samples are compared with params.peak (at least) and params.flat (at most); runs shorter than params.dMinDuration are ignored. A channel whose runs cover at least params.dBadPercent of the recording is returned in bads; the runs of the other channels are merged into "BAD_flat" and "BAD_peak" annotations. Unlike mne, a channel that is bad for both reasons is listed once, and BAD_ACQ_SKIP spans are not skipped (the data matrix carries no annotations).
Parameters:
-
data : const Eigen::MatrixXd & Raw data matrix (n_channels × n_times).
-
info : const FiffInfo & Measurement info (channel types, names and bads).
-
sfreq : double Sampling frequency in Hz.
-
params : const AnnotateAmplitudeParams & Thresholds; at least one of peak and flat must be set.
-
bads : *QStringList ** If not null, receives the channels annotated for too long, in channel order.
Returns:
- FiffAnnotations — "BAD_flat" and "BAD_peak" annotations.
Example
- Full source:
src/examples/ex_dsp_artifacts/main.cpp - Build target:
ex_dsp_artifacts(runs under CTest)
Authors of this file
- Christoph Dinh <christoph.dinh@mne-cpp.org>