Skip to content

Commit

Permalink
Handle xarray zarr backend decoding logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
sharkinsspatial committed Feb 20, 2025
1 parent ddd9622 commit e350cb1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
9 changes: 7 additions & 2 deletions virtualizarr/readers/hdf/hdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import numpy as np
import xarray as xr
from xarray.backends.zarr import FillValueCoder

from virtualizarr.manifests import (
ChunkEntry,
Expand Down Expand Up @@ -48,7 +49,6 @@
complex,
str,
np.integer,
np.nan,
np.floating,
np.bool_,
np.complexfloating,
Expand Down Expand Up @@ -248,11 +248,16 @@ def _extract_cf_fill_value(
fillvalue = None
for n, v in h5obj.attrs.items():
if n == "_FillValue":
# Extract scalar _FillValue
if isinstance(v, np.ndarray) and v.size == 1:
fillvalue = v.item()
else:
fillvalue = v
if (
fillvalue is not None
and h5obj.dtype.kind not in "S"
and h5obj.dtype.fields is None
):
fillvalue = FillValueCoder.encode(fillvalue, h5obj.dtype)
return fillvalue

@staticmethod
Expand Down
40 changes: 26 additions & 14 deletions virtualizarr/tests/test_readers/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,35 +354,47 @@ def scalar_fill_value_hdf5_file(tmpdir):
return filepath


compound_dtype = np.dtype(
[
("id", "i4"), # 4-byte integer
("temperature", "f4"), # 4-byte float
]
)

compound_data = np.array(
[
(1, 98.6),
(2, 101.3),
],
dtype=compound_dtype,
)

compound_fill = (-9999, -9999.0)

fill_values = [
-9999, # Integer fill value
-9999.0, # Floating-point fill value
np.nan, # NaN as fill value
True,
False, # Boolean fill values
"N/A", # String fill value
b"Unknown", # Bytes fill value
1 + 2j, # Complex number fill value
(b"Unknown", -1), # Structured type (Tuple)
{"fill_value": -9999, "data": np.random.randint(0, 10, size=(5))},
{"fill_value": -9999.0, "data": np.random.random(5)},
{"fill_value": np.nan, "data": np.random.random(5)},
{"fill_value": True, "data": np.random.choice([True, False], size=(5))},
{"fill_value": "N/A", "data": np.array(["one", "two"], dtype="S")},
{"fill_value": compound_fill, "data": compound_data},
]


@pytest.fixture(params=fill_values)
def cf_fill_value_hdf5_file(tmpdir, request):
filepath = f"{tmpdir}/cf_fill_value.nc"
f = h5py.File(filepath, "w")
data = np.random.randint(0, 10, size=(5))
dset = f.create_dataset(name="data", data=data, chunks=True)
if request.param is not None:
dset.attrs["_FillValue"] = request.param
dset = f.create_dataset(name="data", data=request.param["data"], chunks=True)
dset.attrs["_FillValue"] = request.param["fill_value"]
return filepath


@pytest.fixture
def cf_array_fill_value_hdf5_file(tmpdir):
filepath = f"{tmpdir}/cf_array_fill_value.nc"
f = h5py.File(filepath, "w")
data = np.random.randint(0, 10, size=(5))
data = np.random.random(5)
dset = f.create_dataset(name="data", data=data, chunks=True)
dset.attrs["_FillValue"] = np.array([np.nan])
return filepath

0 comments on commit e350cb1

Please sign in to comment.