xESMF icon indicating copy to clipboard operation
xESMF copied to clipboard

[Bug] `UnboundLocalError` when longitude crosses 0° in 0–360 grids (cf-xarray #594)

Open tomvothecoder opened this issue 3 months ago • 0 comments

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 .

  • Related cf-xarray issue: https://github.com/xarray-contrib/cf-xarray/issues/594
  • Follow-up PR: https://github.com/xarray-contrib/cf-xarray/pull/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_orders infers "mixed" order for circular grids crossing .
  • cf_xarray.helpers._get_ordered_vertices doesn’t handle "mixed" order, so endpoints is never set → UnboundLocalError.
  • cf-xarray will soon raise a clearer ValueError here instead of failing silently (https://github.com/xarray-contrib/cf-xarray/pull/595)

Why it matters for xESMF

Since xESMF relies on bounds_to_vertices internally, any dataset with longitudes in 0–360 format centered at will currently fail.

Suggestions for xESMF

  • Pre-normalize longitude coordinates before calling bounds_to_vertices:
    • Convert to [-180, 180) and sortby("longitude"), or
    • If keeping 0–360, roll so the seam isn’t inside the array, then sort.
  • Add validation and clear error messages when inputs are not strictly monotonic.
  • Longer term: if cf-xarray adds a circular_period kwarg, pass it through from xESMF.
    • cf-xarray should probably not handle any normalization unless this circular_period arg is added.

tomvothecoder avatar Sep 18 '25 20:09 tomvothecoder