CompartmentedModel
: Compartmented models of disease
- class epydemic.CompartmentedModel
Bases:
Process
The base class a compartmented model of disease, which represents a disease as a collection of discrete compartments with each compartment specifying some facet of the disease’s progression. Nodes transition between compartments with some probability, so the disease’s progression forms a stochastic process in which nodes typically move through several compartments according to the probabilities defined.
When run, a compartmented model generates results consisting of the size of each compartment at the end of the experiment. This can be changed by overriding the
results()
method.
Compartmented models are designed so that their specification is independent of the process dynamics used to simulate them: they can be run in discrete time using synchronous dynamics, or in continuous time using stochastic dynamics.
CompartmentedModel
is an abstract class that must be
sub-classed to define actual disease models. epydemic provides
implementations of the three “reference” compartmented models,
SIR
, SIS
, and SEIR
, as well as several
variants of them: Hethcote [Het00]
provides a survey of a huge range of others.
Model state variables
These are used as tags for attributes on nodes and edges that store the model state.
-
CompartmentedModel.COMPARTMENT:
str
= None State variable holding a node’s compartment.
-
CompartmentedModel.OCCUPIED:
str
= None State variable that’s True for occupied edges.
-
CompartmentedModel.T_OCCUPIED:
str
= None State variable holding the occupation time of an edge.
-
CompartmentedModel.T_HITTING:
str
= None State variable holding the infection time of a node.
Model setup
Immediately before being run, the model is set up by placing all the nodes into compartments. All edges are also marked as unoccupied.
- CompartmentedModel.reset()
Reset the model ready to be built.
- CompartmentedModel.build(params)
Build the process model. This should be overridden by sub-classes, and should create the various elements of the model.
- Parameters:
params (
Dict
[str
,Any
]) – the model parameters
- CompartmentedModel.setUp(params)
Set up the initial population of nodes into compartments.
- Parameters:
params (
Dict
[str
,Any
]) – the simulation parameters
- CompartmentedModel.initialCompartmentDistribution()
Return the initial distribution of nodes to compartments. The result should be a valid distribution, with probabilities summing to one. (A
ValueError
exception is raised if not.) The distribution is used byinitialCompartments()
to set the initial compartment of each node.- Return type:
List
[Tuple
[str
,float
]]- Returns:
a list of (compartment, probability) pairs
- CompartmentedModel.initialCompartments()
Place each node in the network into its initial compartment. The default initialises the nodes into a random compartment according to the initial compartment distribution returned by
initialCompartmentDistribution()
. This method may be overridden to, for example, structure the initial population non-randomly.
- CompartmentedModel.changeInitialCompartment(n, c)
Change the initial compartment of a node. This is called only from
initialCompartments()
, and by default simply callschangeCompartment()
. Overriding this method changes the behaviour of assigning initial compartments independently of the behaviour of later changes.- Parameters:
n (
Any
) – the nodec (
str
) – the new compartment for the node
Building and querying the model
Building a model (within CompartmentedModel.build()
) means specifying
the various compartments, loci, and events, and their associated probabilities.
The initial occupancy of compartments can be set to allow for random initialisation,
and the occupancy of existing components changed to allow better sub-classing.
- CompartmentedModel.addCompartment(c, p=0.0)
Add a compartment to the model. A node is assigned to the compartment initially with the given probability. The probabilities for all compartments in the model must sum to 1.
- Parameters:
c (
str
) – the compartment namep (
float
) – the initial occupancy probability (defaults to 0.0)
. automethod:: CompartmentedModel.changeCompartmentInitialOccupancy
- CompartmentedModel.trackNodesInCompartment(c, name=None)
Add a locus tracking nodes in a given compartment.
- Parameters:
c (
str
) – the compartment to trackname (
Optional
[str
]) – (optional) the name of the locus (defaults to the compartment name)
- Returns:
the locus used to track the nodes
- CompartmentedModel.trackEdgesBetweenCompartments(l, r, name=None)
Add a locus to track edges with endpoint nodes in the given compartments.
- Parameters:
l (
str
) – the compartment of the left noder (
str
) – the compartment of the right nodename (
Optional
[str
]) – (optional) the name of the locus (defaults to a combination of the two compartment names)
- Returns:
the locus used to track the nodes
We can also query the model, which is especially useful within event functions
and when generating results in CompartmentedModel.results()
- CompartmentedModel.compartments()
Return the set of compartments for this model.
- Return type:
List
[str
]- Returns:
the compartments
- CompartmentedModel.compartment(c)
Return all the nodes currently in a particular compartment in a network. This works for all compartments, not just those that are loci for dynamics – but is a lot slower, so it’s better to create a locus is you’re going to access a compartment frequently.
- Parameters:
c (
str
) – the compartment- Return type:
List
[Any
]- Returns:
a collection of nodes
Evolving the network
Events in compartmented models need an interface to change the compartment of nodes, to mark edges used in transmitting the epidemic, and to record the hitting time of nodes.
- CompartmentedModel.setCompartment(n, c)
Set the compartment of a node. This assumes that the node doesn’t already have a compartment set, and so should be used only for initialising new nodes: in all other cases, use
changeCompartment()
.- Parameters:
n (
Any
) – the nodec (
str
) – the new compartment for the node
- CompartmentedModel.getCompartment(n)
Return the compartment of a node.
- Parameters:
n (
Any
) – the node- Return type:
str
- Returns:
its compartment
- CompartmentedModel.changeCompartment(n, c)
Change the compartment of a node.
- Parameters:
n (
Any
) – the nodec (
str
) – the new compartment for the node
- CompartmentedModel.markOccupied(e, t, firstOnly=True)
Mark the given edge as having been occupied by the dynamics, i.e., to have been traversed in transmitting the disease, at time t. By default the time of first occupation is recorded: if firstOnly is False then subsequent occupations overwrite the ealier ones.
- Parameters:
e (
Tuple
[Any
,Any
]) – the edget (
float
) – the simulation time at which it was occupiedfirstOnly (
bool
) – (optional) only record the first occupation time (defaults to True)
- CompartmentedModel.markHit(n, t, firstOnly=True)
Mark the node as “hit”, which happens when the epidemic first reaches the node. By default the first hitting time is recorded: if firstOnly is False then subsequent infections overwrite the ealier ones.
For
SIR
the hitting time is the time of infection; forSIS
the time of first infection; forSEIR
the time of exposure.- Parameters:
n (
Any
) – the nodet (
float
) – the simulation timefirstOnly (
bool
) – (optional) only record the first hitting time (defaults to True)
The network access interface of Process
is extended with methods that
understand the mappings between nodes, edges, and compartments.
- CompartmentedModel.addNode(n, c=None, **kwds)
Add a node to the working network, adding it to the appropriate compartment if one is provided].
- Parameters:
n (
Any
) – the new nodec (
Optional
[str
]) – (optional) compartment for the nodekwds – (optional) node attributes
- CompartmentedModel.removeNode(n)
Remove a node from the working network, updating any affected compartments.
- Parameters:
n (
Any
) – the node
- CompartmentedModel.addEdge(n, m, **kwds)
Add an edge between nodes, adding the edge to any appropriate compartments.
- Parameters:
n (
Any
) – the start nodem (
Any
) – the end nodekwds – (optional) edge attributes
- CompartmentedModel.removeEdge(n, m)
Remove an edge from the working network and from any compartments.
- Parameters:
n (
Any
) – the start nodem (
Any
) – the end node
Generating results
The experiment needs to define a results dict to return when it completes.
- CompartmentedModel.results()
Create a dict of experimental results for the experiment, consisting of the final sizes of all the compartments.
- Return type:
Dict
[str
,Any
]- Returns:
a dict of experimental results
- CompartmentedModel.skeletonise()
Remove unoccupied edges from the network. This leaves the network consisting of only “occupied” edges that were used to transmit the infection between nodes, also known as the contact tree. Note that this process means that further dynamics over the network probably don’t make sense, unless you’re actually wanting to run on the residual network post-infection.
- Return type:
Graph
- Returns:
the network with unoccupied edges removed