Cold-Point Tropopause (CTP) diagnostic and sample recipe - #4565
aoifemcquaid wants to merge 9 commits into
Conversation
…-ML. Longitude hovmoeller plot with CPT P, T, q and RH_i. RH_i derived from other variables.
- Replace the hard-coded local-path-only ICON recipe with ERA5 (native6) and CMIP6 (MPI-ESM1-2-LR), and preserve the original ICON local-path setup as a separate copy outside the repo. - Split each dataset's single 3-panel figure into standalone, self-contained per-variable plots (temperature, specific humidity, RH over ice), so more compatible with ICONEval as plots can be produced independently - Add a parallel time-vs-latitude Hovmoeller view (restricted to -20°/+20°) alongside the existing time-vs-longitude view for every variable/dataset, doubling figure count with a consistent _lon/_lat filename suffix. - Fix main() so preprocessed datasets (ERA5/CMIP6) and a raw ICON block can both run in the same invocation rather than ICON short-circuiting dataset processing, without altering the underlying CTP calculation logic.
schlunma
left a comment
There was a problem hiding this comment.
Thanks @aoifemcquaid, looks great already! Just a couple of comments to make the code simpler.
Please remove all special treatment of ICON data, it should be possible to read this without any special treatment in the diagnostic. If you need the ICON data to be on a regular grid with a regular pressure level Z coordinate, you can use the following preprocessors in the recipe:
preprocessors:
preprocess_icon:
custom_order: true
extract_levels:
levels: {cmor_table: CMIP6, coordinate: plev19}
scheme: linear
coordinate: air_pressure
regrid:
target_grid: 2x2
scheme: area_weightedIt would be great if you could also add documentation to the recipe/diagnostic (e.g., like done in #3155).
If you want, you can also add your name to the CITATION.cff and .zenodo.json to become an official contributor.
Thanks 🚀
| - weigel_katja | ||
| - schlund_manuel |
There was a problem hiding this comment.
| - weigel_katja | |
| - schlund_manuel | |
| - mcquaid_aoife |
There was a problem hiding this comment.
Looks like this has not been changed
| - weigel_katja | ||
| - schlund_manuel | ||
| maintainer: | ||
| - unmaintained |
There was a problem hiding this comment.
| - unmaintained | |
| - schlund_manuel |
There was a problem hiding this comment.
Looks like this has not been changed
schlunma
left a comment
There was a problem hiding this comment.
Thanks so much @aoifemcquaid for addressing my comments! Looks fantastic, just have a couple of minor comments left.
Approving this from a technical point of view. @ESMValGroup/atmosphere would anyone be able to do a quick scientific review of this? Thanks so much!
|
|
||
| suffix = "lon" if axis == "X" else "lat" | ||
| view_desc = "longitude-time" if axis == "X" else "latitude-time" | ||
| basename = f"{cfg.get('plot_filename', 'tropical_cpt_hovmoeller')}_{_safe_name(dataset_label)}" |
There was a problem hiding this comment.
| basename = f"{cfg.get('plot_filename', 'tropical_cpt_hovmoeller')}_{_safe_name(dataset_label)}" | |
| basename = f"{cfg['plot_filename']}_{_safe_name(dataset_label)}" |
You use setdefault before, so this is safe.
| - weigel_katja | ||
| - schlund_manuel |
There was a problem hiding this comment.
Looks like this has not been changed
| - weigel_katja | ||
| - schlund_manuel | ||
| maintainer: | ||
| - unmaintained |
There was a problem hiding this comment.
Looks like this has not been changed
|
|
||
| cbar = fig.colorbar(cf, ax=ax, orientation="vertical", shrink=0.95) | ||
| cbar.set_label("CPT pressure [hPa]", fontsize=16) | ||
| cbar.set_ticks([80, 90, 100, 110, 120]) |
There was a problem hiding this comment.
I guess this is the reason for the weird 110/120 in the plot? Instead of hardcoding it, you can either let matplotlib figure that out or make it configurable in the recipe.
|
|
||
| datasets: | ||
| - {dataset: ERA5, project: native6, type: reanaly, version: v1, tier: 3, alias: ERA5} | ||
| - {dataset: MPI-ESM1-2-LR, project: CMIP6, exp: historical, ensemble: r1i1p1f1, grid: gn, alias: CMIP6} |
There was a problem hiding this comment.
| - {dataset: MPI-ESM1-2-LR, project: CMIP6, exp: historical, ensemble: r1i1p1f1, grid: gn, alias: CMIP6} | |
| - {dataset: MPI-ESM1-2-LR, project: CMIP6, exp: historical, ensemble: r1i1p1f1, grid: gn, alias: MPI-ESM1-2-LR} |
|
|
||
| caption = ( | ||
| f"Tropical CPT {view_desc} Hovmoeller for {dataset_label}: " | ||
| f"colors show CPT pressure; contours show {title.lower()}." |
There was a problem hiding this comment.
| f"colors show CPT pressure; contours show {title.lower()}." | |
| f"colors show CPT pressure; contours show {title}." |
It looks nicer with proper capitalization.
| cpt_q, | ||
| lambda x: f"{x * 1e6:.2f}", | ||
| ), | ||
| ("rhi", "CPT RH over ice contours [%]", cpt_rhi, "%.0f"), |
There was a problem hiding this comment.
| ("rhi", "CPT RH over ice contours [%]", cpt_rhi, "%.0f"), | |
| ("rhi", "CPT relative humidity over ice contours [%]", cpt_rhi, "%.0f"), |
To be more verbose
I can have a look when Levante is up again. |

Summary
This PR adds a new tropical cold-point tropopause (CTP) Hovmoeller diagnostic to ESMValTool. It identifies the CTP as the minimum-temperature level in a configurable pressure range and produces longitude-time and latitude-time Hovmoeller plots of CTP temperature, specific humidity, and relative humidity w.r.t. ice, with CTP pressure shown as filled contours. The recipe runs the diagnostic against ERA5 and CMIP6 data.
Files added/changed
CTP diagnostic workflow
an optional raw-ICON input pathway (file-pattel preprocessing) that can run alongside preprocessed datasets in the same invocation, used for local ICON testing (see below) but not part of this recipe.
Data included
The recipe uses only ERA5 (project: native6) and CMIP6 (MPI-ESM1-2-LR, historical, r1i1p1f1, gn) — both standard ESMValTool-accessible sources. No local or absolute file paths are included in this recipe. A separate ICON-inclusive variant of this recipe (adding a local-path ICON dataset block) exists outside this repository for local development use only and is not part of this PR.
Testing
Run locally end-to-end with ESMValTool via the repo’s pixi environment (project.toml, pixi.lock; ESMValCore dependency pinned to >=2.14.0, ESMValTool dev version v2.14.0-74-g9ea83ca94 per git describe). The recipe completed successfully and produced all expected output plots for every dataset/variable/plot-type combination (12 PNGs: ERA5 and CMIP6, 3 variables each, lon and lat views). No further validation (e.g. against reference/published CTP climatologies) has been performed.
Checklist
It is the responsibility of the author to make sure the pull request is ready to review. The icons indicate whether the item will be subject to the 🛠 Technical or 🧪 Scientific review.
New or updated recipe/diagnostic
To help with the number of pull requests: