phenotypic.grid#

Grid discovery for plated fungal colonies.

Provides tools to define the row/column layout of arrayed plates (e.g., 96- or 384-spot) so downstream detection and measurements align colonies to expected wells. Supports automatic grid inference and manual specification for challenging imaging conditions.

Classes

GridApply

Accepts a PhenoTypic operation as a parameter and applies it to the individual grid sectionss of an image.

AutoGridFinder

Automatically determines grid row and column edges from detected object

ManualGridFinder

A GridFinder implementation where users directly specify grid row and column coordinates.

class phenotypic.grid.AutoGridFinder(nrows: int = 8, ncols: int = 12, residual_fraction: float = 0.25, *, tol: float | None = None, max_iter: int | None = None)[source]

Bases: GridFinder

Automatically determines grid row and column edges from detected object centers using a deterministic robust-fit algorithm.

Unlike histogram or optimizer-based approaches, this class fits a regular grid model directly to the per-object distance-transform maximum centers (deepest interior point of each object’s mask). These centers are anchored in the dense colony body and are unaffected by thin filamentous extensions (e.g., fungal hyphae) that would otherwise pull intensity-weighted centroids off-body and bias the grid fit. Outlier rejection further protects against atypical objects pulling boundaries away from the true positions.

Args:

nrows: Number of rows in the grid (default 8 for 96-well plates). ncols: Number of columns in the grid (default 12 for 96-well plates). residual_fraction: Outlier threshold as a fraction of pitch. Centers

whose fit residual exceeds pitch * residual_fraction are excluded from the refined fit (default 0.25).

tol: Deprecated. Accepted for backward compatibility but ignored. max_iter: Deprecated. Accepted for backward compatibility but ignored.

Category: GRID#

Name

Description

RowNum

The row idx of the object

RowIntervalStart

The start of the row interval of the object

RowIntervalEnd

The end of the row interval of the object

ColNum

The column idx of the object

ColIntervalStart

The start of the column interval of the object

ColIntervalEnd

The end of the column interval of the object

RowMajorIdx

The row-major index of the object. Row major is the standard in most programming and data science array libraries. Used for indexing into 2D arrays.

ColMajorIdx

The col-major index of the object in an array. Lab automation logic uses column-major (column-wise) indexing for well plate operations because 96-well plates are physically arranged with 8 rows (labeled A-H) and 12 columns (numbered 1-12), and this layout maps directly to how multichannel pipettes operate.

Parameters:
__del__()

Automatically stop tracemalloc when the object is deleted.

get_col_edges(image: Image) np.ndarray[source]

Return column edge coordinates for image.

Parameters:

image (Image) – Image with detected objects (image.objects.info()).

Returns:

Integer array of length ncols + 1.

Return type:

np.ndarray

get_row_edges(image: Image) np.ndarray[source]

Return row edge coordinates for image.

Parameters:

image (Image) – Image with detected objects (image.objects.info()).

Returns:

Integer array of length nrows + 1.

Return type:

np.ndarray

inspect(image: Image, show_progress: bool = True)[source]

Interactive diagnostic dashboard for grid fitting.

Profiles the grid-fitting pipeline and displays timing breakdown, object size distribution, centroid scatter with grid overlay, and summary statistics. Useful for identifying bottlenecks when grid.info() is slow (e.g., with filamentous fungi images).

Uses an ipywidgets progress bar in Jupyter, tqdm otherwise.

Parameters:
  • image (Image) – Image with detected objects (must have objmap).

  • show_progress (bool) – Whether to display a progress bar during profiling. Defaults to True.

Returns:

Panel Column layout with 4 diagnostic panels.

Examples

>>> from phenotypic.data import load_synth_yeast_plate
>>> from phenotypic.detect import OtsuDetector
>>> from phenotypic.grid import AutoGridFinder
>>> image = load_synth_yeast_plate()
>>> image = OtsuDetector().apply(image)
>>> finder = AutoGridFinder(nrows=8, ncols=12)
>>> dashboard = finder.inspect(image)
measure(image)

Compute grid edges and assign each detected object to a grid cell.

Parameters:

image – Image with detected objects.

Returns:

DataFrame with grid assignments (ROW_NUM, COL_NUM, ROW_MAJOR_IDX).

class phenotypic.grid.GridApply(image_op: ImageOperation | ImagePipeline, reset_enh_matrix: bool = True)[source]

Bases: object

Accepts a PhenoTypic operation as a parameter and applies it to the individual grid sectionss of an image.

Parameters:
  • image_op (ImageOperation) – A PhenoTypic operation to be applied to each grid section.

  • reset_enh_matrix (bool) – Whether to reset the detect_mat attribute of the image before applying the operation.

apply(image: GridImage)[source]
Parameters:

image (GridImage)

class phenotypic.grid.ManualGridFinder(row_edges: numpy.ndarray, col_edges: numpy.ndarray)[source]

Bases: GridFinder

A GridFinder implementation where users directly specify grid row and column coordinates.

This class allows for complete manual control over grid placement by accepting explicit row and column edge coordinates. No optimization or automatic calculation is performed - the grid is defined exactly as specified by the user.

Parameters:
  • row_edges (np.ndarray)

  • col_edges (np.ndarray)

nrows

Number of rows in the grid (derived from row_edges).

Type:

int

ncols

Number of columns in the grid (derived from col_edges).

Type:

int

row_edges

Array of row edge coordinates defining grid rows.

Type:

np.ndarray

col_edges

Array of column edge coordinates defining grid columns.

Type:

np.ndarray

Example

Create a 3x4 grid with specific coordinates:

>>> import numpy as np
>>> from phenotypic.grid import ManualGridFinder
>>> # Create a 3x4 grid with specific coordinates
>>> row_edges = np.array([0, 100, 200, 300])  # 3 rows
>>> col_edges = np.array([0, 80, 160, 240, 320])  # 4 columns
>>> finder = ManualGridFinder(row_edges=row_edges, col_edges=col_edges)
>>> grid_info = finder.measure(image)  
__del__()

Automatically stop tracemalloc when the object is deleted.

__init__(row_edges: numpy.ndarray, col_edges: numpy.ndarray)[source]

Initialize a ManualGridFinder with explicit row and column edge coordinates.

Parameters:
  • row_edges (np.ndarray) – Array of row edge coordinates. Length should be nrows + 1. Example: [0, 100, 200, 300] defines 3 rows.

  • col_edges (np.ndarray) – Array of column edge coordinates. Length should be ncols + 1. Example: [0, 80, 160, 240, 320] defines 4 columns.

Raises:

ValueError – If row_edges or col_edges have fewer than 2 elements.

get_col_edges(image: Image) np.ndarray[source]

Returns the manually specified column edges.

Parameters:

image (Image) – The image (not used, but required by interface).

Returns:

Array of column edge coordinates.

Return type:

np.ndarray

get_row_edges(image: Image) np.ndarray[source]

Returns the manually specified row edges.

Parameters:

image (Image) – The image (not used, but required by interface).

Returns:

Array of row edge coordinates.

Return type:

np.ndarray

measure(image)

Compute grid edges and assign each detected object to a grid cell.

Parameters:

image – Image with detected objects.

Returns:

DataFrame with grid assignments (ROW_NUM, COL_NUM, ROW_MAJOR_IDX).