Skip to content

Commit 57a4a6c

Browse files
Merge pull request #168 from csiro-coasts/165-connectivity-fill-value-validation
Added additional validation for connectivity checks.
2 parents 0579a7c + 7835307 commit 57a4a6c

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

docs/releases/development.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@
22
Next release (in development)
33
=============================
44

5+
* Added additional validation for ugrid
6+
connectivity(:issue:`165`, :pr:`168`).
57
* Fix datasets hash_key generation when geometry encoding
68
is missing a dtype (:issue:`166`, :pr:`167`).

src/emsarray/conventions/ugrid.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,20 @@ def has_valid_face_edge_connectivity(self) -> bool:
748748
)
749749
return False
750750

751+
if '_FillValue' in data_array.encoding:
752+
fill_value = data_array.encoding['_FillValue']
753+
754+
lower_bound = _get_start_index(data_array)
755+
upper_bound = self.edge_count + lower_bound
756+
757+
if lower_bound <= fill_value <= upper_bound:
758+
warnings.warn(
759+
f"Got a face_edge_connectivity variable {data_array.name!r} with "
760+
f"a _FillValue inside the actual index range",
761+
ConventionViolationWarning,
762+
)
763+
return False
764+
751765
return True
752766

753767
@cached_property

tests/conventions/test_ugrid.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,3 +924,60 @@ def da(attrs: dict) -> xarray.DataArray:
924924

925925
with pytest.raises(ConventionViolationError):
926926
_get_start_index(da({'start_index': 2}))
927+
928+
929+
def test_has_valid_face_edge_connectivity():
930+
# Create dataset with face_edges
931+
dataset = make_dataset(width=3, make_edges=True, make_face_coordinates=True)
932+
topology = dataset.ems.topology
933+
topology.mesh_variable.attrs.update({
934+
'face_edge_connectivity': 'Mesh2_face_edges',
935+
})
936+
937+
mesh2_face_edges_array = topology.face_edge_array
938+
939+
mesh2_face_edges = xarray.DataArray(
940+
mesh2_face_edges_array,
941+
dims=[topology.face_dimension, topology.max_node_dimension],
942+
)
943+
944+
dataset = dataset.assign({
945+
'Mesh2_face_edges': mesh2_face_edges,
946+
})
947+
948+
dataset_fill_value_below_range = dataset.copy()
949+
950+
dataset_fill_value_in_range_on_lower_boundary = dataset.copy()
951+
952+
dataset_fill_value_in_range = dataset.copy()
953+
954+
dataset_fill_value_in_range_on_upper_boundary = dataset.copy()
955+
956+
dataset_fill_value_above_range = dataset.copy()
957+
958+
# Make sure original dataset is valid
959+
assert dataset.ems.topology.has_valid_face_edge_connectivity is True
960+
961+
# Test valid and invalid fill values
962+
dataset_fill_value_below_range['Mesh2_face_edges'].encoding['_FillValue'] = -1
963+
964+
assert dataset_fill_value_below_range.ems.topology.has_valid_face_edge_connectivity is True
965+
966+
dataset_fill_value_in_range_on_lower_boundary['Mesh2_face_edges'].encoding['_FillValue'] = 0
967+
968+
with pytest.warns(ConventionViolationWarning):
969+
assert dataset_fill_value_in_range_on_lower_boundary.ems.topology.has_valid_face_edge_connectivity is not True
970+
971+
dataset_fill_value_in_range['Mesh2_face_edges'].encoding['_FillValue'] = 44
972+
973+
with pytest.warns(ConventionViolationWarning):
974+
assert dataset_fill_value_in_range.ems.topology.has_valid_face_edge_connectivity is not True
975+
976+
dataset_fill_value_in_range_on_upper_boundary['Mesh2_face_edges'].encoding['_FillValue'] = 88
977+
978+
with pytest.warns(ConventionViolationWarning):
979+
assert dataset_fill_value_in_range_on_upper_boundary.ems.topology.has_valid_face_edge_connectivity is not True
980+
981+
dataset_fill_value_above_range['Mesh2_face_edges'].encoding['_FillValue'] = 89
982+
983+
assert dataset_fill_value_above_range.ems.topology.has_valid_face_edge_connectivity is True

0 commit comments

Comments
 (0)