diff --git a/cubed/core/ops.py b/cubed/core/ops.py index 4bcf315c3..e754898ed 100644 --- a/cubed/core/ops.py +++ b/cubed/core/ops.py @@ -212,11 +212,16 @@ def _store_array( shape = target.shape chunks = target.chunks for i, (sl, cs) in enumerate(zip(region, chunks)): - if sl.start % cs != 0 or (sl.stop % cs != 0 and sl.stop != shape[i]): + if (sl.start is not None and sl.start % cs != 0) or ( + sl.stop is not None and sl.stop % cs != 0 and sl.stop != shape[i] + ): raise ValueError( f"Region {region} does not align with target chunks {chunks}" ) - block_offsets = [sl.start // cs for sl, cs in zip(region, chunks)] + block_offsets = [ + (0 if sl.start is None else sl.start // cs) + for sl, cs in zip(region, chunks) + ] def key_function(out_key): out_coords = out_key[1:] diff --git a/cubed/tests/test_core.py b/cubed/tests/test_core.py index dd815f4d6..9f2ffe4c2 100644 --- a/cubed/tests/test_core.py +++ b/cubed/tests/test_core.py @@ -190,7 +190,13 @@ def test_to_zarr_array(tmp_path, spec, executor): def test_to_zarr_region(tmp_path, spec, executor): a = xp.asarray( - [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]], + [ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9, 10, 11, 12], + [13, 14, 15, 16], + [17, 18, 19, 20], + ], chunks=(2, 2), spec=spec, ) @@ -272,6 +278,22 @@ def test_to_zarr_region(tmp_path, spec, executor): ), ) + region = (slice(None), slice(4, 5)) + cubed.to_zarr(a[:, 0:1], z, region=region, executor=executor) + res = open_storage_array(store, mode="r") + assert_array_equal( + res[:], + np.array( + [ + [1, 2, 0, 0, 1], + [5, 6, 0, 0, 5], + [1, 2, 1, 2, 9], + [5, 6, 5, 6, 13], + [0, 0, 9, 10, 17], + ] + ), + ) + def test_to_zarr_region_fails(tmp_path): a = xp.ones((4, 4), chunks=(2, 2))