Source code for scripts.interventions.run_tb_interventions

import tbsim as mtb
import starsim as ss
import sciris as sc
import matplotlib.pyplot as plt
import pprint as pprint
import pandas as pd

# Simple default parameters
DEFAULT_SPARS = dict(
    dt=ss.days(7),
    start=ss.date('1975-01-01'),
    stop=ss.date('2030-12-31'),
    rand_seed=123,
    verbose=0,
)

DEFAULT_TBPARS = dict(
    beta=ss.peryear(0.0025),
    init_prev=ss.bernoulli(p=0.25),
    dt=ss.days(7),      
    start=ss.date('1975-02-01'),
    stop=ss.date('2030-12-31'),
)

# Simple age distribution
age_data = pd.DataFrame({
    'age': [0, 2, 4, 10, 15, 20, 30, 40, 50, 60, 70, 80],
    'value': [20, 10, 25, 15, 10, 5, 4, 3, 2, 1, 1, 1]  # Skewed toward younger ages
})

[docs] def build_sim(scenario=None, spars=None): """ Build and return a complete Starsim-based simulation instance for TB modeling, incorporating optional interventions and user-defined parameters. Args: scenario (dict, optional): A dictionary defining scenario-specific components, such as intervention parameters and TB simulation settings. Expected keys: - 'tbpars' (dict): TB-specific simulation parameters. - 'tptintervention' (dict, optional): Parameters for TPT intervention. - 'bcgintervention' (dict, optional): Parameters for BCG intervention. spars (dict, optional): General simulation parameters (e.g., timestep, duration). These override values in the DEFAULT_SPARS global dictionary. Returns: ss.Sim: A fully initialized simulation object containing: - A population (`People`) with TB-related extra states. - A TB disease module initialized with merged parameters. - A list of social and household network layers. - Optional interventions (TPT, BCG or Beta) as defined by the scenario. - Demographic processes like births and deaths. - Core simulation parameters merged from defaults and user inputs. Notes: - If no parameters are provided, it will use the default values of the participating simulation components. Example: sim = build_sim(scenario=my_scenario, spars={'n_steps': 200}) sim.run() """ scenario = scenario or {} # Merge parameters spars = {**DEFAULT_SPARS, **(spars or {})} tbpars = {**DEFAULT_TBPARS, **(scenario.get('tbpars') or {})} # Create interventions list interventions = [] # Add BCG interventions (can be single or multiple) bcg_params = scenario.get('bcgintervention') if bcg_params: if isinstance(bcg_params, dict): # Single BCG intervention interventions.append(mtb.BCGProtection(pars=bcg_params)) elif isinstance(bcg_params, list): # Multiple BCG interventions for i, params in enumerate(bcg_params): params['name'] = f'BCG_{i}' # Give unique name interventions.append(mtb.BCGProtection(pars=params)) # Add TPT interventions (can be single or multiple) tpt_params = scenario.get('tptintervention') if tpt_params: if isinstance(tpt_params, dict): # Single TPT intervention interventions.append(mtb.TPTInitiation(pars=tpt_params)) elif isinstance(tpt_params, list): # Multiple TPT interventions for i, params in enumerate(tpt_params): params['name'] = f'TPT_{i}' # Give unique name interventions.append(mtb.TPTInitiation(pars=params)) # Add Beta interventions (can be single or multiple) beta_params = scenario.get('betabyyear') if beta_params: if isinstance(beta_params, dict): # Single Beta intervention interventions.append(mtb.BetaByYear(pars=beta_params)) elif isinstance(beta_params, list): # Multiple Beta interventions for i, params in enumerate(beta_params): params['name'] = f'Beta_{i}' # Give unique name interventions.append(mtb.BetaByYear(pars=params)) # Create simulation components pop = ss.People(n_agents=500, age_data=age_data) tb = mtb.TB(pars=tbpars) networks = [ ss.RandomNet({'n_contacts': ss.poisson(lam=5), 'dur': 0}), mtb.HouseholdNet() ] # Create and return simulation return ss.Sim( people=pop, networks=networks, interventions=interventions, diseases=[tb], pars=spars, )
[docs] def get_scenarios(): """ HELP Define a set of simulation scenarios for evaluating TB interventions. Returns: dict: A dictionary where each key is the name of a scenario and the value is a dictionary of simulation parameters. Each scenario may include: - 'name' (str): A human-readable scenario name. - 'tbpars' (dict, optional): Parameters controlling the simulation timeframe. - 'bcgintervention' (dict, optional): BCG vaccine intervention settings. - 'tptintervention' (dict, optional): Tuberculosis Preventive Therapy settings. - 'betabyyear' : (dict, optional): For changing the value of beta during the same simulation period. Scenarios included: - 'Baseline': No intervention, default simulation window. - 'BCG': BCG vaccination with 90% coverage. - 'TPT': TPT with full eligibility, conditional on HIV status. """ return { 'Baseline': { 'name': 'No interventions', 'tbpars': dict(start=ss.date('1975-01-01'), stop=ss.date('2030-12-31')), }, 'Baseline and BetaByYear': { 'name': 'No interventions', 'tbpars': dict(start=ss.date('1975-01-01'), stop=ss.date('2030-12-31')), 'betabyyear':dict(years=[1990, 2000], x_beta=[0.5, 1.4]) }, 'Single BCG': { 'name': 'Single BCG intervention', 'tbpars': dict(start=ss.date('1975-01-01'), stop=ss.date('2030-12-31')), 'bcgintervention': dict( coverage=0.8, start=ss.date('1980-01-01'), stop=ss.date('2020-12-31'), age_range=[1, 5], ), }, 'Multiple BCG': { 'name': 'Multiple BCG interventions', 'tbpars': dict(start=ss.date('1975-01-01'), stop=ss.date('2030-12-31')), 'bcgintervention': [ dict( coverage=0.9, start=ss.date('1980-01-01'), stop=ss.date('2020-12-31'), age_range=[0, 2], # For children ), dict( coverage=0.3, start=ss.date('1985-01-01'), stop=ss.date('2015-12-31'), age_range=[25, 40], # For adults ), ], }, }
[docs] def run_scenarios(plot=True): """Run all scenarios and optionally plot results.""" import tbsim.utils.plots as pl scenarios = get_scenarios() results = {} for name, scenario in scenarios.items(): print(f"\nRunning: {name}") sim = build_sim(scenario=scenario) sim.run() results[name] = sim.results.flatten() if plot: pl.plot_combined(results, heightfold=2, outdir='results/interventions') # filter=mtb.FILTERS.important_metrics) plt.show() return results
if __name__ == '__main__': # Run all scenarios results = run_scenarios(plot=True)