smif.model package

Submodules

smif.model.dependency module

class smif.model.dependency.Dependency(source_model, source, function=None)[source]

Bases: object

Link 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_input

Parameters:
get_data(timestep, model_input)[source]

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.CompositeModel

Wraps 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.Model subclasses

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
guess_results(model, timestep, data)[source]

Dependency-free guess at a model’s result set.

Initially, guess zeroes, or the previous timestep’s results.

Parameters:
  • model (smif.model.composite.Model) –
  • timestep (int) –
  • data (dict) –
Returns:

results

Return type:

dict

simulate(timestep, data=None)[source]

Runs a set of one or more models

Parameters:
  • timestep (int) –
  • data (dict, default=None) –

smif.model.scenario_model module

class smif.model.scenario_model.ScenarioModel(name)[source]

Bases: smif.model.Model

Represents 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:
as_dict()[source]
get_data(output)[source]

Get data associated with output

Parameters:output (str) – The name of the output for which to retrieve data
simulate(timestep, data=None)[source]

Returns the scenario data

timesteps = None

The scenario set to which this scenario belongs

class smif.model.scenario_model.ScenarioModelBuilder(name)[source]

Bases: object

construct(scenario_config, data, timesteps)[source]

Build the complete and populated ScenarioModel

Assumes that a ScenarioModel can only have one output

Parameters:
  • scenario_config (dict) –
  • data (dict) – A dictionary of scenario data, with keys scenario parameter names
  • timesteps (list) – A list of integer years e.g. [2010, 2011, 2013]
finish()[source]

Return the built ScenarioModel

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.Model

A 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:
add_output(name, spatial_resolution, temporal_resolution, units)[source]

Add an output to the sector model

Parameters:
as_dict()[source]

Serialize the SectorModel object as a dictionary

Returns:
Return type:dict
before_model_run()[source]

Implement this method to conduct pre-model run tasks

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 layer

Parameters:results (dict) – A nested dict of the results from the simulate() method
Returns: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_name

Returns:A list of interval names
Return type:list
get_region_names(region_set_name)[source]

Get the list of region names for region_set_name

Returns: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:
  • timestep (int) – The timestep for which to run the SectorModel
  • data (dict, default=None) – A collection of state, parameter values, dependency inputs
Returns:

results – This method should return a results dictionary

Return type:

dict

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

validate()[source]

Validate that this SectorModel has been set up with sufficient data to run

class smif.model.sector_model.SectorModelBuilder(name, sector_model=None)[source]

Bases: object

Build 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:

SectorModel

Examples

Call SectorModelBuilder.construct() to populate a SectorModel object and SectorModelBuilder.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_initial_conditions(initial_conditions)[source]

Adds initial conditions (state) for a model

add_inputs(input_dicts)[source]

Add inputs to the sector model

add_interventions(intervention_list)[source]

Add interventions to the sector model

Parameters:intervention_list (list) – A list of dicts of interventions
add_outputs(output_dicts)[source]

Add outputs to the sector model

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
create_initial_system(initial_conditions)[source]

Set up model with initial system

finish()[source]

Validate and return the sector model

static intervention_state_from_data(intervention_data)[source]

Unpack an intervention from the initial system to extract StateData

load_model(model_path, classname)[source]

Dynamically load model module

Parameters:
  • model_path (str) – The path to the python module which contains the SectorModel implementation
  • classname (str) – The name of the class of the SectorModel implementation
validate()[source]

Check and/or assert that the sector model is correctly set up - should raise errors if invalid

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.CompositeModel

Consists of the collection of models joined via dependencies

This class is populated at runtime by the SosModelBuilder and called from smif.cli.run_model(). SosModel inherits from smif.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
as_dict()[source]

Serialize the SosModel object

Returns:
Return type:dict
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) –
get_state(model, timestep)[source]

Gets the state to pass to SectorModel.simulate

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
timestep_after(timestep)[source]

Returns the timestep after a given timestep, or None

Parameters:timestep (str) –
Returns:
Return type:str
timestep_before(timestep)[source]

Returns the timestep previous to a given timestep, or None

Parameters:timestep (str) –
Returns:
Return type:str
class smif.model.sos_model.SosModelBuilder(name='global')[source]

Bases: object

Constructs a system-of-systems model

Builds a SosModel.

Parameters:name (str, default='') – The unique name of the SosModel

Examples

Call SosModelBuilder.construct() to populate a SosModel object and SosModelBuilder.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

set_convergence_rel_tolerance(config_data)[source]

Set the relative tolerance for iterating class::smif.ModelSet to convergence

set_max_iterations(config_data)[source]

Set the maximum iterations 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.Model

Override 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 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:
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: object

Abstract 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:
  • source_model (smif.composite.Model) – A reference to the source ~smif.composite.Model object
  • source (string) – The name of the model_output defined in the source_model
  • sink (string) – The name of a model_input defined in this object
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
simulate(timestep, data=None)[source]

Override to implement the generation of model results

Generate results for timestep using data

Parameters:
  • timestep (int) – The timestep for which to run the Model
  • data (dict, default=None) – A collection of state, parameter values, dependency inputs.
Returns:

results

Return type:

dict

smif.model.element_after(element, list_)[source]

Return the element after a given element in a list, or None if the given element is last or not in the list.

smif.model.element_before(element, list_)[source]

Return the element before a given element in a list, or None if the given element is first or not in the list.