Disaggregates `coarse` to a finer resolution by integer factor `fact` using Keys cubic convolution interpolation, with a pre-sharpening filter that makes the result mass-preserving: aggregating it back by block mean recovers the input coarse values up to a small truncation error governed by `radius`.
Usage
disagg_cub(
coarse,
fact,
radius = NULL,
max_radius_frac = 1/3,
na_fill = c("auto", "reflect", "fill")
)Arguments
- coarse
SpatRaster. Multi-layer rasters are supported.
- fact
Integer disagg factor (>= 2).
- radius
Integer half-width of the inverse kernel. If `NULL` (the default), `radius` is set to `max(9, fact + 4)`, slightly larger than bilinear's default because cubic's inverse kernel decays more slowly. Users rarely need to change this. Larger values reduce truncation error further at a small one-time cost (the kernel is cached per `fact`); smaller values are faster on small rasters but allow larger residual error. Automatically reduced for small rasters; see `max_radius_frac`.
- max_radius_frac
Numeric. Same semantics as in [disagg_bl()]; upper bound on kernel radius as a fraction of the coarse raster's smaller dimension.
- na_fill
Character. Boundary/NA handling mode, same options as in [disagg_bl()]: `"auto"` (default), `"reflect"`, or `"fill"`.
Details
Compared to [disagg_bl()]:
Cubic produces smoother output (no kinks at cell centers, where bilinear has them) at modestly higher computational cost.
Cubic has negative side lobes and may overshoot input range near sharp gradients. For data with hard physical bounds (precipitation, fractional cover), this may matter.
At the same `radius`, cubic's truncation error is somewhat larger than bilinear's because its inverse kernel decays more slowly. The default `radius` is correspondingly larger to compensate.
**Mass preservation is approximate.** Like [disagg_bl()], the inverse kernel is a finite approximation to an ideal infinite operator. The truncation error is concentrated near the raster boundary and decays with larger `radius`. Cubic's error at equal radius is somewhat larger than bilinear's because its inverse kernel has alternating-sign rings that decay more slowly than bilinear's geometric decay. See [edge_effects()] to visualize which fine cells fall in the edge-affected zone for given inputs.
**Implementation note.** [terra::disagg()] does not expose cubic interpolation directly, so `disagg_cub()` uses [terra::resample()] internally for the interpolation step, with a target fine grid that nests perfectly within the coarse cells. We have verified empirically that `terra::resample(method = "cubic")` uses Keys cubic with `a = -0.5`, which is the convention our pre-sharpening kernel inverts.