Getting-LUTs
Getting-LUTs.Rmd
library(ToolsRTM)A LUT (Look-Up Table) is one row of trait values per simulated spectrum – the input every canopy model, sensitivity analysis, and inversion workflow in this package starts from. Three functions build one, each trading off control against simplicity differently:
| Function | Distribution per trait | Trait correlation | Typical use |
|---|---|---|---|
getLUT() |
Fixed set (see ?getLUT) |
Independent | Quick default LUT, no customization needed |
get.LUTfromRanges() |
One distribution ("uniform"/"gauss") for
every trait, your own min/max |
Independent | Custom ranges, same distribution shape for all traits |
get_distributionLUT() (this page) |
Per-trait "Uniform"/"Gaussian" choice |
Car~Cab, optional (DepCab) |
Different traits need different distribution shapes in the same LUT |
getCor() |
Normal or Uniform | Any two traits, any target correlation (rho) |
General-purpose correlated sampling beyond Car~Cab |
This page focuses on the last two – per-trait distributions and trait
correlation – since
getLUT()/get.LUTfromRanges() are covered in
the main ToolsRTM vignette.
1. get_distributionLUT(): a different distribution per
trait
Real leaf/canopy traits don’t all follow the same distribution shape.
Chlorophyll content (Cab) tends to cluster around a typical
value (Gaussian-like); the leaf-angle parameter LIDFa has
no such tendency across a mixed canopy (closer to Uniform).
get_distributionLUT() lets each trait pick its own shape
instead of forcing one distribution on all of them.
Define the sampling range (minval/maxval,
one column per trait) and, separately, which distribution each trait
uses:
minval <- data.frame('N' = 1.5, 'Cab' = 5, 'Car' = 0, 'Anth' = 0, 'Cbrown' = 0.0,
'EWT' = 0.001, 'Prot' = 0.00001, 'CBC' = 0.00001,
'LIDFa' = 0, 'LAI' = 0.5,
### input for INFORM
LAIu = 0, sd = 200, cd = 0.2, h = 5,
### input for fourSAIL-2
fraction_brown = 0, diss = 0.1, Cv = 0.3, Zeta = 0)
maxval <- data.frame('N' = 3, 'Cab' = 70, 'Car' = 25, 'Anth' = 7, 'Cbrown' = 0.2,
'EWT' = 0.035, 'Prot' = 0.03, 'CBC' = 0.03,
'LIDFa' = 70, 'LAI' = 7,
### input for INFORM
LAIu = 0.8, sd = 1000, cd = 7, h = 20,
### input for fourSAIL-2
fraction_brown = 1, diss = 1, Cv = 1, Zeta = 0.2)
TypeDistrib <- data.frame('N' = 'Gaussian', 'Cab' = 'Gaussian', 'Car' = 'Gaussian',
'Anth' = 'Uniform', 'Cbrown' = 'Uniform',
'EWT' = 'Uniform', 'Prot' = 'Uniform', 'CBC' = 'Uniform',
'LIDFa' = 'Uniform', 'LAI' = 'Gaussian',
### input for INFORM
LAIu = 'Uniform', sd = 'Uniform', cd = 'Uniform', h = 'Uniform',
### input for fourSAIL-2
fraction_brown = 'Uniform', diss = 'Uniform', Cv = 'Uniform', Zeta = 'Uniform')Traits marked "Gaussian" need a mean and standard
deviation too (traits left out of
Mean_gauss/Std_gauss – everything
"Uniform" – are simply ignored for this part):
Mean_gauss <- data.frame('N' = 2.2, 'Cab' = 45, 'Car' = 8, 'LAI' = 2.25)
std_gauss <- Mean_gauss / 2.0
nSamples <- 500
data.LUT <- get_distributionLUT(minval = minval, maxval = maxval,
nSamples = nSamples, TypeDistrib = TypeDistrib,
Mean_gauss = Mean_gauss, Std_gauss = std_gauss,
DepCab = FALSE, setseed = 246)Seeing the difference: Gaussian vs. Uniform
Cab (Gaussian, mean 45) and LIDFa (Uniform,
0-70) came from the exact same get_distributionLUT() call
above – the histograms show why picking the right distribution per trait
matters:
op <- par(mfrow = c(1, 2))
hist(data.LUT$Cab, breaks = 30, col = "#2E8B57", border = "white",
main = "Cab (Gaussian, mean=45)", xlab = "Cab")
hist(data.LUT$LIDFa, breaks = 30, col = "#B2182B", border = "white",
main = "LIDFa (Uniform)", xlab = "LIDFa")
par(op)2. Trait correlation
Independently-sampled traits are the default – but real traits
co-vary (e.g. carotenoid content Car tracks chlorophyll
Cab; plants with more of one pigment tend to have more of
the other). Two ways to get correlated traits into a LUT:
DepCab: the built-in Car~Cab correlation
Setting DepCab = TRUE (instead of FALSE
above) stops sampling Car independently – it’s redrawn as a
function of Cab (correlated at r = 0.8, the empirical
co-variation reported in leaf pigment data):
data.LUT.dep <- get_distributionLUT(minval = minval, maxval = maxval,
nSamples = nSamples, TypeDistrib = TypeDistrib,
Mean_gauss = Mean_gauss, Std_gauss = std_gauss,
DepCab = TRUE, setseed = 246)
cat("Car~Cab correlation, DepCab=FALSE:", round(cor(data.LUT$Cab, data.LUT$Car), 2), "\n")
#> Car~Cab correlation, DepCab=FALSE: 0.03
cat("Car~Cab correlation, DepCab=TRUE: ", round(cor(data.LUT.dep$Cab, data.LUT.dep$Car), 2), "\n")
#> Car~Cab correlation, DepCab=TRUE: 0.98
op <- par(mfrow = c(1, 2))
plot(data.LUT$Cab, data.LUT$Car, pch = 19, col = "#2166AC", cex = 0.6,
xlab = "Cab", ylab = "Car", main = "DepCab = FALSE (independent)")
plot(data.LUT.dep$Cab, data.LUT.dep$Car, pch = 19, col = "#B2182B", cex = 0.6,
xlab = "Cab", ylab = "Car", main = "DepCab = TRUE (correlated)")
par(op)
getCor(): correlate any two traits, any target
strength
DepCab only covers Car~Cab. For any other trait pair (or
a different target correlation), getCor() is the
general-purpose tool – it samples two traits jointly at a chosen
correlation coefficient (rho) instead of independently:
cor_lut <- getCor(n_inputs = 2, nLUT = 300, distribution = "Normal", setseed = 1,
rho = 0.7, Varnames = c("Cab", "LAI"),
MinRange = c(10, 0.5), MaxRange = c(80, 7))
cat("Target rho: 0.7. Achieved correlation:",
round(cor(cor_lut$LUT$Cab, cor_lut$LUT$LAI), 2), "\n")
#> Target rho: 0.7. Achieved correlation: 0.7
plot(cor_lut$LUT$Cab, cor_lut$LUT$LAI, pch = 19, col = "#2E8B57", cex = 0.6,
xlab = "Cab", ylab = "LAI", main = "getCor(): Cab~LAI at rho=0.7")
getCor() returns a list: $LUT (the
correlated trait table to actually use) and $Covarianza
(the covariance matrix behind it, for reference).
distribution accepts "Normal" or
"Uniform" here – note this is capitalized differently from
get.LUTfromRanges()’s own "uniform"/
"gauss", a real inconsistency in the package worth knowing
about rather than guessing past.
Summary
- Need one quick default LUT?
getLUT(). - Need your own ranges, one distribution shape for everything?
get.LUTfromRanges(). - Need different traits to have different distribution shapes in the
same LUT (and optionally the built-in Car~Cab correlation)?
get_distributionLUT(). - Need two specific traits correlated at a chosen strength, beyond
Car~Cab?
getCor(), then splice its columns into whichever LUT you built above.