zarr_indexing.grid
zarr_indexing.grid owns compact chunk-grid metadata so indexing plans can be
constructed without importing Zarr. FixedDimension(size, extent) represents
regular chunks in constant memory, including a clipped final data region;
VaryingDimension(edges, extent) represents explicit rectilinear chunk edges.
ChunkGrid(dimensions=...) combines these dimensions and returns ChunkSpec
objects whose shape is the valid data size and whose codec_shape preserves
the full codec-buffer size at a regular-grid boundary.
dimension_grids_from_chunks returns these compact dimensions: integer chunk
shapes become FixedDimension instances and explicit per-axis edge sequences
become VaryingDimension instances. DimensionGridLike remains the narrow
protocol used by the chunk planner, while EdgeDimensionGrid is kept for
explicit edge-based and coordinate-origin examples.
Zarr's array implementation can later import these compact grid types from
zarr_indexing; this package intentionally has no import dependency on Zarr.
zarr_indexing.grid ¶
Compact chunk grids and the narrow planner protocol.
DimensionGridLike describes only the per-axis operations required by
plan_chunks. The concrete compact grids below also retain enough metadata
to describe chunk data regions and codec buffer regions without importing
Zarr's array implementation.
ChunkGrid
dataclass
¶
A concrete regular or rectilinear arrangement of chunks for one array.
Examples:
A (3, 4) array with (2, 2) chunks has a (2, 2) grid whose bottom
row of chunks is clipped to one valid row of data:
>>> grid = ChunkGrid.from_sizes((3, 4), (2, 2))
>>> grid.grid_shape
(2, 2)
>>> grid.chunk_sizes
((2, 1), (2, 2))
>>> spec = grid[1, 0]
>>> spec.shape, spec.codec_shape, spec.is_boundary
((1, 2), (2, 2), True)
Source code in src/zarr_indexing/grid.py
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | |
chunk_shape
property
¶
The uniform declared chunk shape of a regular grid.
Raises ValueError for rectilinear grids, which have no single chunk shape;
use grid[coords] for per-chunk sizes instead.
chunk_sizes
property
¶
Per-dimension tuples of each chunk's valid data length.
Boundary chunks report their clipped extent, not the declared codec size.
dimensions
instance-attribute
¶
dimensions: tuple[DimensionGrid, ...]
One per-axis grid, each mapping that axis's source indices to chunks.
grid_shape
property
¶
The number of data-bearing chunks along each dimension.
is_regular
property
¶
is_regular: bool
Whether every dimension uses a single fixed chunk size.
False when any axis carries explicit (rectilinear) per-chunk edge lengths.
__getitem__ ¶
Look up the ChunkSpec at the given chunk coordinates (grid cells, not indices).
Returns None when any coordinate falls outside the grid; raises ValueError
when the number of coordinates does not match ndim. The spec's slices are in
global source coordinates.
Source code in src/zarr_indexing/grid.py
__iter__ ¶
Yield a ChunkSpec for every data-bearing chunk in row-major (C) order.
Source code in src/zarr_indexing/grid.py
__post_init__ ¶
all_chunk_coords ¶
all_chunk_coords(
*,
origin: Sequence[int] | None = None,
selection_shape: Sequence[int] | None = None,
) -> Iterator[tuple[int, ...]]
Iterate chunk coordinates over a rectangular grid region in row-major (C) order.
origin defaults to the grid origin and selection_shape to the rest of the grid.
The region is not bounds-checked: an oversized region yields coordinates outside
the grid, which __getitem__ resolves to None.
Source code in src/zarr_indexing/grid.py
from_sizes
classmethod
¶
Build a grid from an array shape and one chunk-size spec per dimension.
An int entry gives a fixed chunk size along that axis; a sequence of ints gives
explicit per-chunk edge lengths. A uniform sequence consistent with the axis extent
collapses to a fixed dimension, so the result may report is_regular.
Parameters:
-
array_shape(Sequence[int]) –The array extent along each dimension, in global source coordinates.
-
chunk_sizes(Sequence[int | Sequence[int]]) –Per-dimension chunk layout: a single size or explicit edge lengths.
Source code in src/zarr_indexing/grid.py
get_nchunks ¶
get_nchunks() -> int
The total number of data-bearing chunks: the product of grid_shape (1 if 0-d).
iter_chunk_regions ¶
iter_chunk_regions(
*,
origin: Sequence[int] | None = None,
selection_shape: Sequence[int] | None = None,
) -> Iterator[tuple[slice, ...]]
Yield each chunk's valid-data slices, in global source coordinates.
Covers the same region as all_chunk_coords, silently skipping coordinates
that fall outside the grid.
Source code in src/zarr_indexing/grid.py
update_shape ¶
Return a grid resized to new_shape by resizing each dimension.
Fixed axes keep their chunk size; rectilinear axes gain one trailing edge when
grown past their declared edges. Raises ValueError when new_shape does not
have ndim entries.
Source code in src/zarr_indexing/grid.py
ChunkSpec
dataclass
¶
A chunk's valid data region and its full codec buffer shape.
Examples:
The last chunk of a size-10 axis chunked by 3 holds one valid element
(slices), while its codec buffer still spans 3:
>>> spec = ChunkGrid.from_sizes((10,), (3,))[3]
>>> spec.slices
(slice(9, 10, 1),)
>>> spec.shape, spec.codec_shape
((1,), (3,))
>>> spec.is_boundary
True
Source code in src/zarr_indexing/grid.py
codec_shape
instance-attribute
¶
The declared (codec buffer) chunk shape, unclipped by the array extent.
is_boundary
property
¶
is_boundary: bool
Whether the valid data region is smaller than the full codec buffer on any axis.
shape
property
¶
The shape of the valid data region described by slices.
Smaller than codec_shape on boundary chunks, where the array extent clips the chunk.
slices
instance-attribute
¶
Per-dimension bounds of the valid data region, in global source coordinates.
DimensionGrid ¶
Bases: Protocol
Structural interface shared by the compact dimension grids.
Examples:
FixedDimension satisfies the protocol structurally:
>>> dim = FixedDimension(size=2, extent=5)
>>> isinstance(dim, DimensionGrid)
True
>>> dim.nchunks, dim.extent
(3, 5)
>>> dim.with_extent(4).nchunks
2
Source code in src/zarr_indexing/grid.py
ngridcells
property
¶
ngridcells: int
The number of declared grid cells; may exceed nchunks when trailing cells are empty.
size_repr
property
¶
size_repr: str
A compact rendering of the chunk sizes, used by ChunkGrid.__repr__.
chunk_offset ¶
chunk_size ¶
data_size ¶
index_to_chunk ¶
Map a global source index to the chunk index that contains it.
Implementers must raise IndexError when idx lies outside [0, extent).
indices_to_chunks ¶
Vectorized index_to_chunk; must raise IndexError for indices outside [0, extent).
resize ¶
resize(new_extent: int) -> DimensionGrid
with_extent ¶
with_extent(new_extent: int) -> DimensionGrid
Return a grid with the existing chunk layout re-clipped to new_extent.
Implementers must not invent new grid cells: raise ValueError when the declared
layout cannot cover new_extent.
Source code in src/zarr_indexing/grid.py
DimensionGridLike ¶
Bases: Protocol
The per-dimension chunk-mapping surface consumed by chunk resolution.
Examples:
EdgeDimensionGrid provides this surface. Chunk sizes (2, 3) tile
source coordinates [0, 5), so index 4 lands in the second chunk:
>>> grid = EdgeDimensionGrid([2, 3])
>>> grid.index_to_chunk(4)
1
>>> grid.chunk_offset(1), grid.chunk_size(1)
(2, 3)
Source code in src/zarr_indexing/grid.py
chunk_offset ¶
chunk_size ¶
index_to_chunk ¶
Map a global source index to the index of the chunk that contains it.
Implementers must raise IndexError when idx lies outside [0, extent).
indices_to_chunks ¶
Vectorized index_to_chunk: map global source indices to chunk indices.
Implementers must raise IndexError if any index lies outside [0, extent).
Source code in src/zarr_indexing/grid.py
EdgeDimensionGrid ¶
An explicitly edge-based grid for coordinate-origin examples and planners.
Examples:
Chunk sizes (2, 3) tile source coordinates [0, 5); lookups outside
that range raise:
>>> grid = EdgeDimensionGrid([2, 3])
>>> grid.num_chunks, grid.extent
(2, 5)
>>> grid.index_to_chunk(2)
1
>>> grid.index_to_chunk(5)
Traceback (most recent call last):
...
IndexError: index 5 is out of bounds for an axis of extent 5
Source code in src/zarr_indexing/grid.py
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 | |
extent
property
¶
extent: int
The axis length in global source coordinates: the sum of all chunk sizes.
sizes
instance-attribute
¶
The length of each chunk along the axis, in order; every entry is positive.
__eq__ ¶
__init__ ¶
Build a one-axis grid from explicit per-chunk sizes.
Every size must be positive; raises ValueError otherwise. A zero-length axis
is spelled as an empty sequence (no chunks), not as a zero size.
Parameters:
Source code in src/zarr_indexing/grid.py
chunk_offset ¶
The global source coordinate where chunk chunk_ix begins.
Raises IndexError when chunk_ix lies outside [0, num_chunks).
Source code in src/zarr_indexing/grid.py
chunk_size ¶
The length of chunk chunk_ix; every chunk holds data, so no boundary clipping applies.
Raises IndexError when chunk_ix lies outside [0, num_chunks).
Source code in src/zarr_indexing/grid.py
index_to_chunk ¶
Map a global source index to the chunk whose interval contains it.
Raises IndexError when idx lies outside [0, extent).
Source code in src/zarr_indexing/grid.py
indices_to_chunks ¶
Vectorized index_to_chunk over an array of global source indices.
Raises IndexError if any index lies outside [0, extent).
Source code in src/zarr_indexing/grid.py
FixedDimension
dataclass
¶
Uniform chunk size with a boundary chunk clipped to the axis extent.
Examples:
Chunks of size 3 on an axis of extent 10 give 4 chunks. The last chunk still declares a codec buffer of 3 but holds only 1 valid element:
>>> dim = FixedDimension(size=3, extent=10)
>>> dim.nchunks
4
>>> dim.index_to_chunk(7)
2
>>> dim.chunk_size(3), dim.data_size(3)
(3, 1)
Source code in src/zarr_indexing/grid.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | |
nchunks
class-attribute
instance-attribute
¶
Derived: the number of chunks holding data within extent.
ngridcells
class-attribute
instance-attribute
¶
Derived: the number of declared grid cells; equals nchunks for a fixed dimension.
size
instance-attribute
¶
size: int
The declared chunk length along this axis; every chunk's codec buffer size.
__post_init__ ¶
Source code in src/zarr_indexing/grid.py
chunk_offset ¶
The global source coordinate where chunk chunk_ix begins (chunk_ix * size).
Not bounds-checked: chunk indices past the last chunk extrapolate linearly.
Source code in src/zarr_indexing/grid.py
chunk_size ¶
The declared chunk length, size for every chunk.
The boundary chunk is not clipped here; use data_size for the valid data length.
data_size ¶
The number of valid data elements in chunk chunk_ix, clipped to extent.
Interior chunks report size; the boundary chunk reports the remainder, and chunk
indices at or past nchunks report 0.
Source code in src/zarr_indexing/grid.py
index_to_chunk ¶
Map a global source index to its chunk index (idx // size).
Raises IndexError when idx lies outside [0, extent).
Source code in src/zarr_indexing/grid.py
indices_to_chunks ¶
Vectorized index_to_chunk over an array of global source indices.
Raises IndexError if any index lies outside [0, extent).
Source code in src/zarr_indexing/grid.py
resize ¶
resize(new_extent: int) -> FixedDimension
Return a copy resized to new_extent; the fixed chunk size covers any new extent.
with_extent ¶
with_extent(new_extent: int) -> FixedDimension
Return a copy with the same chunk size and the axis extent set to new_extent.
VaryingDimension
dataclass
¶
Explicit chunk edge lengths, with trailing data clipped to extent.
Examples:
Edges (2, 3, 5) clipped to extent 9: the last chunk declares 5 but
holds only 4 valid elements, and index 4 lands in the second chunk:
>>> dim = VaryingDimension(edges=(2, 3, 5), extent=9)
>>> dim.nchunks
3
>>> dim.index_to_chunk(4)
1
>>> dim.chunk_offset(2)
5
>>> dim.chunk_size(2), dim.data_size(2)
(5, 4)
Source code in src/zarr_indexing/grid.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | |
cumulative
instance-attribute
¶
Prefix sums of edges; derived, and what index lookups binary-search.
edges
instance-attribute
¶
The declared per-chunk edge lengths, in order; codec buffer sizes, unclipped.
extent
instance-attribute
¶
extent: int
The axis length in global source coordinates; at most the sum of edges.
nchunks
class-attribute
instance-attribute
¶
Derived: the number of chunks holding data within extent.
ngridcells
class-attribute
instance-attribute
¶
Derived: the number of declared edges; exceeds nchunks when trailing cells are empty.
__init__ ¶
Source code in src/zarr_indexing/grid.py
chunk_offset ¶
The global source coordinate where chunk chunk_ix begins (sum of prior edges).
chunk_size ¶
The declared edge length of chunk chunk_ix.
Trailing chunks are not clipped to extent here; use data_size for that.
data_size ¶
The number of valid data elements in chunk chunk_ix, clipped to extent.
Grid cells that lie entirely at or past extent report 0.
Source code in src/zarr_indexing/grid.py
index_to_chunk ¶
Map a global source index to the chunk whose edge interval contains it.
Raises IndexError when idx lies outside [0, extent).
Source code in src/zarr_indexing/grid.py
indices_to_chunks ¶
Vectorized index_to_chunk over an array of global source indices.
Raises IndexError if any index lies outside [0, extent).
Source code in src/zarr_indexing/grid.py
resize ¶
resize(new_extent: int) -> VaryingDimension
Return a copy resized to new_extent.
Shrinking (or growing within the existing edges) keeps the edges and re-clips them; growing past the sum of edges appends one new trailing edge covering the remainder.
Source code in src/zarr_indexing/grid.py
with_extent ¶
with_extent(new_extent: int) -> VaryingDimension
Return a copy with the same edges re-clipped to new_extent.
The existing edges must already cover the new extent; raises ValueError when
new_extent exceeds the sum of edges. Use resize to grow past the edges.
Source code in src/zarr_indexing/grid.py
dimension_grids_from_chunks ¶
dimension_grids_from_chunks(
chunks: Sequence[int] | Sequence[Sequence[int]],
shape: Sequence[int],
) -> tuple[DimensionGrid, ...]
Build compact dimensions from regular sizes or explicit per-axis edges.
Examples:
One integer per dimension builds fixed grids, ready for plan_chunks:
>>> from zarr_indexing import IndexTransform, plan_chunks
>>> grids = dimension_grids_from_chunks((2, 2), shape=(3, 4))
>>> [type(grid).__name__ for grid in grids]
['FixedDimension', 'FixedDimension']
>>> plan = plan_chunks(IndexTransform.from_shape((3, 4))[1, :], grids)
>>> [p.chunk_coords for p in plan]
[(0, 0), (0, 1)]