diff --git a/.zenodo.json b/.zenodo.json index 272476aa5e..6cadfcf3f0 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -66,6 +66,11 @@ "affiliation": "University of Bremen, Germany", "name": "Adeniyi, Kemisola" }, + { + "affiliation": "University of Bremen, Germany", + "name": "Castellani, Giulia", + "orcid": "0000-0001-6151-015X" + }, { "affiliation": "ISAC-CNR, Italy", "name": "Arnone, Enrico", @@ -366,6 +371,10 @@ "affiliation": "DLR, Germany", "name": "Sarauer, Ellen" }, + { + "affiliation": "University of Bremen, Germany", + "name": "Schulze, Kirsten" + }, { "affiliation": "University of Reading, UK", "name": "Roberts, Charles", diff --git a/CITATION.cff b/CITATION.cff index 99930a7003..7858465f5e 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -174,6 +174,10 @@ authors: affiliation: "University of Bremen, Germany" family-names: Gier given-names: Bettina + - + affiliation: "University of Bremen, Germany" + family-names: Castellani + given-names: Giulia - affiliation: "Met Office, UK" family-names: Gillett @@ -358,6 +362,10 @@ authors: family-names: Weigel given-names: Katja orcid: "https://orcid.org/0000-0001-6133-7801" + - + affiliation: "University of Bremen, Germany" + family-names: Schulze + given-names: Kirsten - affiliation: "DLR, Germany" family-names: Sarauer diff --git a/doc/sphinx/source/recipes/figures/sanity_checks/timeseries_ambiguous_variable_group_MPI-ESM1-2-LR_Amon_historical_r1i1p1f1.png b/doc/sphinx/source/recipes/figures/sanity_checks/timeseries_ambiguous_variable_group_MPI-ESM1-2-LR_Amon_historical_r1i1p1f1.png new file mode 100644 index 0000000000..062c7a034a Binary files /dev/null and b/doc/sphinx/source/recipes/figures/sanity_checks/timeseries_ambiguous_variable_group_MPI-ESM1-2-LR_Amon_historical_r1i1p1f1.png differ diff --git a/doc/sphinx/source/recipes/index.rst b/doc/sphinx/source/recipes/index.rst index 4830904576..1f60c94d3e 100644 --- a/doc/sphinx/source/recipes/index.rst +++ b/doc/sphinx/source/recipes/index.rst @@ -25,6 +25,7 @@ large variety of input data. recipe_model_evaluation recipe_monitor recipe_portrait + recipe_sanity_checks recipe_seaborn recipe_ref diff --git a/doc/sphinx/source/recipes/recipe_sanity_checks.rst b/doc/sphinx/source/recipes/recipe_sanity_checks.rst new file mode 100644 index 0000000000..52a20adc56 --- /dev/null +++ b/doc/sphinx/source/recipes/recipe_sanity_checks.rst @@ -0,0 +1,81 @@ +.. _recipe_santiy_checks: + +Sanity checks +============= + +Overview +-------- + +The sanity check recipe (``recipe_sanity_checks.yml``) is intended to perform +some basic sanity checks for new simulations during model development. A subset of variables +is selected to check whether the model is performing in reasonable way. The recipe plots global +monthly means as well as maximum and minimum across all individual grid cells for each time step. +This can be used to check for example for negative mass concentrations occuring at any grid cell +at any time (minimum is less than zero) or whether individual grid cells exceed physically reasonable +values (e.g. total cloud fraction greater than 100%). +The global monthly means can be compared to the minimum and maximum values found in reference +datasets (observations, reanalyses) across all months and all reference datasets. The "reasonable" +limits are shown as red lines. A good model simulations would be expected to not exceed these +limits at any time. The minimum and maximum global averages across all months and all reference +datasets is calculated with ``recipe_create_ranges_obs.yml``. + +Available recipes and diagnostics +--------------------------------- + +Recipes are stored in `recipes/sanity_checks` + +* recipe_sanity_checks.yml +* recipe_create_ranges_obs.yml + +.. note:: + + The time frequency used in ``recipe_create_ranges_obs.yml`` (monthly, daily, etc. values) to + calculate "reasonable" minimum and maximum values must match the time frequency used in + the sanity check recipe (``recipe_sanity_checks.yml``). + +Diagnostics are stored in `diag_scripts/monitor/` + +* :ref:`multi_datasets.py + `: + Monitoring diagnostic to show multiple datasets in one plot (incl. biases). + +Variables: +---------- + +* ps (air mass) +* qep (moisture flux) +* prw (water vapor mass) +* asr +* clivi +* clt +* hfls +* hfss +* lwcre +* lwp +* netcre +* pr +* prc +* prw +* rlds +* rlut +* rtnt +* rsds +* rsut +* swcre +* tas +* tauu +* tauv + +Example plots +------------- + +.. _fig_sanity_check_clt: +.. figure:: /recipes/figures/sanity_checks/timeseries_ambiguous_variable_group_MPI-ESM1-2-LR_Amon_historical_r1i1p1f1.png + :align: center + :width: 14cm + + Time series of monthly global average (solid line) and minimum / maximum + (dashed lines) total cloud cover from MPI-ESM1-2-LR. The red horizontal lines + show the monthly minimum and maximum global average across multiple reference + dataset (here: ESACCI-CLOUD, CLARA-AVHRR, PATMOS-x, MODIS, ERA5) calculated + with recipe_create_ranges_obs.yml. Plot created with recipe_sanity_checks.yml. diff --git a/esmvaltool/config-references.yml b/esmvaltool/config-references.yml index 25943ca45c..cbc8f49e81 100644 --- a/esmvaltool/config-references.yml +++ b/esmvaltool/config-references.yml @@ -30,6 +30,12 @@ authors: email: diego.cammarano@dlr.de github: diegokam orcid: + castellani_giulia: + name: Castellani, Giulia + institute: University of Bremen + email: giulia.castellani@uni-bremen.de + github: giuliacast + orcid: https://orcid.org/0000-0001-6151-015X debeire_kevin: name: Debeire, Kevin institute: DLR, Germany @@ -527,6 +533,11 @@ authors: institute: DLR, Germany orcid: github: ellensarauer + schulze_kirsten: + name: Schulze, Kirsten + institute: Uni Bremen, Germany + orcid: + github: kirsy05 serva_federico: name: Serva, Federico institute: CNR, Italy diff --git a/esmvaltool/recipes/sanity_checks/recipe_create_ranges_obs.yml b/esmvaltool/recipes/sanity_checks/recipe_create_ranges_obs.yml new file mode 100644 index 0000000000..595f01362c --- /dev/null +++ b/esmvaltool/recipes/sanity_checks/recipe_create_ranges_obs.yml @@ -0,0 +1,701 @@ +# ESMValTool +--- +documentation: + title: Reasonable variable ranges for sanity checks (OBS) + description: > + Calculate reasonable variable ranges for sanity checks. + authors: + - lauer_axel + - bock_lisa + maintainer: + - lauer_axel + + +preprocessors: + + pp_min_pr: + custom_order: true + area_statistics: + operator: mean + multi_model_statistics: + span: full + statistics: + - operator: min + keep_input_datasets: false + convert_units: + units: mm day-1 + climate_statistics: + operator: min + + pp_max_pr: + custom_order: true + area_statistics: + operator: mean + multi_model_statistics: + span: full + statistics: + - operator: max + keep_input_datasets: false + convert_units: + units: mm day-1 + climate_statistics: + operator: max + + pp_min: + custom_order: true + align_metadata: + target_project: OBS6 + area_statistics: + operator: mean + multi_model_statistics: + ignore_scalar_coords: true + span: full + statistics: + - operator: min + keep_input_datasets: false + climate_statistics: + operator: min + + pp_max: + custom_order: true + align_metadata: + target_project: OBS6 + area_statistics: + operator: mean + multi_model_statistics: + ignore_scalar_coords: true + span: full + statistics: + - operator: max + keep_input_datasets: false + climate_statistics: + operator: max + + pp_min_sum: + custom_order: true + area_statistics: + operator: sum + multi_model_statistics: + span: full + statistics: + - operator: min + keep_input_datasets: false + climate_statistics: + operator: min + + pp_max_sum: + custom_order: true + area_statistics: + operator: sum + multi_model_statistics: + span: full + statistics: + - operator: max + keep_input_datasets: false + climate_statistics: + operator: max + + pp_min_sum_air: + custom_order: true + convert_units: + units: kg m-2 + area_statistics: + operator: sum + multi_model_statistics: + span: full + statistics: + - operator: min + keep_input_datasets: false + climate_statistics: + operator: min + + pp_max_sum_air: + custom_order: true + convert_units: + units: kg m-2 + area_statistics: + operator: sum + multi_model_statistics: + span: full + statistics: + - operator: max + keep_input_datasets: false + climate_statistics: + operator: max + + pp_min_sum_air_anom: + custom_order: true + convert_units: + units: kg m-2 + area_statistics: + operator: sum + anomalies: + period: full + reference: + start_year: 1990 + start_month: 1 + start_day: 1 + end_year: 1990 + end_month: 12 + end_day: 31 + multi_model_statistics: + span: full + statistics: + - operator: min + keep_input_datasets: false + climate_statistics: + operator: min + + pp_max_sum_air_anom: + custom_order: true + convert_units: + units: kg m-2 + area_statistics: + operator: sum + anomalies: + period: full + reference: + start_year: 1990 + start_month: 1 + start_day: 1 + end_year: 1990 + end_month: 12 + end_day: 31 + multi_model_statistics: + span: full + statistics: + - operator: max + keep_input_datasets: false + climate_statistics: + operator: max + +diagnostics: + + air_mass: + description: Calculate range of reasonable monthly values for global air mass anomaly + variables: + ps_min: + short_name: ps + preprocessor: pp_min_sum_air + mip: Amon + ps_max: + short_name: ps + preprocessor: pp_max_sum_air + mip: Amon + additional_datasets: + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1990, end_year: 2014} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: 5.12.4, + tier: 3, start_year: 1980, end_year: 2021} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, + tier: 2, start_year: 1984, end_year: 2016} + scripts: null + + + air_mass_anom: + description: Calculate range of reasonable monthly values for global air mass anomaly + variables: + ps_min: + short_name: ps + preprocessor: pp_min_sum_air_anom + mip: Amon + ps_max: + short_name: ps + preprocessor: pp_max_sum_air_anom + mip: Amon + additional_datasets: + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1990, end_year: 2014} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: 5.12.4, + tier: 3, start_year: 1980, end_year: 2021} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, + tier: 2, start_year: 1984, end_year: 2016} + scripts: null + + + moisture_flux: + description: Calculate range of reasonable monthly values for moisture flux into the atmosphere + variables: + qep_min: + short_name: qep + derive: true + preprocessor: pp_min_sum + mip: Amon + qep_max: + short_name: qep + derive: true + preprocessor: pp_max_sum + mip: Amon + additional_datasets: + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1990, end_year: 2014} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: 5.12.4, + tier: 3, start_year: 1980, end_year: 2021} + scripts: null + + + prw_global: + description: Calculate range of reasonable monthly values for global water vapour mass + variables: + prw_min: + short_name: prw + preprocessor: pp_min_sum + mip: Amon + prw_max: + short_name: prw + preprocessor: pp_max_sum + mip: Amon + additional_datasets: + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1995, end_year: 2014} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: 5.12.4, + tier: 3, start_year: 1980, end_year: 2021} + - {dataset: ESACCI-WATERVAPOUR, project: OBS6, type: sat, version: CDR2-L3-COMBI-05deg-fv3.1, + tier: 3, start_year: 2002, end_year: 2017} + scripts: null + +################################################################################################################# + + asr: + description: Calculate range of reasonable monthly values for cloud ice path. + variables: + asr_min: + short_name: asr + derive: true + preprocessor: pp_min + mip: Amon + asr_max: + short_name: asr + derive: true + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: CERES-EBAF, project: OBS, type: sat, version: Ed4.2, + tier: 2, start_year: 2001, end_year: 2022} + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, + tier: 2, start_year: 1984, end_year: 2016} + scripts: null + + + clivi: + description: Calculate range of reasonable monthly values for cloud ice water path. + variables: + clivi_min: + short_name: clivi + preprocessor: pp_min + mip: Amon + clivi_max: + short_name: clivi + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: CLOUDSAT-L2, project: OBS, type: sat, + version: P1-R05-gridbox-average-noprecip, + start_year: 2006, end_year: 2017, tier: 3} + - {dataset: CLARA-AVHRR, project: OBS, type: sat, version: V002-01, + tier: 3, start_year: 1982, end_year: 2018} + - {dataset: MODIS, project: OBS, type: sat, version: MYD08-M3, + tier: 3, start_year: 2003, end_year: 2018} + scripts: null + + clt: + description: Calculate range of reasonable monthly values for total cloud cover. + variables: + clt_min: + short_name: clt + preprocessor: pp_min + mip: Amon + clt_max: + short_name: clt + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: CLARA-AVHRR, project: OBS, type: sat, version: V002-01, + tier: 3, start_year: 1982, end_year: 2018} + - {dataset: PATMOS-x, project: OBS, type: sat, version: NOAA, + tier: 2, start_year: 1982, end_year: 2016} + - {dataset: MODIS, project: OBS, type: sat, version: MYD08-M3, + tier: 3, start_year: 2003, end_year: 2018} + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1995, end_year: 2014} + scripts: null + + + hfls: + description: Calculate range of reasonable monthly values for surface upward latent heat flux. + variables: + hfls_min: + short_name: hfls + preprocessor: pp_min + mip: Amon + hfls_max: + short_name: hfls + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', + tier: 3, start_year: 1980, end_year: 2021} + scripts: null + + + hfss: + description: Calculate range of reasonable monthly values for surface upward sensible heat flux. + variables: + hfss_min: + short_name: hfss + preprocessor: pp_min + mip: Amon + hfss_max: + short_name: hfss + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', + tier: 3, start_year: 1980, end_year: 2021} + scripts: null + + + lwcre: + description: Calculate range of reasonable monthly values for lw cloud radiative effect. + variables: + lwcre_min: + short_name: lwcre + derive: true + preprocessor: pp_min + mip: Amon + lwcre_max: + short_name: lwcre + derive: true + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: CERES-EBAF, project: OBS, type: sat, version: Ed4.1, + tier: 2, start_year: 2001, end_year: 2021} + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, tier: 2, + start_year: 1984, end_year: 2016} + scripts: null + + + lwp: + description: Calculate range of reasonable monthly values for cloud liquid water path. + variables: + lwp_min: + short_name: lwp + derive: true + preprocessor: pp_min + mip: Amon + lwp_max: + short_name: lwp + derive: true + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: CLARA-AVHRR, project: OBS, type: sat, + version: V002-01, tier: 3, + start_year: 1982, end_year: 2018} + - {dataset: CLOUDSAT-L2, project: OBS, type: sat, + version: P1-R05-gridbox-average-noprecip, + start_year: 2006, end_year: 2017, tier: 3} + - {dataset: MAC-LWP, project: OBS, type: sat, version: v1, + tier: 3, start_year: 1988, end_year: 2016} + - {dataset: MODIS, project: OBS, type: sat, version: MYD08-M3, + tier: 3, start_year: 2003, end_year: 2018} + scripts: null + + + netcre: + description: Calculate range of reasonable monthly values for met cloud radiative effect. + variables: + netcre_min: + short_name: netcre + derive: true + preprocessor: pp_min + mip: Amon + netcre_max: + short_name: netcre + derive: true + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: CERES-EBAF, project: OBS, type: sat, version: Ed4.1, + tier: 2, start_year: 2001, end_year: 2021} + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, tier: 2, + start_year: 1984, end_year: 2016} + scripts: null + + + pr: + description: Calculate range of reasonable monthly values for precipitation. + variables: + pr_min: + short_name: pr + preprocessor: pp_min_pr + mip: Amon + pr_max: + short_name: pr + preprocessor: pp_max_pr + mip: Amon + additional_datasets: + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', tier: 3, + start_year: 1980, end_year: 2021} + - {dataset: GPCP-SG, project: OBS, type: atmos, version: 2.3, tier: 2, + start_year: 1979, end_year: 2022} + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1979, end_year: 2021} + scripts: null + + + prc: + description: Calculate range of reasonable monthly values for convective precipitation flux. + variables: + prc_min: + short_name: prc + preprocessor: pp_min + mip: Amon + prc_max: + short_name: prc + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', tier: 3, + start_year: 1980, end_year: 2021} + scripts: null + + + prw: + description: Calculate range of reasonable monthly values for atmoshere mass content of water vapor. + variables: + prw_min: + short_name: prw + preprocessor: pp_min + mip: Amon + prw_max: + short_name: prw + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1995, end_year: 2014} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: 5.12.4, + tier: 3, start_year: 1980, end_year: 2021} + - {dataset: ESACCI-WATERVAPOUR, project: OBS6, type: sat, version: CDR2-L3-COMBI-05deg-fv3.1, + tier: 3, start_year: 2002, end_year: 2017} + scripts: null + + + rlds: + description: Calculate range of reasonable monthly values for surface downwelling lw flux. + variables: + rlds_min: + short_name: rlds + preprocessor: pp_min + mip: Amon + rlds_max: + short_name: rlds + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, tier: 2, + start_year: 1984, end_year: 2016} + - {dataset: ERA5, project: OBS6, type: reanaly, version: '1', + tier: 3} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', tier: 3, + start_year: 1980, end_year: 2021} + scripts: null + + + rlut: + description: Calculate range of reasonable monthly values for TOA outgoing lw radiation. + variables: + rlut_min: + short_name: rlut + preprocessor: pp_min + mip: Amon + rlut_max: + short_name: rlut + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: CERES-EBAF, project: OBS, type: sat, version: Ed4.2, + tier: 2, start_year: 2001, end_year: 2022} + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, + tier: 2, start_year: 1984, end_year: 2016} + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1995, end_year: 2014} + scripts: null + + rtnt: + description: Calculate range of reasonable monthly values for TOA net downward total radiation. + variables: + rtnt_min: + short_name: rtnt + derive: true + preprocessor: pp_min + mip: Amon + rtnt_max: + short_name: rtnt + derive: true + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, + tier: 2, start_year: 1984, end_year: 2016} + scripts: null + + + rsds: + description: Calculate range of reasonable monthly values for urface downwelling sw flux. + variables: + rsds_min: + short_name: rsds + preprocessor: pp_min + mip: Amon + rsds_max: + short_name: rsds + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, tier: 2, + start_year: 1984, end_year: 2016} + - {dataset: TROPFLUX, version: v1, project: OBS6, type: reanaly, + tier: 2, start_year: 1979, end_year: 2018} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', tier: 3, + start_year: 1980, end_year: 2021} + scripts: null + + + rsut: + description: Calculate range of reasonable monthly values for TOA outgoing sw radiation. + variables: + rsut_min: + short_name: rsut + preprocessor: pp_min + mip: Amon + rsut_max: + short_name: rsut + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: CERES-EBAF, project: OBS, type: sat, version: Ed4.2, + tier: 2, start_year: 2001, end_year: 2022} + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, + tier: 2, start_year: 1984, end_year: 2016} + scripts: null + + + swcre: + description: Calculate range of reasonable monthly values for sw cloud radiative effect. + variables: + swcre_min: + short_name: swcre + derive: true + preprocessor: pp_min + mip: Amon + swcre_max: + short_name: swcre + derive: true + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: CERES-EBAF, project: OBS, type: sat, version: Ed4.1, + tier: 2, start_year: 2001, end_year: 2021} + - {dataset: ESACCI-CLOUD, project: OBS6, type: sat, + version: v3.0-AVHRR-AMPM, tier: 2, + start_year: 1982, end_year: 2016} + - {dataset: ISCCP-FH, project: OBS, type: sat, version: v0, tier: 2, + start_year: 1984, end_year: 2016} + scripts: null + + + tas: + description: Calculate range of reasonable monthly values for 2-m temperature. + variables: + tas_min: + short_name: tas + preprocessor: pp_min + mip: Amon + tas_max: + short_name: tas + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', tier: 3, + start_year: 1980, end_year: 2021} + - {dataset: ERA5, project: native6, type: reanaly, version: v1, + tier: 3, start_year: 1995, end_year: 2014} + - {dataset: HadCRUT5, project: OBS, type: ground, version: 5.0.1.0-analysis, + tier: 2} + scripts: null + + + tauu: + description: Calculate range of reasonable monthly values for surface downward eastward stress. + variables: + tauu_min: + short_name: tauu + preprocessor: pp_min + mip: Amon + tauu_max: + short_name: tauu + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: TROPFLUX, version: v1, project: OBS6, type: reanaly, + tier: 2, start_year: 1979, end_year: 2018} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', tier: 3, + start_year: 1980, end_year: 2021} + - {dataset: ERA-Interim, project: OBS6, type: reanaly, version: '1', + tier: 3, start_year: 1979, end_year: 2018} + - {dataset: NOAA-CIRES-20CR-V2, project: OBS6, mip: Amon, tier: 2, + type: reanaly, version: v2, start_year: 1871, end_year: 2012} + scripts: null + + + tauv: + description: Calculate range of reasonable monthly values for surface downward westward stress. + variables: + tauv_min: + short_name: tauv + preprocessor: pp_min + mip: Amon + tauv_max: + short_name: tauv + preprocessor: pp_max + mip: Amon + additional_datasets: + - {dataset: TROPFLUX, version: v1, project: OBS6, type: reanaly, + tier: 2, start_year: 1979, end_year: 2018} + - {dataset: MERRA2, project: OBS6, type: reanaly, version: '5.12.4', tier: 3, + start_year: 1980, end_year: 2021} + - {dataset: ERA-Interim, project: OBS6, type: reanaly, version: '1', + tier: 3, start_year: 1979, end_year: 2018} + - {dataset: NOAA-CIRES-20CR-V2, project: OBS6, mip: Amon, tier: 2, + type: reanaly, version: v2, start_year: 1871, end_year: 2012} + scripts: null diff --git a/esmvaltool/recipes/sanity_checks/recipe_sanity_checks.yml b/esmvaltool/recipes/sanity_checks/recipe_sanity_checks.yml new file mode 100644 index 0000000000..a4513768da --- /dev/null +++ b/esmvaltool/recipes/sanity_checks/recipe_sanity_checks.yml @@ -0,0 +1,867 @@ +# ESMValTool +--- +documentation: + title: Basic sanity checks. + description: > + Calculate basic sanity checks on monthly output e.g. for monitoring new model runs. + authors: + - bock_lisa + - castellani_giulia + - lauer_axel + - schulze_kirsten + maintainer: + - lauer_axel + + +# YAML anchors for later use + +plot_script: &plot_script + script: monitor/multi_datasets.py + facet_used_for_labels: legend_label + group_variables_by: short_name # variable_group + plot_filename: "{plot_type}_{exp}_{real_name}_{dataset}_{mip}" + plot_folder: "{plot_dir}" + +timeseries_plot: ×eries_plot + caption: > + Timeseries of global mean {long_name} (solid line) and global min/max values + (dashed lines). As "reasonable" ranges for the global mean, red lines show + min and max values found in reference datasets (observations, reanalyses) + across all months and all reference datasets. + plot_kwargs: + 'global mean': + color: blue + label: null + linestyle: '-' + linewidth: 2 + label: '{dataset}' + 'global min': + color: blue + label: null + linestyle: '--' + linewidth: 1 + 'global max': + color: blue + label: null + linestyle: '--' + linewidth: 1 + + +# Note: The following model is just an example +datasets: + - {dataset: MPI-ESM1-2-LR, grid: gn, project: CMIP6, exp: historical, ensemble: r1i1p1f1, timerange: '1980/2014'} + + +preprocessors: + + globalmean: &pp_globalmean + custom_order: true + regrid: + target_grid: 2x2 + scheme: nearest + area_statistics: + operator: mean + + globalmean_pr: + <<: *pp_globalmean + convert_units: + units: mm day-1 + + globalmin: &pp_globalmin + custom_order: true + regrid: + target_grid: 2x2 + scheme: nearest + area_statistics: + operator: min + + globalmin_pr: + <<: *pp_globalmin + convert_units: + units: mm day-1 + + globalmax: &pp_globalmax + custom_order: true + regrid: + target_grid: 2x2 + scheme: nearest + area_statistics: + operator: max + + globalmax_pr: + <<: *pp_globalmax + convert_units: + units: mm day-1 + + global_sum: + custom_order: true + regrid: + target_grid: 2x2 + scheme: nearest + area_statistics: + operator: sum + + global_sum_air_anom: + custom_order: true + convert_units: + units: kg m-2 + regrid: + target_grid: 2x2 + scheme: nearest + area_statistics: + operator: sum + anomalies: + period: full + reference: + start_year: 1990 + start_month: 1 + start_day: 1 + end_year: 1990 + end_month: 12 + end_day: 31 + + +diagnostics: + + # ******************* + # *** global sums *** + # ******************* + + air_mass_anom: + description: time series of global air mass anomaly + variables: + ps: + preprocessor: global_sum_air_anom + legend_label: 'global sum' + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + caption: "Timeseries of global air mass anomaly (solid blue line)." + pyplot_kwargs: + title: "Anomaly of global air mass" + hlines: + - y: 0. + color: black + linewidth: 2 + plot_kwargs: + 'global sum': + color: blue + label: null + linestyle: '-' + linewidth: 2 + label: '{dataset}' + zorder: 3 + + moisture_flux: + description: time series of moisture flux into the atmosphere + variables: + qep: + derive: true + preprocessor: global_sum + legend_label: 'global sum' + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + caption: > + Timeseries of global moisture flux into the atmosphere (solid line) and + global min/max values (dashed lines). As "reasonable" ranges for the global + mean, red lines show min and max values found in reference datasets + (observations, reanalyses) across all months and all reference datasets. + pyplot_kwargs: + title: "Anomaly of global moisture flux into the atmosphere" + hlines: + - y: 0. + color: black + linewidth: 2 + - y: 4.381299e+08 + color: red + - y: -7.258987e+08 + color: red + plot_kwargs: + 'global sum': + color: blue + label: null + linestyle: '-' + linewidth: 2 + label: '{dataset}' + zorder: 3 + + prw_mass: + description: time series of global water vapour mass + variables: + prw_sum: + short_name: prw + preprocessor: global_sum + legend_label: 'global sum' + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + caption: > + Timeseries of global water vapour mass (solid line) and + global min/max values (dashed lines). As "reasonable" ranges for the global + sum, red lines show min and max values found in reference datasets + (observations, reanalyses) across all months and all reference datasets. + pyplot_kwargs: + title: "Global sum of water vapour" + hlines: + - y: 1.420688e+16 + color: red + linewidth: 2 + - y: 1.128716e+16 + color: red + linewidth: 2 + plot_kwargs: + 'global sum': + color: blue + label: null + linestyle: '-' + linewidth: 2 + label: '{dataset}' + zorder: 3 + + + # *************************** + # *** global min/max/mean *** + # *************************** + + asr: + description: time series of global min/max/mean including "reasonable" ranges + variables: + asr_mean: + legend_label: 'global mean' + short_name: asr + preprocessor: globalmean + derive: true + mip: Amon + asr_min: + short_name: asr + legend_label: 'global min' + preprocessor: globalmin + derive: true + mip: Amon + asr_max: + short_name: asr + legend_label: 'global max' + preprocessor: globalmax + derive: true + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 215.4 + color: red + - y: 248.7 + color: red + + clivi: + description: time series of global min/max/mean including "reasonable" ranges + variables: + clivi_mean: + legend_label: 'global mean' + short_name: clivi + preprocessor: globalmean + mip: Amon + clivi_min: + short_name: clivi + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + clivi_max: + short_name: clivi + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 0.092597 + color: red + - y: 0.0290555 + color: red + + clt: + description: time series of global min/max/mean including "reasonable" ranges + variables: + clt_mean: + legend_label: 'global mean' + short_name: clt + preprocessor: globalmean + mip: Amon + clt_min: + short_name: clt + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + clt_max: + short_name: clt + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 58.7 + color: red + - y: 74.9 + color: red + + hfls: + description: time series of global min/max/mean including "reasonable" ranges + variables: + hfls_mean: + short_name: hfls + legend_label: 'global mean' + preprocessor: globalmean + mip: Amon + hfls_min: + short_name: hfls + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + hfls_max: + short_name: hfls + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 76.4 + color: red + - y: 92.3 + color: red + + hfss: + description: time series of global min/max/mean including "reasonable" ranges + variables: + hfss_mean: + short_name: hfss + legend_label: 'global mean' + preprocessor: globalmean + mip: Amon + hfss_min: + short_name: hfss + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + hfss_max: + short_name: hfss + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 21.5 + color: red + - y: 15.8 + color: red + + lwcre: + description: time series of global min/max/mean including "reasonable" ranges + variables: + lwcre_mean: + short_name: lwcre + legend_label: 'global mean' + preprocessor: globalmean + derive: true + force_derivation: true + mip: Amon + lwcre_min: + short_name: lwcre + legend_label: 'global min' + preprocessor: globalmin + derive: true + force_derivation: true + mip: Amon + lwcre_max: + short_name: lwcre + legend_label: 'global max' + preprocessor: globalmax + derive: true + force_derivation: true + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 30.5 + color: red + - y: 23.6 + color: red + + lwp: + description: time series of global min/max/mean including "reasonable" ranges + variables: + lwp_mean: + short_name: lwp + legend_label: 'global mean' + preprocessor: globalmean + derive: true + force_derivation: true + mip: Amon + lwp_min: + short_name: lwp + legend_label: 'global min' + preprocessor: globalmin + derive: true + force_derivation: true + mip: Amon + lwp_max: + short_name: lwp + legend_label: 'global max' + preprocessor: globalmax + derive: true + force_derivation: true + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 0.1569 + color: red + - y: 0.0229 + color: red + + netcre: + description: time series of global min/max/mean including "reasonable" ranges + variables: + netcre_mean: + short_name: netcre + legend_label: 'global mean' + preprocessor: globalmean + derive: true + force_derivation: true + mip: Amon + netcre_min: + short_name: netcre + legend_label: 'global min' + preprocessor: globalmin + derive: true + force_derivation: true + mip: Amon + netcre_max: + short_name: netcre + legend_label: 'global max' + preprocessor: globalmax + derive: true + force_derivation: true + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: -12.3 + color: red + - y: -47.1 + color: red + + pr: + description: time series of global min/max/mean including "reasonable" ranges + variables: + pr_mean: + short_name: pr + legend_label: 'global mean' + preprocessor: globalmean_pr + mip: Amon + pr_min: + short_name: pr + legend_label: 'global min' + preprocessor: globalmin_pr + mip: Amon + pr_max: + short_name: pr + legend_label: 'global max' + preprocessor: globalmax_pr + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 2.50 + color: red + - y: 3.21 + color: red + + prc: + description: time series of global min/max/mean including "reasonable" ranges + variables: + prc_mean: + short_name: prc + legend_label: 'global mean' + preprocessor: globalmean + mip: Amon + prc_min: + short_name: prc + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + prc_max: + short_name: prc + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 1.115665e-05 + color: red + - y: 7.41801e-06 + color: red + + prw: + description: time series of global min/max/mean including "reasonable" ranges + variables: + prw_mean: + legend_label: 'global mean' + short_name: prw + preprocessor: globalmean + mip: Amon + prw_min: + short_name: prw + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + prw_max: + short_name: prw + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 28.7 + color: red + - y: 22.3 + color: red + + rlds: + description: time series of global min/max/mean including "reasonable" ranges + variables: + rlds_mean: + legend_label: 'global mean' + short_name: rlds + preprocessor: globalmean + mip: Amon + rlds_min: + short_name: rlds + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + rlds_max: + short_name: rlds + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 360.4 + color: red + - y: 319.2 + color: red + + rlut: + description: time series of global min/max/mean including "reasonable" ranges + variables: + rlut_mean: + short_name: rlut + legend_label: 'global mean' + preprocessor: globalmean + mip: Amon + rlut_min: + short_name: rlut + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + rlut_max: + short_name: rlut + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 246.3 + color: red + - y: 226.4 + color: red + + rtnt: + description: time series of global min/max/mean including "reasonable" ranges + variables: + rtnt_mean: + short_name: rtnt + legend_label: 'global mean' + preprocessor: globalmean + derive: true + force_derivation: true + mip: Amon + rtnt_min: + short_name: rtnt + legend_label: 'global min' + preprocessor: globalmin + derive: true + force_derivation: true + mip: Amon + rtnt_max: + short_name: rtnt + legend_label: 'global max' + preprocessor: globalmax + derive: true + force_derivation: true + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 13.4 + color: red + - y: -22.7 + color: red + + rsds: + description: time series of global min/max/mean including "reasonable" ranges + variables: + rsds_mean: + legend_label: 'global mean' + short_name: rsds + preprocessor: globalmean + mip: Amon + rsds_min: + short_name: rsds + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + rsds_max: + short_name: rsds + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 231.8 + color: red + - y: 166.3 + color: red + + rsut: + description: time series of global min/max/mean including "reasonable" ranges + variables: + rsut_mean: + legend_label: 'global mean' + short_name: rsut + preprocessor: globalmean + mip: Amon + rsut_min: + short_name: rsut + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + rsut_max: + short_name: rsut + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 128.8 + color: red + - y: 91.1 + color: red + + swcre: + description: time series of global min/max/mean including "reasonable" ranges + variables: + swcre_mean: + short_name: swcre + legend_label: 'global mean' + preprocessor: globalmean + derive: true + force_derivation: true + mip: Amon + swcre_min: + short_name: swcre + legend_label: 'global min' + preprocessor: globalmin + derive: true + force_derivation: true + mip: Amon + swcre_max: + short_name: swcre + legend_label: 'global max' + preprocessor: globalmax + derive: true + force_derivation: true + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: -40.6 + color: red + - y: -73.5 + color: red + + tas: + description: time series of global min/max/mean including "reasonable" ranges + variables: + tas_mean: + short_name: tas + legend_label: 'global mean' + preprocessor: globalmean + mip: Amon + tas_min: + short_name: tas + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + tas_max: + short_name: tas + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 293.7 + color: red + - y: 283.9 + color: red + + tauu: + description: time series of global min/max/mean including "reasonable" ranges + variables: + tauu_mean: + legend_label: 'global mean' + short_name: tauu + preprocessor: globalmean + mip: Amon + tauu_min: + short_name: tauu + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + tauu_max: + short_name: tauu + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 0.0198 + color: red + - y: -0.0528 + color: red + + tauv: + description: time series of global min/max/mean including "reasonable" ranges + variables: + tauv_mean: + legend_label: 'global mean' + short_name: tauv + preprocessor: globalmean + mip: Amon + tauv_min: + short_name: tauv + legend_label: 'global min' + preprocessor: globalmin + mip: Amon + tauv_max: + short_name: tauv + legend_label: 'global max' + preprocessor: globalmax + mip: Amon + scripts: + timeseries: + <<: *plot_script + plots: + timeseries: + <<: *timeseries_plot + hlines: + - y: 0.0283 + color: red + - y: -0.0144 + color: red