예제 #1
0
def build_reporters(telemetry_bus, config):
    """Instantiates reporters, which record data on the simulation for analysis"""

    for reporter_class, reporter_config in config['reporters'].items():
        log.info(f"Creating reporter '{reporter_class}'...")

        instantiate_class("abmlux.reporters", reporter_class, telemetry_bus,
                          Config(_dict=reporter_config))
예제 #2
0
    def test_enabled(self):
        """Test that distance function works correctly"""

        intervention_config = {
            "__type__": "location_closure.LocationClosures",
            "__prng_seed__": 1,
            "__enabled__": False,
            "__schedule__":
            ["16th March 2020: enable", "25th May 2020: disable"],
            "locations": "Primary School",
            "home_activity_type": "House"
        }

        intervention_class = intervention_config['__type__']

        initial_enabled = False if '__enabled__' in intervention_config and \
                          not intervention_config['__enabled__'] else True

        new_intervention = instantiate_class("abmlux.interventions",
                                             intervention_class,
                                             intervention_config,
                                             initial_enabled)

        assert not new_intervention.enabled

        new_intervention.enable()

        assert new_intervention.enabled
예제 #3
0
    def test_handle_location_change(self):
        """Test that distance function works correctly"""

        intervention_config = {
            "__type__": "location_closure.LocationClosures",
            "__prng_seed__": 1,
            "__enabled__": True,
            "__schedule__":
            ["16th March 2020: enable", "25th May 2020: disable"],
            "locations": "Primary School",
            "home_activity_type": "House"
        }

        intervention_class = intervention_config['__type__']

        initial_enabled = False if '__enabled__' in intervention_config and \
                          not intervention_config['__enabled__'] else True

        new_intervention = instantiate_class("abmlux.interventions",
                                             intervention_class,
                                             intervention_config,
                                             initial_enabled)

        test_current_location = Location("Test type", (0, 0))
        test_agent = Agent(40, "Luxembourg", test_current_location)

        test_home_location = Location("House", (1, 1))
        test_agent.add_activity_location(0, test_home_location)

        test_new_location_1 = Location("Primary School", (2, 2))
        test_new_location_2 = Location("Not a Primary School", (2, 2))

        def test_callback(agent, home_location):
            """Test callback function"""
            if home_location == agent.locations_for_activity(0)[0]:
                result = True
            else:
                result = False
            return result

        test_bus = MessageBus()

        test_bus.handlers["request.agent.location"].append(
            (test_callback, None))

        new_intervention.bus = test_bus
        new_intervention.home_activity_type = 0

        assert new_intervention.handle_location_change(test_agent,
                                                       test_new_location_1)

        assert not new_intervention.handle_location_change(
            test_agent, test_new_location_2)
예제 #4
0
    def test_enabled(self):
        """Test that distance function works correctly"""

        intervention_config = {
            "__type__": "curfew.Curfew",
            "__prng_seed__": 1,
            "__enabled__": False,
            "__schedule__": "26th October 2020",
            "start_time": 23,
            "end_time": 6,
            "locations": ["House", "Care Home", "Restaurant"],
            "home_activity_type": "House"
        }

        intervention_class = intervention_config['__type__']

        initial_enabled = False if '__enabled__' in intervention_config and \
                          not intervention_config['__enabled__'] else True

        new_intervention = instantiate_class("abmlux.interventions",
                                             intervention_class,
                                             intervention_config,
                                             initial_enabled)

        assert not new_intervention.enabled

        new_intervention.enable()

        assert new_intervention.enabled

        new_intervention.active = True

        assert new_intervention.active

        new_intervention.active = False

        assert not new_intervention.active
예제 #5
0
def build_model(sim_factory):
    """Builds world using map and world factories and builds components, such as the activity,
    movement and disease models"""

    config = sim_factory.config

    # -----------------------------------[ World ]---------------------------------

    # Create the map
    map_factory_class = config['map_factory.__type__']
    map_factory_config = config.subconfig('map_factory')
    map_factory = instantiate_class("abmlux.world.map_factory",
                                    map_factory_class, map_factory_config)
    _map = map_factory.get_map()
    sim_factory.set_map(_map)

    # Create the world, providing it with the map
    world_factory_class = config['world_factory.__type__']
    world_factory_config = config.subconfig('world_factory')
    world_factory = instantiate_class("abmlux.world.world_factory",
                                      world_factory_class, sim_factory.map,
                                      sim_factory.activity_manager,
                                      world_factory_config)
    world = world_factory.get_world()
    sim_factory.set_world_model(world)

    # -----------------------------------[ Components ]---------------------------------

    # Disease model
    disease_model_class = config['disease_model.__type__']
    disease_model_config = config.subconfig('disease_model')
    disease_model = instantiate_class("abmlux.disease_model",
                                      disease_model_class,
                                      disease_model_config)
    sim_factory.set_disease_model(disease_model)

    # Activity model
    activity_model_class = config['activity_model.__type__']
    activity_model_config = config.subconfig('activity_model')
    activity_model = instantiate_class("abmlux.activity", activity_model_class,
                                       activity_model_config,
                                       sim_factory.activity_manager)
    sim_factory.set_activity_model(activity_model)

    # How agents move around locations
    movement_model_class = config['movement_model.__type__']
    movement_model_config = config.subconfig('movement_model')
    movement_model = instantiate_class("abmlux.movement_model",
                                       movement_model_class,
                                       movement_model_config)
    sim_factory.set_movement_model(movement_model)

    # Interventions
    for intervention_id, intervention_config in config["interventions"].items(
    ):

        # Extract keys from the intervention config
        intervention_class = intervention_config['__type__']

        log.info("Creating intervention %s of type %s...", intervention_id,
                 intervention_class)
        initial_enabled = False if '__enabled__' in intervention_config \
                                                 and not intervention_config['__enabled__']\
                                else True
        new_intervention = instantiate_class("abmlux.interventions", intervention_class, \
                                             intervention_config, initial_enabled)

        sim_factory.add_intervention(intervention_id, new_intervention)
        sim_factory.add_intervention_schedule(
            new_intervention, intervention_config['__schedule__'])
    def test_world_factory_large(self):
        """Tests distance distributions of the stochatic world factory"""

        config = Config("tests/test_configs/test_config_2.yaml")
        sim_factory = SimulationFactory(config)

        config = sim_factory.config

        # -----------------------------------[ World ]---------------------------------

        # Create the map
        map_factory_class = config['map_factory.__type__']
        map_factory_config = config.subconfig('map_factory')
        map_factory = instantiate_class("abmlux.world.map_factory", map_factory_class,
                                        map_factory_config)
        _map = map_factory.get_map()
        sim_factory.set_map(_map)

        # Create the world, providing it with the map
        world_factory_class = config['world_factory.__type__']
        world_factory_config = config.subconfig('world_factory')
        world_factory = instantiate_class('abmlux.world.world_factory', world_factory_class,
                                          sim_factory.map, sim_factory.activity_manager,
                                          world_factory_config)

        world = world_factory.get_world()
        sim_factory.set_world_model(world)

        activity_manager = sim_factory.activity_manager

        # working_dict = defaultdict(set)
        # for agent in world.agents:
        #     work = agent.activity_locations[activity_manager.as_int('Work')][0]
        #     working_dict[work].add(agent)
        # no_workers = []
        # for location in world.locations:
        #     if location not in set(working_dict.keys()):
        #         if location.typ not in ['Belgium', 'France', 'Germany', 'Cemetery', 'Car',
        #                                 'Outdoor', 'House']:
        #             no_workers.append(location)
        #             print([location.typ, 0])
        # worker_profiles = [[l.typ, len(working_dict[l])] for l in working_dict.keys()]

        def take_first(elem):
            """For sorting tuples below"""
            return elem[0]
        # def take_second(elem):
        #     """For sorting tuples below"""
        #     return elem[1]

        # # sort list with key
        # worker_profiles.sort(reverse=True, key=take_second)

        # print(worker_profiles)
        # print(len(list(working_dict.keys())), len(no_workers))

        # school_dict = defaultdict(set)
        # for agent in world.agents:
        #     school = agent.activity_locations[activity_manager.as_int('School')][0]
        #     if agent.age < 4:
        #         assert school.typ == "House"
        #     if agent.age >= 5 and agent.age < 12:
        #         assert school.typ == "Primary School"
        #     if agent.age >= 12:
        #         assert school.typ in ['Secondary School', 'Belgium', 'France', 'Germany',
        #                               'Care Home']
        #     if agent.age >= 5 and agent.age < 18:
        #         school_dict[school].add(agent)
        # for school in school_dict:
        #     print(school.typ, len(school_dict[school]))

        activities = ['House', 'Work', 'School', 'Restaurant', 'Outdoor', 'Car', 'Public Transport',
        'Shop', 'Medical', 'Place of Worship', 'Indoor Sport', 'Cinema or Theatre', 'Museum or Zoo',
        'Visit']
        av_dist_dict = {}
        for activity in activities:
            total_dist = 0
            dist_dict = {}
            for agent in world.agents:
                if agent.nationality == 'Luxembourg':
                    home = agent.activity_locations[activity_manager.as_int('House')][0]
                    if home.typ != 'Care Home':
                        location = agent.activity_locations[activity_manager.as_int(activity)][0]
                        #print(ETRS89_to_WGS84(home.coord), ETRS89_to_WGS84(location.coord))
                        #print(home.coord, location.coord)
                        rnded_dist = (int(home.distance_euclidean(location))//1000)#*100
                        if rnded_dist in dist_dict:
                            dist_dict[rnded_dist] += 1
                        else:
                            dist_dict[rnded_dist] = 1
                        total_dist += home.distance_euclidean(location)
            average_dist = total_dist/len(world.agents)
            av_dist_dict[activity] = average_dist
            # print(home.distance_euclidean(location), 'meters')
            dist_list = [[a,b] for a, b in dist_dict.items()]
            dist_list.sort(key=take_first)
            # print('ACTIVITY:', activity)
            # print(dist_list)
        for activity in av_dist_dict:
            if activity in ['House', 'Car']:
                assert av_dist_dict[activity] == 0.0
            else:
                assert av_dist_dict[activity] > 0.0
    def test_world_factory(self):
        """Tests basic features of the stochatic world factory"""

        config = Config("tests/test_configs/test_config_1.yaml")
        sim_factory = SimulationFactory(config)

        config = sim_factory.config

        # -----------------------------------[ World ]---------------------------------

        # Create the map
        map_factory_class = config['map_factory.__type__']
        map_factory_config = config.subconfig('map_factory')
        map_factory = instantiate_class("abmlux.world.map_factory", map_factory_class,
                                        map_factory_config)
        _map = map_factory.get_map()
        sim_factory.set_map(_map)

        # Create the world, providing it with the map
        world_factory_class = config['world_factory.__type__']
        world_factory_config = config.subconfig('world_factory')
        world_factory = instantiate_class('abmlux.world.world_factory', world_factory_class,
                                          sim_factory.map, sim_factory.activity_manager,
                                          world_factory_config)

        world = world_factory.get_world()
        sim_factory.set_world_model(world)

        activity_manager = sim_factory.activity_manager

        assert world.scale_factor == 1

        assert len(world.agents) == 1110

        assert len({a for a in world.agents if a.nationality == 'Luxembourg'}) == 960
        assert len({a for a in world.agents if a.nationality == 'Belgium'}) == 50
        assert len({a for a in world.agents if a.nationality == 'France'}) == 50
        assert len({a for a in world.agents if a.nationality == 'Germany'}) == 50

        house_act_int = activity_manager.as_int('House')

        for agent in world.agents:
            if agent.nationality == 'Belgium':
                assert agent.activity_locations[house_act_int][0].typ == 'Belgium'
            if agent.nationality == 'France':
                assert agent.activity_locations[house_act_int][0].typ == 'France'
            if agent.nationality == 'Germany':
                assert agent.activity_locations[house_act_int][0].typ == 'Germany'

        for agent in world.agents:
            if agent.nationality != 'Luxembourg':
                assert agent.age >= config['world_factory']['min_age_border_workers']
                assert agent.age <= config['world_factory']['max_age_border_workers']

        for agent in world.agents:
            if agent.activity_locations[house_act_int][0].typ == 'Care Home':
                assert agent.age >= config['world_factory']['retired_age_limit']

        for location_type in config['locations']:
            assert len(world.locations_for_types(location_type)) > 0

        for location_type in config['world_factory']['deterministic_location_counts']:
            if location_type == 'Primary School':
                classes = config['world_factory']['num_classes_per_school'][location_type]
                count = config['world_factory']['deterministic_location_counts'][location_type]
                assert len(world.locations_for_types(location_type)) == count * classes
            elif location_type == 'Secondary School':
                classes = config['world_factory']['num_classes_per_school'][location_type]
                count = config['world_factory']['deterministic_location_counts'][location_type]
                assert len(world.locations_for_types(location_type)) == count * classes
            else:
                count = config['world_factory']['deterministic_location_counts'][location_type]
                assert len(world.locations_for_types(location_type)) == count

        occupancy_dict = defaultdict(set)
        for agent in world.agents:
            home = agent.activity_locations[activity_manager.as_int('House')][0]
            occupancy_dict[home].add(agent)
        for home in occupancy_dict:
            if len(occupancy_dict[home]) > 7:
                assert home.typ in ['Care Home', 'Belgium', 'France', 'Germany']

        visite_lux_lux  = world_factory._make_distribution('Visite', 'Luxembourg', 'Luxembourg',
                                                           10, 10)
        achats_lux_lux  = world_factory._make_distribution('Achats', 'Luxembourg', 'Luxembourg',
                                                           10, 10)
        repas_lux_lux   = world_factory._make_distribution('Repas', 'Luxembourg', 'Luxembourg',
                                                           10, 10)
        travail_lux_lux = world_factory._make_distribution('Travail', 'Luxembourg', 'Luxembourg',
                                                           10, 10)
        travail_bel_lux = world_factory._make_distribution('Travail', 'Belgique', 'Luxembourg',
                                                           10, 10)
        travail_fra_lux = world_factory._make_distribution('Travail', 'France', 'Luxembourg',
                                                           10, 10)
        travail_all_lux = world_factory._make_distribution('Travail', 'Allemagne', 'Luxembourg',
                                                           10, 10)

        assert abs(sum(visite_lux_lux.values()) - 1.0)  < 1e-9
        assert abs(sum(achats_lux_lux.values()) - 1.0)  < 1e-9
        assert abs(sum(repas_lux_lux.values()) - 1.0)   < 1e-9
        assert abs(sum(travail_lux_lux.values()) - 1.0) < 1e-9
        assert abs(sum(travail_bel_lux.values()) - 1.0) < 1e-9
        assert abs(sum(travail_fra_lux.values()) - 1.0) < 1e-9
        assert abs(sum(travail_all_lux.values()) - 1.0) < 1e-9

        assert world_factory._get_weight(15, visite_lux_lux) == visite_lux_lux[range(10,20)]
        assert world_factory._get_weight(45, achats_lux_lux) == achats_lux_lux[range(50,60)]
        assert world_factory._get_weight(500, travail_fra_lux) == 0

        assert world_factory._get_weight(65, travail_fra_lux) <= 1.0
        assert world_factory._get_weight(17, achats_lux_lux) <= 1.0
        assert world_factory._get_weight(17.434, visite_lux_lux) <= 1.0

        workplace_weights = world_factory._make_work_profile_dictionary(world)
        weights_dict      = {l.typ : workplace_weights[l] for l in list(workplace_weights.keys())}

        for weight in weights_dict.values():
            assert weight > 0

        car_house_dict = defaultdict(set)
        for location in world.locations:
            if location.typ == 'Car' or location.typ == 'House':
                car_house_dict[location.coord].add(location)
        for coord in car_house_dict:
            assert len(car_house_dict[coord]) == 2
예제 #8
0
    def test_handle_location_change(self):
        """Test that distance function works correctly"""

        intervention_config = {
            "__type__": "curfew.Curfew",
            "__prng_seed__": 1,
            "__enabled__": False,
            "__schedule__": "26th October 2020",
            "start_time": 23,
            "end_time": 6,
            "locations": ["House", "Care Home", "Restaurant"],
            "home_activity_type": "House"
        }

        intervention_class = intervention_config['__type__']

        initial_enabled = False if '__enabled__' in intervention_config and \
                            not intervention_config['__enabled__'] else True

        new_intervention = instantiate_class("abmlux.interventions",
                                             intervention_class,
                                             intervention_config,
                                             initial_enabled)

        test_current_location = Location("Test type", (0, 0))
        test_agent = Agent(40, "Luxembourg", test_current_location)

        test_home_location = Location("House", (1, 1))
        test_agent.add_activity_location(0, test_home_location)

        test_new_location_1 = Location("Restaurant", (2, 2))
        test_new_location_2 = Location("Not a Restaurant", (2, 2))

        def test_callback(agent, home_location):
            """Test callback function"""
            if home_location == agent.locations_for_activity(0)[0]:
                result = True
            else:
                result = False
            return result

        test_bus = MessageBus()

        test_bus.handlers["request.agent.location"].append(
            (test_callback, None))

        new_intervention.bus = test_bus
        new_intervention.home_activity_type = 0

        new_intervention.enabled = True
        new_intervention.active = True

        assert new_intervention.handle_location_change(test_agent,
                                                       test_new_location_1)

        assert not new_intervention.handle_location_change(
            test_agent, test_new_location_2)

        assert new_intervention.start_time == datetime.time(23)

        assert new_intervention.end_time != datetime.time(5)

        epoch = "12th December 2004"
        test_clock = SimClock(600, 10, epoch)

        new_intervention.handle_time_change(test_clock, 12)

        assert new_intervention.active

        epoch = "11:14, 12th December 2004"
        test_clock = SimClock(600, 10, epoch)

        new_intervention.handle_time_change(test_clock, 12)

        assert not new_intervention.active