Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/source/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ Bugs
- Fix missing electrode positions (NaN xyz) in six motor-imagery datasets so topographic maps, interpolation, and spatial methods work: :class:`moabb.datasets.Forenzo2023` and :class:`moabb.datasets.GuttmannFlury2025_MI`/``_ME`` normalize Neuroscan ALL_CAPS labels and apply ``standard_1005`` (CB1/CB2 kept as ``misc``); :class:`moabb.datasets.Dreyer2023` falls back to ``standard_1005`` when the BIDS archive ships no ``electrodes.tsv``; :class:`moabb.datasets.BNCI2003_004` maps its 26 legacy Berlin channel labels to their modern 10-5 equivalents for exact positions; :class:`moabb.datasets.BNCI2014_002` applies an approximate 3x5 grid for its unlabeled small-Laplacian channels; and :class:`moabb.datasets.Zhang2017` applies the ``GSN-HydroCel-32`` montage in EGI sensor order. Adds the shared :func:`moabb.datasets.utils.set_neuroscan_montage` helper (:gh:`1089` by `Bruno Aristimunha`_).
- Fix ``BaseEvaluation._aggregate_fold_results`` aborting the whole evaluation with ``TypeError: agg function failed [how->mean,dtype->object]`` when a single fold contributes a non-numeric ``score`` (e.g. an error fold). The numeric aggregation columns are now coerced with ``pandas.to_numeric(errors="coerce")`` before ``groupby.agg``, so a bad fold becomes ``NaN`` and is skipped instead of taking down every subject/pipeline (:gh:`1095` by `Bruno Aristimunha`_).
- Fix :class:`moabb.evaluations.splitters.WithinSessionSplitter` and :class:`moabb.evaluations.splitters.WithinSubjectSplitter` overwriting an explicit ``n_splits`` passed through ``cv_kwargs`` with the ``n_folds`` default; the caller-provided ``n_splits`` now takes precedence, so a single holdout split can be requested directly via ``cv_class=StratifiedShuffleSplit, n_splits=1``. :class:`moabb.evaluations.WithinSessionEvaluation` and :class:`moabb.evaluations.WithinSubjectEvaluation` now honour the ``n_splits`` argument instead of always running 5 folds, and :class:`moabb.evaluations.splitters.WithinSubjectSplitter` now yields reproducible per-subject folds for a fixed ``random_state`` (:gh:`1106` by `Bruno Aristimunha`_).
- Fix ``make html`` crash in ``scripts/generate_macro_table.py`` when a dataset has a missing (``NaN``) value in an optional metadata column (country, DOI, data URL, ...): the float ``NaN`` is truthy, so it slipped past the ``if not value`` guards and crashed the string formatters (``TypeError: object of type 'float' has no len()``). ``NaN`` cells are now normalized to ``""`` before formatting (:gh:`1117` by `Bhargav Kowshik`_).

Code health
~~~~~~~~~~~
- Install CPU-only PyTorch wheels in CI by setting ``UV_TORCH_BACKEND=cpu`` in the test, braindecode, and docs workflows, so runners no longer download multi-GB CUDA builds of ``torch`` (pulled transitively via the ``deeplearning`` extra / braindecode) (:gh:`1083` by `Bhargav Kowshik`_).
Expand Down
6 changes: 6 additions & 0 deletions scripts/generate_macro_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,12 @@ def _truncate(text: str, max_len: int = _TRUNCATE_LEN) -> str:

def _format_cell(value, fmt: str, row=None) -> str:
"""Format a single cell value according to its type."""
# pandas stores missing cells as float NaN, which is truthy and therefore
# slips past the ``if not value`` guards in the formatters below (country,
# _doi_link, _data_url_link, _health_tag), then crashes on str/len ops.
# Normalize it to "" once here so every formatter sees a clean empty value.
if isinstance(value, float) and pd.isna(value):
value = ""
if fmt == "link":
return _dataset_link(value)
if fmt == "paradigm_tag":
Expand Down
Loading