Skip to content

Commit

Permalink
Merge pull request #401 from DHI/netcdf-3d
Browse files Browse the repository at this point in the history
Support for 3d via xarray (NetCDF etc)
  • Loading branch information
ecomodeller authored Jan 24, 2024
2 parents 5463334 + 9c1d9a0 commit b680af1
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 2 deletions.
9 changes: 7 additions & 2 deletions modelskill/model/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def _extract_point(
given a PointObservation. No time interpolation is done!"""
method: str = spatial_method or "linear"

x, y = observation.x, observation.y
x, y, z = observation.x, observation.y, observation.z
if (x is None) or (y is None):
raise ValueError(
f"PointObservation '{observation.name}' cannot be used for extraction "
Expand All @@ -163,7 +163,12 @@ def _extract_point(
assert isinstance(self.data, xr.Dataset)

# TODO: avoid runtrip to pandas if possible (potential loss of metadata)
ds = self.data.interp(coords=dict(x=x, y=y), method=method) # type: ignore
if "z" in self.data.dims and z is not None:
ds = self.data.interp(
coords=dict(x=x, y=y, z=z), method=method # type: ignore
)
else:
ds = self.data.interp(coords=dict(x=x, y=y), method=method) # type: ignore
# TODO: exclude aux cols in dropna
df = ds.to_dataframe().drop(columns=["x", "y"]).dropna()
if len(df) == 0:
Expand Down
2 changes: 2 additions & 0 deletions modelskill/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"north": "y",
"x": "x",
"y": "y",
"z": "z",
"depth": "z",
}
TIME_COORDINATE_NAME_MAPPING = {
"t": "time",
Expand Down
30 changes: 30 additions & 0 deletions tests/integration/test_integration_grid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import modelskill as ms
import pytest
import xarray as xr

def test_extract_point_from_3d():
mr = ms.GridModelResult(
"tests/testdata/cmems_mod_med_phy-sal_anfc_4.2km-3D_PT1H-m_1705916517624.nc",
item="so",
name="MedSea",
)

point_ds = xr.open_dataset("tests/testdata/aegean_sea_salinity_ts.nc")

# TODO use x,y,z without explicitly setting them (NetCDF has them as coordinates)
obs = ms.PointObservation(
point_ds,
x=float(point_ds.longitude),
y=float(point_ds.latitude),
z=float(point_ds.depth),
item="so",
)

cmp = ms.match(obs=obs, mod=mr, spatial_method="nearest")
assert cmp.quantity.name == "Salinity"
assert cmp.quantity.unit == "0.001"

sc = cmp.score()

# "Observed" data is extracted from the 3D model result, so the score should be 0.0
assert sc["MedSea"] == pytest.approx(0.0)
28 changes: 28 additions & 0 deletions tests/model/test_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,31 @@ def test_grid_with_directional_data_with_cf_metadata_is_directional_by_default()
"tests/testdata/SW/CMEMS_DutchCoast_2017-10-28.nc", item="VMDR"
)
assert mr.quantity.is_directional


def test_extract_point_from_3d():
mr = ms.GridModelResult(
"tests/testdata/cmems_mod_med_phy-sal_anfc_4.2km-3D_PT1H-m_1705916517624.nc",
item="so",
name="MedSea",
)

point_ds = xr.open_dataset("tests/testdata/aegean_sea_salinity_ts.nc")

# TODO use x,y,z without explicitly setting them (NetCDF has them as coordinates)
obs = ms.PointObservation(
point_ds,
x=float(point_ds.longitude),
y=float(point_ds.latitude),
z=float(point_ds.depth),
item="so",
)

cmp = ms.match(obs=obs, mod=mr, spatial_method="nearest")
assert cmp.quantity.name == "Salinity"
assert cmp.quantity.unit == "0.001"

sc = cmp.score()

# "Observed" data is extracted from the 3D model result, so the score should be 0.0
assert sc["MedSea"] == pytest.approx(0.0)
Binary file added tests/testdata/aegean_sea_salinity_ts.nc
Binary file not shown.
Binary file not shown.

0 comments on commit b680af1

Please sign in to comment.