Data¶
Data stores hold the arrays backing each visual, along with the request and slice-result types used to fetch data for the current view.
Common¶
cellier.data.DataStoreType
module-attribute
¶
DataStoreType = Annotated[Union[MultiscaleZarrDataStore, ImageMemoryStore, OMEZarrImageDataStore, LabelMemoryStore, PointsMemoryStore, LinesMemoryStore, MeshMemoryStore], Field(discriminator='store_type')]
Images¶
cellier.data.image.ImageMemoryStore ¶
Bases: BaseDataStore
In-memory image data store backed by a numpy array.
Serves axis-aligned slices or full sub-volumes to the AsyncSlicer.
All reads are synchronous (the array is in CPU RAM); the method is
still declared async to satisfy the AsyncSlicer contract.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
ndarray
|
The image data. Any dtype; coerced to float32 on construction. Shape convention follows numpy axis order — e.g. (D, H, W) for 3-D, (H, W) for 2-D, (T, C, D, H, W) for 5-D. |
required |
name
|
str
|
Human-readable label. Default |
required |
level_shapes
property
¶
List with one entry (level 0 = the full array).
get_data
async
¶
get_data(request: ChunkRequest) -> ndarray
Return the requested sub-region as a float32 array.
Interprets request.axis_selections generically:
intentry → sliced axis; the integer index is applied and the axis is dropped from the output.(start, stop)tuple → displayed axis; a slice is applied and the axis is kept in the output.
Out-of-bounds coordinates are clamped to array extents and zero-padded on the output side so the returned shape always matches what the caller requested.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ChunkRequest
|
Built by |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
float32 array with one dimension per displayed (tuple) axis. |
cellier.data.image.MultiscaleZarrDataStore ¶
Bases: BaseDataStore
Data store for a multiscale zarr volume read via tensorstore.
Public fields are validated and serialisable (pydantic).
Tensorstore handles are opened synchronously in model_post_init
and stored as private attributes so they are not serialised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store_type
|
Literal['multiscale_zarr']
|
Discriminator field. Always |
required |
zarr_path
|
Path to the root directory of the multiscale zarr store.
Pass as a string; |
required | |
scale_names
|
Ordered list of subdirectory names, finest → coarsest,
e.g. |
required | |
level_transforms
|
Per-level affine transforms mapping level-k voxel coords to
level-0 voxel coords. |
required | |
name
|
Human-readable name for the store (inherited from
|
required |
Attributes (read-only properties)
n_levels :
Number of scale levels (length of scale_names).
level_shapes :
List of shape tuples, one per level.
level_shapes
property
¶
Shape for each scale level, finest first.
model_post_init ¶
model_post_init(__context: Any) -> None
Open all tensorstore handles.
Called automatically by pydantic after __init__.
Must run before QtAsyncio.run() starts the event loop.
from_scale_and_translation
classmethod
¶
from_scale_and_translation(*, zarr_path: str, scale_names: list[str], level_scales: list[tuple[float, ...]], level_translations: list[tuple[float, ...]], name: str = 'multiscale zarr data store') -> MultiscaleZarrDataStore
Construct from per-level scale and translation vectors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zarr_path
|
str
|
Path to the root directory of the multiscale zarr store. |
required |
scale_names
|
list[str]
|
Ordered list of subdirectory names, finest → coarsest. |
required |
level_scales
|
list[tuple[float, ...]]
|
Per-level scale vectors. |
required |
level_translations
|
list[tuple[float, ...]]
|
Per-level translation vectors. |
required |
name
|
str
|
Human-readable name for the store. |
'multiscale zarr data store'
|
get_data
async
¶
get_data(request: ChunkRequest) -> ndarray
Read a single padded brick, returning a zero-padded float32 array.
Interprets request.axis_selections generically: displayed axes
(tuple ranges) become slice dimensions in the output; sliced axes
(int values) become point selections.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ChunkRequest
|
Padded brick specification. Coordinates may be negative or exceed store bounds; clamping is handled internally. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
out |
ndarray
|
|
cellier.data.image.OMEZarrImageDataStore ¶
Bases: BaseDataStore
Data store for an OME-Zarr v0.5 image read via tensorstore.
Use the :meth:from_path class method to construct from an OME-Zarr URI.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store_type
|
Literal['ome_zarr_image']
|
Discriminator field. Always |
required |
zarr_path
|
str
|
URI to the root OME-Zarr group. Must start with |
required |
multiscale_index
|
int
|
Index into |
required |
scale_names
|
list[str]
|
Per-level relative array paths, finest to coarsest. |
required |
level_transforms
|
list[AffineTransform]
|
Full-rank (all axes) AffineTransform per level: voxel-level-k to voxel-level-0. |
required |
axis_names
|
list[str]
|
All axis names in data order. |
required |
axis_units
|
list[str | None]
|
Physical units per axis ( |
required |
axis_types
|
list[str]
|
OME axis type per axis. |
required |
name
|
str
|
Human-readable name for the store. |
required |
level_shapes
property
¶
Full-rank shape per level (all axes), finest first.
Returns shapes over all axes, including non-spatial ones.
The controller projects to the displayed subshape using
dims.displayed_axes before constructing the render visual.
axes
property
¶
All axes in data order as AxisInfo descriptors.
Use array_dim and type to configure dims.displayed_axes
and dims.selection.slice_indices before rendering. Example::
scene.dims.displayed_axes = [
ax.array_dim for ax in store.axes if ax.type == "space"
]
scene.dims.selection.slice_indices = {
ax.array_dim: 0 for ax in store.axes if ax.type != "space"
}
model_post_init ¶
model_post_init(__context: Any) -> None
Open all TensorStore handles (synchronous, before QtAsyncio).
from_path
classmethod
¶
from_path(zarr_path: str, *, multiscale_index: int = 0, series_index: int = 0, anonymous: bool = False, name: str = 'ome zarr image data store') -> OMEZarrImageDataStore
Construct from an OME-Zarr v0.5 URI.
Supports both standard Image stores and Bf2Raw (bioformats2raw) multi-series containers. For Bf2Raw stores the series_index selects which child image to open.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zarr_path
|
str
|
URI with a scheme prefix: |
required |
multiscale_index
|
int
|
Which |
0
|
series_index
|
int
|
For Bf2Raw containers, which image series to open. Ignored for standard Image stores. Defaults to 0. |
0
|
anonymous
|
bool
|
When True, use anonymous credentials for S3/GCS access (for public buckets). Default False. |
False
|
name
|
str
|
Human-readable name for the store. |
'ome zarr image data store'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the URI scheme is not supported or the series index is out of range. |
TypeError
|
If the OME metadata is neither Image nor Bf2Raw (e.g. a Plate). |
get_data
async
¶
get_data(request: ChunkRequest) -> ndarray
Read a single padded brick, returning a zero-padded float32 array.
Interprets request.axis_selections generically: displayed axes
(tuple ranges) become slice dimensions in the output; sliced axes
(int values) become point selections.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ChunkRequest
|
Padded brick specification. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
|
cellier.data.image.AxisInfo
dataclass
¶
Descriptor for one axis of an OME-Zarr array.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Axis name from OME metadata, e.g. |
required |
unit
|
str or None
|
Physical unit string, or |
required |
type
|
str
|
OME axis type: |
required |
array_dim
|
int
|
Zero-based index of this axis in the full zarr array shape.
Use to populate |
required |
cellier.data.image.ChunkRequest ¶
Bases: NamedTuple
A request for one padded brick / chunk of data.
All coordinates encode the padded region including overlap. They
may be negative or exceed the store bounds; get_data() on the
MultiscaleZarrDataStore is responsible for clamping and
zero-padding so the returned array always has the full requested
shape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chunk_request_id
|
Unique ID for this individual chunk. |
required | |
slice_request_id
|
Shared ID for all chunks that belong to the same planning event. |
required | |
scale_index
|
0-based index into |
required | |
axis_selections
|
Per-axis selection in data axis order. Each element is either:
- |
required |
Labels¶
cellier.data.label.LabelMemoryStore ¶
Bases: BaseDataStore
In-memory label data store backed by a numpy integer array.
Serves axis-aligned slices or full sub-volumes as int32 arrays. Source dtype may be int8, int16, or int32; int64/uint* are rejected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
ndarray
|
Integer label array (int8, int16, or int32). Shape follows numpy axis order — e.g. (D, H, W) for 3-D, (H, W) for 2-D. |
required |
name
|
str
|
Human-readable label. Default |
required |
get_data
async
¶
get_data(request: ChunkRequest) -> ndarray
Return the requested sub-region as an int32 array.
Interprets request.axis_selections generically:
- int entry → sliced axis (dropped from output)
- (start, stop) tuple → displayed axis (kept in output)
Out-of-bounds coordinates are clamped and zero-padded. Always returns int32 regardless of source dtype.
cellier.data.label.OMEZarrLabelDataStore ¶
Bases: BaseDataStore
Multiscale OME-Zarr label store returning int32 bricks.
Use the :meth:from_path class method to construct from a URI that
points to an OME-NGFF label group (containing ome → multiscales
metadata).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store_type
|
Literal['ome_zarr_label']
|
Discriminator field. Always |
required |
zarr_path
|
str
|
URI to the label group. Must point to the label sub-group
(e.g. |
required |
multiscale_index
|
int
|
Which multiscale entry to use (default 0). |
required |
scale_names
|
list[str]
|
Per-level relative array paths, finest to coarsest. |
required |
level_transforms
|
list[AffineTransform]
|
Per-level voxel-level-k → voxel-level-0 transforms. |
required |
axis_names
|
list[str]
|
All axis names in data order. |
required |
axis_units
|
list[str | None]
|
Physical units per axis ( |
required |
axis_types
|
list[str]
|
OME axis type per axis. |
required |
name
|
str
|
Human-readable name for the store. |
required |
level_shapes
property
¶
Full-rank shape per level (all axes), finest first.
model_post_init ¶
model_post_init(__context: Any) -> None
Open all TensorStore handles (synchronous, before QtAsyncio).
from_path
classmethod
¶
from_path(zarr_path: str, *, multiscale_index: int = 0, anonymous: bool = False, name: str = 'ome zarr label data store') -> OMEZarrLabelDataStore
Construct from a URI pointing directly at an OME-NGFF label group.
The URI must point at a zarr group that carries ome.multiscales
metadata (i.e. the label sub-group itself, not the root OME-Zarr).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
zarr_path
|
str
|
URI with a scheme prefix: |
required |
multiscale_index
|
int
|
Which |
0
|
anonymous
|
bool
|
When True, use anonymous credentials for S3/GCS access. |
False
|
name
|
str
|
Human-readable name for the store. |
'ome zarr label data store'
|
get_data
async
¶
Read a padded brick, returning int32 (zero-padded for out-of-bounds).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
ChunkRequest
|
Padded brick specification with |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
int32 array. |
Points¶
cellier.data.points.PointsMemoryStore ¶
Bases: BaseDataStore
In-memory point-cloud data store backed by numpy arrays.
All reads are synchronous (data is in CPU RAM); get_data is
declared async to satisfy the AsyncSlicer contract and to
provide a single cancellation checkpoint.
Positions are stored in data-axis order: column 0 is axis 0 (z),
column 1 is axis 1 (y), column 2 is axis 2 (x). The render layer
applies the [:, [2, 1, 0]] reversal before uploading to pygfx.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
positions
|
ndarray
|
(n_points, ndim) float32 array. |
required |
colors
|
ndarray | None
|
(n_points, 4) float32 RGBA, index-matched to positions. Pass None for uniform-color rendering. |
required |
sizes
|
ndarray | None
|
(n_points,) float32 per-point sizes. Pass None for uniform-size rendering. |
required |
name
|
str
|
Human-readable label. |
required |
get_data
async
¶
get_data(request: PointsSliceRequest) -> PointsData
Return proximity-filtered point data for request.
Checkpoint
A After the proximity mask is built but before gathering surviving points. Fires if the slider is moved quickly enough to cancel the task before the gather.
If CancelledError fires at the checkpoint, the callback is never called, preventing stale geometry from reaching the GPU.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
PointsSliceRequest
|
Built by GFXPointsMemoryVisual.build_slice_request[_2d]. |
required |
Returns:
| Type | Description |
|---|---|
PointsData
|
Proximity-filtered, projected points ready for GPU upload.
|
cellier.data.points.PointsSliceRequest ¶
Bases: NamedTuple
Request for one proximity-filtered slice of points data.
The first three fields satisfy the AsyncSlicer logging contract:
slice_request_id is the task key; chunk_request_id and
scale_index appear in INFO/DEBUG log lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
slice_request_id
|
UUID
|
Shared ID for all requests in one planning event. Used by AsyncSlicer as the dict key for the running task — REQUIRED. |
required |
chunk_request_id
|
UUID
|
Per-request ID. For points (never tiled) this equals
|
required |
scale_index
|
int
|
Always 0 — no LOD levels. Present for slicer logging compat. |
required |
displayed_axes
|
tuple[int, ...]
|
Axis indices rendered in the canvas (2 for 2D, 3 for 3D). |
required |
slice_indices
|
dict[int, int]
|
Collapsed axis → world-space integer slice position. Empty when all axes are displayed (full 3D view). |
required |
thickness
|
float
|
Half-thickness of the proximity slab in data-space voxel units.
A point on a non-displayed axis |
required |
cellier.data.points.PointsData
dataclass
¶
Proximity-filtered points data returned by PointsMemoryStore.get_data().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
UUID
|
Echo of PointsSliceRequest.slice_request_id. |
required |
positions
|
ndarray
|
(n_points, n_displayed_dims) float32. Projected onto displayed axes; padded to 3D in the render layer. |
required |
colors
|
ndarray | None
|
(n_points, 4) float32 RGBA, index-matched to positions. None when the store carries no per-point colors. |
required |
sizes
|
ndarray | None
|
(n_points,) float32 per-point sizes. None when the store carries no per-point sizes. |
required |
color_mode
|
str
|
|
'uniform'
|
size_mode
|
str
|
|
'uniform'
|
is_empty
|
bool
|
True when the proximity filter produced zero surviving points and a placeholder geometry was returned. |
False
|
original_indices
|
ndarray | None
|
(n_points,) int array mapping each row of |
None
|
Lines¶
cellier.data.lines.LinesMemoryStore ¶
Bases: BaseDataStore
In-memory line-segment data store backed by numpy arrays.
Stores a collection of line segments as vertex pairs. For segment n,
positions[n * 2] is the start point and positions[n * 2 + 1]
is the end point.
Positions are stored in data-axis order: column 0 is axis 0 (z),
column 1 is axis 1 (y), column 2 is axis 2 (x). The render layer
applies the [:, [2, 1, 0]] reversal before uploading to pygfx.
All reads are synchronous (data is in CPU RAM); get_data is
declared async to satisfy the AsyncSlicer contract and to
provide a single cancellation checkpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
positions
|
ndarray
|
(n_vertices, ndim) float32 array. Must have an even number of rows. |
required |
colors
|
ndarray | None
|
(n_vertices, 4) float32 RGBA, index-matched to positions. Pass None for uniform-color rendering. |
required |
name
|
str
|
Human-readable label. |
required |
get_data
async
¶
get_data(request: LinesSliceRequest) -> LinesData
Return slab-filtered segment data for request.
Checkpoint
A After the per-vertex slab mask is built but before gathering surviving vertices. Fires if the slider is moved quickly enough to cancel the task before the gather.
If CancelledError fires at the checkpoint the callback is never called, preventing stale geometry from reaching the GPU.
Inclusion rule
A segment survives when both of its endpoints pass the
proximity test on every non-displayed axis:
slice_index - thickness <= coord <= slice_index + thickness
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
LinesSliceRequest
|
Built by GFXLinesMemoryVisual.build_slice_request[_2d]. |
required |
Returns:
| Type | Description |
|---|---|
LinesData
|
Filtered, projected segment data ready for GPU upload.
|
cellier.data.lines.LinesSliceRequest ¶
Bases: NamedTuple
Request for one slab-filtered slice of line-segment data.
The first three fields satisfy the AsyncSlicer logging contract:
slice_request_id is the task key; chunk_request_id and
scale_index appear in INFO/DEBUG log lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
slice_request_id
|
UUID
|
Shared ID for all requests in one planning event. Used by AsyncSlicer as the dict key for the running task — REQUIRED. |
required |
chunk_request_id
|
UUID
|
Per-request ID. For lines (never tiled) this equals
|
required |
scale_index
|
int
|
Always 0 — no LOD levels. Present for slicer logging compat. |
required |
displayed_axes
|
tuple[int, ...]
|
Axis indices rendered in the canvas (2 for 2D, 3 for 3D). |
required |
slice_indices
|
dict[int, int]
|
Collapsed axis → world-space integer slice position. Empty when all axes are displayed (full 3D view). |
required |
thickness
|
float
|
Half-thickness of the slab in data-space voxel units. A segment
is included when both of its endpoints satisfy
|
required |
cellier.data.lines.LinesData
dataclass
¶
Slab-filtered line-segment data returned by LinesMemoryStore.get_data().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
UUID
|
Echo of LinesSliceRequest.slice_request_id. |
required |
positions
|
ndarray
|
(n_vertices, n_displayed_dims) float32. n_vertices is always even;
pair |
required |
colors
|
ndarray | None
|
(n_vertices, 4) float32 RGBA, index-matched to positions. None when the store carries no per-vertex colors. |
required |
color_mode
|
str
|
|
'uniform'
|
is_empty
|
bool
|
True when the slab filter produced zero surviving segments and a placeholder geometry was returned. |
False
|
original_edge_indices
|
ndarray | None
|
(n_segments,) int array mapping each rendered segment to its edge
index in the store's full segment array. This is the slab filter's
surviving-segment list; in a full 3-D view it is the identity
|
None
|
Meshes¶
cellier.data.mesh.MeshMemoryStore ¶
Bases: BaseDataStore
In-memory triangle mesh data store.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
positions
|
ndarray
|
(n_vertices, N) float32 vertex positions for any world dimensionality N ≥ 2. For a 3-D scene use shape (n_vertices, 3); for a 5-D scene (t, z, y, x, c) use shape (n_vertices, 5). |
required |
indices
|
ndarray
|
(n_faces, 3) int32 triangle face indices. Must be int32 — pygfx rejects int64 at upload time. int64 input is coerced silently by the validator. |
required |
colors
|
ndarray | None
|
Per-vertex (n_vertices, 4) or per-face (n_faces, 4) float32 RGBA. Layout inferred from shape. |
required |
name
|
str
|
Human-readable label. |
required |
get_data
async
¶
get_data(request: MeshSliceRequest) -> MeshData
Return slab-filtered, reindexed mesh data for request.
Checkpoints
A After Phase 1 (slab mask built, no reindexing yet). Fires if slider moved before reindexing begins. B After Phase 2 (reindex complete, before projection). Fires if slider moved before projection.
If CancelledError fires at either checkpoint the callback is never called, preventing stale geometry from reaching the GPU.
Inclusion rule
A face survives only when all of its vertices satisfy
slice_index - thickness <= coord <= slice_index + thickness
on every sliced axis. This is the mesh analogue of the lines
store's "both endpoints must pass" rule and avoids projecting
off-slice vertices onto the slice plane with the wrong colors.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
MeshSliceRequest
|
Built by GFXMeshMemoryVisual.build_slice_request[_2d]. |
required |
Returns:
| Type | Description |
|---|---|
MeshData
|
Filtered, reindexed, projected mesh ready for GPU upload.
Normals are computed from the projected geometry.
|
cellier.data.mesh.MeshSliceRequest ¶
Bases: NamedTuple
Request for one slab-filtered slice of mesh data.
The first three fields satisfy the AsyncSlicer logging contract:
slice_request_id is the task key; chunk_request_id and
scale_index appear in INFO/DEBUG log lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
slice_request_id
|
UUID
|
Shared ID for all requests in one planning event. Used by AsyncSlicer as the dict key for the running task — REQUIRED. |
required |
chunk_request_id
|
UUID
|
Per-request ID. For mesh (never tiled) this equals
|
required |
scale_index
|
int
|
Always 0 — no LOD levels. Present for slicer logging compat. |
required |
displayed_axes
|
tuple[int, ...]
|
Axis indices rendered in the canvas. |
required |
slice_indices
|
dict[int, int]
|
Collapsed axis → world-space integer slice position. Empty when all axes are displayed (full 3D view). |
required |
thickness
|
float
|
Half-thickness of the slab in data-space units. Faces whose
at least one vertex satisfies
|
required |
cellier.data.mesh.MeshData
dataclass
¶
Filtered, reindexed mesh data returned by MeshMemoryStore.get_data().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_id
|
UUID
|
Echo of MeshSliceRequest.slice_request_id. |
required |
positions
|
ndarray
|
(n_vertices, n_displayed_dims) float32. Projected onto displayed axes; padded to 3D in the render layer. |
required |
indices
|
ndarray
|
(n_faces, 3) int32. Reindexed to reference only the vertices
in |
required |
normals
|
ndarray
|
(n_vertices, n_displayed_dims) float32. Projected normals. |
required |
colors
|
ndarray | None
|
Per-vertex (n_vertices, 4) or per-face (n_faces, 4) float32 RGBA. None when the store carries no color data. |
required |
color_mode
|
str
|
|
'vertex'
|
is_empty
|
bool
|
True when the slab contained no surviving faces and a placeholder geometry was returned. |
False
|
original_face_indices
|
ndarray | None
|
(n_faces,) int array mapping each row of |
None
|