scopeinpython.fluspect_mscope

Multi-layer (mSCOPE) leaf-optics wrapper around scopeinpython.fluspect.get_fluspect_cx_scope(). Direct port of SCOPEinR/R/fluspect_mSCOPE.R (get.fluspect_mSCOPE).

Computes leaf optical properties (reflectance, transmittance, fluorescence excitation-emission matrices Mb/Mf, pigment contribution factors) once per distinct leaf-biochemistry profile layer, then replicates across the canopy sublayers each profile layer spans, weighted by pLAI.

Note

Two things worth knowing, ported/documented rather than “fixed”:

  • R quirk reproduced exactly: at each profile-layer boundary, the canopy sublayer shared between two consecutive profile layers is assigned twice (once per layer’s replication loop) – the later assignment wins. This mirrors R’s own overlapping-range rho_temp[in1:in2,] <- ... assignment.

  • Real R crash, not offered as a Python default: calling get.fluspect_mSCOPE() in R without the step argument always crashes (“number of items to replace is not a multiple of replacement length”), confirmed via a standalone repro – its Mb/Mf output array is pre-allocated assuming a fixed 1 nm grid, but the function actually calls getFluspect.Cx.SCOPE(..., step=5) internally when step is missing, producing an irreconcilable shape mismatch. Since this R code path can never succeed, step is a required parameter here rather than optional-with-a-crashing-default.

Multi-layer (mSCOPE) leaf-optics wrapper around scopeinpython.fluspect.get_fluspect_cx_scope().

Direct port of SCOPEinR::get.fluspect_mSCOPE (SCOPEinR/R/fluspect_mSCOPE.R). Leaf optical properties (reflectance, transmittance, fluorescence excitation-emission matrices Mb/Mf, and pigment contribution factors) are computed once per distinct leaf-biochemistry profile layer (mly.nly layers), then replicated across the nl canopy layers each profile layer spans (weighted by mly.pLAI).

R quirk reproduced exactly, not “fixed”: at each profile-layer boundary, the canopy sublayer shared between two consecutive profile layers (indStar[i+1] in R / indStar[i] here) is assigned twice – once by the earlier profile layer’s replication, once by the later one – and the later assignment wins. This mirrors R’s own rho_temp[in1:in2,] <- ... overlapping-range assignment (the R source’s own comment notes an earlier version of this bug was more severe, losing entire profile layers rather than just double-writing one boundary row per layer).

A real, confirmed crash in the R source, not offered here: if step is omitted in R, get.fluspect_mSCOPE sets its internal step_to_model to 5 but pre-allocates the Mb/Mf output array using spectral$wlE/spectral$wlF directly (which are always fixed 1 nm grids, 351 x 211, from get.spectra.SCOPE) – not the 53x71 shape getFluspect.Cx.SCOPE(..., step=5) actually returns. The resulting leafopt$Mb[,,in1:in2] <- array(...) assignment then fails with R’s “number of items to replace is not a multiple of replacement length” (confirmed via a standalone repro), i.e. calling get.fluspect_mSCOPE without step always crashes. Since this code path can never succeed, step is a required (not optional-with-a-buggy-default) parameter here.

class scopeinpython.fluspect_mscope.MultiLayerLeafBio(nly, pLAI, pCab, pEWT, pCar, pLMA, pCs, pN)[source]

Bases: object

Multi-layer (mSCOPE) leaf-biochemistry profile. One value per distinct biochemistry layer (nly of them); pLAI is that layer’s share of total LAI (need not sum to 1 – normalised internally, matching R).

Parameters:
nly: int
pLAI: ndarray
pCab: ndarray
pEWT: ndarray
pCar: ndarray
pLMA: ndarray
pCs: ndarray
pN: ndarray
class scopeinpython.fluspect_mscope.FluspectMScopeResult(refl: 'np.ndarray', tran: 'np.ndarray', kChlrel: 'np.ndarray', kCarrel: 'np.ndarray', Mb: 'np.ndarray', Mf: 'np.ndarray', phiI: 'np.ndarray', phiII: 'np.ndarray')[source]

Bases: object

Parameters:
refl: ndarray
tran: ndarray
kChlrel: ndarray
kCarrel: ndarray
Mb: ndarray
Mf: ndarray
phiI: ndarray
phiII: ndarray
scopeinpython.fluspect_mscope.fluspect_mscope(mly, spectral, nl, Cx, fqe, Prot, CBC, Anth, step=5.0)[source]

Direct port of SCOPEinR::get.fluspect_mSCOPE. Cx/fqe/ Prot/CBC/Anth are the baseline leaf properties shared by every profile layer (only Cab/EWT/Car/LMA/Cs/N vary per layer, taken from mly). The R function also accepts a leafopt-unrelated optipar parameter and an soil/plotting path – both dropped here: optipar is documented but never actually used in the R source body (it always calls getFluspect.Cx.SCOPE with the hardcoded optipar2021.Pro.CX), and the get.plots branch only produces diagnostic plots, never modifying the returned leafopt.

Parameters:
Return type:

FluspectMScopeResult