Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
wburke24 committed Feb 20, 2021
2 parents a83636a + b5e5334 commit 6782f36
Show file tree
Hide file tree
Showing 85 changed files with 134,269 additions and 651 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ inst/doc
# prevent readme html from accidentally getting pushed
README.html
.Rproj.user

# ignore test stuff
inst/extdata/out/w8*
inst/extdata/rh_dev
17 changes: 11 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Package: RHESSysIOinR
Type: Package
Title: Tools for Running RHESSys from R
Version: 0.0.0.9001
Version: 2.0.0
Date: 2016-09-11
Author: Ryan R. Bart
Author: Ryan R. Bart, Will Burke
Maintainer: Ryan R. Bart <ryanrbart@ucsb.edu>
Description: This package contains functions for the setup of RHESSys files,
calibration and simulation of RHESSys, and the analysis of RHESSys output.
Expand All @@ -20,10 +20,15 @@ Imports:
lhs,
readr,
tibble,
data.table
RoxygenNote: 7.1.0
Suggests: testthat,
data.table,
sensitivity,
yaml
RoxygenNote: 7.1.1
Suggests:
testthat (>= 3.0.0),
knitr,
rmarkdown
rmarkdown,
gert
VignetteBuilder: knitr
Encoding: UTF-8
Config/testthat/edition: 3
19 changes: 17 additions & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
# Generated by roxygen2: do not edit by hand

export(IOin_clim)
export(IOin_def_pars_simple)
export(IOin_def_pars_sobol)
export(IOin_hdr)
export(IOin_output_filters)
export(IOin_output_vars)
export(IOin_rhessys_input)
export(IOin_std_pars)
export(IOin_tec_std)
export(add_dates)
export(build_output_filter)
export(build_redefine)
export(cal.wyd)
export(change_def_file)
export(cleanup_rhessys)
export(clim_auto)
export(compile_rhessys)
export(evaluation)
export(generate_input_files)
export(generate_option_sets)
export(input_tec)
export(insert_in_worldfile)
export(make_all_option_table)
export(make_clim_base_file)
export(make_dated_seq)
Expand All @@ -19,24 +28,30 @@ export(make_option_set_combinations)
export(make_rhessys_folders)
export(make_tec_file)
export(mkdate)
export(modify_output_filter)
export(patch_fam_agg)
export(process_input_preexisting_table)
export(read_clim)
export(read_output_filter)
export(read_world)
export(readin_rhessys_output)
export(readin_rhessys_output_cal)
export(readin_rhessys_output_old)
export(rhessys_command)
export(run_rhessys)
export(run_rhessys_multi)
export(run_rhessys_single)
export(select_output_variables)
export(select_output_variables_R)
export(select_output_variables_w_awk)
export(select_parameter_sets)
export(separate_canopy_output)
export(tec_repeat)
export(watbal_basin)
export(watbal_basin_of)
export(watbal_patch)
export(watbal_patch_mult)
export(write_output_filter)
export(write_sample_clim)
importFrom(data.table,"%between%")
importFrom(data.table,"%like%")
Expand Down
76 changes: 76 additions & 0 deletions R/IOin_clim.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#' IOin_clim
#'
#' Generate input for run_rhessys climate basestation input
#' @param base_station_id Base station ID.
#' @param x_coordinate X coordinate.
#' @param y_coordinate Y coordinate.
#' @param z_coordinate Z coordinate.
#' @param effective_lai Effective LAI.
#' @param screen_height Screen height.
#' @param annual_prefix Prefix for annual climate inputs.
#' @param num_non_critical_annual_sequences Number of non critical annual climate inputs. Defaults to 0.
#' @param monthly_prefix Prefix for monthly climate inputs.
#' @param num_non_critical_monthly_sequences Number of non critical annual climate inputs. Defaults to 0.
#' @param daily_prefix Prefix for daily climate inputs.
#' @param num_non_critical_daily_sequences Number of non critical annual climate inputs. Defaults to 0.
#' @param hourly_prefix Prefix for hourly climate inputs.
#' @param num_non_critical_hourly_sequences Number of non critical annual climate inputs. Defaults to 0.
#'
#' @author Will Burke
#'
#' @export

IOin_clim = function(base_station_id,
x_coordinate,
y_coordinate,
z_coordinate,
effective_lai,
screen_height,
annual_prefix = "annual",
num_non_critical_annual_sequences = 0,
monthly_prefix = "monthly",
num_non_critical_monthly_sequences = 0,
daily_prefix = "daily",
num_non_critical_daily_sequences = 0,
hourly_prefix = "hourly",
num_non_critical_hourly_sequences = 0) {



output_clim_base = data.frame(
"values" = c(
base_station_id,
x_coordinate,
y_coordinate,
z_coordinate,
effective_lai,
screen_height,
annual_prefix,
num_non_critical_annual_sequences,
monthly_prefix,
num_non_critical_monthly_sequences,
daily_prefix,
num_non_critical_daily_sequences,
hourly_prefix,
num_non_critical_hourly_sequences
),
"vars" = c(
"base_station_id",
"x_coordinate",
"y_coordinate",
"z_coordinate",
"effective_lai",
"screen_height",
"annual_climate_prefix",
"number_non_critical_annual_sequences",
"monthly_climate_prefix",
"number_non_critical_monthly_sequences",
"daily_climate_prefix",
"number_non_critical_daily_sequences",
"hourly_climate_prefix",
"number_non_critical_hourly_sequences"
)
)

return(output_clim_base)
}
90 changes: 90 additions & 0 deletions R/IOin_def_pars_simple.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#' IOin_def_pars_simple
#'
#' The definition file parameters to modify. This input function generates an input parameter object, either for a single simulation,
#' or using simple random sampling over a set range (based on percent difference from input values). This later functionality can be put into
#' a seperate funciton later if desired.
#' @param ... Any number of lists, each containing 3 elements in format: list("<def file>", "<parameter name>", <value>)
#' @param n The number of parameter sets to generate.
#' @param pct_range The percent range of variation from input values over which sampling (if any), will happen.
#' @param rm_dup TRUE/FALSE should duplicate def file + variable entries be automatically removed? A warning will occur regardless.
#'
#' @author Will Burke
#'
#' @export

# pars = list(list("defs/veg_p301_conifer.def", "epc.allocation_flag","dickenson"),
# list("defs/veg_p301_conifer.def", "epc.alloc_frootc_leafc", 1),
# list("defs/veg_p301_conifer.def", "epc.alloc_stemc_leafc", 0.6),
# list("defs/veg_p301_conifer.def", "epc.netpabs_shade", 0.2))

# --- IMPORTANT DATA ASSUMPTIONS ---
# We can discuss revising this, but this code (and potentially other I(WB) write) will assume that parameters
# for a single run will use the following data format (as the ultimate structure that gets passed to run_rhessys_core)
# <list, length = num of unique def file params to change>
# <list, length = 3, elements in order: def file path, variable name, value to be set to>
# < repeat above format for each unique def file variable>
#
# For a set of def file parameters, regardless of how they are generated, I propose using the same format except instead of a single value
# there would be a vector of values for each def file variable. Ex:
# <list, length = num of unique def file params to change>
# <list, length = 3, elements in order: def file path, variable name, VECTOR of values to be set to>
# < repeat above format for each unique def file variable>
#
# Def file variables not being varied, or which don't make sense to be
# (e.g. text fields like epc.allocation_flag) would need to be replicated so that each def variable list has a vector of target values
# that are the same length. These can then be iterated through or lapply'd across, potentially in parallel.
#
# How these data structures are achieved can vary by IOin function/type of parameter variation, since different methods will require
# different inputs (see the simplest option I could come up with below)

IOin_def_pars_simple = function(..., n = 1, pct_range = 0.25, rm_dup = F) {

pars = list(...)

# if ... is already a list of lists, ie you're inputting the output of this function, unlist to keep foramt correct
if (length(pars) == 1 && all(lapply(pars[[1]], length) == 3)) {
pars = pars[[1]]
}

# some checks here, should get done regardless but mostly important for multiple param sets
if (any(lapply(pars, length) != 3)) {
stop("Each input list must have 3 elements - 1) file path to def file 2) def file variable 3) value")
}

# name some things to be helpful
name_pars = function(x) {
names(x) = c("Def_file", "Variable", "Value")
return(x)
}
pars = lapply(pars, name_pars)

# check for duplicate def_file + variable entries, if rm_dup is T, keep only the first
file_var = paste0(sapply(pars, "[[",1), "--", sapply(pars, "[[",2))
if (length(pars[duplicated(file_var)]) > 0) {
warning("There are duplicate def file + variable entries, these should be corrected before running RHESSys.")
if (rm_dup) {
pars[duplicated(file_var)] = NULL
cat("Duplicate def file + variable entries have been removed.\n")
}
}

if (n > 1) {
# only vary the variables that are numbers
values = unlist(lapply(pars, "[[", 3))
values = suppressWarnings(as.numeric(values))
#if (any(is.na(values))) {
#cat() # idk guess doesn't matter
#}

value_sets = lapply(values[!is.na(values)], function(x) runif(n = n, min = x - (pct_range * x), max = x + (pct_range * x)))
pars[!is.na(values)] = mapply(function(x, y) {x[[3]] = y; return(x)}, x = pars[!is.na(values)], y = value_sets, SIMPLIFY = F)

if (any(is.na(values))) {
pars[is.na(values)] = lapply(pars[is.na(values)], function(x) {x[[3]] = rep.int(x[[3]], n); return(x)})
}

}

return(pars)

}
51 changes: 51 additions & 0 deletions R/IOin_def_pars_sobol.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#' IOin_def_pars_sobol
#'
#' Geneartes multiple def file changes based on sobol sensativity.
#' @param ... Any number of lists, each containing 3 elements in format: list("<def file>", "<parameter name>", <value>)
#' @param nboot The number of bootstraps to run for sobol2007
#' @param rm_dup TRUE/FALSE should duplicate def file + variable entries be automatically removed? A warning will occur regardless.

#' @author Will Burke
#'
#' @export


IOin_def_pars_sobol = function(..., nboot = 100, rm_dup) {

pars = list(...)

# if ... is already a list of lists, ie you're inputting the output of this function, unlist to keep format correct
if (length(pars) == 1 && all(lapply(pars[[1]], length) == 3)) {
pars = pars[[1]]
}
# some checks here, should get done regardless but mostly important for multiple param sets
if (any(lapply(pars, length) != 3)) {
stop("Each input list must have 4 elements - Def_file, Variable, Prior_dist")
}
# name some things to be helpful
name_pars = function(x) {
names(x) = c("Def_file", "Variable","Prior_dist")
return(x)
}
pars = lapply(pars, name_pars)

# check for duplicate def_file + variable entries, if rm_dup is T, keep only the first
file_var = paste0(sapply(pars, "[[",1), "--", sapply(pars, "[[",2))
if (length(pars[duplicated(file_var)]) > 0) {
warning("There are duplicate def file + variable entries, these should be corrected before running RHESSys.")
if (rm_dup) {
pars[duplicated(file_var)] = NULL
cat("Duplicate def file + variable entries have been removed.\n")
}
}

par_dists = sapply(pars, "[[", 3)
#colnames(par_dists) = sapply(pars, "[[", 2)

sobol_out = sensitivity::sobol2007(model = NULL, X1 = par_dists, X2 = par_dists, nboot = nboot)

pars_out = mapply(function(x, y) {x[[3]] = y; return(x)}, x = pars, y = as.data.frame(sobol_out$X), SIMPLIFY = F)

return(pars_out)

}
53 changes: 53 additions & 0 deletions R/IOin_hdr.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#' IOin_hdr
#'
#' Creates a header file based on specified parameter definition files and climate basestations.
#' @param basin Path to basin parameter definition file.
#' @param hillslope Path to hillslope parameter definition file.(s)
#' @param zone Path to zone parameter definition file(s).
#' @param soil Path to soil parameter definition file(s).
#' @param landuse Path to landuse parameter definition file(s).
#' @param stratum Path to stratum parameter definition file(s).
#' @param fire Path to fire parameter definition file.
#' @param fire_grid_prefix Path and basename/prefix name of the fire grid files used for the RHESSys WMFire model.
#' @param spinup Path to spinup parameter definition file(s).
#' @param basestations Path to basin climate basestation file(s).
#'
#' @author Will Burke
#'
#' @export

# LIST NAMING - MIRRORS INPUT ARS
# shorter, and still clear since the whole object is the header info, don't need to specify def
# ORDERING - keep in current order, same as args, should use names to reference though


IOin_hdr = function(basin,
hillslope,
zone,
soil,
landuse,
stratum,
fire = NULL,
fire_grid_prefix = NULL,
spinup = NULL,
basestations) {

input_hdr_list <- list()

# TODO check for each file, warn if missing - should work for everything expect clim which might be generated
# remember each input can be a character vector of length 1+

input_hdr_list$basin_def <- basin
input_hdr_list$hillslope_def <- hillslope
input_hdr_list$zone_def <- zone
input_hdr_list$soil_def <- soil
input_hdr_list$landuse_def <- landuse
input_hdr_list$stratum_def <- stratum
input_hdr_list$fire_def <- fire
input_hdr_list$fire_grid_prefix <- fire_grid_prefix
input_hdr_list$spinup <- spinup
input_hdr_list$base_stations <- basestations

return(input_hdr_list)

}
Loading

0 comments on commit 6782f36

Please sign in to comment.