Skip to main content

strains

strains

Strains of a disease (ss.Strains), and protection between them (ss.immunity)

These exist so that one disease can have several strains, with their own values and with protection between them, without being written as several diseases. The strains of a declared disease share its states; a disease written as code (ss.AgentDisease(strains=...)) carries one at a time, as an index for each person (dis.strain), passed on by the same code as a declared disease’s.

Used with: agents and compartments; declared and coded modules

Classes

Name Description
Strains The strains of a disease: ss.Disease(..., strains=ss.Strains(...)), which is then dis.strains
immunity Protection between strains: what having (or having had) one strain does against each strain

Strains

strains.Strains(
    strains,
    immunity=None,
    max_strains=None,
    transmit='one',
    fractions=None,
    name='strain',
    label=None,
    **values,
)

The strains of a disease: ss.Disease(..., strains=ss.Strains(...)), which is then dis.strains

The strains share the disease’s states: a person is in a state once, carrying their strains, with one course. The engine chooses how to run what is declared (one strain at a time, or sets of strains carried together), and describe() says which.

With no immunity=, a person carries one strain at a time, being infected (or recovered) protects against every strain, and a new infection takes its source’s strain. ss.immunity(due_to=...) changes that: protection from a state. With max_strains above 1, people carry sets of strains (the levels of the strain dimension, e.g. ‘DS+RIF’), and a set takes the largest of its strains’ values for a transition; once full, a new strain replaces the oldest (counted in the flow that brought it).

Values for each strain are multipliers on the disease’s transitions (by name: their rate, a duration divided, or a branch’s probability) and on rel_trans. They can be given two ways, which are the same thing: by strain, as a dict of dicts; or by parameter, as lists, one entry per strain.

Parameters

Name Type Description Default
strains list / dict the strains: their names, or a dict of the values of each, by name required
immunity immunity / list protection between strains, one ss.immunity or a list of them; the matrices have rows and columns in the order of the strains None
max_strains int the most strains anyone carries at once (default 1); more allows coinfection (e.g. drug-sensitive and resistant TB together), at the cost of a level for each set of strains None
transmit str what a carrier of several strains passes on: ‘one’ (the default: one strain per transmission, chosen in proportion to the strains’ rel_trans, at the infectiousness of the most infectious), or ‘each’ (each strain at its own rate) 'one'
fractions list / dict the fraction of each strain among the people infected at the start (default: equal); or, by label, the fraction of each strain or set of strains carried together, e.g. fractions={'DS': 0.5, 'DS+INH': 0.5} None
name str the name of the strain dimension, for results (res.I.by('strain')) and conditions (default ‘strain’) 'strain'
label str its label, for plots and printing (default: the name) None
values dict values for each strain by parameter, e.g. rel_trans=[1, 0.575], cure=[1, 1/3]

Examples

# TB: one course for the person, several strains in it
strains = ss.Strains(dict(DS=dict(rel_trans=1, cure=1), RIF=dict(rel_trans=0.575, cure=1/3)), max_strains=2, fractions=[0.9, 0.1],
                     immunity=ss.immunity(due_to=L, protection=0.79)) # Latent infection protects in part against a new strain
DS, RIF = strains
failure = ss.Transition(Tx, I, rate=ss.peryear(0.1), move=DS >> (DS, RIF)) # Treatment fails, and DS acquires resistance
tb = ss.Disease(..., failure, strains=strains)

Attributes

Name Description
immunity The protection between the strains, a list of ss.immunity; it can be set after the strains are made

Methods

Name Description
change A change of the strains people carry, from a strain or a tuple of them to a strain or a tuple of them: strains.change((DS, INH), (RIF, INH)), for what >> cannot write between two tuples
describe The strains of a disease, as rows of its description (out, an ss.display.Description): how they are run, their values, and the protection between them
level_of The level of a set of strains (as indices), in the order given if the levels are ordered
level_protection The protection of the people at each level of the strain dimension (rows) against each strain (columns), from the strains they carry
needs_agents Why the protection between the strains can run only as agents, or None
change
strains.Strains.change(src, dst)

A change of the strains people carry, from a strain or a tuple of them to a strain or a tuple of them: strains.change((DS, INH), (RIF, INH)), for what >> cannot write between two tuples

Parameters
Name Type Description Default
src Strain / tuple the strain or strains people carry required
dst Strain / tuple the strain or strains they carry afterward required
describe
strains.Strains.describe(graph, out)

The strains of a disease, as rows of its description (out, an ss.display.Description): how they are run, their values, and the protection between them

level_of
strains.Strains.level_of(strains, what=None)

The level of a set of strains (as indices), in the order given if the levels are ordered

level_protection
strains.Strains.level_protection(imm)

The protection of the people at each level of the strain dimension (rows) against each strain (columns), from the strains they carry

needs_agents
strains.Strains.needs_agents(graph)

Why the protection between the strains can run only as agents, or None

immunity

strains.immunity(*args, due_to=None, protection=None, combine='max')

Protection between strains: what having (or having had) one strain does against each strain

protection= is the protection against being infected: a matrix, with rows from the strain held and columns against the strain (1 is complete), or a single number, the same protection from any strain held against every strain. Each person’s protection against a strain is combined over the strains they hold by combine=, and multiplies rel_sus by 1 − protection. Several ss.immunity objects, and any modifier or product on rel_sus, multiply.

due_to= is a state (due_to=R) whose people are protected, by the strains they hold there. A state protects against every strain completely unless an ss.immunity says otherwise; partial protection in a state people are infected in (due_to=L) lets them carry another strain as well (superinfection), up to max_strains. A relative rate of superinfection that is a parameter (to fit), or above 1, is written as the transmission itself, e.g. L >> L @ rr*foi, which carries the new strain as well in the same way.

Parameters

Name Type Description Default
due_to State / str what protects, as above None
protection array / float the protection against being infected (0 is none, 1 is complete) None
combine str / func how protection from several strains adds up: ‘max’ (the strongest, the default), ‘sum’ (added, at most 1), ‘multiply’ (independent sources: 1 − Π(1 − p)), or a function of one array of protections, with the strains held on the first axis (0 for those not held), that returns the protection, e.g. lambda p: np.minimum(1, p.max(0) + 0.5*(p.sum(0) - p.max(0))); a function needs agents (it has no gradient) 'max'

Examples

strains = ss.Strains(['DS', 'RIF'], max_strains=2, immunity=ss.immunity(due_to=L, protection=0.79)) # Latent infection protects in part against another strain

Attributes

Name Description
names The names of the states that protect, from what due_to= was given: states, their names, or a list of them
source What protects, in words: the names of the states

Methods

Name Description
matrix The protection as an n×n matrix
rule The combination rule, in words
matrix
strains.immunity.matrix(n)

The protection as an n×n matrix

Parameters
Name Type Description Default
n int the number of strains required
rule
strains.immunity.rule()

The combination rule, in words