Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions docs/source/development/design/defining_new_models.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,16 +463,14 @@ def from_config(

## Other model steps

There are four functions that must be included as part of the model class. The names and
roles of these functions might well change as the Virtual Ecosystem model develops, but
that kind of API change is something that would require significant discussion. Only the
`update` function is used at present. The other functions need to be included, but
there's no need to include any particular content within them (i.e. they can just be
function definitions with docstrings).
There are three methods that must be defined as part of the model class: `spinup`,
`update` and `cleanup`. The names and roles of these functions might well change as the
Virtual Ecosystem model develops, but that kind of API change is something that would
require significant discussion. Only the `update` function is used at present. The other
functions need to be defined, but there's no need to include any particular content
within them (i.e. they can just be function definitions with docstrings).

```python
def setup(self) -> None:
"""Placeholder function to set up the freshwater model."""

def spinup(self) -> None:
"""Placeholder function to spin up the freshwater model."""
Expand Down
18 changes: 10 additions & 8 deletions docs/source/virtual_ecosystem/implementation/main_simulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ science model. These are now used to initialise each requested model using the
for each model. This method checks that the configuration is valid for the science
model.

## Model setup
## Model intialisation

Some models require an additional setup step to calculate values for internal variables
from the initial loaded data or to set up further structures within the model, such as
representations of plant or animal communities. Each model will run the
{meth}`~virtual_ecosystem.core.base_model.BaseModel.setup` method defined for the
specific model. In simple science models, this method may not actually need to do
anything.
When a model instance is created, the
{meth}`~virtual_ecosystem.core.base_model.BaseModel.__init__` runs. This model
initialisation is responsible for any validation of initial model inputs, the
calculattion of values for internal variables from the initial loaded data and setting
up further structures within the model, such as representations of plant or animal
communities. Each model will run the
{meth}`~virtual_ecosystem.core.base_model.BaseModel.__init__` method defined for the
specific model.

## Model spinup

Expand All @@ -38,7 +40,7 @@ model is run as part of the simulation process described below.
## Simulation process

Now that the simulation core and science models have been configure and initialised,
along with any setup or spinup steps, the simulation itself starts.
along with any spinup steps, the simulation itself starts.

### Saving the initial state

Expand Down
2 changes: 1 addition & 1 deletion tests/core/test_base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ class InitVarModel(
# from_config, setup, spinup, update
# versus
# - Can't instantiate abstract class InitVarModel without an implementation for
# abstract methods 'cleanup', 'from_config', 'setup', 'spinup', 'update'
# abstract methods 'cleanup', 'from_config', 'spinup', 'update'
assert str(err.value).startswith("Can't instantiate abstract class InitVarModel ")


Expand Down
4 changes: 2 additions & 2 deletions tests/models/animals/test_animal_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def prepared_animal_model_instance(
functional_group_list_instance,
constants_instance,
):
"""Animal model instance in which setup has already been run."""
"""Full initialised animal model instance."""
from virtual_ecosystem.models.animal.animal_model import AnimalModel

model = AnimalModel(
Expand All @@ -25,7 +25,7 @@ def prepared_animal_model_instance(
functional_groups=functional_group_list_instance,
model_constants=constants_instance,
)
model.setup() # Ensure setup is called

return model


Expand Down
17 changes: 6 additions & 11 deletions virtual_ecosystem/core/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
at that stage. The stages are:

* Creating a model instance (:class:`~virtual_ecosystem.core.base_model.BaseModel`).
* Setup a model instance (:meth:`~virtual_ecosystem.core.base_model.BaseModel.setup`).
* Perform any spinup required to get a model state to equilibrate
(:meth:`~virtual_ecosystem.core.base_model.BaseModel.spinup`).
* Update the model from one time step to the next
Expand Down Expand Up @@ -119,8 +118,8 @@ class BaseModel(ABC):
"""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
API across all Virtual Ecosystem models. This includes methods to initialise, 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
Expand Down Expand Up @@ -182,19 +181,19 @@ class BaseModel(ABC):
"""

vars_populated_by_init: tuple[str, ...]
"""Variables that are initialised by the model during the setup.
"""Variables that are populated when initialising a model instance.

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.
object when running the __init__ method and that will be available for other models
to use in their own __init__ or update methods.
"""

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 methos.
other models to use in their update methods but not in the __init__ methods.
"""

def __init__(
Expand Down Expand Up @@ -246,10 +245,6 @@ def __init__(
# Check the configured update interval is within model bounds
self._check_update_speed()

@abstractmethod
def setup(self) -> None:
"""Function to use input data to set up the model."""

@abstractmethod
def spinup(self) -> None:
"""Function to spin up the model."""
Expand Down
12 changes: 4 additions & 8 deletions virtual_ecosystem/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,11 @@ def ve_run(
if progress:
print(f"* Models initialised: {', '.join(init_sequence.keys())}")

LOGGER.info("All models successfully intialised.")
LOGGER.info("All models successfully initialised.")

# Setup all models (those with placeholder setup processes won't change at all)
for model in models_init.values():
model.setup()

LOGGER.info("All models successfully set up.")

# TODO - A model spin up might be needed here in future
# TODO - A model spin up might be needed here in future. Maybe think about reporting
# here as placeholder spinups might be confusing? Can we have an optional ABC
# method, where we could test if it is defined.

# Create output folder if it does not exist
out_path = Path(config["core"]["data_output_options"]["out_path"])
Expand Down
13 changes: 1 addition & 12 deletions virtual_ecosystem/models/abiotic/abiotic_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class AbioticModel(
"stomatal_conductance",
"canopy_absorption",
),
vars_populated_by_init=( # TODO move functions from setup() to __init__
vars_populated_by_init=(
"soil_temperature",
"vapour_pressure_ref",
"vapour_pressure_deficit_ref",
Expand Down Expand Up @@ -191,12 +191,6 @@ def from_config(
model_constants=model_constants,
)

def setup(self) -> None:
"""No longer in use.

TODO: Remove when the base model is updated.
"""

def _setup(self) -> None:
"""Function to set up the abiotic model.

Expand Down Expand Up @@ -295,11 +289,6 @@ def update(self, time_index: int, **kwargs: Any) -> None:
**kwargs: Further arguments to the update method.
"""

# TODO This selection of layers should be included in LayerStructure at the
# start of the simulation and updated at each time step (except topsoil index)
# At the moment this is duplicated in setup() and other parts of the Virtual
# Ecosystem

# Wind profiles

# Reduce input variables to true above ground rows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class AbioticSimpleModel(
"leaf_area_index",
"layer_heights",
),
vars_populated_by_init=( # TODO move functionality from setup() to __init__
vars_populated_by_init=(
"soil_temperature",
"vapour_pressure_ref",
"vapour_pressure_deficit_ref",
Expand Down Expand Up @@ -118,12 +118,6 @@ def from_config(
model_constants=model_constants,
)

def setup(self) -> None:
"""No longer in use.

TODO: Remove when the base model is updated.
"""

def _setup(self) -> None:
"""Function to set up the abiotic simple model.

Expand Down
36 changes: 16 additions & 20 deletions virtual_ecosystem/models/animal/animal_model.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
"""The :mod:`~virtual_ecosystem.models.animal.animal_model` module creates a
:class:`~virtual_ecosystem.models.animal.animal_model.AnimalModel` class as a
child of the :class:`~virtual_ecosystem.core.base_model.BaseModel` class.
At present a lot of the abstract methods of the parent class (e.g.
:func:`~virtual_ecosystem.core.base_model.BaseModel.setup` and
:func:`~virtual_ecosystem.core.base_model.BaseModel.spinup`) are overwritten using
placeholder functions that don't do anything. This will change as the
Virtual Ecosystem model develops. The factory method
:func:`~virtual_ecosystem.models.animal.animal_model.AnimalModel.from_config`
exists in a more complete state, and unpacks a small number of parameters
from our currently pretty minimal configuration dictionary. These parameters are
then used to generate a class instance. If errors crop up here when converting the
information from the config dictionary to the required types
(e.g. :class:`~numpy.timedelta64`) they are caught and then logged, and at the end
of the unpacking an error is thrown. This error should be caught and handled
by downstream functions so that all model configuration failures can be reported as one.

The factory method
:func:`~virtual_ecosystem.models.animal.animal_model.AnimalModel.from_config` unpacks a
small number of parameters from our currently pretty minimal configuration dictionary.
These parameters are then used to generate a class instance. If errors crop up here when
converting the information from the config dictionary to the required types (e.g.
:class:`~numpy.timedelta64`) they are caught and then logged, and at the end of the
unpacking an error is thrown. This error should be caught and handled by downstream
functions so that all model configuration failures can be reported as one.

The :func:`~virtual_ecosystem.models.animal.animal_model.AnimalModel.spinup` and
:func:`~virtual_ecosystem.models.animal.animal_model.AnimalModel.cleanup` methods are
not currently used by the model and exist only as placeholders.
""" # noqa: D205

from __future__ import annotations
Expand Down Expand Up @@ -89,7 +89,7 @@ def __init__(
self._initialize_communities(functional_groups)
"""Create the dictionary of animal communities and populate each community with
animal cohorts."""
self.setup()
self._setup()
"""Initialize the data variables used by the animal model."""

def _setup_grid_neighbors(self) -> None:
Expand Down Expand Up @@ -179,12 +179,8 @@ def from_config(
model_constants=model_constants,
)

def setup(self) -> None:
"""Method to setup the animal model specific data variables.

TODO: rename this as something else because you've used it crazy

"""
def _setup(self) -> None:
"""Method to setup the animal model specific data variables."""

# animal respiration data variable
# the array should have one value for each animal community
Expand Down
31 changes: 14 additions & 17 deletions virtual_ecosystem/models/litter/litter_model.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
"""The :mod:`~virtual_ecosystem.models.litter.litter_model` module creates a
:class:`~virtual_ecosystem.models.litter.litter_model.LitterModel` class as a child of
the :class:`~virtual_ecosystem.core.base_model.BaseModel` class. At present a lot of
the abstract methods of the parent class (e.g.
:func:`~virtual_ecosystem.core.base_model.BaseModel.setup` and
:func:`~virtual_ecosystem.core.base_model.BaseModel.spinup`) are overwritten using
placeholder functions that don't do anything. This will change as the Virtual Ecosystem
model develops. The factory method
:func:`~virtual_ecosystem.models.litter.litter_model.LitterModel.from_config` exists in
a more complete state, and unpacks a small number of parameters from our currently
pretty minimal configuration dictionary. These parameters are then used to generate a
class instance. If errors crop here when converting the information from the config
dictionary to the required types (e.g. :class:`~numpy.timedelta64`) they are caught and
then logged, and at the end of the unpacking an error is thrown. This error should be
caught and handled by downstream functions so that all model configuration failures can
be reported as one.
the :class:`~virtual_ecosystem.core.base_model.BaseModel` class.

The factory method
:func:`~virtual_ecosystem.models.litter.litter_model.LitterModel.from_config` unpacks a
small number of parameters from our currently pretty minimal configuration dictionary.
These parameters are then used to generate a class instance. If errors crop here when
converting the information from the config dictionary to the required types (e.g.
:class:`~numpy.timedelta64`) they are caught and then logged, and at the end of the
unpacking an error is thrown. This error should be caught and handled by downstream
functions so that all model configuration failures can be reported as one.

The :func:`~virtual_ecosystem.models.litter.litter_model.LitterModel.spinup` and
:func:`~virtual_ecosystem.models.litter.litter_model.LitterModel.cleanup` methods are
not currently used by the model and exist only as placeholders.
""" # noqa: D205

# TODO - At the moment this model only receives two things from the animal model,
Expand Down Expand Up @@ -242,9 +242,6 @@ def from_config(
model_constants=model_constants,
)

def setup(self) -> None:
"""Placeholder function to setup up the litter model."""

def spinup(self) -> None:
"""Placeholder function to spin up the litter model."""

Expand Down
3 changes: 0 additions & 3 deletions virtual_ecosystem/models/plants/plants_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,6 @@ def from_config(
LOGGER.info("Plants model instance generated from configuration.")
return inst

def setup(self) -> None:
"""Placeholder function to set up the plants model."""

def spinup(self) -> None:
"""Placeholder function to spin up the plants model."""

Expand Down
31 changes: 14 additions & 17 deletions virtual_ecosystem/models/soil/soil_model.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
"""The :mod:`~virtual_ecosystem.models.soil.soil_model` module creates a
:class:`~virtual_ecosystem.models.soil.soil_model.SoilModel` class as a child of the
:class:`~virtual_ecosystem.core.base_model.BaseModel` class. At present a lot of the
abstract methods of the parent class (e.g.
:func:`~virtual_ecosystem.core.base_model.BaseModel.setup` and
:func:`~virtual_ecosystem.core.base_model.BaseModel.spinup`) are overwritten using
placeholder functions that don't do anything. This will change as the Virtual Ecosystem
model develops. The factory method
:func:`~virtual_ecosystem.models.soil.soil_model.SoilModel.from_config` exists in a
more complete state, and unpacks a small number of parameters from our currently pretty
minimal configuration dictionary. These parameters are then used to generate a class
instance. If errors crop here when converting the information from the config dictionary
to the required types (e.g. :class:`~numpy.timedelta64`) they are caught and then
logged, and at the end of the unpacking an error is thrown. This error should be caught
and handled by downstream functions so that all model configuration failures can be
reported as one.
:class:`~virtual_ecosystem.core.base_model.BaseModel` class.

The factory method
:func:`~virtual_ecosystem.models.soil.soil_model.SoilModel.from_config` unpacks a small
number of parameters from our currently pretty minimal configuration dictionary. These
parameters are then used to generate a class instance. If errors crop here when
converting the information from the config dictionary to the required types (e.g.
:class:`~numpy.timedelta64`) they are caught and then logged, and at the end of the
unpacking an error is thrown. This error should be caught and handled by downstream
functions so that all model configuration failures can be reported as one.

The :func:`~virtual_ecosystem.models.soil.soil_model.SoilModel.spinup` and
:func:`~virtual_ecosystem.models.soil.soil_model.SoilModel.cleanup` methods are not
currently used by the model and exist only as placeholders.
""" # noqa: D205

from __future__ import annotations
Expand Down Expand Up @@ -153,9 +153,6 @@ def from_config(
model_constants=model_constants,
)

def setup(self) -> None:
"""Placeholder function to setup up the soil model."""

def spinup(self) -> None:
"""Placeholder function to spin up the soil model."""

Expand Down