Internal API

frontend

Frontend for xESMF, exposed to users.

xesmf.frontend.subset_regridder(ds_out, ds_in, method, in_dims, out_dims, locstream_in, locstream_out, periodic, **kwargs)

Compute subset of weights

xesmf.frontend.ds_to_ESMFgrid(ds, need_bounds=False, periodic=None, append=None)

Convert xarray DataSet or dictionary to ESMF.Grid object.

Parameters:
dsxarray DataSet or dictionary

Contains variables lon, lat, and optionally lon_b, lat_b if need_bounds=True.

Shape should be (n_lat, n_lon) or (n_y, n_x), as normal C or Python ordering. Will be then tranposed to F-ordered.

need_boundsbool, optional

Need cell boundary values?

periodicbool, optional

Periodic in longitude?

Returns:
grid

ESMF.Grid object

shape

Shape of the grid

dim_names

Dimension names of the grid

xesmf.frontend.ds_to_ESMFlocstream(ds)

Convert xarray DataSet or dictionary to ESMF.LocStream object.

Parameters:
dsxarray DataSet or dictionary

Contains variables lon, lat.

Returns:
locstreamESMF.LocStream object
xesmf.frontend.ds_to_ESMFmesh(ds)

Convert an xarray Dataset or dictionary to an ESMF.Mesh object.

The input may describe mesh coordinates explicitly using node_lon/node_lat, face_lon/face_lat, and face_node_connectivity variables, or through UGRID-style mesh topology metadata. For topology-driven discovery, the dataset must include a variable with cf_role="mesh_topology" and attributes pointing to node_coordinates, face_coordinates, and face_node_connectivity.

Both spherical lon/lat coordinates and Cartesian xyz coordinates are supported. Homogeneous coordinate modes are required: node and face coordinates must both be lon/lat or both be xyz. The face-node connectivity array may define _FillValue for padded entries and start_index for 0-based or 1-based indexing.

Currently this converter is intended for face-centered mesh input and returns a shape of (1, n_face).

Parameters:
dsxarray Dataset or dict-like

Dataset containing mesh coordinates and face-node connectivity.

Returns:
mesh

ESMF.Mesh object.

shape

Mesh shape as (1, n_face).

dim_names

Dimension names of the face coordinates.

xesmf.frontend.polys_to_ESMFmesh(polys)

Convert a sequence of shapely Polygons to a ESMF.Mesh object.

MultiPolygons are split in their polygon parts and holes are ignored.

Parameters:
polyssequence of shapely Polygon or MultiPolygon
Returns:
exteriorESMF.Mesh

A mesh where elements are the exterior rings of the polygons

tuple

The shape of the mesh : (1, N_elements)

backend

Backend for xESMF. This module wraps ESMPy’s complicated API and can create ESMF Grid and Regrid objects only using basic numpy arrays.

General idea:

1) Only use pure numpy array in this low-level backend. xarray should only be used in higher-level APIs which interface with this low-level backend.

2) Use simple, procedural programming here. Because ESMPy Classes are complicated enough, building new Classes will make debugging very difficult.

3) Add some basic error checking in this wrapper level. ESMPy is hard to debug because the program often dies in the Fortran level. So it would be helpful to catch some common mistakes in Python level.

xesmf.backend.warn_f_contiguous(a)

Give a warning if input array if not Fortran-ordered.

ESMPy expects Fortran-ordered array. Passing C-ordered array will slow down performance due to memory rearrangement.

Parameters:
anumpy array
xesmf.backend.warn_lat_range(lat)

Give a warning if latitude is outside of [-90, 90]

Longitute, on the other hand, can be in any range, since the it the transform is done in (x, y, z) space.

Parameters:
latnumpy array
class xesmf.backend.Grid(max_index=None, num_peri_dims=0, periodic_dim=None, pole_dim=None, coord_sys=None, coord_typekind=None, staggerloc=None, pole_kind=None, filename=None, filetype=None, reg_decomp=None, decompflag=None, is_sphere=None, add_corner_stagger=None, add_user_area=None, add_mask=None, varname=None, coord_names=None, tilesize=None, regDecompPTile=None, name=None)
classmethod from_xarray(lon, lat, periodic=False, mask=None)

Create an ESMF.Grid object, for constructing ESMF.Field and ESMF.Regrid.

Parameters:
lon, lat2D numpy array

Longitute/Latitude of cell centers.

Recommend Fortran-ordering to match ESMPy internal.

Shape should be (Nlon, Nlat) for rectilinear grid, or (Nx, Ny) for general quadrilateral grid.

periodicbool, optional

Periodic in longitude? Default to False. Only useful for source grid.

mask2D numpy array, optional

Grid mask. According to the ESMF convention, masked cells are set to 0 and unmasked cells to 1.

Shape should be (Nlon, Nlat) for rectilinear grid, or (Nx, Ny) for general quadrilateral grid.

Returns:
gridESMF.Grid object
get_shape(loc=<StaggerLoc.CENTER: 0>)

Return shape of grid for specified StaggerLoc

class xesmf.backend.LocStream(location_count, coord_sys=None, name=None, esmf=True)
classmethod from_xarray(lon, lat)

Create an ESMF.LocStream object, for contrusting ESMF.Field and ESMF.Regrid

Parameters:
lon, lat1D numpy array

Longitute/Latitude of cell centers.

Returns:
locstreamESMF.LocStream object
get_shape()

Return LocStream shape.

xesmf.backend.add_corner(grid, lon_b, lat_b)

Add corner information to ESMF.Grid for conservative regridding.

Not needed for other methods like bilinear or nearest neighbour.

Parameters:
gridESMF.Grid object

Generated by Grid.from_xarray(). Will be modified in-place.

lon_b, lat_b2D numpy array

Longitute/Latitude of cell corner Recommend Fortran-ordering to match ESMPy internal. Shape should be (Nlon+1, Nlat+1), or (Nx+1, Ny+1)

class xesmf.backend.Mesh(parametric_dim=None, spatial_dim=None, coord_sys=None, filename=None, filetype=None, convert_to_dual=None, add_user_area=None, meshname='', mask_flag=None, varname='')
classmethod from_ugrid(node_lon, node_lat, face_node_connectivity, face_lon, face_lat, fill_value=None, start_index=None)

Create an ESMF.Mesh from UGRID-style lon/lat mesh coordinates.

Parameters:
node_lon, node_latarray-like

One-dimensional longitude and latitude coordinates of mesh nodes.

face_node_connectivityarray-like

Two-dimensional integer array with shape (n_face, n_max_face_nodes) mapping each face to its corner nodes.

face_lon, face_latarray-like

One-dimensional longitude and latitude coordinates of face centers.

fill_valueint, optional

Fill value used for padded connectivity entries. Defaults to -1.

start_index{0, 1}, optional

Index offset used by face_node_connectivity. If omitted, the offset is inferred from the connectivity values.

Returns:
mesh

ESMF.Mesh object.

Notes

Longitude and latitude coordinates are converted to Cartesian coordinates on the unit sphere before constructing the ESMF mesh. The input face-node ordering is preserved.

classmethod from_ugrid_xyz(node_x, node_y, node_z, face_node_connectivity, face_x, face_y, face_z, fill_value=None, start_index=None)

Create an ESMF.Mesh from UGRID-style Cartesian mesh coordinates.

Parameters:
node_x, node_y, node_zarray-like

One-dimensional Cartesian coordinates of mesh nodes.

face_node_connectivityarray-like

Two-dimensional integer array with shape (n_face, n_max_face_nodes) mapping each face to its corner nodes.

face_x, face_y, face_zarray-like

One-dimensional Cartesian coordinates of face centers.

fill_valueint, optional

Fill value used for padded connectivity entries. Defaults to -1.

start_index{0, 1}, optional

Index offset used by face_node_connectivity. If omitted, the offset is inferred from the connectivity values.

Returns:
mesh

ESMF.Mesh object.

Notes

The input face-node ordering is preserved.

classmethod from_polygons(polys, element_coords='centroid')

Create an ESMF.Mesh object from a list of polygons.

All exterior ring points are added to the mesh as nodes and each polygon is added as an element, with the polygon centroid as the element’s coordinates.

Parameters:
polyssequence of shapely Polygon

Holes are not represented by the Mesh.

element_coordsarray or “centroid”, optional

If “centroid”, the polygon centroids will be used (default) If an array of shape (len(polys), 2) : the element coordinates of the mesh. If None, the Mesh’s elements will not have coordinates.

Returns:
meshESMF.Mesh

A mesh where each polygon is represented as an Element.

get_shape(loc=<MeshLoc.ELEMENT: 1>)

Return the shape of the Mesh at specified MeshLoc location.

xesmf.backend.esmf_regrid_build(sourcegrid, destgrid, method, filename=None, extra_dims=None, extrap_method=None, extrap_dist_exponent=None, extrap_num_src_pnts=None, extrap_num_levels=None, ignore_degenerate=None, vector_regrid=None)

Create an ESMF.Regrid object, containing regridding weights.

Parameters:
sourcegrid, destgridESMF.Grid or ESMF.Mesh object

Source and destination grids.

Should create them by Grid.from_xarray() (with optionally add_corner()), instead of ESMPy’s original API.

methodstr

Regridding method. Options are

  • ‘bilinear’

  • ‘conservative’, need grid corner information

  • ‘conservative_2nd’, need grid corner information; may overshoot

  • ‘conservative_normed’, need grid corner information

  • ‘patch’

  • ‘nearest_s2d’

  • ‘nearest_d2s’

filenamestr, optional

Save the weights to this netCDF file. Require ESMPy 7.1.1 or newer and a parallel IO enabled ESMF. Saving weights here is not needed for xESMF.

extra_dimsa list of integers, optional

Extra dimensions (e.g. time or levels) in the data field

This does NOT affect offline weight file, only affects online regrid.

Extra dimensions will be stacked to the fastest-changing dimensions, i.e. following Fortran-like instead of C-like conventions. For example, if extra_dims=[Nlev, Ntime], then the data field dimension will be [Nlon, Nlat, Nlev, Ntime]

extrap_methodstr, optional

Extrapolation method. Options are

  • ‘inverse_dist’

  • ‘nearest_s2d’

  • ‘creep_fill’

extrap_dist_exponentfloat, optional

The exponent to raise the distance to when calculating weights for the extrapolation method. If none are specified, defaults to 2.0

extrap_num_src_pntsint, optional

The number of source points to use for the extrapolation methods that use more than one source point. If none are specified, defaults to 8

extrap_num_levelsint, optional

Number of extrapolation levels to apply for the ‘creep_fill’ method.

The creep fill algorithm iteratively fills unmapped target points by propagating values from neighboring mapped cells. Each level corresponds to one iteration of this filling process. Larger values allow extrapolation to reach farther into unmapped regions, but may increase computational cost and smoothness of the result.

Required when extrap_method='creep_fill'.

ignore_degeneratebool, optional

If False (default), raise error if grids contain degenerated cells (i.e. triangles or lines, instead of quadrilaterals)

vector_regridbool, optional

If True, treat a single extra (non-spatial) dimension in the source and destination data fields as the components of a vector. (If True and there is more than one extra dimension in either the source or destination data fields, an error will be raised.) If not specified, defaults to False.

Only vector dimensions of size 2 are supported. The first entry is interpreted as the east component and the second as the north component. i.e., extra_dims must be [2].

Requires ESMPy 8.9.0 or newer.

Returns:
regridESMF.Regrid object
xesmf.backend.esmf_regrid_apply(regrid, indata)

Apply existing regridding weights to the data field, using ESMPy’s built-in functionality.

xESMF use Scipy to apply weights instead of this. This is only for benchmarking Scipy’s result and performance.

Parameters:
regridESMF.Regrid object

Contains the mapping from the source grid to the destination grid.

Users should create them by esmf_regrid_build(), instead of ESMPy’s original API.

indatanumpy array of shape (Nlon, Nlat, N1, N2, ...)

Extra dimensions (N1, N2, ...) are specified in esmf_regrid_build().

Recommend Fortran-ordering to match ESMPy internal.

Returns:
outdatanumpy array of shape (Nlon_out, Nlat_out, N1, N2, ...)
xesmf.backend.esmf_regrid_finalize(regrid)

Free the underlying Fortran array to avoid memory leak.

After calling destroy() on regrid or its fields, we cannot use the regrid method anymore, but the input and output data still exist.

Parameters:
regridESMF.Regrid object

smm

Sparse matrix multiplication (SMM) using scipy.sparse library.

xesmf.smm.read_weights(weights, n_in, n_out)

Read regridding weights into a DataArray (sparse COO matrix).

Parameters:
weightsstr, Path, xr.Dataset, xr.DataArray, sparse.COO

Weights generated by ESMF. Can be a path to a netCDF file generated by ESMF, an xarray.Dataset, a dictionary created by ESMPy.api.Regrid.get_weights_dict or directly the sparse array as returned by this function.

n_in, n_outintegers

(N_out, N_in) will be the shape of the returning sparse matrix. They are the total number of grid boxes in input and output grids:

N_in = Nx_in * Ny_in
N_out = Nx_out * Ny_out

We need them because the shape cannot always be inferred from the largest column and row indices, due to unmapped grid boxes.

Returns:
xr.DataArray

A DataArray backed by a sparse.COO array, with dims (‘out_dim’, ‘in_dim’) and size (n_out, n_in).

xesmf.smm.check_shapes(indata, weights, shape_in, shape_out)

Compare the shapes of the input array, the weights and the regridder and raises potential errors.

Parameters:
indataarray

Input array with the two spatial dimensions at the end, which should fit shape_in.

weightsarray

Weights 2D array of shape (out_dim, in_dim). First element should be the product of shape_out. Second element should be the product of shape_in.

shape_in2-tuple of int

Shape of the input of the Regridder.

shape_out2-tuple of int

Shape of the output of the Regridder.

Raises:
ValueError

If any of the conditions is not respected.

xesmf.smm.apply_weights(weights, indata, shape_in, shape_out)

Apply regridding weights to data.

Parameters:
weightssparse COO matrix of shape (n_out, n_in) (2D) OR

(ny_out, nx_out, ny_in, nx_in) (4D, legacy). 2D is preferred — passing 4D triggers a flatten-to-2D step here.

indatanumpy array of shape (..., n_lat, n_lon) or (..., n_y, n_x).

Should be C-ordered. Will be then tranposed to F-ordered.

shape_in, shape_outtuple of two integers

Input/output data shape. For rectilinear grid, it is just (n_lat, n_lon).

Returns:
outdatanumpy array of shape (..., shape_out[0], shape_out[1]).

Extra dimensions are the same as indata. If input data is C-ordered, output will also be C-ordered.

xesmf.smm.post_apply_target_mask_to_weights(weights, target_mask_2d)

Set all contributions to masked target grid cells to zero.

Parameters:
weightsDataArray backed by a sparse.COO array

Sparse weights matrix.

target_mask_2darray-like

Mask array of shape (nx, ny) for the target grid. False / 0 indicates a masked cell whose weights shall be set to zero.

Returns:
DataArray backed by a sparse.COO array

Modified sparse weights matrix with all rows corresponding to masked target cells set to zero.

Notes

This defines a post-processing step applied after ESMF weight generation. It is useful in cases where ESMF/ESMPy masks cannot be used directly, which is the case when source or target are LocStream objects / sequences.

xesmf.smm.add_nans_to_weights(weights)

Add nan in empty rows of the regridding weights sparse matrix.

By default, empty rows in the weights sparse matrix are interpreted as zeroes. This can become problematic when the field being interpreted has legitimate null values. This function inserts nan values in each row to make sure empty weights are propagated as nans instead of zeros. It also removes unnecessary entries, ones where the data is the same as the fill value (0).

Parameters:
weightsDataArray backed by a sparse.COO array

Sparse weights matrix.

Returns:
DataArray backed by a sparse.COO array

Sparse weights matrix.

xesmf.smm.mask_source_indices(weights, source_indices_to_mask)

Remove entries in a sparse.COO weight matrix that map from masked source indices.

Parameters:
weights: DataArray backed by a sparse.COO array

Sparse weights matrix.

source_indices_to_mask: array-like

Flat indices of source grid cells whose contribution should be removed (eg. output of xesmf.util._get_edge_indices_2d)

Returns:
DataArray backed by a sparse.COO array:

New weight matrix with masked source contributions removed

xesmf.smm.gen_mask_from_weights(weights, nlat, nlon)

Generate a 2D mask from the regridding weights sparse matrix.

This function will generate a 2D binary mask out of a regridding weights sparse matrix. The mask shows which pixels of the output grid are mapped in the input grid. This is only feasible when the regridder weights have been created with unmapped_to_nan=True.

Parameters:
weightsDataArray backed by a sparse.COO array

Sparse weights matrix, as computed by the Regridder.

nlat, nlon: int

Shape of the final matrix. nlat * nlon must be equal to the size of the out_dim dimension of the weights.

Returns:
numpy.ndarray of type numpy.int32 and of shape (nlat, nlon)

Binary mask.

Examples

This function acts on lower level inputs, but the regridder has all information needed to construct a DataArray.

>>> reg = xe.Regridder(ds_in, ds_out, 'bilinear', unmapped_to_nan=True)
>>> mask = xe.smm.gen_mask_from_weights(reg.weights, *reg.shape_out)
>>> mask_da = xr.DataArray(mask, dims=reg.out_horiz_dims, coords=reg.out_coords.coords)