What’s new#

  • “Enhancements” for new features

  • “Bugs” for bug fixes

  • “API changes” for backward-incompatible changes

Version 1.6 (Source - GitHub)#

Enhancements#

  • None yet.

API changes#

  • None yet.

Requirements#

  • None yet.

Bugs#

  • None yet.

Code health#

  • None yet.

Version 1.5.0 (Stable - PyPi)#

Enhancements#

API changes#

  • Removed SinglePass and FilterBank intermediate classes from motor imagery and P300 paradigms. FilterBankLeftRightImagery now inherits from LeftRightImagery, FilterBankMotorImagery inherits from MotorImagery, and P300 inherits directly from BaseP300. RestingStateToP300Adapter now inherits from BaseP300. Docstring inheritance is handled via NumpyDocstringInheritanceInitMeta (#467 by Bruno Aristimunha).

  • Allow CodeCarbon script level configurations when instantiating a moabb.evaluations.base.BaseEvaluation child class (#866 by Ethan Davis).

  • When CodeCarbon is installed, MOABB HDF5 results have an additional column codecarbon_task_name. If CodeCarbon is configured to save to file, its own tabular results have a column task_name. These columns are unique UUID4s. Related rows can be joined to see detailed costs and benefits of predictive performance and computing profiling metrics (#866 by Ethan Davis).

  • Isolated model fitting, duration tracking, and CodeCarbon compute profiling tracking. New and consistent ordering of duration and CodeCarbon tracking across all evaluations: (Higher priority, closest to model fitting) required duration tracking, (lower priority, second closest to model fitting) optional CodeCarbon tracking (#866 by Ethan Davis).

  • Replaced unreliable wall clock duration tracking (Python’s time.time()) in favor of performance counter duration tracking (Python’s time.perf_counter()) (#866 by Ethan Davis).

  • Enable choice of online or offline CodeCarbon through the parameterization of codecarbon_config when instantiating a moabb.evaluations.base.BaseEvaluation child class (#956 by Ethan Davis)

  • Renamed stimulus channel from stim to STI in BNCI motor imagery and error-related potential datasets for clarity and BIDS compliance (by Bruno Aristimunha).

  • Added four new BNCI P300/ERP dataset classes: moabb.datasets.BNCI2015_009 (AMUSE), moabb.datasets.BNCI2015_010 (RSVP), moabb.datasets.BNCI2015_012 (PASS2D), and moabb.datasets.BNCI2015_013 (ErrP) (by Bruno Aristimunha).

  • Removed data_size and n_perms parameters from moabb.evaluations.WithinSessionEvaluation. Use cv_class=LearningCurveSplitter with cv_kwargs=dict(data_size=..., n_perms=...) instead (#963 by Bruno Aristimunha)

  • Learning curve results now automatically include “data_size” and “permutation” columns when using LearningCurveSplitter (#963 by Bruno Aristimunha)

  • Replace wildcard imports with explicit class imports in moabb.paradigms (#1004 by Bruno Aristimunha)

Requirements#

  • Allows CodeCarbon environment variables or a configuration file to be defined in the home directory or the current working directory (#866 by Ethan Davis).

  • Added filelock as a core dependency to fix missing import errors in utils (#959 by Mateusz Naklicki).

  • Switch pyriemann dependency from GitHub source back to PyPI (>=0.7). The Riemannian Artifact Rejection tutorial still requires pyriemann from source for PotatoField features and is no longer auto-executed during doc builds (#1011 by Bruno Aristimunha)

  • Add type hints to moabb.evaluations.base.BaseEvaluation and all concrete evaluation classes (#732 by Sarthak Tayal)

  • Add plotly>=5.18.0 as optional interactive dependency (pip install moabb[interactive]), included in moabb[all] (#1039 by Bruno Aristimunha)

Bugs#

  • Fix trial acceptance condition in moabb.datasets.Stieger2021 that allowed epochs to extend beyond actual motor imagery duration into adjacent trials’ resting periods (#816)

  • Fix DOI escaping in “See DOI” fallback link on dataset citation cards (#1000 by Bruno Aristimunha)

  • Prefer paper DOI over data DOI in dataset citation card when both are available (#1000 by Bruno Aristimunha)

  • Fix timeline SVG card artifact caused by link styling on dataset pages (by Bruno Aristimunha)

  • Fix dataset documentation teaser rendering by skipping raw reStructuredText directives in previews, hiding empty page-view rows when analytics are unavailable, and clearing dataset summary reST warnings (#1025 by Bruno Aristimunha)

  • Fix class-balance visualization counts by normalizing metadata/event class labels (e.g., NonTarget vs non-target) and use the first valid dataset subject in generated quickstart snippets instead of hardcoded subjects=[1] (#1000 by Bruno Aristimunha)

  • Fix missing P300 from the list of valid paradigms in the moabb.benchmark() docstring (by Bruno Aristimunha)

  • Fix critical trigger alignment bug in moabb.datasets.Liu2024 where create_event_array() selected the first 40 of 120 STI triggers (mixing instruction, MI, and break onsets) instead of filtering for only the MI onset triggers (value=2). Also fix swapped left/right hand label mapping in encoding() and correct epoch interval from (2, 6) to (0, 4) to match MI onset triggers (by Bruno Aristimunha)

  • Fixed incorrect DOIs in Dreyer2023, RomaniBF2025ERP, BNCI2015_003, BNCI2015_004, and BNCI2015_012 datasets (#977 by Bruno Aristimunha)

  • Added missing metadata DOIs for AlexMI, PhysionetMI, GrosseWentrup2009, Shin2017A, Shin2017B, BNCI2014_004, and BNCI2003_004 datasets (#977 by Bruno Aristimunha)

  • Fixed montage not being set before BIDS cache conversion in BNCI datasets (by Bruno Aristimunha)

  • Fixed measurement date setting for BNCI datasets to use specific collection years from papers (by Bruno Aristimunha)

  • Ensured proper subject ID assignment for BIDS compliance across all BNCI datasets (by Bruno Aristimunha)

  • Correct moabb.pipelines.classification.SSVEP_CCA, moabb.pipelines.classification.SSVEP_TRCA and moabb.pipelines.classification.SSVEP_MsetCCA behavior (#625 by Sylvain Chevallier)

  • Fix scikit-learn LogisticRegression elasticnet penalty parameter deprecation by re-adding penalty=’elasticnet’ for ElasticNet configurations with 0 < l1_ratio < 1 (#869 by Bruno Aristimunha)

  • Fixing option to pickle model (#870 by Ethan Davis)

  • Normalize Zenodo download paths and add a custom user-agent to improve download robustness (#946 by Bruno Aristimunha)

  • Use the BNCI mirror host to avoid download timeouts (#946 by Bruno Aristimunha)

  • Repair incomplete or corrupted moabb.datasets.Zhou2016 subject downloads by validating extracted EEG/events files and re-downloading under a subject-level lock, preventing empty-session failures during parallel docs/CI runs (by Bruno Aristimunha)

  • Prevent Python mutable default argument when defining CodeCarbon configurations (#956 by Ethan Davis)

  • Fix copytree FileExistsError in BrainInvaders2013a download by adding dirs_exist_ok=True (by Bruno Aristimunha)

  • Ensure optional additional scoring columns in evaluation results (#957 by Ethan Davis)

  • Fix pandas ArrowStringArray shuffle warning by converting .unique() results to numpy arrays in splitters, avoiding issues with newer pandas versions (#963 by Bruno Aristimunha)

  • Fix crash in moabb.datasets.Huebner2017 when regex match on vhdr filenames returns None (#1036 by Sarthak Tayal)

  • Replace production assert statements with proper ValueError / TypeError exceptions across analysis, pipelines, paradigms, and datasets modules (#1036 by Sarthak Tayal)

  • Fix silent pipeline name collision in moabb.pipelines.utils.create_pipeline_from_config by raising ValueError on duplicate names (#1036 by Sarthak Tayal)

  • Replace bare print() calls with proper logging in moabb.datasets.MartinezCagigal2023Checker (#1036 by Sarthak Tayal)

  • LearningCurveSplitter now skips training splits that collapse to a single class (e.g., with very small data_size) and emits a RuntimeWarning instead of producing NaN results (#963 by Bruno Aristimunha)

  • Fix double µV-to-V conversion in BNCI2003-004 and BNCI2015-006: data loaded in microvolts was labeled as volts without unit conversion, causing a second scaling during EDF export via mne_bids (by Bruno Aristimunha)

  • Fix Beetl2021_A and Beetl2021_B 403 Forbidden errors by skipping Figshare API calls when data already exists locally, and fix double-nested zip extraction directory structure (#969 by Bruno Aristimunha)

  • Fix wrong channel names in Riemannian Artifact Rejection tutorial that caused pick() to fail on BNCI2014-009 (by Bruno Aristimunha)

  • Fix moabb.datasets.RomaniBF2025ERP to follow MOABB nomenclature pattern by using dynamic folder name MNE-{code}-data instead of hardcoded folder name. Automatically migrates legacy folder BrainForm-BIDS-eeg-dataset to new nomenclature for backward compatibility (by Bruno Aristimunha)

  • Move BIDS cache lock file from the BIDS subject folder to the code/ folder for BIDS validator compliance. Lock files are now written per-session as code/sub-{subject}_ses-{session}_desc-{hash}_lockfile.json. Backward compatibility is preserved for caches created with the old location (#986 by Pierre Guetschel and Bruno Aristimunha)

  • Fixed erase() in BIDSInterfaceBase to handle multi-session datasets correctly by using per-session rm() calls instead of a single subject-level call, which previously caused a RuntimeError when looking up scans.tsv across multiple sessions (#986 by Pierre Guetschel and Bruno Aristimunha)

  • Fix MOABB_RESULTS default path to respect MNE_DATA configuration instead of hardcoding ~/mne_data, and fix docs CI cache to use workspace-relative MNE_DATA path and cache ~/.mne config directory (by Bruno Aristimunha)

  • Fix moabb.datasets.RomaniBF2025ERP get_data() failing with description merge error when adding stim channel, causing sessions to be silently dropped (#991 by Bruno Aristimunha)

  • Fix docs CI cache: set MNE_DATA env var and persist ~/.mne config directory so dataset paths survive cache restore (by Bruno Aristimunha)

  • Fix CI dataset cache reuse across commits/PR updates by using stable cache keys and default-branch cache saves for docs/tests workflows, avoiding repeated dataset downloads (by Bruno Aristimunha)

  • Fix moabb.datasets.Liu2024 download failure by switching Figshare URLs from figshare.com/ndownloader to ndownloader.figshare.com and adding BadZipFile recovery for corrupted cached downloads (#992 by Bruno Aristimunha)

  • Remove redundant autoattribute METADATA from MartinezCagigal2023 Checker and Pary docstrings (#1022 by Bruno Aristimunha)

  • Fix TRCA Riemannian mean convergence failure by regularizing ill-conditioned cross-covariance matrices in moabb.pipelines.classification.SSVEP_TRCA. Eigenvalue clamping bounds the condition number, eliminating Convergence not reached and invalid value encountered in log warnings (by Bruno Aristimunha)

  • Fix SSVEP CCA-family estimator consistency and eCCA formulation: moabb.pipelines.classification.SSVEP_CCA, moabb.pipelines.classification.SSVEP_MsetCCA, moabb.pipelines.classification.SSVEP_itCCA, and moabb.pipelines.classification.SSVEP_eCCA now return predictions in the same label space as classes_ and align predict_proba columns with classes_ order. moabb.pipelines.classification.SSVEP_CCA and moabb.pipelines.classification.SSVEP_eCCA now infer frequencies robustly from epochs metadata (with freq_map override), and moabb.pipelines.classification.SSVEP_eCCA now uses the corrected 4-feature filter assignments with updated reference/citation alignment (by Bruno Aristimunha)

  • Add documentation note to moabb.datasets.PhysionetMI that subject 88 was recorded at 128 Hz instead of 160 Hz, which causes errors when loaded alongside other subjects (#538 by Bruno Aristimunha)

  • Fix BIDS validator compliance: monkey-patch mne_bids to generate electrodes.json sidecar with SpatialReference key required by BIDS validator v2.4.0 when space-CapTrak entity is present (by Bruno Aristimunha)

  • Fix HardwareFilters BIDS sidecar format: wrap flat filter dicts in the required nested structure {"FilterName": {"key": "value"}} instead of writing a flat dict, and wrap string filters similarly (by Bruno Aristimunha)

  • Fix doi field in dataset_description.json to use BIDS-required doi:<value> format by adding the doi: prefix when missing (by Bruno Aristimunha)

  • Fix write_raw_bids overwrite error for multi-session datasets by detecting when a subject already exists in participants.tsv and setting overwrite=True for subsequent sessions (by Bruno Aristimunha)

  • Fix moabb.datasets.Ofner2017 generic channel names (eeg-0 .. eeg-60) in subject 1 execution GDF files by mapping them to correct 10-20 montage labels (by Bruno Aristimunha)

  • Fix moabb.datasets.Wang2021Combined segfault during BIDS conversion by switching from mne.io.read_raw_ant to mne.io.read_raw_cnt, avoiding a crash in the ANT reader’s C library (libEep) on macOS (by Bruno Aristimunha)

  • Fix brittle channel picking in BIDSInterfaceRawEDF that enumerated every MNE channel type keyword; replaced with stim-exclusion approach (#1030 by Bruno Aristimunha)

  • Fix set_montage crash in moabb.datasets.Thielen2015 when return_all_modalities=True by retyping ANA/EXG channels to misc (#1030 by Bruno Aristimunha)

  • Fix duplicate stim channels and dead CPz reference channel in moabb.datasets.Liu2024 when return_all_modalities=True (#1030 by Bruno Aristimunha)

  • Fix RawToEpochs silently stripping all non-EEG channels regardless of return_all_modalities setting (#1030 by Bruno Aristimunha)

  • Fix HED annotation semantics for Motor Imagery events per expert review: decompose each MI event into separate (Sensory-event, Experimental-stimulus, Visual-presentation) and (Agent-action, ...) top-level groups per HED Rules 2b/2e/2f, remove conflated Cue + Experimental-stimulus roles, fix SSVEP rest tag to Experiment-structure, and extract shared _MI_SENSORY constant to reduce tag duplication. Revert arrow-specific cues from paradigm-level HED defaults to generic sensory prefix, and add per-dataset hed_tags overrides for the 6 datasets that actually use arrow cues (BNCI2014-001, BNCI2014-004, Lee2019_MI, Zhou2016, Shin2017A, GrosseWentrup2009) (#1035 by Bruno Aristimunha)

Code health#

  • Generate dataset timeline SVGs at Sphinx build time instead of tracking pre-rendered files in git (by Bruno Aristimunha)

  • Fix Sphinx documentation warnings and move sliding-estimator tutorial to advanced examples (by Bruno Aristimunha)

  • Fix autosummary descriptions in API page by skipping dataset_timeline_ext in summary context (by Bruno Aristimunha)

  • Hide right sidebar and admonition icons on dataset pages for a cleaner layout using per-page meta directives (by Bruno Aristimunha)

  • Add GA4 pageview export script and CI workflow integration for automated dataset traffic metrics (by Bruno Aristimunha)

  • Resolve all 216 pytest warnings across the test suite by addressing root causes: clear Epochs annotations before concatenation, replace lambda with named function in test pipelines, re-apply montage after add_reference_channels, conditionally pass groups parameter in splitters using GroupsConsumerMixin, use os.environ in FakeDataset to avoid non-standard config warnings, and suppress intentional OptunaSearchCV experimental warnings at init (by Bruno Aristimunha)

  • Added systematic DOI validation test suite that checks format, docstring tracking, resolution, and author overlap across all datasets (#977 by Bruno Aristimunha)

  • Further reorganized BNCI datasets into year-specific modules (bnci_2003, bnci_2014, bnci_2015, bnci_2019) with shared helpers in legacy_base for clearer maintenance. The temporary legacy.py file has been removed (by Bruno Aristimunha).

  • Added new datasets moabb.datasets.BNCI2020_001, moabb.datasets.BNCI2020_002, moabb.datasets.BNCI2022_001, moabb.datasets.BNCI2025_001, and moabb.datasets.BNCI2025_002 (by Bruno Aristimunha).

  • Persist docs/test CI MNE dataset cache across runs to reduce cold-cache downloads (#946 by Bruno Aristimunha)

  • Refactor evaluation scoring into shared utility functions for future improvements (#948 by Bruno Aristimunha)

  • Centralize CV resolution in BaseEvaluation with new _resolve_cv() method for consistent cross-validation handling across all evaluation types. Add _build_result() and _build_scored_result() helpers to centralize result dict construction across WithinSession, CrossSession, and CrossSubject evaluations, replacing manual dict assembly in each (#963 by Bruno Aristimunha)

  • Remove redundant learning curve methods (get_data_size_subsets(), score_explicit(), _evaluate_learning_curve()) from WithinSessionEvaluation in favor of unified splitter-based approach (#963 by Bruno Aristimunha)

  • Generic metadata column registration: LearningCurveSplitter declares a metadata_columns class attribute, and BaseEvaluation auto-detects it via hasattr(cv_class, "metadata_columns") instead of hardcoding class checks, making it extensible to future custom splitters (#963 by Bruno Aristimunha)

  • Fix get_n_splits() delegation in WithinSessionSplitter and WithinSubjectSplitter to properly forward to the inner cv_class.get_n_splits() instead of hardcoding n_folds, giving correct split counts when using custom CV classes like LearningCurveSplitter (#963 by Bruno Aristimunha)

  • Remove dead _fit_and_score() function and unused paradigm/mne_labels parameters from _evaluate_fold() in evaluations/base.py (by Bruno Aristimunha)

  • Memory optimization in _process_parallel(): pass X, y, metadata as top-level positional args to joblib.delayed() so the loky backend can auto-mmap large numpy arrays, avoiding N full copies for N parallel tasks (by Bruno Aristimunha)

  • Remove duplicate get_inner_splitter_metadata() from WithinSessionSplitter, WithinSubjectSplitter, and CrossSubjectSplitter. All splitters now store a _current_splitter reference, and BaseEvaluation._build_scored_result() reads metadata generically from it (#963 by Bruno Aristimunha)

  • Extract _fit_cv(), _maybe_save_model_cv(), and _attach_emissions() into BaseEvaluation, removing duplicated model-fitting, model-saving, and carbon-tracking boilerplate from WithinSessionEvaluation, CrossSessionEvaluation, and CrossSubjectEvaluation (#963 by Bruno Aristimunha)

  • Extract _load_data() helper into BaseEvaluation to centralize data loading logic (epoch requirement checking and paradigm.get_data() call) that was duplicated across all three evaluation classes (#963 by Bruno Aristimunha)

  • Extract _get_nchan() helper into BaseEvaluation to replace repeated channel count extraction (X.info["nchan"] if isinstance(X, BaseEpochs) else X.shape[1]) in all evaluation classes (#963 by Bruno Aristimunha)

  • Move _pipeline_requires_epochs() from evaluations.py to utils.py for shared access by BaseEvaluation._load_data() (#963 by Bruno Aristimunha)

  • Move WithinSessionSplitter creation outside the per-session loop in WithinSessionEvaluation, since splitter parameters do not change per session (#963 by Bruno Aristimunha)

  • Add a compile smoke test (moabb/tests/test_compilation.py) that validates syntax for all Python files under moabb/ using py_compile (#960 by Bruno Aristimunha)

  • Add persistent DOI resolution cache (moabb/tests/doi_cache.json) for test_doi_validation.py to avoid network requests on every test run, reducing DOI test time from ~9 minutes to <1 second. Refresh with --update-doi-cache (#996 by Bruno Aristimunha)

  • Fix UtilEvaluation test class not discovered by pytest: renamed to TestUtilEvaluation and replaced self.skipTest (unittest-only) with pytest.skip (#1005 by Bruno Aristimunha)

  • Add 282 parametrized tests in moabb/tests/test_neural_signatures.py covering all five paradigms, HTML generation, template/colorscale utilities, and edge cases for the moabb.analysis.neural_signatures module (#1039 by Bruno Aristimunha)

Version 1.4.3 (Stable - PyPi)#

Enhancements#

API changes#

  • None.

Requirements#

Bugs#

Code health#

Version 1.4.2#

Enhancements#

Bugs#

API changes#

  • None.

Version - 1.4#

Enhancements#

Bugs#

API changes#

  • None.

Version - 1.3#

Enhancements#

Bugs#

API changes#

  • Removing the deep learning module from inside moabb in favour of braindecode integration (#692 by Bruno Aristimunha )

Version - 1.2.0#

Enhancements#

Bugs#

API changes#

Version - 1.1.1#

Enhancements#

Bugs#

API changes#

  • Include optuna as soft-dependency in the benchmark function and in the base of evaluation (#630 by Igor Carrara)

Version - 1.1.0#

Enhancements#

Bugs#

API changes#

  • None

Version - 1.0.0#

Enhancements#

Bugs#

API changes#

  • None

Version - 0.5.0#

Enhancements#

Bugs#

API changes#

  • None

Version - 0.4.6#

Enhancements#

Bugs#

Version - 0.4.5#

Enhancements#

Bugs#

Version - 0.4.4#

Enhancements#

Bugs#

API changes#

  • Minimum supported Python version is now 3.7

  • MOABB now depends on scikit-learn >= 1.0

Version - 0.4.3#

Enhancements#

Bugs#

API changes#

Version - 0.4.2#

Enhancements#

  • None

Bugs#

API changes#

  • None

Version - 0.4.1#

Enhancements#

  • None

Bugs#

API changes#

  • Remove update_path on all datasets, update_path parameter in dataset.data_path() is deprecated (#207 by Sylvain Chevallier)

Version - 0.4.0#

Enhancements#

Bugs#

API changes#

  • Drop update_path from moabb.download.data_path and moabb.download.data_dl

Version 0.3.0#

Enhancements#

Bugs#

API changes#

  • None

Version 0.2.1#

Enhancements#

Bugs#

API changes#

  • None

Version 0.2.0#

Enhancements#

Bugs#

  • None

API changes#

  • None