Example #1
0
    def test_simple_graph(self, get_sector_model):
        regions = Mock()
        regions.name = 'test_regions'
        intervals = Mock()
        intervals.name = 'test_intervals'

        SectorModel = get_sector_model
        elec_scenario = ScenarioModel('scenario')
        elec_scenario.add_output('output', regions, intervals, 'unit')

        energy_model = SectorModel('model')
        energy_model.add_input('input', regions, intervals, 'unit')
        energy_model.add_dependency(elec_scenario, 'output', 'input')

        sos_model = SosModel('energy_sos_model')
        sos_model.add_model(energy_model)
        sos_model.add_model(elec_scenario)

        # Builds the dependency graph
        sos_model.check_dependencies()

        graph = sos_model.dependency_graph

        assert energy_model in graph
        assert elec_scenario in graph

        assert list(graph.edges()) == [(elec_scenario, energy_model)]
Example #2
0
    def test_get_model_sets(self, get_sector_model):
        regions = Mock()
        regions.name = 'test_regions'
        intervals = Mock()
        intervals.name = 'test_intervals'

        elec_scenario = ScenarioModel('scenario')
        elec_scenario.add_output('output', regions, intervals, 'unit')

        SectorModel = get_sector_model
        energy_model = SectorModel('model')
        energy_model.add_input('input', regions, intervals, 'unit')
        energy_model.add_dependency(elec_scenario, 'output', 'input')

        sos_model = SosModel('energy_sos_model')
        sos_model.add_model(energy_model)
        sos_model.add_model(elec_scenario)

        sos_model.check_dependencies()

        actual = sos_model._get_model_sets_in_run_order()
        expected = ['scenario', 'model']

        for model, name in zip(actual, expected):
            assert model.name == name
Example #3
0
    def test_hanging_inputs(self, get_sector_model):
        """
        sos_model_high
            sos_model_lo
               -> em

        """
        SectorModel = get_sector_model
        energy_model = SectorModel('energy_sector_model')
        input_metadata = {
            'name': 'electricity_demand_input',
            'spatial_resolution': Mock(),
            'temporal_resolution': Mock(),
            'units': 'unit'
        }

        energy_model._inputs = MetadataSet([input_metadata])

        sos_model_lo = SosModel('lower')
        sos_model_lo.add_model(energy_model)

        expected = Metadata(input_metadata['name'],
                            input_metadata['spatial_resolution'],
                            input_metadata['temporal_resolution'],
                            input_metadata['units'])

        assert energy_model.free_inputs.names == ['electricity_demand_input']
        assert sos_model_lo.free_inputs.names == ['electricity_demand_input']

        sos_model_high = SosModel('higher')
        sos_model_high.add_model(sos_model_lo)
        actual = sos_model_high.free_inputs['electricity_demand_input']

        assert actual == expected
Example #4
0
    def test_add_parameters(self, get_empty_sector_model):
        sos_model = SosModel('global')
        sos_model_param = {
            'name': 'sos_model_param',
            'description': 'A global parameter passed to all contained models',
            'absolute_range': (0, 100),
            'suggested_range': (3, 10),
            'default_value': 3,
            'units': '%'
        }
        sos_model.add_parameter(sos_model_param)
        expected = sos_model_param

        assert sos_model.parameters['sos_model_param'].as_dict() == expected
        assert sos_model.parameters.names == ['sos_model_param']

        sector_model = get_empty_sector_model('source_model')
        sector_model.add_parameter({
            'name': 'sector_model_param',
            'description': 'Required for the sectormodel',
            'absolute_range': (0, 100),
            'suggested_range': (3, 10),
            'default_value': 3,
            'units': '%'
        })
        sos_model.add_model(sector_model)

        # SosModel contains only its own parameters
        assert 'sos_model_param' in sos_model.parameters.names

        # SectorModel has its own ParameterList, gettable by param name
        assert 'sector_model_param' in sector_model.parameters.names
Example #5
0
 def test_simplest_case(self, get_scenario):
     """One scenario only
     """
     elec_scenario = get_scenario
     sos_model = SosModel('simple')
     sos_model.add_model(elec_scenario)
     data_handle = get_data_handle(sos_model)
     sos_model.simulate(data_handle)
Example #6
0
def get_sos_model_object(get_sector_model_object, get_scenario_model_object):

    sos_model = SosModel('test_sos_model')
    sector_model = get_sector_model_object
    scenario_model = get_scenario_model_object
    sos_model.add_model(sector_model)
    sos_model.add_model(scenario_model)
    sector_model.add_dependency(scenario_model, 'raininess', 'raininess')

    return sos_model
Example #7
0
def sos_model(sector_model, scenario_model, economic_model):
    """SosModel with one scenario and one sector model
    """
    model = SosModel('test_sos_model')
    model.add_model(scenario_model)
    model.add_model(economic_model)
    model.add_model(sector_model)
    model.add_dependency(scenario_model, 'precipitation', sector_model,
                         'precipitation')
    model.add_dependency(economic_model, 'gva', sector_model, 'rGVA')
    return model
Example #8
0
    def test_default_parameter_passing_(self, get_empty_sector_model):
        """Tests that default values for global parameters are passed to all
        models, and others default values only passed into the intended models.
        """

        sos_model_param = {
            'name': 'sos_model_param',
            'description': 'A global parameter passed to all contained models',
            'absolute_range': (0, 100),
            'suggested_range': (3, 10),
            'default_value': 3,
            'units': '%'
        }

        sos_model = SosModel('global')
        sos_model.add_parameter(sos_model_param)

        sector_model = get_empty_sector_model('source_model')

        # Patch the sector model so that it returns the calling arguments
        sector_model.simulate = lambda _, y: {'sm1': y}
        sos_model.add_model(sector_model)
        assert sos_model.simulate(2010) == {'sm1': {'sos_model_param': 3}}

        sector_model.add_parameter({
            'name': 'sector_model_param',
            'description': 'Some meaningful text',
            'absolute_range': (0, 100),
            'suggested_range': (3, 10),
            'default_value': 3,
            'units': '%'
        })

        assert sos_model.simulate(2010) == {
            'sm1': {
                'sector_model_param': 3,
                'sos_model_param': 3
            }
        }

        sector_model_2 = get_empty_sector_model('another')
        sector_model_2.simulate = lambda _, y: {'sm2': y}
        sos_model.add_model(sector_model_2)

        assert sos_model.simulate(2010) == {
            'sm1': {
                'sector_model_param': 3,
                'sos_model_param': 3
            },
            'sm2': {
                'sos_model_param': 3
            }
        }
Example #9
0
 def test_simplest_case(self, get_scenario):
     """One scenario only
     """
     elec_scenario = get_scenario
     sos_model = SosModel('simple')
     sos_model.add_model(elec_scenario)
     actual = sos_model.simulate(2010)
     expected = {
         'electricity_demand_scenario': {
             'electricity_demand_output': np.array([[123]])
         }
     }
     assert actual == expected
Example #10
0
    def test_simulate_data_not_present(self, get_sector_model):
        SectorModel = get_sector_model
        """Raise a NotImplementedError if an input is defined but no dependency links
        it to a data source
        """

        sos_model = SosModel('test')
        model = SectorModel('test_model')
        model.add_input('input', Mock(), Mock(), 'units')
        sos_model.add_model(model)
        data_handle = get_data_handle(sos_model)
        with raises(NotImplementedError):
            sos_model.simulate(data_handle)
Example #11
0
    def test_nested_graph(self, get_sector_model):
        """If we add a nested model, all Sectormodel and ScenarioModel objects
        are added as nodes in the graph with edges along dependencies.

        SosModel objects are not included, as they are just containers for the
        SectorModel and ScenarioModel objects, passing up inputs for deferred
        linkages to dependencies.

        Not implemented yet:
        """
        SectorModel = get_sector_model

        energy_model = SectorModel('energy_sector_model')

        input_metadata = {
            'name': 'electricity_demand_input',
            'spatial_resolution': Mock(),
            'temporal_resolution': Mock(),
            'units': 'unit'
        }

        energy_model._model_inputs = MetadataSet([input_metadata])

        sos_model_lo = SosModel('lower')
        sos_model_lo.add_model(energy_model)

        sos_model_high = SosModel('higher')
        sos_model_high.add_model(sos_model_lo)

        with raises(NotImplementedError):
            sos_model_high.check_dependencies()
        graph = sos_model_high.dependency_graph
        assert graph.edges() == []

        expected = networkx.DiGraph()
        expected.add_node(sos_model_lo)
        expected.add_node(energy_model)

        assert energy_model in graph.nodes()

        scenario = ScenarioModel('electricity_demand')
        scenario.add_output('elec_demand_output', Mock(), Mock(), 'kWh')

        sos_model_high.add_dependency(scenario, 'elec_demand_output',
                                      'electricity_demand_input')

        sos_model_high.check_dependencies()
        assert graph.edges() == [(scenario, sos_model_high)]
Example #12
0
    def test_add_parameters(self, get_empty_sector_model):

        sos_model_param = {
            'name': 'sos_model_param',
            'description': 'A global parameter passed to all contained models',
            'absolute_range': (0, 100),
            'suggested_range': (3, 10),
            'default_value': 3,
            'units': '%'
        }

        sos_model = SosModel('global')
        sos_model.add_parameter(sos_model_param)

        expected = dict(sos_model_param, **{'parent': sos_model})

        assert sos_model.parameters == {
            'global': {
                'sos_model_param': expected
            }
        }
        assert sos_model.parameters['global'].names == ['sos_model_param']

        sector_model = get_empty_sector_model('source_model')
        sector_model.add_parameter({
            'name': 'sector_model_param',
            'description': 'Required for the sectormodel',
            'absolute_range': (0, 100),
            'suggested_range': (3, 10),
            'default_value': 3,
            'units': '%'
        })

        sos_model.add_model(sector_model)

        # SosModel contains ParameterList objects in a nested dict by model name
        assert 'global' in sos_model.parameters
        assert 'sos_model_param' in sos_model.parameters['global'].names
        # SosModel parameter attribute holds references to contained
        # model parameters keyed by model name
        assert 'source_model' in sos_model.parameters
        assert 'sector_model_param' in sos_model.parameters['source_model']
        # SectorModel has a ParameterList, gettable by param name
        assert 'sector_model_param' in sector_model.parameters.names
        assert 'source_model' in sos_model.parameters
        assert 'sector_model_param' in sos_model.parameters['source_model']
Example #13
0
def get_sos_model_with_model_dependency():
    sos_model = SosModel('test_sos_model')
    ws = WaterSupplySectorModel('water_supply')
    ws.inputs = [{
        'name': 'raininess',
        'spatial_resolution': 'LSOA',
        'temporal_resolution': 'annual',
        'units': 'ml'
    }]

    ws.outputs = [{
        'name': 'water',
        'spatial_resolution': 'LSOA',
        'temporal_resolution': 'annual',
        'units': 'Ml'
    }, {
        'name': 'cost',
        'spatial_resolution': 'LSOA',
        'temporal_resolution': 'annual',
        'units': 'million GBP'
    }]
    ws.interventions = [{
        "name": "water_asset_a",
        "location": "oxford"
    }, {
        "name": "water_asset_b",
        "location": "oxford"
    }, {
        "name": "water_asset_c",
        "location": "oxford"
    }]
    sos_model.add_model(ws)

    ws2 = WaterSupplySectorModel('water_supply_2')
    ws2.inputs = [{
        'name': 'water',
        'spatial_resolution': 'LSOA',
        'temporal_resolution': 'annual',
        'units': 'Ml'
    }]
    ws2.add_dependency(ws, 'water', 'water')
    sos_model.add_model(ws2)

    return sos_model
Example #14
0
    def test_add_dependency(self, get_empty_sector_model):

        regions = Mock()
        regions.name = 'test_regions'
        intervals = Mock()
        intervals.name = 'test_intervals'
        units = 'test_units'

        sink_model = get_empty_sector_model('sink_model')
        sink_model.add_input('input_name', regions, intervals, units)

        source_model = get_empty_sector_model('source_model')
        source_model.add_output('output_name', regions, intervals, units)

        sink_model.add_dependency(source_model, 'output_name', 'input_name')

        sos_model = SosModel('test')
        sos_model.add_model(source_model)
        sos_model.add_model(sink_model)
Example #15
0
    def test_loop(self, get_energy_sector_model, get_water_sector_model):
        """Fails because no functionality to deal with loops
        """
        energy_model = get_energy_sector_model

        water_model = get_water_sector_model

        sos_model = SosModel('energy_water_model')
        water_model.add_dependency(energy_model, 'fluffiness', 'fluffyness')
        energy_model.add_dependency(water_model, 'electricity_demand',
                                    'electricity_demand_input')

        sos_model.add_model(water_model)
        sos_model.add_model(energy_model)

        assert energy_model.model_inputs.names == ['electricity_demand_input']
        assert water_model.model_inputs.names == ['fluffyness']
        assert sos_model.model_inputs.names == []

        assert energy_model.free_inputs.names == []
        assert water_model.free_inputs.names == []
        assert sos_model.free_inputs.names == []

        sos_model.check_dependencies()
        graph = sos_model.dependency_graph

        assert (water_model, energy_model) in graph.edges()
        assert (energy_model, water_model) in graph.edges()

        modelset = ModelSet([water_model, energy_model], sos_model)
        actual = modelset.guess_results(water_model, 2010, {})
        expected = {'electricity_demand': np.array([1.])}
        # assert actual == expected

        sos_model.max_iterations = 100
        results = sos_model.simulate(2010)

        expected = np.array([[0.13488114]], dtype=np.float)
        actual = results['energy_sector_model']['fluffiness']
        np.testing.assert_allclose(actual, expected, rtol=1e-5)
        expected = np.array([[0.16469004]], dtype=np.float)
        actual = results['water_supply_model']['electricity_demand']
        np.testing.assert_allclose(actual, expected, rtol=1e-5)
Example #16
0
    def test_add_dependency(self, empty_sector_model):
        """Add models, connect via dependency
        """
        spec = Spec(name='hourly_value',
                    dims=['hours'],
                    coords={'hours': range(24)},
                    dtype='int')
        sink_model = copy(empty_sector_model)
        sink_model.add_input(spec)

        source_model = copy(empty_sector_model)
        source_model.add_output(spec)

        sos_model = SosModel('test')
        sos_model.add_model(source_model)
        sos_model.add_model(sink_model)

        sos_model.add_dependency(source_model, 'hourly_value', sink_model,
                                 'hourly_value')
Example #17
0
    def test_sector_model_one_input(self, get_energy_sector_model,
                                    get_scenario):
        elec_scenario = get_scenario

        energy_model = get_energy_sector_model
        energy_model.add_dependency(elec_scenario,
                                    'electricity_demand_output',
                                    'electricity_demand_input')

        sos_model = SosModel('blobby')
        sos_model.add_model(elec_scenario)
        sos_model.add_model(energy_model)

        data_handle = get_data_handle(sos_model)
        results = sos_model.simulate(data_handle)

        expected = np.array([[100.737]])
        actual = results.get_results('fluffiness', 'energy_sector_model')
        np.testing.assert_allclose(actual, expected, rtol=1e-5)
Example #18
0
    def test_topological_sort(self, get_sector_model):
        SectorModel = get_sector_model
        elec_scenario = ScenarioModel('scenario')
        elec_scenario.add_output('output', Mock(), Mock(), 'unit')

        elec_scenario.add_data(np.array([[[123]]]), [2010])

        energy_model = SectorModel('model')
        energy_model.add_input('input', Mock(), Mock(), 'unit')
        energy_model.add_dependency(elec_scenario, 'output', 'input')

        sos_model = SosModel('energy_sos_model')
        sos_model.add_model(energy_model)
        sos_model.add_model(elec_scenario)

        sos_model.check_dependencies()

        graph = sos_model.dependency_graph
        actual = networkx.topological_sort(graph, reverse=False)
        assert actual == [elec_scenario, energy_model]
Example #19
0
    def test_loop(self, get_energy_sector_model, get_water_sector_model):
        """Fails because no functionality to deal with loops
        """
        energy_model = get_energy_sector_model
        water_model = get_water_sector_model

        sos_model = SosModel('energy_water_model')
        water_model.add_dependency(energy_model, 'fluffiness', 'fluffyness')
        energy_model.add_dependency(water_model, 'electricity_demand',
                                    'electricity_demand_input')
        sos_model.add_model(water_model)
        sos_model.add_model(energy_model)

        assert energy_model.inputs.names == ['electricity_demand_input']
        assert water_model.inputs.names == ['fluffyness']
        assert sos_model.inputs.names == []

        assert energy_model.free_inputs.names == []
        assert water_model.free_inputs.names == []
        assert sos_model.free_inputs.names == []

        sos_model.check_dependencies()
        graph = sos_model.dependency_graph

        assert (water_model, energy_model) in graph.edges()
        assert (energy_model, water_model) in graph.edges()

        sos_model.max_iterations = 100
        data_handle = get_data_handle(sos_model)
        results = sos_model.simulate(data_handle)

        expected = np.array([[0.13488114]], dtype=np.float)
        actual = results.get_results('fluffiness', model_name='energy_sector_model',
                                     modelset_iteration=35)
        np.testing.assert_allclose(actual, expected, rtol=1e-5)

        expected = np.array([[0.16469004]], dtype=np.float)
        actual = results.get_results('electricity_demand', model_name='water_supply_model',
                                     modelset_iteration=35)
        np.testing.assert_allclose(actual, expected, rtol=1e-5)
Example #20
0
    def test_simple_graph(self, get_sector_model):
        SectorModel = get_sector_model
        elec_scenario = ScenarioModel('scenario')
        elec_scenario.add_output('output', Mock(), Mock(), 'unit')
        elec_scenario.add_data(np.array([[[123]]]), [2010])

        energy_model = SectorModel('model')
        energy_model.add_input('input', Mock(), Mock(), 'unit')
        energy_model.add_dependency(elec_scenario, 'output', 'input')

        sos_model = SosModel('energy_sos_model')
        sos_model.add_model(energy_model)
        sos_model.add_model(elec_scenario)

        # Builds the dependency graph
        sos_model.check_dependencies()

        graph = sos_model.dependency_graph

        assert energy_model in graph
        assert elec_scenario in graph

        assert graph.edges() == [(elec_scenario, energy_model)]
Example #21
0
    def test_sector_model_one_input(self, get_energy_sector_model,
                                    get_scenario):
        elec_scenario = get_scenario

        energy_model = get_energy_sector_model
        energy_model.add_dependency(elec_scenario, 'electricity_demand_output',
                                    'electricity_demand_input')

        sos_model = SosModel('blobby')
        sos_model.add_model(elec_scenario)
        sos_model.add_model(energy_model)

        actual = sos_model.simulate(2010)

        expected = {
            'energy_sector_model': {
                'fluffiness': np.array([[100.737]])
            },
            'electricity_demand_scenario': {
                'electricity_demand_output': np.array([[123]])
            }
        }
        assert actual == expected
Example #22
0
    def test_get_model_sets(self, get_sector_model):
        SectorModel = get_sector_model

        elec_scenario = ScenarioModel('scenario')
        elec_scenario.add_output('output', Mock(), Mock(), 'unit')

        elec_scenario.add_data(np.array([[[123]]]), [2010])

        energy_model = SectorModel('model')
        energy_model.add_input('input', Mock(), Mock(), 'unit')
        energy_model.add_dependency(elec_scenario, 'output', 'input')

        sos_model = SosModel('energy_sos_model')
        sos_model.add_model(energy_model)
        sos_model.add_model(elec_scenario)

        sos_model.check_dependencies()

        actual = sos_model._get_model_sets_in_run_order()
        expected = ['scenario', 'model']

        for model, name in zip(actual, expected):
            assert model.name == name
Example #23
0
    def test_topological_sort(self, get_sector_model):
        regions = Mock()
        regions.name = 'test_regions'
        intervals = Mock()
        intervals.name = 'test_intervals'

        SectorModel = get_sector_model
        elec_scenario = ScenarioModel('scenario')
        elec_scenario.add_output('output', regions, intervals, 'unit')

        energy_model = SectorModel('model')
        energy_model.add_input('input', regions, intervals, 'unit')
        energy_model.add_dependency(elec_scenario, 'output', 'input')

        sos_model = SosModel('energy_sos_model')
        sos_model.add_model(energy_model)
        sos_model.add_model(elec_scenario)

        sos_model.check_dependencies()

        graph = sos_model.dependency_graph
        actual = list(networkx.topological_sort(graph))
        assert actual == [elec_scenario, energy_model]
Example #24
0
    def test_composite_nested_sos_model(self, get_sector_model):
        """System of systems example with two nested SosModels, two Scenarios
        and one SectorModel. One dependency is defined at the SectorModel
        level, another at the lower SosModel level
        """
        SectorModel = get_sector_model

        elec_scenario = ScenarioModel('electricity_demand_scenario')
        elec_scenario.add_output('electricity_demand_output',
                                 Mock(), Mock(), 'unit')

        energy_model = SectorModel('energy_sector_model')
        energy_model.add_input(
            'electricity_demand_input', Mock(), Mock(), 'unit')
        energy_model.add_input('fluffiness_input', Mock(), Mock(), 'unit')
        energy_model.add_output('cost', Mock(), Mock(), 'unit')
        energy_model.add_output('fluffyness', Mock(), Mock(), 'unit')

        def energy_function(timestep, input_data):
            """Mimics the running of a sector model
            """
            results = {}
            demand = input_data['electricity_demand_input']
            fluff = input_data['fluffiness_input']
            results['cost'] = demand * 1.2894
            results['fluffyness'] = fluff * 22
            return results

        energy_model.simulate = energy_function
        energy_model.add_dependency(elec_scenario,
                                    'electricity_demand_output',
                                    'electricity_demand_input')

        sos_model_lo = SosModel('lower')
        sos_model_lo.add_model(elec_scenario)
        sos_model_lo.add_model(energy_model)

        fluf_scenario = ScenarioModel('fluffiness_scenario')
        fluf_scenario.add_output('fluffiness', Mock(), Mock(), 'unit')
        # fluf_scenario.add_data('fluffiness', np.array([[[12]]]), [2010])

        assert sos_model_lo.free_inputs.names == ['fluffiness_input']

        sos_model_lo.add_dependency(fluf_scenario,
                                    'fluffiness',
                                    'fluffiness_input')

        assert sos_model_lo.inputs.names == []

        sos_model_high = SosModel('higher')
        sos_model_high.add_model(sos_model_lo)
        sos_model_high.add_model(fluf_scenario)

        data_handle = get_data_handle(sos_model_high)
        actual = sos_model_high.simulate(data_handle)
        expected = {
            'fluffiness_scenario': {
                'fluffiness': 12
            },
            'lower': {
                'electricity_demand_scenario': {
                    'electricity_demand_output': 123
                },
                'energy_sector_model': {
                    'cost': 158.5962,
                    'fluffyness': 264
                }
            }
        }

        assert actual == expected