Skip to content

Commit 5da3159

Browse files
committed
add numcodecs.zarr3.to_zarr3 method
1 parent 3438e16 commit 5da3159

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

numcodecs/tests/test_zarr3.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def test_delta_astype(store: StorePath):
260260
dtype=data.dtype,
261261
fill_value=0,
262262
filters=[
263-
numcodecs.zarr3.Delta(dtype="i8", astype="i2"), # type: ignore[arg-type]
263+
numcodecs.Delta(dtype="i8", astype="i2"), # type: ignore[arg-type]
264264
],
265265
)
266266

@@ -277,3 +277,49 @@ def test_repr():
277277
def test_to_dict():
278278
codec = numcodecs.zarr3.LZ4(level=5)
279279
assert codec.to_dict() == {"name": "numcodecs.lz4", "configuration": {"level": 5}}
280+
281+
@pytest.mark.parametrize(("codec_v2", "expected_v3_cls"),[
282+
(numcodecs.BZ2(), numcodecs.zarr3.BZ2),
283+
(numcodecs.CRC32(), numcodecs.zarr3.CRC32),
284+
(numcodecs.CRC32C(), numcodecs.zarr3.CRC32C),
285+
(numcodecs.LZ4(), numcodecs.zarr3.LZ4),
286+
(numcodecs.LZMA(), numcodecs.zarr3.LZMA),
287+
(numcodecs.ZFPY(), numcodecs.zarr3.ZFPY),
288+
(numcodecs.Adler32(), numcodecs.zarr3.Adler32),
289+
(numcodecs.AsType(encode_dtype=np.float64,decode_dtype=np.float32), numcodecs.zarr3.AsType),
290+
(numcodecs.BitRound(keepbits=10), numcodecs.zarr3.BitRound),
291+
(numcodecs.Blosc(), numcodecs.zarr3.Blosc),
292+
(numcodecs.Delta(dtype=np.float64), numcodecs.zarr3.Delta),
293+
(numcodecs.FixedScaleOffset(offset=1000, scale=10, dtype='f8', astype='u1'), numcodecs.zarr3.FixedScaleOffset),
294+
(numcodecs.Fletcher32(), numcodecs.zarr3.Fletcher32),
295+
(numcodecs.GZip(), numcodecs.zarr3.GZip),
296+
(numcodecs.JenkinsLookup3(), numcodecs.zarr3.JenkinsLookup3),
297+
(numcodecs.PCodec(), numcodecs.zarr3.PCodec),
298+
(numcodecs.PackBits(), numcodecs.zarr3.PackBits),
299+
(numcodecs.Quantize(digits=1, dtype='f8'), numcodecs.zarr3.Quantize),
300+
(numcodecs.Shuffle(), numcodecs.zarr3.Shuffle),
301+
(numcodecs.Zlib(), numcodecs.zarr3.Zlib),
302+
(numcodecs.Zstd(), numcodecs.zarr3.Zstd),
303+
])
304+
def test_cast_numcodecs_to_v3(store: Store, codec_v2, expected_v3_cls) -> None:
305+
result_v3 = numcodecs.zarr3.to_zarr3(codec_v2)
306+
307+
assert result_v3.__class__ == expected_v3_cls
308+
assert result_v3.codec_config == codec_v2.get_config()
309+
310+
if issubclass(expected_v3_cls, numcodecs.zarr3._NumcodecsArrayArrayCodec):
311+
codec_args = {"filters": [result_v3]}
312+
elif issubclass(expected_v3_cls, numcodecs.zarr3._NumcodecsArrayBytesCodec):
313+
codec_args = {"serializer": result_v3}
314+
elif issubclass(expected_v3_cls, numcodecs.zarr3._NumcodecsBytesBytesCodec):
315+
codec_args = {"compressors": [result_v3]}
316+
else:
317+
raise TypeError(f"unsupported type: {expected_v3_cls}")
318+
zarr.create_array(
319+
store,
320+
shape=(64,),
321+
chunks=(64,),
322+
dtype=np.bool,
323+
fill_value=0,
324+
**codec_args
325+
)

numcodecs/zarr3.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,18 @@ def evolve_from_array_spec(self, array_spec: ArraySpec) -> AsType:
399399
"Zlib",
400400
"Zstd",
401401
]
402+
403+
def to_zarr3(codec: numcodecs.abc.Codec) -> _NumcodecsBytesBytesCodec | _NumcodecsArrayBytesCodec | _NumcodecsArrayArrayCodec:
404+
"""Convert a numcodecs codec to its zarr3-compatible equivalent."""
405+
codec_name = codec.__class__.__name__
406+
zarr3_module = numcodecs.zarr3
407+
408+
if not hasattr(zarr3_module, codec_name):
409+
raise ValueError(f"No Zarr3 wrapper found for codec: {codec_name}")
410+
411+
zarr3_codec_class = getattr(zarr3_module, codec_name)
412+
413+
config = codec.get_config()
414+
config.pop("id", None)
415+
416+
return zarr3_codec_class(**config)

0 commit comments

Comments
 (0)