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:
  • LoF_ (ndarray)

  • EoutF_ (ndarray)

  • LoF_sunlit (ndarray)

  • LoF_shaded (ndarray)

  • LoF_scattered (ndarray)

  • LoF_soil (ndarray)

  • EoutF (float)

  • LoutF (float)

  • Femliave_ (ndarray)

  • F685 (float)

  • wl685 (float)

  • F740 (float)

  • wl740 (float)

  • F684 (float)

  • F761 (float)

LoF_: ndarray
EoutF_: ndarray
LoF_sunlit: ndarray
LoF_shaded: ndarray
LoF_scattered: ndarray
LoF_soil: ndarray
EoutF: float
LoutF: float
Femliave_: ndarray
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:
Return type:

RTMfResult