swmmr
swmmr copied to clipboard
read_out() as.POSIXct "GMT" stamp
Hi,
I'm having trouble with the referenced line in read_out
:
time <- as.POSIXct(GetSwmmTimes(), tz = "GMT", origin = "1899-12-30")
In my use case, I am in eastern USA, and use the "America/Panama" time zone for my data (i.e., eastern time with no daylight savings). So the rainfall and climate data that is fed to my SWMM models is in year round Eastern Standard, -5 offset, as is my flow data that I use for calibration.
But then the line referenced above seems to reads my model output and stamp it as GMT, which it is not. Then if I convert that GMT time series to "America/Panama" via standard conversion tools, I will have subtracted 5 hours off of my data creating a lag between simulated and observed.
My current workaround is to read the output with read_out
, then convert those data to a data.frame (as I'm more comfortable manipulating date/times there as opposed to with xts objects), and then I do a super kludgey substring/paste to rip off the "GMT" and stick on "-0500" as tz, basically to undo what read_out() does. Relevant code section from my obj_fun() function is below. Per all my testing thus far this works, but I'm wondering if I'm missing something or if this could actually be a problem for others as well.
## Read sim result
## iType: 0 subs; 1 nodes; 2 links; 3 sys vars
simAll <- read_out(file=swmm_files$out, iType=2,
object_name="l3883", vIndex=0) # see docs for vIndex vals
sim <- simAll[["l3883"]]$flow_rate # directly access to xts object
## SWMMR xts to plain data frame
simDf <- data.frame(dt=index(sim),
sim=coredata(sim))
## Ok rough fix of mis-stamped GMT to EST... here we go
simDf$dt <- as.POSIXct(paste(substr(simDf$dt,1,16), "-0500"),
format="%Y-%m-%d %H:%M %z", tz="America/Panama")
## Merge simulated and observed into single df
combDf <- merge(obs, simDf, all=FALSE)
## Pass merged DF to objective fun
return(nseFun(combDf)*-1)
As a fix, I could imagine adding another input arg to the read_out
function that would take the user's preferred time stamp and pass that to the as.POSIXct
call. I've gone through some of the source files, but the approach/tooling with Rcpp is a bit beyond my current capabilities.
Any feedback appreciated.
Thanks for reporting this!
If you need a quick solution, I would suggest to check out the fantastic lubridate package and simply override the time zone.
The next option would be to change the line
https://github.com/dleutnant/swmmr/blob/3e373e6399a6b25f1644d86a36f2c11b9a73510b/R/read_out.R#L116
and insert either (1) the user’s current timezone, i.e. the one which R found at startup or (2) add a new argument to the function tz = Sys.timezone()
and use this as a parameter in the line shown above (of course, a fallback tz could be set if R fails to detect the time zone.
Thanks Dominik.
What I have above works for me as a workaround, but I just looked and it does appear lubridate has a force_tz
function that many would probably find cleaner than my as.POSIX(paste(substr(..)))
construct. Or modifying the function itself as you suggest.
Flagging this for @mrament and @CChaoE17 as I know they may need a heads up on it.