Check paradigm metadata before loading#

Use moabb.paradigms.MotorImagery.is_valid() on an existing MOABB dataset instance to check its declared paradigm and events without loading recordings. This is a paradigm-only check, not a guarantee that an evaluation can run. The constructors used below only initialize metadata; that is not a guarantee about every dataset constructor, especially custom ones.

A remote catalogue record is not a moabb.datasets.base.BaseDataset. Resolve its identity to an existing loader and verify its metadata first. Do not invent a dataset or substitute a guessed session count for missing information.

# License: BSD (3-clause)

import json

import moabb
from moabb.datasets import BNCI2014_001, AlexMI
from moabb.paradigms import MotorImagery

Require two overlapping classes explicitly#

AlexMI declares right-hand, feet and rest events, but not left-hand events. BNCI2014_001 declares both requested hand events. Neither constructor below downloads data. The check does not call get_data, data_path, used_events or paradigm.datasets (which enumerates datasets).

datasets = [AlexMI(), BNCI2014_001()]
paradigm = MotorImagery(events=["left_hand", "right_hand"], n_classes=2)
report = [
    {
        "dataset": dataset.code,
        "moabb_version": moabb.__version__,
        "paradigm_compatible": paradigm.is_valid(dataset),
        "declared_sessions": dataset.n_sessions,
        "evaluation_compatible": None,
    }
    for dataset in datasets
]
print(json.dumps(report, indent=2))
[
  {
    "dataset": "AlexandreMotorImagery",
    "moabb_version": "1.8.0",
    "paradigm_compatible": false,
    "declared_sessions": 1,
    "evaluation_compatible": null
  },
  {
    "dataset": "BNCI2014-001",
    "moabb_version": "1.8.0",
    "paradigm_compatible": true,
    "declared_sessions": 2,
    "evaluation_compatible": null
  }
]

Preserve the native n_classes semantics#

With n_classes=None (the default), naming events does NOT require two overlapping classes. Thus this predicate accepts AlexMI. It still rejects a non-imagery dataset. Use n_classes=2 when two overlapping classes are your intent; use moabb.paradigms.LeftRightImagery for the fixed hand pair. Do not call used_events as a preflight: it can update n_classes.

unspecified_classes = MotorImagery(events=["left_hand", "right_hand"])
print(unspecified_classes.is_valid(datasets[0]))  # True
print(paradigm.is_valid(datasets[0]))  # False
True
False

Evaluation compatibility stays unknown#

evaluation_compatible above is JSON null, not false. Evaluation predicates are instance methods. Constructing an evaluation is NOT a pure preflight: it creates Results storage and can remove incompatible entries from the supplied dataset list. Do not construct an uninitialized evaluation or call an instance method with a dummy receiver to avoid those effects.

Cross-session evaluation requires multiple sessions; AlexMI declares one, while BNCI2014_001 declares two. These are loader declarations, not evidence that a particular subject or selected session subset has sufficient data. We report the count without reimplementing evaluation predicates. Subject counts, folds, actual trials, channels, pipeline compatibility and runtime feasibility remain unchecked. A true paradigm result is not a runnable benchmark, a verified licence, or approval for data use.

A synthetic discovery record illustrates missingness only. It is deliberately NOT passed to is_valid or converted into a MOABB dataset. Its unknown sessions remain null; missing metadata is not an incompatibility verdict.

remote_record = {"id": "synthetic-unresolved-record", "n_sessions": None}
print(json.dumps(remote_record))
{"id": "synthetic-unresolved-record", "n_sessions": null}

References and provenance#

See the linked API pages above and moabb.evaluations.CrossSessionEvaluation for evaluation usage. For reproducibility, record moabb.__version__ plus the source revision for a development installation. This recipe’s metadata and predicate semantics were checked against MOABB source at 3888687e0. Version labels alone do not identify a particular development checkout.

Total running time of the script: (0 minutes 0.001 seconds)

Gallery generated by Sphinx-Gallery