torch_em.data.datasets.electron_microscopy.tnbc_mito
The TNBC-Mito dataset contains annotations for semantic segmentation of mitochondria in transmission electron microscopy (TEM) images of triple-negative breast cancer (TNBC) models and Drp1-deficient mouse skeletal muscle.
The data covers four cohorts: DRP1-KO (Drp1-deficient mouse primary skeletal muscle cells), HCI-010 and PIM001-P (TNBC patient-derived xenograft models), and Mixture (a pool of TNBC cell-line and xenograft images).
The dataset is available at https://www.ebi.ac.uk/biostudies/bioimages/studies/S-BIAD2271 under the CC0 license. The dataset was published in https://doi.org/10.1101/2025.02.19.635300. Please cite this publication if you use the dataset in your research.
1"""The TNBC-Mito dataset contains annotations for semantic segmentation of mitochondria in transmission 2electron microscopy (TEM) images of triple-negative breast cancer (TNBC) models and Drp1-deficient mouse 3skeletal muscle. 4 5The data covers four cohorts: DRP1-KO (Drp1-deficient mouse primary skeletal muscle cells), HCI-010 and 6PIM001-P (TNBC patient-derived xenograft models), and Mixture (a pool of TNBC cell-line and xenograft images). 7 8The dataset is available at https://www.ebi.ac.uk/biostudies/bioimages/studies/S-BIAD2271 under the CC0 license. 9The dataset was published in https://doi.org/10.1101/2025.02.19.635300. 10Please cite this publication if you use the dataset in your research. 11""" 12 13import os 14from glob import glob 15from typing import List, Literal, Optional, Tuple, Union 16 17from torch.utils.data import DataLoader, Dataset 18 19import torch_em 20 21from .. import util 22 23 24BASE_URL = "https://ftp.ebi.ac.uk/biostudies/fire/S-BIAD/271/S-BIAD2271/Files" 25MANIFEST_URL = f"{BASE_URL}/tem-seg-data_mitochondria_masks.tsv" 26 27COHORTS = ("DRP1-KO", "HCI-010", "Mixture", "PIM001-P") 28SPLIT_DIRS = {"tra_val": "tra_val", "tst": "tst"} 29 30 31def _read_manifest(manifest_path): 32 """Parse the mask-to-source-image manifest into (mask_path, image_path) tuples.""" 33 pairs = [] 34 with open(manifest_path) as f: 35 next(f) # Skip the header line. 36 for line in f: 37 mask_path, image_path = line.strip().split("\t") 38 pairs.append((mask_path, image_path)) 39 return pairs 40 41 42def get_tnbc_mito_data(path: Union[os.PathLike, str], download: bool = False) -> str: 43 """Download the TNBC-Mito dataset. 44 45 Args: 46 path: Filepath to a folder where the downloaded data will be saved. 47 download: Whether to download the data if it is not present. 48 49 Returns: 50 The filepath to the folder that mirrors the remote 'tem-seg/data' directory structure. 51 """ 52 data_root = os.path.join(path, "tem-seg", "data") 53 marker = os.path.join(path, ".download_complete") 54 if os.path.exists(marker): 55 return data_root 56 57 os.makedirs(path, exist_ok=True) 58 59 manifest_path = os.path.join(path, "tem-seg-data_mitochondria_masks.tsv") 60 util.download_source(manifest_path, MANIFEST_URL, download, checksum=None) 61 pairs = _read_manifest(manifest_path) 62 63 for mask_rel, image_rel in pairs: 64 mask_path = os.path.join(path, mask_rel) 65 image_path = os.path.join(path, image_rel) 66 os.makedirs(os.path.dirname(mask_path), exist_ok=True) 67 os.makedirs(os.path.dirname(image_path), exist_ok=True) 68 util.download_source(mask_path, f"{BASE_URL}/{mask_rel}", download, checksum=None) 69 util.download_source(image_path, f"{BASE_URL}/{image_rel}", download, checksum=None) 70 _normalize_mask(mask_path) 71 72 with open(marker, "w"): 73 pass 74 75 return data_root 76 77 78def _normalize_mask(mask_path): 79 """Re-save a palette-indexed mask PNG as a single-channel TIFF. 80 81 The source masks are palette ('P' mode) PNGs. Generic image readers expand palette images to RGB, 82 which breaks single-channel label loading, so this writes the raw index values (already 0/1) once 83 as a plain grayscale TIFF next to the original file. 84 """ 85 import numpy as np 86 import tifffile 87 from PIL import Image 88 89 normalized_path = f"{os.path.splitext(mask_path)[0]}.tif" 90 if os.path.exists(normalized_path): 91 return 92 labels = np.array(Image.open(mask_path)) 93 tifffile.imwrite(normalized_path, labels.astype("uint8")) 94 95 96def get_tnbc_mito_paths( 97 path: Union[os.PathLike, str], 98 split: Literal["tra_val", "tst"], 99 cohort: Optional[str] = None, 100 download: bool = False, 101) -> Tuple[List[str], List[str]]: 102 """Get paths to the TNBC-Mito raw images and mitochondria masks. 103 104 Args: 105 path: Filepath to a folder where the downloaded data will be saved. 106 split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test). 107 cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. 108 If None, uses all cohorts that provide the requested split. 109 download: Whether to download the data if it is not present. 110 111 Returns: 112 The list of raw image paths. 113 The list of mitochondria mask paths. 114 """ 115 assert split in SPLIT_DIRS, f"split must be one of {list(SPLIT_DIRS)}, got {split!r}" 116 if cohort is not None: 117 assert cohort in COHORTS, f"cohort must be one of {COHORTS}, got {cohort!r}" 118 119 data_root = get_tnbc_mito_data(path, download) 120 121 cohorts = [cohort] if cohort is not None else list(COHORTS) 122 raw_paths, label_paths = [], [] 123 for c in cohorts: 124 image_dir = os.path.join(data_root, c, split, "slide_images") 125 mask_dir = os.path.join(data_root, c, split, "mitochondria", "masks") 126 if not os.path.exists(image_dir): 127 continue 128 images = sorted(glob(os.path.join(image_dir, "*.tif"))) 129 for image_path in images: 130 fname = os.path.splitext(os.path.basename(image_path))[0] 131 mask_path = os.path.join(mask_dir, f"{fname}.tif") 132 assert os.path.exists(mask_path), f"Missing normalized mask for '{image_path}' at '{mask_path}'" 133 raw_paths.append(image_path) 134 label_paths.append(mask_path) 135 136 assert len(raw_paths) > 0, f"No images found for split '{split}' (cohort={cohort}) in '{data_root}'" 137 return raw_paths, label_paths 138 139 140def get_tnbc_mito_dataset( 141 path: Union[os.PathLike, str], 142 split: Literal["tra_val", "tst"], 143 patch_shape: Tuple[int, int], 144 cohort: Optional[str] = None, 145 download: bool = False, 146 **kwargs, 147) -> Dataset: 148 """Get the TNBC-Mito dataset for mitochondria segmentation in TEM images. 149 150 Args: 151 path: Filepath to a folder where the downloaded data will be saved. 152 split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test). 153 patch_shape: The patch shape to use for training. 154 cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. 155 If None, uses all cohorts that provide the requested split. 156 download: Whether to download the data if it is not present. 157 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 158 159 Returns: 160 The segmentation dataset. 161 """ 162 raw_paths, label_paths = get_tnbc_mito_paths(path, split, cohort, download) 163 return torch_em.default_segmentation_dataset( 164 raw_paths=raw_paths, 165 raw_key=None, 166 label_paths=label_paths, 167 label_key=None, 168 patch_shape=patch_shape, 169 is_seg_dataset=False, 170 **kwargs, 171 ) 172 173 174def get_tnbc_mito_loader( 175 path: Union[os.PathLike, str], 176 split: Literal["tra_val", "tst"], 177 patch_shape: Tuple[int, int], 178 batch_size: int, 179 cohort: Optional[str] = None, 180 download: bool = False, 181 **kwargs, 182) -> DataLoader: 183 """Get the TNBC-Mito dataloader for mitochondria segmentation in TEM images. 184 185 Args: 186 path: Filepath to a folder where the downloaded data will be saved. 187 split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test). 188 patch_shape: The patch shape to use for training. 189 batch_size: The batch size for training. 190 cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. 191 If None, uses all cohorts that provide the requested split. 192 download: Whether to download the data if it is not present. 193 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch 194 DataLoader. 195 196 Returns: 197 The PyTorch DataLoader. 198 """ 199 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 200 dataset = get_tnbc_mito_dataset(path, split, patch_shape, cohort=cohort, download=download, **ds_kwargs) 201 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
43def get_tnbc_mito_data(path: Union[os.PathLike, str], download: bool = False) -> str: 44 """Download the TNBC-Mito dataset. 45 46 Args: 47 path: Filepath to a folder where the downloaded data will be saved. 48 download: Whether to download the data if it is not present. 49 50 Returns: 51 The filepath to the folder that mirrors the remote 'tem-seg/data' directory structure. 52 """ 53 data_root = os.path.join(path, "tem-seg", "data") 54 marker = os.path.join(path, ".download_complete") 55 if os.path.exists(marker): 56 return data_root 57 58 os.makedirs(path, exist_ok=True) 59 60 manifest_path = os.path.join(path, "tem-seg-data_mitochondria_masks.tsv") 61 util.download_source(manifest_path, MANIFEST_URL, download, checksum=None) 62 pairs = _read_manifest(manifest_path) 63 64 for mask_rel, image_rel in pairs: 65 mask_path = os.path.join(path, mask_rel) 66 image_path = os.path.join(path, image_rel) 67 os.makedirs(os.path.dirname(mask_path), exist_ok=True) 68 os.makedirs(os.path.dirname(image_path), exist_ok=True) 69 util.download_source(mask_path, f"{BASE_URL}/{mask_rel}", download, checksum=None) 70 util.download_source(image_path, f"{BASE_URL}/{image_rel}", download, checksum=None) 71 _normalize_mask(mask_path) 72 73 with open(marker, "w"): 74 pass 75 76 return data_root
Download the TNBC-Mito dataset.
Arguments:
- path: Filepath to a folder where the downloaded data will be saved.
- download: Whether to download the data if it is not present.
Returns:
The filepath to the folder that mirrors the remote 'tem-seg/data' directory structure.
97def get_tnbc_mito_paths( 98 path: Union[os.PathLike, str], 99 split: Literal["tra_val", "tst"], 100 cohort: Optional[str] = None, 101 download: bool = False, 102) -> Tuple[List[str], List[str]]: 103 """Get paths to the TNBC-Mito raw images and mitochondria masks. 104 105 Args: 106 path: Filepath to a folder where the downloaded data will be saved. 107 split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test). 108 cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. 109 If None, uses all cohorts that provide the requested split. 110 download: Whether to download the data if it is not present. 111 112 Returns: 113 The list of raw image paths. 114 The list of mitochondria mask paths. 115 """ 116 assert split in SPLIT_DIRS, f"split must be one of {list(SPLIT_DIRS)}, got {split!r}" 117 if cohort is not None: 118 assert cohort in COHORTS, f"cohort must be one of {COHORTS}, got {cohort!r}" 119 120 data_root = get_tnbc_mito_data(path, download) 121 122 cohorts = [cohort] if cohort is not None else list(COHORTS) 123 raw_paths, label_paths = [], [] 124 for c in cohorts: 125 image_dir = os.path.join(data_root, c, split, "slide_images") 126 mask_dir = os.path.join(data_root, c, split, "mitochondria", "masks") 127 if not os.path.exists(image_dir): 128 continue 129 images = sorted(glob(os.path.join(image_dir, "*.tif"))) 130 for image_path in images: 131 fname = os.path.splitext(os.path.basename(image_path))[0] 132 mask_path = os.path.join(mask_dir, f"{fname}.tif") 133 assert os.path.exists(mask_path), f"Missing normalized mask for '{image_path}' at '{mask_path}'" 134 raw_paths.append(image_path) 135 label_paths.append(mask_path) 136 137 assert len(raw_paths) > 0, f"No images found for split '{split}' (cohort={cohort}) in '{data_root}'" 138 return raw_paths, label_paths
Get paths to the TNBC-Mito raw images and mitochondria masks.
Arguments:
- path: Filepath to a folder where the downloaded data will be saved.
- split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test).
- cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. If None, uses all cohorts that provide the requested split.
- download: Whether to download the data if it is not present.
Returns:
The list of raw image paths. The list of mitochondria mask paths.
141def get_tnbc_mito_dataset( 142 path: Union[os.PathLike, str], 143 split: Literal["tra_val", "tst"], 144 patch_shape: Tuple[int, int], 145 cohort: Optional[str] = None, 146 download: bool = False, 147 **kwargs, 148) -> Dataset: 149 """Get the TNBC-Mito dataset for mitochondria segmentation in TEM images. 150 151 Args: 152 path: Filepath to a folder where the downloaded data will be saved. 153 split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test). 154 patch_shape: The patch shape to use for training. 155 cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. 156 If None, uses all cohorts that provide the requested split. 157 download: Whether to download the data if it is not present. 158 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 159 160 Returns: 161 The segmentation dataset. 162 """ 163 raw_paths, label_paths = get_tnbc_mito_paths(path, split, cohort, download) 164 return torch_em.default_segmentation_dataset( 165 raw_paths=raw_paths, 166 raw_key=None, 167 label_paths=label_paths, 168 label_key=None, 169 patch_shape=patch_shape, 170 is_seg_dataset=False, 171 **kwargs, 172 )
Get the TNBC-Mito dataset for mitochondria segmentation in TEM images.
Arguments:
- path: Filepath to a folder where the downloaded data will be saved.
- split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test).
- patch_shape: The patch shape to use for training.
- cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. If None, uses all cohorts that provide the requested split.
- 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.
175def get_tnbc_mito_loader( 176 path: Union[os.PathLike, str], 177 split: Literal["tra_val", "tst"], 178 patch_shape: Tuple[int, int], 179 batch_size: int, 180 cohort: Optional[str] = None, 181 download: bool = False, 182 **kwargs, 183) -> DataLoader: 184 """Get the TNBC-Mito dataloader for mitochondria segmentation in TEM images. 185 186 Args: 187 path: Filepath to a folder where the downloaded data will be saved. 188 split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test). 189 patch_shape: The patch shape to use for training. 190 batch_size: The batch size for training. 191 cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. 192 If None, uses all cohorts that provide the requested split. 193 download: Whether to download the data if it is not present. 194 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch 195 DataLoader. 196 197 Returns: 198 The PyTorch DataLoader. 199 """ 200 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 201 dataset = get_tnbc_mito_dataset(path, split, patch_shape, cohort=cohort, download=download, **ds_kwargs) 202 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
Get the TNBC-Mito dataloader for mitochondria segmentation in TEM images.
Arguments:
- path: Filepath to a folder where the downloaded data will be saved.
- split: The data split. Either 'tra_val' (pooled train / validation) or 'tst' (test).
- patch_shape: The patch shape to use for training.
- batch_size: The batch size for training.
- cohort: The cohort to restrict to. One of 'DRP1-KO', 'HCI-010', 'Mixture', 'PIM001-P'. If None, uses all cohorts that provide the requested split.
- 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 PyTorch DataLoader.