diff --git a/.github/workflows/ersem.yml b/.github/workflows/ersem.yml index ffc6b29..ea302a7 100644 --- a/.github/workflows/ersem.yml +++ b/.github/workflows/ersem.yml @@ -69,6 +69,25 @@ jobs: python -m pip install pytest pytest github-actions/gotm-fabm-ersem/test_state_variables.py github-actions/gotm-fabm-ersem/test_gotm.py + test-gotm-testcase-yamls-debian: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup python + uses: actions/setup-python@v2 + with: + python-version: '3.x' + - name: Installing GOTM-FABM-ERSEM dependences + run: ./github-actions/gotm-fabm-ersem/gotm-fabm-ersem-dep-debian.sh + - name: Building and installing GOTM-FABM-ERSEM + run: | + BRANCH=${{ github.head_ref }} + ./github-actions/gotm-fabm-ersem/gotm-fabm-ersem-build.sh -b $BRANCH -f '-DCMAKE_Fortran_FLAGS="-fcheck=all"' + - name: Running GOTM testcase YAML tests + run: | + python -m pip install pytest + pytest github-actions/gotm-fabm-ersem/test_testcase_yamls.py + build-fabm0d-gotm-ersem-debian: runs-on: ubuntu-latest steps: diff --git a/github-actions/gotm-fabm-ersem/gotm-testcase-yaml.sh b/github-actions/gotm-fabm-ersem/gotm-testcase-yaml.sh new file mode 100755 index 0000000..4d7d934 --- /dev/null +++ b/github-actions/gotm-fabm-ersem/gotm-testcase-yaml.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +set -euo pipefail + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " >&2 + exit 2 +fi + +TESTCASE_YAML="$1" +if [ ! -f "${TESTCASE_YAML}" ]; then + echo "Testcase YAML not found: ${TESTCASE_YAML}" >&2 + exit 2 +fi + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)" +SETUPS_DIR="${GOTM_ERSEM_SETUPS_DIR:-${REPO_DIR}/ersem-setups}" +L4_DIR="${SETUPS_DIR}/L4" +GOTM_BIN="${GOTM_BIN:-${HOME}/local/gotm/bin/gotm}" +GOTM_TEST_STOP="${GOTM_TEST_STOP:-2007-02-01 00:00:00}" +GOTM_CONFIG_FILENAME="gotm.yaml" + +if [[ "${TESTCASE_YAML,,}" == *n2o* ]] || grep -Eiq 'n2o|nitrous[_ -]oxide' "${TESTCASE_YAML}"; then + GOTM_CONFIG_FILENAME="gotm_n2o.yaml" +fi + +if [ ! -x "${GOTM_BIN}" ]; then + echo "GOTM executable not found or not executable: ${GOTM_BIN}" >&2 + exit 2 +fi + +if [ ! -d "${SETUPS_DIR}" ]; then + echo "Cloning config repo" + git clone https://github.com/pmlmodelling/ersem-setups.git "${SETUPS_DIR}" +fi + +ORIGINAL_GOTM_YAML="$(mktemp "${L4_DIR}/gotm.yaml.original.XXXXXX")" +TEST_GOTM_YAML="$(mktemp "${L4_DIR}/gotm.yaml.testcase.XXXXXX")" +GOTM_CONFIG="${L4_DIR}/${GOTM_CONFIG_FILENAME}" + +if [ ! -f "${GOTM_CONFIG}" ]; then + echo "GOTM config not found for testcase ${TESTCASE_YAML}: ${GOTM_CONFIG}" >&2 + exit 2 +fi + +cp "${L4_DIR}/gotm.yaml" "${ORIGINAL_GOTM_YAML}" + +cleanup() { + cp "${ORIGINAL_GOTM_YAML}" "${L4_DIR}/gotm.yaml" + rm -f "${ORIGINAL_GOTM_YAML}" "${TEST_GOTM_YAML}" +} +trap cleanup EXIT + +awk -v stop="${GOTM_TEST_STOP}" ' + /^time:[[:space:]]*$/ { in_time = 1 } + /^[^[:space:]]/ && !/^time:[[:space:]]*$/ { in_time = 0 } + in_time && /^[[:space:]]+stop:[[:space:]]/ { + sub(/stop:.*/, "stop: " stop) + updated = 1 + } + { print } + END { if (!updated) exit 1 } +' "${GOTM_CONFIG}" > "${TEST_GOTM_YAML}" + +echo "Running GOTM with testcase YAML: ${TESTCASE_YAML}" +echo "Using GOTM config: ${GOTM_CONFIG_FILENAME}" +echo "Using temporary gotm.yaml stop date: ${GOTM_TEST_STOP}" +cp "${TEST_GOTM_YAML}" "${L4_DIR}/gotm.yaml" +cp "${TESTCASE_YAML}" "${L4_DIR}/fabm.yaml" +cd "${L4_DIR}" + +"${GOTM_BIN}" --ignore_unknown_config diff --git a/github-actions/gotm-fabm-ersem/test_testcase_yamls.py b/github-actions/gotm-fabm-ersem/test_testcase_yamls.py new file mode 100644 index 0000000..cbab095 --- /dev/null +++ b/github-actions/gotm-fabm-ersem/test_testcase_yamls.py @@ -0,0 +1,42 @@ +""" +Check that GOTM runs with every testcase YAML configuration. +""" + +import subprocess +from pathlib import Path + +import pytest + + +REPO_DIR = Path(__file__).resolve().parents[2] +TESTCASE_DIR = REPO_DIR / "testcases" +RUNNER = Path(__file__).with_name("gotm-testcase-yaml.sh") + +YAML_PATTERNS = ("*.yaml", "*.yml") +TESTCASE_YAMLS = sorted( + {path for pattern in YAML_PATTERNS for path in TESTCASE_DIR.rglob(pattern)} +) + + +def yaml_id(path): + return path.relative_to(TESTCASE_DIR).as_posix() + + +@pytest.mark.parametrize("testcase_yaml", TESTCASE_YAMLS, ids=yaml_id) +def test_gotm_runs_with_testcase_yaml(testcase_yaml): + """ + Run GOTM with an ERSEM testcase YAML copied to the L4 setup. + """ + result = subprocess.run( + ["bash", str(RUNNER), str(testcase_yaml)], + cwd=REPO_DIR, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + + assert result.returncode == 0, ( + f"GOTM failed for {testcase_yaml.relative_to(REPO_DIR)}\n" + f"stdout:\n{result.stdout}\n" + f"stderr:\n{result.stderr}" + ) diff --git a/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-denit.yaml b/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-denit.yaml index 5875835..545a88f 100644 --- a/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-denit.yaml +++ b/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-denit.yaml @@ -285,6 +285,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -351,6 +352,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.005 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000225 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -414,6 +416,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.045 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.006 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.00035 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -474,6 +477,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.035 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) diff --git a/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-n2o.yaml b/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-n2o.yaml index 27d857a..75b3f55 100644 --- a/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-n2o.yaml +++ b/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop-n2o.yaml @@ -278,6 +278,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -344,6 +345,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.005 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000225 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -407,6 +409,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.045 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.006 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.00035 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -467,6 +470,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.035 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) diff --git a/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop.yaml b/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop.yaml index f59f110..7b92565 100644 --- a/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop.yaml +++ b/testcases/ersem-15.06/fabm-ersem-15.06-L4-ben-docdyn-iop.yaml @@ -268,6 +268,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -334,6 +335,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.005 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000225 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -397,6 +399,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.045 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.006 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.00035 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -457,6 +460,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.035 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) diff --git a/testcases/ersem-15.06/fabm-ersem-15.06-L4-noben-docdyn-iop.yaml b/testcases/ersem-15.06/fabm-ersem-15.06-L4-noben-docdyn-iop.yaml index fd49875..e193457 100644 --- a/testcases/ersem-15.06/fabm-ersem-15.06-L4-noben-docdyn-iop.yaml +++ b/testcases/ersem-15.06/fabm-ersem-15.06-L4-noben-docdyn-iop.yaml @@ -272,6 +272,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -338,6 +339,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.04 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.005 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000225 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -401,6 +403,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.045 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.006 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.00035 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -461,6 +464,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.035 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.2 # respired fraction of primary production (-) qnlc: 0.0042 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.0001 # minimum phosphorus to carbon ratio (mmol P/mg C) diff --git a/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-ben-stdbac-stdlight.yaml b/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-ben-stdbac-stdlight.yaml index fb36f16..18ecf0c 100644 --- a/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-ben-stdbac-stdlight.yaml +++ b/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-ben-stdbac-stdlight.yaml @@ -256,6 +256,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.05 # excreted fraction of primary production (-) + exulim: 0.95 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.1 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -321,6 +322,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.25 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -383,6 +385,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.25 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -442,6 +445,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.05 # excreted fraction of primary production (-) + exulim: 0.95 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.25 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C) diff --git a/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-noben-stdbac-stdlight.yaml b/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-noben-stdbac-stdlight.yaml index 315bdd6..9affd10 100644 --- a/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-noben-stdbac-stdlight.yaml +++ b/testcases/ersem-Blackford2024/fabm-ersem-Blackford2004-L4-noben-stdbac-stdlight.yaml @@ -259,6 +259,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.05 # excreted fraction of primary production (-) + exulim: 0.95 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.1 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -324,6 +325,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.25 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -386,6 +388,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.2 # excreted fraction of primary production (-) + exulim: 0.8 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.25 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C) @@ -445,6 +448,7 @@ instances: q10: 2.0 # Q_10 temperature coefficient (-) srs: 0.05 # specific rest respiration at reference temperature (1/d) pu_ea: 0.05 # excreted fraction of primary production (-) + exulim: 0.95 # excreted fraction of primary production due to nutrient stress,maximum=1._rk-self%pu_ea pu_ra: 0.25 # respired fraction of primary production (-) qnlc: 0.00687 # minimum nitrogen to carbon ratio (mmol N/mg C) qplc: 0.000428 # minimum phosphorus to carbon ratio (mmol P/mg C)