Skip to content

Datasets API

Dataset[T]

cobrabox.dataset.Dataset

Dataset(items: Iterable[T])

Bases: Generic[T]

Immutable, typed collection of Data objects.

Behaves like a read-only sequence: supports indexing, iteration, and len(). All filtering and combination operations return new Dataset instances.

Parameters:

Name Type Description Default
items Iterable[T]

Sequence of Data objects (list, tuple, or another Dataset).

required
Example

ds = cb.load_dataset("dummy_chain") ds[0] # first item ds.filter(groupID="A") # returns new Dataset ds.groupby("subjectID") # returns dict[str, Dataset] ds.describe() # prints summary

Source code in src/cobrabox/dataset.py
def __init__(self, items: Iterable[T]) -> None:
    self._items: tuple[T, ...] = tuple(items)

__len__

__len__() -> int
Source code in src/cobrabox/dataset.py
def __len__(self) -> int:
    return len(self._items)

__getitem__

__getitem__(index: int) -> T
__getitem__(index: slice) -> Dataset[T]
__getitem__(index: int | slice) -> T | Dataset[T]
Source code in src/cobrabox/dataset.py
def __getitem__(self, index: int | slice) -> T | Dataset[T]:
    if isinstance(index, slice):
        return Dataset(self._items[index])
    return self._items[index]

__iter__

__iter__() -> Iterator[T]
Source code in src/cobrabox/dataset.py
def __iter__(self) -> Iterator[T]:
    return iter(self._items)

__contains__

__contains__(item: object) -> bool
Source code in src/cobrabox/dataset.py
def __contains__(self, item: object) -> bool:
    return item in self._items

__add__

__add__(other: Dataset[T]) -> Dataset[T]
Source code in src/cobrabox/dataset.py
def __add__(self, other: Dataset[T]) -> Dataset[T]:
    if not isinstance(other, Dataset):
        return NotImplemented
    return Dataset(self._items + other._items)

__repr__

__repr__() -> str
Source code in src/cobrabox/dataset.py
def __repr__(self) -> str:
    return f"Dataset({len(self._items)} \u00d7 {self._item_type_name()})"

__str__

__str__() -> str
Source code in src/cobrabox/dataset.py
def __str__(self) -> str:
    n = len(self._items)
    type_name = self._item_type_name()
    lines = [f"Dataset  {n} items  [{type_name}]"]

    def _fmt(values: list) -> str:
        return ", ".join(str(v) for v in values)

    subjects = [item.subjectID for item in self._items]
    groups = [item.groupID for item in self._items]
    conditions = [item.condition for item in self._items]

    lines.append(f"  subjectIDs : {_fmt(subjects)}")
    lines.append(f"  groupIDs   : {_fmt(groups)}")
    lines.append(f"  conditions : {_fmt(conditions)}")

    # Collapse repeated shapes
    shapes = [tuple(item.data.shape) for item in self._items]
    shape_counts: dict[tuple, int] = {}
    for s in shapes:
        shape_counts[s] = shape_counts.get(s, 0) + 1
    shape_str = ", ".join(
        f"{s} \u00d7 {c}" if c > 1 else str(s) for s, c in shape_counts.items()
    )
    lines.append(f"  shapes     : {shape_str}")

    return "\n".join(lines)

describe

describe() -> None

Print a human-readable summary of this Dataset.

Source code in src/cobrabox/dataset.py
def describe(self) -> None:
    """Print a human-readable summary of this Dataset."""
    from rich.console import Console

    Console().print(self)

filter

filter(
    *,
    subjectID: str | None = None,
    groupID: str | None = None,
    condition: str | None = None,
) -> Dataset[T]

Return a new Dataset containing only items matching all given criteria.

Parameters:

Name Type Description Default
subjectID str | None

Keep items where item.subjectID == this value.

None
groupID str | None

Keep items where item.groupID == this value.

None
condition str | None

Keep items where item.condition == this value.

None

Returns:

Type Description
Dataset[T]

New Dataset with matching items. Empty Dataset if none match.

Example

ds.filter(groupID="control") ds.filter(subjectID="S01", condition="rest")

Source code in src/cobrabox/dataset.py
def filter(
    self,
    *,
    subjectID: str | None = None,
    groupID: str | None = None,
    condition: str | None = None,
) -> Dataset[T]:
    """Return a new Dataset containing only items matching all given criteria.

    Args:
        subjectID: Keep items where item.subjectID == this value.
        groupID: Keep items where item.groupID == this value.
        condition: Keep items where item.condition == this value.

    Returns:
        New Dataset with matching items. Empty Dataset if none match.

    Example:
        >>> ds.filter(groupID="control")
        >>> ds.filter(subjectID="S01", condition="rest")
    """
    result = list(self._items)
    if subjectID is not None:
        result = [d for d in result if d.subjectID == subjectID]
    if groupID is not None:
        result = [d for d in result if d.groupID == groupID]
    if condition is not None:
        result = [d for d in result if d.condition == condition]
    return Dataset(result)

groupby

groupby(
    attr: Literal["subjectID", "groupID", "condition"],
) -> dict[str, Dataset[T]]

Group items by a metadata attribute.

Parameters:

Name Type Description Default
attr Literal['subjectID', 'groupID', 'condition']

One of "subjectID", "groupID", or "condition".

required

Returns:

Type Description
dict[str, Dataset[T]]

Dict mapping attribute value (as string) to a Dataset of matching items.

dict[str, Dataset[T]]

Items with None for the attribute are grouped under the key "None".

Raises:

Type Description
ValueError

If attr is not one of the valid metadata attributes.

Example

by_group = ds.groupby("groupID") by_group["control"]

Source code in src/cobrabox/dataset.py
def groupby(self, attr: Literal["subjectID", "groupID", "condition"]) -> dict[str, Dataset[T]]:
    """Group items by a metadata attribute.

    Args:
        attr: One of "subjectID", "groupID", or "condition".

    Returns:
        Dict mapping attribute value (as string) to a Dataset of matching items.
        Items with None for the attribute are grouped under the key "None".

    Raises:
        ValueError: If attr is not one of the valid metadata attributes.

    Example:
        >>> by_group = ds.groupby("groupID")
        >>> by_group["control"]
    """
    if attr not in self._GROUPBY_ATTRS:
        raise ValueError(f"attr must be one of {sorted(self._GROUPBY_ATTRS)!r}, got {attr!r}")
    groups: dict[str, list[T]] = {}
    for item in self._items:
        key = str(getattr(item, attr))
        groups.setdefault(key, []).append(item)
    return {k: Dataset(v) for k, v in groups.items()}

load_dataset()

cobrabox.datasets.load_dataset

load_dataset(
    identifier: str,
    *,
    subset: SubsetSpec | None = None,
    accept: bool = False,
    force: bool = False,
) -> Dataset[SignalData]

Load a dataset by identifier.

Parameters:

Name Type Description Default
identifier str

Dataset name, e.g. "dummy_chain" or "swiss_eeg_short".

required
subset SubsetSpec | None

Restrict which data is downloaded and loaded. Two forms:

  • list[str]: subject / set keys to load in full, e.g. ["ID1", "ID2"]. Call :func:dataset_info to see available keys.
  • dict[str, int | list[str] | None]: per-key file-level control. Map each key to:

  • int N — first N files (in file-index order)

  • list[str] — specific filenames
  • None — all files for that key

Example::

  cb.load_dataset("swiss_eeg_long", subset={"ID01": 2})
  cb.load_dataset("swiss_eeg_long", subset={"ID01": ["ID01_1h.mat"]})
  cb.load_dataset("swiss_eeg_long", subset={"ID01": None, "ID02": 3})

None loads everything.

None
accept bool

If False (default), show a confirmation prompt whenever the resolved subset is estimated to pull more than 4 GB into memory at once, and — if files also need to be downloaded — the dataset license and estimated download size. Set to True to skip both prompts (e.g. in scripts where you have already reviewed the memory cost and accepted the license).

False
force bool

If True, delete any existing local files for the selected subset and re-download from scratch.

False

Returns:

Type Description
Dataset[SignalData]

class:~cobrabox.Dataset of :class:~cobrabox.SignalData objects.

Raises:

Type Description
ValueError

If identifier is unknown, or if subset contains keys not present in the dataset.

LargeLoadError

If accept=False and the user declines the large-load memory prompt. Pass a smaller subset, accept=True, or use :func:download_dataset instead to fetch the files without loading them into memory.

DownloadCancelled

If accept=False and the user declines the download.

Source code in src/cobrabox/datasets.py
def load_dataset(
    identifier: str, *, subset: SubsetSpec | None = None, accept: bool = False, force: bool = False
) -> Dataset[SignalData]:
    """Load a dataset by identifier.

    Args:
        identifier: Dataset name, e.g. ``"dummy_chain"`` or
            ``"swiss_eeg_short"``.
        subset: Restrict which data is downloaded and loaded.  Two forms:

            - ``list[str]``: subject / set keys to load in full, e.g.
              ``["ID1", "ID2"]``.  Call :func:`dataset_info` to see available
              keys.
            - ``dict[str, int | list[str] | None]``: per-key file-level
              control.  Map each key to:

              - ``int N``     — first *N* files (in file-index order)
              - ``list[str]`` — specific filenames
              - ``None``      — all files for that key

              Example::

                  cb.load_dataset("swiss_eeg_long", subset={"ID01": 2})
                  cb.load_dataset("swiss_eeg_long", subset={"ID01": ["ID01_1h.mat"]})
                  cb.load_dataset("swiss_eeg_long", subset={"ID01": None, "ID02": 3})

            ``None`` loads everything.
        accept: If ``False`` (default), show a confirmation prompt whenever
            the resolved subset is estimated to pull more than 4 GB into
            memory at once, and — if files also need to be downloaded — the
            dataset license and estimated download size. Set to ``True`` to
            skip both prompts (e.g. in scripts where you have already
            reviewed the memory cost and accepted the license).
        force: If ``True``, delete any existing local files for the selected
            subset and re-download from scratch.

    Returns:
        :class:`~cobrabox.Dataset` of :class:`~cobrabox.SignalData` objects.

    Raises:
        ValueError: If ``identifier`` is unknown, or if ``subset`` contains
            keys not present in the dataset.
        LargeLoadError: If ``accept=False`` and the user declines the
            large-load memory prompt. Pass a smaller ``subset``,
            ``accept=True``, or use :func:`download_dataset` instead to fetch
            the files without loading them into memory.
        DownloadCancelled: If ``accept=False`` and the user declines the download.
    """
    if identifier in {"dummy_chain", "dummy_random", "dummy_star"}:
        return load_structured_dummy(identifier)
    if identifier == "dummy_noise":
        return load_noise_dummy(identifier)
    if identifier == "realistic_swiss":
        return load_realistic_swiss(identifier)

    spec = get_remote_dataset_spec(identifier)
    if spec is not None:
        # Validate subset keys early, before triggering any downloads.
        if subset is not None:
            _validate_subset(spec, subset)
        _check_large_load(spec, subset, accept)

        dataset_dir = ensure_remote_files(spec, subset=subset, accept=accept, force=force)

        # Derive the subset to pass to the loader.
        # For the dict form: expand to a flat list of file stems so the loader
        # can filter by exact filename rather than by subject key.
        # spec.files is now populated (ensure_remote_files resolved it above).
        if isinstance(subset, dict):
            selected = _filter_files_by_dict_subset(subset, spec.files or [])
            loader_subset: Sequence[str] | None = [
                Path(f.filename).stem for f in selected if f.subset_key is not None
            ]
        else:
            loader_subset = list(subset) if subset is not None else None

        return spec.loader(dataset_dir, loader_subset)

    raise ValueError(
        f"Unknown dataset identifier: {identifier!r}. "
        f"Known identifiers: {[*sorted(_LOCAL_DATASET_INFO), *REMOTE_DATASETS]}"
    )

download_dataset()

cobrabox.datasets.download_dataset

download_dataset(
    identifier: str,
    *,
    subset: SubsetSpec | None = None,
    accept: bool = False,
    force: bool = False,
    dry_run: bool = False,
) -> Path

Download a remote dataset without loading it into memory.

Useful for pre-fetching large datasets before analysis, or for downloading to a shared location. Interrupted downloads are resumed automatically.

Parameters:

Name Type Description Default
identifier str

Remote dataset name, e.g. "chb_mit".

required
subset SubsetSpec | None

Restrict which files are downloaded. Two forms:

  • list[str]: subject / set keys to download in full, e.g. ["chb01", "chb02"]. Call :func:dataset_info to see available keys.
  • dict[str, int | list[str] | None]: per-key file-level control. Map each key to:

  • int N — first N files (in file-index order)

  • list[str] — specific filenames
  • None — all files for that key

Example::

  cb.download_dataset("swiss_eeg_long", subset={"ID01": 2})
  cb.download_dataset("swiss_eeg_long", subset={"ID01": None, "ID02": 3})

None downloads everything.

None
accept bool

Skip the confirmation prompt.

False
force bool

Delete existing local files and re-download from scratch.

False
dry_run bool

If True, print a summary of what would be downloaded and return immediately without downloading anything. Useful for checking file counts and size before committing to a large download.

False

Returns:

Type Description
Path

Path to the local dataset directory (may not exist if dry_run=True

Path

and nothing has been downloaded yet).

Raises:

Type Description
ValueError

If identifier is a local dataset (no download needed) or unknown, or if subset contains invalid keys.

DownloadCancelled

If accept=False and the user declines the download.

Source code in src/cobrabox/datasets.py
def download_dataset(
    identifier: str,
    *,
    subset: SubsetSpec | None = None,
    accept: bool = False,
    force: bool = False,
    dry_run: bool = False,
) -> Path:
    """Download a remote dataset without loading it into memory.

    Useful for pre-fetching large datasets before analysis, or for downloading
    to a shared location.  Interrupted downloads are resumed automatically.

    Args:
        identifier: Remote dataset name, e.g. ``"chb_mit"``.
        subset: Restrict which files are downloaded.  Two forms:

            - ``list[str]``: subject / set keys to download in full, e.g.
              ``["chb01", "chb02"]``.  Call :func:`dataset_info` to see
              available keys.
            - ``dict[str, int | list[str] | None]``: per-key file-level
              control.  Map each key to:

              - ``int N``     — first *N* files (in file-index order)
              - ``list[str]`` — specific filenames
              - ``None``      — all files for that key

              Example::

                  cb.download_dataset("swiss_eeg_long", subset={"ID01": 2})
                  cb.download_dataset("swiss_eeg_long", subset={"ID01": None, "ID02": 3})

            ``None`` downloads everything.
        accept: Skip the confirmation prompt.
        force: Delete existing local files and re-download from scratch.
        dry_run: If ``True``, print a summary of what would be downloaded and
            return immediately without downloading anything.  Useful for
            checking file counts and size before committing to a large download.

    Returns:
        Path to the local dataset directory (may not exist if ``dry_run=True``
        and nothing has been downloaded yet).

    Raises:
        ValueError: If ``identifier`` is a local dataset (no download needed)
            or unknown, or if ``subset`` contains invalid keys.
        DownloadCancelled: If ``accept=False`` and the user declines the download.
    """
    if identifier in {*_LOCAL_DATASET_INFO}:
        raise ValueError(f"'{identifier}' is a local dataset — no download needed.")

    spec = get_remote_dataset_spec(identifier)
    if spec is not None:
        if subset is not None:
            _validate_subset(spec, subset)
        return ensure_remote_files(spec, subset=subset, accept=accept, force=force, dry_run=dry_run)

    raise ValueError(
        f"Unknown dataset identifier: {identifier!r}. "
        f"Known identifiers: {[*sorted(_LOCAL_DATASET_INFO), *REMOTE_DATASETS]}"
    )

list_datasets()

cobrabox.datasets.list_datasets

list_datasets() -> dict[str, list[str]]

Return all known dataset identifiers grouped by type.

Example::

cb.list_datasets()
# {
#   'local':  ['dummy_chain', 'dummy_noise', ...],
#   'remote': ['bonn_eeg', 'chb_mit', ...],
# }

Returns:

Type Description
dict[str, list[str]]

Dict with keys "local" (no download required) and "remote",

dict[str, list[str]]

each mapping to a sorted list of identifier strings.

Source code in src/cobrabox/datasets.py
def list_datasets() -> dict[str, list[str]]:
    """Return all known dataset identifiers grouped by type.

    Example::

        cb.list_datasets()
        # {
        #   'local':  ['dummy_chain', 'dummy_noise', ...],
        #   'remote': ['bonn_eeg', 'chb_mit', ...],
        # }

    Returns:
        Dict with keys ``"local"`` (no download required) and ``"remote"``,
        each mapping to a sorted list of identifier strings.
    """
    return {"local": sorted(_LOCAL_DATASET_INFO), "remote": sorted(REMOTE_DATASETS)}

show_datasets()

cobrabox.datasets.show_datasets

show_datasets() -> list[dict[str, str | None]]

Print a summary table of all available datasets and return the data.

Example::

cb.show_datasets()
# Dataset        Source  Data type         Cached  Seizures  Size     Subsets  License
# bonn_eeg       remote  ictal/interictal  yes     100       ~10 MB   5 sets   ...
# chb_mit        remote  ictal/interictal  3/24    200       ~30 GB   24 subj  ...
# dummy_chain    local   —                 —       —         —        —        —

Returns:

Type Description
list[dict[str, str | None]]

List of dicts with keys "identifier", "source", "data_type",

list[dict[str, str | None]]

"cached", "seizures", "size", "subsets", and

list[dict[str, str | None]]

"license". Suitable for programmatic use in notebooks or scripts.

list[dict[str, str | None]]

"cached" is "yes"/"no"/"N/M" for remote datasets and

list[dict[str, str | None]]

None for local ones.

Source code in src/cobrabox/datasets.py
def show_datasets() -> list[dict[str, str | None]]:
    """Print a summary table of all available datasets and return the data.

    Example::

        cb.show_datasets()
        # Dataset        Source  Data type         Cached  Seizures  Size     Subsets  License
        # bonn_eeg       remote  ictal/interictal  yes     100       ~10 MB   5 sets   ...
        # chb_mit        remote  ictal/interictal  3/24    200       ~30 GB   24 subj  ...
        # dummy_chain    local   —                 —       —         —        —        —

    Returns:
        List of dicts with keys ``"identifier"``, ``"source"``, ``"data_type"``,
        ``"cached"``, ``"seizures"``, ``"size"``, ``"subsets"``, and
        ``"license"``.  Suitable for programmatic use in notebooks or scripts.
        ``"cached"`` is ``"yes"``/``"no"``/``"N/M"`` for remote datasets and
        ``None`` for local ones.
    """
    from rich.console import Console
    from rich.table import Table

    table = Table(title="Available Datasets", show_lines=False)
    table.add_column("Dataset", style="bold", no_wrap=True)
    table.add_column("Source", style="dim")
    table.add_column("Data type")
    table.add_column("Cached")
    table.add_column("Seizures", justify="right")
    table.add_column("Size")
    table.add_column("Subsets")
    table.add_column("License")

    rows: list[dict[str, str | None]] = []
    for ident in sorted(_LOCAL_DATASET_INFO) + sorted(REMOTE_DATASETS):
        if ident in _LOCAL_DATASET_INFO:
            table.add_row(
                ident, "local", "\u2014", "\u2014", "\u2014", "\u2014", "\u2014", "\u2014"
            )
            rows.append(
                {
                    "identifier": ident,
                    "source": "local",
                    "data_type": None,
                    "cached": None,
                    "seizures": None,
                    "size": None,
                    "subsets": None,
                    "license": None,
                }
            )
        else:
            spec = get_remote_dataset_spec(ident)
            if spec is None:
                continue
            data_type_str = spec.data_type or "—"
            cached_val = _dataset_cache_status(spec)
            cached_cell = (
                f"[green]{cached_val}[/green]"
                if cached_val == "yes"
                else f"[dim]{cached_val}[/dim]"
            )
            if spec.seizures_per_subject is not None:
                seizures_str = str(sum(spec.seizures_per_subject.values()))
            else:
                seizures_str = "\u2014"
            size = spec.size_hint or "\u2014"
            subset_keys = spec.subset_keys()
            n_keys = len(subset_keys) if subset_keys else None
            subsets = f"{n_keys} {spec.subset_key_name or 'subsets'}" if n_keys else "\u2014"
            lic = spec.license or "\u2014"
            table.add_row(
                ident, "remote", data_type_str, cached_cell, seizures_str, size, subsets, lic
            )
            rows.append(
                {
                    "identifier": ident,
                    "source": "remote",
                    "data_type": None if data_type_str == "\u2014" else data_type_str,
                    "cached": cached_val,
                    "seizures": None if seizures_str == "\u2014" else seizures_str,
                    "size": None if size == "\u2014" else size,
                    "subsets": None if subsets == "\u2014" else subsets,
                    "license": None if lic == "\u2014" else lic,
                }
            )

    console = Console(file=sys.stdout)
    console.print(table)
    console.print(f"[dim]Data directory:[/dim] {get_dataset_dir()}")
    return rows

dataset_info()

cobrabox.datasets.dataset_info

dataset_info(identifier: str) -> DatasetInfo

Return metadata for a dataset, including available subset keys.

Example::

info = cb.dataset_info("swiss_eeg_short")
print(info)
# DatasetInfo: swiss_eeg_short
#   description  : Short-term scalp EEG ...
#   subjects (18): ID1, ID2, ID4a, ...
#   usage        : cb.load_dataset("swiss_eeg_short", subset=["ID1", "ID2"])

Parameters:

Name Type Description Default
identifier str

Dataset name, e.g. "swiss_eeg_short".

required

Returns:

Type Description
DatasetInfo

class:DatasetInfo with description and available subset keys.

Raises:

Type Description
ValueError

If the identifier is unknown.

Source code in src/cobrabox/datasets.py
def dataset_info(identifier: str) -> DatasetInfo:
    """Return metadata for a dataset, including available subset keys.

    Example::

        info = cb.dataset_info("swiss_eeg_short")
        print(info)
        # DatasetInfo: swiss_eeg_short
        #   description  : Short-term scalp EEG ...
        #   subjects (18): ID1, ID2, ID4a, ...
        #   usage        : cb.load_dataset("swiss_eeg_short", subset=["ID1", "ID2"])

    Args:
        identifier: Dataset name, e.g. ``"swiss_eeg_short"``.

    Returns:
        :class:`DatasetInfo` with description and available subset keys.

    Raises:
        ValueError: If the identifier is unknown.
    """
    if identifier in _LOCAL_DATASET_INFO:
        return DatasetInfo(
            identifier=identifier,
            description=_LOCAL_DATASET_INFO[identifier],
            subset_key_name=None,
            subsets=None,
        )

    spec = get_remote_dataset_spec(identifier)
    if spec is not None:
        keys = spec.subset_keys()
        cached_path = get_dataset_dir() / spec.local_rel_dir
        return DatasetInfo(
            identifier=identifier,
            description=spec.description,
            subset_key_name=spec.subset_key_name,
            subsets=tuple(keys) if keys is not None else None,
            size_hint=spec.size_hint,
            subset_size_hint=spec.subset_size_hint,
            data_type=spec.data_type,
            seizures_per_subject=spec.seizures_per_subject,
            seizure_info_url=spec.seizure_info_url,
            info_url=spec.info_url,
            license=spec.license,
            auth_hint=spec.auth_hint,
            local_path=cached_path if _dataset_cache_status(spec) != "no" else None,
            ilae_per_subject=spec.ilae_per_subject,
            resected_zone_per_subject=spec.resected_zone_per_subject,
            excluded_channels_per_subject=spec.excluded_channels_per_subject,
            all_channels_per_subject=spec.all_channels_per_subject,
        )

    raise ValueError(
        f"Unknown dataset identifier: {identifier!r}. "
        f"Known identifiers: {[*sorted(_LOCAL_DATASET_INFO), *REMOTE_DATASETS]}"
    )

delete_dataset()

cobrabox.datasets.delete_dataset

delete_dataset(
    identifier: str,
    *,
    subset: list[str] | None = None,
    confirm: bool = True,
) -> None

Delete locally cached files for a remote dataset.

Useful for freeing disk space after analysis is complete. Use :func:dataset_info to inspect what subset keys are available, and :func:show_datasets to see which datasets are currently cached.

Parameters:

Name Type Description Default
identifier str

Remote dataset name, e.g. "bonn_eeg".

required
subset list[str] | None

If given, only delete files for the listed subset keys (e.g. ["chb01", "chb02"]). None (default) deletes everything for this dataset.

None
confirm bool

If True (default), print a summary and prompt before deleting. Set to False to skip the prompt (e.g. in automated pipelines).

True

Raises:

Type Description
ValueError

If identifier is a local dataset (nothing to delete) or unknown.

DownloadCancelled

If confirm=True and the user declines the deletion.

Example::

# Delete a full dataset
cb.delete_dataset("bonn_eeg")

# Delete specific subjects only
cb.delete_dataset("chb_mit", subset=["chb01", "chb02"])

# Skip confirmation
cb.delete_dataset("bonn_eeg", confirm=False)
Source code in src/cobrabox/datasets.py
def delete_dataset(
    identifier: str, *, subset: list[str] | None = None, confirm: bool = True
) -> None:
    """Delete locally cached files for a remote dataset.

    Useful for freeing disk space after analysis is complete.  Use
    :func:`dataset_info` to inspect what subset keys are available, and
    :func:`show_datasets` to see which datasets are currently cached.

    Args:
        identifier: Remote dataset name, e.g. ``"bonn_eeg"``.
        subset: If given, only delete files for the listed subset keys (e.g.
            ``["chb01", "chb02"]``).  ``None`` (default) deletes everything
            for this dataset.
        confirm: If ``True`` (default), print a summary and prompt before
            deleting.  Set to ``False`` to skip the prompt (e.g. in
            automated pipelines).

    Raises:
        ValueError: If ``identifier`` is a local dataset (nothing to delete)
            or unknown.
        DownloadCancelled: If ``confirm=True`` and the user declines the deletion.

    Example::

        # Delete a full dataset
        cb.delete_dataset("bonn_eeg")

        # Delete specific subjects only
        cb.delete_dataset("chb_mit", subset=["chb01", "chb02"])

        # Skip confirmation
        cb.delete_dataset("bonn_eeg", confirm=False)
    """
    if identifier in _LOCAL_DATASET_INFO:
        raise ValueError(f"'{identifier}' is a local dataset — nothing to delete.")

    spec = get_remote_dataset_spec(identifier)
    if spec is None:
        raise ValueError(
            f"Unknown dataset identifier: {identifier!r}. "
            f"Known identifiers: {[*sorted(_LOCAL_DATASET_INFO), *REMOTE_DATASETS]}"
        )

    delete_remote_files(spec, subset=subset, confirm=confirm)