import matplotlib.pyplot as plt
import numpy as np
from sympy import Max
from epymorph.kit import *
from epymorph.adrio import acs5
Seasonality Beta Editing
SCENARIO:
In many modeling scenarios, it is important to account for seasonal changes in the transmission rate of a pathogen. A classic example is measles, which typically circulates amongst school-aged children. Transmission rate is assumed to be higher during the academic year, but lower in the summer months, when there is less indoor contact between school-aged children. We can address this issue by assuming a time-varying rate of transmission in the model. The exercises in this vignette show you how to do this in epymorph
, as well as exploring how seasonally-changing transmission rates can lead to stable cycling of a disease.
Exercise
class SIRS(CompartmentModel):
"""Defines a compartmental IPM for a generic SIR model."""
= [
compartments 'S'),
compartment('I'),
compartment('R'),
compartment(
]
= [
requirements 'beta', type=float, shape=Shapes.TxN,
AttributeDef(='infectivity'),
comment'gamma', type=float, shape=Shapes.TxN,
AttributeDef(='recovery rate'),
comment'latent', type=float, shape=Shapes.TxN,
AttributeDef(='recovery rate'),
comment
]
def edges(self, symbols):
= symbols.all_compartments
[S, I, R] = symbols.all_requirements
[β, γ, l]
= Max(1, S + I + R)
N
return [
=β * S * I / N),
edge(S, I, rate=γ * I),
edge(I, R, rate=l * R),
edge(R, S, rate ]
class Step_Beta(ParamFunctionTimeAndNode):
def evaluate1(self, day: int, node_index: int) -> float:
= 1.0
winter_beta = 0.5
summer_beta = 120
summer_start = 221
summer_end = day % 365
t_mod
if summer_start <= t_mod <= summer_end:
= summer_beta
x
else:
= winter_beta
x
return x
= CountyScope.in_counties(['Maricopa, AZ'], year=2020)
scope = SIRS()
my_ipm = mm.No()
null_mm
= SingleStrataRUME.build(
rume =my_ipm,
ipm=null_mm,
mm=init.SingleLocation(location=0, seed_size=5),
init=scope,
scope=TimeFrame.of("2015-01-01", 365 * 3),
time_frame={
params'beta': Step_Beta(),
'gamma': 1 / 3,
'latent': 1 / 120,
'population': acs5.Population(),
} )
# Evaluate the transmission rates
= (
beta_values
Step_Beta()
.with_context(=rume.scope,
scope=rume.time_frame,
time_frame
)
.evaluate()
)
### GRAPH ###
= plt.subplots()
fig, ax
ax.plot(beta_values)set(title="beta function", ylabel="beta", xlabel="days")
ax.
fig.tight_layout() plt.show()
= BasicSimulator(rume)
sim with sim_messaging(live = False):
= sim.run(
out =default_rng(5),
rng_factory
)
out.plot.line(=out.rume.scope.select.all(),
geo=out.rume.time_frame.select.all(),
time=out.rume.ipm.select.compartments("I"),
quantity="Infectious dynamics with seasonal forcing",
title )
Loading gpm:all::init::population (epymorph.adrio.acs5.Population):
|####################| 100% (0.992s)
Running simulation (BasicSimulator):
• 2015-01-01 to 2017-12-30 (1095 days)
• 1 geo nodes
|####################| 100%
Runtime: 0.214s