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
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
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')