synthpops.schools module

This module generates school contacts by class and grade in flexible ways. Contacts can be clustered into classes and also mixed across the grade and across the school.

H. Guclu et. al (2016) shows that mixing across grades is low for public schools in elementary and middle schools. Mixing across grades is however higher in high schools.

Functions in this module are flexible to allow users to specify the inter-grade mixing (for ‘age_clustered’ school_mixing_type), and to choose whether contacts are clustered within a grade. Clustering contacts across different grades is not supported because there is no data to suggest that this happens commonly.

synthpops.schools.get_uids_in_school(datadir, n, location, state_location, country_location, age_by_uid_dic=None, homes_by_uids=None, folder_name=None, use_default=False)

Identify who in the population is attending school based on enrollment rates by age.

Parameters
  • datadir (string) – The file path to the data directory.

  • n (int) – The number of people in the population.

  • location (string) – The name of the location.

  • state_location (string) – The name of the state the location is in.

  • country_location (string) – The name of the country the location is in.

  • age_by_uid_dic (dict) – A dictionary mapping ID to age for all individuals in the population.

  • homes_by_uids (list) – A list of lists where each sublist is a household and the IDs of the household members.

  • folder_name (string) – The name of the folder the location is in, e.g. ‘contact_networks’

  • use_default (bool) – If True, try to first use the other parameters to find data specific to the location under study; otherwise, return default data drawing from default_location, default_state, default_country.

Returns

A dictionary of students in schools mapping their ID to their age, a dictionary of students in school mapping age to the list of IDs with that age, and a dictionary mapping age to the number of students with that age.

synthpops.schools.send_students_to_school_with_school_types(school_size_distr_by_type, school_size_brackets, uids_in_school, uids_in_school_by_age, ages_in_school_count, school_types_distr_by_age, school_type_age_ranges, verbose=False)

A method to send students to school together. This method uses the dictionaries school_types_distr_by_age, school_type_age_ranges, and school_size_distr_by_type to first determine the type of school based on the age of a sampled reference student. Then the school type is used to determine the age range of the school. After that, the size of the school is then sampled conditionally on the school type and then the rest of the students are chosen from the lists of students available in the dictionary uids_in_school_by_age. This method is not perfect and requires a strict definition of school type by age. For now, it is not able to model mixed school types such as schools with Kindergarten through Grade 8 (K-8), or Kindergarten through Grade 12. These mixed types of schools may be common in some settings and this feature may be added later.

Parameters
  • school_size_distr_by_type (dict) – A dictionary of school size distributions binned by size groups or brackets for each school type.

  • school_size_brackets (dict) – A dictionary of school size brackets.

  • uids_in_school (dict) – A dictionary of students in school mapping ID to age.

  • uids_in_school_by_age (dict) – A dictionary of students in school mapping age to the list of IDs with that age.

  • ages_in_school_count (dict) – A dictionary mapping age to the number of students with that age.

  • school_types_distr_by_age (dict) – A dictionary of the school type for each age.

  • school_type_age_ranges (dict) – A dictionary of the age range for each school type.

  • verbose (bool) – If True, print statements about the generated schools as they’re being generated.

Returns

Two lists of lists and third flat list, the first where each sublist is the ages of students in the same school, and the second is the same list but with the IDs of each student in place of their age. The third is a list of the school types for each school, where each school has a single string to represent it’s school type.

synthpops.schools.add_contacts_from_edgelist(popdict, edgelist, setting)

Add contacts to popdict from edges in an edgelist. Note that this simply adds to the contacts already in the layer and does not overwrite the contacts.

Parameters
  • popdict (dict) – dict of people

  • edgelist (list) – list of edges

  • setting (str) – social setting layer

Returns

Updated popdict.

synthpops.schools.add_contacts_from_group(popdict, group, setting)

Add contacts to popdict from fully connected group. Note that this simply adds to the contacts already in the layer and does not overwrite the contacts.

Parameters
  • popdict (dict) – dict of people

  • group (list) – list of people in group

  • setting (str) – social setting layer

Returns

Updated popdict.

synthpops.schools.generate_random_contacts_for_additional_school_members(school_uids, additional_school_member_uids, average_additional_school_members_degree=20)

Generate random contacts for additional school members. This might be people like non teaching staff such as principals, administrative staff, cleaning staff, or school nurses.

Parameters
  • school_uids (list) – list of uids of individuals already in the school

  • additional_school_member_uids (list) – list of uids of the additional school member who do not have contacts yet or for whom more contacts are needed

  • average_additional_school_members_degree (float) – average degree for the additional school members

Returns

List of edges for the additional school members in school.

synthpops.schools.generate_random_classes_by_grade_in_school(syn_school_uids, syn_school_ages, age_by_uid_dic, grade_age_mapping, age_grade_mapping, average_class_size=20, inter_grade_mixing=0.1, verbose=False)

Generate edges for contacts mostly within the same age/grade. Edges are randomly distributed so that clustering is roughly average_class_size/size of the grade. Inter grade mixing is done by rewiring edges, specifically swapping endpoints of pairs of randomly sampled edges.

Parameters
  • syn_school_uids (list) – list of uids of students in the school

  • syn_school_ages (list) – list of the ages of the students in the school

  • age_by_uid_dic (dict) – dict mapping uid to age

  • grade_age_mapping (dict) – dict mapping grade to an age

  • age_grade_mapping (dict) – dict mapping age to a grade

  • average_class_size (float) – average class size

  • inter_grade_mixing (float) – percent of edges that rewired to create edges across grades in schools when school_mixing_type is ‘age_clustered’

  • verbose (bool) – print statements throughout

Returns

List of edges between students in school.

synthpops.schools.generate_clustered_classes_by_grade_in_school(syn_school_uids, syn_school_ages, age_by_uid_dic, grade_age_mapping, age_grade_mapping, average_class_size=20, return_edges=False, verbose=False)

Generate edges for contacts mostly within the same age/grade. Edges are randomly distributed so that clustering is roughly average_class_size/size of the grade.

Parameters
  • syn_school_uids (list) – list of uids of students in the school

  • syn_school_ages (list) – list of the ages of the students in the school

  • age_by_uid_dic (dict) – dict mapping uid to age

  • grade_age_mapping (dict) – dict mapping grade to an age

  • age_grade_mapping (dict) – dict mapping age to a grade

  • average_class_size (float) – average class size

  • return_edges (bool) – If True, return edges, else return two groups of contacts - students and teachers for each class

  • verbose (bool) – print statements throughout

Returns

List of edges between students in school or groups of contacts.

synthpops.schools.generate_edges_between_teachers(teachers, average_teacher_teacher_degree)

Generate edges between teachers.

Parameters
  • teachers (list) – a list of teachers

  • average_teacher_teacher_degree (int) – average number of contacts with other teachers

Returns

List of edges between teachers.

synthpops.schools.generate_edges_for_teachers_in_random_classes(syn_school_uids, syn_school_ages, teachers, age_by_uid_dic, average_student_teacher_ratio=20, average_teacher_teacher_degree=4, verbose=False)

Generate edges for teachers, including to both students and other teachers at the same school. Well mixed contacts within the same age/grade, some cross grade mixing. Teachers are clustered by grade mostly.

Parameters
  • syn_school_uids (list) – list of uids of students in the school

  • syn_school_ages (list) – list of the ages of the students in the school

  • teachers (list) – list of teachers in the school

  • age_by_uid_dic (dict) – dict mapping uid to age

  • grade_age_mapping (dict) – dict mapping grade to an age

  • age_grade_mapping (dict) – dict mapping age to a grade

  • average_student_teacher_ratio (float) – average number of students per teacher

  • average_teacher_teacher_degree (float) – average number of contacts with other teachers

  • verbose (bool) – print statements throughout

Returns

List of edges connected to teachers.

synthpops.schools.generate_edges_for_teachers_in_clustered_classes(groups, teachers, average_student_teacher_ratio=20, average_teacher_teacher_degree=4, return_edges=False, verbose=False)

Generate edges for teachers, including to both students and other teachers at the same school. Students and teachers are clustered into disjoint classes.

Parameters
  • groups (list) – list of lists of students, clustered into groups mostly by grade

  • teachers (list) – list of teachers in the school

  • average_student_teacher_ratio (float) – average number of students per teacher

  • average_teacher_teacher_degree (float) – average number of contacts with other teachers

  • return_edges (bool) – If True, return edges, else return two groups of contacts - students and teachers for each class

  • verbose (bool) – print statements throughout

Returns

List of edges connected to teachers.

synthpops.schools.generate_random_contacts_across_school(all_school_uids, average_class_size)

Generate edges for contacts in a school where everyone mixes randomly. Assuming class and thus class size determines effective contacts.

Parameters
  • all_school_uids (list) – list of uids of individuals in the school

  • average_class_size (int) – average class size or number of contacts in school

  • verbose (bool) – If True, print some edges

Returns

List of edges between individuals in school.

synthpops.schools.add_school_edges(popdict, syn_school_uids, syn_school_ages, teachers, non_teaching_staff, age_by_uid_dic, grade_age_mapping, age_grade_mapping, average_class_size=20, inter_grade_mixing=0.1, average_student_teacher_ratio=20, average_teacher_teacher_degree=3, average_additional_staff_degree=20, school_mixing_type='random', verbose=False)

Generate edges for teachers, including to both students and other teachers at the same school. When school_mixing_type is ‘age_clustered’ then inter_grade_mixing will rewire a fraction of the edges between students in the same age or grade to be edges with any other student in the school. When school_mixing_type is ‘random’ or ‘age_and_class_clustered’, inter_grade_mixing has no effect.

Parameters
  • popdict (dict) – dictionary of people

  • syn_school_uids (list) – list of uids of students in the school

  • syn_school_ages (list) – list of the ages of the students in the school

  • teachers (list) – list of teachers in the school

  • non_teaching_staff (list) – list of non teaching staff in the school

  • age_by_uid_dic (dict) – dict mapping uid to age

  • grade_age_mapping (dict) – dict mapping grade to an age

  • age_grade_mapping (dict) – dict mapping age to a grade

  • average_class_size (float) – average class size

  • inter_grade_mixing (float) – percent of edges that rewired to create edges across grades in schools when school_mixing_type is ‘age_clustered’

  • average_student_teacher_ratio (float) – average number of students per teacher

  • average_teacher_teacher_degree (float) – average number of contacts with other teachers

  • average_additional_staff_degree (float) – The average number of contacts per additional non teaching staff in schools.

  • school_mixing_type (str) – ‘random’ for well mixed schools, ‘age_clustered’ for well mixed within the same grade and some intermixing with other grades, ‘age_and_class_clustered’ for disjoint classes in a school by age or grade

  • verbose (bool) – print statements throughout

Returns

Updated popdict.

synthpops.schools.get_school_types_distr_by_age(school_type_age_ranges)

Return probabilities of school type for each age. For now assuming no overlapping of grades between school types.

Returns

A dictionary of default probabilities for the school type likely for each age.

synthpops.schools.get_school_types_by_age_single(school_types_distr_by_age)

Return school type by age by assigning the school type with the highest probability.

Returns

A dictionary of default school type by age.

synthpops.schools.get_school_type_data(datadir, location, state_location, country_location, use_default=False)

Get location specific distributions on school type data if it’s available for all the distributions of interest, otherwise return default data if use_default.

Parameters
  • datadir (string) – file path to the data directory

  • location (string) – name of the location

  • state_location (string) – name of the state the location is in

  • country_location (string) – name of the country the location is in

  • use_default (bool) – if True, try to first use the other parameters to find data specific to the location under study, otherwise returns default data drawing from Seattle, Washington.

Returns

3 dictionaries necessary to generate schools by the type of school (i.e. elementary, middle, high school, etc.).

synthpops.schools.assign_teachers_to_schools(syn_schools, syn_school_uids, employment_rates, workers_by_age_to_assign_count, potential_worker_uids, potential_worker_uids_by_age, potential_worker_ages_left_count, average_student_teacher_ratio=20, teacher_age_min=25, teacher_age_max=75, verbose=False)

Assign teachers to each school according to the average student-teacher ratio.

Parameters
  • syn_schools (list) – list of lists where each sublist is a school with the ages of the students within

  • syn_school_uids (list) – list of lists where each sublist is a school with the ids of the students within

  • employment_rates (dict) – employment rates by age

  • workers_by_age_to_assign_count (dict) – dictionary of the count of workers left to assign by age

  • potential_worker_uids (dict) – dictionary of potential workers mapping their id to their age

  • potential_worker_uids_by_age (dict) – dictionary mapping age to the list of worker ids with that age

  • potential_worker_ages_left_count (dict) – dictionary of the count of potential workers left that can be assigned by age

  • average_student_teacher_ratio (float) – The average number of students per teacher.

  • teacher_age_min (int) – The minimum age for teachers.

  • teacher_age_max (int) – The maximum age for teachers.

  • verbose (bool) – If True, print statements about the generated schools as teachers are being added to each school.

Returns

List of lists of schools with the ages of individuals in each, lists of lists of schools with the ids of individuals in each, dictionary of potential workers mapping id to their age, dictionary mapping age to the list of potential workers of that age, dictionary with the count of workers left to assign for each age after teachers have been assigned.

synthpops.schools.assign_additional_staff_to_schools(syn_school_uids, syn_teacher_uids, workers_by_age_to_assign_count, potential_worker_uids, potential_worker_uids_by_age, potential_worker_ages_left_count, average_student_teacher_ratio=20, average_student_all_staff_ratio=15, staff_age_min=20, staff_age_max=75, with_non_teaching_staff=False, verbose=True)

Assign additional staff to each school according to the average student to all staff ratio.

Parameters
  • syn_school_uids (list) – list of lists where each sublist is a school with the ids of the students within

  • syn_teacher_uids (list) – list of lists where each sublist is a school with the ids of the teachers within

  • workers_by_age_to_assign_count (dict) – dictionary of the count of workers left to assign by age

  • potential_worker_uids (dict) – dictionary of potential workers mapping their id to their age

  • potential_worker_uids_by_age (dict) – dictionary mapping age to the list of worker ids with that age

  • potential_worker_ages_left_count (dict) – dictionary of the count of potential workers left that can be assigned by age

  • average_student_teacher_ratio (float) – The average number of students per teacher.

  • average_student_all_staff_ratio (float) – The average number of students per staff members at school (including both teachers and non teachers).

  • staff_age_min (int) – The minimum age for non teaching staff.

  • staff_age_max (int) – The maximum age for non teaching staff.

  • with_non_teaching_staff (bool) – If True, includes non teaching staff.

  • verbose (bool) – If True, print statements about the generated schools as teachers are being added to each school.

Returns

List of lists of schools with the ids of non teaching staff for each school, dictionary of potential workers mapping id to their age, dictionary mapping age to the list of potential workers of that age, dictionary with the count of workers left to assign for each age after teachers have been assigned.

synthpops.schools.add_random_contacts_from_graph(G, expected_average_degree)

Add additional edges at random to achieve the expected or desired average degree.

Parameters
  • G (networkx Graph) – networkx Graph object

  • expected_average_degree (int) – expected or desired average degree

Returns

Updated networkx Graph object with additional edges added at random.

synthpops.schools.generate_school_sizes(school_size_distr_by_bracket, school_size_brackets, uids_in_school)

Given a number of students in school, generate a list of school sizes to place everyone in a school.

Parameters
  • school_size_distr_by_bracket (dict) – The distribution of binned school sizes.

  • school_size_brackets (dict) – A dictionary of school size brackets.

  • uids_in_school (dict) – A dictionary of students in school mapping ID to age.

Returns

A list of school sizes whose sum is the length of uids_in_school.

synthpops.schools.send_students_to_school(school_sizes, uids_in_school, uids_in_school_by_age, ages_in_school_count, age_brackets, age_by_brackets_dic, contact_matrix_dic, verbose=False)

A method to send students to school together. Using the matrices to construct schools is not a perfect method so some things are more forced than the matrix method alone would create. This method models schools using matrices and so it does not create explicit school types.

Parameters
  • school_sizes (list) – A list of school sizes.

  • uids_in_school (dict) – A dictionary of students in school mapping ID to age.

  • uids_in_school_by_age (dict) – A dictionary of students in school mapping age to the list of IDs with that age.

  • ages_in_school_count (dict) – A dictionary mapping age to the number of students with that age.

  • age_brackets (dict) – A dictionary mapping age bracket keys to age bracket range.

  • age_by_brackets_dic (dict) – A dictionary mapping age to the age bracket range it falls within.

  • contact_matrix_dic (dict) – A dictionary of age specific contact matrix for different physical contact settings.

  • verbose (bool) – If True, print statements about the generated schools as they’re being generated.

Returns

Two lists of lists and third flat list, the first where each sublist is the ages of students in the same school, and the second is the same list but with the IDs of each student in place of their age. The third is a list of the school types for each school, where each school has a single string to represent it’s school type.