From 33d7f71dae4cb8e2d0cb771fb2e3aa5c3a911b9b Mon Sep 17 00:00:00 2001 From: Andrew Gene Brown Date: Sat, 28 Feb 2026 19:36:36 -0800 Subject: [PATCH 1/2] feat!: updates for rosetta-soil 0.3 wip: nboot patch perf: vectorize NNModel.predict docs: add vignette docs: properties fixup: standardize on rosetta-soil 0.3.1 no nboot fix arith --- .Rbuildignore | 2 + .gitignore | 3 + DESCRIPTION | 8 +- NAMESPACE | 5 + NEWS.md | 11 + R/AAAA.R | 1 - R/Class-Rosetta.R | 81 +++++- R/rosesoil.R | 58 ++++ R/rosetta_utils.R | 20 +- R/run_rosetta.R | 102 ++++--- README.Rmd | 102 +++++-- README.md | 337 ++++++++++++---------- man/SoilDataFromArray.Rd | 2 +- man/UnsaturatedK.Rd | 14 + man/figures/README-chunk-10-1.png | Bin 0 -> 23482 bytes man/figures/README-chunk-11-1.png | Bin 0 -> 23393 bytes man/figures/README-unnamed-chunk-10-1.png | Bin 9993 -> 25186 bytes man/figures/README-unnamed-chunk-11-1.png | Bin 9965 -> 25186 bytes man/figures/README-unnamed-chunk-12-1.png | Bin 0 -> 25117 bytes man/predict.Rosetta.Rd | 6 + man/predict.UnsaturatedK.Rd | 21 ++ man/rosesoil.Rd | 23 ++ man/rosettaPTF-package.Rd | 2 +- man/rosetta_pkg_version.Rd | 15 + man/run_rosetta.Rd | 45 ++- tests/testthat/test-predict-Rosetta.R | 15 +- tests/testthat/test-rosesoil.R | 21 ++ tests/testthat/test-rosetta.R | 56 +++- vignettes/performance-raster.Rmd | 155 ++++++++++ 29 files changed, 854 insertions(+), 251 deletions(-) create mode 100644 R/rosesoil.R create mode 100644 man/UnsaturatedK.Rd create mode 100644 man/figures/README-chunk-10-1.png create mode 100644 man/figures/README-chunk-11-1.png create mode 100644 man/figures/README-unnamed-chunk-12-1.png create mode 100644 man/predict.UnsaturatedK.Rd create mode 100644 man/rosesoil.Rd create mode 100644 man/rosetta_pkg_version.Rd create mode 100644 tests/testthat/test-rosesoil.R create mode 100644 vignettes/performance-raster.Rmd diff --git a/.Rbuildignore b/.Rbuildignore index 739ce55..2697148 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -6,3 +6,5 @@ ^\.github$ ^data-raw$ ^README\.Rmd$ +^doc$ +^Meta$ diff --git a/.gitignore b/.gitignore index f6345fa..1acb996 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ .RData .Ruserdata ^rosettaPTF\.Rproj$ +README.html +/doc/ +/Meta/ diff --git a/DESCRIPTION b/DESCRIPTION index 811c6e4..5407b0f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,9 +1,9 @@ Package: rosettaPTF Title: R Frontend for Rosetta Pedotransfer Functions -Version: 0.1.5 +Version: 0.2.0 Author: Soil and Plant Science Division Staff Maintainer: Andrew G. Brown -Description: Access Python rosetta-soil pedotransfer functions in an R environment. Rosetta is a neural network-based model for predicting unsaturated soil hydraulic parameters from basic soil characterization data. The model predicts parameters for the van Genuchten unsaturated soil hydraulic properties model, using sand, silt, and clay, bulk density and water content. The codebase is now maintained by Dr. Todd Skaggs and other U.S. Department of Agriculture employees. This R package is intended to provide for use cases that involve many thousands of calls to the pedotransfer function. Less demanding use cases are encouraged to use the web interface or API endpoint. There are additional wrappers of the API endpoints provided by the soilDB R package `ROSETTA()` method. +Description: Access the rosetta-soil Python pedotransfer functions from R. Rosetta is a neural network-based model for predicting unsaturated soil hydraulic parameters from basic soil characterization data (sand, silt, clay, bulk density, and water content). Predictions are made for the van Genuchten unsaturated hydraulic properties model, with uncertainty quantification via bootstrap ensemble. Designed for efficient batch processing of large datasets through vectorized computation and optional parallel processing. Config/reticulate: list( packages = list( @@ -15,7 +15,7 @@ License: GPL (>= 2) Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.2 +RoxygenNote: 7.3.3 Depends: R (>= 3.5) URL: https://github.com/ncss-tech/rosettaPTF, https://ncss-tech.github.io/rosettaPTF/ BugReports: https://github.com/ncss-tech/rosettaPTF/issues @@ -24,4 +24,6 @@ Imports: reticulate, terra Suggests: + litedown, testthat +VignetteBuilder: litedown diff --git a/NAMESPACE b/NAMESPACE index 4b14cd5..a85d8f9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,7 +1,9 @@ # Generated by roxygen2: do not edit by hand +S3method(ann_predict,Rosetta) S3method(ann_predict,default) S3method(predict,Rosetta) +S3method(predict,UnsaturatedK) S3method(py_to_r,rosetta.rosetta.SoilData) S3method(run_rosetta,RasterBrick) S3method(run_rosetta,RasterStack) @@ -11,10 +13,12 @@ S3method(run_rosetta,default) S3method(run_rosetta,matrix) export(Rosetta) export(SoilDataFromArray) +export(UnsaturatedK) export(ann_predict) export(find_python) export(get_rosetta_module) export(install_rosetta) +export(rosesoil) export(rosetta_module_available) export(run_rosetta) importFrom(parallel,makeCluster) @@ -32,6 +36,7 @@ importFrom(reticulate,r_to_py) importFrom(reticulate,use_condaenv) importFrom(reticulate,use_python) importFrom(stats,na.omit) +importFrom(stats,predict) importFrom(terra,`nlyr<-`) importFrom(terra,rast) importFrom(terra,readStart) diff --git a/NEWS.md b/NEWS.md index e143a61..078d09a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,14 @@ +# rosettaPTF 0.2.0 + +* Compatible with `rosetta-soil` Python package v0.3 + * Updated `run_rosetta()` and `predict.Rosetta()` to handle the 7-parameter output (adding `K0` and `L`) introduced in `rosetta-soil` v0.3. + * Added `estimate_type` argument to `run_rosetta()` to support linear, logarithmic (default), and geometric parameter estimations. Improved documentation and added examples for the geometric scale. + * Added `UnsaturatedK()` R constructor and `predict.UnsaturatedK()` method for predicting `K0` and `L` from retention parameters (requires `rosetta-soil` >= 0.3). + * Added `rosesoil()` R wrapper for the new upstream `rosesoil()` function (requires `rosetta-soil` >= 0.3). + * Deprecated `SoilDataFromArray()` in favor of direct list input (supported in `rosetta-soil` >= 0.3. + * Deprecated `ann_predict()` as the underlying Python method has been removed in v0.3. It now redirects to `predict()`. +* Added a new vignette: **"Performance Optimization and Raster Processing"** covering best practices for high-throughput workflows. + # rosettaPTF 0.1.5 * Fix check logic for whether input SpatRaster is in memory diff --git a/R/AAAA.R b/R/AAAA.R index 07fc060..82353cb 100644 --- a/R/AAAA.R +++ b/R/AAAA.R @@ -31,7 +31,6 @@ numpy_module <- NULL } !is.null(rosetta_module) && !is.null(numpy_module) - } #' @importFrom reticulate configure_environment diff --git a/R/Class-Rosetta.R b/R/Class-Rosetta.R index 5cf54c3..83a5846 100644 --- a/R/Class-Rosetta.R +++ b/R/Class-Rosetta.R @@ -16,7 +16,7 @@ #' @rdname Rosetta-class #' @export Rosetta <- function(rosetta_version = 3, model_code = 3) { - object <- rosetta_module$Rosetta(rosetta_version, model_code) + object <- rosetta_module$Rosetta(as.integer(rosetta_version), as.integer(model_code)) structure(list(object = object), class = "Rosetta") } @@ -24,14 +24,38 @@ Rosetta <- function(rosetta_version = 3, model_code = 3) { #' @param object _Rosetta_ object containing class instance (e.g. from `Rosetta()`) #' @param soildata A list containing vectors; with number of parameters matching the model type of `object` #' @param ... not used +#' @return A list containing `mean` and `stdev` matrices (one row per sample). +#' +#' For `rosetta-soil` >= 0.3, the columns are: `theta_r`, `theta_s`, `alpha`, `npar`, `ksat`. +#' Note that these parameters are in the scale produced by the underlying model (often log10 for alpha, npar, and ksat). #' @importFrom reticulate r_to_py import #' @method predict Rosetta #' @export #' @examples #' # predict(Rosetta(), list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) predict.Rosetta <- function(object, soildata, ...) { - object$object$predict(numpy_module$array(reticulate::r_to_py(soildata), - dtype = "float")) + if (rosetta_pkg_version() >= package_version("0.3.0")) { + res <- object$object$predict(numpy_module$array(reticulate::r_to_py(soildata), + dtype = "float")) + retc_boot <- res[[1]] + ksat_boot <- res[[2]] + + retc_mean <- numpy_module$mean(retc_boot, axis = 0L) + retc_std <- numpy_module$std(retc_boot, axis = 0L) + ksat_mean <- numpy_module$mean(ksat_boot, axis = 0L) + ksat_std <- numpy_module$std(ksat_boot, axis = 0L) + + mean_val <- numpy_module$concatenate(list(retc_mean, ksat_mean), axis = 1L) + std_val <- numpy_module$concatenate(list(retc_std, ksat_std), axis = 1L) + + return(list(mean = mean_val, stdev = std_val)) + + } else { + res <- object$object$predict(numpy_module$array(reticulate::r_to_py(soildata), + dtype = "float")) + names(res) <- c("mean", "stdev") + return(res) + } } #' Extended _Rosetta_ Predictions, Parameter Distributions and Summary Statistics after Zhang & Schaap (2017) @@ -47,16 +71,65 @@ ann_predict <- function(object, soildata, sum_data = TRUE) #' @rdname ann_predict #' @export ann_predict.default <- function(object, soildata, sum_data = TRUE) { - message("ann_predict() is defined for objects with class Rosetta; see `Rosetta()` to create a new instance") + if (rosetta_pkg_version() >= package_version("0.3.0")) { + .Deprecated("predict", msg = "ann_predict() is deprecated in rosetta-soil >= 0.3.0. Use predict() instead.") + } else { + message("ann_predict() is defined for objects with class Rosetta; see `Rosetta()` to create a new instance") + } ann_predict.Rosetta(object = object, soildata = soildata, sum_data = sum_data) } #' @rdname ann_predict #' @method ann_predict Rosetta +#' @export +#' @importFrom stats predict #' @examples #' # ann_predict(Rosetta(), list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) ann_predict.Rosetta <- function(object, soildata, sum_data = TRUE) { + if (rosetta_pkg_version() >= package_version("0.3.0")) { + .Deprecated("predict", msg = "ann_predict() is deprecated in rosetta-soil >= 0.3.0. Use predict() instead.") + return(predict(object, soildata)) + } object$object$ann_predict(numpy_module$array(reticulate::r_to_py(soildata), dtype = "float"), sum_data = sum_data) } + +#' Make an UnsaturatedK object instance +#' +#' @description `UnsaturatedK`: Create an instance of the `UnsaturatedK` class from `rosetta-soil` >= 0.3. This class is used to predict `K0` and `L` from retention parameters. +#' +#' @return an instance of the `UnsaturatedK` class. +#' @export +UnsaturatedK <- function() { + if (rosetta_pkg_version() < package_version("0.3.0")) { + stop("UnsaturatedK requires rosetta-soil >= 0.3.0", call. = FALSE) + } + + object <- rosetta_module$UnsaturatedK() + structure(list(object = object), class = "UnsaturatedK") +} + +#' Predict K0 and L from retention parameters +#' +#' @param object _UnsaturatedK_ object +#' @param retc_params A list or matrix of retention parameters (theta_r, theta_s, alpha, npar) +#' @param ... not used +#' @return a `data.frame` with `log10_K0_mean`, `lpar_mean`, `log10_K0_sd`, `lpar_sd` +#' @method predict UnsaturatedK +#' @export +predict.UnsaturatedK <- function(object, retc_params, ...) { + res <- object$object$predict(numpy_module$array(reticulate::r_to_py(retc_params), + dtype = "float")) + + k0l_mean <- numpy_module$mean(res, axis = 0L) + k0l_std <- numpy_module$std(res, axis = 0L) + + df <- data.frame( + log10_K0_mean = k0l_mean[, 1], + lpar_mean = k0l_mean[, 2], + log10_K0_sd = k0l_std[, 1], + lpar_sd = k0l_std[, 2] + ) + return(df) +} diff --git a/R/rosesoil.R b/R/rosesoil.R new file mode 100644 index 0000000..5094e88 --- /dev/null +++ b/R/rosesoil.R @@ -0,0 +1,58 @@ +#' Run rosesoil() from rosetta-soil >= 0.3.0 +#' +#' @param soildata A list of numeric vectors or a data.frame (3-6 columns: sand, silt, clay, optionally bulk density, th33, and th1500) +#' @param rosetta_version integer, 1-3. Default: 3 +#' @param estimate_type _character_. One of `"arith"` (default), `"log"`, or `"geo"`. Only used if `rosetta-soil` >= 0.3.1. `"log"` returns parameters on a logarithmic (log10) scale for `alpha`, `npar`, `ksat`, and `k0`. `"geo"` returns the geometric mean of bootstrap estimates (exponent of the mean of log-transformed values). This is often preferred for parameters that vary by orders of magnitude, such as `alpha` and `ksat`. +#' @param vars optional column name mapping (same as run_rosetta) +#' @return a data.frame with all RosettaResult fields +#' @export +rosesoil <- function(soildata, rosetta_version = 3, estimate_type = "arith", vars = NULL) { + if (rosetta_pkg_version() < package_version("0.3.0")) { + stop("rosesoil() requires rosetta-soil >= 0.3.0. Please run install_rosetta(upgrade = TRUE).") + } + + if (inherits(soildata, "data.frame")) { + if (!is.null(vars)) { + if (!all(vars %in% colnames(soildata))) { + stop("all custom parameter names in `vars` must be present in `soildata`", + call. = FALSE) + } else { + soildata <- soildata[, vars[seq_along(colnames(soildata))]] + } + } + + nid <- nrow(soildata) + soildatatemplate <- data.frame( + sand = numeric(nid), + silt = numeric(nid), + clay = numeric(nid), + bulkdensity = numeric(nid), + th33 = numeric(nid), + th1500 = numeric(nid) + ) + soildatatemplate[] <- NA_real_ + soildatatemplate[, 1:ncol(soildata)] <- soildata + soildata_list <- unlist(apply(soildatatemplate, 1, + function(x) + list(as.numeric( + stats::na.omit(as.numeric(x)) + ))), + recursive = FALSE) + } else { + soildata_list <- soildata + } + + res_obj <- rosetta_module$rosesoil(as.integer(rosetta_version), + soildata_list, + estimate_type = estimate_type) + + res_dicts <- res_obj$asdicts() + + # handle NULL values in dicts (convert to NA) + res_df <- do.call(rbind, lapply(res_dicts, function(d) { + d[sapply(d, is.null)] <- NA_real_ + as.data.frame(d) + })) + + return(res_df) +} diff --git a/R/rosetta_utils.R b/R/rosetta_utils.R index 3f5900d..9792e20 100644 --- a/R/rosetta_utils.R +++ b/R/rosetta_utils.R @@ -2,12 +2,16 @@ #' Convert list of numeric vectors to _SoilData_ Python object #' -#' @description `SoilDataFromArray`: convert a list of numeric vectors containing soil properties to a `rosetta.rosetta.SoilData` class +#' @description `SoilDataFromArray`: convert a list of numeric vectors containing soil properties to a `rosetta.rosetta.SoilData` class. In `rosetta-soil` >= 0.3, direct list input is preferred. #' #' @param x a list of numeric vectors #' @return an object reference to a Rosetta _SoilData_ Python object constructed from `x` #' @export SoilDataFromArray <- function(x) { + if (rosetta_pkg_version() >= package_version("0.3.0")) { + .Deprecated(msg = "Direct list input is now supported by rosetta-soil >= 0.3.0. SoilDataFromArray is deprecated.") + return(x) + } rosetta_module$SoilData$from_array(x) } @@ -20,6 +24,20 @@ py_to_r.rosetta.rosetta.SoilData <- function(x) { x } +#' Get rosetta-soil Python package version +#' @return `package_version` object +#' @keywords internal +rosetta_pkg_version <- function() { + if (rosetta_module_available()) { + v <- try(rosetta_module$`__version__`, silent = TRUE) + if (inherits(v, "try-error") || is.null(v)) { + return(package_version("0.1.0")) + } + return(package_version(v)) + } + package_version("0.0.0") +} + #' Check if Rosetta module is available for import from local Python environment #' @return _logical_ #' @export diff --git a/R/run_rosetta.R b/R/run_rosetta.R index 9ae541d..3c3e87b 100644 --- a/R/run_rosetta.R +++ b/R/run_rosetta.R @@ -3,40 +3,66 @@ #' @param soildata A list of numeric vectors each containing 3 to 6 values: `"sand"`, `"silt"`, `"clay"`, `"bulkdensity"`, `"th33"`, `"th1500"`, a _data.frame_ or _matrix_ with 3 to 6 columns OR a `Raster*`/`SpatRaster` object with 3 to 6 layers. Sand, silt, and clay must sum to a total of 100%. #' @param vars _character_. Optional: names and order of custom column names if `soildata` is a _data.frame_, _RasterStack_, _RasterBrick_ or _SpatRaster_. Default `NULL` assumes input column order follows `sand`, `silt`, `clay`, `bulkdensity`, `th33`, `th1500` and does not check names. #' @param rosetta_version Default: 3 +#' @param estimate_type _character_. One of `"log"` (default), `"arith"`, or `"geo"`. Only used if `rosetta-soil` >= 0.3.1. Default `"log"` preserves logarithmic (log10) scale for `alpha`, `npar`, and `Ksat`. `"geo"` returns the geometric mean of bootstrap estimates (exponent of the mean of log-transformed values). This is often preferred for parameters that vary by orders of magnitude, such as `alpha` and `Ksat`. #' @param ... additional arguments not used #' -#' @return A _data.frame_ containing `mean` and `stdev` for following five columns (parameters for van Genuchten-Mualem equation) +#' @return A _data.frame_ containing `mean` and `stdev` for the following columns (parameters for van Genuchten-Mualem equation) #' - `"theta_r"`, residual water content #' - `"theta_s"`, saturated water content -#' - `"log10(alpha)"`, 'alpha' shape parameter, log10(1/cm) -#' - `"log10(npar)"`, 'n' shape parameter -#' - `"log10(Ksat)"`, saturated hydraulic conductivity, log10(cm/day) +#' - `"alpha"`, 'alpha' shape parameter (1/cm). Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +#' - `"npar"`, 'n' shape parameter. Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +#' - `"Ksat"`, saturated hydraulic conductivity (cm/day). Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +#' - `"K0"`, unsaturated hydraulic conductivity (cm/day). Only if `rosetta-soil` >= 0.3.1. Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +#' - `"lpar"`, unsaturated hydraulic conductivity exponent. Only if `rosetta-soil` >= 0.3.1. #' #' If the sum of sand, silt, and clay is not 100%, the parameter value estimates will be `NaN`. #' +#' @details +#' ## Performance Note +#' +#' Use `cores > 1` with `SpatRaster` or `Raster*` inputs to parallelize processing of cells across multiple cores. +#' #' @aliases run_rosetta #' @rdname run_rosetta #' @export run_rosetta.default <- function(soildata, vars = NULL, - rosetta_version = 3, ...) { + rosetta_version = 3, + estimate_type = "log", ...) { if (is.numeric(soildata)) { soildata <- as.data.frame(t(soildata)) - run_rosetta.data.frame(soildata = soildata, vars = vars, rosetta_version = rosetta_version) + return(run_rosetta.data.frame(soildata = soildata, vars = vars, rosetta_version = rosetta_version, estimate_type = estimate_type)) } # identify records with enough data good.idx <- which(sapply(soildata, length) >= 3) - # run rosetta - res <- rosetta_module$rosetta(rosetta_version, SoilDataFromArray(soildata[good.idx])) + if (rosetta_pkg_version() >= package_version("0.3.1")) { + res <- rosetta_module$rosetta(as.integer(rosetta_version), + soildata[good.idx], + estimate_type = estimate_type) + } else { + res <- rosetta_module$rosetta(as.integer(rosetta_version), SoilDataFromArray(soildata[good.idx])) + } if (length(res) == 3) { names(res) <- c("mean","stdev","model_codes") - param_names <- c("theta_r", "theta_s", "log10_alpha", "log10_npar", "log10_Ksat") + + nc <- ncol(res[[1]]) + if (nc == 7) { + if (estimate_type == "log") { + param_names <- c("theta_r", "theta_s", "log10_alpha", "log10_npar", "log10_Ksat", "log10_K0", "lpar") + } else { + param_names <- c("theta_r", "theta_s", "alpha", "npar", "ksat", "k0", "lpar") + } + } else { + param_names <- c("theta_r", "theta_s", "log10_alpha", "log10_npar", "log10_Ksat") + } + res[[1]] <- as.data.frame(res[[1]]) colnames(res[[1]]) <- paste0(param_names, "_mean") + res[[2]] <- as.data.frame(res[[2]]) colnames(res[[2]]) <- paste0(param_names, "_sd") res <- data.frame(model_code = res[[3]], cbind(res[[1]], res[[2]])) @@ -56,6 +82,7 @@ run_rosetta.default <- function(soildata, run_rosetta <- function(soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", cores = 1, core_thresh = NULL, file = NULL, @@ -69,6 +96,7 @@ run_rosetta <- function(soildata, run_rosetta.data.frame <- function(soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", ...) { # soildata <- as.data.frame(soildata) @@ -101,13 +129,15 @@ run_rosetta.data.frame <- function(soildata, ) soildatatemplate[] <- NA_real_ soildatatemplate[, 1:ncol(soildata)] <- soildata - soildatain <- unlist(apply(soildatatemplate, 1, - function(x) - list(as.numeric( - na.omit(as.numeric(x)) - ))), - recursive = FALSE) - run_rosetta.default(soildatain, vars = vars, rosetta_version = rosetta_version) + + # Get number of non-NA columns per row + n_cols <- rowSums(!is.na(soildatatemplate)) + m <- as.matrix(soildatatemplate) + soildatain <- lapply(seq_len(nid), function(i) { + m[i, 1:n_cols[i]] + }) + + run_rosetta.default(soildatain, vars = vars, rosetta_version = rosetta_version, estimate_type = estimate_type) } #' @export @@ -115,8 +145,9 @@ run_rosetta.data.frame <- function(soildata, run_rosetta.matrix <- function(soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", ...) { - run_rosetta(as.data.frame(soildata), vars = vars, rosetta_version = 3) + run_rosetta(as.data.frame(soildata), vars = vars, rosetta_version = rosetta_version, estimate_type = estimate_type) } #' @export @@ -125,25 +156,17 @@ run_rosetta.matrix <- function(soildata, run_rosetta.RasterStack <- function(soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", cores = 1, core_thresh = 20000L, file = paste0(tempfile(), ".tif"), nrows = nrow(soildata) / (terra::ncell(soildata) / core_thresh), overwrite = TRUE) { - ## for in memory only, can just convert to data.frame and use that method - # res <- run_rosetta(raster::as.data.frame(soildata), - # vars = vars, - # rosetta_version = rosetta_version) - # resstackout <- soildata - # for(i in 1:ncol(res)) { - # resstackout[[i]] <- res[[i]] - # } - # names(resstackout) <- colnames(res) - # resstackout run_rosetta( terra::rast(soildata), vars = vars, rosetta_version = rosetta_version, + estimate_type = estimate_type, cores = cores, file = file, nrows = nrows, @@ -157,6 +180,7 @@ run_rosetta.RasterStack <- function(soildata, run_rosetta.RasterBrick <- function(soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", cores = 1, core_thresh = 20000L, file = paste0(tempfile(), ".tif"), @@ -165,6 +189,7 @@ run_rosetta.RasterBrick <- function(soildata, run_rosetta(terra::rast(soildata), vars = vars, rosetta_version = rosetta_version, + estimate_type = estimate_type, cores = cores, file = file, nrows = nrows, @@ -183,6 +208,7 @@ run_rosetta.RasterBrick <- function(soildata, run_rosetta.SpatRaster <- function(soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", cores = 1, core_thresh = 20000L, file = paste0(tempfile(), ".tif"), @@ -200,9 +226,11 @@ run_rosetta.SpatRaster <- function(soildata, # create template brick out <- terra::rast(soildata) - cnm <- c("id", "model_code", "theta_r_mean", "theta_s_mean", "log10_alpha_mean", - "log10_npar_mean", "log10_Ksat_mean", "theta_r_sd", "theta_s_sd", - "log10_alpha_sd", "log10_npar_sd", "log10_Ksat_sd") + + # determine output columns by running a small sample + sample_res <- run_rosetta.default(list(c(33, 33, 34)), rosetta_version = rosetta_version, estimate_type = estimate_type) + cnm <- colnames(sample_res) + terra::nlyr(out) <- length(cnm) names(out) <- cnm out_info <- terra::writeStart(out, filename = file, overwrite = overwrite) @@ -220,20 +248,17 @@ run_rosetta.SpatRaster <- function(soildata, cls <- parallel::makeCluster(cores) on.exit(parallel::stopCluster(cls)) - # TODO: can blocks be parallelized? for (i in seq_along(start_row)) { if (n_row[i] > 0) { blockdata <- terra::readValues(soildata, row = start_row[i], nrows = n_row[i], dataframe = TRUE) - ids <- 1:nrow(blockdata) - # soilDB makeChunks logic; what is tradeoff between chunk size and number of requests? - # run_rosetta is a "costly" function and not particularly fast, so in theory parallel would help # parallel within-block processing - n <- floor(length(ids) / core_thresh / cores) + 1 - X <- split(blockdata, rep(seq(from = 1, to = n)))[1:length(ids)] + n <- max(cores, ceiling(nrow(blockdata) / core_thresh)) + X <- split(blockdata, rep(seq_len(n), length.out = nrow(blockdata))) r <- do.call('rbind', parallel::clusterApply(cls, X, function(x) rosettaPTF::run_rosetta(x, vars = vars, - rosetta_version = rosetta_version))) + rosetta_version = rosetta_version, + estimate_type = estimate_type))) terra::writeValues(out, as.matrix(r), start_row[i], nrows = n_row[i]) } @@ -243,7 +268,8 @@ run_rosetta.SpatRaster <- function(soildata, if (n_row[i] > 0) { foo <- rosettaPTF::run_rosetta(terra::readValues(soildata, row = start_row[i], nrows = n_row[i], dataframe = TRUE), vars = vars, - rosetta_version = rosetta_version) + rosetta_version = rosetta_version, + estimate_type = estimate_type) terra::writeValues(out, as.matrix(foo), start_row[i], nrows = n_row[i]) } } diff --git a/README.Rmd b/README.Rmd index e0888f9..c1f931c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -1,11 +1,23 @@ --- output: github_document +knit: (function(input, ...) { + litedown::fuse(input, 'README.md') + x = readLines('README.md') + if (length(x) > 0 && x[1] == '---') { + i = grep('^---$', x) + if (length(i) >= 2) x = x[-(1:i[2])] + } + writeLines(x, 'README.md') + }) --- -```{r, include = FALSE} -knitr::opts_chunk$set( +```{r setup, include = FALSE} +library(rosettaPTF) +library(terra) + +litedown::reactor( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", @@ -46,13 +58,15 @@ library(rosettaPTF) The [rosetta-soil](https://github.com/usda-ars-ussl/rosetta-soil) module is a Python package maintained by Dr. Todd Skaggs (USDA-ARS) and other U.S. Department of Agriculture employees. -The Rosetta pedotransfer function predicts five parameters for the van Genuchten model of unsaturated soil hydraulic properties +The Rosetta pedotransfer function predicts seven parameters (five in versions < 0.2.0) for the van Genuchten model of unsaturated soil hydraulic properties: - - `theta_r` : residual volumetric water content - - `theta_s` : saturated volumetric water content - - `log10(alpha)` : retention shape parameter `[log10(1/cm)]` - - `log10(n)` : retention shape parameter (also referred to as `npar`) - - `log10(ksat)` : saturated hydraulic conductivity `[log10(cm/d)]` +* `theta_r` : residual volumetric water content +* `theta_s` : saturated volumetric water content +* `alpha` : retention shape parameter `[1/cm]`. Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +* `npar` : retention shape parameter (also referred to as `n`). Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +* `ksat` : saturated hydraulic conductivity `[cm/d]`. Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +* `K0` : unsaturated hydraulic conductivity matching point `[cm/d]`. Logarithmic (log10) scale if `estimate_type="log"` (default); Geometric mean if `estimate_type="geo"`. +* `lpar` : unsaturated hydraulic conductivity exponent. For each set of input data a mean and standard deviation of each parameter is given. @@ -62,13 +76,10 @@ Less demanding use cases are encouraged to use the web interface or API endpoint The [Rosetta](http://ncss-tech.github.io/AQP/soilDB/ROSETTA-API.html) model relies on a minimum of 3 soil properties, with increasing (expected) accuracy as additional properties are included: - * Required, `sand`, `silt`, `clay`: USDA soil texture separates (percentages) that sum to 100% - - * Optional, `bulk density (any moisture basis)`: mass per volume after accounting for >2mm fragments, units of grams/cm3 - - * Optional, `volumetric water content at 33 kPa`: roughly “field capacity” for most soils, units of cm3/cm3 - - * Optional, `volumetric water content at 1500 kPa`: roughly “permanent wilting point” for most plants, units of cm3/cm3 + * Required, `sand`, `silt`, `clay`: USDA soil texture separates (percentages) that sum to 100% + * Optional, `bulk density (any moisture basis)`: mass per volume after accounting for >2mm fragments, units of grams/cm3 + * Optional, `volumetric water content at 33 kPa`: roughly “field capacity” for most soils, units of cm3/cm3 + * Optional, `volumetric water content at 1500 kPa`: roughly “permanent wilting point” for most plants, units of cm3/cm3 The default order of inputs is: `sand`, `silt`, `clay`, `bulk density (any basis)`, `water content (field capacity; 33 kPa)`, `water content (permanent wilting point; 1500 kPa)` of which the first three are required. @@ -124,22 +135,48 @@ Alternately, to install the module manually with `pip` you can run the following python -m pip install rosetta-soil ``` +## High-Throughput Processing + +`{rosettaPTF}` supports efficient batch processing of large soil datasets through vectorized computation in the underlying `rosetta-soil` backend. + +For large datasets: + +* Use `cores > 1` with `run_rosetta()` and `SpatRaster` or `Raster*` inputs to parallelize the calls. + ## `run_rosetta()` -Batch runs of Rosetta models can be done using using `list`, `data.frame`, `matrix`, `RasterStack`, `RasterBrick` and `SpatRaster` objects as input. +Batch runs of Rosetta models can be done using `list`, `data.frame`, `matrix`, `RasterStack`, `RasterBrick` and `SpatRaster` objects as input. + +Plain R lists are the preferred input format. The helper `SoilDataFromArray()` is deprecated. ### `list()` Input Example ```{r} +# Plain R lists are passed directly to Python run_rosetta(list(c(30, 30, 40, 1.5), c(55, 25, 20), c(55, 25, 20, 1.1)), rosetta_version = 3) ``` Output `model_code` reflects the number of parameters in the input. -### `data.frame()` Input Example +### Parameter Estimation Scales + +By default, `{rosettaPTF}` uses `estimate_type = "log"` to maintain backward compatibility with previous versions, returning `alpha`, `npar`, and `Ksat` on a logarithmic (log10) scale. You can now request estimates on a linear scale directly: + +```{r} +run_rosetta(list(c(30, 30, 40, 1.5)), estimate_type = "arith") +``` + +Note that the output column names will change to reflect the linear scale (e.g., `ksat_mean` instead of `log10_Ksat_mean`). -The `data.frame` interface allows for using using custom column names and order. If the `vars` argument is not specified it is assumed that the columns are in the order specified in the `run_rosetta()` manual page. +Additionally, `estimate_type = "geo"` can be used to return the **geometric mean** of the bootstrap estimates. This is often preferred for parameters like $K_{sat}$ and $\alpha$ which can span several orders of magnitude, as the geometric mean is less sensitive to extreme outliers in the bootstrap ensemble than the arithmetic mean. Mathematically, the geometric mean is equivalent to the exponent of the mean of the log-transformed values. + +```{r} +run_rosetta(list(c(30, 30, 40, 1.5)), estimate_type = "geo") +``` + +The `data.frame` interface allows for using using custom column names and order. + If the `vars` argument is not specified it is assumed that the columns are in the order specified in the `run_rosetta()` manual page. ```{r} run_rosetta(data.frame( @@ -231,16 +268,35 @@ predict(my_rosetta, list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) ### Extended _Rosetta_ Predictions, Parameter Distributions and Summary Statistics after Zhang & Schaap (2017) with `ann_predict()` +`ann_predict()` is deprecated and redirects to `predict()`, as the underlying bootstrap data is now returned by `predict()` and summarized by R. + ```{r} ann_predict(my_rosetta, list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) ``` -## Selected References +## New Features in `rosetta-soil` 0.3.0 + +### `rosesoil()` + +`rosesoil()` is a new R wrapper for the upstream `rosesoil()` function, which returns a structured result including all model metadata. -Three versions of the ROSETTA model are available, selected using `rosetta_version` argument. +```{r} +rosesoil(list(c(33, 33, 34, 1.5))) +``` + +### `UnsaturatedK()` + +`UnsaturatedK` provides a way to predict unsaturated hydraulic conductivity parameters `K0` and `lpar` from retention parameters. - - `rosetta_version` 1 - Schaap, M.G., F.J. Leij, and M.Th. van Genuchten. 2001. ROSETTA: a computer program for estimating soil hydraulic parameters with hierarchical pedotransfer functions. Journal of Hydrology 251(3-4): 163-176. doi: 10.1016/S0022-1694(01)00466-8. +```{r} +uk <- UnsaturatedK() +predict(uk, list(c(0.12, 0.42, 0.008, 1.29))) +``` + +## Selected References - - `rosetta_version` 2 - Schaap, M.G., A. Nemes, and M.T. van Genuchten. 2004. Comparison of Models for Indirect Estimation of Water Retention and Available Water in Surface Soils. Vadose Zone Journal 3(4): 1455-1463. doi: 10.2136/vzj2004.1455. +Three versions of the ROSETTA model are available, selected using `rosetta_version` argument: - - `rosetta_version` 3 - Zhang, Y., and M.G. Schaap. 2017. Weighted recalibration of the Rosetta pedotransfer model with improved estimates of hydraulic parameter distributions and summary statistics (Rosetta3). Journal of Hydrology 547: 39-53. doi: 10.1016/j.jhydrol.2017.01.004. + - `rosetta_version` 1: Schaap, M.G., F.J. Leij, and M.Th. van Genuchten. 2001. ROSETTA: a computer program for estimating soil hydraulic parameters with hierarchical pedotransfer functions. Journal of Hydrology 251(3-4): 163-176. doi: 10.1016/S0022-1694(01)00466-8. + - `rosetta_version` 2: Schaap, M.G., A. Nemes, and M.T. van Genuchten. 2004. Comparison of Models for Indirect Estimation of Water Retention and Available Water in Surface Soils. Vadose Zone Journal 3(4): 1455-1463. doi: 10.2136/vzj2004.1455. + - `rosetta_version` 3: Zhang, Y., and M.G. Schaap. 2017. Weighted recalibration of the Rosetta pedotransfer model with improved estimates of hydraulic parameter distributions and summary statistics (Rosetta3). Journal of Hydrology 547: 39-53. doi: 10.1016/j.jhydrol.2017.01.004. Version 3 includes predictions for unsaturated conductivity parameters `K0` and `lpar`. diff --git a/README.md b/README.md index dac471f..f4a58e0 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,6 @@ will be notified. ``` r library(rosettaPTF) -#> Error in system2(command = python, args = shQuote(script), stdout = TRUE, : -#> 'CreateProcess' failed to run 'C:\Users\ANDREW~1.BRO\ONEDRI~1\DOCUME~1\VIRTUA~1\R-RETI~1\Scripts\python.exe "C:/Users/Andrew.G.Brown/AppData/Local/R/win-library/4.3/reticulate/config/config.py"' "C:/Users/Andrew.G.Brown/OneDrive - USDA/Documents/.virtualenvs/r-reticulate/Scripts/python.exe" ``` ### `rosetta-soil` Python module @@ -56,14 +54,25 @@ The [rosetta-soil](https://github.com/usda-ars-ussl/rosetta-soil) module is a Python package maintained by Dr. Todd Skaggs (USDA-ARS) and other U.S. Department of Agriculture employees. -The Rosetta pedotransfer function predicts five parameters for the van -Genuchten model of unsaturated soil hydraulic properties +The Rosetta pedotransfer function predicts seven parameters (five in +versions \< 0.2.0) for the van Genuchten model of unsaturated soil +hydraulic properties: - `theta_r` : residual volumetric water content - `theta_s` : saturated volumetric water content -- `log10(alpha)` : retention shape parameter `[log10(1/cm)]` -- `log10(n)` : retention shape parameter (also referred to as `npar`) -- `log10(ksat)` : saturated hydraulic conductivity `[log10(cm/d)]` +- `alpha` : retention shape parameter `[1/cm]`. Logarithmic (log10) + scale if `estimate_type="log"` (default); Geometric mean if + `estimate_type="geo"`. +- `npar` : retention shape parameter (also referred to as `n`). + Logarithmic (log10) scale if `estimate_type="log"` (default); + Geometric mean if `estimate_type="geo"`. +- `ksat` : saturated hydraulic conductivity `[cm/d]`. Logarithmic + (log10) scale if `estimate_type="log"` (default); Geometric mean if + `estimate_type="geo"`. +- `K0` : unsaturated hydraulic conductivity matching point `[cm/d]`. + Logarithmic (log10) scale if `estimate_type="log"` (default); + Geometric mean if `estimate_type="geo"`. +- `lpar` : unsaturated hydraulic conductivity exponent. For each set of input data a mean and standard deviation of each parameter is given. @@ -82,13 +91,10 @@ model relies on a minimum of 3 soil properties, with increasing - Required, `sand`, `silt`, `clay`: USDA soil texture separates (percentages) that sum to 100% - - Optional, `bulk density (any moisture basis)`: mass per volume after accounting for \>2mm fragments, units of grams/cm3 - - Optional, `volumetric water content at 33 kPa`: roughly “field capacity” for most soils, units of cm3/cm3 - - Optional, `volumetric water content at 1500 kPa`: roughly “permanent wilting point” for most plants, units of cm3/cm3 @@ -123,9 +129,10 @@ reticulate::virtualenv_create("r-reticulate") ``` r rosettaPTF::find_python() -#> [1] "C:/Program Files/Python312/python.exe" ``` + ## [1] "/home/andrew/.virtualenvs/r-reticulate/bin/python" + `find_python()` provides heuristics for setting up {reticulate} to use Python in commonly installed locations. @@ -160,10 +167,14 @@ module you should restart your R session. ``` r rosettaPTF::install_rosetta() -#> Using virtual environment "~/.virtualenvs/r-reticulate" ... -#> [1] TRUE ``` + ## Using virtual environment '/home/andrew/.virtualenvs/r-reticulate' ... + + ## + /home/andrew/.virtualenvs/r-reticulate/bin/python -m pip install --upgrade --no-user NA --upgrade 'rosetta-soil==0.3.1' + + ## [1] TRUE + Alternately, to install the module manually with `pip` you can run the following command. This assumes a Python 3 binary called `python` can be found on your path. @@ -172,34 +183,88 @@ found on your path. python -m pip install rosetta-soil ``` +## High-Throughput Processing + +`{rosettaPTF}` supports efficient batch processing of large soil +datasets through vectorized computation in the underlying `rosetta-soil` +backend. + +For large datasets: + +- Use `cores > 1` with `run_rosetta()` and `SpatRaster` or `Raster*` + inputs to parallelize the calls. + ## `run_rosetta()` -Batch runs of Rosetta models can be done using using `list`, -`data.frame`, `matrix`, `RasterStack`, `RasterBrick` and `SpatRaster` -objects as input. +Batch runs of Rosetta models can be done using `list`, `data.frame`, +`matrix`, `RasterStack`, `RasterBrick` and `SpatRaster` objects as +input. + +Plain R lists are the preferred input format. The helper +`SoilDataFromArray()` is deprecated. ### `list()` Input Example ``` r +# Plain R lists are passed directly to Python run_rosetta(list(c(30, 30, 40, 1.5), c(55, 25, 20), c(55, 25, 20, 1.1)), rosetta_version = 3) -#> id model_code theta_r_mean theta_s_mean log10_alpha_mean log10_npar_mean -#> 1 1 3 0.11535773 0.4179120 -2.067139 0.1120102 -#> 2 2 2 0.08613275 0.3888528 -1.898150 0.1347136 -#> 3 3 3 0.09130753 0.4850320 -2.022388 0.1510716 -#> log10_Ksat_mean theta_r_sd theta_s_sd log10_alpha_sd log10_npar_sd -#> 1 0.8325407 0.013350113 0.009377977 0.08251142 0.01323413 -#> 2 1.1858005 0.006014445 0.006273536 0.07481303 0.01160419 -#> 3 1.9060148 0.012771407 0.013062171 0.10020312 0.01763982 -#> log10_Ksat_sd -#> 1 0.09245277 -#> 2 0.08428578 -#> 3 0.14163567 ``` + ## id model_code theta_r_mean theta_s_mean log10_alpha_mean log10_npar_mean + ## 1 1 3 0.11535773 0.4179120 -2.067139 0.1120102 + ## 2 2 2 0.08613275 0.3888528 -1.898150 0.1347136 + ## 3 3 3 0.09130753 0.4850320 -2.022388 0.1510716 + ## log10_Ksat_mean log10_K0_mean lpar_mean theta_r_sd theta_s_sd + ## 1 0.8325407 0.02327444 -1.0349735 0.013356794 0.009382669 + ## 2 1.1858005 0.41950414 -0.9533283 0.006017454 0.006276675 + ## 3 1.9060148 0.37302013 -0.3253938 0.012777798 0.013068707 + ## log10_alpha_sd log10_npar_sd log10_Ksat_sd log10_K0_sd lpar_sd + ## 1 0.08255271 0.01324075 0.09249903 0.2317968 1.588173 + ## 2 0.07485046 0.01161000 0.08432796 0.2275761 1.099102 + ## 3 0.10025326 0.01764865 0.14170654 0.2540277 1.244062 + Output `model_code` reflects the number of parameters in the input. -### `data.frame()` Input Example +### Parameter Estimation Scales + +By default, `{rosettaPTF}` uses `estimate_type = "log"` to maintain +backward compatibility with previous versions, returning `alpha`, +`npar`, and `Ksat` on a logarithmic (log10) scale. You can now request +estimates on a linear scale directly: + +``` r +run_rosetta(list(c(30, 30, 40, 1.5)), estimate_type = "arith") +``` + + ## id model_code theta_r_mean theta_s_mean alpha_mean npar_mean ksat_mean + ## 1 1 3 0.1153577 0.417912 0.008722012 1.294826 6.954245 + ## k0_mean lpar_mean theta_r_sd theta_s_sd alpha_sd npar_sd ksat_sd + ## 1 1.250061 -1.048504 0.01335679 0.009382669 0.001649266 0.03939482 1.470258 + ## k0_sd lpar_sd + ## 1 0.7856297 1.576854 + +Note that the output column names will change to reflect the linear +scale (e.g., `ksat_mean` instead of `log10_Ksat_mean`). + +Additionally, `estimate_type = "geo"` can be used to return the +**geometric mean** of the bootstrap estimates. This is often preferred +for parameters like $K_{sat}$ and $\alpha$ which can span several orders +of magnitude, as the geometric mean is less sensitive to extreme +outliers in the bootstrap ensemble than the arithmetic mean. +Mathematically, the geometric mean is equivalent to the exponent of the +mean of the log-transformed values. + +``` r +run_rosetta(list(c(30, 30, 40, 1.5)), estimate_type = "geo") +``` + + ## id model_code theta_r_mean theta_s_mean alpha_mean npar_mean ksat_mean + ## 1 1 3 0.1153577 0.417912 0.008567645 1.294226 6.800498 + ## k0_mean lpar_mean theta_r_sd theta_s_sd alpha_sd npar_sd ksat_sd + ## 1 1.055053 -1.034973 0.01335679 0.009382669 0.001649266 0.03939482 1.470258 + ## k0_sd lpar_sd + ## 1 0.7666369 1.588173 The `data.frame` interface allows for using using custom column names and order. If the `vars` argument is not specified it is assumed that @@ -213,17 +278,18 @@ run_rosetta(data.frame( a = 20, c = 20 ), vars = letters[1:4]) -#> id model_code theta_r_mean theta_s_mean log10_alpha_mean log10_npar_mean -#> 1 1 2 0.08994502 0.4301366 -2.426236 0.1756873 -#> 2 2 3 0.08495731 0.3887858 -2.318826 0.1598879 -#> log10_Ksat_mean theta_r_sd theta_s_sd log10_alpha_sd log10_npar_sd -#> 1 1.1927311 0.006707593 0.008785824 0.07413139 0.01323068 -#> 2 0.9961317 0.010184683 0.008100061 0.07976954 0.01753829 -#> log10_Ksat_sd -#> 1 0.08709446 -#> 2 0.07771481 ``` + ## id model_code theta_r_mean theta_s_mean log10_alpha_mean log10_npar_mean + ## 1 1 2 0.08994502 0.4301366 -2.426236 0.1756873 + ## 2 2 3 0.08495731 0.3887858 -2.318826 0.1598879 + ## log10_Ksat_mean log10_K0_mean lpar_mean theta_r_sd theta_s_sd + ## 1 1.1927311 -0.10923995 0.1813931 0.006710949 0.008790221 + ## 2 0.9961317 -0.03714337 -0.1213272 0.010189780 0.008104114 + ## log10_alpha_sd log10_npar_sd log10_Ksat_sd log10_K0_sd lpar_sd + ## 1 0.07416849 0.01323730 0.08713804 0.2194768 1.622813 + ## 2 0.07980946 0.01754707 0.07775370 0.2056933 1.363478 + ### Soil Data Access / SSURGO Mapunit Aggregate Input Example This example pulls mapunit/component data from Soil Data Access (SDA). @@ -236,37 +302,36 @@ results (1:1 with `mukey`). ``` r library(soilDB) library(terra) -#> Warning: package 'terra' was built under R version 4.3.3 -#> terra 1.7.78 -``` - -``` r library(rosettaPTF) # obtain mukey map from SoilWeb Web Coverage Service (800m resolution SSURGO derived) res <- mukey.wcs(aoi = list(aoi = c(-114.16, 47.65,-114.08, 47.68), crs = 'EPSG:4326')) -#> Loading required namespace: sf ``` -``` r + ## Loading required namespace: sf +``` r # request input data from SDA varnames <- c("sandtotal_r", "silttotal_r", "claytotal_r", "dbthirdbar_r") resprop <- get_SDA_property(property = varnames, method = "Dominant Component (numeric)", mukeys = unique(values(res$mukey))) +``` + + ## single result set, returning a data.frame +``` r # keep only those where we have a complete set of 4 parameters (sand, silt, clay, bulk density; model code #3) soildata <- resprop[complete.cases(resprop), c("mukey", varnames)] # run Rosetta on the mapunit-level aggregate data system.time(resrose <- run_rosetta(soildata[,varnames])) -#> user system elapsed -#> 0.03 0.00 0.06 ``` -``` r + ## user system elapsed + ## 0.022 0.005 0.027 +``` r # transfer mukey to result resprop$mukey <- as.numeric(resprop$mukey) resrose$mukey <- as.numeric(soildata$mukey) @@ -282,7 +347,7 @@ res2 <- catalyze(res) plot(res2, "log10_Ksat_mean") ``` - +![](README_files/figure-gfm/unnamed-chunk-11-1.png) ### *SpatRaster* (terra) Input Example @@ -306,17 +371,17 @@ res3 <- rast(list( # SpatRaster to data.frame interface (one call on all cells) system.time(test2 <- run_rosetta(res3)) -#> user system elapsed -#> 6.20 0.55 14.42 ``` -``` r + ## user system elapsed + ## 5.312 8.671 13.721 +``` r # make a plot of the predicted Ksat (identical to mukey-based results) plot(test2, "log10_Ksat_mean") ``` - +![](README_files/figure-gfm/unnamed-chunk-12-1.png) You will notice the results for Ksat distribution are identical since the same input values were used, but the latter approach took longer to @@ -340,126 +405,88 @@ my_rosetta <- Rosetta(rosetta_version = 3, model_code = 3) ``` r predict(my_rosetta, list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) -#> [[1]] -#> [,1] [,2] [,3] [,4] [,5] -#> [1,] 0.11535773 0.417912 -2.067139 0.1120102 0.8325407 -#> [2,] 0.09130753 0.485032 -2.022388 0.1510716 1.9060148 -#> -#> [[2]] -#> [,1] [,2] [,3] [,4] [,5] -#> [1,] 0.01335011 0.009377977 0.08251142 0.01323413 0.09245277 -#> [2,] 0.01277141 0.013062171 0.10020312 0.01763982 0.14163567 ``` + ## $mean + ## [,1] [,2] [,3] [,4] [,5] + ## [1,] 0.11535773 0.417912 -2.067139 0.1120102 0.8325407 + ## [2,] 0.09130753 0.485032 -2.022388 0.1510716 1.9060148 + ## + ## $stdev + ## [,1] [,2] [,3] [,4] [,5] + ## [1,] 0.01335011 0.009377977 0.08251142 0.01323413 0.09245277 + ## [2,] 0.01277141 0.013062171 0.10020312 0.01763982 0.14163567 + ### Extended *Rosetta* Predictions, Parameter Distributions and Summary Statistics after Zhang & Schaap (2017) with `ann_predict()` +`ann_predict()` is deprecated and redirects to `predict()`, as the +underlying bootstrap data is now returned by `predict()` and summarized +by R. + ``` r ann_predict(my_rosetta, list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) -#> ann_predict() is defined for objects with class Rosetta; see `Rosetta()` to create a new instance -#> $var_names -#> $var_names[[1]] -#> b'theta_r' -#> -#> $var_names[[2]] -#> b'theta_s' -#> -#> $var_names[[3]] -#> b'alpha' -#> -#> $var_names[[4]] -#> b'npar' -#> -#> $var_names[[5]] -#> b'ks' -#> -#> -#> $sum_res_mean -#> [,1] [,2] -#> [1,] 0.1153577 0.09130753 -#> [2,] 0.4179120 0.48503196 -#> [3,] -2.0671385 -2.02238809 -#> [4,] 0.1120102 0.15107161 -#> [5,] 0.8325407 1.90601478 -#> -#> $sum_res_std -#> [,1] [,2] -#> [1,] 0.013350113 0.01277141 -#> [2,] 0.009377977 0.01306217 -#> [3,] 0.082511421 0.10020312 -#> [4,] 0.013234131 0.01763982 -#> [5,] 0.092452769 0.14163567 -#> -#> $sum_res_cov -#> , , 1 -#> -#> [,1] [,2] [,3] [,4] [,5] -#> [1,] 1.782255e-04 3.719987e-05 5.300747e-05 2.278859e-05 5.965812e-05 -#> [2,] 3.719987e-05 8.794645e-05 2.570007e-04 3.632187e-06 2.662337e-04 -#> [3,] 5.300747e-05 2.570007e-04 6.808135e-03 -3.601399e-04 1.347519e-03 -#> [4,] 2.278859e-05 3.632187e-06 -3.601399e-04 1.751422e-04 8.973559e-05 -#> [5,] 5.965812e-05 2.662337e-04 1.347519e-03 8.973559e-05 8.547515e-03 -#> -#> , , 2 -#> -#> [,1] [,2] [,3] [,4] [,5] -#> [1,] 1.631088e-04 2.342660e-05 2.087559e-05 -9.477980e-06 -0.0003382175 -#> [2,] 2.342660e-05 1.706203e-04 3.156961e-04 -4.577936e-05 0.0005664825 -#> [3,] 2.087559e-05 3.156961e-04 1.004067e-02 -7.685234e-04 0.0012668368 -#> [4,] -9.477980e-06 -4.577936e-05 -7.685234e-04 3.111634e-04 0.0001828960 -#> [5,] -3.382175e-04 5.664825e-04 1.266837e-03 1.828960e-04 0.0200606627 -#> -#> -#> $sum_res_skew -#> [,1] [,2] -#> [1,] -4.52570431 -2.33577302 -#> [2,] -0.01729594 -0.22228088 -#> [3,] -0.18215435 -0.25961263 -#> [4,] -0.15345973 0.04145318 -#> [5,] -0.20386127 -0.35765020 -#> -#> $sum_res_kurt -#> [,1] [,2] -#> [1,] 36.6873026 16.85229297 -#> [2,] 0.5975976 0.02966211 -#> [3,] 0.3016512 0.11663125 -#> [4,] 0.1342581 0.26557316 -#> [5,] 0.3127817 0.54242091 -#> -#> $sum_res_bool -#> [,1] [,2] -#> [1,] TRUE TRUE -#> [2,] TRUE TRUE -#> [3,] TRUE TRUE -#> [4,] TRUE TRUE -#> [5,] TRUE TRUE -#> -#> $nsamp -#> [1] 2 -#> -#> $nout -#> [1] 5 -#> -#> $nin -#> [1] 4 ``` + ## Warning in ann_predict.Rosetta(my_rosetta, list(c(30, 30, 40, 1.5), c(55, : + ## ann_predict() is deprecated in rosetta-soil >= 0.3.0. Use predict() instead. + + ## $mean + ## [,1] [,2] [,3] [,4] [,5] + ## [1,] 0.11535773 0.417912 -2.067139 0.1120102 0.8325407 + ## [2,] 0.09130753 0.485032 -2.022388 0.1510716 1.9060148 + ## + ## $stdev + ## [,1] [,2] [,3] [,4] [,5] + ## [1,] 0.01335011 0.009377977 0.08251142 0.01323413 0.09245277 + ## [2,] 0.01277141 0.013062171 0.10020312 0.01763982 0.14163567 + +## New Features in `rosetta-soil` 0.3.0 + +### `rosesoil()` + +`rosesoil()` is a new R wrapper for the upstream `rosesoil()` function, +which returns a structured result including all model metadata. + +``` r +rosesoil(list(c(33, 33, 34, 1.5))) +``` + + ## sand silt clay rhob th33 th1500 version estimate_type code thr + ## 1 33 33 34 1.5 NA NA 3 linear 3 0.1076822 + ## ths alpha npar ksat k0 lpar thr_std + ## 1 0.4060782 0.00817606 1.320054 7.141391 1.281258 -0.8606394 0.01221764 + ## ths_std alpha_std npar_std ksat_std k0_std lpar_std + ## 1 0.008092908 0.001314515 0.03752358 1.415595 0.7639638 1.481137 + +### `UnsaturatedK()` + +`UnsaturatedK` provides a way to predict unsaturated hydraulic +conductivity parameters `K0` and `lpar` from retention parameters. + +``` r +uk <- UnsaturatedK() +predict(uk, list(c(0.12, 0.42, 0.008, 1.29))) +``` + + ## log10_K0_mean lpar_mean log10_K0_sd lpar_sd + ## 1 -0.04057941 -1.033027 0.2309726 1.662214 + ## Selected References Three versions of the ROSETTA model are available, selected using -`rosetta_version` argument. +`rosetta_version` argument: -- `rosetta_version` 1 - Schaap, M.G., F.J. Leij, and M.Th. van +- `rosetta_version` 1: Schaap, M.G., F.J. Leij, and M.Th. van Genuchten. 2001. ROSETTA: a computer program for estimating soil hydraulic parameters with hierarchical pedotransfer functions. Journal of Hydrology 251(3-4): 163-176. doi: 10.1016/S0022-1694(01)00466-8. - -- `rosetta_version` 2 - Schaap, M.G., A. Nemes, and M.T. van +- `rosetta_version` 2: Schaap, M.G., A. Nemes, and M.T. van Genuchten. 2004. Comparison of Models for Indirect Estimation of Water Retention and Available Water in Surface Soils. Vadose Zone Journal 3(4): 1455-1463. doi: 10.2136/vzj2004.1455. - -- `rosetta_version` 3 - Zhang, Y., and M.G. Schaap. 2017. Weighted +- `rosetta_version` 3: Zhang, Y., and M.G. Schaap. 2017. Weighted recalibration of the Rosetta pedotransfer model with improved estimates of hydraulic parameter distributions and summary statistics (Rosetta3). Journal of Hydrology 547: 39-53. doi: - 10.1016/j.jhydrol.2017.01.004. + 10.1016/j.jhydrol.2017.01.004. Version 3 includes predictions for + unsaturated conductivity parameters `K0` and `lpar`. diff --git a/man/SoilDataFromArray.Rd b/man/SoilDataFromArray.Rd index 9ebc52e..b974647 100644 --- a/man/SoilDataFromArray.Rd +++ b/man/SoilDataFromArray.Rd @@ -16,7 +16,7 @@ SoilDataFromArray(x) an object reference to a Rosetta \emph{SoilData} Python object constructed from \code{x} } \description{ -\code{SoilDataFromArray}: convert a list of numeric vectors containing soil properties to a \code{rosetta.rosetta.SoilData} class +\code{SoilDataFromArray}: convert a list of numeric vectors containing soil properties to a \code{rosetta.rosetta.SoilData} class. In \code{rosetta-soil} >= 0.3, direct list input is preferred. \verb{py_to_r()}: Wrapper S3 method for SoilData objects to prevent automatic conversion of SoilData (subclass of \code{"python.builtin.list"}) to an R \code{"list"} } diff --git a/man/UnsaturatedK.Rd b/man/UnsaturatedK.Rd new file mode 100644 index 0000000..619e720 --- /dev/null +++ b/man/UnsaturatedK.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Class-Rosetta.R +\name{UnsaturatedK} +\alias{UnsaturatedK} +\title{Make an UnsaturatedK object instance} +\usage{ +UnsaturatedK() +} +\value{ +an instance of the \code{UnsaturatedK} class. +} +\description{ +\code{UnsaturatedK}: Create an instance of the \code{UnsaturatedK} class from \code{rosetta-soil} >= 0.3. This class is used to predict \code{K0} and \code{L} from retention parameters. +} diff --git a/man/figures/README-chunk-10-1.png b/man/figures/README-chunk-10-1.png new file mode 100644 index 0000000000000000000000000000000000000000..e6e8f43ff2d5ddb55efb07f0666573d4dcad0752 GIT binary patch literal 23482 zcmeFZ^;etE7cEQ`+EU!z-QA%`@!-Xw#odAyZIR*>w*bZ6i(7FE!CiwSxCJSG)6e(5 z|HQlQ4_P50>zTf~+PA%5#-}547jVcYeHfNMOX4LVx&^2VDbd40;;rijLTp-xLLg<_lcoaVWv ztaehK-UoHg=LC4N>b10l?^qUU-Vv&^xyv#urRHfrdsX;jO_A2p>xA;fsD%|A3{G!l zJUKZ#Q)~oht4epa7r)I_4@ZuEIt2H8fqXvvPJ@bqvLYRieBqQk^b7^1NqrjyCCHG; z4F%;7JDxBK$_7Cs848NaJ2?y#l;+U?_woOCXa0Y?2`Y(DP0SDGDgz%bQ(thtL_tyN z_5>byHKMnpsp_Y&gmE11(p5=y=}yxCL(IFJy}KlZ3WZZ|#V{M%Z&| zW?KCGwMXZ>usO{thihN2vqE}EaUYKu>!Wt=eUVf+)~2YbRN!X%sB)NO>?j_Qi9tRw z4t!J?`^AO2J!4@gxA2FvVBW!N^0A3n;`gKi?X_c2y?sI6E%jW^+~w`zME+_RIfnl` zR_mghi1qaONS^l@&8yGZpPaZa-Q(InWSxA^ZAfBWepoa1vyIr&rQ;SWzn?Q&WbeF3 zp{9e$GCV{Gle7Mi1gzON4l!p^d(>$tj&uMt|BW3X|9lhmRX4tf>CP0QP8OAIJGx0Clic5gwM4d zs4}?$&b%k$q0GI*3WnuZ0+vnF>%YvM*Czz!Ze)v>nBRM%msZtC^H9?f5q@!}J)THE z9n>M9V3-jj?D#Ndu$cVdBOi6?7jE_ddxjF^tbl|uDKzR=xjlY%UY1{&Za@CbD;pZV zHB9q$J|r++^#ZH3kIh_r%C(D|yEww^>#)|p!!Q$86NUJyPZlXX*z1IuWeX`2zQOu% zT|L8w0i&nWSvgkBo$laP8m*^yhI}r~#AH%l^hksp?NtOI)U0-17~Kb_)?a+g$@;RK znM^PC<9ilFjIquR=LbZXlfcdMHXizj1I&$>qpNa=NdEdjg9@$4J9S68}-yiYo8{+%F{B!@duG^5=o|QhIGC z*-srsU_Vr`uoA;Ym#&VMw*nSGnM+WpHHEF=@V95Y(Zk54u>9^TvFCr1ly*EG=hJAv zHn@6x>#gQpr?d;crxqV1bGn`Z`m=!jH#*}yg}Gz;OX=p@vClN(bguCvctF8}R(1*R z6XaZL^3m(l)7|zsXfv16$kKT!H!kS7B3(A7d4&cWOCVSc+vKhbIx#vv9FlZ@`K)y9 zDEcWx8Z6e<1>3pc5c|zx{`@dM!>u-c;b6N6c@9hV+x7cf8Nqcg)mP9m!ZtOEs|U!3 z@tG#yY>otE;MS8XnQ)$~Qge!C3<&{nJb4&avXTs#HnY|Q4p#A89wcL+R9jNNWX0Ia$;C;)BO^;4zJk;R+NGNKEZX6xRHhDW)Qh6l9o!c; z`ft<##Pi!`>2G$jIGM0HQ^ay*Bbx8q#iG__==$r1N-u?4R*MJ2*B*9;1?i7EqDQKf zd9zYJRkNa9dqo%BU*Yi`VE>A-`>>Vf}=r(HA8Zs<;$~ zcdp&!`PP+t28__Dqt0_?OUR)ZFdjZ$3ekt9yIl&M)Q8xkPYwF{M!*Y0>EI_cPl z9q+|Y=Jm-L)v{H5R30-l9y*ooTo%&~Mus?cl#doldvv1&vQ8%Q`r=IqC>?k=lu)hg z@V02+!{PZ+sMZ{5Qu^rGlRTpLuKP=}5A(mh6`M(T)1z}mKOBS>XyKz<=A-#QE~cK_ z&fsog&~w^-RNPzU&VgPej%mhQ32F4%3WdR7;lzO3TAuOvymg~J>E|boi$;IpD?WFC z)WD8$$LG``XlIT&4_`NOA9Vv}-JqZk?@^|{ehc9luj%=Qo)g~|FXJ> z_MfH`X~w1cEf2Q-k~yowPn#KT-KMopD$+;Aj77;+o3zp+@6C0q#82n55y=O$rRvha zvLbx-ZEw6#Y8_w_K*a;y2jJr$7235l;<1UojyCcfSh+F8Raba*@oti3)1G-PDV;2T z&MNGSbmK$(><|GF6E6sfG=GjMcfj6~QDll`^o$EW&ta zh?p0djD3o%OCyBi6@Qy4m-V|V&`+Hwl&j~v3KNZuLr|4>GX8+mR^RBf=Kn$goLID>1WD42}A7ZH1B-> zWmoTo?sQVmZ{l{`1b5-`gza$qJWam3H zQCl+oNe4YAiBC@kdRDh4#)6sWF~St3V>PyhE}To+~zrw$_0 zUeu$#D6D}!m?j#Ona|tn10(|wUJ{3)kM79|z=TKq6dJbl#!S<(%v{dtdjEpRGfnpC z0A2-Ld?dxfJ;hgfB5*^Nb&tO4V4@QyTDy^-$mtc8Or?^dQOi^Ef#5>D&4A;TkyMfO z)4mziV)K#0Bn&dW+klg+4vB_FOXLPAxK~Gi=<3;=Hjap3M85V<^TwgS7-OD4EQ#La zP@+}wG%#t6O*G}mDsNAgd{bxWu-27nnH5wx3gs7NQH>PBm#dUa{1Pt|3X8P~nWvlj6@69#%qjRBQe!89!=p7Kc*8=Bm@=U}vAmD0|Ns{M6n>QWT0T7?}FvxDfl z&O&4|P=E4F3;QMtBozu=k57Q4wsHq2oFG&FJ%^hr*}%}b(lX5v{z)^6I=i=pJmaCJ zlNMl|Sa9gF!>om}m05u~1PJ<)?d_)e)Fg3|rbXT0FqiX=;1R!M_4w1F?|T%i{`25k zx*XpeS30)?`eQk$&QhWA;>z$#o4XnS@eUh<>7WGv* z8-SnKzf#K}-ss!#tHIxtk7Pwzn%hqODKM%lYN=yKg8$8?&45JK-M2lu&XqIP#G(FR zwJnH=U+xq`wXq*JL5tkFg_w}nZgB#Po@k*na z2;{0{k@^MG0^QbQy+EtMkiVR0MX2h)qnh9%QG$w}zu{IcAn?N97`ZSnq7|KvINJ=P zGem0;mJ-t8k`JBZy5a_}{0ER*nLS$0X*mu^Sh2=sZ}ubJ8GX-4oVzfxp^}AyNaWx` zyq}faD`_s$*kmM@Gs_frE6ZCX6-%hrJLp>rK>3JvWv0r(g&=yEm?LRT+FIQt16rAG zL>*8U|IKm(J9IuQ=SF;VyD*RB;H^{O4u?7HfvXt|{?T?p#uIQA*4sj@y!;9U1v2vP z1|iLz^pxkS0_iJ|r)DUe{qsiha_!+jFsH)+}mu9c*bO+=qys|c+l^+ z5`CLu)mY<5TSYVPmGyvYk_1(>wlXszr}mA!5cw3Uu$S;U%Lia2fa1v|UT>)C-rD`-we|coKV)#$&wsl^eP9jbvN= zb^FAM8@F_mLw^)vBHU`WUYN(TnjWt>F9Wu38z21ts_%Y&#_VNf`nmuDF8JE3Tm&kPU(9~?R85ktg= zL0ZQx4yZ_|)ffp=&P-6B10$Cue$`ATdm3a+923<|>?Njur3L*{JrL`C)sen6B|#~$ zLj@s4>Q*OTRNU}Kvh`YzcY9Y^85_yY%R=8%-vvn>i~IOv*&Mbex_Jkr{s9@wRZf?tX6NbZ`pSr)OGo z!kHQ0e-R1$hw8r?h}x-k<2)+(30$j(TAFCFWlUUmQ3y$!yF!FTFlO$PS zf!^-f_QB}I-+fqqK=9W;sp4}BBl=muihS+AQLN9n%*FZekx2kz<+v*Pul#S?K#2o% zYdgeN$2jGU|&XtH4 zS&^hhm=7b%9fO5kC;u4N*Dw4{!(zpp)EXG;5iW;zef2usR(9BZ6R*cE;QK9|*2Cu@ zo;B`j#rc~gmh#AL;Q~SCe=H59$$PI#JKafs@oVIF3ipa7*@bPuXFQnv`$b+*JYJPR zeuCSYYCNi_i-GN#)u4((qleqo7qlq5S`|;`Ffr?MRw|fq9#P&jr{r$FmoC9e|L9at z%>RfKd$ZS-eEl`c)iGxF63;cl)j9C**vJbX2w&e3oi$>8BSp4JS-1X(ifA!;bxE>+ zh6;2Ruf1nu)Tdp1<)OX;5t=D0TacI0FZeY`j-a)!vJkRn>Jkz`<>But8)4)@6&iiz zhT)jTW43$8-x<(ssH&LoHVY(Ka#Uk3{@PRN)rSzKosLJAFT$n>vKuYi>oswI4>hE^IvNdoKIiR`1?;nKkSuydNJk=Vdufe14Rim z_Ey|`Kh#mHbkM~JHZm7(J{!@t#=C2uFw0phILw^0akSx;Br9nojDSU}kCYU+AF3i) zhs9d=vQ`-2YJsOwId@0o^SKAqi{iEH$L*|$WNhc;-K5_hBVpwy=J@y z%CL8TTbU`ycn=&g6`rJY+u+yuCq0mfdAmHV-bGNUQ{WC^{ssCs*v~VBxF4_h^n|?m zXhL1{kpD%Cw7t#NuPuSjd!rXpX<|I#Xr|ltf;kc-;dyO|-w`nIS$btb5hr9vNUl9WsC)_b@Aoj8Lr_~7s$YGKS~-GLBxl$J~wk6rCk)4`s}uUr19 z@=SireA8AA`WKduubY%E=EF118sb(5RHmcv$C3{J`4gmg^yaEt#!f4x^l+UfhOaINwOgcTqAJzE2Kz6Gw z$CfRCNb9VO0@HNILU~1kFS#e3c{N*-YuX~4w=u~0MCrBtd5S-2CU@L`tyMEPBMctA z2X@JO#mk7BEGFNge8Uxw3e3Hs<{mR{a5vHaO5ULHJAB@qp;trNu7O^^uQ6Wuk?P-3 zqYl|deF(T+OU~V0elwLzqw9F+v{;aZJ_eX$WQW;!mErjr z;u7{f12Dx`^i;JgokL`6RijFLNfTRG%8ugo;76JD9t#0ND~+YO9pORl5kQrP?nfgD z%amMn`0xrt9al%KC9U{6;h1Am;k7|Bydc;SyGtqT9@}xKL>S&P~AeJTuO$>$x>j~{U4iYH-|u>ZTN=x^A)R7 z`co{J7%kZ4Td5Z&@9IUD@sz~(R0Zw{I`&lIAu86pEAf5YcJi~~@^J>UbUV4F7=K){ z{&#u9?8B;yQ=4>tx)!cYHmx{^d+akREq($(TtV~|x3ki)fDcbA&&pAoh+O+>znHcB zSD+;Z9fE^#WY&9XnOxmb@zX}l8gKJE=}sz-cquB`<<7;-pZ{re|0_7m69n7WU4iiG znZ!$2fSP=8C!s~gmaVaYuN0r0|K`|v?SUfmR!Ws0{qfqY$;IBR#%8tVMJ>dn^IdUK z)7k6cH)VY339!A-V^rjaj4060zI-yMA2vGMwgoI;S=^0@8B!?UDaAcgS9B+XA z%mD6Vf^RZSe7QAp0%#(eS=0Q1niVn3BUJrlm3%q$W57O$Ef2+_a zvjta0cS0nqBFPZ6_!F!y8wXS1+zDPUWOU^hodCW4bf$sH*<(;5TWzU^Q+)r={ffN6uB!U3 z)QOv+o}hL4EMsCcSyK)(HaB}ye{apb)Z!{fL-9#@1!y`sLS9lN?e`tz|0bMz+mE-R zHz{#TI%;@L-Vw}NC$PIEKRKWKZcpI=&27w=UKoqqN$AlPJ5wt&kzc4(;aa=IfGZ;2 z_*jmGBH~Ffux~(o8GWp9o2Qr9>`T}*nTuJrREaPy&*ss{D?4n;0Wq6m2GBkcO%^N_ z?T(GtoXt(}vU262>WA9Oa_)y&y1=zPf6{<^t1)SttiQ}7SbIE34HM>`-u^VRj0q@aEWs{sK5Bb@*XOAuxioeVwWYKIUeNRYT#L7u2o(~klO5;`&ySbisW>CXW6I=W$TVkRH z+Hj{bB`hAxaWbDS8Xl`f^jyd+P9C8b7sy*}S=?lf(pxKe>0`+wfAv2n7>OMe8)yQ;-b;Y%**?( z>3phXr}mILj3z5|`k~hca!ky0A%+^;{hw+Y^0OysTz++$4(kGY^YX#og6pggWsJIs z22+6hIrT$SGPGKEBudE~x3|YdX@APca;KLG6H-d#ALW)8b+Jv3CTGEGUi61GI zX&J)s3w7sw;=?hO!Bio(Dj3L10A01L)Lt<(4D@C3`|jLNSylhSL%Wrpp?}%^^YcUb zQiUEs3`sIJzts-Cx*89-sl~3xpc6QLfa!9s|D?gIAX>|XWpst!6(1gO}W zP4VO`>{ioQ$~SJIY^AMiK6S>6yYC!#1%5p|w12vB*A4n9MPW7a97VQP>W};rr=A}q zQPll+&+M4ieXVrrWc9<;W$201Lz&Vfs>4b%H&!#2?Ay01X^DA01yL8z?3=I@jc~`K zY6Uuso00tYZI-_3*g%Bp8|rN(V@$x}#)K7C*n&7oF&@MPTQa6ZuTZ>6o3c&IQ#rog zZ zD93$kI=6Y)q7`y05e1Vs@f!8*TJhxB;tWDHhYDSah$GM~8Scz-STi;EBkaFs$25{`{(oKohxNYOGBM-f>>?P0>29rbc|2iN~HqtYyF&+ff!?QjD-PV z>#wQ>B-s02rydC9_3z-1n4~rqE$I}7E`*eGaQ^-`ED8fs%4#(B6Tg$_EQcLmKHevA zs&UMVY$fi@iYIUVgjQJc^rpuJ4g2m)w~8enwGXRj<66Ei&wHQ}{Zd4)7gakndp|xu zeelq{ueY8{IWzqC>&kXA{jHzG+)@hi7$-_oOMjn1RX@38faQA1%c!2@`_&^?Uk@-WtGl83~4ws+;b zn059jEikt}uyW0`RA(e)Z5G+NBiSimxOziAC0cEHV&`J|KF3psL=;cX~M= z7hO9!x~Z?tz6z!A?K<~2ll7;l>{`uhr1{>B{b@Cl1OXY{C>EcE}JdAWS} ziMOIKW$n;Vdr(S1=?8jo*cS_keUkMPi;T%A1>xi6mkj!P^*{2vj03Mc4!v;}ZWjHU zkSDSlcQ$M!r{f@znzE?9-tRpWKlr#TFU+~tiAoO!-1vAci!LV^X9`-+P>9^|-m#K> z$?=|gS{AmQwkoA;z>OC&urkdChViwA%K3&(r#JCY!bXOSxO1#*XQ@C32$tleXR*(p zapZxNq#py~9E6C4+)fpsx06lotXeIH@iA@tonl^YIZKU{BLnRpfYJtosGL?BrZ-mC zV#|jVQ5nd%2N3l+x43$OVM($Zy@FU(jj@n%eMX@!(8&K7C;8Z1JCF9NesrDp5-xA| z_r+8DY-4YlT!+L7j&sqZNKKA3a+j?rC@H-)o>d4h#1H)*O*cueW$`2NiBMx1H4P%@DXEm<0LQ=0@i|Hmx%9ISTax1StZ)96wMxe_ z<~vs+oWmRY}rV@OJC8H+rY#*T7mb-COzJ@&6_H9CX6mq@_E;ZroGc+XD91 zlKWs6iWQkp#4{E#77&*VKDb?E3;WVMM6}{~TRE^;u;t2Bxr(@hxJn4u%P?g}fd1^6 zS@w&HMC56dM#Fyo9qX6Jt(6@jN&j29hQjqyx>n?eEl=t&kZ=u-7!SZ;k=E`8k z=%>Tz+(y^e=KpR=Wywj^Zx=GiL?Pdg1}0u24=Xm&kB~#sn0%ls*0D-23UyzO2AeGr?;iLe z<;p{wr^Y-*Nf!BslJV~E8A07p-!Q8ydx-^$K&!udVFvx;YWD=lGh7p#AJtvhq%f_? z1(>HitPB5`QzgB~EVOj3U)0Bw_$@AmuSpR%GY!h8XkE1H7incKmH?Ig^op&4nGsga zX^j61flkgn9$`_6p~3kzI0=jHxquCl8HE#Mr+IIVVq%f|0Dy(x-1s=imI~sLo`^di z$TowCr*(5{BB!5dPcV=tW6MQEH(WWNE2M5q;B?%ylkcC3Zaz^OkSbsf&F8PiP}DUEPt z<}#dy{T>Pi!Lz za}DgG1mh*6Z}I`L(psY@$=BE&cUAbkMdn7dz+qp`emwgppVn-sEIKjdp1^d3Fj=mt zobs!@4{a9m%U`a823C~Sq!a$Ft!u(I(WBVK2AQ%x1}~p19Jy68wH0YBg_PWRy95Au z3g|f2^02;U0t`Ec!8|uAvY8n`5&Ku)_{08tOfC{$(9OliKn?EJZ|IEwO3dK5cH~9D z{Ts+-TZ87(F><_NZ1uW%D`|qM=ApbVd-4t4%j&CLT||aUPQik+tqvjm3z&&&!}2yxv+;S4!koy56uYdHyweUO)`l^OvKWi0K`#3@u;IzS)-^|D{tabB_wr@8 zyfHdJQg9_PuX>31tqU2D?T=+K!;q8k%-Wyz$|PpSDe+dCDgt$i&3wg-7%*;iV;j5} z`$RSKtY)cW)0lAAUb8P{nf#=0@yRZ?Y_8);K{6Q$Az#CAxlx5Q`N|{qR9XC@4uG0$ z`iqt6*!=UaKXW%T-F{U-en0ofBDx>wa4r~nF>pgQ+Q!T%9~4*SnM$tQZ|SO(J{2j; zmu%SlA;RgabY^IuOOcB6$YAqO8UAw`3!!pZt$*kG?(cKiUsuO+Td|Br_`*BbrISLX zQwDW>DQWRCfk7meVbd+0hAo!$(R|~?I00{E3i2^mho6HI^~a#XDI?fCwzAVkJ7ZD; zZJO|G^m|L8EL@)WVK9=>b_WB)R);)y zpLTcF8%<1MJ(OIbKZ?Y;f_}ExsR_Bt<#93q?$fA^_sC*!t1G}j4b}ADNwz8o=C8*I zJbZzgkzbyX$%G|_N{;DgfMM|&81if2UXl8(piQI2=5S<-X{>docV7B_S~biPtVMS8D;?@i;i6=1 zRj<^bN6?ui+)>(~Du4&?p5%GGCiZ410k_&BH%0=Vx0R|j9X|1o5Tn3r@r6~8+;St< z%F7ZDQswTxsd!V_67n-Kh9-xJ{MZ4H(kkMVU%ZpW2&fZ;Q}{!x-JlOuuc4_952#z< zPA}C*4;AsHnx(KR$=3n7;TV%A*HH|e67N{;3UkPJg)5Ib(i{{e2Obh{kcaqst zy(K6h2JrrA>Gb|H!Ilt?$$@i6Hf&huZnOTbB^z2$yiFvcll&zkqJdZI<)N_;HbXYj zR)}}n*N6KK6}tO(6c}PFHcnU014_C%YG%{l|D~7#?c*y#xKqeXj;X8XqxWl6(XJKx zRrOl$>ivz=AlPWc$foj@%D>L@7;DooYwsNb4TX{;Jqdq;`3Qp(H|vSo|F>EVh`7r@ zN)cVXJfj@wR&|M!!)8S81%uOBsEigdGHmT9yyInmpY?U$)gh)}P<<>bwGeXx>|zF( zYVjiOHFIo4hjX;S^%4|_0bkn=kWkG;o@Tu%*0ONES1D3#IFEtSu7J1g73typD<^X`|U8Okx)LeiHeF6wV!%9{e1xs^}SE`y5Dpo zQj38&(D|m(%eZ3?Hla5}Li}iFd5rqRv);4o^9ny7Bv@k8*R~F4>(zgBR$~9-^W(x{ z_H?lQW9!5)@q@Fmr1#AMJ1t&%#kz^jGVRvvL!vY5mq6vTNKp0CSnyqSTf=(x4+ab; zzq7Z}pbP4|>l4iRMk$olXcQEa;*JoiUt4~S8@Zw8rvA=Tze8VPV#d07?H*Qhit(RG z1u(*_NO~8HiM4WPW#U#ke(8^<#L$@Leh7XIjWahlUo?>$01tsK#B{QtDkP5;s|rh6 zX}|>kMJDhKI$)(slTJj@-gP}Y+r4xIh)t8iBjV76QrsU!^9)-IV?&!ge zAWNaw=zC+}If~6u{RDpUh0v+k0=cfDbmpWHxWRHjgMJcrQ({co+Jzw(u7j`1R6}po{PG<)H@CN5_soB7yCx6-@@4qw?c?3a8|u>1(n^B{o~gXg12c?k zibTTKjd)N|+Hu|=4O0CxqQ~jn5#@OGqhu5W(5=BazMXN|!D_)S2lYGQ0&IuvT_(79}6rvYw zOO2eR7H=1~{L^6LWY*cA%}Rd!tP7D^L{UO5GO)LYh;jzhG}*U5ews`_Sx+?iuoPJ0 zV`)GC)o@m0xMm`AO`}wJovu}c<^32(ZP^RN{*N``M#q~(HHlJqxAagpV!O@?vvogT zfbpP-B9^_)Mq?bwq3A_p=7Gw94v<9PqXZcui82<#}l zW>~p=m~11ndt;aoRh`h>;&rfg0Qq#lzX=n^4aC;uxu%ooe9T<4Q!A-qUOpL34drTL zLVy614L_wapfty@{+~Z+G}|EOg{l{(vUKkP?HHGc>`acF5qp?uKg7&zA-qb~p!353 zW0BA&=mf7(#575+I@l%qy(7;EI$@`rio;0UtP}O8aWyD~p*Q$u@5uI2V!6=^G1_wS zIP-O+hZ4pXAnaP!uZj%bs1c-mT92#}qOvACPcsfr3JDp+U{?4{gs+UlVbwF1n9n^}2MLbQ!VTo+^4^mGgn6 z4HMv8jrm-y$SMqXbs-;Wu~+ns-MRI0WRHH+ zZgs^B@dERt%y)Y}E9(eyC27^2HE!|Ifd_$_mL}#ec1AW?~8uw$tUskpNBX5$9JYi zSBT~LeV>ftfo&ph$zJa00sUm?Owyv&)$(e^y44~(_Hu@~;AsE~Cgn1TW6%muEbRiC%y+cT65vjc)d)$BuwA zsNG!kYtv(uvd}%WMd~jy>pGW-!C8rQo{{spY693@t0EE8YD4|ROjEWDn>gQX^cAQI zfn!pA`g9ENVm!6oDx}CG-ADiO0*5U0O%JXdME&Zmq@E+mJA^i#vK3TxAa+{)^0?h0 z<9yslCU9evYn%O+5BJBlsb{!UG#f z5q2=M5D)EhOtMt&nZ?QEGtkE`AOc9qh4HH0uoIvfjfHr$+7QRo2RHaY2+?jzaGCtO zcQZ{Q=>GMBxiJkNb(Mx-krsQN9A`&_@Q+8hJ3UnR1^w;Y6d+-=ycPmMy4J~~)a~+J zjjV+3tZXAc)J*yYhg)D2kRXTwEu*@w0B5CziKrgje=f*B9!A-W@LU>3n6Memlt$Rf zt`>JoF2b8UKKCf?eO5ioTgs$;j``GXA6&%amnnBW>HEM*$0Yt>a^9U}elM5Tr+wAb z$fXw*O4=@aN`ha%BDQMNmt)_SJFzk9fCeg^)H%0VWPOVhZd&B7*7UJV-vmKb60-Yg zqdu8c;XFB;W+zVh&|vNsv=E7rw6XqAZ~0$QRgI1MCwEt#R2Q=1mzO`SDMl<-yjiF} zTG!i`MSYNW(JW;aQuV&gI$tP|4b(g(4DO^K&&D}JakYi#B3an)WEB0#K~>&u0nss37k0^K=K01kK4B(qkk_q*i^EKwd1Ut#IdCpn*> z>qS?r7K9H*(DVOUmHPRxr9OI|OT;zQqWohv6PLEfE)zLNOKUrUReBCvA zjm3>uCa&w*29dJ;vc>~szHNP_FPp!jAcnO8Mpc4|G5SWjheM9V2#@kz-^hFT^Sfu) zyv6&Uu;H4yEi2-6l+Z8HKrJ#d1o9^aIPyUz)Q$djhc%w_$hOxRlvjK;wntrK)5ke( zh!?ipoN-9dF?SnbP9@5DG4E=E)U2c!bAPJGCDKacWe-KrSf`{x3uN3s6^e{RE9HY< zGG{@-35wZCHajX|TBP37anuTnF%t4g3%rAxO6lC$fNTheN#F3pV|J&l{P6@ce zIdBVin6SM*Prjzby1P ztRe{@3UC~BiL-(;oCMaKT?#q`AeF8d3zS)kT|Bn43* zqEUCJg9c>Nhffx|uKl-|&P(>Hr(AqY8$=oq)TE&@zqIR1jANONH zoNky{L*XmgYo#C?Q!c73Z=85Y32GSLbYKUvH-b!7D*@;){EfQKrHJ6L0MmZXxjytg z7qC5c*q&urV8;xjNQ9T{m1TF3X6+bKr_@EWal&UXBy|d7qxRv#lv57FeJk_azs1W{ zM2*9GzDE()x^m5juD(XLg+x_!4Y83m#`;lf7zv2S+$n|PrfcigCR^VgP~EFD4#!0s zoVVHuolNf#k!QEnRIhosK`jb!8&FbiyztvGSE2ZZcYjo4k8AXVeo7Wq^w9GdJmG9OF%Ne2rJLTiWE)3r_~tU1?m+@Q-Ya!~@d zgTDInEXXjJ0b5I!R`>F zxQa}Z@;10z^8J}qlZx?H6%9jqZyY$78S{p^;1zW|OlKr)bC;LJG0WL@ILu_uN+^qS z(1l+{EjM~9!d0Gqe7NW5-x`}Yo|Cf%#?t9e9GQZMC~oJfgQ?nG@ow>)i%u`4>83Rb zE%T?o?$u+Fu1)xdhQnilFKlixVUNx;aOVIn@1Av}0WgJ0x8Al`0$1X{!W5Rjv_7%u z6|$mS(cbPC3SdvazJAXMZb4*tyN#7luh0E;Qic37xO#++OPuxPXqSFET55=Ug~R(! zIjLNu2{4wFkfBy*VP+w8rC4pH6J}2Js8M~@)CJkKI%-#9Ml3UlPNVSlp?m%AFMPQ% zj+CQEmw4TcD67oZSQpE*tp&@ijO~uY4(XI|JUSfb5IQXZf9f5tV-4>Sxp`h___t$A zvw{pMSU4gr_w$YoRo;pofDjL(%zuUaHEi_PFMNclP1%mPZ{P?7LM=x^6)hqzj#FO~ zY2txK#n99F!Yc&BBqUj(!^~S5LR_?x`;6J)#K)HTyu=6X?xZAK;r=?8QRM*={sRvE zubF{gr%apKbkC_PCuJLwy|`QxaD{C0Tr{Bx94iShE%a}80DD-145_~T`!uqdv9srA zT@4YGfHcS(djM`8p7Dll2#XZANE zZ+Gd<64qUc!*V=y#y~mUEl+mX#ctS;_lkG~m{Re`@Oqrh(xiEet3xi){ZaYv?FGTo zB>G$B1R6|a#dCd{?rpIn_f_j}o2=_gd#z7LLVhf~h{K2nLjr&|Fn3k?7MVgspCJ_+ zeJh;cB%a=g87Dy*PgVUIBsU^)NocU|u+*JSg!ZU$Uwke^Hej)9?A;S^Vb-)rNLUZ1 zr8mqcz2?yunii`VH14;%k9O7&`{z($+h#?-_4_UP-v1fq!%XUAqlw36xgg zPmn_sUZBY5(ipFbV0^ki?&|hNK_S)t_qzZHH7;)`q3oA0x#TyI?Z!i=2CBc~)0W}uP2{~xNE>&#iWwlc<9z%;LKTV7X7}q4 zF)tfWpg=E3G?<7;8%D3>t>=^`Ht>a?E(tYUe58KoSs-N5wmX@5Wc-RjLkY{|V|LyoW zjkkD>OHc;Ej6NAd1XA|l?lpER%KeyKZ$4~Z=#iT7LDAzYPYQ&LVN?--5wzHp8cB^l z`CjO=-EXjN(eP@1pq>c4%NVE0|DlKWQv;F#{J}xC*+?5?-8a9Zyc?ZqbNy37imErq zfZRvQTm&s9CvlHkch_q|nr(wJW1ew=kBOJ`OJZmH6Q0R46q3GY)5F8V6)_iY$MzUC z=KylKY;?b_-)oAnq!ThOe5=gYR6LBSXze@wjWGsLF6UAat_?Y`AFzDy(s4b7Gg8V# zmtmcc*8NLrHCP|*<9aM(^lEZohyV4KHKkvrUvSieepxySRsEPN|KLHmdtuJkR zu2S)KoUxaZrHR%045))@yw22e+I>)@w_ImqeKhsF{5*y4N;noqVsB-sToiSb^y+Psm;~5u|D`Mw&}(yfk}Q=xI+;8B)86og z{eKQI1t#>jGw(AL&-A5TF6(n7?jd*6^D}|A{oCZ6SGM9svdh?q@<+0S^MbcH#0F<$ zE<&-yo~G-uy9BO$0LL>F>)PmVd_U6lL7(Nb69uGvEV;+An{@F)rYUH$R@0Cx-hE#& zJ?M4cNMAY*9~E!}tv{_WerkM&TpYdux+dr)sw4~9+3m*n#p(-xj)1God87@$abzh) zPBbgub?nx$vGf^sezrVJlLe{hnVAYCDh<#y?Tsf%|4Jb2}4$A#y4?KXx(j}XJW-?nbt;KON;eEB$TVAi)M z-|G>6U}H+nf6f&;YOI;RoO%vcx(Ok-UhTJCqJ43pb?mSG>puUqbliMlnMKws1mdaE zcn%`pbMzWlvur9D^Iq81iZ=P6WKCrb38g^{g1)Nv5z%E44TIohh6h&b%H9?h7>B`I zDo78BVTB@+5DVd={iNc*dHFnKp|h*JL4CU&GO_4@PM(~R6*(s{sZLm!ahilHk|hq> zoNY$B@YJhd0yDP6F+g!Kw+ds~V@`?%vy z|Fm=F|7>S%AD<~5bP=Vkc5F>4ZM77|SknfrrKGmnN-Qm=mMF1>B)5@PQA=B-mN2TQ zHB~|hQK~{MseMoEYK&ky%MaGmq|o^!tEbA7Jsyv0TDXA3?*X9`X% zyH)r`;|o&^tt&Npd;G^LnU34JS%CnOhrqgj1;0XI)jrsD6x1)hPA=*s(gTF zw~L@(2Hc-)R2vUGQ>$+wuW=#a5zpd;coC)r{!OMZ{JcVw@OgedOFQ*+{_z;*}Y?vKPNv+Kaxw=zpeQ+^qA5XBPu|!Es^HFtTpK zAX+ehia~RE>waBMtMYZLv^?g~$rAVZi|);DR8H@<%)xoqO=i01$5-81rKaIoPvrr3 zjh+YHX~DctKZTQt*=nBIVWftsw;H#9W3P1;e&~Q<0eW=R|>OM!YWmO zv)aAG&2|+q)fe-r17`u3`6R<)a@*zQApwM9xAJRpB7K>o*Odyi{r^6M&;Sj|zjav- zJI7umpHcbh@Jy>=@u9IRRJ+Cd;mttyu+(qIJuT$p>hn){X~zydMLtSY`!{_Awj1f` zB+@H%J+!Jx66cjhYe`X`=G(H~Qs2MLb81=stVLA4|6v1Q%XMF$q>jkI{Ix$inLE7x zP9;1Vq@d>us%ux%JkQ`R-#X0aUGr~s=h8qjDh#&m-Ny!DN1bS-{Jx+L)vZt@io%Q* z&kC7_LFKe8ZoF(A!IgJHX+P>svw4*db4-(od-id$Xq@U-%Nr+D0#${@hqV?rnrJJ- zK^is&A(Xv*nMjea$PKcA&;F-gfO_NtaRGMj{=nM%XNM*XhS#mm_d9oSv7Au|+Wkg3 zUU1@x9OZr#TY~%2hx)EAN#u1HQ+*NbH~hexOuT%|q}={R`Sqj(>5yWDuY?9v{HSvW zRzrmms1duX0P5aj2&xSC?C_+G-?UuSd9m->*i@V16rPp@TNSmeRHh3bxc`Fy3fx_v z;@gWkx}?JYtJN<3;B5(>lp)f~!=8lFkV9>Xf+p>;BjlFmv%Cn-s#-l!D!-l9vamq} zVpq}DFl4P``;`AZopTH+i~WX&vyqu;nV0jGjSx=$W#2>$!SlQ{`8@Dt}bKZ z*~yDIW4qeGxsr=v0r@v2rI2rR-na^&ZCcA=Y zQqo!>|9h#}KL_cyi2D(JQ1H9wAi0)r-%_tT4G!lA*(D<3Zfq4i+)wSNB@M^UNg$T2 z^a3>C$gS0@hl?tL#Hf}@huu`OEqzPsEm~CXAd8Cj1+15jBzUpwnFkZl>-EeyRg2CS zcV2n)dko0>Yu-K+boWwzrsZhU<%n~0N_i)k`sq-$$yZkttfs}^47%})W-nFs%dMtY zJz;QEt8B1H%<= zyt$o_@OF6R5Bs}WZ>HU|`?P)~%Z7iGeYEv3%Vrz4cfD|V8SySKBsO$DGk_9%QT)Vj zIgy*~!}enfJ^V+a?q5DFHq(+himM!nvODz*42(i?j4Y2T%&A>hPZ-WFdD^8H-!Cms z&EL|VD#U;>B76H+ZJ@s+4n7>D)dwM5;(RAiah(6u8^i=V8!J?tUEU9QW`nYM3>DaL zOHoeb0|N)t>>tsa*Fvr~davNUXES*c73qjFb9vrseP^ZP66O)i+4Y07d^^fx)@!A2 zuf;jnPk#wJquX8vu`*ZhehR+)X#Yt)k7VOJ{IO}x4v2Z=CEjAaJOTuR0k1TNC-Y2Il^9{EtCuf-urwgKIack@B!MzC z{FZK=4zcp|oF^goe^-Ap8)9&+nwO%bq@)DSeXpGmiRZ^5@`w^Qp)u{U4g36a(Irc@K-0LKI8w zimdW67=GTA8%7B}#0mao-X=}!pq*3q8D#8N3~wGOKlE>ZdH=(ir#Jr(2p0znMUAX# zcq<<4@8h{;J#y-a$<2AosJA!$np$UK34MyGr;R6f=Vc0!MAry60%E{SNXL`3*Av=! z&AHllZ|O~Hc|$$8iF2k;o-&f0YK4C=Vh`T@kfW^>=E_L{nW~$Zi5jmn(rUSx+OXAM z(M(3a97qVqj_9eOb&ds8gAuENPp8GFXcPo!d;bitHE!X!Bpb<^T`Wn$7F#RiV{ZNA z1=~q#?}KRg+O*#_rgG-`dwGmA8eACF|~8TKwY|R<%^e&FqR0OXa;2K&^;0B$ruAOOzin$DdPfla|zGFO0X-lt#quDqT|fZ_ikh7ugA? z@-}pUjwla7fwLqoH6;hDujl>$e|; z&>yM>&wc^Ye05|l%7xBV*60y*3p|+z=K*l3%KXXUtSCL`u59&_qQ*NkP7A~<@qpF- zGCFm+zsS1K!ZF`4FmV1qW3*A{>VsDRdi_pE!>>z)!i{D3=cxmIP&8vB2?dgpll!<@ zCJivBn48B#Rc7a>I)c=&pfTh+f`98Gw4+)L6JB)b5~BzaO+b ztvHX`aZReJKK%m}yzO^Ja;$EBD>phD*QjvI_-Fr0)WltwGVa0LutLKc%NN#^jYrV* z{6iOupLWDB!@|3!-tC-SW3Q0(#V9t$)NRw9s7eUGcaHXc!3kug>NYAIR#U-EDX~S- zb@bK_d?9I}jSg}hV{dww z4nJJTK<{i0AcDHL(GzD&p-BE%E(0CcJCOJ)lnq6m`QsDvYt$`pJ@3|Pnh`Le^mqtV zB`BAYIPpEpHJ8lUHDjOcoK9zdMs5DpE3`3&>LS&d?LSvPc6HF_K4CUDiA7)9TNB?= z7jcv!=F&qI15vhIhQQ|J4F%eRpR}(h;ZJj)lP}z%e985A%-w1&LE>MuL+o`oh+Pt@`og-qs}1JeSw1>5<+GoW zG*kM-r@c1pGeDPQAY|?qE79jpmjm_X<`v*XR)qC)l0)p#Eg5~}kOY3a;bOs!Rr*6Ka``(^<>bCX58X#9p7dq=M0Y_hDZ#M6J6$G}} zvCC`j@B@@lI|-0RC~fT$W5I(jL6#~cy3 z!0BIp!V&`7E)D*n<+HfWE|TikXZK9i%$0=CctD`I&r3sj7?E6GEcVW`?(#kOaE!HG zzA#JMjm8k$f}V#Ln9T8YR6FaTH~~|Q$}*Ab@ll1+*@18QRYTUwY&5T@i2!Ru9Gf~* zod88>Z7*e@FsJQUetBJ}{hN%tByNfb*!_1Vy3o>fXvGqS)`!s>W}IX)0|GiIN&1yV zN)C%*`V}P8Fj+dJLPYYh773TG-tn3x3fA8!Uk;EAXg8 zv8jD&avCy`D++j2Vh!Q1smH`$&E;%i8ItuULyHF?FGK?Mm&Zxy2Y!0fBQjuxu&TCI=nYhF zh8mbDA+sEsaDahBN8~kWI~Ur+rs8wP`q%B2nA@5Z_4S<09wJjg0*(8~tWLR_?+z{` zH4sh->G4jxn9?I*1UfGG%T{xxVyE8 z-o2-p{9}chTQl$~$*;BFI|u?oQ`_F;sCDQqPV=hGhwom~W>L#;Se5%)T z>Tncr`yW<+Zx`{=V?T0Q?Z=wF-~|EP)?qz1f#CGLAT3^2t5J9KAR4D8UGfw{j{sD~ zaYLD&Ru!*ucn7BykXxy%EpJziB1#b9wH1%MUK^oYj-$}9Htd*(;-C-p@qIcA?WYU9 zPJkE5MTuBl)Y3|6h?v<#ce4&v{Ig@Ezfv4+0c-jq7v#d=kUM+YWy@CjWpkbTro`$X ztdeH6iL&#o-%$?d$>k|7kl%!Qf=cod|Epl=$t)Z z-lKu%*I^Ryh;QbZ21V+oSW^+fQ=(><&Pb+fIwI(2(aiVkh;EGFmGPQ=?#sC#cWLJYg>8IXlMNZ)U3^`e=T9m%oO4W}CrZ$+iDD7K3rfy)aNiWGSsH46^5uey z6I`hl(YK6X(y#flG_Md$7p*ohyd!Pn?qX36_mBhD@-Az=2#Of^*!HTHUBgDIdOs+5 z+FXUx+J<+Xw8O-pJq}3jeQ~P_yoU!ZwjYw=`Zf240ODxPO_IK{McC44F(CuGMvwt} zg;)7241IoQgqcxxw^Ecugzf&s+%4~P*7YYdWobnA&vBiYdfN)f_u^2E;PA&`^H@FU z;hVl~gz$LkM98uaY#diny3iq`z9hCkQPqnqBrIhi(piPw_4wkGPKLwfJy62vo{4O> z;ubvSGY#~x=kw0GlNo-MwbBtRps^d#3^^%qz{rulas-%bEv8wns~hm8tY|U5?qzt; zcHRJbZ?+RBQ&l_ngFr7qA)fKUOfNg_FP%N5p>eM?yUJ~M{b@6skYvuC_Qe7a;|`vt z+$Ncp5ZNFy?(_1@nvm=oc6@A=l!BK*pxjf-74)6PcbkA^eU+`nC{`RFJ#IB~fZKNz zR&TjCZ+BdyJBRdYx8x>${R@GPSj;qXw^~w%SW;KaYOl?c$=T(}V|mTpv1)H%oVqbv zvOaQcQTfwoR@OlyMjzC#B+7EfH#CwvD5Oolhw&h?-|A-b*y@bNOUwPLJTcx_nyn=; zDiU7HyLhBI2^-#1#Stu}5$;OY#K6PjDC*rH!!THc9o- zKJ(p9xG6|u?oiiBv*U81l-Klm_IclcEgWu1PBZ}`g(dzuTD2m*A4HdsxNdVm zbk{Os+uK$>@wBv~4ssAi?r`bbN_=3e%y>EL&k1q#B%_9GMUDxVaopzXN|&S}g8gjn zTwp+OXFKf~dolwuOD+@$*sF%SyL#X^GM53b%`=O(0$<*uAEhbp>e$zGIBO0-+93tW=iLN)(boZ=~fl`Qr*sv@^< zPgO=pl6GT@_>IVCn?Xa|-FLiXvOZfd0=lLrLSqaPM~C9DdT;q5z8TD~pYrCMXw(NV~7=3lvN zWOV4%xlZ+{@QkQmwhnOw|Dy;050w1>eiJNnje`H0>c0rM!`rsMm>5|YmV;gY`Y-WQ BDn$SQ literal 0 HcmV?d00001 diff --git a/man/figures/README-chunk-11-1.png b/man/figures/README-chunk-11-1.png new file mode 100644 index 0000000000000000000000000000000000000000..42086f45ec0cf0bb8e42327ca51f885541fbc370 GIT binary patch literal 23393 zcmeFZ=R2I=7d|RQ5F!LY5K#xwM;RqV@1q6LqxU-6=m{pe=xq=^O4R5zO7u~qmk?%* z&gk__KHqcByYmm6>-S==87`h@KYOpe)_vdW-V>n#R(SIG#bX>CoF__(vRXJe_f`MB z@b6=P^ZAi;684S2RZ$;;gG03a?{#luT6O{l=M|2UtkgRn`0kRo2e}T-qXV%PyMi&9 zn4~e;jBml=!Q`YAg>18Lt6qJOdi#(-RnG1II z&iXp})90Fikm9`&jMz){8mm+1XGh2;9sDrqhd4OF3K9)8*g<@tBp1QK`SU!I76-?b zP>vV}r!kBX4+m#aI{pC;j&pARJsg|{jdkol7_zzJ;B<2RpFjUUGxPu7Am{}hyfCbH zytvx$pz~qC!O_@SZfikW=zce-3%Uy&`7CHZ_04N{URPj{L7I)c=1MTzZ?8$8euVO2 z!7s(ZWVaSvgV=1|6OXu7sjU4^xphge7jBk~{p}(!CDlZu${_t$9qc5Gq2~zHWRA~e zr1@&xUw&Lz>a;Da=VAifgY#x;Udhf()l1|0&vA8|0{;&S`8MAZXL~4H%H_x~==~p+ z9dYQ94@<8*Z3nm4j8Pjw0A-0*fNC{y*#5|fJts^x<%*T$e%hc~6E!P;!{ z0MRH%EsKIz6c5i^{0Nb3r66;!mdC4c+NWt;?t|8fS>H^f-76FSyZ6Lu@VQi=YZF2b z>gki-WB!8&9VsZ16I6*YH(5>Y(2h*8UOsQDw5y9hLLLfJIKRA6i#W>&;yDcv^a#{0 zcv^d5nAps%a*3`kBbpJfZbiSls_hQ_B16aVB7lP07mDG}Dm*j7m5fhnX8bST;4?4_ zC+$BSPcRA$pKjS!V{-=|`i#Y|vUd+C8kU_3Sv5?qe6?^{855SfkS(5Pf8s?{Qt{RC zF#|IdrI`oQ-XHWq9|h%0#wl^iHmMN<6vsIvjvReKB6m50&0s5E{^c$b=_46j=+xfe zCynEn138`e#FGZzv*lT?=H~shbe~MS{rzYkzh9j%hG#4p+HptdnOgvEwk9jJl3NCr z5Up@!N#+M55rDNFqQtC})nYNp5iNgonqXMbEv3NsZC4;DcuyIdMN>W}!jU<{gLsYS zcsw@f7zwfNdg0e9KE$|USx~U$Z)V~whzaNV&M_H_3^my3-3OhWM8x}nvUgf{WZn0` z!#ap{5xYww1!21aNDUwDf$P5issl3&=0}ogdfu^ zmr#vQ$s@aZ@Ypa$J%Egu0N4?n0rs5PCxKs+55P6zxuRPr952v4;A|G|;ibSfLMqEQ zYG#Qbi5~cu+gsz;^EO--Z0&54c+*j{FN>s5L?&5(4M}sH<=zw3JF4Oza+$i^YWcE3 zGV7o!06xD6O;reAqv9pbAv>(!T5kdf=lqN&@*l=X?uI8rbH7f<0;C8{5!8zR)r+$P zBagzoO?#(zd`Tz){X|rkD)H2u5CUKg;u{@sp88-OJT^}q#|SIqTNjBx=Y@$YF!r*J zJY)@c+&yX4;|7|m5gF^ISxUyvZ~Y?4p=PnVJ^Tcvgm~VxIVdy!+rVWqy<1$_>GxN} zJIe)D)*A6Xeht*}ng}6TZmu|G5!|PQIrHNHZy;+xByzHFMND6nQV9b;uLjHv-B$4dzV9-PiqDs}K6qeFm55!6p@-f<^O$9J zKI3fq8^_{Bbwgx^M@6Rq@te6_RK#x>SSGmF7~Ky0n5>_yp; zk%{7g-EhT}c;p)o_rum8XMZzroC8^Z9TQ%V;Yo|m+=J361#YXGqmGNzr*l3lbyi_z zraS!5%`>q_;*h2#j7K~+`a3zK=Ok*q0)4gbGcbFY&$$?undKa`gH4a2co*gt z1R@O<)0r~aImsZ~!C4sPkSg1mf1v-T_eY`U=Z&q4Mo}v=%yKpTB`2V!rQ*Ku<(rKG zVV2#t=)npVU{;E59x5H zM&z>I+{{nPoVWM{$ZS2ov?CSEi|3|&arE>T<|%RWEvZl;pRL)gz?(}_X#;HTUW?+9 z_kA}FJA8V2%Y28>tkv}_P4_{2nWj%A6nn$*pGhkotRGIY3?+Ge<*8PDj>SK0<^C5( z`$6enG@?`1r|;6Q7RtR60qRBKtS-O%B}@y0es~<8uvn!Y71lYJo|c&k!Ce*vZVxJ> zh=1&OCqDoRM!LphEPKX#Lx7a3UpXI*+In$cyUlMg-^~2*QEGevOpneLliCg|(54`= z%EyNyjwkNhO_BX2X5q1yS3)oF<*Xhjj%dYOgEV{WKrkdSoEm&t%|9C7wPJ*pzQ6A@ zXH*53RG8BH ztCUh@%DI`%-XxZrLoB9AhnDl@%>+P1e%58GW?70-!zJ{v%9t{ z|1eR(pDkx~F46(d_YrlL*>0v(^V>6rnSDPh&F_t zon<84n!lUcK03)Use)*-cB+SVl-U3ZhGpA!yNngrplZ}frxaIx0D+tmszUszfwp#| zkbh`4lq7*Ba-1rWiMV{Zp2{L#tYxhbp-BPnj~^!F`z zg^D0-K2Kl)z{uY;R%)G)$!z-3wG>E><`(bWTNO=2$Dq-JZk!|H%vpMNw)E^-PpaZP za=wS#skV-{?>3g3ZxYejwUQ;m`A11z)apIxE#fnQ&N`@cLOdP9r|36VeYHyjQvb61 zQ!`F?ir4F$25o2lbz5sI6hCVh^zL>YoXuL^CQj2|X*MN>7b!An4L|Ut%r-yE6Lpvo zoUc;W;u_VgU--gL{znyjFQ$KZP^3j~Nl5{j|0`DGLQ%-|)P+ ztvRj?BF^G5*&W=TZ)mA6t>X%jj)rIE1G}LRS}^4aHH>HoEh~f+8T41I`}=;xG@ZoU z^@zFq98Q;Mvc(McF5ne-Q7qC`e3~bUGUQnC?5PZ)+Gk_3AN)e;_N?gJb?P=ggThMz zI11F=2;SR?Och-`U!QtXY_43Kg1=*WBsD6uBw1T;g-!hhtr|o(9iQ?hjUyre*q;N^ ze4eo!kFd||e2ZS=R%TN5GB9b5O*G}sDr-%aB&acTT<*xU$_g$VS``%IP>Tdn$bFYg zG>Zp?A!BV}(=@^OWa|F`19us|hqbTeu$MDti|EPKw%Z|bv#}&Vic?x|P%5A#5J;Ig zMpFJ!dN+5shG=3Ip1W+I$D1riF;}VvD`P zgn*U&_nE}X(1l)zQaK(=TL}ij??|+`nNAa=+L2T3MOu=|w18ecHi^73r5%|qhDh>e z^`we<>F_uC9M~6AUBuxDjabxwN(38m^U~GM6-1r&B;0c;BpmVkR zbI8xH=Wee^I??6W=n(%kp9uHyl94AaF=!ZV2~lPyc{V8F#;AT7{OQvtEUePr!6)J7 zZ(^wyje=w<__%&Wc=&4jMW$IWKH{uXN|;!fW7Xo2vF!Ptc+%7E`k+VAX15=J4U*_z+seFI@gz#0@IX6s+D27sm7cmXKsH zKCeshgec4NGJ7pKR!rHUmz&3`FBMT4aR?UAQo)D67w_yeDlR-Fb+*?N0ulaNC!$n# z$py0Uj2uj>R**<)u5|Jrgm*b~tKX$t9cgLCc;Ys6NcW9n0;%4+Bbn%0p1c(HTgruh zDcr?s5;hyK>!w_)!Ju&vtBv_YK1t$y>)m;d@80EZ=IF}a;f`rneNd|Y4Da5oKTf3H zL?+mN!IzI-IKRCxoy&0{ylm{m*yb*j(#mHdJv~iNp+B3kEmns?tGPhRCYvnvNid!2 z=niGVZS5)`clA|b?ogI#&0rG8tR=i zhhUQ3`JCTKrMc_%_u2G%lApoa6Uu~1rTH`L#Fgh>o>qPjz+5q9huH5{Oi%OuaM0_) zqj_vOO*}ttYEWw?+VC-DPs{6Dh<7pXdYHNN6!Cz#mSyv6buL;DjKgR9q&EQ-j)iXn zZ@_ACMBD9l12yB=z{Nr)qG>wyc8T-OVQ8G*ywK4lsU60||EucHub1h?#12uWzce`|cWIOHztDNI^*g@GsYS|QwW66XAQRR@DPFv*f+*77s z6GOehIJn!wh!m-#>)_xPXAVe94WXl_iZV){unAi674K^}$&ta6!8=kyPx=A-Po{;Q z;NZ|EQAQKs+66I^YwVw}{$lk03zP{AY*Y)$_rwe2w{^I4$h1P8&$oK#)Tv=!#SKFt zkpg*|T3NYvG1h-eoK`-ClWJd3SmU^f3QoY&eT*X$jE7 zEYlpBHdG2Y-2O;W_x#TA{`*pqtd-!4IU< zr+Fh~WIV7Qr+5)EM?4JW&YSW~6=KOPPbbW2Woqdy6)zTP;eSCH0^IYdIWGQmYZ^m+ zyK@EXD^jNt-M~To)2;T+RNbvq=uB&n{Y=Ij%z`wx<_5)p4#$a^d9Nl$t>8)O%mRX7 z2D>JS_yj4?LPR|H#ZFHPV-X|eatXrtU8jJRqxtff?CA$2pGZqwOfs^`wN#r`NEw*q zqNeHzJAM1}oEFz2p~bGJDyjPW_GxA&7rD#T{FPJC?!}*i?*FC%on;wLZLIyQY>sl~&yCJgq~pOE%T$5VZ0bK>JP1&=ew9VG$>bhr$TPUD zyb_+v@;KvZeybYa1bgMH*ikxrO;z7~j}g!>)FL;Q5B_-ql?wXOE(PiT%qOzM79;_@ zR{OrM?w2J-JekAR-Aa}mK*le)l3`8NR+X_}nLU~Mh3)gcEXYf6ZLahKunyncHpKc8 za$>YnYY7EY@2AZaZ2K$sCWjr-PGpk*`cJ29_0TI-ZOC_gBPaD#RM&~o(H+417?Tg% zp++b^*2~mX64@^r3!wvj|6yBe!OFZKDssgeDp&WOwS`$~nxe@%^`9^{Edd{iB& zEIo=CzK3xCxD&EnL_~ii^}CWDZKRe^APqo1wG}+Jow?mj45FDwmYHCJe9P;1S9}|y zu#&Bhj7dMeKv1^PhrR;9qrlpLvvduei^&<)oYd3x`S=?Sd}y8bjPKu6nFsd8b4yv_ zj0)k|l6SlBWeXvbPw)m{yeA0)%d~Zbbq*l;ko^ox15nmeHCZ@LV18X$4YBb z_~^0R?(@UHF|E=c7W!n0rvqHN8>f2}UGEg=GCG>SVtT+{cv|El0Xus`9R4@aA440f zgVJ)LqN0Ey+4p1LZ$Ff={&`=U*2XI%whlY{jSCb|e>5{ULs^|U-af}YyukOGhmpwy z^OnX?$f3fh$vq@4vxj*sva32qVUUYQ1gotT>ET=D3`MAeV;Mq882DI9UWv5?qorYA z|8c1-cim{H5|iydcqep7Y#E2-)tZ48536143%NbPP&{?BUg+q_scnpoKIhK0<(>z zH1<_Vb1gA=FNa!rJty=SzkAj3S2H7z`j9tnyNmimUK@hYz@M8!=!l}s@+bd9drsCQ z$7#RLUiCGa#T(TJhuvxJdfox+_5j1R)7%nrgev;<`eQmP240Q3o;+Rc&BoTxlZd-_}J2jR!wRh^G;bJdLp1D=owfPHcaR$&+g>0#e65(|XN= zV62ZBKKyS-V5K{r&9lj~3L?1`@E2l=ra=p@0oGkhTjD!j`o`|os(G4mwO=7NKeUMZ zH2tdTW_~>LBPWyTKt|8B)J z)l(TI)}ad04|wF-rWNd1G_GQW0)$@ZlSWJLI_8sdolOLndVNm=K-^anAcV$ zx4E$OQJPHXm-1YSC41Nfv8a_xZk?E8gf^IMQk}@tK)FRH`SpsRI;p!{pa#Ut>Ubk> z(*cW0gTdKwA8CBE48wip^ZZdn6;B14$R;C_u1$cg&BfN~FoeUxOV*#ad*V}nne0@8 z+iIwdJDv@a43g*2t~7i6A}ajym`t!IPtLG#GDr6 z{Eq+waHXXcEwDHCymixAPeY{|PU9%R=63pB`BxPc9v6#7HJE89u!y4#2-Rc8WM$ez2;5mDuZ!m#|8S+4=*pV%%3`TspZxzgTsESkxbO3ZKR zjq@v9s~V+X8&;{c`0;gM2T=z%nr&YHotUGO$S^%ZaAgjHlqi{-Q-c z?wFf2s9h-&mkvGBuwCMaZjCZ#*8y>vWj+f{r%CE5vUKv*9(uh@@0!3OBsj=bL#36a zbG$#}i5&IGisQsT515)u{`mHIgAogtE`KYqCi_6Qwsdt8{6op%%Mw9T77vuR_sgBI zc|4dpT5fMYNXz-A(KDIZEh;rF!PB{^azihvkKQ(G7Z7&)))n=IPG+F9-++5W?K{<@ z2@i>|>{ZJ+J~H&?CoUSY5pe~_#oCcEBV}$NoZ-1OXyhIMNf4R=WMEpZF#7uZ&}=xw z%f1UM4n(~ zVp2oJbPM)?G!t(l6?~GO*W-Jwc@A%|}P$K+(?+K2l?P67K@9tdG_Y zdJ?%lhjDlc0J5>D2}JNeeonWPj4So=3)?oKo9!BbomNh$`Xg^w$g;|DIUl~H{B@^~ zSZ}QI9`U!;zTMa!8Tr`bU0M&4%GlywVuMy8DI=jdRx;Gw%EDIG z)~mWEq7C9HZ+>YM)VekYfkx-vJP6B1b@HY8U|Ccsi5AJh#W%lvio=B;A)X4Q~#8 zMfI#aNGFqG;Gd?VA;9~*sk42KM^eIn`nKTFo0ZG04I1sR>y7StUB7MN-+=3;FcM+w zNAiorv*-LEnS8elkK1^apfn%pa@LVrc`l=7o8!ULwjWA$tY?&xY+4MXwF<>s#{_4UaD~QLysalTr1!9O&-qsMjNWf_3vEPMo*ogb)3X z?>@<)#G67C22CcJf78GApgozd%rZIOtFPpE9@u$#vi;yAp%k;^N{k45hC;I>ThG|zo*J`X2VIOD<)343B&_4^c_x z6SHg}7af{$BK@1ef~|0fq?y#EPagp0obFD}q@qib0tdrnH}l4K*HI9c7Sy3AMarzy`>;$#+QAzbKU$oL7L&CL=eAXo{JZY1>Sa# z*!GIJuS|M|9bYKP+Uv>lY?~G6(4ZH#qNe>4jig%e=_I5(ZTEHPlS;f5&#RN_q_rGq=A#dK=901Lmp^tIP8z_PCWrmGSa_eAYm9 zdpyfA-xZWw7Js9#)3BaDIbmjw*V1w)pZCrS`jJhP%K~9~`EI9qik<3!VCo_<_ia47 zqV?PR6Jm9>_s4y$!u#dM2RVXV*u7JQZ;{|IyAk_oZ8hPg_SVtq8y*)Ioy>A_lS8g_ z1M{hi*IJHU$kMs zHyhn9)M>XJ8w-_^x8rm&{a@y$g%ILm&potd^Yub3%dp|B~mK()>!peSnwl zLfv$Z-puE`Rn9)#p!%Xb~UC1Ci+LkGU+ zP4-WN-n1d&UdNrjJTe=JuIvMwkghm%QT-?3f**(B6KK)DZJWtVi<{TyJq;tRJq4&O z98c@=pk(RC0_GM*Ur?B|*J*N#uA&w~RsM3Fb z8UAE{W%^)#c~mlJziviCV*eW%?rcTAmu2jk6EZ47h3-ylVaU$i=OK7Y_D1EZQ)sVt z{JZsg6|T0qhHtSS9g~Qu!B4vT;WKQbw>q#^Yh#}4?QQ`T>)hbDG4*J|t=U87s=t`4 zJs-EdmA=VSf6i+*cya6JPOYAZIkbs;yH~!bryu;)Dg`n3ZNcNQ)-+B3 zbtb-W{xT}#Ar1~$%x$fw>28D}(4g@#e84D6XROjxQd;rm@+8M+jliOk^l|oU$mmoK z{r9b>*H>O;_4z?)iCl|M>GIp1fse8K+?7d0M8v~0fFVVf{0K;_Cz3JQ=I1S~Sg4## z)c#45tIc4}qVDx20mJQ}VCnizAY&>CaTL5RD`kQmFc{ktZXCr3`;D7a1`W;Kql?!e zlQA-tewBcbkN2{GxuEi0CjS!R&;}!vhI;$@P^OwP;ZcR+^5HQho1^wC%YWibZ#xKC zUB3I+pdK|G+h0z9(?ccgrq^#r@i{CI`ByfUux>vKXmPra6HF(4PwKDao7&d|459c0 zb}^Y#jjp{_0Wn*4bnb(RFt2mAf@Ao#M1jn&I{N`)iAOzu^80>11Il8kIavQ_`2otv7jEG z0dKz1>ohSciMj$EemkK)6Me~i&1(VW{#NbH646EK#Qe{Il|rZl9+tO<#u`O?5H*d= z&&7!X;dp0XbRG%nGo=IJtRqbs=FU;4br|9@!HbC%^pnb~(F6y17uf5;o~0D4CN(90 zEOo-!{-50;H2Bp+TjQH!zqWx~Mm?`?kq#d9OPh9sY^I96`tpL5Ra!#Vq_^^@pW#Z2 zL$0x0afwCT?DaQU$$DgDX+DCmLy>wM0HW|6qT0jwICfZ0{GNh1t-{^k--^J+l#hS= z0s`kX7C<3<|AwwR<*jD`BDUGo%IG#oqK*~?rqD6joW}ebZvx?aH=6{LtV!CO?u*!c zi=-Nw;)myM(>(T1nuHJuvIfAm9*eM#BAYg)2P`LAEK3k$1m7m4#G;4g0{)Q$hldZP z={@s#cn_FAM=l<|PW0zH>JG#Av;>nuV3QZJiDhdZ)~uLuO@S}n~iq|y^@4KoqjOpuyjmM3OOuD^l zv5TY7z)f@gX+SU5{J(a;b8gEs92|Ux(1*CvE1&ew9*r!o+Quh(;qd1iJgctNoL{vI zRnaE~3do|cp_2JdiO~wA>;dc$0+TB~ zerAKEmW|Je?H&8_++Wd7O@WKJ{QYuwdas}Iz5v26j^%?i`I2zIZHY@>JbZWlMJdBayeYuYFBKhHFm2tc#rvCCdY(iCW#VBCsvV z+(LG|@uB(IOkF`v=(()))LmHc%@Yf$Fjt&Er-KK!X* zOazt`UQEoZ?5BS0N(!aX)q5YE*gwj5D=_gh-$#P2RSkYmV6`Irb`PV8FXs!KMR`R@Gr465LL zO^qRt$-d%Ar@5=<@yQqL^KFu=DG^g6%!aAKsLo8P@t#I`5qh0nZn2cep|vFbLW)RR zjt19|XG_PSLWB{ks_Dx~ac=QCuOG_xyXr<1{p-h{9^!_--Cc_MMW^1#;XcTumG7oi zSZ8U+$aG6 zGS9jea#Mp=++_v`gF4A+;iqpUrIDp?R?m}_+S5RX7BG)Ohyb{?hJRE}&}u@fh;O8L zvq@!e>{^K(hU-d14Ss$rU}MLxJ>;6y+AH2R8M3`Tj0YNNN@Be-FdB7*y|06Vn~4x> z--?_5Dv^8X)!ei^UWdnVWoG!GQNpZ+s!C=5s{Ds1^~`#$L*XyaP8_FKkBUQ=H zc2_TXmcH!|OcYQY?t}Om(2HlxFVNB2LT}zMVpLW5*Dt=ay2g2&VXi zlnX&9cabn!o=Y!=_Kz-5HE+jrZB2-6I6@7WV)mNsQM85o;mPG)Rnfxb1@L)=m}|RM z_rjx?mR#$|Ixg(g00^XFE)u25oyQypdJ;Dv9khKyhqA!me5NBqX~m#og)uaafd}7W>qNKdrKNv0_J7D58~v z!&SOGPv4fl8P-rJ18p!ji*i`K`LYTe92tWc#Rih5rYy)#t56%45hf9Nz8icQ&9bib z9}{16H(MikGa9yU-VYgUd=7R`iFWZ*2332S{#;_nfq0qIx^o#p;hI===11U z^#Of8XQvZ2$mA3YI~2Avyz_f}KF5p16N+J#k6=7I?neMQ8$KWZwp+<^G`6=?cSkG! zPjZ>5a?{i06FThC@FiVfOo9fqZ+z`$=#K=twy7T=JFp$R-&thWw;UTldr zs}?eZK~k3>oJs{mfVQO*aU0tt;$fg$wvl7{{D|08eFZzVofq}?bPnUzo5(nm_Ni6@ z(UZcHFM2a3tt!Xu^8qo$)V^X2(z{Sr&lcdmo@;`jKK&#NLct_mO&a@hpnW{tpAV-t zhvjQN>+{P}y7>=jlx+?RYjJhUEl$pjB?u-mxjN>KB*=Nf`uX7-cSTe8;ogd)x=(_J z9SR7u(#Fr~>mH=GjdM!J4_w}a=^6t~mV_@(eXb0<-mUv5yHL-1k2nQ*NeZ}q2#L}o zSu1!t*WhB>SdV*u)A}LKf#@#F!+Uh7THL4Hw3w}{#3HWYAj=P-EiyKNeyb%BSD1OA z@Fdl*y}`7a5qjU_J=~Z~!7}=b$DZ5MPl9M^XogNX_^suU1*noOBAbZ=n_c;d>@IlX z&XBwr!lp5NM1y!LqQSOOa?<=ar*d2(R#pp=z=8;N7u6g$gg=n>WlU7sg5v54By@;D zG}kAKW}iO$Wzaz{zBdefEpWZ@_vUlM%lheDWYu@Yk+~+1p991^Cwe8WSh+=(U_gh) zbY?AMt2cRr#lz>Jv zRJ;YkKtsQ99vh`;j}Mf}VhPW0GOUXX$5p`r^k8wjzho3a=ije*Z^Czs!B)4h-b_(^$g6N?xxYLSjMN*JaIk zg}!MhH>HZDDKt`v#;<;}38}iV*X=U*=1`A85aK;S=FovIISs9$L0kktYeAwra+cF|QJC+3LhW$OvN~50 z=d~FkFEz2qU{L@|g1$6L0XI7GYNa5rgoW#6BR~wfvI9K@1+pK%%$kb|F_86*w&tLw zV0(FC)-dgSAcGwO-Qh~t8~aOM^U+qC5+pO%ulLK$7ECRay&xkuWx3}7by;r$gRL>& zB{AMv+FOIh)r|c}r4?yzDtCxS+(3LOa;lE@1yAKmCwp|)6I}LIc907d887MeZc>V9 z=zT10zIS)*+TNx1I{mBhVc+`+dJW?)Pg21hyWBxCWu?%CRPGBv#mwK540VhmEHMEl zl-2FHOdm5@5N)1BWMj)!euH7`O^S>Uy0Z zv7C7kP`1O(!hIVr5z6OVH0FUeWaiw>?32lK)Zl_Sa2AuzppM(xx>9`^A24TiD!YsK zP|H73$FRakFu{$^ut&UjeS@f&nT|QJklRf|?VZ)NZoc009L6^MP(H9YyIc46P|%%A z_v#v7=y}=7RYxzEE|-Cg+awlH44bXA@E5%saZolsf3H|Re|=h-pE$@|IhNeNSMwu~A_uo0Txwv=bU47z2}ZmKb;+nW@H`E5^{BRQ{*rO3+-D$Na{6!S z^|cyv>?cv`t#2OIXkn{>24I>Pz-pJgQYOcdF|ft+S#i#nD4<5cq-qbg;aKzKtuiX( zV|cBiDngw-W6T(9+z1U+W1Rnm4IWml;2}BE1ZZ4-8W(PR z_RrKE8us~aM%JJ! zYr9CPs@tmv;g-Y&FEG^LrXf8|u#58SSX39;za~qkr%^TlmCFb~ikLG_Xu=jZwfUNI zF+Ozhxw~mkvT8XV(;;K|h|qS~eMyyr)G-U1bfs*#D7ods@vn?Du^C$HhMcP9EpY&M|80-MAByyUd9 zp1XxqRDnl!{{vAhu8RA$r~IGX^1t(LLu4xWmcx~7V?0>ivAOw!T>a4~x3}GN%?_`d zO@A}n8}2XUxencXb8HBDLO_KFajnZhZLzHQTcdgCrfM;ZD986gk(LD6RdwP2$wM+K z_(lcksGh{1z2d0IA7|dBOI9mMWawnU;vCswCy&7?mgO#?*FCXB05v=N79Gu(e*(N{ zW%vBEAAEiLPwa%g=9P3e%>E0Sb^)23F;MZzUqFET85mGntwHD6Ena z>gQw$P6r8QTK-OhyAQJbLUnq=DY3fGm=fEoslV&tBw+yey#90+EGZ$$(kY4M&!1oe zN-5ibYAq80ECwQpt5c7bk1g=Eyz)m$Sx$$mleDmp^Aaua!1PDluZXS?Cs909F!ldN zwyfq3-t%L8{Pd3!z|bD?;|EjsxJVTxa3PqUX5=GZ9fc3<(F;M-UVm7=>D;O~pdF4q zQ?M{5YcmzqNc~vTu}D?jG0Cq`*!{~^0S1sr!g`Fs8laA-(3Q&%&rF#d>6|0#Rx7DUj z(%kFe^=G1k$!Gz*gS;WE5Y|mU6BHDDbkE$Vn=PxZ)dV}eoz(4b`xTZ#<|xBzUyuLW z>5GxE%qVQQSUu&nD=z#&7)8F5Du7jEI2nv zio$Y#tCdB@*qVQq#<5B!G1bMf$8HkO6BKsx-boi1*5&2@Go&nqz9Rir3qou2v_&j1 z0)FvlE%@%DlfHVT3P{MqL-XoqC=FrS7ArOP9M~r*x~KIsicjBXt_nl{s5{x+8*h8|YMzov5s)og0Nnb>Aa`uagM&kkJD#*|WD5Qe&IvEU6+?HwIGeLI zdoWB}X>pXHT%*>M7E*#BQjpT;{rb-GpG-+{Kf^F=U>cUmprZJ4SY|w7HT2V$x2Ai> zNr=Ru)S$S?lO=x9v&{)r=^mh2KU_aUC_S1KYF z@ecEhX9F`uMz^+C&B+NjO~t1bnV8eA^?}iC-wFW+{Y;bxqHwCfW|rr=uU+5?8wT#k z2Db6FC`ze_egwKC_(oc3*GKX-ciSbX>>fj?01NX(tMZ%%ZGe2?cMKQT+}O}OQ88wN zs=|7cJxNoPZ|~cNh(6Ub`sZ9fxtk5jRM;>bg&6BVzRT}|bPE*ifX1uI>@%?4@u^sT z*1xOn-jRcLzCel=4U0$IPF-xQqWs|ARNl1_x)` z0S(tyR_hzD|G$nKEnIz;yy_tfa=+NZ9)$$GP#ok8=P|C+9kDOz709t1=;?ReNi-QL zCF*;7oo}-15|lMQG7nAGLN;i672UHAr`}VXR3YdL+MAH%aTpzQ3uugmR$7*6Wi6Fw zc$PHL)FiSgO`X*1kLn%50!QoTfnMXIc!VnqNxMJ?oBg!+(u$isH7oVH9Y-v`MM$UJ zoYt`W%SVBiifG;Xvw!uEzV)opp&>EPEpi5C28P`Ce7la?;XFbqUm#-EZ6fOz`Vk>T z(N3G4(bwN{d>E}8O;aT(50|~Zn|c>fPl#iUdLoH9<;KTFHkPsObPhnck09E?m?|_X zG+{Z<+gtgHAC64UQvZl;H43Xni`hdJA$x_zzuLqnhzgk$Vl8RYm^IE$9zQ(dKgD%! zJ(QPLZ1LJ%_Q$A&@FdikU5B(u4s<}K%5}2rMIpiIg#VRC2M*ox_eIxBfs$MUSt4!4 z%NrJFo}=NtG8 z1zs54x-94Ld@^+^ulLIr$0T!Hg3Ez=*KeI_B3L)bx@XAcX24^x*#^snSfb)-gTW*+ z7G;>W%5p~aD7Kknc_Pf`W6h4~a)P0`G72!JT{FcEW3kp6?-R(OB#%iivspDkPEpk} zg?3Skm8O|B?pL{q>FGAH`wKr@uMG)zO(w9aB2_^W7N~l)P}evNe#+7m zoeWMaH{RxI$;c+642;ahdo4HYY9FDDY6yk~kDMHei2WKaZz~e`GSHQdG<&nhq4n3s zKWgot!1aN_RB8;Be`B{v=(FkKokg4FlLtu}iY>S94|^o8hR+}@L{ELlx0;puTWBvb zg}`T+mL?P^a38==ozJw_t_Dp5PQgmVsY3GR|6@EHiJa2?ABCvGB7D8n#4pZPf1^7wW@#^v8$HM}o*eQ-N7Rye0t;cP&?%&Ra5a_r*ystS5As%aLNSP;l zGJe4^?fepHHBnxq>X~8TjzsBfrCU-R@(mk8n-U0(SELP8U6hk4DMdM=?mkcwkxJj> z7IIUZv9_>gC$VWVUc0^fSLDM@u)d_scH<%)|E=$6ml>t$I$Zs_xw$}7i3JDfJ(kgk z5QtX}%s$-O$KBfW8HO6sKHeDO)FY|*K-Mk0G^{es=iQ0^M94=EEkaRJV0x~n^{E`2 zjKe;y2~BazGMnYkSn@DO${Q-+G&&^r2fsu1*6hYbx){ia{|S!9F+Q$T%-!s1g$Kp< zv-=Fyx((y>;*A?E4LRHACYu@DOD+yGHBR}1DfLf?AXt3>X>BVJ#?VX}0%7N|Zd3u! zO!h;(IH8;!NG%{+30VEtM0&TS$iToo-m6nBzEFnddw8lbDHqB@t$tHaRgkUAe0JM2 zJmU5`nOFkA`7>>OuxMsDs^y@%!!j%LGN!d8#|qoB#Ho5{5x;%=^IJ!I(A`M4V6()O z&rBmq(wJuDXh84t5AMp-^SP*Ou#%FQQ-Pi>STerGi{r5s!@V|_FB6&rt)QR8j&#Y& z<}Q|ny|7|WTQ38HFtfo379&$2w?puDTWX31SdL*_oJJ1+5$@K@VQJn=FLAS-itDSa zmYj2TVV3R8z?r2(sAEn%lk@Ct*W~|WD`0N0);a3VA@=)rjM$MI)p_A6bCdK5uQJEn zX(%tNPKB_1&~RcFWeJ<~=R!V|XB=TUeARFtt~TsaxpVE9gbM_aDHP?%Mtk#*XP)K} zTf~=n_YRQ$4gB`b`=l%2uIT1RC8XsBqYDtKt+&HA{$Az2V$%?|WtFob_$fFVc-r4W zuWIUfp)v$;398nM8bACFtHn0Vjg3||RV;0Lg}YZl*0TWtVtIx=70M-#Nx z)^4A$ji`B?jpSZ&g+&uh60jfkpt6OD^s9%M8Zh0$?N!mb30aEsd&!RdIrZ<3*p5)J z9oDh2MDsMzi1#|?<3+70`o^ehr@>iKwA!<tfS?09#xlv#p!=Ie=*MdiDZ)L8+PJv47mA`o!{b(zUi6r!`v5s zKhGaWrhp8;34z$lIIJ$D&kR5xE<`I!hurD&KYo4$~g=lFQ#hyl!SQu z3r;A9j1xKe8qTLE%7V7lM?YIh0+>+1OuFcw*j|4qCapy z$^QAj+BvVcCbMsk&lw9vMv$t~L=aG#AVq2%a6p=Ta%z+|uwo^4E@nM7bLU#iB}PucHc zxvV-LEDB_fLj9-79yzVXI)OF(tNxwYdSXIsb^ir{R1f2zD6s))YyH+|CvT#6IESm@ zAAjb_aj5m^$t@UOP{j^Qe$3vIn1P8`0|v9F>)_gX-kmiRUuEa)Wa$7gH?K(Zv>74y zKh2Im4Y*gt;txq18Fx8N5zkh|%ztt2t+PWFds7u(vKQ{=TuNfHhx@ygT@Mp1-+ROe zyv`X&G#``j2#`PD_mA}bMm3(bAKZFTYqr9Id{o^0oo|I1kN;J2|1b0f@_cWYw51MU z+zqxw6O-l<9|Q+ z^UB@%9T~ycmg)3+Y)ii>$uyQA^8#uZm1p58o2IAE0Xtf{ujJU29D=w;T@(gk_6PK?*_T3 z$d;=@h%zqt{rB1fPc2Sb7jI-l_DQ!}@RWqrDJsal!E2p*wkJoLEwM>+O#)p& zt*nuH?nHM2Y#8raUq^VrYN{Wy2FBe@H|7R9YNHnN(k3Vej-r`?pMH~K*NK0p|31yZ z%DWla#i5Yg74wUNZVvRNt!H?wZRNcj{Nt2JUcfRKD5HJdetmXCjKRC<0K)Qv2AVXLRPEk{~wu#al>HN`{!@>&wD| ze51w5pKi)DUX^O9*V7E2DlOnSX{`D{lpIHfhI*%EmJ#&Z>!Z@`PfZAbjv;hh+K`8Z z{N@Y0fSu*v*@Bzyjox<#k98$N{H1pPs>I7!piNVE$%=ugaO5 zhNmt$AvK>0I1ekO*m#9R4_^VT{gof4#JyGrUE<1KhzkqBzMook{-qLKI4vc+xN9xvb7W-b z5N1#l*XQ@>4#0^r|HpnwbAx? zqQZMS%#-ZLhOQfbRQN*Y~WR+Ui|1y6cEe!kzEd`58H1^waDrB@Yz~-D?+?(4vIJZBOM2fBsb8 z`mN(oM-InV|9ZC5)DB$pw8YgWh~5s5ptkWX$4F9$z*ybWsI>=mx(9k?)SErd)T*@t zS&-J>Jnx~~=_sDZYa{5;+0Btz4wI%~VK+Rb*6R0Da`8?#FN&#qJ$O;Ewd?hJ^c{J@ z__(FYfc5ot-CyH@kL3k#$jdL1p+bU!N0A1IWVD|!g+f_gUY-NJ>4@(FC-moP@m^NH zHz)v!si&5ha}K2C^_u2PA87Z+kwM84`V*Co>)+1h>q3XH*B52dXW1M~Q}{~C3<7{tLV(Kk4VdScu1?8#T!CJJ|1!>8ThXLn!U z90merOWx)|u^shbLP1W>lcpf=lLZ0Hqt9WxYasM@SB~>y@+XFBbs}KQ=>~r{CjSl5 zs_$$G+~0!#LapAF>p9lAcR#&Z!f5cauJf^FhD*e=H(2`U8rtz0ma^I_Co9`D&%HTb z@~~}7_A$z)^pO*@v&614hmhQnA@Wk=WP0Svn|}!}|Cf_R!OpX`ghcN5)$^|m&k*?CTm7yo| zcy$)MR;g=UACfq->|u6>1zp(P0iZ|$mfpa{F2tyu6>H`3PL784${9n}n7=m6vLNb{ z3xi@{7;vbRt4X90>OC^5Y(HD%-3j2WDA?cU#cd^(x*#8=T1Al?VIudBsq47c=_Ju0o#V6$URHWQ@vLw9WkD-&24 zQkSXvyO792_lZ9U%GCuQ6V_BKRcPWP7l_*hP7)vU5U^^!#Mrcj%7sj>fCn5E-*M? zwfm8=DS1MJ3(T>aEFW8nhu)C)UNQZ1AQcj^gqkwzU`Yhy(*XGf^jYMs^EM?8wI2OB z#MQK}xNOFDXoP*K+FQVeKRGkv_c1H+D96G+eV7GorCQE_xoeY>@@)c*F;Lf+Q__ES zyyzIC)Z6WJ@FFuBux>9OvA0{mYoUEn2L8kElGd;EGpzg`X_*M(KgxrZrt+D)^RJx= z3m>dlW7Ft#SWxeGE~B%0x-iJ!DMQ`U3{1j|-Bs-JuoZ@|e_TMH2ktjVkgE98moxs@ zqEgC?-jJ21c8{T0*#hO4FWH}U znp;2X2RL#i$pprev8!?^l6I?iVAvq|$np{`(SPn6ic^Kv+2x>5?Dgv=YWPl6IDCG@ zMIoEaherl{aVpxqMGJ;S1V+Dwx!rEvEl2(S7F{_jdC!86JsK8D`i-dRV}Y~dI%7K# zrRuXa@uQR#EJ5=beYK)x;qu_B>a$JodKGc1*kzm^5WHb`Bjndgi!KIx*Z~cGBWwaD zG3F^G!We)Ntykhpi!6uVe*whY(sH3oYXya{jx$t}!YK7)57P9lsTI?jp8YD8z@wd* zWfM3rYy*);lGgSmghy>|CD&&ea%$67kT?yP_x`C#e8_o4tp7%8?}4>}vsT5kTO0)2 z0j6bc5?7q-9*>yblZ_=U;1=|`h0F4%ID(&3=8oxNE12vTN_|m&2~yO)#jpz}7bm{O zDTaEjEk@ip?E}Vz{K$Krcpbq%GTo^4{AX_Z2LS86H3WO?LsoF(9$|S?DS6jTT^Jtk z7pI*?nFH~bf~+B>uG`LmU5;(!(j`D3$fMU5rowz~R@Azy%O1}5(?&teQeTGD{b&tS zkhL(6@OjQs?p`-%jJuDh`0#Sdk16}qkmg`8PBfCu{_=^4hf(!j&FLtF(a0oB16JzHA*t79WBsdoF-D)d_p zUZrqy|6mJnmf9gVpcEcBh-xdC3k>V2zs8|!MF(cX(2VBoM0iYNxrpb2miJH+)O*r? zSHSSbL|M4&M5-TcWTp&C{oDrbwcjenBU)s=SHUKnQii2TDv3P#4*SzX$;DL`qQ8Qd z7l`=$GP(PrD#4__}14`vl+s=&Xwsi$N{XhVQedSq8z9q4NqCz5gHYi z)3_A6Cx?ovjYUQFzAXSf0nPHVs|K0vCS<2mCN6B_){3n1`8`%mXWbulkOXYVguVPZ2E*|C7(7bg<9GaQM}+#aVjr@`S|N8iRrf?!b_+54toUEQzzN{; zZSh9vao%K)*1Org+3k8stfQiV?xs^LUx2|TX#r*r(k4wy8p?%!?b>p@2^uLIHB8Ty zAO}{`;X%OC81&rXmG01`cL+zj{Y)}*Kx=S(ACW&?+kxDKiQ-ld#^O8N4CQcG%s9S$ zro$z)><&C@%GLj?Rel&y!2q^3`MR)X5}^Lk`I>`Ob&3s!0p&fiO3b>+z=<;Awt&<% zYzEhQronU&Nx}1gWef9~?N_i9(}lY3Z!p4`@BR>hXJxtWsD7}@KVqJ(9}K0<_BS$h z=3^G-uegLDQHE(Ctm$IWq^vSZ3huMda19`E{}@7|Lkb#J3o=EIRpxUg1Qa;od{_Cd zwztc+KQstlw7gIco_M?a)|r5PI&Uu>1Fc6LzXS4?Yiwo4i4-g+f`z+X0Q*>N)){_L zg6@xl97=V6R+$o+xH2fN3fky2Fj&e#7DtZP-F>?0JITx3{-%^%l=6y?X-G#A=C)I`k)G@3DaMbHpy}F@Jy!~-~6@~%;wJY!L zxU;!hh*W+Zv@fFuHh9GT4+5rZTIgdN>E}r^l2>Fx-66)=IZ8ec4Jx<$XlA%7BYcup zU4`?fp;>PF?s$rS`Rk%lQ8X53Rok{{^}$NPR_|I28`aeu8VRys4EXWaS2|U15YnhZbK9Hrk5L~!HtS7hQU1$Jo{YY%rV7m3&dx~t(5k_fY7I%fhb0RW|7(F zP0Zoel@~`U+Lf+x%UtXRby4UeP)Jgcn~YS^ll12KhyejZ%Hg(wV^OQE?KmKK*;19+ z*`?sSXb)#67J6f38^uqKT@*jEtJ z23z9|Ur})#>5+(ZpDJlLLG?JOhtU3zUcjw%%}Kl_C{HQ`uVO@XTGSMGd#iX~T+}&g zngcG(hR^zf7xJsW&h|=9l7(pVU-_{}4RT6IHWfM0j56ELF`lX#29{EeP1_I($3e3V z0Kk)lkL&-;npJG?k$UT>lMGL~)jpN6_j1xEnw{U{HtoeW2;};&Gq@lz#smppMyC>q z5|Z`J`-{PnB~jr;r@&_NwktWs7c@03%2Jy_Q~y+dXJ{ndXDwUcc`*m_+C}7Vyl%Q_ zjc&<=ebdbLr9<=Wtw`X;B(FZ8+7-EiQ1SV-xF}p#+gTDtjXy<>-^v|7tUUv6aahW* z-<=#pv=kgEXnNDW1(U;wxqrDn+Eh2ST_Blb71!{1gmUg^9Vsd9mNn?OX?NTN5V1{E zsd-Y6MaQ+f0LJ76sjestZnJl=h2rNl+V6%Aid@Rq^xrftht3SdK{^gZSH{uX1~nFk zC{A8hXK2OKReh`oIpQD#t|6(?6!0y<$PFBEb)}$H{1pNg+PwZ&D@3Px(a4Iyr=xJ= zpo%B|u{JTYT>_$YUq&Wk5=9uGZo0c})z5>$PMuZ*WCsdkZr>q&cJF7v^Gm?(XxqSb z#``4{)a}r5Bc1Qwz;*|re^#s_!aVsvBQ3TQnbbRd({H9xl=f9#I;HuP0*>{p<4;)K zCMMX=<$98!n3Fzqf{ZtFp4}Q)OIO}Y`0;`s^27sUFqtVt;brc$^=UZR&IFTfa9{5H zMCd4G?exNNWqM;pNeKAB3);@?vEyJmXliF5Dfr#F!akUAByJJ$v@!`Y9~s8|o)B?B zMzlCKluwQ4V}LLRu|n9!Z789_Bf3NKK7D2EjXun6BS<_PGA|&(^mzX*X&Ojs+*mrF zd34eI@57_Es{N0l^>^ z-;CmolWOR3-``CCx_`II@ae1n E2EHNBV*mgE literal 0 HcmV?d00001 diff --git a/man/figures/README-unnamed-chunk-10-1.png b/man/figures/README-unnamed-chunk-10-1.png index e19f4bb2346fb372696587c0710504e01bae3a89..251474c24691494d7307da6adfdb0ee8f735a5e9 100644 GIT binary patch literal 25186 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 S_W_9F#6wNJ`;{6`BL5F2LKp1- literal 9993 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 b?XoAH8#On~8R^-3rOnFB*0lP>KezrD64m5w diff --git a/man/figures/README-unnamed-chunk-11-1.png b/man/figures/README-unnamed-chunk-11-1.png index 4e1cc4e5d530b89526f846ac7bc76b591c8b5d63..251474c24691494d7307da6adfdb0ee8f735a5e9 100644 GIT binary patch literal 25186 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 S_W_9F#6wNJ`;{6`BL5F2LKp1- literal 9965 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 literal 0 HcmV?d00001 diff --git a/man/predict.Rosetta.Rd b/man/predict.Rosetta.Rd index f308043..168ef81 100644 --- a/man/predict.Rosetta.Rd +++ b/man/predict.Rosetta.Rd @@ -13,6 +13,12 @@ \item{...}{not used} } +\value{ +A list containing \code{mean} and \code{stdev} matrices (one row per sample). + +For \code{rosetta-soil} >= 0.3, the columns are: \code{theta_r}, \code{theta_s}, \code{alpha}, \code{npar}, \code{ksat}. +Note that these parameters are in the scale produced by the underlying model (often log10 for alpha, npar, and ksat). +} \description{ Predict Rosetta Parameter Values and Standard Deviations from a \emph{Rosetta} instance } diff --git a/man/predict.UnsaturatedK.Rd b/man/predict.UnsaturatedK.Rd new file mode 100644 index 0000000..e2d5b10 --- /dev/null +++ b/man/predict.UnsaturatedK.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/Class-Rosetta.R +\name{predict.UnsaturatedK} +\alias{predict.UnsaturatedK} +\title{Predict K0 and L from retention parameters} +\usage{ +\method{predict}{UnsaturatedK}(object, retc_params, ...) +} +\arguments{ +\item{object}{\emph{UnsaturatedK} object} + +\item{retc_params}{A list or matrix of retention parameters (theta_r, theta_s, alpha, npar)} + +\item{...}{not used} +} +\value{ +a \code{data.frame} with \code{log10_K0_mean}, \code{lpar_mean}, \code{log10_K0_sd}, \code{lpar_sd} +} +\description{ +Predict K0 and L from retention parameters +} diff --git a/man/rosesoil.Rd b/man/rosesoil.Rd new file mode 100644 index 0000000..a8e135f --- /dev/null +++ b/man/rosesoil.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/rosesoil.R +\name{rosesoil} +\alias{rosesoil} +\title{Run rosesoil() from rosetta-soil >= 0.3.0} +\usage{ +rosesoil(soildata, rosetta_version = 3, estimate_type = "arith", vars = NULL) +} +\arguments{ +\item{soildata}{A list of numeric vectors or a data.frame (3-6 columns: sand, silt, clay, optionally bulk density, th33, and th1500)} + +\item{rosetta_version}{integer, 1-3. Default: 3} + +\item{estimate_type}{\emph{character}. One of \code{"arith"} (default), \code{"log"}, or \code{"geo"}. Only used if \code{rosetta-soil} >= 0.3.1. \code{"log"} returns parameters on a logarithmic (log10) scale for \code{alpha}, \code{npar}, \code{ksat}, and \code{k0}. \code{"geo"} returns the geometric mean of bootstrap estimates (exponent of the mean of log-transformed values). This is often preferred for parameters that vary by orders of magnitude, such as \code{alpha} and \code{ksat}.} + +\item{vars}{optional column name mapping (same as run_rosetta)} +} +\value{ +a data.frame with all RosettaResult fields +} +\description{ +Run rosesoil() from rosetta-soil >= 0.3.0 +} diff --git a/man/rosettaPTF-package.Rd b/man/rosettaPTF-package.Rd index acad19a..dce9b90 100644 --- a/man/rosettaPTF-package.Rd +++ b/man/rosettaPTF-package.Rd @@ -6,7 +6,7 @@ \alias{rosettaPTF-package} \title{rosettaPTF: R Frontend for Rosetta Pedotransfer Functions} \description{ -Access Python rosetta-soil pedotransfer functions in an R environment. Rosetta is a neural network-based model for predicting unsaturated soil hydraulic parameters from basic soil characterization data. The model predicts parameters for the van Genuchten unsaturated soil hydraulic properties model, using sand, silt, and clay, bulk density and water content. The codebase is now maintained by Dr. Todd Skaggs and other U.S. Department of Agriculture employees. This R package is intended to provide for use cases that involve many thousands of calls to the pedotransfer function. Less demanding use cases are encouraged to use the web interface or API endpoint. There are additional wrappers of the API endpoints provided by the soilDB R package `ROSETTA()` method. +Access the rosetta-soil Python pedotransfer functions from R. Rosetta is a neural network-based model for predicting unsaturated soil hydraulic parameters from basic soil characterization data (sand, silt, clay, bulk density, and water content). Predictions are made for the van Genuchten unsaturated hydraulic properties model, with uncertainty quantification via bootstrap ensemble. Designed for efficient batch processing of large datasets through vectorized computation and optional parallel processing. } \seealso{ Useful links: diff --git a/man/rosetta_pkg_version.Rd b/man/rosetta_pkg_version.Rd new file mode 100644 index 0000000..51d1aa9 --- /dev/null +++ b/man/rosetta_pkg_version.Rd @@ -0,0 +1,15 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/rosetta_utils.R +\name{rosetta_pkg_version} +\alias{rosetta_pkg_version} +\title{Get rosetta-soil Python package version} +\usage{ +rosetta_pkg_version() +} +\value{ +\code{package_version} object +} +\description{ +Get rosetta-soil Python package version +} +\keyword{internal} diff --git a/man/run_rosetta.Rd b/man/run_rosetta.Rd index 4feba8b..0088aa2 100644 --- a/man/run_rosetta.Rd +++ b/man/run_rosetta.Rd @@ -10,16 +10,35 @@ \alias{run_rosetta.SpatRaster} \title{Run \code{rosetta()} method from Python module} \usage{ -\method{run_rosetta}{default}(soildata, vars = NULL, rosetta_version = 3, ...) +\method{run_rosetta}{default}( + soildata, + vars = NULL, + rosetta_version = 3, + estimate_type = "log", + ... +) -\method{run_rosetta}{data.frame}(soildata, vars = NULL, rosetta_version = 3, ...) +\method{run_rosetta}{data.frame}( + soildata, + vars = NULL, + rosetta_version = 3, + estimate_type = "log", + ... +) -\method{run_rosetta}{matrix}(soildata, vars = NULL, rosetta_version = 3, ...) +\method{run_rosetta}{matrix}( + soildata, + vars = NULL, + rosetta_version = 3, + estimate_type = "log", + ... +) \method{run_rosetta}{RasterStack}( soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", cores = 1, core_thresh = 20000L, file = paste0(tempfile(), ".tif"), @@ -31,6 +50,7 @@ soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", cores = 1, core_thresh = 20000L, file = paste0(tempfile(), ".tif"), @@ -42,6 +62,7 @@ soildata, vars = NULL, rosetta_version = 3, + estimate_type = "log", cores = 1, core_thresh = 20000L, file = paste0(tempfile(), ".tif"), @@ -56,6 +77,8 @@ \item{rosetta_version}{Default: 3} +\item{estimate_type}{\emph{character}. One of \code{"log"} (default), \code{"arith"}, or \code{"geo"}. Only used if \code{rosetta-soil} >= 0.3.1. Default \code{"log"} preserves logarithmic (log10) scale for \code{alpha}, \code{npar}, and \code{Ksat}. \code{"geo"} returns the geometric mean of bootstrap estimates (exponent of the mean of log-transformed values). This is often preferred for parameters that vary by orders of magnitude, such as \code{alpha} and \code{Ksat}.} + \item{...}{additional arguments not used} \item{cores}{number of cores; used only for processing \emph{SpatRaster} or \emph{Raster*} input} @@ -69,13 +92,15 @@ \item{overwrite}{logical; overwrite \code{file}? passed to \code{terra::writeStart()}; defaults to \code{TRUE} if needed} } \value{ -A \emph{data.frame} containing \code{mean} and \code{stdev} for following five columns (parameters for van Genuchten-Mualem equation) +A \emph{data.frame} containing \code{mean} and \code{stdev} for the following columns (parameters for van Genuchten-Mualem equation) \itemize{ \item \code{"theta_r"}, residual water content \item \code{"theta_s"}, saturated water content -\item \code{"log10(alpha)"}, 'alpha' shape parameter, log10(1/cm) -\item \code{"log10(npar)"}, 'n' shape parameter -\item \code{"log10(Ksat)"}, saturated hydraulic conductivity, log10(cm/day) +\item \code{"alpha"}, 'alpha' shape parameter (1/cm). Logarithmic (log10) scale if \code{estimate_type="log"} (default); Geometric mean if \code{estimate_type="geo"}. +\item \code{"npar"}, 'n' shape parameter. Logarithmic (log10) scale if \code{estimate_type="log"} (default); Geometric mean if \code{estimate_type="geo"}. +\item \code{"Ksat"}, saturated hydraulic conductivity (cm/day). Logarithmic (log10) scale if \code{estimate_type="log"} (default); Geometric mean if \code{estimate_type="geo"}. +\item \code{"K0"}, unsaturated hydraulic conductivity (cm/day). Only if \code{rosetta-soil} >= 0.3.1. Logarithmic (log10) scale if \code{estimate_type="log"} (default); Geometric mean if \code{estimate_type="geo"}. +\item \code{"lpar"}, unsaturated hydraulic conductivity exponent. Only if \code{rosetta-soil} >= 0.3.1. } If the sum of sand, silt, and clay is not 100\%, the parameter value estimates will be \code{NaN}. @@ -83,3 +108,9 @@ If the sum of sand, silt, and clay is not 100\%, the parameter value estimates w \description{ Run \code{rosetta()} method from Python module } +\details{ +\subsection{Performance Note}{ + +Use \code{cores > 1} with \code{SpatRaster} or \verb{Raster*} inputs to parallelize processing of cells across multiple cores. +} +} diff --git a/tests/testthat/test-predict-Rosetta.R b/tests/testthat/test-predict-Rosetta.R index cdb2835..302a741 100644 --- a/tests/testthat/test-predict-Rosetta.R +++ b/tests/testthat/test-predict-Rosetta.R @@ -4,7 +4,20 @@ test_that("prediction with Rosetta class works", { skip_if_not(py_module_available("rosetta")) one <- predict(Rosetta(), list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) - two <- ann_predict(Rosetta(), list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) + expect_warning({ two <- ann_predict(Rosetta(), list(c(30, 30, 40, 1.5), c(55, 25, 20, 1.1))) }) expect_true(inherits(one, 'list') && inherits(two, 'list')) + expect_true("mean" %in% names(one)) + expect_true("stdev" %in% names(one)) +}) + +test_that("UnsaturatedK works", { + skip_if_not(py_module_available("numpy")) + skip_if_not(py_module_available("rosetta")) + skip_if(rosetta_pkg_version() < package_version("0.3.0")) + + uk <- UnsaturatedK() + res <- predict(uk, list(c(0.12, 0.42, 0.008, 1.29))) + expect_true(inherits(res, "data.frame")) + expect_true("log10_K0_mean" %in% colnames(res)) }) diff --git a/tests/testthat/test-rosesoil.R b/tests/testthat/test-rosesoil.R new file mode 100644 index 0000000..bbeac78 --- /dev/null +++ b/tests/testthat/test-rosesoil.R @@ -0,0 +1,21 @@ +test_that("rosesoil() works", { + skip_if_not(py_module_available("rosetta")) + skip_if(rosetta_pkg_version() < package_version("0.3.0")) + + res <- rosesoil(list(c(30, 30, 40, 1.5))) + expect_true(inherits(res, "data.frame")) + expect_true("thr" %in% colnames(res)) + expect_true("ths" %in% colnames(res)) + expect_true("k0" %in% colnames(res)) + expect_true("lpar" %in% colnames(res)) +}) + +test_that("rosesoil() with data.frame and vars works", { + skip_if_not(py_module_available("rosetta")) + skip_if(rosetta_pkg_version() < package_version("0.3.0")) + + df <- data.frame(S = 30, Si = 30, C = 40, BD = 1.5) + res <- rosesoil(df, vars = c("S", "Si", "C", "BD")) + expect_true(inherits(res, "data.frame")) + expect_true("thr" %in% colnames(res)) +}) diff --git a/tests/testthat/test-rosetta.R b/tests/testthat/test-rosetta.R index 0cdcd3b..3698541 100644 --- a/tests/testthat/test-rosetta.R +++ b/tests/testthat/test-rosetta.R @@ -1,32 +1,56 @@ -test_that("run_rosetta() works", { +test_that("run_rosetta() with sample data", { skip_if_not(py_module_available("numpy")) skip_if_not(py_module_available("rosetta")) - res <- run_rosetta(list(c(30, 30, 40, 1.5), c(55, 25, 20), c(55, 25, 20, 1.1)), - rosetta_version = 3) + data("MUKEY_PROP") + varnames <- c("sandtotal_r", "silttotal_r", "claytotal_r", "dbthirdbar_r") + res <- run_rosetta(MUKEY_PROP[1:10, varnames], rosetta_version = 3) + expect_true(inherits(res, 'data.frame')) + if (rosetta_pkg_version() >= package_version("0.3.0")) { + expect_true(ncol(res) >= 15) + expect_true("log10_K0_mean" %in% colnames(res)) + } else { + expect_true(ncol(res) == 12) + } }) -test_that("data.frame interface", { +test_that("estimate_type argument with sample data", { + skip_if_not(py_module_available("rosetta")) + skip_if(rosetta_pkg_version() < package_version("0.3.0")) + + data("MUKEY_PROP") + varnames <- c("sandtotal_r", "silttotal_r", "claytotal_r", "dbthirdbar_r") + + res_log <- run_rosetta(MUKEY_PROP[1:5, varnames], estimate_type = "log") + expect_true("log10_Ksat_mean" %in% colnames(res_log)) + res_lin <- run_rosetta(MUKEY_PROP[1:5, varnames], estimate_type = "arith") + expect_true("ksat_mean" %in% colnames(res_lin)) + expect_false("log10_Ksat_mean" %in% colnames(res_lin)) + + res_geo <- run_rosetta(MUKEY_PROP[1:5, varnames], estimate_type = "geo") + expect_true("ksat_mean" %in% colnames(res_geo)) +}) + +test_that("data.frame interface", { skip_if_not(py_module_available("numpy")) skip_if_not(py_module_available("rosetta")) - # data.frame interface: using default column order - expect_true(inherits(run_rosetta(data.frame( - a = 20, - b = 60, - c = 20, - d = c(NA, 1.5) - )), 'data.frame')) + # Default column order with sample data + data("MUKEY_PROP") + varnames <- c("sandtotal_r", "silttotal_r", "claytotal_r", "dbthirdbar_r") + res1 <- run_rosetta(MUKEY_PROP[1:5, varnames]) + expect_true(inherits(res1, 'data.frame')) - # data.frame interface: using custom column names/order - expect_true(inherits(run_rosetta(data.frame( + # Custom column order with synthetic data + res2 <- run_rosetta(data.frame( d = c(NA, 1.5), b = 60, a = 20, c = 20 - ), vars = letters[1:4]), 'data.frame')) + ), vars = letters[1:4]) + expect_true(inherits(res2, 'data.frame')) }) test_that("run on SSURGO data", { @@ -34,8 +58,8 @@ test_that("run on SSURGO data", { skip_if_not(py_module_available("rosetta")) data("MUKEY_WCS", package = "rosettaPTF") - res <- terra::rast(MUKEY_WCS, crs = "EPSG:6350") - terra::ext(res) <- c(-114.16, 47.65, -114.08, 47.68) + res <- terra::rast(MUKEY_WCS, crs = "EPSG:5070") + terra::ext(res) <- c(-1365495, -1358925, 2869245, 2873655) names(res) <- "mukey" mukeys <- as.numeric(terra::values(res[[1]])) diff --git a/vignettes/performance-raster.Rmd b/vignettes/performance-raster.Rmd new file mode 100644 index 0000000..534483f --- /dev/null +++ b/vignettes/performance-raster.Rmd @@ -0,0 +1,155 @@ +--- +title: "High-Throughput Raster Processing" +knit: litedown:::knit +vignette: > + %\VignetteIndexEntry{High-Throughput Raster Processing} + %\VignetteEngine{litedown::vignette} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include=FALSE} +library(rosettaPTF) +library(terra) + +EVAL <- rosettaPTF::rosetta_module_available() + +litedown::reactor( + eval = EVAL, + collapse = TRUE, + fig.width = 8, + fig.align = 'center' +) +``` + +## Introduction + +`{rosettaPTF}` is designed for efficient batch processing of soil hydraulic parameters. The package supports multiple input formats and offers options for scaling analysis to large datasets. + +The core implementation uses the `rosetta-soil` Python module, which provides vectorized computation over multiple samples. This vignette demonstrates key parameters for controlling performance and handling large-scale analyses. + +## Processing Point Data + +The `run_rosetta()` function accepts point data as a `data.frame`, where each row represents a single observation. Let's use the sample soil property dataset included with the package. + +```{r point_data} +data("MUKEY_PROP") + +# View the structure of the sample data +str(MUKEY_PROP) + +# Run rosetta on the sample property data +system.time({ + res_points <- run_rosetta(MUKEY_PROP[, c("sandtotal_r", "silttotal_r", "claytotal_r", "dbthirdbar_r")]) +}) + +head(res_points) +``` + +## Processing Continuously Varying Raster Data + +Spatial soil property predictions are commonly stored as raster grids. The `run_rosetta()` function can process `SpatRaster` objects directly, computing predictions for every cell in the grid. + +### Creating a Raster Stack from Sample Data + +We'll use the sample spatial dataset (MUKEY_WCS) to create a continuous raster surface by interpolating soil properties. + +```{r raster_setup} +# Convert MUKEY_WCS matrix to SpatRaster +data("MUKEY_WCS", package = "rosettaPTF") +data("MUKEY_PROP", package = "rosettaPTF") + +r_template <- terra::rast(MUKEY_WCS, crs = "EPSG:5070") +terra::ext(r_template) <- c(-1365495, -1358925, 2869245, 2873655) +names(r_template) <- "mukey" + +levels(r_template) <- MUKEY_PROP[, c("mukey", + "sandtotal_r", "silttotal_r", "claytotal_r", + "dbthirdbar_r")] + +r_input <- terra::catalyze(r_template) +plot(r_input) +``` + +### Running Rosetta on Raster Data + +Pass the `SpatRaster` object to `run_rosetta()`. The output is a multi-layer raster containing mean and standard deviation for each predicted parameter. + +```{r raster_processing} +# Process the raster stack +system.time({ + r_output <- run_rosetta(r_input) +}) + +# Inspect the layers +names(r_output) + +# Plot predicted Ksat (log10 cm/day) +plot(r_output[["log10_Ksat_mean"]], main = "Predicted Ksat") +``` + +## Scaling to Large Datasets + +### Parallel Processing with Multiple Cores + +For large rasters, the `cores` argument enables block-wise processing across multiple CPU cores. This parameter controls how the raster is divided and processed in parallel. + +```{r parallel_raster, eval=FALSE} +# Divide the raster into blocks and process each block on separate cores +r_output_parallel <- run_rosetta(r_input, cores = 2) +``` + +Note that with small rasters, as in this example, parallel processing may be significantly slower than sequential processing. + +### Key Parameters for Scaling + +- **`cores`**: Number of CPU cores to use for parallel processing. Set to 1 (default) for sequential processing, or 2+ for parallel block-wise processing. Useful for rasters that are memory-intensive or computationally demanding. + +- **Input format**: `SpatRaster` objects are preferred for spatial workflows. The function handles memory-efficient extraction and output reconstruction automatically. + +### Batch Processing Workflows + +For extremely large regions or high-resolution grids, consider processing tiles or regions sequentially: + +```{r batch_example, eval=FALSE} +# Example: process raster in regional tiles +tiles <- terra::getTileExtents(r_input, 125) + +results <- terra::merge(terra::sprc(apply(tiles, 1, function(x) { + terra::window(r_input) <- x + run_rosetta(r_input) +}))) +``` + +## Advanced Options + +### Controlling Parameter Estimation Scale + +By default, parameters like `alpha`, `npar`, and `Ksat` are returned on a logarithmic (log10) scale. Alternative scales are available via the `estimate_type` argument: + +```{r estimate_scales} +# Linear scale estimates +res_linear <- run_rosetta(MUKEY_PROP[, c("sandtotal_r", "silttotal_r", "claytotal_r", "dbthirdbar_r")], + estimate_type = "arith") + +# Geometric mean (recommended for log-transformed parameters) +res_geo <- run_rosetta(MUKEY_PROP[, c("sandtotal_r", "silttotal_r", "claytotal_r", "dbthirdbar_r")], + estimate_type = "geo") +``` + +### Bootstrap Ensemble + +By default, predictions include the full 1,000-member bootstrap ensemble for uncertainty quantification. The output includes both mean and standard deviation for each parameter. + +```{r uncertainty} +# The output includes uncertainty estimates +head(res_points[, c("log10_Ksat_mean", "log10_Ksat_sd")]) +``` + +## Summary + +Key considerations for high-throughput analysis: + +1. Use `SpatRaster` objects as input for spatial workflows; the function handles data conversion automatically. +2. Set `cores > 1` to enable parallel block-wise processing for large rasters. +3. Choose `estimate_type` based on your application requirements. +4. For extremely large regions, consider tiling or regional batch processing workflows. From 6558c578d7349eda9d30a426859bcda34fd4b5c5 Mon Sep 17 00:00:00 2001 From: Andrew Gene Brown Date: Fri, 6 Mar 2026 14:01:13 -0800 Subject: [PATCH 2/2] build: update R-CMD-check.yml - Update Ubuntu version and Python version in workflow --- .github/workflows/R-CMD-check.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/R-CMD-check.yml b/.github/workflows/R-CMD-check.yml index 865bcf6..6d574db 100644 --- a/.github/workflows/R-CMD-check.yml +++ b/.github/workflows/R-CMD-check.yml @@ -26,7 +26,7 @@ jobs: - {os: windows-latest, r: 'release'} - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} - {os: ubuntu-latest, r: 'release'} - - {os: ubuntu-20.04, r: '3.6'} + - {os: ubuntu-22.04, r: '3.6'} env: R_REMOTES_NO_ERRORS_FROM_WARNINGS: true @@ -42,7 +42,7 @@ jobs: - uses: actions/setup-python@v4 with: - python-version: '3.11' # Version range or exact version of a Python version to use, using SemVer's version range syntax + python-version: '3.14' # Version range or exact version of a Python version to use, using SemVer's version range syntax architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified - uses: r-lib/actions/setup-pandoc@v2