-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
361 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
jupytext: | ||
cell_metadata_filter: -all | ||
formats: md:myst | ||
main_language: python | ||
text_representation: | ||
extension: .md | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.13.8 | ||
kernelspec: | ||
display_name: vr_python3 | ||
language: python | ||
name: vr_python3 | ||
--- | ||
|
||
# API reference for `abiotic` modules | ||
|
||
```{eval-rst} | ||
.. automodule:: virtual_rainforest.models.abiotic | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
jupytext: | ||
cell_metadata_filter: -all | ||
formats: md:myst | ||
main_language: python | ||
text_representation: | ||
extension: .md | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.13.8 | ||
kernelspec: | ||
display_name: vr_python3 | ||
language: python | ||
name: vr_python3 | ||
--- | ||
|
||
# API for the {mod}`~virtual_rainforest.models.abiotic.constants` module | ||
|
||
```{eval-rst} | ||
.. automodule:: virtual_rainforest.models.abiotic.constants | ||
:autosummary: | ||
:members: | ||
:special-members: __init__ | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
--- | ||
jupytext: | ||
cell_metadata_filter: -all | ||
formats: md:myst | ||
main_language: python | ||
text_representation: | ||
extension: .md | ||
format_name: myst | ||
format_version: 0.13 | ||
jupytext_version: 1.13.8 | ||
kernelspec: | ||
display_name: vr_python3 | ||
language: python | ||
name: vr_python3 | ||
--- | ||
|
||
<!-- markdownlint-disable-next-line MD013 --> | ||
# API documentation for the {mod}`~virtual_rainforest.models.abiotic.abiotic_model` module | ||
|
||
```{eval-rst} | ||
.. automodule:: virtual_rainforest.models.abiotic.abiotic_model | ||
``` | ||
|
||
## The {mod}`~virtual_rainforest.models.abiotic.abiotic_model.AbioticModel` class | ||
|
||
```{eval-rst} | ||
.. autoclass:: virtual_rainforest.models.abiotic.abiotic_model.AbioticModel | ||
:autosummary: | ||
:members: | ||
:exclude-members: model_name | ||
``` |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
"""Test module for abiotic.abiotic_model.py.""" | ||
|
||
from contextlib import nullcontext as does_not_raise | ||
from logging import INFO | ||
|
||
import pint | ||
import pytest | ||
|
||
from tests.conftest import log_check | ||
from virtual_rainforest.models.abiotic.abiotic_model import AbioticModel | ||
|
||
|
||
def test_abiotic_model_initialization( | ||
dummy_climate_data, | ||
layer_roles_fixture, | ||
): | ||
"""Test `AbioticModel` initialization.""" | ||
from virtual_rainforest.models.abiotic.constants import AbioticConsts | ||
|
||
# Initialize model | ||
model = AbioticModel( | ||
dummy_climate_data, | ||
pint.Quantity("1 hour"), | ||
soil_layers=[-0.5, -1.0], | ||
canopy_layers=10, | ||
constants=AbioticConsts(), | ||
) | ||
|
||
# In cases where it passes then checks that the object has the right properties | ||
assert set( | ||
[ | ||
"setup", | ||
"spinup", | ||
"update", | ||
"cleanup", | ||
] | ||
).issubset(dir(model)) | ||
assert model.model_name == "abiotic" | ||
assert repr(model) == "AbioticModel(update_interval = 1 hour)" | ||
assert model.layer_roles == layer_roles_fixture | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"config,time_interval,raises,expected_log_entries", | ||
[ | ||
( | ||
{}, | ||
None, | ||
pytest.raises(KeyError), | ||
(), # This error isn't handled so doesn't generate logging | ||
), | ||
( | ||
{ | ||
"core": { | ||
"timing": { | ||
"start_date": "2020-01-01", | ||
"update_interval": "1 day", | ||
}, | ||
"layers": { | ||
"soil_layers": [-0.5, -1.0], | ||
"canopy_layers": 10, | ||
}, | ||
}, | ||
}, | ||
pint.Quantity("1 day"), | ||
does_not_raise(), | ||
( | ||
( | ||
INFO, | ||
"Information required to initialise the abiotic model " | ||
"successfully extracted.", | ||
), | ||
), | ||
), | ||
], | ||
) | ||
def test_generate_abiotic_model( | ||
caplog, | ||
dummy_climate_data, | ||
config, | ||
time_interval, | ||
raises, | ||
expected_log_entries, | ||
layer_roles_fixture, | ||
): | ||
"""Test that the initialisation of the abiotic model works as expected.""" | ||
|
||
# Check whether model is initialised (or not) as expected | ||
with raises: | ||
model = AbioticModel.from_config( | ||
dummy_climate_data, | ||
config, | ||
pint.Quantity(config["core"]["timing"]["update_interval"]), | ||
) | ||
assert model.layer_roles == layer_roles_fixture | ||
assert model.update_interval == time_interval | ||
|
||
# Final check that expected logging entries are produced | ||
log_check(caplog, expected_log_entries) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
r"""The :mod:`~virtual_rainforest.models.abiotic` module is one of the component | ||
models of the Virtual Rainforest. It is comprised of several submodules that calculate | ||
the microclimate for the Virtual Rainforest. | ||
Each of the abiotic sub-modules has its own API reference page: | ||
* The :mod:`~virtual_rainforest.models.abiotic.abiotic_model` submodule | ||
instantiates the AbioticModel class which consolidates the functionality of the | ||
abiotic model into a single class, which the high level functions of the | ||
Virtual Rainforest can then use. | ||
* The :mod:`~virtual_rainforest.models.abiotic.constants` submodule provides a | ||
set of dataclasses containing the constants required by the broader abiotic model. | ||
""" # noqa: D205, D415 | ||
|
||
from virtual_rainforest.core.base_model import register_model | ||
from virtual_rainforest.models.abiotic.abiotic_model import AbioticModel | ||
|
||
register_model(__name__, AbioticModel) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
"""The :mod:`~virtual_rainforest.models.abiotic.abiotic_model` module creates a | ||
:class:`~virtual_rainforest.models.abiotic.abiotic_model.AbioticModel` | ||
class as a child of the :class:`~virtual_rainforest.core.base_model.BaseModel` class. At | ||
present a lot of the abstract methods of the parent class (e.g. | ||
:func:`~virtual_rainforest.core.base_model.BaseModel.spinup`) are overwritten using | ||
placeholder functions that don't do anything. This will change as the Virtual Rainforest | ||
model develops. The factory method | ||
:func:`~virtual_rainforest.models.abiotic.abiotic_model.AbioticModel.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 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. | ||
""" # noqa: D205, D415 | ||
|
||
from __future__ import annotations | ||
|
||
from typing import Any | ||
|
||
from pint import Quantity | ||
|
||
from virtual_rainforest.core.base_model import BaseModel | ||
from virtual_rainforest.core.config import Config | ||
from virtual_rainforest.core.constants import load_constants | ||
from virtual_rainforest.core.data import Data | ||
from virtual_rainforest.core.logger import LOGGER | ||
from virtual_rainforest.core.utils import set_layer_roles | ||
from virtual_rainforest.models.abiotic.constants import AbioticConsts | ||
|
||
|
||
class AbioticModel(BaseModel): | ||
"""A class describing the abiotic model. | ||
Args: | ||
data: The data object to be used in the model. | ||
update_interval: Time to wait between updates of the model state. | ||
soil_layers: A list setting the number and depths of soil layers to be modelled. | ||
canopy_layers: The initial number of canopy layers to be modelled. | ||
constants: Set of constants for the abiotic model. | ||
""" | ||
|
||
model_name = "abiotic" | ||
"""The model name for use in registering the model and logging.""" | ||
lower_bound_on_time_scale = "1 minute" | ||
"""Shortest time scale that abiotic model can sensibly capture.""" | ||
upper_bound_on_time_scale = "1 day" | ||
"""Longest time scale that abiotic model can sensibly capture.""" | ||
required_init_vars = () | ||
"""The required variables and axes for the abiotic model""" | ||
vars_updated = () | ||
"""Variables updated by the abiotic model""" | ||
|
||
def __init__( | ||
self, | ||
data: Data, | ||
update_interval: Quantity, | ||
soil_layers: list[float], | ||
canopy_layers: int, | ||
constants: AbioticConsts, | ||
**kwargs: Any, | ||
): | ||
super().__init__(data, update_interval, **kwargs) | ||
|
||
# create a list of layer roles | ||
layer_roles = set_layer_roles(canopy_layers, soil_layers) | ||
|
||
self.data | ||
"""A Data instance providing access to the shared simulation data.""" | ||
self.layer_roles = layer_roles | ||
"""A list of vertical layer roles.""" | ||
self.update_interval | ||
"""The time interval between model updates.""" | ||
self.constants = constants | ||
"""Set of constants for the abiotic model""" | ||
|
||
@classmethod | ||
def from_config( | ||
cls, data: Data, config: Config, update_interval: Quantity | ||
) -> AbioticModel: | ||
"""Factory function to initialise the abiotic model from configuration. | ||
This function unpacks the relevant information from the configuration file, and | ||
then uses it to initialise the model. If any information from the config is | ||
invalid rather than returning an initialised model instance an error is raised. | ||
Args: | ||
data: A :class:`~virtual_rainforest.core.data.Data` instance. | ||
config: A validated Virtual Rainforest model configuration object. | ||
update_interval: Frequency with which all models are updated. | ||
""" | ||
|
||
# Find number of soil and canopy layers | ||
soil_layers = config["core"]["layers"]["soil_layers"] | ||
canopy_layers = config["core"]["layers"]["canopy_layers"] | ||
|
||
# Load in the relevant constants | ||
constants = load_constants(config, "abiotic", "AbioticConsts") | ||
|
||
LOGGER.info( | ||
"Information required to initialise the abiotic model successfully " | ||
"extracted." | ||
) | ||
return cls(data, update_interval, soil_layers, canopy_layers, constants) | ||
|
||
def setup(self) -> None: | ||
"""Function to set up the abiotic model.""" | ||
|
||
def spinup(self) -> None: | ||
"""Placeholder function to spin up the abiotic model.""" | ||
|
||
def update(self, time_index: int, **kwargs: Any) -> None: | ||
"""Function to update the abiotic model. | ||
Args: | ||
time_index: The index of the current time step in the data object. | ||
""" | ||
|
||
def cleanup(self) -> None: | ||
"""Placeholder function for abiotic model cleanup.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
"""The ``models.abiotic.constants`` module contains a set of dataclasses which contain | ||
parameters required by the broader :mod:`~virtual_rainforest.models.abiotic` model. | ||
These parameters are constants in that they should not be changed during a particular | ||
simulation. | ||
""" # noqa: D205, D415 | ||
|
||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass(frozen=True) | ||
class AbioticConsts: | ||
"""Dataclass to store all constants for the `abiotic` model.""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"type": "object", | ||
"properties": { | ||
"abiotic": { | ||
"description": "Configuration settings for the abiotic module", | ||
"type": "object", | ||
"properties": { | ||
"constants": { | ||
"description": "Constants for the abiotic module", | ||
"type": "object", | ||
"properties": { | ||
"AbioticConsts": { | ||
"type": "object" | ||
} | ||
}, | ||
"required": [ | ||
"AbioticConsts" | ||
] | ||
} | ||
}, | ||
"default": {}, | ||
"required": [] | ||
} | ||
}, | ||
"required": [ | ||
"abiotic" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters