-
Notifications
You must be signed in to change notification settings - Fork 37
Open
Description
Description
Hey there, @malmans2 ran into an error in xESMF that originates from how cf-xarray handles bounds when longitude coordinates are in the 0–360 format and cross the seam at 0°.
- Related cf-xarray issue: Variable endpoints undefined when order is not ascending or descending xarray-contrib/cf-xarray#594
- Follow-up PR: Raise ValueError in
_get_ordered_vertices()with "mixed" order xarray-contrib/cf-xarray#595
Minimal Reproducible Example (with cf_xarray)
import cf_xarray as cfxr
import xarray as xr
ds = xr.Dataset(
{
"latitude": ("latitude", [-90, 0, 90]),
"longitude": ("longitude", [359, 0, 1]), # 0–360 format crossing the seam
}
)
ds = ds.cf.add_bounds(["longitude", "latitude"])
lon_bnds = ds.cf.get_bounds("longitude")
lon_b = cfxr.bounds_to_vertices(
lon_bnds,
ds.cf.get_bounds_dim_name("longitude"),
order=None,
)This reproduces the failure inside xESMF (see frontend.py#107-111), because bounds_to_vertices receives a “mixed” order coordinate sequence ([359, 0, 1]).
What’s happening
cf_xarray.helpers._get_core_dim_ordersinfers"mixed"order for circular grids crossing0°.cf_xarray.helpers._get_ordered_verticesdoesn’t handle"mixed"order, soendpointsis never set →UnboundLocalError.cf-xarraywill soon raise a clearerValueErrorhere instead of failing silently (Raise ValueError in_get_ordered_vertices()with "mixed" order xarray-contrib/cf-xarray#595)
Why it matters for xESMF
Since xESMF relies on bounds_to_vertices internally, any dataset with longitudes in 0–360 format centered at 0° will currently fail.
Suggestions for xESMF
- Pre-normalize longitude coordinates before calling
bounds_to_vertices:- Convert to
[-180, 180)andsortby("longitude"), or - If keeping
0–360, roll so the seam isn’t inside the array, then sort.
- Convert to
- Add validation and clear error messages when inputs are not strictly monotonic.
- Longer term: if cf-xarray adds a
circular_periodkwarg, pass it through from xESMF.cf-xarrayshould probably not handle any normalization unless thiscircular_periodarg is added.
Metadata
Metadata
Assignees
Labels
No labels