Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2be1e0c
Add RMSE scores based vertical pressure profile recipe and include pl…
Sylviabohnenstengel Jun 24, 2026
8004edb
add functionality to calculate RMSE for each vertical level for a spa…
Sylviabohnenstengel Jun 24, 2026
603588c
include aggregation period into title of vertical profile line plot f…
Sylviabohnenstengel Jun 25, 2026
6a1bc6e
wiring the recipe into the cylc workflow
Sylviabohnenstengel Jun 25, 2026
f52bde4
functionality to select rmse profile for aggregated across all time s…
Sylviabohnenstengel Jun 25, 2026
7081246
removing dependency between vertical profile RMSE for evevry timestep…
Sylviabohnenstengel Jun 29, 2026
537809e
coorect name for vertical profile at each timepoint to SEQUENCE.
Sylviabohnenstengel Jul 6, 2026
7236495
correctly name rmse profile to sequence for profiles at each timestep.
Sylviabohnenstengel Jul 6, 2026
c397b91
adding aggregation mode to recipe and loader to ensure scientific cla…
Sylviabohnenstengel Jul 16, 2026
cbd0f9a
set scores to False in rose-suite.conf_example.
Sylviabohnenstengel Jul 16, 2026
4cc60e3
split scores sections into spatial, timeseries and profile.
Sylviabohnenstengel Jul 16, 2026
ada23aa
Merge branch 'main' into 2229_scores_rmse_vertical_profile_pressure_l…
Sylviabohnenstengel Jul 16, 2026
a0a3e1a
sorting problems after GitHub requested merge with scores crps.
Sylviabohnenstengel Jul 16, 2026
07f5565
pytest failure addressing: FAILED tests/test_recipes.py::test_load_re…
Sylviabohnenstengel Jul 16, 2026
5f0f603
Merge branch 'main' into 2229_scores_rmse_vertical_profile_pressure_l…
Sylviabohnenstengel Jul 16, 2026
36a6151
preserve ensembles for vertical profile RMSE plots and include aggreg…
Sylviabohnenstengel Jul 6, 2026
b443918
include ensemble functionality for RMSE. Calculates RMSE based on ens…
Sylviabohnenstengel Jul 15, 2026
455a340
clarify definition of ensemble RMSE based on ensemble mean calculated…
Sylviabohnenstengel Jul 16, 2026
ffabeda
Merge branch 'main' into 2229_scores_rmse_vertical_profile_pressure_l…
Sylviabohnenstengel Jul 16, 2026
7269983
fixe failing scores_test removing base information from ensemble mean…
Sylviabohnenstengel Jul 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/CSET/cset_workflow/includes/metplus_point_stat.cylc
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
# Runs VerPy metloader utility to create the VerPy databases
inherit = VERPY_METLOADER
[[[environment]]]
VERPY_DIR = {{VERPY_DIR}}
VERPY_DIR = {{VERPY_DIR|default("")}}
VER_METHOD = area
STAT_TYPE = cnt
STREAM = point_stat
Expand Down
53 changes: 45 additions & 8 deletions src/CSET/cset_workflow/meta/verification/rose-meta.conf
Original file line number Diff line number Diff line change
Expand Up @@ -54,36 +54,73 @@ sort-key=met5

###################################
# Scores
[Verification/Scores]
ns=Verification/Scores
[Verification/Scores spatial]
ns=Verification/Scores spatial
sort-key=scores
title=Scores
title=Scores spatial

[template variables=SCORES_ALL]
ns=Verification/Scores
ns=Verification/Scores spatial
description=If selected, all scores shown below will be calculated.
NOTE scores currently only available for model-model intercomparisons.
type=python_boolean
trigger=template variables=SCORES_RMSE_SPATIAL: False;
template variables=SCORES_RMSE_TIMESERIES: False;
compulsory=true
sort-key=scores1
sort-key=scoresspatial1

[template variables=SCORES_RMSE_SPATIAL]
ns=Verification/Scores
ns=Verification/Scores spatial
description=Create spatially mapped RMSE plots for the specified surface fields.
The analysis method(s) set in SPATIAL_SURFACE_FIELD_METHOD will be used.
NOTE currently only available for model-model intercomparisons.
type=python_boolean
compulsory=true
sort-key=scores2
sort-key=scoresspatial2

[Verification/Scores timeseries]
ns=Verification/Scores timeseries
sort-key=scorestimeseries
title=Scores timeseries

[Verification/Scores timeseries]
[template variables=SCORES_RMSE_TIMESERIES]
ns=Verification/Scores
ns=Verification/Scores timeseries
description=Create a timeseries of the RMSE for the specified surface fields.
NOTE currently only available for model-model intercomparisons.
type=python_boolean
compulsory=true
sort-key=scorestimeseries1

[Verification/Scores vertical profiles]
ns=Verification/Scores vertical profiles
sort-key=scoresvertical
title=Scores vertical profiles

[Verification/Scores vertical profiles]
[template variables=SCORES_RMSE_VERTICAL_PROFILES]
ns=Verification/Scores vertical profiles
description=Create vertical profile RMSE plots for the specified level fields.
A total RMSE profile is calculated from all grid points for all timesteps within a case study at each pressure level.
In case of ensembles the ensemble mean is calculated first and the RMSE is then calculated between the ensemble mean and the base model ensemble mean.
type=python_boolean
compulsory=true
sort-key=scoresprofile1

[template variables=SCORES_RMSE_VERTICAL_PROFILES_SEQUENCE]
ns=Verification/Scores vertical profiles
description=Create a sequence of RMSE vertical profiles, one per time step, for each case study.
help=When True, the RMSE is calculated for all grid points and at each level for every
time step, collapsing only the spatial (horizontal) dimensions. This produces
a sequence of vertical RMSE profile plots, one per time step, in addition to
the profile that is aggregated across the whole case study.
In case of ensembles the ensemble mean is calculated first and the RMSE is then calculated between the ensemble mean and the base model ensemble mean.

When False (default), only the case-total vertical RMSE profile is produced.
type=python_boolean
compulsory=true
#trigger=template variables=SCORES_RMSE_VERTICAL_PROFILES: True;
sort-key=scoresprofile2
sort-key=scores3

[template variables=SCORES_CRPS_FOR_ENSEMBLE]
Expand Down
2 changes: 2 additions & 0 deletions src/CSET/cset_workflow/rose-suite.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ RUN_METPLUS_POINT_STAT=False
SCORES_ALL=False
SCORES_RMSE_SPATIAL=False
SCORES_RMSE_TIMESERIES=False
SCORES_RMSE_VERTICAL_PROFILES=False
SCORES_RMSE_VERTICAL_PROFILES_SEQUENCE=False
SCORES_CRPS_FOR_ENSEMBLE=False
SATURATION_FRACTION=False
SCREEN_LEVEL_TEMPERATURE_PROBABILITIES=False
Expand Down
2 changes: 1 addition & 1 deletion src/CSET/cset_workflow/site/nci-gadi.cylc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"""
[[[ environment ]]]
PROJECT = {{ PROJECT }}
PYTHONPATH = "{{VERPY_DIR}}"
PYTHONPATH = "{{VERPY_DIR|default("")}}"

{% if RUN_METPLUS_GRID_STAT|default(False) or RUN_METPLUS_POINT_STAT|default(False) %}
[[METPLUS]]
Expand Down
41 changes: 41 additions & 0 deletions src/CSET/loaders/verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ def load(conf: Config):
"""Yield recipes from the given workflow configuration."""
# Load a list of model detail dictionaries.
models = get_models(conf.asdict())
if not models:
return
# Models are listed in order, so model 1 is the first element.
base_model = models[0]

if conf.SCORES_RMSE_SPATIAL or conf.SCORES_ALL:
base_model = models[0]
Expand Down Expand Up @@ -63,6 +66,25 @@ def load(conf: Config):
model_ids=[base_model["id"], model["id"]],
aggregation=False,
)
# including AGGREGATION_MODE in the variables dictionary to allow for clearer labeling of plots.
if conf.SCORES_RMSE_VERTICAL_PROFILES:
for model, field in itertools.product(models[1:], conf.PRESSURE_LEVEL_FIELDS):
yield RawRecipe(
recipe="generic_level_rmse_scores_profile.yaml",
variables={
"VARNAME": field,
"BASE_MODEL": base_model["name"],
"OTHER_MODEL": model["name"],
"PRESERVED_COORDS": ["pressure"],
"AGGREGATION_MODE": "Case-study RMSE",
"SUBAREA_TYPE": conf.SUBAREA_TYPE if conf.SELECT_SUBAREA else None,
"SUBAREA_EXTENT": conf.SUBAREA_EXTENT
if conf.SELECT_SUBAREA
else None,
},
model_ids=[base_model["id"], model["id"]],
aggregation=False,
)

if conf.SCORES_CRPS_FOR_ENSEMBLE:
for model, field in itertools.product(models, conf.SURFACE_FIELDS):
Expand All @@ -80,3 +102,22 @@ def load(conf: Config):
model_ids=[model["id"]],
aggregation=False,
)
# including AGGREGATION_MODE in the variables dictionary to allow for clearer labeling of plots.
if conf.SCORES_RMSE_VERTICAL_PROFILES_SEQUENCE:
for model, field in itertools.product(models[1:], conf.PRESSURE_LEVEL_FIELDS):
yield RawRecipe(
recipe="generic_level_rmse_scores_profile.yaml",
variables={
"VARNAME": field,
"BASE_MODEL": base_model["name"],
"OTHER_MODEL": model["name"],
"PRESERVED_COORDS": ["time", "pressure"],
"AGGREGATION_MODE": "Time-step RMSE",
"SUBAREA_TYPE": conf.SUBAREA_TYPE if conf.SELECT_SUBAREA else None,
"SUBAREA_EXTENT": conf.SUBAREA_EXTENT
if conf.SELECT_SUBAREA
else None,
},
model_ids=[base_model["id"], model["id"]],
aggregation=False,
)
Loading