Closed cliffckerr closed 2 weeks ago
This topic came up on yesterday's RSV call. Should we enable and distinguish between both (1) modeling parameter inputs sim_time_unit_steps=1 #days
and (2) results display sim_time_display_units=365 #days
?
Yes, love this one. Question: how would this switch work without each parameter explicitly having associated units? (Or maybe that's part of the solution?)
I suggest (responding also to #418) something like:
# Sim in years
s1 = ss.Sim(start=1990, end=2040, dt=0.1, unit='year', diseases='hiv')
# Sim in days
s2 = ss.Sim(start='2025-01-01', end='2025-07-01', dt=7, unit='day', diseases='rsv')
We could probably by default interpret an integer start
and end
as implying years, and a string or datetime
as implying days. For units of days, we should be able to borrow Covasim's logic for handling everything.
Can also make the default start 0, to be agnostic about whether it's a day, year, or just timestep!
Closed by #623
We need to solve how we handle time. I was thinking is that each module could have a time unit defined, which at least initially we could restrict to 'day' or 'year'. Then all parameter values defined in that module would be relative to that module's time unit. (If
unit='day'
, then start and end would be dates; ifunit='year'
, they would be ints/floats, although dates would also work. I was also thinking of a 'none' option, which would just use the timesteps directly.)It would be nice if we had very simple
ss.dur
andss.rate
classes, which are time-unit aware. This would save the user the trouble of remembering to divide/multiply by the correctdt
everywhere. The user wouldn't have to see these; they'd be implemented in the default parameters and merged with user-supplied parameters. So the default for SIR would bepars.dur_inf = ss.dur(6)
, but the user could just supplydiseases=dict(type='sir', dur_inf=6)
and it would get converted a dur based on the default (this is related to the sim API work).The part I really struggled with was how to do the actual integration in
sim.step()
. Should the sim timestep be the smallest of the module timesteps, such that on each sim timestep, each module either runs or ispass
? Or should the sim timestep equal the results timestep, which may or may not correspond to any individual module timestep? And how do we nicely handle results when everything is happening at different times? My best idea was something like this:Some open questions:
update_pre
,update_post
, etc. I haven't figured out how to merge those two, or if we would even want to. How would it work to have an intervention for example that is applied to two modules with different timesteps? When would it even get called?