Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diagnostic for calculating Lamb Weathertypes #3691

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
74ad3a1
weathertyping scripts
Apr 27, 2024
e548c1c
weathertyping scripts
Apr 27, 2024
4e4053d
weathertyping
thomaskroi1996 May 2, 2024
88cfed7
weathertyping
thomaskroi1996 May 2, 2024
682e2a5
weathertyping
thomaskroi1996 May 2, 2024
fea116e
weathertyping module
thomaskroi1996 May 7, 2024
65d406a
weathertyping module
thomaskroi1996 May 7, 2024
f1f8dea
weathertyping
thomaskroi1996 May 7, 2024
05afc1b
weathertyping
thomaskroi1996 May 7, 2024
a780ff4
reformatted code, added anomaly and std plots
thomaskroi1996 May 21, 2024
66d524c
reformatted coe, added anomaly and std plots
thomaskroi1996 May 21, 2024
085e4f2
update
thomaskroi1996 May 26, 2024
507434f
added predefined_slwt
thomaskroi1996 Jun 9, 2024
a90da22
mainly doc, also rewrite functions
thomaskroi1996 Jun 16, 2024
6363728
Merge branch 'main' into weathertyping_wegc
thomaskroi1996 Jun 17, 2024
4b7c412
code reformatting, documentation, bugfixes
thomaskroi1996 Jun 23, 2024
e48c391
reformat
thomaskroi1996 Jun 29, 2024
2afe014
Merge branch 'main' into weathertyping_wegc
thomaskroi1996 Jul 4, 2024
b2255db
bugfix
thomaskroi1996 Jul 4, 2024
e5a0f9c
bugfix
thomaskroi1996 Jul 4, 2024
aa47dc3
add recipes for CMIP5, CORDEX and seasonal occurence plot
thomaskroi1996 Jul 11, 2024
afd343c
add seasonal occurence plot
thomaskroi1996 Jul 11, 2024
7e57854
new recipes
thomaskroi1996 Aug 5, 2024
6acb3f5
doc update, added ensemble to plot names
thomaskroi1996 Aug 8, 2024
836a6c8
commenting models
mwjury Aug 22, 2024
a6928c8
bugfix
thomaskroi1996 Sep 15, 2024
b781eee
predefined wt
thomaskroi1996 Sep 15, 2024
07d9a5a
Merge branch 'main' into weathertyping_wegc
valeriupredoi Sep 19, 2024
97eea08
minor corrections
thomaskroi1996 Sep 24, 2024
9c7c6ad
add era5 to recipe_weathertyping.rst
thomaskroi1996 Sep 24, 2024
4246910
added timerange, fixed prov, more bugfixes
thomaskroi1996 Sep 29, 2024
240bd6e
area
thomaskroi1996 Sep 29, 2024
599dc38
renamed vars
thomaskroi1996 Oct 3, 2024
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions doc/sphinx/source/recipes/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Atmosphere
recipe_validation
recipe_radiation_budget
recipe_aod_aeronet_assess
recipe_weathertyping

Climate metrics
^^^^^^^^^^^^^^^
Expand Down
112 changes: 112 additions & 0 deletions doc/sphinx/source/recipes/recipe_weathertyping.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
.. _recipes_weathertyping:

Lamb Weathertypes
=====

Overview
--------

A diagnostic to calculate Lamb weathertypes over a given region. Furthermore,
correlations between weathertypes and precipitation patterns over a given are can be calculated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
correlations between weathertypes and precipitation patterns over a given are can be calculated
correlations between weathertypes and precipitation patterns over a given area can be calculated

and 'combined' or 'simplified' weathertypes can be derived. Additionally, mean fields, as well as
anomalies and standard deviations can be plotted.


Available recipes and diagnostics
---------------------------------

Recipes are stored in esmvaltool/recipes/

* recipe_weathertyping.yml

Diagnostics are stored in esmvaltool/diag_scripts/weathertyping/

* weathertyping.py: calculate lamb and simplified WT, plot mean, anomalies and std for each WT for psl, tas, prcp
thomaskroi1996 marked this conversation as resolved.
Show resolved Hide resolved


User settings in recipe
-----------------------

#. weathertyping.py

*Required settings for script*

*Optional settings for script*

* correlation_threshold: correlation threshold for selecting similar WT pairs, only needed if automatic_slwt==True and predefined_slwt==False. default=0.9
* rmse_threshold: rmse threshold for selecting similar WT pairs, only needed if automatic_slwt==True and predefined_slwt==False. default=0.002
* plotting: if true, create plots of means, anomalies and std for psl, tas, prcp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* plotting: if true, create plots of means, anomalies and std for psl, tas, prcp
* plotting: if true, create plots of means, anomalies and std for psl, tas, pr

* automatic_slwt: if true, automatically combine WT with similar precipitation patterns over specified area (via thresholds of correlation and rmse OR via predefined_slwt)
* predefined_slwt: dictionary of mappings between weathertypes

.. note::

predefined_slwt can be a dictionary where keys are slwt and the values are arrays of lwt OR where keys are lwt and values are slwt

*Required settings for variables*

*Optional settings for variables*

*Required settings for preprocessor*

*Optional settings for preprocessor*

*Color tables*


Variables
---------

* psl (atmos, day, time longitude latitude)
* tas (atmos, day, time longitude latitude)
* tp (atmos, day, time longitude latitude)
* pr (atmos, day, time longitude latitude)


Observations and reformat scripts
---------------------------------

*Note: (1) obs4MIPs data can be used directly without any preprocessing;
(2) see headers of reformat scripts for non-obs4MIPs data for download
instructions.*

* E-OBS: European Climate Assessment & Dataset gridded observationl daily precipitation sum
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* E-OBS: European Climate Assessment & Dataset gridded observationl daily precipitation sum
* E-OBS: European Climate Assessment & Dataset gridded daily precipitation sum

add ERA5 as well


References
----------

* Maraun, D., Truhetz, H., & Schaffer, A. (2021). Regional climate model biases, their dependence on synoptic circulation biases and the potential for bias adjustment: A process-oriented evaluation of the Austrian regional climate projections. Journal of Geophysical Research: Atmospheres, 126, e2020JD032824. https://doi.org/10.1029/2020JD032824
* Jones, P.D., Hulme, M. and Briffa, K.R. (1993), A comparison of Lamb circulation types with an objective classification scheme. Int. J. Climatol., 13: 655-663. https://doi.org/10.1002/joc.3370130606

Example plots
-------------

.. _fig_weathertyping_1:
.. figure:: /recipes/figures/weathertyping/lwt_1_ERA5_psl_mean.png
:align: center

PSL mean map of Lamb WT 1 for ERA5.

.. _fig_weathertyping_2:
.. figure:: /recipes/figures/weathertyping/lwt_1_TaiESM1_psl_mean.png
:align: center

PSL mean map of Lamb WT 1 for TaiESM1.

.. _fig_weathertyping_3:
.. figure:: /recipes/figures/weathertyping/slwt_EOBS_4_ERA5_psl_mean.png
:align: center

PSL mean map of slwt_EOBS 4 for ERA5 (in this case combined Lamb WT 24 and 23).

.. _fig_weathertyping_4:
.. figure:: /recipes/figures/weathertyping/correlation_matrix_E-OBS.png
:align: center

Heatmap of correlation values for Lamb WTs 1-27.

.. _fig_weathertyping_5:
.. figure:: /recipes/figures/weathertyping/ERA5__lwt_rel_occurrence.png
:align: center

Stackplot of seasonal relative occureences of each WT for ERA5.
12 changes: 12 additions & 0 deletions esmvaltool/config-references.yml
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,11 @@ authors:
name: Juckes, Martin
institute: BADC, UK
orcid:
jury_martin:
name: Jury, Martin
institute: WEGC, Austria
e-mail: [email protected]
orcid: https://orcid.org/0000-0003-0590-7843
kadygrov_nikolay:
name: Kadygrov, Nikolay
institute: IPSL, France
Expand Down Expand Up @@ -315,6 +320,12 @@ authors:
name: Krasting, John
institute: NOAA, USA
orcid: https://orcid.org/0000-0002-4650-9844
kroissenbrunner_thomas:
name: Kroissenbrunner, Thomas
institute: WEGC, Austria
email: [email protected]
github: thomaskroi1996
orcid:
kuehbacher_birgit:
name: Kuehbacher, Birgit
institute: DLR, Germany
Expand Down Expand Up @@ -793,6 +804,7 @@ projects:
trr181: DFG Project TRR-181, Energy transfers in Atmosphere and Ocean
ukesm: UKESM, UK Earth System Model project (NERC)
usmile: ERC Synergy Grant USMILE
preval: PREVAL ÖKS


realms:
Expand Down
222 changes: 222 additions & 0 deletions esmvaltool/diag_scripts/weathertyping/weathertyping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
from wt_utils import (get_cfg_vars, load_wt_preprocessors,
wt_algorithm, get_ancestors_era5_eobs, calc_slwt_obs,
run_predefined_slwt, combine_wt_to_file, load_wt_files,
get_looping_dict, plot_means, get_model_output_filepath,
calc_lwt_slwt_model, write_lwt_to_file, calc_lwt_model,
plot_seasonal_occurrence
)

import iris

# import internal esmvaltool modules here
from esmvaltool.diag_scripts.shared import (
run_diagnostic,
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you could please run isort on this, that'll fix the import order; also - are you importing everything from wt_utils ? - could do the otherwise bad from wt_utils import * if so, and save the reader looking at a huge imports list 😁


def run_automatic_slwt(cfg: dict):
preproc_variables_dict, _, _, \
work_dir, plotting, _, predefined_slwt = get_cfg_vars(cfg)
for dataset_name, dataset_vars in preproc_variables_dict.items():
if dataset_name == 'ERA5':
wt_preproc, wt_preproc_prcp, wt_preproc_prcp_eobs = \
load_wt_preprocessors(dataset_name, preproc_variables_dict)

# calculate lwt
lwt = wt_algorithm(wt_preproc, dataset_name)

era5_ancestors, eobs_ancestors = get_ancestors_era5_eobs(
dataset_name, preproc_variables_dict)

# calculate simplified lwt based on precipitation
# patterns or use predefined_slwt
if predefined_slwt is False:
slwt_era5 = calc_slwt_obs(
cfg,
lwt,
wt_preproc_prcp,
dataset_name,
era5_ancestors,
)
slwt_eobs = calc_slwt_obs(
cfg,
lwt,
wt_preproc_prcp_eobs,
'E-OBS',
eobs_ancestors,
)
else:
slwt_era5, slwt_eobs = run_predefined_slwt(work_dir,
dataset_name,
lwt,
predefined_slwt)

# write to file
wt_list = [lwt, slwt_era5, slwt_eobs]
combine_wt_to_file(cfg, wt_list, wt_preproc,
dataset_name)

# load weathertype files as cubes
wt_cubes = load_wt_files(f'{work_dir}/{dataset_name}.nc')

var_dict = get_looping_dict(
dataset_vars
) # dataset_vars is list of variables for dataset dataset_name
if plotting:
# plot means
for var_name, var_data in var_dict.items():
data_info = {'dataset': dataset_name,
'var': var_name,
'preproc_path': var_data[1]}
plot_means(cfg, var_data[0], wt_cubes, data_info)
plot_seasonal_occurrence(cfg, wt_cubes, dataset_name)
else:
if dataset_name == 'E-OBS':
continue
wt_preproc = iris.load_cube(dataset_vars[0].get('filename'))

output_file_path, preproc_path = get_model_output_filepath(
dataset_name, dataset_vars)

# calculate weathertypes
data_info = {'dataset': dataset_name,
'preproc_path': preproc_path,
'output_file_path': output_file_path}
calc_lwt_slwt_model(cfg, wt_preproc, data_info, predefined_slwt)

# load wt files
wt_cubes = load_wt_files(
f'{work_dir}/{output_file_path}/{dataset_name}.nc')

var_dict = get_looping_dict(
dataset_vars
) # dataset_vars is list of variables for dataset dataset_name

if plotting:
# plot means
ensemble = dataset_vars[0].get('ensemble')
for var_name, var_data in var_dict.items():
data_info = {'dataset': dataset_name,
'var': var_name,
'preproc_path': var_data[1],
'ensemble': ensemble}
plot_means(cfg, var_data[0], wt_cubes, data_info,
only_lwt=True)
plot_seasonal_occurrence(cfg, wt_cubes, dataset_name,
ensemble=ensemble)


def run_lwt(cfg: dict):
preproc_variables_dict, _, _, \
work_dir, plotting, _, _ = get_cfg_vars(cfg)
for dataset_name, dataset_vars in preproc_variables_dict.items():
if dataset_name == 'ERA5':
wt_preproc, wt_preproc_prcp, wt_preproc_prcp_eobs = \
load_wt_preprocessors(dataset_name, preproc_variables_dict)

# calculate lwt
lwt = wt_algorithm(wt_preproc, dataset_name)

era5_ancestors, eobs_ancestors = get_ancestors_era5_eobs(
dataset_name, preproc_variables_dict)

# calculate simplified lwt based on precipitation patterns
_ = calc_slwt_obs(
cfg,
lwt,
wt_preproc_prcp,
dataset_name,
era5_ancestors,
)
_ = calc_slwt_obs(
cfg,
lwt,
wt_preproc_prcp_eobs,
'E-OBS',
eobs_ancestors,
)

# write only lwt to file
write_lwt_to_file(cfg, lwt, wt_preproc, dataset_name)

# load wt files
wt_cubes = load_wt_files(f'{work_dir}/{dataset_name}.nc',
only_lwt=True)

var_dict = get_looping_dict(
dataset_vars
) # dataset_vars is list of variables for dataset dataset_name

if plotting:
# plot means
for var_name, var_data in var_dict.items():
data_info = {'dataset': dataset_name,
'var': var_name,
'preproc_path': var_data[1]}
plot_means(cfg, var_data[0], wt_cubes, data_info,
only_lwt=True)
plot_seasonal_occurrence(cfg, wt_cubes, dataset_name)
else:
if dataset_name == 'E-OBS':
continue
wt_preproc = iris.load_cube(dataset_vars[0].get('filename'))

output_file_path = get_model_output_filepath(
dataset_name, dataset_vars)[1]

# calculate weathertypes
calc_lwt_model(cfg, wt_preproc, dataset_name, output_file_path)

# load wt files
wt_cubes = load_wt_files(f'{work_dir}/{dataset_name}.nc',
only_lwt=True)

var_dict = get_looping_dict(
dataset_vars
) # dataset_vars is list of variables for dataset dataset_name

if plotting:
# plot means
ensemble = dataset_vars[0].get('ensemble')
for var_name, var_data in var_dict.items():
data_info = {'dataset': dataset_name,
'var': var_name,
'preproc_path': var_data[1],
'ensemble': ensemble}
plot_means(cfg, var_data[0], wt_cubes, data_info,
only_lwt=True)
plot_seasonal_occurrence(cfg, wt_cubes, dataset_name,
ensemble=ensemble)


def run_my_diagnostic(cfg: dict):
'''
Arguments:
cfg - nested dictionary of metadata

Returns:
string; runs the user diagnostic

'''
# assemble the data dictionary keyed by dataset name
# this makes use of the handy group_metadata function that
# orders the data by 'dataset'; the resulting dictionary is
# keyed on datasets e.g. dict = {'MPI-ESM-LR': [var1, var2...]}
# where var1, var2 are dicts holding all needed information per variable
automatic_slwt = cfg.get('automatic_slwt')

if automatic_slwt:
run_automatic_slwt(cfg)
# if automatic_slwt is false, and predefined_slwt is false,
# just write selected pairs to file
elif not automatic_slwt:
run_lwt(cfg)


if __name__ == '__main__':

# always use run_diagnostic() to get the config (the preprocessor
# nested dictionary holding all the needed information)
with run_diagnostic() as config:
# list here the functions that need to run
run_my_diagnostic(config)
Loading