Skip to contents

get.spectral.convolution.rfl() needs SMAC atmospheric-correction coefficients bundled; get.spectral.convolution.srf() needs a real, measured, per-nm SRF table. Neither exists for most sensors – often all that is published (or all a student has, e.g. from an instrument's own ENVI header, or their own camera calibration sheet) is a list of band center wavelengths and full widths at half maximum (FWHM). This function covers that case, from three possible inputs:

Usage

get.spectral.convolution.gaussian(
  df = NULL,
  sensor.i = NULL,
  centers = NULL,
  fwhm = NULL,
  get.plots = FALSE,
  rfl = NULL,
  wave = NULL
)

Arguments

df

A data frame with a wave column (wavelength, nm) and an rfl column (reflectance) – same convention as get.spectral.convolution.rfl()/get.spectral.convolution.srf(). Used for a SINGLE spectrum; for many spectra at once (e.g. an entire LUT), use rfl/wave instead (see below) – much faster, vectorized as one matrix multiplication instead of one call per row.

sensor.i

Optional: a bundled sensor name (see above). If given, centers/fwhm are looked up automatically and any values you also pass for them are ignored.

centers

Optional (required if sensor.i is not given): your own sensor's band center wavelengths, nm.

fwhm

Optional: your own sensor's per-band FWHM, nm, same length and order as centers. Derived from band spacing if omitted.

get.plots

logical, plot the convolved spectrum? Default FALSE. Ignored when rfl/wave (bulk mode) is used instead of df.

rfl

Optional: a matrix or data.frame of MANY reflectance spectra at once, one row per spectrum, columns matching wave (e.g. a LUT's simulated reflectance matrix). When supplied (together with wave), df is ignored and the whole matrix is convolved in one vectorized pass – this is the fast path for large tables.

wave

Required together with rfl: the wavelength grid (nm) rfl's columns are on.

Value

Single-spectrum mode (df): a data frame with one row per band: band (index), wl (center wavelength, nm), fwhm (nm), RFL (convolved reflectance) – sorted by wl. Bulk mode (rfl/wave): a numeric matrix, one row per input spectrum (same row order as rfl), one column per band (named by center wavelength, sorted by wl); the per-band wl/fwhm vectors are attached as attr(out, "wl") / attr(out, "fwhm").

Details

  1. sensor.i = "EnMAP"ToolsRTM::EnMap.characteristics's 242 channels (center + FWHM already given).

  2. sensor.i = one of unique(ToolsRTM::sensor.characteristics$Sensor) ("ALI", "Hyperion", "Landsat4", "Landsat5", "Landsat7", "Landsat8", "MODIS", "Quickbird", "RapidEye", "Sentinel2a", "Sentinel2b", "WorldView2-4", "WorldView2-8") – these ship published band edges (lb/ub), not FWHM directly; FWHM is derived as ub - lb and the Gaussian response is additionally hard-truncated to [lb, ub] (same convention get.srf.from_fwhm() already uses for these sensors). (Sentinel-2A/B and PRISMA have a REAL measured SRF table bundled instead – use get.spectral.convolution.srf() for those, it's more accurate than this Gaussian approximation.)

  3. Your OWN sensor/camera: supply centers yourself, in nm (e.g. copied straight out of an ENVI header's wavelength = {...} block). fwhm is optional – if omitted, each band's width is approximated from its distance to its neighboring bands (the standard assumption for a CONTIGUOUS pushbroom imaging spectrometer, e.g. a Headwall camera, where the true per-band SRF calibration isn't available). If you do know each band's real FWHM (e.g. from a camera datasheet, or an ENVI header that includes an fwhm = {...} block), pass it explicitly for a more accurate result.

Examples

df <- data.frame(wave = ToolsRTM::dataSpec_PDB[, 1],
                  rfl = 0.05 + 0.3 * ToolsRTM::dataSpec_PDB[, 1] / 2500)

# A bundled sensor with only nominal characteristics (no measured SRF):
enmap_bands <- get.spectral.convolution.gaussian(df, sensor.i = "EnMAP")
modis_bands <- get.spectral.convolution.gaussian(df, sensor.i = "MODIS")

# Your OWN sensor -- e.g. a 3-camera 15-band synchronized rig, with
# known band center + FWHM for every band:
own_centers <- c(444, 475, 502, 531, 550, 560, 570, 650, 668, 678, 705, 717, 740, 754, 842)
own_fwhm    <- c(28,  32,  18,  14,  12,  27,  14,  16,  14,  14,  10,  12,  18,  10,  57)
own_bands <- get.spectral.convolution.gaussian(df, centers = own_centers, fwhm = own_fwhm)

# A pushbroom imaging spectrometer's own band list from its ENVI header
# (e.g. a Headwall camera) -- only wavelength centers known, no FWHM:
headwall_centers <- c(398.02, 400.25, 402.48, 404.71, 406.94)  # (truncated example)
headwall_bands <- get.spectral.convolution.gaussian(df, centers = headwall_centers)

# Bulk mode: an entire LUT's reflectance matrix at once (fast, vectorized)
wave <- 400:2500
rfl_matrix <- matrix(0.05 + 0.3 * wave / 2500, nrow = 50, ncol = length(wave), byrow = TRUE)
bulk_bands <- get.spectral.convolution.gaussian(centers = own_centers, fwhm = own_fwhm,
                                                 rfl = rfl_matrix, wave = wave)