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 optionallylon_b,lat_bif 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, andface_node_connectivityvariables, or through UGRID-style mesh topology metadata. For topology-driven discovery, the dataset must include a variable withcf_role="mesh_topology"and attributes pointing tonode_coordinates,face_coordinates, andface_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
_FillValuefor padded entries andstart_indexfor 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 optionallyadd_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_dimsmust 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 inesmf_regrid_build().Recommend Fortran-ordering to match ESMPy internal.
- Returns:
- outdatanumpy array of shape
(Nlon_out, Nlat_out, N1, N2, ...)
- outdatanumpy array of shape
- 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).
- weightssparse COO matrix of shape
- 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.
- outdatanumpy array of shape
- 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)