tb
tb
TB natural history model. State definitions and transition diagram are in the API docs (tbsim.tb).
Classes
| Name | Description |
|---|---|
| TB | Agent-based TB natural history adapting the LSHTM compartmental structure [1] (Schwalb et al. 2025). |
| TBS | TB state labels. |
| choice2d | Version of ss.choice() allowing different per-agent probabilities. |
TB
tb.TB(pars=None, **kwargs)Agent-based TB natural history adapting the LSHTM compartmental structure [1] (Schwalb et al. 2025). States in TBS span the spectrum from susceptibility to active disease and treatment. Infectious states are TBS.ASYMPTOMATIC and TBS.SYMPTOMATIC; the force of infection depends on pars.beta and the prevalence of those states, with pars.trans_asymp (kappa) giving the relative infectiousness of asymptomatic vs symptomatic TB. Reinfectable state (TBS.CLEARED) uses per-agent rr_reinfection, set on entry from each pathway (rr_reinfection_cleared, rr_reinfection_rec, rr_reinfection_treat). Per-agent modifiers rr_activation, rr_clearance, rr_death scale selected rates.
Args (pars): Transmission and reinfection
- ``init_prev``: Initial seed infections (prevalence).
- ``beta``: Transmission rate per year.
- ``trans_asymp``: Relative transmissibility, asymptomatic vs symptomatic. (kappa)
- ``rr_reinfection_rec``: Relative risk of reinfection after recovering from NON_INFECTIOUS. (pi)
- ``rr_reinfection_treat``: Relative risk of reinfection after completing treatment. (rho)
- ``rr_reinfection_cleared``: Relative risk of reinfection after clearing latent infection. Default: 1.0
- ``dur_reinfection_protection``: Distribution of duration of reinfection protection. If None, never wanes.
*From INFECTION (latent)*
- ``inf_cle``: Infection -> Cleared (no active TB).
- ``inf_non``: Infection -> Non-infectious TB.
- ``inf_asy``: Infection -> Asymptomatic TB.
*From NON_INFECTIOUS*
- ``non_rec``: Non-infectious -> Recovered.
- ``non_asy``: Non-infectious -> Asymptomatic.
*From ASYMPTOMATIC*
- ``asy_non``: Asymptomatic -> Non-infectious.
- ``asy_sym``: Asymptomatic -> Symptomatic.
*From SYMPTOMATIC*
- ``sym_asy``: Symptomatic -> Asymptomatic.
- ``sym_dead``: Symptomatic -> Dead (TB-specific mortality, mu_TB).
*Background (general mortality is handled by* ``ss.Deaths`` *demographics, not this module)*
- ``cxr_asymp_sens``: CXR sensitivity for screening asymptomatic (0-1).
Attributes
| Name | Type | Description |
|---|---|---|
| - | susceptible (BoolState, default=True |
Whether the agent is susceptible to TB. |
| - | infected (BoolState, default=False |
Whether the agent is currently infected. |
| - | ever_infected (BoolState, default=False |
Whether the agent has ever been infected. |
| - | on_treatment (BoolState, default=False |
Whether the agent is on TB treatment. |
| - | state (FloatArr, default=TBS.SUSCEPTIBLE |
Current TB state (TBS value). |
| - | ti_infected (FloatArr, default=-inf |
Time of infection (never infected = -inf). |
| - | rel_sus (FloatArr, default=1.0 |
Relative susceptibility to TB. |
| - | rel_trans (FloatArr, default=1.0 |
Relative transmissibility of TB. |
| - | rr_activation (FloatArr, default=1.0 |
Multiplier on INFECTION -> NON_INFECTIOUS / ASYMPTOMATIC. |
| - | rr_clearance (FloatArr, default=1.0 |
Multiplier on NON_INFECTIOUS -> CLEARED. |
| - | rr_death (FloatArr, default=1.0 |
Multiplier on SYMPTOMATIC -> DEAD. |
| - | rr_reinfection (FloatArr, default=1.0 |
Per-agent relative reinfection risk; set on entry to CLEARED. |
| - | ti_rr_reinfection_wane (FloatArr, default=np.inf |
Sim time at which rr_reinfection resets to 1.0. |
Example
::
import starsim as ss
import tbsim
sim = ss.Sim(diseases=tbsim.TB(), pars=dict(start='2000', stop='2020'))
sim.run()
sim.plot()
References
[1] Schwalb et al. (2025) Potential impact, costs, and benefits of population-wide screening interventions for tuberculosis in Viet Nam. PLOS Glob Public Health. https://doi.org/10.1371/journal.pgph.0005050
Methods
| Name | Description |
|---|---|
| finalize_results | Compute cumulative series from new-event series after the run. |
| init_results | Define result time series. |
| plot | Plot TB result time series using tbsim.plot(). |
| set_prognoses | Set prognoses for newly infected agents (called when transmission occurs). |
| step | Advance TB state machine one timestep. |
| step_die | Apply death for the given agents and update TB state. |
| transition | Evaluate competing exponential transitions over one dt and apply immediately. |
| update_results | Record current time-step values for all result series. |
finalize_results
tb.TB.finalize_results()Compute cumulative series from new-event series after the run.
init_results
tb.TB.init_results()Define result time series.
plot
tb.TB.plot(**kwargs)Plot TB result time series using tbsim.plot().
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| **kwargs | Forwarded to :func:tbsim.plots.plot. Common options include select, title, n_cols, row_height, style, filename, and show. |
{} |
Returns
| Name | Type | Description |
|---|---|---|
| matplotlib.figure.Figure |
set_prognoses
tb.TB.set_prognoses(uids, sources=None)Set prognoses for newly infected agents (called when transmission occurs).
The base starsim.Infection calls this when a susceptible agent acquires infection. We mark agents infected and set state to INFECTION (latent). Transitions are evaluated per dt each timestep in step.
step
tb.TB.step()Advance TB state machine one timestep.
- Transmission (via
super().step()): handles force of infection. - Reset RR multipliers for all agents (interventions set fresh each step).
- Evaluate transitions: for each state group, evaluate competing-risk transitions and apply immediately. Agents may cascade through multiple states in one step.
- Bookkeeping: update flags, modifiers, deaths, results.
step_die
tb.TB.step_die(uids)Apply death for the given agents and update TB state.
Called by the framework when agents die (e.g. background mortality). Sets state to DEAD, clears flags, and stops transmission.
transition
tb.TB.transition(uids, to, rng)Evaluate competing exponential transitions over one dt and apply immediately.
For each agent in uids, computes the probability of transitioning to each destination in to during one timestep. Uses a single uniform draw per agent to decide (a) whether the agent transitions and (b) which destination it goes to. State is updated immediately.
update_results
tb.TB.update_results()Record current time-step values for all result series.
TBS
tb.TBS()TB state labels.
- Each agent is in exactly one of these states.
- Transitions are driven by exponential rates in
TB.
Methods
| Name | Description |
|---|---|
| active_tb_states | States representing active TB disease (non-infectious, asymptomatic, symptomatic). |
| care_seeking_eligible | States eligible for care-seeking: only SYMPTOMATIC. |
| terminal_states | States that should no longer participate in transmission or care flows. |
active_tb_states
tb.TBS.active_tb_states()States representing active TB disease (non-infectious, asymptomatic, symptomatic).
care_seeking_eligible
tb.TBS.care_seeking_eligible()States eligible for care-seeking: only SYMPTOMATIC. Only individuals with clinical symptoms (cough, fever, night sweats, etc.) recognise their illness and seek healthcare.
terminal_states
tb.TBS.terminal_states()States that should no longer participate in transmission or care flows.
choice2d
tb.choice2d(a=None, p=None, replace=True, **kwargs)Version of ss.choice() allowing different per-agent probabilities.
Temporary location; to be ported to Starsim and potentially merged with ss.choice().
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| a | 1D array | the values to choose from (default: np.arange(p.shape[1])) | None |
| p | 2D array | the probability of each choice for each agent | None |
Example: # Choose between specified options each with a specified probability (must sum to 1) p = np.array([ # Per-agent array of outcome probabilities across 3 options [0.1, 0.5, 0.4], [0.2, 0.3, 0.5], [0.3, 0.4, 0.3], [0.4, 0.2, 0.4], [0.5, 0.3, 0.2], [0.8, 0.1, 0.1], ]) n = len(p) choices = tbsim.choice2d(p=p, strict=False)(n)
Methods
| Name | Description |
|---|---|
| ppf | Always use ppf to allow per-agent probabilities |
ppf
tb.choice2d.ppf(rands)Always use ppf to allow per-agent probabilities
Functions
| Name | Description |
|---|---|
| get_tb | Helper to get the TB infection module from a sim |
get_tb
tb.get_tb(sim, which=None)Helper to get the TB infection module from a sim
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| sim | Sim | the simulation to search for the TB module | required |
| which | type | the class of TB module to get (e.g. TB); if None, returns the first BaseTB subclass found | None |