Muscle artifact detection (annotate_muscle_zscore) placement in vMMR preprocessing pipeline

Hello everyone, I’m working on preprocessing an EEG dataset for a visual mismatch response (vMMR) ERP experiment. I have a specific question: where should mne.preprocessing.annotate_muscle_zscore() be placed in my epoching and preprocessing pipeline - before ICA, after ICA, or should I skip it entirely?

Current Pipeline

  1. Load raw data + montage + average-reference projector

  2. Filter (HP 0.1 Hz only, no LP filter) + downsample to 512 Hz + event alignment

  3. Parse trials (standard and deviant separately)

  4. RANSAC global bad channel detection

  5. Epoching with broadband data (baseline=None)

  6. AutoReject-1 on broadband epochs

  7. ICA fit + ICLabel classification

  8. Apply ICA + AutoReject-2 on broadband epochs + LP 30 Hz filter

I’m using 64-channel BioSemi data.

Minimal reproducible example:

raw.filter(0.1, None, l_trans_bandwidth=0.08)
raw.resample(512)

Where to add annotate_muscle_zscore()?

raw = mne.preprocessing.annotate_muscle_zscore(raw, threshold=2.)

epochs = mne.Epochs(raw, events, event_ids, tmin=-0.2, tmax=1.5,
baseline=None, preload=True,
reject_by_annotation=False)

ar1 = autoreject.AutoReject(n_interpolate=[1, 4, 32], random_state=42)
epochs, reject_log1 = ar1.fit_transform(epochs, return_log=True)

ica = mne.preprocessing.ICA(method=‘infomax’, n_components=0.99, random_state=99)
ica.fit(epochs)

ic_labels = label_components(epochs, ica, method=“iclabel”)
exclude_idx = [idx for idx, label in enumerate(ic_labels[“labels”])
if label not in [“brain”, “other”]]
ica.apply(epochs, exclude=exclude_idx)

Or here instead?

epochs = mne.preprocessing.annotate_muscle_zscore(epochs, threshold=2.)

epochs.apply_baseline((None, 0))
epochs.filter(None, 30)

ar2 = autoreject.AutoReject(n_interpolate=[1, 4, 32], random_state=42)
epochs_clean, reject_log2 = ar2.fit_transform(epochs, return_log=True)

If your evokeds look clean enough for the purposes of your study, there is no need to include annotate_muscle_zscore at all. If the subject was moving during epochs, I think I would perform this step on the raw data, so even before epoching. When creating epochs, any stretches of data annotated with a label that starts with BAD_ will be ignored by default (the function annotates muscle movements with BAD_muscle).

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.