radiative_transfer block
Top-level configuration for the RT solver — quadrature, polarization, truncation, and the projection-cap knobs introduced in v0.7. The full file at src/CoreRT/DefaultParameters.yaml shows a representative config; use this page to look up what each field does, what the defaults are, and which legacy aliases still work.
Required fields
spec_bands—Vector{String}. Each string is a Julia range expression in cm⁻¹, e.g."(1e7/777):0.015:(1e7/757)". Multiple bands run as a band-batched solve. SeeSchema/spec_bands.mdfor the full expression grammar (explicit lists, ranges,u"nm"wavelength tagging).surface—Vector{String}. One BRDF constructor per spectral band. SeeSchema/surface.mdfor the surface vocabulary (LambertianSurfaceScalar,CoxMunkSurface,rpvSurfaceScalar, etc.).polarization_type—String. One of"Stokes_I()","Stokes_IQ()","Stokes_IQU()","Stokes_IQUV()". Sets the Stokes vector dimension (1/2/3/4 channels respectively)."Stokes_IQ()"is parsed but rejected when an RT model is built: neglecting U in multiple scattering can cause intensity errors of several percent. Use"Stokes_IQU()"instead.depol—Real. Rayleigh depolarization factor. A negative value (-1, as inDefaultParameters.yaml) derives the depolarization per band from the N₂/O₂ molecular constants; a value≥ 0is used uniformly for the Rayleigh and Cabannes Greek coefficients and the Rayleigh optical depth (0 = no depolarization, the Natraj-2009 idealization).rayleigh_anisotropy— optionalString, default"DispersiveAnisotropy()". Wavelength dependence of the N₂/O₂ polarizability tensor behind the automatic (depol < 0) Rayleigh depolarization, which sets the Rayleigh Greek coefficients and rescales the Rayleigh optical depth."DispersiveAnisotropy()"takes the mean polarizability and anisotropy from the refractive-index fits and King factors ofUsingRefInd(the depolarization then falls from 0.028 at 400 nm to 0.025 at 2 µm for air);"ConstantAnisotropy()"uses the Raman-module constants with a wavelength-independent anisotropy and reproduces the v2.2 pre-release automatic depolarization bit for bit. The Cabannes fraction always, and the Cabannes depolarization whendepol < 0, use the Raman-module constants, so use"ConstantAnisotropy()"when an elastic-only run is compared with or subtracted from a Raman run (Ring/filling-in spectra). Ignored whendepol ≥ 0.float_type—String."Float64"or"Float32". Float32 is fine for most retrievals and gives a ~2× speedup on large spectral windows; Float64 is required for reproducing published benchmarks at full precision.architecture—String."default_architecture","CPU()","GPU()", or"MetalGPU()"(the last three also accepted with anArchitectures.prefix, e.g."Architectures.CPU()";default_architecturetakes no prefix). The CUDA GPU path is implemented by thevSmartMOMCUDAExtextension. CUDA is currently a direct dependency; CPU execution needs no CUDA device.
Resolution knobs (Phase D — v0.7)
Pick one of the schemas below. The new nstreams knob is the recommended path; legacy max_m + l_trunc configs keep working.
New schema (recommended)
nstreams— optional, default8. Weighted streams per hemisphere, the primary user-facing resolution knob. Public contract:stream_l_cap = 2·nstreams - 1regardless ofquadrature_type. For VLIDORT users: this is the Julia equivalent of VLIDORT'sNSTREAMS.m_max— optional, defaultnull. Explicit Fourier loop bound (order). When set, clamps the trait-aggregator output belowstream_l_cap. Useful when you want to truncate the loop more aggressively than the per-component traits would.greek_beta_cutoff— optional positive number, defaultnull. Applies a second-stage Fourier-support filter after each aerosol size distribution has been integrated into Greek coefficients. For every aerosol, the retained support ends at the largest degree satisfying at any wavelength in the band; the maximum across aerosols enters the component trait aggregator. This tightens the conservative maximum-size-parameter ceiling when the particle distribution has a very weak large-radius tail. It does not inspect α, γ, δ, ϵ, or ζ. Omit it or set it tonullto preserve the full coefficient-length support. The resulting aerosol rule is deliberately two-stage:The maximum Mie size parameter determines the conservative coefficient allocation ceiling.
After integration over the complete size distribution, the last significant β coefficient determines effective Fourier support.
The scan uses magnitude because β may be signed, and uses the last passing degree rather than assuming a monotonic tail. For spectrally resolved β, a degree is retained if it passes at any wavelength in the band. The maximum support across aerosol species is combined with Rayleigh, surface, and source traits. Finally,
m_max,stream_l_cap, and available coefficient length act as upper caps. Aerosol input migration: aerosol YAML/TOML files should now state this choice explicitly. Usegreek_beta_cutoff: 1.0e-5(or another validated positive threshold) to remove insignificant high-degree β tails, or usegreek_beta_cutoff: nullto retain the complete Mie-series support. For backward compatibility, omission still behaves asnull, but the parser emits a warning so legacy aerosol inputs are not silently left unreviewed. This reduces the number of Fourier moments evaluated. It does not reducenstreamsor rebuild a smaller angular operator; choosenstreamsseparately when those memory savings are desired.truncation— optional, defaultauto. Controls how the aerosol phase function is treated relative to the projection cap:"auto"(default): VLIDORT-DO_DELTAM_SCALING-style. With no aerosols, resolves toNoTruncation(). With aerosols, picksδBGE(stream_l_cap)and the per-band Mie loop applies it only whenlength(greek.β) > stream_l_cap— short phase functions automatically fall back toNoTruncation()so the truncation step can never crash on a fits-the-cap series. Logs the choice via@info."NoTruncation()"ornull: exactly no transform. Coefficients abovestream_l_capare silently dropped from the Fourier projection (per Phase C trait clamps)."δBGE(L, Δ)": explicit δ-BGE-fit truncation (Sanghavi & Stephens 2015). Used for benchmark reproducibility when you want exact parity with a published numerical convention. Both arguments are required in the string form; the second is the retiredΔ_angle, so writeδBGE(L, 0.0)(a non-zero value warns once and is forced to0).
Legacy schema (still supported, deprecated v0.7)
max_m—Integer. Number of Fourier moments (count, loop runsm = 0:max_m-1). Triggers legacy parsing —nstreamswill be left unset and the oldmin(ceil((l_max+1)/2), max_m)aggregator semantics apply.l_trunc—Integer. Legendre cutoff. Plays the role ofstream_l_capunder the legacy schema.
Setting both nstreams and l_trunc produces a @warn — the legacy l_trunc is ignored and nstreams wins. Setting both the legacy max_m (a count) and m_max (an order) is rejected with an ArgumentError, because the two conflict.
Other optional fields
Δ_angle—Real, retired (parsed for backward compatibility; non-zero values warn once and are stored as0, so the parsed parameters match what the fit uses). The δBGE fit always uses the full angular domain. In TOML the Unicode key must be quoted ("Δ_angle" = 0.0); new configurations should omit it.quadrature_type— optional, default"GaussLegQuad()". The recommended default."RadauQuad()"is supported but documented as expert/legacy: it includes the SZA as a quadrature node (handy for DNI-on-node configurations) at the cost of being 5–50× less accurate per stream than Gauss-Legendre on Rayleigh-only setups (see the Natraj-2009 commitf9403eband the v0.7 release notes). Sanghavi's guidance: keep Radau as an option, but reach for Gauss by default.numerics— optional. Sub-block with rarely-touched solver knobs:dτ_max_threshold(default0.001) — doubling-step cap. Setsdτ_max = threshold · μ_minwhere μ_min is the smallest TRUE quadrature stream. Smaller → finer initial layers / more doublings; raising to ~0.01 reduces doublings.dτ_min_floor(default1024·eps(FT)) — absolute floor ondτ_max. ~1.2e-4for Float32 /2.3e-13for Float64. Prevents grazing-VZA configs from collapsing dτ below FT precision.blas_threads(defaultnull) — selects the process-wide BLAS thread count whenrt_runstarts.nullleaves the current setting alone; an integer persists after the call. Treat it as an application-level choice: models with different values must not run concurrently in one process.verbose(defaultfalse) — whentrue,rt_runprints theTimerOutputstiming tree at the end of each call (useful for profiling, noisy in batched loops).fourier_convergence(defaultall) —allevaluates every allowed moment;intensitychecks I, andstokeschecks I/Q/U. Aliases arenoneforall, andiquforstokes.fourier_tolerance(default1e-5),fourier_min_m(default3, minimum3), andfourier_n_consecutive(default2, minimum1) control the convergence test. These keys requireintensityorstokes; they are rejected withallso a requested threshold cannot be ignored.ss_correction(defaultnone) —tmsenables the aerosol exact-single-scattering correction for forward elastic SFI. Raman and linearized drivers reject this strategy. Cox–Munk's direct glint correction is separate and is included in forward and linearized ocean solves.
Unknown numerics keys are rejected. The ASCII aliases dtau_max_threshold and dtau_min_floor are accepted; conflicting Unicode/ASCII values are rejected.
Any other key directly under radiative_transfer that the parser does not read (for example a misspelled nstream) is not an error: the parser emits a one-time warning per key and session naming the known keys, and the default stays in effect. The same check applies to the top level and to geometry.
Example — minimal new schema
A new-schema config can omit nstreams (default 8), quadrature_type (default GaussLegQuad), and truncation (default auto). The leanest valid radiative_transfer block is:
radiative_transfer:
spec_bands:
- "[18867.92 18868.92]"
surface:
- LambertianSurfaceScalar(0.0)
polarization_type: Stokes_IQU()
# Δ_angle is retired (always 0)
depol: 0.0
float_type: Float64
architecture: Architectures.CPU()This expands to: nstreams = 8 (so stream_l_cap = 15), quadrature_type = GaussLegQuad(), truncation = auto. For a Rayleigh-only Lambertian scene this resolves to NoTruncation() and the Fourier loop runs m = 0:2 (Phase C trait dispatch).
Example — Cox-Munk ocean retrieval
radiative_transfer:
spec_bands: ["[18867 18870]"]
surface: ["CoxMunkSurface(wind_speed=5.0)"]
polarization_type: Stokes_IQU()
nstreams: 16 # 16 weighted streams ⇒ stream_l_cap = 31
truncation: auto # auto → δBGE truncation at l = 31 once Mie aerosol is added
# Δ_angle is retired (always 0)
depol: 0.0
float_type: Float64
architecture: Architectures.CPU()See also
Schema/spec_bands.md—spec_bandsexpression grammarSchema/surface.md— BRDF vocabularySchema/aerosols.md— Mie size distribution + refractive indexSchema/sources.md—SolarBeam,SurfaceSIF,BlackbodySourcedocs/src/pages/conventions.md§6 —NstreamsvsNquaddistinctiondocs/dev_notes/fourier_stream_resolution_plan.md— design memo for the v0.7 schema migration