Skip to content

Commit 614b8ef

Browse files
larsbuntemeyergithub actionpre-commit-ci[bot]dcherian
authored
check precision of vertex order (#361)
* changed precision of vertex order check comparison * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * added rotated pole datasets with inexact bounds * renamed test datasets * added test on bounds with precision issues * clean up * change check coordinate Co-authored-by: github action <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Deepak Cherian <[email protected]>
1 parent 2750e45 commit 614b8ef

File tree

3 files changed

+110
-2
lines changed

3 files changed

+110
-2
lines changed

cf_xarray/datasets.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,105 @@ def _create_mollw_ds():
221221

222222
mollwds = _create_mollw_ds()
223223

224+
225+
def _create_inexact_bounds():
226+
# Dataset that creates rotated pole curvilinear coordinates with CF bounds in
227+
# counterclockwise order that have precision issues.
228+
lon = np.array(
229+
[
230+
[64.21746363939087, 64.42305921561967, 64.62774455060337],
231+
[64.38488380781622, 64.5906340869802, 64.79546745916944],
232+
[64.55349991538067, 64.75940009330206, 64.96437666717893],
233+
]
234+
)
235+
236+
lat = np.array(
237+
[
238+
[66.63852914622773, 66.57692364510149, 66.51510790697783],
239+
[66.72632651121215, 66.66454929137457, 66.60256232699675],
240+
[66.81394503895442, 66.75199541041104, 66.68983654206977],
241+
]
242+
)
243+
244+
lon_bounds = np.array(
245+
[
246+
[
247+
[64.03109895962405, 64.23707042152387, 64.44213290724275],
248+
[64.19784426308645, 64.40397614495, 64.60919235424163],
249+
[64.36578231818473, 64.57206989228206, 64.77743506492257],
250+
],
251+
[
252+
[64.23707042152385, 64.44213290724275, 64.64629053434521],
253+
[64.40397614494998, 64.60919235424163, 64.81349710155956],
254+
[64.57206989228204, 64.77743506492257, 64.98188214131258],
255+
],
256+
[
257+
[64.40397614494998, 64.60919235424161, 64.81349710155956],
258+
[64.57206989228204, 64.77743506492257, 64.98188214131258],
259+
[64.74136272095073, 64.94687197648351, 65.15145647131322],
260+
],
261+
[
262+
[64.19784426308645, 64.40397614495, 64.60919235424161],
263+
[64.36578231818473, 64.57206989228206, 64.77743506492257],
264+
[64.53492430330854, 64.74136272095075, 64.94687197648351],
265+
],
266+
]
267+
)
268+
269+
lat_bounds = np.array(
270+
[
271+
[
272+
[66.62524451217388, 66.56383049714253, 66.50220514181308],
273+
[66.71321640554079, 66.65163077691872, 66.58983429068188],
274+
[66.801010821918, 66.73925288286632, 66.67728458111449],
275+
],
276+
[
277+
[66.56383049714253, 66.50220514181308, 66.44037016643905],
278+
[66.65163077691872, 66.58983429068188, 66.52782867442114],
279+
[66.73925288286632, 66.67728458111449, 66.61510765153199],
280+
],
281+
[
282+
[66.6516307769187, 66.58983429068185, 66.52782867442114],
283+
[66.73925288286632, 66.67728458111449, 66.61510765153199],
284+
[66.82669478850752, 66.76455398820585, 66.702205074604],
285+
],
286+
[
287+
[66.71321640554079, 66.6516307769187, 66.58983429068185],
288+
[66.801010821918, 66.73925288286632, 66.67728458111449],
289+
[66.88862573342278, 66.82669478850752, 66.76455398820585],
290+
],
291+
]
292+
)
293+
294+
rotated = xr.Dataset(
295+
coords=dict(
296+
lon=xr.DataArray(
297+
lon,
298+
dims=("x", "y"),
299+
attrs={"units": "degrees_east", "bounds": "lon_bounds"},
300+
),
301+
lat=xr.DataArray(
302+
lat,
303+
dims=("x", "y"),
304+
attrs={"units": "degrees_north", "bounds": "lat_bounds"},
305+
),
306+
),
307+
data_vars=dict(
308+
lon_bounds=xr.DataArray(
309+
lon_bounds, dims=("bounds", "x", "y"), attrs={"units": "degrees_east"}
310+
),
311+
lat_bounds=xr.DataArray(
312+
lat_bounds, dims=("bounds", "x", "y"), attrs={"units": "degrees_north"}
313+
),
314+
),
315+
)
316+
317+
return rotated
318+
319+
320+
rotds = _create_inexact_bounds()
321+
322+
224323
forecast = xr.decode_cf(
225324
xr.Dataset.from_dict(
226325
{

cf_xarray/helpers.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ def _bounds_helper(values, n_core_dims, nbounds, order):
9595
vertex_vals = np.block([[bot_left, bot_right], [top_left, top_right]])
9696
if order is None: # We verify if the ccw version works.
9797
calc_bnds = np.moveaxis(vertices_to_bounds(vertex_vals).values, 0, -1)
98-
order = "counterclockwise" if np.all(calc_bnds == values) else "clockwise"
98+
order = (
99+
"counterclockwise" if np.allclose(calc_bnds, values) else "clockwise"
100+
)
99101
if order == "clockwise":
100102
bot_left = values[..., :, :, 0]
101103
top_left = values[..., -1:, :, 1]

cf_xarray/tests/test_helpers.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import cf_xarray as cfxr # noqa
55

6-
from ..datasets import airds, mollwds
6+
from ..datasets import airds, mollwds, rotds
77

88
try:
99
from dask.array import Array as DaskArray
@@ -27,6 +27,13 @@ def test_bounds_to_vertices():
2727
assert_equal(mollwds.lat_vertices, lat_ccw)
2828
assert_equal(lat_no, lat_ccw)
2929

30+
# 2D case with precision issues, check if CF- order is "detected" correctly
31+
lon_ccw = cfxr.bounds_to_vertices(
32+
rotds.lon_bounds, bounds_dim="bounds", order="counterclockwise"
33+
)
34+
lon_no = cfxr.bounds_to_vertices(rotds.lon_bounds, bounds_dim="bounds", order=None)
35+
assert_equal(lon_no, lon_ccw)
36+
3037
# Transposing the array changes the bounds direction
3138
ds = mollwds.transpose("bounds", "y", "x", "y_vertices", "x_vertices")
3239
lon_c = cfxr.bounds_to_vertices(

0 commit comments

Comments
 (0)