toolsrtm.sensitivity

Global sensitivity analysis (Johnson relative-importance index, verified to reproduce R’s sensitivity::johnson() to 8 decimal places; a simplified two-sample-split Sobol-like Si/STi estimator) and correlated/ multi-distribution LUT builders. Direct port of ToolsRTM/R/get.sobol.indices.R, get.spectral.sensitivity.R, Correlated_value.R, Gaussian_MinMax.R, get_distributionLUT.R, getCor.R.

Quick example

from toolsrtm.sensitivity import spectral_sensitivity

result = spectral_sensitivity(n_samples=500, distribution="Uniform",
                               traits=("N", "Cab", "EWT", "LMA", "LIDFa", "LAI"),
                               wl_step=5, seed=11)
at_700nm = result.sti_pct[result.wavelength == 700]
print(dict(zip(result.trait[result.wavelength == 700], at_700nm.round(1))))
Input                              spectral_sensitivity()    Output
---------------------------        ----------------------    ---------------------------
n_samples (LUT runs per trait)                                long-format arrays:
distribution = "Uniform"/...       -------------------->       result.wavelength
traits = tuple of trait names                                  result.trait
wl_step (nm, output resolution)                                result.sti_pct  (sums to 100%
                                                                  per wavelength -- relative
                                                                  contribution to variance)

Global sensitivity analysis and correlated/multi-distribution LUT builders.

Python port of ToolsRTM’s sensitivity-analysis toolkit: Correlated_value.R (correlated_value()), Gaussian_MinMax.R (gauss_by_min_max()), get_distributionLUT.R (get_distribution_lut()), getCor.R` (:func:`get_cor`), ``get.sobol.indices.R (sobol_indices(), via johnson_relative_weights()) and get.spectral.sensitivity.R (spectral_sensitivity()).

The Johnson relative-weights index (Johnson, 2000, “A heuristic method for estimating the relative weight of predictor variables in multiple regression”) is implemented directly here via eigendecomposition rather than calling R’s sensitivity package – verified to reproduce sensitivity::johnson()’s output to 8 decimal places on a fixed reference dataset (see tests/test_sensitivity.py). sobol_indices()’s Si/ STi columns are a simplified two-sample-split estimator (matching the R function’s own docstring: “treat it as a rough indicator rather than a precise total-effect index”) – spectral_sensitivity() uses only the Johnson index, matching what get.spectral.sensitivity.R itself uses despite the “Sobol” name.

toolsrtm.sensitivity.correlated_value(x, r, rng=None)[source]

Draw y correlated with x at approximately r. Direct port of ToolsRTM::correlatedValue. Negative results are clipped to 0 (assumes non-negative quantities, e.g. pigment concentrations).

Parameters:
Return type:

ndarray

toolsrtm.sensitivity.gauss_by_min_max(n, m, s, lwr, upr, nnorm, rng=None)[source]

Truncated-normal sampling by rejection. Direct port of ToolsRTM::gauss_byMin_Max: draw nnorm values from Normal(m, s), keep only those within [lwr, upr], then randomly pick n of the survivors (without replacement). Raises ValueError if fewer than n values survive – increase nnorm.

Parameters:
  • n (int)

  • m (float)

  • s (float)

  • lwr (float)

  • upr (float)

  • nnorm (int)

  • rng (Generator | None)

Return type:

ndarray

toolsrtm.sensitivity.get_distribution_lut(minval, maxval, n_samples, type_distrib, mean_gauss=None, std_gauss=None, dep_cab=False, seed=None)[source]

Build a LUT with a per-trait distribution choice. Direct port of ToolsRTM::get_distributionLUT. mean_gauss/std_gauss are only read for traits marked "Gaussian" in type_distrib. If dep_cab and "Car" is one of the traits, Car is instead drawn as correlated_value() (Cab/4, r=0.8) – the empirical Cab-Car co-variation from leaf pigment data.

Parameters:
  • minval (dict[str, float])

  • maxval (dict[str, float])

  • n_samples (int)

  • type_distrib (dict[str, Literal['Uniform', 'Gaussian']])

  • mean_gauss (dict[str, float] | None)

  • std_gauss (dict[str, float] | None)

  • dep_cab (bool)

  • seed (int | None)

Return type:

dict[str, ndarray]

class toolsrtm.sensitivity.CorrelatedLutResult(lut, covariance)[source]

Bases: object

Result of get_cor().

Parameters:
lut: dict[str, ndarray]
covariance: ndarray

realized (n_inputs, n_inputs) correlation matrix

toolsrtm.sensitivity.get_cor(n_inputs, n_lut=100, distribution='Uniform', seed=123, rho=None, var_names=None, min_range=None, max_range=None)[source]

Generate n_inputs mutually correlated variables at (approximately) rho, each rescaled to its own [min_range, max_range]. Direct port of ToolsRTM::getCor.

Parameters:
  • n_inputs (int)

  • n_lut (int)

  • distribution (Literal['Uniform', 'Normal'])

  • seed (int)

  • rho (float | None)

  • var_names (Sequence[str] | None)

  • min_range (Sequence[float] | None)

  • max_range (Sequence[float] | None)

Return type:

CorrelatedLutResult

toolsrtm.sensitivity.johnson_relative_weights(X, y)[source]

Johnson (2000) relative-weights index for each column of X against y. Equivalent to R’s sensitivity::johnson(X, y, logistic = FALSE)$johnson$original – verified to reproduce it to 8 decimal places on a fixed reference dataset. Weights sum to approximately the R-squared of the OLS regression of y on X.

Parameters:
Return type:

ndarray

class toolsrtm.sensitivity.SobolResult(parameter, si, sti, i_johnson, difference, si_norm=None, i_johnson_norm=None)[source]

Bases: object

Result of sobol_indices(), one entry per input variable.

Parameters:
parameter: list[str]
si: ndarray

simplified two-sample-split first-order index (rough indicator, not a precise Sobol Si)

sti: ndarray

simplified two-sample-split total-order index (same caveat)

i_johnson: ndarray

Johnson relative-importance index – the reliable, independently-verifiable metric

difference: ndarray

si - i_johnson

si_norm: ndarray | None = None
i_johnson_norm: ndarray | None = None
toolsrtm.sensitivity.sobol_indices(data, output, n, normalize=False, seed=None)[source]

First-order/total Sobol-like indices plus the Johnson relative- importance index, computed directly from existing LUT+output data (no extra model evaluations needed). Direct port of ToolsRTM::get.sobol.indices.

i_johnson is the reliable, independently-verifiable metric of the two (see johnson_relative_weights()); si/sti are a rough, simplified two-sample-split estimator – spectral_sensitivity() only uses i_johnson_norm.

Parameters:
  • data (dict[str, ndarray])

  • output (str)

  • n (int)

  • normalize (bool)

  • seed (int | None)

Return type:

SobolResult

class toolsrtm.sensitivity.SpectralSensitivityResult(wavelength, trait, sti_pct, distribution)[source]

Bases: object

Result of spectral_sensitivity() – long-format arrays, ready for a stacked-area “relative contribution vs wavelength” plot.

Parameters:
wavelength: ndarray

(n_wl * n_traits,)

trait: ndarray

(n_wl * n_traits,) string array

sti_pct: ndarray

(n_wl * n_traits,) Johnson relative importance, normalized to sum to 100% per wavelength

distribution: str
toolsrtm.sensitivity.spectral_sensitivity(n_samples=1000, distribution='Uniform', traits=('N', 'Cab', 'EWT', 'LMA', 'LIDFa', 'LAI'), rsoil_base=None, wl_step=5, seed=123)[source]

Run foursail (PROSPECT-D leaf optics) many times while varying a set of plant/soil traits, then compute the Johnson relative-importance index at each wavelength – how much each trait relatively contributes to explaining reflectance variance there. Direct port of ToolsRTM::get.spectral.sensitivity (fixed leaf/canopy model: PROSPECT-D + fourSAIL, matching that function’s own defaults; the R version’s leaf.model/canopy.model arguments aren’t reproduced here).

traits must be a subset of _DEFAULT_TRAIT_BOUNDS’s keys (N, Cab, EWT, LMA, LIDFa, LAI); a soil-brightness multiplier (SoilCoef, 0.5-1.5) is always added on top, matching the classic PROSAIL sensitivity figure (leaf structure, pigment, water, dry matter, leaf angle, LAI, soil).

Parameters:
  • n_samples (int)

  • distribution (Literal['Uniform', 'Gaussian'])

  • traits (Sequence[str])

  • rsoil_base (ndarray | None)

  • wl_step (int)

  • seed (int)

Return type:

SpectralSensitivityResult