def test_calibration(): sc.heading('Testing calibration') pars = dict( verbose=0, start_day='2020-02-05', pop_size=1e3, pop_scale=4, interventions=[cv.test_prob(symp_prob=0.1)], ) sim = cv.Sim(pars, datafile='example_data.csv') calib_pars = dict(beta=[0.013, 0.005, 0.020], test_prob=[0.01, 0.00, 0.30]) def set_test_prob(sim, calib_pars): tp = sim.get_intervention(cv.test_prob) tp.symp_prob = calib_pars['test_prob'] return sim calib = sim.calibrate(calib_pars=calib_pars, custom_fn=set_test_prob, n_trials=5) calib.plot(to_plot=['cum_deaths', 'cum_diagnoses']) assert calib.after.fit.mismatch < calib.before.fit.mismatch return calib
def make_sim(use_defaults=False, do_plot=False): ''' Define a default simulation for testing the baseline -- use hybrid and include interventions to increase coverage. If run directly (not via pytest), also plot the sim by default. ''' # Define the parameters intervs = [ cv.change_beta(days=40, changes=0.5), cv.test_prob(start_day=20, symp_prob=0.1, asymp_prob=0.01) ] # Common interventions pars = dict( pop_size=20000, # Population size pop_infected= 100, # Number of initial infections -- use more for increased robustness pop_type= 'hybrid', # Population to use -- "hybrid" is random with household, school,and work structure verbose=0, # Don't print details of the run interventions=intervs # Include the most common interventions ) # Create the sim if use_defaults: sim = cv.Sim() else: sim = cv.Sim(pars) # Optionally plot if do_plot: s2 = sim.copy() s2.run() s2.plot() return sim
def parse_interventions(int_pars): ''' Parse interventions. Format Args: int_pars = { 'social_distance': [ {'start': 1, 'end': 19, 'level': 'aggressive'}, {'start': 20, 'end': 30, 'level': 'mild'}, ], 'school_closures': [ {'start': 12, 'end': 14} ], 'symptomatic_testing': [ {'start': 8, 'end': 25, 'level': 60} ]} ''' intervs = [] if int_pars is not None: masterlist = [] for ikey,intervlist in int_pars.items(): for iconfig in intervlist: iconfig['ikey'] = ikey masterlist.append(dict(iconfig)) for iconfig in masterlist: ikey = iconfig['ikey'] start = iconfig['start'] end = iconfig['end'] if ikey == 'social_distance': level = iconfig['level'] mapping = { 'mild': 0.8, 'moderate': 0.5, 'aggressive': 0.2, } change = mapping[level] interv = cv.change_beta(days=[start, end], changes=[change, 1.0]) elif ikey == 'school_closures': change = 0.7 interv = cv.change_beta(days=[start, end], changes=[change, 1.0], layers='a') elif ikey == 'symptomatic_testing': level = iconfig['level'] level = float(level)/100 asymp_prob = 0.0 delay = 0.0 interv = cv.test_prob(start_day=start, end_day=end, symp_prob=level, asymp_prob=asymp_prob, test_delay=delay) elif ikey == 'contact_tracing': trace_prob = {'a':1.0} trace_time = {'a':0.0} interv = cv.contact_tracing(start_day=start, end_day=end, trace_probs=trace_prob, trace_time=trace_time) else: raise NotImplementedError intervs.append(interv) return intervs
def test_data_interventions(): sc.heading('Testing data interventions and other special cases') # Create sim sim = cv.Sim(pop_size=100, n_days=60, datafile=csv_file, verbose=verbose) # Intervention conversion ce = cv.InterventionDict(**{ 'which': 'clip_edges', 'pars': { 'days': [10, 30], 'changes': [0.5, 1.0] } }) print(ce) with pytest.raises(sc.KeyNotFoundError): cv.InterventionDict(**{ 'which': 'invalid', 'pars': { 'days': 10, 'changes': 0.5 } }) # Test numbers and contact tracing swab_dict = {'dist': 'uniform', 'par1': 1, 'par2': 3} tp1 = cv.test_prob(0.05, start_day=5, end_day=15, ili_prev=0.1, swab_delay=swab_dict, subtarget={ 'inds': lambda sim: cv.true(sim.people.age > 50), 'vals': 0.3 }) tn1 = cv.test_num(10, start_day=3, end_day=20, ili_prev=0.1, swab_delay=swab_dict) tn2 = cv.test_num(daily_tests='data', quar_policy=[0, 5], subtarget={ 'inds': lambda sim: cv.true(sim.people.age > 50), 'vals': 1.2 }) ct = cv.contact_tracing(presumptive=True, capacity=5) # Create and run sim['interventions'] = [ce, tp1, tn1, tn2, ct] sim.run() return
def intervention_set_test_prob(self, symptomatic_prob=0, asymptomatic_prob=0, asymptomatic_quarantine_prob=0, symp_quar_prob=0, test_sensitivity=1.0, loss_prob=0.0, test_delay=1, start_day=0): self.interventions = test_prob(symp_prob=symptomatic_prob, asymp_prob=asymptomatic_prob, asymp_quar_prob=asymptomatic_quarantine_prob, symp_quar_prob=symp_quar_prob, test_sensitivity=test_sensitivity, loss_prob=loss_prob, test_delay=test_delay, start_day=start_day) pass
def test_basic_contact_trace(): tweaking = { 'n_days': 60, 'pop_size': 2000, 'pop_type': 'hybrid' } start_days = [] interventions = [] test_prob_start_day = 35 prob_test_perfect_symptomatic = test_prob(symp_prob=1.0, symp_quar_prob=1.0, asymp_quar_prob=1.0, test_sensitivity=1.0, test_delay=1, start_day=test_prob_start_day) start_days.append(test_prob_start_day) interventions.append(prob_test_perfect_symptomatic) contact_trace_start_day = 35 all_contacts = { 'h': 1.0, 'w': 1.0, 's': 1.0, 'c': 1.0 } single_day_delays = { 'h': 1, 'w': 1, 's': 1, 'c': 1 } brutal_contact_trace = contact_tracing(trace_probs=all_contacts, trace_time=single_day_delays, start_day=contact_trace_start_day) start_days.append(contact_trace_start_day) interventions.append(brutal_contact_trace) tweaking['interventions'] = interventions test_stuff_simulation = Sim(pars=tweaking) test_stuff_simulation.run() test_stuff_results = test_stuff_simulation.to_json(tostring=False) with open("DEBUG_test_intervention_list_simulation.json","w") as outfile: json.dump(test_stuff_results, outfile, indent=4, sort_keys=True) pass assert test_stuff_results["results"]["n_symptomatic"][test_prob_start_day] > 0 # If there are symptomatics assert sum(test_stuff_results["results"]["new_tests"][test_prob_start_day:test_prob_start_day + 5]) > 0 # then there should be tests assert sum(test_stuff_results["results"]["new_diagnoses"][test_prob_start_day + 1:test_prob_start_day + 6]) > 0 # and some diagnoses assert sum(test_stuff_results["results"]["new_diagnoses"][test_prob_start_day + 2:test_prob_start_day + 7]) > 0 # and therefore some quarantined pass
def test_fit(): sc.heading('Testing fitting function') # Create a testing intervention to ensure some fit to data tp = cv.test_prob(0.1) sim = cv.Sim(pars, rand_seed=1, interventions=tp, datafile="example_data.csv") sim.run() # Checking that Fit can handle custom input custom_inputs = { 'custom_data': { 'data': np.array([1, 2, 3]), 'sim': np.array([1, 2, 4]), 'weights': [2.0, 3.0, 4.0] } } fit1 = sim.compute_fit(custom=custom_inputs, compute=True) # Test that different seed will change compute results sim2 = cv.Sim(pars, rand_seed=2, interventions=tp, datafile="example_data.csv") sim2.run() fit2 = sim2.compute_fit(custom=custom_inputs) assert fit1.mismatch != fit2.mismatch, "Differences between fit and data remains unchanged after changing sim seed" # Test custom analyzers actual = np.array([1, 2, 4]) predicted = np.array([1, 2, 3]) def simple(actual, predicted, scale=2): return np.sum(abs(actual - predicted)) * scale gof1 = cv.compute_gof(actual, predicted, normalize=False, as_scalar='sum') gof2 = cv.compute_gof(actual, predicted, estimator=simple, scale=1.0) assert gof1 == gof2 with pytest.raises(Exception): cv.compute_gof(actual, predicted, skestimator='not an estimator') with pytest.raises(Exception): cv.compute_gof(actual, predicted, estimator='not an estimator') if do_plot: fit1.plot() return fit1
def modify_sim(sim, scenpars, label=None, runinfo=None): ''' Modify the simulation for the scenarios ''' print( f' Note: modifying simulation {label} at day={sim.t}, date={sim.date(sim.t)}, scenpars:\n{scenpars}' ) # Do reopening: modify clip_edges last_calib_day = sim.day(sim.sceninfo.calib_end) first_scen_day = sim.day(sim.sceninfo.scen_start) for ilabel in ['clip_w', 'clip_c']: interv = get_interv(sim, ilabel) valid_days = sc.findinds(interv.days <= last_calib_day) interv.days = np.append( interv.days[valid_days], first_scen_day ) # NB, repr of intervention will be wrong with direct modification! interv.changes = np.append(interv.changes[valid_days], scenpars['reopen']) # Change iso_factor and quar_factor sim.pars['iso_factor'] = sc.dcp(scenpars['i_factor']) sim.pars['quar_factor'] = sc.dcp(scenpars['q_factor']) # Implement testing & tracing interventions tppars = { k: scenpars[k] for k in [ 'symp_prob', 'asymp_prob', 'symp_quar_prob', 'asymp_quar_prob', 'test_delay' ] } ctpars = {k: scenpars[k] for k in ['trace_probs', 'trace_time']} tp = cv.test_prob(start_day=first_scen_day, quar_policy=[0], **tppars) ct = cv.contact_tracing(start_day=first_scen_day, label='contact_tracing', **ctpars) sim['interventions'] += [tp, ct] # Final tidying sim.label = label sim.runinfo = runinfo sim.sceninfo.scenpars = scenpars return sim
def make_sim(use_defaults=False, do_plot=False, **kwargs): ''' Define a default simulation for testing the baseline -- use hybrid and include interventions to increase coverage. If run directly (not via pytest), also plot the sim by default. ''' # Define the interventions tp = cv.test_prob(start_day=20, symp_prob=0.1, asymp_prob=0.01) vx = cv.vaccinate_prob('pfizer', days=30, prob=0.1) cb = cv.change_beta(days=40, changes=0.5) ct = cv.contact_tracing(trace_probs=0.3, start_day=50) # Define the parameters pars = dict( use_waning=True, # Whether or not to use waning and NAb calculations pop_size=20e3, # Population size pop_infected= 100, # Number of initial infections -- use more for increased robustness pop_type= 'hybrid', # Population to use -- "hybrid" is random with household, school,and work structure n_days=60, # Number of days to simulate verbose=0, # Don't print details of the run rand_seed=2, # Set a non-default seed interventions=[cb, tp, ct, vx], # Include the most common interventions ) pars = sc.mergedicts(pars, kwargs) # Create the sim if use_defaults: sim = cv.Sim() else: sim = cv.Sim(pars) # Optionally plot if do_plot: s2 = sim.copy() s2.run() s2.plot() return sim
def test_fit(): sc.heading('Testing fitting function') # Create a testing intervention to ensure some fit to data tp = cv.test_prob(0.1) sim = cv.Sim(pars, rand_seed=1, interventions=tp, datafile="example_data.csv") sim.run() # Checking that Fit can handle custom input custom_inputs = {'custom_data':{'data':np.array([1,2,3]), 'sim':np.array([1,2,4]), 'weights':[2.0, 3.0, 4.0]}} fit1 = sim.compute_fit(custom=custom_inputs, compute=True) # Test that different seed will change compute results sim2 = cv.Sim(pars, rand_seed=2, interventions=tp, datafile="example_data.csv") sim2.run() fit2 = sim2.compute_fit(custom=custom_inputs) assert fit1.mismatch != fit2.mismatch, f"Differences between fit and data remains unchanged after changing sim seed" return fit1
cv.test_num(start_day=start_day, daily_tests=[0.005 * n_people] * n_days, subtarget={ 'inds': sim.people.age > 50, 'val': 2.0 }), } }, 'testelderly': { 'name': 'Test the elderly', 'pars': { 'interventions': cv.test_prob(start_day=start_day, symp_prob=0.1, asymp_prob=0.005, subtarget={ 'inds': sim.people.age > 50, 'val': 2.0 }), } }, } to_plot = [ 'cum_infections', 'new_infections', 'cum_diagnoses', 'n_severe', 'n_critical', 'cum_deaths', ]
s_prob_july = 0.0171 s_prob_august = 0.0171 t_delay = 1.0 iso_vals = [{k:0.1 for k in 'hswc'}] #tracing level at 42.35% in June; 47.22% in July t_eff_june = 0.42 t_eff_july = 0.47 t_probs_june = {k:t_eff_june for k in 'hwsc'} t_probs_july = {k:t_eff_july for k in 'hwsc'} trace_d_1 = {'h':0, 's':1, 'w':1, 'c':2} #testing and isolation intervention interventions += [ cv.test_prob(symp_prob=0.009, asymp_prob=0.0, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tc_day, end_day=te_day-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_april, asymp_prob=0.0, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=te_day, end_day=tt_day-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tt_day, end_day=tti_day-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_june, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day, end_day=tti_day_july-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_july, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_july, end_day=tti_day_august-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_august, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_august, test_delay=t_delay), cv.dynamic_pars({'iso_factor': {'days': te_day, 'vals': iso_vals}}), cv.contact_tracing(trace_probs=t_probs_june, trace_time=trace_d_1, start_day=tti_day, end_day=tti_day_july-1), cv.contact_tracing(trace_probs=t_probs_july, trace_time=trace_d_1, start_day=tti_day_july), ] elif tti_scen == 'optimal_TTI': # Tracing and enhanced testing strategy of symptimatics from 1st June #testing in August needs to increase to avoid a second wave s_prob_march = 0.009
def make_sim(seed, beta, calibration=True, scenario=None, delta_beta=1.6, future_symp_test=None, end_day=None, verbose=0): # Set the parameters total_pop = 67.86e6 # UK population size pop_size = 100e3 # Actual simulated population pop_scale = int(total_pop / pop_size) pop_type = 'hybrid' pop_infected = 1500 beta = beta asymp_factor = 2 contacts = {'h': 3.0, 's': 20, 'w': 20, 'c': 20} beta_layer = {'h': 3.0, 's': 1.0, 'w': 0.6, 'c': 0.3} if end_day is None: end_day = '2021-03-31' pars = sc.objdict( pop_size=pop_size, pop_infected=pop_infected, pop_scale=pop_scale, pop_type=pop_type, start_day=start_day, end_day=end_day, beta=beta, asymp_factor=asymp_factor, contacts=contacts, rescale=True, rand_seed=seed, verbose=verbose, rel_severe_prob=0.4, rel_crit_prob=2.3, #rel_death_prob=1.5, ) sim = cv.Sim(pars=pars, datafile=data_path, location='uk') sim['prognoses']['sus_ORs'][0] = 1.0 # ages 20-30 sim['prognoses']['sus_ORs'][1] = 1.0 # ages 20-30 # ADD BETA INTERVENTIONS sbv = 0.63 beta_past = sc.odict({ '2020-02-14': [1.00, 1.00, 0.90, 0.90], '2020-03-16': [1.00, 0.90, 0.80, 0.80], '2020-03-23': [1.29, 0.02, 0.20, 0.20], '2020-06-01': [1.00, 0.23, 0.40, 0.40], '2020-06-15': [1.00, 0.38, 0.50, 0.50], '2020-07-22': [1.29, 0.00, 0.30, 0.50], '2020-09-02': [1.25, sbv, 0.50, 0.70], '2020-10-01': [1.25, sbv, 0.50, 0.70], '2020-10-16': [1.25, sbv, 0.50, 0.70], '2020-10-26': [1.00, 0.00, 0.50, 0.70], '2020-11-05': [1.25, sbv, 0.30, 0.40], '2020-11-14': [1.25, sbv, 0.30, 0.40], '2020-11-21': [1.25, sbv, 0.30, 0.40], '2020-11-30': [1.25, sbv, 0.30, 0.40], '2020-12-03': [1.50, sbv, 0.50, 0.70], '2020-12-20': [1.25, 0.00, 0.50, 0.70], '2020-12-25': [1.50, 0.00, 0.20, 0.90], '2020-12-26': [1.50, 0.00, 0.20, 0.90], '2020-12-31': [1.50, 0.00, 0.20, 0.90], '2021-01-01': [1.50, 0.00, 0.20, 0.90], '2021-01-04': [1.25, 0.14, 0.30, 0.40], '2021-01-11': [1.25, 0.14, 0.30, 0.40], '2021-01-18': [1.25, 0.14, 0.30, 0.40], '2021-01-18': [1.25, 0.14, 0.30, 0.40] }) if not calibration: ##no schools until 1st March but assue 20% (1 in 5) in schools between 04/01-22/02; ##model transmission remaining at schools as 14% (to account for 30% reduction due to school measures) if scenario == 'FNL': beta_s_feb22, beta_s_mar01, beta_s_mar08, beta_s_mar15, beta_s_mar22, beta_s_mar29, beta_s_apr01 = 0.14, 0.14, 0.14, 0.14, 0.14, 0.14, 0.02 ##primaries and yars 11 and 13 back on 22/02 all other years 01/03 ##9/14 years back -30% transmission reduction = 45% reduction remaining from 22/02 ##transmision increases to 63% remaining from 01/03 ##Easter holiday 01/04-08/04 elif scenario == 'staggeredPNL': beta_s_feb22, beta_s_mar01, beta_s_mar08, beta_s_mar15, beta_s_mar22, beta_s_mar29, beta_s_apr01 = 0.14, 0.14, 0.40, sbv, sbv, sbv, 0.02, ##primaries and secondaries back fully 22/02; 14/14 years but assume 90% attendence and ##30% reduction in transmission due to hygiene, masks etc to remaining transmision to 0.63 ##Easter holiday 01/04-08/04 elif scenario == 'fullPNL': beta_s_feb22, beta_s_mar01, beta_s_mar08, beta_s_mar15, beta_s_mar22, beta_s_mar29, beta_s_apr01 = 0.14, 0.14, sbv, sbv, sbv, sbv, 0.02 elif scenario == 'primaryPNL': beta_s_feb22, beta_s_mar01, beta_s_mar08, beta_s_mar15, beta_s_mar22, beta_s_mar29, beta_s_apr01 = 0.14, 0.14, 0.31, 0.31, 0.40, 0.40, 0.02 elif scenario == 'rotasecondaryPNL': beta_s_feb22, beta_s_mar01, beta_s_mar08, beta_s_mar15, beta_s_mar22, beta_s_mar29, beta_s_apr01 = 0.14, 0.14, 0.31, 0.31, sbv, sbv, 0.02 beta_scens = sc.odict({ '2021-01-30': [1.25, 0.14, 0.30, 0.40], '2021-02-08': [1.25, 0.14, 0.30, 0.40], '2021-02-15': [1.25, 0.14, 0.30, 0.40], '2021-02-22': [1.25, beta_s_feb22, 0.30, 0.40], '2021-03-01': [1.25, beta_s_mar01, 0.30, 0.40], '2021-03-08': [1.25, beta_s_mar08, 0.30, 0.50], '2021-03-15': [1.25, beta_s_mar15, 0.30, 0.50], '2021-03-22': [1.25, beta_s_mar22, 0.30, 0.50], '2021-03-29': [1.25, beta_s_mar29, 0.30, 0.50], '2021-04-01': [1.25, beta_s_apr01, 0.30, 0.50], '2021-04-12': [1.25, 0.02, 0.30, 0.50], '2021-04-19': [1.25, sbv, 0.50, 0.70], '2021-04-26': [1.25, sbv, 0.50, 0.70], '2021-05-03': [1.25, sbv, 0.50, 0.70] }) beta_dict = sc.mergedicts(beta_past, beta_scens) else: beta_dict = beta_past beta_days = list(beta_dict.keys()) h_beta = cv.change_beta(days=beta_days, changes=[c[0] for c in beta_dict.values()], layers='h') s_beta = cv.change_beta(days=beta_days, changes=[c[1] for c in beta_dict.values()], layers='s') w_beta = cv.change_beta(days=beta_days, changes=[c[2] for c in beta_dict.values()], layers='w') c_beta = cv.change_beta(days=beta_days, changes=[c[3] for c in beta_dict.values()], layers='c') # Add a new change in beta to represent the takeover of the novel variant VOC 202012/01 # Assume that the new variant is 60% more transmisible (https://cmmid.github.io/topics/covid19/uk-novel-variant.html, # Assume that between Nov 1 and Jan 30, the new variant grows from 0-100% of cases voc_days = np.linspace(sim.day('2020-08-01'), sim.day('2021-01-30'), 31) voc_prop = 0.6 / ( 1 + np.exp(-0.075 * (voc_days - sim.day('2020-09-30'))) ) # Use a logistic growth function to approximate fig 2A of https://cmmid.github.io/topics/covid19/uk-novel-variant.html voc_change = voc_prop * 1.63 + (1 - voc_prop) * 1. voc_beta = cv.change_beta(days=voc_days, changes=voc_change) interventions = [h_beta, w_beta, s_beta, c_beta, voc_beta] # ADD TEST AND TRACE INTERVENTIONS tc_day = sim.day( '2020-03-16' ) #intervention of some testing (tc) starts on 16th March and we run until 1st April when it increases te_day = sim.day( '2020-04-01' ) #intervention of some testing (te) starts on 1st April and we run until 1st May when it increases tt_day = sim.day( '2020-05-01' ) #intervention of increased testing (tt) starts on 1st May tti_day = sim.day( '2020-06-01' ) #intervention of tracing and enhanced testing (tti) starts on 1st June tti_day_july = sim.day( '2020-07-01' ) #intervention of tracing and enhanced testing (tti) at different levels starts on 1st July tti_day_august = sim.day( '2020-08-01' ) #intervention of tracing and enhanced testing (tti) at different levels starts on 1st August tti_day_sep = sim.day('2020-09-01') tti_day_oct = sim.day('2020-10-01') tti_day_nov = sim.day('2020-11-01') tti_day_dec = sim.day('2020-12-01') tti_day_jan = sim.day('2021-01-01') tti_day_vac = sim.day('2020-12-20') s_prob_april = 0.009 s_prob_may = 0.012 s_prob_june = 0.02769 s_prob_july = 0.02769 s_prob_august = 0.03769 tn = 0.09 s_prob_sept = 0.08769 s_prob_oct = 0.08769 s_prob_nov = 0.08769 s_prob_may = 0.02769 s_prob_june = 0.02769 s_prob_july = 0.02769 s_prob_august = 0.03769 s_prob_sep = 0.08769 s_prob_oct = 0.08769 s_prob_nov = 0.08769 s_prob_dec = 0.08769 if future_symp_test is None: future_symp_test = s_prob_dec t_delay = 1.0 #isolation may-july iso_vals = [{k: 0.1 for k in 'hswc'}] #isolation august iso_vals1 = [{k: 0.7 for k in 'hswc'}] #isolation september iso_vals2 = [{k: 0.5 for k in 'hswc'}] #isolation october iso_vals3 = [{k: 0.5 for k in 'hswc'}] #isolation november iso_vals4 = [{k: 0.5 for k in 'hswc'}] #isolation december iso_vals5 = [{k: 0.5 for k in 'hswc'}] #testing and isolation intervention interventions += [ cv.test_prob(symp_prob=0.0075, asymp_prob=0.0, symp_quar_prob=0.0, start_day=tc_day, end_day=te_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_april, asymp_prob=0.0, symp_quar_prob=0.0, start_day=te_day, end_day=tt_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.00076, symp_quar_prob=0.0, start_day=tt_day, end_day=tti_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_june, asymp_prob=0.00076, symp_quar_prob=0.0, start_day=tti_day, end_day=tti_day_july - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_july, asymp_prob=0.00076, symp_quar_prob=0.0, start_day=tti_day_july, end_day=tti_day_august - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_august, asymp_prob=0.0028, symp_quar_prob=0.0, start_day=tti_day_august, end_day=tti_day_sep - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_sep, asymp_prob=0.0028, symp_quar_prob=0.0, start_day=tti_day_sep, end_day=tti_day_oct - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_oct, asymp_prob=0.0028, symp_quar_prob=0.0, start_day=tti_day_oct, end_day=tti_day_nov - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_nov, asymp_prob=0.0063, symp_quar_prob=0.0, start_day=tti_day_nov, end_day=tti_day_dec - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_dec, asymp_prob=0.0063, symp_quar_prob=0.0, start_day=tti_day_dec, end_day=tti_day_jan - 1, test_delay=t_delay), cv.test_prob(symp_prob=future_symp_test, asymp_prob=0.0063, symp_quar_prob=0.0, start_day=tti_day_jan, test_delay=t_delay), cv.contact_tracing(trace_probs={ 'h': 1, 's': 0.5, 'w': 0.5, 'c': 0.05 }, trace_time={ 'h': 0, 's': 1, 'w': 1, 'c': 2 }, start_day='2020-06-01', quar_period=10), cv.dynamic_pars({'iso_factor': { 'days': te_day, 'vals': iso_vals }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_august, 'vals': iso_vals1 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_sep, 'vals': iso_vals2 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_oct, 'vals': iso_vals3 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_nov, 'vals': iso_vals4 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_dec, 'vals': iso_vals5 }}) ] #cv.dynamic_pars({'rel_death_prob': {'days': tti_day_vac, 'vals': 0.9}})] #cv.vaccine(days=[0,14], rel_sus=0.4, rel_symp=0.2, cumulative=[0.7, 0.3])] # vaccination interventions interventions += [ utils.two_dose_daily_delayed(200e3, start_day=tti_day_vac, dose_delay=14, delay=10 * 7, take_prob=1.0, rel_symp=0.05, rel_trans=0.9, cumulative=[0.7, 1.0], dose_priority=[1, 0.1]) ] analyzers = [] analyzers += [ utils.record_dose_flows(vacc_class=utils.two_dose_daily_delayed) ] # Finally, update the parameters sim.update_pars(interventions=interventions, analyzers=analyzers) # Change death and critical probabilities # interventions += [cv.dynamic_pars({'rel_death_prob':{'days':sim.day('2020-07-01'), 'vals':0.6}})] # Finally, update the parameters #sim.update_pars(interventions=interventions) for intervention in sim['interventions']: intervention.do_plot = False sim.initialize() return sim
def make_sim(seed, beta, change=0.42, policy='remain', threshold=5, symp_prob=0.01, end_day=None): start_day = '2020-06-15' if end_day is None: end_day = '2021-04-30' total_pop = 11.9e6 # Population of central Vietnam n_agents = 100e3 pop_scale = total_pop / n_agents # Calibration parameters pars = { 'pop_size': n_agents, 'pop_infected': 0, 'pop_scale': pop_scale, 'rand_seed': seed, 'beta': beta, 'start_day': start_day, 'end_day': end_day, 'verbose': 0, 'rescale': True, 'iso_factor': dict(h=0.5, s=0.01, w=0.01, c=0.1), # Multiply beta by this factor for people in isolation 'quar_factor': dict(h=1.0, s=0.2, w=0.2, c=0.2), # Multiply beta by this factor for people in quarantine 'location': 'vietnam', 'pop_type': 'hybrid', 'age_imports': [50, 80], 'rel_crit_prob': 1.75, # Calibration parameter due to hospital outbreak 'rel_death_prob': 2., # Calibration parameter due to hospital outbreak } # Make a sim without parameters, just to load in the data to use in the testing intervention and to get the sim days sim = cv.Sim(start_day=start_day, datafile="vietnam_data.csv") # Set up import assumptions pars['dur_imports'] = sc.dcp(sim.pars['dur']) pars['dur_imports']['exp2inf'] = { 'dist': 'lognormal_int', 'par1': 0.0, 'par2': 0.0 } pars['dur_imports']['inf2sym'] = { 'dist': 'lognormal_int', 'par1': 0.0, 'par2': 0.0 } pars['dur_imports']['sym2sev'] = { 'dist': 'lognormal_int', 'par1': 0.0, 'par2': 2.0 } pars['dur_imports']['sev2crit'] = { 'dist': 'lognormal_int', 'par1': 1.0, 'par2': 3.0 } pars['dur_imports']['crit2die'] = { 'dist': 'lognormal_int', 'par1': 3.0, 'par2': 3.0 } # Define import array import_end = sim.day('2020-07-15') border_start = sim.day('2020-11-30') # Open borders for one month border_end = sim.day('2020-12-31') # Then close them again final_day_ind = sim.day('2021-04-30') imports = np.concatenate(( np.array([ 1, 0, 0, 0, 2, 2, 8, 4, 1, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 3, 1, 1, 3, 0, 3, 0, 1, 6, 1, 5, 0, 0 ]), # Generated from cv.n_neg_binomial(1, 0.25) but then hard-copied to remove variation when calibrating pl.zeros( border_start - import_end ), # No imports from the end of the 1st importation window to the border reopening cv.n_neg_binomial( 1, 0.25, border_end - border_start ), # Negative-binomial distributed importations each day pl.zeros(final_day_ind - border_end))) pars['n_imports'] = imports # Add testing and tracing interventions trace_probs = {'h': 1, 's': 0.95, 'w': 0.8, 'c': 0.05} trace_time = {'h': 0, 's': 2, 'w': 2, 'c': 5} pars['interventions'] = [ # Testing and tracing cv.test_num(daily_tests=sim.data['new_tests'].rolling(3).mean(), start_day=2, end_day=sim.day('2020-08-22'), symp_test=80, quar_test=80, do_plot=False), cv.test_prob(start_day=sim.day('2020-08-23'), end_day=sim.day('2020-11-30'), symp_prob=0.05, asymp_quar_prob=0.5, do_plot=False), cv.test_prob(start_day=sim.day('2020-12-01'), symp_prob=symp_prob, asymp_quar_prob=0.5, trigger=cv.trigger('date_diagnosed', 5), triggered_vals={'symp_prob': 0.2}, do_plot=False), cv.contact_tracing(start_day=0, trace_probs=trace_probs, trace_time=trace_time, do_plot=False), # Change death and critical probabilities cv.dynamic_pars( { 'rel_death_prob': { 'days': sim.day('2020-08-31'), 'vals': 1.0 }, 'rel_crit_prob': { 'days': sim.day('2020-08-31'), 'vals': 1.0 } }, do_plot=False ), # Assume these were elevated due to the hospital outbreak but then would return to normal # Increase precautions (especially mask usage) following the outbreak, which are then abandoned after 40 weeks of low case counts cv.change_beta(days=0, changes=change, trigger=cv.trigger('date_diagnosed', 5)), # Close schools and workplaces cv.clip_edges(days=['2020-07-28', '2020-09-14'], changes=[0.1, 1.], layers=['s'], do_plot=True), cv.clip_edges(days=['2020-07-28', '2020-09-05'], changes=[0.1, 1.], layers=['w'], do_plot=False), # Dynamically close them again if cases go over the threshold cv.clip_edges(days=[170], changes=[0.1], layers=['s'], trigger=cv.trigger('date_diagnosed', threshold)), cv.clip_edges(days=[170], changes=[0.1], layers=['w'], trigger=cv.trigger('date_diagnosed', threshold)), ] if policy != 'remain': pars['interventions'] += [ cv.change_beta(days=160, changes=1.0, trigger=cv.trigger('date_diagnosed', 2, direction='below', smoothing=28)) ] if policy == 'dynamic': pars['interventions'] += [ cv.change_beta(days=170, changes=change, trigger=cv.trigger('date_diagnosed', threshold)), ] sim = cv.Sim(pars=pars, datafile="vietnam_data.csv") sim.initialize() return sim
p3 = dict( pop_size = 20000, pop_infected = 50, pop_scale = 10, rescale = False, ) tnp = dict(start_day=0, daily_tests=1000) tpp = dict(symp_prob=0.1, asymp_prob=0.01) sims = [] for st in [1000]: tn = cv.test_num(**tnp, symp_test=st) tp = cv.test_prob(**tpp) ti = tn # Switch testing interventions here s1 = cv.Sim(pars, **p1, interventions=sc.dcp(ti), label=f'full, symp_test={st}') s2 = cv.Sim(pars, **p2, interventions=sc.dcp(ti), label=f'dynamic, symp_test={st}') s3 = cv.Sim(pars, **p3, interventions=sc.dcp(ti), label=f'static, symp_test={st}') sims.extend([s1, s2, s3]) msim = cv.MultiSim(sims) sc.tic() msim.run() sc.toc() for sim in msim.sims: sim.results['n_quarantined'][:] = sim.rescale_vec sim.results['n_quarantined'].name = 'Rescale vec' sim.results['new_quarantined'] = sim.results['rel_test_yield']
#Testing and Isolation interventions until 1st June #s_prob=% of sympomatic that are tested only as part of TI strategies; we fit s_prob_may to data s_prob_march = 0.007 s_prob_april = 0.009 s_prob_may = 0.0135 a_prob = 0.0 q_prob = 0.0 t_delay = 1.0 iso_vals = [{k: 0.1 for k in 'hswc'}] interventions += [ cv.test_prob(symp_prob=s_prob_march, asymp_prob=0.00030, symp_quar_prob=q_prob, asymp_quar_prob=q_prob, start_day=tc_day, end_day=te_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_april, asymp_prob=0.00050, symp_quar_prob=q_prob, asymp_quar_prob=q_prob, start_day=te_day, end_day=tt_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.00075, symp_quar_prob=q_prob, asymp_quar_prob=q_prob, start_day=tt_day,
def make_sim(seed, beta, calibration=True, scenario=None, future_symp_test=None, end_day=None, verbose=0): # Set the parameters total_pop = 67.86e6 # UK population size pop_size = 100e3 # Actual simulated population pop_scale = int(total_pop / pop_size) pop_type = 'hybrid' pop_infected = 1500 beta = beta asymp_factor = 2 contacts = {'h': 3.0, 's': 20, 'w': 20, 'c': 20} if end_day is None: end_day = '2021-03-31' pars = sc.objdict( pop_size=pop_size, pop_infected=pop_infected, pop_scale=pop_scale, pop_type=pop_type, start_day=start_day, end_day=end_day, beta=beta, asymp_factor=asymp_factor, contacts=contacts, rescale=True, rand_seed=seed, verbose=verbose, rel_severe_prob=0.5, rel_crit_prob=2, # rel_death_prob=1.5, ) sim = cv.Sim(pars=pars, datafile=data_path, location='uk') sim['prognoses']['sus_ORs'][0] = 1.0 # ages 20-30 sim['prognoses']['sus_ORs'][1] = 1.0 # ages 20-30 # ADD BETA INTERVENTIONS sbv = 0.77 beta_past = sc.odict({ '2020-02-14': [ 1.00, 1.00, 0.90, 0.90, ], '2020-03-16': [ 1.00, 0.90, 0.80, 0.80, ], '2020-03-23': [ 1.29, 0.02, 0.20, 0.20, ], '2020-06-01': [ 1.00, 0.23, 0.40, 0.40, ], '2020-06-15': [ 1.00, 0.38, 0.50, 0.50, ], '2020-07-22': [ 1.29, 0.00, 0.30, 0.50, ], '2020-09-02': [ 1.00, sbv, 0.60, 0.90, ], '2020-10-26': [ 1.25, 0.00, 0.60, 0.90, ], '2020-11-01': [ 1.25, sbv, 0.20, 0.40, ], '2020-12-03': [ 1.25, sbv, 0.60, 0.90, ], '2020-12-20': [ 1.25, 0.00, 0.40, 0.90, ], '2020-12-25': [ 1.50, 0.00, 0.30, 0.90, ], }) if not calibration: if scenario == 'FNL': beta_s_jan4, beta_s_jan11, beta_s_jan18 = 0.02, 0.02, 0.02 elif scenario == 'primaryPNL': beta_s_jan4, beta_s_jan11, beta_s_jan18 = sbv / 2, sbv / 2, sbv elif scenario == 'staggeredPNL': beta_s_jan4, beta_s_jan11, beta_s_jan18 = sbv / 2, 0.45, sbv beta_scens = sc.odict({ '2021-01-04': [1.00, beta_s_jan4, 0.20, 0.30], '2021-01-11': [1.00, beta_s_jan11, 0.20, 0.30], '2021-01-18': [1.00, beta_s_jan18, 0.20, 0.30], '2021-02-08': [1.00, sbv, 0.50, 0.70], '2021-02-15': [1.00, 0.00, 0.50, 0.70], '2021-02-21': [1.00, 0.00, 0.50, 0.70], '2021-03-01': [1.00, sbv, 0.50, 0.70], '2021-03-20': [1.00, sbv, 0.50, 0.70], '2021-04-01': [1.00, sbv, 0.50, 0.70], '2021-04-17': [1.00, 0.00, 0.50, 0.70] }) beta_dict = sc.mergedicts(beta_past, beta_scens) else: beta_dict = beta_past beta_days = list(beta_dict.keys()) h_beta = cv.change_beta(days=beta_days, changes=[c[0] for c in beta_dict.values()], layers='h') s_beta = cv.change_beta(days=beta_days, changes=[c[1] for c in beta_dict.values()], layers='s') w_beta = cv.change_beta(days=beta_days, changes=[c[2] for c in beta_dict.values()], layers='w') c_beta = cv.change_beta(days=beta_days, changes=[c[3] for c in beta_dict.values()], layers='c') # Add a new change in beta to represent the takeover of the novel variant VOC 202012/01 # Assume that the new variant is 60% more transmisible (https://cmmid.github.io/topics/covid19/uk-novel-variant.html, # Assume that between Nov 1 and Jan 30, the new variant grows from 0-100% of cases voc_days = np.linspace(sim.day('2020-09-01'), sim.day('2021-01-30'), 31) voc_prop = 1 / ( 1 + np.exp(-.1 * (voc_days - sim.day('2020-11-16'))) ) # Use a logistic growth function to approximate fig 2A of https://cmmid.github.io/topics/covid19/uk-novel-variant.html voc_change = voc_prop * 1.6 + (1 - voc_prop) * 1. voc_beta = cv.change_beta(days=voc_days, changes=voc_change) interventions = [h_beta, w_beta, s_beta, c_beta, voc_beta] # ADD TEST AND TRACE INTERVENTIONS tc_day = sim.day( '2020-03-16' ) #intervention of some testing (tc) starts on 16th March and we run until 1st April when it increases te_day = sim.day( '2020-04-01' ) #intervention of some testing (te) starts on 1st April and we run until 1st May when it increases tt_day = sim.day( '2020-05-01' ) #intervention of increased testing (tt) starts on 1st May tti_day = sim.day( '2020-06-01' ) #intervention of tracing and enhanced testing (tti) starts on 1st June tti_day_july = sim.day( '2020-07-01' ) #intervention of tracing and enhanced testing (tti) at different levels starts on 1st July tti_day_august = sim.day( '2020-08-01' ) #intervention of tracing and enhanced testing (tti) at different levels starts on 1st August tti_day_sep = sim.day('2020-09-01') tti_day_oct = sim.day('2020-10-01') tti_day_nov = sim.day('2020-11-01') tti_day_dec = sim.day('2020-12-01') tti_day_jan = sim.day('2021-01-01') s_prob_april = 0.008 s_prob_may = 0.03 s_prob_june = 0.01 s_prob_july = 0.01 s_prob_august = 0.01 tn = 0.09 s_prob_sep = 0.06 s_prob_oct = 0.07 s_prob_nov = 0.09 s_prob_dec = 0.1 if future_symp_test is None: future_symp_test = s_prob_dec t_delay = 1.0 #isolation may-july iso_vals = [{k: 0.1 for k in 'hswc'}] #isolation august-dec iso_vals1 = [{k: 0.7 for k in 'hswc'}] #testing and isolation intervention interventions += [ cv.test_prob(symp_prob=0.0075, asymp_prob=0.0, symp_quar_prob=0.0, start_day=tc_day, end_day=te_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_april, asymp_prob=0.0, symp_quar_prob=0.0, start_day=te_day, end_day=tt_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tt_day, end_day=tti_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_june, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day, end_day=tti_day_july - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_july, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day_july, end_day=tti_day_august - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_august, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day_august, end_day=tti_day_sep - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_sep, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day_sep, end_day=tti_day_oct - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_oct, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day_oct, end_day=tti_day_nov - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_nov, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day_nov, end_day=tti_day_dec - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_dec, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day_dec, end_day=tti_day_jan - 1, test_delay=t_delay), cv.test_prob(symp_prob=future_symp_test, asymp_prob=0.00075, symp_quar_prob=0.0, start_day=tti_day_jan, test_delay=t_delay), cv.contact_tracing(trace_probs={ 'h': 1, 's': 0.5, 'w': 0.5, 'c': 0.05 }, trace_time={ 'h': 0, 's': 1, 'w': 2, 'c': 7 }, start_day='2020-06-01', quar_period=10), cv.dynamic_pars({'iso_factor': { 'days': te_day, 'vals': iso_vals }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_august, 'vals': iso_vals1 }}) ] # Change death and critical probabilities # interventions += [cv.dynamic_pars({'rel_death_prob':{'days':sim.day('2020-07-01'), 'vals':0.6}})] # Finally, update the parameters sim.update_pars(interventions=interventions) for intervention in sim['interventions']: intervention.do_plot = False sim.initialize() return sim
#s_prob=% of sympomatic that are tested only as part of TI strategies; we fit s_prob_may to data s_prob_march = 0.007 s_prob_april = 0.01 s_prob_may = 0.0139 #s_prob_june =0.0139 a_prob = 0.0 #a_prob_june =0.0135 q_prob = 0.0 t_delay = 1.0 iso_vals = [{k: 0.1 for k in 'hswc'}] march_tests = cv.test_prob(symp_prob=s_prob_march, asymp_prob=a_prob, symp_quar_prob=q_prob, asymp_quar_prob=q_prob, start_day=tc_day, end_day=te_day, test_delay=t_delay) april_tests = cv.test_prob(symp_prob=s_prob_april, asymp_prob=a_prob, symp_quar_prob=q_prob, asymp_quar_prob=q_prob, start_day=te_day, end_day=tt_day, test_delay=t_delay) may_tests = cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.00075, symp_quar_prob=q_prob, asymp_quar_prob=q_prob, start_day=tt_day,
n_popfiles = 5 popfile = popfile_stem_change + str( pars['rand_seed'] % n_popfiles) + '.ppl' popfile_new = popfile_stem_change + str( pars['rand_seed'] % n_popfiles) + '.ppl' if scen == 'as_normal': popfile = popfile else: popfile = popfile_new sim = cv.Sim(pars, popfile=popfile, load_pop=True, label=scen) day_schools_reopen = sim.day('2020-09-01') interventions = [ cv.test_prob(start_day='2020-07-01', **tp), cv.contact_tracing(start_day='2020-07-01', **ct), cv.clip_edges(days='2020-08-01', changes=p['clip_edges'], layers='w', label='close_work'), cv.clip_edges(days='2020-08-01', changes=p['clip_edges'], layers='c', label='close_community'), cv.change_beta(days='2020-08-01', changes=0.75, layers='c', label='NPI_community'), cv.change_beta(days='2020-08-01', changes=0.75,
def test_all_interventions(): ''' Test all interventions supported by Covasim ''' pars = sc.objdict( pop_size=1e3, pop_infected=10, pop_type='hybrid', n_days=90, ) #%% Define the interventions # 1. Dynamic pars i00 = cv.test_prob(start_day=5, symp_prob=0.3) i01 = 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 i02 = 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 i03 = cv.change_beta([30, 50], [0.0, 1], layers='h') i04 = cv.change_beta([30, 40, 60], [0.0, 1.0, 0.5]) # 4. Clip edges -- should match the change_beta scenarios i05 = cv.clip_edges(start_day=30, end_day=50, change={'h': 0.0}) i06 = cv.clip_edges(start_day=30, end_day=40, change=0.0) i07 = cv.clip_edges(start_day=60, end_day=None, change=0.5) # 5. Test number i08 = cv.test_num(daily_tests=[100, 100, 100, 0, 0, 0] * (pars.n_days // 6)) # 6. Test probability i09 = cv.test_prob(symp_prob=0.1) # 7. Contact tracing i10 = 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) i11 = 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 i12 = cv.clip_edges(start_day=18, change={'s': 0.0}) # Close schools i13 = cv.clip_edges(start_day=20, end_day=32, change={ 'w': 0.7, 'c': 0.7 }) # Reduce work and community i14 = cv.clip_edges(start_day=32, end_day=45, change={ 'w': 0.3, 'c': 0.3 }) # Reduce work and community more i15 = cv.clip_edges(start_day=45, end_day=None, change={ 'w': 0.9, 'c': 0.9 }) # Reopen work and community more i16 = 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 i17 = 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 #%% Create and run the simulations sims = sc.objdict() sims.dynamic = cv.Sim(pars=pars, interventions=[i00, i01]) sims.sequence = cv.Sim(pars=pars, interventions=i02) sims.change_beta1 = cv.Sim(pars=pars, interventions=i03) sims.clip_edges1 = cv.Sim( pars=pars, interventions=i05) # Roughly equivalent to change_beta1 sims.change_beta2 = cv.Sim(pars=pars, interventions=i04) sims.clip_edges2 = cv.Sim( pars=pars, interventions=[i06, i07]) # Roughly euivalent to change_beta2 sims.test_num = cv.Sim(pars=pars, interventions=i08) sims.test_prob = cv.Sim(pars=pars, interventions=i09) sims.tracing = cv.Sim(pars=pars, interventions=[i10, i11]) sims.combo = cv.Sim(pars=pars, interventions=[i12, i13, i14, i15, i16, i17]) for key, sim in sims.items(): sim.label = key sim.run(verbose=verbose) #%% Plotting if do_plot: for sim in sims.values(): print(f'Running {sim.label}...') sim.plot() fig = pl.gcf() fig.axes[0].set_title(f'Simulation: {sim.label}') return
#tracing level at 42.35% in June; 47.22% in July, 44.4% in August and 49.6% in Septembre (until 16th Sep) t_eff_june = 0.42 t_eff_july = 0.47 t_eff_august = 0.44 t_eff_sep = 0.50 t_eff_oct = 0.50 t_probs_june = {k:t_eff_june for k in 'hwsc'} t_probs_july = {k:t_eff_july for k in 'hwsc'} t_probs_august = {k:t_eff_august for k in 'hwsc'} t_probs_sep = {k:t_eff_sep for k in 'hwsc'} t_probs_oct = {k:t_eff_oct for k in 'hwsc'} trace_d_1 = {'h':0, 's':1, 'w':1, 'c':2} #testing and isolation intervention interventions += [ cv.test_prob(symp_prob=0.009, asymp_prob=0.0, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tc_day, end_day=te_day-1, test_delay=t_delay, test_sensitivity=0.97), cv.test_prob(symp_prob=s_prob_april, asymp_prob=0.0, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=te_day, end_day=tt_day-1, test_delay=t_delay, test_sensitivity=0.97), cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.0075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tt_day, end_day=tti_day-1, test_delay=t_delay, test_sensitivity=0.97), cv.test_prob(symp_prob=s_prob_june, asymp_prob=0.0175, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day, end_day=tti_day_july-1, test_delay=t_delay, test_sensitivity=0.97), cv.test_prob(symp_prob=s_prob_july, asymp_prob=0.0175, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_july, end_day=tti_day_august-1, test_delay=t_delay, test_sensitivity=0.97), cv.test_prob(symp_prob=s_prob_august, asymp_prob=0.0175, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_august, end_day=tti_day_sep-1, test_delay=t_delay,test_sensitivity=0.97), cv.test_prob(symp_prob=s_prob_sept, asymp_prob=0.0175, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_sep, end_day=tti_day_oct-1, test_delay=t_delay, test_sensitivity=0.97), cv.test_prob(symp_prob=s_prob_oct, asymp_prob=0.0175, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_oct, test_delay=t_delay, test_sensitivity=0.97), cv.dynamic_pars({'iso_factor': {'days': te_day, 'vals': iso_vals}}), cv.contact_tracing(trace_probs=t_probs_june, trace_time=trace_d_1, start_day=tti_day, end_day=tti_day_july-1), cv.contact_tracing(trace_probs=t_probs_july, trace_time=trace_d_1, start_day=tti_day_july, end_day=tti_day_august-1), cv.contact_tracing(trace_probs=t_probs_august, trace_time=trace_d_1, start_day=tti_day_august, end_day=tti_day_sep-1), cv.contact_tracing(trace_probs=t_probs_sep, trace_time=trace_d_1, start_day=tti_day_sep, end_day=tti_day_oct-1), cv.contact_tracing(trace_probs=t_probs_sep, trace_time=trace_d_1, start_day=tti_day_oct), cv.dynamic_pars({'iso_factor': {'days': tti_day, 'vals': iso_vals}}), cv.dynamic_pars({'iso_factor': {'days': tti_day_august, 'vals': iso_vals1}}),
Compare simulating the entire population vs. dynamic rescaling vs. static rescaling. ''' import sciris as sc import covasim as cv T = sc.tic() p = sc.objdict() # Parameters s = sc.objdict() # Sims m = sc.objdict() # Multisims # Interventions tn = cv.test_num(start_day=40, daily_tests=1000, symp_test=10) # Test a number of people tp = cv.test_prob(start_day=30, symp_prob=0.1, asymp_prob=0.01) # Test a number of people cb = cv.change_beta(days=50, changes=0.5) # Change beta # Properties that are shared across sims basepop = 10e3 popinfected = 100 popscale1 = 10 popscale2 = 20 # Try a different population scale which_interv = 2 # Which intervention to test shared = sc.objdict( n_days=120, beta=0.015, rand_seed=239487, interventions=[cb, tn, tp], )
def create_sim(test=0.0171, trace=0.47, seed=1): start_day = '2020-01-21' end_day = '2021-12-31' data_path = 'UK_Covid_cases_august02.xlsx' # Set the parameters total_pop = 67.86e6 # UK population size pop_size = 100e3 # Actual simulated population pop_scale = int(total_pop/pop_size) pop_type = 'hybrid' pop_infected = 1500 beta = 0.00593*1.2 asymp_factor = 2 contacts = {'h':3.0, 's':20, 'w':20, 'c':20} pars = sc.objdict( pop_size = pop_size, pop_infected = pop_infected, pop_scale = pop_scale, pop_type = pop_type, start_day = start_day, end_day = end_day, beta = beta, asymp_factor = asymp_factor, contacts = contacts, rescale = True, rand_seed = seed, ) # Create the baseline simulation sim = cv.Sim(pars=pars, datafile=data_path, location='uk') sim['prognoses']['sus_ORs'][0] = 1.0 # ages 0-10 sim['prognoses']['sus_ORs'][1] = 1.0 # ages 10-20 #%% Interventions # Create the baseline simulation tc_day = sim.day('2020-03-16') #intervention of some testing (tc) starts on 16th March and we run until 1st April when it increases te_day = sim.day('2020-04-01') #intervention of some testing (te) starts on 1st April and we run until 1st May when it increases tt_day = sim.day('2020-05-01') #intervention of increased testing (tt) starts on 1st May tti_day= sim.day('2020-06-01') #intervention of tracing and enhanced testing (tti) starts on 1st June ti_day = sim.day('2021-12-20') #schools interventions end date in December 2021 tti_day_july= sim.day('2020-07-01') #intervention of tracing and enhanced testing (tti) at different levels starts on 1st July tti_day_august= sim.day('2020-08-01') #intervention of tracing and enhanced testing (tti) at different levels starts on 1st August #change parameters here for different schools opening strategies with society opening beta_days = ['2020-02-14', '2020-03-16', '2020-03-23', '2020-04-30', '2020-05-15', '2020-06-01', '2020-06-15', '2020-07-22', '2020-09-02', '2020-10-28', '2020-11-01', '2020-12-23', '2021-01-03', '2021-02-17', '2021-02-21', '2021-04-01', '2021-04-17', '2021-05-31', '2021-06-04', '2021-07-20', '2021-09-01', '2021-10-30', '2021-11-10', ti_day] h_beta_changes = [1.00, 1.00, 1.29, 1.29, 1.29, 1.00, 1.00, 1.29, 1.00, 1.29, 1.00, 1.29, 1.00, 1.29, 1.00, 1.29, 1.00, 1.29, 1.00, 1.29, 1.00, 1.29, 1.00, 1.29] s_beta_changes = [1.00, 0.90, 0.02, 0.02, 0.02, 0.23, 0.38, 0.00, 0.77, 0.00, 0.77, 0.00, 0.77, 0.00, 0.77, 0.00, 0.77, 0.00, 0.77, 0.00, 0.77, 0.00, 0.77, 0.00] w_beta_changes = [0.90, 0.80, 0.20, 0.20, 0.20, 0.40, 0.50, 0.50, 0.60, 0.50, 0.60, 0.50, 0.60, 0.50, 0.60, 0.50, 0.60, 0.50, 0.60, 0.50, 0.60, 0.50, 0.60, 0.50] c_beta_changes = [0.90, 0.80, 0.20, 0.20, 0.20, 0.40, 0.50, 0.50, 0.80, 0.62, 0.80, 0.62, 0.80, 0.62, 0.80, 0.62, 0.80, 0.62, 0.80, 0.62, 0.80, 0.62, 0.80, 0.62] # Define the beta changes h_beta = cv.change_beta(days=beta_days, changes=h_beta_changes, layers='h') s_beta = cv.change_beta(days=beta_days, changes=s_beta_changes, layers='s') w_beta = cv.change_beta(days=beta_days, changes=w_beta_changes, layers='w') c_beta = cv.change_beta(days=beta_days, changes=c_beta_changes, layers='c') #next line to save the intervention interventions = [h_beta, w_beta, s_beta, c_beta] # Tracing and enhanced testing strategy of symptimatics to change for phase plots #testing s_prob_march = 0.012 s_prob_april = 0.012 s_prob_may = 0.0165 s_prob_june = 0.0171 s_prob_july = 0.0171 #we want to vary s_prob_august to vary testing level s_prob_august = test t_delay = 1.0 iso_vals = [{k:0.1 for k in 'hswc'}] #tracing level at 68% from June; 50% in July #we want to vary t_eff_august to vary tracing level t_eff_june = 0.42 t_eff_july = 0.47 t_eff_august = trace t_probs_june = {k:t_eff_june for k in 'hwsc'} t_probs_july = {k:t_eff_july for k in 'hwsc'} t_probs_august = {k:t_eff_august for k in 'hwsc'} trace_d_1 = {'h':0, 's':1, 'w':1, 'c':2} #testing and isolation intervention interventions += [ cv.test_prob(symp_prob=s_prob_march, asymp_prob=0.0, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tc_day, end_day=te_day-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_april, asymp_prob=0.0, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=te_day, end_day=tt_day-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tt_day, end_day=tti_day-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_june, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day, end_day=tti_day_july-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_july, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_july, end_day=tti_day_august-1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_august, asymp_prob=0.00075, symp_quar_prob=0.0, asymp_quar_prob=0.0, start_day=tti_day_august, test_delay=t_delay), cv.dynamic_pars({'iso_factor': {'days': te_day, 'vals': iso_vals}}), cv.contact_tracing(trace_probs=t_probs_june, trace_time=trace_d_1, start_day=tti_day, end_day=tti_day_july-1), cv.contact_tracing(trace_probs=t_probs_july, trace_time=trace_d_1, start_day=tti_day_july, end_day=tti_day_august-1), cv.contact_tracing(trace_probs=t_probs_august, trace_time=trace_d_1, start_day=tti_day_august), ] # Finally, update the parameters sim.update_pars(interventions=interventions) for intervention in sim['interventions']: intervention.do_plot = False return sim
pars['n_days'] = 60 pars['quar_period'] = 140 sim = cv.Sim(pars=pars) # Setup sim sim.initialize() people = cv.make_people(sim) # Make the actual people for the simulation inds_o5 = sc.findinds(people.age >= 10) people.rel_sus[inds_o5] = 0 inds_u5 = sc.findinds(people.age < 10) imm_frac = 0.8 inds_u5imm = inds_u5[sc.findinds( np.random.uniform(low=0.0, high=1.0, size=len(inds_u5)) < imm_frac)] people.rel_sus[inds_u5imm] = 0 sim.people = people # sim['interventions'] = [cv.test_prob(symp_prob=1.00, asymp_prob=0.00)] # Test 100% of symptomatics and 0% of asymptomatics sim['interventions'] = [ cv.test_prob(symp_prob=1.00, asymp_prob=0.00), cv.contact_tracing() ] sim.run() sim.plot() ########################################### # # # WARNING - What follows below is scary, poorly written scratch code. Don't judge me. # # ########################################### list1 = ['a'] list2 = list1
def test_interventions(do_plot=False, do_show=True, do_save=False, fig_path=None): sc.heading('Test of testing interventions') sc.heading('Setting up...') sc.tic() n_runs = 3 verbose = 1 base_pars = { 'pop_size': 1000, 'pop_type': 'hybrid', } base_sim = cv.Sim(base_pars) # create sim object n_people = base_sim['pop_size'] npts = base_sim.npts # Define overall testing assumptions # Remember that this is the daily % of the population that gets tested. S Korea (one of the highest-testing places) tested # an average of 10000 people/day over March, or 270,000 in total. This is ~200 people per million every day (0.02%).... max_optimistic_testing = 0.1 # ... which means that this is an artificially high number, for testing purposes only!! optimistic_daily_tests = [ max_optimistic_testing * n_people ] * npts # Very best-case scenario for asymptomatic testing # Define the scenarios scenarios = { 'baseline': { 'name': 'Status quo, no testing', 'pars': { 'interventions': None, } }, 'test_skorea': { 'name': 'Assuming South Korea testing levels of 0.02% daily (untargeted); isolate positives', 'pars': { 'interventions': cv.test_num(daily_tests=optimistic_daily_tests) } }, 'floating': { 'name': 'Test with constant probability based on symptoms', 'pars': { 'interventions': cv.test_prob(symp_prob=max_optimistic_testing, asymp_prob=0.0) } }, 'sequence': { 'name': 'Historical switching to probability', 'pars': { 'interventions': cv.sequence( days=[10, 51], interventions=[ cv.test_num(daily_tests=optimistic_daily_tests), cv.test_prob(symp_prob=0.2, asymp_prob=0.002), ]) } }, } metapars = {'n_runs': n_runs} scens = cv.Scenarios(sim=base_sim, metapars=metapars, scenarios=scenarios) scens.run(verbose=verbose, debug=debug) to_plot = ['cum_infections', 'n_infectious', 'new_tests', 'new_diagnoses'] fig_args = dict(figsize=(20, 24)) if do_plot: scens.plot(do_save=do_save, do_show=do_show, fig_path=fig_path, interval=7, fig_args=fig_args, to_plot=to_plot) return scens
def create_sim(pars=None, label=None, use_safegraph=True, show_intervs=False, people=None, school_reopening_pars=None, teacher_test_scen=None): ''' Create a single simulation for further use ''' p = sc.objdict( sc.mergedicts( define_pars(which='best', kind='both', use_safegraph=use_safegraph), pars)) if 'rand_seed' not in p: seed = 1 print(f'Note, could not find random seed in {pars}! Setting to {seed}') p['rand_seed'] = seed # Ensure this exists if 'end_day' not in p: end_day = '2020-05-30' p['end_day'] = end_day # Basic parameters and sim creation pars = { 'pop_size': 225e3, 'pop_scale': 10, 'pop_type': 'synthpops', 'pop_infected': 400, 'beta': p.beta, 'start_day': '2020-01-27', 'end_day': p['end_day'], 'rescale': True, 'rescale_factor': 1.1, 'verbose': 0.1, 'rand_seed': p.rand_seed, # 'analyzers' : cv.age_histogram(datafile=age_data_file), 'beta_layer': dict(h=p.bl_h, s=p.bl_s, w=p.bl_w, c=p.bl_c, l=p.bl_l), } pars.update({'n_days': cv.daydiff(pars['start_day'], pars['end_day'])}) # If supplied, use an existing people object if people: popfile = people else: # Generate the population filename n_popfiles = 5 popfile = popfile_stem + str(pars['rand_seed'] % n_popfiles) + '.ppl' popfile_change = popfile_stem_change + str( pars['rand_seed'] % n_popfiles) + '.ppl' # Check that the population file exists if not os.path.exists(popfile): errormsg = f'WARNING: could not find population file {popfile}! Please regenerate first' raise FileNotFoundError(errormsg) # Create and initialize the sim sim = cv.Sim(pars, label=label, popfile=popfile, load_pop=True, datafile=epi_data_file ) # Create this here so can be used for test numbers etc. # Define testing interventions test_kwargs = dict(daily_tests=sim.data['new_tests'], quar_test=1.0, test_delay=2) tn1 = cv.test_num(symp_test=p.tn1, start_day='2020-01-27', end_day='2020-03-23', **test_kwargs, label='tn1') tn2 = cv.test_num(symp_test=p.tn2, start_day='2020-03-24', end_day='2020-04-14', **test_kwargs, label='tn2') tn3 = cv.test_num(symp_test=p.tn3, start_day='2020-04-15', end_day=None, **test_kwargs, label='tn3') interventions = [tn1, tn2, tn3] ttq_scen = school_reopening_pars['ttq_scen'] if ttq_scen == 'lower': tp = sc.objdict( symp_prob=0.08, asymp_prob=0.001, symp_quar_prob=0.8, asymp_quar_prob=0.1, test_delay=2.0, ) ct = sc.objdict( trace_probs=0.01, trace_time=3.0, ) elif ttq_scen == 'medium': tp = sc.objdict( symp_prob=0.12, asymp_prob=0.0015, symp_quar_prob=0.8, asymp_quar_prob=0.1, test_delay=2.0, ) ct = sc.objdict( trace_probs=0.25, trace_time=3.0, ) elif ttq_scen == 'upper': tp = sc.objdict( symp_prob=0.24, asymp_prob=0.003, symp_quar_prob=0.8, asymp_quar_prob=0.1, test_delay=2.0, ) ct = sc.objdict( trace_probs=0.5, trace_time=3.0, ) if ttq_scen is not None: interventions += [ cv.test_prob(start_day='2020-06-10', **tp), cv.contact_tracing(start_day='2020-06-10', **ct) ] # Define beta interventions (for school reopening) b_ch = sc.objdict() b_days = [ '2020-03-04', '2020-03-12', '2020-03-23', '2020-04-25', '2020-08-30' ] b_ch.w = [1.00, p.bc_wc1, p.bc_wc2, p.bc_wc3, p.bc_wc3] b_ch.c = [1.00, p.bc_wc1, p.bc_wc2, p.bc_wc3, p.bc_wc3] NPI_schools = school_reopening_pars['NPI_schools'] if NPI_schools is None: b_ch.s = [1.00, 1.00, 1.00, 1.00, 1.00] else: b_ch.s = [1.00, 1.00, 1.00, 1.00, NPI_schools] # LTCF intervention b_days_l = np.arange(sim.day(b_days[0]), sim.day(b_days[2]) + 1) b_ch_l = np.linspace(1.0, p.bc_lf, len(b_days_l)) interventions += [ cv.change_beta(days=b_days_l, changes=b_ch_l, layers='l', label=f'beta_l') ] for lkey, ch in b_ch.items(): interventions += [ cv.change_beta(days=b_days, changes=b_ch[lkey], layers=lkey, label=f'beta_{lkey}') ] # Define school closure interventions network_change = school_reopening_pars['network_change'] if network_change: popfile_new = popfile_change else: popfile_new = None school_start_day = school_reopening_pars['school_start_day'] intervention_start_day = school_reopening_pars['intervention_start_day'] num_pos = None test_prob = teacher_test_scen['test_prob'] trace_prob = teacher_test_scen['trace_prob'] mobility_file = school_reopening_pars['mobility_file'] interventions += [ cv.close_schools(day_schools_closed='2020-03-12', start_day=school_start_day, pop_file=popfile_new, label='close_schools') ] test_freq = teacher_test_scen['test_freq'] interventions += [ cv.reopen_schools(start_day=intervention_start_day, num_pos=num_pos, test=test_prob, trace=trace_prob, ili_prev=0.002, test_freq=test_freq) ] # SafeGraph intervention interventions += make_safegraph(sim, mobility_file) sim['interventions'] = interventions analyzers = [cv.age_histogram(datafile=age_data_file)] sim['analyzers'] += analyzers # Don't show interventions in plots, there are too many if show_intervs == False: for interv in sim['interventions']: interv.do_plot = False # These are copied from parameters.py -- needed to get younger and 60-65 groups right sim['prognoses']['age_cutoffs'] = np.array( [0, 15, 20, 30, 40, 50, 65, 70, 80, 90]) # Age cutoffs (upper limits) return sim
cv.check_version('0.27.9') do_plot = 1 datafile = sc.thisdir(__file__, '../../example_data.csv') pars = sc.objdict(diag_factor=1.0, n_days=30, pop_infected=100) sim = cv.Sim(pars, datafile=datafile) case = 2 testprobdict = { 0: cv.test_prob(symp_prob=0, asymp_prob=0, test_sensitivity=1.0, loss_prob=0.0, test_delay=0, start_day=0), # works, no diagnoses 1: cv.test_prob(symp_prob=1, asymp_prob=0, test_sensitivity=1.0, loss_prob=0.0, test_delay=0, start_day=0), # works, ~half diagnosed 2: cv.test_prob( symp_prob=0, asymp_prob=1, test_sensitivity=1.0, loss_prob=0.0,
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
def make_sim(seed, beta, calibration=True, future_symp_test=None, scenario=None, end_day='2021-10-30', verbose=0): # Set the parameters #total_pop = 67.86e6 # UK population size total_pop = 55.98e6 # UK population size pop_size = 100e3 # Actual simulated population pop_scale = int(total_pop / pop_size) pop_type = 'hybrid' pop_infected = 1000 beta = beta asymp_factor = 2 contacts = {'h': 3.0, 's': 20, 'w': 20, 'c': 20} beta_layer = {'h': 3.0, 's': 1.0, 'w': 0.6, 'c': 0.3} if end_day is None: end_day = '2021-05-05' pars = sc.objdict( use_waning=True, pop_size=pop_size, pop_infected=pop_infected, pop_scale=pop_scale, pop_type=pop_type, start_day=start_day, end_day=end_day, beta=beta, asymp_factor=asymp_factor, contacts=contacts, rescale=True, rand_seed=seed, verbose=verbose, #rel_symp_prob = 1.1, #rel_severe_prob = 0.45, #rel_crit_prob = 1.0, #rel_death_prob=1.15, ) sim = cv.Sim(pars=pars, datafile=data_path, location='uk') sim['prognoses']['sus_ORs'][0] = 1.0 # ages 20-30 sim['prognoses']['sus_ORs'][1] = 1.0 # ages 20-30 # ADD BETA INTERVENTIONS sbv = 0.63 beta_past = sc.odict({ '2020-02-14': [1.00, 1.00, 0.90, 0.90], '2020-03-16': [1.00, 0.90, 0.80, 0.80], '2020-03-23': [1.29, 0.02, 0.20, 0.20], '2020-06-01': [1.00, 0.23, 0.40, 0.40], '2020-06-15': [1.00, 0.38, 0.50, 0.50], '2020-07-22': [1.29, 0.00, 0.30, 0.50], '2020-09-02': [1.25, sbv, 0.50, 0.70], '2020-10-01': [1.25, sbv, 0.50, 0.70], '2020-10-16': [1.25, sbv, 0.50, 0.70], '2020-10-26': [1.00, 0.00, 0.50, 0.70], '2020-11-05': [1.25, sbv, 0.30, 0.40], '2020-11-14': [1.25, sbv, 0.30, 0.40], '2020-11-21': [1.25, sbv, 0.30, 0.40], '2020-11-30': [1.25, sbv, 0.30, 0.40], '2020-12-03': [1.50, sbv, 0.50, 0.70], '2020-12-20': [1.25, 0.00, 0.50, 0.70], '2020-12-25': [1.50, 0.00, 0.20, 0.70], '2020-12-26': [1.50, 0.00, 0.20, 0.70], '2020-12-31': [1.50, 0.00, 0.20, 0.70], '2021-01-01': [1.50, 0.00, 0.20, 0.70], '2021-01-04': [1.25, 0.14, 0.30, 0.40], '2021-01-11': [1.25, 0.14, 0.30, 0.40], '2021-01-18': [1.25, 0.14, 0.30, 0.40], '2021-01-18': [1.25, 0.14, 0.30, 0.40], '2021-01-30': [1.25, 0.14, 0.30, 0.40], '2021-02-08': [1.25, 0.14, 0.30, 0.40], '2021-02-15': [1.25, 0.14, 0.30, 0.40], '2021-02-22': [1.25, 0.14, 0.30, 0.40], '2021-03-08': [1.25, sbv, 0.30, 0.50], '2021-03-15': [1.25, sbv, 0.30, 0.50], '2021-03-22': [1.25, sbv, 0.30, 0.50], '2021-03-29': [1.25, 0.02, 0.30, 0.50], '2021-04-05': [1.25, 0.02, 0.30, 0.50], '2021-04-12': [1.25, 0.02, 0.40, 0.60], '2021-04-19': [1.25, sbv, 0.40, 0.60], '2021-04-26': [1.25, sbv, 0.40, 0.60], '2021-05-03': [1.25, sbv, 0.40, 0.60], '2021-05-10': [1.25, sbv, 0.40, 0.60], '2021-05-17': [1.25, sbv, 0.50, 0.70], '2021-05-21': [1.25, sbv, 0.50, 0.70], '2021-05-28': [1.25, 0.02, 0.50, 0.70], }) if not calibration: ##no schools until 8th March but assue 20% (1 in 5) in schools between 04/01-22/02; ##model transmission remaining at schools as 14% (to account for 30% reduction due to school measures) ## reopening schools on 8th March, society stage 1 29th March, society stage 2 12th April, ## society some more (stage 3) 17th May and everything (stage 4) 21st June 2021. ## Projecting until end of 2021. if scenario == 'Roadmap_All': beta_scens = sc.odict({ '2021-05-03': [1.25, sbv, 0.40, 0.60], '2021-05-10': [1.25, sbv, 0.40, 0.60], '2021-05-17': [1.25, sbv, 0.50, 0.70], '2021-05-21': [1.25, sbv, 0.50, 0.70], '2021-05-28': [1.25, 0.02, 0.50, 0.70], '2021-06-07': [1.25, sbv, 0.50, 0.70], '2021-06-14': [1.25, sbv, 0.50, 0.70], '2021-06-21': [1.25, sbv, 0.70, 0.90], '2021-06-28': [1.25, sbv, 0.70, 0.90], '2021-07-05': [1.25, sbv, 0.70, 0.90], '2021-07-12': [1.25, sbv, 0.70, 0.90], '2021-07-19': [1.25, 0.00, 0.70, 0.90], '2021-07-26': [1.25, 0.00, 0.70, 0.90], '2021-08-02': [1.25, 0.00, 0.70, 0.90], '2021-08-16': [1.25, 0.00, 0.70, 0.90], '2021-09-01': [1.25, 0.63, 0.70, 0.90], '2021-09-15': [1.25, 0.63, 0.70, 0.90], '2021-09-29': [1.25, 0.63, 0.70, 0.90], '2021-10-13': [1.25, 0.63, 0.70, 0.90], '2021-10-27': [1.25, 0.02, 0.70, 0.90], '2021-11-08': [1.25, 0.63, 0.70, 0.90], '2021-11-23': [1.25, 0.63, 0.70, 0.90], '2021-11-30': [1.25, 0.63, 0.70, 0.90], '2021-12-07': [1.25, 0.63, 0.70, 0.90], '2021-12-21': [1.25, 0.63, 0.70, 0.90], }) ## reopening schools on 8th March, society stage 1 29th March, society stage 2 12th April ONLY ## NO (stage 3) 17th May and NO stage 4 21st June 2021. ## Projecting until end of 2021. #elif scenario == 'Roadmap_Stage2': #beta_scens = sc.odict({'2021-04-12': [1.25, 0.02, 0.40, 0.70], # '2021-04-19': [1.25, sbv, 0.40, 0.70], # '2021-04-26': [1.25, sbv, 0.40, 0.70], # '2021-05-03': [1.25, sbv, 0.40, 0.70], # '2021-05-10': [1.25, sbv, 0.40, 0.70], # '2021-05-17': [1.25, sbv, 0.40, 0.70], # '2021-05-21': [1.25, sbv, 0.40, 0.70], # '2021-05-28': [1.25, 0.02, 0.40, 0.70], # '2021-06-07': [1.25, sbv, 0.40, 0.70], # '2021-06-21': [1.25, sbv, 0.40, 0.70], # '2021-06-28': [1.25, sbv, 0.40, 0.70], # '2021-07-05': [1.25, sbv, 0.40, 0.70], # '2021-07-12': [1.25, sbv, 0.40, 0.70], # '2021-07-19': [1.25, 0.00, 0.40, 0.70], # '2021-07-26': [1.25, 0.00, 0.40, 0.70], # '2021-08-02': [1.25, 0.00, 0.40, 0.70], # '2021-08-16': [1.25, 0.00, 0.40, 0.70], # '2021-09-01': [1.25, 0.63, 0.70, 0.90], # '2021-09-15': [1.25, 0.63, 0.70, 0.90], # '2021-09-29': [1.25, 0.63, 0.70, 0.90], # '2021-10-13': [1.25, 0.63, 0.70, 0.90], # '2021-10-27': [1.25, 0.02, 0.70, 0.90], # '2021-11-08': [1.25, 0.63, 0.70, 0.90], # '2021-11-23': [1.25, 0.63, 0.70, 0.90], # '2021-11-30': [1.25, 0.63, 0.70, 0.90], # '2021-12-07': [1.25, 0.63, 0.70, 0.90], # '2021-12-21': [1.25, 0.63, 0.70, 0.90], # }) ## reopening schools on 8th March, society stage 1 29th March, society stage 2 12th April, ## and society some more (stage 3) 17th May but NO stage 4 21st June 2021. ## Projecting until end of 2021. elif scenario == 'Roadmap_Stage3': beta_scens = sc.odict({ '2021-04-12': [1.25, 0.02, 0.40, 0.60], '2021-04-19': [1.25, sbv, 0.40, 0.60], '2021-04-26': [1.25, sbv, 0.40, 0.60], '2021-05-03': [1.25, sbv, 0.40, 0.60], '2021-05-10': [1.25, sbv, 0.40, 0.60], '2021-05-17': [1.25, sbv, 0.50, 0.70], '2021-05-21': [1.25, sbv, 0.50, 0.70], '2021-05-28': [1.25, 0.02, 0.50, 0.70], '2021-06-07': [1.25, sbv, 0.50, 0.70], '2021-06-14': [1.25, sbv, 0.50, 0.70], '2021-06-21': [1.25, sbv, 0.50, 0.70], '2021-06-28': [1.25, sbv, 0.50, 0.70], '2021-07-05': [1.25, sbv, 0.50, 0.70], '2021-07-12': [1.25, sbv, 0.50, 0.70], '2021-07-19': [1.25, 0.00, 0.50, 0.70], '2021-07-26': [1.25, 0.00, 0.50, 0.70], '2021-08-02': [1.25, 0.00, 0.50, 0.70], '2021-08-16': [1.25, 0.00, 0.50, 0.70], '2021-09-01': [1.25, 0.63, 0.70, 0.90], '2021-09-15': [1.25, 0.63, 0.70, 0.90], '2021-09-29': [1.25, 0.63, 0.70, 0.90], '2021-10-13': [1.25, 0.63, 0.70, 0.90], '2021-10-27': [1.25, 0.02, 0.70, 0.90], '2021-11-08': [1.25, 0.63, 0.70, 0.90], '2021-11-23': [1.25, 0.63, 0.70, 0.90], '2021-11-30': [1.25, 0.63, 0.70, 0.90], '2021-12-07': [1.25, 0.63, 0.70, 0.90], '2021-12-21': [1.25, 0.63, 0.70, 0.90], }) beta_dict = sc.mergedicts(beta_past, beta_scens) else: beta_dict = beta_past beta_days = list(beta_dict.keys()) h_beta = cv.change_beta(days=beta_days, changes=[c[0] for c in beta_dict.values()], layers='h') s_beta = cv.change_beta(days=beta_days, changes=[c[1] for c in beta_dict.values()], layers='s') w_beta = cv.change_beta(days=beta_days, changes=[c[2] for c in beta_dict.values()], layers='w') c_beta = cv.change_beta(days=beta_days, changes=[c[3] for c in beta_dict.values()], layers='c') # Add B.1.117 strain b117 = cv.strain('b117', days=np.arange(sim.day('2020-09-01'), sim.day('2020-09-10')), n_imports=100) sim['strains'] += [b117] # Add B.1.1351 strain b1351 = cv.strain('b1351', days=np.arange(sim.day('2020-11-20'), sim.day('2020-11-30')), n_imports=600) sim['strains'] += [b1351] # Add B.X.XXX strain starting middle of April custom_strain = cv.strain(label='custom', strain=cvp.get_strain_pars()['p1'], days=np.arange(sim.day('2021-03-10'), sim.day('2021-03-10')), n_imports=600) sim['strains'] += [custom_strain] # seems like we need to do this to deal with cross immunity?! sim.init_strains() sim.init_immunity() sim['immunity'] prior = {'wild': 0.5, 'b117': 0.8, 'b1351': 0.8, 'custom': 0.8} pre = {'wild': 0.5, 'b117': 0.8, 'b1351': 0.8, 'custom': 0.8} cross_immunities = cvp.get_cross_immunity() for k, v in sim['strain_map'].items(): if v == 'custom': for j, j_lab in sim['strain_map'].items(): sim['immunity'][k][j] = prior[j_lab] sim['immunity'][j][k] = pre[j_lab] #if j != k: # sim['immunity'][k][j] = cross_immunities['b117'][j_lab] # sim['immunity'][j][k] = cross_immunities[j_lab]['b117'] # # Add a new change in beta to represent the takeover of the novel variant VOC B117 202012/01 # # Assume that the new variant is 60% more transmisible (https://cmmid.github.io/topics/covid19/uk-novel-variant.html, # # Assume that between Nov 1 and Jan 30, the new variant grows from 0-100% of cases interventions = [h_beta, w_beta, s_beta, c_beta] # ADD TEST AND TRACE INTERVENTIONS tc_day = sim.day( '2020-03-16' ) #intervention of some testing (tc) starts on 16th March and we run until 1st April when it increases te_day = sim.day( '2020-04-01' ) #intervention of some testing (te) starts on 1st April and we run until 1st May when it increases tt_day = sim.day( '2020-05-01' ) #intervention of increased testing (tt) starts on 1st May tti_day = sim.day( '2020-06-01' ) #intervention of tracing and enhanced testing (tti) starts on 1st June tti_day_july = sim.day( '2020-07-01' ) #intervention of tracing and enhanced testing (tti) at different levels starts on 1st July tti_day_august = sim.day( '2020-08-01' ) #intervention of tracing and enhanced testing (tti) at different levels starts on 1st August tti_day_sep = sim.day('2020-09-01') tti_day_oct = sim.day('2020-10-01') tti_day_nov = sim.day('2020-11-01') tti_day_dec = sim.day('2020-12-01') tti_day_jan = sim.day('2021-01-01') tti_day_feb = sim.day('2021-02-01') tti_day_march = sim.day('2021-03-08') tti_day_april = sim.day('2021-03-01') #start of vaccinating those 75years+ tti_day_vac1 = sim.day('2021-01-03') #start of vaccinating 60+ old tti_day_vac2 = sim.day('2021-02-03') #start of vaccinating 55+ years old tti_day_vac3 = sim.day('2021-02-28') #start of vaccination 50+ years old tti_day_vac4 = sim.day('2021-03-10') #start vaccinating of 45+ tti_day_vac5 = sim.day('2021-03-30') #start vaccinating of 40+ tti_day_vac6 = sim.day('2021-04-20') #start vaccinating of 35+ tti_day_vac7 = sim.day('2021-05-05') #start vaccinating of 30+ tti_day_vac8 = sim.day('2021-05-30') #start vaccinating of 25+ tti_day_vac9 = sim.day('2021-06-10') #start vaccinating of 18+ tti_day_vac10 = sim.day('2021-06-30') #start vaccinating of 11-17 tti_day_vac11 = sim.day('2021-07-10') s_prob_april = 0.009 s_prob_may = 0.012 s_prob_june = 0.02769 s_prob_july = 0.02769 s_prob_august = 0.03769 tn = 0.09 s_prob_sep = 0.08769 s_prob_oct = 0.08769 s_prob_nov = 0.08769 s_prob_dec = 0.08769 s_prob_jan = 0.08769 #0.114=70%; 0.149=80%; 0.205=90% if future_symp_test is None: future_symp_test = s_prob_jan t_delay = 1.0 #isolation may-july iso_vals = [{k: 0.1 for k in 'hswc'}] #isolation august iso_vals1 = [{k: 0.7 for k in 'hswc'}] #isolation september iso_vals2 = [{k: 0.7 for k in 'hswc'}] #isolation october iso_vals3 = [{k: 0.7 for k in 'hswc'}] #isolation november iso_vals4 = [{k: 0.7 for k in 'hswc'}] #isolation december iso_vals5 = [{k: 0.7 for k in 'hswc'}] #isolation January-April #iso_vals6 = [{k:0.3 for k in 'hswc'}] #testing and isolation intervention interventions += [ cv.test_prob(symp_prob=0.009, asymp_prob=0.0, symp_quar_prob=0.0, start_day=tc_day, end_day=te_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_april, asymp_prob=0.0, symp_quar_prob=0.0, start_day=te_day, end_day=tt_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_may, asymp_prob=0.00076, symp_quar_prob=0.0, start_day=tt_day, end_day=tti_day - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_june, asymp_prob=0.00076, symp_quar_prob=0.0, start_day=tti_day, end_day=tti_day_july - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_july, asymp_prob=0.00076, symp_quar_prob=0.0, start_day=tti_day_july, end_day=tti_day_august - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_august, asymp_prob=0.0028, symp_quar_prob=0.0, start_day=tti_day_august, end_day=tti_day_sep - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_sep, asymp_prob=0.0028, symp_quar_prob=0.0, start_day=tti_day_sep, end_day=tti_day_oct - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_oct, asymp_prob=0.0028, symp_quar_prob=0.0, start_day=tti_day_oct, end_day=tti_day_nov - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_nov, asymp_prob=0.0063, symp_quar_prob=0.0, start_day=tti_day_nov, end_day=tti_day_dec - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_dec, asymp_prob=0.0063, symp_quar_prob=0.0, start_day=tti_day_dec, end_day=tti_day_jan - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_jan, asymp_prob=0.0063, symp_quar_prob=0.0, start_day=tti_day_jan, end_day=tti_day_feb - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_jan, asymp_prob=0.012, symp_quar_prob=0.0, start_day=tti_day_feb, end_day=tti_day_march - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_jan, asymp_prob=0.012, symp_quar_prob=0.0, start_day=tti_day_march, end_day=tti_day_april - 1, test_delay=t_delay), cv.test_prob(symp_prob=s_prob_jan, asymp_prob=0.012, symp_quar_prob=0.0, start_day=tti_day_april, test_delay=t_delay), cv.contact_tracing(trace_probs={ 'h': 1, 's': 0.8, 'w': 0.8, 'c': 0.05 }, trace_time={ 'h': 0, 's': 1, 'w': 1, 'c': 2 }, start_day='2020-06-01', end_day='2023-06-30', quar_period=10), #cv.contact_tracing(trace_probs={'h': 1, 's': 0.5, 'w': 0.5, 'c': 0.05}, # trace_time={'h': 0, 's': 1, 'w': 1, 'c': 2}, # start_day='2021-03-08', # quar_period=5), cv.dynamic_pars({'iso_factor': { 'days': te_day, 'vals': iso_vals }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_august, 'vals': iso_vals1 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_sep, 'vals': iso_vals2 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_oct, 'vals': iso_vals3 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_nov, 'vals': iso_vals4 }}), cv.dynamic_pars( {'iso_factor': { 'days': tti_day_dec, 'vals': iso_vals5 }}) ] #cv.dynamic_pars({'rel_death_prob': {'days': tti_day_vac, 'vals': 0.9}})] #cv.vaccine(days=[0,14], rel_sus=0.4, rel_symp=0.2, cumulative=[0.7, 0.3])] # derived from AZ default params (3.0.2) with increased interval between doses) # dose_pars = cvp.get_vaccine_dose_pars()['az'] # dose_pars.update({'nab_interval': 14, 'interval':7*9}) # strain_pars = cvp.get_vaccine_strain_pars()['az'] # hard code them in dose_pars = { 'nab_eff': { 'sus': { 'slope': 1.6, 'n_50': 0.05 } }, 'nab_init': { 'dist': 'normal', 'par1': -0.85, 'par2': 2 }, 'nab_boost': 3, 'doses': 2, 'interval': 7 * 12, 'nab_interval': 14 } strain_pars = { 'wild': 1.0, 'b117': 1 / 2.3, 'b1351': 1 / 9, 'p1': 1 / 2.9, 'custom': 1 / 2.3 } vaccine = sc.mergedicts({'label': 'az_uk'}, sc.mergedicts(dose_pars, strain_pars)) # age targeted vaccination def subtarget_75_100(sim): inds = cv.true(sim.people.age >= 75) return {'inds': inds, 'vals': 0.020 * np.ones(len(inds))} interventions += [ utils_vac.vaccinate(vaccine=vaccine, prob=0.1, subtarget=subtarget_75_100, days=np.arange(sim.day('2020-12-20'), sim.day('2023-01-01'))) ] def subtarget_60_75(sim): inds = cv.true((sim.people.age >= 60) & (sim.people.age < 75)) return {'inds': inds, 'vals': 0.020 * np.ones(len(inds))} interventions += [ utils_vac.vaccinate(vaccine=vaccine, prob=0.1, subtarget=subtarget_60_75, days=np.arange(sim.day('2021-01-28'), sim.day('2023-01-01'))) ] def subtarget_50_60(sim): inds = cv.true((sim.people.age >= 50) & (sim.people.age < 60)) return {'inds': inds, 'vals': 0.010 * np.ones(len(inds))} interventions += [ utils_vac.vaccinate(vaccine=vaccine, prob=0.1, subtarget=subtarget_50_60, days=np.arange(sim.day('2021-02-10'), sim.day('2023-01-01'))) ] def subtarget_40_50(sim): inds = cv.true((sim.people.age >= 40) & (sim.people.age < 50)) return {'inds': inds, 'vals': 0.005 * np.ones(len(inds))} interventions += [ utils_vac.vaccinate(vaccine=vaccine, prob=0.1, subtarget=subtarget_40_50, days=np.arange(sim.day('2021-04-10'), sim.day('2023-01-01'))) ] def subtarget_30_40(sim): inds = cv.true((sim.people.age >= 30) & (sim.people.age < 40)) return {'inds': inds, 'vals': 0.003 * np.ones(len(inds))} interventions += [ utils_vac.vaccinate(vaccine=vaccine, prob=0.1, subtarget=subtarget_30_40, days=np.arange(sim.day('2021-05-10'), sim.day('2023-01-01'))) ] def subtarget_18_30(sim): inds = cv.true((sim.people.age >= 18) & (sim.people.age < 30)) return {'inds': inds, 'vals': 0.003 * np.ones(len(inds))} interventions += [ utils_vac.vaccinate(vaccine=vaccine, prob=0.01, subtarget=subtarget_18_30, days=np.arange(sim.day('2021-06-10'), sim.day('2023-01-01'))) ] analyzers = [] #analyzers += [cv.age_histogram(datafile='uk_stats_by_age.xlsx', edges=np.concatenate([np.linspace(0, 90, 19),np.array([100])]))] # Finally, update the parameters sim.update_pars(interventions=interventions, analyzers=analyzers) # Change death and critical probabilities # interventions += [cv.dynamic_pars({'rel_death_prob':{'days':sim.day('2020-07-01'), 'vals':0.6}})] # Finally, update the parameters #sim.update_pars(interventions=interventions) for intervention in sim['interventions']: intervention.do_plot = False sim.initialize() return sim
'pars': { 'interventions': None, } }, 'distance': { 'name': 'Social distancing', 'pars': { 'interventions': cv.change_beta(days=start_day, changes=0.7) } }, 'ttq': { 'name': 'Test-trace-quarantine', 'pars': { 'interventions': [ cv.test_prob(start_day=start_day, symp_prob=0.2, asymp_prob=0.05, test_delay=1.0), cv.contact_tracing(start_day=start_day, trace_probs=0.8, trace_time=1.0), ] } }, } # Run the scenarios -- this block is required for parallel processing on Windows if __name__ == "__main__": scens = cv.Scenarios(basepars=basepars, metapars=metapars, scenarios=scenarios)