def test__decide_person_goes_to_social_venue(social_venue_distributor): dt = 0.01 person = Person(age=40, sex="m") estimated_day_to_go_to_the_pub = 1 / 0.5 estimated_day_to_go_to_the_pub_weekend = 1 / ( 2 * 0.5) rest = get_days_until_pub(person, dt, False, social_venue_distributor) assert np.isclose(rest, estimated_day_to_go_to_the_pub, atol=0, rtol=0.2) rest = get_days_until_pub(person, dt, True, social_venue_distributor) assert np.isclose(rest, estimated_day_to_go_to_the_pub_weekend, atol=0, rtol=0.2) person = Person(age=68, sex="m") estimated_day_to_go_to_the_pub = 1 / 0.2 estimated_day_to_go_to_the_pub_weekend = 1 / ( 2 * 0.2) rest = get_days_until_pub(person, dt, False, social_venue_distributor) assert np.isclose(rest, estimated_day_to_go_to_the_pub, atol=0, rtol=0.1) rest = get_days_until_pub(person, dt, True, social_venue_distributor) assert np.isclose(rest, estimated_day_to_go_to_the_pub_weekend, atol=0, rtol=0.1) person = Person(age=20, sex="f") estimated_day_to_go_to_the_pub = 1 / 0.1 estimated_day_to_go_to_the_pub_weekend = 1 / ( 2 * 0.1) rest = get_days_until_pub(person, dt, False, social_venue_distributor) assert np.isclose(rest, estimated_day_to_go_to_the_pub, atol=0, rtol=0.1) rest = get_days_until_pub(person, dt, True, social_venue_distributor) assert np.isclose(rest, estimated_day_to_go_to_the_pub_weekend, atol=0, rtol=0.1)
def test__infectivity_profile(): hi = HealthIndexGenerator.from_file() iss = InfectionSelectorSetter(infectivity_profile="xnexp") infection_selector = iss.make_infection_selector(hi) assert infection_selector.health_index_generator == hi assert isinstance(infection_selector, InfectionSelector) person = Person.from_attributes() infection_selector.infect_person_at_time(person, 0) assert person.infection assert isinstance(person.infection.transmission, TransmissionXNExp) iss = InfectionSelectorSetter(infectivity_profile="nature") infection_selector = iss.make_infection_selector(hi) person = Person.from_attributes() infection_selector.infect_person_at_time(person, 0) assert isinstance(person.infection.transmission, TransmissionGamma) iss = InfectionSelectorSetter(infectivity_profile="correction_nature") infection_selector = iss.make_infection_selector(hi) person = Person.from_attributes() infection_selector.infect_person_at_time(person, 0) assert isinstance(person.infection.transmission, TransmissionGamma) iss = InfectionSelectorSetter(infectivity_profile="constant") infection_selector = iss.make_infection_selector(hi) person = Person.from_attributes() infection_selector.infect_person_at_time(person, 0) assert isinstance(person.infection.transmission, TransmissionConstant)
def test__carehome_for_geography(world, carehome_distributor): # add two workers atificially world.care_homes = CareHomes.for_areas(world.areas) p1 = Person.from_attributes() p1.sector = "Q" p2 = Person.from_attributes() p2.sector = "Q" world.super_areas[0].workers = [p1, p2] carehome_distributor.populate_care_home_in_areas(world.areas) care_home = world.care_homes[0] assert len(care_home.residents) == 24 assert len(care_home.workers) == 2
def __init__(self, module_config): self.care_home = None self.people = [] # residents for age in range(50, 101): for _ in range(0, 2): man = Person.from_attributes(sex='m', age=age) self.people.append(man) woman = Person.from_attributes(sex='f', age=age) self.people.append(woman) # workers/carers self.super_area = MockSuperArea(module_config)
def test__household_mates(): house = Household() person1 = Person.from_attributes() house.add(person1, subgroup_type=house.SubgroupType.kids) assert house.residents[0] == person1 person2 = Person.from_attributes() person3 = Person.from_attributes() house.add(person2) house.add(person3) assert person1 in person1.housemates assert person2 in person1.housemates assert person3 in person1.housemates
def test__smaller_than_one(): index_list = HealthIndexGenerator.from_file() increasing_count = 0 for i in range(len(index_list.prob_lists[0])): index_m = index_list(Person.from_attributes(age=i, sex="m")) index_w = index_list(Person.from_attributes(age=i, sex="f")) bool_m = np.sum(np.round(index_m, 7) <= 1) bool_w = np.sum(np.round(index_w, 7) <= 1) if bool_m + bool_w == 14: increasing_count += 1 else: increasing_count == increasing_count assert increasing_count == 121
def test__growing_index(): index_list = HealthIndexGenerator.from_file() increasing_count = 0 for i in range(len(index_list.prob_lists[0])): index_m = index_list(Person.from_attributes(age=i, sex="m")) index_w = index_list(Person.from_attributes(age=i, sex="f")) if sum(np.sort(index_w) == index_w) != len(index_w): increasing_count += 0 if sum(np.sort(index_m) == index_m) != len(index_m): increasing_count += 0 assert increasing_count == 0
def get_health_index_by_age_and_sex(self): health_dict = {"m": defaultdict(int), "f": defaultdict(int)} for sex in ("m", "f"): for age in np.arange(100): health_dict[sex][age] = self.health_index( Person(sex=sex, age=age)) return health_dict
def test__simple_age_profile_test(selector, ): n_people = 10000 ages = np.random.randint(low=0, high=100, size=n_people) people = [Person.from_attributes(age=ages[n]) for n in range(n_people)] seed = InfectionSeed(super_areas=None, selector=selector, age_profile={ '0-9': 0.3, '10-39': 0.5, '40-100': 0.2 }) choice = seed.select_from_susceptible(people, 1000, age_profile=seed.age_profile) ages_infected = np.array([person.age for person in people])[choice] count = Counter(ages_infected) count_0_9 = sum([ count_value for count_key, count_value in count.items() if count_key < 10 ]) assert count_0_9 / len(ages_infected) == pytest.approx(0.3, 0.05) count_10_39 = sum([ count_value for count_key, count_value in count.items() if count_key >= 10 and count_key < 40 ]) assert count_10_39 / len(ages_infected) == pytest.approx(0.5, 0.05) count_40_100 = sum([ count_value for count_key, count_value in count.items() if count_key > 40 ]) assert count_40_100 / len(ages_infected) == pytest.approx(0.2, 0.05)
def test__generate_leisure_from_world(): geography = Geography.from_file({"super_area": ["E02002135"]}) world = generate_world_from_geography(geography, include_households=True, include_commute=False) world.pubs = Pubs.for_geography(geography) world.cinemas = Cinemas.for_geography(geography) world.groceries = Groceries.for_geography(geography) person = Person.from_attributes(sex="m", age=27) household = Household() household.area = world.areas[0] household.add(person) person.area = geography.areas[0] leisure = generate_leisure_for_world( list_of_leisure_groups=["pubs", "cinemas", "groceries"], world=world) leisure.distribute_social_venues_to_households([household]) leisure.generate_leisure_probabilities_for_timestep(0.1, False) n_pubs = 0 n_cinemas = 0 n_groceries = 0 for _ in range(0, 1000): subgroup = leisure.get_subgroup_for_person_and_housemates(person) if subgroup is not None: if subgroup.group.spec == "pub": n_pubs += 1 elif subgroup.group.spec == "cinema": n_cinemas += 1 elif subgroup.group.spec == "grocery": n_groceries += 1 assert 0 < n_pubs < 100 assert 0 < n_cinemas < 100 assert 0 < n_groceries < 107
def test__isolation_compliance(selector): isolation = Isolation( testing_mean_time=3, testing_std_time=1, n_quarantine_days=7, compliance=0.5 ) go_isolation = set() for _ in range(1000): person = Person.from_attributes() infect_person(person, selector, symptom_tag="mild") isolation_units = IsolationUnits([IsolationUnit(area=None)]) for day in range(0, 100): isolation.apply( person, medical_facilities=[isolation_units], days_from_start=day ) if 0 < day < person.infection.time_of_testing: assert person not in isolation_units[0].people elif ( person.infection.time_of_testing < day < person.infection.time_of_testing + isolation.n_quarantine_days ): if person in isolation_units[0].people: go_isolation.add(person.id) else: assert person not in isolation_units[0].people isolation_units[0].clear() assert np.isclose(len(go_isolation), 500, rtol=0.1)
def _assign_work_location(self, i: int, person: Person, wf_area_df: pd.DataFrame): """ Employ people in any given sector. """ if person.sex == "f": work_location = wf_area_df.index.values[self.work_msoa_woman_rnd[i]] else: work_location = wf_area_df.index.values[self.work_msoa_man_rnd[i]] super_area = [ super_area for super_area in self.super_areas if super_area.name == work_location ] if super_area: super_area = super_area[0] super_area.add_worker(person) elif work_location in list(self.non_geographical_work_location.keys()): if self.non_geographical_work_location[work_location] == "home": person.work_super_area = "home" elif self.non_geographical_work_location[work_location] == "bind": self._select_rnd_superarea(person) else: raise ValueError else: self._select_rnd_superarea(person)
def _assign_work_location(self, i: int, person: Person, wf_area_df: pd.DataFrame): """ Employ people in any given sector. """ if person.sex == "f": work_location = wf_area_df.index.values[ self.work_msoa_woman_rnd[i]] else: work_location = wf_area_df.index.values[self.work_msoa_man_rnd[i]] try: super_area = self.super_areas.members_by_name[work_location] super_area.add_worker(person) except KeyError: if work_location in list(self.non_geographical_work_location): if self.non_geographical_work_location[ work_location] == "home": person.work_super_area = None elif self.non_geographical_work_location[ work_location] == "bind": self._select_rnd_superarea(person) else: raise KeyError( f"Work location {work_location} not found in world's geogeraphy" ) else: self._select_rnd_superarea(person)
def make_super_area(): super_area = SuperArea() for i in range(3): super_area.companies.append(Company(sector=i, n_workers_max=i)) person = Person.from_attributes() person.sector = i super_area.workers.append(person) return super_area
def test__time_of_testing(selector, isolation): person = Person.from_attributes(sex="m", age=27) infect_person(person, selector, symptom_tag="mild") testing_times = [] for _ in range(1000): testing_times.append(isolation._generate_time_of_testing(person)) assert np.isclose(np.mean(testing_times), 3 + 5.3, atol=0.1) assert np.isclose(np.std(testing_times), 1, atol=0.1)
def test__comoposition_play_groups(): kid_young = Person.from_attributes(age=3) kid_middle = Person.from_attributes(age=8) kid_old = Person.from_attributes(age=13) kid_very_old = Person.from_attributes(age=16) play_group = PlayGroup() subgroup = play_group.get_leisure_subgroup(person=kid_young) assert subgroup.subgroup_type == 0 subgroup = play_group.get_leisure_subgroup(person=kid_middle) assert subgroup.subgroup_type == 1 subgroup = play_group.get_leisure_subgroup(person=kid_old) assert subgroup.subgroup_type == 2 subgroup = play_group.get_leisure_subgroup(person=kid_very_old) assert subgroup.subgroup_type == 2 not_kid = Person.from_attributes(age=50) subgroup = play_group.get_leisure_subgroup(person=not_kid) assert subgroup is None
def get_oc(): person = Person.from_attributes(age=90, sex="m") area = Area(name='E00003255', super_area='E02000134', coordinates=(0, 0)) area.add(person) super_area = SuperArea(areas=[area], coordinates=(1, 1), name='E02000134') super_areas = SuperAreas([super_area]) health_index = HealthIndexGenerator.from_file() return Observed2Cases.from_file(super_areas=super_areas, health_index=health_index)
def __init__(self, module_config): self.workers = [] n_workers = 5 # workers/carers for _ in range(n_workers): carer = Person.from_attributes() carer.sector = list(module_config["sector"].keys())[0] carer.sub_sector = None self.workers.append(carer)
def test__person_drags_household(leisure): person1 = Person.from_attributes(sex="m", age=26) person2 = Person.from_attributes(sex="f", age=26) person3 = Person.from_attributes(sex="m", age=27) household = Household() household.add(person1) household.add(person2) household.add(person3) person2.busy = False person3.busy = False social_venue = leisure.leisure_distributors["cinemas"].social_venues[0] social_venue.add(person1) leisure.send_household_with_person_if_necessary( person1, person1.leisure, 1.0, ) for person in [person1, person2, person3]: assert person.subgroups.leisure == social_venue.subgroups[0]
def test__allocate_patient_release_patient(hospitals, health_info, selector): dummy_person = Person().from_attributes(age=80, sex='m') selector.infect_person_at_time(dummy_person, 0.0) dummy_person.area = MockArea(hospitals.members[-1].coordinates) assert dummy_person.medical_facility is None dummy_person.health_information.infection.symptoms.tag = getattr( SymptomTag, health_info) hospitals.allocate_patient(dummy_person) if health_info == "hospitalised": assert ( dummy_person in hospitals.members[-1][Hospital.SubgroupType.patients].people) elif health_info == "intensive_care": assert (dummy_person in hospitals.members[-1][ Hospital.SubgroupType.icu_patients].people) selected_hospital = dummy_person.medical_facility assert dummy_person.medical_facility is not None dummy_person.medical_facility.group.release_as_patient(dummy_person) assert dummy_person.medical_facility is None
def make_dummy_world(): teacher = Person.from_attributes(age=100, sex="f") pupil_shift_1 = Person.from_attributes(age=12, sex="f") pupil_shift_2 = Person.from_attributes(age=5, sex="m") pupil_shift_3 = Person.from_attributes(age=11, sex="f") learning_center = LearningCenter(coordinates=None, n_pupils_max=None) household = Household() household.add(person=teacher) household.add(person=pupil_shift_1) household.add(person=pupil_shift_2) household.add(person=pupil_shift_3) learning_center.add(person=teacher, shift=0, subgroup_type=learning_center.SubgroupType.teachers) learning_center.add(person=teacher, shift=1, subgroup_type=learning_center.SubgroupType.teachers) learning_center.add(person=teacher, shift=2, subgroup_type=learning_center.SubgroupType.teachers) learning_center.add(person=pupil_shift_1, shift=0) learning_center.add(person=pupil_shift_2, shift=1) learning_center.add(person=pupil_shift_3, shift=2) world = World() world.learning_centers = LearningCenters([learning_center], learning_centers_tree=False, n_shifts=3) world.households = Households([household]) world.people = Population( [teacher, pupil_shift_1, pupil_shift_2, pupil_shift_3]) for person in world.people.members: person.busy = False learning_center.clear() household.clear() return ( teacher, pupil_shift_1, pupil_shift_2, pupil_shift_3, learning_center, household, world, )
def test__mean_multiplier_reference(): comorbidity_multipliers = {"guapo": 0.8, "feo": 1.2, "no_condition": 1.0} prevalence_reference_population = { "feo": { "f": { "0-10": 0.2, "10-100": 0.4 }, "m": { "0-10": 0.6, "10-100": 0.5 }, }, "guapo": { "f": { "0-10": 0.1, "10-100": 0.1 }, "m": { "0-10": 0.05, "10-100": 0.2 }, }, "no_condition": { "f": { "0-10": 0.7, "10-100": 0.5 }, "m": { "0-10": 0.35, "10-100": 0.3 }, }, } health_index = HealthIndexGenerator.from_file( comorbidity_multipliers=comorbidity_multipliers, prevalence_reference_population=prevalence_reference_population, ) dummy = Person.from_attributes( sex="f", age=40, ) mean_multiplier_uk = ( prevalence_reference_population["feo"]["f"]["10-100"] * comorbidity_multipliers["feo"] + prevalence_reference_population["guapo"]["f"]["10-100"] * comorbidity_multipliers["guapo"] + prevalence_reference_population["no_condition"]["f"]["10-100"] * comorbidity_multipliers["no_condition"]) assert (health_index.get_multiplier_from_reference_prevalence( dummy.age, dummy.sex) == mean_multiplier_uk)
def _assign_work_sector(self, i: int, person: Person): """ Employ people in a given SuperArea. """ if person.sex == "f": sector_idx = self.sector_female_rnd[i] else: sector_idx = self.sector_male_rnd[i] person.sector = self.sector_dict[sector_idx] if person.sector in list(self.sub_sector_ratio.keys()): self._assign_sub_sector(person)
def test__apply_hospitalisation_correction(): health_index = HealthIndexGenerator.from_file( adjust_hospitalisation_adults=False) adjusted_health_index = HealthIndexGenerator.from_file( adjust_hospitalisation_adults=True) dummy = Person.from_attributes( sex="f", age=65, ) hi = health_index(dummy) adjusted_hi = adjusted_health_index(dummy) np.testing.assert_allclose(adjusted_hi, hi) dummy = Person.from_attributes( sex="f", age=18, ) hi = np.diff(health_index(dummy), prepend=0., append=1.) adjusted_hi = np.diff(adjusted_health_index(dummy), prepend=0., append=1.) assert sum(adjusted_hi) == 1. assert adjusted_hi[3] == pytest.approx(hi[3] / 3., rel=0.01) assert adjusted_hi[4] == pytest.approx(hi[4] / 3., rel=0.01) assert adjusted_hi[5] == hi[5] assert adjusted_hi[6] == pytest.approx(hi[6], rel=0.01) assert adjusted_hi[7] == pytest.approx(hi[7], rel=0.01) dummy = Person.from_attributes( sex="f", age=40, ) hi = np.diff(health_index(dummy), prepend=0., append=1.) adjusted_hi = np.diff(adjusted_health_index(dummy), prepend=0., append=1.) assert sum(adjusted_hi) == 1. assert adjusted_hi[3] == pytest.approx(hi[3] * 0.65, rel=0.01) assert adjusted_hi[4] == pytest.approx(hi[4] * 0.65, rel=0.01) assert adjusted_hi[5] == hi[5] assert adjusted_hi[6] == pytest.approx(hi[6], rel=0.01) assert adjusted_hi[7] == pytest.approx(hi[7], rel=0.01)
def create_school(n_students, n_teachers): school = School( n_pupils_max=n_students, age_min=6, age_max=6, coordinates=(1.0, 1.0), sector="primary_secondary", ) people = [] # create students for _ in range(n_students): person = Person.from_attributes(sex="f", age=6) school.add(person) people.append(person) for _ in range(n_teachers): person = Person.from_attributes(sex="m", age=40) school.add(person, subgroup_type=school.SubgroupType.teachers) people.append(person) assert len(people) == n_students + n_teachers assert len(school.people) == n_students + n_teachers assert len(school.subgroups[1].people) == n_students assert len(school.subgroups[0].people) == n_teachers return people, school
def test__play_group_per_area(n_people): people = [ Person.from_attributes(age=age) for age in np.random.randint(low=3, high=16, size=n_people) ] dummy_area = CampArea(name="dummy", super_area=None, coordinates=(12.0, 15.0)) areas = [dummy_area] dummy_area.people = people play_groups = PlayGroups.for_areas(areas=areas, venues_per_capita=1. / 20.) assert len(play_groups) == int(np.ceil(1. / 20. * n_people))
def test_try_allocate_patient_to_full_hospital(hospitals, health_info, selector): dummy_person = Person().from_attributes(age=80, sex='m') selector.infect_person_at_time(dummy_person, 0.0) dummy_person.health_information.infection.symptoms.tag = getattr( SymptomTag, health_info) dummy_person.area = MockArea(hospitals.members[0].coordinates) for hospital in hospitals.members: for _ in range(int(hospital.n_beds)): hospital.add_as_patient(dummy_person) hospitals.allocate_patient(dummy_person) if health_info == 'hospitalised': assert len(dummy_person.medical_facility.people ) > dummy_person.medical_facility.group.n_beds elif health_info == 'intensive_care': assert len(dummy_person.medical_facility.people ) > dummy_person.medical_facility.group.n_icu_beds for hospital in hospitals.members: for _ in range(int(hospital.n_beds)): hospital.release_as_patient(dummy_person)
def test__add_patient_release_patient(hospitals, health_info, selector): dummy_person = Person().from_attributes(age=80, sex='m') selector.infect_person_at_time(dummy_person, 0.0) dummy_person.health_information.infection.symptoms.tag = getattr( SymptomTag, health_info) assert dummy_person.medical_facility is None hospitals.members[0].add_as_patient(dummy_person) if health_info == "hospitalised": assert hospitals.members[0][ Hospital.SubgroupType.patients][0] == dummy_person elif health_info == "intensive_care": assert (hospitals.members[0][Hospital.SubgroupType.icu_patients][0] == dummy_person) assert dummy_person.medical_facility is not None hospitals.members[0].release_as_patient(dummy_person) assert dummy_person.medical_facility is None
def get_symptoms_rates_per_age_sex( self, ) -> dict: """ Computes the rates of ending up with certain SymptomTag for all ages and sex. Returns ------- dictionary with rates of symptoms (fate) as a function of age and sex """ symptoms_rates_dict = {"m": defaultdict(int), "f": defaultdict(int)} for sex in ("m", "f"): for age in np.arange(100): symptoms_rates_dict[sex][age] = np.diff( self.health_index_generator(Person(sex=sex, age=age)), prepend=0.0, append=1.0, ) # need np.diff because health index is cummulative return symptoms_rates_dict
def test__send_to_isolation(selector, isolation): person = Person.from_attributes(sex="m", age=27) infect_person(person, selector, symptom_tag="mild") person.infection.time_of_testing = isolation._generate_time_of_testing(person) isolation_units = IsolationUnits([IsolationUnit(area=None)]) for day in range(0, 100): isolation.apply( person, medical_facilities=[isolation_units], days_from_start=day ) if 0 < day < person.infection.time_of_testing: assert person not in isolation_units[0].people elif ( person.infection.time_of_testing < day < person.infection.time_of_testing + isolation.n_quarantine_days ): assert person in isolation_units[0].people else: assert person not in isolation_units[0].people isolation_units[0].clear()