def test__care_home_visits_leisure_integration(world_visits, leisure): person1 = Person.from_attributes(sex="m", age=26) person2 = Person.from_attributes(sex="f", age=28) household = Household(type="family") household.add(person1) household.add(person2) person1.busy = False person2.busy = False for area in world_visits.areas: if area.care_home is not None: break person1.residence.group.relatives_in_care_homes = [area.care_home.residents[0]] person1.residence.group.social_venues = {"care_home_visits": [area.care_home]} assigned = False for _ in range(0, 100): subgroup = leisure.get_subgroup_for_person_and_housemates( person1 ) if subgroup is not None: assigned = True assert ( subgroup == area.care_home.subgroups[area.care_home.SubgroupType.visitors] ) assert subgroup.group == area.care_home assert assigned
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__households_adding(): household = Household() household2 = Household() household3 = Household() households1 = Households([household]) households2 = Households([household2, household3]) households3 = households1 + households2 assert households3.members == [household, household2, household3]
def get_leisure_subgroup_type(self, person): """ A person wants to come and visit this household. We need to assign the person to the relevant age subgroup, and make sure the residents welcome him and don't go do any other leisure activities. """ return Household.get_leisure_subgroup_type(person)
def test__create_shelters(): shelter = Shelter() household = Household() person1 = Person.from_attributes() household.add(person1) shelter.add(household) assert len(shelter.subgroups) == 2 assert shelter.n_families == 1 assert shelter.n_households == 1 n_families_area = 100 shelters = Shelters.from_families_in_area(n_families_area, sharing_shelter_ratio=0.75) assert np.isclose( len(shelters), 0.75 * n_families_area / 2 + 0.25 * n_families_area, atol=1, rtol=0, )
def test__do_not_visit_dead_people(world_visits, leisure): # look for a person in carehome found = False for area in world_visits.areas: for person in area.people: if person.residence.group.spec == "care_home": found = True break assert found person2 = Person.from_attributes() household = Household(type="family") household.add(person2) household.relatives_in_care_homes = [person] person2.residence.group.social_venues = {"care_home_visits" : [person.residence.group[2]]} person.dead = True leisure.update_household_and_care_home_visits_targets([person2]) for _ in range(0, 100): care_home = leisure.get_subgroup_for_person_and_housemates(person2) assert care_home is None
def load_households_from_hdf5(file_path: str, chunk_size=50000, domain_super_areas=None): """ Loads households from an hdf5 file located at ``file_path``. Note that this object will not be ready to use, as the links to object instances of other classes need to be restored first. This function should be rarely be called oustide world.py """ logger.info("loading households...") households_list = [] with h5py.File(file_path, "r", libver="latest", swmr=True) as f: households = f["households"] n_households = households.attrs["n_households"] n_chunks = int(np.ceil(n_households / chunk_size)) for chunk in range(n_chunks): logger.info(f"Loaded chunk {chunk} of {n_chunks}") idx1 = chunk * chunk_size idx2 = min((chunk + 1) * chunk_size, n_households) length = idx2 - idx1 ids = read_dataset(households["id"], idx1, idx2) types = read_dataset(households["type"], idx1, idx2) max_sizes = read_dataset(households["max_size"], idx1, idx2) super_areas = read_dataset(households["super_area"], idx1, idx2) for k in range(length): if domain_super_areas is not None: super_area = super_areas[k] if super_area == nan_integer: raise ValueError( "if ``domain_super_areas`` is True, I expect not Nones super areas." ) if super_area not in domain_super_areas: continue household = Household(area=None, type=types[k].decode(), max_size=max_sizes[k]) households_list.append(household) household.id = ids[k] return Households(households_list)
def test__probability_of_leisure(leisure): person = Person.from_attributes(sex="m", age=26) household = Household(type="student") household.add(person) person.residence.group.social_venues = { "cinemas": [leisure.leisure_distributors["cinemas"].social_venues[0]], "pubs": [leisure.leisure_distributors["pubs"].social_venues[0]], } estimated_time_for_activity = 1 / (0.5 + 0.2) times = [] times_goes_pub = 0 times_goes_cinema = 0 for _ in range(0, 300): counter = 0 while True: counter += 0.01 subgroup = leisure.get_subgroup_for_person_and_housemates(person) if subgroup is None: continue if subgroup.group.spec == "pub": times_goes_pub += 1 elif subgroup.group.spec == "cinema": times_goes_cinema += 1 else: raise ValueError times.append(counter) break assert np.isclose(np.mean(times), estimated_time_for_activity, atol=0.2, rtol=0) assert np.isclose(times_goes_pub / times_goes_cinema, 0.5 / 0.2, atol=0, rtol=0.25)
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__shelter_distributor(): n_families_area = 100 shelters = Shelters.from_families_in_area(n_families_area, sharing_shelter_ratio=0.75) households = [Household() for _ in range(n_families_area)] for household in households: for _ in range(3): person = Person.from_attributes() household.add(person) shelter_distributor = ShelterDistributor(sharing_shelter_ratio=0.75) shelter_distributor.distribute_people_in_shelters(shelters, households) shelter_one_household = 0 shelter_more_one_household = 0 empty_shelters = 0 for shelter in shelters: assert shelter.n_families <= 2 if shelter.n_families > 1: shelter_more_one_household += 1 elif shelter.n_families == 1: shelter_one_household += 1 else: empty_shelters += 1 assert np.isclose( shelter_one_household / len(shelters), 0.25 / (0.25 + 0.75 / 2), atol=0.02, rtol=0, ) assert np.isclose( shelter_more_one_household / len(shelters), 0.75 / 2 / (0.25 + 0.75 / 2), atol=0.02, rtol=0, ) assert empty_shelters == 0
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 load_households_from_hdf5(file_path: str, chunk_size=50000): """ Loads households from an hdf5 file located at ``file_path``. Note that this object will not be ready to use, as the links to object instances of other classes need to be restored first. This function should be rarely be called oustide world.py """ print("loading households from hdf5 ", end="") with h5py.File(file_path, "r", libver="latest", swmr=True) as f: households = f["households"] households_list = [] n_households = households.attrs["n_households"] n_chunks = int(np.ceil(n_households / chunk_size)) for chunk in range(n_chunks): print(".", end="") idx1 = chunk * chunk_size idx2 = min((chunk + 1) * chunk_size, n_households) ids = households["id"][idx1:idx2] types = households["type"][idx1:idx2] areas = households["area"][idx1:idx2] max_sizes = households["max_size"][idx1:idx2] # TODO: household_complacencies = households["household_complacency"][idx1:idx2] relatives_in_households = households["relatives_in_households"][ idx1:idx2] relatives_in_care_homes = households["relatives_in_care_homes"][ idx1:idx2] social_venues_specs = households["social_venues_specs"][idx1:idx2] social_venues_ids = households["social_venues_ids"][idx1:idx2] for k in range(idx2 - idx1): area = areas[k] if area == nan_integer: area = None type = types[k] if type.decode() == " ": type = None else: type = type.decode() household = Household( type=type, area=area, max_size=max_sizes[k], household_complacency=np.random.rand() # TODO: :household_complacency=household_complacencies[k] ) household.id = ids[k] if relatives_in_households[k][0] == nan_integer: household.relatives_in_households = () else: household.relatives_in_households = relatives_in_households[ k] if relatives_in_care_homes[k][0] == nan_integer: household.relatives_in_care_homes = () else: household.relatives_in_care_homes = relatives_in_care_homes[ k] household.social_venues = defaultdict(list) for sv_spec, sv_id in zip(social_venues_specs[k], social_venues_ids[k]): household.social_venues[sv_spec.decode()].append(sv_id) households_list.append(household) print("\n", end="") return Households(households_list)
def test__reduce_household_visits(self, setup_policy_world): world, pupil, student, worker, sim = setup_policy_world super_area = world.super_areas[0] leisure_instance = leisure.generate_leisure_for_config( world=world, config_filename=test_config) reduce_leisure_probabilities = ChangeLeisureProbability( start_time="2020-03-02", end_time="2020-03-05", leisure_activities_probabilities={ "pubs": { "men": { "0-50": 0.2, "50-100": 0.0 }, "women": { "0-100": 0.2 }, }, }, ) policies = Policies([reduce_leisure_probabilities]) sim.activity_manager.policies = policies sim.activity_manager.leisure = leisure_instance sim.clear_world() leisure_policies = LeisurePolicies.get_active_policies( policies=policies, date=sim.timer.date) leisure_policies.apply(date=sim.timer.date, leisure=sim.activity_manager.leisure) sim.activity_manager.leisure.generate_leisure_probabilities_for_timestep( 0.1, False) original_male_pub_probabilities = sim.activity_manager.leisure.leisure_distributors[ "pubs"].male_probabilities original_female_pub_probabilities = sim.activity_manager.leisure.leisure_distributors[ "pubs"].female_probabilities assert str(sim.timer.date.date()) == "2020-03-01" household = Household() household.area = super_area.areas[0] leisure_instance.distribute_social_venues_to_households([household]) person1 = Person.from_attributes(age=60, sex="m") person1.area = super_area.areas[0] household.add(person1) person2 = Person.from_attributes(age=80, sex="f") person2.area = super_area.areas[0] sim.activity_manager.leisure.distribute_social_venues_to_households( [household]) household.add(person2) pubs1_visits_before = 0 pubs2_visits_before = 0 for _ in range(5000): subgroup = sim.activity_manager.leisure.get_subgroup_for_person_and_housemates( person1) if subgroup is not None and subgroup.group.spec == "pub": pubs1_visits_before += 1 person1.subgroups.leisure = None subgroup = sim.activity_manager.leisure.get_subgroup_for_person_and_housemates( person2) if subgroup is not None and subgroup.group.spec == "pub": pubs2_visits_before += 1 person2.subgroups.leisure = None assert pubs1_visits_before > 0 assert pubs2_visits_before > 0 # next day leisure policies are while str(sim.timer.date.date()) != "2020-03-02": next(sim.timer) leisure_policies = LeisurePolicies.get_active_policies( policies=policies, date=sim.timer.date) leisure_policies.apply(date=sim.timer.date, leisure=sim.activity_manager.leisure) sim.activity_manager.leisure.generate_leisure_probabilities_for_timestep( 0.1, False) assert (sim.activity_manager.leisure.leisure_distributors["pubs"]. male_probabilities[60] == 0.0) assert (sim.activity_manager.leisure.leisure_distributors["pubs"]. female_probabilities[60] == 0.2) pubs1_visits_after = 0 pubs2_visits_after = 0 for _ in range(5000): subgroup = sim.activity_manager.leisure.get_subgroup_for_person_and_housemates( person1) if subgroup is not None and subgroup.group.spec == "pub": pubs1_visits_after += 1 person1.subgroups.leisure = None subgroup = sim.activity_manager.leisure.get_subgroup_for_person_and_housemates( person2) if subgroup is not None and subgroup.group.spec == "pub": pubs2_visits_after += 1 person2.subgroups.leisure = None assert pubs1_visits_after == 0 assert 0 < pubs2_visits_after < pubs2_visits_before # end of policy while str(sim.timer.date.date()) != "2020-03-05": next(sim.timer) leisure_policies = LeisurePolicies.get_active_policies( policies=policies, date=sim.timer.date) leisure_policies.apply(date=sim.timer.date, leisure=sim.activity_manager.leisure) sim.activity_manager.leisure.generate_leisure_probabilities_for_timestep( 0.1, False) pubs1_visits_restored = 0 pubs2_visits_restored = 0 for _ in range(5000): subgroup = sim.activity_manager.leisure.get_subgroup_for_person_and_housemates( person1) if subgroup is not None and subgroup.group.spec == "pub": pubs1_visits_restored += 1 person1.subgroups.leisure = None subgroup = sim.activity_manager.leisure.get_subgroup_for_person_and_housemates( person2) if subgroup is not None and subgroup.group.spec == "pub": pubs2_visits_restored += 1 person2.subgroups.leisure = None assert np.isclose(pubs1_visits_restored, pubs1_visits_before, rtol=0.2) assert np.isclose(pubs2_visits_restored, pubs2_visits_before, rtol=0.2) assert (sim.activity_manager.leisure.leisure_distributors["pubs"]. male_probabilities == original_male_pub_probabilities) assert (sim.activity_manager.leisure.leisure_distributors["pubs"]. female_probabilities == original_female_pub_probabilities)
def make_dummy_world(geog): super_area = geog.super_areas.members[0] company = Company(super_area=super_area, n_workers_max=100, sector="Q") household1 = Household() household1.area = super_area.areas[0] hospital = Hospital( n_beds=40, n_icu_beds=5, super_area=super_area.name, coordinates=super_area.coordinates, ) uni = University( coordinates=super_area.coordinates, n_students_max=2500, ) worker1 = Person.from_attributes(age=44, sex='f', ethnicity='A1', socioecon_index=5) worker1.area = super_area.areas[0] household1.add(worker1, subgroup_type=household1.SubgroupType.adults) worker1.sector = "Q" company.add(worker1) worker2 = Person.from_attributes(age=42, sex='m', ethnicity='B1', socioecon_index=5) worker2.area = super_area.areas[0] household1.add(worker2, subgroup_type=household1.SubgroupType.adults) worker2.sector = "Q" company.add(worker2) student1 = Person.from_attributes(age=20, sex='f', ethnicity='A1', socioecon_index=5) student1.area = super_area.areas[0] household1.add(student1, subgroup_type=household1.SubgroupType.adults) uni.add(student1) pupil1 = Person.from_attributes(age=8, sex='m', ethnicity='C1', socioecon_index=5) pupil1.area = super_area.areas[0] household1.add(pupil1, subgroup_type=household1.SubgroupType.kids) #school.add(pupil1) pupil2 = Person.from_attributes(age=5, sex='f', ethnicity='A1', socioecon_index=5) pupil2.area = super_area.areas[0] household1.add(pupil2, subgroup_type=household1.SubgroupType.kids) #school.add(pupil2) world = World() world.schools = Schools([]) world.hospitals = Hospitals([hospital]) world.households = Households([household1]) world.universities = Universities([uni]) world.companies = Companies([company]) world.people = Population([worker1, worker2, student1, pupil1, pupil2]) world.super_areas = geog.super_areas world.areas = geog.areas world.cemeteries = Cemeteries() cinema = Cinema() cinema.coordinates = super_area.coordinates world.cinemas = Cinemas([cinema]) pub = Pub() pub.coordinates = super_area.coordinates world.pubs = Pubs([pub]) world.areas[0].people = world.people return world