Comparison with the BeMoBIL pipeline#
The BeMoBIL pipeline (Klug et al., 2022) is a widely-used MATLAB toolbox for automated MoBI data analysis. BeMoBIL-MNE is its Python/MNE counterpart, designed to produce equivalent results while integrating with the broader scientific Python ecosystem.
This page describes what the two pipelines share, where they differ and why, and shows a side-by-side minimal example.
Overview#
MATLAB BeMoBIL pipeline |
BeMoBIL-MNE |
|
|---|---|---|
Language |
MATLAB |
Python |
EEG framework |
EEGLAB |
MNE-Python |
ICA |
AMICA (native MATLAB) |
AMICA via |
IC classification |
ICLabel (EEGLAB plugin) |
|
Line-noise removal |
ZapLine-Plus (auto-detect) |
ZapLine-Plus via |
Bad channel detection |
|
PyPREP + FASTER + optional line-noise / flatline criteria |
ASR |
Not used (AMICA autoreject instead) |
Optional ( |
BIDS support |
Manual / separate toolbox |
Built-in via |
Provenance |
|
JSON descriptor in |
Output format |
|
|
Intentional differences#
- Bad channel detection method
The original MATLAB implementation uses
clean_rawdata(a variant of the ASR correlation algorithm) withchancorr_crit=0.8andchan_max_broken_time=0.3. BeMoBIL-MNE uses a combination of PyPREP and FASTER, which are well-validated standalone Python implementations. Both approaches flag channels that decorrelate from their neighbours; the underlying principle is the same.- ASR
The original MATLAB implementation does not apply ASR - it relies on AMICA’s built-in autoreject (
AMICA_autoreject=1, sigma threshold 3). BeMoBIL-MNE also disables ASR by default (asr=False) for the same reason: AMICA’s internal rejection is sufficient for clean ICA decompositions. ASR is available as an opt-in (asr=Trueorasr={"cutoff": 20}) for pipelines that do not use AMICA.- Final high-pass filter
The original MATLAB implementation applies a 0.2 Hz high-pass after ICA (
final_filter_lower_edge=0.2). BeMoBIL-MNE removed this step (final_filter_bandswas dropped) because the main bandpass filter (filter_bands=(0.1, 100.0)by default) already removes sub-0.1 Hz drift, and the final filter adds an implicit dependency on analysis choices that belong downstream. Add it back explicitly if needed:raw_clean.filter(l_freq=0.2, h_freq=None)
- Output format
The original MATLAB implementation saves
.set/.fdt(EEGLAB) files. BeMoBIL-MNE saves.fif.gz(MNE native), which supports lossless compression and carries full metadata including the provenance descriptor.- Bilateral dipole fitting (not yet available)
The original MATLAB implementation supports
number_of_dipoles=2, fitting a symmetric bilateral dipole pair per IC. This is not currently implemented in BeMoBIL-MNE:fit_dipoles_on_ica()’sn_dipolesparameter only supports1(a single equivalent current dipole viamne.fit_dipole()); passingn_dipoles=2raisesNotImplementedErrorrather than silently returning a single-dipole result. MNE has no built-in constrained two-dipole fit, so bilateral fitting would require a custom optimization - unlike the other differences on this page, this is a genuine feature gap rather than a deliberate design choice, and is open for future contribution.
Minimal example#
The following script replicates the core BeMoBIL EEG preprocessing steps using BeMoBIL-MNE.
from bemobil_mne.io import XDFLoader
from bemobil_mne.preproc import EEGPreprocessor
# --- Equivalent to bemobil_process_all_EEG_preprocessing ---
loader = XDFLoader(
montage="standard_1020", # channel_locations_filename
target_sfreq=250.0, # resample_freq = 250
old_reference="FCz", # ref_channel = 'FCz'
)
preprocessor = EEGPreprocessor(
loader=loader,
line_noise_freq="europe", # 50 Hz; use "usa" for 60 Hz
zapline_method="adaptive", # zaplineConfig.noisefreqs = []
filter_bands=(0.1, 100.0), # broad bandpass (BeMoBIL keeps full band)
filter_bands_ica=(1.75, None), # filter_lowCutoffFreqAMICA = 1.75
downsample_ica=250.0, # resample_freq = 250
ica_method="amica", # AMICA
thresh=-1, # iclabel_threshold = -1
# include_labels default = all except eye blink (iclabel_classes = [1 2 4 5 6 7])
fit_dipoles=True, # dipole fitting on
rv_thresh=None, # residualVariance_threshold = 100 (no threshold)
remove_outside_head=False, # do_remove_outside_head = 'off'
)
raw_clean, report, metadata = preprocessor.run(
"sub-01_task-walk_run-01.xdf",
fname_out="sub-01_preprocessed_and_ICA.fif.gz",
overwrite=True,
)
# Access pipeline outputs
ica = metadata["ica"]
ic_labels = metadata["ic_labels"]
dipoles = metadata["dipoles"]
bad_ch_dict = metadata["bad_ch_dict"]
Reference#
Klug, M., Jeung, S., Wunderlich, A., Gehrke, L., Protzak, J., Djebbara, Z., Argubi-Wollesen, A., Wollesen, B., & Gramann, K. (2022). The BeMoBIL Pipeline for automated analyses of multimodal mobile brain and body imaging data. bioRxiv. https://doi.org/10.1101/2022.09.29.510051