Measure (sphero_vem.measure)#

3D morphological shape analysis: voxel-based descriptors, SDF-based surface properties, mesh curvature, fractal dimension, and nucleus distance mapping.

Pipeline#

Pipeline orchestration, I/O, and configuration for label morphology analysis.

class sphero_vem.measure.pipeline.LabelAnalysisConfig(root_path, seg_target, scale_dir, bbox_margin=15, sigma=3.0, eps_voxels=1.5, mesh_downsample_factor=2, h=1.5, voxel_only=False, sigma_frac=0.7, n_steps_frac=30, sep='__')[source]#

Bases: BaseConfig

Configuration for 3D label morphology analysis pipeline.

Defines paths, SDF parameters, and mesh extraction settings for computing shape descriptors from segmented volumetric data stored in zarr format.

Parameters:
  • root_path (Path) – Root path to the zarr store containing segmentation data.

  • seg_target (str) – Name of the segmentation target (e.g., ‘cells’, ‘nuclei’). Used to construct paths: labels/{seg_target}/tables/.

  • scale_dir (str) – Scale directory name within the masks folder (e.g., ‘50-50-50’, ‘s1’).

  • bbox_margin (int, optional) – Margin in voxels to expand bounding boxes for label cropping. Default is 15.

  • sigma (float, optional) – Gaussian smoothing sigma in voxels for SDF computation. Controls surface smoothness for curvature estimation. Default is 3.

  • eps_voxels (float, optional) – Epsilon in voxels for Heaviside volume/area integration. Default is 1.5.

  • mesh_downsample_factor (int, optional) – Factor by which to downsample SDF before marching cubes. Reduces vertex count and computation time. Default is 2.

  • h (float, optional) – Step size in voxels for finite difference curvature estimation. Default is 1.5.

  • voxel_only (bool, optional) – If True, compute only voxel-based properties (skip SDF and mesh). Default is False.

  • sigma_frac (float, optional) – Gaussian smoothing sigma in voxels for SDF computation used during fractal dimension calculation. This should be in the 0.5-1.0 range. Default is 0.7.

  • n_steps_frac (int, optional) – Number of epsilon values sampled in log-space during fractal dimension calculation. Default is 30.

  • sep (str) – Separator used for unpacking tuple columns when saving the region properties dataframe to parquet using save_regionprops. This should be used by read_regionprops to reconstruct the tuple columns, e.g. bbox, centroid… Default is “__”

sphero_vem.measure.pipeline.label_properties(labels, spacing, bbox_margin=15, sigma=3, eps_voxels=1.5, mesh_downsample_factor=2, h=1.5, mesh_save_root=None, voxel_only=False, sigma_frac=0.7, n_steps_frac=30)[source]#

Compute morphological properties for all labels in a 3D volume.

Extracts voxel-based, SDF-based, and mesh-based shape descriptors for each labeled region. Requires isotropic voxel spacing.

Parameters:
  • labels (np.ndarray) – 3D integer array of labeled regions. Background should be 0.

  • spacing (tuple[float]) – Isotropic voxel spacing in physical units (z, y, x).

  • bbox_margin (int, optional) – Margin in voxels to expand bounding boxes when cropping labels. Default is 15.

  • sigma (float, optional) – Gaussian smoothing sigma in voxels for SDF computation. Default is 3.

  • eps_voxels (float, optional) – Epsilon in voxels for Heaviside volume/area integration. Default is 1.5.

  • mesh_downsample_factor (int, optional) – Downsampling factor for SDF before mesh extraction. Default is 2.

  • h (float, optional) – Step size in voxels for finite difference curvature estimation. Default is 1.5.

  • mesh_save_root (Path | None, optional) – If provided, per-label meshes and curvature data are saved as .npz files under {mesh_save_root}/meshes/. Default is None.

  • voxel_only (bool, optional) – If True, skip SDF and mesh computations; return only voxel-based properties. Default is False.

  • sigma_frac (float)

  • n_steps_frac (int)

Returns:

DataFrame with one row per label. Columns include voxel-based properties (label, bbox, centroid, inertia eigenvalues) and, when voxel_only is False, SDF-based properties (volume, surface area, sphericity) and mesh-based curvature statistics.

Return type:

pd.DataFrame

Raises:

ValueError – If spacing is not isotropic.

See also

props_voxel

Voxel-based property extraction.

props_sdf

SDF-based volume and surface area computation.

props_mesh

Mesh-based curvature computation.

sphero_vem.measure.pipeline.analyze_labels(config)[source]#

Run label morphology analysis pipeline from configuration.

Loads labels from zarr, computes shape descriptors via label_properties, and saves results to parquet along with the configuration.

Parameters:

config (LabelAnalysisConfig) – Configuration object specifying paths and analysis parameters.

Raises:

ValueError – If spacing is not isotropic.

Return type:

None

Notes

Outputs are saved to {config.save_root}/: - regionprops.parquet: DataFrame with all computed properties - analysis-config.json: Serialized configuration for reproducibility - meshes/mesh-{label}.npz: Per-label mesh data (if not voxel_only)

sphero_vem.measure.pipeline.save_regionprops(props, dst_path, sep='__')[source]#

Save region properties to parquet with tuple columns flattened.

Tuple and list columns are unpacked into indexed scalar columns (e.g., centroidcentroid__0, centroid__1, …) for parquet compatibility. The index is not saved; all information should be encoded in the columns.

Parameters:
  • props (pd.DataFrame) – DataFrame of region properties, potentially containing tuple or list valued columns.

  • dst_path (Path) – Destination path for the parquet file.

  • sep (str, optional) – Separator for flattened column names. Must match the sep passed to read_regionprops for round-tripping. Default is "__".

Return type:

None

See also

read_regionprops

Inverse operation.

flatten_for_save

Underlying flattening logic.

sphero_vem.measure.pipeline.read_regionprops(src_path, sep='__')[source]#

Read region properties from parquet and reconstruct tuple columns.

Indexed scalar columns (e.g., centroid__0, centroid__1, …) are packed back into tuple columns (centroid).

Parameters:
  • src_path (Path) – Path to the parquet file saved by save_regionprops.

  • sep (str, optional) – Separator used when the file was saved. Default is "__".

Returns:

DataFrame with tuple columns reconstructed.

Return type:

pd.DataFrame

See also

save_regionprops

Inverse operation.

reconstruct_tuples

Underlying reconstruction logic.

Voxel#

Voxel-based shape descriptors and cell assignment.

sphero_vem.measure.voxel.props_voxel(labels, spacing, bbox_margin=15, calc_volume=False)[source]#

Calculate voxel-based properties using GPU acceleration.

This function uses skimage.measure.regionprops (or its CuCIM equivalent if CUDA is available) calculate per-label properties from a voxel image.

Parameters:
  • labels (ArrayLike) – Array with the labeled image.

  • spacing (tuple[float, float, float]) – Physical spacing of the voxel grid. This will only be used when calc_volume is True.

  • bbox_margin (int) – Constant margin for bounding box expansion. The returned bounding box will be expanded by this value in all directions.

  • calc_volume (bool) – Flag that controls whether to calculate volume and related quantities directly from the voxel map. This is useful when SDF and mesh-based approaches are not feasible. Default is False.

Returns:

List of dictionaries containing the calculated properties for each label: - label: label ID - bbox: bounding box of the object - bbox_exp: bounding box expanded by bbox_margin - eigvals: eigenvalues of the gyration tensor (sorted ascending) - centroid: coordinates of the image centroid - volume: label volume in µm^3 (if calc_volume=True) - diam_equiv: equivalent diameter in µm^2 (if calc_volume=True)

Return type:

list[dict]

sphero_vem.measure.voxel.assign_cell(props, cells)[source]#

Assign parent cell and return dataframe by looking up centroid

Parameters:
  • props (pd.DataFrame) – The dataframe containing the region properties. It should have a “centroid” column containing the tuple indexing the object centroid.

  • cells (np.ndarray) – An array containing the cells masks labeled by instance.

Returns:

The updated region properties dataframe with a new column “parent_cell”.

Return type:

pd.DataFrame

SDF#

SDF computation, surface area estimation, and mesh extraction.

sphero_vem.measure.sdf.props_sdf(label_idx, labels, spacing, sigma=3, eps_voxels=1.5)[source]#

Calculate label properties directly from the implicit SDF representation.

Parameters:
  • label_idx (int) – Index of the label.

  • labels (ArrayLike) – Array with the labeled image. Consider passing the image cropped to the region of interest of the label for efficiency.

  • spacing (tuple[float, float, float]) – Physical spacing of the voxel grid. The SDF will be returned in these units.

  • sigma (float) – Standard deviation of the Gaussian kernel used for smoothing the SDF in voxels. Default is 3.

  • epsilon_voxels (float) – Bandwith of the smeared Heavyside function used for calculating the surface, in voxels. Default is 1.5.

  • eps_voxels (float)

Return type:

tuple[dict, ndarray[tuple[Any, ...], dtype[Any]]]

Returns:

  • dict – Dictionary of properties for the given label. Keys: volume, surface_area_real, sphericity, surface_area_boundary, truncation_fraction, diam_equiv.

  • ArrayLike – An array containing the signed distance function (SDF < 0 on the inside).

Mesh#

Mesh calculation and curvature computation from SDF at interpolated points.

sphero_vem.measure.mesh.get_mesh(sdf, spacing)[source]#

Calculate mesh from 0-level set of the SDF using the marching cubes algorithm.

Parameters:
  • sdf (np.ndarray) – Signed distance function, negative on the inside.

  • spacing (tuple[float, float, float]) – Physical spacing of the SDF voxel grid, same units as SDF values.

Return type:

tuple[ndarray, ndarray, ndarray]

Returns:

  • verts (np.ndarray) – Vertices of the mesh.

  • faces (np.ndarray) – Faces of the mesh, with boundary cap faces removed.

  • vertex_areas (np.ndarray) – Area associated to each vertex, equal to 1/3 of the adjacent face areas.

sphero_vem.measure.mesh.props_mesh(sdf, spacing, mesh_downsample_factor=2, h=1.5, mesh_save_path=None)[source]#

Compute curvature-based shape descriptors from SDF via mesh sampling.

Extracts a surface mesh from the downsampled SDF using marching cubes, then samples curvature values from the full-resolution SDF at mesh vertex locations. Returns area-weighted aggregate statistics of local curvature descriptors.

Parameters:
  • sdf (ArrayLike) – Smoothed signed distance function (negative inside).

  • spacing (tuple[float]) – Voxel spacing in physical units (z, y, x).

  • mesh_downsample_factor (int, optional) – Factor by which to downsample SDF before mesh extraction. Reduces vertex count and computation time. Default is 2.

  • h (float, optional) – Step size in voxels for finite difference curvature estimation. Default is 1.5.

  • mesh_save_path (Path | None, optional) – If provided, saves mesh geometry and per-vertex curvature values to this path as .npz file.

Returns:

results – Area-weighted curvature statistics: - curv_mean_avg, curv_mean_std : Mean curvature statistics - curv_gauss_avg, curv_gauss_std : Gaussian curvature statistics - curvedness_avg, curvedness_std : Curvedness statistics - shape_index_avg, shape_index_std : Shape index statistics

Return type:

dict

Notes

Curvature sign convention: positive mean curvature indicates convex regions (outward curving), negative indicates concave regions.

Shape index follows Koenderink (1992) convention with kappa_1 <= kappa_2: - S = -1: spherical cup (concave) - S = 0: saddle - S = +1: spherical cap (convex)

References

Fractal#

Fractal dimension estimation via Minkowski-Bouligand tube scaling.

sphero_vem.measure.fractal.props_fractal(label_idx, labels, spacing, sigma_frac=0.7, n_steps=30)[source]#

Compute fractal dimension via Minkowski-Bouligand tube volume scaling.

Computes a lightly smoothed signed distance field from the label mask, then measures how the volume of an espilon-tube around the zero level set scales with epsilon. For a smooth surface, D ≈ 2.0.

Parameters:
  • label_idx (int) – Index of the label to analyze.

  • labels (ArrayLike) – 3D integer label array (typically a cropped region containing label_idx).

  • spacing (tuple[float]) – Isotropic voxel spacing in physical units.

  • sigma_frac (float, optional) – Light Gaussian smoothing sigma in voxels for the SDF. Should be small (0.5-1.0) to remove EDT quantization artifacts while preserving meso-scale roughness. Default is 0.7.

  • n_steps (int, optional) – Number of epsilon values sampled in log-space. Default is 30.

Returns:

fractal_dimfloat

Estimated fractal dimension (D = 3 - slope).

fractal_r2float

R^2 of the log-log linear fit.

fractal_eps_minfloat

Lower epsilon bound used for fitting.

fractal_eps_maxfloat

Upper epsilon bound (after auto-trimming).

fractal_n_pointsint

Number of points used in the fit.

Return type:

dict

Notes

Uses a light smoothing (sigma = 0.5-1.0 voxels) rather than the raw SDF to suppress EDT quantization artifacts near small ε, but avoid the heavy smoothing (sigma > 1.5) used for curvature.

The lower epsilon bound is calcualtes as the maximum between 1.5 * voxel_size and 3 * sigma_frac * voxel_size.

The upper epsilon bound is auto-trimmed to exclude the finite-size saturation regime where tube volume growth slows. A minimum of 5 epsilon values are used for the log-log regression.

Raises:

ValueError – If the spacing is not isotropic

Parameters:
Return type:

dict

Distance#

Nucleus distance map computation.

sphero_vem.measure.distance.nuclei_distance(root_path, verbose=True)[source]#

Compute and save the nucleus distance map for all cells in a dataset.

For each cell containing at least one nucleus, computes the Euclidean distance from every voxel to the nearest nuclear surface. The result is saved as a zarr array under labels/nuclei/distance/.

Requires that label analysis (via analyze_labels) has been run for both cells and nuclei segmentation targets at the same spacing, and that nuclei properties contain a parent_cell column.

Parameters:
  • root_path (Path) – Root path to the zarr store.

  • verbose (bool, optional) – If True, show a progress bar. Default is True.

Raises:

ValueError – If cells and nuclei were analyzed at different spacings.

Return type:

None

Notes

Output is written to labels/nuclei/distance/{scale_dir} in the zarr store, with units in micrometers. Voxels outside cells or in cells without a detected nucleus are set to NaN.