API documentation for the base_model module#
The base_model module defines the high level API for
the different models within the Virtual Ecosystem. The module creates the
BaseModel abstract base class (ABC) which
defines a consistent API for subclasses defining an actual model. The API defines
abstract methods for each of the key stages in the workflow of running a model:
individual subclasses are required to provide model specific implementations for
each stage, although the specific methods may simply do nothing if no action is needed
at that stage. The stages are:
Creating a model instance (
BaseModel).Setup a model instance (
_setup()). This method should include any initialization logic including validating and populating class attributes.Perform any spinup required to get a model state to equilibrate (
spinup()).Update the model from one time step to the next
update()).Cleanup any unneeded resources at the end of a simulation (
cleanup()).
The BaseModel class also provides default
implementations for the __repr__()
and __str__() special methods.
Declaring new subclasses#
The BaseModel has the following class
attributes that must be specified as arguments to the subclass declaration:
This behaviour is defined in the BaseModel.__init_subclass__() method, which also
gives example code for declaring a new subclass.
The usage of these attributes is described in their docstrings and each is validated when a new subclass is created using the following private methods of the class:
Model checking#
The BaseModel abstract base class defines
the __init_subclass__() class
method. This method is called automatically whenever a subclass of the ABC is imported
and validates the class attributes for the new model class.
The BaseModel.__init__ method#
Each model subclass should include an __init__ method that defines all
model specific attributes. The __init__ should not contain any further
initialization logic, which should happen in the subclass _setup method instead.
The __init__ method must call the
BaseModel.__init__()
method, as this populates core shared model attributes - see the linked method
description for details.
super().__init__(data, core_components)
The from_config factory method#
The ABC also defines the abstract class method
from_config(). This method must be
defined by subclasses and must be a factory method that returns an instance of the model
subclass. The method must follow the signature of that method, providing:
dataas an instance ofData.core_componentsas an instance ofCoreComponents.configurationas an instance ofCompiledConfiguration.
The method should provide any code to validate the configuration for that model and then use the configuration to initialise and return a new instance of the class.
Model registration#
Models have two core components: the
BaseModel subclass itself (model) and a
model configuration module that both defines the configuration options and constants
associated with the model and provides validation of configuration data from TOML files.
All model modules must register these components when they are imported: see the
registry module.
Classes:
|
A superclass for all Virtual Ecosystem disturbance models. |
|
A superclass for all Virtual Ecosystem models. |
Functions:
Discover all the disturbances in Virtual Ecosystem. |
|
Discover all the models in Virtual Ecosystem. |
|
|
Convert a snake_case string to CamelCase. |
- class virtual_ecosystem.core.base_model.BaseDisturbance(data: Data, models: dict[str, BaseModel], disturbance_timing: DisturbanceTiming, **kwargs)[source]#
A superclass for all Virtual Ecosystem disturbance models.
This abstract base class defines the shared common methods and attributes used as an API across all Virtual Ecosystem disturbance models. This includes functions to setup and run the specific model.
The base class defines the core abstract methods that must be defined in subclasses as well as shared helper functions.
- Parameters:
data – A
Datainstance containing variables to be used in the model.core_components – A
CoreComponentsinstance containing shared core elements used throughout models.
Methods:
__init__(data, models, disturbance_timing, ...)Performs core initialization for BaseModel subclasses.
__init_subclass__(model_name, ...)Checks the disturbed models and variables are all known.
__repr__()Represent a Disturbance as a string from the attributes listed in _repr.
_check_model_name(model_name)Check the model_name attribute is valid.
disturb(time_index)Run the disturbance, updating the self.data and/or self.models as needed.
from_config(data, configuration, ...)Factory function to unpack config and initialise a model instance.
Attributes:
A Data instance providing access to the shared simulation data.
A list of data variables that will be updated.
A list of model names that this disturbance will affect.
The model name.
The models this disturbance will disturb.
The DisturbanceTiming details used in the model.
- __init__(data: Data, models: dict[str, BaseModel], disturbance_timing: DisturbanceTiming, **kwargs)[source]#
Performs core initialization for BaseModel subclasses.
This method must be called in the
__init__method of all subclasses.data: the providedDatainstance.models: dictionary ofBaseModelinstances of the models available in the simulation.disturbance_timing: theDisturbanceTiminginstance.
- classmethod __init_subclass__(model_name: str, disturbed_models: tuple[str, ...], data_variables_disturbed: tuple[str, ...])[source]#
Checks the disturbed models and variables are all known.
If so, it adds the disturbance to the registry.
- __repr__() str[source]#
Represent a Disturbance as a string from the attributes listed in _repr.
Each entry in self._repr is a tuple of strings providing a path through the model hierarchy. The method assembles the tips of each path into a repr string.
- classmethod _check_model_name(model_name: str) str[source]#
Check the model_name attribute is valid.
- Parameters:
model_name – The
model_nameattribute to be used for a subclass.- Raises:
ValueError – the model_name is not a string.
- Returns:
The provided
model_nameif valid
- data#
A Data instance providing access to the shared simulation data.
- data_variables_disturbed: tuple[str, ...]#
A list of data variables that will be updated.
This list will be used to validate the configuration and ensure that all the variables to be disturbed will be available in the simulation. Disturbance models do not create new variables.
- disturb(time_index: int) None[source]#
Run the disturbance, updating the self.data and/or self.models as needed.
First, the timing is checked, returning if the disturbance shall not be run at this timestep. Otherwise, it calls the inner _disturb method where the actual disturbance is executed.
- Parameters:
time_index – The index of the current timestep.
- disturbed_models: tuple[str, ...]#
A list of model names that this disturbance will affect.
This list will be used to validate the configuration - check that all the models to disturb are available in the simulation - as well at runtime to select those models when creating an instance of the disturbance.
- abstractmethod classmethod from_config(data: Data, configuration: CompiledConfiguration, core_components: CoreComponents, models: dict[str, BaseModel]) BaseDisturbance[source]#
Factory function to unpack config and initialise a model instance.
- model_name: str#
The model name.
This class attribute sets the name used to refer to identify the disturbance class in the disturbance registry, within the configuration settings and in logging messages.
- models#
The models this disturbance will disturb.
- timing#
The DisturbanceTiming details used in the model.
- class virtual_ecosystem.core.base_model.BaseModel(data: Data, core_components: CoreComponents, static: bool = False, *args: Any)[source]#
A superclass for all Virtual Ecosystem models.
This abstract base class defines the shared common methods and attributes used as an API across all Virtual Ecosystem models. This includes functions to setup, spin up and update the specific model, as well as a function to cleanup redundant model data.
The base class defines the core abstract methods that must be defined in subclasses as well as shared helper functions.
- Parameters:
data – A
Datainstance containing variables to be used in the model.core_components – A
CoreComponentsinstance containing shared core elements used throughout models.
Methods:
__init__(data, core_components[, static])Performs core initialisation for BaseModel subclasses.
__init_subclass__(model_name, ...)Initialise subclasses deriving from BaseModel.
__repr__()Represent a Model as a string from the attributes listed in _repr.
__str__()Inform user what the model type is.
_check_model_name(model_name)Check the model_name attribute is valid.
_check_model_update_bounds(model_update_bounds)Check that the model_update_bounds attribute is valid.
Check a model variables attribute property is valid.
_setup(*args)Function to setup the model during initialisation.
Check the init data contains the required variables.
cleanup()Function to delete objects within the class that are no longer needed.
from_config(data, configuration, core_components)Factory function to unpack config and initialise a model instance.
spinup()Function to spin up the model.
update(time_index, **kwargs)Function to update the model.
Attributes:
The core constants used in the model.
A Data instance providing access to the shared simulation data.
The Grid details used in the model.
The LayerStructure details used in the model.
The model name.
The ModelTiming details used in the model.
Bounds on model update frequencies.
Variables that are initialised by the model during the first update.
Variables that are initialised by the model during the setup.
Required variables for model initialisation.
Variables that are required by the update method of the model.
Variables that are updated by the model.
- __init__(data: Data, core_components: CoreComponents, static: bool = False, *args: Any)[source]#
Performs core initialisation for BaseModel subclasses.
This method must be called in the
__init__method of all subclasses.It populates a set of shared instance attributes from the provided
CoreComponentsandDatavalue:data: the providedDatainstance.model_timing: theModelTiminginstance from thecore_componentsargument.grid: theGridinstance from thecore_componentsargument.layer_structure: theLayerStructureinstance from thecore_componentsargument.core_constants: theCoreConstantsinstance from thecore_componentsargument.
It then uses the
check_init_data()method to confirm that the required variables for the model are present in the provideddataattribute.
- classmethod __init_subclass__(model_name: str, model_update_bounds: tuple[str, str], vars_required_for_init: tuple[str, ...], vars_updated: tuple[str, ...], vars_required_for_update: tuple[str, ...], vars_populated_by_init: tuple[str, ...], vars_populated_by_first_update: tuple[str, ...]) None[source]#
Initialise subclasses deriving from BaseModel.
This method runs when a new BaseModel subclass is imported. It adds the new subclasses to the model registry and populates the values of the class attributes.
Subclasses of the BaseModel need to provide the values for class attributes in their signatures. Those values are defined by the arguments to this method, which validates and sets the class attributes for the subclass. See
BaseModelfor details on the class attributes. For example:class ExampleModel( BaseModel, model_name='example', model_update_bounds= ("30 minutes", "3 months"), vars_required_for_init=(("required_variable", ("spatial",)),), vars_updated=("updated_variable"), ): ...
- Parameters:
model_name – The model name to be used
model_update_bounds – Bounds on update intervals handled by the model
vars_required_for_init – A tuple of the variables required to create a model instance.
vars_populated_by_init – A tuple of the variables initialised when a model instance is created.
vars_populated_by_first_update – A tuple of the variables initialised when a model update method first run.
vars_required_for_update – A tuple of the variables required to update a model instance.
vars_updated – A tuple of the variable names updated by the model.
- Raises:
ValueError – If the model_name or vars_required_for_init properties are not defined
TypeError – If model_name is not a string
- __repr__() str[source]#
Represent a Model as a string from the attributes listed in _repr.
Each entry in self._repr is a tuple of strings providing a path through the model hierarchy. The method assembles the tips of each path into a repr string.
- classmethod _check_model_name(model_name: str) str[source]#
Check the model_name attribute is valid.
- Parameters:
model_name – The
model_nameattribute to be used for a subclass.- Raises:
ValueError – the model_name is not a string.
- Returns:
The provided
model_nameif valid
- classmethod _check_model_update_bounds(model_update_bounds: tuple[str, str]) tuple[Quantity, Quantity][source]#
Check that the model_update_bounds attribute is valid.
This is used to validate the class attribute
model_update_bounds, which describes the lower and upper bounds on model update frequency. The lower bound must be less than the upper bound.- Parameters:
model_update_bounds – A tuple of two strings representing time periods that can be parsed using
pint.Quantity.- Raises:
ValueError – If the provided model_update_bounds cannot be parsed as
pint.Quantitywith time units or if the lower bound is not less than the upper bound.- Returns:
The validated model_update_bounds, converted to a tuple of
pint.Quantityvalues.
- classmethod _check_variables_attribute(variables_attribute_name: str, variables_attribute_value: tuple[str, ...]) tuple[str, ...][source]#
Check a model variables attribute property is valid.
Creating an instance of the BaseModel class requires that several variables attributes are set. Each of these provides a list of variable names that are required or updated by the model at various points. This method is used to validate the structure of the new instance and ensure the resulting model structure is consistent.
- Parameters:
variables_attribute_name – The name of the variables attribute
variables_attribute_value – The provided value for the variables attribute
- Raises:
TypeError – the value of the model variables attribute has the wrong type structure.
- Returns:
The validated variables attribute value
- check_init_data() None[source]#
Check the init data contains the required variables.
This method is used to check that the set of variables defined in the
vars_required_for_initclass attribute are present in theDatainstance used to create a new instance of the class.- Raises:
ValueError – If the Data instance does not contain all the required variables or if those variables do not map onto the required axes.
- abstractmethod cleanup() None[source]#
Function to delete objects within the class that are no longer needed.
- core_constants: CoreConstants#
The core constants used in the model.
- abstractmethod classmethod from_config(data: Data, configuration: CompiledConfiguration, core_components: CoreComponents) BaseModel[source]#
Factory function to unpack config and initialise a model instance.
- layer_structure: LayerStructure#
The LayerStructure details used in the model.
- model_name: str#
The model name.
This class attribute sets the name used to refer to identify the model class in the
MODULE_REGISTRY, within the configuration settings and in logging messages.
- model_timing: ModelTiming#
The ModelTiming details used in the model.
- model_update_bounds: tuple[Quantity, Quantity]#
Bounds on model update frequencies.
This class attribute defines two time intervals that define a lower and upper bound on the update frequency that can reasonably be used with a model. Models updated more often than the lower bound may fail to capture transient dynamics and models updated more slowly than the upper bound may fail to capture important temporal patterns.
- update(time_index: int, **kwargs: Any) None[source]#
Function to update the model.
If the model is static, the inner update method, self._update will only run once, at most.
- Parameters:
time_index – The index representing the current time step in the data object.
**kwargs – Further arguments to the update method.
- vars_populated_by_first_update: tuple[str, ...]#
Variables that are initialised by the model during the first update.
These are the variables that are initialised by the model and stored in the data object when running the update method for the first time. They will be available for other models to use in their update methods but not in the setup methods.
- vars_populated_by_init: tuple[str, ...]#
Variables that are initialised by the model during the setup.
These are the variables that are initialised by the model and stored in the data object when running the setup method and that will be available for other models to use in their own setup or update methods.
- vars_required_for_init: tuple[str, ...]#
Required variables for model initialisation.
This class property defines a set of variable names that must be present in the
Datainstance used to initialise an instance of this class. It is a tuple containing zero or more tuples, each providing a variable name and then a tuple of zero or more core axes that the variable must map onto.For example:
(('temperature', ('spatial', 'temporal')),)
- vars_required_for_update: tuple[str, ...]#
Variables that are required by the update method of the model.
These variables should have been initialised by another model or loaded from external sources, but in either case they will be available in the data object.
- vars_updated: tuple[str, ...]#
Variables that are updated by the model.
At the moment, this tuple is used to decide which variables to output from the
Dataobject, i.e. every variable updated by a model used in the specific simulation. It is also be used warn if multiple models will be updating the same variable and to verify that these variables are indeed initialised by another model, and therefore will be available.
- virtual_ecosystem.core.base_model.discover_disturbances() list[type[BaseDisturbance]][source]#
Discover all the disturbances in Virtual Ecosystem.