API Reference

The API of DeLTA.

Assets

Asset downloads (model files, training sets, and demonstration movies).

We provide our trained models, training sets, and evaluation movies in this google drive folder. We refer to these data files as “assets”.

You can of course download them manually, but shouldn’t have to, because DeLTA knows where to find them and downloads them automatically when needed, with the pooch library, which makes everything completely transparent.

Cache location

Upon downloading the assets, DeLTA caches them in the default OS cache location (see the pooch documentation for details). If you want to download them to a different location, you can specify this path in the DELTA_ASSETS_CACHE environment variable.

For example, to set this variable permanently within your conda environment, you can run the following command in a terminal, inside your conda environment:

(delta_env)$ conda env config vars set DELTA_ASSETS_CACHE="D:/data/delta_cache"
delta.assets.download_demo_movie(presets: Literal['2D', 'mothermachine']) Path[source]

Return the path of the demo movie for the currently loaded configuration.

If necessary, it downloads it first and caches it under a directory that can be specified by the environment variable DELTA_ASSETS_CACHE.

Parameters:
presetsPRESETS

2D or mothermachine

Returns:
pathPath

Path of the demo movie.

delta.assets.download_model(presets: Literal['2D', 'mothermachine'], model: Literal['rois', 'seg', 'track']) Path[source]

Return the path of the downloaded model, after downloading it if needed.

Parameters:
presets: PRESETS

2D or mothermachine

model: MODEL

seg, track or rois

Returns:
path: Path

Path of the downloaded model.

delta.assets.download_training_set(presets: Literal['2D', 'mothermachine'], model: Literal['rois', 'seg', 'track']) Path[source]

Return the path of the training set for the currently loaded configuration.

Depending on the current value of presets (“2D” or “mothermachine”) and of the value of the argument model (“rois”, “seg” or “track”), this function returns the path of the corresponding training set. If necessary, it downloads it first and caches it under a directory that can be specified by the environment variable DELTA_ASSETS_CACHE.

Parameters:
presetsPRESETS

2D or mothermachine

modelstr

Type of training set: rois, seg or track.

Returns:
pathPath

Path of the training set.

Configuration

Define, read and write DeLTA’s configuration.

class delta.config.BackendConfig(number_of_cores: int | None, memory_growth_limit: int | None)[source]

Configuration class containing Backend parameters.

apply_config() None[source]

Apply this configuration to the keras backend.

memory_growth_limit: int | None[source]

If running into OOM issues or having trouble with CuDNN loading, try setting this to a value in MB: 1024, 2048, etc.

number_of_cores: int | None[source]

This will limit the number of cores the backend can use. Default value of this will have the backend determine the number of cores.

update(key: str, value: int) None[source]

Update in place the configuration with the given key and value.

Parameters:
keystr

Config key to update.

valueAny

Value for the given key.

class delta.config.Config(models: dict[str, ModelConfig], backends: dict[str, BackendConfig], correct_rotation: bool, correct_drift: bool, whole_frame_drift: bool = False)[source]

Configuration class containing DeLTA parameters.

apply_backend_config() None[source]

Apply the relevant config settings to the keras backend.

backends: dict[str, BackendConfig][source]

Sub-configs for the deep learning backends.

correct_drift: bool[source]

Whether or not to correct for drift over time (mothermachine only).

correct_rotation: bool[source]

Whether or not to correct for image rotation (mothermachine only).

classmethod default(presets: Literal['2D', 'mothermachine']) Config[source]

Return the default config for this preset.

Parameters:
presetsPRESETS

Can be “2D” or “mothermachine”.

Returns:
configConfig

Config object.

classmethod deserialize(json_str: str) Config[source]

Build a configuration from a JSON string.

Parameters:
json_strstr

JSON string containing a serialized configuration.

models: dict[str, ModelConfig][source]

Sub-configs for the deep learning models.

static read(path: str | Path) Config[source]

Read a configuration file.

Parameters:
pathstr | Path

Path to specific configuration file.

Returns:
configConfig

Loaded config object.

serialize() str[source]

Return a JSON string describing the configuration.

update(key: str, value) None[source]

Update in place the configuration with the given key and value.

Parameters:
keystr

Config key to update.

valueAny

Value for the given key.

whole_frame_drift: bool = False[source]

If correcting for drift, use the entire frame instead of the region above the chambers (mothermachine only).

write(path: str | Path) None[source]

Write a configuration file.

Parameters:
pathstr | Path

Path to configuration file to write.

class delta.config.ModelConfig(model_path: Path, target_size: tuple[int, int], min_area: float, tolerable_resizing_factor: float, batch_size: int, chunk_size: int)[source]

Configuration class containing Model parameters.

batch_size: int[source]

Number of images processed at the same time by the model. If running into OOM issues with the pipeline, try lowering this value. You can also increase it to improve speed.

chunk_size: int[source]

Number of images processed at the same time by the model. If running into OOM issues with the pipeline, try lowering this value. You can also increase it to improve speed.

classmethod default(model: Literal['rois', 'seg', 'track'], presets: Literal['2D', 'mothermachine']) ModelConfig[source]

Return the default config for this model and preset.

Parameters:
modelMODEL

Can be “rois”, “seg” or “track”.

presetsPRESETS

Can be “2D” or “mothermachine”.

Returns:
configModelConfig

Config object.

min_area: float[source]

Minimal size of objects detected by this model, smaller objects will be removed (ROI and segmentation models only).

model() Model[source]

Return the keras model for the specified preset and model type.

If the variable model_file_(rois|seg|track) is non-empty in the configuration, it is assumed to be the filename of the model. If this variable is empty, we download the default model of DeLTA and cache it under a directory that can be optionally specified with the environment variable DELTA_ASSETS_CACHE.

Returns:
modelkeras.Model

The required model.

model_path: Path[source]

Path to the model file.

resizing_tolerable(shape: tuple[int, int]) bool[source]

Determine if resizing is tolerable for an image of this size.

Parameters:
shapetuple[int, int]

Shape of the image.

target_size: tuple[int, int][source]

Input size of the images for this model.

tolerable_resizing_factor: float[source]

Maximum tolerable resizing factor of the input image to scale it to target_size. On either axes (x and y), resizing only happens if ref < target * (tolerable_resizing_factor + 1) where ref is the size of the reference image on one axis, and target is the input size of the neural network defined in the config as target_size on the same axis. If the reference image is larger than that, it is cropped.

update(key: str, value) None[source]

Update in place the configuration with the given key and value.

Parameters:
keystr

Config key to update.

valueAny

Value for the given key.

delta.config.read_json(path: Path) dict[str, Any][source]

Read a JSON file containing a configuration.

This function converts the lists to tuples and the paths to Path s.

Parameters:
pathPath

Path of the file to read.

Returns:
variablesdict[str, Any]

Dictionary representing the JSON.

delta.config.read_toml(path: Path) Config[source]

Read a toml file containing a configuration.

This function converts the lists to tuples and the paths to Path s.

Parameters:
pathPath

Path of the file to read.

Returns:
configConfig

Configuration.

delta.config.write_toml(config: Config, path: Path) None[source]

Write a configuration to a toml file.

This function transforms the Path s to str.

Parameters:
configConfig

Configuration file to write.

pathPath

Path of the file to write.

Data

Data manipulations and input/output operations.

class delta.data.SegmentationDataset(dataset: tuple[list[Image], list[SegmentationMask], list[Image]], target_size: tuple[int, int], mode: Literal['training', 'evaluation'], *, kw_data_aug: dict[str, Any], crop: bool, rng: Generator, stack: bool = False, **kwargs: Unpack[_PyDatasetKwargs])[source]

Dataset used to train the segmentation model.

on_epoch_end() None[source]

Shuffle the samples.

Method executed after each epoch.

delta.data.data_augmentation(images_input: list[ndarray[tuple[Any, ...], dtype[Any]]], aug_par: dict[str, Any], order: int | list[int] | tuple[int, ...] = 0, rng: Generator | None = None) list[ndarray[tuple[Any, ...], dtype[Any]]][source]

Create an augmented sample based on data augmentation parameters.

Parameters:
images_inputlist of 2D numpy arrays

Images to apply augmentation operations to.

aug_pardict
Augmentation operations parameters. Accepted key-value pairs:
illumination_voodoo: bool

Whether to apply the illumination voodoo operation. It simulates a variation in illumination along the Y axis.

histogram_voodoo: bool

Whether to apply the histogram voodoo operation. It performs an elastic deformation on the image histogram to simulate changes in illumination.

elastic_deformation: dict

If this key exists, the elastic deformation operation is applied. The parameters are given as key-value pairs. Sigma values are given under the sigma key, deformation points are given under the points key, for example {"sigma": 25, "points": 5}. See the elasticdeform doc for more info.

gaussian_noise: float

Apply gaussian noise to the image. The sigma value of the gaussian noise is uniformly sampled between 0 and +gaussian_noise.

gaussain_blur: float

Apply gaussian blur to the image. The sigma value is the standard deviation of the kernel in the x and y direction.

horizontal_flip: bool

Whether to flip the images horizontally. Input images have a 50% chance of being flipped.

vertical_flip: bool

Whether to flip the images vertically. Input images have a 50% chance of being flipped

rotations90d: bool

Whether to randomly rotate the images in 90° increments. Each 90° rotation has a 25% chance of happening

resize: bool

Whether to randomly resize the image on both axes.

rotation: int or float

Range of random rotation to apply. The angle is uniformly sampled in the range [-rotation, +rotation].

zoom: float

Range of random “zoom” to apply. The image is randomly zoomed by a factor that is sampled from an exponential distribution with a lambda of 3/zoom. The random factor is clipped at +zoom.

shiftX: int/float

The range of random shifts to apply along X. A uniformly sampled shift between [-shiftX, +shiftX] is applied.

shiftY: int/float

The range of random shifts to apply along Y. A uniformly sampled shift between [-shiftY, +shiftY] is applied.

Note that the same operations are applied to all inputs except for the timeshift ones.

orderint or list/tuple of ints, optional

Interpolation order to use for each image in the input stack. If order is a scalar, the same order is applied to all images. If a list of orders is provided, each image in the stack will have its own operation order. See the skimage.transform.wrap doc. Note that the histogram voodoo operation is only applied to images with a non-zero order. The default is 0.

rngnpr.Generator | None

Numpy random number generator to use for data augmentation. If None, one will be created from entropy with np.random.default_rng(). The default is None.

Returns:
outputlist of 2D numpy arrays

Augmented images array.

delta.data.estimate_classweights(gene: Iterator, num_samples: int = 30) tuple[float, ...][source]

Estimate the class weights to use with the weighted categorical cross-entropy based on the train_generator_track() output.

Parameters:
genegenerator

Tracking U-Net training generator. (output of train_generator_seg/track)

num_samplesint, optional

Number of batches to use for estimation. The default is 30.

Returns:
class_weightstuple of floats

Relative weights of each class. Note that, if 0 elements of a certain class are present in the samples, the weight for this class will be set to 0.

delta.data.estimate_seg2D_classweights(mask_path: Path, sample_size: int | None = None, rng: Generator | None = None) tuple[float, float][source]

Estimate the weights to assign each class in the weight maps.

Parameters:
mask_pathstr

Path to folder containing segmentations.

sample_sizeint, optional

Determines the size of the training set that will be used to calculate class weights. The default is None.

rngnpr.Generator, optional

Pseudo-random number generator used to subsample the dataset if needed.

Returns:
class1float

weight of class 1.

class2float

weight of class 2.

delta.data.histogram_voodoo(image: Image, rng: Generator, num_control_points: int = 3) Image[source]

Perform a deformation on the image histogram to simulate illumination changes.

This function was kindly provided by Daniel Eaton from the Paulsson lab.

Parameters:
image2D numpy array

Input image.

rngnpr.Generator

Pseudo-random number generator.

num_control_pointsint, optional

Number of inflection points to use on the histogram conversion curve. The default is 3.

Returns:
2D numpy array

Modified image.

delta.data.illumination_voodoo(image: Image, rng: Generator, num_control_points: int = 5) Image[source]

Simulate a variation in illumination along the length of the chamber.

This function was inspired by the one above.

Parameters:
image2D numpy array

Input image.

rngnpr.Generator

Pseudo-random number generator.

num_control_pointsint, optional

Number of inflection points to use on the illumination multiplication curve. The default is 5.

Returns:
newimage2D numpy array

Modified image.

delta.data.kernel(n: int) SegmentationMask[source]

Get kernel for morphological operations.

Parameters:
nInt

Determine size of kernel.

Returns:
kernelArray of unit8

Returns a kernel with size of n.

delta.data.load_training_dataset_seg(dataset_path: Path, target_size: tuple[int, int], *, crop: bool, kw_data_aug: dict[str, Any], validation_split: Literal[0] = 0, test_split: Literal[0] = 0, seed: int = 1, stack: bool = False) SegmentationDataset[source]
delta.data.load_training_dataset_seg(dataset_path: Path, target_size: tuple[int, int], *, crop: bool, kw_data_aug: dict[str, Any], validation_split: float, test_split: Literal[0] = 0, seed: int = 1, stack: bool = False) tuple[SegmentationDataset, SegmentationDataset]
delta.data.load_training_dataset_seg(dataset_path: Path, target_size: tuple[int, int], *, crop: bool, kw_data_aug: dict[str, Any], validation_split: Literal[0] = 0, test_split: float, seed: int = 1, stack: bool = False) tuple[SegmentationDataset, SegmentationDataset]
delta.data.load_training_dataset_seg(dataset_path: Path, target_size: tuple[int, int], *, crop: bool, kw_data_aug: dict[str, Any], validation_split: float, test_split: float, seed: int = 1, stack: bool = False) tuple[SegmentationDataset, SegmentationDataset, SegmentationDataset]

Create new segmentation datasets.

Parameters:
dataset_pathPath

Path of the folder that contains subfolders img, seg and optionally wei.

target_size(int, int)

Target size of the images (input size of the neural network).

cropbool

If True, the images are cropped to the target size, if False, they are resized. Typically we resize mother machine images and crop 2D pad images.

kw_data_augdict[str, Any]

Parameters for the data augmentation function (see data_augmentation()).

validation_splitfloat, optional

Proportion (between 0 and 1) of the input images used for the validation set. The default is 0.

test_splitfloat, optional

Proportion (between 0 and 1) of the input images used for the test set. The default is 0.

seedint, optional

Seed for the random number generator. The default is 1.

stackbool, optional

Whether to stack the labels and weights. This is a technicality that should be removed soon. For now, specify True for cell segmentation and False for RoI segmentation (follow the example scripts).

Returns:
train_dsSegmentationDataset,
validation_dsSegmentationDataset, (optional)
test_dsSegmentationDataset, (optional)
delta.data.make_weights(training_dataset_path: str | Path, weights_function: Callable[[SegmentationMask], ndarray[tuple[Any, ...], dtype[float32]]]) None[source]

Create and populate the directory training_dataset_path/wei with the image weights for training.

The directory training_dataset_path should already contain “img” with the input images and “seg” with the segmentation masks (images with 0 for background pixels and 255 for cell pixels).

Parameters:
training_dataset_pathstr or Path

Directory containing two directories: “img” for the images and “seg” for the segmentation masks. A third directory “wei” will be created inside for the weights.

weights_functionCallable[SegmentationMask, npt.NDArray[np.float32]],

Function that takes a segmentation mask (0 for background and 1 for cells) and returns a weight array (non-negative floats). The weights will be normalized by their maximum before being written down as images. Possible values are seg_weights() for mothermachine images, seg_weights_2D() for 2D pads, or custom functions or lambdas.

delta.data.path_from_prototype(prototype: str, fileorder: str, position: int | None = None, chamber: int | None = None, frame: int | None = None, cellnb: int | None = None) Path[source]

Generate full filename for specific frame based on file path, prototype, fileorder, and filenamesindexing.

Parameters:
prototypestr

Filename prototype, written in c-style format. See delta.utils.xpreader for more details

fileorderstr

Filenames ordering. See delta.utils.xpreader for more details

positionint, optional

Position/series index (0-based indexing).

chamberint, optional

Imaging chamber index (0-based indexing).

frameint, optional

Frame/timepoint index (0-based indexing).

cellnb: int, optional

Cell index (0-based indexing).

Returns:
string

Filename.

delta.data.predict_compile_from_seg_track(img_path: Path, seg_path: Path, files_list: list[Path], *, target_size: tuple[int, int] = (256, 32), crop_windows: bool = False) tuple[ndarray[tuple[Any, ...], dtype[float32]], list[Path], list[CroppingBox]][source]

Compile an inputs array for tracking prediction with the tracking U-Net, directly from U-Net segmentation masks saved to disk.

Parameters:
img_pathPath

Path to original single-chamber images folder. The filenames are expected in the printf format Position%02d_Chamber%02d_Frame%03d.png

seg_pathPath

Path to segmentation output masks folder. The filenames must be the same as in the img_path folder.

files_listlist[Path]

List of filenames to compile in the img_path and seg_path folders.

target_sizetuple of 2 ints, optional

Input and output image size. The default is (256,32).

crop_windowsbool, optional

Whether to crop out a window of size target_size around the seed/seg cell to track for all input images instead of resizing. The default is False.

Returns:
inputs_arr4D numpy array of floats

Input images and masks for the tracking U-Net training routine. Dimensions of the tensor are (cells_to_track, target_size[0], target_size[1], 4), with cells_to_track the number of segmented cells in all segmentation masks of the files_list.

seg_name_list[Path]

Filenames to save the tracking outputs as. The printf format is Position%02d_Chamber%02d_Frame%03d_Cell%02d.png, with the ‘_Cell%02d’ string appended to signal which cell is being seeded/tracked (from top to bottom)

boxeslist of CroppingBox

Cropping box to re-place output prediction masks in the original image coordinates.

delta.data.predict_generator_seg(files_path: Path, *, files_list: Sequence[Path] | None = None, target_size: tuple[int, int] = (256, 32), crop_windows: bool = False) Iterator[tuple[Image]][source]

Get a generator for predicting segmentation on new image files once the segmentation U-Net has been trained.

Parameters:
files_pathPath

Path to image files folder.

files_listlist/tuple of Paths, optional

List of file names to read in the folder. If None, all files in the folder will be read. The default is None.

target_sizetuple of 2 ints, optional

Size for the images to be resized. The default is (256,32).

crop_windowsbool

Whether to crop out a window of size target_size around the seed/seg cell to track for all input images instead of resizing. The default is False.

Returns:
mygengenerator

Generator that will yield single image files as 4D numpy arrays of size (1, target_size[0], target_size[1], 1).

delta.data.random_crop(img: Image, seg: SegmentationMask, wei: Image, target_size: tuple[int, int], rng: Generator) tuple[Image, SegmentationMask, Image][source]

Randomly crop a tuple of (image, segmentation mask, weight map).

It is padded with zeros if necessary.

Parameters:
img: Image

Input image.

seg: SegmentationMask

Segmentation mask (binary image with 0 for background and 1 for cells).

wei: Image

Pixel-wise weights.

target_size: tuple[int, int]

Target size for the resizing.

rng: npr.Generator

Random number generator.

Returns:
img, seg, wei: tuple[Image, SegmentationMask, Image]

Resized training sample.

delta.data.save_result_seg(save_path: Path, npyfile: ndarray[tuple[Any, ...], dtype[Any]], *, files_list: list[Path] | None = None, multipage: bool = False) None[source]

Save an array of segmentation output images to disk.

Parameters:
save_pathstring

Path to save folder.

npyfile3D or 4D numpy array

Array of segmentation outputs to save to individual files. If 4D, only the images from the first index of axis=3 will be saved.

files_listlist of strings, optional

Filenames to save the segmentation masks as. png, tif or jpg extensions work. The default is [].

multipagebool, optional

Flag to save all output masks as a single, multi-page TIFF file. Note that if the file already exists, the masks will be appended to it. The default is False.

delta.data.save_result_track(save_path: Path, npyfile: ndarray[tuple[Any, ...], dtype[Any]], files_list: list[Path] | None = None) None[source]

Save tracking output masks to disk.

Parameters:
save_pathPath

Folder to save images to.

npyfile4D numpy array

Array of tracking outputs (logits) to save to individual files.

files_listtuple/list of strings, optional

Filenames to save the masks as. Note that the mother_ and daughter_ prefixes will be added to those names. If None, numbers will be used. The default is None.

delta.data.seg_weights(mask: SegmentationMask, classweights: tuple[float, float] = (1, 1), w0: float = 12, sigma: float = 2) Image[source]

Compute the weight map as described in the original U-Net paper to force the model to learn borders.

(Slow, best to run this offline before training).

Parameters:
mask2D array

Training output segmentation mask.

classweightstuple of 2 int/floats

Weights to apply to background, foreground. The default is (1,1)

w0int or float, optional

Base weight to apply to smallest distance (1 pixel). The default is 12.

sigmaint or float, optional

Exponential decay rate to apply to distance weights. The default is 2.

Returns:
weightmap2D array

Weights map image.

delta.data.seg_weights_2D(mask: SegmentationMask, classweights: tuple[float, float] = (1, 1)) Image[source]

Compute custom weightmaps designed for bacterial images where borders are difficult to distinguish.

Parameters:
mask2D array

Training output segmentation mask.

classweightstuple of 2 int/floats, optional

Weights to apply to cells and border The default is (1,1)

Returns:
weightmap2D array

Weights map image.

delta.data.smart_elastic_deform(img_stack: list[ndarray[tuple[Any, ...], dtype[Any]]], orderlist: int | Sequence[int] = 0, sigma: float = 10, points: int | tuple[int, int] = 5, rng: Generator | None = None) list[ndarray[tuple[Any, ...], dtype[Any]]][source]

Run elastic deformation repeatably and remove touching cell pixels.

Parameters:
img_stacklist[npt.NDArray[Any]]

Images to apply elastic deformation to.

orderlistint | Sequence[int], optional

Interpolation order to use for each image in the input stack. See data_augmentation() for more information. The default is 0.

sigmafloat, optional

Standard deviation of the normal distribution for random displacement, in pixel. The default is 10.

pointsint | tuple[int, int], optional

Number of points of the deformation grid. If a single value is given, the points will be (points, points). The default is 5.

rngnpr.Generator | None, optional

Numpy random number generator for displacement vector generation. If None, one will be created from entropy with npr.default_rng(). The default is None.

Returns:
img_stacklist[npt.NDArray[Any]]

Deformed images.

delta.data.tracking_weights(track: SegmentationMask, segall: SegmentationMask, halo_distance: int = 50) ndarray[tuple[Any, ...], dtype[float32]][source]

Compute weights for tracking training sets.

Parameters:
track2D array

Tracking output mask.

segall2D array

Segmentation mask of all cells in current image.

halo_distanceint, optional

Distance in pixels to emphasize other cells from tracked cell. The default is 50.

Returns:
weights2D array

Tracking weights map.

delta.data.train_generator_track(batch_size: int, img_path: Path, seg_path: Path, previmg_path: Path, segall_path: Path, track_path: Path, weights_path: Path | Literal['online'] | None = None, *, augment_params: dict[str, Any] | None = None, crop_windows: bool = False, target_size: tuple[int, int] = (256, 32), shift: int = 0, seed: int = 1) Iterator[tuple[ndarray[tuple[Any, ...], dtype[float32]], ndarray[tuple[Any, ...], dtype[float32]]]][source]

Create a generato to train the tracking U-Net.

Parameters:
batch_sizeint

Batch size, number of training samples to concatenate together.

img_pathstring

Path to folder containing training input images (current timepoint).

seg_pathstring

Path to folder containing training ‘seed’ images, ie mask of 1 cell in the previous image to track in the current image.

previmg_pathstring

Path to folder containing training input images (previous timepoint).

segall_pathstring

Path to folder containing training ‘segall’ images, ie mask of all cells in the current image.

track_pathstring

Path to folder containing tracking groundtruth, ie mask of the seed cell and its potential daughter tracked in the current frame.

weights_pathstring or None, optional

Path to folder containing pixel-wise weights to apply to the tracking groundtruth. If None, the same weight is applied to all pixels. If the string is ‘online’, weights will be generated on the fly (not recommended, much slower) The default is None.

augment_paramsdict, optional

Data augmentation parameters. See data_augmentation() doc for more info The default is {}.

target_sizetuple of 2 ints, optional

Input and output image size. The default is (256,32).

crop_windowsbool, optional

Whether to crop out a window of size target_size around the seed/seg cell to track for all input images instead of resizing.

shiftint, optional

If crop_windows is True, a shift between [-shift, +shift] will be uniformly sampled for both the X and the Y axis. This shift in pixels will be applied only to the the cropbox for the current timepoint input frames (img, segall, mot_dau, wei), to simulate image drift over time.

seedint, optional

Seed for numpy’s random generator. The default is 1.

Yields:
inputs_arr4D numpy array of floats

Input images and masks for the U-Net training routine. Dimensions of the tensor are (batch_size, target_size[0], target_size[1], 4)

outputs_arr4D numpy array of floats

Output masks for the U-Net training routine. Dimensions of the tensor are (batch_size, target_size[0], target_size[1], 3). The third index of axis=3 contains ‘background’ masks, ie the part of the tracking output groundtruth that is not part of the mother or daughter masks

Image operations

Image manipulation functions.

class delta.imgops.CroppingBox(xtl: int, ytl: int, xbr: int, ybr: int)[source]

Class describing a box to cut out.

crop(images: DataArray) DataArray[source]

Crop an image according to the cropping box.

Pads with zeros if a part of the box falls outside of the image.

Parameters:
imagesxr.DataArray

Image to crop.

Returns:
patchesxr.DataArray

Patch cropped from the image.

classmethod full(image: ndarray[tuple[Any, ...], dtype[Any]]) CroppingBox[source]

Return a cropping box set to the full size of the image.

Parameters:
imagenp.ndarray

Image to use as reference for the bounding box.

Returns:
boxCroppingBox

Cropping box adjusted to the full size of the image.

patch(image: ndarray[tuple[Any, ...], dtype[Any]], patch: ndarray[tuple[Any, ...], dtype[Any]]) ndarray[tuple[Any, ...], dtype[Any]][source]

Apply a patch on an image at the position specified by the box.

Parts of the box may fall outside of the image.

Parameters:
imagenp.ndarray

Image to patch.

patchnp.ndarray

Patch to apply.

Returns:
imagenp.ndarray

The patched image.

resize(fx: float | None = None, fy: float | None = None) CroppingBox[source]

Resize the cropping box to follow an image resizing with the same factors.

If fi is None, the corresponding axis is left unchanged. For fi > 1, the box is enlarged.

Parameters:
fxOptional[float]

Resizing factor for the horizontal axis (column axis).

fyOptional[float]

Resizing factor for the vertical axis (row axis).

Returns:
resized_boxCroppingBox

A copy of the resized box. The original box is left unchanged.

property shape: tuple[int, int][source]

Shape of the cropping box.

property size: int[source]

Size of the cropping box as width * height.

static tracking_box(contour: Contour, shape: tuple[int, int]) CroppingBox[source]

Get a crop box around a cell that fits the tracking target size.

Parameters:
contourContour

Contour of the cell to track.

shapetuple of 2 ints

Target shape of the cropped image.

Returns:
cropboxCroppingBox

The cropbox localises the patch relatively to the source image.

xbr: int[source]

Bottom-right corner X coordinate.

xtl: int[source]

Top-left corner X coordinate.

ybr: int[source]

Bottom-right corner Y coordinate.

ytl: int[source]

Top-left corner Y coordinate.

delta.imgops.affine_transform(image: ndarray[tuple[Any, ...], dtype[Any]], *, zoom: float = 1.0, angle: float = 0.0, shift: tuple[float, float] = (0.0, 0.0), order: int) ndarray[tuple[Any, ...], dtype[Any]][source]

Apply an affine transformation to an image (zoom, rotation and translation).

Parameters:
image2D numpy array

input image.

zoomfloat

Zoom to apply to the image.

anglefloat

Rotation angle to apply to the image.

shift(float, float)

Translation to apply to the image, in pixels (x, y).

orderint

Interpolation order.

Returns:
image2D numpy array

Zoomed and shifted image of same size as input.

delta.imgops.binarize_threshold(array: Image, threshold: float | None) SegmentationMask[source]

Binarize a numpy array by thresholding it.

Parameters:
array2D numpy array of floating-point numbers

Input array/image.

thresholdfloat or None

Binarization threshold. If None, the threshold will be the middle of the dynamic range.

Returns:
newi2D numpy array of uint8

Binarized image.

delta.imgops.centroid(contour: Contour) tuple[int, int][source]

Get centroid of cv2 contour.

Parameters:
contour3D numpy array

Blob contour generated by cv2.findContours().

Returns:
cxint

X-axis coordinate of centroid.

cyint

Y-axis coordinate of centroid.

delta.imgops.compute_drift(images: Image, box: CroppingBox, template: Image) list[tuple[int, int]][source]

Compute drift drift between movie frames and the reference.

Parameters:
images3D numpy array of uint8/uint16/floats

The frames to correct drift for, of shape (t, y, x).

boxCroppingBox

A cropping box to extract the part of the frame to compute drift correction over.

template2D numpy array of uint8/uint16/floats

The template for drift correction (see drift_template()).

Returns:
driftlist[tuple[int, int]]

List of length t with tuples of (xdrift, ydrift).

delta.imgops.correct_drift(images: DataArray, drifts: DataArray) DataArray[source]

Correct the drift for a stack of images.

Parameters:
imagesxr.DataArray

The images to correct drift for. Needs to have at least “y” and “x” dims.

driftsxr.DataArray

The pre-computed drift to apply. Needs to have at least a “xy” dim.

Returns:
correctedxr.DataArray

Drift-corrected images, same dimensions as images.

delta.imgops.create_windows(image: ndarray[tuple[Any, ...], dtype[Any]], target_size: tuple[int, int] = (512, 512), min_overlap: int = 24) tuple[ndarray[tuple[Any, ...], dtype[Any]], ndarray[tuple[Any, ...], dtype[int32]], ndarray[tuple[Any, ...], dtype[int32]]][source]

Crop input image into windows of set size.

Parameters:
image2D array

Input image.

target_sizetuple, optional

Dimensions of the windows to crop out. The default is (512, 512).

min_overlapint, optional

Minimum overlap between windows in pixels. Default is 24.

Returns:
windows: 3D array

Cropped out images to feed into U-Net. Dimensions are (nb_of_windows, *target_size).

loc_yarray of shape (nsplits_y, 2)

List of lower and upper bounds for windows over the y axis (columns).

loc_xarray of shape (nsplits_x, 2)

List of lower and upper bounds for windows over the x axis (rows).

delta.imgops.deskew(image: Image) float[source]

Compute the rotation angle to apply to the image to remove its rotation.

You can skip rotation correction if your chambers are about +/- 1 degrees of horizontal.

Parameters:
image2D numpy array

Input image.

Returns:
anglefloat

Rotation angle of the chambers for correction, in degrees.

delta.imgops.detect_touching_cells(labels: Labels) ndarray[tuple[Any, ...], dtype[bool]][source]

Detect pixels where cells are touching.

Parameters:
labelsLabels

Labelled cells image where cells are possibly touching.

Returns:
touchingnpt.NDArray[bool]

Pixels where cells are touching.

delta.imgops.distance_transform_labels(labels: Labels) Image[source]

Compute the distance transform for a label frame.

Parameters:
labelsLabels

Labelled cells image where cells are possibly touching.

Returns:
distance_mapImage

For each non-zero pixel, what is the distance to the nearest different pixel (zero or otherwise).

delta.imgops.drift_template(chamberboxes: list[CroppingBox], img: Image, *, whole_frame: bool = False) tuple[CroppingBox, Image][source]

Retrieve a region above the chambers to use as drift template.

Parameters:
chamberboxeslist of dictionaries

See getROIBoxes().

img2D numpy array

The first frame of a movie to use as reference for drift correction.

whole_framebool, optional

Whether to use the whole frame as reference instead of the area above the chambers.

Returns:
boxCroppingBox

A cropping box corresponding to a region of an image to use as a template for drift correction.

templateImage

The cropped region of the image in the cropping box.

delta.imgops.filter_areas(image: SegmentationMask, min_area: float | None = 20, max_area: float | None = None) SegmentationMask[source]

Area filtering using openCV instead of skimage.

Parameters:
image2D array

Segmentation mask.

min_areafloat or None, optional

Minimum object area. The default is 20

max_areafloat or None, optional

Maximum object area. The default is None.

Returns:
image2D array

Filtered mask.

delta.imgops.find_contours(mask: SegmentationMask) list[Contour][source]

Find contours of morphological components of a segmentation mask.

This is a wrapper of CV2’s findContours() because it keeps changing signatures.

Parameters:
maskSegmentationMask

Segmentation mask to extract contours from.

Returns:
contourslist[Contour]

List of cv2 type contour arrays.

delta.imgops.label_seg(seg: SegmentationMask, cellnumbers: Sequence[int] | None = None) Labels[source]

Label cells in segmentation mask.

Parameters:
segSegmentationMask

Cells segmentation mask.

cellnumberslist of ints, optional

Numbers to attribute to each cell mask, from top to bottom of image. Because we are using uint16s, maximum cell number is 65535. If None is provided, the cells will be labeled 1,2,3,… Background is 0 The default is None.

Returns:
labels2D numpy array of uint16

Labelled image. Each cell in the image is marked by adjacent pixels with values given by cellnumbers

delta.imgops.postprocess(images: ndarray[tuple[Any, ...], dtype[float32]], *, square_size: int = 5, min_size: float | None = None, crop: bool = False) SegmentationMask[source]

Clean segmentation results based on mathematical morphology.

Parameters:
images2D or 3D numpy array of floating-point numbers between 0 and 1

Input image or images stacked along axis=0.

square_sizeint, optional

Size of the square structuring element to use for morphological opening The default is 5.

min_sizefloat or None, optional

Remove objects smaller than this minimum area value. If None, the operation is not performed. The default is None.

cropbool

If True, the images are cropped (randomly in training mode and with overlapping tiles in evaluation mode). If False, the images are simply resized to the target size.

Returns:
images2D or 3D numpy array of uint8 (0 or 1)

Cleaned, binarized images. Note that the dimensions are squeezed before return (see numpy.squeeze doc)

delta.imgops.read_image(filename: Path) Image[source]

Return the image as a numpy array of np.float32 rescaled between 0 and 1.

Parameters:
filenamePath

Filename of the image to read.

Returns:
imagenp.ndarray of np.float32
delta.imgops.read_reshape(filename: Path, *, target_size: tuple[int, int] = (256, 32), binarize: bool = False, order: int = 1, method: str = 'resize') Image | SegmentationMask[source]

Read image from disk, format it and return it as an array of floating-point numbers between 0 and 1.

Parameters:
filenamePath

Path to file. Only PNG, JPG or single-page TIFF files accepted

target_sizetuple of int or None, optional

Size to reshape the image. The default is (256, 32).

binarizebool, optional

Use the binarize_threshold() function on the image. The default is False.

orderint, optional

interpolation order (see skimage.transform.warp doc). 0 is nearest neighbor 1 is bilinear The default is 1.

method“resize” or “pad”

What to do if the image is smaller than the target size. In the “resize” mode, larger images will be resized too. The default is “resize”.

Returns:
inumpy 2d array of floats

Loaded array.

Raises:
ValueError

Raised if image file is not a PNG, JPEG, or TIFF file.

delta.imgops.rescale_image(img: ndarray[tuple[Any, ...], dtype[Any]]) Image[source]

Rescale an integer image to return an array of np.float32 between 0 and 1.

Parameters:
img: np.ndarray

Image with integer pixel values.

Returns:
image: rescaled image with np.float32 pixel values between 0 and 1.
delta.imgops.resize_image(image: Image, shape: tuple[int, int]) Image[source]

Resize “continuous” images (with linear interpolation).

Parameters:
imageImage

Image to resize.

shapetuple[int, int]

Target image shape.

Returns:
resized_imageImage

Resized image.

delta.imgops.resize_labels(labels: Labels, shape: tuple[int, int], *, prevent_touching: bool = False) Labels[source]

Resize labels.

Parameters:
labelsLabels

Labels to resize.

shapetuple[int, int]

Target labels shape.

prevent_touchingbool

If True, prevent the resized shapes from touching. Note that this can make some shapes disappear. The default is False.

Returns:
resized_labelsLabels

Resized labels.

delta.imgops.resize_mask(mask: SegmentationMask, shape: tuple[int, int], *, prevent_touching: bool = True) SegmentationMask[source]

Resize a segmentation mask.

Parameters:
maskSegmentationMask

Segmentation mask to resize.

shapetuple[int, int]

Target mask shape.

prevent_touchingbool

If True, prevent the resized shapes from touching. Note that this can make some shapes disappear. The default is True.

Returns:
resized_maskSegmentationMask

Resized mask.

delta.imgops.rotate(images: DataArray, angles: DataArray) DataArray[source]

Rotate image.

Parameters:
imagesxr.DataArray

The images to rotate. Need to have at least “y” and “x” dimensions.

anglesxr.DataArray

Rotation angles, in degrees.

Returns:
xr.Dataarray

Rotated images

delta.imgops.smart_resize(image: Image | SegmentationMask, new_shape: tuple[int, int]) Image | SegmentationMask[source]

Resize images with proper interpolation method, & remove touching pixels.

Parameters:
imageImage | SegmentationMask

Image to resize. Can be a microscopy image, segmentation mask, or weight map.

new_shapetuple[int, int]

Target image shape.

Returns:
resized_imageImage | SegmentationMask

Resized image.

delta.imgops.stitch_pic(results: ndarray[tuple[Any, ...], dtype[Any]], loc_y: list[tuple[int, int]] | ndarray[tuple[Any, ...], dtype[int32]], loc_x: list[tuple[int, int]] | ndarray[tuple[Any, ...], dtype[int32]]) ndarray[tuple[Any, ...], dtype[Any]][source]

Stitch segmentation back together from the windows of create_windows().

Parameters:
results3D array

Segmentation outputs from the seg model with dimensions (nb_of_windows, target_size[0], target_size[1])

loc_ylist

List of lower and upper bounds for windows over the y axis

loc_xlist

List of lower and upper bounds for windows over the x axis

Returns:
stitch_norm2D array

Stitched image.

delta.imgops.to_integer_values(frame: Image, dtype: type[object]) ndarray[tuple[Any, ...], dtype[Any]][source]

Return an image with integer-valued pixels of the given size.

Parameters:
frameImage

Input image with np.float32 pixels contained in [0, 1].

dtypenumpy dtype

Integer type of the returned image.

Lineage

Cell- and lineage-related objects and functions.

class delta.lineage.Cell(motherid: int | None, first_frame: int, _daughterids: list[int | None], _features: list[CellFeatures])[source]

Container for a cell across the movie.

daughterid(frame: int) int | None[source]

Return the daughter ID at a given frame, or None.

Parameters:
frameint

Frame number.

Returns:
daughteridint or None

Index of the daughter. None if no division at frame.

Raises:
CellNotOnFrameError

If the cell is not present on the given frame.

features(frame: int) CellFeatures[source]

Return the cell features of the cell at a given frame.

Parameters:
frameint

Frame number.

Returns:
cellfeaturesCellFeatures
Raises:
CellNotOnFrameError

If the cell is not present on the given frame.

first_frame: int[source]

Number of first frame of cell existence

property frames: range[source]

Return the range of frame for which this cell is known.

Returns:
framesrange
property last_frame: int[source]

Return the last frame on which this cell appears.

Returns:
last_frameint
motherid: int | None[source]

Index of cell’s mother

poles(frame: int) tuple[Pole, Pole][source]

Return the poles of the cell at a given frame: (old_pole, new_pole).

Parameters:
frameint

Frame number.

Returns:
old_polePole
new_polePole
Raises:
CellNotOnFrameError

If the cell is not present on the given frame.

exception delta.lineage.CellAlreadyHasDaughterError[source]

The cell already has a daughter at this frame.

exception delta.lineage.CellDoesNotExistError[source]

The given cell does not exist.

exception delta.lineage.CellDoesNotHaveMotherError[source]

The cell does not have a mother.

class delta.lineage.CellFeatures(new_pole: Pole, old_pole: Pole, length: float = 0.0, width: float = 0.0, area: float = 0.0, perimeter: float = 0.0, fluo: list[float] = <factory>, edges: str = '', growthrate_length: float = nan, growthrate_area: float = nan)[source]

Container for cell features of a given cell at a given frame.

area: float = 0.0[source]

Cell area, in square pixels. Sum of pixels inside the contour.

edges: str = ''[source]

String describing image edges touched by the cell. Can be a combination of the following: ‘-x’, ‘+x’, ‘-y’, ‘+y’. Empty otherwise.

fluo: list[float][source]

Average (mean) fluorescence level(s) within cell contour.

growthrate_area: float = nan[source]

Growth rate of the cell area, see documentation.

growthrate_length: float = nan[source]

Growth rate of the cell length, see documentation.

length: float = 0.0[source]

Cell length, in pixels. Long axis of a rotated bounding box.

new_pole: Pole[source]

Location of “Young” cell pole created after division of the septum.

old_pole: Pole[source]

Location of “Old” cell pole that is maintained at division

perimeter: float = 0.0[source]

Cell perimeter length, in pixels. Sum of pixels along the contour as computed by opencv’s arcLength() function

swap_poles() None[source]

Swap the new and old poles of the cell, in place.

width: float = 0.0[source]

Cell width, pixels. Short axis of a rotated bounding box.

exception delta.lineage.CellNotOnFrameError[source]

The cell is not on the specified frame.

class delta.lineage.Lineage(cells: dict[int, ~delta.lineage.Cell]=<factory>)[source]

Represents the cell lineages contained in a ROI.

Only two functions are required to create a full lineage tree:
  • create and extend to create a cell and extend it frame after frame;

                   create(frame=0)
                    ------------>
    frames : 0....5....        0....5....
    cell #1:                   ╺
    
                   create(frame=5)
                    ------------>
    frames : 0....5....        0....5....
    cell #1: ╺╼╼╼╼╼╼╼╼╼        ╺╼╼╼╼╼╼╼╼╼
    cell #2:                        ╺
    
             create(frame=5, motherid=1)
                    ------------>
    frames : 0....5....        0....5....
    cell #1: ╺╼╼╼╼╼╼╼╼╼        ╺╼╼╼╼┮╼╼╼╼
    cell #2:                        ┕
    
                   extend(cellid=2)
                    ------------>
    frames : 0....5....        0....5....
    cell #1: ╺╼╼╼╼┮╼╼╼╼        ╺╼╼╼╼┮╼╼╼╼
    cell #2:      ┕                 ┕╼
    
To manipulate an already created tree, one needs four more:
  • split and merge, to split a cell into two cells, and reverse the operation;

  • adopt, to change the mother of a cell;

  • pivot, to switch the roles of mother and daughter cells.

The use of these methods is best illustrated by the following diagrams:

              split(1, frame=5)
                ------------>
frames : 0....5....        0....5....
cell #1: ╺╼╼╼╼╼╼╼╼╼        ╺╼╼╼╼
cell #2:                        ╺╼╼╼╼
                <------------
                 merge(2, 1)

                 adopt(2, 1)        pivot(2)        adopt(2, None)
                ------------>     ------------>     ------------->
frames : 0..3......        0..3......        0..3......        0..3......
cell #1: ╺╼╼╼╼╼╼╼╼╼        ╺╼╼┮╼╼╼╼╼╼        ╺╼╼┮╼╼╼           ╺╼╼╼╼╼╼
cell #2:    ╺╼╼╼              ┕╼╼╼              ┕╼╼╼╼╼╼           ╺╼╼╼╼╼╼
                <------------     <------------     <-------------
                adopt(2, None)       pivot(2)         adopt(2, 1)
adopt(cellid: int, motherid: int | None) None[source]

Attribute a new mother motherid (which can be None) to the cell cellid.

The mother motherid needs to exist at the frame where the cellid appears for the first time, and not already have a daughter in the same frame.

This function is its own inverse.

Parameters:
cellidint

The cellid of the cell that will become the daughter.

motheridint | None

The cellid of the cell that will become the mother.

Notes

This function only modifies the Lineage class. If you want to also update the ROI.label_stack, use instead the similar ROI.adopt() method.

Examples

frames    : ..........
cell #0001: ╺╼╼╼╼╼╼╼╼╼
cell #0002:      ╺╼╼╼╼

    adopt(cellid=2, motherid=1)

frames    : ..........
cell #0001: ╺╼╼╼╼┮╼╼╼╼
cell #0002:      ┕╼╼╼╼

    adopt(cellid=2, motherid=None)

frames    : ..........
cell #0001: ╺╼╼╼╼╼╼╼╼╼
cell #0002:      ╺╼╼╼╼
cells: dict[int, Cell][source]

Dictionary of cellids to Cell s

compare(other: object, level: int = 0) list | None[source]

Print or return the list of differences between two Lineage objects.

compute_growthrates(feature: str, smooth_frames: int = 7) None[source]

Compute the growth rates of all cells on all frames and store them.

Essentially, if a cell and its daughter have the following lengths:

m₀ ---> m₁ ---> m₂ -+-> m₃ ---> m₄ ---> m₅
                    |
                    +-> d₃ ---> d₄ ---> d₅

Then the following ratios give the size increase:

            mother                  daughter
frame 1:    m₂ / m₀
frame 2:    (m₃+d₃) / m₁
frame 3:    m₄ / (m₂m₃/(m₃+d₃))     d₄ / (m₂d₃/(m₃+d₃))
frame 4:    m₅ / m₃                 d₅ / d₃

Notice that if we write the lengths in the following way:

            mother                  daughter
frame 0:    m₀
frame 1:    m₁
frame 2:    m₂                      m₂ / (1+m₃/d₃)
frame 3:    m₃ (1+d₃/m₃)            d₃
frame 4:    m₄ (1+d₃/m₃)            d₄
frame 5:    m₅ (1+d₃/m₃)            d₅

Then dividing frame+1 by frame-1 always gives the correct growth ratios. We add another similar factor for each division.

This function just does the same thing directly in log, to avoid lengths increasing too much during long experiments.

The values computed are in units of 1/frame, because DeLTA doesn’t know the interval between frames. To convert these values into other units, they should be divided by the interval between frames, in any unit, for example, if frames are 5 minutes apart and you want the growth rate in 1/h:

GR[1/h] = GR[DeLTA] / (5 / 60)
-------   ---------   -------- Interval between frames in [h/frame]
       \           \
        \           Growth rate given by DeLTA in [1/frame]
         \
          Growth rate in [1/h]
Parameters:
featurestr

Feature to use for the growth rate computation, typically “length” or “area”.

smooth_framesint, default 7

Size of the centered window over which to smooth the growth rate.

create(frame: int, features: CellFeatures, motherid: int | None = None) int[source]

Create a new cell at frame frame.

Parameters:
frameint

The frame where the new cell appears for the first time.

featuresCellFeatures

Cell features at first frame.

motheridint | None

Cell ID of the mother cell, if there is one. The default is None.

Returns:
cellidint

The cellid of the newly created cell.

extend(cellid: int, features: CellFeatures) None[source]

Extend cellid with one more frame.

Equivalent to creating a new cell and then merging it into cellid, but avoids increasing the cell counter while doing so.

Examples

frames    : ......
cell #0001: ╺╼╼╼╼

    extend(cellid=1, features=features)

frames    : ......
cell #0001: ╺╼╼╼╼╼
merge(cellid: int, merge_into_cellid: int) None[source]

Rename a cell (cellid) to merge it into another one (merge_into_cellid).

The cells need to be exactly consecutive (i.e. cellid’s first frame is one frame after merge_into_cellid’s last frame).

Inverse of split().

Parameters:
cellidint

The cellid of the cell to be renamed.

merge_into_cellidint

The cellid of the cell that will incorporate the other one.

Notes

This function only modifies the Lineage class. If you want to also update the ROI.label_stack, use instead the similar ROI.merge() method.

Examples

frames    : ..........
cell #0001: ╺╼╼╼╼
cell #0002:      ╺╼╼╼╼

    merge(cellid=2, merge_into_cellid=1)

frames    : ..........
cell #0001: ╺╼╼╼╼╼╼╼╼╼
pivot(cellid: int) None[source]

Swap the roles between cell cellid and its mother.

Notes

This function only modifies the Lineage class. If you want to also update the ROI.label_stack, use instead the similar ROI.pivot() method.

Examples

frames    : .......
cell #0001: ╺┮┮╼
cell #0003:  │┕╼╼
cell #0002:  ┕╼┮╼╼
cell #0004:    ┕╼╼╼

    pivot(cellid=2)

frames    : .......
cell #0001: ╺┮╼┮╼╼
cell #0004:  │ ┕╼╼╼
cell #0002:  ┕┮╼
cell #0003:   ┕╼╼
plot(*, order_key: Callable[[Cell], float] | None = None, ax: Axes, colors: dict[int, tuple[float, float, float]] | None = None, labels: bool = True) Axes[source]

Create a plot of the lineage tree on the provided ax.

Parameters:
order_keyCallable[[Cell], float] | None

Function that takes a Cell and returns a number. The ordering of these numbers will determine the order of the mother cells on the figure.

axplt.Axes | None

The matplotlib axes object on which to plot the graph.

labels: bool = True

Whether or not to display labels next to the cells.

Examples

To plot lineages from vertical mothermachines you might want to order the initial cells in the order they have on the first frame of the mothermachine:

import matplotlib.pyplot as plt

def order_key(cell: Cell) -> int:
    # sort by the y coordinate of the first pole
    pole1, pole2 = cell.poles(cell.first_frame)
    return pole1[0]

fig, ax = plt.subplots()
roi.plot(order_key=order_key, ax=ax)
plt.show()
split(cellid: int, frame: int) int[source]

Break a cell lineage into two independent cell lineages.

Inverse of merge().

Parameters:
cellidint

The cellid of the cell to break.

frameint

The frame number of the first frame of the new cell.

Returns:
new_cellidint

The cellid of the newly created cell.

Notes

This function only modifies the Lineage class. If you want to also update the ROI.label_stack, use instead the similar ROI.split() method.

Examples

frames    : 0....5....
cell #0001: ╺╼╼╼╼╼╼╼╼╼

    split(cellid=1, frame=5)

frames    : 0....5....
cell #0001: ╺╼╼╼╼
cell #0002:      ╺╼╼╼╼
swap_poles(cellid: int, frame: int | None = None) None[source]

Swap the poles of the cell cellid for all the frames or for frame frame onwards.

This operation can lead to some tree reassignments if cellid has daughters, to respect the pole ages.

Notes

This function only modifies the Lineage class. If you want to also update the ROI.label_stack, use instead the similar ROI.swap_poles() method.

This function assumes that track_poles() and division_poles() are symmetrical with respect to prev_old and prev_new (i.e. switching prev_old and prev_new also switch their results).

exception delta.lineage.NonConsecutiveCellsError[source]

The cells are not consecutive.

exception delta.lineage.OverlappingCellsError[source]

The cells overlap in time.

Models

Model and loss/metrics functions definitions.

This module contains the declaration of the U-Nets in Keras / Tensorflow as well as the loss function we used to train them. See our publications for descriptions of the models and losses.

For the seminal paper describing the structure of the U-Net model:

Ronneberger, Olaf, Philipp Fischer, and Thomas Brox. “U-net: Convolutional networks for biomedical image segmentation.” International Conference on Medical image computing and computer-assisted intervention. 2015

delta.model.hash_model(model: Model) str[source]

Return a hashsum of the given keras model.

Parameters:
modelModel

Model to hash.

Returns:
hashstr

Hashsum of the model.

delta.model.pixelwise_weighted_binary_crossentropy_seg(seg_weights: KerasTensor, logits: KerasTensor) KerasTensor[source]

Pixel-wise weighted binary cross-entropy loss.

The code is adapted from the Keras TF backend. (see their github).

Parameters:
seg_weightsTensor

Stack of groundtruth segmentation masks + weight maps.

logitsTensor

Predicted segmentation masks.

Returns:
Tensor

Pixel-wise weight binary cross-entropy between inputs.

delta.model.pixelwise_weighted_binary_crossentropy_track(seg_weights: KerasTensor, logits: KerasTensor) KerasTensor[source]

Pixel-wise weighted binary cross-entropy loss.

The code is adapted from the Keras TF backend. (see their github).

Parameters:
seg_weightsTensor

Stack of groundtruth segmentation masks + weight maps.

logitsTensor

Predicted segmentation masks.

Returns:
Tensor

Pixel-wise weight binary cross-entropy between inputs.

delta.model.unet(input_size: tuple[int | None, int | None, int] = (None, None, 1), final_activation: str = 'linear', output_classes: int = 1, dropout: float = 0, levels: int = 5, filters: list[int] | None = None) Model[source]

Create a U-Net.

Parameters:
input_sizetuple of 3 ints, optional

Dimensions of the input tensor, excluding batch size. The default is (None, None, 1), which means that any image size is accepted.

final_activationstring or function, optional

Activation function for the final 2D convolutional layer. see keras.activations The default is “linear” (no activation: outputs logits).

output_classesint, optional

Number of output classes, ie dimensionality of the output space of the last 2D convolutional layer. The default is 1.

dropoutfloat, optional

Dropout layer rate in the contracting & expanding blocks. Valid range is [0,1). If 0, no dropout layer is added. The default is 0.

levelsint, optional

Number of levels of the U-Net, ie number of successive contraction then expansion blocks are combined together. Ignored if filters is specified. The default is 5.

filters[int], optional

Number of convolutional kernels at each level. The default is starting with 64 and multiplying by 2 at each level.

Returns:
modelModel

Defined U-Net model (not compiled yet).

delta.model.unet_rois(input_size: tuple[int, int, int] = (512, 512, 1), levels: int = 5, filters: list[int] | None = None) Model[source]

Segmentation U-Net for ROIs.

Parameters:
input_sizetuple of 3 ints, optional

Dimensions of the input tensor, without batch size. The default is (512,512,1).

levelsint, optional

Number of levels of the U-Net, ie number of successive contraction then expansion blocks are combined together. Ignored if filters is specified. The default is 5.

filters[int], optional

Number of convolutional kernels at each level. The default is starting with 64 and multiplying by 2 at each level.

Returns:
modelModel

ROIs ID U-Net (compiled).

delta.model.unet_seg(pretrained_weights: str | None = None, input_size: tuple[int, int, int] = (256, 32, 1), levels: int = 5, filters: list[int] | None = None) Model[source]

Cell segmentation U-Net definition function.

Parameters:
pretrained_weightsmodel file, optional

Model will load weights from file and start training. The default is None

input_sizetuple of 3 ints, optional

Dimensions of the input tensor, without batch size. The default is (256,32,1).

levelsint, optional

Number of levels of the U-Net, ie number of successive contraction then expansion blocks are combined together. Ignored if filters is specified. The default is 5.

filters[int], optional

Number of convolutional kernels at each level. The default is starting with 64 and multiplying by 2 at each level.

Returns:
modelModel

Segmentation U-Net (compiled).

delta.model.unet_track(pretrained_weights: str | None = None, input_size: tuple[int, int, int] = (256, 32, 4), levels: int = 5, filters: list[int] | None = None) Model[source]

Tracking U-Net definition function.

Parameters:
pretrained_weightsmodel file, optional

Model will load weights from file and start training. The default is None

input_sizetuple of 3 ints, optional

Dimensions of the input tensor, without batch size. The default is (256,32,4).

levelsint, optional

Number of levels of the U-Net, ie number of successive contraction then expansion blocks are combined together. Ignored if filters is specified. The default is 5.

filters[int], optional

Number of convolutional kernels at each level. The default is starting with 64 and multiplying by 2 at each level.

Returns:
modelModel

Tracking U-Net (compiled).

delta.model.unstack_acc(seg_weights: KerasTensor, logits: KerasTensor) KerasTensor[source]

Compute binary accuracy from a stacked tensor with mask and weight map.

Parameters:
seg_weightsTensor

Stack of groundtruth segmentation masks + weight maps.

logitsTensor

Predicted segmentation masks.

Returns:
Tensor

Binary prediction accuracy.

Pipeline

Main processing pipeline.

class delta.pipeline.Pipeline(xpreader: XPReader, config: Config, resfolder: str | Path | None = None)[source]

Main Pipeline class to process all positions.

config: Config[source]

Configuration parameters object

positions: dict[int, Position][source]

Dict of Position objects for experiment

process(*, positions: Sequence[int] | None = None, frames: range | slice | None = None, save_as: Sequence[str] = ('netCDF', 'movie'), clear: bool = True, progress_bar: bool = False) None[source]

Run pipeline.

Parameters:
positionslist of int or None, optional

List of positions to run. If None, all positions are run. The default is None.

framesint or None, optional

Number of frames to run. If None, all frames are run. The default is None.

save_as: Sequence[str]

List of formats to save the results. Can be “netCDF”, “movie” or “labeled-movie”. The default is ("netCDF", "movie").

clearbool, optional

Clear variables of each Position object after it has been processed and saved to disk, to prevent memory issues. The default is True.

progress_barbool, optional (default False)

Display a progress bar

reader: XPReader[source]

Experiment reader object

resfolder: Path[source]

Folder to save results to

class delta.pipeline.Position(position_nb: int, config: Config)[source]

Position-processing object.

clear() None[source]

Clear Position-specific variables from memory (can be loaded back with load()).

compare(other: object, level: int = 0) list | None[source]

Compare this Position with another and print the differences.

compute_growthrates(frames: range, smooth_frames: int = 9) None[source]

Extract features for all ROIs in frames.

Parameters:
framesrange

Frames to run.

smooth_framesint, default 9

Size of the centered window over which to smooth the growth rate.

config: Config[source]

Configuration parameters object

drift_values: list[tuple[int, int]][source]

XY drift correction values over time

static find_roi_boxes(reference: Image, config: Config, min_overlap_crop: int = 24) list[CroppingBox][source]

Use U-Net to detect ROIs (chambers etc…).

Parameters:
referenceImage

Reference image to use to detect ROIs.

configConfig

DeLTA configuration object.

min_overlap_cropint, optional

Minimum overlap between windows in pixels. Default is 24.

Returns:
boxesList[CroppingBox]

List of ROI boxes.

labels(frames: range | None = None, *, undo_corrections: bool = True) list[Labels][source]

Generate full-size frames with labelled cells.

Parameters:
framesrange | None

Range of frames indexes to generate labelled images for. If None, all of them will be used. The default is None.

undo_correctionsbool

If True, undo drift and rotation corrections to match the original input images. The default is True.

Returns:
labelslist[Labels]

List of labelled frames

classmethod load_netcdf(filename: str | Path) Position[source]

Load position from netCDF file.

Parameters:
filenamestr or Path

File name for the save file.

Returns:
positionpipeline.Position object

Reloaded position object.

position_nb[source]

Position index number in the experiment

preprocess(all_frames: DataArray, frames: range, reference: Image | None = None) None[source]

Pre-process position (Rotation correction, identify ROIs, initialize drift correction).

Parameters:
all_framesxr.DataArray

All frames for this position. Shape: (frames, channels, Y, X).

reference2D array, optional

Reference image to use to perform pre-processing. If None, the first image of each position will be used. The default is None.

results_movie(reader: XPReader, frames: range | None = None, *, with_labels: bool = False) list[ndarray[tuple[Any, ...], dtype[uint8]]][source]

Generate movie illustrating segmentation and tracking.

Parameters:
readerutils.XPReader

XPReader object (needed to reconstruct the movie in case of mothermachines).

framesrange | None

Range of frames to use for the movie. If None, all of them will be used. The default is None.

with_labelsbool

Add cellids to the movie next to each cell.

Returns:
movielist of 3D numpy arrays

List of compiled movie frames

rois: list[ROI][source]

List of ROI objects under position

rotate: float[source]

Rotation angle of the position to compensate

save(filename: str | Path | None = None, frames: range | None = None, reader: XPReader | None = None, save_as: str | Sequence[str] = ('netCDF', 'movie'), *, progress_bar: bool = False) None[source]

Save to disk.

Parameters:
filenamestr or None, optional

File name for save file. If None, the file will be saved to PositionXXXXXX in the current directory. The default is None.

framesrange | None

Range of frames to save. If None, all frames will be saved. The default is None.

readerutils.XPReader | None

Only needed if saving as a movie.

save_asstr or tuple of str, optional

Formats to save the data to. Options are “netCDF”, “movie” or “labeled-movie”. The default is (“netCDF”, “movie”).

progress_barbool, optional (default False)

Display a progress bar.

segment(frames: range, *, progress_bar: bool = False) None[source]

Segment cells in all ROIs in position.

Parameters:
framesrange

Frames to run.

progress_barbool, optional (default False)

Display a progress bar.

shape: tuple[int, int][source]

Shape of full-frame images. (Y, X) convention

to_netcdf(path: Path, *, progress_bar: bool = False, **kwargs: dict[str, Any]) None[source]

Save the position as a netCDF file.

The file will contain one group per ROI, with names roi00, roi01, etc.

Parameters:
pathPath

Path where to save the netCDF file.

progress_barbool, optional (default False)

Display a progress bar.

kwargsdict

Keyword arguments passed to ROI.to_netcdf.

track(frames: range, *, progress_bar: bool = False) None[source]

Track cells in all ROIs in position.

Parameters:
framesrange

Frames to track.

progress_barbool, optional (default False)

Display a progress bar.

class delta.pipeline.ROI(stack: DataArray, roi_nb: int, first_frame: int, box: CroppingBox, config: Config)[source]

ROI processor object.

adopt(cellid: int, motherid: int | None) None[source]

Attribute a new mother motherid (which can be None) to the cell cellid.

For more information, see the Lineage.adopt() method.

This one also updates the labels in the label stack.

box[source]

ROI crop box

static chunks_predict(inputs: ndarray, model: Model, chunk_size: int, batch_size: int | None = 1) Image[source]

Run keras model, but by splitting the input data into “chunks”.

These chunks will be processed and then retrieved before moving on to the next chunk. The reason for doing this is that, especially on smaller GPUs or long movies, keras/TF sometimes tries to move a large input tensor all at once on the GPU, leading to OOMs. Note that this is a different problem than batch size.

Parameters:
inputsnp.ndarray

Input tensor to predict on.

modelkeras.Model

Model to use.

chunk_sizeint
batch_sizeint | None

Batch size for model predictions. This is NOT the same thing as chunk size. The default is 1.

Returns:
outputsnp.ndarray

Predictions array.

compare(other: object, level: int = 0) list | None[source]

Compare this ROI with another and print the differences.

config: Config[source]

Configuration parameters object

first_frame[source]

Index of the first frame

fluo_stack[source]

Fluo images stack

static from_xarray(dataset: Dataset) ROI[source]

Create a ROI from an xarray.Dataset.

Parameters:
datasetxr.Dataset

An xarray.Dataset representing a ROI.

Returns:
roiROI

The corresponding ROI.

get_fluo(frame: int) Image[source]

Return the ROI fluo images at a given frame.

Parameters:
frameint

Frame index.

Returns:
imageImage

List of fluo images of the ROI.

get_img(frame: int) Image[source]

Return the ROI image at a given frame.

Parameters:
frameint

Frame index.

Returns:
imageImage

Image of the ROI.

get_labels(frame: int) Labels[source]

Return the ROI labels at a given frame.

Parameters:
frameint

Frame index.

Returns:
labelsLabels

Labels frame.

get_seg(frame: int) SegmentationMask[source]

Return the ROI segmentation mask at a given frame.

Parameters:
frameint

Frame index.

Returns:
segSegmentationMask

Segmentation mask of the ROI.

get_segmentation_inputs(frame: int) tuple[Image, tuple[ndarray[tuple[Any, ...], dtype[int32]], ndarray[tuple[Any, ...], dtype[int32]]] | None][source]

Compile segmentation inputs for ROI.

Parameters:
frameint

Frame number for the segmentation inputs.

Returns:
x4D array

Segmentation input array. Dimensions are (windows, *self.config.models["seg"].target_size, 1).

windowstuple of 2 lists

y and x coordinates of crop windows if any, or None.

get_tracking_inputs(frame: int) tuple[Image, list[CroppingBox]][source]

Compile tracking inputs for ROI from seg_stack.

Parameters:
frameint

The frame to compile for.

Returns:
inputs4D array or None

Tracking input array. Dimensions are (previous_cells, *self.config.models["track"].target_size, 4).

boxeslist[CroppingBox]

Crop boxes to re-place outputs in the ROI.

Raises:
RuntimeError

Segmentation has not been completed up to frame yet.

img_stack[source]

Input images stack

label_stack: list[Labels][source]

Labelled images stack

lineage[source]

Lineage object for ROI

classmethod load_netcdf(filename: str | Path, group: str | None = None) ROI[source]

Load a ROI from a netCDF file.

Parameters:
filenamestr or Path

Path to the netCDF file.

groupstr | None

netCDF group to open, for example roiXX if the file is a saved position.

Returns:
roiROI

Loaded ROI.

merge(cellid: int, merge_into_cellid: int) None[source]

Rename a cell (cellid) to merge it into another one (merge_into_cellid).

For more information, see the Lineage.merge() method.

This one also updates the labels in the label stack.

pivot(cellid: int) None[source]

Swap the roles between cell cellid and its mother.

For more information, see the Lineage.pivot() method.

This one also updates the labels in the label stack.

process_segmentation_outputs(logits: ndarray[tuple[Any, ...], dtype[float32]], frame: int, windows: tuple[ndarray[tuple[Any, ...], dtype[int32]], ndarray[tuple[Any, ...], dtype[int32]]] | None = None) None[source]

Process outputs after they have been segmented.

Parameters:
logits4D array

Segmentation output array. Dimensions are (windows, *self.config.models["seg"].target_size, 1).

frameint

Frame index.

windowstuple of 2 lists

y and x coordinates of crop windows if any, or None.

process_tracking_outputs(logits: ndarray[tuple[Any, ...], dtype[float32]], frame: int, boxes: list[CroppingBox]) None[source]

Process output from tracking U-Net.

Get poles, update lineage and create label_stack.

Parameters:
logits4D array

Tracking output array. Dimensions are (previous_cells, *self.config.models["track"].target_size, 1).

frameint

The frame to process for.

boxeslist[CroppingBox]

Crop boxes to re-place outputs in the ROI.

roi_nb[source]

The ROI index number

scaling: tuple[float, float][source]

Resizing ratios along Y and X

seg_stack: list[SegmentationMask][source]

Segmentation images stack

segment(frames: range, model: Model | None = None) None[source]

Segment img_stack and store the results in seg_stack.

Parameters:
framesrange

Frames to run.

modelkeras.Model | None

Segmentation model to use. This is to avoid having to reload it for every ROI. If None, will use self.config.models[“seg”].model(). The default is None.

split(cellid: int, frame: int) int[source]

Break a cell lineage into two independent cell lineages.

For more information, see the Lineage.split() method.

This one also updates the labels in the label stack.

swap_poles(cellid: int, frame: int | None = None) None[source]

Swap the poles of the cell cellid for all the frames or for frame frame onwards.

For more information, see the Lineage.swap_poles() method.

This one also updates the labels in the label stack.

to_netcdf(filename: str | Path, **kwargs: dict[str, Any]) None[source]

Save the ROI as a netCDF file.

This function compresses the relevant variables, so it should be more space-efficient than doing roi.to_xarray().to_netcdf(path).

Parameters:
filenamestr or Path

Path where to save the netCDF file.

kwargsdict

Keyword arguments passed to xarray.to_netcdf.

to_xarray() Dataset[source]

Convert the ROI into a xarray.Dataset.

Returns:
datasetxr.Dataset
track(frames: range, model: Model | None = None, *, progress_bar: bool = False) None[source]

Track cells in the ROI.

Parameters:
framesrange

Frames to track.

modelkeras.Model | None

Tracking model to use. This is to avoid having to reload the model for every ROI. If None, will use self.config.models[“track”].model(). The default is None.

progress_barbool, optional (default False)

Display a progress bar.

Utilities

Utility functions and class definitions that are used in pipeline.py.

class delta.utils.XPReader(path: Path | str)[source]

Class to read experiment files from single files or from file sequences in folders.

channel_names: tuple[str, ...] | None[source]

Names of the imaging channels (optional)

channels: tuple[int, ...][source]

Imaging channels

dtype: DTypeLike[source]

Datatype of images

filehandle: Any[source]

Handle to file reader or base directory

filetype[source]

Type / extension of filehandle

frames: range[source]

Frame numbers in the experiment

image_path(position: int, channel: int | str, frame: int) Path[source]

Generate full filename for specific frame based on position, channel and frame.

Parameters:
positionint

Position/series index.

channelint | str

Imaging channel index, index or name.

frameint

Frame/timepoint index.

Returns:
string

Filename.

images(position: int, channels: int | str | Sequence[int | str] | None = None, frames: range | None = None, rotate: float | None = None) DataArray[source]

Get images from experiment.

Parameters:
positionint

The position index for which the frames are requested.

channelsint or str or sequence of ints or strs, optional

The frames from the channel index or indexes passed as an integer, string, or sequence of integers or strings will be returned. If None is passed, all thannels are returned. The default is None.

framesrange, optional

Range of frames returned. If None is passed, all frames are returned. The default is None.

rotatefloat, optional

Rotation to apply to the image (in degrees). The default is None.

Returns:
xarray.DataArray

Concatenated frames as requested by the different input options. The array is 4-dimensional, with the shape being: (frames, channels, Y, X).

Raises:
ValueError

If channel names are not correct.

path[source]

File or folder name for the experiment

positions: tuple[int, ...][source]

Positions in the experiment

x: int[source]

Size of images along X axis

y: int[source]

Size of images along Y axis

delta.utils.attributions(scores: ndarray[tuple[Any, ...], dtype[float32]]) ndarray[tuple[Any, ...], dtype[bool]][source]

Get attribution matrix from tracking scores.

Parameters:
scores2D array of floats

Tracking scores matrix as produced by the tracking_scores function.

Returns:
attrib2D array of bools

Attribution matrix. Cells from the old frame (axis 0) are attributed to cells in the new frame (axis 1). Each old cell can be attributed to 1 or 2 new cells.

delta.utils.cell_area(contour: Contour) float[source]

Area of a single cell.

Parameters:
contourlist

Single cell contour from cv2 findcontours.

Returns:
areafloat

Cell area

delta.utils.cell_fluo(fluo_frames: Image, mask: SegmentationMask) ndarray[tuple[Any, ...], dtype[float32]][source]

Extract mean fluorescence level from mask.

Parameters:
fluo_frames3D array

Fluorescent images to extract fluo from. Dimensions are (channels, size_y, size_x).

mask2D numpy array of bool

Mask of the region to extract (typically a single cell). Dimensions are (size_y, size_x).

Returns:
fluo_valuesarray of floats

Mean value per cell for each fluo frame.

delta.utils.cell_perimeter(contour: Contour) float[source]

Get single cell perimeter.

Parameters:
contourlist

Single cell contour from cv2 findcontours.

Returns:
perimeterint

Cell perimeter

delta.utils.cell_width_length(cell_poles: tuple[Pole, Pole], distance_map: Image) tuple[float, float][source]

Measure width and length of single cell.

Parameters:
cell_polestuple[Pole, Pole]

Poles of the cell.

distance_mapImage

Distance transform of the segmentation mask.

Returns:
widthfloat

Cell width.

lengthfloat

cell length.

delta.utils.cells_in_frame(labels: Labels, *, return_contours: Literal[True]) tuple[list[int], list[Contour]][source]
delta.utils.cells_in_frame(labels: Labels, *, return_contours: Literal[False] = False) list[int]

Get numbers of cells present in frame, sorted along Y axis.

Parameters:
labels2D numpy array of uint16

Single frame from labels stack.

return_contoursbool, optional

Flag to get cv2 contours.

Returns:
cellidslist

Cell ids.

contourslist

List of cv2 contours for each cell. Returned if return_contours==True.

delta.utils.color_diff(prefix: str, a: Any, b: Any) str[source]

Return the string f”{prefix}{red_a} ≠ {green_b}”.

delta.utils.compare_arrays(array1: ndarray[tuple[Any, ...], dtype[Any]], array2: ndarray[tuple[Any, ...], dtype[Any]], name: str = 'array') list[str][source]

Return a list of differences between two arrays, for use in compare.

delta.utils.contour_curvature(contour: Contour, stride: int | None = None) ndarray[tuple[Any, ...], dtype[float32]][source]

Compute the curvature of a cell’s contour.

Inspired by https://stackoverflow.com/a/68757937.

Parameters:
contour: Contour

Cell contour to consider

stride: int | None, optional

Distance between contour points to compute curvature. If None (default), it will use the default value 5 but reduce it if the contour is too small.

Returns:
npt.NDArray[np.float32]

Curvature along the contour

delta.utils.division_poles(features1: CellFeatures, features2: CellFeatures, prev_old: Pole, prev_new: Pole) tuple[CellFeatures, CellFeatures, bool][source]

Identify which poles belong to the mother and which to the daughter.

Parameters:
features1CellFeatures

Features of one of the 2 cells after division (with possibly swapped poles).

features2CellFeatures

Features of the other of the 2 cells after division (with possibly swapped poles).

prev_oldPole

Previous old pole of the cell.

prev_newPole

Previous new pole of the cell.

Returns:
motherCellFeatures
daughterCellFeatures
first_cell_is_motherbool
delta.utils.eucl(p1: ndarray[tuple[Any, ...], dtype[Any]], p2: ndarray[tuple[Any, ...], dtype[Any]]) float[source]

Euclidean point to point distance.

Parameters:
p11D array

Coordinates of first point.

p21D array

Coordinates of second point.

Returns:
float

Euclidean distance between p1 and p2.

delta.utils.find_poles(contour: Contour) tuple[Pole, Pole][source]

Get cell poles from contour.

Parameters:
contourContour

OpenCV contour of a cell

Returns:
poles(Pole, Pole)

Two cell poles in arbitrary order

delta.utils.image_edges(contour: Contour, shape: tuple[int, int]) str[source]

Identify if cell touches image borders.

Parameters:
contourlist

Single cell contour from cv2 findcontours.

shapetuple[int, int]

Shape of the image.

Returns:
edge_strstr

String describing edges touched by the cell. Can be a combination of the following strs: ‘-x’, ‘+x’, ‘-y’, ‘+y’. Empty otherwise.

delta.utils.list_files(directory: Path, suffixes: Iterable[str]) list[Path][source]

Return a sorted list of filenames in directory that have one of the specified extensions.

Parameters:
directoryPath

Directory to iterate.

suffixesIterable[str]

List, tuple, set, etc. of allowed extensions.

Returns:
[Path]

List of matching filenames.

delta.utils.pathfinding(cost_map: Image, start: Pole, goal: Pole) ndarray[tuple[Any, ...], dtype[int16]][source]

Find the shortest path between two poles that minimizes the cost map.

Parameters:
cost_map: Image

Map of cost per pixel to find path through. Typically inverse of the distance transform. Dimensions are (size_y, size_x)

start: Pole

Coordinates of the starting point of the path. Typically should be a cell pole.

goal: Pole

Coordinates of the end point of the path. Typically should be a cell pole.

Returns:
starttuple[int]
delta.utils.print_diffs(diffs: list[str | list], lasts: list[bool] | None = None) None[source]

Print a hierarchical list of differences.

delta.utils.random_colors(cellids: Sequence[int], seed: int = 0) dict[int, tuple[float, float, float]][source]

Generate list of random hsv colors.

Parameters:
cellidsIterable (for example list, tuple or iterator)

Cellids which should be assigned random colors.

seedint, optional

Random seed used to shuffle colors.

Returns:
colorsdict[int, tuple[float, float, float]]

Dictionary of cellids to colors (RGB values in [0,1]).

delta.utils.roi_features(labels: Labels, poles: dict[int, tuple[Pole, Pole]], fluo_frames: Image) dict[int, CellFeatures][source]

Extract single-cell morphological and fluorescence features.

Parameters:
labelsLabels

Labels image of numbered cell regions.

polesdict[int, tuple[Pole, Pole]],

Dict of cellid to poles.

fluo_framesImage

Array of fluo frames to extract fluorescence from. Dimensions are (size_x, size_y, fluo_channels). The number of fluo_channels must match the number of fluo features to extract.

Returns:
cell_featuresdict[int, CellFeatures]

Dictionary that associates cellids and CellFeatures.

delta.utils.tensorboard_callback() TensorBoard[source]

Return a callback for TensorBoard logging.

Returns:
TensorBoard

TensorBoard callback.

delta.utils.track_poles(features: CellFeatures, prev_old: Pole, prev_new: Pole) CellFeatures[source]

Track poles of a cell to the previous old and new poles.

Parameters:
featuresCellFeatures

Cell features object with possibly switched poles.

prev_oldPole

Previous old pole of the cell.

prev_newPole

Previous new pole of the cell.

Returns:
featuresCellFeatures

Cell features object with correct poles.

delta.utils.tracking_scores(labels: Labels, logits: ndarray[tuple[Any, ...], dtype[float32]], boxes: list[CroppingBox]) ndarray[tuple[Any, ...], dtype[float32]][source]

Get overlap scores between input/target cells and tracking outputs.

Parameters:
labels2D array of np.uint16

Labelled image (untracked) of the current frame.

logits3D array of floats (previous_cells, sizex, sizey)

Tracking U-Net output.

boxeslist[CroppingBox]

Cropping boxes to re-place output prediction masks in the original coordinates to index the labels frame.

Returns:
scores2D array of floats (previous_cells, current_cells)

Overlap scores matrix between tracking predictions and current segmentation mask for each new-old cell.

delta.utils.training_callbacks(model_file: str | Path, verbose: int = 1) list[Any][source]

Return common callbacks convenient for training.

delta.utils.write_video(images: list[ndarray[tuple[Any, ...], dtype[uint8]]], filename: str | Path, crf: int = 20, verbose: int = 1) None[source]

Write images stack to video file with h264 compression.

Parameters:
images4D numpy array

Stack of RGB images to write to video file.

filenamestr or Path

File name to write video to. (Overwritten if exists)

crfint, optional

Compression rate. ‘Sane’ values are 17-28. See https://trac.ffmpeg.org/wiki/Encode/H.264 The default is 20.

verboseint, optional

Verbosity of console output. The default is 1.