easyclimate.interp.barnes

Fast Barnes interpolation

Functions

interp_spatial_barnes(data, var_name, *[, lon_dim, ...])

Computes Barnes interpolation for observation values var_name sampled at irregular

interp_spatial_barnes_rs(data, var_name, *[, lon_dim, ...])

Rust-accelerated Barnes interpolation wrapper (lon/lat in degrees).

interp_spatial_barnesS2([lambert_proj, lambert_grid])

Computes Barnes interpolation on the unit sphere \(S^2\) (spherical metric)

interp_spatial_barnesS2_rs([lambert_proj, lambert_grid])

Rust-accelerated Barnes interpolation on the unit sphere \(S^2\) (spherical metric).

Module Contents

easyclimate.interp.barnes.interp_spatial_barnes(data: pandas.DataFrame, var_name: str, *, lon_dim: str = 'lon', lat_dim: str = 'lat', grid_res_deg: float = 0.25, auto_domain: bool = True, buffer_deg: float = 1.0, point: tuple[float, float] | None = None, grid_x: float | None = None, grid_y: float | None = None, sigma_deg: float | None = None, influence_radius_deg: float | None = None, influence_k_sigma: float = 4.0, num_iter: int = 2, method: str = 'optimized_convolution', max_dist_sigma: float | None = None, min_weight: float = 1e-06, mask_radius_deg: float | None = None, missing_sentinels: tuple[float, Ellipsis] = (9999.9, 9999.0, -9999.0, -9999.9))

Computes Barnes interpolation for observation values var_name sampled at irregular locations in data (lon/lat in degrees), using Gaussian weights with width parameter sigma_deg and returning a regular lon/lat grid as an xarray.DataArray.

Barnes interpolation is widely used in meteorology and geosciences to remodel irregular point observations into a smooth gridded field. It can be written as

\[\begin{split}f(\\boldsymbol{x})=\\frac{\\sum_{k=1}^N f_k\\cdot w_k(\\boldsymbol{x})}{\\sum_{k=1}^N w_k(\\boldsymbol{x})}\end{split}\]

with Gaussian weights

\[\begin{split}w_k(\\boldsymbol{x})=\\text{e}^{-\\frac{1}{2\\sigma^2}\\left|x-\\boldsymbol{x}_k\\right|^2}\end{split}\]

Naive computation of Barnes interpolation leads to an algorithmic complexity of \(O(N \\times W \\times H)\), where \(N\) is the number of sample points and \(W \\times H\) the size of the underlying grid.

For sufficiently large \(n\) (in general in the range from 3 to 6) a good approximation of Barnes interpolation with a reduced complexity \(O(N + W \\times H)\) can be obtained by the convolutional expression

\[\begin{split}f(\\boldsymbol{x})\\approx \\frac{ (\\sum_{k=1}^{N}f_k\\cdot\\delta_{\\boldsymbol{x}_k}) * ( r_n^{*n[x]}(x)\\cdot r_n^{*n[y]}(y) ) }{ ( \\sum_{k=1}^{N} \\delta_{\\boldsymbol{x}_k} ) * ( r_{n}^{*n[x]}(x)\\cdot r_{n}^{*n[y]}(y) ) }\end{split}\]

where \(\\delta\) is the Dirac impulse function and \(r(.)\) an elementary rectangular function of a specific length that depends on \(\\sigma\) and \(n\).

This wrapper is degree-based:

  • grid_res_deg / sigma_deg / influence_radius_deg / mask_radius_deg are all in degrees.

  • Internally converts to the fast-barnes “grid units” used by the core implementation:

\[\begin{split}\\sigma_{\\text{grid}} = \\sigma_{\deg} / \\Delta_{\\deg}, \\qquad \\text{max_dist_sigma} = R_{\\deg} / \\sigma_{\\deg}.\end{split}\]
  • If sigma_deg is not provided, it is estimated from station density using a simple spacing heuristic.

  • Optional masking keeps only grid points that have at least one station within mask_radius_deg using a radius-search KD-tree.

Parameters

datapandas.DataFrame

Input table containing at least lon_dim, lat_dim and var_name columns. Any rows with NaN/Inf in these columns are dropped after cleaning.

There should be a similar structure as follows

lon

lat

qff

-3.73

56.33

995.1

2.64

47.05

1012.5

Note

Data points should contain longitude (lon), latitude (lat) and data variables (the above data variable name is qff).

var_namestr

Name of the variable column to interpolate. This should match the one in the parameter data.

lon_dim, lat_dimstr, optional

Column names for longitude/latitude (degrees). Defaults are "lon" and "lat".

grid_res_degfloat, optional

Output grid spacing in degrees. Must be > 0. Default is 0.25.

auto_domainbool, optional

If True (default), the interpolation domain is set to the data bounding box expanded by buffer_deg on each side.

buffer_degfloat, optional

Padding (degrees) added around the data bounding box when auto_domain=True.

pointtuple(float, float), optional

Lower-left corner (lon0, lat0) of the output grid (degrees). Required when auto_domain=False.

grid_x, grid_yfloat, optional

Domain size in degrees in x (lon) / y (lat). Required when auto_domain=False.

sigma_degfloat, optional

Gaussian width in degrees. If None, an automatic estimate based on station density is used.

influence_radius_degfloat, optional

Radius of influence in degrees. If None, uses influence_k_sigma * sigma_deg.

influence_k_sigmafloat, optional

Multiplier used when influence_radius_deg is None. Default is 4.0.

num_iterint, optional

Number of self-convolutions used by convolution-based methods. Must be >= 1. The number of performed self-convolutions of the underlying rect-kernel. Applies only if method is ‘optimized_convolution’ or ‘convolution’. The default is 2. Applies only to Convol interpolations: one of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 50.

methodstr, optional

Passed to fastbarnes_new.interpolation.barnes(). Common values include "optimized_convolution", "convolution", "radius", "naive". The possible implementations that can be chosen are ‘naive’ for the straightforward implementation (algorithm A from paper), ‘radius’ to consider only sample points within a specific radius of influence, both with an algorithmic complexity of \(O(N \\times W \\times H)\). The choice ‘convolution’ implements algorithm B specified in the paper and ‘optimized_convolution’ is its optimization by appending tail values to the rectangular kernel. The latter two algorithms reduce the complexity down to \(O(N + W \\times H)\).

max_dist_sigmafloat, optional

Maximum distance (in units of sigma) for which interpolation is computed. If None, uses influence_radius_deg / sigma_deg.

min_weightfloat, optional

Minimum Gaussian weight threshold used by radius-based methods in the backend.

mask_radius_degfloat, optional

If provided (or if None defaults to influence_radius_deg), grid points farther than this radius (degrees) from all stations are set to NaN.

missing_sentinelstuple(float, …), optional

Values treated as missing in var_name and replaced by NaN before cleaning.

Returns

xarray.DataArray

Interpolated field on a regular lat/lon grid. Dimensions are (lat_dim, lon_dim). The returned DataArray includes useful metadata in attrs (grid spacing, sigma, influence radius, domain definition, etc.).

See also

easyclimate.interp.barnes.interp_spatial_barnes_rs(data: pandas.DataFrame, var_name: str, *, lon_dim: str = 'lon', lat_dim: str = 'lat', grid_res_deg: float = 0.25, auto_domain: bool = True, buffer_deg: float = 1.0, point: tuple[float, float] | None = None, grid_x: float | None = None, grid_y: float | None = None, sigma_deg: float | None = None, influence_radius_deg: float | None = None, influence_k_sigma: float = 4.0, num_iter: int = 2, method: str = 'optimized_convolution', max_dist_sigma: float | None = None, min_weight: float = 1e-06, mask_radius_deg: float | None = None, missing_sentinels: tuple[float, Ellipsis] = (9999.9, 9999.0, -9999.0, -9999.9))

Rust-accelerated Barnes interpolation wrapper (lon/lat in degrees).

This function is API-compatible with interp_spatial_barnes() but calls the Rust backend (easyclimate_rust._easyclimate_rust.barnes()) for the core interpolation step, and (optionally) uses the Rust radius mask (easyclimate_rust._easyclimate_rust.radius_mask_2d()) to avoid showing extrapolation far from stations.

Mathematically, the method targets the same Barnes analysis:

\[f(\boldsymbol{x})=\frac{\sum_{k=1}^N f_k\cdot w_k(\boldsymbol{x})}{\sum_{k=1}^N w_k(\boldsymbol{x})}\]

with Gaussian weights

\[w_k(\boldsymbol{x})=\text{e}^{-\frac{1}{2\sigma^2}\left|x-\boldsymbol{x}_k\right|^2}\]

Note

  • All user-facing spatial parameters are in degrees (same conversion rules as interp_spatial_barnes()).

  • sigma_deg auto-estimation uses a station-density spacing heuristic.

  • If mask_radius_deg is enabled, masking is performed in Rust on the regular grid.

Parameters

Identical to interp_spatial_barnes().

Returns

xarray.DataArray

Interpolated field on a regular lat/lon grid. Dimensions are (lat_dim, lon_dim). The returned DataArray includes useful metadata in attrs (grid spacing, sigma, influence radius, domain definition, etc.).

See also

easyclimate.interp.barnes.interp_spatial_barnesS2(data: pandas.DataFrame, var_name: str, *, lon_dim: str = 'lon', lat_dim: str = 'lat', grid_res_deg: float = 0.25, auto_domain: bool = True, buffer_deg: float = 1.0, point: tuple[float, float] | None = None, grid_x: float | None = None, grid_y: float | None = None, sigma_deg: float | None = None, influence_radius_deg: float | None = None, influence_k_sigma: float = 4.0, num_iter: int = 4, method: Literal['optimized_convolution_S2', 'naive_S2'] = 'optimized_convolution_S2', max_dist_sigma: float | None = None, resample: bool = True, mask_radius_deg: float | None = None, missing_sentinels: tuple[float, Ellipsis] = (9999.9, 9999.0, -9999.0, -9999.9), lambert_proj=None, lambert_grid=None, auto_proj: bool = True) xarray.DataArray

Computes Barnes interpolation on the unit sphere \(S^2\) (spherical metric) for observations given in lon/lat degrees, returning a regular lon/lat grid as an xarray.DataArray.

Compared to planar Barnes interpolation, the \(S^2\) variant uses spherical geometry internally (implemented by fastbarnes_new.interpolationS2.barnes_S2()). For performance, the optimized method relies on a Lambert projection and a projected grid; this wrapper forwards Lambert options and performs early validation so errors are raised in Python (more readable than deep backend errors).

Parameters

datapandas.DataFrame

Input table containing at least lon_dim, lat_dim and var_name columns. Any rows with NaN/Inf in these columns are dropped after cleaning.

There should be a similar structure as follows

lon

lat

qff

-3.73

56.33

995.1

2.64

47.05

1012.5

Note

Data points should contain longitude (lon), latitude (lat) and data variables (the above data variable name is qff).

var_namestr

Name of the variable column to interpolate. This should match the one in the parameter data.

lon_dim, lat_dimstr, optional

Column names for longitude/latitude (degrees). Defaults are "lon" and "lat".

grid_res_degfloat, optional

Output grid spacing in degrees. Must be > 0. Default is 0.25.

auto_domainbool, optional

If True (default), the interpolation domain is set to the data bounding box expanded by buffer_deg on each side.

buffer_degfloat, optional

Padding (degrees) added around the data bounding box when auto_domain=True.

pointtuple(float, float), optional

Lower-left corner (lon0, lat0) of the output grid (degrees). Required when auto_domain=False.

grid_x, grid_yfloat, optional

Domain size in degrees in x (lon) / y (lat). Required when auto_domain=False.

sigma_degfloat, optional

Gaussian width in degrees. If None, an automatic estimate based on station density is used.

influence_radius_degfloat, optional

Radius of influence in degrees. If None, uses influence_k_sigma * sigma_deg.

influence_k_sigmafloat, optional

Multiplier used when influence_radius_deg is None. Default is 4.0.

num_iterint, optional

Number of self-convolutions used by convolution-based methods. Must be >= 1. The number of performed self-convolutions of the underlying rect-kernel. Applies only if method is ‘optimized_convolution’ or ‘convolution’. The default is 2. Applies only to Convol interpolations: one of 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 50.

method{‘optimized_convolution_S2’, ‘naive_S2’}, default: ‘optimized_convolution_S2’.

Designates the Barnes interpolation method to be used. The possible implementations that can be chosen are ‘naive_S2’ for the straightforward implementation (algorithm A from the paper) with an algorithmic complexity of \(O(N \times W \times H)\). The choice ‘optimized_convolution_S2’ implements the optimized algorithm B specified in the paper by appending tail values to the rectangular kernel. The latter algorithm has a reduced complexity of \(O(N + W \times H)\). The default is ‘optimized_convolution_S2’.

max_dist_sigmafloat, optional

Maximum distance (in units of sigma) for which interpolation is computed. If None, uses influence_radius_deg / sigma_deg.

min_weightfloat, optional

Minimum Gaussian weight threshold used by radius-based methods in the backend.

mask_radius_degfloat, optional

If provided (or if None defaults to influence_radius_deg), grid points farther than this radius (degrees) from all stations are set to NaN.

missing_sentinelstuple(float, …), optional

Values treated as missing in var_name and replaced by NaN before cleaning.

resamplebool, default True

Passed through to the S2 backend (controls internal resampling behavior).

lambert_proj, lambert_grid, auto_proj

Lambert projection configuration forwarded to barnes_S2(). If auto_proj=True and no lambert_proj is provided, the backend will infer a projection; domains crossing the equator are not supported by the optimized S2 convolution path (split into hemispheres or pass an explicit projection/grid).

Returns

xarray.DataArray

Interpolated spherical Barnes field on a regular lat/lon grid, with metadata in attrs.

See also

easyclimate.interp.barnes.interp_spatial_barnesS2_rs(data: pandas.DataFrame, var_name: str, *, lon_dim: str = 'lon', lat_dim: str = 'lat', grid_res_deg: float = 0.25, auto_domain: bool = True, buffer_deg: float = 1.0, point: tuple[float, float] | None = None, grid_x: float | None = None, grid_y: float | None = None, sigma_deg: float | None = None, influence_radius_deg: float | None = None, influence_k_sigma: float = 4.0, num_iter: int = 4, method: Literal['optimized_convolution_S2', 'naive_S2'] = 'optimized_convolution_S2', max_dist_sigma: float | None = None, resample: bool = True, mask_radius_deg: float | None = None, missing_sentinels: tuple[float, Ellipsis] = (9999.9, 9999.0, -9999.0, -9999.9), lambert_proj=None, lambert_grid=None, auto_proj: bool = True) xarray.DataArray

Rust-accelerated Barnes interpolation on the unit sphere \(S^2\) (spherical metric).

This function mirrors interp_spatial_barnesS2() but uses the Rust backend (easyclimate_rust._easyclimate_rust.barnes_s2()) for the S2 interpolation. It keeps the same degree-based, user-friendly API and returns the same xarray.DataArray layout.

Parameters

Identical to interp_spatial_barnesS2().

Returns

xarray.DataArray

Interpolated spherical Barnes field on a regular lat/lon grid, with metadata in attrs.

See also