예제 #1
0
    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))
예제 #2
0
    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)
예제 #3
0
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)
예제 #4
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