Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
130 changes: 49 additions & 81 deletions esmvaltool/diag_scripts/seaice/seaice_sensitivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import iris
import matplotlib.pyplot as plt
import pandas as pd
import yaml
from matplotlib.colors import Normalize
from scipy import stats

Expand Down Expand Up @@ -37,13 +38,24 @@ def get_provenance_record(cfg, caption):
return record


def list_datasets(data):
"""Actually returns a set of datatsets, to avoid duplication."""
logger.debug("listing datasets")
datasets = set()
def create_categorised_dataset_dict(data):
"""Create a dictionary of datasets categorised into models and observations."""
logger.debug("Creating categorised dataset dictionary from %s", data)
# Initialise blank dictionary
dict = {
'models': {},
'observations': {},
}

# Iterate over the data
for element in data:
datasets.add(element["dataset"])
return datasets
if 'observation' in element:
if element['observation']:
dict['observations'][element['dataset']] = {}
else:
dict['models'][element['dataset']] = {}

return dict


def extract_cube(data, variable_group):
Expand Down Expand Up @@ -142,28 +154,6 @@ def write_obs_from_cfg(cfg):
obs_dict["notz_style"]["std_dev"] = notz_values["standard deviation"]
obs_dict["notz_style"]["plausible"] = notz_values["plausible range"]

# Add a blank dictionary for the Roach-style plot
obs_dict["roach_style"] = {}

# Add each observation point to the dictionary
roach_values = cfg["observations"]["annual trends (Roach-style plot)"]
for point in roach_values.keys():
obs_dict["roach_style"][point] = {}

# Add the individual values for the observation point
obs_dict["roach_style"][point]["annual_tas_trend"] = roach_values[
point
]["GMST trend"]
obs_dict["roach_style"][point]["annual_siconc_trend"] = roach_values[
point
]["SIA trend"]
obs_dict["roach_style"][point]["r_value"] = roach_values[point][
"Pearson CC of SIA over GMST"
]
obs_dict["roach_style"][point]["p_value"] = roach_values[point][
"significance of SIA over GMST"
]

return obs_dict


Expand Down Expand Up @@ -208,7 +198,7 @@ def write_dictionary_to_csv(cfg, model_dict, filename):
csv_filepath = f"{cfg['work_dir']}/{filename}.csv"

# Write the data to a csv file (via a Pandas DataFrame)
pd.DataFrame.from_dict(model_dict, orient="index").to_csv(csv_filepath)
pd.DataFrame.from_dict(model_dict, orient="index").to_csv(csv_filepath, index_label="Dataset")
logger.info("Wrote data to %s", csv_filepath)

# Create a provenance record for the csv file
Expand Down Expand Up @@ -349,54 +339,36 @@ def roach_style_plot_from_dict(data_dictionary, titles_dictionary, cfg):
if inner_dict["label"] == "to_label":
plt.annotate(dataset, xy=(x, y), xytext=(x + 0.01, y - 0.005))

# Read from observations dictionary
obs_years = titles_dictionary["obs"]["obs_period"]
obs_dict = titles_dictionary["obs"]["roach_style"]

# Add the observations
for point in obs_dict.keys():
# Get the values for the point
x = obs_dict[point]["annual_tas_trend"]
y = obs_dict[point]["annual_siconc_trend"]
r_corr = obs_dict[point]["r_value"]
p_val = obs_dict[point]["p_value"]

# Provide a default colour for the point if Pearson coefficient is missing
if r_corr is None:
r_corr = 0

# Provide a pattern for the point if the p-value is present and sufficiently large
if p_val is not None and p_val >= 0.05:
h = 5 * "/" # This is a hatch pattern
else:
h = None

# Plot the point only if both x and y values are provided
if x is not None and y is not None:
plt.scatter(
x,
y,
marker="s",
s=150,
c=[r_corr],
hatch=h,
cmap=cmap,
norm=norm,
zorder=0,
edgecolors="black",
)
# # Provide a default colour for the point if Pearson coefficient is missing
# if r_corr is None:
# r_corr = 0
#
# # Provide a pattern for the point if the p-value is present and sufficiently large
# if p_val is not None and p_val >= 0.05:
# h = 5 * "/" # This is a hatch pattern
# else:
# h = None
#
# # Plot the point only if both x and y values are provided
# if x is not None and y is not None:
# plt.scatter(
# x,
# y,
# marker="s",
# s=150,
# c=[r_corr],
# hatch=h,
# cmap=cmap,
# norm=norm,
# zorder=0,
# edgecolors="black",
# )

# Add a colour bar
plt.colorbar(label="Pearson correlation coefficient")

# Create caption based on whether observational temp trend is present
if obs_dict["first point"]["annual_tas_trend"] is not None:
caption = (
"Decadal trends of sea ice area and global mean temperature."
f"Observations from {obs_years} are plotted as squares."
)
else:
caption = "Decadal trends of sea ice area and global mean temperature."
# Create caption
caption = "Decadal trends of sea ice area and global mean temperature."

# Save the figure (also closes it)
save_figure(
Expand All @@ -419,22 +391,18 @@ def main(cfg):
titles_and_obs_dict = create_titles_dict(input_data, cfg)
logger.debug("Titles and observations dictionary: %s", titles_and_obs_dict)

# Initialize blank data dictionary to send to plotting codes later
data_dict = {}

# Get list of datasets from cfg
logger.info("Listing datasets in the data")
datasets = list_datasets(input_data)
dataset_dict = create_categorised_dataset_dict(input_data)
data_dict = dataset_dict['models']


# Iterate over each dataset
for dataset in datasets:
for dataset in data_dict.keys():
# Select only data from that dataset
logger.debug("Selecting data from %s", dataset)
selection = select_metadata(input_data, dataset=dataset)

# Add the dataset to the dictionary with a blank inner dictionary
data_dict[dataset] = {}

# Add an entry to determine labelling in plots
if "label_dataset" in selection[0]:
data_dict[dataset]["label"] = "to_label"
Expand Down
107 changes: 57 additions & 50 deletions esmvaltool/recipes/recipe_seaice_sensitivity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,33 @@ documentation:
maintainer:
- parsons_naomi

defaults: &defaults {ensemble: r1i1p1f1, exp: historical, grid: gn, project: CMIP6}
datasets:
- {<<: *defaults, dataset: HadGEM3-GC31-LL, institute: MOHC, ensemble: r1i1p1f3, label_dataset: True}
- {<<: *defaults, dataset: UKESM1-0-LL, institute: MOHC, ensemble: r1i1p1f2, label_dataset: True}
- {<<: *defaults, dataset: ACCESS-CM2, institute: CSIRO-ARCCSS}
- {<<: *defaults, dataset: ACCESS-ESM1-5, institute: CSIRO}
- {<<: *defaults, dataset: BCC-CSM2-MR, institute: BCC}
- {<<: *defaults, dataset: CAMS-CSM1-0, institute: CAMS}
- {<<: *defaults, dataset: CanESM5, institute: CCCma}
- {<<: *defaults, dataset: CESM2, institute: NCAR}
- {<<: *defaults, dataset: CESM2-WACCM, institute: NCAR}
- {<<: *defaults, dataset: CESM2-WACCM-FV2, institute: NCAR}
- {<<: *defaults, dataset: FIO-ESM-2-0, institute: FIO-QLNM}
- {<<: *defaults, dataset: MIROC6, institute: MIROC}
- {<<: *defaults, dataset: MPI-ESM-1-2-HAM, institute: HAMMOZ-Consortium}
- {<<: *defaults, dataset: MPI-ESM1-2-HR, institute: MPI-M}
- {<<: *defaults, dataset: MPI-ESM1-2-LR, institute: MPI-M}
- {<<: *defaults, dataset: MRI-ESM2-0, institute: MRI}
model_defaults: &model_defaults { ensemble: r1i1p1f1, exp: historical, grid: gn, project: CMIP6}
model_datasets: &model_datasets
- {<<: *model_defaults, dataset: HadGEM3-GC31-LL, institute: MOHC, ensemble: r1i1p1f3, label_dataset: True}
- {<<: *model_defaults, dataset: UKESM1-0-LL, institute: MOHC, ensemble: r1i1p1f2, label_dataset: True}
- {<<: *model_defaults, dataset: ACCESS-CM2, institute: CSIRO-ARCCSS}
- {<<: *model_defaults, dataset: ACCESS-ESM1-5, institute: CSIRO}
- {<<: *model_defaults, dataset: BCC-CSM2-MR, institute: BCC}
- {<<: *model_defaults, dataset: CAMS-CSM1-0, institute: CAMS}
- {<<: *model_defaults, dataset: CanESM5, institute: CCCma}
- {<<: *model_defaults, dataset: CESM2, institute: NCAR}
- {<<: *model_defaults, dataset: CESM2-WACCM, institute: NCAR}
- {<<: *model_defaults, dataset: CESM2-WACCM-FV2, institute: NCAR}
- {<<: *model_defaults, dataset: FIO-ESM-2-0, institute: FIO-QLNM}
- {<<: *model_defaults, dataset: MIROC6, institute: MIROC}
- {<<: *model_defaults, dataset: MPI-ESM-1-2-HAM, institute: HAMMOZ-Consortium}
- {<<: *model_defaults, dataset: MPI-ESM1-2-HR, institute: MPI-M}
- {<<: *model_defaults, dataset: MPI-ESM1-2-LR, institute: MPI-M}
- {<<: *model_defaults, dataset: MRI-ESM2-0, institute: MRI}

obs_defaults: &obs_defaults { project: OBS, observation: True, tier: 2}
tasa_obs: &tasa_obs
- { <<: *obs_defaults, dataset: GISTEMP, type: ground, version: v4 }
- { <<: *obs_defaults, dataset: HadCRUT5, type: ground, version: 5.0.1.0-analysis }
- { <<: *obs_defaults, dataset: NOAAGlobalTemp, type: ground, version: v5.0.0, mip: Amon }

arctic_si_obs: &arctic_si_obs
- { <<: *obs_defaults, dataset: OSI-450-nh, type: reanaly, version: v3, mip: OImon, supplementary_variables: [{short_name: areacello, mip: fx}]}

preprocessors:
extract_test_period:
Expand Down Expand Up @@ -112,9 +121,24 @@ diagnostics:
siconc:
preprocessor: pp_arctic_sept_sea_ice
mip: SImon
additional_datasets:
*model_datasets
tas:
preprocessor: pp_avg_ann_global_temp
mip: Amon
additional_datasets:
*model_datasets
si_obs:
short_name: siconc
preprocessor: pp_arctic_sept_sea_ice
additional_datasets:
*arctic_si_obs
tasa_obs:
short_name: tasa
preprocessor: pp_avg_ann_global_temp
mip: Amon
additional_datasets:
*tasa_obs
scripts:
sea_ice_sensitivity_script:
script: seaice/seaice_sensitivity.py
Expand All @@ -124,22 +148,6 @@ diagnostics:
mean: -4.01
standard deviation: 0.32
plausible range: 1.28
annual trends (Roach-style plot):
first point:
GMST trend:
SIA trend:
Pearson CC of SIA over GMST:
significance of SIA over GMST:
second point:
GMST trend:
SIA trend:
Pearson CC of SIA over GMST:
significance of SIA over GMST:
third point:
GMST trend:
SIA trend:
Pearson CC of SIA over GMST:
significance of SIA over GMST:


antarctic:
Expand All @@ -148,9 +156,24 @@ diagnostics:
siconc:
preprocessor: pp_antarctic_avg_ann_sea_ice
mip: SImon
additional_datasets:
*model_datasets
tas:
preprocessor: pp_avg_ann_global_temp
mip: Amon
additional_datasets:
*model_datasets
# si_obs:
# short_name: siconc
# preprocessor: pp_antarctic_avg_ann_sea_ice
# additional_datasets:
# *antarctic_si_obs
tasa_obs:
short_name: tasa
preprocessor: pp_avg_ann_global_temp
mip: Amon
additional_datasets:
*tasa_obs
scripts:
sea_ice_sensitivity_script:
script: seaice/seaice_sensitivity.py
Expand All @@ -160,19 +183,3 @@ diagnostics:
mean:
standard deviation:
plausible range:
annual trends (Roach-style plot):
first point:
GMST trend:
SIA trend:
Pearson CC of SIA over GMST:
significance of SIA over GMST:
second point:
GMST trend:
SIA trend:
Pearson CC of SIA over GMST:
significance of SIA over GMST:
third point:
GMST trend:
SIA trend:
Pearson CC of SIA over GMST:
significance of SIA over GMST: