From eb05c5b5b007460ffc1512c6e95ea6c4fa9d817d Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Feret Date: Thu, 4 Jan 2024 12:12:17 +0100 Subject: [PATCH] minor update of the code, based on recommendations from package goodpractices. minor update of the JOSS paper --- R/Lib_PROSPECT.R | 14 +-- R/Lib_PROSPECT_Inversion.R | 101 +++++++++++----------- R/SpecPROSPECT_FullRange-data.R | 6 +- data-raw/DATASET.R | 3 +- man/CostVal_RMSE.Rd | 2 +- man/FitSpectralData.Rd | 12 +-- man/Get_Nprior.Rd | 6 +- man/Invert_PROSPECT.Rd | 36 ++++---- man/Merit_RMSE_PROSPECT.Rd | 4 +- man/PROSPECT_LUT.Rd | 2 +- man/SetInitParm.Rd | 2 +- man/SetNValues.Rd | 2 +- man/SpecPROSPECT_FullRange.Rd | 6 +- man/check_prospect_parms.Rd | 15 ++-- man/tryInversion.Rd | 9 +- paper/paper.md | 13 ++- tests/testthat/test-Invert_PROSPECT.R | 6 +- tests/testthat/test-Invert_PROSPECT_OPT.R | 9 +- vignettes/prospect1.Rmd | 2 +- vignettes/prospect2.Rmd | 7 +- vignettes/prospect3.Rmd | 4 +- vignettes/prospect4.Rmd | 5 +- vignettes/prospect5.Rmd | 2 +- 23 files changed, 144 insertions(+), 124 deletions(-) diff --git a/R/Lib_PROSPECT.R b/R/Lib_PROSPECT.R index d88716e..a196397 100644 --- a/R/Lib_PROSPECT.R +++ b/R/Lib_PROSPECT.R @@ -197,14 +197,14 @@ check_version_prospect <- function(LMA, PROT, CBC){ #' This function adapts SpecPROSPECT accordingly to experimental data #' or to a spectral domain defined by UserDomain #' @param lambda numeric. Spectral bands corresponding to experimental data -#' @param SpecPROSPECT list. Includes optical constants -#' refractive index, specific absorption coefficients and corresponding spectral bands +#' @param SpecPROSPECT list. Includes optical constants: refractive index, +#' specific absorption coefficients and corresponding spectral bands #' @param Refl numeric. Measured reflectance data #' @param Tran numeric. Measured Transmittance data -#' @param UserDomain numeric. either Lower and upper bounds for domain of interest (optional) -#' or list of spectral bands of interest -#' @param UL_Bounds boolean. set to TRUE if UserDomain only includes lower and upper band, -#' set to FALSE if UserDomain is a list of spectral bands (in nm) +#' @param UserDomain numeric. either Lower and upper bounds for domain of +#' interest (optional) or list of spectral bands of interest +#' @param UL_Bounds boolean. set to TRUE if UserDomain only includes lower and +#' upper band, set to FALSE if UserDomain is a list of spectral bands (in nm) #' #' @return list including spectral properties at the new resolution #' @import dplyr @@ -248,9 +248,9 @@ FitSpectralData <- function(lambda, SpecPROSPECT = NULL, #' computation of a LUT of leaf optical properties using a set of #' leaf chemical & structural parameters #' +#' @param Input_PROSPECT dataframe. list of PROSPECT input parameters. #' @param SpecPROSPECT list. spectral constants #' refractive index, specific absorption coefficients & spectral bands -#' @param Input_PROSPECT dataframe. full list of PROSPECT input parameters. Default = Set to NULL #' #' @return list. LUT including leaf reflectance and transmittance #' @export diff --git a/R/Lib_PROSPECT_Inversion.R b/R/Lib_PROSPECT_Inversion.R index cd145b7..3fa18f9 100644 --- a/R/Lib_PROSPECT_Inversion.R +++ b/R/Lib_PROSPECT_Inversion.R @@ -12,22 +12,22 @@ #' Performs PROSPECT inversion using iterative optimization #' in order to define estimate a set of user defined parameters -#' @param SpecPROSPECT list. Includes optical constants -#' refractive index, specific absorption coefficients and corresponding spectral bands +#' @param SpecPROSPECT list. Includes optical constants refractive index, +#' specific absorption coefficients and corresponding spectral bands #' @param Refl numeric. Measured reflectance data #' @param Tran numeric. Measured Transmittance data -#' @param Parms2Estimate character vector. Parameters to estimate (can be 'ALL') +#' @param Parms2Estimate character. Parameters to estimate (can be 'ALL') #' @param InitValues data.frame. Default values of PROSPECT parameters. During optimization, #' they are used either as initialization values for parameters to estimate, #' or as fix values for other parameters. #' Parameters not compatible with PROSPECT_version are not taken into account. -#' @param PROSPECT_version character. Version of prospect model used for the inversion: '5', '5B', 'D', 'DB', 'PRO', 'PROB', +#' @param PROSPECT_version character. prospect version used for inversion: 'D' or 'PRO' #' See details. #' @param MeritFunction character. name of the function to be used as merit function #' with given criterion to minimize (default = RMSE) #' @param xlub data.frame. Boundaries of the parameters to estimate. -#' The data.frame must have columns corresponding to \code{Parms2Estimate} first line being -#' the lower boundaries and second line the upper boundaries. +#' The data.frame must have columns corresponding to \code{Parms2Estimate} +#' first line being the lower boundaries and second line the upper boundaries. #' @param Est_Brown_Pigments boolean. should brown pigments be accounted for during inversion? #' @param Est_alpha boolean. should alpha be accounted for during inversion? #' @param verbose boolean. set true to get info about adjustment of tolerance or initialization @@ -37,20 +37,20 @@ #' @return OutPROSPECT estimated values corresponding to Parms2Estimate #' @importFrom progress progress_bar #' @details -#' Six versions of prospect are available for inversion. +#' Two versions of prospect are available for inversion. #' The version is depending on the parameters taken into account: #' -#' | Version | 5 | 5B | D | DB | PRO | PROB -#' | :------: |:--------------------------------------:|:--------------------------------------:|:--------------------------------------:|:--------------------------------------:|:--------------------------------------:|:---------------------------------------:| -#' | CHL |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| -#' | CAR |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| -#' | ANT | | |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| -#' | BROWN | |`r emojifont::emoji('white_check_mark')`| |`r emojifont::emoji('white_check_mark')`| |`r emojifont::emoji('white_check_mark')`| -#' | EWT |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| -#' | LMA |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| | -#' | PROT | | | | |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| -#' | CBC | | | | |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| -#' | N |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| +#' | Version | D | PRO +#' | :------: |:--------------------------------------:|:--------------------------------------:| +#' | CHL |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| +#' | CAR |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| +#' | ANT |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| +#' | BROWN |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| +#' | EWT |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| +#' | LMA |`r emojifont::emoji('white_check_mark')`| | +#' | PROT | |`r emojifont::emoji('white_check_mark')`| +#' | CBC | |`r emojifont::emoji('white_check_mark')`| +#' | N |`r emojifont::emoji('white_check_mark')`|`r emojifont::emoji('white_check_mark')`| #' #' Argument `InitValues` is expecting a default value for each of the parameters as well as an `alpha` value. #' @importFrom pracma fmincon @@ -111,12 +111,13 @@ Invert_PROSPECT <- function(SpecPROSPECT = NULL, lb = parms_checked$lb, ub = parms_checked$ub, verbose = verbose) if (NA %in% res$par){ - ModifyInit <- match(parms_checked$Parms2Estimate,names(parms_checked$InitValues)) + ModifyInit <- match(parms_checked$Parms2Estimate, + names(parms_checked$InitValues)) updateInitValues <- parms_checked$InitValues updateInitValues[ModifyInit] <- 1.1*updateInitValues[ModifyInit] res <- tryInversion(x0 = updateInitValues, MeritFunction = MeritFunction, SpecPROSPECT = SpecPROSPECT, - Refl = RT$Refl[[idsample]], Tran = RT$Tran[[idsample]], + Refl = RT$Refl[[idsample]], Tran =RT$Tran[[idsample]], Parms2Estimate = parms_checked$Parms2Estimate, lb = parms_checked$lb, ub = parms_checked$ub, verbose = verbose) @@ -133,16 +134,17 @@ Invert_PROSPECT <- function(SpecPROSPECT = NULL, #' Function handling error during inversion #' #' @param x0 numeric. Vector of input variables to estimate -#' @param MeritFunction character. name of the function to be used as merit function -#' @param SpecPROSPECT list. Includes optical constants -#' refractive index, specific absorption coefficients and corresponding spectral bands +#' @param MeritFunction character. name of the merit function +#' @param SpecPROSPECT list. Includes optical constants refractive index, +#' specific absorption coefficients and corresponding spectral bands #' @param Refl numeric. measured reflectance data #' @param Tran numeric. measured Transmittance data #' @param Parms2Estimate character vector. Parameters to estimate #' to be estimated through inversion #' @param lb numeric. Lower bound #' @param ub numeric. Upper bound -#' @param verbose boolean. Set to TRUE if you want information about adjustment of tolerance during inversion. +#' @param verbose boolean. Set TRUE for information on adjustment of tolerance +#' during inversion. #' #' @return res estimates of the parameters #' @details @@ -198,7 +200,7 @@ tryInversion <- function(x0, MeritFunction, SpecPROSPECT, Refl, Tran, for (parm in Parms2Estimate) x0[parm] <- lb[[parm]]+runif(1)*(ub[[parm]]-lb[[parm]]) reinit <- TRUE } - # if lower or upper band reached, perform new inversion with readjusted initial values + # perform inversion with readjusted initial values if lower/upper band reached while (reinit==TRUE & attempt<2){ attempt <- attempt+1 if (verbose) print_msg(cause = 'ULBounds') @@ -209,7 +211,7 @@ tryInversion <- function(x0, MeritFunction, SpecPROSPECT, Refl, Tran, res <- tryCatch( { res <- fmincon( - x0 = as.numeric(x0[Parms2Estimate]), fn = MeritFunction, gr = NULL, + x0 = as.numeric(x0[Parms2Estimate]), fn = MeritFunction, gr =NULL, SpecPROSPECT = SpecPROSPECT, Refl = Refl, Tran = Tran, Input_PROSPECT = x0, Parms2Estimate = Parms2Estimate, method = "SQP", A = NULL, b = NULL, Aeq = NULL, beq = NULL, @@ -244,8 +246,8 @@ tryInversion <- function(x0, MeritFunction, SpecPROSPECT, Refl, Tran, #' Merit function for PROSPECT inversion #' #' @param x numeric. Vector of input variables to estimate -#' @param SpecPROSPECT list. Includes optical constants -#' refractive index, specific absorption coefficients and corresponding spectral bands +#' @param SpecPROSPECT list. Includes optical constants refractive index, +#' specific absorption coefficients and corresponding spectral bands #' @param Refl numeric. measured reflectance data #' @param Tran numeric. measured Transmittance data #' @param Input_PROSPECT dataframe. set of PROSPECT input variables @@ -268,7 +270,7 @@ Merit_RMSE_PROSPECT <- function(x, SpecPROSPECT, Refl, Tran, #' @param Refl numeric. Reflectance on which PROSPECT ins inverted #' @param Tran numeric. Transmittance on which PROSPECT ins inverted #' -#' @return fc sum of squared difference between simulated and measured leaf optical properties +#' @return fc sum of squared difference bw simulated and measured leaf optics #' @export CostVal_RMSE <- function(RT, Refl, Tran) { if (is.null(Tran)) { @@ -284,14 +286,14 @@ CostVal_RMSE <- function(RT, Refl, Tran) { #' This function defines a regression model to estimate N from R only or T only #' @param lambda numeric. spectral bands corresponding to experimental data -#' @param SpecPROSPECT list. Includes optical constants -#' refractive index, specific absorption coefficients and corresponding spectral bands +#' @param SpecPROSPECT list. Includes optical constants refractive index, +#' specific absorption coefficients and corresponding spectral bands #' @param Refl numeric. Measured reflectance data #' @param Tran numeric. Measured Transmittance data #' @param OptWL_R list. optimal wavelengths used to estimate N from R only #' @param OptWL_T list. optimal wavelengths used to estimate N from T only #' -#' @return Nprior vector corresponding to teh prior estimation of N based on R only or T only +#' @return Nprior prior estimation of N with R or T only #' @importFrom stats lm runif #' @export Get_Nprior <- function(lambda, SpecPROSPECT = NULL, Refl = NULL, Tran = NULL, @@ -656,8 +658,8 @@ Invert_PROSPECT_subdomain <- function(New_Features, Refl, Tran, SpecPROSPECT, xlub = data.frame( CHL = c(1e-4, 150), CAR = c(1e-4, 25), ANT = c(0, 50), BROWN = c(0, 1), - EWT = c(1e-8, 0.1), LMA = c(1e-6, .06), - PROT = c(1e-7, .006), CBC = c(1e-6, .054), + EWT = c(1e-8, 0.1), LMA = c(1e-6, 0.06), + PROT = c(1e-7, .006), CBC = c(1e-6, 0.054), N = c(.5, 4), alpha = c(10, 90)), verbose = FALSE){ @@ -822,20 +824,19 @@ reshape_lop4inversion <- function(Refl, Tran, SpecPROSPECT){ #' Function to check good agreement between prospect version and parameter list #' -#' @param PROSPECT_version character. Version of prospect model used for the inversion: '5', '5B', 'D', 'DB', 'PRO', 'PROB', -#' See details. +#' @param PROSPECT_version character. version used for inversion: 'D' or 'PRO' #' @param Est_Brown_Pigments boolean. should brown pigments be accounted for during inversion? #' @param Est_alpha boolean. should alpha be accounted for during inversion? #' @param Parms2Estimate character vector. Parameters to estimate (can be 'ALL') #' @param xlub data.frame. Boundaries of the parameters to estimate. -#' The data.frame must have columns corresponding to \code{Parms2Estimate} first line being -#' the lower boundaries and second line the upper boundaries. -#' @param InitValues data.frame. Default values of PROSPECT parameters. During optimization, -#' they are used either as initialization values for parameters to estimate, -#' or as fix values for other parameters. +#' The data.frame must have columns corresponding to \code{Parms2Estimate} first +#' line being the lower boundaries and second line the upper boundaries. +#' @param InitValues dataframe. Default values of PROSPECT parameters. During +#' optimization, they are used either as initialization values for parameters to +#' estimate, or as fix values for other parameters. #' Parameters not compatible with PROSPECT_version are not taken into account. #' -#' @return list consolidated list of parameters to estimate and corresponding lower / upper boundaries +#' @return list of parameters to estimate & corresponding lower/upper boundaries #' @export check_prospect_parms <- function(PROSPECT_version, Parms2Estimate, @@ -884,7 +885,7 @@ check_prospect_parms <- function(PROSPECT_version, Parms2Estimate, #' @param Tran dataframe. transmittance data #' @param SpecPROSPECT dataframe. spectral properties used in PROSPECT #' -#' @return Nprior dataframe. N values corresponding to reflectance or transmittance +#' @return Nprior dataframe. N values corresponding to Refl or Tran #' @export SetNValues <- function(Refl, Tran, SpecPROSPECT){ @@ -904,7 +905,7 @@ SetNValues <- function(Refl, Tran, SpecPROSPECT){ #' Function to set initial parameterization when performing PROSPECT inversion #' using optimal configuration #' -#' @param Parms2Estimate character vector. Parameters to estimate (can be 'ALL') +#' @param Parms2Estimate character. Parameters to estimate #' @param ParmEst character. PROSPECT parameters to be estimated #' @param PROSPECT_version character. Version of prospect model used for the #' inversion: '5', '5B', 'D', 'DB', 'PRO', 'PROB', @@ -921,7 +922,8 @@ SetNValues <- function(Refl, Tran, SpecPROSPECT){ SetInitParm <- function(Parms2Estimate, ParmEst, PROSPECT_version, Nprior, ANTinit, OptDomain, Refl, Tran){ - UL_Bounds <- PROSPECT_version_tmp <- Parms2Estimate_tmp <- InitValues <- list() + UL_Bounds <- PROSPECT_version_tmp <- + Parms2Estimate_tmp <- InitValues <- list() for (parm in Parms2Estimate){ ParmEst[[parm]] <- c() InitValues[[parm]] <- list() @@ -942,15 +944,16 @@ SetInitParm <- function(Parms2Estimate, ParmEst, PROSPECT_version, Nprior, InitValues[[parm]] <- data.frame(CHL=40, CAR=10, ANT=ANTinit, BROWN=0, EWT=0.01, LMA=0.01, N=Nprior) } - if (parm == "CHL" | parm == "CAR"){ PROSPECT_version_tmp[[parm]] <- PROSPECT_version - if (!PROSPECT_version =='5'){ Parms2Estimate_tmp[[parm]] <- c('CHL', 'CAR', 'ANT')} - else if (PROSPECT_version =='5'){ Parms2Estimate_tmp[[parm]] <- c('CHL', 'CAR')} + if (!PROSPECT_version =='5'){ + Parms2Estimate_tmp[[parm]] <- c('CHL', 'CAR', 'ANT') + } else if (PROSPECT_version =='5'){ + Parms2Estimate_tmp[[parm]] <- c('CHL', 'CAR') + } InitValues[[parm]] <- data.frame(CHL=40, CAR=10, ANT=ANTinit, BROWN=0, EWT=0.01, LMA=0.01, N=Nprior) } - if (parm == "EWT"){ PROSPECT_version_tmp[[parm]] <- PROSPECT_version if (!PROSPECT_version =='PRO'){ diff --git a/R/SpecPROSPECT_FullRange-data.R b/R/SpecPROSPECT_FullRange-data.R index 7c68c1f..ef72ea7 100644 --- a/R/SpecPROSPECT_FullRange-data.R +++ b/R/SpecPROSPECT_FullRange-data.R @@ -20,6 +20,8 @@ #' - *SAC_LMA*: specific absorption coefficient for dry matter (Leaf Mass per Area) #' - *SAC_PROT*: specific absorption coefficient for proteins #' - *SAC_CBC*: specific absorption coefficient for carbon-base constituents -#' - *calctav_90*: transmissivity of a dielectric plane surface, averaged over all directions of incidence and over all polarizations for solid angle of 90 degrees -#' - *calctav_40*: transmissivity of a dielectric plane surface, averaged over all directions of incidence and over all polarizations for solid angle of 40 degrees +#' - *calctav_90*: transmissivity of a dielectric plane surface, averaged over +#' all directions of incidence & all polarizations for solid angle of 90 deg +#' - *calctav_40*: transmissivity of a dielectric plane surface, averaged over +#' all directions of incidence & all polarizations for solid angle of 40 deg "SpecPROSPECT_FullRange" diff --git a/data-raw/DATASET.R b/data-raw/DATASET.R index 07c5a2f..a014831 100644 --- a/data-raw/DATASET.R +++ b/data-raw/DATASET.R @@ -6,5 +6,6 @@ ANT <- 2*runif(10) EWT <- 0.04*runif(10) LMA <- 0.02*runif(10) N <- 1+2*runif(10) -Input_PROSPECT <- data.frame('CHL'=CHL,'CAR'=CAR,'ANT'=ANT,'EWT'=EWT,'LMA'=LMA,'N'=N) +Input_PROSPECT <- data.frame('CHL'=CHL,'CAR'=CAR,'ANT'=ANT, + 'EWT'=EWT,'LMA'=LMA,'N'=N) diff --git a/man/CostVal_RMSE.Rd b/man/CostVal_RMSE.Rd index 73fdf1a..ca61fac 100644 --- a/man/CostVal_RMSE.Rd +++ b/man/CostVal_RMSE.Rd @@ -14,7 +14,7 @@ CostVal_RMSE(RT, Refl, Tran) \item{Tran}{numeric. Transmittance on which PROSPECT ins inverted} } \value{ -fc sum of squared difference between simulated and measured leaf optical properties +fc sum of squared difference bw simulated and measured leaf optics } \description{ Value of the cost criterion to minimize during PROSPECT inversion diff --git a/man/FitSpectralData.Rd b/man/FitSpectralData.Rd index 787bc72..8b7e54e 100644 --- a/man/FitSpectralData.Rd +++ b/man/FitSpectralData.Rd @@ -17,18 +17,18 @@ FitSpectralData( \arguments{ \item{lambda}{numeric. Spectral bands corresponding to experimental data} -\item{SpecPROSPECT}{list. Includes optical constants -refractive index, specific absorption coefficients and corresponding spectral bands} +\item{SpecPROSPECT}{list. Includes optical constants: refractive index, +specific absorption coefficients and corresponding spectral bands} \item{Refl}{numeric. Measured reflectance data} \item{Tran}{numeric. Measured Transmittance data} -\item{UserDomain}{numeric. either Lower and upper bounds for domain of interest (optional) -or list of spectral bands of interest} +\item{UserDomain}{numeric. either Lower and upper bounds for domain of +interest (optional) or list of spectral bands of interest} -\item{UL_Bounds}{boolean. set to TRUE if UserDomain only includes lower and upper band, -set to FALSE if UserDomain is a list of spectral bands (in nm)} +\item{UL_Bounds}{boolean. set to TRUE if UserDomain only includes lower and +upper band, set to FALSE if UserDomain is a list of spectral bands (in nm)} } \value{ list including spectral properties at the new resolution diff --git a/man/Get_Nprior.Rd b/man/Get_Nprior.Rd index 4873d47..bec9575 100644 --- a/man/Get_Nprior.Rd +++ b/man/Get_Nprior.Rd @@ -16,8 +16,8 @@ Get_Nprior( \arguments{ \item{lambda}{numeric. spectral bands corresponding to experimental data} -\item{SpecPROSPECT}{list. Includes optical constants -refractive index, specific absorption coefficients and corresponding spectral bands} +\item{SpecPROSPECT}{list. Includes optical constants refractive index, +specific absorption coefficients and corresponding spectral bands} \item{Refl}{numeric. Measured reflectance data} @@ -28,7 +28,7 @@ refractive index, specific absorption coefficients and corresponding spectral ba \item{OptWL_T}{list. optimal wavelengths used to estimate N from T only} } \value{ -Nprior vector corresponding to teh prior estimation of N based on R only or T only +Nprior prior estimation of N with R or T only } \description{ This function defines a regression model to estimate N from R only or T only diff --git a/man/Invert_PROSPECT.Rd b/man/Invert_PROSPECT.Rd index 85b3c6c..23eed7f 100644 --- a/man/Invert_PROSPECT.Rd +++ b/man/Invert_PROSPECT.Rd @@ -24,8 +24,8 @@ Invert_PROSPECT( ) } \arguments{ -\item{SpecPROSPECT}{list. Includes optical constants -refractive index, specific absorption coefficients and corresponding spectral bands} +\item{SpecPROSPECT}{list. Includes optical constants refractive index, +specific absorption coefficients and corresponding spectral bands} \item{Refl}{numeric. Measured reflectance data} @@ -36,17 +36,17 @@ they are used either as initialization values for parameters to estimate, or as fix values for other parameters. Parameters not compatible with PROSPECT_version are not taken into account.} -\item{Parms2Estimate}{character vector. Parameters to estimate (can be 'ALL')} +\item{Parms2Estimate}{character. Parameters to estimate (can be 'ALL')} -\item{PROSPECT_version}{character. Version of prospect model used for the inversion: '5', '5B', 'D', 'DB', 'PRO', 'PROB', +\item{PROSPECT_version}{character. prospect version used for inversion: 'D' or 'PRO' See details.} \item{MeritFunction}{character. name of the function to be used as merit function with given criterion to minimize (default = RMSE)} \item{xlub}{data.frame. Boundaries of the parameters to estimate. -The data.frame must have columns corresponding to \code{Parms2Estimate} first line being -the lower boundaries and second line the upper boundaries.} +The data.frame must have columns corresponding to \code{Parms2Estimate} +first line being the lower boundaries and second line the upper boundaries.} \item{Est_Brown_Pigments}{boolean. should brown pigments be accounted for during inversion?} @@ -64,18 +64,18 @@ Performs PROSPECT inversion using iterative optimization in order to define estimate a set of user defined parameters } \details{ -Six versions of prospect are available for inversion. -The version is depending on the parameters taken into account:\tabular{ccccccc}{ - Version \tab 5 \tab 5B \tab D \tab DB \tab PRO \tab PROB \cr - CHL \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \cr - CAR \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \cr - ANT \tab \tab \tab ✅ \tab ✅ \tab ✅ \tab ✅ \cr - BROWN \tab \tab ✅ \tab \tab ✅ \tab \tab ✅ \cr - EWT \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \cr - LMA \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab \tab \cr - PROT \tab \tab \tab \tab \tab ✅ \tab ✅ \cr - CBC \tab \tab \tab \tab \tab ✅ \tab ✅ \cr - N \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \tab ✅ \cr +Two versions of prospect are available for inversion. +The version is depending on the parameters taken into account:\tabular{ccc}{ + Version \tab D \tab PRO \cr + CHL \tab ✅ \tab ✅ \cr + CAR \tab ✅ \tab ✅ \cr + ANT \tab ✅ \tab ✅ \cr + BROWN \tab ✅ \tab ✅ \cr + EWT \tab ✅ \tab ✅ \cr + LMA \tab ✅ \tab \cr + PROT \tab \tab ✅ \cr + CBC \tab \tab ✅ \cr + N \tab ✅ \tab ✅ \cr } diff --git a/man/Merit_RMSE_PROSPECT.Rd b/man/Merit_RMSE_PROSPECT.Rd index 8a83ad8..45ef67c 100644 --- a/man/Merit_RMSE_PROSPECT.Rd +++ b/man/Merit_RMSE_PROSPECT.Rd @@ -16,8 +16,8 @@ Merit_RMSE_PROSPECT( \arguments{ \item{x}{numeric. Vector of input variables to estimate} -\item{SpecPROSPECT}{list. Includes optical constants -refractive index, specific absorption coefficients and corresponding spectral bands} +\item{SpecPROSPECT}{list. Includes optical constants refractive index, +specific absorption coefficients and corresponding spectral bands} \item{Refl}{numeric. measured reflectance data} diff --git a/man/PROSPECT_LUT.Rd b/man/PROSPECT_LUT.Rd index 12742aa..d3c1b41 100644 --- a/man/PROSPECT_LUT.Rd +++ b/man/PROSPECT_LUT.Rd @@ -8,7 +8,7 @@ leaf chemical & structural parameters} PROSPECT_LUT(Input_PROSPECT, SpecPROSPECT = NULL) } \arguments{ -\item{Input_PROSPECT}{dataframe. full list of PROSPECT input parameters. Default = Set to NULL} +\item{Input_PROSPECT}{dataframe. list of PROSPECT input parameters.} \item{SpecPROSPECT}{list. spectral constants refractive index, specific absorption coefficients & spectral bands} diff --git a/man/SetInitParm.Rd b/man/SetInitParm.Rd index 34b8bff..63bb31d 100644 --- a/man/SetInitParm.Rd +++ b/man/SetInitParm.Rd @@ -17,7 +17,7 @@ SetInitParm( ) } \arguments{ -\item{Parms2Estimate}{character vector. Parameters to estimate (can be 'ALL')} +\item{Parms2Estimate}{character. Parameters to estimate} \item{ParmEst}{character. PROSPECT parameters to be estimated} diff --git a/man/SetNValues.Rd b/man/SetNValues.Rd index 1cb78ed..0680de9 100644 --- a/man/SetNValues.Rd +++ b/man/SetNValues.Rd @@ -14,7 +14,7 @@ SetNValues(Refl, Tran, SpecPROSPECT) \item{SpecPROSPECT}{dataframe. spectral properties used in PROSPECT} } \value{ -Nprior dataframe. N values corresponding to reflectance or transmittance +Nprior dataframe. N values corresponding to Refl or Tran } \description{ Function set N values if reflectance or transmittance is missing diff --git a/man/SpecPROSPECT_FullRange.Rd b/man/SpecPROSPECT_FullRange.Rd index 1e77b90..b927e3c 100644 --- a/man/SpecPROSPECT_FullRange.Rd +++ b/man/SpecPROSPECT_FullRange.Rd @@ -17,8 +17,10 @@ A dataframe including 2101 rows and 10 columns \item \emph{SAC_LMA}: specific absorption coefficient for dry matter (Leaf Mass per Area) \item \emph{SAC_PROT}: specific absorption coefficient for proteins \item \emph{SAC_CBC}: specific absorption coefficient for carbon-base constituents -\item \emph{calctav_90}: transmissivity of a dielectric plane surface, averaged over all directions of incidence and over all polarizations for solid angle of 90 degrees -\item \emph{calctav_40}: transmissivity of a dielectric plane surface, averaged over all directions of incidence and over all polarizations for solid angle of 40 degrees +\item \emph{calctav_90}: transmissivity of a dielectric plane surface, averaged over +all directions of incidence & all polarizations for solid angle of 90 deg +\item \emph{calctav_40}: transmissivity of a dielectric plane surface, averaged over +all directions of incidence & all polarizations for solid angle of 40 deg } } \usage{ diff --git a/man/check_prospect_parms.Rd b/man/check_prospect_parms.Rd index a232664..cf64a1a 100644 --- a/man/check_prospect_parms.Rd +++ b/man/check_prospect_parms.Rd @@ -14,8 +14,7 @@ check_prospect_parms( ) } \arguments{ -\item{PROSPECT_version}{character. Version of prospect model used for the inversion: '5', '5B', 'D', 'DB', 'PRO', 'PROB', -See details.} +\item{PROSPECT_version}{character. version used for inversion: 'D' or 'PRO'} \item{Parms2Estimate}{character vector. Parameters to estimate (can be 'ALL')} @@ -24,16 +23,16 @@ See details.} \item{Est_alpha}{boolean. should alpha be accounted for during inversion?} \item{xlub}{data.frame. Boundaries of the parameters to estimate. -The data.frame must have columns corresponding to \code{Parms2Estimate} first line being -the lower boundaries and second line the upper boundaries.} +The data.frame must have columns corresponding to \code{Parms2Estimate} first +line being the lower boundaries and second line the upper boundaries.} -\item{InitValues}{data.frame. Default values of PROSPECT parameters. During optimization, -they are used either as initialization values for parameters to estimate, -or as fix values for other parameters. +\item{InitValues}{dataframe. Default values of PROSPECT parameters. During +optimization, they are used either as initialization values for parameters to +estimate, or as fix values for other parameters. Parameters not compatible with PROSPECT_version are not taken into account.} } \value{ -list consolidated list of parameters to estimate and corresponding lower / upper boundaries +list of parameters to estimate & corresponding lower/upper boundaries } \description{ Function to check good agreement between prospect version and parameter list diff --git a/man/tryInversion.Rd b/man/tryInversion.Rd index a125256..63ed3f1 100644 --- a/man/tryInversion.Rd +++ b/man/tryInversion.Rd @@ -19,10 +19,10 @@ tryInversion( \arguments{ \item{x0}{numeric. Vector of input variables to estimate} -\item{MeritFunction}{character. name of the function to be used as merit function} +\item{MeritFunction}{character. name of the merit function} -\item{SpecPROSPECT}{list. Includes optical constants -refractive index, specific absorption coefficients and corresponding spectral bands} +\item{SpecPROSPECT}{list. Includes optical constants refractive index, +specific absorption coefficients and corresponding spectral bands} \item{Refl}{numeric. measured reflectance data} @@ -35,7 +35,8 @@ to be estimated through inversion} \item{ub}{numeric. Upper bound} -\item{verbose}{boolean. Set to TRUE if you want information about adjustment of tolerance during inversion.} +\item{verbose}{boolean. Set TRUE for information on adjustment of tolerance +during inversion.} } \value{ res estimates of the parameters diff --git a/paper/paper.md b/paper/paper.md index 31981b7..c67abd6 100644 --- a/paper/paper.md +++ b/paper/paper.md @@ -75,11 +75,14 @@ spectroscopy [@jay_physically-based_2016] and PROSAIL for canopy reflectance mod Note that PROSPECT is also available in packages written in [python](https://github.com/jgomezdans/prosail), [Julia](https://github.com/RemoteSensingTools/CanopyOptics.jl) and [R](https://github.com/ashiklom/rrtm). -The R package `prospect` includes recent versions of PROSPECT, and aims -at providing up-to-date developments in terms of model version and inversion strategies. +PROSPECT versions 4 and 5 developed by [@feret2008] are deprecated. +Therefore PROSPECT-D and PROSPECT-PRO are recommended versions. +The R package `prospect` includes recent versions of PROSPECT (D and PRO), +and aims at providing up-to-date developments in terms of future model version +and inversion strategies. This includes parameterizable inversion routines, to ease physical model inversion for beginners, and to help advanced users in designing and testing their own -inversion strategy. +inversion strategy. # Overview @@ -116,6 +119,8 @@ LMA: leaf mass per area; PROT: proteins; CBC: carbon based constituents).\label{ As PROSPECT is a relatively simple and computationally efficient model, iterative optimization is the most widespread method to invert PROSPECT and assess leaf chemistry and structure from their optical properties. +It usually takes less than 1 second to perform PROSPECT inversion, which is acceptable +when processing experimental datasets of leaf optical properties including 100-1000 samples. Iterative optimization aims at minimizing a cost function comparing measured and simulated leaf optical properties. This procedure is based on the function `fmincon` included in the package `pracma`. @@ -350,4 +355,4 @@ the initial version of the PROSPECT model. We also warmly thank Luc Bidel, Christophe François and Gabriel Pavan who collected the ANGERS data set. -# References \ No newline at end of file +# References diff --git a/tests/testthat/test-Invert_PROSPECT.R b/tests/testthat/test-Invert_PROSPECT.R index f0fa631..c919c63 100644 --- a/tests/testthat/test-Invert_PROSPECT.R +++ b/tests/testthat/test-Invert_PROSPECT.R @@ -12,8 +12,10 @@ test_that("PROSPECT-D inversion produces accurate biophysical assessment", { expect_true(abs(leafBP$EWT-BPinit$EWT)<1e-6) expect_true(abs(leafBP$LMA-BPinit$LMA)<1e-6) - lrt$Reflectance <- lrt$Reflectance*(1+rnorm(length(lrt$Reflectance),0,0.01)) - lrt$Transmittance <- lrt$Transmittance*(1+rnorm(length(lrt$Transmittance),0,0.01)) + lrt$Reflectance <- lrt$Reflectance*(1+rnorm(length(lrt$Reflectance), + 0,0.01)) + lrt$Transmittance <- lrt$Transmittance*(1+rnorm(length(lrt$Transmittance), + 0,0.01)) leafBP <- Invert_PROSPECT(Refl = lrt$Reflectance, Tran = lrt$Transmittance) diff --git a/tests/testthat/test-Invert_PROSPECT_OPT.R b/tests/testthat/test-Invert_PROSPECT_OPT.R index b161b33..852b5ab 100644 --- a/tests/testthat/test-Invert_PROSPECT_OPT.R +++ b/tests/testthat/test-Invert_PROSPECT_OPT.R @@ -12,12 +12,15 @@ test_that("PROSPECT-D inversion over optimal domains produces accurate biophysic expect_true(abs(leafBP$EWT-BPinit$EWT)<1e-7) expect_true(abs(leafBP$LMA-BPinit$LMA)<1e-7) - lrt$Reflectance <- lrt$Reflectance*(1+rnorm(length(lrt$Reflectance),0,0.01)) - lrt$Transmittance <- lrt$Transmittance*(1+rnorm(length(lrt$Transmittance),0,0.01)) + lrt$Reflectance <- lrt$Reflectance*(1+rnorm(length(lrt$Reflectance), + 0,0.01)) + lrt$Transmittance <- lrt$Transmittance*(1+rnorm(length(lrt$Transmittance), + 0,0.01)) leafBPopt <- Invert_PROSPECT_OPT(lambda = lrt$wvl, Refl = lrt$Reflectance, Tran = lrt$Transmittance, - Parms2Estimate = c('CHL', 'CAR', 'EWT', 'LMA')) + Parms2Estimate = c('CHL', 'CAR', + 'EWT', 'LMA')) expect_true(abs(leafBPopt$CHL-BPinit$CHL)<1e-0) expect_true(abs(leafBPopt$CAR-BPinit$CAR)<1e-0) expect_true(abs(leafBPopt$EWT-BPinit$EWT)<1e-4) diff --git a/vignettes/prospect1.Rmd b/vignettes/prospect1.Rmd index 230ac44..75282b2 100644 --- a/vignettes/prospect1.Rmd +++ b/vignettes/prospect1.Rmd @@ -78,7 +78,7 @@ When run without input parameters, `PROSPECT` is run with default values: ```{r prospect direct mode default} library(prospect) LRT_default <- PROSPECT() -# the following command is equivalent for simulation over the full spectral domain +# the following command is equivalent when simulating over the full spectral domain LRT_default <- PROSPECT(SpecPROSPECT = prospect::SpecPROSPECT_FullRange) ``` diff --git a/vignettes/prospect2.Rmd b/vignettes/prospect2.Rmd index 6116485..5670406 100644 --- a/vignettes/prospect2.Rmd +++ b/vignettes/prospect2.Rmd @@ -113,8 +113,8 @@ SubData <- FitSpectralData(lambda = LRT_D$wvl, Tran = LRT_D$Transmittance, UserDomain = SpectralSubDomain) -# Note that FitSpectralData can also run with UserDomain defining upper and lower bounds -# Then you will need to set UL_Bounds = TRUE +# Note that FitSpectralData can also run with UserDomain defining +# upper and lower bounds when setting input argument 'UL_Bounds = TRUE' ULBounds <- c(400,800) SubData <- FitSpectralData(lambda = LRT_D$wvl, Refl = LRT_D$Reflectance, @@ -189,7 +189,8 @@ Parms2Estimate <- c('CHL','CAR','ANT','EWT','LMA') # define initial values for the inversion InitValues <- data.frame(CHL = 40, CAR = 8, ANT = 0.1, BROWN = 0, EWT = 0.01, LMA = 0.01, N = 1.5) -# call Invert_PROSPECT_OPT in order to automaticall get optimal estimation of leaf parameters following latest published results +# call Invert_PROSPECT_OPT to get optimal estimation of leaf parameters +# using optimal spectral domains ParmEst <- Invert_PROSPECT_OPT(lambda = LRT_D$wvl, Refl = LRT_D$Reflectance, Tran = LRT_D$Transmittance, diff --git a/vignettes/prospect3.Rmd b/vignettes/prospect3.Rmd index 18d307f..e58220f 100644 --- a/vignettes/prospect3.Rmd +++ b/vignettes/prospect3.Rmd @@ -49,7 +49,7 @@ fileName <- list('DataBioch.txt','ReflectanceData.txt','TransmittanceData.txt') DataBioch <- fread(file.path(gitlab_Rep,dbName,fileName[[1]])) Refl <- fread(file.path(gitlab_Rep,dbName,fileName[[2]])) Tran <- fread(file.path(gitlab_Rep,dbName,fileName[[3]])) -# Get the wavelengths corresponding to the reflectance and transmittance measurements +# Get wavelengths corresponding to the reflectance & transmittance measurements lambda <- Refl$wavelength Refl$wavelength <- NULL Tran$wavelength <- NULL @@ -69,7 +69,7 @@ Experimental leaf optics and optical constants of PROSPECT need to be adjusted b Parms2Estimate <- 'ALL' InitValues <- data.frame(CHL = 40, CAR = 10, ANT = 0.1, BROWN = 0, EWT = 0.01, LMA = 0.01, N = 1.5) -# adjust PROSPECT optical constants and experimental leaf optics before inversion +# adjust PROSPECT optical constants & experimental leaf optics before inversion SubData <- FitSpectralData(lambda = lambda, Refl = Refl, Tran = Tran) diff --git a/vignettes/prospect4.Rmd b/vignettes/prospect4.Rmd index cc9331d..d299294 100644 --- a/vignettes/prospect4.Rmd +++ b/vignettes/prospect4.Rmd @@ -49,7 +49,8 @@ library(data.table) # repository where data are stored gitlab_Rep <- 'https://gitlab.com/jbferet/myshareddata/raw/master/LOP/' # Datasets -dbName <- list('LOPEX_DRY_CAL','LOPEX_FRESH_CAL','LOPEX_DRY_VAL','LOPEX_FRESH_VAL') +dbName <- list('LOPEX_DRY_CAL','LOPEX_FRESH_CAL', + 'LOPEX_DRY_VAL','LOPEX_FRESH_VAL') # files available fileName <- list('DataBioch.txt','ReflectanceData.txt','TransmittanceData.txt') # download LOPEX data @@ -73,7 +74,7 @@ The optimal spectral domains are defined based on the results described in [Fér ```{r Invert PROSPECT-PRO} Parms2Estimate <- c('EWT','PROT','CBC') EWT_mod <- PROT_mod <- CBC_mod <- list() -# perform PROSPECT inversion using the optimal spectral domains for EWT, PROT and CBC +# perform PROSPECT inversion using optimal spectral domains for EWT, PROT & CBC InitValues <- data.frame(CHL = 40, CAR = 8, ANT = 0.1, BROWN = 0, EWT = 0.01, CBC = 0.009, PROT = 0.001, N = 1.5) for (db in dbName){ diff --git a/vignettes/prospect5.Rmd b/vignettes/prospect5.Rmd index 0e66e53..7e38bdd 100644 --- a/vignettes/prospect5.Rmd +++ b/vignettes/prospect5.Rmd @@ -57,7 +57,7 @@ fileName <- list('DataBioch.txt','ReflectanceData.txt','TransmittanceData.txt') DataBioch <- fread(file.path(gitlab_Rep,dbName,fileName[[1]])) Refl <- fread(file.path(gitlab_Rep,dbName,fileName[[2]])) Tran <- fread(file.path(gitlab_Rep,dbName,fileName[[3]])) -# Get the wavelengths corresponding to the reflectance and transmittance measurements +# Get wavelengths corresponding to the reflectance and transmittance measurements lambda <- Refl$wavelength Refl$wavelength <- NULL Tran$wavelength <- NULL