Skip to content

Commit d9b1365

Browse files
committed
Add failing test
1 parent 9383257 commit d9b1365

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

cf_xarray/helpers.py

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ def _guess_bounds_1d(da, dim):
2323
ADDED_INDEX = True
2424

2525
diff = da.diff(dim)
26+
# Here we would need some escape based on a check of whether we were
27+
# looking at cftime or not. It's not clear to me whether the fix should be
28+
# here or further upstream though (either the casting shouldn't happen or
29+
# numpy should be able to handle operations with cftime or we have some odd
30+
# use case and need a workaround here).
2631
lower = da - diff / 2
2732
upper = da + diff / 2
2833
bounds = xr.concat([lower, upper], dim="bounds")

cf_xarray/tests/test_accessor.py

+35-1
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,40 @@ def test_add_bounds_nd_variable() -> None:
878878
ds.cf.add_bounds("z").cf.add_bounds("x")
879879

880880

881+
def test_add_bounds_cftime() -> None:
882+
ds = airds.copy(deep=False)
883+
# Switch to cftime objects
884+
time, time_units, time_calendar = xr.coding.times.encode_cf_datetime(ds["time"])
885+
time_cftime = xr.coding.times.decode_cf_datetime(
886+
time,
887+
units=time_units,
888+
calendar=time_calendar,
889+
use_cftime=True,
890+
)
891+
892+
ds["time"] = ("time", time_cftime)
893+
894+
da_time = ds["time"]
895+
# Resorting to loop as something casts things to numpy types which causes explosions
896+
time_diffs = np.array(
897+
[da_time.values[i + 1] - da_time.values[i] for i in range(len(da_time) - 1)]
898+
)
899+
900+
# `1:` indexing to mimic xarray's diff behaviour which drops the first value
901+
lower = da_time.values[1:] - time_diffs / 2
902+
lower = np.concatenate([[lower[0] - time_diffs[0]], lower])
903+
upper = da_time.values[1:] + time_diffs / 2
904+
upper = np.concatenate([[upper[0] - time_diffs[0]], upper])
905+
906+
lower = xr.DataArray(lower, dims=["time"], coords=da_time.coords)
907+
upper = xr.DataArray(upper, dims=["time"], coords=da_time.coords)
908+
expected = xr.concat([lower, upper], dim="bounds").transpose(..., "bounds")
909+
910+
ds.cf.add_bounds("time")
911+
actual = ds.cf.add_bounds("time").time_bounds.reset_coords(drop=True)
912+
xr.testing.assert_identical(actual, expected)
913+
914+
881915
def test_bounds() -> None:
882916
ds = airds.copy(deep=False).cf.add_bounds("lat")
883917

@@ -947,7 +981,7 @@ def test_bounds_to_vertices() -> None:
947981
with pytest.raises(ValueError):
948982
dsv = dsb.cf.bounds_to_vertices("T")
949983

950-
# Words on datetime arrays to
984+
# Works on datetime arrays to
951985
dsb = dsb.cf.add_bounds("time")
952986
dsv = dsb.cf.bounds_to_vertices()
953987
assert "time_bounds" in dsv

0 commit comments

Comments
 (0)