Skip to content

Regridding calls and plans ​

Use regrid for one transfer, plan_regrid to reuse the same spatial mapping, and regrid! to write into an existing destination. These functions belong to GlobalRegridding and are re-exported by DiscreteGlobalGrids. Choose the meaning of the transfer in Choosing a regridding method.

One transfer ​

This example transfers a constant field between two HEALPix levels. A plain vector needs an explicit source grid because it carries no spatial metadata.

julia
import DiscreteGlobalGrids as DGG

source = DGG.levelgrid(DGG.HEALPixSystem(), 1)
target = DGG.levelgrid(DGG.HEALPixSystem(), 2)
values = fill(3.0, DGG.ncells(source))
result = DGG.regrid(values; from=source, to=target, method=DGG.NearestCell())
@assert length(result) == DGG.ncells(target)
@assert all(==(3.0), result)
size(result)
(192,)

A dimensional source can describe its own spatial axes. DGGS targets accept complete or partial grids, cell vectors, cell lookups, and mixed-level sets. A bare system as to chooses a level from the source resolution. Use an explicit grid when the level must be fixed.

Source spatial dimensions must come first and follow the source space's cell order. Other dimensions follow them in their original order. Dimensional results use the destination's axes; DGGS destinations provide a Cells axis. Plain array inputs return arrays. Results are floating point, including containing-cell transfers of integer categories.

Reuse a plan or destination ​

A plan fixes the spaces, cell order, method, and weight policy. Reuse it for fields with that same spatial layout; changing geometry or cell order requires a new plan.

julia
plan = DGG.plan_regrid(values; from=source, to=target,
    method=DGG.NearestCell())
dest = zeros(DGG.ncells(target))
DGG.regrid!(dest, 2 .* values, plan)
@assert dest == 2 .* result
sum(dest)
1152.0

regrid(values, plan) allocates a result. regrid!(dest, values, plan) uses existing storage. The destination must have the expected shape and an element type that can hold its missing-value sentinel. A dimensional source can contain time or band slices; one plan serves those slices without rebuilding weights.

Lazy execution and memory ​

ControlMeaning
lazy=trueCompute destination data on demand; defaults to true for chunked sources
chunksLazy output tiling; separate from the spatial chunks in DGGSpace
budgetTarget bytes for lazy reads and weights, not a strict total-process memory limit
storage=PerChunk()Cache lazy weight blocks; this explicit form has no cache size limit
storage=Spilled(directory)Store lazy weight blocks on disk
DGGSpace(grid; chunklevel, chunkcells)Control the DGGS space's ancestor chunks

Without an explicit storage policy, lazy plans use a budget-limited cache. chunks, budget, and storage apply to lazy execution. sampling controls lookup sampling for eager execution. See Assigning chunks to workers for partitioning an existing lazy plan's dependencies.

Missing-value normalization and output sentinels are separate choices; read Missing data before reusing a plan across fields with different coverage.

Callable reference ​

GlobalRegridding.regrid Function
julia
regrid(data; to, from = nothing, method = Conservative(),
       missingpolicy = Weighted(0.5), missingval = sourcemissingval(data),
       lazy = declareschunks(data), chunks = nothing, budget = nothing,
       storage = nothing, sampling = nothing, locator = TreeLocator())
regrid(data, plan::AbstractRegriddingPlan; missingval = outputmissingval(data))

Regrid data onto to. Spatial dimensions must come first and flatten in the source space's cell order. Non-spatial dimensions retain their order. One plan is reused for all non-spatial slices.

A dimensional source comes back labelled with the destination's own axes — a RasterGrid echoes the dimension order it was constructed with — followed by its unchanged non-spatial dimensions. Destinations without axes of their own keep a flat Cell axis. Lazy results carry the same labels and shape over a disk-backed array.

Results are floating point. Weighted blanks uncovered destination cells with the source's own nodata sentinel (outputmissingval): a Rasters.AbstractRaster comes back as a raster declaring the missingval it was handed, and every other array takes missing when its element type holds it and NaN otherwise.

Keyword arguments

  • to: destination RegridSpace, a dimensional raster or tuple of dimensions naming a RasterGrid, or a package-specific target.

  • from: source space, spelled any of those ways; nothing derives a RasterGrid from data.

  • method: weight-building method; defaults to Conservative.

  • locator: how candidate cells are found while weights are built, a CandidateLocator; defaults to TreeLocator. The weights do not depend on it.

  • missingpolicy: Weighted means or Extensive sums.

  • missingval: the nodata sentinel of the regrid — invalid in the source, and written into blanked destination cells. Left out, the source's comes from sourcemissingval(data) and the destination's from outputmissingval(data), a raster's own missingval. missing and NaN are always invalid whatever it is. Give it a value the destination element type holds and the result stays concrete: missingval = NaN regrids a Union{Missing,Float64} raster into a Float64 one.

  • lazy: compute on demand (LazyRegridArray); defaults to chunked sources.

  • chunks: lazy destination tiling. nothing derives it automatically.

  • budget: target bytes for lazy reads and weights, default 2^31.

  • storage: lazy weight storage, PerChunk or Spilled.

  • sampling: destination lookup sampling. nothing follows the method — area-based methods give Intervals, point samples give Points (outputsampling).

chunks, budget and storage apply only to lazy = true, and sampling only to lazy = false. The plan form takes missingval alone: a plan settles how weights are built, and the sentinel is what the caller does with them.

Every other keyword above is plan_regrid's and is forwarded to it, so each default and each check is stated there once. The relation keywords dependencies, refine and narrow describe a plan that is kept and are refused here.

source
GlobalRegridding.regrid! Function
julia
regrid!(dest, data; to, from = nothing, method = Conservative(),
        missingpolicy = Weighted(0.5), missingval = destinationmissingval(dest),
        lazy = declareschunks(data), chunks = nothing, budget = nothing,
        storage = nothing, sampling = nothing)
regrid!(dest, data, plan::AbstractRegriddingPlan;
        missingval = destinationmissingval(dest))

Regrid data into the preallocated dest and return dest.

dest starts with the destination's own axes, or one flat cell dimension, followed by data's non-spatial dimensions; either leading shape is accepted. Keywords match regrid and are forwarded to plan_regrid.

dest declares the destination's nodata convention here, so missingval defaults to destinationmissingval(dest) — its own missingval for a Rasters.AbstractRaster, and missing or NaN for a plain array. Passing one names the sentinel on both sides, as it does for regrid, and it must be a value eltype(dest) holds.

source
GlobalRegridding.plan_regrid Function
julia
plan_regrid(data; to, from = nothing, method = Conservative(),
            missingpolicy = Weighted(0.5), missingval = sourcemissingval(data),
            lazy = declareschunks(data), chunks = nothing, budget = nothing,
            storage = nothing, sampling = nothing, dependencies = nothing,
            refine = nothing, narrow = nothing) -> AbstractRegriddingPlan

Build a reusable regridding plan without reading source values. missingval is the source sentinel alone here — a plan reads data and never writes it, so the destination's sentinel belongs to regrid. In-memory data uses one whole-domain DirectPlan. Lazy plans build blocks on demand and default to a budget-limited PerChunk cache. Use PerChunk() for an unlimited cache or Spilled(dir) for disk storage. Keywords match regrid; chunks, budget, storage, dependencies, refine and narrow apply only to lazy = true, and sampling only to lazy = false.

The chunk dependency relation

A lazy plan is the sole owner of its chunk dependency relation, and this is the only place a narrow phase may be supplied. dependencies chooses whether the plan builds one (nothing, the default, or true), adopts and validates one somebody else built (a ChunkDependencyGraph), or holds none (false). Every lazy read needs one — for tile order, wave costing, refcounts and prefetch, and on the chunk-pair route for the source chunks themselves — so a plan that holds none cannot back a LazyRegridArray. refine is the conservative narrow phase to apply while building, refine(dstchunk, srcchunk) -> Bool, and narrow the Symbol that names it in the relation's identity. A refine must only ever reject pairs it can prove disconnected; a wrong one silently corrupts results. dependencies documents each branch.

dependencies(plan) reads the relation back and builds nothing. It is deliberately impossible to narrow, replace or rebuild a plan's relation once the plan exists: regrid and regrid! forward every other keyword here but refuse dependencies, refine and narrow, and chunk_dependency_graph has no plan method. A caller that wants a different relation makes a different plan.

source
DiscreteGlobalGrids.DGGSpace Type
julia
DGGSpace(grid::AbstractGrid; chunklevel = nothing, chunkcells = 4096)

Wrap grid as a GlobalRegridding.RegridSpace.

Chunks are non-empty ancestor subtrees at chunklevel. By default, the level is chosen to keep roughly chunkcells cells per chunk. Grids without sorted subtrees use one chunk. Construction computes only one covering cap per chunk.

source

Point methods and weight storage ​

Conservative, Weighted, and Extensive are documented on the method-choice page.

GlobalRegridding.NearestCell Type
julia
NearestCell()

Give weight 1 to the source cell containing each destination centroid.

Requires cellcentroid of the destination space and cellat of the source space. A destination centroid outside the source's coverage emits no entry at all; the missing policy decides what that destination cell becomes.

This method does not preserve integrals.

source
GlobalRegridding.DirectNearest Type
julia
DirectNearest()

Take each destination's value from the source cell containing its sample site, without building weights for it.

The stencil is NearestCell's exactly — one source cell, weight one — and so are the results, element for element, under either missing policy and with any nodata sentinel. What differs is that no WeightCOO, WeightBlock or sparse matrix is ever assembled: a plan holds only the two spaces, and the apply loop calls cellat per destination cell and copies the value across.

Which of the two to use

Prefer DirectNearest when the operator is applied about as many times as it is built — a one-shot regrid, or a chunked run whose plan serves one destination column and is then dropped, which is every lazy read. It allocates far less: the plan is O(1) rather than a row per destination cell, and a chunked read carries one Int per cell of the tile instead of a sparse block per source chunk. That is what it buys, and under many concurrent workers sharing one heap it is most of what matters.

Prefer NearestCell when one plan is applied to many different sources. Its matrix locates every destination once, for good, and each later application is a gather over stored indices; DirectNearest re-locates every destination on every application, and locating is the expensive half. Both methods locate once for all the non-spatial slices of a single source, so a multi-slice source is not the case this distinguishes. NearestCell is also the one to reach for when the operator itself is wanted — to inspect, to store, or to apply outside this package — since DirectNearest never materializes one.

buildweights! is still supplied, so any route that has not been specialized for this method (a chunk pair built through pairblock, a weight file, a test) falls back to NearestCell's own assembly and answers the same.

source
GlobalRegridding.BarycentricPoint Type
julia
BarycentricPoint(; poles = NearestCell())

Interpolate between source sample sites at each destination sample site.

  • The stencil is the dual cell of source sample sites containing the point, weighted by the coordinates that cell's basis names: tensor Q1 on a quadrilateral, or mean-value coordinates on a convex polygon, which on a triangle are that triangle's barycentric coordinates.

  • Weights are nonnegative and sum to one, so the result lies between the source values it came from. Integrals are not preserved.

  • Requires cellcentroid of the destination space and a source space that answers point queries; a destination outside the source's dual complex emits no entry at all and the missing policy decides what it becomes.

  • poles is the policy where a source's own sample sites stop short of a pole: NearestCell takes the nearest site of the polemost row with weight one, nothing leaves those points unmapped. A source whose sites reach the poles — every conforming grid — has no such region and ignores it.

source
GlobalRegridding.PerChunk Type
julia
PerChunk(capacity)
PerChunk(; capacity = typemax(Int), maxbytes = typemax(Int))

Cache weight blocks, evicting least-recently-used entries when capacity or maxbytes is exceeded.

  • A chunk pair is keyed by (destination chunk, source chunk); a point method whose build unit is a destination tile is keyed by tile number instead, through gettile!.

  • The newest entry is retained. Tiles and chunk pairs share the recency clock, the entry count and the byte budget, and evict each other by recency alone.

  • Builds run outside the lock. Duplicate concurrent builds of a pair keep the first result; one tile is built once, a request meeting a build already in flight waiting for it.

source
GlobalRegridding.Spilled Type
julia
Spilled(dir; capacity = typemax(Int), maxbytes = typemax(Int))

Store blocks in scratch directory dir behind a PerChunk cache.

  • The caller owns dir and its lifetime, deleting it included.

  • Filenames carry a per-instance tag, so only this storage can read them: once the plan is dropped they are unreadable garbage.

source

Index ​