Exemplo n.º 1
0
    def test_tracing_dial(self):

        sim = cv.Sim(SIM_PARAMS, popfile=popfile, load_pop=True)

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             start_day='2020-08-05',
                             label='close_schools'),
            cv.reopen_schools(start_day='2020-08-05',
                              ili_prev=0,
                              num_pos=None,
                              trace=0.1,
                              label='reopen_schools')
        ]

        sim['interventions'] = interventions

        sim.run()
        cum_infected_a = sim.results['cum_infections']

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             start_day='2020-08-05',
                             label='close_schools'),
            cv.reopen_schools(start_day='2020-08-05',
                              ili_prev=0,
                              num_pos=None,
                              trace=0.4,
                              label='reopen_schools')
        ]

        sim['interventions'] = interventions

        sim.run()
        cum_infected_b = sim.results['cum_infections']

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             start_day='2020-08-05',
                             label='close_schools'),
            cv.reopen_schools(start_day='2020-08-05',
                              ili_prev=0,
                              num_pos=None,
                              trace=0.7,
                              label='reopen_schools')
        ]

        sim['interventions'] = interventions

        sim.run()
        cum_infected_c = sim.results['cum_infections']

        self.assertGreater(cum_infected_c, cum_infected_b)
        self.assertGreater(cum_infected_b, cum_infected_a)
Exemplo n.º 2
0
    def test_testing_dial(self):
        sim = cv.Sim(SIM_PARAMS, popfile=popfile, load_pop=True)
        # Setting test to 0.1, trace to 0 so that trace doesn't mess up validation
        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           test=0.1,
                                           trace=0,
                                           ili_prev=0,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]

        sim['interventions'] = interventions

        sim.run()
        diagnoses_a = reopen_schools.num_diagnosed

        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           test=0.4,
                                           ili_prev=0,
                                           trace=0,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             start_day='2020-08-05',
                             label='close_schools'), reopen_schools
        ]
        sim['interventions'] = interventions

        sim.run()
        diagnoses_b = reopen_schools.num_diagnosed

        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           test=0.8,
                                           ili_prev=0,
                                           trace=0,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             start_day='2020-08-05',
                             label='close_schools'), reopen_schools
        ]
        sim['interventions'] = interventions

        diagnoses_c = reopen_schools.num_diagnosed

        # This requires a bit of fenegling and testing to determine reasonable relative
        # values
        self.assertGreater(diagnoses_a, diagnoses_b)
        self.assertGreater(diagnoses_b, diagnoses_c)
Exemplo n.º 3
0
    def test_ili_schooldays(self):

        SIM_PARAMS = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 0,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-08-30',
            'rand_seed': 0,
        }
        sim = cv.Sim(SIM_PARAMS, popfile=popfile, load_pop=True)

        reopen_schools = cv.reopen_schools(start_day={
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        },
                                           ili_prev=0,
                                           label='reopen_schools')
        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]

        sim['interventions'] = interventions

        sim.run()
        # No students should be left undiagnosed
        num_school_days_lost_a = sim.school_info['school_days_lost']

        reopen_schools = cv.reopen_schools(start_day={
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        },
                                           ili_prev=0.8,
                                           label='reopen_schools')
        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]

        sim['interventions'] = interventions

        sim.run()
        # Can add more cases for greater granularity of testing
        num_school_days_lost_b = sim.school_info['school_days_lost']

        self.assertGreater(num_school_days_lost_b, num_school_days_lost_a)
Exemplo n.º 4
0
    def test_no_infected(self):
        SIM_PARAMS2 = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 0,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-09-01',
            'rand_seed': 0,
        }
        popfile = f'inputs/kc_synthpops_clustered_withstaff_10e3.ppl'

        sim = cv.Sim(SIM_PARAMS2, popfile=popfile, load_pop=True)

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'),
            cv.reopen_schools(start_day='2020-08-01',
                              test=0.99,
                              ili_prev=0,
                              num_pos=None,
                              label='reopen_schools'),
            cv.change_beta(1, 0)
        ]

        sim['interventions'] = interventions

        sim.run()
        num_school_days_lost = sim.school_info['school_days_lost']
        num_student_school_days = sim.school_info['total_student_school_days']

        #assertinhg that all school days are lost
        self.assertEqual(num_school_days_lost, 0)
        self.assertGreater(num_student_school_days, 0)
Exemplo n.º 5
0
    def test_numpos_limit(self):
        SIM_PARAMS6 = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 100,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-08-10',
            'rand_seed': 0,
        }

        sim = cv.Sim(SIM_PARAMS6, popfile=popfile, load_pop=True)
        reopen_schools = cv.reopen_schools(start_day={
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        },
                                           test=0.99,
                                           ili_prev=0,
                                           num_pos=0,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]
        sim['interventions'] = interventions
        sim.run()
        self.assertEqual(reopen_schools.num_schools,
                         reopen_schools.closed.count(
                             True))  # Ensuring that all schools are closed
Exemplo n.º 6
0
    def test_testing_params(self):
        SIM_PARAMS = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 100,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-09-01',
            'rand_seed': 0,
        }
        sim = cv.Sim(SIM_PARAMS, popfile=popfile, load_pop=True)

        reopen_schools = cv.reopen_schools(start_day={
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        },
                                           test=1,
                                           test_freq=1,
                                           ili_prev=0,
                                           label='reopen_schools')
        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]

        sim['interventions'] = interventions

        sim.run()
        # No students should be left undiagnosed
        self.assertEqual(reopen_schools.num_undiagnosed, 0)
Exemplo n.º 7
0
    def test_all_infected(self):
        SIM_PARAMS3 = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 10e3,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-09-01',
            'rand_seed': 0,
        }

        sim = cv.Sim(SIM_PARAMS3, popfile=popfile, load_pop=True)
        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           test=0.99,
                                           ili_prev=0,
                                           num_pos=50,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]

        sim['interventions'] = interventions

        sim.run()
        #asserting that all schools are closed
        self.assertEqual(reopen_schools.num_schools,
                         reopen_schools.school_closures)

        num_school_days_lost = sim.school_info['school_days_lost']
        num_student_school_days = sim.school_info['total_student_school_days']

        #assertinhg that all school days are lost
        self.assertEqual(num_school_days_lost, num_student_school_days)
Exemplo n.º 8
0
    def test_iliprev_exceptions(self):
        SIM_PARAMS6 = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 100,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-09-91',
            'rand_seed': 0,
        }
        # testing higher value of ili_prev
        sim = cv.Sim(SIM_PARAMS6, popfile=popfile, load_pop=True)
        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           test=0.99,
                                           ili_prev=2,
                                           label='reopen_schools')
        # testing negative value of ili_prev
        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             start_day='2020-08-05',
                             label='close_schools'), reopen_schools
        ]
        sim['interventions'] = interventions
        self.assertRaises(
            ValueError, sim.run
        )  # Need to either skip this test or fine tune error message

        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           ili_prev=-1,
                                           num_pos=0,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             start_day='2020-08-05',
                             label='close_schools'), reopen_schools
        ]
        sim['interventions'] = interventions
        self.assertRaises(ValueError, sim.run)
Exemplo n.º 9
0
    def test_freq_dial(self):
        is_debugging = False
        SIM_PARAMS8 = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 5e3,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-08-30',
            'rand_seed': 0,
        }
        sim = cv.Sim(SIM_PARAMS8, popfile=popfile, load_pop=True)
        # Testing daily, bidaily, and every third day testing, trace set to 0 so it doesn't mess with validation
        # since if you have teachers tested and traced then infectious kiddos would be sent home and the infection rate would
        # be substantially lower
        results = []
        for i in range(1, 3):
            reopen_schools = cv.reopen_schools(start_day={
                'pk': '2020-08-05',
                'es': '2020-08-05',
                'ms': '2020-08-05',
                'hs': '2020-08-05',
                'uv': '2020-08-05'
            },
                                               test_freq=i,
                                               trace=0,
                                               ili_prev=0,
                                               label='reopen_schools')

            interventions = [
                cv.close_schools(day_schools_closed='2020-08-01',
                                 label='close_schools'), reopen_schools
            ]

            sim['interventions'] = interventions

            sim.run()

            # May want to load school_info from differently saved json
            #sim.to_json(output_filename=f"DEBUG_test_freq_{i}.json")
            #with open(f"json_test_allinfected.json") as f:
            #    json_format = json.load(f)

            results.append(sim.school_info['num_teachers_tested'])

        # This requires a bit of fenegling and testing to determine reasonable relative
        # values, but more frequent testing should lead to more diagnoses in absence of tracing
        self.assertGreater(results[0], results[1])
        self.assertGreater(results[1], results[2])
Exemplo n.º 10
0
    def test_numpos_days(self):

        sim = cv.Sim(SIM_PARAMS, popfile=popfile, load_pop=True)
        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           test=0.99,
                                           num_pos=1,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]

        sim['interventions'] = interventions

        sim.run()
        num_school_days_lost_a = sim.school_info['school_days_lost']

        reopen_schools = cv.reopen_schools(start_day='2020-08-05',
                                           test=0.99,
                                           ili_prev=0,
                                           num_pos=100,
                                           label='reopen_schools')

        interventions = [
            cv.close_schools(day_schools_closed='2020-08-01',
                             label='close_schools'), reopen_schools
        ]
        sim['interventions'] = interventions

        sim.run()
        num_school_days_lost_b = sim.school_info['school_days_lost']

        # This will require a bit of fenegling and testing to determine reasonable relative
        # values
        self.assertGreater(num_school_days_lost_a, num_school_days_lost_b)
Exemplo n.º 11
0
    'end_day': '2020-08-30',
    'rand_seed': 0,
}
sim = cv.Sim(SIM_PARAMS, popfile=popfile, load_pop=True)

reopen_schools = cv.reopen_schools(start_day={
    'pk': '2020-08-05',
    'es': '2020-08-05',
    'ms': '2020-08-05',
    'hs': '2020-08-05',
    'uv': '2020-08-05'
},
                                   ili_prev=0,
                                   label='reopen_schools')
interventions = [
    cv.close_schools(day_schools_closed='2020-08-01', label='close_schools'),
    reopen_schools
]

sim['interventions'] = interventions

sim.run()
# No students should be left undiagnosed
num_school_days_lost_a = sim.school_info['school_days_lost']

reopen_schools = cv.reopen_schools(start_day={
    'pk': '2020-08-05',
    'es': '2020-08-05',
    'ms': '2020-08-05',
    'hs': '2020-08-05',
    'uv': '2020-08-05'
Exemplo n.º 12
0
def run_sim(params):

    p = sc.objdict(
        sc.mergedicts(define_pars(which='best', kind='both'), params))
    if 'rand_seed' not in p:
        seed = 1
        print(
            f'Note, could not find random seed in {params}! Setting to {seed}')
        p['rand_seed'] = seed  # Ensure this exists

    popfile_stem = f'inputs/kc_synthpops_clustered_withstaff_seed'

    tp = sc.objdict(
        symp_prob=0.03,
        asymp_prob=0.001,
        symp_quar_prob=0.01,
        asymp_quar_prob=0.001,
        test_delay=5.0,
    )
    ct = sc.objdict(
        trace_probs={
            'w': 0.1,
            'c': 0,
            'h': 0.8,
            's': 0.8
        },
        trace_time=5.0,
    )

    pars = {
        'pop_size': 225e3,
        'pop_scale': 10,
        'pop_type': 'synthpops',
        'pop_infected': p.pop_infected,
        'rescale': True,
        'rescale_factor': 1.1,
        'verbose': 0,
        'start_day': '2020-07-01',
        'end_day': '2020-12-01',
        'rand_seed': p.rand_seed,
    }
    n_popfiles = 5
    popfile = popfile_stem + str(params['rand_seed'] % n_popfiles) + '.ppl'
    sim = cv.Sim(pars, popfile=popfile, load_pop=True)
    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,
                       layers='w',
                       label='NPI_work'),
        cv.close_schools(day_schools_closed='2020-07-01',
                         start_day=None,
                         label='close_schools')
    ]
    sim['interventions'] = interventions
    for interv in sim['interventions']:
        interv.do_plot = False
    sim.run()
    return (sim)
Exemplo n.º 13
0
    def test_lost_days_startday(self):
        day_schools_open1 = {
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        }
        day_schools_open2 = {
            'pk': '2020-08-25',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        }
        day_schools_open3 = {
            'pk': '2020-08-25',
            'es': '2020-08-25',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        }
        day_schools_open4 = {
            'pk': '2020-08-25',
            'es': '2020-08-25',
            'ms': '2020-08-25',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        }
        day_schools_open5 = {
            'pk': '2020-08-25',
            'es': '2020-08-25',
            'ms': '2020-08-25',
            'hs': '2020-08-25',
            'uv': '2020-08-05'
        }
        day_schools_open6 = {
            'pk': '2020-08-25',
            'es': '2020-08-25',
            'ms': '2020-08-25',
            'hs': '2020-08-25',
            'uv': '2020-08-25'
        }
        day_schools_open = [
            day_schools_open1, day_schools_open2, day_schools_open3,
            day_schools_open4, day_schools_open5, day_schools_open6
        ]

        sim = cv.Sim(SIM_PARAMS, popfile=popfile, load_pop=True)

        cum_infected_prev = -1
        num_school_days_lost_prev = 10000000
        for schedule in day_schools_open:
            interventions = [
                cv.close_schools(day_schools_closed='2020-08-01',
                                 start_day='2020-08-05',
                                 label='close_schools'),
                cv.reopen_schools(start_day=schedule,
                                  ili_prev=0,
                                  num_pos=None,
                                  trace=0.1,
                                  label='reopen_schools')
            ]

            sim['interventions'] = interventions

            sim.run()
            cum_infected_current = sim.results['cum_infections']
            num_school_days_lost = sim.school_info['school_days_lost']

            self.assertGreater(cum_infected_current, cum_infected_prev)
            self.assertGreater(num_school_days_lost_prev, num_school_days_lost)

            cum_infected_prev = cum_infected_current
            num_school_days_lost_prev = num_school_days_lost
Exemplo n.º 14
0
    def test_different_schedules(self):
        day_schools_open1 = {
            'pk': '2020-08-05',
            'es': '2020-09-05',
            'ms': '2020-09-05',
            'hs': '2020-09-05',
            'uv': '2020-09-05'
        }
        day_schools_open2 = {
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-09-05',
            'hs': '2020-09-05',
            'uv': '2020-09-05'
        }
        day_schools_open3 = {
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-09-05',
            'hs': '2020-09-05',
            'uv': '2020-09-05'
        }
        day_schools_open4 = {
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-09-05'
        }
        day_schools_open5 = {
            'pk': '2020-08-05',
            'es': '2020-08-05',
            'ms': '2020-08-05',
            'hs': '2020-08-05',
            'uv': '2020-08-05'
        }

        school_types = ['pk', 'es', 'ms', 'hs', 'uv']

        schedules = [
            day_schools_open1, day_schools_open2, day_schools_open3,
            day_schools_open4, day_schools_open5
        ]
        popfile = f'inputs/kc_synthpops_clustered_withstaff_10e3.ppl'
        SIM_PARAMS5 = pars = {
            'pop_size': 10e3,
            'pop_type': 'synthpops',
            'pop_infected': 100,
            'verbose': 1,
            'start_day': '2020-08-01',
            'end_day': '2020-09-10',
            'rand_seed': 0,
        }

        sim = cv.Sim(SIM_PARAMS5, popfile=popfile, load_pop=True)

        opened_initial = 10000  #arbitrarily large number
        for i, schedule in enumerate(schedules):
            reopen_schools = cv.reopen_schools(
                start_day=schedule,
                test=
                0.99,  # high test in order to make the validation less prone to "stochastic effects"
                ili_prev=0,
                num_pos=None,
                label='reopen_schools')

            interventions = [
                cv.close_schools(day_schools_closed='2020-08-01',
                                 label='close_schools'), reopen_schools
            ]

            sim['interventions'] = interventions
            sim.run()
            new_opened = reopen_schools.closed.count(
                False)  #ensuring that fewer and fewer schools closed
            self.assertGreater(new_opened, initial_opened)
            opened_initial = new_opened
Exemplo n.º 15
0
                                      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,
                                       layers='w',
                                       label='NPI_work'),
                        cv.close_schools(day_schools_closed=day_schools_close,
                                         start_day=day_schools_open[i],
                                         label='close_schools'),
                        cv.reopen_schools(start_day=intervention_start_day[i],
                                          test=test_prob[i],
                                          trace=trace_prob[i],
                                          ili_prev=0.002,
                                          schedule=schedule[i],
                                          num_pos=None,
                                          label='reopen_schools')
                    ]
                    if rel_trans:
                        sim['prognoses']['trans_ORs'][0] = 0.5
                    if beta_layer:
                        sim['beta_layer']['s'] = 3

                    if NPI[i] is not None:
Exemplo n.º 16
0
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 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