-
Notifications
You must be signed in to change notification settings - Fork 102
Add wrappers for zarr v3 #524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 54 commits
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
4f7c12c
import zarr-python#1839
normanrz f6d2652
pep8
normanrz 9593c43
remove try/catch
normanrz 2dc9281
pep8
normanrz 1822576
update to latest zarr-python interfaces
normanrz 636624b
Merge remote-tracking branch 'origin/main' into zarr3-codecs
normanrz 8ba9da7
flake
normanrz 3459871
add zarr-python to ci
normanrz 8e10124
fix import
normanrz 14807a5
tests
normanrz 9932a1d
fixes
normanrz 2a12c40
skip zarr3 tests on older python versions
normanrz 92f247d
merge
normanrz cd49cf7
ruff
normanrz 5083d66
add zfpy and pcodec
normanrz 64e081a
Merge remote-tracking branch 'origin/main' into zarr3-codecs
normanrz 7a40530
remove zarr from dependencies
normanrz 2654737
change prefix
normanrz 8c37d5d
fixes for ci
normanrz 37700a5
fix for tests
normanrz c9c8f5e
Merge branch 'main' into zarr3-codecs
normanrz 57fd71b
Merge branch 'main' into zarr3-codecs
normanrz b75e41e
pr feedback
normanrz a4cf7ad
Sync with zarr 3 beta (#597)
mpiannucci 860956f
Update numcodecs/tests/test_zarr3.py
normanrz a62d258
moves zarr3 to private module, adds test for zarr-python2 installs
normanrz 6d8bad2
Merge remote-tracking branch 'origin/main' into zarr3-codecs
normanrz f28775d
add typing_extensions as dep
normanrz 6a8115c
tests
normanrz 82fa7a8
importorskip minversion
normanrz 20aa698
ci install
normanrz bd426e7
Merge remote-tracking branch 'origin/main' into zarr3-codecs
normanrz 0ad1fdf
drop zarr 2 in ci
normanrz 5a956a9
no zarr2 + make zarr3 a public module
normanrz aa3f708
pre-commit
normanrz 8cfce5b
fixes?
normanrz ce6b4b5
fix validate
normanrz 6a795b6
fix pcodec test
normanrz 26a0374
fix pcodec test
normanrz 77f9e05
codecov
normanrz dd8afc5
codecov
normanrz 97bea53
fix error match
normanrz 795c899
codecov
normanrz 0285e22
codecov
normanrz a4ef678
Merge remote-tracking branch 'origin/main' into zarr3-codecs
normanrz da7538e
merge
normanrz bc2e704
coverage
normanrz e31bb2f
wip docs
normanrz b2e18ca
docs and renames all codecs
normanrz c37e7cf
docs
normanrz efcf24f
new zarr beta
normanrz bf9b18e
no zfpy for macos-14
normanrz 73d4dc4
xfail
normanrz 71178b0
rm dead code
normanrz d0f2ab9
Update .github/workflows/ci.yaml
normanrz 5d03a0f
debug rtd
normanrz 9f55819
debug ci
normanrz a774df7
Merge branch 'main' into zarr3-codecs
dstansby 9ea916f
Filter warnings in zarr3 tests
dstansby 96747f4
Fix warning ignore
dstansby f39b32d
Merge remote-tracking branch 'origin/main' into zarr3-codecs
normanrz 153d340
pr feedback
normanrz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,3 +10,4 @@ API reference | |
checksum32 | ||
abc | ||
registry | ||
zarr3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
Zarr 3 codecs | ||
============= | ||
.. automodule:: numcodecs.zarr3 | ||
|
||
|
||
Bytes-to-bytes codecs | ||
--------------------- | ||
.. autoclass:: Blosc() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: LZ4() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: Zstd() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: Zlib() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: GZip() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: BZ2() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: LZMA() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: Shuffle() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
|
||
Array-to-array codecs | ||
--------------------- | ||
.. autoclass:: Delta() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: BitRound() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: FixedScaleOffset() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: Quantize() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: PackBits() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: AsType() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
|
||
Bytes-to-bytes checksum codecs | ||
------------------------------ | ||
.. autoclass:: CRC32() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: CRC32C() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: Adler32() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: Fletcher32() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: JenkinsLookup3() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
|
||
Array-to-bytes codecs | ||
--------------------- | ||
.. autoclass:: PCodec() | ||
|
||
.. autoattribute:: codec_name | ||
|
||
.. autoclass:: ZFPY() | ||
|
||
.. autoattribute:: codec_name |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
from __future__ import annotations | ||
|
||
import numpy as np | ||
import pytest | ||
|
||
import numcodecs.zarr3 | ||
|
||
zarr = pytest.importorskip("zarr") | ||
|
||
pytestmark = pytest.mark.skipif( | ||
zarr.__version__ < "3.0.0", reason="zarr 3.0.0 or later is required" | ||
) | ||
|
||
get_codec_class = zarr.registry.get_codec_class | ||
Array = zarr.Array | ||
JSON = zarr.core.common.JSON | ||
BytesCodec = zarr.codecs.BytesCodec | ||
Store = zarr.abc.store.Store | ||
MemoryStore = zarr.storage.MemoryStore | ||
StorePath = zarr.storage.StorePath | ||
|
||
|
||
EXPECTED_WARNING_STR = "Numcodecs codecs are not in the Zarr version 3.*" | ||
|
||
|
||
@pytest.fixture | ||
def store() -> Store: | ||
return StorePath(MemoryStore(mode="w")) | ||
|
||
|
||
ALL_CODECS = [getattr(numcodecs.zarr3, cls_name) for cls_name in numcodecs.zarr3.__all__] | ||
|
||
|
||
@pytest.mark.parametrize("codec_class", ALL_CODECS) | ||
def test_entry_points(codec_class: type[numcodecs.zarr3._NumcodecsCodec]): | ||
codec_name = codec_class.codec_name | ||
assert get_codec_class(codec_name) == codec_class | ||
|
||
|
||
@pytest.mark.parametrize("codec_class", ALL_CODECS) | ||
def test_docstring(codec_class: type[numcodecs.zarr3._NumcodecsCodec]): | ||
assert "See :class:`numcodecs." in codec_class.__doc__ | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"codec_class", | ||
[ | ||
numcodecs.zarr3.Blosc, | ||
numcodecs.zarr3.LZ4, | ||
numcodecs.zarr3.Zstd, | ||
numcodecs.zarr3.Zlib, | ||
numcodecs.zarr3.GZip, | ||
numcodecs.zarr3.BZ2, | ||
numcodecs.zarr3.LZMA, | ||
numcodecs.zarr3.Shuffle, | ||
], | ||
) | ||
def test_generic_codec_class(store: Store, codec_class: type[numcodecs.zarr3._NumcodecsCodec]): | ||
data = np.arange(0, 256, dtype="uint16").reshape((16, 16)) | ||
|
||
with pytest.warns(UserWarning, match=EXPECTED_WARNING_STR): | ||
a = Array.create( | ||
store / "generic", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype=data.dtype, | ||
fill_value=0, | ||
codecs=[BytesCodec(), codec_class()], | ||
) | ||
|
||
a[:, :] = data.copy() | ||
np.testing.assert_array_equal(data, a[:, :]) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
("codec_class", "codec_config"), | ||
[ | ||
(numcodecs.zarr3.Delta, {"dtype": "float32"}), | ||
(numcodecs.zarr3.FixedScaleOffset, {"offset": 0, "scale": 25.5}), | ||
(numcodecs.zarr3.FixedScaleOffset, {"offset": 0, "scale": 51, "astype": "uint16"}), | ||
(numcodecs.zarr3.AsType, {"encode_dtype": "float32", "decode_dtype": "float64"}), | ||
], | ||
ids=[ | ||
"delta", | ||
"fixedscaleoffset", | ||
"fixedscaleoffset2", | ||
"astype", | ||
], | ||
) | ||
def test_generic_filter( | ||
store: Store, codec_class: type[numcodecs.zarr3._NumcodecsCodec], codec_config: dict[str, JSON] | ||
): | ||
data = np.linspace(0, 10, 256, dtype="float32").reshape((16, 16)) | ||
|
||
with pytest.warns(UserWarning, match=EXPECTED_WARNING_STR): | ||
a = Array.create( | ||
store / "generic", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype=data.dtype, | ||
fill_value=0, | ||
codecs=[ | ||
codec_class(**codec_config), | ||
BytesCodec(), | ||
], | ||
) | ||
|
||
a[:, :] = data.copy() | ||
a = Array.open(store / "generic") | ||
np.testing.assert_array_equal(data, a[:, :]) | ||
|
||
|
||
def test_generic_filter_bitround(store: Store): | ||
data = np.linspace(0, 1, 256, dtype="float32").reshape((16, 16)) | ||
|
||
with pytest.warns(UserWarning, match=EXPECTED_WARNING_STR): | ||
a = Array.create( | ||
store / "generic_bitround", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype=data.dtype, | ||
fill_value=0, | ||
codecs=[numcodecs.zarr3.BitRound(keepbits=3), BytesCodec()], | ||
) | ||
|
||
a[:, :] = data.copy() | ||
a = Array.open(store / "generic_bitround") | ||
assert np.allclose(data, a[:, :], atol=0.1) | ||
|
||
|
||
def test_generic_filter_quantize(store: Store): | ||
data = np.linspace(0, 10, 256, dtype="float32").reshape((16, 16)) | ||
|
||
with pytest.warns(UserWarning, match=EXPECTED_WARNING_STR): | ||
a = Array.create( | ||
store / "generic_quantize", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype=data.dtype, | ||
fill_value=0, | ||
codecs=[numcodecs.zarr3.Quantize(digits=3), BytesCodec()], | ||
) | ||
|
||
a[:, :] = data.copy() | ||
a = Array.open(store / "generic_quantize") | ||
assert np.allclose(data, a[:, :], atol=0.001) | ||
|
||
|
||
def test_generic_filter_packbits(store: Store): | ||
data = np.zeros((16, 16), dtype="bool") | ||
data[0:4, :] = True | ||
|
||
with pytest.warns(UserWarning, match=EXPECTED_WARNING_STR): | ||
a = Array.create( | ||
store / "generic_packbits", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype=data.dtype, | ||
fill_value=0, | ||
codecs=[numcodecs.zarr3.PackBits(), BytesCodec()], | ||
) | ||
|
||
a[:, :] = data.copy() | ||
a = Array.open(store / "generic_packbits") | ||
np.testing.assert_array_equal(data, a[:, :]) | ||
|
||
with pytest.raises(ValueError, match=".*requires bool dtype.*"): | ||
Array.create( | ||
store / "generic_packbits_err", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype="uint32", | ||
fill_value=0, | ||
codecs=[numcodecs.zarr3.PackBits(), BytesCodec()], | ||
) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"codec_class", | ||
[ | ||
numcodecs.zarr3.CRC32, | ||
numcodecs.zarr3.CRC32C, | ||
numcodecs.zarr3.Adler32, | ||
numcodecs.zarr3.Fletcher32, | ||
numcodecs.zarr3.JenkinsLookup3, | ||
], | ||
) | ||
def test_generic_checksum(store: Store, codec_class: type[numcodecs.zarr3._NumcodecsCodec]): | ||
data = np.linspace(0, 10, 256, dtype="float32").reshape((16, 16)) | ||
|
||
with pytest.warns(UserWarning, match=EXPECTED_WARNING_STR): | ||
a = Array.create( | ||
store / "generic_checksum", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype=data.dtype, | ||
fill_value=0, | ||
codecs=[BytesCodec(), codec_class()], | ||
) | ||
|
||
a[:, :] = data.copy() | ||
a = Array.open(store / "generic_checksum") | ||
np.testing.assert_array_equal(data, a[:, :]) | ||
|
||
|
||
@pytest.mark.parametrize("codec_class", [numcodecs.zarr3.PCodec, numcodecs.zarr3.ZFPY]) | ||
def test_generic_bytes_codec(store: Store, codec_class: type[numcodecs.zarr3._NumcodecsCodec]): | ||
try: | ||
codec_class()._codec # noqa: B018 | ||
except ValueError as e: | ||
if "codec not available" in str(e): | ||
pytest.xfail(f"{codec_class.codec_name} is not available: {e}") | ||
else: | ||
raise # pragma: no cover | ||
except ImportError as e: | ||
pytest.xfail(f"{codec_class.codec_name} is not available: {e}") | ||
|
||
data = np.arange(0, 256, dtype="float32").reshape((16, 16)) | ||
|
||
with pytest.warns(UserWarning, match=EXPECTED_WARNING_STR): | ||
a = Array.create( | ||
store / "generic", | ||
shape=data.shape, | ||
chunk_shape=(16, 16), | ||
dtype=data.dtype, | ||
fill_value=0, | ||
codecs=[ | ||
codec_class(), | ||
], | ||
) | ||
|
||
a[:, :] = data.copy() | ||
np.testing.assert_array_equal(data, a[:, :]) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from __future__ import annotations | ||
|
||
import pytest | ||
|
||
|
||
def test_zarr3_import(): | ||
ERROR_MESSAGE_MATCH = "zarr 3.0.0 or later.*" | ||
|
||
try: | ||
import zarr # noqa: F401 | ||
except ImportError: # pragma: no cover | ||
with pytest.raises(ImportError, match=ERROR_MESSAGE_MATCH): | ||
import numcodecs.zarr3 # noqa: F401 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.