Output depends on the time when the code is executed
Closed this issue · 0 comments
rSOILWAT2
produces (slightly) different outputs depending on the time the code is executed -- independent of inputs. The output varies depending on whether year (when the simulation is run) is a leap year or not.
This issue is caused by a bug in SOILWAT2
, see DrylandEcology/SOILWAT2#273
To reproduce this error: (i) change your time or (ii) modify function src/SOILWAT2/Times.c/Time_now()
. Here code for the latter option:
# Produce "master-branch" output (dependent on user's current year):
devtools::clean_dll()
devtools::load_all()
output_ref <- sw_exec(inputData = rSOILWAT2::sw_exampleData)
# Modify SOILWAT2 function `Time_now()` to return a fixed time of a non-leap year (here, 1970):
void Time_now(void) {
/* =================================================== */
/*
time_t x = time(NULL );
memcpy(&_tym, (struct tm *) localtime(&x), sizeof(struct tm));
*/
// Initialize to Jan 1, 1970
_tym.tm_year = 70;
_tym.tm_mon = 0;
_tym.tm_mday = 1;
_tym.tm_hour = 0;
_tym.tm_min = 0;
_tym.tm_sec = 0;
mktime(&_tym);
_reinit();
}
# Compile and produce output
devtools::clean_dll()
devtools::load_all()
output_ref1970 <- sw_exec(inputData = rSOILWAT2::sw_exampleData)
# Modify function `Time_now()` to return a fixed time of a leap year (here, 1980):
...
_tym.tm_year = 80;
...
# Compile and produce output
devtools::clean_dll()
devtools::load_all()
output_ref1980 <- sw_exec(inputData = rSOILWAT2::sw_exampleData)
# Modify function `Time_now()` to return a fixed time of another non-leap year (here, 1990):
...
_tym.tm_year = 90;
...
# Compile and produce output
devtools::clean_dll()
devtools::load_all()
output_ref1990 <- sw_exec(inputData = rSOILWAT2::sw_exampleData)
# Compare output
all.equal(output_ref, output_ref1970)
all.equal(output_ref, output_ref1980)
all.equal(output_ref1970, output_ref1980)
all.equal(output_ref1970, output_ref1990)
--> depending on user time leap/non-leap year, output_ref
will be either identical to output_ref1970
(non-leap year) or to output_ref1980
(leap year), but not both because output_ref1970
and output_ref1980
are different -- whereas Output_ref1970
and Output_ref1990
are identical (both non-leap years)
all.equal(output_ref1970, output_ref1980)
[1] "Attributes: < Component “AET”: Attributes: < Component “Day”: Mean relative difference: 0.003021888 > >"
[2] "Attributes: < Component “AET”: Attributes: < Component “Month”: Mean relative difference: 0.002148168 > >"
[3] "Attributes: < Component “AET”: Attributes: < Component “Week”: Mean relative difference: 0.002509078 > >"
[4] "Attributes: < Component “AET”: Attributes: < Component “Year”: Mean relative difference: 0.0005890469 > >"
...
all.equal(output_ref1970, output_ref1990)
[1] TRUE