smif.model package¶
Submodules¶
smif.model.dependency module¶
-
class
smif.model.dependency.Dependency(source_model, source, function=None)[source]¶ Bases:
objectLink a model input to a data source
Parameters: - source_model (smif.composite.Model) – The source model object
- source (smif.metadata.Metadata) – The source parameter (output) object
- function=None (func) – A conversion function
-
convert(data, model_input)[source]¶ Convert dependency data to the resolution of
model_inputParameters: - data (numpy.ndarray) – The data series for conversion
- model_input (smif.metadata.MetadataSet) –
smif.model.model_set module¶
Wrap and solve a set of interdependent models
Given a directed graph of dependencies between models, any cyclic dependencies are contained within the strongly-connected components of the graph.
A ModelSet corresponds to the set of models within a single strongly- connected component. This class provides the machinery necessary to find a solution to each of the interdependent models.
The current implementation first estimates the outputs for each model in the set, guaranteeing that each model will then be able to run, then begins iterating, running every model in the set at each iteration, monitoring the model outputs over the iterations, and stopping at timeout, divergence or convergence.
-
class
smif.model.model_set.ModelSet(models, max_iterations=25, relative_tolerance=1e-05, absolute_tolerance=1e-08)[source]¶ Bases:
smif.model.CompositeModelWraps a set of interdependent models
Parameters: - models (list) – A list of
smif.model.Model - max_iterations (int, default=25) – The maximum number of iterations that the model set will run before returning results
- relative_tolerance (float, default=1e-05) – Used to calculate when the model interations have converged
- absolute_tolerance (float, default=1e-08) – Used to calculate when the model interations have converged
-
timestep¶ int
-
iterated_results¶ dict – Holds results for each iteration upto max_iterations
-
max_iterations¶ int – The maximum number of iterations
-
models¶ list – The list of
smif.model.Modelsubclasses
-
converged()[source]¶ Check whether the results of a set of models have converged.
Returns: converged – True if the results have converged to within a tolerance Return type: bool Raises: DiverganceError– If the results appear to be diverging
-
get_last_iteration_results()[source]¶ Return results from the last iteration
Returns: results – Dictionary of Model results, keyed by model name Return type: dict
- models (list) – A list of
smif.model.scenario_model module¶
-
class
smif.model.scenario_model.ScenarioModel(name)[source]¶ Bases:
smif.model.ModelRepresents exogenous scenario data
Parameters: name (string) – The unique name of this scenario -
add_data(output, data, timesteps)[source]¶ Add data to the scenario
Parameters: - output (str) – The name of the output to which to add data
- data (numpy.ndarray) –
- timesteps (list) –
Example
>>> elec_scenario = ScenarioModel('elec_scenario') >>> data = np.array([[[120.23]]]) >>> timesteps = [2010] >>> elec_scenario.add_data(data, timesteps)
-
add_output(name, spatial_resolution, temporal_resolution, units)[source]¶ Add an output to the scenario model
Parameters: - name (str) –
- spatial_resolution (
smif.convert.area.RegionRegister) – - temporal_resolution (
smif.convert.interval.TimeIntervalRegister) – - units (str) –
-
get_data(output)[source]¶ Get data associated with output
Parameters: output (str) – The name of the output for which to retrieve data
-
timesteps= None¶ The scenario set to which this scenario belongs
-
smif.model.sector_model module¶
This module acts as a bridge to the sector models from the controller
The SectorModel exposes several key methods for running wrapped
sector models. To add a sector model to an instance of the framework,
first implement SectorModel.
Utility Methods¶
A number of utility methods are included to ease the integration of a SectorModel wrapper within a System of Systems model. These include:
- get_scenario_data(input_name)
- Get an array of scenario data (timestep-by-region-by-interval)
- get_region_names(region_set_name)
- Get a list of region names
- get_interval_names(interval_set_name)
- Get a list of interval names
Key Functions¶
This class performs several key functions which ease the integration of sector models into the system-of-systems framework.
The user must implement the various abstract functions throughout the class to
provide an interface to the sector model, which can be called upon by the
framework. From the model’s perspective, SectorModel provides a bridge
from the sector-specific problem representation to the general representation
which allows reasoning across infrastructure systems.
The key functions include
- converting input/outputs to/from geographies/temporal resolutions
- converting control vectors from the decision layer of the framework, to asset Interventions specific to the sector model
- returning scaler/vector values to the framework to enable measurements of performance, particularly for the purposes of optimisation and rule-based approaches
-
class
smif.model.sector_model.SectorModel(name)[source]¶ Bases:
smif.model.ModelA representation of the sector model with inputs and outputs
Parameters: name (str) – The unique name of the sector model -
add_input(name, spatial_resolution, temporal_resolution, units)[source]¶ Add an input to the sector model
The inputs should be specified in a list. For example:
- name: electricity_price spatial_resolution: GB temporal_resolution: annual units: £/kWh
Parameters: - name (str) –
- spatial_resolution (
smif.convert.area.RegionSet) – - temporal_resolution (
smif.convert.interval.IntervalSet) – - units (str) –
-
add_output(name, spatial_resolution, temporal_resolution, units)[source]¶ Add an output to the sector model
Parameters: - name (str) –
- spatial_resolution (
smif.convert.area.RegionSet) – - temporal_resolution (
smif.convert.interval.IntervalSet) – - units (str) –
-
extract_obj(results)[source]¶ Implement this method to return a scalar value objective function
This method should take the results from the output of the
simulate()method, process the results, and return a scalar value which can be used as a component of the objective function by the decision layerParameters: results (dict) – A nested dict of the results from the simulate()methodReturns: A scalar component generated from the simulation model results Return type: float
-
get_interval_names(interval_set_name)[source]¶ Get the list of interval names for
interval_set_nameReturns: A list of interval names Return type: list
-
get_region_names(region_set_name)[source]¶ Get the list of region names for
region_set_nameReturns: A list of region names Return type: list
-
get_scenario_data(input_name)[source]¶ Returns all scenario dependency data as a numpy array
Returns: A numpy.ndarray which has the dimensions timestep-by-regions-by-intervals Return type: numpy.ndarray
-
initialise(initial_conditions)[source]¶ Implement this method to set up the model system
This method is called as the SectorModel is constructed, and prior to establishment of dependencies and other data links.
Parameters: initial_conditions (list) – A list of past Interventions, with build dates and locations as necessary to specify the infrastructure system to be modelled.
-
intervention_names¶ The names of the interventions
Returns: A list of the names of the interventions Return type: list
-
simulate(timestep, data=None)[source]¶ Implement this method to run the model
Parameters: Returns: results – This method should return a results dictionary
Return type: Notes
In the results returned from the
simulate()method:interval- should reference an id from the interval set corresponding to the output parameter, as specified in model configuration
region- should reference a region name from the region set corresponding to the output parameter, as specified in model configuration
-
user_data¶ A utility dictionary provided for use by the model wrapper
-
-
class
smif.model.sector_model.SectorModelBuilder(name, sector_model=None)[source]¶ Bases:
objectBuild the components that make up a sectormodel from the configuration
Parameters: - name (str) – The name of the sector model
- sector_model (smif.model.SectorModel, default=None) – The sector model object
Returns: Return type: SectorModelExamples
Call
SectorModelBuilder.construct()to populate aSectorModelobject andSectorModelBuilder.finish()to return the validated and dependency-checked system-of-systems model.>>> builder = SectorModelBuilder(name, secctor_model) >>> builder.construct(config_data) >>> sos_model = builder.finish()
-
add_interventions(intervention_list)[source]¶ Add interventions to the sector model
Parameters: intervention_list (list) – A list of dicts of interventions
-
add_parameters(parameter_config)[source]¶ Add parameter configuration to sector model
Parameters: parameter_config (list) – A list of dicts with keys name,description,absolute_range,suggested_range,default_value,units,parent
-
construct(sector_model_config)[source]¶ Constructs the sector model
Parameters: sector_model_config (dict) – The sector model configuration data
-
static
intervention_state_from_data(intervention_data)[source]¶ Unpack an intervention from the initial system to extract StateData
smif.model.sos_model module¶
This module coordinates the software components that make up the integration framework.
A system of systems model contains simulation and scenario models, and the dependencies between the models.
-
class
smif.model.sos_model.SosModel(name)[source]¶ Bases:
smif.model.CompositeModelConsists of the collection of models joined via dependencies
This class is populated at runtime by the
SosModelBuilderand called fromsmif.cli.run_model(). SosModel inherits fromsmif.composite.Model.Parameters: name (str) – The unique name of the SosModel -
add_model(model)[source]¶ Adds a sector model to the system-of-systems model
Parameters: model ( smif.sector_model.SectorModel) – A sector model wrapper
-
check_dependencies()[source]¶ For each contained model, compare dependency list against list of available models and build the dependency graph
-
get_decisions(model, timestep)[source]¶ Gets the interventions that correspond to the decisions
Parameters: - model (
smif.sector_model.SectorModel) – The instance of the sector model wrapper to run - timestep (int) – The current model year
- TODO (Move into DecisionManager class) –
- model (
-
intervention_names¶ Names (id-like keys) of all known asset type
-
results¶ Get nested dict of model results
Returns: Nested dictionary in the format results[str:model][str:parameter] Return type: dict
-
scenario_models¶ Scenario model objects contained in the SosModel
Returns: A dict of scenario model objects Return type: dict
-
sector_models¶ Sector model objects contained in the SosModel
Returns: A dict of sector model objects Return type: dict
-
set_data(model, timestep, results)[source]¶ Sets results output from model as data available to other/future models
Stores only latest estimated results (i.e. not holding on to iterations here while trying to solve interdependencies)
-
set_state(model, from_timestep, state)[source]¶ Sets state output from model ready for next timestep
-
simulate(timestep, data=None)[source]¶ Run the SosModel
Returns: results – Nested dict keyed by model name, parameter name Return type: dict
-
-
class
smif.model.sos_model.SosModelBuilder(name='global')[source]¶ Bases:
objectConstructs a system-of-systems model
Builds a
SosModel.Parameters: name (str, default='') – The unique name of the SosModel Examples
Call
SosModelBuilder.construct()to populate aSosModelobject andSosModelBuilder.finish()to return the validated and dependency-checked system-of-systems model.>>> builder = SosModelBuilder('test_model') >>> builder.construct(config_data, timesteps) >>> sos_model = builder.finish()
-
add_dependencies(dependency_list)[source]¶ Add dependencies between models
Parameters: dependency_list (list) – A list of dicts of dependency configuration data Examples
>>> dependencies = [{'source_model': 'raininess', 'source_model_output': 'raininess', 'sink_model': 'water_supply', 'sink_model_input': 'raininess'}] >>> builder.add_dependencies(dependencies)
-
construct(sos_model_config)[source]¶ Set up the whole SosModel
Parameters: sos_model_config (dict) – A valid system-of-systems model configuration dictionary
-
finish()[source]¶ Returns a configured system-of-systems model ready for operation
Includes validation steps, e.g. to check dependencies
-
load_models(model_list)[source]¶ Loads the sector models into the system-of-systems model
Parameters: model_list (list) – A list of SectorModel objects
-
load_scenario_models(scenario_list)[source]¶ Loads the scenario models into the system-of-systems model
Parameters: scenario_list (list) – A list of ScenarioModel objects
-
set_convergence_abs_tolerance(config_data)[source]¶ Set the absolute tolerance for iterating class::smif.ModelSet to convergence
-
Module contents¶
Implements a composite scenario/sector model/system-of-systems model
Begin by declaring the atomic units (scenarios and sector models) which make up
a the composite system-of-systems model and then add these to the composite.
Declare dependencies by using the add_dependency() method, passing in a
reference to the source model object, and a pointer to the model output
and sink parameter name for the destination model.
Run the model by calling the simulate() method, passing in a dictionary
containing data for any free hanging model inputs, not linked through a
dependency. A fully defined SosModel should have no hanging model inputs, and
can therefore be called using simulate() with no arguments.
Responsibility for passing required data to the contained models lies with the calling class. This means data is only ever passed one layer down. This simplifies the interface, and allows as little or as much hiding of data, dependencies and model inputs as required.
Example
A very simple example with just one scenario:
>>> elec_scenario = ScenarioModel('scenario', ['demand'])
>>> elec_scenario.add_data({'demand': 123})
>>> sos_model = SosModel('simple')
>>> sos_model.add_model(elec_scenario)
>>> sos_model.simulate()
{'scenario': {'demand': 123}}
A more comprehensive example with one scenario and one scenario model:
>>> elec_scenario = ScenarioModel('scenario', ['output'])
>>> elec_scenario.add_data({'output': 123})
>>> energy_model = SectorModel('model', [], [])
>>> energy_model.add_input('input')
>>> energy_model.add_dependency(elec_scenario, 'output', 'input')
>>> energy_model.add_executable(lambda x: x)
>>> sos_model = SosModel('blobby')
>>> sos_model.add_model(elec_scenario)
>>> sos_model.add_model(energy_model)
>>> sos_model.simulate()
{'model': {'input': 123}, 'scenario': {'output': 123}}
-
class
smif.model.CompositeModel(name)[source]¶ Bases:
smif.model.ModelOverride to implement models which contain models.
Inherited by smif.model.sos_model.SosModel and smif.model.model_set.ModelSet
-
free_inputs¶ Returns the free inputs not linked to a dependency at this layer
For this composite
CompositeModelthis includes the free_inputs from all contained smif.model.Model objectsFree inputs are passed up to higher layers for deferred linkages to dependencies.
Returns: Return type: smif.metadata.MetadataSet
-
parameters¶ Returns all the contained parameters as {model name – ParameterList}
Returns: A combined collection of parameters for all the contained models Return type: smif.parameters.ParameterList
-
-
class
smif.model.Model(name)[source]¶ Bases:
objectAbstract class represents the interface used to implement the composite SosModel and leaf classes SectorModel and Scenario.
Parameters: - name (str) –
- inputs (smif.metadata.MetaDataSet) –
- outputs (smif.metadata.MetaDataSet) –
-
add_dependency(source_model, source, sink, function=None)[source]¶ Adds a dependency to the current Model object
Parameters:
-
add_parameter(parameter_dict)[source]¶ Add a parameter to the model
Parameters: parameter_dict (dict) – Contains the keys name,description,absolute_range,suggested_range,default_value,units
-
free_inputs¶ 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: Return type: smif.metadata.MetadataSet
-
model_inputs¶ All model inputs defined at this layer
Returns: Return type: smif.metadata.MetadataSet
-
model_outputs¶ All model outputs defined at this layer
Returns: Return type: smif.metadata.MetadataSet
-
parameters¶ A list of parameters
Returns: Return type: smif.parameters.ParameterList