What’s new#

  • “Enhancements” for new features

  • “Bugs” for bug fixes

  • “API changes” for backward-incompatible changes

Version 1.5 (Source - GitHub)#

Enhancements#

  • Add 9 new dataset adapters (8 SSVEP and 1 ERP) covering 357+ subjects: moabb.datasets.Liu2020BETA (70 subjects, 40-class JFPM), moabb.datasets.Liu2022EldBETA (100 elderly subjects, 9-class, BIDS/GDF format), moabb.datasets.Kim2025BetaRange (40 subjects, 40-class beta-range), moabb.datasets.Dong2023 (59 subjects, 40-class), moabb.datasets.Lee2021Mobile_SSVEP and moabb.datasets.Lee2021Mobile_ERP (24 subjects, mobile BCI), moabb.datasets.Chen2017SingleFlicker (12 subjects, spatial SSVEP), moabb.datasets.Wang2021Combined (8 subjects, combined SSVEP), and moabb.datasets.Han2024Fatigue (24 subjects, fatigue study with low/high frequency paradigms). Add shared utilities build_raw_from_epochs, TSINGHUA_64CH_NAMES, and FIGSHARE_DL_URL to moabb.datasets.utils (by Bruno Aristimunha)

  • Add 17 new motor imagery dataset adapters covering 345+ subjects: moabb.datasets.Tavakolan2017, moabb.datasets.Zhang2017, moabb.datasets.Forenzo2023, moabb.datasets.Zhou2020, moabb.datasets.Jeong2020, moabb.datasets.Kaya2018, moabb.datasets.Kumar2024, moabb.datasets.Rozado2015, moabb.datasets.Brandl2020, moabb.datasets.Ma2020, moabb.datasets.Wairagkar2018, moabb.datasets.Wu2020, moabb.datasets.Yang2025, moabb.datasets.Chang2025, moabb.datasets.HefmiIch2025, moabb.datasets.TrianaGuzman2024, moabb.datasets.Yi2025, and moabb.datasets.Zuo2025 (by Bruno Aristimunha)

  • Add moabb.datasets.GuttmannFlury2025_MI, moabb.datasets.GuttmannFlury2025_ME, moabb.datasets.GuttmannFlury2025_SSVEP, and moabb.datasets.GuttmannFlury2025_P300 multi-paradigm dataset adapters with Zenodo re-hosted data (by Bruno Aristimunha)

  • Add moabb.datasets.Liu2025 visual imagery dataset adapter (62 subjects) with Zenodo re-hosted data, and fix moabb.datasets.Zhou2020 download path (by Bruno Aristimunha)

  • Add moabb.datasets.Gao2026 visual imagery dataset adapter (25 subjects) (by Bruno Aristimunha)

  • Add 20 moabb.datasets.Mainsah2025 (BigP3BCI) P300 dataset adapters (studies A-S2, ~305 subjects from PhysioNet) (by Bruno Aristimunha)

  • Add 7 new P300/ERP dataset adapters: moabb.datasets.Simoes2020 (15 ASD subjects, Zenodo re-hosted from Kaggle), moabb.datasets.Speier2017 (13 subjects, RSVP), moabb.datasets.Chailloux2020 (15 subjects), moabb.datasets.Guger2009 (4 subjects), moabb.datasets.McCann2015 (10 subjects, auditory), moabb.datasets.LeBlanc2024_A and moabb.datasets.LeBlanc2024_B (20 subjects each, hybrid paradigm) (by Bruno Aristimunha)

  • Add get_trial_info() and suggest_interval() methods to help users choose an optimal epoch interval for variable-length trials, and preserve per-trial triallength metadata through BIDS conversion via annotation extras (#816)

  • Redesign dataset API pages with a structured snapshot card, visual summary blocks, HED-tag visualization, benchmark highlights, citation/public API cards, and responsive mobile improvements (#1000 by Bruno Aristimunha)

  • Add GA4 pageview metrics and popularity ranking to dataset documentation cards, with inline sparkline charts showing 90-day traffic trends (by Bruno Aristimunha)

  • Refine dataset documentation cards by removing PapersWithCode links from summary tables, folding page-view metrics into the Citation & Impact card, and adding an expandable Overview teaser with a direct link to the Overview tab (#1025 by Bruno Aristimunha)

  • Polish API reference page with color-coded concept highlights, section breaks, table styling, and scoped CSS to avoid affecting other pages (by Bruno Aristimunha)

  • Implementation of Pseudo-Online framework (#641 by Igor Carrara and Bruno Aristimunha)

  • Introduce a new logo for the MOABB library (#858 by Pierre Guetschel and community)

  • Better verbosity control for initialization of the library (#850 by Bruno Aristimunha)

  • Enhanced BNCI datasets with comprehensive participant demographics documentation (by Bruno Aristimunha)

  • Added _participant_demographics class attribute to BNCI2014-002, BNCI2014-009, BNCI2015-001, and BNCI2015-004 for programmatic access to demographics (by Bruno Aristimunha)

  • Improved BIDS conversion with guaranteed montage preservation for all BNCI datasets (by Bruno Aristimunha)

  • Dataset-specific metadata extraction for BNCI2014-001, BNCI2014-004, and BNCI2014-008 with age, gender, and clinical information (by Bruno Aristimunha)

  • Improved error messages for dataset compatibility checks in evaluations - now provides specific reasons when datasets are incompatible (e.g., “dataset has only 1 session(s), but CrossSessionEvaluation requires at least 2 sessions”) by Bruno Aristimunha

  • Ability to join rows from the tables of MOABB predictive performance scores and detailed CodeCarbon compute profiling metrics by the column codecarbon_task_name in MOABB results and the column task_name in CodeCarbon results (#866 by Ethan Davis).

  • Adding two c-VEP datasets: moabb.datasets.MartinezCagigal2023Checker and moabb.datasets.MartinezCagigal2023Pary by Victor Martinez-Cagigal

  • Allow custom paradigms to have multiple scores for evaluations (#948 by Ethan Davis)

  • Ability to parameterize the scoring rule of paradigms (#948 by Ethan Davis)

  • Extend scoring configuration to accept lists of metric callables, scorer objects, and tuple kwargs (e.g., needs_proba/needs_threshold) for multi-metric evaluations (#948 by Ethan Davis and Bruno Aristimunha)

  • Implement moabb.evaluations.WithinSubjectSplitter for k-fold cross-validation within each subject across all sessions (by Bruno Aristimunha)

  • Add cv_class and cv_kwargs parameters to all evaluation classes (WithinSessionEvaluation, CrossSessionEvaluation, CrossSubjectEvaluation) for custom cross-validation strategies (#963 by Bruno Aristimunha)

  • Implement moabb.evaluations.splitters.LearningCurveSplitter as a dedicated sklearn-compatible cross-validator for learning curves, enabling learning curve analysis with any evaluation type (#963 by Bruno Aristimunha)

  • Flattened parallel evaluation: CV folds are now evaluated in parallel within each dataset via _process_parallel(), replacing per-fold sequential evaluation while preserving per-dataset scheduling (by Bruno Aristimunha)

  • Auto-generate dataset documentation admonitions (Participants, Equipment, Preprocessing, Data Access, Experimental Protocol) from class-level METADATA when missing, while preserving manually written sections (#960 by Bruno Aristimunha)

  • Add a “Report an Issue on GitHub” feedback section to all dataset docstrings so users can easily report dataset problems (#982 by Bruno Aristimunha)

  • Add additional_metadata parameter to paradigm.get_data() to fetch additional metadata columns from BIDS events.tsv files. Supports "all" to load all columns or a list of specific column names (#744 by Matthias Dold)

  • Add get_additional_metadata() method to moabb.datasets.base.BaseDataset allowing datasets to provide additional metadata for epochs. Implemented for BIDS datasets in moabb.datasets.base.BaseBIDSDataset (#744 by Matthias Dold)

  • Add automatic HED 8.4.0 (Hierarchical Event Descriptors) annotations to BIDS export with 83 validated paradigm-specific tags covering all MOABB datasets, HEDVersion in dataset_description.json, events.json sidecar patching, per-dataset override via ExperimentMetadata.hed_tags, and Label/ fallback for unmapped events (#974 by Bruno Aristimunha)

  • Add tutorial on time-resolved decoding with mne.decoding.SlidingEstimator, showing how to evaluate per-time-point AUC across subjects as an alternative to pseudo-online evaluation (#718 by Bruno Aristimunha)

  • Add advanced tutorial on Riemannian Artifact Rejection (Riemannian Potato and Potato Field) as a pre-processing step using pipeline surgery (by Davoud Hajhassani and Bruno Aristimunha)

  • Simplify the Riemannian Artifact Rejection tutorial by using pyRiemann’s enhanced PotatoField API (per-potato metrics and configurable p-value combination), and refresh the 2D potato visualization to better match the pyRiemann reference (#1011 by Bruno Aristimunha)

  • Add pipeline surgery methods (find_steps, insert_step, remove_step) to moabb.datasets.preprocessing.FixedPipeline for easier pipeline manipulation (by Davoud Hajhassani and Bruno Aristimunha)

  • Add license metadata to all datasets with known licenses, covering BNCI, BrainInvaders, ErpCore2021, Castillos, MartinezCagigal2023, Beetl2021, Kojima2024, Dreyer2023, and many others (#989 by Bruno Aristimunha)

  • Add parametrized test test_all_datasets_have_license to ensure all datasets declare a license in their documentation metadata (#989 by Bruno Aristimunha)

  • Add and correct license and repository fields in DocumentationMetadata across all datasets against upstream sources; standardize all license strings to SPDX identifiers; correct DOIs for BNCI2014_002 and MAMEM1/2/3 datasets (by Katelyn Begany)

  • Validate and correct metadata across 45 datasets against original publications, fixing ~920 fields including country codes, preprocessing conflation, reference electrodes, and fabricated auxiliary channels (#1001 by Bruno Aristimunha)

  • Add convert_to_bids() method for exporting raw EEG datasets to clean BIDS-compliant directory structures without processing-pipeline hash in filenames (by Bruno Aristimunha)

  • Expose subjects and sessions parameters on all dataset constructors to allow filtering at instantiation time (e.g., PhysionetMI(subjects=[1, 2, 3])). Add all_subjects property and sessions parameter to get_data() (by Bruno Aristimunha)

  • Enhance Tutorial 4 (“Creating a dataset class”) with a new section demonstrating BaseBIDSDataset and LocalBIDSDataset as the recommended approach for adding BIDS-format datasets to MOABB (#1007 by Bruno Aristimunha)

  • Add Copy and CSV export buttons to benchmark results tables on the results webpage, enabling users to copy or download table data directly (#1002 by Bruno Aristimunha)

  • Add license chip with official Creative Commons SVG icons to dataset documentation pages, showing license type with inline icons and links to license deeds (#1015 by Bruno Aristimunha)

  • Add adjusted chance levels, distribution plot, and restyle analysis plots with colorblind-friendly palette (#1019 by Bruno Aristimunha)

  • Enrich documentation metadata for Hinss2021, ErpCore2021 (all 7 variants), Schirrmeister2017, MartinezCagigal2023 (Checker + Pary), and Rodrigues2017 with investigators, institution, country, ethics approval, funding, contact info, acknowledgements, and citation instructions extracted from published papers. All 83 datasets now have investigators populated (#1017 by Bruno Aristimunha)

  • Add return_all_modalities keyword-only parameter to moabb.datasets.base.BaseDataset and 30+ multi-modal dataset subclasses, allowing users to retain non-EEG channels (EOG, EMG, ECG, misc) when loading data. Accepts True (all non-stim channels), or a dict of mne.pick_types() keyword arguments for fine-grained control (e.g. dict(eeg=True, eog=True)). The setting is respected through the preprocessing pipeline (moabb.datasets.preprocessing.RawToEpochs) and BIDS conversion so non-EEG channels survive epoching and export. Add shared pick_channels_for_modalities() helper to moabb.datasets.utils (#966, #1030 by Bruno Aristimunha)

  • Add new moabb.analysis.neural_signatures module with interactive Plotly-based neural signature visualizations for all five BCI paradigms: Motor Imagery ERD/ERS topomaps, P300/ERP waveforms, SSVEP power spectra and SNR, c-VEP evoked responses with PSD, and Resting State band power distributions. Public API: generate_neural_signature(), neural_signature_html(), get_plotly_template(), get_plotly_colorscale(). Produces standalone HTML reports with MOABB branding, interactive SVG head diagrams, electrode selection, and per-subject views (#1039 by Bruno Aristimunha)

  • Add generate_figures parameter to convert_to_bids() for optional neural signature generation into {bids_root}/derivatives/neural_signatures/ during BIDS export (#1039 by Bruno Aristimunha)

  • Conditionally export generate_neural_signature() and neural_signature_html() from moabb.analysis when plotly is installed (#1039 by Bruno Aristimunha)

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).

  • Temporarily track pyriemann from GitHub source (master) to use new PotatoField capabilities introduced in pyRiemann PR #423 (#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.Huebner2022 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 moabb.datasets.bids_interface.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 moabb.datasets.bids_interface.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 moabb.datasets.preprocessing.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#

  • Add “Open in Colab” buttons for gallery examples (#853 by Bruno Aristimunha)

  • Refresh docs homepage design and citation visibility (#853 by Bruno Aristimunha)

  • Add moabb.datasets.preprocessing.FixedPipeline and moabb.datasets.preprocessing.make_fixed_pipeline() to avoid scikit-learn unfitted pipeline warnings (#850 by Bruno Aristimunha)

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