resistance.tb_resistant

resistance.tb_resistant

Multi-strain (drug-resistance) TB natural history.

TBResistant extends the single-strain tbsim.TB state machine with a strain-membership overlay: each agent carries a set of strains encoded as a single integer strain_mask (bit j = carries strain j; see tbsim.resistance.Strains). The agent-level TB.state machine is unchanged — resistance is an overlay on top of it.

Transmission reuses Starsim’s common-random-number force-of-infection engine (ss.Infection.infect): step_bookkeeping sets state-dependent susceptible / rel_sus / rel_trans so the engine does the transmission arithmetic, and set_prognoses picks which strain is passed (∝ fitness), enforces identical-strain blocking, and applies superinfection. step_transitions overlays the strain-aware natural history: de-novo resistance acquisition (p_rand, per drug, per carried strain), the progression bottleneck (p_multi), clear-all-strains on natural clearance, and the superinfection rate modifiers (rr_prog_super ψ, rr_clear_super ω).

This reproduces the two-strain reference ODE (tbsim.compartmental.TwoStrainODE) in the n=1 case; see tests/test_resistance.py.

Classes

Name Description
TBResistant Strain-aware TB. See module docstring for the architecture.

TBResistant

resistance.tb_resistant.TBResistant(
    pars=None,
    drugs=None,
    rel_fitness=None,
    name=None,
    label=None,
    **kwargs,
)

Strain-aware TB. See module docstring for the architecture.

Parameters

Name Type Description Default
pars dict TB and resistance parameter overrides. None
drugs list ordered drug/class names defining the strain space (default ['TX'] = the two-strain A/B reference). None
rel_fitness dict per-drug transmission fitness cost r_i (default none). None

Resistance parameters (pars): - rr_reinfection_inf (σ_L): susceptibility of an INFECTION agent to a 2nd strain. Default Nonerr_reinfection_rec (the spec’s coupling; set to 1.0 for the ODE null). - rr_reinfection_non (σ_N): of a NON_INFECTIOUS agent. Default Nonerr_reinfection_inf. - rr_reinfection_asy (σ_A): of a mono ASYMPTOMATIC agent. Default 0. - rr_reinfection_sym (σ_Y): of a mono SYMPTOMATIC agent. Default 0. - p_multi: prob. both strains co-progress at →ASYMPTOMATIC (1 = no bottleneck). Default 1. - rr_prog_super (ψ): progression-rate multiplier for multi-strain agents. Default 1. - rr_clear_super (ω): natural-clearance multiplier for multi-strain agents. Default 1. - p_rand: de-novo resistance {drug: prob} per not-yet-resistant drug at each INFECTION→NON_INFECTIOUS and INFECTION→ASYMPTOMATIC progression; each carried strain mutates independently. Default none (off). - prog_resist_mode: de-novo mechanism, 'mixed' (→ superinfection) or 'replacement'. Default 'mixed'. - prog_select: strain selected when one progresses under the bottleneck, 'random' or 'fitness'. Default 'random'. - init_strains: probability vector over strain ids for seeded infections (default all on id 0, pan-susceptible).

Methods

Name Description
agnostic Construct a TBResistant configured to behave like single-strain tbsim.TB (L7).
set_prognoses Assign strains to newly infected / superinfected agents.
step Reset per-step counters, then run the TB step (transmission → transitions → bookkeeping).
step_bookkeeping Set flags, request TB deaths, reset modifiers, and set strain-aware susceptible / rel_sus / rel_trans.
step_die Clear strains (and their counts) on death, then apply the base TB death handling.
step_transitions Strain-aware natural-history transitions (mirrors the reference ODE).
sterilize_covered Clear (with certainty) every carried strain susceptible to all of regimen_drugs; any
agnostic
resistance.tb_resistant.TBResistant.agnostic(pars=None, **kwargs)

Construct a TBResistant configured to behave like single-strain tbsim.TB (L7).

Sets the “effectively single-strain” defaults — one drug, all seed infections pan-susceptible (init_strains=[1, 0]) and no de-novo resistance (p_rand=None) — so no resistant strain ever arises (and the counter never activates). Reinfection is left at base tbsim.TB’s defaults (rr_reinfection_inf/_non coupling), so a latent/non-infectious agent can be re-exposed exactly as in single-strain TB; because the only circulating strain is pan-susceptible, such re-exposure just resets the infection clock and never creates resistance. This gives a one-liner for strain-aware-vs-agnostic comparison runs without hand-tuning. It does not create a true m=1 strain space (the bitmask needs m = 2**n); it is the documented convenience recipe, not a separate mode.

Parameters
Name Type Description Default
pars dict extra parameter overrides merged over the agnostic defaults. None
**kwargs forwarded to TBResistant (e.g. name). {}

Example::

tb = tbsim.TBResistant.agnostic(pars=dict(beta=ss.permonth(0.2), init_prev=ss.bernoulli(0.05)))
set_prognoses
resistance.tb_resistant.TBResistant.set_prognoses(uids, sources=None)

Assign strains to newly infected / superinfected agents.

Seeds (sources is None or a scalar) draw a single strain from init_strains and start it at count 1. Transmission events (sources is a UID array, one per target) draw the transmitted strain from the source’s carried strains ∝ count × fitness. A target already carrying the drawn strain is superinfected with an identical strain — its count for that strain is incremented (spec §1; previously this was blocked). Otherwise the strain is added (entering INFECTION from a susceptible state, or keeping the current state for a superinfection) at count 1, regardless of how many copies the source carried.

step
resistance.tb_resistant.TBResistant.step()

Reset per-step counters, then run the TB step (transmission → transitions → bookkeeping).

step_bookkeeping
resistance.tb_resistant.TBResistant.step_bookkeeping()

Set flags, request TB deaths, reset modifiers, and set strain-aware susceptible / rel_sus / rel_trans.

step_die
resistance.tb_resistant.TBResistant.step_die(uids)

Clear strains (and their counts) on death, then apply the base TB death handling.

step_transitions
resistance.tb_resistant.TBResistant.step_transitions()

Strain-aware natural-history transitions (mirrors the reference ODE).

sterilize_covered
resistance.tb_resistant.TBResistant.sterilize_covered(uids, regimen_drugs)

Clear (with certainty) every carried strain susceptible to all of regimen_drugs; any regimen-resistant strain persists. An agent left carrying no strain moves to CLEARED (with post-clearance reinfection protection). Shared by strain-aware TPT sterilization and latent treatment (TR-5). Returns the uids that were fully cleared.