torch_em.data.datasets.medical.segthor

The SegTHOR dataset contains annotations for thoracic organ-at-risk segmentation in CT scans of lung or esophageal cancer patients.

It comprises the training set of the SegTHOR challenge (https://competitions.codalab.org/competitions/21145): 40 thoracic CT scans with a dense annotation of the esophagus, heart, trachea and aorta. The 20 test volumes of the challenge are distributed without annotations and are therefore not included here.

NOTE: The label legend is as follows:

  • background: 0, esophagus: 1, heart: 2, trachea: 3, aorta: 4 The ids were verified on the data: label 2 is by far the largest structure and sits anteriorly in the lower thorax (heart), label 3 is confined to the upper thorax anterior to label 1 (trachea vs. esophagus), and label 4 spans the whole craniocaudal extent (aorta).

The data is a redistribution of the official challenge data at https://doi.org/10.5281/zenodo.16663661 (CC BY 4.0). The official release at https://competitions.codalab.org/competitions/21145 requires a signed user agreement, so please make sure that you are allowed to use the data for your purpose.

This dataset is from the publication https://doi.org/10.1109/ICPR48806.2021.9411873. Please cite it if you use this dataset in your research.

  1"""The SegTHOR dataset contains annotations for thoracic organ-at-risk segmentation in CT scans
  2of lung or esophageal cancer patients.
  3
  4It comprises the training set of the SegTHOR challenge (https://competitions.codalab.org/competitions/21145):
  540 thoracic CT scans with a dense annotation of the esophagus, heart, trachea and aorta. The 20 test volumes
  6of the challenge are distributed without annotations and are therefore not included here.
  7
  8NOTE: The label legend is as follows:
  9- background: 0, esophagus: 1, heart: 2, trachea: 3, aorta: 4
 10The ids were verified on the data: label 2 is by far the largest structure and sits anteriorly in the lower
 11thorax (heart), label 3 is confined to the upper thorax anterior to label 1 (trachea vs. esophagus), and
 12label 4 spans the whole craniocaudal extent (aorta).
 13
 14The data is a redistribution of the official challenge data at https://doi.org/10.5281/zenodo.16663661
 15(CC BY 4.0). The official release at https://competitions.codalab.org/competitions/21145 requires a signed
 16user agreement, so please make sure that you are allowed to use the data for your purpose.
 17
 18This dataset is from the publication https://doi.org/10.1109/ICPR48806.2021.9411873.
 19Please cite it if you use this dataset in your research.
 20"""
 21
 22import os
 23from glob import glob
 24from natsort import natsorted
 25from typing import Union, Tuple, List
 26
 27from torch.utils.data import Dataset, DataLoader
 28
 29import torch_em
 30
 31from .. import util
 32
 33
 34URL = "https://zenodo.org/records/16663661/files/SegTHOR.zip"
 35CHECKSUM = "5dba9bcc681c895b7d7b59cf5a26cae570bc8bba02c74f9cb128f3292410fb15"
 36
 37LABEL_IDS = {"background": 0, "esophagus": 1, "heart": 2, "trachea": 3, "aorta": 4}
 38
 39
 40def get_segthor_data(path: Union[os.PathLike, str], download: bool = False) -> str:
 41    """Download the SegTHOR dataset.
 42
 43    Args:
 44        path: Filepath to a folder where the data is downloaded for further processing.
 45        download: Whether to download the data if it is not present.
 46
 47    Returns:
 48        Filepath where the data is stored.
 49    """
 50    data_dir = os.path.join(path, "SegTHOR")
 51    if os.path.exists(data_dir):
 52        return data_dir
 53
 54    os.makedirs(path, exist_ok=True)
 55
 56    zip_path = os.path.join(path, "SegTHOR.zip")
 57    util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM)
 58    util.unzip(zip_path=zip_path, dst=path)
 59
 60    return data_dir
 61
 62
 63def get_segthor_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
 64    """Get paths to the SegTHOR data.
 65
 66    Args:
 67        path: Filepath to a folder where the data is downloaded for further processing.
 68        download: Whether to download the data if it is not present.
 69
 70    Returns:
 71        List of filepaths for the image data.
 72        List of filepaths for the label data.
 73    """
 74    data_dir = get_segthor_data(path, download)
 75
 76    case_dirs = natsorted(glob(os.path.join(data_dir, "Patient_*")))
 77    raw_paths = [os.path.join(p, f"{os.path.basename(p)}.nii.gz") for p in case_dirs]
 78    label_paths = [os.path.join(p, "GT.nii.gz") for p in case_dirs]
 79    assert len(raw_paths) > 0 and all(os.path.exists(p) for p in raw_paths + label_paths)
 80
 81    return raw_paths, label_paths
 82
 83
 84def get_segthor_dataset(
 85    path: Union[os.PathLike, str],
 86    patch_shape: Tuple[int, ...],
 87    resize_inputs: bool = False,
 88    download: bool = False,
 89    **kwargs
 90) -> Dataset:
 91    """Get the SegTHOR dataset for thoracic organ-at-risk segmentation.
 92
 93    Args:
 94        path: Filepath to a folder where the data is downloaded for further processing.
 95        patch_shape: The patch shape to use for training.
 96        resize_inputs: Whether to resize inputs to the desired patch shape.
 97        download: Whether to download the data if it is not present.
 98        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
 99
100    Returns:
101        The segmentation dataset.
102    """
103    raw_paths, label_paths = get_segthor_paths(path, download)
104
105    if resize_inputs:
106        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False}
107        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
108            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
109        )
110
111    return torch_em.default_segmentation_dataset(
112        raw_paths=raw_paths,
113        raw_key="data",
114        label_paths=label_paths,
115        label_key="data",
116        patch_shape=patch_shape,
117        is_seg_dataset=True,
118        **kwargs
119    )
120
121
122def get_segthor_loader(
123    path: Union[os.PathLike, str],
124    batch_size: int,
125    patch_shape: Tuple[int, ...],
126    resize_inputs: bool = False,
127    download: bool = False,
128    **kwargs
129) -> DataLoader:
130    """Get the SegTHOR dataloader for thoracic organ-at-risk segmentation.
131
132    Args:
133        path: Filepath to a folder where the data is downloaded for further processing.
134        batch_size: The batch size for training.
135        patch_shape: The patch shape to use for training.
136        resize_inputs: Whether to resize inputs to the desired patch shape.
137        download: Whether to download the data if it is not present.
138        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
139
140    Returns:
141        The DataLoader.
142    """
143    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
144    dataset = get_segthor_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
145    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
URL = 'https://zenodo.org/records/16663661/files/SegTHOR.zip'
CHECKSUM = '5dba9bcc681c895b7d7b59cf5a26cae570bc8bba02c74f9cb128f3292410fb15'
LABEL_IDS = {'background': 0, 'esophagus': 1, 'heart': 2, 'trachea': 3, 'aorta': 4}
def get_segthor_data(path: Union[os.PathLike, str], download: bool = False) -> str:
41def get_segthor_data(path: Union[os.PathLike, str], download: bool = False) -> str:
42    """Download the SegTHOR dataset.
43
44    Args:
45        path: Filepath to a folder where the data is downloaded for further processing.
46        download: Whether to download the data if it is not present.
47
48    Returns:
49        Filepath where the data is stored.
50    """
51    data_dir = os.path.join(path, "SegTHOR")
52    if os.path.exists(data_dir):
53        return data_dir
54
55    os.makedirs(path, exist_ok=True)
56
57    zip_path = os.path.join(path, "SegTHOR.zip")
58    util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM)
59    util.unzip(zip_path=zip_path, dst=path)
60
61    return data_dir

Download the SegTHOR dataset.

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

def get_segthor_paths( path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
64def get_segthor_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
65    """Get paths to the SegTHOR data.
66
67    Args:
68        path: Filepath to a folder where the data is downloaded for further processing.
69        download: Whether to download the data if it is not present.
70
71    Returns:
72        List of filepaths for the image data.
73        List of filepaths for the label data.
74    """
75    data_dir = get_segthor_data(path, download)
76
77    case_dirs = natsorted(glob(os.path.join(data_dir, "Patient_*")))
78    raw_paths = [os.path.join(p, f"{os.path.basename(p)}.nii.gz") for p in case_dirs]
79    label_paths = [os.path.join(p, "GT.nii.gz") for p in case_dirs]
80    assert len(raw_paths) > 0 and all(os.path.exists(p) for p in raw_paths + label_paths)
81
82    return raw_paths, label_paths

Get paths to the SegTHOR 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:

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

def get_segthor_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, ...], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
 85def get_segthor_dataset(
 86    path: Union[os.PathLike, str],
 87    patch_shape: Tuple[int, ...],
 88    resize_inputs: bool = False,
 89    download: bool = False,
 90    **kwargs
 91) -> Dataset:
 92    """Get the SegTHOR dataset for thoracic organ-at-risk segmentation.
 93
 94    Args:
 95        path: Filepath to a folder where the data is downloaded for further processing.
 96        patch_shape: The patch shape to use for training.
 97        resize_inputs: Whether to resize inputs to the desired patch shape.
 98        download: Whether to download the data if it is not present.
 99        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
100
101    Returns:
102        The segmentation dataset.
103    """
104    raw_paths, label_paths = get_segthor_paths(path, download)
105
106    if resize_inputs:
107        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False}
108        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
109            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
110        )
111
112    return torch_em.default_segmentation_dataset(
113        raw_paths=raw_paths,
114        raw_key="data",
115        label_paths=label_paths,
116        label_key="data",
117        patch_shape=patch_shape,
118        is_seg_dataset=True,
119        **kwargs
120    )

Get the SegTHOR dataset for thoracic organ-at-risk segmentation.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • patch_shape: The patch shape to use for training.
  • 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_segthor_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, ...], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
123def get_segthor_loader(
124    path: Union[os.PathLike, str],
125    batch_size: int,
126    patch_shape: Tuple[int, ...],
127    resize_inputs: bool = False,
128    download: bool = False,
129    **kwargs
130) -> DataLoader:
131    """Get the SegTHOR dataloader for thoracic organ-at-risk segmentation.
132
133    Args:
134        path: Filepath to a folder where the data is downloaded for further processing.
135        batch_size: The batch size for training.
136        patch_shape: The patch shape to use for training.
137        resize_inputs: Whether to resize inputs to the desired patch shape.
138        download: Whether to download the data if it is not present.
139        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
140
141    Returns:
142        The DataLoader.
143    """
144    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
145    dataset = get_segthor_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
146    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the SegTHOR dataloader for thoracic organ-at-risk segmentation.

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