taufactor.metrics
- taufactor.metrics.estimate_3d_psd_saltykov(apparent_diameters, bins='auto', bin_edges=None, clip_negative=True, normalize=True)[source]
Estimate a 3D sphere diameter distribution from 2D section diameters.
Uses a Saltykov-style unfolding under the assumption of spherical particles cut by a random plane.
- Parameters:
apparent_diameters – 1D array of apparent 2D section diameters.
bins – Histogram bin spec passed to
numpy.histogram_bin_edgeswhenbin_edgesis not provided.bin_edges – Explicit histogram bin edges.
clip_negative – If
True, clip negative unfolded counts to zero.normalize – If
True, also return normalized bin fractions.
- Returns:
Bin edges, centers, 2D histogram counts, and unfolded 3D counts.
- Return type:
dict
- taufactor.metrics.extract_through_feature(array, grayscale_value, axis, periodic=[False, False, False], connectivity=1, open_end=True, debug=False)[source]
Extract spanning features and their fractions for a phase.
For the given
grayscale_value, labels connected components at one or more neighbor connectivities, detects which labels span the domain alongaxis, and returns boolean masks plus the fraction of the phase volume that is spanning.- Parameters:
array (numpy.ndarray) – 3D segmented image.
grayscale_value (int) – Target label value whose spanning network is evaluated.
axis (str) – One of
'x','y', or'z'along which spanning is checked.periodic (Sequence[bool], optional) – Periodicity flags per axis (e.g.
(True, False, False)). Defaults to[False, False, False].connectivity (int | None, optional) – If
1,2, or3, evaluate that connectivity only. IfNone, evaluates all (1, 2, 3). Defaults to1.debug (bool, optional) – Print simple diagnostics. Defaults to
False.
- Returns:
If the phase is present: a list of boolean masks (one per connectivity) indicating the spanning network, and a 1D array of spanning fractions (per connectivity) relative to the phase volume.
If the phase volume is zero:
(0, 0).
- Return type:
tuple[list[numpy.ndarray], numpy.ndarray] | tuple[int, int]
Notes
Connectivity meanings in 3D: - 1: faces (6-neighborhood), - 2: faces + edges (18-neighborhood), - 3: faces + edges + corners (26-neighborhood).
- taufactor.metrics.find_front_labels(labelled_array, axis)[source]
Find features that are connected to the front of given axis
- Returns:
Labels that appear in the first slice of the given axis.
- Return type:
set
- taufactor.metrics.find_spanning_labels(labelled_array, axis)[source]
Find labels that span the domain along an axis.
A label is considered spanning if it appears on both opposing faces along the specified axis; background label
0is ignored.- Parameters:
labelled_array (numpy.ndarray) – Labeled 3D array.
axis (str) – One of
'x','y', or'z'.
- Returns:
Set of labels that appear on both faces along
axis.- Return type:
set[int]
- Raises:
ValueError – If
axisis not one of'x','y','z'.
- taufactor.metrics.interfacial_areas(img, spacing=(1, 1, 1), method='face_counting', periodic=[False, False, False], normalize=True, device='cuda', smoothing=True, verbose=False)[source]
- taufactor.metrics.label_periodic(field, grayscale_value, neighbour_structure, periodic, debug=False)[source]
Label connected components with periodic boundary conditions.
Wraps the image in periodic directions, labels connected components equal to
grayscale_value, then merges labels that touch across periodic boundaries. Finally, crops back to the original shape.- Parameters:
field (numpy.ndarray) – Input array (2D or 3D).
grayscale_value (int | float) – Target value to label.
neighbour_structure (numpy.ndarray) – Structuring element as from
scipy.ndimage.generate_binary_structure.periodic (Sequence[bool]) – Periodicity flags per axis (e.g.
(True, False, True)).debug (bool, optional) – Print simple diagnostics. Defaults to
False.
- Returns:
Tuple
(labels, num_labels)wherelabelsis the cropped labeled array andnum_labelsis the number of connected components after periodic merging.- Return type:
tuple[numpy.ndarray, int]
- taufactor.metrics.particle_size_distribution(labelled_array, spacing=(1, 1, 1), periodic=(False, False, False), compute_sphericity=False, surface_area_method='gradient', return_field=False, relabel=True, warn=True)[source]
Measure 3D particle volumes, equivalent sphere diameters, and sphericity.
- Parameters:
labelled_array – 3D labeled particle array with background label
0.spacing – Voxel spacing
(dx, dy, dz). Defaults to(1, 1, 1).periodic – Periodicity flags for
(x, y, z). Periodic axes are ignored when removing boundary-touching labels.compute_sphericity – If
True, also compute particle surface areas and sphericity values.surface_area_method – Surface-area method passed to
specific_surface_area(). Defaults to'gradient'.relabel – If
True, relabel surviving particles consecutively.warn – If
True, warn when boundary removal discards more than half of the particles or more than half of the particle mass.
- Returns:
Particle analysis results with cleaned labels, per-particle volumes, equivalent diameters, and optional surface areas and sphericity.
- Return type:
dict
- taufactor.metrics.particle_size_distribution_2d(labelled_array, spacing=(1, 1), return_field=False, relabel=True, warn=True, perimeter_method='crofton')[source]
Measure 2D particle areas, equivalent circle diameters, and circularity.
- Parameters:
labelled_array – 2D labeled particle array with background label
0.spacing – Pixel spacing
(dx, dy). Defaults to(1, 1).return_field – If
True, include the filtered labeled image.relabel – If
True, relabel surviving particles consecutively.warn – If
True, warn when edge removal discards more than half of the particles or more than half of the particle area.perimeter_method – Either
'crofton'or'standard'.
- Returns:
Particle analysis results with per-particle areas, equivalent diameters, perimeters, and circularity.
- Return type:
dict
- taufactor.metrics.relabel_random_order(array)[source]
Relabel an array with shuffled consecutive integer labels.
- Parameters:
array – Input labeled array.
- Returns:
Array with labels remapped to consecutive integers in random order. If label
0is present, it remains0.
- taufactor.metrics.relabel_sequential(array)[source]
Relabel an array with consecutive integer labels.
- taufactor.metrics.remove_boundary_features(labelled_array, verbose=True, periodic=(False, False, False))[source]
Remove labeled features that touch the domain boundary.
- Parameters:
labelled_array – 3D array of connected-component labels, where
0is background and each feature has its own positive integer label.verbose – If
True, print how many labels remain after filtering.periodic – Periodicity flags for
(x, y, z). Periodic axes are ignored when checking boundary contact.
- Returns:
A new array where all boundary-touching labels have been set to
0.- Raises:
ValueError – If the input does not look like a labeled array with background plus at least two feature labels.
- taufactor.metrics.specific_surface_area(img, spacing=(1, 1, 1), phases={}, method='gradient', periodic=[False, False, False], device='cuda', smoothing=True, sigma=0.8, verbose=False)[source]
Compute specific surface area per phase.
Supports three methods: -
'gradient'(default): Smooth binary masks and integrate gradient magnitude. -'face_counting': Count voxel face changes between neighboring cells. -'marching_cubes': Extract surfaces and compute mesh area (CPU-only; assumesdx == dy == dz).- Parameters:
img (torch.Tensor | numpy.ndarray) – Labeled microstructure; integer values represent phases.
spacing (tuple[float, float, float], optional) – Voxel spacing
(dx, dy, dz). Defaults to(1, 1, 1).phases (dict[str, int], optional) – Mapping from phase name to the integer label in
img. If empty, all labels are processed. Defaults to{}.method (str, optional) – One of
'gradient','face_counting', or'marching_cubes'. Defaults to'gradient'.device (str | torch.device, optional) – Device for GPU-accelerated methods. Only used for
'gradient'/'face_counting'. Defaults to'cuda'.smoothing (bool, optional) – Apply light Gaussian smoothing to the binary mask prior to measurement (used in
'gradient'and'marching_cubes'). Defaults toTrue.verbose (bool, optional) – Print simple memory usage diagnostics. Defaults to
False.
- Returns:
Mapping from phase name to specific surface area (surface per unit volume).
- Return type:
dict[str, float]
- Raises:
ImportError – If PyTorch is not available for
'gradient'or'face_counting'methods.ValueError – If
methodis invalid, or if'marching_cubes'is used with anisotropic spacing (requiresdx == dy == dz).
- taufactor.metrics.split_lumped_labels(labelled_array, connectivity=1, background=0, verbose=True, return_report=False)[source]
Split groups of particles with one lumped label into new labels.
- Parameters:
labelled_array – 2D or 3D labeled array.
connectivity – Connectivity passed to
scipy.ndimage.label.background – Background label to ignore. Defaults to
0.verbose – If
True, print a short summary.return_report – If
True, also return a summary of the applied splits.
- Returns:
A relabeled copy of the input array, optionally with a report describing the performed splits.
- Return type:
numpy.ndarray | tuple[numpy.ndarray, dict]
- taufactor.metrics.triple_phase_boundary(img)[source]
Compute triple-phase boundary (TPB) density.
Calculates the fraction of voxel vertices/edges that are shared by at least three distinct phases. The input image must contain exactly three unique labels.
- Parameters:
img (numpy.ndarray | torch.Tensor) – Segmented 2D or 3D image with exactly three phase labels.
- Returns:
Triple-phase boundary density (normalized by the number of candidate vertices/edges).
- Return type:
float
- Raises:
ImportError – If PyTorch is not available.
ValueError – If the image does not contain exactly three phases.
- taufactor.metrics.volume_fraction(img, phases={})[source]
Compute volume fractions for labels in a segmented image.
Calculates the fraction of voxels belonging to each phase. If
phasesis empty, all unique labels inimgare measured. Otherwise, uses the provided mapping of phase names to label values.- Parameters:
img (torch.Tensor | numpy.ndarray) – Segmented image. If not a
torch.Tensor, it will be converted to one.phases (dict[str, int], optional) – Mapping from phase name to the integer label in
img. If empty (default), all labels in the image are measured and names are derived from the label values.
- Returns:
Mapping from phase name to volume fraction in the range
[0, 1].- Return type:
dict[str, float]
- Raises:
ImportError – If PyTorch is not available.
Modules