scopeinpython.rtmf
SCOPE canopy fluorescence radiative transfer model. Direct port of
SCOPEinR/R/RTMf.R (get.RTMf), computing the TOC fluorescence
radiance in the observation direction and the TOC hemispherical upward
fluorescence flux, given Mb/Mf (from
scopeinpython.fluspect_mscope.fluspect_mscope()) and per-layer
fluorescence quantum efficiencies (from
scopeinpython.biochemical.get_biochemical()) as composable inputs.
Note
The final upsampling from the native 53-point fluorescence
wavelength grid to the 211-point display grid (spectral.wlF) uses
scipy’s not-a-knot cubic spline, a close but not bit-identical
approximation of R’s fmm-method spline
(signal::interp1(...,'spline')) — see the module docstring for
measured error bounds. This is the one place in the whole Python port
with a deliberate, documented sub-floating-point-precision
approximation.
RTMf: SCOPE canopy fluorescence radiative transfer model.
Direct port of SCOPEinR::get.RTMf (SCOPEinR/R/RTMf.R), computing
the TOC fluorescence radiance in the observation direction and the TOC
hemispherical upward fluorescence flux, given per-canopy-layer
fluorescence excitation-emission matrices (Mb/Mf, from
scopeinpython.fluspect_mscope.fluspect_mscope()) and per-layer
fluorescence quantum efficiencies (etau for sunlit leaves, etah
for shaded leaves – from scopeinpython.biochemical.get_biochemical(),
called once per leaf micro-environment; NOT computed here, matching how
the R function itself takes them as plain arguments rather than an
iterative energy-balance dependency, so this is composable without the
SCOPE thermal energy-balance loop, ebal.R, being ported).
NumPy’s matrix * vector_of_length_ncol broadcasting (NumPy aligns
trailing axes) matches R’s own sweep()-based per-column scaling used
throughout the derivation below.
A real, deliberate numerical approximation, not an exact match: R’s
signal::interp1(..., method='spline') calls stats::splinefun(),
whose default method ("fmm", Forsythe-Malcolm-Moler) estimates
end-point derivatives via the unique cubic through the first/last 4
points – a different construction from any boundary condition
scipy.interpolate.CubicSpline offers directly. This port uses
bc_type='not-a-knot', which is close (confirmed via a standalone
R-vs-Python comparison on synthetic data: the discrepancy is localized to
within a few nm of each end of the native 640-850 nm, 4 nm-step
fluorescence grid, decaying to ~0 a few points in; ~1.5e-3 absolute worst
case against a spectrum spanning a range of ~2) but not bit-identical.
Every other quantity in this module (everything computed before the
spline step – piLo1..``piLo4``, the native-grid LoF_/Fhem_,
etc.) matches R to the same floating-point precision as the rest of this
port; only the final upsampling from the 53-point native fluorescence
grid to the 211-point spectral.wlF display grid carries this
localized approximation. R’s own extrap=NA default (unused here
since signal::interp1 is called without an explicit extrap
argument) means R itself leaves the last 2 of spectral.wlF’s 211
points (849, 850 nm, beyond the native grid’s 848 nm endpoint) as NaN
– reproduced here via CubicSpline(..., extrapolate=False) for those
two points specifically (see _interp_wlf()).
- class scopeinpython.rtmf.RTMfResult(LoF_: 'np.ndarray', EoutF_: 'np.ndarray', LoF_sunlit: 'np.ndarray', LoF_shaded: 'np.ndarray', LoF_scattered: 'np.ndarray', LoF_soil: 'np.ndarray', EoutF: 'float', LoutF: 'float', Femliave_: 'np.ndarray', F685: 'float', wl685: 'float', F740: 'float', wl740: 'float', F684: 'float', F761: 'float')[source]
Bases:
object- Parameters:
- EoutF: float
- LoutF: float
- F685: float
- wl685: float
- F740: float
- wl740: float
- F684: float
- F761: float
- scopeinpython.rtmf.rtmf(spectral, rtmo, canopy, tts, tto, psi, rsoil, Mb, Mf, etau, etah)[source]
Direct port of
SCOPEinR::get.RTMf(see module docstring).- Parameters:
rtmo (RTMoResult) – From
scopeinpython.rtmo.run_rtmo(), called with the samecanopy/tts/tto/psi/rsoilas here.rsoil (array_like, shape (2001,)) – Same 400-2400nm soil reflectance array passed to
run_rtmo.Mb (array_like, shape (53, 71, nl)) – From
scopeinpython.fluspect_mscope.fluspect_mscope()called withstep=5(its default) and this samenl.Mf (array_like, shape (53, 71, nl)) – From
scopeinpython.fluspect_mscope.fluspect_mscope()called withstep=5(its default) and this samenl.etau (array_like, shape (nl, 13, 36)) – Sunlit-leaf fluorescence quantum efficiency (
eta, fromscopeinpython.biochemical.get_biochemical()) per canopy layer x leaf-inclination class x leaf-azimuth class.etah (array_like, shape (nl,)) – Shaded-leaf fluorescence quantum efficiency per canopy layer.
spectral (SpectralConfig)
canopy (CanopyStructure)
tts (float)
tto (float)
psi (float)
- Return type: