Skip to main content

interventions

interventions

Interventions, which change the course of a sim during a run

Interventions typically include things like testing, treatment, and vaccination. An event (ss.Event) moves the people it reaches, on a schedule or when another event happens, e.g. seeding infections; a delivery (ss.Delivery, and ss.vaccinate(), ss.screen(), and ss.treat()) is an event that gives a product. Both exist so that the same intervention can be written once and run under any solver. It also works with a disease written as code, as agents.

Used with: agents and compartments; declared and coded modules

Classes

Name Description
Delivery Deliver a product to people: an ss.Event with what only interventions need; see ss.vaccinate(), ss.screen(), and ss.treat()
Event Something that happens to people: a move between states, on a schedule or when another event happens; see ss.Delivery to deliver a product
Intervention Base class for interventions written as code
at_age Who an event reaches: people as they reach an age, as its who=; e.g. ss.vaccinate(who=ss.at_age(ss.months(9)))
capacity How many a delivery can serve, who is served first, and what happens to the rest, as its capacity=
screen Deliver a diagnostic test; see ss.Delivery for the arguments
treat Deliver a treatment; see ss.Delivery for the arguments
vaccinate Deliver a vaccine; see ss.Delivery for the arguments

Delivery

interventions.Delivery(
    what=None,
    who=None,
    when=None,
    coverage=None,
    capacity=None,
    strain=None,
    increment=None,
    trace=None,
    skip_reached_within=None,
    disease=None,
    start=None,
    stop=None,
    name=None,
    label=None,
    **kwargs,
)

Deliver a product to people: an ss.Event with what only interventions need; see ss.vaccinate(), ss.screen(), and ss.treat()

Who and when are as for ss.Event. What is delivered is a product (an ss.Vaccine, ss.Diagnostic, or ss.Treatment, or one written as code, an ss.Product with an administer(uids) method), or a move, as for an event, which a campaign can make (e.g. dict(vaccinated=True)). How many is said as for services: coverage=, the fraction reached, and capacity=, how many can be served, with ss.capacity() for who is served first and whether the rest wait. With an event as when=, the delivery reaches the people it happened to: an outcome of another delivery (when=screening.positive) on the same step, a transition of a disease (when=tb.care) on the next, since deliveries run before the diseases in each step.

A delivery is an event too, and so is each outcome of its product (a test’s positive and negative, a cure’s cured, failed, and unneeded): a follow-up is a delivery of its own, triggered by one (ss.treat(drug, when=screening.positive)), and runs after it in the same step.

Its methods are how it runs as agents; in a compartmental run, what differs is delivery.in_compartments (see ss.solvers.CompartmentalDelivery).

Note: CRN safe as agents.

Parameters

Name Type Description Default
what Product / Transition / dict what is delivered: a product, or a move as for ss.Event; ss.vaccinate(), ss.screen(), and ss.treat() instead take the product’s own keywords and make it, e.g. ss.vaccinate(efficacy=0.9, ...) None
who Cond / func / at_age who is eligible, as for ss.Event None
when date / list / dur / event / func / schedule when it is delivered, as for ss.Event: in rounds (times, or ss.schedule(), e.g. with every=), on an event (with ss.on(event, delay=...) for a time after it, which is the time from the trigger to delivery, drawn per person if a distribution, agents only), or with none, routinely: each person is offered it once, at the first step they are eligible None
start date / float / dur the start of a window it is delivered in, with any when=, as for ss.Event: e.g. when=onset, start=2001, on an event from 2001 None
stop date / float / dur the end of the window, likewise None
coverage float / rate / func the fraction of those eligible who are reached; also ss.by(...), a typed rate or probability (e.g. ss.perday(0.1), ss.probperyear(0.5)): the chance over the step or the round (and, for routine delivery, offered at every step to those eligible); or a function of the sim, called at each step, returning one of these or, as agents, a probability for each person: an array over everyone alive, in the order of sim.people.uid, or an ss.Arr, read by UID; only the values of those eligible are used None
capacity float / rate / capacity how many can be served: a number per round (or per step, for delivery on events), or a rate (e.g. ss.peryear(50_000)), which routine delivery needs; or ss.capacity(n, priority=..., queue=...), also saying who is served first and whether the rest wait. A capacity is for a service limited by supply or staff, rather than by how many come forward None
strain str / Strain with a move into a state where people carry a strain, the strain they arrive with None
increment str / dict instead of a product, a counter that goes up for those reached, as for ss.Event None
trace str / Network / list contact tracing: deliver to the contacts, in this network (or these), of the people the event in when= reaches, instead of to them; who= and coverage= then apply to the contacts. Agents only. A network with memory= also gives the partnerships of that long ago that have ended (e.g. ss.DegreeNet(..., memory=ss.months(12))) None
skip_reached_within dur skip the people this delivery reached less than this long ago (agents only), e.g. ss.years(1) for a re-screening interval; the same as who=~(delivery.since < ss.years(1)), which the delivery cannot name before it exists None
disease str / list the disease the product acts on (default: the only one); or a list of them, for one product that acts on several (e.g. a bivalent vaccine), delivered once None
name str the name; if not given, taken from the variable it is assigned to None
label str a human-readable name None

Examples

# A campaign that leaves a mark, for 70% of the unvaccinated in two rounds
rollout = ss.Delivery(dict(vaccinated=True), coverage=0.7, when=[5, 30], who=~sir.vaccinated)

# A test, and a treatment of those who test positive, as two deliveries
screening = ss.screen(sensitivity=0.9, specificity=0.95, who=ss.person.age > 30, coverage=0.4, when=ss.schedule(every=ss.days(7)))
treatment = ss.treat(cure=0.95, when=screening.positive, coverage=0.8)

# Routine vaccination at nine months, from 2025 (the same as when=ss.schedule(start=2025))
mcv1 = ss.vaccinate(efficacy=0.85, who=ss.at_age(ss.months(9)), coverage=0.8, start=2025)

# Testing those with symptoms, from 2001 to 2010
testing = ss.screen(sensitivity=0.9, when=sir.infection, coverage=0.3, start=2001, stop=2010)

Event

interventions.Event(
    what=None,
    who=None,
    when=None,
    n=None,
    p=None,
    strain=None,
    increment=None,
    start=None,
    stop=None,
    name=None,
    label=None,
    **kwargs,
)

Something that happens to people: a move between states, on a schedule or when another event happens; see ss.Delivery to deliver a product

An event has three parts, each optional. What happens to those it reaches: a move between two states (S >> I), levels of a stratification (dict(risk=('low', 'high'))), or strains (DS >> RIF), or an increment of a counter; with none, it is only an event, which others trigger on (e.g. a clinic visit). Who it reaches: a condition on people, or on the population (sir.I.n > 1000, which decides for everyone at once), or people as they reach an age (ss.at_age()). And when: at times (when=[2025, 2030], when='2024-03-01', or when=ss.days(30), 30 days after the start), on a schedule (when=ss.schedule(every=ss.months(1), start='2024-01-01', stop='2025-01-01')), when another event happens (when=sir.infection, or when=ss.on(sir.infection, delay=ss.days(5))), or, with no when=, routinely: each person once, at the first step they are eligible. start= and stop= limit any of these to a window (the same as when=ss.schedule(start=..., stop=...) for routine events), e.g. when=screening.positive, start=2001.

n= and p= say how many it reaches each time, as for ss.move(): at most n of those eligible, chosen at random, and each with probability p.

It is an event itself: others trigger on it (when=seeding), and it remembers per person whether (.ever), how often (.n_times), and how long ago (.since) it happened. event.reached() is the UIDs of the people it reached on the step (agents only).

Note: CRN safe as agents.

Parameters

Name Type Description Default
what Transition / dict / str what happens to those it reaches: a move between states (S >> I, from any of several, U + P >> P, or by the paths of the states, 'sir.S >> sir.I'), a move to a level of a stratification (dict(vaccinated=True)) or from one level to another (dict(risk=('low', 'high'))), or a change of strains (DS >> RIF) None
who Cond / func / at_age who it can reach: a condition on people (ss.person.age < 5, or a state by its path, 'sir.I'), on the population (sir.I.n > 1000), or both joined with &; people as they reach an age (ss.at_age(ss.months(9))); or a function of the sim returning who is eligible (UIDs, a mask, or True or False for everyone); to reach exactly those it returns at each step, also give when= every step None
when date / list / dur / event / func / schedule when it happens: a time or list of them (dates, years, or durations after the start of the sim: ss.days(10) is 10 days in, and with no calendar day 10); an event that triggers it (sir.infection, screening.positive, or a transition by its path), or ss.on(event, delay=...) for a time after it; a function of the date of each step, true when it happens; or ss.schedule(), for how often (every=), or any of these with a start= and stop= (with only those, routinely between them) None
start date / float / dur the start of a window it happens in, with any when= (e.g. on an event, from 2001): a shorthand for when=ss.schedule(start=...) that also goes with an event (default: the start of the sim) None
stop date / float / dur the end of the window, likewise (default: the end of the sim) None
n float / rate the most it reaches each time: a number, or a rate (e.g. ss.peryear(20)), which routine events need, since they have no rounds for a number to be per None
p float / rate / func the probability that each person eligible is reached; also ss.by(...), a typed rate or probability (e.g. ss.perday(0.1)), or a function of the sim returning one, or (as agents) one per person None
strain str / Strain with a move into a state where people carry a strain (e.g. S >> E), the strain they arrive with None
increment str / dict instead of a move, a counter that goes up for those reached: its name, which adds 1, or a dict of the amount for each None
name str the name; if not given, taken from the variable it is assigned to None
label str a human-readable name None

Examples

# Seeding: three people, chosen from everyone susceptible, infected every 30 days for ten years
seeds = ss.Event(S >> I, n=3, when=ss.schedule(every=ss.days(30), start=ss.days(30), stop=ss.years(10)))

# A new strain on a date
alpha = ss.Event(S >> E, n=20, when='2021-01-01', strain='alpha')

# Twenty importations a year, for the first five years
imports = ss.Event(S >> I, n=ss.peryear(20), stop=ss.years(5))

# Moving people to high risk, five days after infection, half of them
risky = ss.Event(dict(risk=('low', 'high')), when=ss.on(sir.infection, delay=ss.days(5)), p=0.5)

# Each round of a campaign adds a dose (with sim.stratify(doses=[0, 1, 2, 3]))
campaign = ss.Event(increment='doses', p=0.6, when=[2025, 2026, 2027])

Attributes

Name Description
age_years With at_age=: the age, in years
cost The cost of each delivery: its product’s
dis The disease the product acts on: declared, or written as code
disease The disease whose engine evaluates the conditions: as given, else the one whose states move= names, else the first that the product names, else the first declared disease its conditions name
dt_sim The timestep, in the sim’s unit
eng The engine of the disease, which applies its effects (see ss.solvers.Effects)
event_owners What fires its events: the delivery, and its product if it has one
holds Whether people hold what is delivered
in_rounds Whether it is given in rounds (at times, or every so often), rather than routinely or on an event
move_arrow With move= between states: the move, as written (S >> V)
move_names With move= between states: the names of the states it moves people from, and the one it moves them to
offered The name of the property of people that records who has been offered it (see remembers)
remembers Whether the model has to record who has been offered the product; not if everyone eligible receives something they then hold for good, nor for a rate among those eligible
routine Whether each person is offered the product once, at the first step on which they are eligible
selector The selector of the disease’s engine, which evaluates the delivery’s conditions
span The time this delivery stands for now: the step, or the round
tabulated Whether a compartmental run can apply this delivery in the compiled kernels, for the whole run at once (fast), rather than step by
waits Whether the results of the test it delivers come after a delay

Methods

Name Description
add Add people to a result (and to its part for one disease and transition): agents by UID, or people by group
age_reason With at_age=: why a compartmental run cannot deliver it, or None. As compartments, people reach the age by aging from
agent_reasons The reasons, if any, that this delivery needs agents (a priority per agent is ignored by a compartmental solver that was asked for, with a note: see key())
arrivals Who is offered it now, before eligibility: everyone, or those its event happened to (with a delay, those it happened to the delay ago)
boxed Whether holding the product has the levels of a boxcar in this sim: in a compartmental run, for a product that wanes as an ss.boxcar (see ss.products.Held.boxcar_form)
check_coded For a disease written as code: agents only, and it has the parts the product uses, or this raises naming the missing one
convert Convert a typed quantity to a plain number in the sim’s unit
cure Move the people treated along the transitions of the treatment (see ss.Treatment), and record the outcomes as results
default_eligible Who is eligible if nothing is said: for a treatment that is not triggered, the people it can cure (those in the sources of its moves, or who are infected)
delay_steps The number of steps from the trigger to delivery, with a fixed delay (when=ss.on(…, delay=…), at least one)
delayed_arrivals With a delay (when=ss.on(event, delay=…); agents only): those triggered since its last step start waiting (unless waiting already), and those whose wait is over arrive
describe A line saying what is delivered and how
dim_moves Movement along those properties that happens by itself: losing the protection of a product (at a rate, or through the levels of a boxcar)
dims The properties of people that this delivery needs, as stratifications where everyone starts at the first level
due Whether it acts on this step: within its window, on one of its rounds (if it has them), and when its when= function holds (if it has one)
edge_prob The probability of moving along one of the treatment’s transitions: its own (a number, or a dict by state), times the modifiers of the transition if it is undriven (scalar, per agent, or per state and group)
edge_sources The condition of being in a source state of a transition the treatment moves people along
eligible_now Who can receive it now: eligible, in a state a move is from (or carrying the strains a change of strains is from), not holding it already (unless held=False, or its protection fades by a function of time, when a new dose restarts it), and not at the level a transfer moves them to
fire Record an event of this delivery, which is one of its product too (see ss.products.EventSource)
follow Move the selected people to other levels of some dimensions; returns those chosen among them, as they now are
give Deliver the product to the people chosen, and record them (and the outcomes) as its events
hold Those chosen now hold the product: at level 1, or with doses (doses=), the next dose
infected_states The infected states of the disease, which a test with no detects= finds and a treatment with no who= is for; raises if there are none
init_pre Find the disease and the product, check them against the sim, and set up what is delivered
init_results The number delivered, eligible, and covered on each step, and the cost, capacity lost, outcomes, and queue, as it has them
key The order in which each agent, or each state and group, is served (lowest first), or None for a random order: a
key_product For a delivery for several diseases (disease=[...]): their names, as the sim has them, and the product keyed by them
limit The most people that can be served now: what is left of the capacity this step
mark_offered Record that the selected people have been offered the product; returns those chosen, as they now are
marks When the delivery acts, as times on the results’ time axis, for marking on plots (see sim.plot()): a list of times
max_wait The most steps anyone waits (inf for queue=True)
moved_edges The transitions the product moves people along, as (disease, transition) names, once initialized
n_agents As agents, the number of agents selected
n_selected The number of people selected, as results count them (see ss.results.people_scale())
new_spells Routine delivery is once per spell of being eligible: those offered it who are no longer eligible can be offered it again when they are
offer Those of some people who are eligible: not holding the product already, not yet offered it (for routine delivery), and so on
outcome_names The names of its outcomes, which are events and results: its product’s, and never_ran for a queue with a limit
people The number of people selected, whatever the results count in
per_state A value for each state (each a number or an ss.by), as a value for each agent, or each state and group (of eng, the delivery’s disease by default)
receive Offer the product to some people: those eligible among them, thinned by coverage, served within capacity, and recorded as offered it
record_events The coverage of what was delivered in the step
report Count the results, from the least severe (see ss.Diagnostic.result_names), and record the people with each as an event, which the steps that follow it act on
row The row of the results by group that time point ti is in
score A priority given as a score (served highest first), per agent or per state and group
serve Who is served now, of those chosen (and those waiting, with queue=), within what is left of the capacity; returns those offered and those served
serve_queue Serve those waiting and those just chosen, by priority and then by how long they have waited; the rest wait, until queue=
shift Move the selected people to other levels of some dimensions (mover is the event they are, if known, which a compartmental run uses)
skip_past For at_age=: the people already past the age are recorded as offered it, so only those who reach the age get it: on its
step Deliver the product to whoever it is due to in this step (at its time point, as for all code in a step: see ss.loop.Loop), before the disease’s transitions in it, under every solver
step_results Act on the test results that have become available (agents only)
take Choose n people (a number of people, not agents) from the candidates, in the order of priority=: as agents,
tally Add the people selected to a result, in total and by group; returns the total
test Work out the result of each test (one draw per person, from the probability of each result: see ss.Diagnostic.tails()), and either act on it or wait for it
tiebreak A random number per agent, the same for every choice of the step (from the delivery’s own stream, so scenarios stay paired)
trigger_disease The disease of the first transition or delivery in the event that triggers this delivery, if any
typed_function Whether the coverage is a function of the sim that gives a typed rate (e.g. lambda sim: ss.peryear(4)): worked out the first time it can be called
uids As agents, the UIDs of the agents selected
use Record the people served, against the capacity of the step
used_now The number of people served so far in this step, against the capacity
add
interventions.Event.add(key, uids=None, groups=None, part=None)

Add people to a result (and to its part for one disease and transition): agents by UID, or people by group

age_reason
interventions.Event.age_reason(sim)

With at_age=: why a compartmental run cannot deliver it, or None. As compartments, people reach the age by aging from the age group below it into the one it starts, so the sim needs age groups with an edge at the age. It is an error rather than a reason for solver='auto' to run as agents (see ss.solvers.init_capabilities()), since a comparison with a baseline without it would then compare two solvers.

agent_reasons
interventions.Event.agent_reasons(sim)

The reasons, if any, that this delivery needs agents (a priority per agent is ignored by a compartmental solver that was asked for, with a note: see key())

arrivals
interventions.Event.arrivals()

Who is offered it now, before eligibility: everyone, or those its event happened to (with a delay, those it happened to the delay ago)

boxed
interventions.Event.boxed(sim)

Whether holding the product has the levels of a boxcar in this sim: in a compartmental run, for a product that wanes as an ss.boxcar (see ss.products.Held.boxcar_form)

check_coded
interventions.Event.check_coded(sim)

For a disease written as code: agents only, and it has the parts the product uses, or this raises naming the missing one

convert
interventions.Event.convert(val)

Convert a typed quantity to a plain number in the sim’s unit

cure
interventions.Event.cure(chosen)

Move the people treated along the transitions of the treatment (see ss.Treatment), and record the outcomes as results and events: each person in a source of one of a disease’s moves along it with its probability (cured), or does not (failed); one in none is unneeded.

default_eligible
interventions.Event.default_eligible()

Who is eligible if nothing is said: for a treatment that is not triggered, the people it can cure (those in the sources of its moves, or who are infected)

delay_steps
interventions.Event.delay_steps(sim)

The number of steps from the trigger to delivery, with a fixed delay (when=ss.on(…, delay=…), at least one)

delayed_arrivals
interventions.Event.delayed_arrivals()

With a delay (when=ss.on(event, delay=…); agents only): those triggered since its last step start waiting (unless waiting already), and those whose wait is over arrive

It runs whether or not its trigger has run in the step (see order_steps()), so it reads the events of the step before that it has not read yet (those of deliveries that run after it), then those of this step. A wait is at least a step: one drawn as less (including zero) ends on the step after the trigger.

describe
interventions.Event.describe()

A line saying what is delivered and how

dim_moves
interventions.Event.dim_moves(sim=None)

Movement along those properties that happens by itself: losing the protection of a product (at a rate, or through the levels of a boxcar)

dims
interventions.Event.dims(sim=None)

The properties of people that this delivery needs, as stratifications where everyone starts at the first level

due
interventions.Event.due()

Whether it acts on this step: within its window, on one of its rounds (if it has them), and when its when= function holds (if it has one)

edge_prob
interventions.Event.edge_prob(e, eng, state=None)

The probability of moving along one of the treatment’s transitions: its own (a number, or a dict by state), times the modifiers of the transition if it is undriven (scalar, per agent, or per state and group)

edge_sources
interventions.Event.edge_sources()

The condition of being in a source state of a transition the treatment moves people along

eligible_now
interventions.Event.eligible_now(held=True)

Who can receive it now: eligible, in a state a move is from (or carrying the strains a change of strains is from), not holding it already (unless held=False, or its protection fades by a function of time, when a new dose restarts it), and not at the level a transfer moves them to

fire
interventions.Event.fire(outcome, sel, eng=None, before=None)

Record an event of this delivery, which is one of its product too (see ss.products.EventSource)

follow
interventions.Event.follow(sel, chosen, changes, mover=None)

Move the selected people to other levels of some dimensions; returns those chosen among them, as they now are

give
interventions.Event.give(chosen, capped=False)

Deliver the product to the people chosen, and record them (and the outcomes) as its events

hold
interventions.Event.hold(chosen)

Those chosen now hold the product: at level 1, or with doses (doses=), the next dose

infected_states
interventions.Event.infected_states()

The infected states of the disease, which a test with no detects= finds and a treatment with no who= is for; raises if there are none

init_pre
interventions.Event.init_pre(sim)

Find the disease and the product, check them against the sim, and set up what is delivered

Parameters
Name Type Description Default
sim Sim the sim being initialized required
init_results
interventions.Event.init_results()

The number delivered, eligible, and covered on each step, and the cost, capacity lost, outcomes, and queue, as it has them

key
interventions.Event.key(strict=False)

The order in which each agent, or each state and group, is served (lowest first), or None for a random order: a condition’s people (or the first of a list’s) first, then the next; or the highest score first

Parameters
Name Type Description Default
strict bool in a compartmental run, raise ss.CapabilityError for a priority that is per agent, rather than ignoring it with a note False
key_product
interventions.Event.key_product(sim)

For a delivery for several diseases (disease=[...]): their names, as the sim has them, and the product keyed by them

limit
interventions.Event.limit()

The most people that can be served now: what is left of the capacity this step

mark_offered
interventions.Event.mark_offered(sel, chosen)

Record that the selected people have been offered the product; returns those chosen, as they now are

marks
interventions.Event.marks()

When the delivery acts, as times on the results’ time axis, for marking on plots (see sim.plot()): a list of times (for each round, up to 10 of them) or of (start, stop) pairs (for routine delivery, or more rounds, from a start or to a stop within the run); none for delivery on an event, a condition, or a function, whose times are not fixed

max_wait
interventions.Event.max_wait(sim)

The most steps anyone waits (inf for queue=True)

moved_edges
interventions.Event.moved_edges()

The transitions the product moves people along, as (disease, transition) names, once initialized

n_agents
interventions.Event.n_agents(sel)

As agents, the number of agents selected

n_selected
interventions.Event.n_selected(sel)

The number of people selected, as results count them (see ss.results.people_scale())

new_spells
interventions.Event.new_spells()

Routine delivery is once per spell of being eligible: those offered it who are no longer eligible can be offered it again when they are

offer
interventions.Event.offer(sel)

Those of some people who are eligible: not holding the product already, not yet offered it (for routine delivery), and so on

outcome_names
interventions.Event.outcome_names()

The names of its outcomes, which are events and results: its product’s, and never_ran for a queue with a limit

people
interventions.Event.people(sel)

The number of people selected, whatever the results count in

per_state
interventions.Event.per_state(values, what, eng=None)

A value for each state (each a number or an ss.by), as a value for each agent, or each state and group (of eng, the delivery’s disease by default)

receive
interventions.Event.receive(sel)

Offer the product to some people: those eligible among them, thinned by coverage, served within capacity, and recorded as offered it

record_events
interventions.Event.record_events()

The coverage of what was delivered in the step

report
interventions.Event.report(sels)

Count the results, from the least severe (see ss.Diagnostic.result_names), and record the people with each as an event, which the steps that follow it act on

row
interventions.Event.row(ti)

The row of the results by group that time point ti is in

score
interventions.Event.score(val)

A priority given as a score (served highest first), per agent or per state and group

serve
interventions.Event.serve(sel, chosen)

Who is served now, of those chosen (and those waiting, with queue=), within what is left of the capacity; returns those offered and those served

serve_queue
interventions.Event.serve_queue(sel, chosen)

Serve those waiting and those just chosen, by priority and then by how long they have waited; the rest wait, until queue=

shift
interventions.Event.shift(sel, changes, mover=None)

Move the selected people to other levels of some dimensions (mover is the event they are, if known, which a compartmental run uses)

skip_past
interventions.Event.skip_past()

For at_age=: the people already past the age are recorded as offered it, so only those who reach the age get it: on its first step, everyone past it (as agents, older by more than a step; in a compartmental run, everyone in an age group at or above it); and as agents, on each step after, the agents who have arrived since (e.g. immigrants made by people.grow())

step
interventions.Event.step()

Deliver the product to whoever it is due to in this step (at its time point, as for all code in a step: see ss.loop.Loop), before the disease’s transitions in it, under every solver

step_results
interventions.Event.step_results()

Act on the test results that have become available (agents only)

take
interventions.Event.take(cands, n, carry=False, wait=None)

Choose n people (a number of people, not agents) from the candidates, in the order of priority=: as agents, sorted by priority with ties broken at random; as compartments, whole cells in order and pro rata within a tie

Parameters
Name Type Description Default
cands array the candidates, as a selection required
n float the number of people required
carry bool as agents, keep the part of an agent left over for the next step (for a capacity) False
wait array the steps each has waited (per agent, or the level of waiting of each group): longest first, after the priority None
tally
interventions.Event.tally(key, sel, weight=1.0)

Add the people selected to a result, in total and by group; returns the total

test
interventions.Event.test(chosen)

Work out the result of each test (one draw per person, from the probability of each result: see ss.Diagnostic.tails()), and either act on it or wait for it

tiebreak
interventions.Event.tiebreak(uids)

A random number per agent, the same for every choice of the step (from the delivery’s own stream, so scenarios stay paired)

trigger_disease
interventions.Event.trigger_disease(sim)

The disease of the first transition or delivery in the event that triggers this delivery, if any

typed_function
interventions.Event.typed_function()

Whether the coverage is a function of the sim that gives a typed rate (e.g. lambda sim: ss.peryear(4)): worked out the first time it can be called

uids
interventions.Event.uids(sel)

As agents, the UIDs of the agents selected

use
interventions.Event.use(served)

Record the people served, against the capacity of the step

used_now
interventions.Event.used_now()

The number of people served so far in this step, against the capacity

Intervention

interventions.Intervention(*args, who=None, **kwargs)

Base class for interventions written as code

Write one when the built-in events and deliveries cannot say what the intervention does. Its key method is step(), called on each timestep, which can change the states of the diseases (e.g. treating or vaccinating agents). To deliver a product, or to move people between states, use ss.vaccinate(), ss.screen(), ss.treat(), or ss.Event() instead, which run under every solver.

An intervention written as code can be given who=, who it can reach, as for a delivery: a condition on people (ss.person.age < 5), or a function of the sim (and of the intervention, as self) returning UIDs or a mask. Its step() then reads the people eligible now with check_eligibility().

Parameters

Name Type Description Default
args list passed to ss.Module
who Cond / func who it can reach (by default everyone alive), read by check_eligibility() None
kwargs dict passed to ss.Module

Example:

class Discount(ss.Intervention):
    def step(self):
        uids = self.check_eligibility() # Those who= holds for now, alive
        self.sim.diseases.sis.rel_trans[uids] = 0.5

sim = ss.Sim(diseases='sis', networks='random', interventions=Discount(who=ss.person.age < 15)).run()

Attributes

Name Description
has_product Whether the intervention delivers a product

Methods

Name Description
check_eligibility The UIDs of the people eligible now: those alive whom who= holds for (evaluated as a delivery’s who= is), or everyone alive
init_pre Initialize the module, and its product if it has one
check_eligibility
interventions.Intervention.check_eligibility()

The UIDs of the people eligible now: those alive whom who= holds for (evaluated as a delivery’s who= is), or everyone alive

A subclass can override it, for a rule of its own.

init_pre
interventions.Intervention.init_pre(sim)

Initialize the module, and its product if it has one

Parameters
Name Type Description Default
sim Sim the sim being initialized required

at_age

interventions.at_age(age, who=None)

Who an event reaches: people as they reach an age, as its who=; e.g. ss.vaccinate(who=ss.at_age(ss.months(9)))

Each person is reached once, at the first step on which they are that age or older; not those already past it when the event starts, nor (as agents) those who arrive past it later, e.g. immigrants. As compartments, people reach it by aging into the age group it starts, so the sim needs age groups with an edge at the age (an error otherwise). Join it to other conditions with &, e.g. ss.at_age(ss.years(9)) & ss.person.female.

Parameters

Name Type Description Default
age dur / float the age (a bare number is in years) required
who Cond any other condition on who is reached; usually given by joining with & instead None

capacity

interventions.capacity(n, priority=None, queue=False)

How many a delivery can serve, who is served first, and what happens to the rest, as its capacity=

capacity=n is the same as capacity=ss.capacity(n): this is for when there is a priority or a queue too.

Parameters

Name Type Description Default
n float / rate the number that can be served: per round (or per step, for delivery triggered by an event or by a function), or a rate (e.g. ss.peryear(50_000)), which routine delivery needs, since it has no rounds for a number to be per; a rate in rounds gives what accrues between them required
priority Cond / list / Expr / func who is served first: a condition, or a list of them served in order (all of the first, then the second); a score, highest first: an expression (e.g. -hiv.cd4, the lowest CD4 first) or a function of the sim (or of (sim, uids), agents only); or a list of conditions and scores, each breaking the ties of the ones before (e.g. [due, ss.person.age], those due first, and among them the oldest); other ties are broken at random None
queue bool / dur what happens to those not served (agents only): False (the default), they are lost; True, they wait until served; a duration, they wait at most that long, and those still waiting then are the outcome never_ran. Those waiting are served before anyone newly reached in their class (longest first), and leave the queue if they stop being eligible. A queue is for a service with a waiting list (e.g. treatment slots), where demand turned away comes back rather than being lost False

Examples

art = ss.treat(drug, who=hiv.diagnosed, capacity=ss.capacity(ss.peryear(50_000), priority=-hiv.cd4, queue=True))

screen

interventions.screen(
    what=None,
    who=None,
    when=None,
    coverage=None,
    capacity=None,
    strain=None,
    increment=None,
    trace=None,
    skip_reached_within=None,
    disease=None,
    start=None,
    stop=None,
    name=None,
    label=None,
    **kwargs,
)

Deliver a diagnostic test; see ss.Delivery for the arguments

when=ss.on(event, delay=...) is the delivery’s, the time from its trigger to the test, as for any delivery; the time from the test to its result is the test’s (ss.Diagnostic(result_delay=...)).

Its outcomes, positive and negative, are events on the step the result is available (after the test’s result_delay), and results: the number with each result on each step. What happens next is a step of its own, triggered by an outcome (when=screening.positive).

Note: CRN safe as agents.

Examples

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)
screening = ss.screen(sensitivity=0.9, specificity=0.98, coverage=0.4, when=ss.schedule(every=ss.days(7)))
treatment = ss.treat(cure=0.95, when=screening.positive, coverage=0.8)
sim = ss.Sim(sir, interventions=[screening, treatment], stop=100).run()

treat

interventions.treat(
    what=None,
    who=None,
    when=None,
    coverage=None,
    capacity=None,
    strain=None,
    increment=None,
    trace=None,
    skip_reached_within=None,
    disease=None,
    start=None,
    stop=None,
    name=None,
    label=None,
    **kwargs,
)

Deliver a treatment; see ss.Delivery for the arguments

Note: CRN safe as agents.

Examples

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)
treatment = ss.treat(cure=0.95, coverage=0.5, when=ss.schedule(every=ss.days(7))) # Makes the drug, ss.Treatment(cure=0.95)
sim = ss.Sim(sir, interventions=treatment, stop=100).run()

vaccinate

interventions.vaccinate(
    what=None,
    who=None,
    when=None,
    coverage=None,
    capacity=None,
    strain=None,
    increment=None,
    trace=None,
    skip_reached_within=None,
    disease=None,
    start=None,
    stop=None,
    name=None,
    label=None,
    **kwargs,
)

Deliver a vaccine; see ss.Delivery for the arguments

Note: CRN safe as agents.

Examples

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)
campaign = ss.vaccinate(efficacy=0.85, coverage=0.7, when=[20, 40]) # Makes the vaccine, ss.Vaccine(efficacy=0.85)
sim = ss.Sim(sir, interventions=campaign, stop=100).run()

Functions

Name Description
check_replaced An error for a keyword that an event or delivery does not take (Starsim 3’s, one of replaced, or one only a delivery takes), saying what to give instead
coded_disease The disease of this name if it is written as code (not declared), else None
fired The people an event happened to on this step (see ss.conditions.Selector.leaf())
flush_memory At the start of a step: put any events not yet there into the memory
memory_needs The events whose memory something in the sim reads, by (module name, outcome): the kinds read (ever, count, since)
modules_of The modules of a kind (‘interventions’, ‘connectors’, ‘diseases’): the sim’s, once it has them, and before then those in its parameters
move_paths For move= as a string, e.g. ‘sir.S >> sir.V’ or ‘U + B >> B’: the names of the states people move from (a list) and to, and the name of their module (None if not given)
movers The names of the products and deliveries that name a transition: those that move people along it, and those triggered by it
order_steps The interventions in the order they run: each delivery after the deliveries whose events trigger it, so a step acts on
parse_when The when= of an event, as the keywords of Event._init(): nothing (routine), an event that triggers it, times (a date, a year,
parse_who The who= of an event, as the keywords of Event._init(): a condition on people (who=), one on the population (where=), or ss.at_age()
product_keys The keywords of a kind of product (e.g. efficacy and waning for ss.Vaccine), which its delivery takes to make one
remembered The memory of an event for each agent or group: whether (ever), how often (n_times), or how long ago (since, in the sim’s unit) it happened
trigger_moves The transitions triggered by an event of a delivery or product (e.g. ss.Transition(I, R_res, when=drug.failed, p=0.05)):

check_replaced

interventions.check_replaced(kwargs, cls)

An error for a keyword that an event or delivery does not take (Starsim 3’s, one of replaced, or one only a delivery takes), saying what to give instead

coded_disease

interventions.coded_disease(sim, name)

The disease of this name if it is written as code (not declared), else None

fired

interventions.fired(selector, cond)

The people an event happened to on this step (see ss.conditions.Selector.leaf())

flush_memory

interventions.flush_memory(sim)

At the start of a step: put any events not yet there into the memory

memory_needs

interventions.memory_needs(sim)

The events whose memory something in the sim reads, by (module name, outcome): the kinds read (ever, count, since)

Found by walking every expression of the interventions, connectors, diseases, and demographics: conditions, rates, p=, dur=, attributes, results, and modifier amounts.

modules_of

interventions.modules_of(sim, key)

The modules of a kind (‘interventions’, ‘connectors’, ‘diseases’): the sim’s, once it has them, and before then those in its parameters

move_paths

interventions.move_paths(move, name)

For move= as a string, e.g. ‘sir.S >> sir.V’ or ‘U + B >> B’: the names of the states people move from (a list) and to, and the name of their module (None if not given)

movers

interventions.movers(sim, modname, name)

The names of the products and deliveries that name a transition: those that move people along it, and those triggered by it

order_steps

interventions.order_steps(mods)

The interventions in the order they run: each delivery after the deliveries whose events trigger it, so a step acts on the step its trigger happens; otherwise in the order given. A delivery with a delay (when=ss.on(event, delay=...)) is at least a step after its trigger, so it need not run after it, and may be in a cycle of triggers (e.g. a test repeated a year after a negative result); any other cycle raises.

parse_when

interventions.parse_when(when, name, start=None, stop=None)

The when= of an event, as the keywords of Event._init(): nothing (routine), an event that triggers it, times (a date, a year, a duration after the start of the sim, or a list of them), a function of the date, or an ss.schedule() with these, how often, and a start and stop; and the window of start= and stop=, which any of these can have (the same as in ss.schedule(), which then must have none of its own)

parse_who

interventions.parse_who(who)

The who= of an event, as the keywords of Event._init(): a condition on people (who=), one on the population (where=), or ss.at_age()

product_keys

interventions.product_keys(kind)

The keywords of a kind of product (e.g. efficacy and waning for ss.Vaccine), which its delivery takes to make one

remembered

interventions.remembered(selector, cond)

The memory of an event for each agent or group: whether (ever), how often (n_times), or how long ago (since, in the sim’s unit) it happened

trigger_moves

interventions.trigger_moves(owner, outcome, sel, eng=None, before=None)

The transitions triggered by an event of a delivery or product (e.g. ss.Transition(I, R_res, when=drug.failed, p=0.05)): the people it happened to who are in the transition’s source, and meet the rest of its condition, move now, with its probability (p=), or split between its destinations; under every solver

Parameters

Name Type Description Default
owner Event / Product what fired the event required
outcome str the outcome (None for the delivery itself) required
sel uids / array the people it happened to: UIDs, or a fraction of each state and group of eng required
eng Engine in a compartmental run, the engine whose states and groups sel is a fraction of None
before array in a compartmental run, the people in each state and group that sel is a fraction of, if not those now None