Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions tests/io/test_odim.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,186 @@ def test_get_azimuth_where(nrays):
assert udiff[0] == 360.0 / nrays


def test_odim_azimuth_nominal(odim_file):
import xarray as xr

ds = xr.open_dataset(
odim_file, engine="odim", angle_spec="nominal", group="sweep_0"
)

azimuth = ds.azimuth.values
udiff = np.unique(np.diff(azimuth))
assert len(azimuth) == 360
assert len(udiff) == 1
assert udiff[0] == 1.0


def test_odim_azimuth_auto(odim_file):
import xarray as xr

ds = xr.open_dataset(odim_file, engine="odim", angle_spec="auto", group="sweep_0")

azimuth = ds.azimuth.values
udiff = np.unique(np.diff(azimuth))
assert len(azimuth) == 360
assert len(udiff) == 1
assert udiff[0] == 1.0


def test_odim_azimuth_reindex_deprecation(odim_file):
import xarray as xr

with pytest.warns(
DeprecationWarning, match="The 'reindex_angle' kwarg is deprecated"
):
ds = xr.open_dataset(
odim_file, engine="odim", reindex_angle=False, group="sweep_0"
)
azimuth = ds.azimuth.values
udiff = np.unique(np.diff(azimuth))
assert len(azimuth) == 360
assert len(udiff) == 1
assert udiff[0] == 1.0


def test_odim_azimuth_raw(odim_file):
import xarray as xr

ds = xr.open_dataset(odim_file, engine="odim", group="sweep_0", angle_spec="raw")
azimuth = ds.azimuth.values
assert len(azimuth) == 360
# raw should still give uniform spacing for this file
udiff = np.unique(np.diff(azimuth))
assert len(udiff) == 1
assert udiff[0] == 1.0


@pytest.mark.parametrize("angle_spec", ["nominal", "auto", "raw"])
def test_odim_azimuth_nonstandard_nrays(tmp_path, angle_spec):
import h5netcdf

nrays = 361
ascale = 360.0 / nrays

startazA = np.arange(0, 360, ascale, dtype=np.float32)
stopazA = np.arange(ascale, 360 + ascale, ascale, dtype=np.float32)

filepath = tmp_path / "test_nonstandard.h5"
with h5netcdf.File(filepath, "w") as f:
f.attrs["Conventions"] = "ODIM_H5/V2_2"
wg = f.create_group("where")
wg.attrs["lon"] = 0.0
wg.attrs["lat"] = 0.0
wg.attrs["height"] = 0.0
dg = f.create_group("dataset1")
dw = dg.create_group("where")
dw.attrs["nrays"] = nrays
dw.attrs["nbins"] = 100
dw.attrs["rstart"] = 0.0
dw.attrs["rscale"] = 100.0
dw.attrs["elangle"] = 0.5
dw.attrs["a1gate"] = 0
dh = dg.create_group("how")
dh.attrs["startazA"] = startazA
dh.attrs["stopazA"] = stopazA
dh.attrs["startazT"] = np.zeros(nrays, dtype=np.float64)
dh.attrs["stopazT"] = np.ones(nrays, dtype=np.float64)
dwhat = dg.create_group("what")
dwhat.attrs["quantity"] = "DBZH"
dwhat.attrs["startdate"] = "20000101"
dwhat.attrs["starttime"] = "000000"
dwhat.attrs["enddate"] = "20000101"
dwhat.attrs["endtime"] = "000030"
dg.create_group("data1")

import xarray as xr

if angle_spec == "nominal":
context = pytest.raises(ValueError, match="Unexpected number of rays")
elif angle_spec == "auto":
context = pytest.warns(RuntimeWarning, match="Unexpected number of rays")
wanted = np.arange(0.5, 360, 1.0)
else:
context = nullcontext()
# should match per-ray midpoint
wanted = (startazA + np.where(stopazA < startazA, stopazA + 360, stopazA)) / 2
wanted[wanted >= 360] -= 360

with context:
ds = xr.open_dataset(
filepath, engine="odim", angle_spec=angle_spec, group="sweep_0"
)

if angle_spec != "nominal":
azimuth = ds.azimuth.values
assert len(azimuth) == 360 if angle_spec == "auto" else nrays
np.testing.assert_array_almost_equal(azimuth, wanted, decimal=4)


@pytest.mark.parametrize("angle_spec", ["nominal", "auto", "raw"])
def test_odim_azimuth_fallback_nonstandard_nrays_with_duplicate(tmp_path, angle_spec):
import h5netcdf

nrays = 361
startazA = create_startazA(nrays)
stopazA = create_stopazA(nrays)

filepath = tmp_path / "test_nonstandard_dup.h5"
with h5netcdf.File(filepath, "w") as f:
f.attrs["Conventions"] = "ODIM_H5/V2_2"
wg = f.create_group("where")
wg.attrs["lon"] = 0.0
wg.attrs["lat"] = 0.0
wg.attrs["height"] = 0.0
dg = f.create_group("dataset1")
dw = dg.create_group("where")
dw.attrs["nrays"] = nrays
dw.attrs["nbins"] = 100
dw.attrs["rstart"] = 0.0
dw.attrs["rscale"] = 100.0
dw.attrs["elangle"] = 0.5
dw.attrs["a1gate"] = 0
dh = dg.create_group("how")
dh.attrs["startazA"] = startazA
dh.attrs["stopazA"] = stopazA
dh.attrs["startazT"] = np.zeros(nrays, dtype=np.float64)
dh.attrs["stopazT"] = np.ones(nrays, dtype=np.float64)
dwhat = dg.create_group("what")
dwhat.attrs["quantity"] = "DBZH"
dwhat.attrs["startdate"] = "20000101"
dwhat.attrs["starttime"] = "000000"
dwhat.attrs["enddate"] = "20000101"
dwhat.attrs["endtime"] = "000030"
dg.create_group("data1")

import xarray as xr

if angle_spec == "nominal":
context = pytest.raises(ValueError, match="Unexpected number of rays")
elif angle_spec == "auto":
context = pytest.warns(RuntimeWarning, match="Unexpected number of rays")
wanted = np.arange(0.5, 360, 1.0)
else:
context = nullcontext()
# should match per-ray midpoint
wanted = (startazA + np.where(stopazA < startazA, stopazA + 360, stopazA)) / 2
wanted[wanted >= 360] -= 360

with context:
ds = xr.open_dataset(
filepath, engine="odim", angle_spec=angle_spec, group="sweep_0"
)

if angle_spec != "nominal":
azimuth = ds.azimuth.values
assert len(azimuth) == 360 if angle_spec == "auto" else nrays
# assert len(azimuth) == nrays
# wanted = (startazA + np.where(stopazA < startazA, stopazA + 360, stopazA)) / 2
# wanted[wanted >= 360] -= 360
print(azimuth)
np.testing.assert_array_almost_equal(azimuth, wanted, decimal=4)


@pytest.mark.parametrize(
"ang",
[("az_angle", "elevation"), ("az_angle", "elevation"), ("elangle", "azimuth")],
Expand Down
Loading
Loading