Skip to content

Commit 6782f36

Browse files
committed
Merge branch 'develop'
2 parents a83636a + b5e5334 commit 6782f36

85 files changed

Lines changed: 134269 additions & 651 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,7 @@ inst/doc
4949
# prevent readme html from accidentally getting pushed
5050
README.html
5151
.Rproj.user
52+
53+
# ignore test stuff
54+
inst/extdata/out/w8*
55+
inst/extdata/rh_dev

DESCRIPTION

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
Package: RHESSysIOinR
22
Type: Package
33
Title: Tools for Running RHESSys from R
4-
Version: 0.0.0.9001
4+
Version: 2.0.0
55
Date: 2016-09-11
6-
Author: Ryan R. Bart
6+
Author: Ryan R. Bart, Will Burke
77
Maintainer: Ryan R. Bart <ryanrbart@ucsb.edu>
88
Description: This package contains functions for the setup of RHESSys files,
99
calibration and simulation of RHESSys, and the analysis of RHESSys output.
@@ -20,10 +20,15 @@ Imports:
2020
lhs,
2121
readr,
2222
tibble,
23-
data.table
24-
RoxygenNote: 7.1.0
25-
Suggests: testthat,
23+
data.table,
24+
sensitivity,
25+
yaml
26+
RoxygenNote: 7.1.1
27+
Suggests:
28+
testthat (>= 3.0.0),
2629
knitr,
27-
rmarkdown
30+
rmarkdown,
31+
gert
2832
VignetteBuilder: knitr
2933
Encoding: UTF-8
34+
Config/testthat/edition: 3

NAMESPACE

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
export(IOin_clim)
4+
export(IOin_def_pars_simple)
5+
export(IOin_def_pars_sobol)
6+
export(IOin_hdr)
7+
export(IOin_output_filters)
8+
export(IOin_output_vars)
9+
export(IOin_rhessys_input)
10+
export(IOin_std_pars)
11+
export(IOin_tec_std)
312
export(add_dates)
13+
export(build_output_filter)
414
export(build_redefine)
515
export(cal.wyd)
616
export(change_def_file)
717
export(cleanup_rhessys)
8-
export(clim_auto)
918
export(compile_rhessys)
1019
export(evaluation)
1120
export(generate_input_files)
1221
export(generate_option_sets)
13-
export(input_tec)
22+
export(insert_in_worldfile)
1423
export(make_all_option_table)
1524
export(make_clim_base_file)
1625
export(make_dated_seq)
@@ -19,24 +28,30 @@ export(make_option_set_combinations)
1928
export(make_rhessys_folders)
2029
export(make_tec_file)
2130
export(mkdate)
31+
export(modify_output_filter)
2232
export(patch_fam_agg)
2333
export(process_input_preexisting_table)
2434
export(read_clim)
35+
export(read_output_filter)
2536
export(read_world)
2637
export(readin_rhessys_output)
2738
export(readin_rhessys_output_cal)
2839
export(readin_rhessys_output_old)
2940
export(rhessys_command)
3041
export(run_rhessys)
42+
export(run_rhessys_multi)
43+
export(run_rhessys_single)
3144
export(select_output_variables)
3245
export(select_output_variables_R)
3346
export(select_output_variables_w_awk)
3447
export(select_parameter_sets)
3548
export(separate_canopy_output)
3649
export(tec_repeat)
3750
export(watbal_basin)
51+
export(watbal_basin_of)
3852
export(watbal_patch)
3953
export(watbal_patch_mult)
54+
export(write_output_filter)
4055
export(write_sample_clim)
4156
importFrom(data.table,"%between%")
4257
importFrom(data.table,"%like%")

R/IOin_clim.R

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#' IOin_clim
2+
#'
3+
#' Generate input for run_rhessys climate basestation input
4+
#' @param base_station_id Base station ID.
5+
#' @param x_coordinate X coordinate.
6+
#' @param y_coordinate Y coordinate.
7+
#' @param z_coordinate Z coordinate.
8+
#' @param effective_lai Effective LAI.
9+
#' @param screen_height Screen height.
10+
#' @param annual_prefix Prefix for annual climate inputs.
11+
#' @param num_non_critical_annual_sequences Number of non critical annual climate inputs. Defaults to 0.
12+
#' @param monthly_prefix Prefix for monthly climate inputs.
13+
#' @param num_non_critical_monthly_sequences Number of non critical annual climate inputs. Defaults to 0.
14+
#' @param daily_prefix Prefix for daily climate inputs.
15+
#' @param num_non_critical_daily_sequences Number of non critical annual climate inputs. Defaults to 0.
16+
#' @param hourly_prefix Prefix for hourly climate inputs.
17+
#' @param num_non_critical_hourly_sequences Number of non critical annual climate inputs. Defaults to 0.
18+
#'
19+
#' @author Will Burke
20+
#'
21+
#' @export
22+
23+
IOin_clim = function(base_station_id,
24+
x_coordinate,
25+
y_coordinate,
26+
z_coordinate,
27+
effective_lai,
28+
screen_height,
29+
annual_prefix = "annual",
30+
num_non_critical_annual_sequences = 0,
31+
monthly_prefix = "monthly",
32+
num_non_critical_monthly_sequences = 0,
33+
daily_prefix = "daily",
34+
num_non_critical_daily_sequences = 0,
35+
hourly_prefix = "hourly",
36+
num_non_critical_hourly_sequences = 0) {
37+
38+
39+
40+
output_clim_base = data.frame(
41+
"values" = c(
42+
base_station_id,
43+
x_coordinate,
44+
y_coordinate,
45+
z_coordinate,
46+
effective_lai,
47+
screen_height,
48+
annual_prefix,
49+
num_non_critical_annual_sequences,
50+
monthly_prefix,
51+
num_non_critical_monthly_sequences,
52+
daily_prefix,
53+
num_non_critical_daily_sequences,
54+
hourly_prefix,
55+
num_non_critical_hourly_sequences
56+
),
57+
"vars" = c(
58+
"base_station_id",
59+
"x_coordinate",
60+
"y_coordinate",
61+
"z_coordinate",
62+
"effective_lai",
63+
"screen_height",
64+
"annual_climate_prefix",
65+
"number_non_critical_annual_sequences",
66+
"monthly_climate_prefix",
67+
"number_non_critical_monthly_sequences",
68+
"daily_climate_prefix",
69+
"number_non_critical_daily_sequences",
70+
"hourly_climate_prefix",
71+
"number_non_critical_hourly_sequences"
72+
)
73+
)
74+
75+
return(output_clim_base)
76+
}

R/IOin_def_pars_simple.R

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#' IOin_def_pars_simple
2+
#'
3+
#' The definition file parameters to modify. This input function generates an input parameter object, either for a single simulation,
4+
#' or using simple random sampling over a set range (based on percent difference from input values). This later functionality can be put into
5+
#' a seperate funciton later if desired.
6+
#' @param ... Any number of lists, each containing 3 elements in format: list("<def file>", "<parameter name>", <value>)
7+
#' @param n The number of parameter sets to generate.
8+
#' @param pct_range The percent range of variation from input values over which sampling (if any), will happen.
9+
#' @param rm_dup TRUE/FALSE should duplicate def file + variable entries be automatically removed? A warning will occur regardless.
10+
#'
11+
#' @author Will Burke
12+
#'
13+
#' @export
14+
15+
# pars = list(list("defs/veg_p301_conifer.def", "epc.allocation_flag","dickenson"),
16+
# list("defs/veg_p301_conifer.def", "epc.alloc_frootc_leafc", 1),
17+
# list("defs/veg_p301_conifer.def", "epc.alloc_stemc_leafc", 0.6),
18+
# list("defs/veg_p301_conifer.def", "epc.netpabs_shade", 0.2))
19+
20+
# --- IMPORTANT DATA ASSUMPTIONS ---
21+
# We can discuss revising this, but this code (and potentially other I(WB) write) will assume that parameters
22+
# for a single run will use the following data format (as the ultimate structure that gets passed to run_rhessys_core)
23+
# <list, length = num of unique def file params to change>
24+
# <list, length = 3, elements in order: def file path, variable name, value to be set to>
25+
# < repeat above format for each unique def file variable>
26+
#
27+
# 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
28+
# there would be a vector of values for each def file variable. Ex:
29+
# <list, length = num of unique def file params to change>
30+
# <list, length = 3, elements in order: def file path, variable name, VECTOR of values to be set to>
31+
# < repeat above format for each unique def file variable>
32+
#
33+
# Def file variables not being varied, or which don't make sense to be
34+
# (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
35+
# that are the same length. These can then be iterated through or lapply'd across, potentially in parallel.
36+
#
37+
# How these data structures are achieved can vary by IOin function/type of parameter variation, since different methods will require
38+
# different inputs (see the simplest option I could come up with below)
39+
40+
IOin_def_pars_simple = function(..., n = 1, pct_range = 0.25, rm_dup = F) {
41+
42+
pars = list(...)
43+
44+
# if ... is already a list of lists, ie you're inputting the output of this function, unlist to keep foramt correct
45+
if (length(pars) == 1 && all(lapply(pars[[1]], length) == 3)) {
46+
pars = pars[[1]]
47+
}
48+
49+
# some checks here, should get done regardless but mostly important for multiple param sets
50+
if (any(lapply(pars, length) != 3)) {
51+
stop("Each input list must have 3 elements - 1) file path to def file 2) def file variable 3) value")
52+
}
53+
54+
# name some things to be helpful
55+
name_pars = function(x) {
56+
names(x) = c("Def_file", "Variable", "Value")
57+
return(x)
58+
}
59+
pars = lapply(pars, name_pars)
60+
61+
# check for duplicate def_file + variable entries, if rm_dup is T, keep only the first
62+
file_var = paste0(sapply(pars, "[[",1), "--", sapply(pars, "[[",2))
63+
if (length(pars[duplicated(file_var)]) > 0) {
64+
warning("There are duplicate def file + variable entries, these should be corrected before running RHESSys.")
65+
if (rm_dup) {
66+
pars[duplicated(file_var)] = NULL
67+
cat("Duplicate def file + variable entries have been removed.\n")
68+
}
69+
}
70+
71+
if (n > 1) {
72+
# only vary the variables that are numbers
73+
values = unlist(lapply(pars, "[[", 3))
74+
values = suppressWarnings(as.numeric(values))
75+
#if (any(is.na(values))) {
76+
#cat() # idk guess doesn't matter
77+
#}
78+
79+
value_sets = lapply(values[!is.na(values)], function(x) runif(n = n, min = x - (pct_range * x), max = x + (pct_range * x)))
80+
pars[!is.na(values)] = mapply(function(x, y) {x[[3]] = y; return(x)}, x = pars[!is.na(values)], y = value_sets, SIMPLIFY = F)
81+
82+
if (any(is.na(values))) {
83+
pars[is.na(values)] = lapply(pars[is.na(values)], function(x) {x[[3]] = rep.int(x[[3]], n); return(x)})
84+
}
85+
86+
}
87+
88+
return(pars)
89+
90+
}

R/IOin_def_pars_sobol.R

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#' IOin_def_pars_sobol
2+
#'
3+
#' Geneartes multiple def file changes based on sobol sensativity.
4+
#' @param ... Any number of lists, each containing 3 elements in format: list("<def file>", "<parameter name>", <value>)
5+
#' @param nboot The number of bootstraps to run for sobol2007
6+
#' @param rm_dup TRUE/FALSE should duplicate def file + variable entries be automatically removed? A warning will occur regardless.
7+
8+
#' @author Will Burke
9+
#'
10+
#' @export
11+
12+
13+
IOin_def_pars_sobol = function(..., nboot = 100, rm_dup) {
14+
15+
pars = list(...)
16+
17+
# if ... is already a list of lists, ie you're inputting the output of this function, unlist to keep format correct
18+
if (length(pars) == 1 && all(lapply(pars[[1]], length) == 3)) {
19+
pars = pars[[1]]
20+
}
21+
# some checks here, should get done regardless but mostly important for multiple param sets
22+
if (any(lapply(pars, length) != 3)) {
23+
stop("Each input list must have 4 elements - Def_file, Variable, Prior_dist")
24+
}
25+
# name some things to be helpful
26+
name_pars = function(x) {
27+
names(x) = c("Def_file", "Variable","Prior_dist")
28+
return(x)
29+
}
30+
pars = lapply(pars, name_pars)
31+
32+
# check for duplicate def_file + variable entries, if rm_dup is T, keep only the first
33+
file_var = paste0(sapply(pars, "[[",1), "--", sapply(pars, "[[",2))
34+
if (length(pars[duplicated(file_var)]) > 0) {
35+
warning("There are duplicate def file + variable entries, these should be corrected before running RHESSys.")
36+
if (rm_dup) {
37+
pars[duplicated(file_var)] = NULL
38+
cat("Duplicate def file + variable entries have been removed.\n")
39+
}
40+
}
41+
42+
par_dists = sapply(pars, "[[", 3)
43+
#colnames(par_dists) = sapply(pars, "[[", 2)
44+
45+
sobol_out = sensitivity::sobol2007(model = NULL, X1 = par_dists, X2 = par_dists, nboot = nboot)
46+
47+
pars_out = mapply(function(x, y) {x[[3]] = y; return(x)}, x = pars, y = as.data.frame(sobol_out$X), SIMPLIFY = F)
48+
49+
return(pars_out)
50+
51+
}

R/IOin_hdr.R

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#' IOin_hdr
2+
#'
3+
#' Creates a header file based on specified parameter definition files and climate basestations.
4+
#' @param basin Path to basin parameter definition file.
5+
#' @param hillslope Path to hillslope parameter definition file.(s)
6+
#' @param zone Path to zone parameter definition file(s).
7+
#' @param soil Path to soil parameter definition file(s).
8+
#' @param landuse Path to landuse parameter definition file(s).
9+
#' @param stratum Path to stratum parameter definition file(s).
10+
#' @param fire Path to fire parameter definition file.
11+
#' @param fire_grid_prefix Path and basename/prefix name of the fire grid files used for the RHESSys WMFire model.
12+
#' @param spinup Path to spinup parameter definition file(s).
13+
#' @param basestations Path to basin climate basestation file(s).
14+
#'
15+
#' @author Will Burke
16+
#'
17+
#' @export
18+
19+
# LIST NAMING - MIRRORS INPUT ARS
20+
# shorter, and still clear since the whole object is the header info, don't need to specify def
21+
# ORDERING - keep in current order, same as args, should use names to reference though
22+
23+
24+
IOin_hdr = function(basin,
25+
hillslope,
26+
zone,
27+
soil,
28+
landuse,
29+
stratum,
30+
fire = NULL,
31+
fire_grid_prefix = NULL,
32+
spinup = NULL,
33+
basestations) {
34+
35+
input_hdr_list <- list()
36+
37+
# TODO check for each file, warn if missing - should work for everything expect clim which might be generated
38+
# remember each input can be a character vector of length 1+
39+
40+
input_hdr_list$basin_def <- basin
41+
input_hdr_list$hillslope_def <- hillslope
42+
input_hdr_list$zone_def <- zone
43+
input_hdr_list$soil_def <- soil
44+
input_hdr_list$landuse_def <- landuse
45+
input_hdr_list$stratum_def <- stratum
46+
input_hdr_list$fire_def <- fire
47+
input_hdr_list$fire_grid_prefix <- fire_grid_prefix
48+
input_hdr_list$spinup <- spinup
49+
input_hdr_list$base_stations <- basestations
50+
51+
return(input_hdr_list)
52+
53+
}

0 commit comments

Comments
 (0)