Part 5 - Global warming levels (ii)
Prepared by Mathias Hauser.
In the fifth part, we will continue our work on global warming levels. Instead of comparing the pattern of two models at the same warming level, we want to compare the average over all available models for two different warming levels. At the end of this part we will have a figure that is very similar to one from Chapter 11 of the sixth (i.e. most recent) Assessment Report of Working Group I of the Intergovernmental Panel on Climate Change (IPCC AR6 WG1) — Figure 11.11.
Loading 20 (or so) models manually would be quite tedious. We will therefore introduce (or repeat) some python constructions that will hopefully make our lives easier.
The first problem we will tackle is how to handle the 20+ models in
python. We could store each model in a separate variable
(tas_model1 =
, tas_model2 =
, etc.), but this would become
annoying very quickly. There are many alternative ways to do this -
we’ll see one of them. What we need is some sort of “container” where we can
can store the data from more than one model. There are several options,
we could
combine all models into a single
DataArray
(orDataset
) as for the global mean temperaturesuse a tuple or a list,
a dictionary, or
something else.
There is no right solution - each of them would work and has different advantages and disadvanges. Here, we will go with dictionaries which are described below.
Then we also need a way to dynamically construct the filename and should be able to “insert” the model name into a template. We will use f-strings for this.
Learning goals
programming goals
get to know dictionaries and f-strings
using some new functions and methods
how to expand the analysis from single models to many models
scientific and data analysis goals
assess TXx at different global warming levels
see how spatial patterns are smoothed when averaging across multiple climate models
Preparation
Create a new notebook with the name p5_warming_level_comparison_name.ipynb
.
Dictionaries
Dictionaries are a native python data container that store data as
key-value pairs. In the following example the "a"
is the key
and 5
the value
:
d = dict(a=5)
The key needs to be a string while the value can be any python object.
We will use this to work with data from different models - the name of
the model (e.g., "ACCESS-CM2"
) will be the key while its data (an
xarray DataArray
or Dataset
) will be the value. Passing the
key to the dictionary in square brackets, e.g. d["a"]
will then return the value.
Create a new dictionary named
d
(as above). Set"a"
to 5 and"b"
to 7.You can get the value from a dictionary using square brackets:
d["a"]
. Read back the value of"b"
.What happens if you pass a key that does not exist in the dictionary, e.g.
d["c"]
?There is an alternative way to get a key from a dictionary - using
d.get("b")
. What happens if you pass a key that does not exist in the dictionary toget
, e.g.,d.get("c")
?We can assign new values to an existing dictionary using
d["d"] = 9
. Assign11
to"e"
.What happens if you do
d["a"] = 7
? Is the old value overwritten?We have now learned how to get and assigned values from a dictionary. Before moving on we need to see how we can loop through a dictionary. There are three possibilities - per default it loops over the keys, but we can also loop through the values or both:
for key in d: print(f"{key=}") for value in d.values(): print(f"{value=}") for key, value in d.items(): print(f"{key=}, {value=}")
Copy the three for loops and execute them - do they do what you expect?
There are two ways to create dictionaries. Either with curly braces (d = {"a": 5}
)
or using d = dict(a=5)
. They result in the same dictionary.
f-strings
To open the files with the data we need to pass the filename. Until now we constructed the filename manually, e.g.:
file1 = "tasmax_ann_ACCESS-CM2_historical_r1i1p1f1_g025.nc"
file2 = "tasmax_ann_GFDL-ESM4_historical_r1i1p1f1_g025.nc"
However, (i) this becomes cumbersome fast and (ii) the only part that is
different is the name of the model. Wouldn’t it be nice if we can
somehow substitute the model name in the string? And indeed this is
possible with so-called f-strings, which are strings where an “f” is
added before the quotes: f""
and the “f” stands for format. In
an f-string everything in curly braces (and including the braces) is
substituted by a variable of the same name. Thus, the following example will print
'tas'
:
var = "tas"
print(f"{var}")
Or for our case we can do:
model = "ACCESS-CM2"
f"tasmax_ann_{model}_historical_r1i1p1f1_g025.nc"
where "{model}"
would now be replaced by "ACCESS-CM2"
(test this
by copying it to a code cell).
Test this by copying the two lines to your notebook.
Read global mean temperature
After these excursions let’s dive in to the analysis.
Add a new markdown title e.g.
# Analysis
.Open the netCDF file with annual mean global mean temperatures you saved in Part 2 (“Convert to a Dastaset”).
Compute anomalies w.r.t. 1850 – 1900 and select the variable tas.
Load tasmax data
Now we are finally ready to load the tasmax data of all the models. We want to load the netCDF files in a for loop over all model names, create the filename using a f-string and store it in a dictionary.
Create filename dynamically
Start with the filename and adapt it such that it shows
"EC-Earth3"
instead of"MIROC6"
using an f-string:model = "EC-Earth3" filename = "../data/cmip6/tasmax/txx/txx_tasmax_day_MIROC6_historical-ssp585_r1i1p1f1_g025.nc print(filename)
Create the new filename in a loop:
create a loop over
tas.models.values
Copy the adapted “filename” from above and print the result.
Load data
To load the data we need to we need to have the following structure:
# create dictionary to store the data
tasmax_dict = dict()
# loop over models
for model in tas.models.values:
# create filename
filename = ...
# read netcdf
ds = xr.open_dataset(filename)
# get the DataArray from the Dataset
da = ds.tasmax
# calculate the anomaly
da = ...
# assign to dict
tasmax_dict[model] = da
Update the code above to load and process all models.
Test the dictionary
Read the model
"EC-Earth3"
from the dict.Select the first timestep and plot it.
Create a weighted or unweighted mean (over whole time period) and plot the resulting time series.
Calculate tasmax at the 1.5 °C warming level
The next step is to calculate tasmax for all models for a certain warming level. Again we will loop through all models, calculate the warming level period and select the respective years from the tasmax data and average over them. Thus adapt the following code:
tasmax_at_15_dict = dict()
for model in tas.models.values:
# select global mean temperature for the model
tas_ = ...
# select TXx for the model
tasmax = ...
# compute the warming level period
period = ...
# average over the warming level period
tasmax = tasmax.sel(year=period).mean("year")
# assign to dict
tasmax_at_15_dict[model] = tasmax
Tip
tas
is a DataArray
while tasmax_dict
is a dictionary so you need to select
the model differently.
Concatenate all models
Now we have one entry for each model in the tasmax_at_15_dict
. The dictionary was
helpful to read and process each individual model. However, we now want to average over
all the models, for this it’s better to have all models in the same xr.DataArray
(as tas
). Therefore we concatenate all models into one DataArray:
Using
xr.concat()
concatenate all models into a singleDataArray
over a new dimension named"models"
. Becausetasmax_at_15_dict
is a dict you have to pass the.values()
to the function.Use
tasmax_at_15 = tasmax_at_15.assign_coords(models=list(tasmax_at_15_dict.keys()))
to assign the model names as coordinates.
Plot
Calculate the mean over the
"models"
dimension, and create a plot.
Check the function
There is a function
def at_warming_level(tas, index, warming_level): ...
in computation.py. Have a look at the it to see how it compares with yours.
Comparison
Calculate
tasmax_at_15
again using the function.Calculate the mean over the
"models"
dimension, and create a plot.Make sure the plot shows the same as the one above.
Calculate tasmax at the 2.0 °C warming level
Calculate
tasmax_at_20
, i.e. for a global warming level of 2.0 °C using the new function.
Create a plot of the two warming levels
Prepare a map plot with two subplots. Choose a projection of your liking. Add coastlines.
You can copy the code from Part 4 but be sure to adapt everything that is necessary.
Plot the mean over the models for
tasmax_at_15
andtasmax_at_20
.Make sure the two variables show the same color scale.
Add a the name of the model as title.
Compare your figure to the one from the IPCC: Figure 11.11.
This concludes Part 5.