diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c7f3f9b5..26395124 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,10 @@ Changelog v2.1.1 ------ +(`#118 `_) Development branch merged in + +(`#130 `_) Fixed breaking change in xarray 2023.9.0 + (`#127 `_) Add a calibrated, constrained example to the documentation (`#121 `_) Make `FAIR.ghg_forcing_offset` an attribute diff --git a/Makefile b/Makefile index 5c2754b0..7ef1d7cf 100644 --- a/Makefile +++ b/Makefile @@ -40,16 +40,16 @@ format: ## re-format files .PHONY: black black: $(VENV_DIR) ## use black to autoformat code - $(VENV_DIR)/bin/black --target-version py37 $(FILES_TO_FORMAT_PYTHON) + $(VENV_DIR)/bin/black --target-version py311 $(FILES_TO_FORMAT_PYTHON) isort: $(VENV_DIR) ## format the code $(VENV_DIR)/bin/isort $(FILES_TO_FORMAT_PYTHON) virtual-environment: $(VENV_DIR) ## update venv, create a new venv if it doesn't exist $(VENV_DIR): setup.py - [ -d $(VENV_DIR) ] || python3 -m venv $(VENV_DIR) + [ -d $(VENV_DIR) ] || python3.11 -m venv $(VENV_DIR) - $(VENV_DIR)/bin/pip install --upgrade 'pip>=20.3' + $(VENV_DIR)/bin/pip install --upgrade pip $(VENV_DIR)/bin/pip install wheel $(VENV_DIR)/bin/pip install -e .[dev] diff --git a/README.md b/README.md new file mode 100644 index 00000000..7efbf240 --- /dev/null +++ b/README.md @@ -0,0 +1,97 @@ +[![image](https://github.com/OMS-NetZero/FAIR/actions/workflows/checks.yml/badge.svg)](https://github.com/OMS-NetZero/FAIR/actions) +[![image](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gh/OMS-NetZero/FAIR/master?filepath=examples/basic_run_example.ipynb) +[![Documentation Status](https://readthedocs.org/projects/fair/badge/?version=latest)](http://fair.readthedocs.io/en/latest/?badge=latest) +[![image](https://zenodo.org/badge/DOI/10.5281/zenodo.1247898.svg)](https://doi.org/10.5281/zenodo.1247898) +[![image](https://codecov.io/gh/OMS-NetZero/FAIR/branch/master/graph/badge.svg)](https://codecov.io/gh/OMS-NetZero/FAIR) +[![image](https://img.shields.io/pypi/v/fair)](https://pypi.org/project/fair/) [![Anaconda-Server Badge](https://anaconda.org/chrisroadmap/fair/badges/version.svg)](https://anaconda.org/chrisroadmap/fair) + +# FaIR + +FaIR (the Finite-amplitude Impulse-Response) climate model is a simple +climate model, or *emulator*, useful for producing global mean +temperature projections from a wide range of emissions or prescribed +forcing scenarios. + +## Requirements + +- python 3.7+ + +## Installation + +### From the Python Package Index + + pip install fair + +### From anaconda + + conda install -c chrisroadmap fair + +### From source + +Refer to [the +documentation](https://fair.readthedocs.io/en/latest/install.html) + +## Usage + +FaIR can be driven by emissions of greenhouse gases (GHGs) and +short-lived forcers (SLCFs), concentrations of GHGs, or effective +radiative forcing (ERF), with different input methods for different +species possible in the same run. If run concentration-driven, emissions +are back-calculated. Custom GHGs and SLCFs can be defined, and all +components are optional allowing experiments such as pulse-response +analyses to single forcers or gathering up non-CO~2~ species as an +aggregate forcing. + +## Examples + +The examples directory contains Jupyter notebooks with some +simple examples showing how to run FaIR and the standalone energy +balance model. + +If you want to try this out online, [go +here](https://mybinder.org/v2/gh/OMS-NetZero/FAIR/master?filepath=examples/basic_run_example.ipynb). + +## Important: A note about calibrating and constraining + +FaIR is naive. It will run whatever climate scenario and climate +configuration you give it. If you violate the laws of physics, FaIR +won\'t stop you. For simple climate models as for complex, garbage in +leads to garbage out. More subtle to spot are those analyses with simple +climate models where the present day warming (or historical) is wrong or +the climate is warming too slowly or too quickly. At least, plot a +historical temperature reconstruction over your results and see if it +looks right. + +We have produced IPCC AR6 Working Group 1 consistent probabilistic +ensembles to run with. The calibration data can be obtained +[here](https://doi.org/10.5281/zenodo.7694879). These parameter sets are +calibrated to CMIP6 models, run in a large Monte Carlo ensemble, and +constrained based on observed and assessed climate metrics. For an +example of how to use this calibration data set with SSP emissions, see +[this +example](https://docs.fairmodel.net/en/latest/examples/calibrated_constrained_ensemble.html). +If you\'re writing a paper using FaIR, you should use these. There\'ll +be a paper on this at some point, for now please cite the Zenodo DOI. + +## Citation + +If you use FaIR in your work, please cite the following references +depending on the version: + +- **v2.0+:** Leach, N. J., Jenkins, S., Nicholls, Z., Smith, C. J., + Lynch, J., Cain, M., Walsh, T., Wu, B., Tsutsui, J., and Allen, M. + R.: FaIRv2.0.0: a generalized impulse response model for climate + uncertainty and future scenario exploration, Geosci. Model Dev., 14, + 3007--3036, , 2021 +- **v1.1-v1.6**: Smith, C. J., Forster, P. M., Allen, M., Leach, N., + Millar, R. J., Passerello, G. A., and Regayre, L. A.: FAIR v1.3: A + simple emissions-based impulse response and carbon cycle model, + Geosci. Model Dev., + , 2018. +- **v1.0** (or the concept of the state-dependent impulse-response + function for CO2): Millar, R. J., Nicholls, Z. R., Friedlingstein, + P., and Allen, M. R.: A modified impulse-response representation of + the global near-surface air temperature and atmospheric + concentration response to carbon dioxide emissions, Atmos. Chem. + Phys., 17, 7213-7228, + , 2017. diff --git a/README.rst b/README.rst deleted file mode 100644 index d1dc444e..00000000 --- a/README.rst +++ /dev/null @@ -1,68 +0,0 @@ -.. image:: https://github.com/OMS-NetZero/FAIR/actions/workflows/checks.yml/badge.svg - :target: https://github.com/OMS-NetZero/FAIR/actions - -.. image:: https://mybinder.org/badge.svg - :target: https://mybinder.org/v2/gh/OMS-NetZero/FAIR/master?filepath=examples/basic_run_example.ipynb - -.. image:: https://readthedocs.org/projects/fair/badge/?version=latest - :target: http://fair.readthedocs.io/en/latest/?badge=latest - :alt: Documentation Status - -.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.1247898.svg - :target: https://doi.org/10.5281/zenodo.1247898 - -.. image:: https://codecov.io/gh/OMS-NetZero/FAIR/branch/master/graph/badge.svg - :target: https://codecov.io/gh/OMS-NetZero/FAIR - -.. image:: https://img.shields.io/pypi/v/fair - :target: https://pypi.org/project/fair/ - - -FaIR -==== - -FaIR (the Finite-amplitude Impulse-Response) climate model is a simple climate model, or *emulator*, useful for producing global mean temperature projections from a wide range of emissions or prescribed forcing scenarios. - -Requirements ------------- - -- python 3.7+ - - -Installation ------------- - -From the Python Package Index:: - - pip install fair - -For other options refer to `the documentation `_ - -Usage ------ - -FaIR can be driven by emissions of greenhouse gases (GHGs) and short-lived forcers (SLCFs), concentrations of GHGs, or effective radiative forcing (ERF), with different input methods for different species possible in the same run. If run concentration-driven, emissions are back-calculated. Custom GHGs and SLCFs can be defined, and all components are optional allowing experiments such as pulse-response analyses to single forcers or gathering up non-CO\ :sub:`2` species as an aggregate forcing. - -Examples --------- - -The `examples `_ folder contains Jupyter notebooks with some simple examples showing how to run FaIR and the standalone energy balance model. - -If you want to try this out online, `go here `_. - - -Important: A note about calibrating and constraining ----------------------------------------------------- - -FaIR is naive. It will run whatever climate scenario and climate configuration you give it. If you violate the laws of physics, FaIR won't stop you. For simple climate models as for complex, garbage in leads to garbage out. More subtle to spot are those analyses with simple climate models where the present day warming (or historical) is wrong or the climate is warming too slowly or too quickly. At least, plot a historical temperature reconstruction over your results and see if it looks right. - -We have produced IPCC AR6 Working Group 1 consistent probabilistic ensembles to run with. The calibration data can be obtained `here `_. These parameter sets are calibrated to CMIP6 models, run in a large Monte Carlo ensemble, and constrained based on observed and assessed climate metrics. For an example of how to use this calibration data set with SSP emissions, see `this example `_. If you're writing a paper using FaIR, you should use these. There'll be a paper on this at some point, for now please cite the Zenodo DOI. - -Citation --------- - -If you use FaIR in your work, please cite the following references depending on the version: - -- **v2.0+:** Leach, N. J., Jenkins, S., Nicholls, Z., Smith, C. J., Lynch, J., Cain, M., Walsh, T., Wu, B., Tsutsui, J., and Allen, M. R.: FaIRv2.0.0: a generalized impulse response model for climate uncertainty and future scenario exploration, Geosci. Model Dev., 14, 3007–3036, https://doi.org/10.5194/gmd-14-3007-2021, 2021 -- **v1.1-v1.6**: Smith, C. J., Forster, P. M., Allen, M., Leach, N., Millar, R. J., Passerello, G. A., and Regayre, L. A.: FAIR v1.3: A simple emissions-based impulse response and carbon cycle model, Geosci. Model Dev., https://doi.org/10.5194/gmd-11-2273-2018, 2018. -- **v1.0** (or the concept of the state-dependent impulse-response function for CO\ :sub:`2`): Millar, R. J., Nicholls, Z. R., Friedlingstein, P., and Allen, M. R.: A modified impulse-response representation of the global near-surface air temperature and atmospheric concentration response to carbon dioxide emissions, Atmos. Chem. Phys., 17, 7213-7228, https://doi.org/10.5194/acp-17-7213-2017, 2017. diff --git a/docs/examples/basic_run_example.rst b/docs/examples/basic_run_example.rst index e906b57b..b4d819e0 100644 --- a/docs/examples/basic_run_example.rst +++ b/docs/examples/basic_run_example.rst @@ -14,11 +14,24 @@ contains all information about the scenario(s), the forcer(s) we want to investigate, and any configurations specific to each species and the response of the climate. +Note +---- + +The code in this introductory block is explanatory and if you try to +copy and paste it it you’ll get errors. The code in this file is +self-contained below the heading “1. Create FaIR instance” below. +Alternatively, check out the repository from GitHub and run this example +notebook in ``jupyter``. Details +`here `__. + +Some basics +----------- + A run is initialised as follows: :: - f = FAIR() + f = FAIR() To this we need to add some information about the time horizon of our model, forcers we want to run with, their configuration (and the @@ -27,38 +40,38 @@ options: :: - f.define_time(2000, 2050, 1) - f.define_scenarios(['abrupt', 'ramp']) - f.define_configs(['high', 'central', 'low']) - f.define_species(species, properties) - f.ghg_method='Myhre1998' + f.define_time(2000, 2050, 1) + f.define_scenarios(['abrupt', 'ramp']) + f.define_configs(['high', 'central', 'low']) + f.define_species(species, properties) + f.ghg_method='Myhre1998' We generate some variables: emissions, concentrations, forcing, temperature etc.: :: - f.allocate() + f.allocate() which creates ``xarray`` DataArrays that we can fill in: :: - fill(f.emissions, 40, scenario='abrupt', specie='CO2 FFI') - ... + fill(f.emissions, 40, scenario='abrupt', specie='CO2 FFI') + ... Finally, the model is run with :: - f.run() + f.run() Results are stored within the ``FAIR`` instance as ``xarray`` DataArrays or Dataset, and can be obtained such as :: - print(fair.temperature) + print(fair.temperature) Multiple ``scenarios`` and ``configs`` can be supplied in a ``FAIR`` instance, and due to internal parallelisation is the fastest way to run @@ -242,7 +255,7 @@ the properties; but - ``type`` defines the species type such as CO2, an aerosol precursor, or volcanic forcing; there’s around 20 pre-defined types in FaIR. Some can only be defined once in a run, some can have multiple - instances (e.g. ``f-gas``). See ``fair.structure.species`` for a + instances (e.g. ``f-gas``). See ``fair.structure.species`` for a list. - ``input_mode``: how the model should be driven with this ``specie``. Valid values are ``emissions``, ``concentration``, ``forcing`` or @@ -451,8 +464,8 @@ future. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This defines how the model responds to a forcing: the default behaviour -is the three-layer energy balance model as described in Cummins et -al. (2020). The number of layers can be changed in ``run_control``. +is the three-layer energy balance model as described in Cummins et al. +(2020). The number of layers can be changed in ``run_control``. ``climate_configs`` is an ``xarray`` Dataset. diff --git a/docs/examples/calibrated_constrained_ensemble.rst b/docs/examples/calibrated_constrained_ensemble.rst index af6b3949..ccd7a374 100644 --- a/docs/examples/calibrated_constrained_ensemble.rst +++ b/docs/examples/calibrated_constrained_ensemble.rst @@ -12,6 +12,13 @@ reproduce both observed climate change since pre-industrial and assessed climate metrics such as the equilibrium climate sensitivity from the IPCC Sixth Assessement Report. +**Note**: if you are reading this tutorial online and want to reproduce +the results, you will need one additional file. Grab this from +https://github.com/OMS-NetZero/FAIR/blob/master/examples/data/species_configs_properties_calibration1.1.0.csv. +In Step 5 below, this is read in from the ``data/`` directory relative +to here. This does not apply if you are running this notebook from +Binder or have cloned it from GitHub - it should run out of the box. + The calibrations will be continually updated, as new data for surface temperature, ocean heat content, external forcing and emissions become available. For now, we have an IPCC AR6 WG1 version (where observational diff --git a/docs/examples/n-layer-ebm.rst b/docs/examples/n-layer-ebm.rst index a015001e..3a359688 100644 --- a/docs/examples/n-layer-ebm.rst +++ b/docs/examples/n-layer-ebm.rst @@ -5,7 +5,7 @@ This notebook shows examples of extending the 3-layer energy balance model to general n. For the two and three layer cases we’ll take the MLE estimates from -Cummins et al. (2020) for HadGEM2-ES, and we’ll use the GISS forcing. +Cummins et al. (2020) for HadGEM2-ES, and we’ll use the GISS forcing. Where n > 3 the data is fake. .. code:: ipython3 diff --git a/docs/install.rst b/docs/install.rst index 7572ca39..9276da3e 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -4,11 +4,11 @@ Installation From the Python Package Index (PyPI) ------------------------------------ -Probably the easiest way to get up and running:: +Requires `python` 3.7+. Probably the easiest way to get up and running. +:: pip install fair - From anaconda ------------- @@ -20,44 +20,44 @@ From anaconda From GitHub ----------- -Download and install -~~~~~~~~~~~~~~~~~~~~ +The latest release can be obtained from https://github.com/OMS-NetZero/FAIR/releases as zip or tarball files, or the most current unreleased version can be cloned from https://github.com/OMS-NetZero/FAIR. + +To install:: -The latest release can be obtained from https://github.com/OMS-NetZero/FAIR/releases as zip or tarball files, or the most current unreleased version can be cloned from https://github.com/OMS-NetZero/FAIR. + pip install -e .[dev] + +This will also give access to the notebooks in the `examples` directory, so you can experiment with the model using these as a starting point. For this to work, you should launch notebooks from the same directory in which you install `FAIR` locally. -Developing -~~~~~~~~~~ +Guide for developers +-------------------- -1. Fork the repository, then clone it to your local disk. `cd` to the `FAIR` directory in your working copy. +1. Navigate to the GitHub repository, fork to your personal account, then clone it to your local disk. `cd` to the `FAIR` directory in your working copy. 2. Create a new branch for your changes:: git checkout -b -3. Optional, but we highly recommend developing FaIR in a virtual environment to keep your base installation of `python` nice and clean. -4. Install `fair` in development mode:: +3. The development package includes a Makefile which will set up a virtual environment for you along with other tools, keeping your base installation clean. `python` 3.11 is used for developing FaIR. To set this up, run:: - pip install -e .[dev] + make venv -5. Make your changes. -6. Write a test that tests your new feature (in the ``tests`` directory of the repository). -7. Format your code, and run tests locally:: +4. Make your code changes. +5. Write a test that tests your new feature (in the ``tests`` directory of the repository). +6. Format your code, and run tests locally:: make format make checks - make tests + make test make test_notebooks -If you find errors at this point, they will need fixing before GitHub will allow merging to the `master` branch. Running the test suite ensures that your code change does not break or change existing functionality. +If you find errors at this point, they will need fixing before GitHub will allow merging to the `master` branch. Running the test suite ensures that your code change does not break or change existing functionality. The remote and local tests will also fail if you have not increased the code coverage (basically, if you haven't written a test for your change). -8. Commit and push your changes:: +7. Commit and push your changes:: git add git commit -m "informative commit message" git push origin -9. Create a pull request on the parent repository to merge in your changes. You will see there's a checklist of processes to go through... -10. One of which is adding a line to `CHANGELOG.rst` with a summary of the changes made. -11. The checks and tests will run using GitHub actions. If all pass, you should be able to submit the pull request for review. -12. If the codeowners are happy, the branch will be merged in. - -TODO: Check out the (currently non-existent) contributing guide, but it's basically this. +8. Create a pull request on the parent repository to merge in your changes. You will see there's a checklist of processes to go through... +9. One of which is adding a line to `CHANGELOG.rst` with a summary of the changes made. +10. The checks and tests will run using GitHub actions. If all pass, you should be able to submit the pull request for review. +11. If the codeowners are happy, the branch will be merged in. diff --git a/examples/basic_run_example.ipynb b/examples/basic_run_example.ipynb index 8eea23cb..622b22f6 100644 --- a/examples/basic_run_example.ipynb +++ b/examples/basic_run_example.ipynb @@ -11,6 +11,12 @@ "\n", "The structure of FaIR 2.1 centres around the `FAIR` class, which contains all information about the scenario(s), the forcer(s) we want to investigate, and any configurations specific to each species and the response of the climate.\n", "\n", + "## Note\n", + "\n", + "The code in this introductory block is explanatory and if you try to copy and paste it it you'll get errors. The code in this file is self-contained below the heading \"1. Create FaIR instance\" below. Alternatively, check out the repository from GitHub and run this example notebook in `jupyter`. Details [here](https://docs.fairmodel.net/en/latest/install.html).\n", + "\n", + "## Some basics\n", + "\n", "A run is initialised as follows:\n", "\n", "```\n", @@ -892,7 +898,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.15" + "version": "3.11.2" } }, "nbformat": 4, diff --git a/examples/calibrated_constrained_ensemble.ipynb b/examples/calibrated_constrained_ensemble.ipynb index 4e7f0263..41a472db 100644 --- a/examples/calibrated_constrained_ensemble.ipynb +++ b/examples/calibrated_constrained_ensemble.ipynb @@ -11,6 +11,8 @@ "\n", "We are [developing a set of parameter calibrations](https://github.com/chrisroadmap/fair-calibrate) that reproduce both observed climate change since pre-industrial and assessed climate metrics such as the equilibrium climate sensitivity from the IPCC Sixth Assessement Report.\n", "\n", + "**Note**: if you are reading this tutorial online and want to reproduce the results, you will need one additional file. Grab this from https://github.com/OMS-NetZero/FAIR/blob/master/examples/data/species_configs_properties_calibration1.1.0.csv. In Step 5 below, this is read in from the `data/` directory relative to here. This does not apply if you are running this notebook from Binder or have cloned it from GitHub - it should run out of the box.\n", + "\n", "The calibrations will be continually updated, as new data for surface temperature, ocean heat content, external forcing and emissions become available. For now, we have an IPCC AR6 WG1 version (where observational constraints are generally up to somewhere in the 2014 to 2020 period), and assessments of emergent climate metrics are from the IPCC AR6 WG1 Chapter 7. We use emissions data (historical + SSP) from the Reduced Complexity Model Intercomparison Project which was compiled for IPCC AR6 WG3 Chapter 3. We also have calibration versions for replacing historical CO2 emissions by Global Carbon Project estimates. This is v1.1.0 of the `fair-calibrate` package, and can be obtained from the DOI link below.\n", "\n", "A two-step constraining process is produced. The first step ensures that historical simulations match observed climate change to a root-mean-square error of less than 0.16°C. The second step simultaneously distribution-fits to the following assessed ranges:\n", @@ -1025,7 +1027,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.9" + "version": "3.11.2" } }, "nbformat": 4, diff --git a/setup.py b/setup.py index 74bc76ef..fb18ed1f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ here = pathlib.Path(__file__).parent.resolve() # Get the long description from the README file -long_description = (here / "README.rst").read_text(encoding="utf-8") +long_description = (here / "README.md").read_text(encoding="utf-8") # using climate-assessment as a template here REQUIREMENTS_INSTALL = [ @@ -39,6 +39,7 @@ ] REQUIREMENTS_DOCS = ["ipython", "pandoc", "sphinx==6.2.1", "sphinx_rtd_theme==1.2.0"] REQUIREMENTS_DEPLOY = [ + "build", "twine", "setuptools", "wheel", diff --git a/src/fair/fair.py b/src/fair/fair.py index 74d97cf5..8df03864 100644 --- a/src/fair/fair.py +++ b/src/fair/fair.py @@ -1388,7 +1388,9 @@ def run(self, progress=True, suppress_warnings=True): with warnings.catch_warnings(): if suppress_warnings: warnings.filterwarnings( - "ignore", message="covariance is not positive-semidefinite." + "ignore", + category=RuntimeWarning, + module="scipy.stats._multivariate", ) self._make_ebms() @@ -1404,9 +1406,9 @@ def run(self, progress=True, suppress_warnings=True): + self.emissions[..., self._co2_afolu_indices].data ) self.cumulative_emissions[1:, ...] = ( - self.emissions.cumsum(axis=0, skipna=False) * self.timestep + self.emissions.cumsum(dim="timepoints", skipna=False) * self.timestep + self.cumulative_emissions[0, ...] - ) + ).data # create numpy arrays alpha_lifetime_array = self.alpha_lifetime.data diff --git a/tests/reproduction_test.py b/tests/reproduction_test.py index 032b6536..2870f0ab 100644 --- a/tests/reproduction_test.py +++ b/tests/reproduction_test.py @@ -3,6 +3,7 @@ import os import pandas as pd +import pytest import xarray as xr from fair import FAIR @@ -10,6 +11,7 @@ from fair.io import read_properties +@pytest.mark.filterwarnings("ignore:numpy.ndarray size changed") def test_ssp_emissions_cmip6_ebm3_calibrations(): f = FAIR(ch4_method="thornhill2021") f.define_time(1750, 2100, 1) diff --git a/tests/unit_tests/energy_balance_model_test.py b/tests/unit_tests/energy_balance_model_test.py index 45324250..daa28e92 100644 --- a/tests/unit_tests/energy_balance_model_test.py +++ b/tests/unit_tests/energy_balance_model_test.py @@ -87,7 +87,7 @@ def test_ebm_emergent_parameters(): ) -@pytest.mark.filterwarnings("ignore:covariance is not positive-semidefinite") +@pytest.mark.filterwarnings("ignore:covariance") def test_ebm_run(): EBM_CAMS_STOCHASTIC.add_forcing(np.zeros(5), timestep=1) EBM_CAMS_STOCHASTIC.run() diff --git a/tests/unit_tests/fair_test.py b/tests/unit_tests/fair_test.py index 740c2b25..6f2058ce 100644 --- a/tests/unit_tests/fair_test.py +++ b/tests/unit_tests/fair_test.py @@ -1,6 +1,7 @@ """Module for unit test of fair.""" import tempfile +import warnings import numpy as np import pytest @@ -12,14 +13,14 @@ f = FAIR() -def minimal_ghg_run(): +def minimal_ghg_run(timestep=270, stochastic_run=False, seed=37): fair_obj = FAIR() species = ["CO2", "CH4", "N2O"] species, properties = read_properties(species=species) for specie in species: properties[specie]["input_mode"] = "concentration" fair_obj.define_species(species, properties) - fair_obj.define_time(1750, 2020, 270) + fair_obj.define_time(1750, 2020, timestep) fair_obj.define_scenarios(["historical"]) fair_obj.define_configs(["UKESM1-0-LL"]) fair_obj.allocate() @@ -31,13 +32,17 @@ def minimal_ghg_run(): ) fair_obj.climate_configs["deep_ocean_efficacy"][0] = 1.133708775 fair_obj.climate_configs["gamma_autocorrelation"][0] = 3.548407499 + fair_obj.climate_configs["sigma_xi"][0] = 0.439126403 / np.sqrt(timestep) + fair_obj.climate_configs["sigma_eta"][0] = 0.497441140 / np.sqrt(timestep) fair_obj.climate_configs["forcing_4co2"][0] = 7.378788155 - fair_obj.climate_configs["stochastic_run"][0] = False + fair_obj.climate_configs["stochastic_run"][0] = stochastic_run + fair_obj.climate_configs["use_seed"][0] = True + fair_obj.climate_configs["seed"][0] = seed fair_obj.fill_species_configs() fair_obj.species_configs["baseline_concentration"][0, :] = [277, 731, 270] fair_obj.species_configs["forcing_reference_concentration"][0, :] = [277, 731, 270] fair_obj.concentration[0, 0, 0, :] = [277, 731, 270] - fair_obj.concentration[1, 0, 0, :] = [410, 1900, 325] + fair_obj.concentration[1:, 0, 0, :] = [410, 1900, 325] fair_obj.forcing[0, 0, 0, :] = 0 fair_obj.temperature[0, 0, 0, :] = 0 fair_obj.cumulative_emissions[0, 0, 0, :] = 0 @@ -222,6 +227,21 @@ def test__make_ebms_climate_configs_nan(): ftest._make_ebms() +def test_run_runtime_warning(): + # need to run stochastic (to trigger the problem in the first place) and at a + # big enough time step to trigger the warning but not too big, else the matrix + # really is wrong. Doesn't seem the most robust test to future scipy whims. + ftest = minimal_ghg_run(stochastic_run=True, timestep=27) + # I want a warning (Idlewild; 2005) + with pytest.warns(RuntimeWarning): + ftest.run(suppress_warnings=False) + # I don't want a warning + with warnings.catch_warnings(): + warnings.simplefilter("error") + ftest.run(suppress_warnings=True) + ftest.run() + + def test_to_netcdf(): ftest = minimal_ghg_run() with tempfile.TemporaryFile() as tf: