Cells and pooling¶
Functions for mapping nuclei onto image tokens and pooling those tokens into one pre-projection cell embedding per nucleus.
The membership builders support label maps, centroids, and polygons.
AlhenaEncoder.encode_cells() performs these steps automatically, while the functions below
expose the lower-level operations for custom workflows and validation.
Membership tables created by ALHENA record their image geometry. Cell-level workflows verify this metadata against the current tile geometry before pooling. See Advanced: membership geometry checks.
When tile origins are available, ALHENA can identify a nucleus represented in several overlapping tiles and select one primary tile. See A nucleus in several tiles.
alhena.cells.membership_from_labels
¶
membership_from_labels(label_maps, tile_indices, *, mpp=None, target_mpp=REFERENCE_MPP, tile_origins=None, tile_scale=1.0, progress=None)
Build a membership table from integer label maps, one per tile.
Label values are cell identifiers, unique across the tiles. Given the tile origins, the table
also records the tile centers and one position per nucleus, from the map holding most of its
pixels before the crop, the lowest tile index among equals. The table records mpp and the size
of every map, so a call refuses it beside tiles that reach the canvas otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label_maps
|
ndarray | Sequence[ndarray]
|
One |
required |
tile_indices
|
Sequence[int] | ndarray
|
Index of the tile each label map belongs to. |
required |
mpp
|
float | None
|
Microns per pixel of the tiles, as declared for the images. Without it, each map is stretched onto the whole canvas. |
None
|
target_mpp
|
float
|
Microns per pixel the model reads at. |
REFERENCE_MPP
|
tile_origins
|
ndarray | None
|
The x, y origin of every tile in a shared frame, |
None
|
tile_scale
|
float
|
Pixels of that frame one tile pixel spans. |
1.0
|
progress
|
bool | None
|
Whether to report progress on standard error. None follows
|
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A table with |
DataFrame
|
the resolution, and where origins were given the tile centers, the nucleus positions and the |
DataFrame
|
microns per pixel of their frame. |
Raises:
| Type | Description |
|---|---|
AlhenaValueError
|
If a resolution is not positive or exceeds |
GeometryError
|
If a label map is not a 2-D array of non-negative integers. |
MembershipError
|
If the tile indices or the origins do not match the maps. |
alhena.cells.membership_from_centroids
¶
membership_from_centroids(centroids, tile_indices, radius_px, *, cell_ids=None, tile_shape=(INPUT_SIZE, INPUT_SIZE), mpp=None, target_mpp=REFERENCE_MPP, tile_origins=None, tile_scale=1.0, progress=None)
Build a membership table by rasterizing a disk around each nucleus centroid.
The pooling weights follow a circle of the radius given rather than the segmented shape, so the table is flagged approximate and a warning is raised; where disks overlap, the later centroid owns the pixel. Centroids are read in the pixels of their own tile. Given the tile origins, the table records the tile centers and one position per cell, the mean of its rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
centroids
|
ndarray
|
An |
required |
tile_indices
|
Sequence[int] | ndarray
|
Index of the tile each centroid belongs to. |
required |
radius_px
|
float | Sequence[float] | ndarray
|
Nucleus radius in tile pixels, one value or one per centroid. |
required |
cell_ids
|
Sequence[Any] | ndarray | None
|
Identifier of each centroid, repeated where a cell is given on several tiles. Defaults to positions. |
None
|
tile_shape
|
tuple[int, int]
|
Height and width of the tiles the centroids were measured on. |
(INPUT_SIZE, INPUT_SIZE)
|
mpp
|
float | None
|
Microns per pixel of the tiles, as declared for the images. Without it, the disks are stretched onto the whole canvas. |
None
|
target_mpp
|
float
|
Microns per pixel the model reads at. |
REFERENCE_MPP
|
tile_origins
|
ndarray | None
|
The x, y origin of every tile in a shared frame, |
None
|
tile_scale
|
float
|
Pixels of that frame one tile pixel spans. |
1.0
|
progress
|
bool | None
|
Whether to report progress on standard error. None follows
|
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A table with |
DataFrame
|
where origins were given the tile centers, the cell positions and the microns per pixel of |
DataFrame
|
their frame. |
Raises:
| Type | Description |
|---|---|
AlhenaValueError
|
If a resolution is not positive or exceeds |
MembershipError
|
If the inputs disagree, a cell repeats on a tile, or a radius is invalid. |
alhena.cells.membership_from_polygons
¶
membership_from_polygons(polygons, tile_bounds, *, cell_ids=None, mpp=None, target_mpp=REFERENCE_MPP, tile_scale=1.0, progress=None)
Build a membership table by rasterizing nucleus polygons into each tile.
Polygons and tile windows share one frame, so a nucleus in several tiles is found in each; where
polygons overlap, the later one owns the pixel. A nucleus is placed at the area centroid of its
boundary. The table records mpp and the grid of every window, so a call refuses it beside
tiles that reach the canvas otherwise.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
polygons
|
Sequence[ndarray]
|
One |
required |
tile_bounds
|
ndarray
|
An |
required |
cell_ids
|
Sequence[Any] | ndarray | None
|
Identifier of each polygon. Defaults to positions. |
None
|
mpp
|
float | None
|
Microns per pixel of the tiles, as declared for the images. Without it, each window is stretched onto the whole canvas. |
None
|
target_mpp
|
float
|
Microns per pixel the model reads at. |
REFERENCE_MPP
|
tile_scale
|
float
|
Pixels of the shared frame one tile pixel spans. |
1.0
|
progress
|
bool | None
|
Whether to report progress on standard error. None follows
|
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A table with |
DataFrame
|
nucleus centroids, and the microns per pixel of the frame where |
Raises:
| Type | Description |
|---|---|
AlhenaValueError
|
If a resolution is not positive or exceeds |
MembershipError
|
If a polygon has fewer than three vertices, or a tile window is empty. |
alhena.cells.validate_membership
¶
Check that a membership table can be pooled against a set of tiles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
DataFrame
|
A table with |
required |
n_tiles
|
int
|
Number of tiles the table indexes into. |
required |
Raises:
| Type | Description |
|---|---|
MembershipError
|
If a column, dtype, range or key is wrong, or the recorded cells disagree. |
alhena.cells.pool_cells
¶
Pool tile tokens into one embedding per cell, resolving cells found in several tiles.
The result holds one row per cell that reached a token, by identifier, with the provenance the
membership table records. The encoder, the cell space and the geometry are not visible from
tokens and are left None; AlhenaEncoder.encode_cells records them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tokens
|
ndarray | Tensor
|
An |
required |
membership
|
DataFrame
|
A table with |
required |
tile_centers
|
ndarray | None
|
An |
None
|
cell_centers
|
Mapping[Any, Sequence[float]] | None
|
Nucleus centroids in that frame, by identifier. Defaults to what the table recorded, with the name and scale of its frame; centroids given here carry neither. |
None
|
project
|
Callable[[ndarray], ndarray] | None
|
The image-side cell head, applied to the pooled pre-projection cell embeddings. |
None
|
Returns:
| Type | Description |
|---|---|
CellEmbeddings
|
One embedding per cell, with the nucleus pixels supporting it, the tile it was read from, |
CellEmbeddings
|
how many tiles held it, and whether it may be used. |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If the tokens do not carry the token grid of the canvas. |
MembershipError
|
If the table is malformed, or a cell in several tiles has no center. |
alhena.cells.pool_tokens
¶
Pool tile tokens into one vector per (tile, cell) group.
A token weighs its nucleus pixel count over alpha + 1e-6, alpha being the nucleus pixels of
the cell in that tile, so the weights sum to alpha / (alpha + 1e-6). The weights of a tile
form one matrix, so the result does not depend on the order of the rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tokens
|
ndarray | Tensor
|
An |
required |
membership
|
DataFrame
|
A table with |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
The pooled vectors, |
DataFrame
|
cell identifier then tile index. |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If the tokens do not carry the token grid of the canvas. |
MembershipError
|
If the membership table is malformed. |
alhena.cells.resolve_main_tile
¶
Choose the tile each cell is read from when tiles overlap.
A cell is read from the tile holding most of its nucleus, then from the tile whose center its centroid is nearest, then from the lowest tile index, then the lowest row. Without a shared frame, a cell found in several tiles is refused.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
groups
|
DataFrame
|
A table with |
required |
tile_centers
|
ndarray | None
|
An |
None
|
cell_centers
|
Mapping[Any, Sequence[float]] | None
|
Nucleus centroid of each cell in the shared frame, by identifier. |
None
|
Returns:
| Type | Description |
|---|---|
tuple[ndarray, ndarray]
|
The selected row of |
Raises:
| Type | Description |
|---|---|
MembershipError
|
If a cell is found in several tiles and no center places it. |
alhena.cells.token_index_map
¶
token_index_map(size=INPUT_SIZE, patch_size=PATCH_SIZE)
Return the token index of every pixel of the model input canvas, row-major over the grid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
int
|
Side of the canvas, in pixels. |
INPUT_SIZE
|
patch_size
|
int
|
Side of one token, in pixels. |
PATCH_SIZE
|
Returns:
| Type | Description |
|---|---|
ndarray
|
A |
Raises:
| Type | Description |
|---|---|
GeometryError
|
If the canvas is not a whole number of tokens across. |
alhena.cells.fit_mask
¶
fit_mask(mask, mpp=None, target_mpp=REFERENCE_MPP, size=INPUT_SIZE)
Carry an integer label mask onto the model input canvas, as the image of its tile is.
Nearest-neighbor resampling keeps label values, and the padding is background. Declare the same
mpp as for the image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mask
|
ndarray
|
A |
required |
mpp
|
float | None
|
Microns per pixel of the tile the mask belongs to. |
None
|
target_mpp
|
float
|
Microns per pixel to resample to. |
REFERENCE_MPP
|
size
|
int
|
Side of the model input canvas. |
INPUT_SIZE
|
Returns:
| Type | Description |
|---|---|
ndarray
|
A |
Raises:
| Type | Description |
|---|---|
AlhenaValueError
|
If a resolution is not positive or exceeds |
GeometryError
|
If the mask is not a non-empty 2-D array of non-negative integers. |
alhena.cells.missing_cells
¶
Return the cells of the input that reached no token, sorted.
A nucleus outside the center crop, or lost to nearest-neighbor downsampling, has no token to pool.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
DataFrame
|
A table one of the membership builders returned. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
The identifiers of the cells with no token, sorted. |
Raises:
| Type | Description |
|---|---|
MembershipError
|
If the table records no input set, not having been built by a builder. |
alhena.cells.membership_source
¶
Return the kind of nucleus input a membership table was built from.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
DataFrame
|
A membership table. |
required |
Returns:
| Type | Description |
|---|---|
str
|
|
alhena.cells.membership_is_approximate
¶
Report whether the pixel counts of a membership table approximate the nucleus shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame
|
DataFrame
|
A membership table a builder made. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True for disks drawn around centroids, False for label maps and outlines. |
Raises:
| Type | Description |
|---|---|
MembershipError
|
If the table records no provenance, not having been built by a builder. |
alhena.cells.GROUP_COLUMNS
module-attribute
¶
Columns of the table of (tile, cell) groups pool_tokens returns, in order.
alhena.cells.ORIGINS_FRAME
module-attribute
¶
Frame name recorded for positions placed by tile origins given by hand or from a table.
alhena.cells.POLYGONS_FRAME
module-attribute
¶
Name of the frame of positions read from boundaries whose windows are not a tile source's.
Next: Retrieval