''' Demonstrate the vaccine intervention with subtargeting ''' import covasim as cv import numpy as np # Define the vaccine subtargeting def vaccinate_by_age(sim): young = cv.true(sim.people.age < 50) # cv.true() returns indices of people matching this condition, i.e. people under 50 middle = cv.true((sim.people.age >= 50) * (sim.people.age < 75)) # Multiplication means "and" here old = cv.true(sim.people.age > 75) inds = sim.people.uid # Everyone in the population -- equivalent to np.arange(len(sim.people)) vals = np.ones(len(sim.people)) # Create the array vals[young] = 0.1 # 10% probability for people <50 vals[middle] = 0.5 # 50% probability for people 50-75 vals[old] = 0.9 # 90% probbaility for people >75 output = dict(inds=inds, vals=vals) return output # Define the vaccine vaccine = cv.simple_vaccine(days=20, rel_sus=0.8, rel_symp=0.06, subtarget=vaccinate_by_age) if __name__ == '__main__': # Create, run, and plot the simulations sim1 = cv.Sim(label='Baseline') sim2 = cv.Sim(interventions=vaccine, label='With age-targeted vaccine') msim = cv.parallel([sim1, sim2]) msim.plot()
def test_all_interventions(do_plot=False): ''' Test all interventions supported by Covasim ''' sc.heading('Testing default interventions') # Default parameters, using the random layer pars = sc.objdict( pop_size=1e3, scaled_pop=10e3, pop_infected=10, n_days=90, verbose=verbose, ) hpars = sc.mergedicts( pars, {'pop_type': 'hybrid'}) # Some, but not all, tests require layers rsim = cv.Sim(pars) hsim = cv.Sim(hpars) def make_sim(which='r', interventions=None): ''' Helper function to avoid having to recreate the sim each time ''' if which == 'r': sim = sc.dcp(rsim) elif which == 'h': sim = sc.dcp(hsim) sim['interventions'] = interventions sim.initialize() return sim #%% Define the interventions # 1. Dynamic pars i1a = cv.test_prob(start_day=5, symp_prob=0.3) i1b = cv.dynamic_pars({ 'beta': { 'days': [40, 50], 'vals': [0.005, 0.015] }, 'rel_death_prob': { 'days': 30, 'vals': 2.0 } }) # Starting day 30, make diagnosed people stop transmitting # 2. Sequence i2 = cv.sequence(days=[15, 30, 45], interventions=[ cv.test_num(daily_tests=[20] * pars.n_days), cv.test_prob(symp_prob=0.0), cv.test_prob(symp_prob=0.2), ]) # 3. Change beta i3a = cv.change_beta([30, 50], [0.0, 1.0], layers='h') i3b = cv.change_beta([30, 40, 60], [0.0, 1.0, 0.5]) # 4. Clip edges -- should match the change_beta scenarios -- note that intervention i07 was removed i4a = cv.clip_edges([30, 50], [0.0, 1.0], layers='h') i4b = cv.clip_edges([30, 40, 60], [0.0, 1.0, 0.5]) # 5. Test number i5 = cv.test_num(daily_tests=[100, 100, 100, 0, 0, 0] * (pars.n_days // 6)) # 6. Test probability i6 = cv.test_prob(symp_prob=0.1) # 7. Contact tracing i7a = cv.test_prob(start_day=20, symp_prob=0.01, asymp_prob=0.0, symp_quar_prob=1.0, asymp_quar_prob=1.0, test_delay=0) i7b = cv.contact_tracing(start_day=20, trace_probs=dict(h=0.9, s=0.7, w=0.7, c=0.3), trace_time=dict(h=0, s=1, w=1, c=3)) # 8. Combination, with dynamically set days def check_inf(interv, sim, thresh=10, close_day=18): days = close_day if sim.people.infectious.sum() > thresh else np.nan return days i8a = cv.clip_edges(days=check_inf, changes=0.0, layers='s') # Close schools i8b = cv.clip_edges(days=[20, 32, 45], changes=[0.7, 0.3, 0.9], layers=['w', 'c']) # Reduce work and community i8c = cv.test_prob(start_day=38, symp_prob=0.01, asymp_prob=0.0, symp_quar_prob=1.0, asymp_quar_prob=1.0, test_delay=2) # Start testing for TTQ i8d = cv.contact_tracing(start_day=40, trace_probs=dict(h=0.9, s=0.7, w=0.7, c=0.3), trace_time=dict(h=0, s=1, w=1, c=3)) # Start tracing for TTQ # 9. Vaccine i9a = cv.simple_vaccine(days=20, prob=1.0, rel_sus=1.0, rel_symp=0.0) i9b = cv.simple_vaccine(days=50, prob=1.0, rel_sus=0.0, rel_symp=0.0) #%% Create the simulations sims = sc.objdict() sims.dynamic = make_sim('r', [i1a, i1b]) sims.sequence = make_sim('r', i2) sims.change_beta1 = make_sim('h', i3a) sims.clip_edges1 = make_sim('h', i4a) # Roughly equivalent to change_beta1 sims.change_beta2 = make_sim('r', i3b) sims.clip_edges2 = make_sim('r', i4b) # Roughly equivalent to change_beta2 sims.test_num = make_sim('r', i5) sims.test_prob = make_sim('r', i6) sims.tracing = make_sim('h', [i7a, i7b]) sims.combo = make_sim('h', [i8a, i8b, i8c, i8d]) sims.vaccine = make_sim('r', [i9a, i9b]) # Run the simualations for key, sim in sims.items(): sim.label = key sim.run() # Test intervention retrieval methods sim = sims.combo ce1, ce2 = sim.get_interventions(cv.clip_edges) ce, tp = sim.get_interventions([0, 2]) inds = sim.get_interventions(cv.clip_edges, as_inds=True) # Returns [0,1] assert inds == [0, 1] sim.get_interventions('summary') # Prints a summary # Test other intervention methods ce.disp() ce.shrink() #%% Plotting if do_plot: for sim in sims.values(): print(f'Running {sim.label}...') sim.plot() fig = pl.gcf() try: fig.axes[0].set_title(f'Simulation: {sim.label}') except: pass return
def test_states(): ''' Test state consistency against state_diagram.xlsx ''' filename = 'state_diagram.xlsx' sheets = ['Without waning', 'With waning'] indexcol = 'In ↓ you can be →' # Load state diagram dfs = sc.odict() for sheet in sheets: dfs[sheet] = pd.read_excel(filename, sheet_name=sheet) dfs[sheet] = dfs[sheet].set_index(indexcol) # Create and run simulation for use_waning in [False, True]: sc.heading(f'Testing state consistency with waning = {use_waning}') df = dfs[use_waning] # Different states are possible with or without waning # Parameters chosen to be midway through the sim so as few states as possible are empty pars = dict( pop_size = 1e3, pop_infected = 20, n_days = 70, use_waning = use_waning, verbose = 0, interventions = [ cv.test_prob(symp_prob=0.4, asymp_prob=0.01), cv.contact_tracing(trace_probs=0.1), cv.simple_vaccine(days=60, prob=0.1) ] ) sim = cv.Sim(pars).run() ppl = sim.people # Check states errormsg = '' states = df.columns.values.tolist() for s1 in states: for s2 in states: if s1 != s2: relation = df.loc[s1, s2] # e.g. df.loc['susceptible', 'exposed'] print(f'Checking {s1:13s} → {s2:13s} = {relation:2n} ... ', end='') inds = cv.true(ppl[s1]) n_inds = len(inds) vals2 = ppl[s2][inds] is_true = cv.true(vals2) is_false = cv.false(vals2) n_true = len(is_true) n_false = len(is_false) if relation == 1 and n_true != n_inds: errormsg = f'Being {s1}=True implies {s2}=True, but only {n_true}/{n_inds} people are' print(f'× {n_true}/{n_inds} error!') elif relation == -1 and n_false != n_inds: errormsg = f'Being {s1}=True implies {s2}=False, but only {n_false}/{n_inds} people are' print(f'× {n_false}/{n_inds} error!') else: print(f'✓ {n_true}/{n_inds}') if errormsg: raise RuntimeError(errormsg) return
output = dict(inds=inds, vals=vals) return output # Load the sim sim2 = cv.load('Seattle100kV' + str(version) + '.sim') if (choice == 0): seeds = generateSeeds(version) if (choice == 1): seeds = generateRandomSeeds(version) if (choice == 2): seeds = generateDegreeSeeds(version) # Define the vaccine and add it to the sim vaccine = cv.simple_vaccine(days=31 + (version * 7), rel_sus=0.0, rel_symp=0.02, subtarget=vaccinateSeeds(sim2, seeds)) vaccine.vaccinations = vaccine.subtarget['vals'].astype(int) vaccine.initialize(sim2) sim2.pars['interventions'].append(vaccine) # setting 'rel_trans' od vaccinated seeds ensure edge probability on outgoing edges are set to zero for seed in seeds: sim2.people.rel_trans[seed] = 0.0 # Let it run for a week sim2.run(until='2020-04-30') # Save the sim sim2.save('Seattle100kV' + str(version + 1) + '.sim')