API Reference

Function documentation is generated from in-code docstrings.

Featurization utils

Colocalization feature extraction utilities for 3D image objects.

Computes per-object colocalization metrics (Pearson correlation, Manders coefficients, overlap coefficient, K1/K2 coefficients) between pairs of fluorescence channels using the Costes automatic thresholding method.

class zedprofiler.featurization.colocalization.SupportsTwoObjectLoader(*args, **kwargs)[source]

Minimal loader interface required for paired-object colocalization.

compartment: str
image1: ndarray
image2: ndarray
image_set_loader: _SupportsImageSetName
label_image: ndarray
object_ids: Sequence[int]
zedprofiler.featurization.colocalization.bisection_costes_threshold_calculation(first_image: ndarray, second_image: ndarray, scale_max: int = 255) tuple[float, float][source]

Find the Costes Automatic Threshold for colocalization via bisection. Candidate thresholds are selected from within a window of possible intensities, this window is narrowed based on the R value of each tested candidate. We’re looking for the first point at 0, and R value can become highly variable at lower thresholds in some samples. Therefore the candidate tested in each loop is 1/6th of the window size below the maximum value (as opposed to the midpoint).

Parameters:
  • first_image (numpy.ndarray) – The first fluorescence image.

  • second_image (numpy.ndarray) – The second fluorescence image.

  • scale_max (int, optional) – The maximum value for the image scale, by default 255.

Returns:

The calculated thresholds for the first and second images.

Return type:

Tuple[float, float]

zedprofiler.featurization.colocalization.calculate_colocalization(cropped_image_1: ndarray, cropped_image_2: ndarray, thr: int = 15, fast_costes: str = 'Accurate') dict[str, float][source]

This function calculates the colocalization coefficients between two images. It computes the correlation coefficient, Manders’ coefficients, overlap coefficient, and Costes’ coefficients. The results are returned as a dictionary.

Parameters:
  • cropped_image_1 (numpy.ndarray) – The first cropped image.

  • cropped_image_2 (numpy.ndarray) – The second cropped image.

  • thr (int, optional) – The threshold for the Manders’ coefficients, by default 15

  • fast_costes (str, optional) – The mode for Costes’ threshold calculation, by default “Accurate”. Options are “Accurate”, “Fast”, or “Faster” (matching CellProfiler’s three Costes methods). “Accurate” tests every threshold value using a linear scan (slowest, most precise). “Fast” uses the same linear scan but skips candidate thresholds when the Pearson R is far from the crossing point (faster, slightly less precise). “Faster” uses a bisection algorithm and is substantially faster for 16-bit images (least precise).

Returns:

The output features for colocalization analysis.

Return type:

Dict[str, float]

zedprofiler.featurization.colocalization.compute_colocalization(two_object_loader: SupportsTwoObjectLoader, thr: int = 15, fast_costes: str = 'Accurate', channel1: str | None = None, channel2: str | None = None) DataFrame[source]

Compute colocalization features for pairs of objects from two channels.

Parameters:
  • two_object_loader (SupportsTwoObjectLoader) – The loader that provides access to the two channels and their corresponding labels.

  • thr (int, optional) – The threshold for the Manders’ coefficients, by default 15

  • fast_costes (str, optional) – The mode for Costes’ threshold calculation, by default “Accurate”. Options are “Accurate”, “Fast”, or “Faster” (matching CellProfiler’s three Costes methods). “Accurate” tests every threshold value using a linear scan (slowest, most precise). “Fast” uses the same linear scan but skips candidate thresholds when the Pearson R is far from the crossing point (faster, slightly less precise). “Faster” uses a bisection algorithm and is substantially faster for 16-bit images (least precise).

  • channel1 (str | None, optional) – The name of the first channel, used for feature naming, by default None

  • channel2 (str | None, optional) – The name of the second channel, used for feature naming, by default None

Returns:

Wide-format DataFrame with one row per object pair and one column per colocalization metric, plus Metadata columns.

Return type:

pandas.DataFrame

zedprofiler.featurization.colocalization.linear_costes_threshold_calculation(first_image: ndarray, second_image: ndarray, scale_max: int = 255, fast_costes: str = 'Accurate') tuple[float, float][source]

Finds the Costes Automatic Threshold for colocalization using a linear algorithm. Candidate thresholds are gradually decreased until Pearson R falls below 0. If “Fast” mode is enabled the “steps” between tested thresholds will be increased when Pearson R is much greater than 0. The other mode is “Accurate” which will always step down by the same amount.

Parameters:
  • first_image (numpy.ndarray) – The first fluorescence image.

  • second_image (numpy.ndarray) – The second fluorescence image.

  • scale_max (int, optional) – The maximum value for the image scale, by default 255.

  • fast_costes (str, optional) – The mode for the Costes threshold calculation, by default “Accurate”.

Returns:

The calculated thresholds for the first and second images.

Return type:

Tuple[float, float]

zedprofiler.featurization.colocalization.prepare_two_images_for_colocalization(*, label_object1: ndarray, label_object2: ndarray, image_object1: ndarray, image_object2: ndarray, object_id1: int, object_id2: int) tuple[ndarray, ndarray][source]

Prepare two images for colocalization analysis by cropping to object bbox. It selects objects from label images, calculates their bounding boxes, and crops both images accordingly.

Parameters:
  • label_object1 (numpy.ndarray) – The segmented label image for the first object.

  • label_object2 (numpy.ndarray) – The segmented label image for the second object.

  • image_object1 (numpy.ndarray) – The spectral image to crop for the first object.

  • image_object2 (numpy.ndarray) – The spectral image to crop for the second object.

  • object_id1 (int) – The object index to select from the label image for the first object.

  • object_id2 (int) – The object index to select from the label image for the second object.

Returns:

The two cropped images for colocalization analysis.

Return type:

Tuple[numpy.ndarray, numpy.ndarray]

Calculate the granularity spectrum of a 3D image.

zedprofiler.featurization.granularity.anisotropic_ball(radius: int, spacing: tuple[float, float, float] | None = None) ndarray[source]

Build a spherical structuring element that is physically isotropic.

Parameters:
  • radius (int) – Radius of the structuring element in voxel units.

  • spacing (tuple[float, float, float] or None) – Physical spacing of the image in (z, y, x) order. If None, the structuring element is isotropic in voxel space. If provided, the structuring element will be isotropic in physical space, taking into account the anisotropy of the voxel spacing.

Returns:

  • numpy.ndarray – A boolean array representing the structuring element, where True values indicate the presence of the struct during element and False values indicate the absence.

zedprofiler.featurization.granularity.compute_granularity(object_loader: ObjectLoader, *, radius: int = 10, granular_spectrum_length: int = 16, subsample_size: float = 0.25, image_sample_size: float = 0.25, mask_threshold: float = 0.9, verbose: bool = False, image_mask: ndarray | None = None) DataFrame[source]

Calculate the granularity spectrum of a 3D image.

Based on the CellProfiler MeasureGranularity algorithm, generalized to 3D: 1. Subsample the image uniformly (same factor for Z, Y, X). 2. Further subsample for background tophat removal. 3. Iteratively erode with a spherical structuring element and reconstruct, measuring signal lost at each scale as image-level and per-object values.

The structuring elements used for background removal and the erosion spectrum are physically isotropic spheres (see anisotropic_ball), not raw voxel-space spheres, so results are correct rather than biased when z-spacing differs from x/y-spacing.

Parameters:
  • object_loader (ObjectLoader) – Loader containing the image and label arrays.

  • radius (int) – Radius of the structuring element for background removal. Should correspond to texture radius after subsampling.

  • granular_spectrum_length (int) – Number of granularity scales to measure.

  • subsample_size (float) – Subsampling factor for the image (0, 1]. Applied uniformly to Z/Y/X.

  • image_sample_size (float) – Subsampling factor for background reduction (0, 1]. Applied relative to the already-subsampled image.

  • mask_threshold (float) – Threshold for converting interpolated masks back to boolean.

  • verbose (bool) – Print diagnostic information.

  • image_mask (numpy.ndarray or None) – Boolean mask matching the image shape. Corresponds to CellProfiler’s im.mask. If None (default), all pixels are considered valid (all-True mask), matching the typical CellProfiler behavior for unmasked images.

  • channel (str or None) – Optional channel name for feature naming. If None, channel is not included in feature names.

  • compartment (str or None) – Optional compartment name for feature naming. If None, compartment is not included in feature names.

Returns:

Wide-format DataFrame with one row per object and one column per granularity scale, plus Metadata columns.

Return type:

pandas.DataFrame

Intensity feature extraction utilities for 3D image objects.

Provides functions to compute intensity statistics (mean, median, min, max, standard deviation, quartiles), edge-based measurements, center-of-mass coordinates, and mass displacement for segmented 3D objects.

zedprofiler.featurization.intensity.compute_intensity(object_loader: ObjectLoader) DataFrame[source]

Measure the intensity of objects in a 3D image.

Parameters:

object_loader (ObjectLoader) – The object loader containing the image and label image.

Returns:

Wide-format DataFrame with one row per object and one column per intensity measurement, plus Metadata columns.

Return type:

pandas.DataFrame

zedprofiler.featurization.intensity.get_outline(mask: ndarray) ndarray[source]

Get the outline of a 3D mask.

Parameters:

mask (numpy.ndarray) – The input mask.

Returns:

The outline of the mask.

Return type:

numpy.ndarray

Neighbors featurization module.

zedprofiler.featurization.neighbors.adjacency_footprint(anisotropy_factor: float) ndarray[source]

Build a 6-connectivity dilation footprint sized to represent one physical unit of “touching” distance in each direction.

skimage.morphology.dilation’s default footprint expands 1 voxel in every axis, which only means the same physical distance in every direction when voxels are isotropic. When z-spacing is coarser than x/y-spacing (anisotropy_factor > 1), 1 z-voxel already represents anisotropy_factor times more physical distance than 1 x/y-voxel, so the x/y arms are extended by that same factor to match.

At anisotropy_factor == 1 this reduces to exactly the same 6-connected cross skimage uses by default.

Parameters:

anisotropy_factor (float) – Ratio of z-spacing to x/y-spacing.

Returns:

Boolean footprint of shape (3, 2*xy_radius + 1, 2*xy_radius + 1).

Return type:

numpy.ndarray

zedprofiler.featurization.neighbors.calculate_centroid(coords: DataFrame) ndarray[source]

Calculate the centroid of cell coordinates.

zedprofiler.featurization.neighbors.classify_cells_into_shells(coords: DataFrame | dict, n_shells: int = 5, method: str = 'mahalanobis', min_cells_per_shell: int = 3, centroid: ndarray | None = None, spacing: tuple[float, float, float] | None = None) tuple[dict, ndarray | None][source]

Classify cells into radial shells based on distance from centroid.

Automatically adjusts n_shells for small organoids to ensure meaningful statistics.

Parameters:
  • coords (pandas.DataFrame or dict) – Cell coordinates with /keys: object_id, z, y, x

  • n_shells (int) – Number of concentric shells to create (will be adjusted if needed)

  • method (str) – ‘euclidean’ or ‘mahalanobis’

  • min_cells_per_shell (int) – Minimum average cells per shell (default: 3)

  • centroid (numpy.ndarray, optional) – Pre-calculated centroid (if None, will be calculated from coords)

  • spacing (tuple[float, float, float], optional) – Physical voxel spacing in (z, y, x) order, matching coords. Pass this when the volume has anisotropic spacing so that distances (and therefore shell assignments) reflect physical space rather than raw voxel counts. Defaults to None (isotropic, all axes weighted equally).

Returns:

results – Dictionary containing: - ‘ShellAssignments’: Shell number for each cell (0 = innermost) - ‘DistancesFromCenter’: Distance from centroid for each cell - ‘DistancesFromExterior’: Distance from exterior for each cell - ‘NormalizedDistancesFromCenter’: Normalized distances (0-1)

Return type:

dict

zedprofiler.featurization.neighbors.compute_neighbors(object_loader: ObjectLoader, distance_threshold: int = 10, anisotropy_factor: int = 10) DataFrame[source]

This function calculates the number of neighbors for each object in a 3D image.

Parameters:
  • object_loader (ObjectLoader) – The object loader object that contains the image and label image.

  • distance_threshold (int, optional) – The distance threshold for counting neighbors, by default 10

  • anisotropy_factor (int, optional) – The anisotropy factor for the image where the anisotropy factor is the ratio of the pixel size in the z direction to the pixel size in the x and y directions, by default 10

Returns:

Wide-format DataFrame with one row per object and columns for NeighborsCountAdjacent and NeighborsCountByDistance, plus Metadata columns.

Return type:

pandas.DataFrame

zedprofiler.featurization.neighbors.create_results_dataframe(results: dict) DataFrame[source]

Create a pandas DataFrame with all cell information.

Parameters:

results (dict) – Results from classify_cells_into_shells

Returns:

df – DataFrame with cell information

Return type:

pandas.DataFrame

zedprofiler.featurization.neighbors.crop_3D_image(image: ndarray, bbox: tuple[int, int, int, int, int, int]) ndarray[source]

Crop the 3D image to the bounding box of the object.

Parameters:
  • image (numpy.ndarray) – The 3D image to be cropped.

  • bbox (BBox3D) – The bounding box of the object in the format (z1, y1, x1, z2, y2, x2).

Returns:

The cropped 3D image.

Return type:

numpy.ndarray

zedprofiler.featurization.neighbors.euclidean_distance_from_centroid(coords: ndarray, centroid: ndarray, spacing: tuple[float, float, float] | None = None) ndarray[source]

Calculate Euclidean distance from centroid for each cell.

Parameters:
  • coords (ndarray) – Cell coordinates (n_cells, 3), in (z, y, x) order.

  • centroid (ndarray) – Centroid coordinates (3,), in (z, y, x) order.

  • spacing (tuple[float, float, float] or None) – Physical voxel spacing in (z, y, x) order, matching coords. If None (default), coordinates are treated as already isotropic (all axes weighted equally). Pass this whenever coords are raw voxel indices from an anisotropic volume, so distances reflect physical space rather than voxel counts.

zedprofiler.featurization.neighbors.get_coordinates(nuclei_mask: ndarray, object_ids: list | None = None) DataFrame[source]

Extract coordinates from a labeled mask.

Parameters:
  • nuclei_mask (ndarray) – 3D labeled mask where each object has a unique ID

  • object_ids (list) – List of object IDs to extract

Returns:

coords – DataFrame with columns: object_id, x, y, z

Return type:

pandas.DataFrame

zedprofiler.featurization.neighbors.mahalanobis_distance_from_centroid(coords: ndarray, centroid: ndarray, min_cells_threshold: int = 50, spacing: tuple[float, float, float] | None = None) ndarray[source]

Calculate Mahalanobis distance from centroid for each cell. This accounts for the covariance structure (shape) of the organoid.

For small sample sizes (<50 cells), uses regularization or falls back to Euclidean.

Parameters:
  • coords (ndarray) – Cell coordinates (n_cells, 3), in (z, y, x) order.

  • centroid (ndarray) – Centroid coordinates (3,), in (z, y, x) order.

  • min_cells_threshold (int) – Minimum cells needed for reliable Mahalanobis (default: 50)

  • spacing (tuple[float, float, float] or None) – Physical voxel spacing in (z, y, x) order, matching coords. If None (default), coordinates are treated as already isotropic. Pass this whenever coords are raw voxel indices from an anisotropic volume, so both the covariance structure and the distance reflect physical space rather than voxel counts.

Returns:

distances – Mahalanobis distances for each cell

Return type:

ndarray

zedprofiler.featurization.neighbors.neighbors_expand_box(min_coor: int, max_coord: int, current_min: int, current_max: int, expand_by: int) tuple[int, int][source]

Expand the bounding box of the object by a specified distance in each direction.

Parameters:
  • min_coor (Union[int, float]) – The global minimum coordinate of the image.

  • max_coord (Union[int, float]) – The global maximum coordinate of the image.

  • current_min (Union[int, float]) – The current minimum coordinate of the object.

  • current_max (Union[int, float]) – The current maximum coordinate of the object.

  • expand_by (int) – The distance by which to expand the bounding box.

Returns:

The new minimum and maximum coordinates of the bounding box.

Return type:

Tuple[Union[int, float], Union[int, float]]

zedprofiler.featurization.neighbors.plot_distance_distributions(classification_results: dict, n_shells: int | None = None) Figure[source]

Plot distance distributions for each shell.

Parameters:
  • classification_results (dict) – Results from classify_cells_into_shells

  • n_shells (int, optional) – Number of shells (will use ShellsUsed from results if not provided)

zedprofiler.featurization.neighbors.visualize_organoid_shells(coords: DataFrame, classification_results: dict, title: str = 'Organoid Shell Classification', centroid: ndarray | None = None) Figure[source]

Create 3D visualization of organoid with shell coloring.

Parameters:
  • coords (pandas.DataFrame or dict) – Cell coordinates with columns/keys: object_id, z, y, x

  • classification_results (dict) – Results from classify_cells_into_shells

  • title (str) – Plot title

This module generates texture features for each object in the image using Haralick features.

We do this in a as close to zero-copy way as possible. We want to make this module fast, memory efficient, and robust to large images and objects. We want this module to be python api callable and scalable.

zedprofiler.featurization.texture.compute_texture(object_loader: ObjectLoader, distance: int = 1, grayscale: int = 256) DataFrame[source]

Calculate texture features for each object in the image using Haralick features.

The features are calculated for each object separately and the mean value is returned.

Parameters:
  • object_loader (ObjectLoader) – The object loader containing the image and object information.

  • distance (int, optional) – The distance parameter for Haralick features, by default 1

  • grayscale (int, optional) – The number of gray levels to scale the image to, by default 256

Returns:

Wide-format DataFrame with one row per object and one column per Haralick texture feature (direction x feature_name x distance x grayscale), plus Metadata columns. Feature names follow the pattern: <compartment>_<channel>_Texture_<feature>-<distance>-<direction>-<grayscale>

Haralick features measured per direction: AngularSecondMoment, Contrast, Correlation, Variance, InverseDifferenceMoment, SumAverage, SumVariance, SumEntropy, Entropy, DifferenceVariance, DifferenceEntropy, InformationMeasureOfCorrelation1, InformationMeasureOfCorrelation2

Return type:

pandas.DataFrame

zedprofiler.featurization.texture.resample_to_isotropic(image: ndarray, anisotropy_factor: float, order: int = 3) ndarray[source]

Resample a (z, y, x) volume to isotropic voxel spacing along z. This function is written to be used for both the signal image and the mask image. The order parameter controls the interpolation for the resampling. For the signal image, we use cubic spline interpolation (order=3). For the mask image, we use nearest neighbor interpolation (order=0).

mahotas.features.haralick’s distance parameter is a voxel count, not a physical length, and several of its 13 directions step along z. If z spacing is coarser than x/y spacing (the common microscopy case), those directions sample a larger physical distance than the in-plane directions, which biases the resulting Haralick features. Stretching the z axis by the anisotropy factor before computing texture makes “1 voxel” represent the same physical distance in every direction.

Parameters:
  • image (numpy.ndarray) – 3D array in (z, y, x) order.

  • anisotropy_factor (float) – Ratio of z-spacing to x/y-spacing (assumes isotropic x/y spacing).

  • order (int, optional) – Interpolation order for the resampling, by default 1 (linear).

Returns:

The volume resampled so that voxels are isotropic in physical space.

Return type:

numpy.ndarray

zedprofiler.featurization.texture.scale_image(image: ndarray, num_gray_levels: int = 256) ndarray[source]

Scale the image to a specified number of gray levels. Example: 1024 gray levels will be scaled to 256 gray levels if num_gray_levels=256. An image with a pixel value of 0 will be scaled to 0 and a pixel value of 1023 will be scaled to 255.

Parameters:
  • image (numpy.ndarray) – The input image to be scaled. Can be a ndarray of any shape.

  • num_gray_levels (int, optional) – The number of gray levels to scale the image to, by default 256

Returns:

The gray level scaled image of any shape.

Return type:

numpy.ndarray

Volume, size, and shape features for 3D objects.

class zedprofiler.featurization.volumesizeshape.SupportsImageSetLoader(*args, **kwargs)[source]

Minimal image-set loader interface required by this module.

anisotropy_spacing: tuple[float, float, float]
class zedprofiler.featurization.volumesizeshape.SupportsObjectLoader(*args, **kwargs)[source]

Minimal object loader interface required by this module.

channel: str
compartment: str
image_set_loader: _SupportsImageSetName
label_image: ndarray
object_ids: Sequence[int]
zedprofiler.featurization.volumesizeshape.calculate_surface_area(label_object: ndarray, props: dict[str, ndarray], spacing: tuple[float, float, float], label: int | None = None) float[source]

Calculate surface area for one labeled object using marching cubes.

zedprofiler.featurization.volumesizeshape.compute_volume_size_shape(image_set_loader: SupportsImageSetLoader | None = None, object_loader: SupportsObjectLoader | None = None) DataFrame[source]

Compute volume/size/shape features for one object loader.

Supports two invocation modes:

  • no arguments: returns an empty deterministic schema so dispatchers can call the function without crashing.

  • both loaders provided: executes feature extraction.

zedprofiler.featurization.volumesizeshape.measure_3D_volume_size_shape(image_set_loader: SupportsImageSetLoader, object_loader: SupportsObjectLoader) DataFrame[source]

Measure volume/size/shape features for each non-zero label object.

Image utils

zedprofiler.image_utils.image_utils.check_for_xy_squareness(bbox: tuple[int, int, int, int, int, int]) float[source]

This function returns the ratio of the x length to the y length A value of 1 indicates a square bbox is present

Parameters:

bbox (The bbox to check) – (z_min, y_min, x_min, z_max, y_max, x_max) Where each value is an int representing the pixel coordinate of the bbox in that dimension

Returns:

The ratio of the y length to the x length of the bbox. A value of 1 indicates a square bbox.

Return type:

float

zedprofiler.image_utils.image_utils.crop_3D_image(image: ndarray, bbox: tuple[int, int, int, int, int, int]) ndarray[source]

Crop a 3D image to the bounding box of a mask.

Parameters:
  • image (numpy.ndarray) – The image to crop.

  • bbox (BBox3D) – The bounding box of the mask.

Returns:

The cropped image.

Return type:

numpy.ndarray

zedprofiler.image_utils.image_utils.expand_box(min_coor: int, max_coord: int, current_min: int, current_max: int, expand_by: int) tuple[int, int][source]

Expand the bounding box of an object in a 3D image.

Parameters:
  • min_coor (int) – The minimum coordinate of the image for any dimension.

  • max_coord (int) – The maximum coordinate of the image for any dimension.

  • current_min (int) – The current minimum coordinate of an object’s bounding box for any dimension.

  • current_max (int) – The current maximum coordinate of an object’s bounding box for any dimension.

  • expand_by (int) – The amount to expand the bounding box by.

Returns:

The new minimum and maximum coordinates of the bounding box.

Return type:

Tuple[int, int]

Raises:

ValueError – If the expansion is not possible.

zedprofiler.image_utils.image_utils.new_crop_border(bbox1: tuple[int, int, int, int, int, int], bbox2: tuple[int, int, int, int, int, int], image: ndarray) tuple[tuple[int, int, int, int, int, int], tuple[int, int, int, int, int, int]][source]

Expand the bounding boxes of two objects in a 3D image to match their sizes.

Parameters:
  • bbox1 (BBox3D) – The bounding box of the first object.

  • bbox2 (BBox3D) – The bounding box of the second object.

  • image (numpy.ndarray) – The image to crop for each of the bounding boxes.

Returns:

The new bounding boxes of the two objects.

Return type:

tuple[BBox3D, BBox3D]

Raises:

ValueError – If the expansion is not possible.

zedprofiler.image_utils.image_utils.select_objects_from_label(label_image: ndarray, object_ids: list | ndarray | int) ndarray[source]

Selects objects from a label image based on the provided object IDs.

Parameters:
  • label_image (numpy.ndarray) – The segmented label image.

  • object_ids (list) – The object IDs to select.

Returns:

The label image with only the selected objects.

Return type:

numpy.ndarray

zedprofiler.image_utils.image_utils.single_3D_image_expand_bbox(image: ndarray, bbox: tuple[int, int, int, int, int, int], expand_pixels: int, anisotropy_factor: int) tuple[int, int, int, int, int, int][source]

Expand the bbox in a way that keeps the crop within the confines of the image volume

Parameters:
  • image (numpy.ndarray) – 3D image array from which the bbox was derived

  • bbox (tuple[int, int, int, int, int, int]) – 3D bbox in the format (zmin, ymin, xmin, zmax, ymax, xmax)

  • expand_pixels (int) – number of pixels to expand the bbox in each direction (z, y, x) the coordinates become isotropic here so the expansion is the same across dimensions, but the anisotropy factor is used to adjust for the z dimension

  • anisotropy_factor (int) – The ratio of “pixel” size in um between the z dimension and the x/y dimensions. This is used to adjust the expansion of the bbox in the z dimension to account for anisotropy in the image volume. For example, if the z spacing is 5um and the x/y spacing is 1um, then the anisotropy factor would be 5.

Returns:

Updated bbox in the format (zmin, ymin, xmin, zmax, ymax, xmax) after expansion and adjustment for anisotropy

Return type:

tuple[int, int, int, int, int, int]

zedprofiler.image_utils.image_utils.square_off_xy_crop_bbox(bbox: tuple[int, int, int, int, int, int]) tuple[int, int, int, int, int, int][source]

Adjust the bbox to be square in the XY plane.

The function computes the new bbox from the current X/Y dimensions.

Parameters:

bbox (tuple[int, int, int, int, int, int]) –

The bbox to adjust: (z_min, y_min, x_min, z_max, y_max, x_max)

Each value is an integer pixel coordinate in that dimension.

Returns:

The adjusted bbox that is square in the XY plane: (z_min, new_y_min, new_x_min, z_max, new_y_max, new_x_max)

Each value is an integer pixel coordinate in that dimension.

Return type:

tuple[int, int, int, int, int, int]

IO utils

Functions for formatting morphology feature names in a consistent way.

Formats morphology feature names and saves features as parquet files.

class zedprofiler.IO.feature_writing_utils.FeatureMetadata(compartment: str, channel: str, feature_type: str, cpu_or_gpu: str)[source]

Metadata for feature output.

channel: str
compartment: str
cpu_or_gpu: str
feature_type: str
zedprofiler.IO.feature_writing_utils.format_morphology_feature_name(compartment: object, channel: object, feature_type: object, measurement: object) str[source]

Format a morphology feature name consistently across all morphology features. This format follows specification for the following: https://github.com/WayScience/NF1_3D_organoid_profiling_pipeline/blob/main/docs/RFC-2119-Feature-Naming-Convention.md

Parameters:
  • compartment (str) – The compartment name.

  • channel (str) – The channel name.

  • feature_type (str) – The feature type.

  • measurement (str) – The measurement name.

Returns:

The formatted feature name.

Return type:

str

zedprofiler.IO.feature_writing_utils.remove_underscores_from_string(string: object) str[source]

Remove unwanted delimiters from a string and replace them with hyphens.

Parameters:

string (str) – The string to remove unwanted delimiters from.

Returns:

The string with unwanted delimiters removed and replaced with hyphens.

Return type:

str

zedprofiler.IO.feature_writing_utils.save_features_as_parquet(parent_path: Path, df: DataFrame, metadata: FeatureMetadata, atomic: bool = False) Path[source]

Save features as parquet files in a consistent way.

Saves features as parquet files with consistent naming across morphology features.

Parameters:
  • parent_path (pathlib.Path) – The parent path to save the features to.

  • df (pandas.DataFrame) – The dataframe containing the features to save.

  • metadata (FeatureMetadata) – Metadata for the feature output (compartment, channel, feature_type, cpu_or_gpu).

  • atomic (bool) – When True, write to a sibling .tmp file then atomically replace the destination via os.replace. This prevents a crashed write from leaving a partial parquet file that a restartable caller (using --skip-existing) could mistake for a complete one. Default False preserves the existing direct-write behavior.

Return type:

pathlib.Path

Data-loading classes for featurization workflows.

class zedprofiler.IO.loading_classes.ImageSetConfig(image_set_name: str | None = None, label_key_name: list[str] | None = None, raw_image_key_name: list[str] | None = None, patient_tumor: str | None = None, plate: str | None = None, well: str | None = None, field_of_view: int | str | None = None)[source]

Configuration options for ImageSetLoader.

field_of_view: int | str | None = None
property image_id: str | None

Deterministic Metadata_Imaging_ImageID value, or None if unset.

Returns build_image_id(...) when all four coordinate fields are set, otherwise None (the loader then falls back to image_set_name).

image_set_name: str | None = None
label_key_name: list[str] | None = None
patient_tumor: str | None = None
plate: str | None = None
raw_image_key_name: list[str] | None = None
well: str | None = None
class zedprofiler.IO.loading_classes.ImageSetLoader(*, anisotropy_spacing: tuple[float, float, float], channel_mapping: dict[str, str], image_set_path: Path | None, label_set_path: Path | None, image_set_array: ndarray | None = None, label_set_array: ndarray | None = None, config: ImageSetConfig | None = None)[source]

ImageSet in this context refers to a set of images that can be related to each other via their metadata. For example all images coming from the same well, FOV or timepoint but different spectral channels and segmentation labels.

Load an image set consisting of raw z stack images and segmentation labels.

A class to load an image set consisting of raw z stack images from multiple spectral channels and segmentation labels. The images are loaded into a dictionary, and various attributes and compartments are extracted from the images. The class also provides methods to retrieve images and their attributes.

Parameters:
  • image_set_path (pathlib.Path) – Path to the image set directory.

  • label_set_path (pathlib.Path) – Path to the label set directory.

  • anisotropy_spacing (tuple) – The anisotropy spacing of the images in format (z_spacing, y_spacing, x_spacing).

  • channel_mapping (dict) – A dictionary mapping channel names to their corresponding image file names. Example: {'nuclei': 'nuclei_', 'cell': 'cell_', 'cytoplasm': 'cytoplasm_'}

image_set_name

The name of the image set.

Type:

str

anisotropy_spacing

The anisotropy spacing of the images.

Type:

tuple

anisotropy_factor

The anisotropy factor calculated from the spacing.

Type:

float

image_set_dict

A dictionary containing the loaded images, with keys as channel names.

Type:

dict

unique_label_objects

A dictionary containing unique object IDs for each label in the image set.

Type:

dict

unique_compartment_objects

A dictionary containing unique object IDs for each compartment in the image set. A compartment is defined as a segmented region in the image (e.g., Cell, Cytoplasm, Nuclei, Organoid). The compartments are bounds for measurements.

Type:

dict

image_names

A list of image names in the image set.

Type:

list

compartments

A list of compartment names in the image set.

Type:

list

classmethod from_image_dict(image_dict: dict[str, ndarray], *, anisotropy_spacing: tuple[float, float, float], image_set_name: str | None = None, label_key_names: list[str] | None = None, patient_tumor: str | None = None, plate: str | None = None, well: str | None = None, field_of_view: int | str | None = None) ImageSetLoader[source]

Build an ImageSetLoader from an in-memory channel/label dict.

Existing constructors only accept a directory glob (path-based) or a single array (array-based). A well/FOV shard carries multiple channels and multiple compartments as distinct arrays, so this classmethod builds the image_set_dict directly from a pre-loaded {key: ndarray} mapping. It formalizes the ImageSetLoader.__new__ workaround previously used in the colocalization test helper.

Parameters:
  • image_dict (dict[str, numpy.ndarray]) – Mapping of channel names and compartment names to their arrays. Each array is validated through ImageArrayModel.

  • anisotropy_spacing (tuple[float, float, float]) – (z_spacing, y_spacing, x_spacing).

  • image_set_name (str | None) – Optional image set name (emitted as Metadata_Experiment_ImageSet).

  • label_key_names (list[str] | None) – Keys in image_dict that are compartment labels (not channels). Used by get_compartments to distinguish compartments from raw channels.

  • patient_tumor (optional) – Imaging-coordinate identifier fields. When all four are set, the loader’s image_id is the deterministic Metadata_Imaging_ImageID; otherwise it falls back to image_set_name.

  • plate (optional) – Imaging-coordinate identifier fields. When all four are set, the loader’s image_id is the deterministic Metadata_Imaging_ImageID; otherwise it falls back to image_set_name.

  • well (optional) – Imaging-coordinate identifier fields. When all four are set, the loader’s image_id is the deterministic Metadata_Imaging_ImageID; otherwise it falls back to image_set_name.

  • field_of_view (optional) – Imaging-coordinate identifier fields. When all four are set, the loader’s image_id is the deterministic Metadata_Imaging_ImageID; otherwise it falls back to image_set_name.

Returns:

A fully initialized loader (compartments, image names, and unique compartment objects populated).

Return type:

ImageSetLoader

get_anisotropy() float[source]

Return the anisotropy factor for the image set.

Returns:

Ratio of z-spacing to y-spacing.

Return type:

float

get_compartments() list[str][source]

Populate compartment names from available keys.

A compartment is a key explicitly declared as a label key via ImageSetConfig.label_key_name, not a raw intensity channel.

Returns:

List of compartment keys.

Return type:

list[str]

get_image(key: str) ndarray[source]

Return an image array for a given key.

Parameters:

key (str) – Channel or label key.

Returns:

Image array for the requested key.

Return type:

numpy.ndarray

get_image_names() list[str][source]

Populate image (non-compartment) names.

Returns:

List of image names excluding compartment labels.

Return type:

list[str]

get_unique_objects_in_compartments() None[source]

Populate unique object IDs per compartment.

Parameters:

None – This method does not take any parameters.

class zedprofiler.IO.loading_classes.ObjectLoader(image_set_loader: ImageSetLoader, channel_name: str, compartment_name: str)[source]

A class to load objects from a labeled image and extract their properties. Where an object is defined as a segmented region in the image. This could be a cell, a nucleus, or any other compartment segmented.

Parameters:
  • image (numpy.ndarray) – The image from which to extract objects. Preferably a 3D image -> z, y, x

  • label_image (numpy.ndarray) – The labeled image containing the segmented objects.

  • channel_name (str) – The name of the channel from which the objects are extracted.

  • compartment_name (str) – The name of the compartment from which the objects are extracted.

image_set_loader

An instance of the ImageSetLoader class containing the image set.

Type:

ImageSetLoader

config

The configuration object containing image set parameters.

Type:

ImageSetConfig

__init__(image, label_image, channel_name, compartment_name)[source]

Initializes the ObjectLoader with the image, label image, channel name, and compartment name.

object_ids: list[int]
class zedprofiler.IO.loading_classes.TwoObjectLoader(image_set_loader: ImageSetLoader, compartment: str, channel1: str, channel2: str)[source]

A class to load two images and a label image for a specific compartment. This class is primarily used for loading images for two-channel analysis like co-localization.

Parameters:
  • image_set_loader (ImageSetLoader) – An instance of the ImageSetLoader class containing the image set.

  • compartment (str) – The name of the compartment for which the label image is loaded.

  • channel1 (str) – The name of the first channel to be loaded.

  • channel2 (str) – The name of the second channel to be loaded.

image_set_loader

An instance of the ImageSetLoader class containing the image set.

Type:

ImageSetLoader

compartment

The name of the compartment for which the label image is loaded.

Type:

str

label_image

The labeled image containing the segmented objects for the specified compartment.

Type:

numpy.ndarray

image1

The image corresponding to the first channel.

Type:

numpy.ndarray

image2

The image corresponding to the second channel.

Type:

numpy.ndarray

object_ids

The unique object IDs for the segmented objects in the specified compartment.

Type:

numpy.ndarray

__init__(image_set_loader, compartment, channel1, channel2)[source]

Initializes the TwoObjectLoader with the image set loader, compartment, and channel names.

Contracts

Core data contracts shared across featurizers.

We have contracts for the data inputs and outputs of featurizers, as well as for column names in the output DataFrame. These contracts are enforced through a combination of Pydantic models, Beartypes Pandera schemas.

Where inputs are the image path or arrays. Outputs are the feature DataFrame and metadata dictionary/Dfs.

The package accepts: - Single-channel 3D arrays shaped (z, y, x)

class zedprofiler.contracts.AnisotropyFactorModel(*, anisotropy_factor: float, y_spacing: float | None = None, x_spacing: float | None = None)[source]

Pydantic model for validating the anisotropy factor.

Feature modules (e.g. texture, neighbors) assume the z-spacing is never finer than the x/y-spacing, so anisotropy_factor (z_spacing / y_spacing) must be 1 or greater. anisotropy_factor collapses to a single z/y ratio, so it is only meaningful when the transverse (y, x) spacings are equal; y_spacing/x_spacing are optional and, when both are provided, are checked for equality.

anisotropy_factor: float
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

classmethod validate_at_least_one(value: float) float[source]

Ensure the anisotropy factor is finite and 1 or greater.

validate_transverse_spacing_equal() AnisotropyFactorModel[source]

Ensure y/x spacing are equal, when both are provided.

x_spacing: float | None
y_spacing: float | None
class zedprofiler.contracts.ColumnNameModel(*, column_name: str, compartment: str | None = None, channel: str | None = None, feature: str | None = None)[source]

Pydantic model for parsing and validating column names.

channel: str | None
column_name: str
compartment: str | None
feature: str | None
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

parse_column_name() ColumnNameModel[source]

Parse column name into components.

classmethod validate_is_string(v: object) str[source]

Ensure column_name is a string.

class zedprofiler.contracts.ExpectedFeatureNameValues(*, compartments: list[str] | None = <factory>, channels: list[str] | None = <factory>, features: list[str] | None = <factory>, expected_values_dict: dict[str, list[str]]=<factory>)[source]

Pydantic model for expected values in feature naming validation.

channels: list[str] | None
compartments: list[str] | None
expected_values_dict: dict[str, list[str]]
features: list[str] | None
model_config = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class zedprofiler.contracts.FeatureDictModel(*, features: dict[str, Any])[source]

Pydantic model for validating feature dictionaries.

features: dict[str, Any]
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

classmethod validate_is_dict(v: object) dict[str, Any][source]

Ensure features is a dictionary.

class zedprofiler.contracts.ImageArrayModel(*, array: ndarray)[source]

Pydantic model for validating image arrays.

array: np.ndarray
model_config = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

classmethod validate_array_dtype_and_shape(arr: ndarray) ndarray[source]

Validate array dtype is numeric and shape is valid.

classmethod validate_array_type(v: object) ndarray[source]

Ensure array is a numpy array.

class zedprofiler.contracts.MetadataDictModel(*, metadata: dict[str, Any])[source]

Pydantic model for validating metadata dictionaries.

metadata: dict[str, Any]
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

classmethod validate_is_dict(v: object) dict[str, Any][source]

Ensure metadata is a dictionary.

class zedprofiler.contracts.ReturnSchemaModel(*, result: dict[str, Any])[source]

Pydantic model for validating return schema.

model_config = {'arbitrary_types_allowed': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

result: dict[str, Any]
classmethod validate_is_dict(v: object) dict[str, Any][source]

Ensure result is a dictionary.

classmethod validate_keys_and_types(result: dict[str, Any]) dict[str, Any][source]

Validate result has correct keys in correct order and correct types.

zedprofiler.contracts.create_image_array_schema() SeriesSchema[source]

Create a Pandera schema for image array validation.

Returns:

Pandera schema for numeric arrays

Return type:

pa.SeriesSchema

zedprofiler.contracts.validate_anisotropy_factor_with_pydantic(anisotropy_factor: float, y_spacing: float | None = None, x_spacing: float | None = None) AnisotropyFactorModel[source]

Validate the anisotropy factor using a Pydantic model.

Parameters:
  • anisotropy_factor (float) – Ratio of z-spacing to y-spacing to validate.

  • y_spacing (float | None, optional) – Y (transverse) spacing. When provided along with x_spacing, they are checked for equality since anisotropy_factor only captures a single z/y ratio.

  • x_spacing (float | None, optional) – X (transverse) spacing. See y_spacing.

Returns:

Validated anisotropy factor model.

Return type:

AnisotropyFactorModel

Raises:

ContractError – If the anisotropy factor is less than MIN_ANISOTROPY_FACTOR, is not finite, or if y_spacing and x_spacing are unequal.

zedprofiler.contracts.validate_column_name_schema(column_name: str, channels: list[str], compartments: list[str], features: list[str] | None = None) bool[source]

Validate the column name schema for required fields and types

Parameters:
  • column_name (str) – The column name to validate

  • channels (list[str]) – List of valid channels for feature naming

  • compartments (list[str]) – List of valid compartments for feature naming

  • features (list[str] | None, optional) – List of valid features for feature naming, by default None

Returns:

The status of the validation

Return type:

bool

Raises:

ContractError – If the column name does not meet the expected schema

zedprofiler.contracts.validate_column_name_with_pydantic(column_name: str) ColumnNameModel[source]

Validate column name using Pydantic model.

Parameters:

column_name (str) – Column name to validate

Returns:

Validated column name model with parsed components

Return type:

ColumnNameModel

Raises:

ContractError – If validation fails

zedprofiler.contracts.validate_image_array_shape_contracts(arr: ndarray) bool[source]

Validate the input array for dimensionality

Parameters:

arr (np.ndarray) – Input array to validate

Returns:

The status of the validation

Return type:

bool

Raises:

ContractError – If the input array does not meet the expected contract

zedprofiler.contracts.validate_image_array_type_contracts(arr: ndarray) bool[source]

Validate the input array for type

Parameters:

arr (np.ndarray) – Input array to validate

Returns:

The status of the validation

Return type:

bool

Raises:

ContractError – If the input array does not meet the expected contract

zedprofiler.contracts.validate_image_with_pydantic(arr: ndarray) ImageArrayModel[source]

Validate the input image array using Pydantic model.

Parameters:

arr (np.ndarray) – Input image array to validate

Returns:

Validated image array model

Return type:

ImageArrayModel

Raises:

ContractError – If validation fails

zedprofiler.contracts.validate_return_schema_contract(result: dict[str, object]) bool[source]

Validate return schema keys, types, and deterministic key ordering.

zedprofiler.contracts.validate_return_with_pydantic(result: dict[str, object]) ReturnSchemaModel[source]

Validate return schema using Pydantic model.

Parameters:

result (dict[str, object]) – Return result to validate

Returns:

Validated return schema model

Return type:

ReturnSchemaModel

Raises:

ContractError – If validation fails

Exceptions

Custom exception types for ZedProfiler.

exception zedprofiler.exceptions.ContractError[source]

Raised when an input violates a documented data contract.

exception zedprofiler.exceptions.ZedProfilerError[source]

Base exception for package-level failures.