diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000000..58bb5ccb80f --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,57 @@ +# +# Add project labels +# + +# Add 'Documentation' label to any changes in the documentation + +'Documentation': + - book_source/** + - documentation/** + - CONTRIBUTING.md + - DEBUGING.md + - DEV-INTRO.md + - README.md + +# Add 'Dockerfile' label to any changes in the docker directory +'Dockerfile': + - docker/** + + +# Add 'Website' label to any changes in the web directory + +'Website': + - web/** + +# Add 'Base' label to any changes in the base directory + +'Base': + - base/** + +# Add 'Models' label to any changes in the models directory + +'Models': + - models/** + +# Add 'Modules' label to any changes in the modules directory + +'Modules': + - modules/** + +# Add 'GitHub Actions' label to any changes in the .github/workflows directory + +'GitHub Actions': + - .github/workflows/** + +# Add 'Scripts' label to any changes in the scripts directory + +'Scripts': + - scripts/** + +# Add 'Tests' label to any changes in the tests directory + +'Tests': + - tests/** + - '**/tests/**' + - '!**/tests/Rcheck_reference.log' + + diff --git a/.github/settings.yml b/.github/settings.yml new file mode 100644 index 00000000000..a7d87f7d2f9 --- /dev/null +++ b/.github/settings.yml @@ -0,0 +1,30 @@ +#Define the colour of labels over here + +labels: + + - name: "Documentation" + color: a2dcf2 + + - name: "Dockerfile" + color: 0052CC + + - name: "Website" + color: 84b6eb + + - name: "Base" + color: 1ED626 + + - name: "Models" + color: C5DEF5 + + - name: "Modules" + color: FBCA04 + + - name: "GitHub Actions" + color: 84b6eb + + - name: "Scripts" + color: 3B8924 + + - name: "Tests" + color: ff8c00 diff --git a/.github/workflows/prlabeler.yml b/.github/workflows/prlabeler.yml new file mode 100644 index 00000000000..1a29e659168 --- /dev/null +++ b/.github/workflows/prlabeler.yml @@ -0,0 +1,22 @@ +# This workflow is based on github action official label action v4. +# This workflow action is triggered on pull request event(on both fork & inside repo) +# Labels will be applied based on filepath modification in PR. +# This workflow uses a regex based labeling config file(.github/labeler.yml) to take labeling decision. + +name: "PR Labeler" +on: + - pull_request_target +jobs: + label: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + configuration-path: ".github/labeler.yml" + sync-labels: false + dot: true diff --git a/Makefile b/Makefile index cda4ad6f72b..10fa7950f82 100644 --- a/Makefile +++ b/Makefile @@ -153,7 +153,8 @@ clean: + ./scripts/time.sh "roxygen2 ${1}" Rscript -e ${SETROPTIONS} \ -e "if (!requireNamespace('roxygen2', quietly = TRUE)" \ -e " || packageVersion('roxygen2') != '7.2.3') {" \ - -e " devtools::install_github('r-lib/roxygen2@v7.2.3')" \ + -e " cran <- c(getOption('repos'), 'cloud.r-project.org')" \ + -e " remotes::install_version('roxygen2', '7.2.3', repos = cran, upgrade = FALSE)" \ -e "}" $(eval INSTALLED_ROXYGEN_VERSION := 7.2.3) echo `date` > $@ diff --git a/Makefile.depends b/Makefile.depends index be631f3bfe1..bc5143e0671 100644 --- a/Makefile.depends +++ b/Makefile.depends @@ -30,7 +30,7 @@ $(call depends,models/template): | .install/base/db .install/base/logger .instal $(call depends,modules/allometry): | .install/base/db $(call depends,modules/assim.batch): | .install/base/db .install/base/logger .install/base/remote .install/base/settings .install/base/utils .install/base/workflow .install/modules/benchmark .install/modules/emulator .install/modules/meta.analysis .install/modules/uncertainty $(call depends,modules/assim.sequential): | .install/base/db .install/base/logger .install/base/remote .install/base/settings .install/base/utils .install/base/visualization .install/base/workflow .install/modules/benchmark .install/modules/data.land .install/modules/data.remote .install/modules/uncertainty -$(call depends,modules/benchmark): | .install/base/db .install/base/logger .install/base/remote .install/base/settings .install/base/utils .install/modules/data.land +$(call depends,modules/benchmark): | .install/base/db .install/base/logger .install/base/settings .install/base/utils .install/modules/data.land $(call depends,modules/data.atmosphere): | .install/base/db .install/base/logger .install/base/remote .install/base/settings .install/base/utils $(call depends,modules/data.hydrology): | .install/base/logger .install/base/utils $(call depends,modules/data.land): | .install/base/db .install/base/logger .install/base/remote .install/base/settings .install/base/utils .install/base/visualization .install/modules/benchmark .install/modules/data.atmosphere diff --git a/base/all/DESCRIPTION b/base/all/DESCRIPTION index ed96934ee9a..18f93be1bb3 100644 --- a/base/all/DESCRIPTION +++ b/base/all/DESCRIPTION @@ -64,6 +64,7 @@ Depends: Imports: utils Suggests: + mockery, PEcAn.ED2, PEcAn.SIPNET, PEcAn.BIOCRO, @@ -71,6 +72,7 @@ Suggests: PEcAn.LINKAGES, PEcAn.allometry, PEcAn.photosynthesis, + sessioninfo, testthat License: BSD_3_clause + file LICENSE Copyright: Authors diff --git a/base/all/R/pecan_version.R b/base/all/R/pecan_version.R index 51f983f0be9..85c9fc346db 100644 --- a/base/all/R/pecan_version.R +++ b/base/all/R/pecan_version.R @@ -16,13 +16,16 @@ #' locations in `.libPaths()`, or if you've loaded a new version into your #' current session by loading it from its source directory without installing #' it to the R library. -#' If you see multiple rows unexpectedly, try `find.package(, verbose = TRUE)` to see where each version was found. +#' If you see multiple rows unexpectedly, try +#' `find.package(, verbose = TRUE)` to see where each version was found. #' #' @param version PEcAn release number to use for expected package versions #' @param exact Show only tags that exactly match `version`, #' or all tags that have it as a substring? #' @return data frame with columns for package name, expected version(s), -#' and installed version +#' and installed version. +#' If the `sessioninfo` package is installed, a fourth column reports where +#' each package was installed from: local, github, CRAN, etc. #' #' @examples #' pecan_version() @@ -35,25 +38,6 @@ #' @export pecan_version <- function(version = max(PEcAn.all::pecan_releases$version), exact = FALSE) { - all_pkgs <- as.data.frame(utils::installed.packages()) - our_pkgs <- all_pkgs[ - grepl("PEcAn", all_pkgs$Package), - c("Package", "Version") - ] - colnames(our_pkgs) <- c("package", "installed") - our_pkgs$installed <- package_version(our_pkgs$installed) - - # Check in currently loaded packages too, - # add rows for any that differ from installed versions - sess <- utils::sessionInfo() - sess <- c(sess$otherPkgs, sess$loadedOnly) - our_loaded <- sess[grepl("PEcAn", names(sess))] - our_loaded <- data.frame( - package = names(our_loaded), - installed = sapply(our_loaded, `[[`, "Version")) - our_loaded$installed <- package_version(our_loaded$installed) - our_pkgs <- merge(our_pkgs, our_loaded, all = TRUE) - if (!exact) { version <- sapply( X = version, @@ -62,9 +46,58 @@ pecan_version <- function(version = max(PEcAn.all::pecan_releases$version), ) version <- unique(unlist(version)) } + cols_to_return <- c("package", version, "installed") + + + if (requireNamespace("sessioninfo", quietly = TRUE)) { + cols_to_return <- c(cols_to_return, "source") + + all_pkgs <- sessioninfo::package_info(pkgs = "installed", dependencies = FALSE) + our_pkgs <- all_pkgs[grepl("PEcAn", all_pkgs$package),] + + all_loaded <- sessioninfo::package_info(pkgs = "loaded", dependencies = FALSE) + our_loaded <- all_loaded[grepl("PEcAn", all_loaded$package),] + + unloaded <- our_pkgs[!our_pkgs$package %in% our_loaded$package,] + our_pkgs <- rbind(our_loaded, unloaded) + our_pkgs <- our_pkgs[order(our_pkgs$package),] + + + # TODO: consider using package_info's callouts of packages where loaded and + # installed versions mismatch -- it's a more elegant version of what we + # were trying for with the "multiple rows for packages with multiple + # versions found" behavior. + our_pkgs$installed <- ifelse( + test = is.na(our_pkgs$loadedversion), + yes = our_pkgs$ondiskversion, + no = our_pkgs$loadedversion) + our_pkgs <- our_pkgs[, c("package", "installed", "source")] + our_pkgs$installed <- package_version(our_pkgs$installed) + + } else { + all_pkgs <- as.data.frame(utils::installed.packages()) + our_pkgs <- all_pkgs[ + grepl("PEcAn", all_pkgs$Package), + c("Package", "Version") + ] + colnames(our_pkgs) <- c("package", "installed") + our_pkgs$installed <- package_version(our_pkgs$installed) + sess <- utils::sessionInfo() + sess <- c(sess$otherPkgs, sess$loadedOnly) + our_loaded <- sess[grepl("PEcAn", names(sess))] + our_loaded <- data.frame( + package = names(our_loaded), + installed = sapply(our_loaded, `[[`, "Version")) + our_loaded$installed <- package_version(our_loaded$installed) + our_pkgs <- merge(our_pkgs, our_loaded, all = TRUE) + } + - res <- merge(our_pkgs, PEcAn.all::pecan_version_history, all = TRUE) - res <- res[, c("package", version, "installed")] + res <- merge( + x = our_pkgs, + y = PEcAn.all::pecan_version_history, + all = TRUE) + res <- res[, cols_to_return] drop_na_version_rows(res) } diff --git a/base/all/man/pecan_version.Rd b/base/all/man/pecan_version.Rd index e2ded17e8b1..a0275089a9a 100644 --- a/base/all/man/pecan_version.Rd +++ b/base/all/man/pecan_version.Rd @@ -14,7 +14,9 @@ or all tags that have it as a substring?} } \value{ data frame with columns for package name, expected version(s), -and installed version +and installed version. +If the \code{sessioninfo} package is installed, a fourth column reports where +each package was installed from: local, github, CRAN, etc. } \description{ Reports the currently installed or loaded version(s) of each PEcAn package, @@ -34,7 +36,8 @@ This can occur if you have installed different versions to different locations in \code{.libPaths()}, or if you've loaded a new version into your current session by loading it from its source directory without installing it to the R library. -If you see multiple rows unexpectedly, try \verb{find.package(, verbose = TRUE)} to see where each version was found. +If you see multiple rows unexpectedly, try +\verb{find.package(, verbose = TRUE)} to see where each version was found. } \examples{ pecan_version() diff --git a/base/all/tests/testthat/test-pecan_version.R b/base/all/tests/testthat/test-pecan_version.R index 2a9100d4d7a..c1e45b0c267 100644 --- a/base/all/tests/testthat/test-pecan_version.R +++ b/base/all/tests/testthat/test-pecan_version.R @@ -26,7 +26,7 @@ test_that("pecan_version", { # tags substring matched only when exact = FALSE expect_named( pecan_version("v1.5"), - c("package", paste0("v1.5.", 0:3), "installed") + c("package", paste0("v1.5.", 0:3), "installed", "source") ) expect_error( pecan_version("v1.5", exact = TRUE), @@ -34,14 +34,14 @@ test_that("pecan_version", { ) expect_named( pecan_version("v1.3", exact = TRUE), - c("package", "v1.3", "installed") + c("package", "v1.3", "installed", "source") ) # returns current release if no args given noargs <- pecan_version() expected_tag <- tail(PEcAn.all::pecan_releases, 1)$tag - expect_length(noargs, 3) - expect_named(noargs, c("package", expected_tag, "installed")) + expect_length(noargs, 4) + expect_named(noargs, c("package", expected_tag, "installed", "source")) # Why the `any()`s below? # Because R CMD check runs tests with local test dir added to .libPaths, @@ -67,3 +67,27 @@ test_that("pecan_version", { ) ) }) + + +test_that("pecan_version without sessioninfo", { + + with_sessinfo <- pecan_version() + + # make pecan_version think the sessioninfo package is unavailable + mockery::stub(pecan_version, 'requireNamespace', FALSE) + without_sessinfo <- pecan_version() + + expect_length(with_sessinfo, 4) + expect_length(without_sessinfo, 3) + expect_equal( + with_sessinfo[, colnames(with_sessinfo) != "source"], + without_sessinfo) +}) + +# TODO: Would be nice to add a check here that will notice if the list of PEcAn +# releases falls out of date, but it's not clear what other source of truth +# to consult to determine that. +# +# The approach that failed just before I wrote this note: +# No, the version of PEcAn.all (1.8.1.9000 today) is not reliably in sync with +# the PEcAn version last tagged as a release (1.7.2 today). diff --git a/base/workflow/DESCRIPTION b/base/workflow/DESCRIPTION index efd8efabefd..137b9499eb8 100644 --- a/base/workflow/DESCRIPTION +++ b/base/workflow/DESCRIPTION @@ -31,20 +31,21 @@ Description: The Predictive Ecosystem Carbon Analyzer that can be used to run the major steps of a PEcAn analysis. License: BSD_3_clause + file LICENSE Imports: - dplyr, - PEcAn.data.atmosphere, - PEcAn.data.land, - PEcAn.DB, - PEcAn.logger, - PEcAn.remote, - PEcAn.settings, - PEcAn.uncertainty, - PEcAn.utils, - purrr (>= 0.2.3), - XML + dplyr, + PEcAn.data.atmosphere, + PEcAn.data.land, + PEcAn.DB, + PEcAn.logger, + PEcAn.remote, + PEcAn.settings, + PEcAn.uncertainty, + PEcAn.utils, + purrr (>= 0.2.3), + XML Suggests: - testthat, - mockery + mockery, + testthat, + withr Copyright: Authors Encoding: UTF-8 RoxygenNote: 7.2.3 diff --git a/base/workflow/R/start_model_runs.R b/base/workflow/R/start_model_runs.R index 37771d9bf2b..3c84d588180 100644 --- a/base/workflow/R/start_model_runs.R +++ b/base/workflow/R/start_model_runs.R @@ -23,7 +23,7 @@ start_model_runs <- function(settings, write = TRUE, stop.on.error = TRUE) { run_file <- file.path(settings$rundir, "runs.txt") # check if runs need to be done - if (!file.exists(file.path(settings$rundir, "runs.txt"))) { + if (!file.exists(run_file)) { PEcAn.logger::logger.warn( "runs.txt not found, assuming no runs need to be done") return() diff --git a/base/workflow/tests/testthat/test.start_model_runs.R b/base/workflow/tests/testthat/test.start_model_runs.R new file mode 100644 index 00000000000..052950e2c93 --- /dev/null +++ b/base/workflow/tests/testthat/test.start_model_runs.R @@ -0,0 +1,20 @@ +test_that("`start_model_runs` throws a warning if runs.txt not provided", { + withr::with_tempdir({ + PEcAn.logger::logger.setUseConsole(TRUE, FALSE) + on.exit(PEcAn.logger::logger.setUseConsole(TRUE, TRUE)) + settings <- list(rundir = getwd()) + expect_output(start_model_runs(settings), "runs.txt not found") + }) +}) + +test_that("`start_model_runs` throws a warning if runs.txt is empty", { + withr::with_tempdir({ + PEcAn.logger::logger.setUseConsole(TRUE, FALSE) + on.exit(PEcAn.logger::logger.setUseConsole(TRUE, TRUE)) + settings <- list(rundir = getwd()) + file_path <- file.path(getwd(), "runs.txt") + file.create(file_path) + expect_output(start_model_runs(settings), "runs.txt found, but is empty") + }) +}) + diff --git a/docker/depends/pecan.depends.R b/docker/depends/pecan.depends.R index 64ef77eb10d..0f3057d896d 100644 --- a/docker/depends/pecan.depends.R +++ b/docker/depends/pecan.depends.R @@ -15,7 +15,7 @@ condense_version_requirements <- function(specs) { specs <- unique(specs[specs != "*"]) versions <- package_version( gsub("[^[:digit:].-]+", "", specs)) - + if ((length(unique(versions)) > 1) && any(!grepl(">", specs))) { # Can't assume the latest version works for all, so give up. # We *could* write more to handle this case if needed, but it seems very rare: @@ -39,30 +39,30 @@ condense_version_requirements <- function(specs) { # Install or newer, # upgrading dependencies only if needed to satisfy stated version requirements ensure_version <- function(pkg, version) { - vers <- gsub('[^[:digit:].-]+', '', version) - cmp <- get(gsub('[^<>=]+', '', version)) - ok <- requireNamespace(pkg, quietly = TRUE) && - cmp(packageVersion(pkg), vers) - if (!ok) { - # install pkg and any *missing* dependencies - remotes::install_version(pkg, version, dependencies = TRUE, upgrade = FALSE) - # Now check for installed but *incompatible* dependencies - # (install_version doesn't resolve these when upgrade=FALSE) - dep <- desc::desc_get_deps(system.file("DESCRIPTION", package = pkg)) - dep <- dep[ - dep$type %in% c("Depends", "Imports", "LinkingTo") - & dep$version != "*" - & dep$package != "R",] - invisible(Map(ensure_version, dep$package, dep$version)) - } - + vers <- gsub('[^[:digit:].-]+', '', version) + cmp <- get(gsub('[^<>=]+', '', version)) + ok <- requireNamespace(pkg, quietly = TRUE) && + cmp(packageVersion(pkg), vers) + if (!ok) { + # install pkg and any *missing* dependencies + remotes::install_version(pkg, version, dependencies = TRUE, upgrade = FALSE) + # Now check for installed but *incompatible* dependencies + # (install_version doesn't resolve these when upgrade=FALSE) + dep <- desc::desc_get_deps(system.file("DESCRIPTION", package = pkg)) + dep <- dep[ + dep$type %in% c("Depends", "Imports", "LinkingTo") + & dep$version != "*" + & dep$package != "R",] + invisible(Map(ensure_version, dep$package, dep$version)) + } + } # Read list of dependencies. # NOTE: These files are autogenerated -- # use scripts/generate_dependencies.R to edit them. all_deps <- read.csv("pecan_package_dependencies.csv") |> - subset(!is_pecan) + subset(!is_pecan) gh_repos <- readLines("pecan_deps_from_github.txt") @@ -74,9 +74,9 @@ remotes::install_github(gh_repos, lib = rlib) # For deps used by multiple packages, find a version that works for all uniq_deps <- tapply( - all_deps$version, - INDEX = all_deps$package, - FUN = condense_version_requirements) + all_deps$version, + INDEX = all_deps$package, + FUN = condense_version_requirements) # Install deps that declare no version restriction. @@ -92,9 +92,8 @@ install.packages(missing, lib = rlib) # it can't fill the version req from snapshot versions. # (Assumes our CRAN uses the same URL scheme as Posit package manager) options(repos = c( - getOption('repos'), - sub(r'(\d{4}-\d{2}-\d{2})', 'latest', getOption('repos')) + getOption('repos'), + sub(r'(\d{4}-\d{2}-\d{2})', 'latest', getOption('repos')) )) versioned <- uniq_deps[uniq_deps != "*"] -invisible(Map(ensure_version, names(versioned), versioned)) - +invisible(Map(ensure_version, names(versioned), versioned)) \ No newline at end of file diff --git a/docker/depends/pecan_package_dependencies.csv b/docker/depends/pecan_package_dependencies.csv index 8345db18103..2ffb26841a7 100644 --- a/docker/depends/pecan_package_dependencies.csv +++ b/docker/depends/pecan_package_dependencies.csv @@ -39,7 +39,6 @@ "datapack","*","modules/data.land","Imports",FALSE "DBI","*","base/db","Imports",FALSE "DBI","*","modules/data.remote","Imports",FALSE -"dbplyr","*","modules/benchmark","Imports",FALSE "dbplyr",">= 2.4.0","base/db","Imports",FALSE "devtools","*","models/ed","Suggests",FALSE "doParallel","*","modules/data.atmosphere","Suggests",FALSE @@ -184,6 +183,7 @@ "mgcv","*","modules/data.atmosphere","Imports",FALSE "minpack.lm","*","modules/rtm","Suggests",FALSE "mlegp","*","modules/assim.batch","Imports",FALSE +"mockery","*","base/all","Suggests",FALSE "mockery","*","base/qaqc","Suggests",FALSE "mockery","*","base/remote","Suggests",FALSE "mockery","*","base/settings","Suggests",FALSE @@ -352,7 +352,6 @@ "PEcAn.remote","*","models/stics","Imports",TRUE "PEcAn.remote","*","modules/assim.batch","Imports",TRUE "PEcAn.remote","*","modules/assim.sequential","Imports",TRUE -"PEcAn.remote","*","modules/benchmark","Imports",TRUE "PEcAn.remote","*","modules/data.atmosphere","Imports",TRUE "PEcAn.remote","*","modules/data.land","Imports",TRUE "PEcAn.remote","*","modules/data.remote","Imports",TRUE @@ -438,6 +437,7 @@ "purrr",">= 0.2.3","modules/data.atmosphere","Imports",FALSE "pwr","*","modules/rtm","Suggests",FALSE "R.utils","*","base/db","Imports",FALSE +"randomForest","*","modules/assim.sequential","Suggests",FALSE "randtoolbox","*","base/utils","Suggests",FALSE "randtoolbox","*","modules/uncertainty","Imports",FALSE "raster","*","base/visualization","Suggests",FALSE @@ -446,6 +446,7 @@ "raster","*","modules/data.land","Suggests",FALSE "raster","*","modules/data.remote","Suggests",FALSE "rcrossref","*","base/db","Suggests",FALSE +"readr","*","modules/assim.sequential","Suggests",FALSE "REddyProc","*","modules/data.atmosphere","Imports",FALSE "redland","*","modules/data.land","Suggests",FALSE "reshape","*","modules/data.remote","Suggests",FALSE @@ -528,6 +529,7 @@ "RPostgreSQL","*","models/biocro","Suggests",FALSE "Rpreles","*","models/preles","Suggests",FALSE "RSQLite","*","base/db","Suggests",FALSE +"sessioninfo","*","base/all","Suggests",FALSE "sf","*","modules/assim.sequential","Suggests",FALSE "sf","*","modules/data.atmosphere","Imports",FALSE "sf","*","modules/data.land","Imports",FALSE @@ -554,6 +556,7 @@ "stringr",">= 1.1.0","modules/data.atmosphere","Imports",FALSE "suntools","*","modules/data.atmosphere","Imports",FALSE "swfscMisc","*","modules/data.land","Imports",FALSE +"terra","*","modules/assim.sequential","Suggests",FALSE "terra","*","modules/data.atmosphere","Imports",FALSE "terra","*","modules/data.land","Imports",FALSE "terra","*","modules/data.remote","Imports",FALSE @@ -639,6 +642,7 @@ "withr","*","base/settings","Suggests",FALSE "withr","*","base/utils","Suggests",FALSE "withr","*","base/visualization","Suggests",FALSE +"withr","*","base/workflow","Suggests",FALSE "withr","*","models/ed","Suggests",FALSE "withr","*","models/sibcasa","Suggests",FALSE "withr","*","modules/allometry","Suggests",FALSE diff --git a/modules/assim.sequential/DESCRIPTION b/modules/assim.sequential/DESCRIPTION index b90f15a18cd..78641f263c6 100644 --- a/modules/assim.sequential/DESCRIPTION +++ b/modules/assim.sequential/DESCRIPTION @@ -47,11 +47,14 @@ Suggests: PEcAn.visualization, plotrix, plyr (>= 1.8.4), + randomForest, raster, + readr, reshape2 (>= 1.4.2), rlist, sf, stats, + terra, testthat, tictoc, tidyr, diff --git a/modules/assim.sequential/R/Analysis_sda_block.R b/modules/assim.sequential/R/Analysis_sda_block.R index 50a2046a773..f5bc2f634be 100644 --- a/modules/assim.sequential/R/Analysis_sda_block.R +++ b/modules/assim.sequential/R/Analysis_sda_block.R @@ -102,7 +102,6 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { } else if (settings$state.data.assimilation$q.type == "wishart") { q.type <- 4 } - #grab basic arguments based on X. site.ids <- unique(attributes(X)$Site) var.names <- unique(attributes(X)$dimnames[[2]]) @@ -112,7 +111,6 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { diag(Pf)[which(diag(Pf)==0)] <- min(diag(Pf)[which(diag(Pf) != 0)])/5 #fixing det(Pf)==0 PEcAn.logger::logger.warn("The zero variances in Pf is being replaced by one fifth of the minimum variance in those matrices respectively.") } - #distance calculations and localization site.locs <- settings$run %>% purrr::map('site') %>% @@ -128,14 +126,16 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { blocked.dis <- block_matrix(dis.matrix %>% as.numeric(), rep(length(var.names), length(site.ids))) Pf <- Localization.FUN(Pf, blocked.dis, settings$state.data.assimilation$scalef %>% as.numeric()) } - #Handle observation #observation number per site - obs_per_site <- purrr::map_int(obs.mean[[t]], length) + #free run special case. + if (is.null(obs.mean[[t]])) { + obs_per_site <- rep(0, length(site.ids)) %>% purrr::set_names(site.ids) + } else { + obs_per_site <- purrr::map_int(obs.mean[[t]], length) + } #if we do free run or the current obs.mean are all NULL. if (as.logical(settings$state.data.assimilation$free.run) | all(is.null(unlist(obs.mean[[t]])))) { - obs.mean[[t]] <- vector("list", length(site.ids)) %>% `names<-`(site.ids) - obs.cov[[t]] <- vector("list", length(site.ids)) %>% `names<-`(site.ids) H <- list(ind = seq_along(rep(var.names, length(site.ids)))) Y <- rep(NA, length(H$ind)) R <- diag(1, length(H$ind)) @@ -174,8 +174,8 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { #name matching between observation names and state variable names. f.2.y.ind <- obs.mean[[t]] %>% purrr::map(\(x)which(var.names %in% names(x))) %>% - base::unlist %>% - base::unique + unlist %>% + unique H <- list(ind = f.2.y.ind %>% purrr::map(function(start){ seq(start, length(site.ids) * length(var.names), length(var.names)) }) %>% unlist() %>% sort) @@ -187,7 +187,6 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { by = "block_pft_var") } } - #start the blocking process #should we consider interactions between sites? if(as.numeric(settings$state.data.assimilation$scalef) == 0){ @@ -198,28 +197,32 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { block.list[[i]]$sites.per.block <- i block.list[[i]]$site.ids <- site.ids[i] block.list[[i]]$t <- t - #fill in mu.f and Pf f.start <- (i - 1) * length(var.names) + 1 f.end <- i * length(var.names) block.list[[i]]$data$muf <- mu.f[f.start:f.end] block.list[[i]]$data$pf <- Pf[f.start:f.end, f.start:f.end] - + #find indexs for Y. + y.start <- sum(obs_per_site[1:i]) + y.end <- y.start + obs_per_site[i] - 1 #fill in y and r - if (obs_per_site[i] == 0) { - y.start <- 1 - y.end <- length(var.names) - block.list[[i]]$data$y.censored <- rep(NA, length(var.names)) - block.list[[i]]$data$r <- diag(1, length(var.names)) - block.h <- matrix(1, 1, length(var.names)) + #if there is no observation for this site. + if (y.end < y.start) { + #if every site has zero observation/free run. + if (max(obs_per_site) == 0) { + block.list[[i]]$data$y.censored <- rep(NA, length(var.names)) + block.list[[i]]$data$r <- diag(1, length(var.names)) + block.h <- matrix(1, 1, length(var.names)) + } else { + block.list[[i]]$data$y.censored <- rep(NA, max(obs_per_site)) + block.list[[i]]$data$r <- diag(1, max(obs_per_site)) + block.h <- matrix(1, 1, max(obs_per_site)) + } } else { - y.start <- sum(obs_per_site[1:i-1]) + 1#obs_per_site[i] * (i - 1) + 1 - y.end <- y.start + obs_per_site[i] - 1#obs_per_site[i] * i block.list[[i]]$data$y.censored <- y.censored[y.start:y.end] block.list[[i]]$data$r <- solve(R[y.start:y.end, y.start:y.end]) block.h <- Construct.H.multisite(site.ids[i], var.names, obs.mean[[t]]) } - #fill in constants. block.list[[i]]$H <- block.h block.list[[i]]$constant$H <- which(apply(block.h, 2, sum) == 1) @@ -253,15 +256,9 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { for (j in seq_along(ids)) { f.start <- (ids[j] - 1) * length(var.names) + 1 f.end <- ids[j] * length(var.names) - # site.ind <- ids[j] - y.start <- sum(obs_per_site[1:ids[j]]) y.end <- y.start + obs_per_site[ids[j]] - 1 - # y.start <- obs_per_site[ids[j]] * (ids[j] - 1) + 1 - # y.end <- obs_per_site[ids[j]] * ids[j] - f.ind <- c(f.ind, f.start:f.end) - #if the current site has greater or equal than 1 observation. if (y.end >= y.start) { # y.ind <- c(y.ind, y.start:y.end) @@ -269,17 +266,28 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { r.block <- c(r.block, diag(R)[y.start:y.end]) } else { #if the current site has zero observation. - y.block <- c(y.block, rep(NA, max(obs_per_site))) - r.block <- c(r.block, rep(1, max(obs_per_site))) + #if for free run. + if (max(obs_per_site) == 0) { + y.block <- c(y.block, rep(NA, length(var.names))) + r.block <- c(r.block, rep(1, length(var.names))) + } else { + y.block <- c(y.block, rep(NA, max(obs_per_site))) + r.block <- c(r.block, rep(1, max(obs_per_site))) + } } } - # H + #if we have NA for y, we will build H differently. if (any(is.na(y.block))) { - block.h <- matrix(0, 1, length(ids)*length(var.names))#matrix(1, 1, length(var.names)) - f.2.y.ind <- obs.mean[[t]] %>% - purrr::map(\(x)which(var.names %in% names(x))) %>% - base::unlist %>% - base::unique + block.h <- matrix(0, 1, length(ids)*length(var.names)) + #if for free run. + if (is.null(obs.mean[[t]])) { + f.2.y.ind <- seq_along(var.names) + } else { + f.2.y.ind <- obs.mean[[t]] %>% + purrr::map(\(x)which(var.names %in% names(x))) %>% + unlist %>% + unique + } seq.ind <- f.2.y.ind %>% purrr::map(function(start){ seq(start, dim(block.h)[2], length(var.names)) }) %>% unlist() @@ -287,29 +295,16 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { } else { block.h <- Construct.H.multisite(site.ids[ids], var.names, obs.mean[[t]]) } - #fill in mu.f and Pf block.list[[i]]$data$muf <- mu.f[f.ind] block.list[[i]]$data$pf <- GrabFillMatrix(Pf, f.ind) - #fill in y and R - # y.block[which(is.na(y.block))] <- mu.f[f.ind[seq.ind[which(is.na(y.block))]]] - # r.block[which(is.na(r.block))] <- diag(Pf)[f.ind[seq.ind[which(is.na(r.block))]]] - block.list[[i]]$data$y.censored <- y.block#y.censored[y.ind] + block.list[[i]]$data$y.censored <- y.block if (length(r.block) == 1) { block.list[[i]]$data$r <- 1/r.block } else { - block.list[[i]]$data$r <- solve(diag(r.block))#GrabFillMatrix(solve(R), y.ind) + block.list[[i]]$data$r <- solve(diag(r.block)) } - - #fill in constants - # if (all(is.na(y.block))) { - # block.h <- matrix(0, 1, length(ids)*length(var.names))#matrix(1, 1, length(var.names)) - # f.2.y.ind <- which(grepl(unique(names(unlist(obs.mean[[t]] %>% set_names(NULL)))), var.names, fixed = T)) - # block.h[1, seq(f.2.y.ind, dim(block.h)[2], length(var.names))] <- 1 - # } else { - # block.h <- Construct.H.multisite(site.ids[ids], var.names, obs.mean[[t]]) - # } block.list[[i]]$H <- block.h block.list[[i]]$constant$H <- which(apply(block.h, 2, sum) == 1) block.list[[i]]$constant$N <- length(f.ind) @@ -317,7 +312,36 @@ build.block.xy <- function(settings, block.list.all, X, obs.mean, obs.cov, t) { block.list[[i]]$constant$q.type <- q.type } } - + #if it's Wishart Q, we need to replace any NA Y with corresponding muf, and r with Pf. + #also, if length of observation is 1, the Wishart Q is not suitable for the MCMC. + #we will then need to change the Q type to 3, which is the vector Q. + if (q.type == 4) { + for (i in seq_along(block.list)) { + #check length. + if (block.list[[i]]$constant$YN == 1) { + block.list[[i]]$constant$q.type <- 3 + next + } + # #check NAs. + # na.ind <- which(is.na(block.list[[i]]$data$y.censored)) + # if (length(na.ind) > 0) { + # block.list[[i]]$constant$YN <- block.list[[i]]$constant$YN - length(na.ind) + # block.list[[i]]$constant$H <- block.list[[i]]$constant$H[-na.ind] + # block.list[[i]]$data$y.censored <- block.list[[i]]$data$y.censored[-na.ind] + # block.list[[i]]$data$r <- diag(diag(block.list[[i]]$data$r)[-na.ind]) + # } + # na.site.ind <- which(obs_per_site[block.list[[i]]$site.ids] == 0) + # na.ind <- which(is.na(block.list[[i]]$data$y.censored)) + # if (length(na.site.ind) > 0) { + # site.inds <- block.list[[i]]$sites.per.block[na.site.ind] + # y.2.muf.ind <- f.2.y.ind %>% purrr::map(function(start){ + # seq(start, length(mu.f), length(var.names))[site.inds] + # }) %>% unlist() %>% sort() + # block.list[[i]]$data$y.censored[na.ind] <- mu.f[y.2.muf.ind] + # block.list[[i]]$data$r[na.ind, na.ind] <- Pf[y.2.muf.ind, y.2.muf.ind] + # } + } + } #return values. block.list.all[[t]] <- block.list return(list(block.list.all = block.list.all, H = H, Y = Y, R = R)) diff --git a/modules/assim.sequential/R/downscale_function.R b/modules/assim.sequential/R/downscale_function.R new file mode 100644 index 00000000000..4a64beef645 --- /dev/null +++ b/modules/assim.sequential/R/downscale_function.R @@ -0,0 +1,93 @@ +##' @title North America Downscale Function +##' @name NA_downscale +##' @author Joshua Ploshay +##' +##' @param data In quotes, file path for .rds containing ensemble data. +##' @param focus_year In quotes, if SDA site run, format is yyyy/mm/dd, if NEON, yyyy-mm-dd. Restricted to years within file supplied to 'data'. +##' @param C_pool In quotes, carbon pool of interest. Name must match carbon pool name found within file supplied to 'data'. +##' @param covariates In quotes, file path of SpatRaster stack, used as predictors in randomForest. Layers within stack should be named. +##' @param cords In quotes, file path for .csv file containing the site coordinates, columns named "lon" and "lat". +##' @details This function will downscale forecast data to unmodeled locations using covariates and site locations +##' +##' @description This function uses the randomForest model. +##' +##' @return It returns the `downscale_output` list containing lists for the training and testing data sets, models, and predicted maps for each ensemble member. + + +NA_downscale <- function(data, cords, covariates, focus_year, C_pool){ + + # Read in the covariates and set CRS to EPSG:4326 + covariates <- terra::rast(covariates) # ADD package to every function + terra::crs(covariates) <- "EPSG:4326" + + # Read the input data and site coordinates + input_data <- readRDS(data) + site_coordinates <- terra::vect(readr::read_csv(cords), geom=c("lon", "lat"), crs="EPSG:4326") + + # Extract the carbon data for the specified focus year + index <- which(names(input_data) == focus_year) + data <- input_data[[index]] + carbon_data <- as.data.frame(t(data[which(names(data) == C_pool)])) + names(carbon_data) <- paste0("ensemble",seq(1:ncol(carbon_data))) + + # Extract predictors from covariates raster using site coordinates + predictors <- as.data.frame(terra::extract(covariates, site_coordinates)) + predictors <- dplyr::select(predictors, -1) + + # Combine each ensemble member with all predictors + ensembles <- list() + for (i in seq_along(carbon_data)) { + ensembles[[i]] <- cbind(carbon_data[[i]], predictors) + } + + # Rename the carbon_data column for each ensemble member + for (i in 1:length(ensembles)) { + ensembles[[i]] <- dplyr::rename(ensembles[[i]], "carbon_data" = "carbon_data[[i]]") + } + + # Split the observations in each data frame into two data frames based on the proportion of 3/4 + ensembles <- lapply(ensembles, function(df) { + sample <- sample(1:nrow(df), size = round(0.75*nrow(df))) + train <- df[sample, ] + test <- df[-sample, ] + split_list <- list(train, test) + return(split_list) + }) + + # Rename the training and testing data frames for each ensemble member + for (i in 1:length(ensembles)) { + # names(ensembles) <- paste0("ensemble",seq(1:length(ensembles))) + names(ensembles[[i]]) <- c("training", "testing") + } + + # Train a random forest model for each ensemble member using the training data + output <- list() + for (i in 1:length(ensembles)) { + output[[i]] <- randomForest::randomForest(ensembles[[i]][[1]][["carbon_data"]] ~ land_cover+tavg+prec+srad+vapr+nitrogen+phh2o+soc+sand, + data = ensembles[[i]][[1]], + ntree = 1000, + na.action = stats::na.omit, + keep.forest = T, + importance = T) + } + + # Generate predictions (maps) for each ensemble member using the trained models + maps <- list(ncol(output)) + for (i in 1:length(output)) { + maps[[i]] <- terra::predict(object = covariates, + model = output[[i]],na.rm = T) + } + + # Organize the results into a single output list + downscale_output <- list(ensembles, output, maps) + + # Rename each element of the output list with appropriate ensemble numbers + for (i in 1:length(downscale_output)) { + names(downscale_output[[i]]) <- paste0("ensemble",seq(1:length(downscale_output[[i]]))) + } + + # Rename the main components of the output list + names(downscale_output) <- c("data", "models", "maps") + + return(downscale_output) +} diff --git a/modules/assim.sequential/man/NA_downscale.Rd b/modules/assim.sequential/man/NA_downscale.Rd new file mode 100644 index 00000000000..8ab6a5ea946 --- /dev/null +++ b/modules/assim.sequential/man/NA_downscale.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/downscale_function.R +\name{NA_downscale} +\alias{NA_downscale} +\title{North America Downscale Function} +\usage{ +NA_downscale(data, cords, covariates, focus_year, C_pool) +} +\arguments{ +\item{data}{In quotes, file path for .rds containing ensemble data.} + +\item{focus_year}{In quotes, if SDA site run, format is yyyy/mm/dd, if NEON, yyyy-mm-dd. Restricted to years within file supplied to 'data'.} + +\item{C_pool}{In quotes, carbon pool of interest. Name must match carbon pool name found within file supplied to 'data'.} + +\item{covariates}{In quotes, file path of SpatRaster stack, used as predictors in randomForest. Layers within stack should be named.} + +\item{cords}{In quotes, file path for .csv file containing the site coordinates, columns named "lon" and "lat".} +} +\value{ +It returns the `downscale_output` list containing lists for the training and testing data sets, models, and predicted maps for each ensemble member. +} +\description{ +This function uses the randomForest model. +} +\details{ +This function will downscale forecast data to unmodeled locations using covariates and site locations +} +\author{ +Joshua Ploshay +} diff --git a/modules/benchmark/DESCRIPTION b/modules/benchmark/DESCRIPTION index 2cb70a15458..8ebd5bf11bc 100644 --- a/modules/benchmark/DESCRIPTION +++ b/modules/benchmark/DESCRIPTION @@ -19,7 +19,6 @@ Description: The Predictive Ecosystem Carbon Analyzer (PEcAn) is a scientific streamline the interaction between data and models, and to improve the efficacy of scientific investigation. Imports: - dbplyr, dplyr, ggplot2, gridExtra, @@ -28,7 +27,6 @@ Imports: ncdf4 (>= 1.15), PEcAn.DB, PEcAn.logger, - PEcAn.remote, PEcAn.settings, PEcAn.utils, reshape2, diff --git a/modules/benchmark/R/align_by_first_observation.R b/modules/benchmark/R/align_by_first_observation.R index 38ee061c118..b1ae51afd0e 100644 --- a/modules/benchmark/R/align_by_first_observation.R +++ b/modules/benchmark/R/align_by_first_observation.R @@ -18,9 +18,11 @@ #' table$plant_functional_type_two<- c('a','a','b', 'b') # PFT groupings #' table<-as.data.frame(table) #' -#' aligned<-align_by_first_observation(observation_one = observation_one, observation_two = observation_two, -#' custom_table = table) -#' +#' aligned <- align_by_first_observation( +#' observation_one = observation_one, +#' observation_two = observation_two, +#' custom_table = table) +#' #' # aligned should be a vector '[1] "AMCA3" "ARHY" "AMCA3" "AMCA3"' #' @export align_by_first_observation<-function(observation_one, observation_two, custom_table){ diff --git a/modules/benchmark/R/align_data.R b/modules/benchmark/R/align_data.R index 51169417e06..d3aee1468ac 100644 --- a/modules/benchmark/R/align_data.R +++ b/modules/benchmark/R/align_data.R @@ -1,13 +1,14 @@ -##' @name align_data -##' @title Align timeseries data -##' @export +##' Align timeseries data +##' ##' @param model.calc data.frame ##' @param obvs.calc data.frame ##' @param var data.frame +##' @param align_method name of function to use for alignment +##' ##' @importFrom rlang .data ##' @return dat ##' @author Betsy Cowdery - +##' @export ## Align timeseries data using different functions @@ -43,15 +44,19 @@ align_data <- function(model.calc, obvs.calc, var, align_method = "match_timeste coarse.unit <- compare$diff_units[coarse] # Round to the larger time step (experimental) - obvs.calc$round.posix <- as.POSIXct(round(obvs.calc$posix, units = coarse.unit)) - model.calc$round.posix <- as.POSIXct(round(model.calc$posix, units = coarse.unit)) + # Note: Oddly, the second argument to `round()` has to be unnamed here + # because of an inconsistency in base R's rounding methods. + # The generic `round()` expects the second arg to be called `digits`, + # but then dispatches to `round.POSIXt`, which takes `units`. + obvs.calc$round.posix <- as.POSIXct(round(obvs.calc$posix, coarse.unit)) + model.calc$round.posix <- as.POSIXct(round(model.calc$posix, coarse.unit)) # Determine the overlaping range of dates # Compare the rounded dates because you can't compare dates of different units with range rng_obvs <- range(unique(obvs.calc$round.posix)) rng_model <- range(unique(model.calc$round.posix)) - rng_dat <- sort(c(rng_obvs, rng_model))[c(2, 3)] %>% lubridate::with_tz(., tzone = "UTC") + rng_dat <- sort(c(rng_obvs, rng_model))[c(2, 3)] %>% lubridate::with_tz(tzone = "UTC") # Special case for annual timestep if(setequal(c(365,366), compare$diff_days[coarse]) | setequal(c(365), compare$diff_days[coarse]) | @@ -79,7 +84,7 @@ align_data <- function(model.calc, obvs.calc, var, align_method = "match_timeste filter(coarse_range_check[1] <= .data$round.posix) %>% filter(coarse_range_check[2] >= .data$round.posix) - out1 <- date_subsets[[compare$type[coarse]]] %>% dplyr::select(.,one_of(var)) + out1 <- date_subsets[[compare$type[coarse]]] %>% dplyr::select(dplyr::one_of(var)) colnames(out1) <- paste0(colnames(out1), ".", compare$type[coarse]) @@ -89,7 +94,7 @@ align_data <- function(model.calc, obvs.calc, var, align_method = "match_timeste date.coarse <- date_subsets[[compare$type[coarse]]]$round.posix date.fine <- date_subsets[[compare$type[fine]]]$round.posix - data.fine <- date_subsets[[compare$type[fine]]] %>% dplyr::select(.,one_of(var)) + data.fine <- date_subsets[[compare$type[fine]]] %>% dplyr::select(dplyr::one_of(var)) colnames(data.fine) <- paste0(colnames(data.fine), ".", compare$type[fine]) out2 <- apply(data.fine, 2, @@ -104,10 +109,10 @@ align_data <- function(model.calc, obvs.calc, var, align_method = "match_timeste } else if (mode.o == mode.m) { # here coarse and fine are just index values but but the time steps are the same size - out2 <- date_subsets[[compare$type[fine]]] %>% dplyr::select(.,one_of(var)) + out2 <- date_subsets[[compare$type[fine]]] %>% dplyr::select(dplyr::one_of(var)) colnames(out2) <- paste0(colnames(out2), ".", compare$type[fine]) dat <- cbind(out1, out2) - dat$posix <- date_subsets[[compare$type[fine]]] %>% dplyr::select(.,one_of("round.posix")) %>% .[,1] + dat$posix <- date_subsets[[compare$type[fine]]] %>% dplyr::select(dplyr::one_of("round.posix")) %>% .[,1] } diff --git a/modules/benchmark/R/align_pft.R b/modules/benchmark/R/align_pft.R index 4bfebca9cff..e6d15f04ebe 100644 --- a/modules/benchmark/R/align_pft.R +++ b/modules/benchmark/R/align_pft.R @@ -1,7 +1,6 @@ -################################################################# -#'align_pft +#' Align vectors of Plant Functional Type and species. +#' #'@details -#' Aligns vectors of Plant Fucntional Typed and species. #' Can align: #' - two vectors of plant fucntional types (pft's) if a custom map is provided #' - a list of species (usda, fia, or latin_name format) to a plant fucntional type @@ -28,6 +27,9 @@ #' @param format_two The output of query.format.vars() of observation two of the form output$vars$bety_names #' @param subset_is_ok When aligning two species lists, this allows for alignement when species lists aren't identical. #' set to FALSE by default. +#' @param comparison_type one of "data_to_model", "data_to_data", or "model_to_model" +#' @param ... other arguments, currently ignored +#' #' @return \code{list} containing the following columns: #' \describe{ #' \item{\code{$original}}{Will spit back out original vectors pre-alignment} diff --git a/modules/benchmark/R/bm_settings.R b/modules/benchmark/R/bm_settings.R index 10ca924aa9f..0f679bd6dbe 100644 --- a/modules/benchmark/R/bm_settings.R +++ b/modules/benchmark/R/bm_settings.R @@ -26,12 +26,12 @@ read_settings_BRR <- function(settings){ filter(.data$id == settings$benchmarking$reference_run_id) %>% collect() - BRR.settings <- BRR %>% pull(settings) %>% unlist() %>% - xmlToList(.,"pecan") + BRR.settings <- BRR %>% dplyr::pull(settings) %>% unlist() %>% + XML::xmlToList("pecan") PEcAn.logger::logger.debug(names(BRR.settings)) - settings <- BRR.settings %>% append(settings,.) %>% PEcAn.settings::Settings() + settings <- append(settings, BRR.settings) %>% PEcAn.settings::Settings() invisible(settings) } @@ -86,8 +86,8 @@ clean_settings_BRR <- function(inputfile){ ##' @author Betsy Cowdery add_workflow_info <- function(settings, bety){ - if (is.MultiSettings(settings)) { - return(papply(settings, add_workflow_id)) + if (PEcAn.settings::is.MultiSettings(settings)) { + return(PEcAn.settings::papply(settings, add_workflow_id)) } if(!as.logical(settings$benchmarking$new_run)){ settings$workflow$id <- tbl(bety,"ensembles") %>% @@ -109,8 +109,8 @@ add_workflow_info <- function(settings, bety){ ##' @author Betsy Cowdery bm_settings2pecan_settings <- function(bm.settings){ - if (is.MultiSettings(bm.settings)) { - return(papply(bm.settings, bm_settings2pecan_settings)) + if (PEcAn.settings::is.MultiSettings(bm.settings)) { + return(PEcAn.settings::papply(bm.settings, bm_settings2pecan_settings)) } out <- bm.settings["reference_run_id"] for(i in grep("benchmark", names(bm.settings))){ diff --git a/modules/benchmark/R/calc_benchmark.R b/modules/benchmark/R/calc_benchmark.R index 72a36ef56ac..508f6c67b9c 100644 --- a/modules/benchmark/R/calc_benchmark.R +++ b/modules/benchmark/R/calc_benchmark.R @@ -1,10 +1,10 @@ -##-------------------------------------------------------------------------------------------------# +##' Calculate benchmarking statistics +##' ##' For each benchmark id, calculate metrics and update benchmarks_ensemble_scores ##' -##' @name calc_benchmark -##' @title Calculate benchmarking statistics -##' @param bm.ensemble object, either from create_BRR or start.bm.ensemle +##' @param settings settings object describing the run to calculate ##' @param bety database connection +##' @param start_year,end_year time range to read. If NA, these are taken from `settings` ##' @export ##' ##' @author Betsy Cowdery @@ -135,9 +135,9 @@ calc_benchmark <- function(settings, bety, start_year = NA, end_year = NA) { var <- dplyr::filter(format$vars, .data$variable_id == bm$variable_id)[, "pecan_name"] var.list <- c(var.list, var) - obvs.calc <- obvs_full %>% dplyr::select(., dplyr::one_of(c("posix", var))) + obvs.calc <- obvs_full %>% dplyr::select(dplyr::one_of(c("posix", var))) obvs.calc[,var] <- as.numeric(obvs.calc[,var]) - model.calc <- model_full %>% dplyr::select(., dplyr::one_of(c("posix", var))) + model.calc <- model_full %>% dplyr::select(dplyr::one_of(c("posix", var))) # Check that the variables actually got loaded, otherwise don't send to calc_metrics @@ -157,7 +157,7 @@ calc_benchmark <- function(settings, bety, start_year = NA, end_year = NA) { bm_dir) for(metric.id in metrics$id){ - metric.name <- filter(metrics,id == metric.id)[["name"]] + metric.name <- dplyr::filter(metrics,.data$id == metric.id)[["name"]] score <- out.calc_metrics[["benchmarks"]] %>% dplyr::filter(.data$metric == metric.name) %>% dplyr::select(score) diff --git a/modules/benchmark/R/check_if_legal_table.R b/modules/benchmark/R/check_if_legal_table.R index a0b3fe15b52..126b231b6b6 100644 --- a/modules/benchmark/R/check_if_legal_table.R +++ b/modules/benchmark/R/check_if_legal_table.R @@ -1,14 +1,16 @@ -#' check_if_legal_table +#' check_if_legal_table +#' #' @details #' Checks if custom_table: #' 1. is formated correctly #' 2. is complete (has all of the species/pft's in both observations) #' 3. is condense-able (Could be represented as a hierachry) #' +#' @param table a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. +#' In the second case, must be passable to match_species_id. #' @param observation_one a vector of plant functional types, or species #' @param observation_two anouther vector of plant functional types, or species -#' @param custom_table a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. -#' In the second case, must be passable to match_species_id. +#' #' @return \code{boolean} #' @author Tempest McCabe check_if_legal_table<-function(table, observation_one, observation_two){ diff --git a/modules/benchmark/R/check_if_list_of_pfts.R b/modules/benchmark/R/check_if_list_of_pfts.R index 0d2f8979db9..3b587240d94 100644 --- a/modules/benchmark/R/check_if_list_of_pfts.R +++ b/modules/benchmark/R/check_if_list_of_pfts.R @@ -1,9 +1,9 @@ #' check_if_list_of_pfts -#' @details Checks if format contains a variable named "plant_functional_type" -#' @param observation_one a vector of plant fucntional types, or species -#' @param observation_two anouther vector of plant fucntional types, or species -#' @param custom_table a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. -#' In the second case, must be passable to match_species_id. +#' +#' Checks if format contains a variable named "plant_functional_type" +#' +#' @param vars names to check +#' #' @return \code{boolean} #' @author Tempest McCabe check_if_list_of_pfts<-function(vars){ diff --git a/modules/benchmark/R/check_if_species_list.R b/modules/benchmark/R/check_if_species_list.R index 620f281c7e8..bbba2729af2 100644 --- a/modules/benchmark/R/check_if_species_list.R +++ b/modules/benchmark/R/check_if_species_list.R @@ -1,11 +1,12 @@ -#'@title check_if_species_list +#' check_if_species_list +#' #'@details #' Checks if format contains a species list in a known format, or a declared custom format. -#' -#' @param observation_one a vector of plant functional types, or species -#' @param observation_two another vector of plant functional types, or species +#' +#' @param vars format #' @param custom_table a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. #' In the second case, must be passable to match_species_id. +#' #' @return \code{boolean} #' @author Tempest McCabe check_if_species_list<-function(vars,custom_table=NULL){ diff --git a/modules/benchmark/R/create_BRR.R b/modules/benchmark/R/create_BRR.R index 8f4660faba4..d2e4d7f7e3b 100644 --- a/modules/benchmark/R/create_BRR.R +++ b/modules/benchmark/R/create_BRR.R @@ -1,10 +1,10 @@ -##-------------------------------------------------------------------------------------------------# +##' Create benchmark reference run and ensemble +##' ##' For each benchmark id, calculate metrics and update benchmarks_ensemble_scores ##' -##' @name create_BRR -##' @title Create benchmark reference run and ensemble ##' @param ens_wf table made from joining ensemble and workflow tables ##' @param con database connection +##' @param user_id Optional user id to use for this record in reference_runs table ##' @export ##' ##' @author Betsy Cowdery @@ -36,7 +36,7 @@ create_BRR <- function(ens_wf, con, user_id = ""){ }else if(dim(ref_run)[1] > 1){# There shouldn't be more than one reference run with the same settings PEcAn.logger::logger.error("There is more than one reference run in the database with these settings. Review for duplicates. ") } - BRR <- ref_run %>% dplyr::rename(.,reference_run_id = id) + BRR <- ref_run %>% dplyr::rename(reference_run_id = .data$id) return(BRR) # }else{logger.error(sprintf("Cannot create a benchmark reference run for a run on hostname: %s", # ens_wf$hostname))} diff --git a/modules/benchmark/R/define_benchmark.R b/modules/benchmark/R/define_benchmark.R index 629828b9e4d..6178b942db0 100644 --- a/modules/benchmark/R/define_benchmark.R +++ b/modules/benchmark/R/define_benchmark.R @@ -1,16 +1,18 @@ +##' Benchmark Definition: Retrieve or Create Bety Benchmarking Records +##' ##' Creates records for benchmarks, benchmarks_benchmarks_reference_runs, benchmarks_metrics ##' -##' @name define_benchmark -##' @title Benchmark Definition: Retrieve or Create Bety Benchmarking Records -##' @param bm.settings settings list +##' @param settings settings list +##' @param bety database connection +##' ##' @return updated settings list ##' @author Betsy Cowdery -##' @export define_benchmark ##' @importFrom dplyr tbl filter rename collect select +##' @export define_benchmark <- function(settings, bety){ - if (is.MultiSettings(settings)) { - return(papply(settings, function(x) define_benchmark(x, bety))) + if (PEcAn.settings::is.MultiSettings(settings)) { + return(PEcAn.settings::papply(settings, function(x) define_benchmark(x, bety))) } bm.settings <- settings$benchmarking @@ -22,18 +24,18 @@ define_benchmark <- function(settings, bety){ if(!is.null(bm.settings$ensemble_id)){ # check if there is already a BRR for ensemble.id, otherwise make one - bm_ens <- tbl(bety,"benchmarks_ensembles") %>% rename(bm_ensemble_id = id) %>% - filter(ensemble_id == bm.settings$ensemble_id) %>% collect() + bm_ens <- dplyr::tbl(bety,"benchmarks_ensembles") %>% rename(bm_ensemble_id = .data$id) %>% + filter(.data$ensemble_id == bm.settings$ensemble_id) %>% collect() if(length(bm_ens) == 0){ # Get workflow id from ensemble id - ens_wf <- tbl(bety, 'ensembles') %>% filter(id == bm.settings$ensemble_id) %>% - rename(ensemble_id = id) %>% - left_join(.,tbl(bety, "workflows") %>% rename(workflow_id = id), by="workflow_id") %>% collect() + ens_wf <- dplyr::tbl(bety, 'ensembles') %>% filter(.data$id == bm.settings$ensemble_id) %>% + rename(ensemble_id = .data$id) %>% + dplyr::left_join(tbl(bety, "workflows") %>% rename(workflow_id = .data$id), by="workflow_id") %>% collect() BRR <- create_BRR(ens_wf, con = bety, user_id = settings$info$userid) }else if(dim(bm_ens)[1] == 1){ - BRR <- tbl(bety,"reference_runs") %>% filter(id == bm_ens$reference_run_id) %>% - rename(reference_run_id = id) %>% collect() + BRR <- tbl(bety,"reference_runs") %>% filter(.data$id == bm_ens$reference_run_id) %>% + rename(reference_run_id = .data$id) %>% collect() }else if(dim(bm_ens)[1] > 1){ # There shouldn't be more than one reference run per run PEcAn.logger::logger.error("There is more than one reference run in the database for this ensemble id. Review for duplicates. ") } @@ -41,8 +43,8 @@ define_benchmark <- function(settings, bety){ bm.settings$reference_run_id <- BRR$reference_run_id # bm.settings$ensemble_id <- NULL - }else{logger.error("Cannot find or create benchmark reference run")} - }else{logger.debug("Reference run already created")} + }else{PEcAn.logger::logger.error("Cannot find or create benchmark reference run")} + }else{PEcAn.logger::logger.debug("Reference run already created")} # Retrieve/create benchmark entries @@ -58,7 +60,7 @@ define_benchmark <- function(settings, bety){ if(!is.null(benchmark$metrics)){ metric_ids <- as.numeric(unlist(benchmark$metrics)) }else{ - metric_ids <- tbl(bety, 'metrics') %>% pull(id) + metric_ids <- tbl(bety, 'metrics') %>% dplyr::pull(.data$id) } # If site is not specified in benchmark settings (this may be unnecessary) @@ -71,8 +73,8 @@ define_benchmark <- function(settings, bety){ } bm <- tbl(bety, 'benchmarks') %>% - filter(input_id == benchmark$input_id) %>% - filter(variable_id == benchmark$variable_id) %>% + filter(.data$input_id == benchmark$input_id) %>% + filter(.data$variable_id == benchmark$variable_id) %>% filter(site_id == site_id) %>% collect() # Retrieve/create benchmark record @@ -81,27 +83,27 @@ define_benchmark <- function(settings, bety){ "VALUES ( %s, %s, %s, %s) RETURNING * ;"), benchmark$input_id, benchmark$variable_id, site_id, settings$info$userid) - bm <- db.query(cmd, bety) - logger.debug(sprintf("Benchmark %.0f for input %.0f variable %.0f created", + bm <- PEcAn.DB::db.query(cmd, bety) + PEcAn.logger::logger.debug(sprintf("Benchmark %.0f for input %.0f variable %.0f created", bm$id, bm$input_id, bm$variable_id)) }else if(dim(bm)[1] >1){ PEcAn.logger::logger.error(sprintf("DUPLICATE records exist for input %.0f variable %.0f", as.numeric(benchmark$input_id), benchmark$variable_id)) }else{ - logger.debug(sprintf("Benchmark %.0f for input %.0f variable %.0f exists", + PEcAn.logger::logger.debug(sprintf("Benchmark %.0f for input %.0f variable %.0f exists", bm$id, bm$input_id, bm$variable_id)) } # Retrieve/create benchmarks_benchmarks_reference_runs record bmBRR <- tbl(bety, 'benchmarks_benchmarks_reference_runs') %>% - filter(benchmark_id == bm$id) %>% - filter(reference_run_id == bm.settings$reference_run_id) %>% collect() + filter(.data$benchmark_id == bm$id) %>% + filter(.data$reference_run_id == bm.settings$reference_run_id) %>% collect() if(dim(bmBRR)[1] == 0){ cmd <- sprintf(paste0("INSERT INTO benchmarks_benchmarks_reference_runs", " (benchmark_id, reference_run_id) VALUES (%s, %s)"), bm$id, bm.settings$reference_run_id) - db.query(cmd, bety) + PEcAn.DB::db.query(cmd, bety) }else if(dim(bmBRR)[1] > 1){ PEcAn.logger::logger.error("Duplicate record entries in benchmarks_benchmarks_reference_runs") } @@ -109,13 +111,13 @@ define_benchmark <- function(settings, bety){ # Retrieve/create benchmarks_metrics record for(k in seq_along(metric_ids)){ bmmetric <- tbl(bety, 'benchmarks_metrics') %>% - filter(benchmark_id == bm$id) %>% - filter(metric_id == metric_ids[[k]]) %>% collect() + filter(.data$benchmark_id == bm$id) %>% + filter(.data$metric_id == metric_ids[[k]]) %>% collect() if(dim(bmmetric)[1] == 0){ cmd <- sprintf(paste0("INSERT INTO benchmarks_metrics (benchmark_id, metric_id) VALUES (%s, %s)"), bm$id, metric_ids[[k]]) - db.query(cmd, bety) + PEcAn.DB::db.query(cmd, bety) }else if(dim(bmmetric)[1] > 1){ PEcAn.logger::logger.error("Duplicate record entries in benchmarks_metrics") } diff --git a/modules/benchmark/R/format_wide2long.R b/modules/benchmark/R/format_wide2long.R index 62dffbbd351..8ab93062e74 100644 --- a/modules/benchmark/R/format_wide2long.R +++ b/modules/benchmark/R/format_wide2long.R @@ -1,14 +1,12 @@ -##' @name format_wide2long -##' @title format_wide2long +##' Function to convert wide format to long format ##' ##' @param out wide format data ##' @param format as returned by query.format.vars -##' @param vars_used -##' @param time.row +##' @param vars_used data frame mapping `input_name` to `bety_name` +##' @param time.row ignored; value in output is set from `format$vars$storage_type` ##' @return list of updated values ##' @export ##' @author Istem Fer -##' Function to convert wide format to long format format_wide2long <- function(out, format, vars_used, time.row){ # GapMacro example: diff --git a/modules/benchmark/R/get_species_list_standard.R b/modules/benchmark/R/get_species_list_standard.R index e1bae78078b..d7872a31f96 100644 --- a/modules/benchmark/R/get_species_list_standard.R +++ b/modules/benchmark/R/get_species_list_standard.R @@ -1,13 +1,11 @@ #' get_species_list_standard -#' @details +#' #' Returns the format type for convience of use with match_species_id -#' @param observation_one a vector of plant fucntional types, or species -#' @param observation_two anouther vector of plant fucntional types, or species -#' @param custom_table a table that either maps two pft's to one another or maps custom species codes to bety id codes. -#' In the second case, must be passable to match_species_id. +#' +#' @param vars format to be matched #' @return \code{character} Returns "usda", "latin_name", "fia" or "custom" #' @author Tempest McCabe -get_species_list_standard<-function(vars){ +get_species_list_standard <- function(vars) { if(any(c("species_id", "species_USDA_symbol") %in% vars)){ return("usda") @@ -15,11 +13,11 @@ get_species_list_standard<-function(vars){ return('latin_name') }else if("species_FIA_symbol" %in% vars){ return('fia') - }else if(!is.null(custom_table)){ - if("bety_species_id" %in% names(custom_table)){ + }else if(!is.null(vars)){ + if("bety_species_id" %in% names(vars)){ return("custom") }else{ - logger.warn("Note: custom_table does not have column named 'bety_species_id' and cannot be used with match_species_id(). This prohibits species-level mapping, but allows PFT level mapping.") + PEcAn.logger::logger.warn("Note: `vars` does not have column named 'bety_species_id' and cannot be used with match_species_id(). This prohibits species-level mapping, but allows PFT level mapping.") } }else{ return(FALSE) diff --git a/modules/benchmark/R/load_csv.R b/modules/benchmark/R/load_csv.R index 2b0ff3486b6..28c9bdea4ef 100644 --- a/modules/benchmark/R/load_csv.R +++ b/modules/benchmark/R/load_csv.R @@ -1,31 +1,30 @@ -##' @name load_csv -##' @title load_csv -##' @export +##' load_csv +##' ##' @param data.path character ##' @param format list -##' @param start_year numeric -##' @param end_year numeric ##' @param site list +##' @param vars column names to return. If NULL, returns all columns ##' ##' @author Betsy Cowdery +##' @export load_csv <- function(data.path, format, site, vars = NULL) { data.path <- sapply(data.path, function(x) dir(dirname(x), basename(x), full.names = TRUE)) if (format$header == 0 | format$header == 1) { - dat <- read.csv(data.path, skip = format$skip, na.strings = format$na.strings, + dat <- utils::read.csv(data.path, skip = format$skip, na.strings = format$na.strings, as.is = TRUE, check.names = FALSE, header = as.logical(format$header)) } else if (format$header > 1) { - dat <- read.csv(data.path, skip = format$skip, na.strings = format$na.strings, + dat <- utils::read.csv(data.path, skip = format$skip, na.strings = format$na.strings, as.is = TRUE, check.names = FALSE, header = TRUE) - dat <- dat[-c(1:header - 1), ] + dat <- dat[-c(1:format$header - 1), ] } else { - dat <- read.csv(data.path, skip = format$skip, na.strings = format$na.strings, + dat <- utils::read.csv(data.path, skip = format$skip, na.strings = format$na.strings, as.is = TRUE, check.names = FALSE) } if(!is.null(vars)){ - return(dplyr::select(dat, one_of(vars))) + return(dplyr::select(dat, dplyr::one_of(vars))) }else{ return(dat) } diff --git a/modules/benchmark/R/load_data.R b/modules/benchmark/R/load_data.R index 10289ae9898..3f72ad3d3ea 100644 --- a/modules/benchmark/R/load_data.R +++ b/modules/benchmark/R/load_data.R @@ -1,15 +1,19 @@ -##' @name load_data -##' @title load_data -##' @export -##' @param data.path character -##' @param format list -##' @param start_year numeric -##' @param end_year numeric -##' @param site list -##' @author Betsy Cowdery, Istem Fer, Joshua Mantooth -##' Generic function to convert input files containing observational data to -##' a common PEcAn format. +#' load data +#' +#' Generic function to convert input files containing observational data to +#' a common PEcAn format. +#' +#' @param data.path character +#' @param format list +#' @param start_year numeric +#' @param end_year numeric +#' @param site list +#' @param vars.used.index which variables to use? If NULL, these are taken from `format` +#' @param ... further arguments, currently ignored +#' +#' @author Betsy Cowdery, Istem Fer, Joshua Mantooth #' @importFrom magrittr %>% +#' @export load_data <- function(data.path, format, start_year = NA, end_year = NA, site = NA, vars.used.index=NULL, ...) { @@ -128,13 +132,13 @@ load_data <- function(data.path, format, start_year = NA, end_year = NA, site = # This was part of the arguments but never implemented if(!is.na(start_year)){ out$year <- lubridate::year(out$posix) - out <- out %>% filter(.,year >= as.numeric(start_year)) + out <- out %>% filter(.data$year >= as.numeric(start_year)) print("subsetting by start year") } if(!is.na(end_year)){ out$year <- lubridate::year(out$posix) - out <- out %>% filter(.,year <= as.numeric(end_year)) + out <- out %>% filter(.data$year <= as.numeric(end_year)) print("subsetting by end year") } diff --git a/modules/benchmark/R/load_netcdf.R b/modules/benchmark/R/load_netcdf.R index 629ee006f36..2e956ffee85 100644 --- a/modules/benchmark/R/load_netcdf.R +++ b/modules/benchmark/R/load_netcdf.R @@ -1,13 +1,11 @@ -##' @name load_x_netcdf -##' @title load_x_netcdf -##' @export +##' Load from netCDF +##' ##' @param data.path character vector or list ##' @param format list -##' @param start_year numeric -##' @param end_year numeric ##' @param site list ##' @param vars character ##' @author Istem Fer +##' @export load_x_netcdf <- function(data.path, format, site, vars = NULL) { data.path <- sapply(data.path, function(x) dir(dirname(x), basename(x), full.names = TRUE)) nc <- lapply(data.path, ncdf4::nc_open) diff --git a/modules/benchmark/R/load_rds.R b/modules/benchmark/R/load_rds.R index f7b81c49cda..7fb82daa5b8 100644 --- a/modules/benchmark/R/load_rds.R +++ b/modules/benchmark/R/load_rds.R @@ -4,7 +4,7 @@ ##' @param data.path character ##' @param format list, not used, for compatibility ##' @param site not used, for compatibility -##' @param vars +##' @param vars optional variable names to load. if NULL, returns all variables in file ##' ##' @author Istem Fer load_rds <- function(data.path, format, site, vars = NULL) { @@ -14,7 +14,7 @@ load_rds <- function(data.path, format, site, vars = NULL) { dat <- readRDS(data.path) if(!is.null(vars)){ - return(dplyr::select(dat, one_of(vars))) + return(dplyr::select(dat, dplyr::one_of(vars))) }else{ return(dat) } diff --git a/modules/benchmark/R/load_tab.R b/modules/benchmark/R/load_tab.R index 6b13ee6c278..4f95eca6413 100644 --- a/modules/benchmark/R/load_tab.R +++ b/modules/benchmark/R/load_tab.R @@ -1,36 +1,34 @@ -##' @name load_tab_separated_values -##' @title load_tab_separated_values -##' @export +##' Load files with mime-type 'text/tab-separated-values' +##' ##' @param data.path character ##' @param format list -##' @param start_year numeric -##' @param end_year numeric ##' @param site list +##' @param vars variable names to load. If NULL, loads all columns ##' ##' @author Betsy Cowdery, Mike Dietze +##' @export load_tab_separated_values <- function(data.path, format, site=NULL, vars = NULL) { - ## load's mime-type = text/tab-separated-values data.path <- sapply(data.path, function(x) dir(dirname(x), basename(x), full.names = TRUE)) if (format$header == 0) { - dat <- read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, + dat <- utils::read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, as.is = TRUE, check.names = FALSE, header = FALSE) colnames(dat)[format$vars$column_number] <- format$vars$input_name } else if (format$header == 1) { - dat <- read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, + dat <- utils::read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, as.is = TRUE, check.names = FALSE, header = TRUE) } else if (format$header > 1) { - dat <- read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, + dat <- utils::read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, as.is = TRUE, check.names = FALSE, header = TRUE) - dat <- dat[-c(1:header - 1), ] + dat <- dat[-c(1:format$header - 1), ] } else { - dat <- read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, + dat <- utils::read.table(data.path, sep="\t",skip = format$skip, na.strings = format$na.strings, as.is = TRUE, check.names = FALSE) } if(!is.null(vars)){ - return(dplyr::select(dat, one_of(vars))) + return(dplyr::select(dat, dplyr::one_of(vars))) }else{ return(dat) } diff --git a/modules/benchmark/R/match_timestep.R b/modules/benchmark/R/match_timestep.R index 8f59533a338..bb030ed447f 100644 --- a/modules/benchmark/R/match_timestep.R +++ b/modules/benchmark/R/match_timestep.R @@ -8,7 +8,7 @@ ##' @author Istem Fer match_timestep <- function(date.coarse, date.fine, data.fine) { - midpoints <- c(-Inf, head(as.numeric(date.fine), -1)) + c(0, diff(as.numeric(date.fine)) / 2) + midpoints <- c(-Inf, utils::head(as.numeric(date.fine), -1)) + c(0, diff(as.numeric(date.fine)) / 2) return(data.fine[findInterval(date.coarse, midpoints)]) } # match_timestep diff --git a/modules/benchmark/R/metric_AME.R b/modules/benchmark/R/metric_AME.R index 805d54dcbf8..cd5950bac97 100644 --- a/modules/benchmark/R/metric_AME.R +++ b/modules/benchmark/R/metric_AME.R @@ -1,9 +1,10 @@ -##' @name metric_AME -##' @title Absolute Maximum Error -##' @export +##' Absolute Maximum Error +##' ##' @param dat dataframe +##' @param ... ignored ##' ##' @author Betsy Cowdery +##' @export metric_AME <- function(dat, ...) { PEcAn.logger::logger.info("Metric: Absolute Maximum Error") diff --git a/modules/benchmark/R/metric_Frechet.R b/modules/benchmark/R/metric_Frechet.R index 3a11cb96a77..e79014c6450 100644 --- a/modules/benchmark/R/metric_Frechet.R +++ b/modules/benchmark/R/metric_Frechet.R @@ -2,12 +2,13 @@ ##' @title Frechet Distance ##' @export ##' @param metric_dat dataframe +##' @param ... ignored ##' ##' @author Betsy Cowdery metric_Frechet <- function(metric_dat, ...) { - logger.info("Metric: Frechet Distance") - dat.no.na <- na.omit(metric_dat) + PEcAn.logger::logger.info("Metric: Frechet Distance") + dat.no.na <- stats::na.omit(metric_dat) Fdist <- SimilarityMeasures::Frechet(as.matrix(dat.no.na$obvs), as.matrix(dat.no.na$model)) return(Fdist) } # metric_Frechet diff --git a/modules/benchmark/R/metric_MAE.R b/modules/benchmark/R/metric_MAE.R index 03229d1f0b5..06fa9577a4e 100644 --- a/modules/benchmark/R/metric_MAE.R +++ b/modules/benchmark/R/metric_MAE.R @@ -1,10 +1,10 @@ -##' @name metric_MAE -##' @title Mean Absolute Error -##' @export +##' Mean Absolute Error ##' @param dat dataframe +##' @param ... ignored ##' ##' @author Betsy Cowdery ##' +##' @export metric_MAE <- function(dat, ...) { PEcAn.logger::logger.info("Metric: Mean Absolute Error") return(mean(abs(dat$model - dat$obvs),na.rm=TRUE)) diff --git a/modules/benchmark/R/metric_MSE.R b/modules/benchmark/R/metric_MSE.R index 1ace772a42f..a3d91a14764 100644 --- a/modules/benchmark/R/metric_MSE.R +++ b/modules/benchmark/R/metric_MSE.R @@ -2,6 +2,7 @@ ##' @title Mean Square Error ##' @export ##' @param dat dataframe +##' @param ... ignored ##' ##' @author Betsy Cowdery diff --git a/modules/benchmark/R/metric_PPMC.R b/modules/benchmark/R/metric_PPMC.R index 6c3d7a55dd9..53ec1151c84 100644 --- a/modules/benchmark/R/metric_PPMC.R +++ b/modules/benchmark/R/metric_PPMC.R @@ -2,6 +2,7 @@ ##' @title Pearson Product Moment Correlation ##' @export ##' @param metric_dat dataframe +##' @param ... ignored ##' ##' @author Betsy Cowdery @@ -10,5 +11,5 @@ metric_PPMC <- function(metric_dat, ...) { # numer <- sum((metric_dat$obvs - mean(metric_dat$obvs)) * (metric_dat$model - mean(metric_dat$model))) # denom <- sqrt(sum((metric_dat$obvs - mean(metric_dat$obvs)) ^ 2)) * sqrt(sum((metric_dat$model - mean(metric_dat$model)) ^ 2)) # return(numer / denom) - return(cor(metric_dat$obvs, metric_dat$model)) + return(stats::cor(metric_dat$obvs, metric_dat$model)) } # metric_PPMC diff --git a/modules/benchmark/R/metric_R2.R b/modules/benchmark/R/metric_R2.R index 8de8b497bd5..94e5df7677b 100644 --- a/modules/benchmark/R/metric_R2.R +++ b/modules/benchmark/R/metric_R2.R @@ -2,6 +2,7 @@ ##' @title Coefficient of Determination (R2) ##' @export ##' @param metric_dat dataframe +##' @param ... ignored ##' ##' @author Betsy Cowdery @@ -13,7 +14,7 @@ metric_R2 <- function(metric_dat, ...) { out <- (numer / denom) ^ 2 if(is.na(out)){ - fit <- lm(metric_dat$model ~ metric_dat$obvs) + fit <- stats::lm(metric_dat$model ~ metric_dat$obvs) out <- summary(fit)$r.squared } diff --git a/modules/benchmark/R/metric_RAE.R b/modules/benchmark/R/metric_RAE.R index 77e4b9004c2..b644aabb56a 100644 --- a/modules/benchmark/R/metric_RAE.R +++ b/modules/benchmark/R/metric_RAE.R @@ -2,12 +2,13 @@ ##' @title Relative Absolute Error ##' @export ##' @param metric_dat dataframe -##' +##' @param ... ignored +##' ##' @author Betsy Cowdery metric_RAE <- function(metric_dat, ...) { PEcAn.logger::logger.info("Metric: Relative Absolute Error") - metric_dat <- na.omit(metric_dat) + metric_dat <- stats::na.omit(metric_dat) numer <- mean(abs(metric_dat$obvs - metric_dat$model)) denom <- mean(abs(metric_dat$obvs - mean(metric_dat$obvs))) return(numer/denom) diff --git a/modules/benchmark/R/metric_RMSE.R b/modules/benchmark/R/metric_RMSE.R index 6ae45498b82..ebd02fc89c2 100644 --- a/modules/benchmark/R/metric_RMSE.R +++ b/modules/benchmark/R/metric_RMSE.R @@ -2,6 +2,7 @@ ##' @title Root Mean Square Error ##' @export ##' @param dat dataframe +##' @param ... ignored ##' ##' @author Betsy Cowdery diff --git a/modules/benchmark/R/metric_cor.R b/modules/benchmark/R/metric_cor.R index 26780eb757a..cf3bfa026f3 100644 --- a/modules/benchmark/R/metric_cor.R +++ b/modules/benchmark/R/metric_cor.R @@ -2,10 +2,11 @@ ##' @title Correlation Coefficient ##' @export ##' @param dat dataframe +##' @param ... ignored ##' ##' @author Mike Dietze metric_cor <- function(dat, ...) { PEcAn.logger::logger.info("Metric: Correlation Coefficient") - return(cor(dat$model,dat$obvs,use ="pairwise.complete.obs")) + return(stats::cor(dat$model,dat$obvs,use ="pairwise.complete.obs")) } # metric_cor diff --git a/modules/benchmark/R/metric_lmDiag_plot.R b/modules/benchmark/R/metric_lmDiag_plot.R index 5519f4f6ec6..2be6f50d951 100644 --- a/modules/benchmark/R/metric_lmDiag_plot.R +++ b/modules/benchmark/R/metric_lmDiag_plot.R @@ -2,14 +2,17 @@ ##' @title Linear Regression Diagnostic Plot ##' @export ##' @param metric_dat data.frame +##' @param var ignored +##' @param filename path to save plot, or NA to not save +##' @param draw.plot logical: return plot object? ##' ##' @author Betsy Cowdery metric_lmDiag_plot <- function(metric_dat, var, filename = NA, draw.plot = FALSE) { PEcAn.logger::logger.info("Metric: Linear Regression Diagnostic Plot") - fit <- lm(metric_dat[, 1] ~ metric_dat[, 2]) + fit <- stats::lm(metric_dat[, 1] ~ metric_dat[, 2]) - p1 <- ggplot2::ggplot(fit, aes(.fitted, .resid)) + p1 <- ggplot2::ggplot(fit, ggplot2::aes(.data$.fitted, .data$.resid)) p1 <- p1 + ggplot2::geom_point() p1 <- p1 + ggplot2::stat_smooth(method = "loess") p1 <- p1 + ggplot2::geom_hline(yintercept = 0, col = "red", linetype = "dashed") @@ -18,15 +21,15 @@ metric_lmDiag_plot <- function(metric_dat, var, filename = NA, draw.plot = FALSE p1 <- p1 + ggplot2::ggtitle("Residual vs Fitted Plot") p1 <- p1 + ggplot2::theme_bw() - p2 <- ggplot2::ggplot(fit, aes(qqnorm(.stdresid)[[1]], .stdresid)) + p2 <- ggplot2::ggplot(fit, ggplot2::aes(stats::qqnorm(.data$.stdresid)[[1]], .data$.stdresid)) p2 <- p2 + ggplot2::geom_point(na.rm = TRUE) - p2 <- p2 + ggplot2::geom_abline(aes(qqline(.stdresid))) + p2 <- p2 + ggplot2::geom_abline(ggplot2::aes(stats::qqline(.data$.stdresid))) p2 <- p2 + ggplot2::xlab("Theoretical Quantiles") p2 <- p2 + ggplot2::ylab("Standardized Residuals") p2 <- p2 + ggplot2::ggtitle("Normal Q-Q") p2 <- p2 + ggplot2::theme_bw() - p3 <- ggplot2::ggplot(fit, aes(.fitted, sqrt(abs(.stdresid)))) + p3 <- ggplot2::ggplot(fit, ggplot2::aes(.data$.fitted, sqrt(abs(.data$.stdresid)))) p3 <- p3 + ggplot2::geom_point(na.rm = TRUE) p3 <- p3 + ggplot2::stat_smooth(method = "loess", na.rm = TRUE) p3 <- p3 + ggplot2::xlab("Fitted Value") @@ -34,15 +37,15 @@ metric_lmDiag_plot <- function(metric_dat, var, filename = NA, draw.plot = FALSE p3 <- p3 + ggplot2::ggtitle("Scale-Location") p3 <- p3 + ggplot2::theme_bw() - p4 <- ggplot2:: ggplot(fit, aes(seq_along(.cooksd), .cooksd)) + p4 <- ggplot2:: ggplot(fit, ggplot2::aes(seq_along(.data$.cooksd), .data$.cooksd)) p4 <- p4 + ggplot2::geom_bar(stat = "identity", position = "identity") p4 <- p4 + ggplot2::xlab("Obs. Number") p4 <- p4 + ggplot2::ylab("Cook's distance") p4 <- p4 + ggplot2::ggtitle("Cook's distance") p4 <- p4 + ggplot2::theme_bw() - p5 <- ggplot2::ggplot(fit, aes(.hat, .stdresid)) - p5 <- p5 + ggplot2::geom_point(aes(size = .cooksd), na.rm = TRUE) + p5 <- ggplot2::ggplot(fit, ggplot2::aes(.data$.hat, .data$.stdresid)) + p5 <- p5 + ggplot2::geom_point(ggplot2::aes(size = .data$.cooksd), na.rm = TRUE) p5 <- p5 + ggplot2::stat_smooth(method = "loess", na.rm = TRUE) p5 <- p5 + ggplot2::xlab("Leverage") p5 <- p5 + ggplot2::ylab("Standardized Residuals") @@ -51,7 +54,7 @@ metric_lmDiag_plot <- function(metric_dat, var, filename = NA, draw.plot = FALSE p5 <- p5 + ggplot2::theme_bw() p5 <- p5 + ggplot2::theme(legend.position = "bottom") - p6 <- ggplot2::ggplot(fit, aes(.hat, .cooksd)) + p6 <- ggplot2::ggplot(fit, ggplot2::aes(.data$.hat, .data$.cooksd)) p6 <- p6 + ggplot2::geom_point(na.rm = TRUE) p6 <- p6 + ggplot2::stat_smooth(method = "loess", na.rm = TRUE) p6 <- p6 + ggplot2::xlab("Leverage hii") @@ -63,9 +66,9 @@ metric_lmDiag_plot <- function(metric_dat, var, filename = NA, draw.plot = FALSE p <- gridExtra::grid.arrange(p1, p2, p3, p4, p5, p6, nrow = 3) if (!is.na(filename)) { - pdf(filename, width = 10, height = 6) + grDevices::pdf(filename, width = 10, height = 6) plot(p) - dev.off() + grDevices::dev.off() } if (draw.plot) { diff --git a/modules/benchmark/R/metric_residual_plot.R b/modules/benchmark/R/metric_residual_plot.R index e7f4b624183..38a20a65125 100644 --- a/modules/benchmark/R/metric_residual_plot.R +++ b/modules/benchmark/R/metric_residual_plot.R @@ -1,28 +1,28 @@ -##' @name metric_residual_plot -##' @title Residual Plot -##' @export -##' @param metric_dat -##' @param var -##' @param filename -##' @param draw.plot +##' Residual Plot +##' +##' @param metric_dat dataframe to plot, with at least columns `time`, `model`, `obvs` +##' @param var variable name, used as plot title +##' @param filename path to save plot, or NA to not save +##' @param draw.plot logical: Return the plot object? ##' ##' @author Betsy Cowdery +##' @export metric_residual_plot <- function(metric_dat, var, filename = NA, draw.plot = is.na(filename)) { PEcAn.logger::logger.info("Metric: Residual Plot") metric_dat$time <- lubridate::year(as.Date(as.character(metric_dat$time), format = "%Y")) metric_dat$diff <- abs(metric_dat$model - metric_dat$obvs) - metric_dat$zeros <- rep(0, length(time)) + metric_dat$zeros <- rep(0, length(metric_dat$time)) - p <- ggplot2::ggplot(data = metric_dat, aes(x = time)) - p <- p + ggplot2::geom_path(aes(y = zeros), colour = "#666666", size = 2, linetype = 2, lineend = "round") - p <- p + ggplot2::geom_point(aes(y = diff), size = 4, colour = "#619CFF") + p <- ggplot2::ggplot(data = metric_dat, ggplot2::aes(x = .data$time)) + p <- p + ggplot2::geom_path(ggplot2::aes(y = .data$zeros), colour = "#666666", size = 2, linetype = 2, lineend = "round") + p <- p + ggplot2::geom_point(ggplot2::aes(y = .data$diff), size = 4, colour = "#619CFF") p <- p + ggplot2::labs(title = var, x = "years", y = "abs(model - observation)") if (!is.na(filename)) { - pdf(filename, width = 10, height = 6) + grDevices::pdf(filename, width = 10, height = 6) plot(p) - dev.off() + grDevices::dev.off() } if (draw.plot) { diff --git a/modules/benchmark/R/metric_run.R b/modules/benchmark/R/metric_run.R index 5b07163eef4..40183a872e8 100644 --- a/modules/benchmark/R/metric_run.R +++ b/modules/benchmark/R/metric_run.R @@ -1,9 +1,9 @@ -##' @name metric_run -##' @title Model Run Check -##' @export +##' Model Run Check +##' ##' @param settings list ##' ##' @author Betsy Cowdery +##' @export metric_run <- function(settings){ # The goal of this function is to determine if a model run has been successfully completed. diff --git a/modules/benchmark/R/metric_scatter_plot.R b/modules/benchmark/R/metric_scatter_plot.R index 3e285f7d71d..751d08e53b4 100644 --- a/modules/benchmark/R/metric_scatter_plot.R +++ b/modules/benchmark/R/metric_scatter_plot.R @@ -1,25 +1,25 @@ -##' @name metric_scatter_plot -##' @title Scatter Plot -##' @export -##' @param metric_dat -##' @param var -##' @param filename -##' @param draw.plot +##' Scatter Plot +##' +##' @param metric_dat dataframe to plot, with at least columns `model` and `obvs` +##' @param var ignored +##' @param filename path to save plot, or NA to not save +##' @param draw.plot logical: Return the plot object? ##' ##' @author Betsy Cowdery +##' @export metric_scatter_plot <- function(metric_dat, var, filename = NA, draw.plot = is.na(filename)) { PEcAn.logger::logger.info("Metric: Scatter Plot") p <- ggplot2::ggplot(data = metric_dat) - p <- p + ggplot2::geom_point(aes(x = model, y = obvs), size = 4) + p <- p + ggplot2::geom_point(ggplot2::aes(x = .data$model, y = .data$obvs), size = 4) p <- p + ggplot2::geom_abline(slope = 1, intercept = 0, colour = "#666666", size = 2, linetype = 2) if (!is.na(filename)) { - pdf(filename, width = 10, height = 6) + grDevices::pdf(filename, width = 10, height = 6) plot(p) - dev.off() + grDevices::dev.off() } if (draw.plot) { diff --git a/modules/benchmark/R/metric_timeseries_plot.R b/modules/benchmark/R/metric_timeseries_plot.R index a35dc007c3f..ca879b95648 100644 --- a/modules/benchmark/R/metric_timeseries_plot.R +++ b/modules/benchmark/R/metric_timeseries_plot.R @@ -1,12 +1,13 @@ -##' @name metric_timeseries_plot -##' @title Timeseries Plot -##' @export -##' @param metric_dat -##' @param var -##' @param filename -##' @param draw.plot -##' @importFrom ggplot2 ggplot labs geom_path geom_point +##' Timeseries Plot +##' +##' @param metric_dat dataframe to plot, with at least columns `time`, `model`, `obvs` +##' @param var variable name, used as plot title +##' @param filename path to save plot, or NA to not save +##' @param draw.plot logical: Return the plot object? +##' ##' @author Betsy Cowdery +##' @importFrom ggplot2 ggplot labs geom_path geom_point +##' @export metric_timeseries_plot <- function(metric_dat, var, filename = NA, draw.plot = is.na(filename)) { PEcAn.logger::logger.info("Metric: Timeseries Plot") @@ -19,17 +20,17 @@ metric_timeseries_plot <- function(metric_dat, var, filename = NA, draw.plot = i metric_dat$time <- date.time } - p <- ggplot(data = metric_dat, aes(x = time)) + p <- ggplot(data = metric_dat, ggplot2::aes(x = .data$time)) p <- p + labs(title = var, y = "") - p <- p + geom_path(aes(y = model, colour = "Model"), size = 2) - p <- p + geom_point(aes(y = model, colour = "Model"), size = 4) - p <- p + geom_path(aes(y = obvs, colour = "Observed"), size = 2) - p <- p + geom_point(aes(y = obvs, colour = "Observed"), size = 4) + p <- p + geom_path(ggplot2::aes(y = .data$model, colour = "Model"), size = 2) + p <- p + geom_point(ggplot2::aes(y = .data$model, colour = "Model"), size = 4) + p <- p + geom_path(ggplot2::aes(y = .data$obvs, colour = "Observed"), size = 2) + p <- p + geom_point(ggplot2::aes(y = .data$obvs, colour = "Observed"), size = 4) if (!is.na(filename)) { - pdf(filename, width = 10, height = 6) + grDevices::pdf(filename, width = 10, height = 6) plot(p) - dev.off() + grDevices::dev.off() } if (draw.plot) { diff --git a/modules/benchmark/R/pecan_bench.R b/modules/benchmark/R/pecan_bench.R index 85441429869..598a25c4260 100644 --- a/modules/benchmark/R/pecan_bench.R +++ b/modules/benchmark/R/pecan_bench.R @@ -51,7 +51,7 @@ pecan_bench <- function(comp_run, bench_id, imp_limit, high_limit) { # more than one site, more than one variable we want to track) so we need flexibility. More # generally, files should never be hardcoded since these tests will run on many different machines - obs_file <- read.table("Location of the data table") + obs_file <- utils::read.table("Location of the data table") obs_value <- obs_file$value N <- size(obs_value) @@ -70,7 +70,7 @@ pecan_bench <- function(comp_run, bench_id, imp_limit, high_limit) { # purpose of that run was recorded elsewhere. seems like it would be much better to have all that # in one place - bench_file <- read.table("Location of the data table", bench_id) + bench_file <- utils::read.table("Location of the data table", bench_id) bench_value <- bench_file$value # First calculate the differences between the current benchmark run and the observed values @@ -179,8 +179,8 @@ pecan_bench <- function(comp_run, bench_id, imp_limit, high_limit) { # calculate the if (bench_ratio_mean < imp_limit & bench_ratio_count > 0.8) { - Set_Bench(...) #Subroutine which sets the current run to be the new benchmark comparison run as well as saves the previous benchmark comparison run a database - Compare_Bench(...) #Subroutine which calculates a new vector of values which are essentially the benchmark ratios between old runs and the current comparison run. + #Set_Bench(...) #Subroutine which sets the current run to be the new benchmark comparison run as well as saves the previous benchmark comparison run a database + #Compare_Bench(...) #Subroutine which calculates a new vector of values which are essentially the benchmark ratios between old runs and the current comparison run. } ## MCD: I wonder if this should be automatic (i.e. every time the model does better it becomes the ## new benchmark) or whether it should be something where the user is prompted to confirm that we diff --git a/modules/benchmark/man/align_by_first_observation.Rd b/modules/benchmark/man/align_by_first_observation.Rd index dba4cf7e7f9..4bc3c0efca8 100644 --- a/modules/benchmark/man/align_by_first_observation.Rd +++ b/modules/benchmark/man/align_by_first_observation.Rd @@ -30,8 +30,10 @@ table$plant_functional_type_one<- c("AMCA3","AMCA3","ARHY", "ARHY") table$plant_functional_type_two<- c('a','a','b', 'b') # PFT groupings table<-as.data.frame(table) -aligned<-align_by_first_observation(observation_one = observation_one, observation_two = observation_two, -custom_table = table) +aligned <- align_by_first_observation( + observation_one = observation_one, + observation_two = observation_two, + custom_table = table) # aligned should be a vector '[1] "AMCA3" "ARHY" "AMCA3" "AMCA3"' } diff --git a/modules/benchmark/man/align_data.Rd b/modules/benchmark/man/align_data.Rd index 5ab6125b9e2..c62f819314d 100644 --- a/modules/benchmark/man/align_data.Rd +++ b/modules/benchmark/man/align_data.Rd @@ -12,6 +12,8 @@ align_data(model.calc, obvs.calc, var, align_method = "match_timestep") \item{obvs.calc}{data.frame} \item{var}{data.frame} + +\item{align_method}{name of function to use for alignment} } \value{ dat diff --git a/modules/benchmark/man/align_pft.Rd b/modules/benchmark/man/align_pft.Rd index 407af6a61bd..71a24566e2f 100644 --- a/modules/benchmark/man/align_pft.Rd +++ b/modules/benchmark/man/align_pft.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/align_pft.R \name{align_pft} \alias{align_pft} -\title{align_pft} +\title{Align vectors of Plant Functional Type and species.} \usage{ align_pft( con, @@ -32,6 +32,10 @@ In the second case, must be passable to match_species_id.} \item{subset_is_ok}{When aligning two species lists, this allows for alignement when species lists aren't identical. set to FALSE by default.} + +\item{comparison_type}{one of "data_to_model", "data_to_data", or "model_to_model"} + +\item{...}{other arguments, currently ignored} } \value{ \code{list} containing the following columns: @@ -43,10 +47,9 @@ set to FALSE by default.} } } \description{ -align_pft +Align vectors of Plant Functional Type and species. } \details{ -Aligns vectors of Plant Fucntional Typed and species. Can align: - two vectors of plant fucntional types (pft's) if a custom map is provided - a list of species (usda, fia, or latin_name format) to a plant fucntional type diff --git a/modules/benchmark/man/calc_benchmark.Rd b/modules/benchmark/man/calc_benchmark.Rd index 9d988bfc72a..0b970147d80 100644 --- a/modules/benchmark/man/calc_benchmark.Rd +++ b/modules/benchmark/man/calc_benchmark.Rd @@ -7,9 +7,11 @@ calc_benchmark(settings, bety, start_year = NA, end_year = NA) } \arguments{ +\item{settings}{settings object describing the run to calculate} + \item{bety}{database connection} -\item{bm.ensemble}{object, either from create_BRR or start.bm.ensemle} +\item{start_year, end_year}{time range to read. If NA, these are taken from `settings`} } \description{ For each benchmark id, calculate metrics and update benchmarks_ensemble_scores diff --git a/modules/benchmark/man/check_if_legal_table.Rd b/modules/benchmark/man/check_if_legal_table.Rd index d31609148f6..c9c62085ff3 100644 --- a/modules/benchmark/man/check_if_legal_table.Rd +++ b/modules/benchmark/man/check_if_legal_table.Rd @@ -7,12 +7,12 @@ check_if_legal_table(table, observation_one, observation_two) } \arguments{ +\item{table}{a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. +In the second case, must be passable to match_species_id.} + \item{observation_one}{a vector of plant functional types, or species} \item{observation_two}{anouther vector of plant functional types, or species} - -\item{custom_table}{a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. -In the second case, must be passable to match_species_id.} } \value{ \code{boolean} diff --git a/modules/benchmark/man/check_if_list_of_pfts.Rd b/modules/benchmark/man/check_if_list_of_pfts.Rd index ed2fa46c778..f515eb38a14 100644 --- a/modules/benchmark/man/check_if_list_of_pfts.Rd +++ b/modules/benchmark/man/check_if_list_of_pfts.Rd @@ -7,20 +7,12 @@ check_if_list_of_pfts(vars) } \arguments{ -\item{observation_one}{a vector of plant fucntional types, or species} - -\item{observation_two}{anouther vector of plant fucntional types, or species} - -\item{custom_table}{a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. -In the second case, must be passable to match_species_id.} +\item{vars}{names to check} } \value{ \code{boolean} } \description{ -check_if_list_of_pfts -} -\details{ Checks if format contains a variable named "plant_functional_type" } \author{ diff --git a/modules/benchmark/man/check_if_species_list.Rd b/modules/benchmark/man/check_if_species_list.Rd index 02637b73657..60357127e67 100644 --- a/modules/benchmark/man/check_if_species_list.Rd +++ b/modules/benchmark/man/check_if_species_list.Rd @@ -7,12 +7,10 @@ check_if_species_list(vars, custom_table = NULL) } \arguments{ +\item{vars}{format} + \item{custom_table}{a table that either maps two pft's to one anouther or maps custom species codes to bety id codes. In the second case, must be passable to match_species_id.} - -\item{observation_one}{a vector of plant functional types, or species} - -\item{observation_two}{another vector of plant functional types, or species} } \value{ \code{boolean} diff --git a/modules/benchmark/man/create_BRR.Rd b/modules/benchmark/man/create_BRR.Rd index df6d1b4988c..a0c26b7e6bf 100644 --- a/modules/benchmark/man/create_BRR.Rd +++ b/modules/benchmark/man/create_BRR.Rd @@ -10,6 +10,8 @@ create_BRR(ens_wf, con, user_id = "") \item{ens_wf}{table made from joining ensemble and workflow tables} \item{con}{database connection} + +\item{user_id}{Optional user id to use for this record in reference_runs table} } \description{ For each benchmark id, calculate metrics and update benchmarks_ensemble_scores diff --git a/modules/benchmark/man/define_benchmark.Rd b/modules/benchmark/man/define_benchmark.Rd index 5f7c4451650..f93a799506d 100644 --- a/modules/benchmark/man/define_benchmark.Rd +++ b/modules/benchmark/man/define_benchmark.Rd @@ -7,7 +7,9 @@ define_benchmark(settings, bety) } \arguments{ -\item{bm.settings}{settings list} +\item{settings}{settings list} + +\item{bety}{database connection} } \value{ updated settings list diff --git a/modules/benchmark/man/format_wide2long.Rd b/modules/benchmark/man/format_wide2long.Rd index ee1250fe320..c5a985f7cba 100644 --- a/modules/benchmark/man/format_wide2long.Rd +++ b/modules/benchmark/man/format_wide2long.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/format_wide2long.R \name{format_wide2long} \alias{format_wide2long} -\title{format_wide2long} +\title{Function to convert wide format to long format} \usage{ format_wide2long(out, format, vars_used, time.row) } @@ -11,15 +11,16 @@ format_wide2long(out, format, vars_used, time.row) \item{format}{as returned by query.format.vars} -\item{vars_used}{} +\item{vars_used}{data frame mapping `input_name` to `bety_name`} + +\item{time.row}{ignored; value in output is set from `format$vars$storage_type`} } \value{ list of updated values } \description{ -format_wide2long +Function to convert wide format to long format } \author{ Istem Fer -Function to convert wide format to long format } diff --git a/modules/benchmark/man/get_species_list_standard.Rd b/modules/benchmark/man/get_species_list_standard.Rd index 944f8492026..f1e26ffa981 100644 --- a/modules/benchmark/man/get_species_list_standard.Rd +++ b/modules/benchmark/man/get_species_list_standard.Rd @@ -7,20 +7,12 @@ get_species_list_standard(vars) } \arguments{ -\item{observation_one}{a vector of plant fucntional types, or species} - -\item{observation_two}{anouther vector of plant fucntional types, or species} - -\item{custom_table}{a table that either maps two pft's to one another or maps custom species codes to bety id codes. -In the second case, must be passable to match_species_id.} +\item{vars}{format to be matched} } \value{ \code{character} Returns "usda", "latin_name", "fia" or "custom" } \description{ -get_species_list_standard -} -\details{ Returns the format type for convience of use with match_species_id } \author{ diff --git a/modules/benchmark/man/load_csv.Rd b/modules/benchmark/man/load_csv.Rd index 1b9dcd7c089..fdf055ac6bd 100644 --- a/modules/benchmark/man/load_csv.Rd +++ b/modules/benchmark/man/load_csv.Rd @@ -13,9 +13,7 @@ load_csv(data.path, format, site, vars = NULL) \item{site}{list} -\item{start_year}{numeric} - -\item{end_year}{numeric} +\item{vars}{column names to return. If NULL, returns all columns} } \description{ load_csv diff --git a/modules/benchmark/man/load_data.Rd b/modules/benchmark/man/load_data.Rd index 70bfbd5993e..c1a993f314b 100644 --- a/modules/benchmark/man/load_data.Rd +++ b/modules/benchmark/man/load_data.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/load_data.R \name{load_data} \alias{load_data} -\title{load_data} +\title{load data} \usage{ load_data( data.path, @@ -24,12 +24,15 @@ load_data( \item{end_year}{numeric} \item{site}{list} + +\item{vars.used.index}{which variables to use? If NULL, these are taken from `format`} + +\item{...}{further arguments, currently ignored} } \description{ -load_data +Generic function to convert input files containing observational data to +a common PEcAn format. } \author{ Betsy Cowdery, Istem Fer, Joshua Mantooth -Generic function to convert input files containing observational data to -a common PEcAn format. } diff --git a/modules/benchmark/man/load_rds.Rd b/modules/benchmark/man/load_rds.Rd index e684a796cf2..a1e1e552bbd 100644 --- a/modules/benchmark/man/load_rds.Rd +++ b/modules/benchmark/man/load_rds.Rd @@ -13,7 +13,7 @@ load_rds(data.path, format, site, vars = NULL) \item{site}{not used, for compatibility} -\item{vars}{} +\item{vars}{optional variable names to load. if NULL, returns all variables in file} } \description{ load_rds diff --git a/modules/benchmark/man/load_tab_separated_values.Rd b/modules/benchmark/man/load_tab_separated_values.Rd index 22a307047c8..1f7d4eba7cc 100644 --- a/modules/benchmark/man/load_tab_separated_values.Rd +++ b/modules/benchmark/man/load_tab_separated_values.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/load_tab.R \name{load_tab_separated_values} \alias{load_tab_separated_values} -\title{load_tab_separated_values} +\title{Load files with mime-type 'text/tab-separated-values'} \usage{ load_tab_separated_values(data.path, format, site = NULL, vars = NULL) } @@ -13,12 +13,10 @@ load_tab_separated_values(data.path, format, site = NULL, vars = NULL) \item{site}{list} -\item{start_year}{numeric} - -\item{end_year}{numeric} +\item{vars}{variable names to load. If NULL, loads all columns} } \description{ -load_tab_separated_values +Load files with mime-type 'text/tab-separated-values' } \author{ Betsy Cowdery, Mike Dietze diff --git a/modules/benchmark/man/load_x_netcdf.Rd b/modules/benchmark/man/load_x_netcdf.Rd index 7534f711a7d..c02d2b55229 100644 --- a/modules/benchmark/man/load_x_netcdf.Rd +++ b/modules/benchmark/man/load_x_netcdf.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/load_netcdf.R \name{load_x_netcdf} \alias{load_x_netcdf} -\title{load_x_netcdf} +\title{Load from netCDF} \usage{ load_x_netcdf(data.path, format, site, vars = NULL) } @@ -14,13 +14,9 @@ load_x_netcdf(data.path, format, site, vars = NULL) \item{site}{list} \item{vars}{character} - -\item{start_year}{numeric} - -\item{end_year}{numeric} } \description{ -load_x_netcdf +Load from netCDF } \author{ Istem Fer diff --git a/modules/benchmark/man/metric_AME.Rd b/modules/benchmark/man/metric_AME.Rd index b7b8c539163..76564fc901e 100644 --- a/modules/benchmark/man/metric_AME.Rd +++ b/modules/benchmark/man/metric_AME.Rd @@ -8,6 +8,8 @@ metric_AME(dat, ...) } \arguments{ \item{dat}{dataframe} + +\item{...}{ignored} } \description{ Absolute Maximum Error diff --git a/modules/benchmark/man/metric_Frechet.Rd b/modules/benchmark/man/metric_Frechet.Rd index ab81bcb5044..86136671b42 100644 --- a/modules/benchmark/man/metric_Frechet.Rd +++ b/modules/benchmark/man/metric_Frechet.Rd @@ -8,6 +8,8 @@ metric_Frechet(metric_dat, ...) } \arguments{ \item{metric_dat}{dataframe} + +\item{...}{ignored} } \description{ Frechet Distance diff --git a/modules/benchmark/man/metric_MAE.Rd b/modules/benchmark/man/metric_MAE.Rd index 8bcf95b9509..e19e885e814 100644 --- a/modules/benchmark/man/metric_MAE.Rd +++ b/modules/benchmark/man/metric_MAE.Rd @@ -8,6 +8,8 @@ metric_MAE(dat, ...) } \arguments{ \item{dat}{dataframe} + +\item{...}{ignored} } \description{ Mean Absolute Error diff --git a/modules/benchmark/man/metric_MSE.Rd b/modules/benchmark/man/metric_MSE.Rd index 2c2ad1600e2..aea5795eeb6 100644 --- a/modules/benchmark/man/metric_MSE.Rd +++ b/modules/benchmark/man/metric_MSE.Rd @@ -8,6 +8,8 @@ metric_MSE(dat, ...) } \arguments{ \item{dat}{dataframe} + +\item{...}{ignored} } \description{ Mean Square Error diff --git a/modules/benchmark/man/metric_PPMC.Rd b/modules/benchmark/man/metric_PPMC.Rd index 413340bcd5c..31c6a43abf4 100644 --- a/modules/benchmark/man/metric_PPMC.Rd +++ b/modules/benchmark/man/metric_PPMC.Rd @@ -8,6 +8,8 @@ metric_PPMC(metric_dat, ...) } \arguments{ \item{metric_dat}{dataframe} + +\item{...}{ignored} } \description{ Pearson Product Moment Correlation diff --git a/modules/benchmark/man/metric_R2.Rd b/modules/benchmark/man/metric_R2.Rd index cd047b5183a..65b1feb7fea 100644 --- a/modules/benchmark/man/metric_R2.Rd +++ b/modules/benchmark/man/metric_R2.Rd @@ -8,6 +8,8 @@ metric_R2(metric_dat, ...) } \arguments{ \item{metric_dat}{dataframe} + +\item{...}{ignored} } \description{ Coefficient of Determination (R2) diff --git a/modules/benchmark/man/metric_RAE.Rd b/modules/benchmark/man/metric_RAE.Rd index 69195ce87c6..a062ff76839 100644 --- a/modules/benchmark/man/metric_RAE.Rd +++ b/modules/benchmark/man/metric_RAE.Rd @@ -8,6 +8,8 @@ metric_RAE(metric_dat, ...) } \arguments{ \item{metric_dat}{dataframe} + +\item{...}{ignored} } \description{ Relative Absolute Error diff --git a/modules/benchmark/man/metric_RMSE.Rd b/modules/benchmark/man/metric_RMSE.Rd index e6b0b608aee..0335f86187e 100644 --- a/modules/benchmark/man/metric_RMSE.Rd +++ b/modules/benchmark/man/metric_RMSE.Rd @@ -8,6 +8,8 @@ metric_RMSE(dat, ...) } \arguments{ \item{dat}{dataframe} + +\item{...}{ignored} } \description{ Root Mean Square Error diff --git a/modules/benchmark/man/metric_cor.Rd b/modules/benchmark/man/metric_cor.Rd index b2ea61b01d0..a8e84fd9743 100644 --- a/modules/benchmark/man/metric_cor.Rd +++ b/modules/benchmark/man/metric_cor.Rd @@ -8,6 +8,8 @@ metric_cor(dat, ...) } \arguments{ \item{dat}{dataframe} + +\item{...}{ignored} } \description{ Correlation Coefficient diff --git a/modules/benchmark/man/metric_lmDiag_plot.Rd b/modules/benchmark/man/metric_lmDiag_plot.Rd index 56628c76ad2..a73af4e12af 100644 --- a/modules/benchmark/man/metric_lmDiag_plot.Rd +++ b/modules/benchmark/man/metric_lmDiag_plot.Rd @@ -8,6 +8,12 @@ metric_lmDiag_plot(metric_dat, var, filename = NA, draw.plot = FALSE) } \arguments{ \item{metric_dat}{data.frame} + +\item{var}{ignored} + +\item{filename}{path to save plot, or NA to not save} + +\item{draw.plot}{logical: return plot object?} } \description{ Linear Regression Diagnostic Plot diff --git a/modules/benchmark/man/metric_residual_plot.Rd b/modules/benchmark/man/metric_residual_plot.Rd index 9583f352ab7..ff80b0c547d 100644 --- a/modules/benchmark/man/metric_residual_plot.Rd +++ b/modules/benchmark/man/metric_residual_plot.Rd @@ -12,7 +12,13 @@ metric_residual_plot( ) } \arguments{ -\item{draw.plot}{} +\item{metric_dat}{dataframe to plot, with at least columns `time`, `model`, `obvs`} + +\item{var}{variable name, used as plot title} + +\item{filename}{path to save plot, or NA to not save} + +\item{draw.plot}{logical: Return the plot object?} } \description{ Residual Plot diff --git a/modules/benchmark/man/metric_scatter_plot.Rd b/modules/benchmark/man/metric_scatter_plot.Rd index 46f8a6d22f0..93da2a3db5e 100644 --- a/modules/benchmark/man/metric_scatter_plot.Rd +++ b/modules/benchmark/man/metric_scatter_plot.Rd @@ -12,7 +12,13 @@ metric_scatter_plot( ) } \arguments{ -\item{draw.plot}{} +\item{metric_dat}{dataframe to plot, with at least columns `model` and `obvs`} + +\item{var}{ignored} + +\item{filename}{path to save plot, or NA to not save} + +\item{draw.plot}{logical: Return the plot object?} } \description{ Scatter Plot diff --git a/modules/benchmark/man/metric_timeseries_plot.Rd b/modules/benchmark/man/metric_timeseries_plot.Rd index 89b647ff561..e5a7b1d9604 100644 --- a/modules/benchmark/man/metric_timeseries_plot.Rd +++ b/modules/benchmark/man/metric_timeseries_plot.Rd @@ -11,6 +11,15 @@ metric_timeseries_plot( draw.plot = is.na(filename) ) } +\arguments{ +\item{metric_dat}{dataframe to plot, with at least columns `time`, `model`, `obvs`} + +\item{var}{variable name, used as plot title} + +\item{filename}{path to save plot, or NA to not save} + +\item{draw.plot}{logical: Return the plot object?} +} \description{ Timeseries Plot } diff --git a/modules/benchmark/tests/Rcheck_reference.log b/modules/benchmark/tests/Rcheck_reference.log index 3675e758938..825ed0601a0 100644 --- a/modules/benchmark/tests/Rcheck_reference.log +++ b/modules/benchmark/tests/Rcheck_reference.log @@ -1,5 +1,5 @@ -* using log directory ‘/home/tanishq010/pecan/modules/PEcAn.benchmark.Rcheck’ -* using R version 4.2.1 (2022-06-23) +* using log directory ‘/tmp/Rtmps3SFpV/PEcAn.benchmark.Rcheck’ +* using R version 4.1.3 (2022-03-10) * using platform: x86_64-pc-linux-gnu (64-bit) * using session charset: UTF-8 * using options ‘--no-manual --as-cran’ @@ -7,49 +7,6 @@ * checking extension type ... Package * this is package ‘PEcAn.benchmark’ version ‘1.7.2’ * package encoding: UTF-8 -* checking CRAN incoming feasibility ... WARNING -Maintainer: ‘Mike Dietze ’ - -New submission - -License components with restrictions and base license permitting such: - BSD_3_clause + file LICENSE -File 'LICENSE': - University of Illinois/NCSA Open Source License - - Copyright (c) 2012, University of Illinois, NCSA. All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal with the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimers. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - Neither the names of University of Illinois, NCSA, nor the names - of its contributors may be used to endorse or promote products - derived from this Software without specific prior written permission. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR - ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. - -Strong dependencies not in mainstream repositories: - PEcAn.DB, PEcAn.logger, PEcAn.remote, PEcAn.settings, PEcAn.utils -Suggests or Enhances not in mainstream repositories: - PEcAn.data.land - -The Date field is over a month old. * checking package namespace information ... OK * checking package dependencies ... OK * checking if this is a source package ... OK @@ -63,11 +20,7 @@ The Date field is over a month old. * checking installed package size ... OK * checking package directory ... OK * checking for future file timestamps ... OK -* checking DESCRIPTION meta-information ... NOTE -Author field differs from that derived from Authors@R - Author: ‘Michael Dietze, David LeBauer, Rob Kooper, Toni Viskari’ - Authors@R: ‘Mike Dietze [aut, cre], David LeBauer [aut], Rob Kooper [aut], Toni Viskari [aut], University of Illinois, NCSA [cph]’ - +* checking DESCRIPTION meta-information ... OK * checking top-level files ... OK * checking for left-over files ... OK * checking index information ... OK @@ -80,117 +33,20 @@ Author field differs from that derived from Authors@R * checking whether the namespace can be loaded with stated dependencies ... OK * checking whether the namespace can be unloaded cleanly ... OK * checking loading without being on the library search path ... OK -* checking use of S3 registration ... OK -* checking dependencies in R code ... NOTE -Namespaces in Imports field not imported from: - ‘PEcAn.remote’ ‘XML’ ‘dbplyr’ - All declared Imports should be used. +* checking dependencies in R code ... OK * checking S3 generic/method consistency ... OK * checking replacement functions ... OK * checking foreign function calls ... OK * checking R code for possible problems ... NOTE -Warning: : ... may be used in an incorrect context: ‘Set_Bench(...)’ - -Warning: : ... may be used in an incorrect context: ‘Compare_Bench(...)’ - -add_workflow_info: no visible global function definition for - ‘is.MultiSettings’ -add_workflow_info: no visible global function definition for ‘papply’ add_workflow_info: no visible binding for global variable ‘add_workflow_id’ add_workflow_info: no visible binding for global variable ‘.’ -align_data: possible error in round(obvs.calc$posix, units = - coarse.unit): unused argument (units = coarse.unit) -align_data: possible error in round(model.calc$posix, units = - coarse.unit): unused argument (units = coarse.unit) align_data: no visible binding for global variable ‘.’ -align_data: no visible global function definition for ‘one_of’ -bm_settings2pecan_settings: no visible global function definition for - ‘is.MultiSettings’ -bm_settings2pecan_settings: no visible global function definition for - ‘papply’ -calc_benchmark: no visible binding for global variable ‘.’ -calc_benchmark: no visible binding for global variable ‘id’ -create_BRR: no visible binding for global variable ‘.’ -create_BRR: no visible binding for global variable ‘id’ -define_benchmark: no visible global function definition for - ‘is.MultiSettings’ -define_benchmark: no visible global function definition for ‘papply’ -define_benchmark: no visible binding for global variable ‘id’ -define_benchmark: no visible binding for global variable ‘ensemble_id’ -define_benchmark: no visible global function definition for ‘left_join’ -define_benchmark: no visible binding for global variable ‘.’ -define_benchmark: no visible global function definition for - ‘logger.error’ -define_benchmark: no visible global function definition for - ‘logger.debug’ -define_benchmark: no visible global function definition for ‘pull’ -define_benchmark: no visible binding for global variable ‘input_id’ -define_benchmark: no visible binding for global variable ‘variable_id’ -define_benchmark: no visible global function definition for ‘db.query’ -define_benchmark: no visible binding for global variable ‘benchmark_id’ -define_benchmark: no visible binding for global variable - ‘reference_run_id’ -define_benchmark: no visible binding for global variable ‘metric_id’ -get_species_list_standard: no visible binding for global variable - ‘custom_table’ -get_species_list_standard: no visible global function definition for - ‘logger.warn’ -load_csv: no visible global function definition for ‘read.csv’ -load_csv: no visible binding for global variable ‘header’ -load_csv: no visible global function definition for ‘one_of’ load_data: no visible binding for global variable ‘username’ load_data: no visible binding for global variable ‘password’ load_data: no visible binding for global variable ‘output_path’ -load_data: no visible binding for global variable ‘.’ -load_data: no visible binding for global variable ‘year’ -load_rds: no visible global function definition for ‘one_of’ -load_tab_separated_values: no visible global function definition for - ‘read.table’ -load_tab_separated_values: no visible binding for global variable - ‘header’ -load_tab_separated_values: no visible global function definition for - ‘one_of’ -match_timestep: no visible global function definition for ‘head’ -metric_Frechet: no visible global function definition for ‘logger.info’ -metric_Frechet: no visible global function definition for ‘na.omit’ -metric_PPMC: no visible global function definition for ‘cor’ -metric_R2: no visible global function definition for ‘lm’ -metric_RAE: no visible global function definition for ‘na.omit’ -metric_cor: no visible global function definition for ‘cor’ -metric_lmDiag_plot: no visible global function definition for ‘lm’ -metric_lmDiag_plot: no visible global function definition for ‘aes’ -metric_lmDiag_plot: no visible binding for global variable ‘.fitted’ -metric_lmDiag_plot: no visible binding for global variable ‘.resid’ -metric_lmDiag_plot: no visible global function definition for ‘qqnorm’ -metric_lmDiag_plot: no visible binding for global variable ‘.stdresid’ -metric_lmDiag_plot: no visible global function definition for ‘qqline’ -metric_lmDiag_plot: no visible binding for global variable ‘.cooksd’ -metric_lmDiag_plot: no visible binding for global variable ‘.hat’ -metric_lmDiag_plot: no visible global function definition for ‘pdf’ -metric_lmDiag_plot: no visible global function definition for ‘dev.off’ -metric_residual_plot: no visible binding for global variable ‘time’ -metric_residual_plot: no visible global function definition for ‘aes’ -metric_residual_plot: no visible binding for global variable ‘zeros’ -metric_residual_plot: no visible global function definition for ‘pdf’ -metric_residual_plot: no visible global function definition for - ‘dev.off’ -metric_scatter_plot: no visible global function definition for ‘aes’ -metric_scatter_plot: no visible binding for global variable ‘model’ -metric_scatter_plot: no visible binding for global variable ‘obvs’ -metric_scatter_plot: no visible global function definition for ‘pdf’ -metric_scatter_plot: no visible global function definition for - ‘dev.off’ -metric_timeseries_plot: no visible global function definition for ‘aes’ -metric_timeseries_plot: no visible binding for global variable ‘time’ -metric_timeseries_plot: no visible binding for global variable ‘model’ -metric_timeseries_plot: no visible binding for global variable ‘obvs’ -metric_timeseries_plot: no visible global function definition for ‘pdf’ -metric_timeseries_plot: no visible global function definition for - ‘dev.off’ pecan_bench: no visible global function definition for ‘validation_check’ -pecan_bench: no visible global function definition for ‘read.table’ pecan_bench: no visible global function definition for ‘size’ pecan_bench: no visible binding for global variable ‘comp_value’ pecan_bench: no visible binding for global variable @@ -198,169 +54,24 @@ pecan_bench: no visible binding for global variable pecan_bench: no visible binding for global variable ‘ratio_dif_uncertainty’ pecan_bench: no visible binding for global variable ‘ratio_dif’ -pecan_bench: no visible global function definition for ‘Set_Bench’ -pecan_bench: ... may be used in an incorrect context: ‘Set_Bench(...)’ -pecan_bench: no visible global function definition for ‘Compare_Bench’ -pecan_bench: ... may be used in an incorrect context: - ‘Compare_Bench(...)’ -read_settings_BRR: no visible global function definition for ‘pull’ -read_settings_BRR: no visible global function definition for - ‘xmlToList’ -read_settings_BRR: no visible binding for global variable ‘.’ Undefined global functions or variables: - . .cooksd .fitted .hat .resid .stdresid Compare_Bench Set_Bench - add_workflow_id aes benchmark_id comp_dif_uncertainty comp_value cor - custom_table db.query dev.off ensemble_id head header id input_id - is.MultiSettings left_join lm logger.debug logger.error logger.info - logger.warn metric_id model na.omit obvs one_of output_path papply - password pdf pull qqline qqnorm ratio_dif ratio_dif_uncertainty - read.csv read.table reference_run_id size time username - validation_check variable_id xmlToList year zeros -Consider adding - importFrom("grDevices", "dev.off", "pdf") - importFrom("stats", "cor", "lm", "na.omit", "qqline", "qqnorm", "time") - importFrom("utils", "head", "read.csv", "read.table") -to your NAMESPACE file. - -Warning: : ... may be used in an incorrect context: ‘Set_Bench(...)’ - -Warning: : ... may be used in an incorrect context: ‘Compare_Bench(...)’ - + . add_workflow_id comp_dif_uncertainty comp_value output_path + password ratio_dif ratio_dif_uncertainty size username + validation_check * checking Rd files ... OK * checking Rd metadata ... OK -* checking Rd line widths ... NOTE -Rd file 'align_by_first_observation.Rd': - \examples lines wider than 100 characters: - aligned<-align_by_first_observation(observation_one = observation_one, observation_two = observation_two, - -These lines will be truncated in the PDF manual. +* checking Rd line widths ... OK * checking Rd cross-references ... OK * checking for missing documentation entries ... OK * checking for code/documentation mismatches ... OK -* checking Rd \usage sections ... WARNING -Undocumented arguments in documentation object 'align_data' - ‘align_method’ - -Undocumented arguments in documentation object 'align_pft' - ‘comparison_type’ ‘...’ - -Undocumented arguments in documentation object 'calc_benchmark' - ‘settings’ ‘start_year’ ‘end_year’ -Documented arguments not in \usage in documentation object 'calc_benchmark': - ‘bm.ensemble’ - -Undocumented arguments in documentation object 'check_if_legal_table' - ‘table’ -Documented arguments not in \usage in documentation object 'check_if_legal_table': - ‘custom_table’ - -Undocumented arguments in documentation object 'check_if_list_of_pfts' - ‘vars’ -Documented arguments not in \usage in documentation object 'check_if_list_of_pfts': - ‘observation_one’ ‘observation_two’ ‘custom_table’ - -Undocumented arguments in documentation object 'check_if_species_list' - ‘vars’ -Documented arguments not in \usage in documentation object 'check_if_species_list': - ‘observation_one’ ‘observation_two’ - -Undocumented arguments in documentation object 'create_BRR' - ‘user_id’ - -Undocumented arguments in documentation object 'define_benchmark' - ‘settings’ ‘bety’ -Documented arguments not in \usage in documentation object 'define_benchmark': - ‘bm.settings’ - -Undocumented arguments in documentation object 'format_wide2long' - ‘time.row’ - -Undocumented arguments in documentation object 'get_species_list_standard' - ‘vars’ -Documented arguments not in \usage in documentation object 'get_species_list_standard': - ‘observation_one’ ‘observation_two’ ‘custom_table’ - -Undocumented arguments in documentation object 'load_csv' - ‘vars’ -Documented arguments not in \usage in documentation object 'load_csv': - ‘start_year’ ‘end_year’ - -Undocumented arguments in documentation object 'load_data' - ‘vars.used.index’ ‘...’ - -Undocumented arguments in documentation object 'load_tab_separated_values' - ‘vars’ -Documented arguments not in \usage in documentation object 'load_tab_separated_values': - ‘start_year’ ‘end_year’ - -Documented arguments not in \usage in documentation object 'load_x_netcdf': - ‘start_year’ ‘end_year’ - -Undocumented arguments in documentation object 'metric_AME' - ‘...’ - -Undocumented arguments in documentation object 'metric_Frechet' - ‘...’ - -Undocumented arguments in documentation object 'metric_MAE' - ‘...’ - -Undocumented arguments in documentation object 'metric_MSE' - ‘...’ - -Undocumented arguments in documentation object 'metric_PPMC' - ‘...’ - -Undocumented arguments in documentation object 'metric_R2' - ‘...’ - -Undocumented arguments in documentation object 'metric_RAE' - ‘...’ - -Undocumented arguments in documentation object 'metric_RMSE' - ‘...’ - -Undocumented arguments in documentation object 'metric_cor' - ‘...’ - -Undocumented arguments in documentation object 'metric_lmDiag_plot' - ‘var’ ‘filename’ ‘draw.plot’ - -Undocumented arguments in documentation object 'metric_residual_plot' - ‘metric_dat’ ‘var’ ‘filename’ - -Undocumented arguments in documentation object 'metric_scatter_plot' - ‘metric_dat’ ‘var’ ‘filename’ - -Undocumented arguments in documentation object 'metric_timeseries_plot' - ‘metric_dat’ ‘var’ ‘filename’ ‘draw.plot’ - -Functions with \usage entries need to have the appropriate \alias -entries, and all their arguments documented. -The \usage entries must correspond to syntactically valid R code. -See chapter ‘Writing R documentation files’ in the ‘Writing R -Extensions’ manual. -* checking Rd contents ... WARNING -Argument items with no description in Rd object 'format_wide2long': - ‘vars_used’ - -Argument items with no description in Rd object 'load_rds': - ‘vars’ - -Argument items with no description in Rd object 'metric_residual_plot': - ‘draw.plot’ - -Argument items with no description in Rd object 'metric_scatter_plot': - ‘draw.plot’ - +* checking Rd \usage sections ... OK +* checking Rd contents ... OK * checking for unstated dependencies in examples ... OK * checking examples ... OK * checking for unstated dependencies in ‘tests’ ... OK -* checking tests ... +* checking tests ... OK Running ‘testthat.R’ - OK * checking for non-standard things in the check directory ... OK * checking for detritus in the temp directory ... OK * DONE - -Status: 3 WARNINGs, 4 NOTEs +Status: 1 NOTE diff --git a/modules/data.atmosphere/R/temporal.downscaling.R b/modules/data.atmosphere/R/temporal.downscaling.R index 76600f91420..4032fe61135 100644 --- a/modules/data.atmosphere/R/temporal.downscaling.R +++ b/modules/data.atmosphere/R/temporal.downscaling.R @@ -120,7 +120,7 @@ cfmet.downscale.subdaily <- function(subdailymet, output.dt = 1) { cfmet.downscale.daily <- function(dailymet, output.dt = 1, lat) { tint <- 24/output.dt - tseq <- 0:(23 * output.dt)/output.dt + tseq <- seq(from = 0, to = 23, by = output.dt) data.table::setkeyv(dailymet, c("year", "doy")) diff --git a/modules/data.atmosphere/tests/testthat/test.cf-downscaling.R b/modules/data.atmosphere/tests/testthat/test.cf-downscaling.R index 2d3d34be2f7..2b514f84b6a 100644 --- a/modules/data.atmosphere/tests/testthat/test.cf-downscaling.R +++ b/modules/data.atmosphere/tests/testthat/test.cf-downscaling.R @@ -21,6 +21,32 @@ test_that( expect_equal(b[,signif(range(wind), 2)], c(0.066, 6.60)) }) +test_that("downscaling with timestep", { + df <- data.table::data.table( + year = 2020, doy = 100, + air_temperature_min = 293.15, air_temperature_max = 303.15, air_temperature = 298.15, + surface_downwelling_shortwave_flux_in_air = 1000, + air_pressure = 1030, + wind_speed = 0, + relative_humidity = 0.5, + precipitation_flux = 2 / (60 * 60)) # units: mm/sec + + r1 <- cfmet.downscale.daily(df, output.dt = 1, lat = 40) + r6 <- cfmet.downscale.daily(df, output.dt = 6, lat = 40) + r12 <- cfmet.downscale.daily(df, output.dt = 12, lat = 40) + + expect_equal(nrow(r1), 24) + expect_equal(nrow(r6), 4) + expect_equal(nrow(r12), 2) + + list(r1, r6,r12) %>% + purrr::walk(~{ + expect_equal(mean(.$air_temperature), (df$air_temperature - 273.15)) # input is K, output is C + expect_equal(sum(.$precipitation_flux), df$precipitation_flux) + expect_true(all(.$air_pressure == df$air_pressure)) + }) + +}) test_that("get.ncvector works",{ run.dates <- data.table::data.table(index = 1:2, date = c(lubridate::ymd("1951-01-01 UTC"), lubridate::ymd("1951-01-02 UTC"))) diff --git a/web/workflow.R b/web/workflow.R index 1fab4b6062a..ea5ae7d9510 100755 --- a/web/workflow.R +++ b/web/workflow.R @@ -31,6 +31,10 @@ options(error = quote({ # ---------------------------------------------------------------------- # PEcAn Workflow # ---------------------------------------------------------------------- + +# Report package versions for provenance +PEcAn.all::pecan_version() + # Open and read in settings file for PEcAn run. settings <- PEcAn.settings::read.settings(args$settings)