diff --git a/projects/docs/continuing_your_project_after_the_course.md b/projects/docs/continuing_your_project_after_the_course.md index 2da661e4a..487aa7de1 100644 --- a/projects/docs/continuing_your_project_after_the_course.md +++ b/projects/docs/continuing_your_project_after_the_course.md @@ -1,8 +1,8 @@ # Climatematch Impact Scholars program -Scientific discovery takes time. Recognizing this, Neuromatch and Climatematch Academy, in collaboration with the [**Learning the Earth with Artificial Intelligence and Physics (LEAP)**](https://leap.columbia.edu/), a National Science Foundation (NSF)-funded Science & Technology Center based at Columbia University, offer the Climate Impact Scholars program. This program provides selected student groups with access to computing resources for 10 months after the courses end, allowing scholars to further develop projects initiated during the courses or to explore new projects provided by the academies or our partners. -Scholars will benefit from the mentorship of experienced researchers who will provide guidance, constructive feedback, and professional insights over the course of 10 months, from October to July, enhancing the quality and impact of their work. +Scientific discovery takes time. Recognizing this, Neuromatch and Climatematch Academy, in collaboration with the [**Learning the Earth with Artificial Intelligence and Physics (LEAP)**](https://leap.columbia.edu/), a National Science Foundation (NSF)-funded Science & Technology Center based at Columbia University, offer the Climate Impact Scholars program. This program provides selected student groups with access to computing resources for 6 months after the courses end, allowing scholars to further develop projects initiated during the courses or to explore new projects provided by the academies or our partners. +Scholars will benefit from the mentorship of experienced researchers who will provide guidance, constructive feedback, and professional insights over the course of 10 months, from October 2024 to March 2025, enhancing the quality and impact of their work. Additionally, scholars will have the chance to present their research to seasoned experts, gaining valuable feedback and engaging with a broader scientific community. This program also includes the opportunity to showcase their projects at the Academies Open Ceremony, inspiring future scholars and demonstrating the significance of their research. -Please refer to [this link](https://neuromatch.io/impact-scholars/) for a detailed outline and description of the Impact Scholars Program. +Please refer to [this link](https://impact-scholars.neuromatch.io/impact-scholars/intro.html) for a detailed outline and description of the Impact Scholars Program. diff --git a/tutorials/Projects_GoodResearchPractices/Projects_Tutorial8.ipynb b/tutorials/Projects_GoodResearchPractices/Projects_Tutorial8.ipynb index d7e974053..c751055bd 100644 --- a/tutorials/Projects_GoodResearchPractices/Projects_Tutorial8.ipynb +++ b/tutorials/Projects_GoodResearchPractices/Projects_Tutorial8.ipynb @@ -99,7 +99,7 @@ " return tab_contents\n", "\n", "\n", - "video_ids = [('Youtube', 'HEsrjlyza5o'), ('Bilibili', 'BV1494y1B7qs')]\n", + "video_ids = [('Youtube', 'HEsrjlyza5o'), ('Bilibili', 'BV1NtbyeeEqA')]\n", "tab_contents = display_videos(video_ids, W=730, H=410)\n", "tabs = widgets.Tab()\n", "tabs.children = tab_contents\n", diff --git a/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial5.ipynb b/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial5.ipynb index 500f42b8d..facc1531c 100644 --- a/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial5.ipynb +++ b/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial5.ipynb @@ -216,7 +216,7 @@ " return tab_contents\n", "\n", "\n", - "video_ids = [('Youtube', 'SyvFyT3jVM8'), ('Bilibili', 'BV1ho4y1C7Eo')]\n", + "video_ids = [('Youtube', 'SyvFyT3jVM8'), ('Bilibili', 'BV1PhbyeaEMk')]\n", "tab_contents = display_videos(video_ids, W=730, H=410)\n", "tabs = widgets.Tab()\n", "tabs.children = tab_contents\n", diff --git a/tutorials/W1D2_Ocean-AtmosphereReanalysis/W1D2_Tutorial6.ipynb b/tutorials/W1D2_Ocean-AtmosphereReanalysis/W1D2_Tutorial6.ipynb index 3091a8933..4068e0475 100644 --- a/tutorials/W1D2_Ocean-AtmosphereReanalysis/W1D2_Tutorial6.ipynb +++ b/tutorials/W1D2_Ocean-AtmosphereReanalysis/W1D2_Tutorial6.ipynb @@ -66,7 +66,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "tags": [ "colab" ] @@ -82,9 +81,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "import xarray as xr\n", @@ -101,8 +98,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -130,8 +126,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -158,8 +153,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -177,7 +171,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "tags": [] }, "outputs": [], @@ -235,7 +228,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "pycharm": { "name": "#%%\n" }, @@ -271,9 +263,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# import preprocessed ECCO data. This data is full depth temperature data over 1992 to 2016 (annual mean)\n", @@ -301,9 +291,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Quick plot of the ocean temperature in Kelvin\n", @@ -324,9 +312,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# take the temporal mean over the period 1992 to 1994\n", @@ -348,9 +334,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# plot the zonal mean section of this data\n", @@ -390,9 +374,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "theta_area_int = (\n", @@ -403,9 +385,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# define reference density of salt water and the specific heat capacity\n", @@ -460,9 +440,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "area_of_ocean = (\n", @@ -492,9 +470,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -508,8 +484,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -540,9 +515,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# this cell may take a while to run!\n", @@ -624,9 +597,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots()\n", @@ -667,9 +638,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -683,8 +652,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -713,9 +681,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# first let's plot where heat is stored in the mean\n", @@ -769,9 +735,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# we already defined an object that's the mean over years 1992 to 1994 (subset_theta)\n", @@ -799,9 +763,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# plot 2 maps to compare changes in heat content in those two layers\n", @@ -920,7 +882,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W1D4_Paleoclimate/W1D4_Tutorial2.ipynb b/tutorials/W1D4_Paleoclimate/W1D4_Tutorial2.ipynb index 72200afc1..e09623e48 100644 --- a/tutorials/W1D4_Paleoclimate/W1D4_Tutorial2.ipynb +++ b/tutorials/W1D4_Paleoclimate/W1D4_Tutorial2.ipynb @@ -51,7 +51,7 @@ "\n", "### An Overview of Isotopes in Paleoclimate\n", "\n", - "In this tutorial, and many of the remaining tutorials on this day, you will be looking at data of hydrogen and oxygen isotopes (δD and δ18O). As you learned in the video, isotopes are forms of the same element that contain the same numbers of protons but different numbers of neutrons. The two oxygen isotopes that are most commonly used in paleoclimate are oxygen 16 (16O), which is the which is the **\"lighter\"** oxygen isotope, and oxygen 18 (16O), which is the **\"heavier\"** oxygen isotope. The two hydrogen isotopes that are most commonly used in paleoclimate are hydrogen (H), which is the **\"lighter\"** oxygen isotope, and deuterium (D), which is the **\"heavier\"** oxygen isotope. \n", + "In this tutorial, and many of the remaining tutorials on this day, you will be looking at data of hydrogen and oxygen isotopes (δD and δ18O). As you learned in the video, isotopes are forms of the same element that contain the same numbers of protons but different numbers of neutrons. The two oxygen isotopes that are most commonly used in paleoclimate are oxygen 16 (16O), which is the which is the **\"lighter\"** oxygen isotope, and oxygen 18 (18O), which is the **\"heavier\"** oxygen isotope. The two hydrogen isotopes that are most commonly used in paleoclimate are hydrogen (H), which is the **\"lighter\"** oxygen isotope, and deuterium (D), which is the **\"heavier\"** oxygen isotope. \n", "\n", "![image-1.png](https://github.com/neuromatch/climate-course-content/blob/main/tutorials/W1D4_Paleoclimate/images/t2_image1.png?raw=true)\n", "\n", diff --git a/tutorials/W1D5_IntroductiontoClimateModeling/W1D5_Tutorial7.ipynb b/tutorials/W1D5_IntroductiontoClimateModeling/W1D5_Tutorial7.ipynb index 8bde70873..06158082b 100644 --- a/tutorials/W1D5_IntroductiontoClimateModeling/W1D5_Tutorial7.ipynb +++ b/tutorials/W1D5_IntroductiontoClimateModeling/W1D5_Tutorial7.ipynb @@ -60,7 +60,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "tags": [ "colab" ] @@ -82,7 +81,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 2, "status": "ok", @@ -116,8 +114,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -146,7 +143,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "tags": [] }, "outputs": [], @@ -166,7 +162,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "tags": [] }, "outputs": [], @@ -223,8 +218,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -237,7 +231,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "pycharm": { "name": "#%%\n" }, @@ -261,8 +254,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -332,9 +324,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "col = intake.open_esm_datastore(\n", @@ -408,7 +398,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 6561, "status": "ok", @@ -458,9 +447,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "cat.keys()" @@ -485,7 +472,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 1011, "status": "ok", @@ -530,9 +516,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "ssp585 = dt[\"TaiESM1\"][\"ssp585\"].ds\n", @@ -551,9 +535,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "ssp585.tos" @@ -583,7 +565,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 11488, "status": "ok", @@ -645,7 +626,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 163, "status": "error", @@ -707,7 +687,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 36973, "status": "ok", @@ -798,8 +777,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -827,7 +805,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "tags": [] }, "outputs": [], @@ -845,8 +822,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -884,7 +860,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 1822, "status": "ok", @@ -925,7 +900,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "tags": [] }, "outputs": [], @@ -942,8 +916,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -968,7 +941,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 190, "status": "ok", @@ -997,7 +969,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 9588, "status": "ok", @@ -1023,7 +994,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 3184, "status": "ok", @@ -1050,7 +1020,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 191, "status": "ok", @@ -1084,7 +1053,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 21337, "status": "ok", @@ -1149,7 +1117,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "tags": [] }, "outputs": [], @@ -1165,8 +1132,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -1240,7 +1206,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W2D1_AnEnsembleofFutures/instructor/W2D1_Tutorial5.ipynb b/tutorials/W2D1_AnEnsembleofFutures/instructor/W2D1_Tutorial5.ipynb deleted file mode 100644 index 774e4a28d..000000000 --- a/tutorials/W2D1_AnEnsembleofFutures/instructor/W2D1_Tutorial5.ipynb +++ /dev/null @@ -1,716 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/neuromatch/climate-course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial5.ipynb)   \"Open\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 5: Internal Climate Variability\n", - "\n", - "**Week 2, Day 1, Future Climate: The Physical Basis**\n", - "\n", - "**Content creators:** Brodie Pearson, Julius Busecke, Tom Nicholas\n", - "\n", - "**Content reviewers:** Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS, Google DeepMind, and CMIP\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In this tutorial, we will learn about the concept of internal climate variability, how it influences the predictability of climate phenomena and how it contributes to uncertainty in CMIP6 models. We will work with a _single-model ensemble_, which utilizes the _MPI-ESM1-2-LR_ model from CMIP6, to isolate and quantify internal climate variability.\n", - "\n", - "By the end of this tutorial, you would be able to:\n", - "\n", - "- Understand the importance of internal climate variability and its role in climate prediction and model uncertainty.\n", - "- Create and evaluate a single-model ensemble using IPCC uncertainty bands, providing a visual representation of model uncertainty.\n", - "- Contrast the uncertainty due to internal variability against the uncertainty within a multi-model ensemble (which includes internal variability _and_ the impacts of human/coding choices).\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 93464, - "status": "ok", - "timestamp": 1683413540687, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# installations ( uncomment and run this cell ONLY when using google colab or kaggle )\n", - "\n", - "# !pip install condacolab &> /dev/null\n", - "# import condacolab\n", - "# condacolab.install()\n", - "\n", - "# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail\n", - "# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import time\n", - "\n", - "tic = time.time()\n", - "\n", - "import intake\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "\n", - "from xmip.preprocessing import combined_preprocessing\n", - "from xarrayutils.plotting import shaded_line_plot\n", - "\n", - "from datatree import DataTree\n", - "from xmip.postprocessing import _parse_metric" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "\n", - "def global_mean(ds: xr.Dataset) -> xr.Dataset:\n", - " \"\"\"Global average, weighted by the cell area\"\"\"\n", - " return ds.weighted(ds.areacello.fillna(0)).mean([\"x\", \"y\"], keep_attrs=True)\n", - "\n", - "\n", - "# Calculate anomaly to reference period\n", - "def datatree_anomaly(dt):\n", - " dt_out = DataTree()\n", - " for model, subtree in dt.items():\n", - " # for the coding exercise, ellipses will go after sel on the following line\n", - " ref = dt[model][\"historical\"].ds.sel(time=slice(\"1950\", \"1980\")).mean()\n", - " dt_out[model] = subtree - ref\n", - " return dt_out\n", - "\n", - "\n", - "def plot_historical_ssp126_combined(dt):\n", - " for model in dt.keys():\n", - " datasets = []\n", - " for experiment in [\"historical\", \"ssp126\"]:\n", - " datasets.append(dt[model][experiment].ds.tos)\n", - "\n", - " da_combined = xr.concat(datasets, dim=\"time\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Video 1: Internal Climate Variability\n", - "\n", - "from ipywidgets import widgets\n", - "from IPython.display import YouTubeVideo\n", - "from IPython.display import IFrame\n", - "from IPython.display import display\n", - "\n", - "\n", - "class PlayVideo(IFrame):\n", - " def __init__(self, id, source, page=1, width=400, height=300, **kwargs):\n", - " self.id = id\n", - " if source == \"Bilibili\":\n", - " src = f\"https://player.bilibili.com/player.html?bvid={id}&page={page}\"\n", - " elif source == \"Osf\":\n", - " src = f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render\"\n", - " super(PlayVideo, self).__init__(src, width, height, **kwargs)\n", - "\n", - "\n", - "def display_videos(video_ids, W=400, H=300, fs=1):\n", - " tab_contents = []\n", - " for i, video_id in enumerate(video_ids):\n", - " out = widgets.Output()\n", - " with out:\n", - " if video_ids[i][0] == \"Youtube\":\n", - " video = YouTubeVideo(\n", - " id=video_ids[i][1], width=W, height=H, fs=fs, rel=0\n", - " )\n", - " print(\n", - " f\"Video available at https://youtube.com/watch?v={video.id}\")\n", - " else:\n", - " video = PlayVideo(\n", - " id=video_ids[i][1],\n", - " source=video_ids[i][0],\n", - " width=W,\n", - " height=H,\n", - " fs=fs,\n", - " autoplay=False,\n", - " )\n", - " if video_ids[i][0] == \"Bilibili\":\n", - " print(\n", - " f\"Video available at https://www.bilibili.com/video/{video.id}\"\n", - " )\n", - " elif video_ids[i][0] == \"Osf\":\n", - " print(f\"Video available at https://osf.io/{video.id}\")\n", - " display(video)\n", - " tab_contents.append(out)\n", - " return tab_contents\n", - "\n", - "\n", - "video_ids = [(\"Youtube\", \"YcIAaljLRh4\"), (\"Bilibili\", \"BV1HF41197qn\")]\n", - "tab_contents = display_videos(video_ids, W=730, H=410)\n", - "tabs = widgets.Tab()\n", - "tabs.children = tab_contents\n", - "for i in range(len(tab_contents)):\n", - " tabs.set_title(i, video_ids[i][0])\n", - "display(tabs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @markdown\n", - "from ipywidgets import widgets\n", - "from IPython.display import IFrame\n", - "\n", - "link_id = \"cy5bh\"\n", - "\n", - "download_link = f\"https://osf.io/download/{link_id}/\"\n", - "render_link = f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render\"\n", - "# @markdown\n", - "out = widgets.Output()\n", - "with out:\n", - " print(f\"If you want to download the slides: {download_link}\")\n", - " display(IFrame(src=f\"{render_link}\", width=730, height=410))\n", - "display(out)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Internal Climate Variability & Single-model Ensembles\n", - "\n", - "One of the CMIP6 models we are using in today's tutorials, _MPI-ESM1-2-LR_, is part of single-model ensemble, where its modelling centre carried out multiple simulations of the model for many of the CMIP6 experiments. To create a single-model ensemble, the modelling centre will run a model using the same forcing data, but with small changes in the initial conditions. Due to the chaotic nature of the climate system, these small changes in initial conditions lead to differences in the modelled climate as time progresses. These differences are often referred to as internal variability. By running this single-model ensemble and comparing the results to simulations using different forcing datasets, it allows us to separate the internal variability from the externally-forced variability. If you are interested in learning more about large ensemble climate models, you can [read this paper](https://esd.copernicus.org/articles/12/401/2021/).\n", - "\n", - "Let's take advantage of this single-model ensemble to quantify the internal variability of this model's simulated climate, and contrast this against the multi-model uncertainty we diagnosed in the previous tutorial.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Coding Exercise 1.1\n", - "\n", - "Complete the following code to:\n", - "\n", - "1. Load 5 different _realizations_ of the _MPI-ESM1-2-LR_ experiments (_r1i1p1f1_ through _r5i1p1f1_). This numbering convention means they were each initialized using a different time-snapshot of the base/spin-up simulation.\n", - "2. Plot the _historical_ and _SSP1-2.6_ experiment data for each realization, using a distinct color for each realization, but keeping that color the same across both the historical period and future period for a given realization.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 420, - "status": "error", - "timestamp": 1683413710306, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "```python\n", - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ") # open an intake catalog containing the Pangeo CMIP cloud data\n", - "\n", - "cat_ensemble = col.search(\n", - " source_id=\"MPI-ESM1-2-LR\",\n", - " variable_id=\"tos\",\n", - " table_id=\"Omon\",\n", - " # select the 5 ensemble members described above\n", - " member_id=[\"r1i1p1f1\", \"r2i1p1f1\", \"r3i1p1f1\", \"r4i1p1f1\", \"r5i1p1f1\"],\n", - " grid_label=\"gn\",\n", - " experiment_id=[\"historical\", \"ssp126\", \"ssp585\"],\n", - " require_all_on=[\"source_id\", \"member_id\"],\n", - ")\n", - "\n", - "# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)\n", - "kwargs = dict(\n", - " preprocess=combined_preprocessing, # apply xMIP fixes to each dataset\n", - " xarray_open_kwargs=dict(\n", - " use_cftime=True\n", - " ), # ensure all datasets use the same time index\n", - " storage_options={\n", - " \"token\": \"anon\"\n", - " }, # anonymous/public authentication to google cloud storage\n", - ")\n", - "# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the\n", - "# actual tutorial, so this would be a lot cleaner\n", - "cat_ensemble.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_ensemble = cat_ensemble.to_datatree(**kwargs)\n", - "\n", - "cat_area = col.search(\n", - " source_id=[\"MPI-ESM1-2-LR\"],\n", - " # for the coding exercise, ellipses will go after the equals on this line\n", - " variable_id=\"areacello\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Ofx\", # for the coding exercise, ellipses will go after the equals on this line\n", - " grid_label=\"gn\",\n", - " experiment_id=[\n", - " \"historical\"\n", - " ], # for the coding exercise, ellipses will go after the equals on this line\n", - " require_all_on=[\"source_id\"],\n", - ")\n", - "# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the\n", - "# actual tutorial, so this would be a lot cleaner\n", - "cat_area.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_area = cat_area.to_datatree(**kwargs)\n", - "\n", - "# add the area (we can reuse the area from before, since for a given model the horizontal are does not vary between members)\n", - "dt_ensemble_with_area = DataTree()\n", - "for model, subtree in dt_ensemble.items():\n", - " metric = dt_area[\"MPI-ESM1-2-LR\"][\"historical\"].ds[\"areacello\"].squeeze()\n", - " dt_ensemble_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)\n", - "\n", - "# global average\n", - "# average every dataset in the tree globally\n", - "dt_ensemble_gm = dt_ensemble_with_area.map_over_subtree(global_mean)\n", - "\n", - "# calculate anomaly\n", - "dt_ensemble_gm_anomaly = datatree_anomaly(dt_ensemble_gm)\n", - "\n", - "\n", - "def plot_historical_ssp126_ensemble_combined(dt, ax):\n", - " for model in dt.keys():\n", - " datasets = []\n", - " for experiment in [\"historical\", \"ssp126\"]:\n", - " datasets.append(dt[model][experiment].ds.coarsen(time=12).mean().tos)\n", - "\n", - " # concatenate the historical and ssp126 timeseries for each ensemble member\n", - " da_combined = ...\n", - " # plot annual averages\n", - " da_combined.plot(hue=\"member_id\", ax=ax)\n", - "\n", - "\n", - "fig, ax = plt.subplots()\n", - "# Uncomment below after filling in above ellipses\n", - "# plot_historical_ssp126_ensemble_combined(dt_ensemble_gm_anomaly, ax)\n", - "\n", - "ax.set_title(\n", - " \"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\"\n", - ")\n", - "ax.set_ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "ax.set_xlabel(\"Year\")\n", - "\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 183867, - "status": "ok", - "timestamp": 1683413898135, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# to_remove solution\n", - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ") # open an intake catalog containing the Pangeo CMIP cloud data\n", - "\n", - "cat_ensemble = col.search(\n", - " source_id=\"MPI-ESM1-2-LR\",\n", - " variable_id=\"tos\",\n", - " table_id=\"Omon\",\n", - " # select the 5 ensemble members described above\n", - " member_id=[\"r1i1p1f1\", \"r2i1p1f1\", \"r3i1p1f1\", \"r4i1p1f1\", \"r5i1p1f1\"],\n", - " grid_label=\"gn\",\n", - " experiment_id=[\"historical\", \"ssp126\", \"ssp585\"],\n", - " require_all_on=[\"source_id\", \"member_id\"],\n", - ")\n", - "\n", - "# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)\n", - "kwargs = dict(\n", - " preprocess=combined_preprocessing, # apply xMIP fixes to each dataset\n", - " xarray_open_kwargs=dict(\n", - " use_cftime=True\n", - " ), # ensure all datasets use the same time index\n", - " storage_options={\n", - " \"token\": \"anon\"\n", - " }, # anonymous/public authentication to google cloud storage\n", - ")\n", - "# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the\n", - "# actual tutorial, so this would be a lot cleaner\n", - "cat_ensemble.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_ensemble = cat_ensemble.to_datatree(**kwargs)\n", - "\n", - "cat_area = col.search(\n", - " source_id=[\"MPI-ESM1-2-LR\"],\n", - " # for the coding exercise, ellipses will go after the equals on this line\n", - " variable_id=\"areacello\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Ofx\", # for the coding exercise, ellipses will go after the equals on this line\n", - " grid_label=\"gn\",\n", - " experiment_id=[\n", - " \"historical\"\n", - " ], # for the coding exercise, ellipses will go after the equals on this line\n", - " require_all_on=[\"source_id\"],\n", - ")\n", - "# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the\n", - "# actual tutorial, so this would be a lot cleaner\n", - "cat_area.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_area = cat_area.to_datatree(**kwargs)\n", - "\n", - "# add the area (we can reuse the area from before, since for a given model the horizontal are does not vary between members)\n", - "dt_ensemble_with_area = DataTree()\n", - "for model, subtree in dt_ensemble.items():\n", - " metric = dt_area[\"MPI-ESM1-2-LR\"][\"historical\"].ds[\"areacello\"].squeeze()\n", - " dt_ensemble_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)\n", - "\n", - "# global average\n", - "# average every dataset in the tree globally\n", - "dt_ensemble_gm = dt_ensemble_with_area.map_over_subtree(global_mean)\n", - "\n", - "# calculate anomaly\n", - "dt_ensemble_gm_anomaly = datatree_anomaly(dt_ensemble_gm)\n", - "\n", - "\n", - "def plot_historical_ssp126_ensemble_combined(dt, ax):\n", - " for model in dt.keys():\n", - " datasets = []\n", - " for experiment in [\"historical\", \"ssp126\"]:\n", - " datasets.append(dt[model][experiment].ds.coarsen(time=12).mean().tos)\n", - "\n", - " # concatenate the historical and ssp126 timeseries for each ensemble member\n", - " da_combined = xr.concat(datasets, dim=\"time\")\n", - " # plot annual averages\n", - " da_combined.plot(hue=\"member_id\", ax=ax)\n", - "\n", - "\n", - "fig, ax = plt.subplots()\n", - "# Uncomment below after filling in above ellipses\n", - "# plot_historical_ssp126_ensemble_combined(dt_ensemble_gm_anomaly, ax)\n", - "plot_historical_ssp126_ensemble_combined(dt_ensemble_gm_anomaly, ax)\n", - "\n", - "ax.set_title(\n", - " \"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\"\n", - ")\n", - "ax.set_ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "ax.set_xlabel(\"Year\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.2**\n", - "\n", - "Complete the following code to:\n", - "\n", - "1. Repeat the final figure of the last tutorial, except now display means and uncertainty bands of the single-model ensemble that you just loaded, rather than the multi-model ensemble analyzed in the previous tutorial.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 313, - "status": "error", - "timestamp": 1682795255008, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "source": [ - "```python\n", - "fig, ax = plt.subplots()\n", - "for experiment, color in zip([\"historical\", \"ssp126\", \"ssp585\"], [\"C0\", \"C1\", \"C2\"]):\n", - " da = (\n", - " dt_ensemble_gm_anomaly[\"MPI-ESM1-2-LR\"][experiment]\n", - " .ds.tos.coarsen(time=12)\n", - " .mean()\n", - " .load()\n", - " )\n", - " # calculate the mean across ensemble members\n", - " da.mean(\"member_id\").plot(color=color, label=experiment, ax=ax)\n", - "\n", - " # shading representing spread between members\n", - " x = da.time.data\n", - " # diagnose the lower range of the likely bounds\n", - " da_lower = ...\n", - " # diagnose the upper range of the likely bounds\n", - " da_upper = ...\n", - " # Uncomment below after filling in above ellipses\n", - " # ax.fill_between(x, da_lower, da_upper, alpha=0.5, color=color)\n", - "\n", - "ax.set_title(\n", - " \"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\"\n", - ")\n", - "ax.set_ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "ax.set_xlabel(\"Year\")\n", - "ax.legend()\n", - "\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 206089, - "status": "ok", - "timestamp": 1683414257178, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# to_remove solution\n", - "fig, ax = plt.subplots()\n", - "for experiment, color in zip([\"historical\", \"ssp126\", \"ssp585\"], [\"C0\", \"C1\", \"C2\"]):\n", - " da = (\n", - " dt_ensemble_gm_anomaly[\"MPI-ESM1-2-LR\"][experiment]\n", - " .ds.tos.coarsen(time=12)\n", - " .mean()\n", - " .load()\n", - " )\n", - " # calculate the mean across ensemble members\n", - " da.mean(\"member_id\").plot(color=color, label=experiment, ax=ax)\n", - "\n", - " # shading representing spread between members\n", - " x = da.time.data\n", - " # diagnose the lower range of the likely bounds\n", - " da_lower = da.squeeze().quantile(0.17, dim=\"member_id\")\n", - " # diagnose the upper range of the likely bounds\n", - " da_upper = da.squeeze().quantile(0.83, dim=\"member_id\")\n", - " # Uncomment below after filling in above ellipses\n", - " # ax.fill_between(x, da_lower, da_upper, alpha=0.5, color=color)\n", - " ax.fill_between(x, da_lower, da_upper, alpha=0.5, color=color)\n", - "\n", - "ax.set_title(\n", - " \"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\"\n", - ")\n", - "ax.set_ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "ax.set_xlabel(\"Year\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Question 1.2: Climate Connection**\n", - "\n", - "1. How does this figure compare to the multi-model ensemble figure from the previous tutorial (included below)? Can you interpret differences using the science we have discussed today?\n", - "\n", - "![tutorial 4 solution](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/img/W2D1_Tutorial_5_Insert_Figure.png?raw=true)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# to_remove explanation\n", - "\n", - "\"\"\"\n", - "1. The uncertainty of the single-model ensemble is much smaller than the uncertainty of the multi-model ensemble. The single-model ensemble variations are driven only by internal climate variability, whereas the multi-model ensemble includes inter-model differences (numerics, physics, discretization) in addition to internal climate variability. Comparing the two plots suggests that most of our uncertainty in future projections of global mean SST come from inter-model differences. Internal climate variability is a relatively small contributor to this uncertainty.\n", - "\"\"\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we explored the internal climate variability and its implications for climate modeling and prediction. We discussed the utility of single-model ensembles for isolating the effects of internal variability by contrasting simulations with identical physics, numerics, and discretization. We quantified the internal variability of _MPI-ESM1-2-LR_ model's simulated climate and compared it to the uncertainty introduced by multi-model ensembles. Through this tutorial, we better understand the boundaries of climate prediction and the different sources of uncertainty in CMIP6 models.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "This tutorial uses data from the simulations conducted as part of the [CMIP6](https://wcrp-cmip.org/) multi-model ensemble.\n", - "\n", - "For examples on how to access and analyze data, please visit the [Pangeo Cloud CMIP6 Gallery](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)\n", - "\n", - "For more information on what CMIP is and how to access the data, please see this [page](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md).\n", - "\n", - "For more information about large ensemble climate modelling [see this paper](https://esd.copernicus.org/articles/12/401/2021/).\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial5", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680298239014 - } - ], - "toc_visible": true - }, - "gpuClass": "standard", - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.18" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tutorials/W2D1_AnEnsembleofFutures/instructor/W2D1_Tutorial6.ipynb b/tutorials/W2D1_AnEnsembleofFutures/instructor/W2D1_Tutorial6.ipynb deleted file mode 100644 index b6eafb78f..000000000 --- a/tutorials/W2D1_AnEnsembleofFutures/instructor/W2D1_Tutorial6.ipynb +++ /dev/null @@ -1,635 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/neuromatch/climate-course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial6.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 6: Synthesising & Interpreting Diverse Data Sources\n", - "\n", - "**Week 2, Day 1, Future Climate: The Physical Basis**\n", - "\n", - "**Content creators:** Brodie Pearson, Julius Busecke, Tom Nicholas\n", - "\n", - "**Content reviewers:** Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS, Google DeepMind, and CMIP" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "In this tutorial, we will synthesize scientific knowledge from various sources and use this diverse information to validate and contextualize CMIP6 simulations. By the end of this tutorial, you will be able to \n", - "- Create a time series of global mean sea surface temperature from observations, models, and proxy data;\n", - "- Use this data to validate & contextualize climate models, and to provide a holistic picture of Earth's past and future climate evolution." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup\n", - "\n", - " \n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 97497, - "status": "ok", - "timestamp": 1684265107976, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# installations ( uncomment and run this cell ONLY when using google colab or kaggle )\n", - "\n", - "# !pip install condacolab &> /dev/null\n", - "# import condacolab\n", - "# condacolab.install()\n", - "\n", - "# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail\n", - "# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import time\n", - "\n", - "tic = time.time()\n", - "\n", - "import intake\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "\n", - "from xmip.preprocessing import combined_preprocessing\n", - "from xarrayutils.plotting import shaded_line_plot\n", - "\n", - "from datatree import DataTree\n", - "from xmip.postprocessing import _parse_metric" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "# If any helper functions you want to hide for clarity (that has been seen before\n", - "# or is simple/uniformative), add here\n", - "# If helper code depends on libraries that aren't used elsewhere,\n", - "# import those libaries here, rather than in the main import cell\n", - "\n", - "\n", - "def global_mean(ds: xr.Dataset) -> xr.Dataset:\n", - " \"\"\"Global average, weighted by the cell area\"\"\"\n", - " return ds.weighted(ds.areacello.fillna(0)).mean([\"x\", \"y\"], keep_attrs=True)\n", - "\n", - "\n", - "# calculate anomaly to reference period\n", - "def datatree_anomaly(dt):\n", - " dt_out = DataTree()\n", - " for model, subtree in dt.items():\n", - " # for the coding exercise, ellipses will go after sel on the following line\n", - " ref = dt[model][\"historical\"].ds.sel(time=slice(\"1950\", \"1980\")).mean()\n", - " dt_out[model] = subtree - ref\n", - " return dt_out\n", - "\n", - "\n", - "def plot_historical_ssp126_combined(dt):\n", - " for model in dt.keys():\n", - " datasets = []\n", - " for experiment in [\"historical\", \"ssp126\"]:\n", - " datasets.append(dt[model][experiment].ds.tos)\n", - "\n", - " da_combined = xr.concat(datasets, dim=\"time\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Video 1: Historical Context for Future Projections\n", - "\n", - "from ipywidgets import widgets\n", - "from IPython.display import YouTubeVideo\n", - "from IPython.display import IFrame\n", - "from IPython.display import display\n", - "\n", - "\n", - "class PlayVideo(IFrame):\n", - " def __init__(self, id, source, page=1, width=400, height=300, **kwargs):\n", - " self.id = id\n", - " if source == 'Bilibili':\n", - " src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'\n", - " elif source == 'Osf':\n", - " src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'\n", - " super(PlayVideo, self).__init__(src, width, height, **kwargs)\n", - "\n", - "\n", - "def display_videos(video_ids, W=400, H=300, fs=1):\n", - " tab_contents = []\n", - " for i, video_id in enumerate(video_ids):\n", - " out = widgets.Output()\n", - " with out:\n", - " if video_ids[i][0] == 'Youtube':\n", - " video = YouTubeVideo(id=video_ids[i][1], width=W,\n", - " height=H, fs=fs, rel=0)\n", - " print(f'Video available at https://youtube.com/watch?v={video.id}')\n", - " else:\n", - " video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,\n", - " height=H, fs=fs, autoplay=False)\n", - " if video_ids[i][0] == 'Bilibili':\n", - " print(f'Video available at https://www.bilibili.com/video/{video.id}')\n", - " elif video_ids[i][0] == 'Osf':\n", - " print(f'Video available at https://osf.io/{video.id}')\n", - " display(video)\n", - " tab_contents.append(out)\n", - " return tab_contents\n", - "\n", - "\n", - "video_ids = [('Youtube', 'lodJMDN6lbg'), ('Bilibili', 'BV1Bu41157mn')]\n", - "tab_contents = display_videos(video_ids, W=730, H=410)\n", - "tabs = widgets.Tab()\n", - "tabs.children = tab_contents\n", - "for i in range(len(tab_contents)):\n", - " tabs.set_title(i, video_ids[i][0])\n", - "display(tabs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @markdown\n", - "from ipywidgets import widgets\n", - "from IPython.display import IFrame\n", - "\n", - "link_id = \"b4fsp\"\n", - "\n", - "download_link = f\"https://osf.io/download/{link_id}/\"\n", - "render_link = f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render\"\n", - "# @markdown\n", - "out = widgets.Output()\n", - "with out:\n", - " print(f\"If you want to download the slides: {download_link}\")\n", - " display(IFrame(src=f\"{render_link}\", width=730, height=410))\n", - "display(out)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Reproduce Global SST for Historical and Future Scenario Experiments\n", - "\n", - "We are now going to reproduce the plot you created in Tutorial 4, which showed the likely range of CMIP6 simulated global mean sea surface temperature for historical and future scenario (*SSP1-2.6* and *SSP5-8.5*) experiments from a *multi-model ensemble*. However, now we will add some an additional dataset called *HadISST* which is an observational dataset spanning back to the 1870. Later in the tutorial, we will also include the paleo data you saw in the previous mini-lecture.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Load CMIP6 SST Data from Several Models using `xarray`\n", - "\n", - "Let's load the five different CMIP6 models again for the three CMIP6 experiments.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ") # open an intake catalog containing the Pangeo CMIP cloud data\n", - "\n", - "# pick our five example models\n", - "# there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models\n", - "source_ids = [\"IPSL-CM6A-LR\", \"GFDL-ESM4\", \"ACCESS-CM2\", \"MPI-ESM1-2-LR\", \"TaiESM1\"]\n", - "experiment_ids = [\"historical\", \"ssp126\", \"ssp585\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 17912, - "status": "ok", - "timestamp": 1684265194265, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=source_ids,\n", - " variable_id=\"tos\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Omon\",\n", - " grid_label=\"gn\",\n", - " experiment_id=experiment_ids,\n", - " require_all_on=[\n", - " \"source_id\"\n", - " ], # make sure that we only get models which have all of the above experiments\n", - ")\n", - "\n", - "# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)\n", - "kwargs = dict(\n", - " preprocess=combined_preprocessing, # apply xMIP fixes to each dataset\n", - " xarray_open_kwargs=dict(\n", - " use_cftime=True\n", - " ), # ensure all datasets use the same time index\n", - " storage_options={\n", - " \"token\": \"anon\"\n", - " }, # anonymous/public authentication to google cloud storage\n", - ")\n", - "\n", - "cat.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt = cat.to_datatree(**kwargs)\n", - "\n", - "cat_area = col.search(\n", - " source_id=source_ids,\n", - " variable_id=\"areacello\", # for the coding exercise, ellipses will go after the equals on this line\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Ofx\", # for the coding exercise, ellipses will go after the equals on this line\n", - " grid_label=\"gn\",\n", - " experiment_id=[\n", - " \"historical\"\n", - " ], # for the coding exercise, ellipses will go after the equals on this line\n", - " require_all_on=[\"source_id\"],\n", - ")\n", - "\n", - "cat_area.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_area = cat_area.to_datatree(**kwargs)\n", - "\n", - "dt_with_area = DataTree()\n", - "\n", - "for model, subtree in dt.items():\n", - " metric = dt_area[model][\"historical\"].ds[\"areacello\"]\n", - " dt_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)\n", - "\n", - "# average every dataset in the tree globally\n", - "dt_gm = dt_with_area.map_over_subtree(global_mean)\n", - "\n", - "dt_gm_anomaly = datatree_anomaly(dt_gm)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "### Coding Exercise 1.1\n", - "\n", - "Complete the following code to:\n", - "\n", - "\n", - "1. Calculate a time series of the global mean sea surface temperature (GMSST) from the HadISST dataset\n", - "2. Subtract a base period from the HadISST GMSST time series. Use the same base period as the CMIP6 timeseries you are comparing against. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 114, - "status": "error", - "timestamp": 1684265198522, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "source": [ - "```python\n", - "fig, ax = plt.subplots()\n", - "for experiment, color in zip([\"historical\", \"ssp126\", \"ssp585\"], [\"C0\", \"C1\", \"C2\"]):\n", - " datasets = []\n", - " for model in dt_gm_anomaly.keys():\n", - " annual_sst = (\n", - " dt_gm_anomaly[model][experiment]\n", - " .ds.tos.coarsen(time=12)\n", - " .mean()\n", - " .assign_coords(source_id=model)\n", - " .load()\n", - " )\n", - " datasets.append(\n", - " annual_sst.sel(time=slice(None, \"2100\")).load()\n", - " ) # the french model has a long running member for ssp 126 (we could change the model to keep this clean)\n", - " da = xr.concat(datasets, dim=\"source_id\", join=\"override\").squeeze()\n", - " da.mean(\"source_id\").plot(color=color, label=experiment, ax=ax)\n", - " x = da.time.data\n", - " da_lower = da.squeeze().quantile(0.17, dim=\"source_id\")\n", - " da_upper = da.squeeze().quantile(0.83, dim=\"source_id\")\n", - " ax.fill_between(x, da_lower, da_upper, alpha=0.5, color=color)\n", - "\n", - "# but now add observations (https://pangeo-forge.org/dashboard/feedstock/43)\n", - "store = \"https://ncsa.osn.xsede.org/Pangeo/pangeo-forge/HadISST-feedstock/hadisst.zarr\"\n", - "ds_obs = xr.open_dataset(store, engine=\"zarr\", chunks={}).convert_calendar(\n", - " \"standard\", use_cftime=True\n", - ")\n", - "# mask missing values\n", - "ds_obs = ds_obs.where(ds_obs > -1000)\n", - "weights = np.cos(\n", - " np.deg2rad(ds_obs.latitude)\n", - ") # In a regular lon/lat grid, area is ~cos(latitude)\n", - "# calculate weighted global mean for observations\n", - "sst_obs_gm = ...\n", - "# calculate anomaly for observations\n", - "sst_obs_gm_anomaly = ...\n", - "\n", - "# plot observations\n", - "# Uncomment below once you fill in the above ellipses\n", - "# sst_obs_gm_anomaly.coarsen(time=12, boundary=\"trim\").mean().plot(\n", - "# color=\"0.3\", label=\"Observations\", ax=ax\n", - "# )\n", - "ax.set_ylabel(\"Global Mean SST with respect to 1950-1980\")\n", - "ax.set_xlabel(\"Year\")\n", - "ax.legend()\n", - "\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 66611, - "status": "ok", - "timestamp": 1684265266986, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# to_remove solution\n", - "fig, ax = plt.subplots()\n", - "for experiment, color in zip([\"historical\", \"ssp126\", \"ssp585\"], [\"C0\", \"C1\", \"C2\"]):\n", - " datasets = []\n", - " for model in dt_gm_anomaly.keys():\n", - " annual_sst = (\n", - " dt_gm_anomaly[model][experiment]\n", - " .ds.tos.coarsen(time=12)\n", - " .mean()\n", - " .assign_coords(source_id=model)\n", - " .load()\n", - " )\n", - " datasets.append(\n", - " annual_sst.sel(time=slice(None, \"2100\")).load()\n", - " ) # the french model has a long running member for ssp 126 (we could change the model to keep this clean)\n", - " da = xr.concat(datasets, dim=\"source_id\", join=\"override\").squeeze()\n", - " da.mean(\"source_id\").plot(color=color, label=experiment, ax=ax)\n", - " x = da.time.data\n", - " da_lower = da.squeeze().quantile(0.17, dim=\"source_id\")\n", - " da_upper = da.squeeze().quantile(0.83, dim=\"source_id\")\n", - " ax.fill_between(x, da_lower, da_upper, alpha=0.5, color=color)\n", - "\n", - "\n", - "# but now add observations (https://pangeo-forge.org/dashboard/feedstock/43)\n", - "store = \"https://ncsa.osn.xsede.org/Pangeo/pangeo-forge/HadISST-feedstock/hadisst.zarr\"\n", - "ds_obs = xr.open_dataset(store, engine=\"zarr\", chunks={}).convert_calendar(\n", - " \"standard\", use_cftime=True\n", - ")\n", - "# mask missing values\n", - "ds_obs = ds_obs.where(ds_obs > -1000)\n", - "weights = np.cos(\n", - " np.deg2rad(ds_obs.latitude)\n", - ") # In a regular lon/lat grid, area is ~cos(latitude)\n", - "# calculate weighted global mean for observations\n", - "sst_obs_gm = ds_obs.sst.weighted(weights).mean([\"longitude\", \"latitude\"])\n", - "# calculate anomaly for observations\n", - "sst_obs_gm_anomaly = sst_obs_gm - sst_obs_gm.sel(time=slice(\"1950\", \"1980\")).mean()\n", - "\n", - "# plot observations\n", - "# Uncomment below once you fill in the above ellipses\n", - "# sst_obs_gm_anomaly.coarsen(time=12, boundary=\"trim\").mean().plot(\n", - "# color=\"0.3\", label=\"Observations\", ax=ax\n", - "# )\n", - "sst_obs_gm_anomaly.coarsen(time=12, boundary=\"trim\").mean().plot(\n", - " color=\"0.3\", label=\"Observations\", ax=ax\n", - ")\n", - "ax.set_ylabel(\"Global Mean SST with respect to 1950-1980\")\n", - "ax.set_xlabel(\"Year\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1.1 Climate Connection\n", - "\n", - "Now that you have a modern and projected time series containing models and observations,\n", - "1. What context and/or validation of the simulations does this information provide?\n", - "2. What additional context/validation can you glean by also considering the paleo proxy information in the figure below? (This figure was shown in the last video)\n", - "\n", - "Note the paleo periods on this figure represent the Mid-Pleiocene Warm Period (MPWP), the Last Inter-glacial (LIG) ad the Last Glacial Maximum (LGM)\n", - "\n", - "![](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/img/W2D1_Tutorial_6_Insert_Figure.png?raw=true)\n", - "\n", - "This image shows part of panel a) from Figure 9.3 from the IPCC AR6 WG1 report. This figure has the following caption: **Figure 9.3** | Sea surface temperature (SST) and its changes with time. (a) Time series of global mean SST anomaly relative to 1950–1980 climatology. Shown are paleoclimate reconstructions and PMIP models, observational reanalyses (HadISST) and multi-model means from the Coupled Model Intercomparison Project (CMIP) historical simulations, CMIP projections, and HighResMIP experiment. (b) Map of observed SST (1995–2014 climatology HadISST). (c) Historical SST changes from observations. (d) CMIP 2005–2100 SST change rate. (e) Bias of CMIP. (f) CMIP change rate. (g) 2005–2050 change rate for SSP5-8.5 for the CMIP ensemble. (h) Bias of HighResMIP (bottom left) over 1995–2014. (i) HighResMIP change rate for 1950–2014. (j) 2005–2050 change rate for SSP5-8.5 for the HighResMIP ensemble. No overlay indicates regions with high model agreement, where ≥80% of models agree on sign of change. Diagonal lines indicate regions with low model agreement, where <80% of models agree on sign of change (see Cross-Chapter Box Atlas.1 for more information). Further details on data sources and processing are available in the chapter data table (Table 9.SM.9)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# to_remove explanation\n", - "\n", - "\"\"\"\n", - "1. I will let you decide what you take away from synthesizing these figures and data!\n", - "\"\"\";" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In the final tutorial of the day, we learned about the importance of synthesizing CMIP6 model data (future projections and historical simulations), alongside modern climate and palroclimate observations. This synthesis provides validation of CMIP6 simulation data, and it provides historical context for recent and projected rapid changes in Earth's climate, as many of these changes are unprecedented in human-recored history.\n", - "\n", - "In the upcoming tutorials, we will shift our focus towards the socio-economic aspects of future climate change. This exploration will take various forms, including the design of the Shared Socioeconomic Pathways (SSPs) we began using today. We'll contemplate the realism of different socio-economic future scenarios and examine their potential impacts on future climate forcings. Moreover, we'll delve into how a changing climate might affect society. As we proceed with the next tutorials, keep in mind the intricate connection between physical and socio-economic changes." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "This tutorial uses data from the simulations conducted as part of the [CMIP6](https://wcrp-cmip.org/) multi-model ensemble. \n", - "\n", - "For examples on how to access and analyze data, please visit the [Pangeo Cloud CMIP6 Gallery](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html) \n", - "\n", - "For more information on what CMIP is and how to access the data, please see this [page](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial6", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680298239014 - } - ], - "toc_visible": true - }, - "gpuClass": "standard", - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.18" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tutorials/W2D1_AnEnsembleofFutures/student/W2D1_Tutorial5.ipynb b/tutorials/W2D1_AnEnsembleofFutures/student/W2D1_Tutorial5.ipynb deleted file mode 100644 index 344b3a796..000000000 --- a/tutorials/W2D1_AnEnsembleofFutures/student/W2D1_Tutorial5.ipynb +++ /dev/null @@ -1,606 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/neuromatch/climate-course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial5.ipynb)   \"Open\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 5: Internal Climate Variability\n", - "\n", - "**Week 2, Day 1, Future Climate: The Physical Basis**\n", - "\n", - "**Content creators:** Brodie Pearson, Julius Busecke, Tom Nicholas\n", - "\n", - "**Content reviewers:** Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS, Google DeepMind, and CMIP\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In this tutorial, we will learn about the concept of internal climate variability, how it influences the predictability of climate phenomena and how it contributes to uncertainty in CMIP6 models. We will work with a _single-model ensemble_, which utilizes the _MPI-ESM1-2-LR_ model from CMIP6, to isolate and quantify internal climate variability.\n", - "\n", - "By the end of this tutorial, you would be able to:\n", - "\n", - "- Understand the importance of internal climate variability and its role in climate prediction and model uncertainty.\n", - "- Create and evaluate a single-model ensemble using IPCC uncertainty bands, providing a visual representation of model uncertainty.\n", - "- Contrast the uncertainty due to internal variability against the uncertainty within a multi-model ensemble (which includes internal variability _and_ the impacts of human/coding choices).\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 93464, - "status": "ok", - "timestamp": 1683413540687, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# installations ( uncomment and run this cell ONLY when using google colab or kaggle )\n", - "\n", - "# !pip install condacolab &> /dev/null\n", - "# import condacolab\n", - "# condacolab.install()\n", - "\n", - "# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail\n", - "# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import time\n", - "\n", - "tic = time.time()\n", - "\n", - "import intake\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "\n", - "from xmip.preprocessing import combined_preprocessing\n", - "from xarrayutils.plotting import shaded_line_plot\n", - "\n", - "from datatree import DataTree\n", - "from xmip.postprocessing import _parse_metric" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "\n", - "def global_mean(ds: xr.Dataset) -> xr.Dataset:\n", - " \"\"\"Global average, weighted by the cell area\"\"\"\n", - " return ds.weighted(ds.areacello.fillna(0)).mean([\"x\", \"y\"], keep_attrs=True)\n", - "\n", - "\n", - "# Calculate anomaly to reference period\n", - "def datatree_anomaly(dt):\n", - " dt_out = DataTree()\n", - " for model, subtree in dt.items():\n", - " # for the coding exercise, ellipses will go after sel on the following line\n", - " ref = dt[model][\"historical\"].ds.sel(time=slice(\"1950\", \"1980\")).mean()\n", - " dt_out[model] = subtree - ref\n", - " return dt_out\n", - "\n", - "\n", - "def plot_historical_ssp126_combined(dt):\n", - " for model in dt.keys():\n", - " datasets = []\n", - " for experiment in [\"historical\", \"ssp126\"]:\n", - " datasets.append(dt[model][experiment].ds.tos)\n", - "\n", - " da_combined = xr.concat(datasets, dim=\"time\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Video 1: Internal Climate Variability\n", - "\n", - "from ipywidgets import widgets\n", - "from IPython.display import YouTubeVideo\n", - "from IPython.display import IFrame\n", - "from IPython.display import display\n", - "\n", - "\n", - "class PlayVideo(IFrame):\n", - " def __init__(self, id, source, page=1, width=400, height=300, **kwargs):\n", - " self.id = id\n", - " if source == \"Bilibili\":\n", - " src = f\"https://player.bilibili.com/player.html?bvid={id}&page={page}\"\n", - " elif source == \"Osf\":\n", - " src = f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render\"\n", - " super(PlayVideo, self).__init__(src, width, height, **kwargs)\n", - "\n", - "\n", - "def display_videos(video_ids, W=400, H=300, fs=1):\n", - " tab_contents = []\n", - " for i, video_id in enumerate(video_ids):\n", - " out = widgets.Output()\n", - " with out:\n", - " if video_ids[i][0] == \"Youtube\":\n", - " video = YouTubeVideo(\n", - " id=video_ids[i][1], width=W, height=H, fs=fs, rel=0\n", - " )\n", - " print(\n", - " f\"Video available at https://youtube.com/watch?v={video.id}\")\n", - " else:\n", - " video = PlayVideo(\n", - " id=video_ids[i][1],\n", - " source=video_ids[i][0],\n", - " width=W,\n", - " height=H,\n", - " fs=fs,\n", - " autoplay=False,\n", - " )\n", - " if video_ids[i][0] == \"Bilibili\":\n", - " print(\n", - " f\"Video available at https://www.bilibili.com/video/{video.id}\"\n", - " )\n", - " elif video_ids[i][0] == \"Osf\":\n", - " print(f\"Video available at https://osf.io/{video.id}\")\n", - " display(video)\n", - " tab_contents.append(out)\n", - " return tab_contents\n", - "\n", - "\n", - "video_ids = [(\"Youtube\", \"YcIAaljLRh4\"), (\"Bilibili\", \"BV1HF41197qn\")]\n", - "tab_contents = display_videos(video_ids, W=730, H=410)\n", - "tabs = widgets.Tab()\n", - "tabs.children = tab_contents\n", - "for i in range(len(tab_contents)):\n", - " tabs.set_title(i, video_ids[i][0])\n", - "display(tabs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @markdown\n", - "from ipywidgets import widgets\n", - "from IPython.display import IFrame\n", - "\n", - "link_id = \"cy5bh\"\n", - "\n", - "download_link = f\"https://osf.io/download/{link_id}/\"\n", - "render_link = f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render\"\n", - "# @markdown\n", - "out = widgets.Output()\n", - "with out:\n", - " print(f\"If you want to download the slides: {download_link}\")\n", - " display(IFrame(src=f\"{render_link}\", width=730, height=410))\n", - "display(out)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Internal Climate Variability & Single-model Ensembles\n", - "\n", - "One of the CMIP6 models we are using in today's tutorials, _MPI-ESM1-2-LR_, is part of single-model ensemble, where its modelling centre carried out multiple simulations of the model for many of the CMIP6 experiments. To create a single-model ensemble, the modelling centre will run a model using the same forcing data, but with small changes in the initial conditions. Due to the chaotic nature of the climate system, these small changes in initial conditions lead to differences in the modelled climate as time progresses. These differences are often referred to as internal variability. By running this single-model ensemble and comparing the results to simulations using different forcing datasets, it allows us to separate the internal variability from the externally-forced variability. If you are interested in learning more about large ensemble climate models, you can [read this paper](https://esd.copernicus.org/articles/12/401/2021/).\n", - "\n", - "Let's take advantage of this single-model ensemble to quantify the internal variability of this model's simulated climate, and contrast this against the multi-model uncertainty we diagnosed in the previous tutorial.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Coding Exercise 1.1\n", - "\n", - "Complete the following code to:\n", - "\n", - "1. Load 5 different _realizations_ of the _MPI-ESM1-2-LR_ experiments (_r1i1p1f1_ through _r5i1p1f1_). This numbering convention means they were each initialized using a different time-snapshot of the base/spin-up simulation.\n", - "2. Plot the _historical_ and _SSP1-2.6_ experiment data for each realization, using a distinct color for each realization, but keeping that color the same across both the historical period and future period for a given realization.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 420, - "status": "error", - "timestamp": 1683413710306, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ") # open an intake catalog containing the Pangeo CMIP cloud data\n", - "\n", - "cat_ensemble = col.search(\n", - " source_id=\"MPI-ESM1-2-LR\",\n", - " variable_id=\"tos\",\n", - " table_id=\"Omon\",\n", - " # select the 5 ensemble members described above\n", - " member_id=[\"r1i1p1f1\", \"r2i1p1f1\", \"r3i1p1f1\", \"r4i1p1f1\", \"r5i1p1f1\"],\n", - " grid_label=\"gn\",\n", - " experiment_id=[\"historical\", \"ssp126\", \"ssp585\"],\n", - " require_all_on=[\"source_id\", \"member_id\"],\n", - ")\n", - "\n", - "# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)\n", - "kwargs = dict(\n", - " preprocess=combined_preprocessing, # apply xMIP fixes to each dataset\n", - " xarray_open_kwargs=dict(\n", - " use_cftime=True\n", - " ), # ensure all datasets use the same time index\n", - " storage_options={\n", - " \"token\": \"anon\"\n", - " }, # anonymous/public authentication to google cloud storage\n", - ")\n", - "# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the\n", - "# actual tutorial, so this would be a lot cleaner\n", - "cat_ensemble.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_ensemble = cat_ensemble.to_datatree(**kwargs)\n", - "\n", - "cat_area = col.search(\n", - " source_id=[\"MPI-ESM1-2-LR\"],\n", - " # for the coding exercise, ellipses will go after the equals on this line\n", - " variable_id=\"areacello\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Ofx\", # for the coding exercise, ellipses will go after the equals on this line\n", - " grid_label=\"gn\",\n", - " experiment_id=[\n", - " \"historical\"\n", - " ], # for the coding exercise, ellipses will go after the equals on this line\n", - " require_all_on=[\"source_id\"],\n", - ")\n", - "# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the\n", - "# actual tutorial, so this would be a lot cleaner\n", - "cat_area.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_area = cat_area.to_datatree(**kwargs)\n", - "\n", - "# add the area (we can reuse the area from before, since for a given model the horizontal are does not vary between members)\n", - "dt_ensemble_with_area = DataTree()\n", - "for model, subtree in dt_ensemble.items():\n", - " metric = dt_area[\"MPI-ESM1-2-LR\"][\"historical\"].ds[\"areacello\"].squeeze()\n", - " dt_ensemble_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)\n", - "\n", - "# global average\n", - "# average every dataset in the tree globally\n", - "dt_ensemble_gm = dt_ensemble_with_area.map_over_subtree(global_mean)\n", - "\n", - "# calculate anomaly\n", - "dt_ensemble_gm_anomaly = datatree_anomaly(dt_ensemble_gm)\n", - "\n", - "\n", - "def plot_historical_ssp126_ensemble_combined(dt, ax):\n", - " for model in dt.keys():\n", - " datasets = []\n", - " for experiment in [\"historical\", \"ssp126\"]:\n", - " datasets.append(dt[model][experiment].ds.coarsen(time=12).mean().tos)\n", - "\n", - " # concatenate the historical and ssp126 timeseries for each ensemble member\n", - " da_combined = ...\n", - " # plot annual averages\n", - " da_combined.plot(hue=\"member_id\", ax=ax)\n", - "\n", - "\n", - "fig, ax = plt.subplots()\n", - "# Uncomment below after filling in above ellipses\n", - "# plot_historical_ssp126_ensemble_combined(dt_ensemble_gm_anomaly, ax)\n", - "\n", - "ax.set_title(\n", - " \"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\"\n", - ")\n", - "ax.set_ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "ax.set_xlabel(\"Year\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 183867, - "status": "ok", - "timestamp": 1683413898135, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/neuromatch/climate-course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial5_Solution_df9b548d.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.2**\n", - "\n", - "Complete the following code to:\n", - "\n", - "1. Repeat the final figure of the last tutorial, except now display means and uncertainty bands of the single-model ensemble that you just loaded, rather than the multi-model ensemble analyzed in the previous tutorial.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 313, - "status": "error", - "timestamp": 1682795255008, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "for experiment, color in zip([\"historical\", \"ssp126\", \"ssp585\"], [\"C0\", \"C1\", \"C2\"]):\n", - " da = (\n", - " dt_ensemble_gm_anomaly[\"MPI-ESM1-2-LR\"][experiment]\n", - " .ds.tos.coarsen(time=12)\n", - " .mean()\n", - " .load()\n", - " )\n", - " # calculate the mean across ensemble members\n", - " da.mean(\"member_id\").plot(color=color, label=experiment, ax=ax)\n", - "\n", - " # shading representing spread between members\n", - " x = da.time.data\n", - " # diagnose the lower range of the likely bounds\n", - " da_lower = ...\n", - " # diagnose the upper range of the likely bounds\n", - " da_upper = ...\n", - " # Uncomment below after filling in above ellipses\n", - " # ax.fill_between(x, da_lower, da_upper, alpha=0.5, color=color)\n", - "\n", - "ax.set_title(\n", - " \"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\"\n", - ")\n", - "ax.set_ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "ax.set_xlabel(\"Year\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 206089, - "status": "ok", - "timestamp": 1683414257178, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/neuromatch/climate-course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial5_Solution_4f341bd8.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Question 1.2: Climate Connection**\n", - "\n", - "1. How does this figure compare to the multi-model ensemble figure from the previous tutorial (included below)? Can you interpret differences using the science we have discussed today?\n", - "\n", - "![tutorial 4 solution](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/img/W2D1_Tutorial_5_Insert_Figure.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/neuromatch/climate-course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial5_Solution_872e9265.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we explored the internal climate variability and its implications for climate modeling and prediction. We discussed the utility of single-model ensembles for isolating the effects of internal variability by contrasting simulations with identical physics, numerics, and discretization. We quantified the internal variability of _MPI-ESM1-2-LR_ model's simulated climate and compared it to the uncertainty introduced by multi-model ensembles. Through this tutorial, we better understand the boundaries of climate prediction and the different sources of uncertainty in CMIP6 models.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "This tutorial uses data from the simulations conducted as part of the [CMIP6](https://wcrp-cmip.org/) multi-model ensemble.\n", - "\n", - "For examples on how to access and analyze data, please visit the [Pangeo Cloud CMIP6 Gallery](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)\n", - "\n", - "For more information on what CMIP is and how to access the data, please see this [page](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md).\n", - "\n", - "For more information about large ensemble climate modelling [see this paper](https://esd.copernicus.org/articles/12/401/2021/).\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial5", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680298239014 - } - ], - "toc_visible": true - }, - "gpuClass": "standard", - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.18" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tutorials/W2D1_AnEnsembleofFutures/student/W2D1_Tutorial6.ipynb b/tutorials/W2D1_AnEnsembleofFutures/student/W2D1_Tutorial6.ipynb deleted file mode 100644 index 60ef8c4b4..000000000 --- a/tutorials/W2D1_AnEnsembleofFutures/student/W2D1_Tutorial6.ipynb +++ /dev/null @@ -1,585 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/neuromatch/climate-course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial6.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 6: Synthesising & Interpreting Diverse Data Sources\n", - "\n", - "**Week 2, Day 1, Future Climate: The Physical Basis**\n", - "\n", - "**Content creators:** Brodie Pearson, Julius Busecke, Tom Nicholas\n", - "\n", - "**Content reviewers:** Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS, Google DeepMind, and CMIP" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "In this tutorial, we will synthesize scientific knowledge from various sources and use this diverse information to validate and contextualize CMIP6 simulations. By the end of this tutorial, you will be able to \n", - "- Create a time series of global mean sea surface temperature from observations, models, and proxy data;\n", - "- Use this data to validate & contextualize climate models, and to provide a holistic picture of Earth's past and future climate evolution." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup\n", - "\n", - " \n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 97497, - "status": "ok", - "timestamp": 1684265107976, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# installations ( uncomment and run this cell ONLY when using google colab or kaggle )\n", - "\n", - "# !pip install condacolab &> /dev/null\n", - "# import condacolab\n", - "# condacolab.install()\n", - "\n", - "# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail\n", - "# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import time\n", - "\n", - "tic = time.time()\n", - "\n", - "import intake\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "\n", - "from xmip.preprocessing import combined_preprocessing\n", - "from xarrayutils.plotting import shaded_line_plot\n", - "\n", - "from datatree import DataTree\n", - "from xmip.postprocessing import _parse_metric" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "# If any helper functions you want to hide for clarity (that has been seen before\n", - "# or is simple/uniformative), add here\n", - "# If helper code depends on libraries that aren't used elsewhere,\n", - "# import those libaries here, rather than in the main import cell\n", - "\n", - "\n", - "def global_mean(ds: xr.Dataset) -> xr.Dataset:\n", - " \"\"\"Global average, weighted by the cell area\"\"\"\n", - " return ds.weighted(ds.areacello.fillna(0)).mean([\"x\", \"y\"], keep_attrs=True)\n", - "\n", - "\n", - "# calculate anomaly to reference period\n", - "def datatree_anomaly(dt):\n", - " dt_out = DataTree()\n", - " for model, subtree in dt.items():\n", - " # for the coding exercise, ellipses will go after sel on the following line\n", - " ref = dt[model][\"historical\"].ds.sel(time=slice(\"1950\", \"1980\")).mean()\n", - " dt_out[model] = subtree - ref\n", - " return dt_out\n", - "\n", - "\n", - "def plot_historical_ssp126_combined(dt):\n", - " for model in dt.keys():\n", - " datasets = []\n", - " for experiment in [\"historical\", \"ssp126\"]:\n", - " datasets.append(dt[model][experiment].ds.tos)\n", - "\n", - " da_combined = xr.concat(datasets, dim=\"time\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Video 1: Historical Context for Future Projections\n", - "\n", - "from ipywidgets import widgets\n", - "from IPython.display import YouTubeVideo\n", - "from IPython.display import IFrame\n", - "from IPython.display import display\n", - "\n", - "\n", - "class PlayVideo(IFrame):\n", - " def __init__(self, id, source, page=1, width=400, height=300, **kwargs):\n", - " self.id = id\n", - " if source == 'Bilibili':\n", - " src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'\n", - " elif source == 'Osf':\n", - " src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'\n", - " super(PlayVideo, self).__init__(src, width, height, **kwargs)\n", - "\n", - "\n", - "def display_videos(video_ids, W=400, H=300, fs=1):\n", - " tab_contents = []\n", - " for i, video_id in enumerate(video_ids):\n", - " out = widgets.Output()\n", - " with out:\n", - " if video_ids[i][0] == 'Youtube':\n", - " video = YouTubeVideo(id=video_ids[i][1], width=W,\n", - " height=H, fs=fs, rel=0)\n", - " print(f'Video available at https://youtube.com/watch?v={video.id}')\n", - " else:\n", - " video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,\n", - " height=H, fs=fs, autoplay=False)\n", - " if video_ids[i][0] == 'Bilibili':\n", - " print(f'Video available at https://www.bilibili.com/video/{video.id}')\n", - " elif video_ids[i][0] == 'Osf':\n", - " print(f'Video available at https://osf.io/{video.id}')\n", - " display(video)\n", - " tab_contents.append(out)\n", - " return tab_contents\n", - "\n", - "\n", - "video_ids = [('Youtube', 'lodJMDN6lbg'), ('Bilibili', 'BV1Bu41157mn')]\n", - "tab_contents = display_videos(video_ids, W=730, H=410)\n", - "tabs = widgets.Tab()\n", - "tabs.children = tab_contents\n", - "for i in range(len(tab_contents)):\n", - " tabs.set_title(i, video_ids[i][0])\n", - "display(tabs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @markdown\n", - "from ipywidgets import widgets\n", - "from IPython.display import IFrame\n", - "\n", - "link_id = \"b4fsp\"\n", - "\n", - "download_link = f\"https://osf.io/download/{link_id}/\"\n", - "render_link = f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render\"\n", - "# @markdown\n", - "out = widgets.Output()\n", - "with out:\n", - " print(f\"If you want to download the slides: {download_link}\")\n", - " display(IFrame(src=f\"{render_link}\", width=730, height=410))\n", - "display(out)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Reproduce Global SST for Historical and Future Scenario Experiments\n", - "\n", - "We are now going to reproduce the plot you created in Tutorial 4, which showed the likely range of CMIP6 simulated global mean sea surface temperature for historical and future scenario (*SSP1-2.6* and *SSP5-8.5*) experiments from a *multi-model ensemble*. However, now we will add some an additional dataset called *HadISST* which is an observational dataset spanning back to the 1870. Later in the tutorial, we will also include the paleo data you saw in the previous mini-lecture.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Load CMIP6 SST Data from Several Models using `xarray`\n", - "\n", - "Let's load the five different CMIP6 models again for the three CMIP6 experiments.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ") # open an intake catalog containing the Pangeo CMIP cloud data\n", - "\n", - "# pick our five example models\n", - "# there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models\n", - "source_ids = [\"IPSL-CM6A-LR\", \"GFDL-ESM4\", \"ACCESS-CM2\", \"MPI-ESM1-2-LR\", \"TaiESM1\"]\n", - "experiment_ids = [\"historical\", \"ssp126\", \"ssp585\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 17912, - "status": "ok", - "timestamp": 1684265194265, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=source_ids,\n", - " variable_id=\"tos\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Omon\",\n", - " grid_label=\"gn\",\n", - " experiment_id=experiment_ids,\n", - " require_all_on=[\n", - " \"source_id\"\n", - " ], # make sure that we only get models which have all of the above experiments\n", - ")\n", - "\n", - "# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)\n", - "kwargs = dict(\n", - " preprocess=combined_preprocessing, # apply xMIP fixes to each dataset\n", - " xarray_open_kwargs=dict(\n", - " use_cftime=True\n", - " ), # ensure all datasets use the same time index\n", - " storage_options={\n", - " \"token\": \"anon\"\n", - " }, # anonymous/public authentication to google cloud storage\n", - ")\n", - "\n", - "cat.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt = cat.to_datatree(**kwargs)\n", - "\n", - "cat_area = col.search(\n", - " source_id=source_ids,\n", - " variable_id=\"areacello\", # for the coding exercise, ellipses will go after the equals on this line\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Ofx\", # for the coding exercise, ellipses will go after the equals on this line\n", - " grid_label=\"gn\",\n", - " experiment_id=[\n", - " \"historical\"\n", - " ], # for the coding exercise, ellipses will go after the equals on this line\n", - " require_all_on=[\"source_id\"],\n", - ")\n", - "\n", - "cat_area.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - "dt_area = cat_area.to_datatree(**kwargs)\n", - "\n", - "dt_with_area = DataTree()\n", - "\n", - "for model, subtree in dt.items():\n", - " metric = dt_area[model][\"historical\"].ds[\"areacello\"]\n", - " dt_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)\n", - "\n", - "# average every dataset in the tree globally\n", - "dt_gm = dt_with_area.map_over_subtree(global_mean)\n", - "\n", - "dt_gm_anomaly = datatree_anomaly(dt_gm)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "### Coding Exercise 1.1\n", - "\n", - "Complete the following code to:\n", - "\n", - "\n", - "1. Calculate a time series of the global mean sea surface temperature (GMSST) from the HadISST dataset\n", - "2. Subtract a base period from the HadISST GMSST time series. Use the same base period as the CMIP6 timeseries you are comparing against. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 114, - "status": "error", - "timestamp": 1684265198522, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "for experiment, color in zip([\"historical\", \"ssp126\", \"ssp585\"], [\"C0\", \"C1\", \"C2\"]):\n", - " datasets = []\n", - " for model in dt_gm_anomaly.keys():\n", - " annual_sst = (\n", - " dt_gm_anomaly[model][experiment]\n", - " .ds.tos.coarsen(time=12)\n", - " .mean()\n", - " .assign_coords(source_id=model)\n", - " .load()\n", - " )\n", - " datasets.append(\n", - " annual_sst.sel(time=slice(None, \"2100\")).load()\n", - " ) # the french model has a long running member for ssp 126 (we could change the model to keep this clean)\n", - " da = xr.concat(datasets, dim=\"source_id\", join=\"override\").squeeze()\n", - " da.mean(\"source_id\").plot(color=color, label=experiment, ax=ax)\n", - " x = da.time.data\n", - " da_lower = da.squeeze().quantile(0.17, dim=\"source_id\")\n", - " da_upper = da.squeeze().quantile(0.83, dim=\"source_id\")\n", - " ax.fill_between(x, da_lower, da_upper, alpha=0.5, color=color)\n", - "\n", - "# but now add observations (https://pangeo-forge.org/dashboard/feedstock/43)\n", - "store = \"https://ncsa.osn.xsede.org/Pangeo/pangeo-forge/HadISST-feedstock/hadisst.zarr\"\n", - "ds_obs = xr.open_dataset(store, engine=\"zarr\", chunks={}).convert_calendar(\n", - " \"standard\", use_cftime=True\n", - ")\n", - "# mask missing values\n", - "ds_obs = ds_obs.where(ds_obs > -1000)\n", - "weights = np.cos(\n", - " np.deg2rad(ds_obs.latitude)\n", - ") # In a regular lon/lat grid, area is ~cos(latitude)\n", - "# calculate weighted global mean for observations\n", - "sst_obs_gm = ...\n", - "# calculate anomaly for observations\n", - "sst_obs_gm_anomaly = ...\n", - "\n", - "# plot observations\n", - "# Uncomment below once you fill in the above ellipses\n", - "# sst_obs_gm_anomaly.coarsen(time=12, boundary=\"trim\").mean().plot(\n", - "# color=\"0.3\", label=\"Observations\", ax=ax\n", - "# )\n", - "ax.set_ylabel(\"Global Mean SST with respect to 1950-1980\")\n", - "ax.set_xlabel(\"Year\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 66611, - "status": "ok", - "timestamp": 1684265266986, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/neuromatch/climate-course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial6_Solution_970b7c15.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1.1 Climate Connection\n", - "\n", - "Now that you have a modern and projected time series containing models and observations,\n", - "1. What context and/or validation of the simulations does this information provide?\n", - "2. What additional context/validation can you glean by also considering the paleo proxy information in the figure below? (This figure was shown in the last video)\n", - "\n", - "Note the paleo periods on this figure represent the Mid-Pleiocene Warm Period (MPWP), the Last Inter-glacial (LIG) ad the Last Glacial Maximum (LGM)\n", - "\n", - "![](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/img/W2D1_Tutorial_6_Insert_Figure.png?raw=true)\n", - "\n", - "This image shows part of panel a) from Figure 9.3 from the IPCC AR6 WG1 report. This figure has the following caption: **Figure 9.3** | Sea surface temperature (SST) and its changes with time. (a) Time series of global mean SST anomaly relative to 1950–1980 climatology. Shown are paleoclimate reconstructions and PMIP models, observational reanalyses (HadISST) and multi-model means from the Coupled Model Intercomparison Project (CMIP) historical simulations, CMIP projections, and HighResMIP experiment. (b) Map of observed SST (1995–2014 climatology HadISST). (c) Historical SST changes from observations. (d) CMIP 2005–2100 SST change rate. (e) Bias of CMIP. (f) CMIP change rate. (g) 2005–2050 change rate for SSP5-8.5 for the CMIP ensemble. (h) Bias of HighResMIP (bottom left) over 1995–2014. (i) HighResMIP change rate for 1950–2014. (j) 2005–2050 change rate for SSP5-8.5 for the HighResMIP ensemble. No overlay indicates regions with high model agreement, where ≥80% of models agree on sign of change. Diagonal lines indicate regions with low model agreement, where <80% of models agree on sign of change (see Cross-Chapter Box Atlas.1 for more information). Further details on data sources and processing are available in the chapter data table (Table 9.SM.9)." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/neuromatch/climate-course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial6_Solution_7818edff.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In the final tutorial of the day, we learned about the importance of synthesizing CMIP6 model data (future projections and historical simulations), alongside modern climate and palroclimate observations. This synthesis provides validation of CMIP6 simulation data, and it provides historical context for recent and projected rapid changes in Earth's climate, as many of these changes are unprecedented in human-recored history.\n", - "\n", - "In the upcoming tutorials, we will shift our focus towards the socio-economic aspects of future climate change. This exploration will take various forms, including the design of the Shared Socioeconomic Pathways (SSPs) we began using today. We'll contemplate the realism of different socio-economic future scenarios and examine their potential impacts on future climate forcings. Moreover, we'll delve into how a changing climate might affect society. As we proceed with the next tutorials, keep in mind the intricate connection between physical and socio-economic changes." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "This tutorial uses data from the simulations conducted as part of the [CMIP6](https://wcrp-cmip.org/) multi-model ensemble. \n", - "\n", - "For examples on how to access and analyze data, please visit the [Pangeo Cloud CMIP6 Gallery](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html) \n", - "\n", - "For more information on what CMIP is and how to access the data, please see this [page](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial6", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680298239014 - } - ], - "toc_visible": true - }, - "gpuClass": "standard", - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.18" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Intro.ipynb b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Intro.ipynb index 7dc02673c..cb660f85e 100644 --- a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Intro.ipynb +++ b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Intro.ipynb @@ -37,7 +37,7 @@ "execution": {} }, "source": [ - "## TODO Day Learning Objectives" + "## Day Learning Objectives" ] }, { @@ -47,10 +47,9 @@ "execution": {} }, "source": [ - "1. Describe the logic behind the socioeconomic pathway framework, and explain how the pathways differ from one another in both climate and socioeconomic variables using CMIP6 data and integrated assessment modeling results, respectively (building off of W2D1).\n", - "2. Examine the strengths and weaknesses of integrated assessment modeling practice and compare models whose results are included in the IPCC reports and understand how these results impact the report’s conclusions.\n", - "3. Examine the socioeconomic factors at the origin of anthropogenic warming and a *Just Transition*.\n", - "\n" + "1. Describe the motivation behind the Shared Socioeconomic Pathway (SSP) framework, and explain how the 5 pathways differ from one another in both climate and socioeconomic aspects using CMIP6 data and integrated assessment modeling results, respectively.\n", + "2. Examine the strengths and weaknesses of SSP-focussed integrated assessment modeling practice and understand how these support and weaken the IPCC report’s conclusions, respectively.\n", + "3. Examine the socioeconomic factors at the origin of anthropogenic warming and a *Just Transition*." ] } ], @@ -81,7 +80,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial1.ipynb b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial1.ipynb index ee54a8842..1c259f076 100644 --- a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial1.ipynb +++ b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial1.ipynb @@ -59,9 +59,7 @@ "cell_type": "code", "execution_count": null, "id": "368d0c90-ae7e-43d9-ada7-ad42c75f5f95", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# import\n", @@ -73,8 +71,7 @@ "execution_count": null, "id": "f831d869-6072-44f2-8568-ddf04ace1abb", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -103,8 +100,7 @@ "execution_count": null, "id": "6db786f8-e5c4-42a9-9837-e41027b9ad4d", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -122,8 +118,7 @@ "execution_count": null, "id": "e11e3bbb-ce8f-4404-8d04-b6f86d4a9ea9", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -151,8 +146,7 @@ "execution_count": null, "id": "ea9d553f-c3eb-4723-a922-e81f97e1e3ba", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -210,8 +204,7 @@ "execution_count": null, "id": "e3fe59d0-0e89-48ec-b652-2ec007d4c6f3", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -224,8 +217,7 @@ "execution_count": null, "id": "52ca5582-816c-423c-9ed7-cda1c7319731", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -244,8 +236,7 @@ "execution_count": null, "id": "f9b620a1-41ec-4ded-a186-7f598ceaa045", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -280,8 +271,7 @@ "execution_count": null, "id": "9c6b2260-bdb0-4d7b-a07d-41551d5ccf92", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -362,9 +352,7 @@ "cell_type": "code", "execution_count": null, "id": "30a81fb8-c21b-490c-9297-a6705f114957", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -391,8 +379,7 @@ "execution_count": null, "id": "2523a1bd-56cc-4594-b6d6-fa84288cadfb", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -405,8 +392,7 @@ "execution_count": null, "id": "05df13b5-14ce-4515-aaae-7cc9e3765445", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -418,7 +404,6 @@ "\n", "download_link = f\"https://img.climateinteractive.org/2019/09/EnROADS-one-page-guide-to-control-panel-v11-dec-2021.pdf\"\n", "render_link = f\"https://img.climateinteractive.org/2019/09/EnROADS-one-page-guide-to-control-panel-v11-dec-2021.pdf\"\n", - "# @markdown\n", "out = widgets.Output()\n", "with out:\n", " print(f\"If you want to download a cheatsheet for the En-ROADS Control Panel:\\n{download_link}\")\n", @@ -447,9 +432,7 @@ "cell_type": "code", "execution_count": null, "id": "b17595a7-b326-4edb-9f80-b8e21f1d4e5e", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -473,8 +456,7 @@ "execution_count": null, "id": "39410eaf-5020-4646-a821-b90df4c361f7", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -539,7 +521,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial2.ipynb b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial2.ipynb index 6e1108064..6ceaa9c98 100644 --- a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial2.ipynb +++ b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial2.ipynb @@ -263,7 +263,7 @@ "\n", "You might already have clicked through the toggles at the top of the control panel of En-ROADS and tried the different *Views* (Main graphs, Kaya graphs, Miniature graphs). Select now the **Kaya graphs** view and reset the simulator (click on the anti-clockwise circular arrow to 'Reset all policies & assumptions' or just reload the page/model [here](https://en-roads.climateinteractive.org/)).\n", "\n", - "The Kaya graphs depict four drivers of growth in carbon dioxide emissions from energy use, which reflects about two-thirds of all greenhouse gas emissions (the remaining third of emissions are from land use changes and other gases, such as methane (CH4) and nitrous oxide (N2O), which are not considered here). The corresponding equation, the so-called [***Kaya identity***](https://en.wikipedia.org/wiki/Kaya_identity) below was developed by Yoichi Kaya:\n", + "The Kaya graphs depict four drivers of growth in carbon dioxide emissions from energy use, which reflects about two-thirds of all greenhouse gas emissions (the remaining third of emissions are from land use changes and other gases, such as methane (CH$_4$) and nitrous oxide (N$_2$O), which are not considered here). The corresponding equation, the so-called [***Kaya identity***](https://en.wikipedia.org/wiki/Kaya_identity) below was developed by Yoichi Kaya:\n", "\n", "***CO$_2$ Emissions from Energy = Global Population × GDP per Capita × Energy Intensity of GDP × Carbon Intensity of Energy***\n", "\n", @@ -608,7 +608,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial3.ipynb b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial3.ipynb index c80f26fbd..2a3bf926a 100644 --- a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial3.ipynb +++ b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial3.ipynb @@ -43,7 +43,7 @@ "source": [ "# Tutorial Objectives\n", "\n", - "*Estimated timing of tutorial:* 15 minutes\n", + "*Estimated timing of tutorial:* 20 minutes\n", "\n", "The last tutorials covered the necessity for an energy transition to tackle the climate emergency and many solutions at once. As emissions accumulate, it becomes substantially harder to succeed the longer we take to make big changes. This tutorial explores the temporal dimension of action, here policies, by using the Climate Solution Simulator named [En-ROADS](https://www.climateinteractive.org/en-roads/).\n", "\n", @@ -56,9 +56,7 @@ "cell_type": "code", "execution_count": null, "id": "062c4b1a-6239-4644-a0dd-03fe1342fe99", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# import\n", @@ -70,8 +68,7 @@ "execution_count": null, "id": "33ac31c0-ac52-447a-82d7-aec0b98dc6e6", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -100,8 +97,7 @@ "execution_count": null, "id": "8b4722fe-cbd5-484a-be6d-96ed7aafbf62", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -119,8 +115,7 @@ "execution_count": null, "id": "053ee0ea-d704-45c8-8b4b-aad17216710d", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -148,8 +143,7 @@ "execution_count": null, "id": "5b50c362", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -208,8 +202,7 @@ "execution_count": null, "id": "74b1c5e6-ed8f-4ca8-bbab-a0a6c417dced", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -222,8 +215,7 @@ "execution_count": null, "id": "703ee8f2", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -242,8 +234,7 @@ "execution_count": null, "id": "9fd96992-bab2-4494-aeb5-997cc8689746", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -297,9 +288,7 @@ "cell_type": "code", "execution_count": null, "id": "c97e6d3d-1718-479b-a19a-ffc6a082347b", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -320,8 +309,7 @@ "execution_count": null, "id": "867fc0d6-6802-4d3d-888b-be960ffd54e8", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -338,7 +326,7 @@ "source": [ "# Summary\n", "\n", - "In this tutorial, we discussed the temporal dimension of the carbon price implementation in order to understand why no policy might be a silver bullet to solve all problems but comes with various ethical and political implications. At last, we discussed a few limitations of the En-ROADs model approach." + "In this tutorial, we discussed the temporal dimension of the carbon price implementation in order to understand why no policy might be a silver bullet to solve all problems but comes with various ethical and political implications. " ] }, { @@ -386,7 +374,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial4.ipynb b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial4.ipynb index c0c11f540..7600707fe 100644 --- a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial4.ipynb +++ b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial4.ipynb @@ -38,6 +38,8 @@ "source": [ "# Tutorial Objectives\n", "\n", + "*Estimated timing of tutorial:* 35 minutes\n", + "\n", "In this tutorial, you will learn about Integrated Assessment Models (IAMs), a class of models that combine climatology, economics, and social science, reflecting the intertwined nature of these domains in addressing climate change. Based on these models the IPCC established the socioeconomic pathway framework. You are going to learn how these pathways differ from one another in both climate and socioeconomic variables as well as assumptions.\n", "\n", "After finishing this tutorial, you will know how to \n", @@ -60,9 +62,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# installations ( uncomment and run this cell ONLY when using google colab or kaggle )" @@ -72,7 +72,6 @@ "cell_type": "code", "execution_count": null, "metadata": { - "execution": {}, "executionInfo": { "elapsed": 1460, "status": "ok", @@ -103,8 +102,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -132,8 +130,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -153,7 +150,6 @@ "code_folding": [ 0 ], - "execution": {}, "tags": [] }, "outputs": [], @@ -188,7 +184,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "tags": [] }, "outputs": [], @@ -246,8 +241,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -260,7 +254,6 @@ "execution_count": null, "metadata": { "cellView": "form", - "execution": {}, "pycharm": { "name": "#%%\n" }, @@ -284,8 +277,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -309,7 +301,7 @@ "jp-MarkdownHeadingCollapsed": true }, "source": [ - "In this, and subsequent, tutorials, you will explore Integrated Assessment Models (IAMs) which are the standard class of models used to make climate change projections. IAMs couple a climate model with an economic model, allowing us to evaluate the two-way coupling between economic productivity and climate change severity. IAMs can also account for changes that result from mitigation efforts, which lessen anthropogenic emissions.\n", + "In this, and the subsequent, tutorial, you will explore Integrated Assessment Models (IAMs) which are the standard class of models used to make climate change projections. IAMs couple a climate model with an economic model, allowing us to evaluate the two-way coupling between economic productivity and climate change severity. IAMs can also account for changes that result from mitigation efforts, which lessen anthropogenic emissions.\n", "\n", "Let's start by investigating some IAM model output.\n", "\n", @@ -332,9 +324,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# Load SSP data from .csv file\n", @@ -359,9 +349,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "print(df.SCENARIO.unique()) # print all scenarios\n", @@ -385,8 +373,8 @@ "- and **forcing** (`'Diagnostics|MAGICC6|Forcing'`).\n", "\n", "- As a `REGION`, we choose the `'World'`,\n", - "- and our `SCENARIO`s are called `'SSP1-26'` and `'SSP5-85'`.\n", - "- The model of choice for the former scenario is by convention `'IMAGE'` and `'REMIND-MAGPIE'` for the latter, respectively.\n", + "- and our `SCENARIO`s are called `'SSP1-Baseline'` and `'SSP5-Baseline'`.\n", + "- The model of choice for the former scenario is by convention `'IMAGE'` and `'REMIND-MAGPIE'` for the latter, respectively.\n", "\n", "A function named `get_SSPs_for_variable()` applies all this generally and is hidden in the next cell. Please execute it, such that the subsequent cells can make use of it. If you are interested in its procedure and want to adjust it, don't forget to save a copy beforehand." ] @@ -395,8 +383,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -447,9 +434,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# put variables of interest in a list\n", @@ -457,7 +442,7 @@ "# create new names for structured data series and axes labels\n", "val_name = ['GDP (billion US$/yr)', 'Emissions (Mt CO$_2$/yr)', 'Energy use (EJ/yr)', 'Forcing (W/m$^2$)']\n", "# choose scenarios of interest and a color for plotting\n", - "scenarios = ['SSP1-26', 'SSP5-Baseline']\n", + "scenarios = ['SSP1-Baseline', 'SSP5-Baseline']\n", "colors = ['darkblue','darkorange']\n", "\n", "# init figure and axis\n", @@ -496,7 +481,7 @@ "\n", "Our plots show that the SSP5-Baseline scenario exhibits very high levels of energy use, and emissions (due to fossil fuel exploitation), it marks the upper end of the scenarios in several dimensions (cf. [Kriegler et al. (2014)](https://doi.org/10.1016/j.gloenvcha.2016.05.015)). \n", "\n", - "The SSP1-26 scenario contrarily caps the increase of energy use by 2030, combined with other actions leading to decreasing emissions and subsequently a decreasing forcing for the second half of the century. However, economic growth continues with half the slope of SSP5-Baseline. In summary, it is the most optimistic projection: we transition to a global society of sustainability-focused growth." + "The SSP1-Baseline scenario contrarily caps the increase of energy use by 2030, combined with other actions leading to decreasing emissions and subsequently a decreasing forcing for the second half of the century. However, economic growth continues with half the slope of SSP5-Baseline. In summary, it is the most optimistic projection: we transition to a global society of sustainability-focused growth." ] }, { @@ -566,9 +551,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# put variables of interest in a list\n", @@ -576,7 +559,7 @@ "# create new names for structured data series and plot labels\n", "val_name = ['Population\\n(millions)', 'GDP (billion US$/yr)']\n", "# choose scenarios of interest and a color for plotting\n", - "scenarios = ['SSP1-26', 'SSP5-Baseline']\n", + "scenarios = ['SSP1-Baseline', 'SSP5-Baseline']\n", "colors = ['darkblue','darkorange']\n", "\n", "# init figure and axis\n", @@ -620,7 +603,7 @@ "execution": {} }, "source": [ - "# Section 1.3: Differences of SSP1 and SSP5\n", + "## Section 1.4: Differences of SSP1 and SSP5\n", "\n", "Major differences are visible when you contrast emissions and assume direct causation with ecosystem health. Increasing emissions then translate into decreasing ecosystem health." ] @@ -631,7 +614,7 @@ "execution": {} }, "source": [ - "## Coding exercise 1.3\n", + "## Coding exercise 1.4\n", "\n", "1. Choose two variables to emphasize ecosystem health differences in the SSP1 and SSP5 scenarios and assign them to `vars`. Then assign axis labels with the correct units for plotting to the `val_name` variable.\n", "2. Explain to your pod why the chosen variables emphasize a difference in the scenarios and describe this difference based on your current knowledge of the narratives." @@ -640,9 +623,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# put two variables of interest in a list\n", @@ -650,7 +631,7 @@ "# create new names for structured data series and plot labels\n", "val_name = ...\n", "# choose scenarios of interest and a color for plotting\n", - "scenarios = ['SSP1-26', 'SSP5-Baseline']\n", + "scenarios = ['SSP1-Baseline', 'SSP5-Baseline']\n", "colors = ['darkblue','darkorange']\n", "\n", "#################################################\n", @@ -691,9 +672,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove solution\n", @@ -703,7 +682,7 @@ "# create new names for structured data series and plot labels\n", "val_name = ['Emissions\\n(Mt CO$_2$/yr)','Land covered by\\nforest (million ha)']\n", "# choose scenarios of interest and a color for plotting\n", - "scenarios = ['SSP1-26', 'SSP5-Baseline']\n", + "scenarios = ['SSP1-Baseline', 'SSP5-Baseline']\n", "colors = ['darkblue','darkorange']\n", "\n", "\n", @@ -736,9 +715,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", @@ -758,13 +735,12 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ "# @title Submit your feedback\n", - "content_review(f\"{feedback_prefix}_Coding_Exercise_1_3\")" + "content_review(f\"{feedback_prefix}_Coding_Exercise_1_4\")" ] }, { @@ -789,7 +765,7 @@ "\n", "It is possible to download the SSP data used in this tutorial, when you provide an email address, from [this IIASA database](https://tntcat.iiasa.ac.at/SspDb/dsd), where all data from the main simulations of the IAMs used in the [IPCC reports](https://www.ipcc.ch/reports/) is freely available.\n", "\n", - "Find a summary of all SSP narratives in this paper by [Oneill et al. (2017)](https://doi.org/10.1016/j.gloenvcha.2015.01.004).\n", + "Find a summary of all SSP narratives in this paper by [O'Neill et al. (2017)](https://doi.org/10.1016/j.gloenvcha.2015.01.004).\n", "\n", "Find even more information in\n", "\n", @@ -825,7 +801,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial5.ipynb b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial5.ipynb index 5c2577851..b505eb3ae 100644 --- a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial5.ipynb +++ b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial5.ipynb @@ -22,11 +22,11 @@ "\n", "**Content creators:** Paul Heubel, Maximilian Puelma Touzel\n", "\n", - "**Content reviewers:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", + "**Content reviewers:** Jenna Pearson, Ohad Zivan\n", "\n", - "**Content editors:** Paul Heubel, Jenna Pearson, Chi Zhang, Ohad Zivan\n", + "**Content editors:** Paul Heubel, Jenna Pearson, Ohad Zivan\n", "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Konstantine Tsafatinos, Chi Zhang, Ohad Zivan\n", + "**Production editors:** Jenna Pearson, Konstantine Tsafatinos, Chi Zhang, Ohad Zivan\n", "\n", "**Our 2024 Sponsors:** CMIP, NFDI4Earth" ] @@ -40,22 +40,25 @@ "source": [ "# Tutorial objectives\n", "\n", - "* " + "*Estimated timing of tutorial:* 25 minutes\n", + "\n", + "In this tutorial, you discuss the narratives of the SSP framework and step back to reflect on the framework's assumptions and their consequences for modeling socioeconomics and climate futures. It further emphasizes how equity aspects need to be thought of when solving the climate crisis.\n", + "\n", + "After working through this Tutorial you know how to \n", + "\n", + "* map Shared Socioeconomic Pathways in a feature space of equality and environmental health,\n", + "* reflect on narratives when discussing future scenarios and their socioeconomic implications." ] }, { "cell_type": "code", "execution_count": null, "id": "1af3e766-b9c3-4bf8-815c-4087e7811925", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# import\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "#import dicelib # https://github.com/mptouzel/PyDICE" + "import matplotlib.pyplot as plt" ] }, { @@ -63,8 +66,7 @@ "execution_count": null, "id": "bf05ea3d-be91-4007-b4dd-210179c2f6f1", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -93,8 +95,7 @@ "execution_count": null, "id": "e7392de8-f946-453b-bedf-8a07c705ee7f", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -112,8 +113,7 @@ "execution_count": null, "id": "6c10210c-a3d9-4996-a3d3-4bafa4b72637", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -141,8 +141,7 @@ "execution_count": null, "id": "80412217-b5a7-4fed-b29e-b8751eb8c847", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -201,8 +200,7 @@ "execution_count": null, "id": "ddbb472a-a055-4f48-800b-ec9ac36cb3c6", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -215,8 +213,7 @@ "execution_count": null, "id": "2dc2f6c1-637b-4506-a667-45750dd7fbe5", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -230,6 +227,17 @@ "IFrame(src=f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render\", width=854, height=480)" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "693f9f9c-c8c0-4118-99cd-a9ccf1f55766", + "metadata": {}, + "outputs": [], + "source": [ + "# @title Submit your feedback\n", + "content_review(f\"{feedback_prefix}_Mapping_the_Narrative_Space_Slides\")" + ] + }, { "cell_type": "markdown", "id": "c7ce6e92-a46d-437a-9e03-c5b80eb63474", @@ -243,14 +251,14 @@ "\n", "Let's begin with a brief recall of the IAM features:\n", "\n", - "- IAMs resolve the economy spatially, in contrast, the toy model En-ROADs for example, which we applied in Tutorial 1 to 3, aggregates all variables and is non-spatial.\n", + "- IAMs resolve the economy spatially, in contrast, the toy model En-ROADS for example, which we applied in Tutorial 1 to 3, aggregates all variables and is non-spatial.\n", "- Like En-ROADS, the world models used in IAMs usually have *exogeneous* (externally set) times series for variables, in addition to fixed world system parameters. These exogenous variables are assumed to be under our society's control (e.g. mitigation). \n", "- IAMs come equipped with an objective function (a formula that calculates the quantity to be optimized). This function returns the value of a projected future obtained from running the world model under a given climate policy. This value is defined by the time series of these exogenous variables. In this sense, the objective function is what defines \"good\" in \"good climate policy\". \n", "- The computation in an IAM is then an optimization of this objective as a function of the time series of these exogenous variables over some fixed time window.\n", "\n", "Most IAMs are based on *Neo-classical economics* (also referred to as \"establishment economics\"). This is an approach to economics that makes particular assumptions. For example, it is assumed that production, consumption, and valuation of goods and services are driven solely by the supply and demand model. One fundamental concept is *utility* (i.e. economic value), which is not only central to economics but also to decision theory as a whole, which is a research field that mathematically formalizes the activity of *planning* (planning here means selecting strategies based on how they are expected to play out given a model that takes those strategies and projects forward into the future).\n", "\n", - "As we want to discuss the background of IAM economics, you are going to reflect on these particular *Neo-classical* assumptions." + "Six of the most well-established IAMs have been chosen to represent a certain SSP narrative as discussed by Max in the video. Their simulations result in energy use and emissions characteristics for the respective SSP. These narratives try to describe broad socioeconomic trends that are plausible while reflecting worlds in which mitigation and adaptation challenges vary from low to very high.\n" ] }, { @@ -262,7 +270,7 @@ "source": [ "## Questions 1\n", "\n", - "As a follow-up to its presentation in the tutorial video, try now to place all 5 SSP narratives in the three-dimensional feature space yourself. You can use the SSP narrative names as a hint.\n", + "As a repetition and a follow-up of the tutorial video, try now to place all 5 SSP narratives in the three-dimensional feature space of ***Intra-nation equality***, ***Inter-nation equality***, and ***Environmental Health*** yourself. You can use the SSP narrative names as a hint.\n", "\n", "* SSP1: Sustainability\n", "* SSP2: Middle of the road\n", @@ -270,6 +278,8 @@ "* SSP4: A road divided\n", "* SSP5: Fossil Fueled development\n", "\n", + "As an additional hint, you might want to check out detailed SSP summaries in the 'SSP narratives' section in [this Carbon Brief article](https://www.carbonbrief.org/explainer-how-shared-socioeconomic-pathways-explore-future-climate-change/).\n", + "\n", "Which were easy to place? Which were harder? What made them easy or hard to place? Discuss with your pod.\n" ] }, @@ -277,17 +287,39 @@ "cell_type": "code", "execution_count": null, "id": "a7b00ec8-495f-4e07-ab13-989dd26b2c92", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", "'''\n", - "Guidance for TAs: The solution is already given in the slides, to further discuss these slides, please read the detailed SSP summaries in the 'SSP narratives' section from the carbon brief website under https://www.carbonbrief.org/explainer-how-shared-socioeconomic-pathways-explore-future-climate-change/\n", + "The solution is already given in the slides, to further discuss these slides, please read the detailed SSP summaries in the 'SSP narratives' section from the carbon brief website under https://www.carbonbrief.org/explainer-how-shared-socioeconomic-pathways-explore-future-climate-change/\n", "'''" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "11591351-d85d-4737-835d-b1ca218f1354", + "metadata": {}, + "outputs": [], + "source": [ + "# @title Submit your feedback\n", + "content_review(f\"{feedback_prefix}_Questions_1\")" + ] + }, + { + "cell_type": "markdown", + "id": "97a7001b-1122-4f8c-9ef9-b42b03823f21", + "metadata": {}, + "source": [ + "This feature space is one way to dissect the narratives that underlie the SSPs. \n", + "\n", + "A consideration of the future socio-economic situation in the light of the resulting challenges is also fruitful. For example, low challenges to mitigation and adaptation due to rapid technological development, relative global equality of income and focus on environmental sustainability arise in SSP1. SSP4, on the other hand, features similarly low challenges to mitigation due to its rapid technological development, but high challenges to climate adaptation due to persistent inequality and poverty in many parts of the world (cf. [Carbon Brief Explainer, Hausfather, 2018](https://www.carbonbrief.org/explainer-how-shared-socioeconomic-pathways-explore-future-climate-change/)). \n", + "Note that mitigation and adaptation responses are not implemented in the SSPs, such that other studies can assess the effects of policies and of impacts by comparing outcomes to those in the reference SSPs. Hence, a large number of studies investigate a variety of policies and projected risks (cf. [O'Neill et al., 2020](https://www.nature.com/articles/s41558-020-00952-0)).\n", + "\n", + "Let us finally summarize a few advantages and disadvantages of the SSP framework in general." + ] + }, { "cell_type": "markdown", "id": "35fa283c-f214-45a4-9b45-bf263d989f74", @@ -297,26 +329,45 @@ "source": [ "## Questions 2\n", "\n", - "The SSP framework. Take a minute to list the strengths and weaknesses of the scenario approach to socio-economic climate projections. \n" + "The SSP framework. Take a minute to list the strengths and weaknesses of the scenario approach to socio-economic climate projections you can think of. \n" ] }, { "cell_type": "code", "execution_count": null, "id": "c8f40968-8d7a-487f-aeb3-b901ebfe53fd", - "metadata": { - "execution": {} - }, + "metadata": {}, "outputs": [], "source": [ "# to_remove explanation\n", "\n", "'''\n", - "Strength: SSPs are an approach that nicely balances (biased) expert opinion with more objective (but perhaps inaccurate) models.\n", - "Weakness: even larger set of assumptions/complexity gives over confidence?\n", + "Strengths: SSPs are an approach that nicely balances (biased) expert opinion with more objective (but perhaps inaccurate) models. The framework underlines the importance of baseline assumptions on resulting emissions and temperatures. \n", + "There is now more than one baseline/business-as-usual scenario, however, these scenarios result in at least 3.1°C warming (and up to 5.1°C) by 2100. \n", + "With the framework, one is easily able to model climate policies and compare them to the benchmark futures. It furthermore allows for climate change-related research globally across research communities and is extendable to other scales, sectors, and issue areas. \n", + "Global narrative extensions can be produced and applied in key sectors to support quantitative projections from e.g. energy and land-use models, and projections from IAMs. \n", + "\n", + "...\n", + "\n", + "Weaknesses: An even larger set of assumptions/complexity leads to overconfidence while complexity and uncertainty are increased. It is not easy to apply SSPs regionally. \n", + "Futures with non-neo-classical economics like no or limited growth in high-income countries or scenarios oriented around eco-communalism are not represented in the SSPs. \n", + "There might also be plausible futures that are under-represented including those driven by disruptive events, whether technological, social, political, or environmental, e.g. implications of violent conflicts, the crossing of biophysical and social tipping points or unexpectedly rapid technological innovation; for example, in artificial intelligence or energy efficiency.\n", + "...\n", + "cf. e.g https://www.nature.com/articles/s41558-020-00952-0\n", "'''" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "041ce3f4-15b5-48e5-b810-3194f27f5766", + "metadata": {}, + "outputs": [], + "source": [ + "# @title Submit your feedback\n", + "content_review(f\"{feedback_prefix}_Questions_2\")" + ] + }, { "cell_type": "markdown", "id": "28c0a077-c9a0-42d9-ada6-e8b835668c3b", @@ -324,17 +375,23 @@ "execution": {} }, "source": [ - "# Summary" + "# Summary\n", + "\n", + "In this tutorial, you discussed the narratives of the SSP framework and stepped back to reflect on the framework's assumptions and their consequences for modeling socioeconomics and climate futures. It helps to prepare a thoughtful development of your own climate scenario via En-ROADS in the next tutorial. Equality aspects, prerequisites and socioeconomic necessities as well as other implications need to be thought of when solving the climate crisis." ] }, { + "attachments": {}, "cell_type": "markdown", - "id": "9e904e57-b6b9-4ee8-aefb-140dce3c93c2", - "metadata": { - "execution": {} - }, + "id": "3469e417-cb2e-49a8-82bc-0b600337244c", + "metadata": {}, "source": [ - "# Resources" + "# Resources\n", + "\n", + "- [Carbon Brief Explainer: How ‘Shared Socioeconomic Pathways’ explore future climate change, Hausfather, 2018](https://www.carbonbrief.org/explainer-how-shared-socioeconomic-pathways-explore-future-climate-change/)\n", + "- [The Shared Socioeconomic Pathways and their energy, land use, and greenhouse gas emissions implications: An overview, Riahi et al., Global Environmental Change 42, 169-180 (2017). doi.org/10.1016/j.gloenvcha.2015.01.004](https://doi.org/10.1016/j.gloenvcha.2015.01.004)\n", + "- [O’Neill, B.C., Carter, T.R., Ebi, K. et al. Achievements and needs for the climate change scenario framework. Nat. Clim. Chang. 10, 1074–1084 (2020). doi.org/10.1038/s41558-020-00952-0](https://doi.org/10.1038/s41558-020-00952-0)\n", + "- [En-ROADS documentation](https://docs.climateinteractive.org/projects/en-roads/en/latest/index.html)" ] } ], @@ -365,7 +422,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4, diff --git a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial6.ipynb b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial6.ipynb index abd0c7ff2..8b2c1e246 100644 --- a/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial6.ipynb +++ b/tutorials/W2D2_TheSocioeconomicsofClimateChange/W2D2_Tutorial6.ipynb @@ -56,8 +56,7 @@ "execution_count": null, "id": "7550a995-8abf-45a7-83fe-4eb7565d43f4", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -86,8 +85,7 @@ "execution_count": null, "id": "b591486d-dff5-4dc6-b83b-1125977a7758", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -140,6 +138,18 @@ "display(tabs)" ] }, + { + "cell_type": "markdown", + "id": "8e98eb20-8e63-4a64-a9b3-47c2f0ee7383", + "metadata": {}, + "source": [ + "# Section 1: CO$_2$ Removal\n", + "\n", + "While substantial emissions mitigations are necessary to reduce future climate suffering, they can not make up for the hundreds of billions of tons of CO$_2$ that humans have already emitted. However, both natural and technological methods for removing CO$_2$ from the atmosphere exist. Although they are presently miniscule compared to the tens-of-gigatons scale of global emissions, some experts expect that CO$_2$ removal methods will play a key role in the future once major mitigation goals have been accomplished. \n", + "\n", + "Video 1 briefly explains how Carbon Removal is addressed in EN-ROADS. Keep its representation in mind for the following exercises." + ] + }, { "cell_type": "markdown", "id": "a516e969-8b67-4f8a-9d39-061770ffb4c9", @@ -174,8 +184,7 @@ "execution_count": null, "id": "d485bbc9-f179-4516-bc51-eb34211e8255", "metadata": { - "cellView": "form", - "execution": {} + "cellView": "form" }, "outputs": [], "source": [ @@ -211,7 +220,9 @@ "- [En-ROADS User Guide PDF](https://docs.climateinteractive.org/projects/en-roads/en/latest/en-roads-user-guide.pdf)\n", "- [Guided Assignment - Simulating Climate Futures in En-ROADS: Short Version](https://www.climateinteractive.org/guided-assignment/)\n", "\n", - "**A Planetary Crisis Planning Computer Game**\n", + "**Planetary Crisis Planning Computer Games**\n", + "Play the games listed below to explore alternative societal futures\n", + "- [The Climate Game](https://ig.ft.com/climate-game/)\n", "- [Half Earth Socialism](https://play.half.earth/).\n" ] } @@ -243,7 +254,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.19" + "version": "3.9.18" } }, "nbformat": 4,