numcodecs-combinators 0.2.8__tar.gz → 0.2.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/PKG-INFO +1 -1
- numcodecs_combinators-0.2.9/_typos.toml +2 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/pyproject.toml +1 -1
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/abc.py +2 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/stack.py +39 -6
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/tests/test_stack.py +34 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/.github/workflows/ci.yml +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/.github/workflows/publish.yml +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/.gitignore +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/.python-version +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/.readthedocs.yaml +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/LICENSE +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/README.md +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/docs/index.md +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/docs/requirements.txt +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/mkdocs.yml +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/__init__.py +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/best.py +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/framed.py +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/py.typed +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/tests/test_best.py +0 -0
- {numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/tests/test_framed.py +0 -0
{numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/stack.py
RENAMED
|
@@ -140,6 +140,8 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
|
|
|
140
140
|
buffer protocol.
|
|
141
141
|
"""
|
|
142
142
|
|
|
143
|
+
chunked = getattr(buf, "chunked", False)
|
|
144
|
+
|
|
143
145
|
encoded = np.asarray(
|
|
144
146
|
numcodecs.compat.ensure_contiguous_ndarray_like(buf, flatten=False)
|
|
145
147
|
)
|
|
@@ -149,16 +151,23 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
|
|
|
149
151
|
silhouettes.append((encoded.shape, encoded.dtype))
|
|
150
152
|
encoded = np.asarray(
|
|
151
153
|
numcodecs.compat.ensure_contiguous_ndarray_like(
|
|
152
|
-
codec.encode((encoded)),
|
|
154
|
+
codec.encode(_MaybeChunkedNdArray(encoded) if chunked else encoded),
|
|
155
|
+
flatten=False,
|
|
153
156
|
)
|
|
154
157
|
)
|
|
155
158
|
|
|
156
|
-
decoded = encoded
|
|
159
|
+
decoded = encoded.view(np.ndarray)
|
|
157
160
|
|
|
158
161
|
for codec in reversed(self):
|
|
159
162
|
shape, dtype = silhouettes.pop()
|
|
160
163
|
out = np.empty(shape=shape, dtype=dtype)
|
|
161
|
-
decoded =
|
|
164
|
+
decoded = (
|
|
165
|
+
codec.decode(decoded, _MaybeChunkedNdArray(out) if chunked else out)
|
|
166
|
+
.view(dtype)
|
|
167
|
+
.reshape(shape)
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
decoded = decoded.view(np.ndarray)
|
|
162
171
|
|
|
163
172
|
if isinstance(decoded, type(buf)):
|
|
164
173
|
return decoded
|
|
@@ -167,7 +176,8 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
|
|
|
167
176
|
|
|
168
177
|
def encode_decode_data_array(self, da: "xr.DataArray") -> "xr.DataArray":
|
|
169
178
|
"""
|
|
170
|
-
Encode, then decode
|
|
179
|
+
Encode, then decode the data array `da`. If `da` is chunked, each chunk
|
|
180
|
+
is encoded and decoded *independently*.
|
|
171
181
|
|
|
172
182
|
Since each chunk is encoded *independently*, this method may cause
|
|
173
183
|
chunk boundary artifacts. Do *not* use this method if the codec
|
|
@@ -195,6 +205,8 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
|
|
|
195
205
|
|
|
196
206
|
import xarray as xr
|
|
197
207
|
|
|
208
|
+
chunked = da.chunks is not None
|
|
209
|
+
|
|
198
210
|
def encode_decode_data_array_single_chunk(
|
|
199
211
|
da: xr.DataArray,
|
|
200
212
|
) -> xr.DataArray:
|
|
@@ -205,9 +217,11 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
|
|
|
205
217
|
return da.copy(deep=False).chunk(single_chunk)
|
|
206
218
|
|
|
207
219
|
# eagerly compute the input chunk and encode and decode it
|
|
208
|
-
decoded = self.encode_decode(da.values) # type: ignore
|
|
220
|
+
decoded = self.encode_decode(_MaybeChunkedNdArray(da.values, chunked)) # type: ignore
|
|
209
221
|
|
|
210
|
-
return da.copy(deep=False, data=decoded).chunk(
|
|
222
|
+
return da.copy(deep=False, data=np.array(decoded).view(np.ndarray)).chunk(
|
|
223
|
+
single_chunk
|
|
224
|
+
)
|
|
211
225
|
|
|
212
226
|
return xr.map_blocks(encode_decode_data_array_single_chunk, da)
|
|
213
227
|
|
|
@@ -293,3 +307,22 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
|
|
|
293
307
|
|
|
294
308
|
|
|
295
309
|
numcodecs.registry.register_codec(CodecStack)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
class _MaybeChunkedNdArray(np.ndarray):
|
|
313
|
+
__slots__ = ("_chunked",)
|
|
314
|
+
_chunked: bool
|
|
315
|
+
|
|
316
|
+
def __new__(cls, array, chunked: bool = True):
|
|
317
|
+
obj = np.asarray(array).view(cls)
|
|
318
|
+
obj._chunked = chunked
|
|
319
|
+
return obj
|
|
320
|
+
|
|
321
|
+
def __array_finalize__(self, obj):
|
|
322
|
+
if obj is None:
|
|
323
|
+
return
|
|
324
|
+
self._chunked = getattr(obj, "chunked", True)
|
|
325
|
+
|
|
326
|
+
@property
|
|
327
|
+
def chunked(self) -> bool:
|
|
328
|
+
return self._chunked
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import numcodecs
|
|
2
2
|
import numpy as np
|
|
3
3
|
import xarray as xr
|
|
4
|
+
from numcodecs.abc import Codec
|
|
4
5
|
|
|
5
6
|
import numcodecs_combinators
|
|
6
7
|
from numcodecs_combinators.stack import CodecStack
|
|
@@ -51,6 +52,39 @@ def test_encode_decode():
|
|
|
51
52
|
assert encoded_decoded.equals(xr.DataArray([1.0, 2.0, 3.0]))
|
|
52
53
|
|
|
53
54
|
|
|
55
|
+
def test_chunked_encode_decode():
|
|
56
|
+
class CheckChunkedCodec(Codec):
|
|
57
|
+
__slots__ = ("is_chunked",)
|
|
58
|
+
is_chunked: bool
|
|
59
|
+
|
|
60
|
+
def __init__(self, is_chunked: bool):
|
|
61
|
+
self.is_chunked = is_chunked
|
|
62
|
+
|
|
63
|
+
def encode(self, buf):
|
|
64
|
+
assert getattr(buf, "chunked", False) == self.is_chunked
|
|
65
|
+
return buf
|
|
66
|
+
|
|
67
|
+
def decode(self, buf, out=None):
|
|
68
|
+
assert getattr(buf, "chunked", False) is False
|
|
69
|
+
assert getattr(out, "chunked", False) == self.is_chunked
|
|
70
|
+
return numcodecs.compat.ndarray_copy(buf, out)
|
|
71
|
+
|
|
72
|
+
stack = CodecStack(CheckChunkedCodec(False))
|
|
73
|
+
|
|
74
|
+
encoded_decoded = stack.encode_decode(np.array([1.0, 2.0, 3.0]))
|
|
75
|
+
assert np.all(encoded_decoded == np.array([1.0, 2.0, 3.0]))
|
|
76
|
+
|
|
77
|
+
encoded_decoded = stack.encode_decode_data_array(xr.DataArray([1.0, 2.0, 3.0]))
|
|
78
|
+
assert encoded_decoded.equals(xr.DataArray([1.0, 2.0, 3.0]))
|
|
79
|
+
|
|
80
|
+
stack = CodecStack(CheckChunkedCodec(True))
|
|
81
|
+
|
|
82
|
+
encoded_decoded = stack.encode_decode_data_array(
|
|
83
|
+
xr.DataArray([1.0, 2.0, 3.0]).chunk(1)
|
|
84
|
+
)
|
|
85
|
+
assert encoded_decoded.equals(xr.DataArray([1.0, 2.0, 3.0]))
|
|
86
|
+
|
|
87
|
+
|
|
54
88
|
def test_map():
|
|
55
89
|
stack = CodecStack(numcodecs.Zlib(level=9), numcodecs.CRC32())
|
|
56
90
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/__init__.py
RENAMED
|
File without changes
|
{numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/best.py
RENAMED
|
File without changes
|
{numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/framed.py
RENAMED
|
File without changes
|
{numcodecs_combinators-0.2.8 → numcodecs_combinators-0.2.9}/src/numcodecs_combinators/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|