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_datasetor for the PyTorch DataLoader.
Returns:
The DataLoader.