Skip to content

Commit

Permalink
Merge pull request #99 from silx-kit/bool
Browse files Browse the repository at this point in the history
Fix fetching boolean data as binary
  • Loading branch information
axelboc authored Sep 9, 2024
2 parents 55f9fdf + d0bd0b7 commit fb73f41
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 deletions.
20 changes: 8 additions & 12 deletions h5grove/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,25 +208,21 @@ def get_type_metadata(type_id: h5py.h5t.TypeID) -> TypeMetadata:


def _sanitize_dtype(dtype: np.dtype) -> np.dtype:
"""Sanitize numpy dtype to one with a matching typed array in modern JavaScript.
:raises ValueError: If trying to sanitize a non-numeric numpy dtype
"""
if dtype.kind not in ("f", "i", "u"):
raise ValueError(f"Unsupported numpy dtype `{dtype}`. Expected numeric dtype.")

# Convert to little endian
result = dtype.newbyteorder("<")
"""Sanitize numpy dtype to one with a matching typed array in modern JavaScript."""

# Convert float16 to float32
if result.kind == "f" and result.itemsize < 4:
if dtype.kind == "f" and dtype.itemsize < 4:
return np.dtype("<f4")

# Convert float128 to float64 (unavoidable loss of precision)
if result.kind == "f" and result.itemsize > 8:
if dtype.kind == "f" and dtype.itemsize > 8:
return np.dtype("<f8")

return result
# Convert native and big-endian byte-orders to little-endian
if dtype.byteorder == "=" or dtype.byteorder == ">":
return dtype.newbyteorder("<")

return dtype


T = TypeVar("T", np.ndarray, np.number, np.bool_)
Expand Down
21 changes: 21 additions & 0 deletions test/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,27 @@ def test_data_on_slice_with_format_and_flatten(self, server, format_arg):

assert retrieved_data - data[100, 0] < 1e-8

def test_data_on_bool(self, server):
"""Test /data/ endpoint on boolean dataset with format=bin"""
tested_h5entity_path = "/bool"
data = np.array([True, False, True, True])

filename = "test.h5"
with h5py.File(server.served_directory / filename, mode="w") as h5file:
dset = h5file.create_dataset(tested_h5entity_path, data=data)
dtype = dset.dtype
shape = dset.shape

response = server.get(
f"/data/?{urlencode({'file': filename, 'path': tested_h5entity_path, 'format': 'bin'})}"
)

content_type = response.find_header_value("content-type")
assert content_type == "application/octet-stream"

retrieved_data = decode_array_response(response, "bin", dtype.str, shape)
assert np.array_equal(retrieved_data, data)

def test_data_on_opaque(self, server):
"""Test /data/ endpoint on opaque dataset with format=bin"""
tested_h5entity_path = "/opaque"
Expand Down

0 comments on commit fb73f41

Please sign in to comment.