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 None → rr_reinfection_rec (the spec’s coupling; set to 1.0 for the ODE null). - rr_reinfection_non (σ_N): of a NON_INFECTIOUS agent. Default None → rr_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.