def test_create_metadata_set(self, interval_set, region_set): """Create MetadataSet to hold a list of Metadata """ metadata_list = [{ "name": "heat_demand", "spatial_resolution": region_set, "temporal_resolution": interval_set, "units": "kilowatt" }] metadata_set = MetadataSet(metadata_list) # direct access to single metadata metadata = metadata_set["heat_demand"] assert metadata.name == "heat_demand" assert metadata.spatial_resolution == region_set assert metadata.temporal_resolution == interval_set assert metadata.units == "kilowatt" # direct access to list of contained metadata assert len(metadata_set) == 1 assert metadata_set.metadata == [ Metadata("heat_demand", region_set, interval_set, "kilowatt") ] # access single metadata attribute assert metadata_set.get_spatial_res("heat_demand") == region_set assert metadata_set.get_temporal_res("heat_demand") == interval_set assert metadata_set.get_units("heat_demand") == "kilowatt" # access list of metadata attributes assert metadata_set.names == ["heat_demand"] assert metadata_set.spatial_resolutions == [region_set] assert metadata_set.temporal_resolutions == [interval_set] assert metadata_set.units == ["kilowatt"]
def mock_model(): model = Mock() model.name = 'test_model' model.parameters = ParameterList() model.parameters.add_parameter({ 'name': 'smart_meter_savings', 'description': 'The savings from smart meters', 'absolute_range': (0, 100), 'suggested_range': (3, 10), 'default_value': 3, 'units': '%', 'parent': None }) regions = Mock() regions.name = 'test_regions' intervals = Mock() intervals.name = 'test_intervals' model.inputs = MetadataSet( [Metadata('test', regions, intervals, 'test_unit')]) model.outputs = MetadataSet( [Metadata('test', regions, intervals, 'test_unit')]) source_model = Mock() source_model.name = 'test_source' model.deps = { 'test': Dependency(source_model, Metadata('test_output', regions, intervals, 'test_unit'), Metadata('test', regions, intervals, 'test_unit')) } return model
def test_add_meta_object(self): metadata = Metadata("total_lane_kilometres", region_set, interval_set, "kilometer") metadata_set = MetadataSet([]) metadata_set.add_metadata_object(metadata) # access list of metadata attributes assert metadata_set.names == ["total_lane_kilometres"] assert metadata_set.spatial_resolutions == [region_set] assert metadata_set.temporal_resolutions == [interval_set] assert metadata_set.units == ["kilometer"]
def __init__(self, name): self.name = name self.description = '' self._inputs = MetadataSet([]) self._outputs = MetadataSet([]) self.deps = {} self._parameters = ParameterList() self.regions = get_region_register() self.intervals = get_interval_register() self.timesteps = [] self.logger = getLogger(__name__)
def test_key_error(self): """Expect a KeyError on trying to access missing Metadata """ metadata_set = MetadataSet([]) with raises(KeyError) as ex: metadata_set["missing"] assert "No metadata found for name 'missing'" in str(ex.value)
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
def test_sector_model_null_model(self, get_energy_sector_model): no_inputs = get_energy_sector_model no_inputs._model_inputs = MetadataSet([]) no_inputs.simulate = lambda x: x actual = no_inputs.simulate(2010) expected = 2010 assert actual == expected
def test_metadata_order(self, interval_set, region_set): """Expect list of Metadata to be sorted by name """ metadata_list = [ { "name": "total_lane_kilometres", "spatial_resolution": region_set, "temporal_resolution": interval_set, "units": "kilometer" }, { "name": "heat_demand", "spatial_resolution": region_set, "temporal_resolution": interval_set, "units": "kilowatt" }, ] metadata_set = MetadataSet(metadata_list) assert len(metadata_set) == 2 assert metadata_set.metadata == [ Metadata("heat_demand", region_set, interval_set, "kilowatt"), Metadata("total_lane_kilometres", region_set, interval_set, "kilometer") ]
def test_sector_model_null_model(self, get_energy_sector_model): no_inputs = get_energy_sector_model no_inputs._inputs = MetadataSet([]) no_inputs.simulate = lambda x: x data_handle = Mock() no_inputs.simulate(data_handle) data_handle.assert_not_called()
def test_one_free_input(self, get_sector_model): SectorModel = get_sector_model energy_model = SectorModel('energy_sector_model') expected = Metadata('electricity_demand_input', Mock(), Mock(), 'unit') energy_model._inputs = MetadataSet([expected]) actual = energy_model.free_inputs['electricity_demand_input'] assert actual == expected
def test_add_meta_dict(self): """Should allow adding a dict with required keys """ metadata = { "name": "total_lane_kilometres", "spatial_resolution": region_set, "temporal_resolution": interval_set, "units": "kilometers" } metadata_set = MetadataSet() metadata_set.add_metadata(metadata) # access list of metadata attributes assert metadata_set.names == ["total_lane_kilometres"] assert metadata_set.spatial_resolutions == [region_set] assert metadata_set.temporal_resolutions == [interval_set] assert metadata_set.units == ["kilometer"]
def test_iterate_over_populated(self): """Should initialise with list of metadata if provided """ metadata_list = [{ "name": "total_lane_kilometres", "spatial_resolution": region_set, "temporal_resolution": interval_set, "units": "kilometers" }] metadata_set = MetadataSet(metadata_list) expected_metadata = Metadata("total_lane_kilometres", region_set, interval_set, "kilometers") actual = metadata_set.metadata assert actual == [expected_metadata] actual = [(k, v) for k, v in metadata_set.items()] assert actual == [("total_lane_kilometres", expected_metadata)]
def free_inputs(self): """Returns the free inputs not linked to a dependency at this layer Free inputs are passed up to higher layers for deferred linkages to dependencies. Returns ------- smif.metadata.MetadataSet """ all_input_names = set(self.inputs.names) dep_input_names = set(dep.sink.name for dep in self.deps.values()) free_input_names = all_input_names - dep_input_names return MetadataSet(self.inputs[name] for name in free_input_names)
def test_get_temporal_property(self, two_output_metrics, interval_set): """Access different temporal resolutions for different metadata """ outputs = MetadataSet(two_output_metrics) assert outputs.get_temporal_res('total_cost') == interval_set assert outputs.get_temporal_res('water_demand') == interval_set with raises(KeyError) as ex: outputs.get_temporal_res('missing') assert "No metadata found for name 'missing'" in str(ex.value)
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)]
def test_one_free_input(self, get_sector_model): SectorModel = get_sector_model energy_model = SectorModel('energy_sector_model') input_metadata = { 'name': 'electricity_demand_input', 'spatial_resolution': Mock(), 'temporal_resolution': Mock(), 'units': 'unit' } expected = MetadataSet([input_metadata]) energy_model._model_inputs = expected assert energy_model.free_inputs['electricity_demand_input'] == \ expected['electricity_demand_input']
def test_access_registers(self, region_set, interval_set): """Individual Metadata in a Set should provide region and interval names when registers are available """ metadata_list = [ { "name": "total_lane_kilometres", "spatial_resolution": region_set, "temporal_resolution": interval_set, "units": "kilometers" } ] metadata_set = MetadataSet(metadata_list) metadata = metadata_set["total_lane_kilometres"] assert metadata.get_region_names() == ["a", "b"] assert metadata.get_interval_names() == ["winter", "spring", "summer", "autumn"]
def test_iterate_over_populated(self): metadata_list = [ { "name": "total_lane_kilometres", "spatial_resolution": region_set, "temporal_resolution": interval_set, "units": "kilometers" } ] metadata_set = MetadataSet(metadata_list) actual = metadata_set.metadata assert actual == [Metadata("total_lane_kilometres", region_set, interval_set, "kilometers")] assert [x for x in metadata_set] == [Metadata("total_lane_kilometres", region_set, interval_set, "kilometers")]
def free_inputs(self): """Returns the free inputs not linked to a dependency at this layer For this composite :class:`~smif.model.CompositeModel` this includes the free_inputs from all contained smif.model.Model objects Free inputs are passed up to higher layers for deferred linkages to dependencies. Returns ------- smif.metadata.MetadataSet """ # free inputs of current layer free_inputs = super().free_inputs.metadata # free inputs of all contained models for model in self.models.values(): free_inputs.extend(model.free_inputs.metadata) # compose a new MetadataSet containing the free inputs metadataset = MetadataSet(free_inputs) return metadataset
def test_iterate_over_empty(self): metadata_set = MetadataSet([]) assert metadata_set.metadata == [] assert [x for x in metadata_set] == []
def outputs(self): outputs = super().outputs.metadata for model in self.models.values(): outputs.extend(model.outputs.metadata) return MetadataSet(outputs)
def test_iterate_over_empty(self): """Should initialise as empty by default """ metadata_set = MetadataSet() assert metadata_set.metadata == [] assert [x for x in metadata_set] == []