diff --git a/DESCRIPTION b/DESCRIPTION index 6c5caff..c867845 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: prospect Title: PROSPECT leaf radiative transfer model and inversion routines -Version: 1.6.1 +Version: 1.6.2 Authors@R: c(person(given = "Jean-Baptiste", family = "Feret", email = "jb.feret@teledetection.fr", @@ -20,12 +20,12 @@ LazyData: true Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.0 Suggests: + data.table, knitr, emojifont, rmarkdown, testthat (>= 3.0.0) Imports: - data.table, dplyr, expint, future, diff --git a/NAMESPACE b/NAMESPACE index d001035..918fa93 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,6 +7,7 @@ export(Invert_PROSPECT) export(Invert_PROSPECT_OPT) export(Invert_PROSPECT_subdomain) export(Merit_PROSPECT_RMSE) +export(Merit_PROSPECT_dRMSE) export(PROSPECT) export(PROSPECT_LUT) export(SetInitParm) @@ -22,7 +23,6 @@ export(print_msg) export(reshape_lop4inversion) export(tryInversion) import(dplyr) -importFrom(data.table,fread) importFrom(expint,expint) importFrom(future,multisession) importFrom(future,plan) @@ -33,4 +33,3 @@ importFrom(pracma,rmserr) importFrom(progress,progress_bar) importFrom(stats,lm) importFrom(stats,runif) -importFrom(utils,tail) diff --git a/NEWS.md b/NEWS.md index 4ff8e87..f38b726 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,13 @@ +# prospect v1.6.2 +## fix +- fixed wrong merge for correction of JOSS paper + +## addition +- added merit function Merit_PROSPECT_dRMSE to perform inversion based on 1st derivative + +## change +- moved data.table from Imports to Suggestions + # prospect v1.6.1 ## addition - added input dataframe InputPROSPECT to function PROSPECT diff --git a/R/Lib_PROSPECT.R b/R/Lib_PROSPECT.R index 2ade9ac..2f76eec 100644 --- a/R/Lib_PROSPECT.R +++ b/R/Lib_PROSPECT.R @@ -32,17 +32,23 @@ #' @param PROT numeric. protein content (g.cm-2) #' @param CBC numeric. NonProt Carbon-based constituent content (g.cm-2) #' @param alpha numeric. Solid angle for incident light at surface of leaf +#' @param check boolean. set to TRUE to check input data format #' #' @return leaf directional-hemispherical reflectance and transmittance #' @importFrom expint expint #' @export PROSPECT <- function(SpecPROSPECT = NULL, Input_PROSPECT = NULL, N = 1.5, CHL = 40.0, CAR = 8.0, ANT = 0.0, BROWN = 0.0, - EWT = 0.01, LMA = NULL, PROT = 0, CBC = 0, alpha = 40.0) { + EWT = 0.01, LMA = NULL, PROT = 0, CBC = 0, alpha = 40.0, + check = TRUE) { # define PROSPECT input in a dataframe - Input_PROSPECT <- define_Input_PROSPECT(Input_PROSPECT, CHL, CAR, ANT, BROWN, - EWT, LMA, PROT, CBC, N, alpha) + Input_PROSPECT <- define_Input_PROSPECT(Input_PROSPECT, CHL, CAR, + ANT, BROWN, EWT, LMA, PROT, + CBC, N, alpha) + # if (check) Input_PROSPECT <- define_Input_PROSPECT(Input_PROSPECT, CHL, CAR, + # ANT, BROWN, EWT, LMA, PROT, + # CBC, N, alpha) # default: simulates leaf optics using full spectral range if (is.null(SpecPROSPECT)) SpecPROSPECT <- prospect::SpecPROSPECT_FullRange # compute total absorption corresponding to each homogeneous layer @@ -260,7 +266,6 @@ define_Input_PROSPECT <- function(Input_PROSPECT, CHL = NULL, CAR = NULL, #' #' @return list including spectral properties at the new resolution #' @import dplyr -#' @importFrom utils tail #' @export FitSpectralData <- function(lambda, SpecPROSPECT = NULL, @@ -269,8 +274,10 @@ FitSpectralData <- function(lambda, SpecPROSPECT = NULL, # default: simulates leaf optics using full spectral range if (is.null(SpecPROSPECT)) SpecPROSPECT <- prospect::SpecPROSPECT_FullRange # convert Refl and Tran into dataframe if needed - if (class(Refl)[1]%in%c('numeric', 'matrix')) Refl <- data.frame(Refl) - if (class(Tran)[1]%in%c('numeric', 'matrix')) Tran <- data.frame(Tran) + if (inherits(Refl, what = c('numeric', 'matrix'))) Refl <- data.frame(Refl) + if (inherits(Tran, what = c('numeric', 'matrix'))) Tran <- data.frame(Tran) + # if (class(Refl)[1]%in%c('numeric', 'matrix')) Refl <- data.frame(Refl) + # if (class(Tran)[1]%in%c('numeric', 'matrix')) Tran <- data.frame(Tran) # Adjust LOP: check common spectral domain between PROSPECT and leaf optics if (!is.null(Refl)) Refl <- Refl %>% filter(lambda%in%SpecPROSPECT$lambda) if (!is.null(Tran)) Tran <- Tran %>% filter(lambda%in%SpecPROSPECT$lambda) @@ -356,7 +363,6 @@ PROSPECT_LUT <- function(Input_PROSPECT, SpecPROSPECT = NULL) { #' @param dbName character. name of the database available online #' #' @return list. Includes leaf chemistry, refl, tran & number of samples -#' @importFrom data.table fread #' @export download_LeafDB <- function(urldb = NULL, diff --git a/R/Lib_PROSPECT_Inversion.R b/R/Lib_PROSPECT_Inversion.R index 0dfcb21..b45153c 100644 --- a/R/Lib_PROSPECT_Inversion.R +++ b/R/Lib_PROSPECT_Inversion.R @@ -84,6 +84,8 @@ Invert_PROSPECT <- function(SpecPROSPECT = NULL, Est_alpha = Est_alpha, xlub = xlub, InitValues = InitValues) + # complement initial values + parms_checked$InitValues <- define_Input_PROSPECT(Input_PROSPECT = parms_checked$InitValues) # check if data class is compatible and convert into data.frame RT <- reshape_lop4inversion(Refl = Refl, Tran = Tran, @@ -253,6 +255,7 @@ tryInversion <- function(x0, MeritFunction, SpecPROSPECT, Refl, Tran, #' #' @return fc estimates of the parameters #' @export + Merit_PROSPECT_RMSE <- function(x, SpecPROSPECT, Refl, Tran, Input_PROSPECT, @@ -260,6 +263,9 @@ Merit_PROSPECT_RMSE <- function(x, SpecPROSPECT, x[x < 0] <- 0 Input_PROSPECT[Parms2Estimate] <- x RT <- do.call("PROSPECT", c(list(SpecPROSPECT = SpecPROSPECT), Input_PROSPECT)) + # RT <- do.call("PROSPECT", args = list(SpecPROSPECT = SpecPROSPECT, + # Input_PROSPECT = Input_PROSPECT, + # check = F)) fcr <- fct <- 0 if (!is.null(Refl)) fcr <- sqrt(sum((Refl - RT$Reflectance)**2) / length(RT$Reflectance)) if (!is.null(Tran)) fct <- sqrt(sum((Tran - RT$Transmittance)**2) / length(RT$Transmittance)) @@ -267,6 +273,35 @@ Merit_PROSPECT_RMSE <- function(x, SpecPROSPECT, return(fc) } + +#' 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 Refl numeric. measured reflectance data +#' @param Tran numeric. measured Transmittance data +#' @param Input_PROSPECT dataframe. set of PROSPECT input variables +#' @param Parms2Estimate numeric. location of variables from Input_PROSPECT +#' to be estimated through inversion +#' +#' @return fc estimates of the parameters +#' @export + +Merit_PROSPECT_dRMSE <- function(x, SpecPROSPECT, + Refl, Tran, + Input_PROSPECT, + Parms2Estimate) { + x[x < 0] <- 0 + Input_PROSPECT[Parms2Estimate] <- x + RT <- do.call("PROSPECT", c(list(SpecPROSPECT = SpecPROSPECT), Input_PROSPECT)) + fcr <- fct <- 0 + if (!is.null(Refl)) fcr <- sqrt(sum((diff(Refl) - diff(RT$Reflectance))**2) / (length(RT$Reflectance)-1)) + if (!is.null(Tran)) fct <- sqrt(sum((diff(Tran) - diff(RT$Transmittance))**2) / (length(RT$Transmittance)-1)) + fc <- fcr + fct + return(fc) +} + #' 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, diff --git a/man/Merit_PROSPECT_dRMSE.Rd b/man/Merit_PROSPECT_dRMSE.Rd new file mode 100644 index 0000000..3077b3f --- /dev/null +++ b/man/Merit_PROSPECT_dRMSE.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Lib_PROSPECT_Inversion.R +\name{Merit_PROSPECT_dRMSE} +\alias{Merit_PROSPECT_dRMSE} +\title{Merit function for PROSPECT inversion} +\usage{ +Merit_PROSPECT_dRMSE( + x, + SpecPROSPECT, + Refl, + Tran, + Input_PROSPECT, + Parms2Estimate +) +} +\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{Refl}{numeric. measured reflectance data} + +\item{Tran}{numeric. measured Transmittance data} + +\item{Input_PROSPECT}{dataframe. set of PROSPECT input variables} + +\item{Parms2Estimate}{numeric. location of variables from Input_PROSPECT +to be estimated through inversion} +} +\value{ +fc estimates of the parameters +} +\description{ +Merit function for PROSPECT inversion +} diff --git a/man/PROSPECT.Rd b/man/PROSPECT.Rd index 3dc9491..cb9740b 100644 --- a/man/PROSPECT.Rd +++ b/man/PROSPECT.Rd @@ -18,7 +18,8 @@ PROSPECT( LMA = NULL, PROT = 0, CBC = 0, - alpha = 40 + alpha = 40, + check = TRUE ) } \arguments{ @@ -47,6 +48,8 @@ and corresponding spectral bands} \item{CBC}{numeric. NonProt Carbon-based constituent content (g.cm-2)} \item{alpha}{numeric. Solid angle for incident light at surface of leaf} + +\item{check}{boolean. set to TRUE to check input data format} } \value{ leaf directional-hemispherical reflectance and transmittance diff --git a/paper/paper.md b/paper/paper.md index af58b7e..0443740 100644 --- a/paper/paper.md +++ b/paper/paper.md @@ -56,16 +56,16 @@ Hence, it is a key component for remote sensing applications dedicated to vegetation monitoring. Multiple versions have been released since its first version [@jacquemoud1990]. -[@feret2008] introduced carotenoids and [@feret2017] introduced anthocyanins, +@feret2008 introduced carotenoids and @feret2017 introduced anthocyanins, to simulate leaf optical properties from juvenile to mature and senescent development stages. -[@feret2021] introduced PROSPECT-PRO, the latest version separating dry matter +@feret2021 introduced PROSPECT-PRO, the latest version separating dry matter constituents into proteins and carbon based constituents. In parallel with updated versions of the model, model inversion strategies have been introduced to improve the assessment of leaf chemical constituents [@feret2019; @spafford2021]. -PROSPECT implementations since [@feret2008] can be found at +PROSPECT implementations since @feret2008 can be found at [this webpage](http://teledetection.ipgp.jussieu.fr/prosail/). This includes distributions in matlab, R and fortran programming languages. PROSPECT is coupled with vegetation models, including COSINE dedicated to