torch_em.data.datasets.histopathology.cd47_ihcnusc

The CD47-IHCNuSC dataset contains nucleus annotations for CD47 immunohistochemistry (IHC) images of esophageal cancer.

The dataset holds 86 patches of 1024 x 1024 pixels at 40x magnification (0.25 micrometer per pixel), 70 for training and 16 for validation / testing, with 18,483 annotated nuclei. The annotations were made in a human-in-the-loop process: HoverFast created coarse nucleus masks, which were refined by hand in QuPath over several rounds and then validated by experts. Every nucleus carries one of seven types (see 'TYPES'). The 'ambiguous' type of the annotation protocol is not part of the release, so ambiguous nuclei are background in the labels.

The dataset is located at https://doi.org/10.5524/102830 (CC0 1.0). This dataset is from the publication https://doi.org/10.1093/gigascience/giag091. Please cite it if you use this dataset for your research.

  1"""The CD47-IHCNuSC dataset contains nucleus annotations for CD47 immunohistochemistry (IHC) images
  2of esophageal cancer.
  3
  4The dataset holds 86 patches of 1024 x 1024 pixels at 40x magnification (0.25 micrometer per pixel),
  570 for training and 16 for validation / testing, with 18,483 annotated nuclei.
  6The annotations were made in a human-in-the-loop process: HoverFast created coarse nucleus masks, which were
  7refined by hand in QuPath over several rounds and then validated by experts. Every nucleus carries one of
  8seven types (see 'TYPES'). The 'ambiguous' type of the annotation protocol is not part of the release,
  9so ambiguous nuclei are background in the labels.
 10
 11The dataset is located at https://doi.org/10.5524/102830 (CC0 1.0).
 12This dataset is from the publication https://doi.org/10.1093/gigascience/giag091.
 13Please cite it if you use this dataset for your research.
 14"""
 15
 16import os
 17from glob import glob
 18from tqdm import tqdm
 19from natsort import natsorted
 20from typing import Union, Tuple, List, Literal
 21
 22import imageio.v3 as imageio
 23
 24from torch.utils.data import Dataset, DataLoader
 25
 26import torch_em
 27
 28from .. import util
 29
 30
 31BASE_URL = "https://s3.ap-northeast-1.wasabisys.com/gigadb-datasets/live/pub/10.5524/102000_103000/102830"
 32ARCHIVES = {
 33    "CD47-IHCNuSC_images.zip": "016e2f8f0e6efcb8d55ecf9fb22eeffcefd28ef4127e804e6dffe27ce12a21cb",
 34    "CD47-IHCNuSC_annotations.zip": "90c4e2c799a48a80ceaaa1e0a03d9632ca47b8f82bd7e464d49a4654a879d5e9",
 35}
 36TYPES = {
 37    1: "positive_tumor", 2: "positive_immune", 3: "positive_others", 4: "negative_tumor",
 38    5: "negative_immune", 6: "negative_others", 7: "negative_stroma",
 39}
 40
 41
 42def _create_h5_files(path):
 43    import h5py
 44    from scipy.io import loadmat
 45
 46    for split in ("train", "val"):
 47        out_dir = os.path.join(path, "preprocessed", split)
 48        os.makedirs(out_dir, exist_ok=True)
 49        image_paths = natsorted(glob(os.path.join(path, "images", split, "*.tif")))
 50        for image_path in tqdm(image_paths, desc=f"Preprocess CD47-IHCNuSC {split} images"):
 51            name = os.path.splitext(os.path.basename(image_path))[0]
 52            image = imageio.imread(image_path)[..., :3]
 53            labels = loadmat(os.path.join(path, "annotations", split, f"{name}.mat"))
 54            instances, types = labels["inst_map"].astype("uint32"), labels["type_map"].astype("uint8")
 55            assert image.shape[:2] == instances.shape == types.shape, name
 56
 57            with h5py.File(os.path.join(out_dir, f"{name}.h5"), "w") as f:
 58                f.create_dataset("raw", data=image.transpose(2, 0, 1), compression="gzip")
 59                f.create_dataset("labels/instances", data=instances, compression="gzip")
 60                f.create_dataset("labels/semantic", data=types, compression="gzip")
 61
 62
 63def get_cd47_ihcnusc_data(path: Union[os.PathLike, str], download: bool = False) -> str:
 64    """Download the CD47-IHCNuSC dataset.
 65
 66    Args:
 67        path: Filepath to a folder where the downloaded data is saved.
 68        download: Whether to download the data if it is not present.
 69
 70    Returns:
 71        Filepath where the preprocessed data is stored.
 72    """
 73    data_dir = os.path.join(path, "preprocessed")
 74    if os.path.exists(data_dir):
 75        return data_dir
 76
 77    os.makedirs(path, exist_ok=True)
 78    for name, checksum in ARCHIVES.items():
 79        zip_path = os.path.join(path, name)
 80        util.download_source(zip_path, f"{BASE_URL}/{name}", download, checksum=checksum)
 81        util.unzip(zip_path, path, remove=False)
 82
 83    _create_h5_files(path)
 84    return data_dir
 85
 86
 87def get_cd47_ihcnusc_paths(
 88    path: Union[os.PathLike, str], split: Literal["train", "val"], download: bool = False
 89) -> List[str]:
 90    """Get paths to the CD47-IHCNuSC data.
 91
 92    Args:
 93        path: Filepath to a folder where the downloaded data is saved.
 94        split: The choice of data split. Either 'train' or 'val' (the validation / test split of the authors).
 95        download: Whether to download the data if it is not present.
 96
 97    Returns:
 98        List of filepaths for the input data.
 99    """
100    assert split in ("train", "val"), split
101    data_dir = get_cd47_ihcnusc_data(path, download)
102    return natsorted(glob(os.path.join(data_dir, split, "*.h5")))
103
104
105def get_cd47_ihcnusc_dataset(
106    path: Union[os.PathLike, str],
107    patch_shape: Tuple[int, int],
108    split: Literal["train", "val"],
109    label_choice: Literal["instances", "semantic"] = "instances",
110    download: bool = False,
111    **kwargs
112) -> Dataset:
113    """Get the CD47-IHCNuSC dataset for nucleus segmentation.
114
115    Args:
116        path: Filepath to a folder where the downloaded data is saved.
117        patch_shape: The patch shape to use for training.
118        split: The choice of data split. Either 'train' or 'val' (the validation / test split of the authors).
119        label_choice: The choice of labels, 'instances' or 'semantic' (the nucleus types, see 'TYPES').
120        download: Whether to download the data if it is not present.
121        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
122
123    Returns:
124        The segmentation dataset.
125    """
126    assert label_choice in ("instances", "semantic"), label_choice
127    paths = get_cd47_ihcnusc_paths(path, split, download)
128    return torch_em.default_segmentation_dataset(
129        raw_paths=paths,
130        raw_key="raw",
131        label_paths=paths,
132        label_key=f"labels/{label_choice}",
133        patch_shape=patch_shape,
134        ndim=2,
135        with_channels=True,
136        **kwargs
137    )
138
139
140def get_cd47_ihcnusc_loader(
141    path: Union[os.PathLike, str],
142    batch_size: int,
143    patch_shape: Tuple[int, int],
144    split: Literal["train", "val"],
145    label_choice: Literal["instances", "semantic"] = "instances",
146    download: bool = False,
147    **kwargs
148) -> DataLoader:
149    """Get the CD47-IHCNuSC dataloader for nucleus segmentation.
150
151    Args:
152        path: Filepath to a folder where the downloaded data is 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. Either 'train' or 'val' (the validation / test split of the authors).
156        label_choice: The choice of labels, 'instances' or 'semantic' (the nucleus types, see 'TYPES').
157        download: Whether to download the data if it is not present.
158        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
159
160    Returns:
161        The DataLoader.
162    """
163    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
164    dataset = get_cd47_ihcnusc_dataset(path, patch_shape, split, label_choice, download, **ds_kwargs)
165    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
BASE_URL = 'https://s3.ap-northeast-1.wasabisys.com/gigadb-datasets/live/pub/10.5524/102000_103000/102830'
ARCHIVES = {'CD47-IHCNuSC_images.zip': '016e2f8f0e6efcb8d55ecf9fb22eeffcefd28ef4127e804e6dffe27ce12a21cb', 'CD47-IHCNuSC_annotations.zip': '90c4e2c799a48a80ceaaa1e0a03d9632ca47b8f82bd7e464d49a4654a879d5e9'}
TYPES = {1: 'positive_tumor', 2: 'positive_immune', 3: 'positive_others', 4: 'negative_tumor', 5: 'negative_immune', 6: 'negative_others', 7: 'negative_stroma'}
def get_cd47_ihcnusc_data(path: Union[os.PathLike, str], download: bool = False) -> str:
64def get_cd47_ihcnusc_data(path: Union[os.PathLike, str], download: bool = False) -> str:
65    """Download the CD47-IHCNuSC dataset.
66
67    Args:
68        path: Filepath to a folder where the downloaded data is saved.
69        download: Whether to download the data if it is not present.
70
71    Returns:
72        Filepath where the preprocessed data is stored.
73    """
74    data_dir = os.path.join(path, "preprocessed")
75    if os.path.exists(data_dir):
76        return data_dir
77
78    os.makedirs(path, exist_ok=True)
79    for name, checksum in ARCHIVES.items():
80        zip_path = os.path.join(path, name)
81        util.download_source(zip_path, f"{BASE_URL}/{name}", download, checksum=checksum)
82        util.unzip(zip_path, path, remove=False)
83
84    _create_h5_files(path)
85    return data_dir

Download the CD47-IHCNuSC dataset.

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

Filepath where the preprocessed data is stored.

def get_cd47_ihcnusc_paths( path: Union[os.PathLike, str], split: Literal['train', 'val'], download: bool = False) -> List[str]:
 88def get_cd47_ihcnusc_paths(
 89    path: Union[os.PathLike, str], split: Literal["train", "val"], download: bool = False
 90) -> List[str]:
 91    """Get paths to the CD47-IHCNuSC data.
 92
 93    Args:
 94        path: Filepath to a folder where the downloaded data is saved.
 95        split: The choice of data split. Either 'train' or 'val' (the validation / test split of the authors).
 96        download: Whether to download the data if it is not present.
 97
 98    Returns:
 99        List of filepaths for the input data.
100    """
101    assert split in ("train", "val"), split
102    data_dir = get_cd47_ihcnusc_data(path, download)
103    return natsorted(glob(os.path.join(data_dir, split, "*.h5")))

Get paths to the CD47-IHCNuSC data.

Arguments:
  • path: Filepath to a folder where the downloaded data is saved.
  • split: The choice of data split. Either 'train' or 'val' (the validation / test split of the authors).
  • download: Whether to download the data if it is not present.
Returns:

List of filepaths for the input data.

def get_cd47_ihcnusc_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, int], split: Literal['train', 'val'], label_choice: Literal['instances', 'semantic'] = 'instances', download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
106def get_cd47_ihcnusc_dataset(
107    path: Union[os.PathLike, str],
108    patch_shape: Tuple[int, int],
109    split: Literal["train", "val"],
110    label_choice: Literal["instances", "semantic"] = "instances",
111    download: bool = False,
112    **kwargs
113) -> Dataset:
114    """Get the CD47-IHCNuSC dataset for nucleus segmentation.
115
116    Args:
117        path: Filepath to a folder where the downloaded data is saved.
118        patch_shape: The patch shape to use for training.
119        split: The choice of data split. Either 'train' or 'val' (the validation / test split of the authors).
120        label_choice: The choice of labels, 'instances' or 'semantic' (the nucleus types, see 'TYPES').
121        download: Whether to download the data if it is not present.
122        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
123
124    Returns:
125        The segmentation dataset.
126    """
127    assert label_choice in ("instances", "semantic"), label_choice
128    paths = get_cd47_ihcnusc_paths(path, split, download)
129    return torch_em.default_segmentation_dataset(
130        raw_paths=paths,
131        raw_key="raw",
132        label_paths=paths,
133        label_key=f"labels/{label_choice}",
134        patch_shape=patch_shape,
135        ndim=2,
136        with_channels=True,
137        **kwargs
138    )

Get the CD47-IHCNuSC dataset for nucleus segmentation.

Arguments:
  • path: Filepath to a folder where the downloaded data is saved.
  • patch_shape: The patch shape to use for training.
  • split: The choice of data split. Either 'train' or 'val' (the validation / test split of the authors).
  • label_choice: The choice of labels, 'instances' or 'semantic' (the nucleus types, see 'TYPES').
  • 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_cd47_ihcnusc_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, int], split: Literal['train', 'val'], label_choice: Literal['instances', 'semantic'] = 'instances', download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
141def get_cd47_ihcnusc_loader(
142    path: Union[os.PathLike, str],
143    batch_size: int,
144    patch_shape: Tuple[int, int],
145    split: Literal["train", "val"],
146    label_choice: Literal["instances", "semantic"] = "instances",
147    download: bool = False,
148    **kwargs
149) -> DataLoader:
150    """Get the CD47-IHCNuSC dataloader for nucleus segmentation.
151
152    Args:
153        path: Filepath to a folder where the downloaded data is 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. Either 'train' or 'val' (the validation / test split of the authors).
157        label_choice: The choice of labels, 'instances' or 'semantic' (the nucleus types, see 'TYPES').
158        download: Whether to download the data if it is not present.
159        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
160
161    Returns:
162        The DataLoader.
163    """
164    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
165    dataset = get_cd47_ihcnusc_dataset(path, patch_shape, split, label_choice, download, **ds_kwargs)
166    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the CD47-IHCNuSC dataloader for nucleus segmentation.

Arguments:
  • path: Filepath to a folder where the downloaded data is saved.
  • batch_size: The batch size for training.
  • patch_shape: The patch shape to use for training.
  • split: The choice of data split. Either 'train' or 'val' (the validation / test split of the authors).
  • label_choice: The choice of labels, 'instances' or 'semantic' (the nucleus types, see 'TYPES').
  • 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.