Skip to main content

diseases

diseases

Diseases: the base class (ss.Disease), diseases with transmission written as code (ss.AgentDisease), the record of who infected whom (InfectionLog), and the textbook models (ss.SIR, ss.SIS, ss.SEIR)

ss.Disease exists so that one class can hold a disease declared from states and transitions, written as code, or both. A declared disease runs with any solver; ss.AgentDisease and other code that works on individual agents runs as agents.

Used with: agents and compartments; declared and coded modules

Classes

Name Description
AgentDisease A transmitted disease written as code, as agents: the plain array operations of an infection, each a method to override
BuiltAfterInit Build what a disease declares in its __init__() (define_states(), define_transitions()) once that has finished
Disease A disease: states people are in and the transitions between them (declared), code, or both
InfectionLog A record of who infected whom, and when: kept by a disease when an analyzer needs it (e.g. ss.infection_log), to trace chains of transmission
SEIR An SEIR model: as ss.SIR, with an exposed (latent) state before people become infectious
SIR An SIR model: susceptible, infected, and recovered, optionally with deaths from infection
SIS An SIS model: people recover from infection and are susceptible again

AgentDisease

diseases.AgentDisease(pars=None, strains=None, **kwargs)

A transmitted disease written as code, as agents: the plain array operations of an infection, each a method to override

Gives the susceptible, infected (and infectious, by default the same), rel_sus, rel_trans, and ti_infected states; seeds init_prev of the people at the start; and each step transmits from transmissibility() to susceptibility() over the sim’s networks (transmit()), counts the new cases in the infection result, and gives them their prognoses (set_prognoses()). A subclass overrides only what it needs: usually set_prognoses(), for what happens to those infected, and step_state(), for how their states change; those infected before birth (over ss.PrenatalNet) go to set_congenital() instead, which a disease with outcomes at birth overrides. Anything else is plain code on the arrays. The betas of the networks are route_betas(), which can be overridden too (e.g. by sex).

With strains=ss.Strains(...), each person carries one strain at a time (self.strain, the index of the strain of their current or last infection, -1 if none), which the disease’s code reads (e.g. in set_prognoses(), with strain_value() for a strain’s values). The strains are transmitted in one pass, each by those infectious with it at its rel_trans; each new case is infected by one of those who reached them in the step, at random, and takes their strain, unless protected against it (strain_sus(): protection from ss.immunity(due_to=<state>, protection=matrix) by the strain they had, or the disease’s own), as a declared disease’s strains are passed on.

An infection in a step happens at its end, so a course scheduled from it starts at the next step: schedule a move dur steps after it at self.ti + 1 + dur, in an ss.TimeArr, and take it when due(). The seeds are dated by the step before the first (self.ti is -1 while they are set), so they have the same course.

A disease that can be written as states and transitions is shorter declared (see ss.SIR), and runs with every solver.

Parameters

Name Type Description Default
pars dict parameters, e.g. beta and init_prev (a fraction, or an ss.bernoulli) None
strains ss.Strains the strains, carried one at a time, sharing the disease’s states (also define_strains()) None
kwargs dict parameters

Example

class SIR(ss.AgentDisease):
    def __init__(self, **kwargs):
        super().__init__()
        self.define_pars(beta=ss.perday(0.05), init_prev=0.01, dur_inf=10)
        self.define_states(ss.BoolState('recovered'), ss.TimeArr('ti_recovered'))
        self.update_pars(**kwargs)

    def step_state(self):
        done = (self.infected & self.ti_recovered.due()).uids
        self.infected[done] = False
        self.recovered[done] = True

    def set_prognoses(self, uids, sources=None):
        super().set_prognoses(uids, sources)
        self.ti_recovered[uids] = self.ti + 1 + self.pars.dur_inf

sim = ss.Sim(diseases=SIR(), networks='random', unit='day', stop=100).run()

# With two strains, the second more transmissible; recovering from one protects fully against it, and partly against the other
class SIRS(SIR):
    def step_state(self):
        super().step_state()
        self.susceptible[self.recovered] = True # Protected only by the immunity of their strain

    def set_prognoses(self, uids, sources=None):
        super().set_prognoses(uids, sources)
        self.recovered[uids] = False

strains = ss.Strains(['H1', 'H3'], rel_trans=[1, 1.5], immunity=ss.immunity(due_to='recovered', protection=[[1, 0.5], [0.5, 1]]))
sim = ss.Sim(diseases=SIRS(strains=strains, name='flu'), networks='random', unit='day', stop=100).run()
sim.diseases.flu.strain # The strain of each person's current or last infection

Methods

Name Description
define_strains Give the disease strains (ss.Strains, also as strains=), carried one at a time: the strain of each person (self.strain, added when the
infect Infect some agents now: those susceptible, counted in infection (except the seeds, which are prevalent), and given their prognoses
init_post Seed init_prev of the people born by the start (not the fetuses of pregnancies begun before it), dated by the step before the first
init_results The counts of the states (one for each ss.BoolState), and the prevalence and new infections
make_naive Reset agents to never having had the disease, for dynamic rescaling: every state to its default, except skip_states
not_naive The agents who have ever been infected, for dynamic rescaling (see ss.Sim.rescale())
record_states The counts of the states, and the prevalence, at the start of the step
set_congenital What happens to those infected before birth (over ss.PrenatalNet; see set_outcomes()): by default, the same as anyone infected (set_prognoses())
set_outcomes Give those just infected their outcomes: those infected before birth (age 0 or less, e.g. over ss.PrenatalNet) by set_congenital(), the rest by set_prognoses()
set_prognoses What happens to those infected, at the end of this step: by default, they are infected and no longer susceptible; override this for more
step Transmit (transmit()), and infect the new cases
strain_sus The fraction of their susceptibility to strain k that each agent (by UID) keeps: 1 − protection from each ss.immunity of the strains,
strain_value The value of key (given to ss.Strains, e.g. dur=[0.5, 1]) for the strain each of some agents carries (1 if they have none)
susceptibility The susceptibility of each agent, by UID: rel_sus, 0 for those not susceptible
transmissibility The transmissibility of each agent, by UID: rel_trans, 0 for those not infectious
transmit Who is infected in this step: by default, from transmissibility() to susceptibility() (see ss.Disease.transmit()); nobody, for a disease with no beta (e.g. one infected only from code, with infect())
update_pars As ss.Module.update_pars(), and strains= for define_strains(), so a subclass that passes its keywords on here takes it too (e.g. ssl.AgentSIR(strains=...))
define_strains
diseases.AgentDisease.define_strains(strains)

Give the disease strains (ss.Strains, also as strains=), carried one at a time: the strain of each person (self.strain, added when the sim is initialized, and set for those infected by transmission, at the start, and by infect(); code that infects people itself sets it)

Parameters
Name Type Description Default
strains Strains the strains; those infected at the start, or by infect() with no strain, have one drawn by its fractions required
infect
diseases.AgentDisease.infect(uids, log=True, strain=None)

Infect some agents now: those susceptible, counted in infection (except the seeds, which are prevalent), and given their prognoses

Parameters
Name Type Description Default
uids uids the agents (e.g. imported cases); those not susceptible are left as they are required
log bool record them in an ss.infection_log, with no source (-1) True
strain str / int / array with strains, the strain they are infected with: its name or index, or one for each agent; by default drawn by the strains’ fractions None
Returns
Name Type Description
The agents infected
Example
flu.infect(sim.people.auids[:20], strain='H3') # 20 imported cases of H3
init_post
diseases.AgentDisease.init_post()

Seed init_prev of the people born by the start (not the fetuses of pregnancies begun before it), dated by the step before the first

init_results
diseases.AgentDisease.init_results()

The counts of the states (one for each ss.BoolState), and the prevalence and new infections

make_naive
diseases.AgentDisease.make_naive(uids, skip_states=('rel_sus', 'rel_trans'))

Reset agents to never having had the disease, for dynamic rescaling: every state to its default, except skip_states

Parameters
Name Type Description Default
uids uids the agents required
skip_states list the names of the states to keep (by default rel_sus and rel_trans, which other modules, e.g. vaccines, may have set) ('rel_sus', 'rel_trans')
not_naive
diseases.AgentDisease.not_naive()

The agents who have ever been infected, for dynamic rescaling (see ss.Sim.rescale())

record_states
diseases.AgentDisease.record_states()

The counts of the states, and the prevalence, at the start of the step

set_congenital
diseases.AgentDisease.set_congenital(uids, sources=None)

What happens to those infected before birth (over ss.PrenatalNet; see set_outcomes()): by default, the same as anyone infected (set_prognoses())

A disease with outcomes at birth overrides this, e.g. ssl.CongenitalDisease (import starsim.library as ssl), which schedules a birth outcome (a stillbirth, a congenital infection) for each.

Parameters
Name Type Description Default
uids uids the people infected before birth required
sources array who infected them, if known None
set_outcomes
diseases.AgentDisease.set_outcomes(uids, sources=None)

Give those just infected their outcomes: those infected before birth (age 0 or less, e.g. over ss.PrenatalNet) by set_congenital(), the rest by set_prognoses()

Parameters
Name Type Description Default
uids uids the agents infected required
sources array who infected them, if known None
set_prognoses
diseases.AgentDisease.set_prognoses(uids, sources=None)

What happens to those infected, at the end of this step: by default, they are infected and no longer susceptible; override this for more

Parameters
Name Type Description Default
uids uids the agents infected required
sources array who infected them, if known None
step
diseases.AgentDisease.step()

Transmit (transmit()), and infect the new cases

strain_sus
diseases.AgentDisease.strain_sus(k)

The fraction of their susceptibility to strain k that each agent (by UID) keeps: 1 − protection from each ss.immunity of the strains, for those in its state (e.g. due_to='recovered') by the strain they had; a disease with protection of its own (e.g. from antibodies) overrides this

Parameters
Name Type Description Default
k int the index of the strain required
strain_value
diseases.AgentDisease.strain_value(key, uids)

The value of key (given to ss.Strains, e.g. dur=[0.5, 1]) for the strain each of some agents carries (1 if they have none)

Parameters
Name Type Description Default
key str the name of the value required
uids array the agents required
susceptibility
diseases.AgentDisease.susceptibility()

The susceptibility of each agent, by UID: rel_sus, 0 for those not susceptible

transmissibility
diseases.AgentDisease.transmissibility()

The transmissibility of each agent, by UID: rel_trans, 0 for those not infectious

transmit
diseases.AgentDisease.transmit(rel_trans=None, rel_sus=None, beta=None)

Who is infected in this step: by default, from transmissibility() to susceptibility() (see ss.Disease.transmit()); nobody, for a disease with no beta (e.g. one infected only from code, with infect())

update_pars
diseases.AgentDisease.update_pars(pars=None, **kwargs)

As ss.Module.update_pars(), and strains= for define_strains(), so a subclass that passes its keywords on here takes it too (e.g. ssl.AgentSIR(strains=...))

BuiltAfterInit

diseases.BuiltAfterInit()

Build what a disease declares in its __init__() (define_states(), define_transitions()) once that has finished

Disease

diseases.Disease(
    *args,
    pars=None,
    strains=None,
    stratify=None,
    solver=None,
    _names=None,
    **kwargs,
)

A disease: states people are in and the transitions between them (declared), code, or both

Declared from its states and transitions, no methods need to be defined, and the disease can be run with any solver (see ss.Sim):

S, I, R = ss.states(3)
sir = ss.Disease(
    infection = S >> I @ 0.3 * I,
    recovery  = ss.Transition(I, R, dur=10),
    init_prev = 0.01,
)

The same disease can be declared in a class body (the class form), which can also add behavior by defining methods; ss.SIR, ss.SIS, and ss.SEIR are written this way.

A disease can also be written as code: a subclass that declares nothing, defines its per-agent arrays (define_states()), and changes them in its own step_state() and step(); it runs as agents. One class can mix the two, e.g. a declared natural history and a coded array that its step() updates after super().step() has taken the declared transitions. Each lifecycle method runs the declared part through the disease’s engine (which, for a disease that declares nothing, has nothing to run), so an override calls super() as for any module. ss.AgentDisease adds transmission written as code: transmit(rel_trans=..., rel_sus=...), the same array operation as a declared transmission’s (see transmit()).

Note: CRN safe as agents.

Parameters

Name Type Description Default
args list transitions and outcomes, named from the variables they are assigned to (one by one, or in a list)
pars dict parameter values by name None
transitions list transitions, as a list (for longer models)
results list extra results: sums and ratios of states
outcomes list ss.outcome objects
init_prev float the initial prevalence, a fraction of people (up to 1), seeded through the transmission (by default 0.01, unless a state is given an initial value)
init dict the fraction of people who start in each state, e.g. dict(S=0.90, I=0.01, R=0.09), and, for a state that is not people, its amount, which can be read from the people (e.g. dict(Sv=m*N), with N = (S + I).n); each value can be an ss.by or a function of the sim (in the class form, init = dict(I=0.01) in the class body; likewise init_n and init_prev)
init_n int / dict instead, a number of people: one number is seeded through the transmission, as init_prev is (e.g. init_n=10, a parameter, like init_prev); a dict is the number who start in each state, e.g. dict(I=1) for one person
default_state str / State the state that everyone not put elsewhere starts in, and is born into (its name, or the state): by default, the one named S or susceptible, else the first state of people made (in the class form, default_state = 'N' in the class body). A state with a name of its own given under another keyword (e.g. first=S) raises, rather than being renamed
strains Strains its strains (ss.Strains), which share its states; then dis.strains None
stratify dict the dimensions, as stratify() takes them, e.g. dict(age={0: 0.3, 15: 0.6, 65: 0.1}, risk=ss.levels(['low', 'high'], states=[I])) None
solver abm how this disease runs as agents, whatever the sim’s solver says, e.g. ss.solvers.abm(step='wholestep') (see below); an error for a compartmental run None
kwargs dict one keyword per state, transition, parameter, result, function, or modifier (ss.modify(), of its own quantities, e.g. fading=ss.modify('rel_trans', multiply=0.5, who=I)); also name, label, and dt

A disease’s own solver= is useful when one disease of a sim needs a different way of running as agents from the others:

  • ss.solvers.abm(step='wholestep'): by steps, with rates applied over whole steps to those in the state at the start of the step, as code with ss.bernoulli() does; faster, and a little less exact when the step is coarse
  • ss.solvers.abm(step='events'): event by event, in continuous time
  • by default: the sim’s, if it names a step; else the class’s suggested_solver (e.g. suggested_solver = ss.solvers.abm(step='wholestep') in the class body); else 'midstep' (see ss.solvers.abm() and ss.solvers.agent_solver())

The results are the number in each state (I), the flow along each transition by its name (infection, with its cumulative total as res.infection.cum), and the results and outcomes declared (e.g. active=(E + I).frac). Its infected states also give the results infected, the number in them, and prevalence, their fraction of everyone in the disease’s states, unless it defines its own: those of its force of infection (E and I in S >> E @ beta*I), or those it says are infected (infected = E + I + H, ss.State(infected=True), or ss.states('S E I H R', infected='E I H')).

Examples

# Operator form: declare the states, then the transitions
S, I, R   = ss.states(3)
infection = S >> I @ 0.3 * I
recovery  = I >> R @ ss.days(10)
sir = ss.Disease(infection, recovery, init_prev=0.01)
ss.Sim(sir, stop=100).run().plot()

# Class form: for when there is behavior that is not a transition
class SIR(ss.Disease):
    S, I, R   = ss.states(3)
    infection = S >> I @ 0.3 * I
    recovery  = I >> R @ ss.days(10)

# Written as code: a disease that is not transmitted
class Anemia(ss.Disease):
    def __init__(self, **kwargs):
        super().__init__()
        self.define_pars(p_onset=ss.bernoulli(0.01))
        self.update_pars(**kwargs)
        self.define_states(ss.BoolState('anemic', label='Anemic'))

    def step_state(self):
        self.anemic[self.pars.p_onset.filter()] = True

Attributes

Name Description
abm Whether it runs as agents
custom_transmit Whether the disease is declared and has its own transmit(), which the engine calls for its transmissions
states Its declared states (ss.State) by name, e.g. 'second_line' in tb.states or [s for s in tb.states.values() if s.people]; empty for a disease written as code. (The arrays behind them are state_dict.)
strats Its stratifications by name, e.g. tb.strats.age.edges or tb.strats.risk.labels (as a condition, a level is tb.age)
transitions The table of declared transitions; printing it also shows the matrix of sources by destinations

Methods

Name Description
R0 The basic reproduction number, from the next-generation matrix at the disease-free state
Rt The reproduction number over the course of a run, as a result: the number one infectious person infects at each time point
add_callback Call fn(uids) at the end of each step with the agents who went through a declared transition or event of this disease in it, from a module written as code (agents only)
add_code_pars Parameters its own code reads, not its graph’s: see define_pars()
also_happened As agents, others an event (a transition, by name) also happens to, as UIDs (e.g. the fetuses of a mother at a delivery); None for nobody else
build_graph Build the graph from what was declared: when the disease is made, or for one declared in its init(), after that (see BuiltAfterInit)
burnin_plan People part way through at the start: None for none (the default), or the plan for them (see ss.Pregnancy.burnin_plan() and ss.solvers.Agents.backfill_burnin())
call_transmit The disease’s own transmit() for one of its transmissions, with or without the transition as its argument (see transmit())
check_par_members A parameter given by keyword under the name it already has (name=), and read by a transition, as if it were a result (e.g. eir=eir) is an error: a result needs a name of its own
compartmental_form A module that runs only as agents unless it defines this: make its small compartmental form, used only when a compartmental solver is named, and return the note that says what it leaves out
current_state The state each agent is in, as a read-only ss.IntArr (by UID) of its index among states, or -1 for none
current_value rel_sus or rel_trans (key) of each agent with the modifiers and products active on it applied (ss.modify(dis.rel_sus, ...)), as agents:
declare Add declared members (states, transitions, results), to be built with the rest; see define_transitions()
define_pars Create or merge parameters; see ss.Module.define_pars()
define_results Define results: for a declared disease, sums and ratios of states by name (e.g. prevalence=I/(S + I + R), or active=(E + I).frac); otherwise ss.Result objects (see ss.Module.define_results())
define_states Define its states: declared states (ss.State), or for a disease written as code, arrays (see ss.Module.define_states())
define_transitions Define its transitions, in its __init__(), after its states
describe The resolved model, with every guessed default marked, as text that shows itself (ss.display.Text), as diagram() is
diagram The state-transition diagram: drawn as a Matplotlib figure, or as the text of a Mermaid flowchart (https://mermaid.js.org)
equations The ODE system of the declared transitions, with symbolic parameter names, as text that shows itself (ss.display.Text; print() it in a script)
finish_step Once the step’s flows are recorded (and the analyzers have run), its engine starts counting them afresh
has_structure Whether these keywords declare part of a model, not just a parameter’s value
infect Infect some agents now, from code (e.g. a strain introduced on a date): those in the first state move where its transmission puts them, counted in its flow and dated as its infections are (ti_I.isclose(sim.ti)), with a source of -1 in an ss.infection_log
init_graph Build the graph of declared states and transitions; see ss.graph.Graph
init_post Initialize the values of the states, and set the initial conditions of the declared states
init_pre Link the disease to the sim, create its engine and objects, initialize results, and start its infection log if an analyzer needs it (e.g. ss.infection_log); see ss.Module.init_pre()
make_children As agents, the children of the parents who went through a transition with births (ss.birth(when=)); returns their UIDs
make_naive Put agents back in the first state, as if they had never had the disease; for dynamic rescaling (see ss.Sim.rescale())
move Move people between this disease’s states from code, the same way under every solver: ss.move() with the disease given
not_naive The agents who have left the first state (e.g. who are no longer susceptible), for dynamic rescaling (see ss.Sim.rescale())
on_death What happens to agents when they die: as agents, they leave every declared state
record_events The flows of the step, and the results worked out from them
record_states The counts of the states at the start of the step; for a disease written as code, the count of each ss.BoolState (see ss.Module.record_states())
reuse States and transitions that already belong to another disease are copied (together, so they refer to each other, and with their parameters), so one set can build several independent diseases
route_betas The beta of each of the sim’s networks (by name), as a pair (p1 to p2, p2 to p1), that transmit(rel_trans=..., rel_sus=...) uses when not given beta=: by default pars.beta, as a number, rate, or dict by network, checked against them
run_callbacks Call each function of add_callback() with the agents its event happened to since it was last called
step Take the declared transitions of the step, those that are not contact-mediated and then those that are, followed by any custom functions; a disease written as code overrides this
step_state State changes at the start of the step, before the networks and interventions, by a disease written as code (e.g. recovery)
stratify Stratify the disease by a property of the people in it (age, risk, place, …), in place, and return it
transmit Who is infected in this step by transmission: by one of the disease’s declared transmissions (transition), or, as agents, from the
transmit_arrays The transmission of transmit(rel_trans=..., rel_sus=...): the new cases, with their sources and routes recorded in an ss.infection_log
R0
diseases.Disease.R0(matrix=False)

The basic reproduction number, from the next-generation matrix at the disease-free state

By definition it is in a population with no infection and no immunity: the people infected at the start are left out, and everyone else is taken to be in the first state (e.g. S), each group keeping its size, whoever starts immune (init=dict(R=0.9)). So where transmission is density-dependent (beta*I.n), R0 is for the population less the people seeded, which matters only when many are (half the people seeded halves it). If no transition links some states to the first (a chain of states for each host species), their people are in the state their own chain starts from. People filled by a constant inflow (births of a number a day) and counts that are not people (mosquitoes) are at their equilibrium, which the inflow and the rates out of them set (Λ/μ). The reproduction number at the start, with any immunity, is in the line a run prints as it starts, when it differs (R0 = 15.2 (R = 1.52 at the start, with 10% susceptible)).

The model is laid out as an ODE: if the disease is in a sim, a copy of that sim is made with solver='ode', with its mixing and stratification; otherwise a sim with the disease alone, under homogeneous mixing, with the default number of people. Values that vary in time (a seasonal β) are taken at the start, so this is R0 at the start time. A sim runs a copy of the disease it is given, so the R0 of a sim’s model is sim.diseases.<name>.R0(); this matters where a count is a number rather than a fraction of the people (mosquitoes per person).

This is the largest eigenvalue of the next-generation matrix. Where infection passes through a vector (people infect mosquitoes, which infect people), each passage is a generation, so R0 is the square root of the classical Ross–Macdonald value. Shedding into a reservoir that is a count (such as water) is not an infection, so there R0 is the number of people infected through the reservoir by one person.

Parameters
Name Type Description Default
matrix bool if True, return the next-generation matrix (over the infected compartments of every group) rather than its largest eigenvalue False
Example
S, I, R = ss.states(3)
sir = ss.Disease(infection=S >> I @ 0.3*I, recovery=ss.Transition(I, R, dur=10))
sir.R0() # 3.0
Rt
diseases.Disease.Rt()

The reproduction number over the course of a run, as a result: the number one infectious person infects at each time point

This is R0 at the state of the run at each time point: the largest eigenvalue of the next-generation matrix with the people in each state of each group as they were then (so fewer when some are immune), and the rates as they were then (so lower while an ss.modify() halves β). It falls below 1 as an outbreak peaks. As in R0(), the model is laid out as an ODE, a copy of the sim with solver='ode', stepped alongside the run; a run as agents is taken by the counts in each state of each group. A state with several compartments (the stages of a dwell time) is split among them as in the copy; and the copy is what an intervention triggered by the state of the run sees.

Example
S, I, R = ss.states(3)
sir = ss.Disease(infection=S >> I @ 0.3*I, recovery=ss.Transition(I, R, dur=10), name='sir')
sim = ss.Sim(sir, total_pop=10_000, stop=150).run()
sim.diseases.sir.Rt().plot() # From 3 at the start, below 1 after the peak
add_callback
diseases.Disease.add_callback(event, fn)

Call fn(uids) at the end of each step with the agents who went through a declared transition or event of this disease in it, from a module written as code (agents only)

A declared module reacts to the same events with ss.on() instead. Pass a bound method (e.g. self.on_delivery), or register from init_pre(): the sim runs its own copy of each module, and a lambda made in __init__() would still refer to the original.

Parameters
Name Type Description Default
event Transition / str the transition or event, e.g. preg.stillbirth, preg.loss, or its name required
fn func called with the agents’ UIDs (once for each time, so an agent can appear twice), only on a step when there are some required
Example
preg.add_callback(preg.stillbirth, lambda uids: self.n_stillbirths.__setitem__(uids, self.n_stillbirths[uids] + 1))
add_code_pars
diseases.Disease.add_code_pars(keys)

Parameters its own code reads, not its graph’s: see define_pars()

Parameters
Name Type Description Default
keys list the names of the parameters required
also_happened
diseases.Disease.also_happened(name, uids)

As agents, others an event (a transition, by name) also happens to, as UIDs (e.g. the fetuses of a mother at a delivery); None for nobody else

Parameters
Name Type Description Default
name str the name of the transition required
uids array the agents it happened to required
build_graph
diseases.Disease.build_graph()

Build the graph from what was declared: when the disease is made, or for one declared in its init(), after that (see BuiltAfterInit)

burnin_plan
diseases.Disease.burnin_plan(engine)

People part way through at the start: None for none (the default), or the plan for them (see ss.Pregnancy.burnin_plan() and ss.solvers.Agents.backfill_burnin())

Parameters
Name Type Description Default
engine Engine the engine running this module required
call_transmit
diseases.Disease.call_transmit(tr)

The disease’s own transmit() for one of its transmissions, with or without the transition as its argument (see transmit())

check_par_members
diseases.Disease.check_par_members(args, members, kwargs)

A parameter given by keyword under the name it already has (name=), and read by a transition, as if it were a result (e.g. eir=eir) is an error: a result needs a name of its own

compartmental_form
diseases.Disease.compartmental_form(sim)

A module that runs only as agents unless it defines this: make its small compartmental form, used only when a compartmental solver is named, and return the note that says what it leaves out

Parameters
Name Type Description Default
sim Sim the sim being initialized required
current_state
diseases.Disease.current_state(states=None)

The state each agent is in, as a read-only ss.IntArr (by UID) of its index among states, or -1 for none

The names of the states, in order, are its .labels, so arr.labels[i] is the name of index i.

Parameters
Name Type Description Default
states list the states to look in, as names or states (default: the module’s states of people, in order) None
Example
cs = sir.current_state() # 0 for S, 1 for I, 2 for R
cs.labels[cs[uid]] # The name of an agent's state
current_value
diseases.Disease.current_value(key, uids=None)

rel_sus or rel_trans (key) of each agent with the modifiers and products active on it applied (ss.modify(dis.rel_sus, ...)), as agents: what transmission uses, whereas reading dis.rel_sus gives the base values, which a modifier never changes. Or a parameter (key is its name) with the modifiers active on it, in its own type, declared or written as code: one value, or one for each agent if they differ between agents.

A disease written as code that reads one in its own code (including by transmit(rel_trans=..., rel_sus=...)) says so in its class, allow_modifiers = ('rel_sus',), so that modifiers of it are applied rather than refused. A parameter it doesn’t say this of is read from self.pars with the modifiers applied, which is one value, so a modifier of it can’t differ between agents.

Parameters
Name Type Description Default
key str ‘rel_sus’, ‘rel_trans’, or the name of a parameter required
uids uids the agents to give the values of (default: an array of every agent, by UID) None
Example
sim.diseases.sir.current_value('rel_sus') # With a vaccine's efficacy applied

class Diabetes(ss.Disease):
    allow_modifiers = ('rel_sus',) # ss.modify(diabetes.rel_sus, ...) scales its onset
    def step(self):
        uids = self.at_risk.uids
        onset = self.pars.p_onset.rvs(uids)*self.current_value('rel_sus', uids) # ...
declare
diseases.Disease.declare(args=(), kwargs=None, names=None, overwrite=False)

Add declared members (states, transitions, results), to be built with the rest; see define_transitions()

Parameters
Name Type Description Default
args list the members to add, without names ()
kwargs dict the members to add, by name None
names dict the names of the variables the members were assigned to, if known None
overwrite bool whether a member can replace one of the same name False
define_pars
diseases.Disease.define_pars(inherit=True, **kwargs)

Create or merge parameters; see ss.Module.define_pars()

For a declared disease, a parameter defined here that is not one of its graph’s (e.g. by a subclass, after super().__init__(), for its own code to read) is added to code_pars, so the sim does not reject it as one that nothing reads. A parameter set any other way (e.g. a misspelling in pars=) is still rejected.

Parameters
Name Type Description Default
inherit bool whether to add to the parameters that exist, rather than replace them True
kwargs dict the parameters, by name
define_results
diseases.Disease.define_results(*args, **kwargs)

Define results: for a declared disease, sums and ratios of states by name (e.g. prevalence=I/(S + I + R), or active=(E + I).frac); otherwise ss.Result objects (see ss.Module.define_results())

Parameters
Name Type Description Default
args list the results, as ss.Result objects or expressions
kwargs dict the results of a declared disease, by name
define_states
diseases.Disease.define_states(*args, overwrite=False, **kwargs)

Define its states: declared states (ss.State), or for a disease written as code, arrays (see ss.Module.define_states())

Declared states are given in its __init__(), as for define_transitions(), and each is an attribute at once (self.S).

Parameters
Name Type Description Default
args list the states (ss.states('S I R'), or held in variables), or lists of them; or arrays (ss.BoolState, …)
overwrite bool replace a state of the same name, rather than raising False
kwargs dict states by name (S=ss.State(label='Susceptible')); or for arrays, aliases
define_transitions
diseases.Disease.define_transitions(*args, overwrite=False, **kwargs)

Define its transitions, in its __init__(), after its states

For a declared disease whose structure depends on its arguments, so that it cannot be written in a class body: the states (define_states()), transitions, and results (define_results()) are built together once its __init__() has finished. Each is an attribute at once (self.infection).

Parameters
Name Type Description Default
args list transitions and outcomes, or lists of them, named by name= or by the variable they were assigned to
overwrite bool replace a transition of the same name (e.g. one whose rate is changed), rather than raising False
kwargs dict transitions by name
Examples
class SIRS(ss.Disease):
    def __init__(self, waning=True, **kwargs):
        super().__init__(init_prev=0.01, **kwargs)
        self.define_states(ss.states('S I R'))
        beta = ss.par(0.3)
        self.define_transitions(
            infection = self.S >> self.I @ beta*self.I,
            recovery  = self.I >> self.R @ ss.days(10),
        )
        if waning:
            self.define_transitions(waning=self.R >> self.S @ ss.days(100))
describe
diseases.Disease.describe(out=None)

The resolved model, with every guessed default marked, as text that shows itself (ss.display.Text), as diagram() is

Parameters
Name Type Description Default
out ss.display.Description if given, add the description to it and return it None
diagram
diseases.Disease.diagram(kind='plot', **kwargs)

The state-transition diagram: drawn as a Matplotlib figure, or as the text of a Mermaid flowchart (https://mermaid.js.org)

People states are rounded and counts square (slanted in the text); transmissions are dashed; each arrow is labeled with its transition’s name and value (recovery: 10 days), and the fraction that takes it for a transition with p=. For every disease of a sim, and how they act on each other, see sim.diagram().

Parameters
Name Type Description Default
kind str ‘plot’ to draw it, or ‘text’ for the Mermaid text, which a notebook draws and print() shows (see ss.display.Diagram) 'plot'
kwargs dict for a plot, passed to ss.return_fig() (e.g. filename=, do_show=)
Example
S, I, R = ss.states(3)
sir = ss.Disease(infection=S >> I @ 0.3*I, recovery=ss.Transition(I, R, dur=ss.days(10)))
sir.diagram()
print(sir.diagram('text'))
equations
diseases.Disease.equations()

The ODE system of the declared transitions, with symbolic parameter names, as text that shows itself (ss.display.Text; print() it in a script)

finish_step
diseases.Disease.finish_step()

Once the step’s flows are recorded (and the analyzers have run), its engine starts counting them afresh

has_structure
diseases.Disease.has_structure(kwargs)

Whether these keywords declare part of a model, not just a parameter’s value

infect
diseases.Disease.infect(uids, strain=None)

Infect some agents now, from code (e.g. a strain introduced on a date): those in the first state move where its transmission puts them, counted in its flow and dated as its infections are (ti_I.isclose(sim.ti)), with a source of -1 in an ss.infection_log

Parameters
Name Type Description Default
uids uids the agents; those not in the first state are left where they are required
strain str / Strain for a disease with strains in shared states, the strain they are infected with (by default, as the split says) None
Returns
Name Type Description
The agents infected
Example
covid.infect(sim.people.auids[:20], strain='alpha') # 20 imported cases of alpha
init_graph
diseases.Disease.init_graph(args, members, pars, kwargs, names=None)

Build the graph of declared states and transitions; see ss.graph.Graph

init_post
diseases.Disease.init_post()

Initialize the values of the states, and set the initial conditions of the declared states

init_pre
diseases.Disease.init_pre(sim)

Link the disease to the sim, create its engine and objects, initialize results, and start its infection log if an analyzer needs it (e.g. ss.infection_log); see ss.Module.init_pre()

Parameters
Name Type Description Default
sim Sim the sim being initialized required
make_children
diseases.Disease.make_children(tr, parents, ti)

As agents, the children of the parents who went through a transition with births (ss.birth(when=)); returns their UIDs

Parameters
Name Type Description Default
tr Transition the transition with births required
parents array the parents required
ti int the step of the births required
make_naive
diseases.Disease.make_naive(uids)

Put agents back in the first state, as if they had never had the disease; for dynamic rescaling (see ss.Sim.rescale())

Parameters
Name Type Description Default
uids ss.uids the agents to make naive required
move
diseases.Disease.move(*args, **kwargs)

Move people between this disease’s states from code, the same way under every solver: ss.move() with the disease given

Parameters
Name Type Description Default
args list passed to ss.move(): what to move, from where, and to where
kwargs dict passed to ss.move(), e.g. p or uids
Examples
sir.move(sir.I, sir.R, p=0.5) # Cure half of those infectious
sir.move(uids, sir.R) # These agents, from wherever they are (or sir.move(uids, 'R'))
self.move(self.I, self.R, uids=uids) # In the disease's own code: these agents, if they are infectious
not_naive
diseases.Disease.not_naive()

The agents who have left the first state (e.g. who are no longer susceptible), for dynamic rescaling (see ss.Sim.rescale())

on_death
diseases.Disease.on_death(uids)

What happens to agents when they die: as agents, they leave every declared state

It is called once the step’s deaths are settled, before the analyzers run. A disease written as code overrides it for what changes at death (e.g. clearing infected). A death is only requested during the step (e.g. in step_state(), as ssl.AgentSIR does), so an intervention on the same step can still avert it, and nothing needs undoing, since these changes are made only if the death happens. The sim does not call it directly: people.step_die() does, once it knows who died.

Parameters
Name Type Description Default
uids array the agents who died required
record_events
diseases.Disease.record_events()

The flows of the step, and the results worked out from them

record_states
diseases.Disease.record_states()

The counts of the states at the start of the step; for a disease written as code, the count of each ss.BoolState (see ss.Module.record_states())

reuse
diseases.Disease.reuse(args, members, names=None)

States and transitions that already belong to another disease are copied (together, so they refer to each other, and with their parameters), so one set can build several independent diseases

route_betas
diseases.Disease.route_betas()

The beta of each of the sim’s networks (by name), as a pair (p1 to p2, p2 to p1), that transmit(rel_trans=..., rel_sus=...) uses when not given beta=: by default pars.beta, as a number, rate, or dict by network, checked against them

Override it for betas worked out by code, e.g. by sex or genotype, starting from super().route_betas().

Example:

class STI(ss.AgentDisease):
    def route_betas(self):
        betamap = super().route_betas()
        betamap['sexual'] = [self.pars.beta_m2f, self.pars.beta_f2m] # Male to female and female to male, on ss.SexualNet
        return betamap
run_callbacks
diseases.Disease.run_callbacks()

Call each function of add_callback() with the agents its event happened to since it was last called

step
diseases.Disease.step()

Take the declared transitions of the step, those that are not contact-mediated and then those that are, followed by any custom functions; a disease written as code overrides this

step_state
diseases.Disease.step_state()

State changes at the start of the step, before the networks and interventions, by a disease written as code (e.g. recovery)

The declared transitions are all taken together in step(), after the interventions, so a delivery sees the same people under every solver (as agents and as compartments).

stratify
diseases.Disease.stratify(inplace=True, **kwargs)

Stratify the disease by a property of the people in it (age, risk, place, …), in place, and return it

Every keyword is a dimension, with its levels: bin edges (for a continuous property such as age) or labels, or a dict of the fraction of the population in each level (if not given: from a named population or geography; for age groups, the world’s ages; for a boolean dimension, or one that people are moved along, everyone at the first level; otherwise equal). ss.levels() adds the options that are needed less often: the states it applies to (states=), the people it applies to (who=), its kind, and the movement between places. A value by level, e.g. a rate, is ss.by(): S >> I @ beta*ss.by(risk=[1, 3])*I, or for a disease already written, ss.modify(sir.infection, multiply=ss.by(risk=[1, 3])).

Parameters
Name Type Description Default
inplace bool if False, return a stratified copy and leave this disease unchanged True
kwargs dict each dimension and its levels, e.g. age=[0, 15, 65], risk={'low': 0.8, 'high': 0.2}, or severity=ss.levels(['mild', 'severe'], states=[I]); an ss.transfer passed as a keyword is added under that name
Examples
sir.stratify(age={0: 0.3, 15: 0.6, 65: 0.1}) # With the fraction of people in each age group
sir.stratify(age=[0, 15, 65], risk={'low': 0.8, 'high': 0.2})
sir.stratify(sex=['female', 'male'], parity=ss.levels(['0', '1-2', '3+'], who=ss.person.female)) # Only women have a parity
sir.stratify(severity=ss.levels({'mild': 0.9, 'severe': 0.1}, states=[sir.I]))
transmit
diseases.Disease.transmit(
    transition=None,
    rel_trans=None,
    rel_sus=None,
    beta=None,
)

Who is infected in this step by transmission: by one of the disease’s declared transmissions (transition), or, as agents, from the transmissibility and susceptibility of each agent (rel_trans and rel_sus), over the sim’s networks and other routes

Declared. A declared disease’s transmissions are its transitions whose rate depends on contact with infectious people (e.g. S >> I @ beta*I). Override this to write one as code, and call super().transmit(transition) for what the solver would do, e.g. to add a route of its own or remove some of the cases. The engine calls it once a step for each transmission, and moves those it gives along that transition, counted in its flow. A disease with one transmission can leave out the argument (def transmit(self):); with several, transition says which (e.g. if transition.name == 'infection':). As agents, it gives the new cases’ UIDs (those not in one of the transition’s source states are not moved); as compartments, the number infected in each group (or one number), taken from the source states in proportion. Under the ODE, it is taken once a step, at the start, as a move of that many (as ss.move() from code is), so the ODE no longer integrates that transition within the step: give a rate (e.g. S >> I @ (lambda self, sim: ...)) to keep it exact. Anything that needs individuals (UIDs) raises an error in a compartmental run; if isinstance(self.sim.solver, ss.solvers.ode): can give each its own.

As array operations. With rel_trans and rel_sus, it is the same transmission as an operation that code calls, as agents (in a disease written as code, or in a declared one’s own code): each edge of a network from u to v transmits with probability 1 − exp(−rel_trans[u]·rel_sus[v]·H), where H is the hazard of the network’s chance for the step (see ss.Network.transmit()), with the modifiers and products on rel_trans and rel_sus applied (so the disease says allow_modifiers = ('rel_sus', 'rel_trans')), and the draws of each edge from the disease’s trans_rng; other routes (e.g. a mixing pool) give their own (compute_transmission()). Someone reached by several is infected by the first, which is their source, recorded with the route in an ss.infection_log. Nobody is moved: the code that calls it says what happens to those infected.

Parameters
Name Type Description Default
transition ss.Transition the declared transmission; may be left out for a disease with only one None
rel_trans array the transmissibility of each agent, by UID, 0 for those not infectious (e.g. self.rel_trans.raw*self.I.raw) None
rel_sus array the susceptibility of each agent, by UID, 0 for those not susceptible None
beta float/ss.Rate/dict with rel_trans and rel_sus, the beta (a rate, or a number in the sim’s unit; a dict gives one per network); by default self.pars.beta None
Returns
Name Type Description
As agents, the UIDs of the new cases (ss.uids); as compartments, the number of them in each group
Examples
class Imported(ss.SIR): # A declared disease, with 2 imported cases a step added to its transmission
    def transmit(self, transition):
        new = super().transmit(transition)
        if isinstance(self.sim.solver, ss.solvers.abm): # And 2 imported cases a step, as agents
            return new | self.sim.people.auids[self.S.raw[self.sim.people.auids]][:2]
        return new + 2/self.sim.groups.n_groups

class SIR(ss.Disease): # Written as code: the S >> I @ beta*I of ss.SIR, as agents
    allow_modifiers = ('rel_sus', 'rel_trans') # Read here, by transmit()
    ...
    def step(self):
        new = self.transmit(rel_trans=self.rel_trans.raw*self.I.raw, rel_sus=self.rel_sus.raw*self.S.raw)
        self.S[new] = False
        self.I[new] = True
transmit_arrays
diseases.Disease.transmit_arrays(rel_trans, rel_sus, beta=None)

The transmission of transmit(rel_trans=..., rel_sus=...): the new cases, with their sources and routes recorded in an ss.infection_log

InfectionLog

diseases.InfectionLog(disease=None, networks=None, timeline=None)

A record of who infected whom, and when: kept by a disease when an analyzer needs it (e.g. ss.infection_log), to trace chains of transmission

The infection log records transmission events and optionally other data associated with each transmission. Entries are stored as one chunk of arrays per call, so logging is cheap; they are combined when the log is read. Basic functionality is to track transmission with

Disease.infection_log.add_entries(targets, sources, t)

or, for a single infection,

Disease.infection_log.append(source, target, t)

Seed infections can be recorded with a source of None (or NaN), although all infections should have a target and a time. Other data can be captured in the log, either at the time of creation, or later on. For example

Disease.infection_log.add_entries(targets, sources, t, variant=variants)

records extra data for each infection (ss.Disease.transmit() records the network this way). Modules can optionally add per-infection outcomes later as well, for example

Disease.infection_log.add_data(uids, t_dead=2024.25)

This would be equivalent to having specified the data at the original time the log entry was created - however, it is more useful for tracking events that may or may not occur after the infection and could be modified by interventions (e.g., tracking diagnosis, treatment, notification etc.)

A table of outcomes can be returned using InfectionLog.to_df(), and a NetworkX graph with InfectionLog.to_graph(). An analyzer that follows transmission as the sim runs reads each step’s entries with to_df(ti=self.ti):

new = sim.diseases.sir.infection_log.to_df(ti=self.ti) # In an analyzer’s step()

Parameters

Name Type Description Default
disease str the name of the disease being logged None
networks list the names of the networks, used to convert the network IDs recorded by ss.Disease.transmit() to names in to_df() None
timeline ss.Timeline the disease’s timeline, so that each entry has the time index it was logged at, for to_df(ti=...) None

Methods

Name Description
add_data Record extra infection data
add_entries Record new infections
append Record a single infection
disp Full display of the infection log
to_df Return a tabular representation of the log as a line list dataframe
to_graph Return the log as a NetworkX MultiDiGraph, with sources and targets as nodes and the time as the edge key
add_data
diseases.InfectionLog.add_data(uids, **kwargs)

Record extra infection data

This method can be used to add data to an existing transmission event. The most recent transmission event for each agent will be used.

Parameters
Name Type Description Default
uids array The UIDs of the target nodes (the agents that were infected) required
kwargs dict Remaining arguments are stored as data for each entry, either a scalar or one value per UID
add_entries
diseases.InfectionLog.add_entries(uids, sources=None, time=None, **kwargs)

Record new infections

Parameters
Name Type Description Default
uids array the UIDs of the infected agents (targets) required
sources array / int the UIDs of the infecting agents; None or NaN for seed infections, or -1 (as a declared disease records its seeds) None
time any the time of infection (all entries in the chunk share it); by default the time point of the current step (the start, for seeds set before the first) None
kwargs dict extra data to store, either a scalar or one value per UID
append
diseases.InfectionLog.append(source, target, t, **kwargs)

Record a single infection

Parameters
Name Type Description Default
source int who did the infecting required
target int who was infected required
t int the time of the infection required
kwargs dict other data to store with the entry
disp
diseases.InfectionLog.disp(**kwargs)

Full display of the infection log

Parameters
Name Type Description Default
kwargs dict passed to sc.pr()
to_df
diseases.InfectionLog.to_df(ti=None)

Return a tabular representation of the log as a line list dataframe

This function returns a dataframe containing columns for all quantities recorded in the log. Note that the log will contain NaN for quantities that are defined for some edges and not others (and which are missing for a particular entry)

Parameters
Name Type Description Default
ti int if given, only the entries logged at this time index of the disease (e.g. ti=self.ti in an analyzer’s step(), for the infections of the step just taken; at ti=0, the seeds); it reads only those entries, so is quick to call every step None
Example
class new_infections(ss.Analyzer):
    def init_results(self):
        super().init_results()
        self.define_results(ss.Result('known', label='Infections from a known source', kind='flow'))

    def step(self):
        df = self.sim.diseases.sir.infection_log.to_df(ti=self.ti)
        self.results.known[self.ti] = (df.source >= 0).sum() # Not seeds (-1), nor those with no source (NA)

sim = ss.Sim(diseases='sir', networks='random', analyzers=[ss.infection_log(), new_infections()]).run()
to_graph
diseases.InfectionLog.to_graph()

Return the log as a NetworkX MultiDiGraph, with sources and targets as nodes and the time as the edge key

SEIR

diseases.SEIR(
    *args,
    pars=None,
    strains=None,
    stratify=None,
    solver=None,
    _names=None,
    **kwargs,
)

An SEIR model: as ss.SIR, with an exposed (latent) state before people become infectious

Note: CRN safe as agents.

Parameters

Name Type Description Default
beta float/ss.per/dict the transmission rate (per contact, if there are networks, over each step of the contact, so ss.probperday(p) gives each contact a chance p in a day; a dict gives one per network, and default= for the networks it does not name)
init_prev float the fraction of people who start infected, who start exposed, in E (for a number of people, give init_n= instead); to start people infectious, give init=dict(I=0.01) or init_n=dict(I=10) instead
dur_exp float/ss.Duration/ss.Dist the mean time that people are exposed (latent) for (by default 3 days; a number is in the model’s unit), as an exponential
dur_inf float/ss.Duration/ss.Dist the mean time that people are infectious for (by default 10 days), as an exponential
p_death float the probability of death from infection, at the end of the infection (by default 0)
kwargs dict passed to ss.Disease, e.g. name
pars dict the same parameters, as a dict None

As in ss.SIR, the defaults are those of a respiratory infection, each duration is exponential unless a distribution is given, and nobody dies of the infection unless p_death is given.

An SEIR model written as code, with lognormal durations and p_death=0.01, is ssl.AgentSEIR.

SIR

diseases.SIR(
    *args,
    pars=None,
    strains=None,
    stratify=None,
    solver=None,
    _names=None,
    **kwargs,
)

An SIR model: susceptible, infected, and recovered, optionally with deaths from infection

Declared from states and transitions (see ss.Disease), so it runs with any solver: as agents over networks, or as compartments. It is the textbook SIR: the infectious period is exponential, as any declared duration is, and nobody dies of the infection unless p_death is given. Its defaults are those of a respiratory infection: infectious for 10 days, with an R0 of 3 without a network (β × the duration); with a network, β is per contact, so R0 is that many times the number of contacts.

Note: CRN safe as agents.

Parameters

Name Type Description Default
beta float/ss.per/dict the transmission rate (per contact, if there are networks, over each step of the contact, so ss.probperday(p) gives each contact a chance p in a day; a dict gives one per network, and default= for the networks it does not name)
init_prev float the fraction of people who start infected (for a number of people, give init_n= instead, e.g. init_n=10)
dur_inf float/ss.Duration/ss.Dist the mean time that people are infected for (by default 10 days), as an exponential; give a distribution (e.g. ss.lognormal(mean=ss.days(10))) for another shape
p_death float the probability of death from infection, at the end of the infection (by default 0)
kwargs dict passed to ss.Disease, e.g. name
pars dict the same parameters, as a dict None

An SIR model written as code, with a lognormal dur_inf and p_death=0.01, is ssl.AgentSIR.

Example

sim = ss.Sim(diseases=ss.SIR(beta=0.03, dur_inf=ss.days(10)), networks='random', n_agents=5000) # R0 of 3 with 10 contacts each
sim.run().plot()

SIS

diseases.SIS(
    *args,
    pars=None,
    strains=None,
    stratify=None,
    solver=None,
    _names=None,
    **kwargs,
)

An SIS model: people recover from infection and are susceptible again

Declared from states and transitions (see ss.Disease), so it runs with any solver. Its defaults are those of a respiratory infection that leaves no immunity: infectious for 10 days, with an R0 of 2 without a network, so that half of people are infected once it is endemic.

Note: CRN safe as agents.

Parameters

Name Type Description Default
beta float/ss.per/dict the transmission rate (per contact, if there are networks, over each step of the contact, so ss.probperday(p) gives each contact a chance p in a day; a dict gives one per network, and default= for the networks it does not name)
init_prev float the fraction of people who start infected (for a number of people, give init_n= instead, e.g. init_n=10)
dur_inf float/ss.Duration/ss.Dist the mean time that people are infected for (by default 10 days), as an exponential unless a distribution is given
kwargs dict passed to ss.Disease, e.g. name
pars dict the same parameters, as a dict None

An SIS model with a per-agent immunity level, boosted by each infection and waning over time (waning=, imm_boost=), which has no declared form, is ssl.AgentSIS, written as code.

Functions

Name Description
check_init_prev Check the starting infections: init_prev= is a fraction of people (up to 1; for a number of people, init_n=), so a whole number 1 means everyone and warns; init_n= is not negative
check_stratify The stratify= of a disease or a sim: one dict of dimensions, as stratify() takes them
rebind_member A member given to an instance of a declared class (e.g. ssl.Measles(rash=ss.outcome(0.9*ssl.Measles.onset))), reading the instance’s copies of the class’s states, transitions, and parameters (memo, see ss.expressions.rebind()); a transition is copied only if it reads any of them

check_init_prev

diseases.check_init_prev(init_prev, seed_n, name)

Check the starting infections: init_prev= is a fraction of people (up to 1; for a number of people, init_n=), so a whole number 1 means everyone and warns; init_n= is not negative

check_stratify

diseases.check_stratify(stratify, where)

The stratify= of a disease or a sim: one dict of dimensions, as stratify() takes them

rebind_member

diseases.rebind_member(obj, memo)

A member given to an instance of a declared class (e.g. ssl.Measles(rash=ss.outcome(0.9*ssl.Measles.onset))), reading the instance’s copies of the class’s states, transitions, and parameters (memo, see ss.expressions.rebind()); a transition is copied only if it reads any of them