torch_em.data.datasets.histopathology.rings

The RINGS dataset contains annotations for prostate gland and tumor region segmentation in H&E stained prostate histopathological images.

The dataset is located at https://data.mendeley.com/datasets/h8bdwrtnr5/1. This dataset is from the publication https://doi.org/10.1016/j.artmed.2021.102076. Please cite it if you use this dataset for your research.

  1"""The RINGS dataset contains annotations for prostate gland and tumor region
  2segmentation in H&E stained prostate histopathological images.
  3
  4The dataset is located at https://data.mendeley.com/datasets/h8bdwrtnr5/1.
  5This dataset is from the publication https://doi.org/10.1016/j.artmed.2021.102076.
  6Please cite it if you use this dataset for your research.
  7"""
  8
  9import os
 10from glob import glob
 11from natsort import natsorted
 12from typing import List, Literal, Tuple, Union
 13
 14from torch.utils.data import Dataset, DataLoader
 15
 16import torch_em
 17
 18from .. import util
 19
 20
 21URLS = {
 22    "train": "https://data.mendeley.com/public-files/datasets/h8bdwrtnr5/files/8416eb6b-d1c8-4a8c-96fd-2f36a2768e46/file_downloaded",  # noqa
 23    "test": "https://data.mendeley.com/public-files/datasets/h8bdwrtnr5/files/5846b131-09fa-44c5-afa8-8fbc52adbd88/file_downloaded",  # noqa
 24}
 25CHECKSUMS = {
 26    "train": "af426249bd96d36e2c5e0110d42ceb67a8ebb79d94e2b2c15f4e727ebca38329",
 27    "test": "f8134f01ce4cbcfd703bf96a8501e6267fe87a66301e15749dac463742f8958d",
 28}
 29
 30
 31def get_rings_data(path: Union[os.PathLike, str], split: Literal["train", "test"], download: bool = False) -> str:
 32    """Download the RINGS dataset.
 33
 34    Args:
 35        path: Filepath to a folder where the downloaded data will be saved.
 36        split: The choice of data split.
 37        download: Whether to download the data if it is not present.
 38
 39    Returns:
 40        Filepath to the folder where the split data is stored.
 41    """
 42    if split not in URLS:
 43        raise ValueError(f"'{split}' is not a valid split choice.")
 44
 45    data_dir = os.path.join(path, split.upper())
 46    if os.path.exists(data_dir):
 47        return data_dir
 48
 49    os.makedirs(path, exist_ok=True)
 50    zip_path = os.path.join(path, f"{split}.zip")
 51    util.download_source(path=zip_path, url=URLS[split], download=download, checksum=CHECKSUMS[split])
 52    util.unzip(zip_path=zip_path, dst=path)
 53
 54    return data_dir
 55
 56
 57def get_rings_paths(
 58    path: Union[os.PathLike, str],
 59    split: Literal["train", "test"],
 60    label_choice: Literal["glands", "tumor"] = "glands",
 61    download: bool = False,
 62) -> Tuple[List[str], List[str]]:
 63    """Get paths to the RINGS data.
 64
 65    Args:
 66        path: Filepath to a folder where the downloaded data will be saved.
 67        split: The choice of data split.
 68        label_choice: The segmentation target. Either 'glands' for gland segmentation
 69            or 'tumor' for tumor region segmentation.
 70        download: Whether to download the data if it is not present.
 71
 72    Returns:
 73        List of filepaths for the image data.
 74        List of filepaths for the label data.
 75    """
 76    if label_choice not in ("glands", "tumor"):
 77        raise ValueError(f"'{label_choice}' is not a valid label choice.")
 78
 79    data_dir = get_rings_data(path, split, download)
 80    raw_paths = natsorted(glob(os.path.join(data_dir, "IMAGES", "*.png")))
 81
 82    label_folder = "MANUAL GLANDS" if label_choice == "glands" else "MANUAL TUMOR"
 83    label_paths = natsorted(glob(os.path.join(data_dir, label_folder, "*.png")))
 84
 85    assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0
 86    assert all(
 87        os.path.basename(raw_path) == os.path.basename(label_path)
 88        for raw_path, label_path in zip(raw_paths, label_paths)
 89    )
 90
 91    return raw_paths, label_paths
 92
 93
 94def get_rings_dataset(
 95    path: Union[os.PathLike, str],
 96    patch_shape: Tuple[int, int],
 97    split: Literal["train", "test"],
 98    label_choice: Literal["glands", "tumor"] = "glands",
 99    resize_inputs: bool = False,
100    download: bool = False,
101    **kwargs,
102) -> Dataset:
103    """Get the RINGS dataset for prostate gland or tumor region segmentation.
104
105    Args:
106        path: Filepath to a folder where the downloaded data will be saved.
107        patch_shape: The patch shape to use for training.
108        split: The choice of data split.
109        label_choice: The segmentation target. Either 'glands' for gland segmentation
110            or 'tumor' for tumor region segmentation.
111        resize_inputs: Whether to resize the inputs.
112        download: Whether to download the data if it is not present.
113        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
114
115    Returns:
116        The segmentation dataset.
117    """
118    raw_paths, label_paths = get_rings_paths(path, split, label_choice, download)
119
120    if resize_inputs:
121        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True}
122        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
123            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
124        )
125
126    return torch_em.default_segmentation_dataset(
127        raw_paths=raw_paths,
128        raw_key=None,
129        label_paths=label_paths,
130        label_key=None,
131        is_seg_dataset=False,
132        patch_shape=patch_shape,
133        ndim=2,
134        with_channels=True,
135        **kwargs,
136    )
137
138
139def get_rings_loader(
140    path: Union[os.PathLike, str],
141    batch_size: int,
142    patch_shape: Tuple[int, int],
143    split: Literal["train", "test"],
144    label_choice: Literal["glands", "tumor"] = "glands",
145    resize_inputs: bool = False,
146    download: bool = False,
147    **kwargs,
148) -> DataLoader:
149    """Get the RINGS dataloader for prostate gland or tumor region segmentation.
150
151    Args:
152        path: Filepath to a folder where the downloaded data will be saved.
153        batch_size: The batch size for training.
154        patch_shape: The patch shape to use for training.
155        split: The choice of data split.
156        label_choice: The segmentation target. Either 'glands' for gland segmentation
157            or 'tumor' for tumor region segmentation.
158        resize_inputs: Whether to resize the inputs.
159        download: Whether to download the data if it is not present.
160        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
161
162    Returns:
163        The DataLoader.
164    """
165    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
166    dataset = get_rings_dataset(path, patch_shape, split, label_choice, resize_inputs, download, **ds_kwargs)
167    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
URLS = {'train': 'https://data.mendeley.com/public-files/datasets/h8bdwrtnr5/files/8416eb6b-d1c8-4a8c-96fd-2f36a2768e46/file_downloaded', 'test': 'https://data.mendeley.com/public-files/datasets/h8bdwrtnr5/files/5846b131-09fa-44c5-afa8-8fbc52adbd88/file_downloaded'}
CHECKSUMS = {'train': 'af426249bd96d36e2c5e0110d42ceb67a8ebb79d94e2b2c15f4e727ebca38329', 'test': 'f8134f01ce4cbcfd703bf96a8501e6267fe87a66301e15749dac463742f8958d'}
def get_rings_data( path: Union[os.PathLike, str], split: Literal['train', 'test'], download: bool = False) -> str:
32def get_rings_data(path: Union[os.PathLike, str], split: Literal["train", "test"], download: bool = False) -> str:
33    """Download the RINGS dataset.
34
35    Args:
36        path: Filepath to a folder where the downloaded data will be saved.
37        split: The choice of data split.
38        download: Whether to download the data if it is not present.
39
40    Returns:
41        Filepath to the folder where the split data is stored.
42    """
43    if split not in URLS:
44        raise ValueError(f"'{split}' is not a valid split choice.")
45
46    data_dir = os.path.join(path, split.upper())
47    if os.path.exists(data_dir):
48        return data_dir
49
50    os.makedirs(path, exist_ok=True)
51    zip_path = os.path.join(path, f"{split}.zip")
52    util.download_source(path=zip_path, url=URLS[split], download=download, checksum=CHECKSUMS[split])
53    util.unzip(zip_path=zip_path, dst=path)
54
55    return data_dir

Download the RINGS dataset.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • split: The choice of data split.
  • download: Whether to download the data if it is not present.
Returns:

Filepath to the folder where the split data is stored.

def get_rings_paths( path: Union[os.PathLike, str], split: Literal['train', 'test'], label_choice: Literal['glands', 'tumor'] = 'glands', download: bool = False) -> Tuple[List[str], List[str]]:
58def get_rings_paths(
59    path: Union[os.PathLike, str],
60    split: Literal["train", "test"],
61    label_choice: Literal["glands", "tumor"] = "glands",
62    download: bool = False,
63) -> Tuple[List[str], List[str]]:
64    """Get paths to the RINGS data.
65
66    Args:
67        path: Filepath to a folder where the downloaded data will be saved.
68        split: The choice of data split.
69        label_choice: The segmentation target. Either 'glands' for gland segmentation
70            or 'tumor' for tumor region segmentation.
71        download: Whether to download the data if it is not present.
72
73    Returns:
74        List of filepaths for the image data.
75        List of filepaths for the label data.
76    """
77    if label_choice not in ("glands", "tumor"):
78        raise ValueError(f"'{label_choice}' is not a valid label choice.")
79
80    data_dir = get_rings_data(path, split, download)
81    raw_paths = natsorted(glob(os.path.join(data_dir, "IMAGES", "*.png")))
82
83    label_folder = "MANUAL GLANDS" if label_choice == "glands" else "MANUAL TUMOR"
84    label_paths = natsorted(glob(os.path.join(data_dir, label_folder, "*.png")))
85
86    assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0
87    assert all(
88        os.path.basename(raw_path) == os.path.basename(label_path)
89        for raw_path, label_path in zip(raw_paths, label_paths)
90    )
91
92    return raw_paths, label_paths

Get paths to the RINGS data.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • split: The choice of data split.
  • label_choice: The segmentation target. Either 'glands' for gland segmentation or 'tumor' for tumor region segmentation.
  • 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_rings_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, int], split: Literal['train', 'test'], label_choice: Literal['glands', 'tumor'] = 'glands', resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
 95def get_rings_dataset(
 96    path: Union[os.PathLike, str],
 97    patch_shape: Tuple[int, int],
 98    split: Literal["train", "test"],
 99    label_choice: Literal["glands", "tumor"] = "glands",
100    resize_inputs: bool = False,
101    download: bool = False,
102    **kwargs,
103) -> Dataset:
104    """Get the RINGS dataset for prostate gland or tumor region segmentation.
105
106    Args:
107        path: Filepath to a folder where the downloaded data will be saved.
108        patch_shape: The patch shape to use for training.
109        split: The choice of data split.
110        label_choice: The segmentation target. Either 'glands' for gland segmentation
111            or 'tumor' for tumor region segmentation.
112        resize_inputs: Whether to resize the inputs.
113        download: Whether to download the data if it is not present.
114        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
115
116    Returns:
117        The segmentation dataset.
118    """
119    raw_paths, label_paths = get_rings_paths(path, split, label_choice, download)
120
121    if resize_inputs:
122        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True}
123        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
124            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
125        )
126
127    return torch_em.default_segmentation_dataset(
128        raw_paths=raw_paths,
129        raw_key=None,
130        label_paths=label_paths,
131        label_key=None,
132        is_seg_dataset=False,
133        patch_shape=patch_shape,
134        ndim=2,
135        with_channels=True,
136        **kwargs,
137    )

Get the RINGS dataset for prostate gland or tumor region segmentation.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • patch_shape: The patch shape to use for training.
  • split: The choice of data split.
  • label_choice: The segmentation target. Either 'glands' for gland segmentation or 'tumor' for tumor region segmentation.
  • resize_inputs: Whether to resize the inputs.
  • 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_rings_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, int], split: Literal['train', 'test'], label_choice: Literal['glands', 'tumor'] = 'glands', resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
140def get_rings_loader(
141    path: Union[os.PathLike, str],
142    batch_size: int,
143    patch_shape: Tuple[int, int],
144    split: Literal["train", "test"],
145    label_choice: Literal["glands", "tumor"] = "glands",
146    resize_inputs: bool = False,
147    download: bool = False,
148    **kwargs,
149) -> DataLoader:
150    """Get the RINGS dataloader for prostate gland or tumor region segmentation.
151
152    Args:
153        path: Filepath to a folder where the downloaded data will be saved.
154        batch_size: The batch size for training.
155        patch_shape: The patch shape to use for training.
156        split: The choice of data split.
157        label_choice: The segmentation target. Either 'glands' for gland segmentation
158            or 'tumor' for tumor region segmentation.
159        resize_inputs: Whether to resize the inputs.
160        download: Whether to download the data if it is not present.
161        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
162
163    Returns:
164        The DataLoader.
165    """
166    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
167    dataset = get_rings_dataset(path, patch_shape, split, label_choice, resize_inputs, download, **ds_kwargs)
168    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the RINGS dataloader for prostate gland or tumor region segmentation.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • batch_size: The batch size for training.
  • patch_shape: The patch shape to use for training.
  • split: The choice of data split.
  • label_choice: The segmentation target. Either 'glands' for gland segmentation or 'tumor' for tumor region segmentation.
  • resize_inputs: Whether to resize the inputs.
  • 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.