torch_em.data.datasets.light_microscopy.cellbindb
CellBinDB contains annotations for cell segmentation in multi-modal images.
- Consists of DAPI, ssDNA, H&E, and mIF staining.
- Covers more than 30 normal and diseased tissue types from human and mouse samples.
The dataset is located at https://db.cngb.org/search/project/CNP0006370/. This dataset is from the publication https://doi.org/10.1101/2024.11.20.619750. Please cite it if you use this dataset for your research.
1"""CellBinDB contains annotations for cell segmentation in multi-modal images. 2- Consists of DAPI, ssDNA, H&E, and mIF staining. 3- Covers more than 30 normal and diseased tissue types from human and mouse samples. 4 5The dataset is located at https://db.cngb.org/search/project/CNP0006370/. 6This dataset is from the publication https://doi.org/10.1101/2024.11.20.619750. 7Please cite it if you use this dataset for your research. 8""" 9 10import os 11import warnings 12import subprocess 13from glob import glob 14from natsort import natsorted 15from typing import Union, Tuple, List, Optional 16 17import torch_em 18 19from torch.utils.data import Dataset, DataLoader 20 21from .. import util 22from .neurips_cell_seg import to_rgb 23 24 25DOWNLOAD_SCRIPT = 'wget -c -nH -np -r -R "index.html*" --cut-dirs 4 ftp://ftp.cngb.org/pub/CNSA/data5/CNP0006370/Other/' 26 27# Files that are corrupted in the source archive (5 of 1044 pairs): one truncated ssDNA image and four 28# instance masks that are not TIFF files. Their image-label pairs are skipped. 29CORRUPTED_FILES = { 30 "HH799999864GO_W8_36_62-img.tif", 31 "X98668W8-x10151_y9176_w256_h256-instancemask.tif", 32 "Z98801V5-x15153_y13890_w256_h256-instancemask.tif", 33 "HH799999356_M1-x1536_y9216_w512_h512-instancemask.tif", 34 "X97754Z3-x17024_y19696_w512_h512-instancemask.tif", 35} 36 37CHOICES = ["10×Genomics_DAPI", "10×Genomics_HE", "DAPI", "HE", "mIF", "ssDNA"] 38 39 40def get_cellbindb_data(path: Union[os.PathLike, str], download: bool = False) -> str: 41 """Download the CellBinDB dataset. 42 43 Args: 44 path: Filepath to a folder where the data is downloaded. 45 download: Whether to download the data if it is not present. 46 47 Returns: 48 The filepath to the data. 49 """ 50 data_dir = os.path.join(path, "Other") 51 if os.path.exists(data_dir): 52 return data_dir 53 54 os.makedirs(path, exist_ok=True) 55 56 if not download: 57 raise AssertionError("The dataset is not found and download is set to 'False'.") 58 59 print( 60 "Downloading the dataset takes several hours and is extremely (like very very) slow. " 61 "Make sure you have consistent internet connection or run it in background over a cluster." 62 ) 63 splits = DOWNLOAD_SCRIPT.split(" ") 64 subprocess.run([*splits[:-1], "-P", os.path.abspath(path), splits[-1]]) 65 return data_dir 66 67 68def get_cellbindb_paths( 69 path: Union[os.PathLike, str], data_choice: Optional[Union[str, List[str]]] = None, download: bool = False 70) -> Tuple[List[str], List[str]]: 71 """Get paths to the CellBinDB data. 72 73 Args: 74 path: Filepath to a folder where the data is downloaded. 75 data_choice: The choice of datasets. 76 download: Whether to download the data if it is not present. 77 78 Returns: 79 List of filepaths for the image data. 80 List of filepaths for the label data. 81 """ 82 data_dir = get_cellbindb_data(path, download) 83 84 if data_choice is None: 85 data_choice = CHOICES 86 else: 87 if isinstance(data_choice, str): 88 data_choice = [data_choice] 89 90 raw_paths, label_paths = [], [] 91 for dchoice in data_choice: 92 assert dchoice in CHOICES, f"'{dchoice}' is not a valid data choice." 93 raw_paths.extend(natsorted(glob(os.path.join(data_dir, dchoice, "*", "*-img.tif")))) 94 label_paths.extend(natsorted(glob(os.path.join(data_dir, dchoice, "*", "*-instancemask.tif")))) 95 96 # NOTE: Some files are corrupted from source. Since it's just a few of them, let's bump them out. 97 valid_paired_images = [ 98 (rp, lp) for rp, lp in zip(raw_paths, label_paths) 99 if not {os.path.basename(rp), os.path.basename(lp)} & CORRUPTED_FILES 100 and _is_valid_image(rp) and _is_valid_image(lp) 101 ] 102 raw_paths, label_paths = zip(*valid_paired_images) 103 raw_paths, label_paths = list(raw_paths), list(label_paths) 104 105 assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0 106 107 return raw_paths, label_paths 108 109 110def _is_valid_image(im_path): 111 import tifffile 112 113 try: 114 _ = tifffile.imread(im_path) 115 return True 116 except Exception as e: 117 warnings.warn(f"Skipping the corrupted CellBinDB file '{im_path}': {type(e).__name__}: {e}") 118 return False 119 120 121def get_cellbindb_dataset( 122 path: Union[os.PathLike, str], 123 patch_shape: Tuple[int, int], 124 data_choice: Optional[Union[str, List[str]]] = None, 125 download: bool = False, 126 **kwargs 127) -> Dataset: 128 """Get the CellBinDB dataset for cell segmentation. 129 130 Args: 131 path: Filepath to a folder where the data is downloaded. 132 patch_shape: The patch shape to use for training. 133 data_choice: The choice of datasets. 134 download: Whether to download the data if it is not present. 135 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 136 137 Returns: 138 The segmentation dataset. 139 """ 140 raw_paths, label_paths = get_cellbindb_paths(path, data_choice, download) 141 142 if "raw_transform" not in kwargs: 143 kwargs["raw_transform"] = torch_em.transform.get_raw_transform(augmentation2=to_rgb) 144 145 return torch_em.default_segmentation_dataset( 146 raw_paths=raw_paths, 147 raw_key=None, 148 label_paths=label_paths, 149 label_key=None, 150 is_seg_dataset=False, 151 ndim=2, 152 patch_shape=patch_shape, 153 **kwargs 154 ) 155 156 157def get_cellbindb_loader( 158 path: Union[os.PathLike, str], 159 batch_size: int, 160 patch_shape: Tuple[int, int], 161 data_choice: Optional[Union[str, List[str]]] = None, 162 download: bool = False, 163 **kwargs 164) -> DataLoader: 165 """Get the CellBinDB dataloader for cell segmentation. 166 167 Args: 168 path: Filepath to a folder where the data is downloaded. 169 patch_shape: The patch shape to use for training. 170 data_choice: The choice of datasets. 171 download: Whether to download the data if it is not present. 172 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 173 174 Returns: 175 The DataLoader. 176 """ 177 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 178 dataset = get_cellbindb_dataset(path, patch_shape, data_choice, download, **ds_kwargs) 179 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
DOWNLOAD_SCRIPT =
'wget -c -nH -np -r -R "index.html*" --cut-dirs 4 ftp://ftp.cngb.org/pub/CNSA/data5/CNP0006370/Other/'
CORRUPTED_FILES =
{'Z98801V5-x15153_y13890_w256_h256-instancemask.tif', 'HH799999864GO_W8_36_62-img.tif', 'X97754Z3-x17024_y19696_w512_h512-instancemask.tif', 'HH799999356_M1-x1536_y9216_w512_h512-instancemask.tif', 'X98668W8-x10151_y9176_w256_h256-instancemask.tif'}
CHOICES =
['10×Genomics_DAPI', '10×Genomics_HE', 'DAPI', 'HE', 'mIF', 'ssDNA']
def
get_cellbindb_data(path: Union[os.PathLike, str], download: bool = False) -> str:
41def get_cellbindb_data(path: Union[os.PathLike, str], download: bool = False) -> str: 42 """Download the CellBinDB dataset. 43 44 Args: 45 path: Filepath to a folder where the data is downloaded. 46 download: Whether to download the data if it is not present. 47 48 Returns: 49 The filepath to the data. 50 """ 51 data_dir = os.path.join(path, "Other") 52 if os.path.exists(data_dir): 53 return data_dir 54 55 os.makedirs(path, exist_ok=True) 56 57 if not download: 58 raise AssertionError("The dataset is not found and download is set to 'False'.") 59 60 print( 61 "Downloading the dataset takes several hours and is extremely (like very very) slow. " 62 "Make sure you have consistent internet connection or run it in background over a cluster." 63 ) 64 splits = DOWNLOAD_SCRIPT.split(" ") 65 subprocess.run([*splits[:-1], "-P", os.path.abspath(path), splits[-1]]) 66 return data_dir
Download the CellBinDB dataset.
Arguments:
- path: Filepath to a folder where the data is downloaded.
- download: Whether to download the data if it is not present.
Returns:
The filepath to the data.
def
get_cellbindb_paths( path: Union[os.PathLike, str], data_choice: Union[List[str], str, NoneType] = None, download: bool = False) -> Tuple[List[str], List[str]]:
69def get_cellbindb_paths( 70 path: Union[os.PathLike, str], data_choice: Optional[Union[str, List[str]]] = None, download: bool = False 71) -> Tuple[List[str], List[str]]: 72 """Get paths to the CellBinDB data. 73 74 Args: 75 path: Filepath to a folder where the data is downloaded. 76 data_choice: The choice of datasets. 77 download: Whether to download the data if it is not present. 78 79 Returns: 80 List of filepaths for the image data. 81 List of filepaths for the label data. 82 """ 83 data_dir = get_cellbindb_data(path, download) 84 85 if data_choice is None: 86 data_choice = CHOICES 87 else: 88 if isinstance(data_choice, str): 89 data_choice = [data_choice] 90 91 raw_paths, label_paths = [], [] 92 for dchoice in data_choice: 93 assert dchoice in CHOICES, f"'{dchoice}' is not a valid data choice." 94 raw_paths.extend(natsorted(glob(os.path.join(data_dir, dchoice, "*", "*-img.tif")))) 95 label_paths.extend(natsorted(glob(os.path.join(data_dir, dchoice, "*", "*-instancemask.tif")))) 96 97 # NOTE: Some files are corrupted from source. Since it's just a few of them, let's bump them out. 98 valid_paired_images = [ 99 (rp, lp) for rp, lp in zip(raw_paths, label_paths) 100 if not {os.path.basename(rp), os.path.basename(lp)} & CORRUPTED_FILES 101 and _is_valid_image(rp) and _is_valid_image(lp) 102 ] 103 raw_paths, label_paths = zip(*valid_paired_images) 104 raw_paths, label_paths = list(raw_paths), list(label_paths) 105 106 assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0 107 108 return raw_paths, label_paths
Get paths to the CellBinDB data.
Arguments:
- path: Filepath to a folder where the data is downloaded.
- data_choice: The choice of datasets.
- 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_cellbindb_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, int], data_choice: Union[List[str], str, NoneType] = None, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
122def get_cellbindb_dataset( 123 path: Union[os.PathLike, str], 124 patch_shape: Tuple[int, int], 125 data_choice: Optional[Union[str, List[str]]] = None, 126 download: bool = False, 127 **kwargs 128) -> Dataset: 129 """Get the CellBinDB dataset for cell segmentation. 130 131 Args: 132 path: Filepath to a folder where the data is downloaded. 133 patch_shape: The patch shape to use for training. 134 data_choice: The choice of datasets. 135 download: Whether to download the data if it is not present. 136 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 137 138 Returns: 139 The segmentation dataset. 140 """ 141 raw_paths, label_paths = get_cellbindb_paths(path, data_choice, download) 142 143 if "raw_transform" not in kwargs: 144 kwargs["raw_transform"] = torch_em.transform.get_raw_transform(augmentation2=to_rgb) 145 146 return torch_em.default_segmentation_dataset( 147 raw_paths=raw_paths, 148 raw_key=None, 149 label_paths=label_paths, 150 label_key=None, 151 is_seg_dataset=False, 152 ndim=2, 153 patch_shape=patch_shape, 154 **kwargs 155 )
Get the CellBinDB dataset for cell segmentation.
Arguments:
- path: Filepath to a folder where the data is downloaded.
- patch_shape: The patch shape to use for training.
- data_choice: The choice of datasets.
- 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_cellbindb_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, int], data_choice: Union[List[str], str, NoneType] = None, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
158def get_cellbindb_loader( 159 path: Union[os.PathLike, str], 160 batch_size: int, 161 patch_shape: Tuple[int, int], 162 data_choice: Optional[Union[str, List[str]]] = None, 163 download: bool = False, 164 **kwargs 165) -> DataLoader: 166 """Get the CellBinDB dataloader for cell segmentation. 167 168 Args: 169 path: Filepath to a folder where the data is downloaded. 170 patch_shape: The patch shape to use for training. 171 data_choice: The choice of datasets. 172 download: Whether to download the data if it is not present. 173 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 174 175 Returns: 176 The DataLoader. 177 """ 178 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 179 dataset = get_cellbindb_dataset(path, patch_shape, data_choice, download, **ds_kwargs) 180 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
Get the CellBinDB dataloader for cell segmentation.
Arguments:
- path: Filepath to a folder where the data is downloaded.
- patch_shape: The patch shape to use for training.
- data_choice: The choice of datasets.
- 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.