torch_em.data.datasets.medical.bpd_neo

BPD-Neo is a dataset for segmentation of the lungs and trachea in neonatal MRI.

The dataset consists of 40 free-breathing 3D stack-of-stars radial gradient echo (StarVIBE) MRI scans of neonates, most of whom are diagnosed with bronchopulmonary dysplasia (BPD), together with semantic segmentation masks. All 40 scans have a lung mask, and 36 of them additionally have a trachea mask (4 patients: BPD-Neo-01, BPD-Neo-03, BPD-Neo-11 and BPD-Neo-22 have no trachea mask).

This dataset is located at https://doi.org/10.5281/zenodo.15768091 (Zenodo, CC BY 4.0). The dataset is from the publication https://doi.org/10.1038/s41597-026-07006-8. Please cite it if you use this dataset for your research.

  1"""BPD-Neo is a dataset for segmentation of the lungs and trachea in neonatal MRI.
  2
  3The dataset consists of 40 free-breathing 3D stack-of-stars radial gradient echo (StarVIBE) MRI
  4scans of neonates, most of whom are diagnosed with bronchopulmonary dysplasia (BPD), together with
  5semantic segmentation masks. All 40 scans have a lung mask, and 36 of them additionally have a
  6trachea mask (4 patients: BPD-Neo-01, BPD-Neo-03, BPD-Neo-11 and BPD-Neo-22 have no trachea mask).
  7
  8This dataset is located at https://doi.org/10.5281/zenodo.15768091 (Zenodo, CC BY 4.0).
  9The dataset is from the publication https://doi.org/10.1038/s41597-026-07006-8.
 10Please cite it if you use this dataset for your research.
 11"""
 12
 13import os
 14from glob import glob
 15from natsort import natsorted
 16from typing import Union, Tuple, Literal, List
 17
 18from torch.utils.data import Dataset, DataLoader
 19
 20import torch_em
 21
 22from .. import util
 23
 24
 25URL = "https://zenodo.org/records/15768091/files/BPD-Neo-data.zip"
 26CHECKSUM = "cae6eb7ad6cbd3b1bf488fe88af9b17147f02bf2d754a304ec3b94d0ec1c75a9"
 27
 28
 29def get_bpd_neo_data(path: Union[os.PathLike, str], download: bool = False) -> str:
 30    """Download the BPD-Neo data.
 31
 32    Args:
 33        path: Filepath to a folder where the data is downloaded for further processing.
 34        download: Whether to download the data if it is not present.
 35
 36    Returns:
 37        Filepath where the data is downloaded.
 38    """
 39    data_dir = os.path.join(path, "Nifti-data")
 40    if os.path.exists(data_dir):
 41        return data_dir
 42
 43    os.makedirs(path, exist_ok=True)
 44
 45    zip_path = os.path.join(path, "BPD-Neo-data.zip")
 46    util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM)
 47    util.unzip(zip_path=zip_path, dst=path)
 48
 49    return data_dir
 50
 51
 52def get_bpd_neo_paths(
 53    path: Union[os.PathLike, str], structure: Literal['lung', 'trachea'] = "lung", download: bool = False
 54) -> Tuple[List[str], List[str]]:
 55    """Get paths to the BPD-Neo data.
 56
 57    Args:
 58        path: Filepath to a folder where the data is downloaded for further processing.
 59        structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
 60        download: Whether to download the data if it is not present.
 61
 62    Returns:
 63        List of filepaths for the image data.
 64        List of filepaths for the label data.
 65    """
 66    data_dir = get_bpd_neo_data(path, download)
 67
 68    if structure not in ("lung", "trachea"):
 69        raise ValueError(f"'{structure}' is not a valid structure. Choose either 'lung' or 'trachea'.")
 70
 71    patient_dirs = natsorted(glob(os.path.join(data_dir, "BPD-Neo-*")))
 72
 73    raw_paths, label_paths = [], []
 74    for patient_dir in patient_dirs:
 75        raw_path = os.path.join(patient_dir, "image.nii.gz")
 76        label_path = os.path.join(patient_dir, f"{structure}_seg.nii.gz")
 77        if os.path.exists(raw_path) and os.path.exists(label_path):
 78            raw_paths.append(raw_path)
 79            label_paths.append(label_path)
 80
 81    assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0
 82
 83    return raw_paths, label_paths
 84
 85
 86def get_bpd_neo_dataset(
 87    path: Union[os.PathLike, str],
 88    patch_shape: Tuple[int, ...],
 89    structure: Literal['lung', 'trachea'] = "lung",
 90    resize_inputs: bool = False,
 91    download: bool = False,
 92    **kwargs
 93) -> Dataset:
 94    """Get the BPD-Neo dataset for lung and trachea segmentation in neonatal MRI.
 95
 96    Args:
 97        path: Filepath to a folder where the data is downloaded for further processing.
 98        patch_shape: The patch shape to use for training.
 99        structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
100        resize_inputs: Whether to resize inputs to the desired patch shape.
101        download: Whether to download the data if it is not present.
102        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
103
104    Returns:
105        The segmentation dataset.
106    """
107    raw_paths, label_paths = get_bpd_neo_paths(path, structure, download)
108
109    if resize_inputs:
110        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False}
111        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
112            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
113        )
114
115    return torch_em.default_segmentation_dataset(
116        raw_paths=raw_paths,
117        raw_key="data",
118        label_paths=label_paths,
119        label_key="data",
120        patch_shape=patch_shape,
121        is_seg_dataset=True,
122        **kwargs
123    )
124
125
126def get_bpd_neo_loader(
127    path: Union[os.PathLike, str],
128    batch_size: int,
129    patch_shape: Tuple[int, ...],
130    structure: Literal['lung', 'trachea'] = "lung",
131    resize_inputs: bool = False,
132    download: bool = False,
133    **kwargs
134) -> DataLoader:
135    """Get the BPD-Neo dataloader for lung and trachea segmentation in neonatal MRI.
136
137    Args:
138        path: Filepath to a folder where the data is downloaded for further processing.
139        batch_size: The batch size for training.
140        patch_shape: The patch shape to use for training.
141        structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
142        resize_inputs: Whether to resize inputs to the desired patch shape.
143        download: Whether to download the data if it is not present.
144        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
145
146    Returns:
147        The DataLoader.
148    """
149    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
150    dataset = get_bpd_neo_dataset(path, patch_shape, structure, resize_inputs, download, **ds_kwargs)
151    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
URL = 'https://zenodo.org/records/15768091/files/BPD-Neo-data.zip'
CHECKSUM = 'cae6eb7ad6cbd3b1bf488fe88af9b17147f02bf2d754a304ec3b94d0ec1c75a9'
def get_bpd_neo_data(path: Union[os.PathLike, str], download: bool = False) -> str:
30def get_bpd_neo_data(path: Union[os.PathLike, str], download: bool = False) -> str:
31    """Download the BPD-Neo data.
32
33    Args:
34        path: Filepath to a folder where the data is downloaded for further processing.
35        download: Whether to download the data if it is not present.
36
37    Returns:
38        Filepath where the data is downloaded.
39    """
40    data_dir = os.path.join(path, "Nifti-data")
41    if os.path.exists(data_dir):
42        return data_dir
43
44    os.makedirs(path, exist_ok=True)
45
46    zip_path = os.path.join(path, "BPD-Neo-data.zip")
47    util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM)
48    util.unzip(zip_path=zip_path, dst=path)
49
50    return data_dir

Download the BPD-Neo data.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • download: Whether to download the data if it is not present.
Returns:

Filepath where the data is downloaded.

def get_bpd_neo_paths( path: Union[os.PathLike, str], structure: Literal['lung', 'trachea'] = 'lung', download: bool = False) -> Tuple[List[str], List[str]]:
53def get_bpd_neo_paths(
54    path: Union[os.PathLike, str], structure: Literal['lung', 'trachea'] = "lung", download: bool = False
55) -> Tuple[List[str], List[str]]:
56    """Get paths to the BPD-Neo data.
57
58    Args:
59        path: Filepath to a folder where the data is downloaded for further processing.
60        structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
61        download: Whether to download the data if it is not present.
62
63    Returns:
64        List of filepaths for the image data.
65        List of filepaths for the label data.
66    """
67    data_dir = get_bpd_neo_data(path, download)
68
69    if structure not in ("lung", "trachea"):
70        raise ValueError(f"'{structure}' is not a valid structure. Choose either 'lung' or 'trachea'.")
71
72    patient_dirs = natsorted(glob(os.path.join(data_dir, "BPD-Neo-*")))
73
74    raw_paths, label_paths = [], []
75    for patient_dir in patient_dirs:
76        raw_path = os.path.join(patient_dir, "image.nii.gz")
77        label_path = os.path.join(patient_dir, f"{structure}_seg.nii.gz")
78        if os.path.exists(raw_path) and os.path.exists(label_path):
79            raw_paths.append(raw_path)
80            label_paths.append(label_path)
81
82    assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0
83
84    return raw_paths, label_paths

Get paths to the BPD-Neo data.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
  • download: Whether to download the data if it is not present.
Returns:

List of filepaths for the image data. List of filepaths for the label data.

def get_bpd_neo_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, ...], structure: Literal['lung', 'trachea'] = 'lung', resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
 87def get_bpd_neo_dataset(
 88    path: Union[os.PathLike, str],
 89    patch_shape: Tuple[int, ...],
 90    structure: Literal['lung', 'trachea'] = "lung",
 91    resize_inputs: bool = False,
 92    download: bool = False,
 93    **kwargs
 94) -> Dataset:
 95    """Get the BPD-Neo dataset for lung and trachea segmentation in neonatal MRI.
 96
 97    Args:
 98        path: Filepath to a folder where the data is downloaded for further processing.
 99        patch_shape: The patch shape to use for training.
100        structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
101        resize_inputs: Whether to resize inputs to the desired patch shape.
102        download: Whether to download the data if it is not present.
103        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
104
105    Returns:
106        The segmentation dataset.
107    """
108    raw_paths, label_paths = get_bpd_neo_paths(path, structure, download)
109
110    if resize_inputs:
111        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False}
112        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
113            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
114        )
115
116    return torch_em.default_segmentation_dataset(
117        raw_paths=raw_paths,
118        raw_key="data",
119        label_paths=label_paths,
120        label_key="data",
121        patch_shape=patch_shape,
122        is_seg_dataset=True,
123        **kwargs
124    )

Get the BPD-Neo dataset for lung and trachea segmentation in neonatal MRI.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • patch_shape: The patch shape to use for training.
  • structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
  • resize_inputs: Whether to resize inputs to the desired patch shape.
  • download: Whether to download the data if it is not present.
  • kwargs: Additional keyword arguments for torch_em.default_segmentation_dataset.
Returns:

The segmentation dataset.

def get_bpd_neo_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, ...], structure: Literal['lung', 'trachea'] = 'lung', resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
127def get_bpd_neo_loader(
128    path: Union[os.PathLike, str],
129    batch_size: int,
130    patch_shape: Tuple[int, ...],
131    structure: Literal['lung', 'trachea'] = "lung",
132    resize_inputs: bool = False,
133    download: bool = False,
134    **kwargs
135) -> DataLoader:
136    """Get the BPD-Neo dataloader for lung and trachea segmentation in neonatal MRI.
137
138    Args:
139        path: Filepath to a folder where the data is downloaded for further processing.
140        batch_size: The batch size for training.
141        patch_shape: The patch shape to use for training.
142        structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
143        resize_inputs: Whether to resize inputs to the desired patch shape.
144        download: Whether to download the data if it is not present.
145        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
146
147    Returns:
148        The DataLoader.
149    """
150    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
151    dataset = get_bpd_neo_dataset(path, patch_shape, structure, resize_inputs, download, **ds_kwargs)
152    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the BPD-Neo dataloader for lung and trachea segmentation in neonatal MRI.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • batch_size: The batch size for training.
  • patch_shape: The patch shape to use for training.
  • structure: The anatomical structure to segment. Either 'lung' or 'trachea'.
  • resize_inputs: Whether to resize inputs to the desired patch shape.
  • download: Whether to download the data if it is not present.
  • kwargs: Additional keyword arguments for torch_em.default_segmentation_dataset or for the PyTorch DataLoader.
Returns:

The DataLoader.