Time handling in pyrenew#

Every pyrenew model has a fundamental discrete time unit. All time-aware arrays used in the model should have units expressible as integer multiples of this fundamental unit.

The fundamental time unit should represent a period of fixed (or approximately fixed) duration. That is, “days” could make for a good fundamental time unit; “months” would not, since different months represent different absolute lengths of time.

For many infectious disease renewal models of interest, the fundamental time unit will be days, and we will proceed with this tutorial treating days as our fundamental unit.

pyrenew deals with time having RandomVariables carry information about (i) their own time unit expressed relative to the fundamental unit (t_unit) and (ii) the starting time, t_start, measured relative to t = 0 in model time in fundamental time units.

The tuple (t_unit, t_start) can encode different types of time series data. For example:

Description

t_unit

t_start

Daily starting on day two

1

1

Weekly starting on week two

7

7

Daily starting on day 40

1

39

Biweekly starting on day 40

14

39

Daily, with the first observation starting five days before the model (as in the seeding process)

1

-5

How it relates to periodicity#

The PeriodicBroadcaster() class provides a way of tiling and repeating data accounting starting time, but it does not encode the time unit, only the period length and starting point. Furthermore, samples returned from PeriodicEffect.sample() and RtPeriodicDiffProcess.sample() both currently return daily values shifted so that the first entry of their arrays matches day 0 in the model.

Unimplemented features#

The following section describes some preliminary design principles that may be included in future versions of pyrenew.

Validation#

With random variables possibly spanning different time scales, e.g., weekly, daily, hourly, the metaclass Model should ensure random variables within the model share the same time unit.

Array alignment#

Using t_unit and t_start, random variables should be able to align input and output data. For example, in the case of the RtInfectionsRenewalModel.sample(), the computed values of Rt and infections are padded left with nan values to account for the seeding process. Instead, we expect to either pre-process the padding leveraging the t_start information of the involved variables or simplify the process via a function call that aligns the arrays. A possible implementation could be a method align() that takes a list of random variables and aligns them based on the t_unit and t_start information, e.g.:

Rt_aligned, infections_aligned = align([Rt, infections])