def set_sim_prog_prob(self, params_dict): """ Allows for testing prognoses probability as absolute rather than relative. NOTE: You can only call this once per test or you will overwrite your stuff. """ supported_probabilities = [ 'rel_symp_prob', 'rel_severe_prob', 'rel_crit_prob', 'rel_death_prob' ] if not self.sim_pars: self.set_sim_pars() if not self.sim_progs: self.sim_progs = cv.get_prognoses(self.sim_pars['prog_by_age']) for k in params_dict: prognosis_in_question = None expected_prob = params_dict[k] if k == 'rel_symp_prob': prognosis_in_question = 'symp_probs' elif k == 'rel_severe_prob': prognosis_in_question = 'severe_probs' elif k == 'rel_crit_prob': prognosis_in_question = 'crit_probs' elif k == 'rel_death_prob': prognosis_in_question = 'death_probs' else: raise KeyError( f"Key {k} not found in {supported_probabilities}.") old_probs = self.sim_progs[prognosis_in_question] self.sim_progs[prognosis_in_question] = np.array([expected_prob] * len(old_probs))
def run_sim(self, params_dict=None, write_results_json=False, population_type=None): if not self.sim_pars or params_dict: # If we need one, or have one here self.set_sim_pars(params_dict=params_dict) self.sim_pars['interventions'] = self.interventions self.sim = cv.Sim(pars=self.sim_pars, datafile=None) if not self.sim_progs: self.sim_progs = cv.get_prognoses(self.sim_pars['prog_by_age']) self.sim['prognoses'] = self.sim_progs if population_type: self.sim.update_pars(pop_type=population_type) self.sim.run(verbose=0) self.simulation_result = self.sim.to_json(tostring=False) if write_results_json or self.is_debugging: with open(self.expected_result_filename, 'w') as outfile: json.dump(self.simulation_result, outfile, indent=4, sort_keys=True)
pars = dict( pop_size=50e3, pop_type='hybrid', rand_seed=1, n_days=365, pop_infected=10, beta=0.016, verbose=0.1, iso_factor={k: 0.0 for k in 'hswc'}, quar_factor={k: 0.0 for k in 'hswc'}, ) # To change symptomatic probability pars['prognoses'] = cv.get_prognoses() pars['prognoses']['symp_probs'][:] = 1 # Define interventions sd = 30 t = sc.objdict() t.prob = cv.test_prob(start_day=sd, symp_prob=0.06, asymp_prob=0.0006, symp_quar_prob=1.0, asymp_quar_prob=1.0) t.num = cv.test_num(start_day=sd, daily_tests=500, symp_test=10.0, quar_test=10.0) ct = cv.contact_tracing(start_day=sd, trace_probs=1, trace_time=0)
'dist': 'lognormal_int', 'par1': 14.0, 'par2': 2.4 }, 'crit2rec': { 'dist': 'lognormal_int', 'par1': 14.0, 'par2': 2.4 }, 'crit2die': { 'dist': 'lognormal_int', 'par1': 6.2, 'par2': 1.7 } } prognoses = cv.get_prognoses() prognoses['sus_ORs'] = np.array( [1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.0, 1.0, 1.0, 1.0]) # Equally susceptible prognoses['symp_probs'] = np.array( [0.905, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) # Equally susceptible prognoses['severe_probs'] = np.array( [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) # Zero'd out prognoses['crit_probs'] = np.array( [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) # Zero'd out prognoses['death_probs'] = np.array( [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) # Zero'd out pars['prognoses'] = prognoses pars['start_day'] = '2020-01-01' pars['n_days'] = 60
def create_sim(pars=None, use_safegraph=True, label=None, show_intervs=False, people=None, adjust_ORs=False, num_pos=None, test_prob=None, trace_prob=None, NPI_schools=None, test_freq=None, network_change=False, schedule=None, school_start_day=None, intervention_start_day=None, ttq_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 # Basic parameters and sim creation pars = {'pop_size': 225e3, 'pop_scale': 10, 'pop_type': 'synthpops', 'pop_infected': p.pop_infected, 'beta': p.beta, 'start_day': '2020-02-01', '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, states=['exposed', 'dead', 'tested', 'diagnosed', 'severe'])], 'beta_layer': dict(h=p.bl_h, s=p.bl_s, w=p.bl_w, c=p.bl_c, l=p.bl_l), } # 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 print(f'Creating sim! safegraph={use_safegraph}, seed={p.rand_seed}') 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. interventions = [] # Testing bins df = pd.read_csv(age_series_file) age_bins = [0, 20, 40, 60, 80, np.inf] test_num_subtargs = [ftest_num_subtarg1, ftest_num_subtarg2, ftest_num_subtarg3, ftest_num_subtarg4, ftest_num_subtarg5] for ia in range(len(age_bins) - 1): label = '{}-{}'.format(age_bins[ia], age_bins[ia + 1] - 1) df_ = df[(df['age'] >= age_bins[ia]) & (df['age'] < age_bins[ia + 1])] # sum for the dates df_ = df_.groupby('date').sum() df_['age'] = age_bins[ia] df_['datetime'] = [sc.readdate(d) for d in df_.index.values] df_ = df_.set_index('datetime') # make sure we have all the days we care about new_index = pd.date_range(df_.index[0], df_.index[-1], freq='1d') df_ = df_.reindex(new_index, fill_value=0.0, method='nearest') test_kwargs = dict(daily_tests=df_['new_tests'], quar_test=1.0, test_delay=2, subtarget=test_num_subtargs[ia]) interventions += [cv.test_num(symp_test=p.tn1, start_day='2020-01-27', end_day='2020-03-23', **test_kwargs, label='tn1 ' + label)] interventions += [cv.test_num(symp_test=p.tn2, start_day='2020-03-24', end_day='2020-04-14', **test_kwargs, label='tn2 ' + label)] interventions += [cv.test_num(symp_test=p.tn3, start_day='2020-04-15', end_day='2020-05-07', **test_kwargs, label='tn3 ' + label)] interventions += [cv.test_num(symp_test=p.tn4, start_day='2020-05-08', end_day='2020-06-04', **test_kwargs, label='tn4 ' + label)] interventions += [cv.test_num(symp_test=p.tn5, start_day='2020-06-17', end_day='2020-06-18', **test_kwargs, label='tn5 ' + label)] interventions += [cv.test_num(symp_test=p.tn6, start_day='2020-06-19', end_day=None, **test_kwargs, label='tn6 ' + label)] # Seed in LTCF interventions += [seed_ltcf(days=[15], seeds=[p.lseeds])] # Define beta interventions b_days = ['2020-03-02', '2020-03-12', '2020-03-23', '2020-04-15', '2020-05-08', '2020-06-05', '2020-06-19' ] # Home and school beta changes interventions += [ cv.change_beta(days=b_days[1], changes=p.bc_s, layers='s', label="beta_s") ] # Work and community beta changes b_days_wc = np.arange(sim.day(b_days[0]), sim.day(b_days[1]) + 1).tolist() + b_days[2:] b_ch_wc = np.linspace(1.0, p.bc_wc1, len(b_days_wc) - 5).tolist() + [p.bc_wc2, p.bc_wc3, p.bc_wc4, p.bc_wc5, p.bc_wc6] for lkey in ['w', 'c']: interventions += [cv.change_beta(days=b_days_wc, changes=b_ch_wc, layers=lkey, label=f'beta_{lkey}')] # LTCF beta change 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='beta_l')] # sim.people.contacts['c'] = remove_ltcf_community(sim) # Remove community contacts from LTCF # Age-based beta changes b_age_days = ["2020-05-08", "2020-06-05", "2020-06-19"] b_age_changes = [[p.bc_age_u10_a, # 0 p.bc_age_10_20_a, # 10 p.bc_age_20_30_a, # 20 p.bc_age_30_40_a, # 30 1.0, # 40 1.0, # 50 p.bc_age_65u_a, # 65 p.bc_age_65u_a, # 70 p.bc_age_65u_a, # 80 p.bc_age_65u_a, # 90 ], [p.bc_age_u10_b, # 0 p.bc_age_10_20_b, # 10 p.bc_age_20_30_b, # 20 p.bc_age_30_40_b, # 30 1.0, # 40 1.0, # 50 p.bc_age_65u_b, # 65 p.bc_age_65u_b, # 70 p.bc_age_65u_b, # 80 p.bc_age_65u_b, # 90 ], [p.bc_age_u10_c, # 0 p.bc_age_10_20_c, # 10 p.bc_age_20_30_c, # 20 p.bc_age_30_40_c, # 30 1.0, # 40 1.0, # 50 p.bc_age_65u_c, # 65 p.bc_age_65u_c, # 70 p.bc_age_65u_c, # 80 p.bc_age_65u_c, # 90 ] ] interventions += [beta_change_age.change_beta_age(b_age_days, b_age_changes)] # SafeGraph intervention & tidy up if use_safegraph: interventions += make_safegraph(sim) 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-07-10', **tp), cv.contact_tracing(start_day='2020-07-10', **ct)] if network_change: popfile_new = popfile_change else: popfile_new = None if NPI_schools is not None: interventions += [cv.change_beta(days=sim.day('2020-09-01'), changes=NPI_schools, layers='s')] interventions += [cv.close_schools(day_schools_closed='2020-03-12', start_day=school_start_day, pop_file=popfile_new)] 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, schedule=schedule)] sim['interventions'] = interventions # Don't show interventions in plots, there are too many for interv in sim['interventions']: interv.do_plot = False # Prognoses (particularly to severe/hospitalizations) need attention prognoses = sc.dcp(cv.get_prognoses()) prognoses['severe_probs'] *= prognoses[ 'symp_probs'] # Conditional probability of symptoms becoming severe, given symptomatic prognoses['crit_probs'] *= prognoses[ 'severe_probs'] # Conditional probability of symptoms becoming critical, given severe prognoses['death_probs'] *= prognoses['crit_probs'] # Conditional probability of dying, given critical symptoms prognoses.update({'age_cutoff': np.array([0, 10, 20, 30, 40, 50, 65, 70, 80, 90])}) prognoses.update({'severe_probs': np.array([1, 1, 1, p.rsp1, p.rsp1, p.rsp1, p.rsp1, p.rsp1, p.rsp2, p.rsp2]) * prognoses['severe_probs']}) prognoses['death_probs'] /= prognoses['crit_probs'] # Conditional probability of dying, given critical symptoms prognoses['crit_probs'] /= prognoses[ 'severe_probs'] # Conditional probability of symptoms becoming critical, given severe prognoses['severe_probs'] /= prognoses[ 'symp_probs'] # Conditional probability of symptoms becoming severe, given symptomatic sim.pars.update({'prognoses': prognoses}) return sim