Open In Colab   Open in Kaggle

The Impact of ENSO on Precipitation and Temperature#

Content creators: Olawale Ikuyajolu & Patrick Orenstein

Content reviewers: Marguerite Brown, Yuxin Zhou

Content editors: Zane Mitrevica, Natalie Steinemann, Jenna Pearson, Chi Zhang, Ohad Zivan

Production editors: Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan

Our 2023 Sponsors: NASA TOPS, Google DeepMind, and CMIP

In this project you will work with climate model output, reanalysis data, and Niño 3.4 indices from CMIP5/6, ERA5, NOAA, and HadISST to understand the historical and future impacts of El Niño Southern Oscillation (ENSO) events on rainfall and temperature. You will focus on variables like sea surface temperature, surface air temperature, and precipitation. You will also be able to investigate the relationships between these variables and how they affect community efforts to prepare for the impacts of El Niño phases.

Recall from W1D1 that ENSO is a climate phenomena that originates in the tropical Pacific ocean but has global impacts on atmospheric circulation, temperature and precipitation. The two phases of ENSO are El Niño (warmer than average SSTs in the central and eastern tropical Pacific Ocean) and La Niña (cooler than average SSTs in the central and eastern tropical Pacific Ocean). The Niño 3.4 region is an area in the central and eastern Pacific Ocean that is often used for determining the phase of ENSO.

You may also reference W1D5, W2D1, and W2D4 tutorials on CMIP6 and read more about the different CMIP6 scenarios here. Please see the Resources section at the bottom of this notebook for more information.

Project Template#

Project Template

Note: The dashed boxes are socio-economic questions.

Data Exploration Notebook#

Project Setup#

# google colab installs

# !pip install condacolab &> /dev/null
# import condacolab
# condacolab.install()

# install all packages in one call (+ use mamba instead of conda)
# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils "esmf<=8.3.1" xesmf &> /dev/null
# imports

import time

tic = time.time()

import intake
import numpy as np
import matplotlib.pyplot as plt
import xarray as xr
import xesmf as xe
from xmip.preprocessing import combined_preprocessing
from xarrayutils.plotting import shaded_line_plot
from datatree import DataTree
from xmip.postprocessing import _parse_metric
import cartopy.crs as ccrs
import pooch
import os
import tempfile
# functions

%matplotlib inline

col = intake.open_esm_datastore(
    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
)  # open an intake catalog containing the Pangeo CMIP cloud data


def load_cmip6(source_id, variable_id, member_id, table_id):  # load selected model
    cat = col.search(
        source_id=source_ids,
        variable_id=variable_id,
        member_id=member_id,
        table_id=table_id,
        grid_label="gn",
        experiment_id=[
            "historical",
            "ssp126",
            "ssp245",
            "ssp585",
        ],  # downloading the scenarios out of the total 5+historical
        require_all_on=["source_id"],
    )

    kwargs = dict(
        preprocess=combined_preprocessing,
        xarray_open_kwargs=dict(use_cftime=True),
        storage_options={"token": "anon"},
    )
    cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
    dt = cat.to_datatree(**kwargs)

    return dt
# helper functions

def pooch_load(filelocation=None,filename=None,processor=None):
    shared_location='/home/jovyan/shared/Data/Projects/ENSO' # this is different for each day
    user_temp_cache=tempfile.gettempdir()
    
    if os.path.exists(os.path.join(shared_location,filename)):
        file = os.path.join(shared_location,filename)
    else:
        file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)

    return file

Dataset 1: Load CMIP6 Model of Your Choice#

Following W2D1 (Week 2 Day 1) tutorial notebooks:

  • We use the CESM2 model (source_id) and ensemble member r4i1p1f1 (member_id) in this template, but you are free to select any model and ensemble member. Make sure the member_id selected is available for your model. You can learn more about the member_id and other CMIP6 facets through the links at the end of the CMIP Resource Bank

  • load_cmip6 function load both historical and ssp585 (future: climate change)

To learn more about CMIP, including additional ways to access CMIP data, please see our CMIP Resource Bank and the CMIP website.

# pick your model

source_ids = "CESM2"

dm_tas = load_cmip6(
    source_ids, "tas", "r4i1p1f1", "Amon"
)  # tas is atmoerhpere temprature
dm_pr = load_cmip6(source_ids, "pr", "r4i1p1f1", "Amon")  # pr is precipitation rate
dm_sst = load_cmip6(
    source_ids, "tos", "r4i1p1f1", "Omon"
)  # tos is surface ocean temprature
print(
    dm_tas.keys()
)  # an example for one of the datatrees, you can duplicate this for the other DT
--> The keys in the returned dictionary of datasets are constructed as follows:
	'source_id/experiment_id'
100.00% [4/4 00:02<00:00]
--> The keys in the returned dictionary of datasets are constructed as follows:
	'source_id/experiment_id'
100.00% [4/4 00:00<00:00]
--> The keys in the returned dictionary of datasets are constructed as follows:
	'source_id/experiment_id'
100.00% [4/4 00:01<00:00]
KeysView(DataTree('None', parent=None)
└── DataTree('CESM2')
    ├── DataTree('ssp245')
    │       Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1032, y: 192,
    │                            x: 288, nbnd: 2)
    │       Coordinates:
    │         * y               (y) float64 2kB -90.0 -89.06 -88.12 ... 88.12 89.06 90.0
    │         * x               (x) float64 2kB 0.0 1.25 2.5 3.75 ... 356.2 357.5 358.8
    │         * time            (time) object 8kB 2015-01-15 12:00:00 ... 2100-12-15 12:0...
    │           lat_bounds      (y, nbnd, x) float64 885kB dask.array<chunksize=(192, 2, 288), meta=np.ndarray>
    │           time_bounds     (time, nbnd) object 17kB dask.array<chunksize=(1032, 2), meta=np.ndarray>
    │           lon_bounds      (x, nbnd, y) float64 885kB dask.array<chunksize=(288, 2, 192), meta=np.ndarray>
    │         * nbnd            (nbnd) int64 16B 0 1
    │           lon             (x, y) float64 442kB 360.0 360.0 360.0 ... 358.8 358.8 358.8
    │           lat             (x, y) float64 442kB -90.0 -89.06 -88.12 ... 89.06 90.0
    │         * member_id       (member_id) object 8B 'r4i1p1f1'
    │         * dcpp_init_year  (dcpp_init_year) float64 8B nan
    │       Data variables:
    │           tas             (member_id, dcpp_init_year, time, y, x) float32 228MB dask.array<chunksize=(1, 1, 408, 192, 288), meta=np.ndarray>
    │       Attributes: (12/61)
    │           Conventions:                      CF-1.7 CMIP-6.2
    │           activity_id:                      ScenarioMIP
    │           branch_method:                    standard
    │           branch_time_in_child:             735110.0
    │           branch_time_in_parent:            735110.0
    │           case_id:                          1732
    │           ...                               ...
    │           intake_esm_attrs:variable_id:     tas
    │           intake_esm_attrs:grid_label:      gn
    │           intake_esm_attrs:zstore:          gs://cmip6/CMIP6/ScenarioMIP/NCAR/CESM2...
    │           intake_esm_attrs:version:         20200528
    │           intake_esm_attrs:_data_format_:   zarr
    │           intake_esm_dataset_key:           CESM2/ssp245
    ├── DataTree('ssp126')
    │       Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1032, y: 192,
    │                            x: 288, nbnd: 2)
    │       Coordinates:
    │         * y               (y) float64 2kB -90.0 -89.06 -88.12 ... 88.12 89.06 90.0
    │         * x               (x) float64 2kB 0.0 1.25 2.5 3.75 ... 356.2 357.5 358.8
    │         * time            (time) object 8kB 2015-01-15 12:00:00 ... 2100-12-15 12:0...
    │           lat_bounds      (y, nbnd, x) float64 885kB dask.array<chunksize=(192, 2, 288), meta=np.ndarray>
    │           time_bounds     (time, nbnd) object 17kB dask.array<chunksize=(1032, 2), meta=np.ndarray>
    │           lon_bounds      (x, nbnd, y) float64 885kB dask.array<chunksize=(288, 2, 192), meta=np.ndarray>
    │         * nbnd            (nbnd) int64 16B 0 1
    │           lon             (x, y) float64 442kB 360.0 360.0 360.0 ... 358.8 358.8 358.8
    │           lat             (x, y) float64 442kB -90.0 -89.06 -88.12 ... 89.06 90.0
    │         * member_id       (member_id) object 8B 'r4i1p1f1'
    │         * dcpp_init_year  (dcpp_init_year) float64 8B nan
    │       Data variables:
    │           tas             (member_id, dcpp_init_year, time, y, x) float32 228MB dask.array<chunksize=(1, 1, 408, 192, 288), meta=np.ndarray>
    │       Attributes: (12/61)
    │           Conventions:                      CF-1.7 CMIP-6.2
    │           activity_id:                      ScenarioMIP
    │           branch_method:                    standard
    │           branch_time_in_child:             735110.0
    │           branch_time_in_parent:            735110.0
    │           case_id:                          1729
    │           ...                               ...
    │           intake_esm_attrs:variable_id:     tas
    │           intake_esm_attrs:grid_label:      gn
    │           intake_esm_attrs:zstore:          gs://cmip6/CMIP6/ScenarioMIP/NCAR/CESM2...
    │           intake_esm_attrs:version:         20200528
    │           intake_esm_attrs:_data_format_:   zarr
    │           intake_esm_dataset_key:           CESM2/ssp126
    ├── DataTree('ssp585')
    │       Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1032, y: 192,
    │                            x: 288, nbnd: 2)
    │       Coordinates:
    │         * y               (y) float64 2kB -90.0 -89.06 -88.12 ... 88.12 89.06 90.0
    │         * x               (x) float64 2kB 0.0 1.25 2.5 3.75 ... 356.2 357.5 358.8
    │         * time            (time) object 8kB 2015-01-15 12:00:00 ... 2100-12-15 12:0...
    │           lat_bounds      (y, nbnd, x) float64 885kB dask.array<chunksize=(192, 2, 288), meta=np.ndarray>
    │           time_bounds     (time, nbnd) object 17kB dask.array<chunksize=(1032, 2), meta=np.ndarray>
    │           lon_bounds      (x, nbnd, y) float64 885kB dask.array<chunksize=(288, 2, 192), meta=np.ndarray>
    │         * nbnd            (nbnd) int64 16B 0 1
    │           lon             (x, y) float64 442kB 360.0 360.0 360.0 ... 358.8 358.8 358.8
    │           lat             (x, y) float64 442kB -90.0 -89.06 -88.12 ... 89.06 90.0
    │         * member_id       (member_id) object 8B 'r4i1p1f1'
    │         * dcpp_init_year  (dcpp_init_year) float64 8B nan
    │       Data variables:
    │           tas             (member_id, dcpp_init_year, time, y, x) float32 228MB dask.array<chunksize=(1, 1, 408, 192, 288), meta=np.ndarray>
    │       Attributes: (12/61)
    │           Conventions:                      CF-1.7 CMIP-6.2
    │           activity_id:                      ScenarioMIP
    │           branch_method:                    standard
    │           branch_time_in_child:             735110.0
    │           branch_time_in_parent:            735110.0
    │           case_id:                          1735
    │           ...                               ...
    │           intake_esm_attrs:variable_id:     tas
    │           intake_esm_attrs:grid_label:      gn
    │           intake_esm_attrs:zstore:          gs://cmip6/CMIP6/ScenarioMIP/NCAR/CESM2...
    │           intake_esm_attrs:version:         20200528
    │           intake_esm_attrs:_data_format_:   zarr
    │           intake_esm_dataset_key:           CESM2/ssp585
    └── DataTree('historical')
            Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1980, y: 192,
                                 x: 288, nbnd: 2)
            Coordinates:
              * y               (y) float64 2kB -90.0 -89.06 -88.12 ... 88.12 89.06 90.0
              * x               (x) float64 2kB 0.0 1.25 2.5 3.75 ... 356.2 357.5 358.8
              * time            (time) object 16kB 1850-01-15 12:00:00 ... 2014-12-15 12:...
                lat_bounds      (y, nbnd, x) float64 885kB dask.array<chunksize=(192, 2, 288), meta=np.ndarray>
                time_bounds     (time, nbnd) object 32kB dask.array<chunksize=(1980, 2), meta=np.ndarray>
                lon_bounds      (x, nbnd, y) float64 885kB dask.array<chunksize=(288, 2, 192), meta=np.ndarray>
              * nbnd            (nbnd) int64 16B 0 1
                lon             (x, y) float64 442kB 360.0 360.0 360.0 ... 358.8 358.8 358.8
                lat             (x, y) float64 442kB -90.0 -89.06 -88.12 ... 89.06 90.0
              * member_id       (member_id) object 8B 'r4i1p1f1'
              * dcpp_init_year  (dcpp_init_year) float64 8B nan
            Data variables:
                tas             (member_id, dcpp_init_year, time, y, x) float32 438MB dask.array<chunksize=(1, 1, 600, 192, 288), meta=np.ndarray>
            Attributes: (12/61)
                Conventions:                      CF-1.7 CMIP-6.2
                activity_id:                      CMIP
                branch_method:                    standard
                branch_time_in_child:             674885.0
                branch_time_in_parent:            182500.0
                case_id:                          18
                ...                               ...
                intake_esm_attrs:variable_id:     tas
                intake_esm_attrs:grid_label:      gn
                intake_esm_attrs:zstore:          gs://cmip6/CMIP6/CMIP/NCAR/CESM2/histor...
                intake_esm_attrs:version:         20190308
                intake_esm_attrs:_data_format_:   zarr
                intake_esm_dataset_key:           CESM2/historical)
# load cell areas for computing ocean surface temparuters means

dt_ocean_area = load_cmip6(source_ids, "areacello", "r4i1p1f1", "Ofx")
dt_atmos_area = load_cmip6(source_ids, "areacella", "r4i1p1f1", "fx")

dt_ocean_with_area = DataTree()
dt_atmos_with_area = DataTree()

for model, subtree in dm_sst.items():
    metric_ocean = dt_ocean_area[model]["historical"].ds["areacello"]
    dt_ocean_with_area[model] = subtree.map_over_subtree(_parse_metric, metric_ocean)

for model, subtree in dm_pr.items():
    metric_atmos = dt_atmos_area[model]["historical"].ds["areacella"]
    dt_atmos_with_area[model] = subtree.map_over_subtree(_parse_metric, metric_atmos)

print(dt_ocean_with_area.keys())
--> The keys in the returned dictionary of datasets are constructed as follows:
	'source_id/experiment_id'
100.00% [4/4 00:01<00:00]
--> The keys in the returned dictionary of datasets are constructed as follows:
	'source_id/experiment_id'
100.00% [4/4 00:00<00:00]
KeysView(DataTree('None', parent=None)
└── DataTree('CESM2')
    ├── DataTree('ssp126')
    │       Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1032, y: 384,
    │                            x: 320, vertex: 4, bnds: 2)
    │       Coordinates: (12/13)
    │           lat             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
    │           lon             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
    │         * time            (time) object 8kB 2015-01-15 13:00:00 ... 2100-12-15 12:0...
    │           lon_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
    │           lat_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
    │           time_bounds     (time, bnds) object 17kB dask.array<chunksize=(1032, 2), meta=np.ndarray>
    │           ...              ...
    │         * x               (x) int64 3kB 0 1 2 3 4 5 6 ... 313 314 315 316 317 318 319
    │           lon_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
    │           lat_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
    │         * member_id       (member_id) object 8B 'r4i1p1f1'
    │         * dcpp_init_year  (dcpp_init_year) float64 8B nan
    │           areacello       (member_id, dcpp_init_year, y, x) float32 492kB dask.array<chunksize=(1, 1, 384, 320), meta=np.ndarray>
    │       Dimensions without coordinates: vertex, bnds
    │       Data variables:
    │           tos             (member_id, dcpp_init_year, time, y, x) float32 507MB dask.array<chunksize=(1, 1, 199, 384, 320), meta=np.ndarray>
    │       Attributes: (12/61)
    │           Conventions:                      CF-1.7 CMIP-6.2
    │           activity_id:                      ScenarioMIP
    │           branch_method:                    standard
    │           branch_time_in_child:             735110.0
    │           branch_time_in_parent:            735110.0
    │           case_id:                          1729
    │           ...                               ...
    │           intake_esm_attrs:variable_id:     tos
    │           intake_esm_attrs:grid_label:      gn
    │           intake_esm_attrs:zstore:          gs://cmip6/CMIP6/ScenarioMIP/NCAR/CESM2...
    │           intake_esm_attrs:version:         20200528
    │           intake_esm_attrs:_data_format_:   zarr
    │           intake_esm_dataset_key:           CESM2/ssp126
    ├── DataTree('historical')
    │       Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1980, y: 384,
    │                            x: 320, vertex: 4, bnds: 2)
    │       Coordinates: (12/13)
    │           lat             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
    │           lon             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
    │         * time            (time) object 16kB 1850-01-15 12:59:59.999997 ... 2014-12...
    │           lon_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
    │           lat_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
    │           time_bounds     (time, bnds) object 32kB dask.array<chunksize=(1980, 2), meta=np.ndarray>
    │           ...              ...
    │         * x               (x) int64 3kB 0 1 2 3 4 5 6 ... 313 314 315 316 317 318 319
    │           lon_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
    │           lat_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
    │         * member_id       (member_id) object 8B 'r4i1p1f1'
    │         * dcpp_init_year  (dcpp_init_year) float64 8B nan
    │           areacello       (member_id, dcpp_init_year, y, x) float32 492kB dask.array<chunksize=(1, 1, 384, 320), meta=np.ndarray>
    │       Dimensions without coordinates: vertex, bnds
    │       Data variables:
    │           tos             (member_id, dcpp_init_year, time, y, x) float32 973MB dask.array<chunksize=(1, 1, 403, 384, 320), meta=np.ndarray>
    │       Attributes: (12/61)
    │           Conventions:                      CF-1.7 CMIP-6.2
    │           activity_id:                      CMIP
    │           branch_method:                    standard
    │           branch_time_in_child:             674885.0
    │           branch_time_in_parent:            182500.0
    │           case_id:                          18
    │           ...                               ...
    │           intake_esm_attrs:variable_id:     tos
    │           intake_esm_attrs:grid_label:      gn
    │           intake_esm_attrs:zstore:          gs://cmip6/CMIP6/CMIP/NCAR/CESM2/histor...
    │           intake_esm_attrs:version:         20190308
    │           intake_esm_attrs:_data_format_:   zarr
    │           intake_esm_dataset_key:           CESM2/historical
    ├── DataTree('ssp245')
    │       Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1032, y: 384,
    │                            x: 320, vertex: 4, bnds: 2)
    │       Coordinates: (12/13)
    │           lat             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
    │           lon             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
    │         * time            (time) object 8kB 2015-01-15 13:00:00 ... 2100-12-15 12:0...
    │           lon_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
    │           lat_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
    │           time_bounds     (time, bnds) object 17kB dask.array<chunksize=(1032, 2), meta=np.ndarray>
    │           ...              ...
    │         * x               (x) int64 3kB 0 1 2 3 4 5 6 ... 313 314 315 316 317 318 319
    │           lon_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
    │           lat_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
    │         * member_id       (member_id) object 8B 'r4i1p1f1'
    │         * dcpp_init_year  (dcpp_init_year) float64 8B nan
    │           areacello       (member_id, dcpp_init_year, y, x) float32 492kB dask.array<chunksize=(1, 1, 384, 320), meta=np.ndarray>
    │       Dimensions without coordinates: vertex, bnds
    │       Data variables:
    │           tos             (member_id, dcpp_init_year, time, y, x) float32 507MB dask.array<chunksize=(1, 1, 199, 384, 320), meta=np.ndarray>
    │       Attributes: (12/61)
    │           Conventions:                      CF-1.7 CMIP-6.2
    │           activity_id:                      ScenarioMIP
    │           branch_method:                    standard
    │           branch_time_in_child:             735110.0
    │           branch_time_in_parent:            735110.0
    │           case_id:                          1732
    │           ...                               ...
    │           intake_esm_attrs:variable_id:     tos
    │           intake_esm_attrs:grid_label:      gn
    │           intake_esm_attrs:zstore:          gs://cmip6/CMIP6/ScenarioMIP/NCAR/CESM2...
    │           intake_esm_attrs:version:         20200528
    │           intake_esm_attrs:_data_format_:   zarr
    │           intake_esm_dataset_key:           CESM2/ssp245
    └── DataTree('ssp585')
            Dimensions:         (member_id: 1, dcpp_init_year: 1, time: 1032, y: 384,
                                 x: 320, vertex: 4, bnds: 2)
            Coordinates: (12/13)
                lat             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
                lon             (y, x) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray>
              * time            (time) object 8kB 2015-01-15 13:00:00 ... 2100-12-15 12:0...
                lon_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
                lat_verticies   (y, x, vertex) float32 2MB dask.array<chunksize=(384, 320, 4), meta=np.ndarray>
                time_bounds     (time, bnds) object 17kB dask.array<chunksize=(1032, 2), meta=np.ndarray>
                ...              ...
              * x               (x) int64 3kB 0 1 2 3 4 5 6 ... 313 314 315 316 317 318 319
                lon_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
                lat_bounds      (bnds, y, x) float32 983kB dask.array<chunksize=(1, 384, 320), meta=np.ndarray>
              * member_id       (member_id) object 8B 'r4i1p1f1'
              * dcpp_init_year  (dcpp_init_year) float64 8B nan
                areacello       (member_id, dcpp_init_year, y, x) float32 492kB dask.array<chunksize=(1, 1, 384, 320), meta=np.ndarray>
            Dimensions without coordinates: vertex, bnds
            Data variables:
                tos             (member_id, dcpp_init_year, time, y, x) float32 507MB dask.array<chunksize=(1, 1, 199, 384, 320), meta=np.ndarray>
            Attributes: (12/61)
                Conventions:                      CF-1.7 CMIP-6.2
                activity_id:                      ScenarioMIP
                branch_method:                    standard
                branch_time_in_child:             735110.0
                branch_time_in_parent:            735110.0
                case_id:                          1735
                ...                               ...
                intake_esm_attrs:variable_id:     tos
                intake_esm_attrs:grid_label:      gn
                intake_esm_attrs:zstore:          gs://cmip6/CMIP6/ScenarioMIP/NCAR/CESM2...
                intake_esm_attrs:version:         20200528
                intake_esm_attrs:_data_format_:   zarr
                intake_esm_dataset_key:           CESM2/ssp585)

Dataset 2: Load Observations#

We use the NOAA Extended Reconstructed Sea Surface Temperature (ERSST) v5 product, a widely used and trusted gridded compilation of historical data going back to 1854. Since the data is provided via an OPeNDAP server, we can load it directly without downloading anything.

For precipitation, we are using CPC Merged Analysis of Precipitation (CMAP). We can download this dataset from the NOAA PSL, Boulder, Colorado, USA website at https://psl.noaa.gov

For air temperature, we are using anomalies from NASA GISS Surface Temperature Analysis which we can also download from NOAA PSL, Boulder, Colorado, USA website at https://psl.noaa.gov

# Ocean surface temprature 
filename_SST='sst.mnmean.nc'
url_SST = 'https://downloads.psl.noaa.gov/Datasets/noaa.ersst.v5/sst.mnmean.nc'

do_sst = xr.open_dataset(pooch_load(url_SST,filename_SST), drop_variables=['time_bnds'])

# Precipitation rate (notice the units in the plot below)
filename_prec_rate='precip.mon.mean.nc'
url_prec_rate='https://downloads.psl.noaa.gov/Datasets/cmap/enh/precip.mon.mean.nc'
do_pr = xr.open_dataset(pooch_load(url_prec_rate,filename_prec_rate))

# Air Temperature Anomalies
filename_tas='air.2x2.1200.mon.anom.comb.nc'
url_tas='https://downloads.psl.noaa.gov/Datasets/gistemp/combined/1200km/air.2x2.1200.mon.anom.comb.nc'
do_tas = xr.open_dataset(pooch_load(url_tas,filename_tas))
Downloading data from 'https://downloads.psl.noaa.gov/Datasets/noaa.ersst.v5/sst.mnmean.nc' to file '/tmp/sst.mnmean.nc'.
SHA256 hash of downloaded file: b081bcaadc442321a0bc37499368e83dc59e35da1e04f7949cbdfcf693d3103f
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://downloads.psl.noaa.gov/Datasets/cmap/enh/precip.mon.mean.nc' to file '/tmp/precip.mon.mean.nc'.
SHA256 hash of downloaded file: d5c94dcb8f58b5661fa57d0e7653956304993d2f72785d49a9adac76a9c64da7
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://downloads.psl.noaa.gov/Datasets/gistemp/combined/1200km/air.2x2.1200.mon.anom.comb.nc' to file '/tmp/air.2x2.1200.mon.anom.comb.nc'.
SHA256 hash of downloaded file: d0661aee5b66556110d153579a23c78fbcff40a18825a8a44f72c5d880f2d76f
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.

We can now visualize the content of the dataset.

# code to print the shape, array names, etc of the dataset

# select just a single model and experiment
hist_precip = dm_pr["CESM2"]["historical"].ds.pr

fig, ax_july2000 = plt.subplots(
    ncols=1, nrows=1, figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
)

hist_precip.sel(time="2000-07").squeeze().plot(
    ax=ax_july2000,
    x="lon",
    y="lat",
    transform=ccrs.PlateCarree(),
    cmap="magma",
    robust=True,
)

ax_july2000.coastlines()
ax_july2000.set_title("July 2000")
Text(0.5, 1.0, 'July 2000')
/opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/110m_physical/ne_110m_coastline.zip
  warnings.warn(f'Downloading: {url}', DownloadWarning)
../../_images/b8959672ff780511fb016b2aff53c89b1cd39687e57306f5b86f9d61c596f19d.png
hist_sst = dm_sst["CESM2"]["historical"].ds.tos

fig, ax = plt.subplots(
    ncols=1,
    nrows=1,
    figsize=[12, 6],
    subplot_kw={"projection": ccrs.Robinson(central_longitude=180)},
)

ax.coastlines()
ax.gridlines()
hist_sst.sel(time="2000-07").squeeze().plot(
    ax=ax,
    x="lon",
    y="lat",
    transform=ccrs.PlateCarree(),
    vmin=-2,
    vmax=30,
    cmap="magma",
    robust=True,
)
<cartopy.mpl.geocollection.GeoQuadMesh at 0x7f2a72a25130>
../../_images/c85b27e93b33b6d12df4605b285ac49e412da57d83538cd7883c5327b2392574.png

Dataset 3: Oceanic Nino Index#

There are several indices used to identify ENSO in the tropical Pacific Ocean. These indices are based on SST anomalies averaged across a given region and are used to define El Niño and La Niña events. Two indices that you will explore in this project are the Nino 3.4 Index and the Oceanic Niño Index (ONI). Both of these indices are averaged over the same region in the tropical Pacific (5N-5S, 170W-120W), but use different running means and criteria for identifying El Niño and La Niña events (i.e. for ONI, SST anomalies must exceed +/- 0.5C for at least five consecutive months to be defined as an ENSO event, whereas for Nino 3.4, SST anomalies must exceed +/- 0.4C for at least six consecutive months). You can find additional information about these indices here. For now, we will download the ONI data that we used in W1D3.

# get El Nino data from W1D3 tutorial 7
filename_nino='t6_oceanic-nino-index.nc'
url_nino = "https://osf.io/8rwxb/download/"
oni = xr.open_dataset(pooch_load(url_nino,filename_nino))
print(oni.keys())
Downloading data from 'https://osf.io/8rwxb/download/' to file '/tmp/t6_oceanic-nino-index.nc'.
SHA256 hash of downloaded file: 583ae1ce6f9a990d2535f5c7ef816edd3252990208438c2d84a88025b7a21419
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
KeysView(<xarray.Dataset> Size: 8kB
Dimensions:  (time: 499)
Coordinates:
  * time     (time) datetime64[ns] 4kB 1981-09-01 1981-10-01 ... 2023-03-01
    month    (time) int32 2kB ...
Data variables:
    sst      (time) float32 2kB ...)

Further Reading#

Resources#

This tutorial uses data from the simulations conducted as part of the CMIP6 multi-model ensemble.

For examples on how to access and analyze data, please visit the Pangeo Cloud CMIP6 Gallery

For more information on what CMIP is and how to access the data, please see this page.