예제 #1
0
def test_plot_with_cvpeople(create_pop, do_show=False, do_save=False):
    """
    Test plotting method works on covasim.people.People object.

    Notes:
        With this pop type, you will need to supply more information to
        tell the method where to look for expected data.
    """
    sp.logger.info(
        "Test that the age comparison plotting method works on cv.people.People and plotting styles can be easily updated."
    )
    pop = create_pop
    popdict = pop.to_dict()
    cvpopdict = cv.make_synthpop(population=popdict,
                                 community_contacts=2)  # array based

    # Actually create the people
    people_pars = dict(
        pop_size=pars.n,
        beta_layer={k: 1.0
                    for k in 'hswcl'
                    },  # Since this is used to define hat layers exist
        beta=
        1.0,  # TODO: this is required for plotting (people.plot()), but shouldn't be (in covasim)
    )
    people = cv.People(people_pars,
                       strict=False,
                       uid=cvpopdict['uid'],
                       age=cvpopdict['age'],
                       sex=cvpopdict['sex'])
    kwargs = sc.objdict(sc.mergedicts(pars, pop.loc_pars))
    kwargs.datadir = sp.settings.datadir
    kwargs.figname = f"test_ages_{kwargs.location}_cvpeople"
    kwargs.do_show = do_show
    kwargs.do_save = do_save

    # modify some plotting styles
    kwargs.color_1 = '#9966cc'
    kwargs.color_2 = 'indigo'
    kwargs.markersize = 4.5
    fig, ax = sp.plot_ages(people, **kwargs)
    # fig, ax = sp.plot_ages(people)  # to plot without extra information

    assert isinstance(fig, mplt.figure.Figure), 'Check failed.'
    print('Check passed. Figure made.')

    return fig, ax, people
예제 #2
0
def test_basepeople():
    sc.heading('Testing base.py people and contacts...')

    # Create a small sim for later use
    sim = cv.Sim(pop_size=100, verbose=verbose)
    sim.initialize()

    # BasePeople methods
    ppl = sim.people
    ppl.get(['susceptible', 'infectious'])
    ppl.keys()
    ppl.person_keys()
    ppl.state_keys()
    ppl.date_keys()
    ppl.dur_keys()
    ppl.indices()
    ppl._resize_arrays(
        new_size=200
    )  # This only resizes the arrays, not actually create new people
    ppl._resize_arrays(new_size=100)  # Change back
    ppl.to_df()
    ppl.to_arr()
    ppl.person(50)
    people = ppl.to_people()
    ppl.from_people(people)
    ppl.make_edgelist([{'new_key': [0, 1, 2]}])
    ppl.brief()

    # Contacts methods
    contacts = ppl.contacts
    df = contacts['a'].to_df()
    ppl.remove_duplicates(df)
    with pytest.raises(sc.KeyNotFoundError):
        contacts['invalid_key']
    contacts.values()
    len(contacts)
    print(contacts)
    print(contacts['a'])

    # Layer methods
    hospitals_layer = cv.Layer()
    contacts.add_layer(hospitals=hospitals_layer)
    contacts.pop_layer('hospitals')
    df = hospitals_layer.to_df()
    hospitals_layer.from_df(df)

    # Generate an average of 10 contacts for 1000 people
    n = 10_000
    n_people = 1000
    p1 = np.random.randint(n_people, size=n)
    p2 = np.random.randint(n_people, size=n)
    beta = np.ones(n)
    layer = cv.Layer(p1=p1, p2=p2, beta=beta)

    # Convert one layer to another with extra columns
    index = np.arange(n)
    self_conn = p1 == p2
    layer2 = cv.Layer(**layer, index=index, self_conn=self_conn)
    assert len(layer2) == n
    assert len(layer2.keys()) == 5

    # Test dynamic layers, plotting, and stories
    pars = dict(pop_size=100,
                n_days=10,
                verbose=verbose,
                pop_type='hybrid',
                beta=0.02)
    s1 = cv.Sim(pars, dynam_layer={'c': 1})
    s1.run()
    s1.people.plot()
    for person in [0, 50]:
        s1.people.story(person)

    # Run without dynamic layers and assert that the results are different
    s2 = cv.Sim(pars, dynam_layer={'c': 0})
    s2.run()
    assert cv.diff_sims(s1, s2, output=True)

    # Create a bare People object
    ppl = cv.People(100)
    with pytest.raises(sc.KeyNotFoundError):  # Need additional parameters
        ppl.initialize()

    return
def make_population(pop_size,
                    rand_seed=1,
                    max_pop_seeds=None,
                    do_save=True,
                    popfile=None,
                    cohorting=True,
                    n_brackets=20,
                    community_contacts=20,
                    **kwargs):
    '''
    Generate the synthpops population.

    Args:
        pop_size (int): number of people in the model
        rand_seed (int): random seed to use for generating the population
        max_pop_seeds (int): if supplied, take the random seed as modulus of this to limit number of populations generated
        do_save (bool): whether to save the population
        popfile (str): if so, where to save it to
        cohorting (bool): whether to use cohorting
        n_brackets (int): whether to use 16- or 20-bracket age bins
        community_contacts (int): how many community contacts there are
        kwargs (dict): passed to sp.make_population()
    '''

    sp.set_nbrackets(
        n_brackets)  # Essential for getting the age distribution right

    pars = sc.objdict(
        n=pop_size,
        rand_seed=rand_seed,
        with_facilities=True,
        use_two_group_reduction=True,
        average_LTCF_degree=20,
        ltcf_staff_age_min=20,
        ltcf_staff_age_max=60,
        with_school_types=True,
        average_class_size=20,
        inter_grade_mixing=0.1,
        average_student_teacher_ratio=20,
        average_teacher_teacher_degree=3,
        teacher_age_min=25,
        teacher_age_max=75,
        with_non_teaching_staff=True,
        # if with_non_teaching_staff is False, but generate is True, then ,average_all_staff_ratio should be average_student_teacher_ratio or 0
        average_student_all_staff_ratio=11,
        average_additional_staff_degree=20,
        staff_age_min=20,
        staff_age_max=75,
    )

    pars.update(kwargs)  # Update any parameters

    # For reference re: school_types
    # school_mixing_type = 'random' means that students in the school have edges randomly chosen from other students, teachers, and non teaching staff across the school. Students, teachers, and non teaching staff are treated the same in terms of edge generation.
    # school_mixing_type = 'age_clustered' means that students in the school have edges mostly within their own age/grade, with teachers, and non teaching staff. Strict classrooms are not generated. Teachers have some additional edges with other teachers.
    # school_mixing_type = 'age_and_class_clustered' means that students are cohorted into classes of students of the same age/grade with at least 1 teacher, and then some have contact with non teaching staff. Teachers have some additional edges with other teachers.

    if cohorting:
        strategy = 'clustered'  # students in pre-k, elementary, and middle school are cohorted into strict classrooms
        pars.school_mixing_type = {
            'pk': 'age_and_class_clustered',
            'es': 'age_and_class_clustered',
            'ms': 'age_and_class_clustered',
            'hs': 'random',
            'uv': 'random'
        }
    else:
        strategy = 'normal'
        pars.school_mixing_type = {
            'pk': 'age_clustered',
            'es': 'age_clustered',
            'ms': 'age_clustered',
            'hs': 'random',
            'uv': 'random'
        }

    if popfile is None:
        popfile = os.path.join(
            'inputs', f'kc_{strategy}_{int(pars.n)}_seed{pars.rand_seed}.ppl')

    T = sc.tic()
    print('Making population...')

    # Make the population
    population = sp.make_population(**pars)

    # Convert to a popdict
    popdict = cv.make_synthpop(population=sc.dcp(population),
                               community_contacts=community_contacts)
    school_ids = [None] * int(pop_size)
    teacher_flag = [False] * int(pop_size)
    staff_flag = [False] * int(pop_size)
    student_flag = [False] * int(pop_size)
    school_types = {'pk': [], 'es': [], 'ms': [], 'hs': [], 'uv': []}
    school_type_by_person = [None] * int(pop_size)
    schools = dict()

    for uid, person in population.items():
        if person['scid'] is not None:
            school_ids[uid] = person['scid']
            school_type_by_person[uid] = person['sc_type']
            if person['scid'] not in school_types[person['sc_type']]:
                school_types[person['sc_type']].append(person['scid'])
            if person['scid'] in schools:
                schools[person['scid']].append(uid)
            else:
                schools[person['scid']] = [uid]
            if person['sc_teacher'] is not None:
                teacher_flag[uid] = True
            elif person['sc_student'] is not None:
                student_flag[uid] = True
            elif person['sc_staff'] is not None:
                staff_flag[uid] = True

    popdict['school_id'] = np.array(school_ids)
    popdict['schools'] = schools
    popdict['teacher_flag'] = teacher_flag
    popdict['student_flag'] = student_flag
    popdict['staff_flag'] = staff_flag
    popdict['school_types'] = school_types
    popdict['school_type_by_person'] = school_type_by_person

    assert sum(
        popdict['teacher_flag']
    ), 'Uh-oh, no teachers were found: as a school analysis this is treated as an error'
    assert sum(
        popdict['student_flag']
    ), 'Uh-oh, no students were found: as a school analysis this is treated as an error'

    # Actually create the people
    people_pars = dict(
        pop_size=pars.n,
        beta_layer={k: 1.0
                    for k in 'hswcl'
                    },  # Since this is used to define hat layers exist
        beta=
        1.0,  # TODO: this is required for plotting (people.plot()), but shouldn't be
    )
    people = cv.People(people_pars,
                       strict=False,
                       uid=popdict['uid'],
                       age=popdict['age'],
                       sex=popdict['sex'],
                       contacts=popdict['contacts'],
                       school_id=popdict['school_id'],
                       schools=popdict['schools'],
                       school_types=popdict['school_types'],
                       student_flag=popdict['student_flag'],
                       teacher_flag=popdict['teacher_flag'],
                       staff_flag=popdict['staff_flag'],
                       school_type_by_person=popdict['school_type_by_person'])

    if do_save:
        print(f'Saving to "{popfile}"...')
        sc.saveobj(popfile, people)

    sc.toc(T)

    print('Done')
    return people
예제 #4
0
import sciris as sc
import covasim as cv

sc.tic()

people = cv.People(pop_size=2000)

sc.toc(label='default')

plist = people.to_people()

sc.toc(label='to people')

ppl2 = cv.People()
ppl2.from_people(plist)

sc.toc(label='from people')

ppl3 = people + ppl2

sim = cv.Sim(pop_type='random', pop_size=20000)
cv.make_people(sim)
ppl4 = sim.people

sc.toc(label='as sim')

df = ppl4.to_df()
arr = ppl4.to_arr()

sc.toc(label='to df/arr')