def run_msim(self, new_deaths=False): ''' Run the simulation -- if new_deaths, fit to daily deaths rather than cumulative cases + deaths ''' if self.n_runs == 1: sim = self.sim sim.run() else: msim = cv.MultiSim(base_sim=self.sim) msim.run(n_runs=self.n_runs) sim = msim.reduce(output=True) if new_deaths: offset = cv.daydiff(sim['start_day'], sim.data['date'][0]) d_data = self.smooth(sim.data['new_deaths'].values) d_sim = self.smooth(sim.results['new_deaths'].values[offset:]) minlen = min(len(d_data), len(d_sim)) d_data = d_data[:minlen] d_sim = d_sim[:minlen] deaths = {'deaths': dict(data=d_data, sim=d_sim, weights=1)} sim.compute_fit(custom=deaths, keys=['cum_diagnoses', 'cum_deaths'], weights={ 'cum_diagnoses': 0.2, 'cum_deaths': 0.2 }, output=False) else: sim.compute_fit(output=False) self.sim = sim self.mismatch = sim.results.fit.mismatch return sim
def test_misc(): sc.heading('Testing miscellaneous functions') sim_path = 'test_misc.sim' json_path = 'test_misc.json' gitinfo_path = 'test_misc.gitinfo' fig_path = 'test_misc.png' fig_comments = 'Test comment' # Data loading cv.load_data(csv_file) cv.load_data(xlsx_file) with pytest.raises(NotImplementedError): cv.load_data('example_data.unsupported_extension') with pytest.raises(ValueError): cv.load_data(xlsx_file, columns=['missing_column']) # Dates d1 = cv.date('2020-04-04') d2 = cv.date(sc.readdate('2020-04-04')) ds = cv.date('2020-04-04', d2) assert d1 == d2 assert d2 == ds[0] with pytest.raises(ValueError): cv.date([(2020, 4, 4)]) # Raises a TypeError which raises a ValueError with pytest.raises(ValueError): cv.date('Not a date') cv.daydiff('2020-04-04') # Run sim for more investigations sim = cv.Sim(pop_size=500, verbose=0) sim.run() sim.plot(do_show=False) # Saving and loading cv.savefig(fig_path, comments=fig_comments) cv.save(filename=sim_path, obj=sim) cv.load(filename=sim_path) # Version checks cv.check_version('0.0.0') # Nonsense version print('↑ Should complain about version') with pytest.raises(ValueError): cv.check_version('0.0.0', die=True) # Git checks cv.git_info(json_path) cv.git_info(json_path, check=True) # Poisson tests c1 = 5 c2 = 8 for alternative in ['two-sided', 'larger', 'smaller']: cv.poisson_test(c1, c2, alternative=alternative) for method in ['score', 'wald', 'sqrt', 'exact-cond']: cv.poisson_test(c1, c2, method=method) with pytest.raises(ValueError): cv.poisson_test(c1, c2, method='not a method') # Test locations for location in [None, 'viet-nam']: cv.data.show_locations(location) # Test versions with pytest.raises(ValueError): cv.check_save_version('1.3.2', die=True) cv.check_save_version(cv.__version__, filename=gitinfo_path, comments='Test') # Test PNG try: metadata = cv.get_png_metadata(fig_path, output=True) assert metadata['Covasim version'] == cv.__version__ assert metadata['Covasim comments'] == fig_comments except ImportError as E: print( f'Cannot test PNG function since pillow not installed ({str(E)}), skipping' ) # Tidy up remove_files(sim_path, json_path, fig_path, gitinfo_path) return
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
def test_misc(): sc.heading('Testing miscellaneous functions') sim_path = 'test_misc.sim' json_path = 'test_misc.json' # Data loading cv.load_data(csv_file) cv.load_data(xlsx_file) with pytest.raises(NotImplementedError): cv.load_data('example_data.unsupported_extension') with pytest.raises(ValueError): cv.load_data(xlsx_file, columns=['missing_column']) # Dates d1 = cv.date('2020-04-04') d2 = cv.date(sc.readdate('2020-04-04')) ds = cv.date('2020-04-04', d2) assert d1 == d2 assert d2 == ds[0] with pytest.raises(ValueError): cv.date([(2020, 4, 4)]) # Raises a TypeError which raises a ValueError with pytest.raises(ValueError): cv.date('Not a date') cv.daydiff('2020-04-04') # Saving and loading sim = cv.Sim() cv.save(filename=sim_path, obj=sim) cv.load(filename=sim_path) # Version checks cv.check_version('0.0.0') # Nonsense version print('↑ Should complain about version') with pytest.raises(ValueError): cv.check_version('0.0.0', die=True) # Git checks cv.git_info(json_path) cv.git_info(json_path, check=True) # Poisson tests c1 = 5 c2 = 8 for alternative in ['two-sided', 'larger', 'smaller']: cv.poisson_test(c1, c2, alternative=alternative) for method in ['score', 'wald', 'sqrt', 'exact-cond']: cv.poisson_test(c1, c2, method=method) with pytest.raises(ValueError): cv.poisson_test(c1, c2, method='not a method') # Tidy up remove_files(sim_path, json_path) return
def create_sim(pars=None, label=None, use_safegraph=True, show_intervs=False, people=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-07-19' 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': '2020-07-19', 'rescale': True, 'rescale_factor': 1.1, 'verbose': 0, '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' # 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] # Define beta interventions (for calibration) b_ch = sc.objdict() b_days = ['2020-03-04', '2020-03-12', '2020-04-25'] b_ch.s = [1.00, 0.00, 0.00] b_ch.w = [p.bc_wc1, p.bc_wc2, p.bc_wc3] b_ch.c = [p.bc_wc1, p.bc_wc2, p.bc_wc3] for lkey, ch in b_ch.items(): interventions += [ cv.change_beta(days=b_days, changes=b_ch[lkey], layers=lkey, label=f'beta_{lkey}') ] # 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') ] # SafeGraph intervention & tidy up interventions += make_safegraph(sim) sim['interventions'] = interventions # 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
import os import sciris as sc import numpy as np import covasim as cv t = cv.daydiff('2020-01-21', '2020-09-01') scenarios = [ 'no_masks', 'low_comp', 'med_comp', 'low_comp_notschools', 'med_comp_notschools' ] testcases = [ ## (scenario, trace, test, infections) (0, 0.47, 0.03, 110000), (0, 0.47, 0.12, 17000), (1, 0.47, 0.03, 70000), (1, 0.47, 0.12, 5800), ] for scenario, trace, test, expected in testcases: ## run the simulation cmd = "python UK_tradeoffs.py --samples 12 --scenario %s --test %.02f --trace %.02f" % ( scenario, test, trace) os.system(cmd) ## load the results outfile = "%s/test%.02f-trace%.02f.obj" % (scenarios[scenario], test, trace) results = sc.loadobj(outfile)