zarr_indexing.json
zarr_indexing.json ¶
Lowering between canonical ndsel bodies and in-memory IndexTransforms.
This is the engine layer. Where messages.py is pure JSON→JSON and imposes
no array constraints, this module converts a canonical ndsel transform body
(spec section 4.3, as produced by zarr_indexing.messages.normalize_ndsel)
into the numpy-backed IndexTransform the chunk engine runs on, and back.
Two engine constraints live here and only here:
- Finite bounds. An
IndexDomainaddresses a finite array, so a canonical body carrying a"-inf"/"+inf"bound cannot be lowered;from_jsonraises. - Implicit bounds lower by value. The
[n]-bracket implicit/explicit flag is a message-layer concern; the engine keeps only the integer value.
The index_array wire format (and the degenerate-collapse it documents)¶
ndsel and TensorStore both reject an output map that carries both
input_dimension and index_array. The in-memory ArrayMap, however, records
an input_dimension to pin the axis an orthogonal (oindex) array varies over.
This module bridges the gap:
- On serialize (
transform_to_canonical): - An all-singleton
index_array(size 1) selects a single coordinate regardless of input, so it is collapsed to aconstantmap{offset: offset + stride*value}. The size-1 input dimension stays in the domain, unconsumed — a valid transform. This makes a length-1oindexselection round-trip behaviorally (anArrayMapbecomes aConstantMap) rather than by object identity. -
Non-degenerate
index_arraymaps are emitted withoutinput_dimension. -
On load (
transform_from_canonical): the in-memoryinput_dimensionis reconstructed from the full-rank array's dependency axes (its non-singleton axes, seetransform._array_map_dependency_axes). An array that solely owns a single non-singleton axis is orthogonal (input_dimension = that axis); arrays that share non-singleton axes, or vary over several, are correlated (vindex,input_dimension = None). A single 1-D array over a rank-1 domain is inherently ambiguous between the two flavours; it reconstructs as orthogonal, which is behaviorally identical for the single-array case.
index_transform_to_json / index_transform_from_json (and the *_domain_*
variants) are these canonical converters under their historical names.
IndexDomainJSON ¶
Bases: TypedDict
Canonical JSON representation of an IndexDomain.
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
IndexTransformJSON ¶
Bases: TypedDict
Canonical JSON representation of an IndexTransform (spec section 4.3).
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
OutputIndexMapJSON ¶
Bases: TypedDict
Canonical JSON representation of a single output index map.
Exactly one of three forms (distinguished by which fields are present):
{"offset": 5}— constant{"offset": 0, "stride": 1, "input_dimension": 0}— single_input_dimension{"offset": 0, "stride": 1, "index_array": [...], "index_array_bounds": ["-inf", "+inf"]}— index_array
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
index_domain_from_json ¶
index_domain_from_json(
data: IndexDomainJSON,
) -> IndexDomain
Construct an IndexDomain from its canonical JSON representation.
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
index_domain_to_json ¶
index_domain_to_json(
domain: IndexDomain,
) -> IndexDomainJSON
Convert an IndexDomain to its canonical JSON representation.
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
output_index_map_from_json ¶
output_index_map_from_json(
data: OutputIndexMapJSON,
) -> OutputIndexMap
Construct an output index map from its canonical JSON representation.
An index_array map's input_dimension is reconstructed from the array's
dependency axes in isolation (single non-singleton axis → orthogonal). The
transform-level loader classifies globally; use it when several maps may
share axes.
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
output_index_map_to_json ¶
output_index_map_to_json(
m: OutputIndexMap,
) -> OutputIndexMapJSON
Convert an output index map to its canonical JSON representation.
A degenerate all-singleton ArrayMap collapses to a constant map; a
non-degenerate one is emitted without input_dimension (see the module
docstring on the wire format).
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
transform_from_canonical ¶
transform_from_canonical(
data: IndexTransformJSON,
) -> IndexTransform
Construct an IndexTransform from a canonical (or canonicalizable) body.
The body is first run through the message layer (normalize_ndsel) so that
omitted fields — identity output, default bounds/labels — are filled and
validated, then lowered to the engine representation. index_array maps'
input_dimension values are reconstructed by global dependency-axis
ownership (see the module docstring).
Source code in packages/zarr-indexing/src/zarr_indexing/json.py
transform_to_canonical ¶
transform_to_canonical(
transform: IndexTransform,
) -> IndexTransformJSON
Convert an IndexTransform to its canonical ndsel transform body.
The result is fully explicit (spec section 4.3): input_rank, fully written
bounds and labels, and an explicit output with offset/stride present
on every affine and array map.