Skip to content

Commit 32b70f3

Browse files
added example with bounds -- fixed assign_ugrid_topology
1 parent ca5b65a commit 32b70f3

File tree

5 files changed

+50
-16
lines changed

5 files changed

+50
-16
lines changed
216 KB
Binary file not shown.

pixi.lock

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[build-system]
2-
requires = ["setuptools>=61", "wheel", "setuptools_scm[toml]>=6.2"]
2+
requires = ["setuptools>=72", "wheel", "setuptools_scm[toml]>=8.0"]
33
build-backend = "setuptools.build_meta"
44

55
[project]
@@ -8,7 +8,7 @@ authors = [
88
{ name = "Matthew Iannucci", email = "[email protected]" },
99
{ name = "Christopher H. Barker", email = "[email protected]" },
1010
]
11-
description = "Subset Xarray datasets in space"
11+
description = "Subset Xarray datasets in time and space"
1212
readme = "README.md"
1313
requires-python = ">=3.10"
1414
keywords = ["xarray"]
@@ -31,7 +31,7 @@ dynamic = ["version"]
3131

3232
dependencies = [
3333
"numpy",
34-
"xarray>=2023.10.0",
34+
"xarray>=2024.6",
3535
"cf_xarray",
3636
"cftime",
3737
"dask[complete]",
@@ -99,7 +99,7 @@ default = { solve-group = "default" }
9999
dev = { features = ["dev"], solve-group = "default" }
100100
examples = { features = ["examples"], solve-group = "default" }
101101
all = { features = ["dev", "examples"], solve-group = "default" }
102-
test310 = ["dev", "py310"] # implicit: test310 = ["dev", "py310", "default"]
102+
test310 = ["dev", "py310"] # implicit: test310 = ["dev", "py310", "default"]
103103
test311 = ["dev", "py311"]
104104
test312 = ["dev", "py312"]
105105

@@ -109,8 +109,8 @@ test312 = ["dev", "py312"]
109109
[tool.pixi.dependencies]
110110
python = ">=3.10"
111111
numpy = "*"
112-
xarray = ">=2023.10.0"
113-
pandas = ">=2.2.2"
112+
xarray = ">=2024.6"
113+
pandas = "*"
114114
cf_xarray = "*"
115115
dask = "*"
116116
fsspec = "*"

tests/test_grids/test_ugrid.py

+37-3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
lonc:standard_name = "longitude" ;
5050
lonc:long_name = "zonal longitude" ;
5151
lonc:units = "degree_east" ;
52+
5253
float latc(nele) ;
5354
latc:standard_name = "latitude" ;
5455
latc:long_name = "zonal latitude" ;
@@ -60,7 +61,7 @@
6061
6162
face_face_connectivity:
6263
int nbe(three, nele) ;
63-
nbe:long_name = "elements surrounding anch element" ;
64+
nbe:long_name = "elements surrounding each element" ;
6465
6566
The depth coordinates (xarray is not sure what to do with these ...)
6667
@@ -87,10 +88,8 @@
8788
time:format = "defined reference date" ;
8889
time:time_zone = "UTC" ;
8990
90-
9191
Data on the grid:
9292
93-
9493
float h(node) ;
9594
h:standard_name = "sea_floor_depth_below_geoid" ;
9695
h:long_name = "Bathymetry" ;
@@ -265,7 +264,11 @@ def test_assign_ugrid_topology_min():
265264
assert mesh["face_coordinates"] == "lonc latc"
266265
assert mesh["face_face_connectivity"] == "nbe"
267266
assert mesh["face_dimension"] == "nele"
267+
assert mesh["start_index"] == 1
268268

269+
# There should be no empty attributes
270+
for key, val in mesh.items():
271+
assert val
269272

270273
def test_assign_ugrid_topology_dict():
271274
"""
@@ -292,6 +295,36 @@ def test_assign_ugrid_topology_dict():
292295
assert mesh["face_face_connectivity"] == "nbe"
293296
assert mesh["face_dimension"] == "nele"
294297

298+
def test_assign_ugrid_topology_no_face_coords():
299+
"""
300+
test for no face coords
301+
302+
"""
303+
# this example has triangles and bounds -- no face coordinates
304+
ds = xr.open_dataset(EXAMPLE_DATA / "tris_and_bounds.nc")
305+
with pytest.raises(KeyError):
306+
ds["mesh"]
307+
308+
ds = ugrid.assign_ugrid_topology(ds, face_node_connectivity='tris',
309+
node_coordinates = ('lon lat'),
310+
boundary_node_connectivity = 'bounds'
311+
)
312+
313+
# there are others, but these are the ones that really matter.
314+
mesh = ds["mesh"].attrs
315+
assert mesh["cf_role"] == "mesh_topology"
316+
assert mesh["node_coordinates"] == "lon lat"
317+
assert mesh["face_node_connectivity"] == "tris"
318+
assert mesh["face_dimension"] == "tris"
319+
320+
assert mesh.keys() == {'cf_role',
321+
'topology_dimension',
322+
'face_node_connectivity',
323+
'boundary_node_connectivity',
324+
'node_coordinates',
325+
'face_dimension',
326+
'start_index',
327+
}
295328

296329
def test_assign_ugrid_topology_existing_mesh_var():
297330
"""
@@ -351,6 +384,7 @@ def test_assign_ugrid_topology_start_index_zero_infer():
351384
assert ds["mesh_boundary_nodes"].attrs["start_index"] == 0
352385

353386

387+
354388
# NOTE: these tests are probably not complete -- but they are something.
355389
# we really should have a complete UGRID example to test with.
356390
def test_grid_vars():

xarray_subset_grid/grids/ugrid.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -413,12 +413,11 @@ def assign_ugrid_topology(
413413
raise ValueError(
414414
"face_node_connectivity is a required parameter if it is not in the mesh_topology variable" # noqa: E501
415415
)
416-
417416
if mesh.face_coordinates is None:
418417
try:
419-
mesh.face_coordinates = ds[mesh.face_node_connectivity].cf.coordinates
418+
face_coordinates = ds[mesh.face_node_connectivity].cf.coordinates
420419
mesh.face_coordinates = " ".join(f"{coord[0]}"
421-
for coord in mesh.face_coordinates.values())
420+
for coord in face_coordinates.values())
422421
except AttributeError:
423422
mesh.face_coordinates = None
424423

@@ -487,7 +486,8 @@ def assign_ugrid_topology(
487486

488487
# push the non-None mesh attributes back into the variable
489488
for key, val in mesh.__dict__.items():
490-
if val is not None:
489+
# can't use truthiness, as 0 is false
490+
if not ((val is None) or (val == "")):
491491
mesh_attrs[key] = val
492492

493493
return ds

0 commit comments

Comments
 (0)