API Reference

Module

SatelliteGriddingModule
SatelliteGridding

A Julia package for gridding satellite Level-2 data onto regular rectangular grids with footprint-aware oversampling.

Satellite instruments have irregularly shaped footprints (quadrilaterals defined by 4 corner coordinates) that can overlap multiple output grid cells. Rather than computing exact geometric intersections, this package subdivides each footprint into n×n sub-pixels and uses "point-in-box" binning. The mean per grid cell is computed incrementally using Welford's online algorithm for numerical stability.

Main functions

  • grid_l2: Grid Level-2 data with footprint oversampling
  • grid_center: Grid data using center coordinates only (e.g., MODIS)
  • load_config: Load a TOML/JSON data source configuration

Example

using SatelliteGridding

config = load_config("tropomi_sif.toml")
grid_spec = GridSpec(lat_min=-90f0, lat_max=90f0, lon_min=-180f0, lon_max=180f0,
                     dlat=1f0, dlon=1f0)
time_spec = TimeSpec(DateTime("2019-01-01"), DateTime("2019-12-31"),
                     Dates.Day(8), 1.0f0)
grid_l2(config, grid_spec, time_spec; outfile="output.nc")
source

Main Functions

SatelliteGridding.gridFunction
grid(config, grid_spec, time_spec; method=SubpixelGridding(), kwargs...)
grid(config, grid_spec, time_spec, method::AbstractGriddingMethod; kwargs...)

Dispatch-based library entry point for gridding. The CLI still exposes explicit l2 and center commands, while library callers can choose a gridding method with a first-class type such as SubpixelGridding, CircularFootprintGridding, or CenterPointGridding.

source
SatelliteGridding.grid_l2Function
grid_l2(config, grid_spec, time_spec; kwargs...)

Grid Level-2 satellite data with footprint-aware oversampling.

Reads input NetCDF files as specified by config, applies quality filters, subdivides each satellite footprint into sub-pixels for proper overlap handling, and accumulates gridded averages. Output is written to a NetCDF4 file. Quadrilateral footprints are used by default; pass footprint_method=CircularFootprintGridding(...) for circular products such as GOSAT. Circular footprints can be read from lat_bnd/lon_bnd or from center lat/lon plus radius.

Arguments

  • config::DataSourceConfig: Data source configuration (from TOML/JSON)
  • grid_spec::GridSpec: Output grid geometry
  • time_spec::TimeSpec: Temporal binning parameters

Keyword Arguments

  • n_oversample::Union{Nothing,Int}=nothing: Sub-pixel factor. nothing = auto-compute from footprint/grid ratio.
  • footprint_method::AbstractGriddingMethod=SubpixelGridding(n_oversample): Footprint geometry method.
  • compute_std::Bool=false: Also compute per-cell standard deviation
  • outfile::String="gridded_output.nc": Output file path
  • backend: KernelAbstractions backend (default: nothing for sequential Welford path). Use CPU(), CUDABackend(), MetalBackend(), or another compatible KA backend.
  • keep_going::Bool=false: Continue after per-file errors. By default, the first file error stops the run.
source
SatelliteGridding.grid_centerFunction
grid_center(config, grid_spec, time_spec; kwargs...)

Grid data using center coordinates only (no footprint bounds), suitable for MODIS-style data where each pixel maps to exactly one grid cell.

Keyword Arguments

  • geo_table::Union{Nothing,String}=nothing: Path to a legacy monolithic geolocation lookup table (NetCDF)
  • geo_cache::Union{Nothing,String}=nothing: Directory for generated per-tile MODIS geolocation cache
  • geo_provider::Union{Symbol,String}=:auto: :auto, :variables, :lut, or :modis
  • veg_indices::Bool=false: Compute vegetation indices (EVI, NDVI, NIRv, NDWI)
  • compute_std::Bool=false: Compute per-cell standard deviation
  • outfile::String="gridded_output.nc": Output file path
  • keep_going::Bool=false: Continue after per-file errors. By default, the first file error stops the run.
source
SatelliteGridding.load_configFunction
load_config(config_path::String) -> DataSourceConfig

Load a configuration file (TOML or JSON) and return a DataSourceConfig.

The file must contain a [grid] section plus filePattern and folder. Footprint-aware L2 gridding usually uses [basic] entries for lat_bnd and lon_bnd. Circular footprints can alternatively use center lat/lon plus a radius variable or scalar [circle] radius. Center-coordinate gridding can use [basic] lat and lon, a geolocation lookup table, or generated MODIS sinusoidal geolocation. Filters are defined in an optional [filter] section using intuitive string expressions:

Example TOML

filePattern = "S5P_PAL__L2B_SIF____YYYYMMDD*.nc"
folder = "/path/to/data/"

[basic]
lat = "PRODUCT/latitude"
lon = "PRODUCT/longitude"
lat_bnd = "PRODUCT/SUPPORT_DATA/GEOLOCATIONS/latitude_bounds"
lon_bnd = "PRODUCT/SUPPORT_DATA/GEOLOCATIONS/longitude_bounds"

[grid]
sif_743 = "PRODUCT/SIF_743"
sif_735 = "PRODUCT/SIF_735"

[filter]
"PRODUCT/SUPPORT_DATA/GEOLOCATIONS/solar_zenith_angle" = "< 80"
"PRODUCT/qa_value" = "> 0.5"
"PRODUCT/methane" = "1600 < x < 2200"
"PRODUCT/mode" = "== 1"

The legacy JSON format with separate filter_gt/filter_lt/filter_eq sections is still supported for backward compatibility.

source

Backends

SatelliteGridding.resolve_backendFunction
resolve_backend(name) -> Union{Nothing, KernelAbstractions.Backend}

Resolve a user-facing backend name to a KernelAbstractions backend object. The optional GPU packages are weak dependencies and are loaded only when the corresponding backend is requested.

source

Types

SatelliteGridding.AbstractGridSpecType
AbstractGridSpec{T<:AbstractFloat}

Common supertype for output-grid specifications. Subtypes describe how a satellite observation's (lat, lon) maps onto cell indices on a particular grid geometry and how the matching output NetCDF file is laid out.

Every concrete subtype G <: AbstractGridSpec{T} must implement five methods so the same gridder/oversampling/ncio machinery serves all grids via multiple dispatch:

MethodReturnsPurpose
to_fractional_index(spec, lat, lon)Tuple of fractional indicesProject a point onto continuous cell indices
in_bounds(spec, lat, lon)BoolCheap scalar bounding-box pre-filter
grid_shape(spec)NTuple{N, Int}Spatial size of the output accumulator array
payload_dims(spec)NTuple{N, String}NetCDF dimension names for payload variables
write_coordinates!(ds, spec)NothingWrite the spatial coordinate axes / aux coords to a NetCDF dataset

N is the spatial dimensionality of the accumulator: 2 for a regular lat/lon grid ((n_lon, n_lat)), 3 for a cubed sphere ((Nc, Nc, 6)). The fractional-index tuple is allowed to mix types when an axis is categorical (e.g. cubed sphere returns (panel::Int, s::T, t::T)), so the return type is documented as Tuple rather than NTuple{N, T}. The first N integer cell indices recovered via floor(Int, …) along spatial axes match grid_shape(spec) axis-for-axis.

source
SatelliteGridding.RectangularGridSpecType
RectangularGridSpec{T<:AbstractFloat} <: AbstractGridSpec{T}

Output grid on a regular latitude/longitude rectangle with uniform cell spacing. The legacy name GridSpec is a const alias of this type for back-compatibility.

Fields

  • lat_min, lat_max: Latitude bounds (degrees)
  • lon_min, lon_max: Longitude bounds (degrees)
  • dlat, dlon: Grid cell size (degrees)
  • lat, lon: Vectors of cell center coordinates
source
SatelliteGridding.TimeSpecType
TimeSpec

Specification of the temporal gridding parameters.

Two temporal modes are supported:

  • Tiled (default): snapshots are spaced by time_step; each snapshot averages a forward window [d, d + time_step·oversample_temporal − 1 day]. With oversample_temporal == 1 the windows tile with no overlap.
  • Rolling mean: set sample_step and window_halfwidth_days. Snapshots are spaced by sample_step and each averages a centered window [c − N, c + N] (N = window_halfwidth_days). When 2N+1 > sample_step the windows overlap, smoothing the temporal evolution. Each calendar day is gridded only once and reused across overlapping windows (in-memory day cache). time_step/oversample_temporal are ignored in this mode.

Fields

  • start_date, stop_date: Date range of snapshot centers
  • time_step: Tiled-mode bin size (Dates.Day or Dates.Month)
  • oversample_temporal: Tiled-mode window multiplier (>1 gives moving-average-like behavior)
  • sample_step: Rolling-mode snapshot spacing (Dates.Day), or nothing for tiled mode
  • window_halfwidth_days: Rolling-mode half-width N (days), or nothing for tiled mode
source
SatelliteGridding.DataSourceConfigType
DataSourceConfig

Configuration loaded from a TOML/JSON file that defines a satellite data source.

Fields

  • basic: Maps internal keys ("lat", "lon", "lat_bnd", "lon_bnd", "radius") to variable paths in the NetCDF files
  • grid_vars: Ordered mapping of output variable names to input variable paths (all will be gridded)
  • filters: Quality filter rules parsed from [filter] section
  • file_pattern: Glob pattern with YYYY/MM/DD/DOY placeholders for finding input files
  • folder: Root folder for input data (may also contain YYYY/MM/DD placeholders)
  • options: Optional processing settings from [options], [center], or [modis]
source
SatelliteGridding.FilterRuleType
FilterRule

A single filter condition for a NetCDF variable.

Fields

  • variable: Path to the NetCDF variable (may include group separators /)
  • op: Operation — :lt, :gt, :eq, :between
  • lo: Lower bound (threshold for :gt/:lt/:eq, low end for :between)
  • hi: Upper bound (only used for :between)

Config syntax (TOML [filter] section)

[filter]
"solar_zenith_angle" = "< 80"         # less than
"qa_value" = "> 0.5"                  # greater than
"mode" = "== 1"                       # equality
"methane" = "1600 < x < 2200"         # range (between)
source
SatelliteGridding.SubpixelGriddingType
SubpixelGridding(; n_oversample=nothing)

Footprint-aware gridding by sampling an n × n grid of subpoints inside each quadrilateral footprint. nothing keeps the existing automatic oversampling heuristic.

source
SatelliteGridding.CircularFootprintGriddingType
CircularFootprintGridding(; n_oversample=nothing)

Footprint-aware gridding for circular or near-circular footprints described by a center coordinate and four bounding coordinates. The implementation samples an n × n grid over the footprint bounding box and keeps points inside the inferred circle or ellipse. nothing keeps the existing automatic oversampling heuristic.

source
SatelliteGridding.ExactIntersectionGriddingType
ExactIntersectionGridding()

Reserved method for exact footprint/grid-cell intersection gridding. This is not implemented yet, but the type keeps the public API open for an exact geometry backend without changing callers.

source

Cubed-Sphere Grids

SatelliteGridding.CubedSphereGridSpecType
CubedSphereGridSpec{T,D} <: AbstractGridSpec{T}

Cubed-sphere output grid with Nc cells per panel edge and 6 panels (6·Nc² cells total). The default definition is GMAOCubedSphereDefinition — the GEOS/GCHP convention (equal-distance gnomonic, GEOS-native panels, -10° longitude shift), e.g. CubedSphereGridSpec(Nc=360) for C360.

Accumulator folding

Internally the cube (Nc, Nc, 6) is folded into a 2D accumulator of shape grid_shape(spec) = (Nc, 6·Nc) so the existing rectangular gridder machinery (_welford_update!, finalize_mean!, accumulate_center!) is reused unchanged: cell (i, j, panel) maps to col = i, row = (panel-1)·Nc + j. to_fractional_index returns the folded (col, row); the NetCDF writer un-folds via reshape(slice, Nc, Nc, 6) back to (Xdim, Ydim, nf).

Fields

  • Nc::Int: cells per panel edge
  • definition::D: cubed-sphere geometry contract
  • centers_lon, centers_lat: (Nc, Nc, 6) cell-center coords (degrees, lon in [0,360))
  • corners_lon, corners_lat: (Nc+1, Nc+1, 6) cell-corner coords (degrees)
source
SatelliteGridding.CubedSphereDefinitionType
CubedSphereDefinition(coordinate_law, center_law, panel_convention;
                      longitude_offset_deg=0, tag=:custom)

Complete horizontal cubed-sphere geometry contract: how logical face edges are placed on the gnomonic cube (coordinate_law), how cell centers are derived (center_law), how the six faces are ordered/oriented (panel_convention), and a final rigid z-axis rotation (longitude_offset_deg). For native GMAO files use GMAOCubedSphereDefinition.

source
SatelliteGridding.GMAOCubedSphereDefinitionFunction
GMAOCubedSphereDefinition(; convention=GEOSNativePanelConvention(),
                            longitude_offset_deg=-10)

Native GMAO/GEOS cubed-sphere definition used by GEOS-IT C180 / GEOS-FP C720 (and GCHP when driven by GMAO met): GMAOEqualDistanceGnomonic edges, FourCornerNormalizedCenter centers, GEOSNativePanelConvention, and a final -10° longitude shift. This is the default for CubedSphereGridSpec.

source
SatelliteGridding.lonlat_to_panel_xyFunction
lonlat_to_panel_xy(def::CubedSphereDefinition, Nc, lon_deg, lat_deg, FT)
    -> (panel::Int, s_frac, t_frac)

Closed-form inverse of the cubed-sphere forward map for a single (lon, lat) in degrees. Returns the panel id panel ∈ 1..6 and continuous edge indices s_frac, t_frac on the panel's [1, Nc+1)² parameter square (half-open at the upper edge). The integer cell index is floor(Int, s_frac) (x) and floor(Int, t_frac) (y), guaranteed in 1..Nc for every finite (lon, lat) — upper-edge points are nudged to prevfloat(Nc+1) and sub-1 round-off is raised to 1, the standard half-open-cell convention. The whole sphere is covered.

Honors the definition's panel convention, coordinate law, and longitude offset.

source
SatelliteGridding.accumulator_shapeFunction
accumulator_shape(spec::AbstractGridSpec) -> NTuple{M, Int}

Spatial dimensions of the in-memory accumulator array that the gridder allocates, in the same axis order as the indices returned by to_fractional_index. This is the layout the Welford / scatter machinery indexes with (col, row).

For grids whose accumulator matches the NetCDF spatial layout this is just grid_shape (the default). A cubed-sphere grid folds its (Nc, Nc, 6) cube into a 2D (Nc, 6·Nc) accumulator and un-folds only at write time, so its accumulator_shape equals its (already-folded) grid_shape.

source

Oversampling

SatelliteGridding.sort_corners_ccwFunction
sort_corners_ccw(lat_corners, lon_corners) -> (sorted_lat, sorted_lon)

Sort 4 footprint corners into counter-clockwise order by computing the angle from the centroid to each corner. This ensures edges 1→2 and 4→3 are always opposite edges, which is required by compute_subpixels!.

Different satellite products store corners in different orders (e.g., TROPOMI uses CCW order while OCO-2 uses a different convention). This function normalizes them.

source
SatelliteGridding.sort_corners_ccw_ka!Function
sort_corners_ccw_ka!(backend, lat_mat, lon_mat)

KA kernel that sorts footprint corners into CCW order for all soundings in parallel. Uses a 5-comparator sorting network (optimal for 4 elements, no allocations).

  • lat_mat, lon_mat: N×4 matrices of corner coordinates
source
SatelliteGridding.compute_subpixels!Function
compute_subpixels!(points, vert_lat, vert_lon, n, lats_0, lons_0, lats_1, lons_1)

Fill the n×n×2 array points with sub-pixel positions inside the quadrilateral defined by 4 corner coordinates (vert_lat[1:4], vert_lon[1:4]).

The algorithm:

  1. Subdivide edge 1→2 into n baseline points
  2. Subdivide edge 4→3 into n baseline points
  3. For each pair of corresponding baseline points, subdivide the connecting line into n interior points

This produces sub-pixels that fill the footprint quadrilateral. Temporary buffers lats_0, lons_0, lats_1, lons_1 (each length n) must be provided.

source
SatelliteGridding.floor_indices!Function
floor_indices!(ix, iy, points)

Convert the floating-point sub-pixel positions in points to integer grid cell indices via floor. Results stored in ix and iy (each length ).

source
SatelliteGridding.compute_n_oversampleFunction
compute_n_oversample(footprint_extent, cell_size; n_min=2, n_max=20)

Estimate an appropriate oversampling factor n based on the ratio of footprint size to grid cell size. Aims for ~3 sub-pixels per grid cell width.

Returns an integer in [n_min, n_max].

source
SatelliteGridding.compute_footprint_indices_ka!Function
compute_footprint_indices_ka!(backend, ix_out, iy_out, skip_flag,
                              lat_corners, lon_corners, n)

KA kernel that computes n×n sub-pixel grid indices for each footprint. Also sets skip_flag[fp] = true if the footprint's longitude extent >= n (too wide to oversample meaningfully).

For footprints where all 4 corners fall in the same cell, the kernel stores the single cell index in position 1 and marks all other positions with ix=-1 (sentinel). The accumulation kernel handles these fast-path footprints by checking skip_flag.

  • ix_out: (n_fp, n²) Int32 — lat grid cell indices
  • iy_out: (n_fp, n²) Int32 — lon grid cell indices
  • skip_flag: (n_fp,) Int32 — 0=oversample, 1=fast-path (single cell), 2=skip (too wide)
  • lat_corners, lon_corners: (n_fp, 4) — fractional grid indices of corners
  • n: oversampling factor
source
SatelliteGridding.compute_circular_footprint_indices_ka!Function
compute_circular_footprint_indices_ka!(backend, ix_out, iy_out, inside_count,
                                       skip_flag, center_lat, center_lon,
                                       lat_corners, lon_corners, n)

KA kernel that computes sampled grid-cell indices for circular or near-circular footprints. The four coordinates define the footprint bounding box or edge points around the center coordinate. Points outside the inferred circle/ellipse are marked with -1; inside_count[fp] stores the number of valid samples used for normalizing the scatter weight.

source

Geometry

SatelliteGridding.exact_footprint_weightsFunction
exact_footprint_weights(lat_corners, lon_corners; n_lon, n_lat)

Compute exact planar overlap weights between one quadrilateral footprint and regular grid cells in fractional grid-index coordinates. The returned matrix has shape (n_lon, n_lat) and sums to one when the footprint is fully inside the domain.

source
SatelliteGridding.circle_footprint_weightsFunction
circle_footprint_weights(center_lat, center_lon, lat_corners, lon_corners;
                         n_lon, n_lat, n_oversample)

Compute sampled per-cell weights for one circular or near-circular footprint in fractional grid-index coordinates. The four coordinates define the footprint bounding box or edge points. In grid-index space the sampled shape may be an ellipse when the output grid has unequal latitude and longitude resolutions.

source
circle_footprint_weights(center_lat, center_lon, radius_lat, radius_lon;
                         n_lon, n_lat, n_oversample)

Convenience overload for a circular or elliptical footprint specified directly by center coordinate and radius in fractional grid-index units.

source
SatelliteGridding.footprint_weightsFunction
footprint_weights(method, lat_corners, lon_corners; n_lon, n_lat)

Return per-cell footprint weights for a single footprint using the requested geometry method. This is a lightweight geometry-level API used by tests and by future exact-intersection gridders.

source

Accumulation

SatelliteGridding.accumulate_footprint!Function
accumulate_footprint!(grid_data, grid_std, grid_weights, compute_std,
                      lat_idx, lon_idx, values, n_pixels, n_vars, n_oversample,
                      grid_spec, points_buf, ix_buf, iy_buf,
                      lats0_buf, lons0_buf, lats1_buf, lons1_buf)

Accumulate a batch of satellite observations into the output grid using footprint-aware oversampling and Welford's online averaging algorithm.

For each pixel:

  • Fast path: If all 4 corner coordinates fall into the same grid cell, the full observation value is assigned to that cell (weight=1).
  • Oversample path: If the footprint spans multiple cells, it is subdivided into n_oversample × n_oversample sub-pixels. Each sub-pixel contributes weight 1/n² to whichever grid cell it falls in.

The Welford algorithm maintains a running mean and sum-of-squared-deviations (M2), enabling numerically stable computation of mean and variance in a single pass.

Arguments

  • grid_data: Output array (n_lon, n_lat, n_vars) — running mean
  • grid_std: Output array (n_lon, n_lat, n_vars) — running M2 (sum of squared deviations)
  • grid_weights: Output array (n_lon, n_lat) — accumulated weights
  • compute_std: Whether to track variance
  • lat_idx, lon_idx: Pre-computed fractional grid indices for corners, size (n_pixels, 4)
  • values: Input data, size (n_pixels, n_vars)
  • n_pixels: Number of observations in this batch
  • n_vars: Number of variables being gridded
  • n_oversample: Sub-pixel subdivision factor (n)
  • Remaining arguments are pre-allocated work buffers
source
SatelliteGridding.accumulate_footprint_cs!Function
accumulate_footprint_cs!(grid_data, grid_std, grid_weights, compute_std, spec,
                         lat_c, lon_c, values, n_pixels, n_vars, n_oversample,
                         points_buf, lats0_buf, lons0_buf, lats1_buf, lons1_buf)

Footprint-aware accumulation onto a CubedSphereGridSpec folded into the (Nc, 6·Nc) accumulator. Unlike the rectangular [accumulate_footprint!], the subdivision happens in lon/lat space (not fractional-index space) because the cubed-sphere map is nonlinear and discontinuous across panel boundaries; each sub-point is then projected independently via [to_fractional_index], so a footprint straddling a cube edge correctly deposits weight on both panels.

For each pixel:

  • Fast path: all 4 corners project to the same (col, row) cell → full value, weight 1.
  • Oversample path: subdivide the corner quadrilateral into n × n sub-points (longitudes unwrapped to a common ±180° branch first, so the linear interpolation is sane for near-pole footprints that span the dateline), project each, and add weight 1/n² to the cell it lands in.

lat_c/lon_c are (n_pixels, 4) corner coordinates in degrees (CCW-sorted); lat_center/lon_center are (n_pixels,) center coordinates. Buffers match [compute_subpixels!].

source
SatelliteGridding.accumulate_circular_footprint!Function
accumulate_circular_footprint!(grid_data, grid_std, grid_weights, compute_std,
                               center_lat_idx, center_lon_idx,
                               lat_idx, lon_idx, values,
                               n_pixels, n_vars, n_oversample)

Accumulate observations with circular or near-circular footprints. The center coordinate gives the footprint center and the four coordinates define its bounding box or edge points. Sampling is done in fractional grid-index space.

source
SatelliteGridding.accumulate_batch!Function
accumulate_batch!(backend, grid_sum, grid_weights,
                  lat_corners, lon_corners, values, n;
                  compute_std=false, grid_std=nothing, grid_mean=nothing)

Accumulate observations into the grid using the KA kernel pipeline. This function works identically on CPU and GPU backends.

The pipeline:

  1. Sort corners into CCW order
  2. Compute n×n subpixel grid indices per footprint
  3. Scatter-accumulate weighted sums into grid cells (using atomics)

After processing all files, call finalize_mean! to convert sums to means.

For compute_std=true, a two-pass approach is used:

  1. First call accumulate_batch! without std to accumulate sums
  2. Call finalize_mean! to get the mean
  3. Call accumulate_std_pass! with the computed mean to accumulate variance

Arguments

  • backend: KernelAbstractions backend (CPU(), CUDABackend(), MetalBackend(), etc.)
  • grid_sum: (nlon, nlat, n_vars) — weighted sum accumulator
  • grid_weights: (nlon, nlat) — weight accumulator
  • lat_corners, lon_corners: (n_fp, 4) — fractional grid indices of corners
  • values: (nfp, nvars) — observation values
  • n: oversampling factor
source
SatelliteGridding.accumulate_circular_batch!Function
accumulate_circular_batch!(backend, grid_sum, grid_weights,
                           center_lat, center_lon,
                           lat_corners, lon_corners, values, n, n_vars)

Accumulate circular or near-circular footprints using the KA pipeline. This is the sum-based backend counterpart to accumulate_circular_footprint! and works with KA CPU, CUDA, Metal, and other compatible backends.

source
SatelliteGridding.accumulate_center!Function
accumulate_center!(grid_data, grid_weights, lat, lon, values, grid_spec)

Accumulate observations using center coordinates only (no footprint bounds). Used for MODIS-style gridding where each pixel maps to exactly one grid cell. Simple sum accumulation — divide by grid_weights afterward to get the mean.

source
SatelliteGridding.scatter_accumulate!Function
scatter_accumulate!(grid_sum, grid_weights, ix, iy, skip_flag, values, n, n_vars)

Sequential scatter-accumulate of weighted values into grid cells. Uses precomputed grid indices from compute_footprint_indices_ka!.

For each footprint:

  • skip_flag == 1 (fast path): add weight=1, value to single cell
  • skip_flag == 0 (oversample): add weight=1/n² to each subpixel's cell
  • skip_flag == 2 (skip): do nothing

This function is sequential (no atomics needed) and works with any array type. For GPU backends, use the @kernel version with @atomic instead.

  • grid_sum: (nlon, nlat, n_vars) — weighted sum accumulator
  • grid_weights: (nlon, nlat) — weight accumulator
  • ix, iy: (n_fp, n²) — precomputed grid indices
  • skip_flag: (n_fp,) — 0=oversample, 1=fast-path, 2=skip
  • values: (nfp, nvars) — observation values
source
SatelliteGridding.scatter_accumulate_ka!Function
scatter_accumulate_ka!(backend, grid_sum, grid_weights,
                       ix, iy, skip_flag, values, n, n_vars)

KA kernel version of scatter-accumulate using @atomic for thread safety. Required for GPU backends where multiple threads write to the same grid cells. For CPU backends, use scatter_accumulate! (sequential) instead.

source
SatelliteGridding.scatter_accumulate_circular!Function
scatter_accumulate_circular!(grid_sum, grid_weights, ix, iy, inside_count,
                             skip_flag, values, n, n_vars)

Sequential scatter-accumulate for circular footprints. Oversampled footprints use per-footprint weights 1 / inside_count[fp] because samples outside the circle/ellipse are masked out.

source
SatelliteGridding.finalize_mean!Function
finalize_mean!(grid_data, grid_weights)

Convert weighted-sum accumulator to mean: mean = sum / weight. Cells with near-zero weight are left as zero.

source

I/O

SatelliteGridding.find_filesFunction
find_files(pattern::String, folder::String, date::DateTime) -> Vector{String}

Find input files matching the given pattern for a specific date.

Resolves YYYY, YY, MM, DD, and DOY placeholders in both pattern and folder, then globs for matching files. Returns only non-empty files.

source
SatelliteGridding.read_nc_variableFunction
read_nc_variable(dataset, path::String; bounds=false)

Read a variable from a NetCDF dataset, handling nested groups via / separators.

If bounds=true, reshape the result so that footprint vertices are in the last dimension, returning an N×4 matrix (N soundings, 4 corners).

source
SatelliteGridding.read_variable_from_fileFunction
read_variable_from_file(path, variable; bounds=false)

Read a variable from a NetCDF-like file. Falls back to the system libnetcdf for flat HDF4/HDF-EOS variables when the Julia NetCDF build cannot open them.

source
SatelliteGridding.read_system_netcdf_variableFunction
read_system_netcdf_variable(path, varname)

Read a flat variable through the system libnetcdf. This is primarily a fallback for HDF4/HDF-EOS2 files when the Julia NetCDF_jll build lacks HDF4 support.

source
SatelliteGridding.create_output_datasetFunction
create_output_dataset(outfile, grid_spec::CubedSphereGridSpec, n_times,
                      grid_vars, compute_std) -> Dataset, Dict

Cubed-sphere output file: GCHP-style dims Xdim/Ydim/nf (=Nc, Nc, 6) plus an unlimited time. Spatial coordinates (lons/lats and corner_lons/ corner_lats aux arrays, index coords, global attrs) are written by write_coordinates!. Payload variables are 4D (Xdim, Ydim, nf, time).

source

Geolocation

SatelliteGridding.modis_sinusoidal_latlonFunction
modis_sinusoidal_latlon(h, v, line, sample; pixels=2400)

Compute the latitude/longitude at a MODLAND sinusoidal pixel center. h and v are zero-based tile indices; line and sample are one-based pixel indices within the tile.

source
SatelliteGridding.write_modis_tile_geolocationFunction
write_modis_tile_geolocation(path, h, v; pixels=2400, overwrite=false)

Generate and write one MODIS sinusoidal tile geolocation file. The output is a small per-tile NetCDF file with latitude(y, x) and longitude(y, x).

source

Filters

SatelliteGridding.apply_filtersFunction
apply_filters(dataset, config::DataSourceConfig, lat_bounds, lon_bounds,
              grid_spec::GridSpec) -> Vector{Int}

Apply spatial bounding box and quality filters, returning indices of pixels that pass all criteria.

The spatial filter requires all 4 corners to be within the grid bounds and the footprint to not cross the dateline (lon span < 50°). Quality filters from config.filters are applied as additional criteria.

source
apply_filters(dataset, config, lat_bounds, lon_bounds,
              grid_spec::CubedSphereGridSpec) -> Vector{Int}

Cubed-sphere variant: a cubed-sphere grid covers the whole sphere, so there is no spatial bounding box and no dateline span check (a valid high-latitude or near-pole footprint can legitimately span a large longitude range). Only the quality filters from config.filters are applied.

source

Vegetation Indices

SatelliteGridding.compute_eviFunction
compute_evi(red, nir, blue; G=2.5f0, C1=6.0f0, C2=7.5f0, L=10000.0f0)

Compute the Enhanced Vegetation Index (EVI).

EVI = G × (NIR - RED) / (NIR + C1×RED - C2×BLUE + L)
source

CLI

SatelliteGridding.parse_l2_argsFunction
parse_l2_args(args=ARGS) -> Dict

Parse command-line arguments for L2 gridding. Matches the interface of the original gridL2_Dates.jl script.

source
SatelliteGridding.args_to_grid_specFunction
args_to_grid_spec(args::Dict) -> AbstractGridSpec

Convert parsed CLI arguments to a grid spec. Returns a RectangularGridSpec for --gridType rect (default) or a CubedSphereGridSpec for --gridType cs (GEOS/GCHP cubed sphere; requires --Nc).

source