Skip to content

Reading data

Functions for converting supported image, nucleus, coordinate, and saved-result formats into the objects used by ALHENA.

Image readers return a TileSource, which reads tiles on demand. Nucleus readers convert supported segmentation or centroid representations into the formats used by encode_cells() and annotate(). Saved tile embeddings, cell embeddings and annotations can be reconstructed with read_tile_embeddings(), read_cells() and read_annotations(), and add_annotation() adds an annotation to a table of cells. read_region() reads a rectangle of a slide or an image to draw results over it.

Cell identifiers must refer to unique cells

Reusing the same identifier for different cells can cause ALHENA to interpret them as repeated observations of one cell. read_label_maps() renumbers per-tile identifiers by default.

alhena.io.read_tiles

read_tiles(source, *, mpp=None, tile_ids=None, coords=None, pattern=None, coords_scale=None, image_dataset=H5_IMAGE_DATASET, barcode_dataset=H5_BARCODE_DATASET, coords_dataset=H5_COORDS_DATASET)

Read tiles from an array, a .npy file, a directory of images or an HDF5 file.

An HDF5 file holds the tiles in img, and may hold their names in barcode and their origins in coords. A single image or slide file is refused: read_image and read_slide cut it into tiles.

Parameters:

Name Type Description Default
source ndarray | Sequence[ndarray] | str | Path

A (n_tiles, height, width, 3) uint8 array, a list of such tiles, or the path of a .npy file, a directory of images or an HDF5 file.

required
mpp float | None

Microns per pixel of the tiles, carried by the source for later calls.

None
tile_ids Sequence[str] | None

Name of each tile of an array or a directory. Defaults to positions, or to the file stems of a directory.

None
coords ndarray | None

Top-left pixel of each tile in a shared frame, (n_tiles, 2), x then y, in whole pixels.

None
pattern str | None

Glob selecting the files of a directory.

None
coords_scale float | None

Frame pixels per tile pixel, for tiles stored at another size than they were cut at. Defaults to what an HDF5 file records, else 1.

None
image_dataset str

HDF5 dataset holding the tiles.

H5_IMAGE_DATASET
barcode_dataset str | None

HDF5 dataset holding the tile names, or None to name them by position.

H5_BARCODE_DATASET
coords_dataset str | None

HDF5 dataset holding the tile origins, or None to read none.

H5_COORDS_DATASET

Returns:

Type Description
TileSource

A tile source that reads its tiles on demand.

Raises:

Type Description
AlhenaValueError

If the source holds no readable tile, or an argument does not fit them.

GeometryError

If the tiles are not uint8 RGB.

alhena.io.read_slide

read_slide(path, *, tile_px=None, stride_px=None, level=0, mpp=None, edge='pad', coords=None, columns=None, coords_dataset=H5_COORDS_DATASET, region=None)

Cut a whole slide into tiles read one region at a time: a grid, or the tiles selected.

The slide is any TIFF file tiffslide opens, whatever its pyramid. Without mpp, the resolution of level zero is read from the slide's metadata. The grid is cut in the pixels of the level read, and the origins of its tiles are recorded in level-zero pixels.

Parameters:

Name Type Description Default
path str | Path

Path of the slide.

required
tile_px int | None

Side of each tile, in pixels of the level read. Defaults to the side that fills the canvas at the resolution of that level.

None
stride_px int | None

Step between tile origins, in those pixels. Defaults to tile_px; refused beside coords.

None
level int

Pyramid level the tiles are read from.

0
mpp float | None

Microns per pixel of level zero, taking precedence over the resolution the slide declares.

None
edge str

One of EDGE_RULES: what becomes of the tiles the edge of the level cuts.

'pad'
coords ndarray | DataFrame | str | Path | None

Level-zero origins of the tiles to cut instead of the grid, x then y: an array, a DataFrame of x and y, or the path of a table, a .npy file or an HDF5 file.

None
columns Mapping[str, str] | None

Columns of a table of origins holding x and y, where named otherwise.

None
coords_dataset str

Dataset of an HDF5 file of origins holding them.

H5_COORDS_DATASET
region Sequence[float] | None

x0, y0, x1, y1 in level-zero pixels, upper bounds excluded: only the tiles lying wholly inside it are kept, from the grid or from coords.

None

Returns:

Type Description
SlideTileSource

A tile source carrying the resolution of the level it reads, and where it was read from.

Raises:

Type Description
AlhenaValueError

If the slide cannot be read, an argument is out of range, or no tile fits.

GeometryError

If mpp is not given and the slide declares no usable resolution.

MissingExtraError

If tiffslide is not installed.

alhena.io.read_region

read_region(image, *, window=None, downsample=1.0)

Read one rectangle of a slide or an image for display, as coarse as a downsample allows.

A slide is read from its coarsest level within the downsample, and an image is decimated by the largest whole step within it. The extent places the result in level-zero pixels, pixel centers at integer coordinates, as tile bounds and cell centroids are written, so both land on their tissue when drawn over it. A window reaching past the edge is cut there.

Parameters:

Name Type Description Default
image str | Path | ndarray

Path of a slide, any TIFF file tiffslide opens; or an image as read_image takes it, a (height, width, 3) uint8 array or the path of a .npy file or another image file.

required
window Sequence[float] | ndarray | None

x0, y0, x1, y1 in level-zero pixels, upper bounds excluded, or an (n, 4) array of such windows, such as TileEmbeddings.bounds, whose union is read. All of it when None.

None
downsample float

Level-zero pixels one pixel of the result may span at most.

1.0

Returns:

Type Description
ndarray

The (height, width, 3) uint8 image, and its left, right, bottom and top edges in

tuple[float, float, float, float]

level-zero pixels, the extent matplotlib.pyplot.imshow takes.

Raises:

Type Description
AlhenaValueError

If the image cannot be read, or the window or downsample is invalid.

GeometryError

If an array is not a (height, width, 3) uint8 image.

MissingExtraError

If tiffslide is not installed when a slide is read.

alhena.io.read_image

read_image(image, *, mpp=None, tile_px=None, stride_px=None, edge='shift', coords=None, columns=None, coords_dataset=H5_COORDS_DATASET, region=None)

Cut one large image into tiles read one window at a time: a grid, or the tiles selected.

The image is cut as read_slide cuts level zero of a slide: a TIFF file gives the same tiles with both under the same edge, which defaults to "shift" here and "pad" there. No resolution is read from the file: mpp declares it, and without it tile_px is required.

Parameters:

Name Type Description Default
image ndarray | str | Path

A (height, width, 3) uint8 RGB array, an array read by slicing such as a memmap, or the path of a .npy file or an image file, one of IMAGE_SUFFIXES.

required
mpp float | None

Microns per pixel of the image.

None
tile_px int | None

Side of each tile, in pixels of the image. Defaults to the side that fills the canvas at mpp.

None
stride_px int | None

Step between tile origins. Defaults to tile_px; refused beside coords.

None
edge str

One of EDGE_RULES: what becomes of the tiles the edge of the image cuts.

'shift'
coords ndarray | DataFrame | str | Path | None

Origins of the tiles to cut instead of the grid, in pixels of the image, as read_slide takes them.

None
columns Mapping[str, str] | None

Columns of a table of origins holding x and y, where named otherwise.

None
coords_dataset str

Dataset of an HDF5 file of origins holding them.

H5_COORDS_DATASET
region Sequence[float] | None

x0, y0, x1, y1 in pixels of the image, upper bounds excluded: only the tiles lying wholly inside it are kept, from the grid or from coords.

None

Returns:

Type Description
ImageTileSource

A tile source carrying the resolution declared, the origins of its tiles and the shape of

ImageTileSource

the image.

Raises:

Type Description
AlhenaValueError

If the image cannot be read, or an argument does not fit the image.

GeometryError

If the image is not a (height, width, 3) uint8 array.

alhena.io.read_tile_origins

read_tile_origins(source, *, tiles, columns=None)

Read the origin of every tile from a table naming the tiles.

Rows are matched to tiles by name, compared as text. The origins are what read_tiles takes as coords.

Parameters:

Name Type Description Default
source str | Path | DataFrame

A DataFrame, or the path of a .csv, .tsv, .txt, .parquet or .pq file.

required
tiles TileSource | ndarray | Sequence[ndarray]

The tiles the origins belong to: a tile source, or tiles in memory, named by position.

required
columns Mapping[str, str] | None

Columns holding tile_id, x and y, where named otherwise.

None

Returns:

Type Description
ndarray

An (n_tiles, 2) int64 array, x then y, in the order of tiles.tile_ids.

Raises:

Type Description
AlhenaValueError

If the table cannot be read, or does not give each tile one origin.

GeometryError

If tiles given in memory are not uint8 RGB.

alhena.io.read_nuclei

read_nuclei(source, *, kind=None, tiles=None, progress=None, **options)

Read nuclei into the mapping CellTyper.annotate reads, with the reader the source selects.

The reader follows from what the source is, never from its values, unless kind names it. A table of boundary vertices is read with kind="polygons".

Parameters:

Name Type Description Default
source Any

Label maps, a DataFrame, or the path of a directory, an HDF5 file, a label image, a table, a GeoJSON file or a GeoParquet file.

required
kind str | None

One of NUCLEI_KINDS, naming the reader.

None
tiles TileSource | ndarray | Sequence[ndarray] | None

The tiles these nuclei were segmented on, a tile source or tiles in memory.

None
progress bool | None

Whether to report progress on standard error. None follows ALHENA_DISABLE_PROGRESS_BARS.

None
**options Any

Passed on to the reader selected.

{}

Returns:

Type Description
dict[str, Any]

A mapping holding the nuclei under label_maps, centroids or polygons, with the

dict[str, Any]

arguments their builder needs.

Raises:

Type Description
AlhenaValueError

If the kind or an option is unknown, or the source cannot be read.

GeometryError

If tiles given in memory are not uint8 RGB.

MissingExtraError

If a GeoParquet file is given and geopandas is not installed.

alhena.io.read_label_maps

read_label_maps(source, *, tiles=None, dataset=H5_LABEL_DATASET, renumber=True, stride=CELL_ID_STRIDE)

Read one integer label map per tile.

Values numbered within each tile are renumbered by global_cell_ids; renumber=False keeps identifiers already unique across the tiles. One label image over the whole image is read by read_label_image instead.

Parameters:

Name Type Description Default
source ndarray | Sequence[ndarray] | str | Path

An (n_tiles, height, width) integer array, a list of (height, width) maps, or the path of a directory of label files, an HDF5 file or a memory-mapped .npy stack.

required
tiles TileSource | ndarray | Sequence[ndarray] | None

The tiles the maps belong to. Required for maps stored one per file or HDF5 dataset, matched to them by name; a stack holds one map per tile, in their order.

None
dataset str

Dataset of an HDF5 file stacking every map. Where the file holds no such dataset, its two-dimensional datasets are read one per tile, in sorted order.

H5_LABEL_DATASET
renumber bool

Make the label values unique across the tiles.

True
stride int

Number of identifiers in the block each tile owns, when renumbering.

CELL_ID_STRIDE

Returns:

Type Description
dict[str, Any]

A mapping holding label_maps and tile_indices. Where the tiles carry their positions,

dict[str, Any]

it also holds their windows and frame, tile_bounds and tile_frame.

Raises:

Type Description
AlhenaValueError

If a map is unreadable or not integer, or the maps do not fit the tiles.

GeometryError

If tiles given in memory are not uint8 RGB.

alhena.io.read_label_image

read_label_image(source, *, tiles=None, progress=None)

Cut the label image of one large image into a label map for each tile cut from it.

The identifiers are kept as they are, so a nucleus two overlapping tiles hold is one cell. Pixels a padded tile holds past the edge of the image are background, and a tile over no nucleus gets no map. Each map is read from the label image when it is used, so a label image larger than memory stays where it is held: keep an HDF5 file holding it open until then.

Parameters:

Name Type Description Default
source ndarray | str | Path

A (height, width) integer array, an array read by slicing (memmap, zarr, HDF5), or the path of a memory-mapped .npy or a .png, .tif or .tiff file.

required
tiles TileSource | None

The tiles read_slide or read_image cut, at level zero, from the image the label image covers.

None
progress bool | None

Whether to report progress on standard error. None follows ALHENA_DISABLE_PROGRESS_BARS.

None

Returns:

Type Description
dict[str, Any]

A mapping holding label_maps, a sequence of (height, width) maps read when indexed,

dict[str, Any]

tile_indices, and the windows and frame of the tiles, tile_bounds and tile_frame.

Raises:

Type Description
AlhenaValueError

If the label image does not fit the tiles, or no tile holds a nucleus.

alhena.io.label_map_from_masks

label_map_from_masks(masks, cell_ids, shape=None, progress=None)

Paint one mask per nucleus into one label map, resolving the pixels masks share.

A shared pixel goes to the smaller nucleus, and between equal areas to the lower identifier. The map keeps the identifiers given, so read it with renumber=False.

Parameters:

Name Type Description Default
masks ndarray | Sequence[ndarray]

One mask per nucleus, true or nonzero where it covers the pixel: an (n_nuclei, height, width) array or a list of (height, width) arrays.

required
cell_ids Sequence[int] | ndarray

Positive identifier of each nucleus, unique across the tiles.

required
shape tuple[int, int] | None

Height and width of the map. Defaults to that of the masks; required without any.

None
progress bool | None

Whether to report progress on standard error. None follows ALHENA_DISABLE_PROGRESS_BARS.

None

Returns:

Type Description
tuple[ndarray, ndarray]

The int64 label map, zero for background, and the sorted identifiers left with no pixel.

Raises:

Type Description
AlhenaValueError

If an identifier is not positive or unique, or a mask's shape differs.

alhena.io.read_centroids

read_centroids(source, *, tiles=None, tile_indices=None, radius_px=None, columns=None, stride=CELL_ID_STRIDE, frame='tile', units='px', transform=None, progress=None)

Read nucleus centroids from a table.

By default each row names its tile and gives its position in that tile's pixels. With frame="origins", each row is one nucleus in the frame of the tile origins, given to every tile holding it, and a centroid no tile holds is left out with a warning. A centroid has no extent: a disk of the radius given stands in for the nucleus.

Parameters:

Name Type Description Default
source str | Path | DataFrame

A DataFrame, or the path of a .csv, .tsv, .txt, .parquet or .pq file.

required
tiles TileSource | ndarray | Sequence[ndarray] | None

The tiles the centroids were measured on: a tile source, or tiles in memory as as_tile_source takes them. Required with frame="origins" and with units="um".

None
tile_indices Sequence[int] | ndarray | None

Tile of each centroid, where the table has no such column; refused with frame="origins".

None
radius_px float | None

Nucleus radius in tile pixels, where the table has no such column.

None
columns Mapping[str, str] | None

Columns holding x, y, tile_index, cell_id and radius_px, where named otherwise.

None
stride int

Number of identifiers in the block each tile owns, where a table read with frame="tile" names no cells.

CELL_ID_STRIDE
frame str

One of CENTROID_FRAMES.

'tile'
units str

One of COORDINATE_UNITS.

'px'
transform ndarray | Sequence[Sequence[float]] | str | Path | None

A 2 by 3 or 3 by 3 affine matrix carrying the coordinates into the frame of the tile origins, or a .csv or .npy file of one; only with frame="origins".

None
progress bool | None

Whether to report progress on standard error. None follows ALHENA_DISABLE_PROGRESS_BARS.

None

Returns:

Type Description
dict[str, Any]

A mapping holding centroids, tile_indices, radius_px, cell_ids, and tile_shape

dict[str, Any]

where the tiles were given. With frame="origins", it holds one entry per centroid and tile

dict[str, Any]

holding it, and the windows and frame of the tiles, tile_bounds and tile_frame.

Raises:

Type Description
AlhenaValueError

If the table is unreadable, names a cell twice, or fits no tile.

GeometryError

If tiles given in memory are not uint8 RGB.

alhena.io.read_polygons

read_polygons(source, *, tiles=None, id_property='cell_id', geometry_property=None, columns=None, units='px', transform=None, multipart='refuse', progress=None)

Read nucleus boundaries from GeoJSON, a table of vertices or GeoParquet.

Boundaries are read in the frame of the tile origins, so a nucleus in several tiles is found in each. A file of BOUNDARY_TABLE_SUFFIXES is a table of vertices, one row per vertex in outline order, or GeoParquet where the file declares itself one; any other file is GeoJSON: a feature collection, a list of features, one feature or one geometry. A boundary of several polygons is read under multipart.

Parameters:

Name Type Description Default
source str | Path | DataFrame

A GeoDataFrame, a DataFrame of vertices, or the path of a GeoJSON file, a table of vertices or a GeoParquet file.

required
tiles TileSource | None

The tiles the boundaries are placed against, whose windows are added to the result. Required with units="um".

None
id_property str

Property of a GeoJSON feature naming the cell; where absent, the feature id, then its position.

'cell_id'
geometry_property str | None

Member of a GeoJSON feature holding the nucleus outline, read instead of its geometry: beside the geometry, else among the properties.

None
columns Mapping[str, str] | None

Columns holding cell_id, x and y of a table of vertices, or cell_id of GeoParquet, where named otherwise.

None
units str

One of COORDINATE_UNITS.

'px'
transform ndarray | Sequence[Sequence[float]] | str | Path | None

A 2 by 3 or 3 by 3 affine matrix carrying the coordinates into the frame of the tile origins, or the path of a .csv or .npy file holding one.

None
multipart str

One of MULTIPART_RULES.

'refuse'
progress bool | None

Whether to report progress on standard error. None follows ALHENA_DISABLE_PROGRESS_BARS.

None

Returns:

Type Description
dict[str, Any]

A mapping holding polygons and cell_ids, and where the tiles were given tile_bounds,

dict[str, Any]

tile_scale and tile_frame, with which other tiles of that frame are refused.

Raises:

Type Description
AlhenaValueError

If the source is unreadable, names a cell twice, or meets no tile.

MissingExtraError

If a GeoParquet file is given and geopandas is not installed.

alhena.io.tile_bounds

tile_bounds(source, tile_shapes=None)

Return the window of every tile, in the frame its coordinates are written in.

A tile w pixels wide ends coords_scale * w pixels after its origin. A source declaring no shared tile size, such as a directory, is read for the sizes of the tiles it has not read yet, and keeps them; tile_shapes gives them instead.

Parameters:

Name Type Description Default
source TileSource

A tile source declaring coordinates.

required
tile_shapes ndarray | None

Height and width of every tile, (n_tiles, 2), for a caller that has read them already.

None

Returns:

Type Description
ndarray

An (n_tiles, 4) float64 array of x0, y0, x1, y1, the upper bound excluded.

Raises:

Type Description
AlhenaValueError

If the source declares no coordinates, or the sizes do not match it.

alhena.io.as_tile_source

as_tile_source(tiles, *, mpp=None)

Return tiles as a tile source.

A tile source is returned as it is, and tiles in memory are wrapped in one. A file is read by read_tiles, read_slide or read_image instead.

Parameters:

Name Type Description Default
tiles TileSource | ndarray | Sequence[ndarray]

A tile source, a (n_tiles, height, width, 3) uint8 array, or a list of (height, width, 3) uint8 tiles, which may differ in size.

required
mpp float | None

Microns per pixel of the tiles. A source's own resolution is checked against it, not replaced.

None

Returns:

Type Description
TileSource

The source itself, or one holding the tiles given.

Raises:

Type Description
AlhenaValueError

If the tiles are missing or of an unknown kind, or mpp contradicts them.

GeometryError

If the tiles are not uint8 RGB.

alhena.io.global_cell_ids

global_cell_ids(tile_index, instance, stride=CELL_ID_STRIDE)

Make per-tile instance numbers unique across the tiles, as tile_index * stride + instance.

The rule depends on the tile index and the instance number alone. A cell lying in two tiles gets two identifiers, so the rule applies only to instances numbered within each tile.

Parameters:

Name Type Description Default
tile_index int | Sequence[int] | ndarray

Index of the tile each instance was numbered in.

required
instance int | Sequence[int] | ndarray

Instance number within that tile, zero or above.

required
stride int

Number of identifiers in the block each tile owns.

CELL_ID_STRIDE

Returns:

Type Description
ndarray

An int64 array of identifiers, broadcast over the two inputs.

Raises:

Type Description
AlhenaValueError

If an argument is out of range, or an instance does not fit its block.

alhena.io.TileSource

TileSource(n_tiles, *, tile_ids=None, coords=None, mpp=None, tile_shape=None, coords_scale=None, coords_frame=None, image_shape=None)

Bases: Sequence

A sequence of uint8 RGB tiles read on demand.

Indexing returns one tile, and batches reads several at a time, so a source larger than memory is embedded one batch at a time.

Attributes:

Name Type Description
tile_ids

Name of each tile, in the order the source returns them.

coords

Top-left pixel of each tile in the frame the tiles were cut from, (n_tiles, 2), x then y, or None.

coords_scale

Pixels of that frame one tile pixel spans.

coords_frame

Name of the frame coords is written in, or None.

mpp

Microns per pixel of the tiles, or None where none was declared.

mpp_source

Where mpp was read from, "mpp argument" where the caller declared it, or None.

tile_shape

Height and width shared by every tile, or None where the source declares none, as for tiles of several sizes or a directory of files.

image_shape

Height and width of the image the tiles were cut from, in the pixels of the frame of coords, or None for tiles cut already.

Record what a subclass knows about its tiles before any of them is read.

Parameters:

Name Type Description Default
n_tiles int

How many tiles the source holds.

required
tile_ids Sequence[str] | None

Name of each tile. Defaults to positions.

None
coords ndarray | None

Origin of each tile, (n_tiles, 2), x then y, or None.

None
mpp float | None

Microns per pixel of the tiles, or None.

None
tile_shape tuple[int, int] | None

Height and width shared by every tile, or None.

None
coords_scale float | None

Pixels of the frame of the origins one tile pixel spans. Defaults to 1; refused without origins.

None
coords_frame str | None

Name of the frame of the origins. Defaults to ORIGINS_FRAME.

None
image_shape tuple[int, int] | None

Height and width of the image the tiles were cut from, or None.

None

Raises:

Type Description
AlhenaValueError

If mpp is out of range, or the names, origins or scale do not fit.

batches

batches(batch_size=DEFAULT_BATCH_SIZE)

Yield tiles in batches, reading each batch only when it is asked for.

Parameters:

Name Type Description Default
batch_size int

Tiles per batch.

DEFAULT_BATCH_SIZE

Yields:

Type Description
list[ndarray]

Lists of (height, width, 3) uint8 RGB tiles, which need not share a size.

Raises:

Type Description
AlhenaValueError

If the batch size is below one.

close

close()

Release any file handle the source holds. Reading from it again reopens the file.

alhena.io.ArrayTileSource

ArrayTileSource(tiles, *, tile_ids=None, coords=None, mpp=None, coords_scale=None)

Bases: TileSource

Tiles already held in memory, as a stacked array or as one array per tile.

read_tiles and as_tile_source build it.

Parameters:

Name Type Description Default
tiles ndarray | Sequence[ndarray]

A (n_tiles, height, width, 3) uint8 array, or a list of such tiles.

required
tile_ids Sequence[str] | None

Name of each tile. Defaults to positions.

None
coords ndarray | None

Top-left pixel of each tile in a shared frame, (n_tiles, 2), x then y.

None
mpp float | None

Microns per pixel of the tiles, carried by the source for later calls.

None
coords_scale float | None

Frame pixels per tile pixel, for tiles stored at another size. Defaults to 1.

None

Raises:

Type Description
AlhenaValueError

If no tile is given, or the tiles, names or origins are unusable.

GeometryError

If the tiles are not uint8 RGB.

alhena.io.DirectoryTileSource

DirectoryTileSource(directory, *, pattern=None, suffixes=IMAGE_SUFFIXES, tile_ids=None, coords=None, mpp=None, coords_scale=None)

Bases: TileSource

Tiles held one image file per tile, read when they are indexed.

read_tiles builds it. Files are taken in sorted order, hidden files never, and each tile is named by the stem of its file.

Parameters:

Name Type Description Default
directory str | Path

Directory holding the image files.

required
pattern str | None

Glob selecting the files.

None
suffixes Sequence[str]

Suffixes a file must carry to be read.

IMAGE_SUFFIXES
tile_ids Sequence[str] | None

Name of each tile. Defaults to the file stems.

None
coords ndarray | None

Top-left pixel of each tile in a shared frame, (n_tiles, 2), x then y.

None
mpp float | None

Microns per pixel of the tiles, carried by the source for later calls.

None
coords_scale float | None

Frame pixels per tile pixel, for tiles stored at another size. Defaults to 1.

None

Raises:

Type Description
AlhenaValueError

If the directory holds no image file, or names or origins do not fit.

paths property

paths

Path of each tile, in the order the source returns them.

alhena.io.HDF5TileSource

HDF5TileSource(path, *, image_dataset=H5_IMAGE_DATASET, barcode_dataset=H5_BARCODE_DATASET, coords_dataset=H5_COORDS_DATASET, mpp=None, coords_scale=None)

Bases: TileSource

Tiles held in one HDF5 file, read when they are indexed.

read_tiles builds it. A dataset an argument names must exist, and None reads the tiles without names or origins. A file may record the side of its tiles under one of H5_SCALE_RECORDS, on its datasets as named; two records, or a record and coords_scale, must agree within half a pixel.

Parameters:

Name Type Description Default
path str | Path

Path of the HDF5 file.

required
image_dataset str

Dataset holding the tiles.

H5_IMAGE_DATASET
barcode_dataset str | None

Dataset holding the tile names, or None to name them by position.

H5_BARCODE_DATASET
coords_dataset str | None

Dataset holding the tile origins, or None to read none.

H5_COORDS_DATASET
mpp float | None

Microns per pixel of the tiles, carried by the source for later calls.

None
coords_scale float | None

Frame pixels per tile pixel. Defaults to what the file records, else 1.

None

Raises:

Type Description
AlhenaValueError

If the file or a dataset named is missing, or the records disagree.

GeometryError

If the tiles are not an (n_tiles, height, width, 3) uint8 array.

path property

path

Path of the file the tiles are read from.

close

close()

Close the file. Reading from the source again reopens it.

alhena.io.SlideTileSource

SlideTileSource(path, *, tile_px=None, stride_px=None, level=0, mpp=None, edge='pad', coords=None, region=None)

Bases: TileSource

Tiles cut from a whole slide, read one region at a time: a grid, or the tiles selected.

read_slide builds it. Origins are in level-zero pixels whatever the level read, and coords_scale is the downsample of that level. A selected origin read at a coarser level is recorded at the first level-zero pixel of the level pixel it falls in.

Attributes:

Name Type Description
level

Pyramid level the regions are read from.

downsample

Pixels of level zero one pixel of that level covers.

edge

The rule the tiles the edge of the level cuts were read under.

mpp_source

Where the resolution of level zero was read from, such as "mpp argument", "OME PhysicalSizeX", "aperio.MPP" or "TIFF resolution tags".

Open a slide and settle the tiles to read from one of its levels.

Parameters:

Name Type Description Default
path str | Path

Path of the slide.

required
tile_px int | None

Side of each tile, in pixels of the level read. Defaults to the side that fills the canvas at the resolution of that level.

None
stride_px int | None

Step between tile origins, in those pixels. Defaults to tile_px; refused beside coords.

None
level int

Pyramid level the tiles are read from.

0
mpp float | None

Microns per pixel of level zero, taking precedence over the slide's own.

None
edge str

One of EDGE_RULES: what becomes of the tiles the edge of the level cuts.

'pad'
coords ndarray | None

Level-zero origins of the tiles to cut instead of the grid, (n_tiles, 2), x then y.

None
region Sequence[float] | None

x0, y0, x1, y1 in level-zero pixels, upper bounds excluded: only the tiles lying wholly inside it are kept.

None

Raises:

Type Description
AlhenaValueError

If the slide cannot be read, the level is invalid, or no tile fits.

GeometryError

If mpp is not given and the slide declares no usable resolution.

MissingExtraError

If tiffslide is not installed.

path property

path

Path of the slide the tiles are read from.

close

close()

Close the slide. Reading from the source again reopens it.

alhena.io.ImageTileSource

ImageTileSource(image, *, tile_px=None, stride_px=None, mpp=None, edge='shift', coords=None, coords_frame=None, region=None)

Bases: TileSource

Tiles cut from one image held whole, read one window at a time.

read_image builds it. Origins are in the pixels of the image, and coords_frame names the file and its level zero, or is IMAGE_FRAME for an array.

Attributes:

Name Type Description
edge

The rule the tiles the edge of the image cuts were read under.

Hold one image and settle the tiles to cut from it.

Parameters:

Name Type Description Default
image ndarray | str | Path

A (height, width, 3) uint8 RGB array, an array read by slicing such as a memory map, or the path of a .npy file or an image file.

required
tile_px int | None

Side of each tile, in pixels of the image. Defaults to the side that fills the canvas at mpp; one of the two is required.

None
stride_px int | None

Step between tile origins. Defaults to tile_px; refused beside coords.

None
mpp float | None

Microns per pixel of the image.

None
edge str

One of EDGE_RULES: what becomes of the tiles the edge of the image cuts.

'shift'
coords ndarray | None

Origins of the tiles to cut instead of the grid, (n_tiles, 2), x then y, in pixels of the image.

None
coords_frame str | None

Name of the frame of the origins. Defaults to the file and its level zero, or IMAGE_FRAME for an array.

None
region Sequence[float] | None

x0, y0, x1, y1 in pixels of the image, upper bounds excluded: only the tiles lying wholly inside it are kept.

None

Raises:

Type Description
AlhenaValueError

If the image cannot be read, or an argument does not fit the image.

GeometryError

If the image is not a (height, width, 3) uint8 array.

path property

path

Path of the image file the tiles are cut from, or None for an array.

close

close()

Release the pixels of an image file, read again on demand; an array is left alone.

alhena.io.NUCLEI_KINDS module-attribute

NUCLEI_KINDS = ('label_maps', 'centroids', 'polygons')

Kinds of nucleus input read_nuclei dispatches to.

alhena.io.CENTROID_FRAMES module-attribute

CENTROID_FRAMES = ('tile', 'origins')

Frames a table of centroids is read in: its tile's pixels, or the frame of the tile origins.

alhena.io.COORDINATE_UNITS module-attribute

COORDINATE_UNITS = ('px', 'um')

Units nucleus coordinates are read in: pixels of their frame, or microns.

alhena.io.MULTIPART_RULES module-attribute

MULTIPART_RULES = ('refuse', 'split', 'largest')

Rules for a boundary of several polygons: refuse it, split it, or keep its largest polygon.

alhena.io.EDGE_RULES module-attribute

EDGE_RULES = ('drop', 'shift', 'pad')

Rules for tiles cut by the image edge: leave out, shift inward, or pad with white.

alhena.io.IMAGE_FRAME module-attribute

IMAGE_FRAME = 'image, level 0'

Name of the frame of the tiles read_image cuts from an array: the pixels of that array.

alhena.io.PART_SEPARATOR module-attribute

PART_SEPARATOR = ':'

Separator between a boundary's identifier and a polygon's position, under "split".

alhena.io.CELL_ID_STRIDE module-attribute

CELL_ID_STRIDE = 100000

Number of identifiers in the block each tile owns when global_cell_ids renumbers.

alhena.io.IMAGE_SUFFIXES module-attribute

IMAGE_SUFFIXES = ('.png', '.jpg', '.jpeg', '.tif', '.tiff', '.bmp', '.webp')

Suffixes read as tile images.

alhena.io.LABEL_SUFFIXES module-attribute

LABEL_SUFFIXES = ('.png', '.tif', '.tiff', '.npy')

Suffixes read as integer label maps.

alhena.io.HDF5_SUFFIXES module-attribute

HDF5_SUFFIXES = ('.h5', '.hdf5')

Suffixes read as HDF5.

alhena.io.TABLE_SUFFIXES module-attribute

TABLE_SUFFIXES = ('.csv', '.tsv', '.txt', '.parquet', '.pq')

Suffixes read as tables, of centroids or of tile origins.

alhena.io.GEOJSON_SUFFIXES module-attribute

GEOJSON_SUFFIXES = ('.geojson', '.json')

Suffixes read as GeoJSON collections of polygons.

alhena.io.BOUNDARY_TABLE_SUFFIXES module-attribute

BOUNDARY_TABLE_SUFFIXES = TABLE_SUFFIXES

Suffixes of boundary files read as tables of vertices or GeoParquet; others are GeoJSON.

alhena.io.TRANSFORM_SUFFIXES module-attribute

TRANSFORM_SUFFIXES = ('.csv', '.npy')

Suffixes an affine matrix is read from: comma-separated numbers, or a NumPy array.

alhena.io.SLIDE_SUFFIXES module-attribute

SLIDE_SUFFIXES = ('.svs', '.ndpi', '.scn', '.bif', '.tif', '.tiff', '.btf')

Suffixes of whole slides, read by read_slide: TIFF and the slide formats built on it.

alhena.io.UNREAD_SLIDE_FORMATS module-attribute

UNREAD_SLIDE_FORMATS = {'.mrxs': 'MIRAX', '.vms': 'Hamamatsu VMS', '.vmu': 'Hamamatsu VMU', '.dcm': 'DICOM', '.zvi': 'Zeiss ZVI', '.czi': 'Zeiss CZI'}

Slide formats the slide reader cannot open, by suffix, refused before they are opened.

alhena.io.H5_IMAGE_DATASET module-attribute

H5_IMAGE_DATASET = 'img'

HDF5 dataset holding the tiles, an (n_tiles, height, width, 3) uint8 array.

alhena.io.H5_COORDS_DATASET module-attribute

H5_COORDS_DATASET = 'coords'

HDF5 dataset holding the top-left origin of each tile, (n_tiles, 2) integers, x then y.

alhena.io.H5_BARCODE_DATASET module-attribute

H5_BARCODE_DATASET = 'barcode'

HDF5 dataset holding the name of each tile, an (n_tiles, 1) array of UTF-8 strings.

alhena.io.H5_FRAME_SIDE_ATTRIBUTE module-attribute

H5_FRAME_SIDE_ATTRIBUTE = 'patch_size_level0'

Attribute of coords recording the side of a tile in the pixels of the frame of coords.

alhena.io.H5_TILE_SIDE_ATTRIBUTE module-attribute

H5_TILE_SIDE_ATTRIBUTE = 'patch_size'

Attribute of coords recording the side of a tile in the pixels of the tile.

alhena.io.H5_SCALE_RECORDS module-attribute

H5_SCALE_RECORDS = ((H5_COORDS_DATASET, H5_FRAME_SIDE_ATTRIBUTE, H5_TILE_SIDE_ATTRIBUTE), (H5_IMAGE_DATASET, 'patch_size_src', 'patch_size_target'))

Where an HDF5 file records its tile side: dataset, side in the frame, side in the tile.

alhena.io.H5_LABEL_DATASET module-attribute

H5_LABEL_DATASET = 'labels'

HDF5 dataset holding the label maps of every tile, stacked into one array.

alhena.io.CENTROID_COLUMNS module-attribute

CENTROID_COLUMNS = {'x': ('x', 'centroid_x', 'x_centroid'), 'y': ('y', 'centroid_y', 'y_centroid'), 'tile_index': ('tile_index', 'tile', 'patch_index'), 'cell_id': ('cell_id', 'cell', 'id'), 'radius_px': ('radius_px', 'radius')}

Column names tried for each field of a table of centroids, unless columns names one.

alhena.io.VERTEX_COLUMNS module-attribute

VERTEX_COLUMNS = {'cell_id': ('cell_id', 'cell', 'id'), 'x': ('vertex_x', 'x'), 'y': ('vertex_y', 'y')}

Column names tried for each field of a table of vertices, unless columns names one.

alhena.io.ORIGIN_COLUMNS module-attribute

ORIGIN_COLUMNS = {'tile_id': ('tile_id', 'tile'), 'x': ('x',), 'y': ('y',)}

Column names tried for each field of a table of tile origins, unless columns names one.

alhena.io.MPP_X_PROPERTIES module-attribute

MPP_X_PROPERTIES = ('aperio.MPP', 'tiffslide.mpp-x', 'openslide.mpp-x')

Slide properties read, in order, for the microns per pixel of level zero across.

alhena.io.MPP_Y_PROPERTIES module-attribute

MPP_Y_PROPERTIES = ('aperio.MPP', 'tiffslide.mpp-y', 'openslide.mpp-y')

Slide properties read, in order, for the microns per pixel of level zero down.

alhena.io.OME_LENGTH_UNITS module-attribute

OME_LENGTH_UNITS = {'m': 1000000.0, 'dm': 100000.0, 'cm': 10000.0, 'mm': 1000.0, 'µm': 1.0, 'nm': 0.001, 'pm': 1e-06, 'Å': 0.0001, 'in': 25400.0}

Microns in each unit an OME pixel size may be written in; no unit means micrometers.

Tile embeddings on disk

One table layout holds tile embeddings: the embedding of every tile, its spatial bounds in the source image and their center when available, and the provenance of the pass. TileEmbeddings.write_h5ad writes it, to_anndata returns it in memory, and read_tile_embeddings reads it back. The table layouts set it out.

alhena.io.read_tile_embeddings

read_tile_embeddings(source)

Read tile embeddings back from a table ALHENA wrote.

A table written for tiles sharing no frame reads back without bounds.

Parameters:

Name Type Description Default
source str | Path | AnnData

Path of an .h5ad file, or an AnnData table in memory.

required

Returns:

Type Description
TileEmbeddings

The tiles in the order of the table, with the bounds and the provenance they were written

TileEmbeddings

with.

Raises:

Type Description
AlhenaValueError

If the file is missing, or the table lacks a field the layout carries.

alhena.io.TILES_SUFFIX module-attribute

TILES_SUFFIX = CELLS_SUFFIX

Suffix of a table of tile embeddings, the one a table of cells is written to.

alhena.io.TILE_ID_COLUMN module-attribute

TILE_ID_COLUMN = 'tile_id'

Column of a table of tiles holding the name of each tile, which its index holds too.

alhena.io.TILE_BOUNDS_COLUMNS module-attribute

TILE_BOUNDS_COLUMNS = ('alhena_tile_x0', 'alhena_tile_y0', 'alhena_tile_x1', 'alhena_tile_y1')

Columns of the bounds x0, y0, x1, y1 of each tile in its frame, upper bounds excluded.

alhena.io.TILE_EMBEDDING_KEY module-attribute

TILE_EMBEDDING_KEY = 'X_alhena_tile'

Array of a table of tiles holding the tile embeddings.

alhena.io.TILES_PROVENANCE_KEY module-attribute

TILES_PROVENANCE_KEY = 'alhena_tiles'

Entry of uns holding the provenance of tile embeddings.

Cells on disk

One table layout holds cells alone, annotations together with their underlying cell embeddings, and the table cells_to_spatialdata stores. CellEmbeddings.write_h5ad and AnnotationResult.write_h5ad write it, and to_anndata returns it in memory. read_cells reads the cells back out of it with their provenance, and read_annotations one annotation together with its cells. The cells are held once, and add_annotation adds further annotations of them, each under fields named after it. The table layouts set it out.

alhena.io.read_cells

read_cells(source)

Read cells back from a table ALHENA wrote, to annotate them again without the encoder.

A table of annotations, or the table alhena.spatial.cells_to_spatialdata stores, reads back the same way.

Parameters:

Name Type Description Default
source str | Path | AnnData

Path of an .h5ad file, or an AnnData table in memory.

required

Returns:

Type Description
CellEmbeddings

The cells in the order of the table, with the provenance they were written with; tiles is

CellEmbeddings

None.

Raises:

Type Description
AlhenaValueError

If the file is missing, or the table lacks a field the layout carries.

alhena.io.read_annotations

read_annotations(source, *, name=None)

Read one annotation back from a table ALHENA wrote, with the cells it was made from.

A table AnnotationResult.write_h5ad wrote, add_annotation added to or alhena.spatial.cells_to_spatialdata stored reads back the same way. The similarities of the retrieved neighbors are not written, so they read back zero columns wide.

Parameters:

Name Type Description Default
source str | Path | AnnData

Path of an .h5ad file, or an AnnData table in memory.

required
name str | None

Name the annotation was stored under, its axis unless another was given. May be left out where the table holds one annotation.

None

Returns:

Type Description
AnnotationResult

The annotation, in the order of the table, with its cells attached as read_cells reads

AnnotationResult

them.

Raises:

Type Description
AlhenaValueError

If the table is not one ALHENA wrote, or name picks no annotation.

alhena.io.add_annotation

add_annotation(table, result, name=None, overwrite=False)

Add an annotation to a table of the cells it was made from, beside those it holds.

The table is changed in place. Each annotation adds fields named after it, so annotations on several axes, or against several references, share one table.

Parameters:

Name Type Description Default
table AnnData

A table of cells ALHENA wrote, held in memory, with the cell-space embedding.

required
result AnnotationResult

The annotations, made from the cells of the table, in its order.

required
name str | None

Name the fields of the annotation carry. Defaults to the axis of the annotations.

None
overwrite bool

Replace the annotation stored under name, and that one alone.

False

Returns:

Type Description
AnnData

The table, with the annotation added.

Raises:

Type Description
AlhenaValueError

If the annotations are of other cells, or the name is unusable or taken.

alhena.io.CELLS_SUFFIX module-attribute

CELLS_SUFFIX = '.h5ad'

Suffix of a table of cells, and of annotations written together with their cells.

alhena.io.CELL_ID_COLUMN module-attribute

CELL_ID_COLUMN = 'cell_id'

Column of a table of cells holding the identifiers, in the type they were given in.

alhena.io.TILE_INDEX_COLUMN module-attribute

TILE_INDEX_COLUMN = 'alhena_tile_index'

Column of the tile index: each tile's position among those given, or each cell's tile.

alhena.io.NUCLEUS_PX_COLUMN module-attribute

NUCLEUS_PX_COLUMN = 'alhena_nucleus_px'

Column holding the nucleus pixels supporting each cell in the tile it was read from.

alhena.io.CANDIDATE_TILES_COLUMN module-attribute

CANDIDATE_TILES_COLUMN = 'alhena_n_candidate_tiles'

Column holding how many tiles held each nucleus.

alhena.io.EMBEDDING_VALID_COLUMN module-attribute

EMBEDDING_VALID_COLUMN = 'alhena_embedding_valid'

Column holding whether each cell embedding may be used.

alhena.io.LABEL_COLUMN module-attribute

LABEL_COLUMN = 'alhena_celltype'

Stem of the column of an annotation's predicted cell types, suffixed with its name.

alhena.io.CONFIDENCE_COLUMN module-attribute

CONFIDENCE_COLUMN = 'alhena_confidence'

Stem of the column of the mass the winning class received.

alhena.io.VALID_COLUMN module-attribute

VALID_COLUMN = 'alhena_valid'

Stem of the column of whether an annotation was assigned.

alhena.io.CLASS_ENTROPY_COLUMN module-attribute

CLASS_ENTROPY_COLUMN = 'alhena_class_entropy'

Stem of the column of the class entropy.

alhena.io.NEIGHBOR_ENTROPY_COLUMN module-attribute

NEIGHBOR_ENTROPY_COLUMN = 'alhena_neighbor_entropy'

Stem of the column of the neighbor entropy.

alhena.io.BACKBONE_KEY module-attribute

BACKBONE_KEY = 'X_alhena_backbone'

Array of the pre-projection cell embeddings.

alhena.io.CELL_SPACE_KEY module-attribute

CELL_SPACE_KEY = 'X_alhena_cell'

Array of the embeddings in the shared cell space.

alhena.io.SPATIAL_KEY module-attribute

SPATIAL_KEY = 'spatial'

Array of positions: the nucleus centroids, or the centers of the tile bounds.

alhena.io.MASS_KEY module-attribute

MASS_KEY = 'alhena_mass'

Stem of the array of an annotation's class mass, in class order.

alhena.io.CELLS_PROVENANCE_KEY module-attribute

CELLS_PROVENANCE_KEY = 'alhena_cells'

Entry of uns holding the provenance of the cells.

alhena.io.PROVENANCE_KEY module-attribute

PROVENANCE_KEY = 'alhena'

Entry of uns holding the provenance of the annotations.

alhena.io.ANNOTATIONS_KEY module-attribute

ANNOTATIONS_KEY = 'annotations'

Entry under PROVENANCE_KEY holding one record per annotation, keyed by its name.


Next: Preprocessing