Skip to content

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 (H, W) integer array per tile, zero for background, of any size.

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, (n_tiles, 2), by tile index. None records no position.

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 ALHENA_DISABLE_PROGRESS_BARS.

None

Returns:

Type Description
DataFrame

A table with MEMBERSHIP_COLUMNS. Its attributes hold the cells that reached no token and

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 MAX_MICROSCOPE_MPP.

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 (n, 2) array of x and y in the pixels of the tile of each centroid, before any resampling.

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, (n_tiles, 2), by tile index. None records no position.

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 ALHENA_DISABLE_PROGRESS_BARS.

None

Returns:

Type Description
DataFrame

A table with MEMBERSHIP_COLUMNS, flagged approximate and recording the resolution, and

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 MAX_MICROSCOPE_MPP.

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 (m, 2) array of x and y vertices per nucleus, in the shared frame.

required
tile_bounds ndarray

An (n_tiles, 4) array of x0, y0, x1, y1 windows in the shared frame, upper bound excluded, by tile index.

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 ALHENA_DISABLE_PROGRESS_BARS.

None

Returns:

Type Description
DataFrame

A table with MEMBERSHIP_COLUMNS, recording the resolution, the tile centers and the

DataFrame

nucleus centroids, and the microns per pixel of the frame where mpp is given.

Raises:

Type Description
AlhenaValueError

If a resolution is not positive or exceeds MAX_MICROSCOPE_MPP.

MembershipError

If a polygon has fewer than three vertices, or a tile window is empty.

alhena.cells.validate_membership

validate_membership(frame, n_tiles)

Check that a membership table can be pooled against a set of tiles.

Parameters:

Name Type Description Default
frame DataFrame

A table with MEMBERSHIP_COLUMNS.

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_cells(tokens, membership, tile_centers=None, cell_centers=None, project=None)

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 (n_tiles, 256, dim) array or tensor of post-LayerNorm patch tokens.

required
membership DataFrame

A table with MEMBERSHIP_COLUMNS.

required
tile_centers ndarray | None

An (n_tiles, 2) array of tile centers in a shared frame. Defaults to what the table recorded.

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_tokens(tokens, membership)

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 (n_tiles, 256, dim) array or tensor of post-LayerNorm patch tokens, without the class and register tokens.

required
membership DataFrame

A table with MEMBERSHIP_COLUMNS.

required

Returns:

Type Description
ndarray

The pooled vectors, (n_groups, dim) float32, and a table with GROUP_COLUMNS ordered by

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

resolve_main_tile(groups, tile_centers=None, cell_centers=None)

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 GROUP_COLUMNS, one row per (tile, cell) group.

required
tile_centers ndarray | None

An (n_tiles, 2) array of tile centers in the shared frame.

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 groups for each cell, and how many tiles held it, by cell identifier.

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 (size, size) int32 array holding (y // patch_size) * grid + (x // patch_size).

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 (H, W) integer array, zero for background and one identifier per nucleus.

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 (size, size) array of the dtype of the input.

Raises:

Type Description
AlhenaValueError

If a resolution is not positive or exceeds MAX_MICROSCOPE_MPP.

GeometryError

If the mask is not a non-empty 2-D array of non-negative integers.

alhena.cells.missing_cells

missing_cells(frame)

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

membership_source(frame)

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

"labels", "centroids" or "polygons", or "unknown" for a table built by hand.

alhena.cells.membership_is_approximate

membership_is_approximate(frame)

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

GROUP_COLUMNS = ('tile_index', 'cell_id', 'alpha')

Columns of the table of (tile, cell) groups pool_tokens returns, in order.

alhena.cells.ORIGINS_FRAME module-attribute

ORIGINS_FRAME = 'tile origins'

Frame name recorded for positions placed by tile origins given by hand or from a table.

alhena.cells.POLYGONS_FRAME module-attribute

POLYGONS_FRAME = 'polygons'

Name of the frame of positions read from boundaries whose windows are not a tile source's.


Next: Retrieval