Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read more daily input #228

Merged
merged 34 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a453395
Updated submodule to `read_more_daily_input`
Jan 10, 2023
e0329b1
New constant: MAX_INPUT_COLUMNS
Jan 11, 2023
26d8006
Read and transfer new weather input values
Jan 11, 2023
aac3d5f
New scaling factors and flags
Jan 11, 2023
ba7c61f
New input calculations/interpolation to `rSW2_setAllWeather()`
Jan 11, 2023
7e55a7f
Merge branch 'release/devel_v6.0.0' into read_more_daily_input
Jan 17, 2023
1c7b55b
Updated submodule
Jan 17, 2023
8b8390f
Adjusted functions for new input flag array on SOILWAT2 side
Jan 17, 2023
3fb9828
Correct "nINT" size to include MAX_INPUT_COLUMNS
Jan 17, 2023
53e8c34
New function: `strip_weather_data_NA_columns()`
Feb 13, 2023
66db0e2
Updated submodule
Feb 13, 2023
df3ea0d
Reversed commit 53e8c34891b6a6ef98a32d90a78fd0d353e4c356
Feb 21, 2023
4203367
`swWeatherData` mimics "allHist" from SOILWAT2
Feb 21, 2023
58cc60e
Merge branch 'release/devel_v6.0.0' into read_more_daily_input
dschlaep May 2, 2023
b9ca8c7
Update SOILWAT2 to latest version on "read_more_daily_input"
dschlaep Jun 2, 2023
8de12d7
Update SOILWAT2 (v7.0.0) example inputs
dschlaep Jun 2, 2023
e65f89e
Fix updated "MonthlyScalingParams"
dschlaep Jun 2, 2023
61b6494
Merge branch 'release/devel_v6.0.0' into read_more_daily_input
dschlaep Jun 2, 2023
4d67488
`get_version()` now passes through numeric version objects
dschlaep Jun 2, 2023
2101c3a
Update weather and weather data classes to match SOILWAT2
dschlaep Jun 2, 2023
e115d33
`getWeatherData_folders()` now handles new daily weather inputs
dschlaep Jun 2, 2023
cfc106b
Upgrade mechanism for updated classes "swWeather" and "swWeatherData"
dschlaep Jun 2, 2023
bb024a1
Update all weather-related functions to handle new daily inputs
dschlaep Jun 2, 2023
70ca97a
Update data for package and tests
dschlaep Jun 2, 2023
1648229
Update tests for new daily variables and updated functionality
dschlaep Jun 2, 2023
6b6fbf8
New tests for previous versions of weather history objects
dschlaep Jun 2, 2023
1d79d80
New tests that run with different supported weather input datasets
dschlaep Jun 2, 2023
bb1428b
Updates to vignette for functionality related to new daily variables
dschlaep Jun 2, 2023
785d11c
Update NEWS to reflect changes with new daily input variables
dschlaep Jun 2, 2023
7c4ea2e
Fix some lint problems
dschlaep Jun 2, 2023
44d2363
`get_version()` now again returns consistently a character output
dschlaep Jun 2, 2023
edcb10e
Simplify weather generator unit tests
dschlaep Jun 2, 2023
fa83af5
Update SOILWAT2 to latest version on "read_more_daily_input"
dschlaep Jun 3, 2023
2f427a3
Improve weather generator tests
dschlaep Jun 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "src/SOILWAT2"]
path = src/SOILWAT2
url = https://github.com/DrylandEcology/SOILWAT2
branch = release/devel_v7.0.0
branch = read_more_daily_input
dschlaep marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export(calc_RRs_Chambers2014)
export(calc_RRs_Maestas2016)
export(calc_SMTRs)
export(calc_SiteClimate)
export(calc_dailyInputFlags)
export(check_SWRC_vs_PTF)
export(check_TranspirationRegions)
export(check_ptf_availability)
Expand Down Expand Up @@ -84,6 +85,7 @@ export(get_version)
export(get_years_from_weatherDF)
export(get_years_from_weatherData)
export(has_soilTemp_failed)
export(is_missing_weather)
export(list_matched_swrcs_ptfs)
export(lookup_annual_CO2a)
export(nrow_output)
Expand Down Expand Up @@ -146,7 +148,11 @@ export(swrc_vwc_to_swp)
export(time_columns)
export(update_biomass)
export(update_requested_years)
export(upgrade_weatherHistory)
export(weatherGenerator_dataColumns)
export(weatherHistory)
export(weather_dataAggFun)
export(weather_dataColumns)
exportClasses(swCarbon)
exportClasses(swCloud)
exportClasses(swEstab)
Expand Down
35 changes: 31 additions & 4 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
* `SOILWAT2` updated to v7.0.0
* This version produces nearly identical simulation output
as the previous release under default values.
Small deviations arise due to a fix in the handling of soil moisture values
between field capacity and saturation.
Small deviations arise due to
1. a fix in the handling of soil moisture values
between field capacity and saturation;
2. a fix in the calculation of potential natural vegetation; and
3. a fix in the calculation of climate variables (if used).

## New features
* New method `sw_upgrade()` upgrades objects with
outdated `rSOILWAT2` S4 classes to the current version.
outdated `rSOILWAT2` S4 classes to the current version;
new `upgrade_weatherHistory()` upgrades outdated weather history objects.
* New `get_soilmoisture()` to consistently extract soil moisture content,
volumetric water content (bulk soil), or
volumetric water content for the matric component.
Expand All @@ -21,6 +25,21 @@
* New `time_columns()` returns the output column indices with time information.
* New `nrow_output()` returns the number of time steps in output.

* Daily weather inputs, in addition to the previous variables
maximum air temperature, minimum air temperature, and precipitation amount,
can now process the following variables (issue #229; @dschlaep, @N1ckP3rsl3y):
* Cloud cover (can be replaced by shortwave radiation)
* Wind speed (can be replaced by wind components)
* Wind speed eastward component (optional)
* Wind speed northward component (optional)
* Relative humidity (can be replaced by max/min humidity, specific humidity
dew point temperature, or vapor pressure)
* Maximum relative humidity (optional)
* Minimum relative humidity (optional)
* Specific humidity (optional)
* Dew point temperature (optional)
* Actual vapor pressure (optional)
* Downward surface shortwave radiation (optional)

* This version now handles a variety of soil water retention curves `SWRC`
and pedotransfer functions `PTF` (issue #207, @dschlaep).
Expand Down Expand Up @@ -94,7 +113,15 @@
as inputs (value 0, as previously).
* `SWPtoVWC()` and `VWCtoSWP()` are deprecated in favor of
`swrc_swp_to_vwc()` and `swrc_vwc_to_swp()` respectively.

* Class `swWeather` gains new slots (issue #229)
* `"use_cloudCoverMonthly"`, `"use_windSpeedMonthly"`, and
`"use_humidityMonthly"` which determine whether mean monthly values
(from `swCloud`) or daily values (from `swWeatherData`) are utilized;
* `"dailyInputFlags"` which indicates which of the 14 possible daily
weather variables are present in the inputs;
* `"desc_rsds"` which describes units of input shortwave radiation.
* Class `swWeatherData` gains new columns in slot `"data"` that accommodate
all 14 possible daily weather variables (issue #229).

# rSOILWAT2 v5.4.1
* This version produces identical simulation output as the previous release.
Expand Down
15 changes: 11 additions & 4 deletions R/A_swGenericMethods.R
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ rSW2_version <- function() {
#' @examples
#' get_version(rSOILWAT2::sw_exampleData)
#' get_version(sw_exec(rSOILWAT2::sw_exampleData))
#' get_version(as.numeric_version("4.1.3"))
#' get_version(packageVersion("rSOILWAT2"))
#'
#' @export
setGeneric("get_version", function(object) standardGeneric("get_version"))
Expand All @@ -57,11 +59,16 @@ setMethod(
"get_version",
signature = "ANY",
definition = function(object) {
tmp <- try(object@version, silent = TRUE)
if (inherits(tmp, "try-error")) {
NA_character_
tmp <- try(inherits(object, "numeric_version"), silent = TRUE)
if (inherits(tmp, "try-error") || !isTRUE(tmp)) {
tmp <- try(object@version, silent = TRUE)
if (inherits(tmp, "try-error")) {
NA_character_
} else {
as.character(as.numeric_version(tmp))
}
} else {
as.character(as.numeric_version(tmp))
as.character(object) # numeric version
}
}
)
Expand Down
132 changes: 119 additions & 13 deletions R/D_swWeather.R
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ setClass(
prototype = list(
MonthlyScalingParams = array(
NA_real_,
dim = c(12, 6),
dim = c(12, 8),
dimnames = list(
NULL,
c("PPT", "MaxT", "MinT", "SkyCover", "Wind", "rH")
c("PPT", "MaxT", "MinT", "SkyCover", "Wind", "rH", "ActVP", "ShortWR")
)
)
)
Expand All @@ -72,10 +72,10 @@ setValidity(
val <- TRUE
temp <- dim(object@MonthlyScalingParams)

if (temp[2] != 6) {
if (temp[2] != 8) {
msg <- paste(
"@MonthlyScalingParams must have exactly 6 columns ",
"corresponding to PPT, MaxT, MinT, SkyCover, Wind, rH"
"@MonthlyScalingParams must have exactly 8 columns ",
"corresponding to PPT, MaxT, MinT, SkyCover, Wind, rH, ActVP, ShortWR"
)
val <- if (isTRUE(val)) msg else c(val, msg)
}
Expand Down Expand Up @@ -120,6 +120,52 @@ swMonthlyScalingParams <- function(...) {
do.call("new", args = c("swMonthlyScalingParams", tmp))
}

sw_upgrade_MonthlyScalingParams <- function( # nolint: object_length_linter.
MonthlyScalingParams,
verbose = FALSE
) {
if (verbose) {
message("Upgrading object `MonthlyScalingParams`.")
}

#--- Add new columns (use default values)
default <- swMonthlyScalingParams()
vars_exp <- colnames(default@MonthlyScalingParams)
vars_has <- colnames(MonthlyScalingParams)

if (!all(vars_exp %in% vars_has)) {
res <- default@MonthlyScalingParams
res[, vars_has] <- MonthlyScalingParams[, vars_has]
res
} else {
MonthlyScalingParams
}
}


#' @rdname sw_upgrade
setMethod(
"sw_upgrade",
signature = "swMonthlyScalingParams",
definition = function(object, verbose = FALSE) {
tmp <- try(validObject(object), silent = TRUE)
if (inherits(tmp, "try-error")) {
if (verbose) {
message("Upgrading object of class `swMonthlyScalingParams`.")
}

object@MonthlyScalingParams <- suppressWarnings(
sw_upgrade_MonthlyScalingParams(object@MonthlyScalingParams)
)

#--- Check validity and return
validObject(object)
}

object
}
)



#####################WEATHERSETUP.IN###################################
Expand Down Expand Up @@ -163,7 +209,12 @@ setClass(
pct_SnowRunoff = "numeric",
use_weathergenerator = "logical",
use_weathergenerator_only = "logical",
FirstYear_Historical = "integer"
FirstYear_Historical = "integer",
use_cloudCoverMonthly = "logical",
use_windSpeedMonthly = "logical",
use_humidityMonthly = "logical",
desc_rsds = "integer",
dailyInputFlags = "logical"
),
# TODO: this class should not contain `swMonthlyScalingParams` but
# instead be a composition, i.e., have a slot of that class
Expand All @@ -174,7 +225,14 @@ setClass(
pct_SnowRunoff = NA_real_,
use_weathergenerator = NA,
use_weathergenerator_only = NA,
FirstYear_Historical = NA_integer_
FirstYear_Historical = NA_integer_,
use_cloudCoverMonthly = NA,
use_windSpeedMonthly = NA,
use_humidityMonthly = NA,
desc_rsds = NA_integer_,
# NOTE: 14 must be
# equal to rSW2_glovars[["kSOILWAT2"]][["kINT"]][["MAX_INPUT_COLUMNS"]]
dailyInputFlags = rep(NA, 14L)
)
)

Expand All @@ -185,8 +243,18 @@ setValidity(
sns <- setdiff(slotNames("swWeather"), inheritedSlotNames("swWeather"))

for (sn in sns) {
if (length(slot(object, sn)) != 1) {
msg <- paste0("@", sn, " must have exactly one value.")
n_exp <- if (sn %in% "dailyInputFlags") {
rSW2_glovars[["kSOILWAT2"]][["kINT"]][["MAX_INPUT_COLUMNS"]]
} else {
1L
}

n_has <- length(slot(object, sn))

if (n_has != n_exp) {
msg <- paste0(
"@", sn, " has n = ", n_has, " instead of n = ", n_exp, " value(s)."
)
val <- if (isTRUE(val)) msg else c(val, msg)
}
}
Expand Down Expand Up @@ -233,6 +301,36 @@ swWeather <- function(...) {
}




#' @rdname sw_upgrade
setMethod(
"sw_upgrade",
signature = "swWeather",
definition = function(object, verbose = FALSE) {
tmp <- try(validObject(object), silent = TRUE)
if (inherits(tmp, "try-error")) {
# Upgrade `MonthlyScalingParams` with dedicated upgrade method first;
# `swMonthlyScalingParams()` via `swWeather()` cannot handle
# an increased number of columns in `MonthlyScalingParams` otherwise
object@MonthlyScalingParams <- suppressWarnings(
sw_upgrade_MonthlyScalingParams(
object@MonthlyScalingParams,
verbose = verbose
)
)

if (verbose) {
message("Upgrading object of class `swWeather`.")
}
object <- suppressWarnings(swWeather(object))
}

object
}
)


#' @rdname swWeather-class
#' @export
setMethod(
Expand Down Expand Up @@ -427,14 +525,22 @@ setMethod(
object@pct_SnowRunoff <- readNumeric(infiletext[6])
object@use_weathergenerator <- readLogical(infiletext[7])
object@FirstYear_Historical <- readInteger(infiletext[8])
object@use_cloudCoverMonthly <- readLogical(infiletext[9])
object@use_windSpeedMonthly <- readLogical(infiletext[10])
object@use_relHumidityMonthly <- readLogical(infiletext[11])
object@desc_rsds <- readLogical(infiletext[12])

for (i in seq_len(14)) {
object@dailyInputFlags[i] <- readLogical(infiletext[12 + 1])
}

data <- matrix(data = c(rep(1, 12), rep(NA, 12 * 5)), nrow = 12, ncol = 6)
colnames(data) <- c("PPT", "MaxT", "MinT", "SkyCover", "Wind", "rH")
data <- matrix(data = c(rep(1, 12), rep(NA, 12 * 5)), nrow = 12, ncol = 8)
colnames(data) <- c("PPT", "MaxT", "MinT", "SkyCover", "Wind", "rH", "actVP", "shortWR")
rownames(data) <- c("January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December")

for (i in 21:32) {
data[i - 20, ] <- readNumerics(infiletext[i], 8)[2:8]
for (i in 1:12) {
data[i, ] <- readNumerics(infiletext[12 + 14 + i], 8)[2:8]
}
object@MonthlyScalingParams <- data

Expand Down
Loading