diff --git a/Copy_from_google_drive.ipynb b/Copy_from_google_drive.ipynb deleted file mode 100644 index 67d3ab617..000000000 --- a/Copy_from_google_drive.ipynb +++ /dev/null @@ -1,631 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 7, - "id": "931e6f03-32dd-4008-8432-7379ccf7b319", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import os\n", - "import re\n", - "import shutil\n", - "import glob\n", - "from pathlib import Path" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "99931fe4-8637-4f43-997b-f08af2704490", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "files = glob.glob(os.environ[\"GDRIVE_NOTEBOOKS\"] + \"/**/*\", recursive=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "654ff02b-6fe5-41c9-9be6-74fbe49e1757", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "file_extensions = set([file.split(\".\")[-1] for file in files if os.path.isfile(file)])" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "0b952322-dfae-4f81-90fd-75dd5155547a", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'csv',\n", - " 'docx',\n", - " 'gdoc',\n", - " 'gif',\n", - " 'gsheet',\n", - " 'gslides',\n", - " 'io/Shared drives/Academy/Courses/Climate/Climatematch/02-Curriculum/Climatematch Content Folder/W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) /W2D3 Tutorials/day8_tutorial5_sentiment_analysis_FILES NEEDED/stored_tweets',\n", - " 'ipynb',\n", - " 'jl',\n", - " 'lpd',\n", - " 'mkv',\n", - " 'mp4',\n", - " 'nc',\n", - " 'npz',\n", - " 'pdf',\n", - " 'png',\n", - " 'pptx',\n", - " 'py',\n", - " 'pyc',\n", - " 'txt',\n", - " 'vtt',\n", - " 'xlsx',\n", - " 'zip'}" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "file_extensions" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "d92f404e-9ee8-4004-805c-bf1882138535", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "\u001b[0;31mSignature:\u001b[0m \u001b[0mshutil\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy2\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msrc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdst\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfollow_symlinks\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mDocstring:\u001b[0m\n", - "Copy data and metadata. Return the file's destination.\n", - "\n", - "Metadata is copied with copystat(). Please see the copystat function\n", - "for more information.\n", - "\n", - "The destination may be a directory.\n", - "\n", - "If follow_symlinks is false, symlinks won't be followed. This\n", - "resembles GNU's \"cp -P src dst\".\n", - "\u001b[0;31mFile:\u001b[0m ~/miniconda3/envs/rms-3.10/lib/python3.10/shutil.py\n", - "\u001b[0;31mType:\u001b[0m function\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "shutil.copy2?" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "c54db2de-8571-42e4-9842-eedb854eac74", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "W1D5 - Climate Modeling\n", - "W1D3 - Remote Sensing (Land, Ocean and Atmosphere) \n", - "W1D1 - Climate System Overview\n", - "W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) \n", - "W2D2 - Projects Day \n", - "W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) \n", - "W2D1 - Future Climate - IPCC I (Physical Basis) \n", - "W2D5 - Climate Response - Adaptation Impact \n", - "W1D4 - Paleoclimate\n", - "W2D4 - Climate Response - Extremes & Variability\n" - ] - } - ], - "source": [ - "gdrive_notebooks_path = os.environ[\"GDRIVE_NOTEBOOKS\"]\n", - "\n", - "\n", - "bad_folders = []\n", - "bad_files = []\n", - "\n", - "for day_folder in os.listdir(gdrive_notebooks_path):\n", - " if re.match(\"^W\\dD\\d\", day_folder) is not None:\n", - " print(day_folder)\n", - " new_folder_name = day_folder.replace(\" \", \"\")\n", - " try:\n", - " os.mkdir(os.path.join(\"tutorials\", new_folder_name))\n", - " except FileExistsError:\n", - " pass\n", - " tutorials_found = False\n", - " for tutorials_folder in os.listdir(\n", - " os.path.join(gdrive_notebooks_path, day_folder)\n", - " ):\n", - " if re.match(\".*utorials\", tutorials_folder) is not None:\n", - " tutorials_found = True\n", - " for file in os.listdir(\n", - " os.path.join(gdrive_notebooks_path, day_folder, tutorials_folder)\n", - " ):\n", - " if file.endswith(\".ipynb\"):\n", - " shutil.copy2(\n", - " os.path.join(\n", - " gdrive_notebooks_path,\n", - " day_folder,\n", - " tutorials_folder,\n", - " file,\n", - " ),\n", - " os.path.join(\".\", \"tutorials\", new_folder_name, file),\n", - " )\n", - " elif os.path.isdir(\n", - " os.path.join(\n", - " gdrive_notebooks_path, day_folder, tutorials_folder, file\n", - " )\n", - " ):\n", - " bad_folders.append((tutorials_folder, file))\n", - " continue\n", - " else:\n", - " bad_files.append((tutorials_folder, file))\n", - "\n", - " if not tutorials_found:\n", - " raise ValueError(f\"Missing tutorials {folder}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 102, - "id": "a5f55292-3606-4e6a-a517-1b82528ba062", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "def handle_w1d1(day_folder, new_folder):\n", - " folder_to_copy = os.path.join(\n", - " gdrive_notebooks_path, day_folder, \"W1D1 Tutorials\", \"Tutorials for Pre-Pod\"\n", - " )\n", - " for file in os.listdir(folder_to_copy):\n", - " new_file_name = file.replace(\" \", \"\")\n", - " new_file_name = new_file_name[:4] + \"_\" + new_file_name[4:]\n", - " shutil.copy2(\n", - " os.path.join(folder_to_copy, file),\n", - " os.path.join(\"tutorials\", new_folder, new_file_name),\n", - " )\n", - "\n", - "\n", - "def handle_w1d2(day_folder, new_folder):\n", - " pass\n", - "\n", - "\n", - "def handle_w1d3(day_folder, new_folder):\n", - " folder_to_copy = os.path.join(gdrive_notebooks_path, day_folder, \"W1D3 Tutorials\")\n", - " for file in os.listdir(folder_to_copy):\n", - " if file.endswith(\".ipynb\"):\n", - " new_file_name = \"W1D3_\" + file.replace(\"_\", \"\").replace(\"W1D3\", \"\")\n", - " shutil.copy2(\n", - " os.path.join(folder_to_copy, file),\n", - " os.path.join(\"tutorials\", new_folder, new_file_name),\n", - " )\n", - " elif file == \"asset\":\n", - " pass\n", - "\n", - "\n", - "def handle_w1d4(day_folder, new_folder):\n", - " folder_to_copy = os.path.join(gdrive_notebooks_path, day_folder, \"W1D4 Tutorials\")\n", - " for file in os.listdir(folder_to_copy):\n", - " if file.endswith(\".ipynb\"):\n", - " new_file_name = (\n", - " \"W1D4_\" + file[: file.find(\"(\") - 1].replace(\" #\", \"\") + \".ipynb\"\n", - " )\n", - " shutil.copy2(\n", - " os.path.join(folder_to_copy, file),\n", - " os.path.join(\"tutorials\", new_folder, new_file_name),\n", - " )\n", - " elif file == \"data\":\n", - " pass\n", - "\n", - "\n", - "def handle_w2d3(day_folder, new_folder):\n", - " \"feasible\"\n", - " pass" - ] - }, - { - "cell_type": "code", - "execution_count": 109, - "id": "3e557f00-496e-4117-b9dc-c74b8e5e9f84", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "for day_folder in os.listdir(gdrive_notebooks_path):\n", - " if re.match(\"^W\\dD\\d\", day_folder) is not None:\n", - " new_folder_name = day_folder.replace(\" \", \"\").replace(\"(\", \"\").replace(\")\", \"\")\n", - " new_folder_name = new_folder_name[:4] + \"_\" + new_folder_name[5:]\n", - " try:\n", - " os.mkdir(os.path.join(\"tutorials\", new_folder_name))\n", - " except FileExistsError:\n", - " pass\n", - " Path(f\"tutorials/{new_folder_name}/further_reading.md\").touch()\n", - " if day_folder.startswith(\"W1D1\"):\n", - " handle_w1d1(day_folder, new_folder_name)\n", - " elif day_folder.startswith(\"W1D2\"):\n", - " handle_w1d2(day_folder, new_folder_name)\n", - " elif day_folder.startswith(\"W1D3\"):\n", - " handle_w1d3(day_folder, new_folder_name)\n", - " elif day_folder.startswith(\"W1D4\"):\n", - " handle_w1d4(day_folder, new_folder_name)" - ] - }, - { - "cell_type": "code", - "execution_count": 97, - "id": "f76d8e4d-52c2-4007-877f-eb3463a8bb7e", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'W2D4_ClimateResponse-Extremes&Variability'" - ] - }, - "execution_count": 97, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "new_folder_name[:4] + \"_\" + new_folder_name[5:]" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "b8a2c02a-cbe4-41c1-bafe-a0c20912b7d2", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'www('" - ] - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\"www(\"[:4]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1212b7c1-1bb5-41a0-952a-ba95bd90c0f0", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "25e15b91-7cd9-46b7-92be-300a5fd4010a", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import re\n", - "\n", - "re.match(\"W\\dD\\d\", \"W1D1\")" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "9c129676-369e-485f-9cec-2e7c38032f24", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "file_extensions_to_keep = set({\"py\", \"ipynb\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "42eca46c-ac3c-46e5-bc4c-b84e4adb8dfa", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "tutorials/Notebook Template.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_6_W1D3.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_3_W1D3.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_4_W1D3.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_1_W1D3.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_2_W1D3.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_7_W1D3.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_8_W1D3.ipynb\n", - "tutorials/W1D3 - Remote Sensing (Land, Ocean and Atmosphere) /W1D3 Tutorials/Tutorial_5_W1D3.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/W1D1 Tutorials 1-3-reviewed.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/W1D1_Tutorials_4_9-reviewed.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/computation-masking.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/xarray-intro.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/OLD VERSIONS/W1D1 Tutorials 1-3.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/OLD VERSIONS/W1D1 Tutorials 4-9.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/OLD VERSIONS/Untitled0.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/OLD VERSIONS/OLD VERSION - W1D4 All Tutorials.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/OLD VERSIONS/OLD VERSION - Tutorial #5 (W1D1).ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 9.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 8.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 4.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 6.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 2.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 7.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 5.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 1.ipynb\n", - "tutorials/W1D1 - Climate System Overview/W1D1 Tutorials/Tutorials for Pre-Pod/W1D1 Tutorial 3.ipynb\n", - "tutorials/W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) /W2D3 Tutorials/day8_tutorial5_sentiment_analysis_FILES NEEDED/day8_tutorial5_sentiment_analysis-REVIEWed.ipynb\n", - "tutorials/W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) /W2D3 Tutorials/day8_tutorial5_sentiment_analysis_FILES NEEDED/day8_tutorial5_sentiment_analysis.ipynb\n", - "tutorials/W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) /W2D3 Tutorials/day8_tutorial3_IAMs/tutorial3_IAMs - REVIEWED.ipynb\n", - "tutorials/W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) /W2D3 Tutorials/day8_tutorial3_IAMs/tutorial3_IAMs.ipynb\n", - "tutorials/W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) /W2D3 Tutorials/waste/tutorial_1_limits_of_growth - REVIEWED.ipynb\n", - "tutorials/W2D3 - Future Climate - IPCC II & III (Socio-Economic Basis) /W2D3 Tutorials/day8_tutorial1_limits_to_growth/tutorial_1_limits_of_growth.ipynb\n", - "tutorials/W2D2 - Projects Day /Good Research Practices 1-4.ipynb\n", - "tutorials/W2D2 - Projects Day /Good Research Practices 5-8.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Tutorial6_new.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Tutorial #1 (W1D2).ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Tutorial7_new.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Process_Data_tut7.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Tutorial 4 global_winds.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Tutorial_1_enso-xarray-reviewed.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Tutorial_1_enso-xarray.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Process_Data_tut6.ipynb\n", - "tutorials/W1D2 - State of the Climate (Ocean and Atmosphere Reanalysis) /W1D2 Tutorials /Tutorial 3 - ERA5 Intro (2).ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/OLD_copy of W2D1_Tutorial_Draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/W2D1_Tutorial_Draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/OLD_IPCC_Future_Climate_Tutorials_draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/W2D1_Tutorial_Draft - Ohad messing about.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Tutorials for Pre-Pod (Sloane)/Copy of Copy of W2D1_Tutorial_Draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Tutorials for Pre-Pod (Sloane)/Copy of Copy of Copy of Copy of Copy of Copy of W2D1_Tutorial_Draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Tutorials for Pre-Pod (Sloane)/Copy of Copy of Copy of W2D1_Tutorial_Draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Tutorials for Pre-Pod (Sloane)/Copy of Copy of Copy of Copy of W2D1_Tutorial_Draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Tutorials for Pre-Pod (Sloane)/Copy of Copy of Copy of Copy of Copy of W2D1_Tutorial_Draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Tutorials for Pre-Pod (Sloane)/W2D1 Tutorial 1.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Testing/W2D1_Tutorials_draft.ipynb\n", - "tutorials/W2D1 - Future Climate - IPCC I (Physical Basis) /W2D1 Tutorials/Code_for_Patrick/Notebook_for_Project_Patrick.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 3 - Dengue Fever Data Set - reviewed.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 4 - Dengue Fever Regression.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 3 - Dengue Fever Data Set.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 4 - Dengue Fever Regression - reviewer.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 7 - Logistic Regression on Crops Data.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 6 - Remote sensing crops dataset - reviewer.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 1 - Linear Regression.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 5 - Decision Trees - reviewer.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 2 - Logistic Regression.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 7 - Logistic Regression on Crops Data - reviewer.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 6 - Remote Sensing Crops Dataset.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 8 - Artificial Neural Networks on Crops Data - reviewer.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 9 - Identifying Applications - reviewer.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 9 - Identifying Applications.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 8 - Artificial Neural Networks on Crops Data.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/W2D5 Tutorial 5 - Decision Trees on Dengue data.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/old_versions_dont_use/W2D5 Tutorial 4 - Dengue Fever Regression.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/old_versions_dont_use/W2D5 Tutorial 3 - Dengue Fever Data Set.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/old_versions_dont_use/W2D5 Tutorial 1 - Linear Regression.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/old_versions_dont_use/W2D5 Tutorial 1 - Linear Regression-Reviewed.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/old_versions_dont_use/W2D5 Tutorial 2 - Logistic Regression.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/old_versions_dont_use/W2D5 Tutorial 5 - Decision Trees.ipynb\n", - "tutorials/W2D5 - Climate Response - Adaptation Impact /W2D5 Tutorials/old_versions_dont_use/W2D5 Tutorial 6 - Remote sensing crops dataset.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #7 (W1D4)-Sloane-Revisions.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #5 (W1D4)-reviewed.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #8 (W1D4)-reviewed.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #1 (W1D4) - WORKING.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #9 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #6 (W1D4)-reviewed.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #3 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #4 (W1D4)-reviewed.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Tutorial #2 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Copy of Tutorial #3 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial_2_(W1D4) - Reviewed.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #1 (W1D4)-reviewed.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #6 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #7 (W1D4)-reviewed (1).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #7 (W1D4)-reviewed.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Copy of Tutorial #8 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Copy of Tutorial #2 TEST.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #8 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Old Tutorial 1.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #2 TEST.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial 9 Extra Cells.ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #8 (W1D4) (1).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #4 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Copy of Tutorial #1 (W1D4).ipynb\n", - "tutorials/W1D4 - Paleoclimate/W1D4 Tutorials/Old Versions/Tutorial #5 (W1D4).ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_8.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_1_Review.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_2-Review.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_1.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_3-reviewed.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_3.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/extremes_functions.py\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_7.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_5.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_2.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_6-reviewed.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_4.ipynb\n", - "tutorials/W2D4 - Climate Response - Extremes & Variability/W2D4 Tutorials/tutorial_6.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/blackbody_curves.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/W1D5_Tutorial_5.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/W1D5_Tutorial_3.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/W1D5_Tutorial_1.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/W1D5_Tutorial_6.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/W1D5_Tutorial_4.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/W1D5_Tutorial_2.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/waste/Old Copy of Not_Ready_Tutorial #3.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/waste/Untitled0.ipynb\n", - "tutorials/W1D5-Climate Modeling/W1D5 Tutorials/waste/Copy of Not_Ready_Tutorial # 6.ipynb\n" - ] - } - ], - "source": [ - "for file in files:\n", - " if file.split(\".\")[-1] in file_extensions_to_keep:\n", - " relative_path = Path(file).relative_to(Path(os.environ[\"GDRIVE_NOTEBOOKS\"]))\n", - " print(os.path.join(\"tutorials\", relative_path))" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "bcc2eeca-1469-4063-8216-60a7057274c4", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "acd11c5b-fb78-4323-8520-d1fba5edfd20", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "PosixPath('Notebook Template.ipynb')" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "Path(file).relative_to(Path(os.environ[\"GDRIVE_NOTEBOOKS\"]))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "ca65c97c-583e-42ff-9101-14406a961ad3", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'/Users/wesleybanfield/Library/CloudStorage/GoogleDrive-wesley.banfield@climatematch.io/Shared drives/Academy/Courses/Climate/Climatematch/02-Curriculum/Climatematch Content Folder'" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "os.path.commonpath((os.environ[\"GDRIVE_NOTEBOOKS\"], file))" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "936f5804-93c4-49df-adb9-d5c3a691ca4d", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'/Users/wesleybanfield/Library/CloudStorage/GoogleDrive-wesley.banfield@climatematch.io/Shared drives/Academy/Courses/Climate/Climatematch/02-Curriculum/Climatematch Content Folder'" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "os.environ[\"GDRIVE_NOTEBOOKS\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e59aa70c-183e-4513-a770-a35eb6523ff7", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "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.10.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/README.md b/README.md index 7270dd6a5..8ef1c6e6c 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # ClimateMatch Academy (CMA) Computational Climate Science syllabus -*July 11-29, 2023* +*July 15-26, 2024* Please check out [expected prerequisites here](https://github.com/NeuromatchAcademy/precourse/blob/main/prereqs/ComputationalNeuroscience.md)! -**The content should primarily be accessed from our ebook: https://compclimate.neuromatch.io/ [under continuous development]** +**The content should primarily be accessed from our ebook: https://comptools.climatematch.io [under continuous development]** -**Schedule for 2023: https://github.com/NeuromatchAcademy/course-climatema/blob/main/tutorials/Schedule/daily_schedules.md** +**Schedule for 2024: https://github.com/neuromatch/climate-course-content/blob/main/tutorials/Schedule/daily_schedules.md and https://comptools.climatematch.io/tutorials/Schedule/daily_schedules.html** --- diff --git a/book/_build/html/.buildinfo b/book/_build/html/.buildinfo deleted file mode 100644 index 0392820c4..000000000 --- a/book/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 9c4e528cd29de93456e754feafd9cc1a -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/book/_build/html/_images/03ad33868ef3228d232eaa6911a6377ee4a3b25f268dc8c562b3bb3c377fe17d.png b/book/_build/html/_images/03ad33868ef3228d232eaa6911a6377ee4a3b25f268dc8c562b3bb3c377fe17d.png deleted file mode 100644 index e33340e05..000000000 Binary files a/book/_build/html/_images/03ad33868ef3228d232eaa6911a6377ee4a3b25f268dc8c562b3bb3c377fe17d.png and /dev/null differ diff --git a/book/_build/html/_images/0625e346565833288d173c5d356f8fe736cf6f11ee8f2d22dfd533daea8e149d.png b/book/_build/html/_images/0625e346565833288d173c5d356f8fe736cf6f11ee8f2d22dfd533daea8e149d.png deleted file mode 100644 index 0295602ce..000000000 Binary files a/book/_build/html/_images/0625e346565833288d173c5d356f8fe736cf6f11ee8f2d22dfd533daea8e149d.png and /dev/null differ diff --git a/book/_build/html/_images/17ffb4fa320b0d314c107156dd556762d6cbf9880999fe36d34766ec680b0608.png b/book/_build/html/_images/17ffb4fa320b0d314c107156dd556762d6cbf9880999fe36d34766ec680b0608.png deleted file mode 100644 index 33b0afa25..000000000 Binary files a/book/_build/html/_images/17ffb4fa320b0d314c107156dd556762d6cbf9880999fe36d34766ec680b0608.png and /dev/null differ diff --git a/book/_build/html/_images/18d06b1d45b118b7aa862a27522c4d13d53241791a4fd568bc18ee394b1ab84e.png b/book/_build/html/_images/18d06b1d45b118b7aa862a27522c4d13d53241791a4fd568bc18ee394b1ab84e.png deleted file mode 100644 index ed6c63ca5..000000000 Binary files a/book/_build/html/_images/18d06b1d45b118b7aa862a27522c4d13d53241791a4fd568bc18ee394b1ab84e.png and /dev/null differ diff --git a/book/_build/html/_images/19e6459bf0db8f6a316360d9c498ca691a4b3be3aeba83573aad987ad3670ef0.png b/book/_build/html/_images/19e6459bf0db8f6a316360d9c498ca691a4b3be3aeba83573aad987ad3670ef0.png deleted file mode 100644 index 6f48eea25..000000000 Binary files a/book/_build/html/_images/19e6459bf0db8f6a316360d9c498ca691a4b3be3aeba83573aad987ad3670ef0.png and /dev/null differ diff --git a/book/_build/html/_images/2bc3c4e84f3e58c49077ac2ea8af56698cdd381929f3bd12275bca5c8adb9e1d.png b/book/_build/html/_images/2bc3c4e84f3e58c49077ac2ea8af56698cdd381929f3bd12275bca5c8adb9e1d.png deleted file mode 100644 index c2d9756c5..000000000 Binary files a/book/_build/html/_images/2bc3c4e84f3e58c49077ac2ea8af56698cdd381929f3bd12275bca5c8adb9e1d.png and /dev/null differ diff --git a/book/_build/html/_images/38ddd01ce5ef822d002a6cdba129ad78a3a8a9f25fcf5e33a67d9c2541890ecf.png b/book/_build/html/_images/38ddd01ce5ef822d002a6cdba129ad78a3a8a9f25fcf5e33a67d9c2541890ecf.png deleted file mode 100644 index 8e3ff83a2..000000000 Binary files a/book/_build/html/_images/38ddd01ce5ef822d002a6cdba129ad78a3a8a9f25fcf5e33a67d9c2541890ecf.png and /dev/null differ diff --git a/book/_build/html/_images/39ffd1b6c75b29f52a65766c91ffa62a5d5897dffb1c1148f91ec2ad0f9a6561.png b/book/_build/html/_images/39ffd1b6c75b29f52a65766c91ffa62a5d5897dffb1c1148f91ec2ad0f9a6561.png deleted file mode 100644 index ae763073b..000000000 Binary files a/book/_build/html/_images/39ffd1b6c75b29f52a65766c91ffa62a5d5897dffb1c1148f91ec2ad0f9a6561.png and /dev/null differ diff --git a/book/_build/html/_images/434da9b63d15efbbb137d0ca7d88a406e3d42a6faaeb6aeca695fc939d5ccf73.png b/book/_build/html/_images/434da9b63d15efbbb137d0ca7d88a406e3d42a6faaeb6aeca695fc939d5ccf73.png deleted file mode 100644 index 6fe757500..000000000 Binary files a/book/_build/html/_images/434da9b63d15efbbb137d0ca7d88a406e3d42a6faaeb6aeca695fc939d5ccf73.png and /dev/null differ diff --git a/book/_build/html/_images/4666ba79386ae77c963620b7cb94ca8dd5335854f4ab40881f929bf84da0a8fe.png b/book/_build/html/_images/4666ba79386ae77c963620b7cb94ca8dd5335854f4ab40881f929bf84da0a8fe.png deleted file mode 100644 index 3fbbdb40f..000000000 Binary files a/book/_build/html/_images/4666ba79386ae77c963620b7cb94ca8dd5335854f4ab40881f929bf84da0a8fe.png and /dev/null differ diff --git a/book/_build/html/_images/4be4b8a1bc9e84c913f9f955b9bdff53ff5d816a8edd5a277306804e5a545cbc.png b/book/_build/html/_images/4be4b8a1bc9e84c913f9f955b9bdff53ff5d816a8edd5a277306804e5a545cbc.png deleted file mode 100644 index c7b068be8..000000000 Binary files a/book/_build/html/_images/4be4b8a1bc9e84c913f9f955b9bdff53ff5d816a8edd5a277306804e5a545cbc.png and /dev/null differ diff --git a/book/_build/html/_images/4d076215be9f9456505de5714cd88911873814d882326c14ffb7bfd7e3cf6faf.png b/book/_build/html/_images/4d076215be9f9456505de5714cd88911873814d882326c14ffb7bfd7e3cf6faf.png deleted file mode 100644 index 0f63f22d2..000000000 Binary files a/book/_build/html/_images/4d076215be9f9456505de5714cd88911873814d882326c14ffb7bfd7e3cf6faf.png and /dev/null differ diff --git a/book/_build/html/_images/4ee7623b574e7f8fff035732b650facbe58e747f9f1ab071eadc7f64ae9e0843.png b/book/_build/html/_images/4ee7623b574e7f8fff035732b650facbe58e747f9f1ab071eadc7f64ae9e0843.png deleted file mode 100644 index 555e5082b..000000000 Binary files a/book/_build/html/_images/4ee7623b574e7f8fff035732b650facbe58e747f9f1ab071eadc7f64ae9e0843.png and /dev/null differ diff --git a/book/_build/html/_images/592c9d283ed2676eb88bfaab84125f9fe32d49e06c01b343ab9a03483ad419a1.png b/book/_build/html/_images/592c9d283ed2676eb88bfaab84125f9fe32d49e06c01b343ab9a03483ad419a1.png deleted file mode 100644 index 489c03994..000000000 Binary files a/book/_build/html/_images/592c9d283ed2676eb88bfaab84125f9fe32d49e06c01b343ab9a03483ad419a1.png and /dev/null differ diff --git a/book/_build/html/_images/5ae970affeeb315a630531e71190da5fab24f4888a5baf380be63956c0ac655d.png b/book/_build/html/_images/5ae970affeeb315a630531e71190da5fab24f4888a5baf380be63956c0ac655d.png deleted file mode 100644 index ee0bbc332..000000000 Binary files a/book/_build/html/_images/5ae970affeeb315a630531e71190da5fab24f4888a5baf380be63956c0ac655d.png and /dev/null differ diff --git a/book/_build/html/_images/79282f37fd4fc31ca734769fdda3e6bfa23aee996106f42d7b17e28b29a19a7a.png b/book/_build/html/_images/79282f37fd4fc31ca734769fdda3e6bfa23aee996106f42d7b17e28b29a19a7a.png deleted file mode 100644 index 939db9f53..000000000 Binary files a/book/_build/html/_images/79282f37fd4fc31ca734769fdda3e6bfa23aee996106f42d7b17e28b29a19a7a.png and /dev/null differ diff --git a/book/_build/html/_images/86599188d06be4a355ff93f111ee83265a83e559eb4bef3e60e4db7cd0cac2ba.png b/book/_build/html/_images/86599188d06be4a355ff93f111ee83265a83e559eb4bef3e60e4db7cd0cac2ba.png deleted file mode 100644 index 22c0abeb9..000000000 Binary files a/book/_build/html/_images/86599188d06be4a355ff93f111ee83265a83e559eb4bef3e60e4db7cd0cac2ba.png and /dev/null differ diff --git a/book/_build/html/_images/86b67c87ed5b1c43d92368dd9bf35d01e839b99e863ca049b75bb4029bc2aff4.png b/book/_build/html/_images/86b67c87ed5b1c43d92368dd9bf35d01e839b99e863ca049b75bb4029bc2aff4.png deleted file mode 100644 index c2a759bf2..000000000 Binary files a/book/_build/html/_images/86b67c87ed5b1c43d92368dd9bf35d01e839b99e863ca049b75bb4029bc2aff4.png and /dev/null differ diff --git a/book/_build/html/_images/8f43c02f87bde0c5c5c4d604bca5bd5880ad154da62a634d208a9a3fbcf8ae7f.png b/book/_build/html/_images/8f43c02f87bde0c5c5c4d604bca5bd5880ad154da62a634d208a9a3fbcf8ae7f.png deleted file mode 100644 index b7541bf15..000000000 Binary files a/book/_build/html/_images/8f43c02f87bde0c5c5c4d604bca5bd5880ad154da62a634d208a9a3fbcf8ae7f.png and /dev/null differ diff --git a/book/_build/html/_images/93b2007cb4b9715143a5bf905a3827a9232cee46c470dd9074e2f72a16c35f61.png b/book/_build/html/_images/93b2007cb4b9715143a5bf905a3827a9232cee46c470dd9074e2f72a16c35f61.png deleted file mode 100644 index d8031db74..000000000 Binary files a/book/_build/html/_images/93b2007cb4b9715143a5bf905a3827a9232cee46c470dd9074e2f72a16c35f61.png and /dev/null differ diff --git a/book/_build/html/_images/9ff326100fa0045b5fe921217ff18627c22bdb5b05afb64771ae8d1c4ee0d6b0.png b/book/_build/html/_images/9ff326100fa0045b5fe921217ff18627c22bdb5b05afb64771ae8d1c4ee0d6b0.png deleted file mode 100644 index bf82678bf..000000000 Binary files a/book/_build/html/_images/9ff326100fa0045b5fe921217ff18627c22bdb5b05afb64771ae8d1c4ee0d6b0.png and /dev/null differ diff --git a/book/_build/html/_images/CMA_Concept_Map.png b/book/_build/html/_images/CMA_Concept_Map.png deleted file mode 100644 index f15e838c5..000000000 Binary files a/book/_build/html/_images/CMA_Concept_Map.png and /dev/null differ diff --git a/book/_build/html/_images/ENSO_impact_on_precipitation_and_temperature_14_1.png b/book/_build/html/_images/ENSO_impact_on_precipitation_and_temperature_14_1.png deleted file mode 100644 index 98b254c35..000000000 Binary files a/book/_build/html/_images/ENSO_impact_on_precipitation_and_temperature_14_1.png and /dev/null differ diff --git a/book/_build/html/_images/ENSO_impact_on_precipitation_and_temperature_15_1.png b/book/_build/html/_images/ENSO_impact_on_precipitation_and_temperature_15_1.png deleted file mode 100644 index dbc712710..000000000 Binary files a/book/_build/html/_images/ENSO_impact_on_precipitation_and_temperature_15_1.png and /dev/null differ diff --git a/book/_build/html/_images/Heatwaves_14_1.png b/book/_build/html/_images/Heatwaves_14_1.png deleted file mode 100644 index 8c3ef9e24..000000000 Binary files a/book/_build/html/_images/Heatwaves_14_1.png and /dev/null differ diff --git a/book/_build/html/_images/Sea_level_rise_8_1.png b/book/_build/html/_images/Sea_level_rise_8_1.png deleted file mode 100644 index 4c1c3f168..000000000 Binary files a/book/_build/html/_images/Sea_level_rise_8_1.png and /dev/null differ diff --git a/book/_build/html/_images/Sea_level_rise_9_1.png b/book/_build/html/_images/Sea_level_rise_9_1.png deleted file mode 100644 index 27c104877..000000000 Binary files a/book/_build/html/_images/Sea_level_rise_9_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_ClimateSystemOverview-Sloane_Garelick.svg b/book/_build/html/_images/W1D1_ClimateSystemOverview-Sloane_Garelick.svg deleted file mode 100644 index 5ea641155..000000000 --- a/book/_build/html/_images/W1D1_ClimateSystemOverview-Sloane_Garelick.svg +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/book/_build/html/_images/W1D1_Tutorial3_33_1.png b/book/_build/html/_images/W1D1_Tutorial3_33_1.png deleted file mode 100644 index bacda8f2c..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial3_33_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial3_36_1.png b/book/_build/html/_images/W1D1_Tutorial3_36_1.png deleted file mode 100644 index 457865332..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial3_36_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial3_41_1.png b/book/_build/html/_images/W1D1_Tutorial3_41_1.png deleted file mode 100644 index e45d15290..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial3_41_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial4_31_0.png b/book/_build/html/_images/W1D1_Tutorial4_31_0.png deleted file mode 100644 index a7406e346..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial4_31_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial5_17_0.png b/book/_build/html/_images/W1D1_Tutorial5_17_0.png deleted file mode 100644 index 5415464c2..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial5_17_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial5_27_0.png b/book/_build/html/_images/W1D1_Tutorial5_27_0.png deleted file mode 100644 index a47943b50..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial5_27_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial5_33_0.png b/book/_build/html/_images/W1D1_Tutorial5_33_0.png deleted file mode 100644 index ecdc2d382..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial5_33_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial5_35_0.png b/book/_build/html/_images/W1D1_Tutorial5_35_0.png deleted file mode 100644 index 8838803b1..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial5_35_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial6_18_1.png b/book/_build/html/_images/W1D1_Tutorial6_18_1.png deleted file mode 100644 index 1da728982..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial6_18_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial6_20_1.png b/book/_build/html/_images/W1D1_Tutorial6_20_1.png deleted file mode 100644 index 0d6d105c2..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial6_20_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial6_27_1.png b/book/_build/html/_images/W1D1_Tutorial6_27_1.png deleted file mode 100644 index 2ffcf170b..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial6_27_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial7_17_1.png b/book/_build/html/_images/W1D1_Tutorial7_17_1.png deleted file mode 100644 index 0efa1a878..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial7_17_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial7_20_1.png b/book/_build/html/_images/W1D1_Tutorial7_20_1.png deleted file mode 100644 index 2cd6b7491..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial7_20_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial7_23_1.png b/book/_build/html/_images/W1D1_Tutorial7_23_1.png deleted file mode 100644 index d67c44dc0..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial7_23_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial7_26_0.png b/book/_build/html/_images/W1D1_Tutorial7_26_0.png deleted file mode 100644 index f75989d0d..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial7_26_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial8_23_0.png b/book/_build/html/_images/W1D1_Tutorial8_23_0.png deleted file mode 100644 index 46d2322a0..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial8_23_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial8_25_1.png b/book/_build/html/_images/W1D1_Tutorial8_25_1.png deleted file mode 100644 index 08ea754ce..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial8_25_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial9_17_0.png b/book/_build/html/_images/W1D1_Tutorial9_17_0.png deleted file mode 100644 index 56910a23a..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial9_17_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial9_20_0.png b/book/_build/html/_images/W1D1_Tutorial9_20_0.png deleted file mode 100644 index 8a41dce45..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial9_20_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial9_23_0.png b/book/_build/html/_images/W1D1_Tutorial9_23_0.png deleted file mode 100644 index a155686c5..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial9_23_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D1_Tutorial9_26_1.png b/book/_build/html/_images/W1D1_Tutorial9_26_1.png deleted file mode 100644 index 97229670f..000000000 Binary files a/book/_build/html/_images/W1D1_Tutorial9_26_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_OceanAtmosphereReanalysis-Sloane_Garelick.svg b/book/_build/html/_images/W1D2_OceanAtmosphereReanalysis-Sloane_Garelick.svg deleted file mode 100644 index 157653fe3..000000000 --- a/book/_build/html/_images/W1D2_OceanAtmosphereReanalysis-Sloane_Garelick.svg +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/book/_build/html/_images/W1D2_Tutorial1_25_1.png b/book/_build/html/_images/W1D2_Tutorial1_25_1.png deleted file mode 100644 index e6a80bda2..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial1_25_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial1_38_0.png b/book/_build/html/_images/W1D2_Tutorial1_38_0.png deleted file mode 100644 index ee9cb1337..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial1_38_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial1_44_1.png b/book/_build/html/_images/W1D2_Tutorial1_44_1.png deleted file mode 100644 index 7214db7bd..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial1_44_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial1_47_1.png b/book/_build/html/_images/W1D2_Tutorial1_47_1.png deleted file mode 100644 index 13cdb6332..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial1_47_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial4_33_1.png b/book/_build/html/_images/W1D2_Tutorial4_33_1.png deleted file mode 100644 index 841db4052..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial4_33_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial4_39_1.png b/book/_build/html/_images/W1D2_Tutorial4_39_1.png deleted file mode 100644 index e65e57c53..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial4_39_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial5_22_0.png b/book/_build/html/_images/W1D2_Tutorial5_22_0.png deleted file mode 100644 index 0af0f258a..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial5_22_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial5_23_0.png b/book/_build/html/_images/W1D2_Tutorial5_23_0.png deleted file mode 100644 index 3133d29ca..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial5_23_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial5_27_0.png b/book/_build/html/_images/W1D2_Tutorial5_27_0.png deleted file mode 100644 index 87f16d3e6..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial5_27_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial5_30_1.png b/book/_build/html/_images/W1D2_Tutorial5_30_1.png deleted file mode 100644 index d999d7bee..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial5_30_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D2_Tutorial5_31_1.png b/book/_build/html/_images/W1D2_Tutorial5_31_1.png deleted file mode 100644 index d999d7bee..000000000 Binary files a/book/_build/html/_images/W1D2_Tutorial5_31_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D3_RemoteSensing-Sloane_Garelick.svg b/book/_build/html/_images/W1D3_RemoteSensing-Sloane_Garelick.svg deleted file mode 100644 index 18fbdf93f..000000000 --- a/book/_build/html/_images/W1D3_RemoteSensing-Sloane_Garelick.svg +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/book/_build/html/_images/W1D3_Tutorial7_102_1.png b/book/_build/html/_images/W1D3_Tutorial7_102_1.png deleted file mode 100644 index 2b013c9ea..000000000 Binary files a/book/_build/html/_images/W1D3_Tutorial7_102_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D3_Tutorial7_104_0.png b/book/_build/html/_images/W1D3_Tutorial7_104_0.png deleted file mode 100644 index 91eaab137..000000000 Binary files a/book/_build/html/_images/W1D3_Tutorial7_104_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D3_Tutorial7_109_1.png b/book/_build/html/_images/W1D3_Tutorial7_109_1.png deleted file mode 100644 index d77615e90..000000000 Binary files a/book/_build/html/_images/W1D3_Tutorial7_109_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D3_Tutorial7_111_1.png b/book/_build/html/_images/W1D3_Tutorial7_111_1.png deleted file mode 100644 index 75634da45..000000000 Binary files a/book/_build/html/_images/W1D3_Tutorial7_111_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D3_Tutorial7_98_1.png b/book/_build/html/_images/W1D3_Tutorial7_98_1.png deleted file mode 100644 index dbf7fe241..000000000 Binary files a/book/_build/html/_images/W1D3_Tutorial7_98_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Paleoclimate-Sloane_Garelick.svg b/book/_build/html/_images/W1D4_Paleoclimate-Sloane_Garelick.svg deleted file mode 100644 index 0eb08664b..000000000 --- a/book/_build/html/_images/W1D4_Paleoclimate-Sloane_Garelick.svg +++ /dev/null @@ -1,302 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/book/_build/html/_images/W1D4_Tutorial2_19_0.png b/book/_build/html/_images/W1D4_Tutorial2_19_0.png deleted file mode 100644 index 617d615a6..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial2_19_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial3_35_1.png b/book/_build/html/_images/W1D4_Tutorial3_35_1.png deleted file mode 100644 index 084158d2c..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial3_35_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial4_22_1.png b/book/_build/html/_images/W1D4_Tutorial4_22_1.png deleted file mode 100644 index a210cd925..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial4_22_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial4_28_1.png b/book/_build/html/_images/W1D4_Tutorial4_28_1.png deleted file mode 100644 index 4e1435ccf..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial4_28_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial4_30_1.png b/book/_build/html/_images/W1D4_Tutorial4_30_1.png deleted file mode 100644 index c4e65fa4f..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial4_30_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial5_29_1.png b/book/_build/html/_images/W1D4_Tutorial5_29_1.png deleted file mode 100644 index 2bde173cf..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial5_29_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial5_34_1.png b/book/_build/html/_images/W1D4_Tutorial5_34_1.png deleted file mode 100644 index 2bde173cf..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial5_34_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial5_38_1.png b/book/_build/html/_images/W1D4_Tutorial5_38_1.png deleted file mode 100644 index 2bde173cf..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial5_38_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial5_63_1.png b/book/_build/html/_images/W1D4_Tutorial5_63_1.png deleted file mode 100644 index 1e56594b6..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial5_63_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial6_23_1.png b/book/_build/html/_images/W1D4_Tutorial6_23_1.png deleted file mode 100644 index 2bde173cf..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial6_23_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial6_28_1.png b/book/_build/html/_images/W1D4_Tutorial6_28_1.png deleted file mode 100644 index e0aff1696..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial6_28_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial6_30_1.png b/book/_build/html/_images/W1D4_Tutorial6_30_1.png deleted file mode 100644 index 5ce94f6b5..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial6_30_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial6_34_1.png b/book/_build/html/_images/W1D4_Tutorial6_34_1.png deleted file mode 100644 index 0163bbfd3..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial6_34_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial6_36_1.png b/book/_build/html/_images/W1D4_Tutorial6_36_1.png deleted file mode 100644 index 8b0160926..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial6_36_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial6_40_1.png b/book/_build/html/_images/W1D4_Tutorial6_40_1.png deleted file mode 100644 index 532c3ee5b..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial6_40_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial7_19_1.png b/book/_build/html/_images/W1D4_Tutorial7_19_1.png deleted file mode 100644 index dce2e734b..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial7_19_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial7_24_1.png b/book/_build/html/_images/W1D4_Tutorial7_24_1.png deleted file mode 100644 index 69f07867d..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial7_24_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial7_31_1.png b/book/_build/html/_images/W1D4_Tutorial7_31_1.png deleted file mode 100644 index 772308dc5..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial7_31_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial7_33_1.png b/book/_build/html/_images/W1D4_Tutorial7_33_1.png deleted file mode 100644 index b0bbd4cea..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial7_33_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial7_36_1.png b/book/_build/html/_images/W1D4_Tutorial7_36_1.png deleted file mode 100644 index cf3c1cd78..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial7_36_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial8_19_1.png b/book/_build/html/_images/W1D4_Tutorial8_19_1.png deleted file mode 100644 index 5ff199373..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial8_19_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial8_31_0.png b/book/_build/html/_images/W1D4_Tutorial8_31_0.png deleted file mode 100644 index ab2b70d77..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial8_31_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial8_35_0.png b/book/_build/html/_images/W1D4_Tutorial8_35_0.png deleted file mode 100644 index e0b66e7bf..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial8_35_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial8_40_1.png b/book/_build/html/_images/W1D4_Tutorial8_40_1.png deleted file mode 100644 index 47549cf73..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial8_40_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial9_22_0.png b/book/_build/html/_images/W1D4_Tutorial9_22_0.png deleted file mode 100644 index fe01fb8cb..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial9_22_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial9_29_0.png b/book/_build/html/_images/W1D4_Tutorial9_29_0.png deleted file mode 100644 index 6822653ba..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial9_29_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D4_Tutorial9_32_0.png b/book/_build/html/_images/W1D4_Tutorial9_32_0.png deleted file mode 100644 index b0e551170..000000000 Binary files a/book/_build/html/_images/W1D4_Tutorial9_32_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial2_55_1.png b/book/_build/html/_images/W1D5_Tutorial2_55_1.png deleted file mode 100644 index f13531697..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial2_55_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial3_47_0.png b/book/_build/html/_images/W1D5_Tutorial3_47_0.png deleted file mode 100644 index 88b2eb581..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial3_47_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial3_53_1.png b/book/_build/html/_images/W1D5_Tutorial3_53_1.png deleted file mode 100644 index 24000eef6..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial3_53_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial3_73_0.png b/book/_build/html/_images/W1D5_Tutorial3_73_0.png deleted file mode 100644 index 8bb6bbc4d..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial3_73_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial3_74_1.png b/book/_build/html/_images/W1D5_Tutorial3_74_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial3_74_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial4_32_1.png b/book/_build/html/_images/W1D5_Tutorial4_32_1.png deleted file mode 100644 index 2c219fd28..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial4_32_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial4_40_1.png b/book/_build/html/_images/W1D5_Tutorial4_40_1.png deleted file mode 100644 index e706a3e6a..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial4_40_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial4_47_0.png b/book/_build/html/_images/W1D5_Tutorial4_47_0.png deleted file mode 100644 index a88762fc7..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial4_47_0.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial4_55_1.png b/book/_build/html/_images/W1D5_Tutorial4_55_1.png deleted file mode 100644 index b57219d41..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial4_55_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial4_62_1.png b/book/_build/html/_images/W1D5_Tutorial4_62_1.png deleted file mode 100644 index a05219b35..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial4_62_1.png and /dev/null differ diff --git a/book/_build/html/_images/W1D5_Tutorial5_57_0.png b/book/_build/html/_images/W1D5_Tutorial5_57_0.png deleted file mode 100644 index baeb322c4..000000000 Binary files a/book/_build/html/_images/W1D5_Tutorial5_57_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D1_Tutorial2_37_2.png b/book/_build/html/_images/W2D1_Tutorial2_37_2.png deleted file mode 100644 index d37d29ff2..000000000 Binary files a/book/_build/html/_images/W2D1_Tutorial2_37_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D1_Tutorial3_49_2.png b/book/_build/html/_images/W2D1_Tutorial3_49_2.png deleted file mode 100644 index dd284d079..000000000 Binary files a/book/_build/html/_images/W2D1_Tutorial3_49_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D2_Projects-Sloane_Garelick.svg b/book/_build/html/_images/W2D2_Projects-Sloane_Garelick.svg deleted file mode 100644 index 3bdcc33b2..000000000 --- a/book/_build/html/_images/W2D2_Projects-Sloane_Garelick.svg +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/book/_build/html/_images/W2D2_Tutorial5_17_1.png b/book/_build/html/_images/W2D2_Tutorial5_17_1.png deleted file mode 100644 index 7fb00b55b..000000000 Binary files a/book/_build/html/_images/W2D2_Tutorial5_17_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D2_Tutorial6_7_1.png b/book/_build/html/_images/W2D2_Tutorial6_7_1.png deleted file mode 100644 index 8d1ed879f..000000000 Binary files a/book/_build/html/_images/W2D2_Tutorial6_7_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D2_Tutorial6_9_1.png b/book/_build/html/_images/W2D2_Tutorial6_9_1.png deleted file mode 100644 index 331cd2669..000000000 Binary files a/book/_build/html/_images/W2D2_Tutorial6_9_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial1_41_1.png b/book/_build/html/_images/W2D3_Tutorial1_41_1.png deleted file mode 100644 index 52721709f..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial1_41_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial1_41_3.png b/book/_build/html/_images/W2D3_Tutorial1_41_3.png deleted file mode 100644 index 52721709f..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial1_41_3.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial2_46_1.png b/book/_build/html/_images/W2D3_Tutorial2_46_1.png deleted file mode 100644 index 4f8ea2924..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial2_46_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial2_52_0.png b/book/_build/html/_images/W2D3_Tutorial2_52_0.png deleted file mode 100644 index 6eae0c17c..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial2_52_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial2_56_1.png b/book/_build/html/_images/W2D3_Tutorial2_56_1.png deleted file mode 100644 index 90ce1cf10..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial2_56_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial2_71_1.png b/book/_build/html/_images/W2D3_Tutorial2_71_1.png deleted file mode 100644 index 8e2a16655..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial2_71_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial2_73_1.png b/book/_build/html/_images/W2D3_Tutorial2_73_1.png deleted file mode 100644 index 8e2a16655..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial2_73_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial4_83_1.png b/book/_build/html/_images/W2D3_Tutorial4_83_1.png deleted file mode 100644 index 0a3060fc6..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial4_83_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D3_Tutorial4_93_1.png b/book/_build/html/_images/W2D3_Tutorial4_93_1.png deleted file mode 100644 index e54d1fd31..000000000 Binary files a/book/_build/html/_images/W2D3_Tutorial4_93_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_ExtremesVulnerability-Sloane_Garelick.svg b/book/_build/html/_images/W2D4_ExtremesVulnerability-Sloane_Garelick.svg deleted file mode 100644 index 905f46fb5..000000000 --- a/book/_build/html/_images/W2D4_ExtremesVulnerability-Sloane_Garelick.svg +++ /dev/null @@ -1,141 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/book/_build/html/_images/W2D4_Tutorial1_36_1.png b/book/_build/html/_images/W2D4_Tutorial1_36_1.png deleted file mode 100644 index 181d38a6e..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial1_36_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial1_38_1.png b/book/_build/html/_images/W2D4_Tutorial1_38_1.png deleted file mode 100644 index bfd1f1b36..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial1_38_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial1_42_1.png b/book/_build/html/_images/W2D4_Tutorial1_42_1.png deleted file mode 100644 index 3006575e5..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial1_42_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial1_48_1.png b/book/_build/html/_images/W2D4_Tutorial1_48_1.png deleted file mode 100644 index 1535cd1bc..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial1_48_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial1_53_1.png b/book/_build/html/_images/W2D4_Tutorial1_53_1.png deleted file mode 100644 index b854f1a6d..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial1_53_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial2_33_1.png b/book/_build/html/_images/W2D4_Tutorial2_33_1.png deleted file mode 100644 index 181d38a6e..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial2_33_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial2_49_1.png b/book/_build/html/_images/W2D4_Tutorial2_49_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial2_49_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial2_51_1.png b/book/_build/html/_images/W2D4_Tutorial2_51_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial2_51_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial2_55_1.png b/book/_build/html/_images/W2D4_Tutorial2_55_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial2_55_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial2_56_1.png b/book/_build/html/_images/W2D4_Tutorial2_56_1.png deleted file mode 100644 index d4edee048..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial2_56_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_32_1.png b/book/_build/html/_images/W2D4_Tutorial3_32_1.png deleted file mode 100644 index 55d05b8fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_32_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_34_0.png b/book/_build/html/_images/W2D4_Tutorial3_34_0.png deleted file mode 100644 index 4a1c174c5..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_34_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_39_1.png b/book/_build/html/_images/W2D4_Tutorial3_39_1.png deleted file mode 100644 index b1af726cb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_39_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_41_0.png b/book/_build/html/_images/W2D4_Tutorial3_41_0.png deleted file mode 100644 index 11f0bed15..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_41_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_44_1.png b/book/_build/html/_images/W2D4_Tutorial3_44_1.png deleted file mode 100644 index 85744300c..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_44_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_47_2.png b/book/_build/html/_images/W2D4_Tutorial3_47_2.png deleted file mode 100644 index 21104cc6a..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_47_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_49_2.png b/book/_build/html/_images/W2D4_Tutorial3_49_2.png deleted file mode 100644 index 21104cc6a..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_49_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial3_51_2.png b/book/_build/html/_images/W2D4_Tutorial3_51_2.png deleted file mode 100644 index 21104cc6a..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial3_51_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial4_45_0.png b/book/_build/html/_images/W2D4_Tutorial4_45_0.png deleted file mode 100644 index 5c7754efb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial4_45_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial4_48_1.png b/book/_build/html/_images/W2D4_Tutorial4_48_1.png deleted file mode 100644 index c00a734de..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial4_48_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial4_53_3.png b/book/_build/html/_images/W2D4_Tutorial4_53_3.png deleted file mode 100644 index 438ca204e..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial4_53_3.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial5_33_1.png b/book/_build/html/_images/W2D4_Tutorial5_33_1.png deleted file mode 100644 index 32ac8d0d4..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial5_33_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial5_36_1.png b/book/_build/html/_images/W2D4_Tutorial5_36_1.png deleted file mode 100644 index 3da7701d4..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial5_36_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial5_41_1.png b/book/_build/html/_images/W2D4_Tutorial5_41_1.png deleted file mode 100644 index f0a5e91c0..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial5_41_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial6_55_1.png b/book/_build/html/_images/W2D4_Tutorial6_55_1.png deleted file mode 100644 index 16084076f..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial6_55_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial6_57_2.png b/book/_build/html/_images/W2D4_Tutorial6_57_2.png deleted file mode 100644 index 869d7b5d0..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial6_57_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial6_64_1.png b/book/_build/html/_images/W2D4_Tutorial6_64_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial6_64_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial6_69_1.png b/book/_build/html/_images/W2D4_Tutorial6_69_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial6_69_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial6_73_1.png b/book/_build/html/_images/W2D4_Tutorial6_73_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial6_73_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial6_81_2.png b/book/_build/html/_images/W2D4_Tutorial6_81_2.png deleted file mode 100644 index 6ad4d9258..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial6_81_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial6_84_1.png b/book/_build/html/_images/W2D4_Tutorial6_84_1.png deleted file mode 100644 index 7bd6e62d0..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial6_84_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial7_52_2.png b/book/_build/html/_images/W2D4_Tutorial7_52_2.png deleted file mode 100644 index 3b895d2b4..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial7_52_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial8_46_1.png b/book/_build/html/_images/W2D4_Tutorial8_46_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial8_46_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial8_50_2.png b/book/_build/html/_images/W2D4_Tutorial8_50_2.png deleted file mode 100644 index 3b895d2b4..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial8_50_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial8_55_1.png b/book/_build/html/_images/W2D4_Tutorial8_55_1.png deleted file mode 100644 index 3b895d2b4..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial8_55_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial8_59_1.png b/book/_build/html/_images/W2D4_Tutorial8_59_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial8_59_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial8_65_1.png b/book/_build/html/_images/W2D4_Tutorial8_65_1.png deleted file mode 100644 index 13f0ca4fb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial8_65_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial8_87_2.png b/book/_build/html/_images/W2D4_Tutorial8_87_2.png deleted file mode 100644 index b453ae5eb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial8_87_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D4_Tutorial8_89_1.png b/book/_build/html/_images/W2D4_Tutorial8_89_1.png deleted file mode 100644 index b453ae5eb..000000000 Binary files a/book/_build/html/_images/W2D4_Tutorial8_89_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_AdaptationImpact-Sloane_Garelick.svg b/book/_build/html/_images/W2D5_AdaptationImpact-Sloane_Garelick.svg deleted file mode 100644 index 0fdf1dfaf..000000000 --- a/book/_build/html/_images/W2D5_AdaptationImpact-Sloane_Garelick.svg +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/book/_build/html/_images/W2D5_Tutorial1_38_0.png b/book/_build/html/_images/W2D5_Tutorial1_38_0.png deleted file mode 100644 index 6e457487c..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_38_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_50_1.png b/book/_build/html/_images/W2D5_Tutorial1_50_1.png deleted file mode 100644 index a6e4b6e40..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_50_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_53_1.png b/book/_build/html/_images/W2D5_Tutorial1_53_1.png deleted file mode 100644 index 9a4f5d722..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_53_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_60_1.png b/book/_build/html/_images/W2D5_Tutorial1_60_1.png deleted file mode 100644 index 1386b827c..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_60_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_64_0.png b/book/_build/html/_images/W2D5_Tutorial1_64_0.png deleted file mode 100644 index d7c3f0194..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_64_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_66_1.png b/book/_build/html/_images/W2D5_Tutorial1_66_1.png deleted file mode 100644 index 88bb13022..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_66_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_71_1.png b/book/_build/html/_images/W2D5_Tutorial1_71_1.png deleted file mode 100644 index 1f2be232d..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_71_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_76_1.png b/book/_build/html/_images/W2D5_Tutorial1_76_1.png deleted file mode 100644 index 1f2be232d..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_76_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial1_80_1.png b/book/_build/html/_images/W2D5_Tutorial1_80_1.png deleted file mode 100644 index 78a2b66f8..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial1_80_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial2_65_2.png b/book/_build/html/_images/W2D5_Tutorial2_65_2.png deleted file mode 100644 index bbac6732a..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial2_65_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial2_77_2.png b/book/_build/html/_images/W2D5_Tutorial2_77_2.png deleted file mode 100644 index a3644fead..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial2_77_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial2_82_2.png b/book/_build/html/_images/W2D5_Tutorial2_82_2.png deleted file mode 100644 index 5669a10c8..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial2_82_2.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial2_92_1.png b/book/_build/html/_images/W2D5_Tutorial2_92_1.png deleted file mode 100644 index b60fd9d98..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial2_92_1.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial3_51_0.png b/book/_build/html/_images/W2D5_Tutorial3_51_0.png deleted file mode 100644 index 29e4df011..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial3_51_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial3_58_0.png b/book/_build/html/_images/W2D5_Tutorial3_58_0.png deleted file mode 100644 index 5c10a858b..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial3_58_0.png and /dev/null differ diff --git a/book/_build/html/_images/W2D5_Tutorial3_62_0.png b/book/_build/html/_images/W2D5_Tutorial3_62_0.png deleted file mode 100644 index 91529bd78..000000000 Binary files a/book/_build/html/_images/W2D5_Tutorial3_62_0.png and /dev/null differ diff --git a/book/_build/html/_images/Wildfires_and_burnt_areas_14_1.png b/book/_build/html/_images/Wildfires_and_burnt_areas_14_1.png deleted file mode 100644 index e5bcaca8c..000000000 Binary files a/book/_build/html/_images/Wildfires_and_burnt_areas_14_1.png and /dev/null differ diff --git a/book/_build/html/_images/a7fe4d8bcff237dcbb851ca9c950c32c12d582531b9433499bdf700e25056e50.png b/book/_build/html/_images/a7fe4d8bcff237dcbb851ca9c950c32c12d582531b9433499bdf700e25056e50.png deleted file mode 100644 index ba9a90a9e..000000000 Binary files a/book/_build/html/_images/a7fe4d8bcff237dcbb851ca9c950c32c12d582531b9433499bdf700e25056e50.png and /dev/null differ diff --git a/book/_build/html/_images/ad4d321620cf6d850bf33a6d650f383beca4d8376fe5466cb0367414b7d7026c.png b/book/_build/html/_images/ad4d321620cf6d850bf33a6d650f383beca4d8376fe5466cb0367414b7d7026c.png deleted file mode 100644 index 50af3e2ef..000000000 Binary files a/book/_build/html/_images/ad4d321620cf6d850bf33a6d650f383beca4d8376fe5466cb0367414b7d7026c.png and /dev/null differ diff --git a/book/_build/html/_images/b77a79bac92db1bcc60574ba3f138e42fe82b37a5d1d1b9dce686cb4a719a052.png b/book/_build/html/_images/b77a79bac92db1bcc60574ba3f138e42fe82b37a5d1d1b9dce686cb4a719a052.png deleted file mode 100644 index ddcb32aeb..000000000 Binary files a/book/_build/html/_images/b77a79bac92db1bcc60574ba3f138e42fe82b37a5d1d1b9dce686cb4a719a052.png and /dev/null differ diff --git a/book/_build/html/_images/c32b82ecf075804565b45f8bd917f1105b8c12a75d4f81f0666645bd04646708.png b/book/_build/html/_images/c32b82ecf075804565b45f8bd917f1105b8c12a75d4f81f0666645bd04646708.png deleted file mode 100644 index 0de0ef7b5..000000000 Binary files a/book/_build/html/_images/c32b82ecf075804565b45f8bd917f1105b8c12a75d4f81f0666645bd04646708.png and /dev/null differ diff --git a/book/_build/html/_images/chapter_cover.png b/book/_build/html/_images/chapter_cover.png deleted file mode 100644 index 472e4f2d4..000000000 Binary files a/book/_build/html/_images/chapter_cover.png and /dev/null differ diff --git a/book/_build/html/_images/dd1a4c940225c27c69a1fa2aefc3c464eba993adc145aa4ba3a73b2a0c5073d3.png b/book/_build/html/_images/dd1a4c940225c27c69a1fa2aefc3c464eba993adc145aa4ba3a73b2a0c5073d3.png deleted file mode 100644 index bc41e7c1a..000000000 Binary files a/book/_build/html/_images/dd1a4c940225c27c69a1fa2aefc3c464eba993adc145aa4ba3a73b2a0c5073d3.png and /dev/null differ diff --git a/book/_build/html/_images/e7bd70b689d2236457e4b19b56b835fd31490be118eb751f01ba441a406d2ed0.png b/book/_build/html/_images/e7bd70b689d2236457e4b19b56b835fd31490be118eb751f01ba441a406d2ed0.png deleted file mode 100644 index 91ae26c3b..000000000 Binary files a/book/_build/html/_images/e7bd70b689d2236457e4b19b56b835fd31490be118eb751f01ba441a406d2ed0.png and /dev/null differ diff --git a/book/_build/html/_images/ed253f13d1a9f4c36390287b7c0ec138d432061c6b742c8161c174668ddce750.png b/book/_build/html/_images/ed253f13d1a9f4c36390287b7c0ec138d432061c6b742c8161c174668ddce750.png deleted file mode 100644 index e03288b27..000000000 Binary files a/book/_build/html/_images/ed253f13d1a9f4c36390287b7c0ec138d432061c6b742c8161c174668ddce750.png and /dev/null differ diff --git a/book/_build/html/_images/ed39e449c5ad2d6689c67ed3b842a0bba41f205e3a897dd78b7648d544c3bae8.png b/book/_build/html/_images/ed39e449c5ad2d6689c67ed3b842a0bba41f205e3a897dd78b7648d544c3bae8.png deleted file mode 100644 index 3bdff94e7..000000000 Binary files a/book/_build/html/_images/ed39e449c5ad2d6689c67ed3b842a0bba41f205e3a897dd78b7648d544c3bae8.png and /dev/null differ diff --git a/book/_build/html/_images/f63a0756c67f065411cc741910e53fb201a014e3d67a3d9609c93ab5f37b07ec.png b/book/_build/html/_images/f63a0756c67f065411cc741910e53fb201a014e3d67a3d9609c93ab5f37b07ec.png deleted file mode 100644 index 01dc3964c..000000000 Binary files a/book/_build/html/_images/f63a0756c67f065411cc741910e53fb201a014e3d67a3d9609c93ab5f37b07ec.png and /dev/null differ diff --git a/book/_build/html/_images/f9037e8013e3e2b21587a371853bb666704b3c8c4de15e6827c9ba22b871d1ba.png b/book/_build/html/_images/f9037e8013e3e2b21587a371853bb666704b3c8c4de15e6827c9ba22b871d1ba.png deleted file mode 100644 index cb2da4d3d..000000000 Binary files a/book/_build/html/_images/f9037e8013e3e2b21587a371853bb666704b3c8c4de15e6827c9ba22b871d1ba.png and /dev/null differ diff --git a/book/_build/html/_images/fc7646c2070380c4b51afac35000b40f8f9330903c8651888e2ab1a4db280ca1.png b/book/_build/html/_images/fc7646c2070380c4b51afac35000b40f8f9330903c8651888e2ab1a4db280ca1.png deleted file mode 100644 index fff4bc827..000000000 Binary files a/book/_build/html/_images/fc7646c2070380c4b51afac35000b40f8f9330903c8651888e2ab1a4db280ca1.png and /dev/null differ diff --git a/book/_build/html/_images/jHub1.png b/book/_build/html/_images/jHub1.png deleted file mode 100644 index d31f66e5e..000000000 Binary files a/book/_build/html/_images/jHub1.png and /dev/null differ diff --git a/book/_build/html/_images/jHub2.png b/book/_build/html/_images/jHub2.png deleted file mode 100644 index c726c7ba2..000000000 Binary files a/book/_build/html/_images/jHub2.png and /dev/null differ diff --git a/book/_build/html/_images/jHub3.png b/book/_build/html/_images/jHub3.png deleted file mode 100644 index b627fe946..000000000 Binary files a/book/_build/html/_images/jHub3.png and /dev/null differ diff --git a/book/_build/html/_images/jHub4.png b/book/_build/html/_images/jHub4.png deleted file mode 100644 index 37839cf2c..000000000 Binary files a/book/_build/html/_images/jHub4.png and /dev/null differ diff --git a/book/_build/html/_images/jHub5.png b/book/_build/html/_images/jHub5.png deleted file mode 100644 index 8a9b949c3..000000000 Binary files a/book/_build/html/_images/jHub5.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_internet_enabled.png b/book/_build/html/_images/kaggle_internet_enabled.png deleted file mode 100644 index 39962996c..000000000 Binary files a/book/_build/html/_images/kaggle_internet_enabled.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step1.png b/book/_build/html/_images/kaggle_step1.png deleted file mode 100644 index c0eab6cbc..000000000 Binary files a/book/_build/html/_images/kaggle_step1.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step2.png b/book/_build/html/_images/kaggle_step2.png deleted file mode 100644 index 88fac3ecf..000000000 Binary files a/book/_build/html/_images/kaggle_step2.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step3.png b/book/_build/html/_images/kaggle_step3.png deleted file mode 100644 index e2a02f2ad..000000000 Binary files a/book/_build/html/_images/kaggle_step3.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step4.png b/book/_build/html/_images/kaggle_step4.png deleted file mode 100644 index 40c20dcd3..000000000 Binary files a/book/_build/html/_images/kaggle_step4.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step5.png b/book/_build/html/_images/kaggle_step5.png deleted file mode 100644 index 0e875703b..000000000 Binary files a/book/_build/html/_images/kaggle_step5.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step6.png b/book/_build/html/_images/kaggle_step6.png deleted file mode 100644 index 2984f4c97..000000000 Binary files a/book/_build/html/_images/kaggle_step6.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step6_1.png b/book/_build/html/_images/kaggle_step6_1.png deleted file mode 100644 index 663c0efe9..000000000 Binary files a/book/_build/html/_images/kaggle_step6_1.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step6_2.png b/book/_build/html/_images/kaggle_step6_2.png deleted file mode 100644 index 44be0dfb9..000000000 Binary files a/book/_build/html/_images/kaggle_step6_2.png and /dev/null differ diff --git a/book/_build/html/_images/kaggle_step7.png b/book/_build/html/_images/kaggle_step7.png deleted file mode 100644 index 248d410c7..000000000 Binary files a/book/_build/html/_images/kaggle_step7.png and /dev/null differ diff --git a/book/_build/html/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css b/book/_build/html/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css deleted file mode 100644 index fc14abc85..000000000 --- a/book/_build/html/_panels_static/panels-main.c949a650a448cc0ae9fd3441c0e17fb0.css +++ /dev/null @@ -1 +0,0 @@ -details.dropdown .summary-title{padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.dropdown:hover{cursor:pointer}details.dropdown .summary-content{cursor:default}details.dropdown summary{list-style:none;padding:1em}details.dropdown summary .octicon.no-title{vertical-align:middle}details.dropdown[open] summary .octicon.no-title{visibility:hidden}details.dropdown summary::-webkit-details-marker{display:none}details.dropdown summary:focus{outline:none}details.dropdown summary:hover .summary-up svg,details.dropdown summary:hover .summary-down svg{opacity:1}details.dropdown .summary-up svg,details.dropdown .summary-down svg{display:block;opacity:.6}details.dropdown .summary-up,details.dropdown .summary-down{pointer-events:none;position:absolute;right:1em;top:.75em}details.dropdown[open] .summary-down{visibility:hidden}details.dropdown:not([open]) .summary-up{visibility:hidden}details.dropdown.fade-in[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out;animation:panels-fade-in .5s ease-in-out}details.dropdown.fade-in-slide-down[open] summary~*{-moz-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;-webkit-animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out;animation:panels-fade-in .5s ease-in-out, panels-slide-down .5s ease-in-out}@keyframes panels-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes panels-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.octicon{display:inline-block;fill:currentColor;vertical-align:text-top}.tabbed-content{box-shadow:0 -.0625rem var(--tabs-color-overline),0 .0625rem var(--tabs-color-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.tabbed-content>:first-child{margin-top:0 !important}.tabbed-content>:last-child{margin-bottom:0 !important}.tabbed-content>.tabbed-set{margin:0}.tabbed-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.tabbed-set>input{opacity:0;position:absolute}.tabbed-set>input:checked+label{border-color:var(--tabs-color-label-active);color:var(--tabs-color-label-active)}.tabbed-set>input:checked+label+.tabbed-content{display:block}.tabbed-set>input:focus+label{outline-style:auto}.tabbed-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.tabbed-set>label{border-bottom:.125rem solid transparent;color:var(--tabs-color-label-inactive);cursor:pointer;font-size:var(--tabs-size-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .tabbed-set>label:hover{color:var(--tabs-color-label-active)} diff --git a/book/_build/html/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css b/book/_build/html/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css deleted file mode 100644 index adc616622..000000000 --- a/book/_build/html/_panels_static/panels-variables.06eb56fa6e07937060861dad626602ad.css +++ /dev/null @@ -1,7 +0,0 @@ -:root { ---tabs-color-label-active: hsla(231, 99%, 66%, 1); ---tabs-color-label-inactive: rgba(178, 206, 245, 0.62); ---tabs-color-overline: rgb(207, 236, 238); ---tabs-color-underline: rgb(207, 236, 238); ---tabs-size-label: 1rem; -} \ No newline at end of file diff --git a/book/_build/html/_sources/projects/README.md b/book/_build/html/_sources/projects/README.md deleted file mode 100644 index 024a9c751..000000000 --- a/book/_build/html/_sources/projects/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# Projects - -Welcome to the Projects of Climatematch Academy! - -Every day, you will spend 3 hours working on projects and professional development activities. - -Projects will give you an opportunity to apply your newly acquired knowledge to real climate data and work on one topic in depth. It will give you the confidence that ***you can***. - -By working together with 4-6 peers from your pod, you will learn to -- engage in self-directed learning, -- find meaningful problems to work on, -- ask questions that are well-defined and answerable, -- put concepts into practice, -- connect physical climate phenomena to socio-economic impacts. - -Everything you need to know about projects -- from the daily schedule and tasks to useful tips and resources -- can be found in the **[Daily Guide for Projects](./docs/project_guidance.md)**. - -We are also providing a range of **[project materials](./docs/datasets_overview.md)** to help you get started. - -Together with other professional development activities, projects will also give you the space to start connecting your new knowledge, skills, ideas, and personal and professional connections to **your life after the course**. - -If you would like to continue working on your project after the two-week course, we encourage you to apply to the **[Climatematch Impact Scholars program](./docs/continuing_your_project_after_the_course.md)** - - diff --git a/book/_build/html/_sources/projects/docs/continuing_your_project_after_the_course.md b/book/_build/html/_sources/projects/docs/continuing_your_project_after_the_course.md deleted file mode 100644 index 3d6f8a110..000000000 --- a/book/_build/html/_sources/projects/docs/continuing_your_project_after_the_course.md +++ /dev/null @@ -1,42 +0,0 @@ -# Climatematch Impact Scholars program - -Two weeks is a very short period of time for scientific discovery! To take projects to the next level, Climatematch Academy, in collaboration with [2i2c](https://2i2c.org/), will be able to provide selected student groups with computing resources for 5 months after the course ends as part of the **Climatematch Impact Scholars program**. Thanks to our partnership with [Fresh Eyes on CMIP](https://wcrp-cmip.org/fresh-eyes-on-cmip/), student groups will also have an opportunity to showcase their work to, and get feedback from, experienced researchers working on similar questions. - - -## **Eligibility** - -**Each project group can submit one application**. Groups can be of any size. We understand that not every member of a group will be able to dedicate time to the project after the course. Any eventual publication should acknowledge all contributions made during or after the course. - -**Teaching Assistants are welcome to join teams as equal collaborators**. They can join as many of their groups as they would be able to contribute to in case the applications are successful. - ---- -## **Application process** -### 1. Expression of interest -**July 27, 2023** (slots 2,5) / **July 28, 2023** (slots 1,3,4) - -Upon submission of your project slides at the end of Day 9, we ask that you indicate the number of people from your team who are planning to apply for extended computing resources to continue the project. We also ask whether either or both of your Teaching Assistants are interested in joining you, so please discuss this with them before submitting the form! - -You will have access to computing resources until the application deadline so that you can ground your project proposal in solid preliminary analysis. - - -### 2. Application deadline -**August 31, 2023** - -To apply for extended resources, **submit a detailed project proposal** by the deadline. The application form will be posted here soon! - -The strongest proposals will: - -* directly build on, and be supported by, analyses conducted during the course and the following month; -* have a clear research focus; -* connect the climate phenomenon of interest to its socio-economic impact. - -### 3. Application decisions -Applications will be reviewed on a rolling basis. We will aim to get back to you within two weeks of proposal submission. - ---- -## **What is involved** -Selected groups will be provided with continued access to computing resources **until December 31, 2023**, and invited to present their work at a *Fresh Eyes on CMIP* workshop. - - -We are actively working on providing you with more professional and academic opportunities. Stay tuned! - diff --git a/book/_build/html/_sources/projects/docs/datasets_overview.md b/book/_build/html/_sources/projects/docs/datasets_overview.md deleted file mode 100644 index 76065dfda..000000000 --- a/book/_build/html/_sources/projects/docs/datasets_overview.md +++ /dev/null @@ -1,16 +0,0 @@ -# Project materials - -You have been matched with 4-6 students from your pod to form a project group. Based on the joint project preferences of the people in your group, you have been assigned one of seven project topics. You can find your project topic on the portal. Your pod's Teaching Assistant will tell you your project group on the first day of the course. - -In this section, you will find materials to help you get started on your project. These include a brief background, an introductory video (except _Heatwaves_ and _ENSO impact on precipitation and temperature_), a project map, a data exploration notebook, as well as some further reading recommendations. - -You can find project materials in the left side panel or by clicking on the project titles below. -- [Sea level rise](./project-notebooks/Sea_level_rise.ipynb) -- [Regional precipitation variability and extreme events](./project-notebooks/Regional_precipitation_variability.ipynb) -- [Change in Earth’s albedo and its dependence on land cover changes in the past 20 years](./project-notebooks/Surface_albedo_and_land_use.ipynb) -- [Monitoring and mapping wildfires using satellite data](./project-notebooks/Wildfires_and_burnt_areas.ipynb) -- [Ocean acidification](./project-notebooks/Ocean_acidification.ipynb) -- [The impact of ENSO on precipitation and temperature](./project-notebooks/ENSO_impact_on_precipitation_and_temperature.ipynb) -- [Heatwaves: Assessing the dynamic interactions of the atmosphere and land](./project-notebooks/Heatwaves.ipynb) - - diff --git a/book/_build/html/_sources/projects/docs/project_guidance.md b/book/_build/html/_sources/projects/docs/project_guidance.md deleted file mode 100644 index ccb26e594..000000000 --- a/book/_build/html/_sources/projects/docs/project_guidance.md +++ /dev/null @@ -1,267 +0,0 @@ -# Daily guide for projects - - -## Summary - -The project component of Climatematch Academy is designed to guide you through the entire research process, providing a comprehensive journey from project ideation to outcome presentation, all within a condensed time frame of just two weeks. Within a dedicated three-hour time slot each day, you will collaborate with a group of 4-6 fellow students from your pod to collectively develop a single research project. - -On Day 1, you will learn about good research practices by working on a ‘mock’ project through the lens of equity. You will then spend eight days applying those skills to a scientific question and a geographical region that interests you and your teammates. To familiarize yourselves with the datasets at hand, you will examine the spatial and temporal distribution of one climate variable on global and local scales, as well as its social and economic impact. After performing a brief literature review, you will develop a sense of interesting open questions in the field and will devise a specific testable hypothesis accordingly. On Day 4, your group will submit a project proposal that you will swap with other groups to practice giving and receiving feedback through a peer review process. For the rest of the course, you will focus on acquiring evidence for or against your hypothesis. Throughout this time, you will be supported by your pod’s Teaching Assistant and a dedicated Project Teaching Assistant. Finally, on the last two days of the course, you will prepare a short presentation showcasing the story of your project and meet with other groups in your megapod to discuss your findings with them. - - -## Submission Links - -- Day 4: Proposal Submission **[here](https://airtable.com/shrQ5CLEla3dDkKbk)** - -- Day 9: Project Submission **[here](https://airtable.com/shr7EAY3x39x8swZu)** - - -## Project materials - -You have been assigned one of seven research projects based on the preferences listed in your application. Each project comes with an introductory video, a template, and a data loading jupyter notebook. - -Student groups will define their own research question. Project templates are maps of research ideas developed by the Climatematch Academy team. They are composed of **_GREEN_**, **_YELLOW_**, and **_RED_** questions in accordance with their difficulty. Each difficulty level is further divided into questions relating to a physical climate phenomenon (borderless) and those relating to socio-economic issues (dashed border). - -The templates should be used in several ways: - -* All teams **must** work through the **_GREEN_** questions on Day 2. This will let you familiarize yourselves with the relevant datasets and appreciate the global variability of your selected climate phenomenon before defining your research question. -* All teams **must** work on a research question related to a physical climate phenomenon, such as those found in borderless-boxes. -* In addition, all teams are **highly encouraged** to consider the socio-economic impact of their climate phenomenon of interest (dashed border). We advise you to support your conclusions with data if it is possible to find open-source socio-economic data, reports, or case studies from a trustworthy source relevant to your country or continent of interest. -* If you are new to climate science or do not have a lot of research experience, we strongly recommend that you use the research questions provided in the template extensively. The templates have been designed to give you enough structure to get started and enough options to keep going if you stick with the template. Comprehensively answering just one **_YELLOW_** or **_RED_** question from the template would be an achievement! You can pick the question that interests you the most right away without following the flow suggested by the template. -* If you are an experienced climate researcher, you are more than welcome to branch out beyond the template and define your own research questions! However, we do ask you to stick to the climate datasets. - - -## Project Teaching Assistants - -Project Teaching Assistants are your friendly project experts to consult with on all issues related to your project topics and datasets. They can help with brainstorming project ideas, literature searches, and coding. You will meet with them on a regular basis. - -They will visit your group on Day 1 to make introductions and will subsequently meet with you, on average, for 45-60 minutes every day or 1.5-2 hours every other day. As projects progress, Project Teaching Assistants might need to prioritize junior groups, but they can also be summoned to senior groups for meetings when needed. Since they can arrive unannounced at any time (busy schedules!), please stop what you were doing to have the meeting, and then resume your work when the Project Teaching Assistant leaves. Please also post questions on discord in the project-specific channels. All project Teaching Assistants have time set aside specifically to answer discord questions and to provide additional meetings when necessary. - - -## Project Time - -You will have 2.5-3 hours each day to work on projects. The goal during the **first week** is to learn about the research process and develop a project idea. To simplify logistics, we have already broken you into project groups. Among other reasons, you were (climate)matched with your pod and research group, because you share an interest in similar climate phenomena. We understand that specific interests and motivations will vary even within project groups and becoming part of the Climatematch community is as much about finding your role in the team as it is about pursuing a specific personal research interest. During the **second week**, which includes the Project Day (W2D2), you will implement the analyses, interpret your findings, and present them to your megapod peers on the last day of Climatematch Academy. - -Embedded in the project time will also be a set of **professional development activities**: a series of Impact Talks, meetings with mentors, and career panels. - -### POD INTRODUCTIONS W1D1 -_Monday, 17th July (PM) for everyone_ - -On W1D1, you will meet your pod 30 minutes before the regular start of the tutorial time for introductory activities. Your pod’s Teaching Assistant will also tell you the project group you have been assigned to and its project topic. In some pods, the two groups will work on the same topic while others might be assigned two different topics depending on student interests. If you wish to work in the other group, discuss it with your Teaching Assistant. - -During the pod introduction on W1D1, your Teaching Assistant will also inform you about your project group’s schedule for watching and discussing the Impact Talks. One group will do this activity during the first 30 minutes of a project block, while the other will dedicate to it the last 30 minutes of a project block. The discussions following the Impact Talks will be facilitated by you - the students. Each discussion should have one student leading from the front and one student leading from behind, with every student in your project group taking on one of these leadership roles at least once. Your Teaching Assistant will help you appoint yourselves to these roles during the pod introductions. You can read more about the associated responsibilities [here](https://comptools.climatematch.io/professional_development/impact_talks.html). - ---- -### SESSION 1 -_Monday, 17th July (PM) for groups in timezone slots 2 and 5_ - -_Tuesday, 18th July (AM) for groups in timezone slots 1, 3, and 4_ - -Work through the [tutorial on good research practices](https://comptools.climatematch.io/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.html) in your project groups. Your Project Teaching Assistant will come by at some point during this period to introduce themselves and facilitate your progression through the tutorial for 30-45 minutes. - ---- -### SESSION 2 -_Tuesday, 18th July (PM) for groups in timezone slots 2 and 5_ - -_Wednesday, 19th July (AM) for groups in timezone slots 1, 3, and 4_ - ->**Professional Development:** Watch the interview about [Climate Justice](https://comptools.climatematch.io/professional_development/impact_talks.html#climate-justice) and use the provided prompts to discuss the topic within your project group for 15 minutes As agreed during introductions on W1D1, one project group in the pod should do this during the first 30 minutes of the project block, while the other should leave this for the last 30 minutes of the block. Also as decided on W1D1, two students should practice their leadership skills by leading the discussion from the front and from behind. - -The remaining 2.5 hours are time to get your hands dirty! Explore one of the provided climate datasets by working through the **_GREEN_** questions of your project template. Use the **data loading notebook** to get started and try to understand what is being done and why. Parts of this code might be reusable or adaptable later. Be on the lookout for interesting hypotheses and remember to work as a team! Ask for help, assist others, and discuss your findings throughout the day. - -* Apply the data wrangling skills you have acquired in tutorials thus far to generate the global maps suggested in **Q1**. Examine your plots. Do you notice any interesting patterns across the globe or over time? -* Plot the global mean of the variable(s) over the time period suggested in **Q2**. Do you observe any trends? Does the result align with your expectations? Why? Why not? -* As a group, agree on a geographical region to focus on and answer **Q3**. Depending on the variable you explore, choosing a continent, subcontinent, or country might be appropriate choices. How does the result compare with your answer to Q2? Does _this_ result align with your expectations? Why? Why not? -* Consider the socio-economic impact of your climate phenomenon by addressing **Q4**. Depending on your project topic, you may or may not have additional numerical data provided specifically for this question. Feel free to seek information from reliable sources online to support your arguments. - ---- -### SESSION 3 -_Wednesday, 19th July (PM) for groups in timezone slots 2 and 5_ - -_Thursday, 20th July (AM) for groups in timezone slots 1, 3, and 4_ - ->**Professional Development:** Watch the interview about, [Equity in Climate and Climate Science](https://comptools.climatematch.io/professional_development/impact_talks.html#equity-in-climate-and-climate-science) and use the provided prompts to discuss the topic within your project group for 15 minutes. As agreed during introductions on W1D1, one project group in the pod should do this during the first 30 minutes of the project block, while the other should leave this for the last 30 minutes of the block. Also as decided on W1D1, two students should practice their leadership skills by leading the discussion from the front and from behind. - ->**Professional Development:** On any two days between now and the end of the course, your project group will be visited by mentors. In 1-hour meetings, they will share their professional path in a climate-related field, offer personalized career advice, and provide a networking opportunity. Your pod’s Teaching Assistant can tell you the exact times of these meetings. Make sure to familiarize yourself with the suggested meeting structure and tips for getting the most out of these meetings [here](https://comptools.climatematch.io/professional_development/mentors.html). - -The remaining time will be dedicated to brainstorming and reviewing the literature! The goal of this literature review is to find out what is known or has been hypothesized about your climate phenomenon, to determine what aspects are currently the most debated, and to help you define some keywords that you will use in your project proposal tomorrow. You do not need to come up with a completely original question! Do, however, situate your research within the relevant literature, and try to get hints/suggestions from other papers. Revisit Step 2 of the [tutorial on good research practices](https://comptools.climatematch.io/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial1.html) to review the literature more efficiently! - - -* (**15 min**) Start by discussing your initial project ideas! As a group, try to come up with one or a few questions of interest, either by yourselves or directly from the project template. Was there anything weird or intriguing you noticed in the data yesterday? Are there any questions in the template you find particularly exciting? -* (**30 min**) On your own, start doing a literature review using search engines like Google or Baidu. Look only at abstracts to select 2-3 promising ones. -* (**15 min**) Report to the whole group what papers you found and pool them together. Assign one paper per person to read/skim in the next 1h. -* (**1 h**) On your own, read the paper that was assigned to you. Make notes in a common google doc shared with your group, and especially write down important keywords or concepts which you might use in your project proposal. If you are interested in a closed-access paper and are not connected to an .edu domain or a VPN, try to find full versions of papers on preprint servers like arXiv or bioRxiv. You could also ask your Teaching Assistants to get it for you (and they might in turn ask someone who has access to a university VPN). There might be other options too… -* (**30 min**) Report back to the group. In ~5 minutes, try to tell them as much as you understand about the paper. Get into details, but do not just read whole sections from the paper out loud. Ask the other students questions about the papers they are presenting to understand them better. - ---- -### SESSION 4 -_Thursday, 20th July (PM) for groups in timezone slots 2 and 5_ - -_Friday, 21st July (AM) for groups in timezone slots 1, 3, and 4_ - -By the end of this project session, you should submit your project proposal via **[Airtable link](https://airtable.com/shrQ5CLEla3dDkKbk)**. - -(**30 min**) Based on your observations on Day 2 and the literature review yesterday, try to converge on a research question and devise a hypothesis. Try to come up with one or a few questions of interest, either by yourselves or directly from the project template. We encourage you to consider not only the physical science aspects of a climate phenomenon, but also its socio-economic impact. Use the question boxes with dashed outlines for inspiration. We understand that specific interests and motivations will vary even within project groups and becoming part of the Climatematch community is as much about finding your role in the team as it is about pursuing a specific personal research interest. Please consider your teammates interests and ideas with as much respect as your own. - -(**30 min**) By yourself, read the [Ten simple rules for structuring papers](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1005619). Pay close attention to figure 1, and how it specifies the same overall structure for the abstract, for each paragraph in the paper, and for the paper as a whole. - -(**1 h**) As a group, try to write a proposal for this project based on the way you understand it now, following the C-C-C scheme described in the _Ten simple rules_ paper. - - - -* **Context**: scientific background and the knowledge gap your project will aim to fill. Include keywords and concepts that you identified in your literature review. -* **Content**: your hypothesis and a description of the analyses and the results (positive or negative) you would need to answer your question. -* **Conclusion**: the potential significance and societal impact of the work. - -The proposal can be a list of bullet points or a coherent paragraph; don’t worry about the structure too much. The goal is to structure your thoughts and ideas so that a person unfamiliar with the topic can understand the importance of your research question and approach.. - -(**30 min**) It is always revealing to present your research to someone who has never heard about it. Share your proposal with the other team in your pod and receive their proposal in return. In your group, read and discuss the other team’s abstract and write down some feedback. What do you understand about their project? What do you _not_ understand about it? When giving your feedback, keep in mind that the other research group has put a lot of effort into generating the proposal and may not have had time to polish the language or presentation of their ideas. We always aim to be direct and specific, but also polite, respectful, and kind in our communication with each other. - -(**30 min**) Work to address the feedback received from the other team. When done, submit the project proposal **[here](https://airtable.com/shrQ5CLEla3dDkKbk)**. Your proposal will not be graded, but its submission is required to receive a project badge on your Climatematch Academy certificate. - ---- -### SESSION 5 -_Friday, 21st July (PM) for groups in timezone slots 2 and 5_ - -_Monday, 24th July (AM) for groups in timezone slots 1, 3, and 4_ - -You should now have a sense of the data, and you have probably refined your hypothesis a little. Writing a proposal will have helped you get a rough idea of what tools you might use to tackle your research question, and what the answer could look like. You will use the remaining project time to implement the analyses you have planned and make progress towards an answer. Your group might not be able to complete their research plan, but don’t get discouraged: answering a research question usually takes months if not years of work and you should consider making meaningful progress towards that goal a great success! - -A few pieces of general advice: - - - -* See if you can allocate tasks efficiently within the team! -* TAs are here to help you, if you know what analysis you need, but don’t know how to do it. They can point you to useful toolkits that may be difficult to find otherwise. -* Try not to implement complicated analyses from scratch. Use existing toolkits, and learn how to use them well. This kind of knowledge is very helpful long-term. - ---- -### SESSION 6 -_Monday, 24th July (PM) for groups in timezone slots 2 and 5_ - -_Tuesday, 25th July (AM) for groups in timezone slots 1, 3, and 4_ - ->**Professional Development:** Watch the interview about [Open Climate Science](https://comptools.climatematch.io/professional_development/impact_talks.html#open-climate-science) and use the provided prompts to discuss the topic within your project group for 15 minutes. As agreed during introductions on W1D1, one project group in the pod should do this during the first 30 minutes of the project block, while the other should leave this for the last 30 minutes of the block. Also as decided on W1D1, two students should practice their leadership skills by leading the discussion from the front and from behind. - - -Continue working on your project! - - - -* If you find a negative answer to your question, that is absolutely ok! Please do report that. Then go back and think about how this affects your initial hypothesis. Does it rule it out, or could there be limitations in this particular data that lead to the negative result? What other data could you seek out that would be more well-suited for answering this question? Try to design a new experiment in specific details and tell us about it. Who knows, somebody might run that experiment someday! -* If you find a positive result (i.e. the data matches your hypothesis), you should spend the rest of your time validating it to make absolutely sure it is a real effect. For example, if you created a proxy-based paleoclimate reconstruction of precipitation hydrogen isotopes (δD) to assess past changes in rainfall amount, there are a few factors you could consider to ensure that the climate signal in your data is real and reliable. Are the δD values in the part of your record closest to present similar to modern measurements of rainfall δD at your study site? Are there other factors in addition to your variable of interest (rainfall amount) that may be contributing to the δD signal in your data? Can you remove the effect of these other factors so that the dominant signal in your δD record is recording changes in rainfall amount? - - ---- -### PROJECT DAY (W2D2) -_Tuesday, 25th July (AM) for groups in timezone slots 2 and 5_ - -_Tuesday, 25th July (PM) for groups in timezone slots 1, 3, and 4_ - -Watch the keynote talk _“Futures from the Frontiers of Climate Science”_ by Dr Paul Behrens. - - - -Continue working on your project for the rest of the day! Your pod’s Teaching Assistant will be around during the tutorial time block and your Project Teaching Assistant will be available during the project time block as usual. - -During the last hour of the tutorial block, there will be a **live** [career panel](https://comptools.climatematch.io/professional_development/career_panels.html) with an opportunity to ask questions to the panelists: - - - -* 8:00 - 9:00 UTC for groups in timezone slots 1 and 2 -* 14:30 - 15:30 UTC for groups in timezone slot 3 -* 20:30 - 21:30 UTC for groups in timezone slots 4 and 5 - ---- -### SESSION 7 -_Tuesday, 25th July (PM) for groups in timezone slots 2 and 5_ - -_Wednesday, 26th July (AM) for groups in timezone slots 1, 3, and 4_ - -Continue working on your project! Make sure to reconvene with your teammates every 1-1.5 hours to discuss your progress. If you are struggling with something, ask others for help right away! Use your Project Teaching Assistant and your pod’s Teaching Assistant as a resource when your group gets stuck. - -On Day 7, the curriculum of the course will start shifting from topics surrounding physical climate phenomena to issues of socio-economic impact as well as mitigation and adaptation strategies. This is a good point to start thinking about the impact the research topic you are studying as part of your project has on ecosystems and communities. - ---- -### SESSION 8 -_Wednesday, 26th July (PM) for groups in timezone slots 2 and 5_ - -_Thursday, 27th July (AM) for groups in timezone slots 1, 3, and 4_ - ->**Professional Development:** Watch the interview about [Psychology of the climate crisis and climate science communication](https://comptools.climatematch.io/professional_development/impact_talks.html#psychology-of-the-climate-crisis-and-climate-science-communication) and use the provided prompts to discuss the topic within your project group for 15 minutes. As agreed during introductions on W1D1, one project group in the pod should do this during the first 30 minutes of the project block, while the other should leave this for the last 30 minutes of the block. Also as decided on W1D1, two students should practice their leadership skills by leading the discussion from the front and from behind. - -Continue working on your project and start thinking about your conclusions. - -The project submission form you will complete tomorrow also includes a question about your interest in potentially **continuing your project after the course** as a Climatematch Impact Scholar. Please take a moment to [read about this opportunity](https://comptools.climatematch.io/projects/docs/continuing_your_project_after_the_course.html) and discuss it with your teammates and Teaching Assistants. - ---- -### SESSION 9 -_Thursday, 27th July (PM) for groups in timezone slots 2 and 5_ - -_Friday, 28th July (AM) for groups in timezone slots 1, 3, and 4_ - -Tie up loose ends and prepare a short slideshow about your project! - -At the end of this project block, you should submit your slides via **[this Airtable link](https://airtable.com/shr7EAY3x39x8swZu)**. - -Keep in mind that you will be giving a live presentation of your project to your megapod peers after the final tutorial block on 28th July. - -Use [this presentation template](https://docs.google.com/presentation/d/13sSzoXhTq7R5YKznbPXH2Fo7IboMDaFKEhWQOOchT14/edit?usp=sharing). Make a copy for your team to edit! - -You can add your group name and project title to the bottom panel of non-title slides through **Slide** -> **Edit theme**. - - -#### **Content** - -The 1 minute - 1 slide rule might seem like an impossible limit. However, it is one of the most useful formats you can learn, often referred to as a “one minute elevator pitch”. If you can become an expert at giving short pitches about your work, it will help you get the interest of a lot of people, for example when presenting posters at scientific conferences or when advocating for policy changes with your local government. Or when you accidentally find yourself in an elevator with a potential investor: this could be your chance to secure a million dollars in research funds! - -The key to a good presentation is to practice it by yourself many times. It is no different from other performing arts (acting, playing a musical instrument etc), where rehearsals are crucial to a good performance. - -If something in your presentation does not sound good or does not make sense, you WILL get annoyed by it when you say it the tenth time, and that will make you want to change it. (Secret: this how professors prepare all of their presentations and it is why they always sound like they know what they are talking about) - -Always have an introduction slide and a conclusion slide. If your group is relatively large (>=5 people), then someone should be assigned to each of the intro and conclusion slides. If your group is small, then the same person can present the intro + next slide, or conclusion slide + previous slide. - -Short anecdotes can work like magic for engaging your audience. As a rule, most listeners are passive, bored, not paying attention. You can grab their attention with that smart elevator pitch, or with a short anecdote about something that happened to your group while working on projects. - -Most groups will not have a result and this is absolutely normal. If this is true for your group, the main goal will be to communicate the logic of your project proposal. For example, did you design an innovative comparison of climate datasets to assess the impact of El Niño Southern Oscillation (ENSO) on global temperature, but then did not find the appropriate data to get answers (e.g., the spatial and temporal resolution of the data available was not sufficient to answer your question)? That can also be very interesting for others to hear about! Furthermore it will make it clear that research never stops. It continues as a series of questions and answers, not just within your own project, but at the level of the entire research field. In the case of this example, the takeaways from your project could potentially highlight the need for more temperature data from specific regions or time periods in order to assess ENSO variability. Tell us what got you excited about this particular project, and try to dream big. What could your project evolve into if given more time and resources? - - ---- -### W2D5: FINAL PRESENTATIONS -_Friday, 28th July (PM) for everyone!_ - -This is the day you present your project to other groups in your megapod. You can invite your Project Teaching Assistant too, but they might not make it if they are busy. Groups will take turns to share their screens. You can use figures and other graphics to highlight specific aspects of your research, but your presentation is meant to be told as a story, and everyone from your group should take their turn in telling a part of that story. Tell us about the different hypotheses you have had at different points and how you refined them using some of the tools you learned during the course. - - -#### **Schedule** - -* **10 minutes of meet & greet**. Do a round of introductions (one Teaching Assistant calls out names from the zoom list). Everyone says their name, pod name, position, institution or other area of work, and subject of study, as well as one interesting fact about themselves. “Hi, I’m Jonny from the wiggly caterpillars and I am a PhD student at University of Notre Dame in Paris. I study the relationship between moisture and storms, and in my free time I like to go on long bike rides”. -* **30-40 minutes of presentations**, including questions. Each group should speak for approximately 5 minutes (depending on group size), and then take questions for 1-2 minutes. The Lead Teaching Assistant of your megapod will determine the order of presentations. -* **10-20 minutes of general discussion**. Use the following questions to guide the group discussion. Spend a few minutes on each question. It’s ok not to use all these questions, especially if you have your own questions to ask! - * What was missing in the dataset that you would have really liked to have? - * Does anyone plan to continue working on this project in the future? Climatematch Academy will be able to support selected groups with the computing resources required to take projects to the next level. Read more about the opportunity to become a Climatematch Impact Scholar [here](https://comptools.climatematch.io/projects/docs/continuing_your_project_after_the_course.html). - * Which one of the 8 steps of good research practices was hardest and why? - * Based on your experience with the project, what project would you most like to do next? Make up your own, or pick from the other projects available in the course. - * What surprised you the most about the process of working on a project? In what way was this project most different from other projects you have worked on in the past? - * What technique did you learn in the course that you think you can immediately apply to your own project (if you are currently doing research)? - - -#### **Logistics** - -Presentations will take place 1.5 hours after the end of your W2D5 tutorials. **For groups in timezone slots 1, 3, 4, this will fall outside of their regular course hours.** - -You will present to other groups (3-5 groups per room). An email will be sent with the zoom room of one of the pods and all groups will meet there for one hour. There is a hard cutoff at the one hour mark, and it will be the Teaching Assistants’ responsibility to ensure everyone gets a turn to present. - -One minute per person and one slide per person only! This is primarily to ensure that everyone in your megapod gets to present before the hard cutoff at the one hour mark. - -Do not introduce yourselves again, just present the material directly. - -When you are done presenting, leave the last slide up (with conclusions), and open the floor for questions. - - -#### **Questions** - -If your presentation was short enough, there is time for questions from the audience. These are a great way to get feedback on your project! - -Before you ask a question, consider whether others might be interested in that topic too. This usually means asking big picture questions, as opposed to detailed, technical questions, but there are exceptions. - -If you are answering the question, try to be short and concise. Your audience will notice if you start rambling, and it can seem as if you are avoiding the question. Answering concisely is another very useful skill in “real life”. It also means that you can take more questions given our time constraints. diff --git a/book/_build/html/_sources/projects/professional_development/README.md b/book/_build/html/_sources/projects/professional_development/README.md deleted file mode 100644 index 4257ef351..000000000 --- a/book/_build/html/_sources/projects/professional_development/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Professional Development - -Professional development encompasses four different activities: Impact Talks, Mentor Meetings, Career Features and Career Panels. Use this guide to find out more about each activity and when and how to attend them! - -## Why Professional Development? - -Professional development enables students to connect and expand their experiences, skills and interest, broadening students’ perception of how they can make an impact via different career options. - -Specifically, students will: - -* Watch recorded interviews on selected topics, relevant to a more just climate science -* Reflect and share how they and their work may relate to those selected topics -* Expand their views about career pathways via live panel discussions with professionals in climate-related fields -* Meet with mentors with different career backgrounds -* Expand their views about making impact by browsing different career profiles - - -## Impact Talks - -**Recorded interviews** of practitioners sharing their perspectives on topics relevant to a more just climate science. Impact talks aim to foster discussion, reflection, and self-discovery inside and outside the course. - -Learn more about [Impact Talks](impact_talks.ipynb) - - -## Mentor Meetings - -Professionals with experience in various climate-related fields **meet with student groups live** to share their career experiences. Mentor meetings aim to inspire and expand students’ perspectives, during and after the course. - -Learn more about [Mentor Meetings](mentors.md) - - -## Career Features - -**Online spotlights** of diverse climate science practitioners to inspire students on climate actions and/or career paths. Career Features aim to inspire students in career exploration and to expand their views on making a positive impact. - -Learn more about [Career Features](career_features.md) - - -## Career Panels - -**Live panel discussions** with practitioners about their career paths with live Questions & Answers. Career Panels aim to inspire students in their career exploration and to expand their views on how to make a positive impact. - -Learn more about [Career Panels](career_panels.md) diff --git a/book/_build/html/_sources/projects/professional_development/career_features.md b/book/_build/html/_sources/projects/professional_development/career_features.md deleted file mode 100644 index 4ef27ea02..000000000 --- a/book/_build/html/_sources/projects/professional_development/career_features.md +++ /dev/null @@ -1,6 +0,0 @@ -# Career Features - - -* **_Why_**: There is no fixed career pathways for everyone. Career features are tailored to **showcase a range of professionals** working to support action to address our current climate crisis, and that may inspire students for their own career exploration. -* **_What_**: **Online write-ups** of practitioners in climate and related fields that are part of the program book during the program. These career features may include mentors, impact speakers, career panelists, and other volunteers in CMA. -* **_How_**: Students are encouraged to **browse career features** that interest them **at their own pace**, and follow up with practitioners if they want to learn more about different career pathways. \ No newline at end of file diff --git a/book/_build/html/_sources/projects/professional_development/career_panels.md b/book/_build/html/_sources/projects/professional_development/career_panels.md deleted file mode 100644 index c7b96f5fe..000000000 --- a/book/_build/html/_sources/projects/professional_development/career_panels.md +++ /dev/null @@ -1,25 +0,0 @@ -# Career Panels - -As part of the professional development activities, career panels are planned to **bring a variety of professionals across different sectors and career stages together** to share their unique career experiences in climate-related fields that can inspire students’ career exploration beyond the program of Climatematch Academy. - -Career panels will be a series of **live moderated panel discussions** including live Q&A with participating students. These live panel discussions will take place on Tuesday, July 25th (W2D2). The career panels will usually be in the last hour of the time usually reserved for tutorials. The three scheduled time slots for the career panels include: -* 8:00 - 9:00 UTC for groups in timezone slots 1 and 2 -* 14:30 - 15:30 UTC for groups in timezone slot 3 -* 20:30 - 21:30 UTC for groups in timezone slots 4 - -Although each career panel has a targeted student groups based on time zone, you are always invited to join any career panel events that lie outside of your course schedule and work for your personal schedule. Career panel events are great opportunities for students to have direct interactions with professionals in climate-related fields and peer CMA participants and volunteers. You are encouraged to use these opportunities to expand your professional networks! - - -## Confirmed Panelists - -### Panel at 08:00-09:00 UTC -* [Dr. Shipra Jain](https://www.linkedin.com/in/shipra-jain-9aa1382a/?originalSubdomain=sg), Former Executive Committee member, [Young Earth System Scientists Community](https://www.yess-community.org/) -* [Mpho Sadiki](https://www.linkedin.com/in/mpho-sadiki-086662174/?originalSubdomain=za), Earth Observation Data Scientist, [Digital Earth Africa](https://www.digitalearthafrica.org/about-us/governance/technical-advisory-committee/mpho-sadiki) - -### Panel at 08:00-09:00 UTC -* [Dr. Yaítza Luna-Cruz](https://www.earthdata.nasa.gov/learn/data-chats/environmental_justice_luna_cruz), Program Executive, Chief Science Data Office, NASA Science Mission Directory ([NASA TOPS](https://science.nasa.gov/open-science/transform-to-open-science)) -* [Steven Ramage](https://www.linkedin.com/in/stevenr/?originalSubdomain=fr), CEO of [Réseau](https://www.reseauconsulting.com/about) & Senior Business Advisor for United Nations - -### Panel at 20:30-21:30 UTC -* [Dr. Sheila Saia](https://www.linkedin.com/in/sheila-m-saia-phd-69427292/), Associate Director for [North Carolina State Climate Office](https://climate.ncsu.edu/) -* [Dr. Faten Attig-Bahar](https://scholar.google.com/citations?user=dBxY5CQAAAAJ&hl=en), University of Carthage, [Future Earth Water/Energy/Food Nexus](https://wefnexus.org/members/attig-bahar-faten/) \ No newline at end of file diff --git a/book/_build/html/_sources/projects/professional_development/impact_talks.ipynb b/book/_build/html/_sources/projects/professional_development/impact_talks.ipynb deleted file mode 100644 index 156c86aac..000000000 --- a/book/_build/html/_sources/projects/professional_development/impact_talks.ipynb +++ /dev/null @@ -1,499 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Impact Talks" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "How we do research or work on projects can be as important or more than the research and projects themselves. “Impact talks” were created to put an emphasis on the “**how**” and its implications when it comes to Climate Science and the current Climate crisis. \n", - "\n", - "In this activity, you will listen to four pre-recorded ~15 minutes talks and interviews with practitioners on selected topics followed by live discussion within student project groups, for a total time of 30 minutes (~15’ videos + ~15’ discussion).\n", - "\n", - "These interviews with practitioners in the field are designed to spark reflections and discussions among students about important topics that may not always be on the forefront of everyone's mind when thinking about Climate Science and Climate Change. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Guidance for discussions\n", - "\n", - "All talks will be watched in the first or the last half hour of the respective project slots and will be followed by a discussion within the project groups. \n", - "* These discussions will be an opportunity for students not only to delve deeper into the topics, but also to hone their leadership skills - all/most will get to lead the discussion, whether leading “from the front of from behind” \n", - "* For each talk, please decide during “pod introduction” who will be the two leaders: \n", - " * One student/leader will be tasked with leading the discussion \"from the front\" by \n", - " (1) reading out loud and putting on the chat the prompt being addressed, \n", - " (2) answering discussion prompts at first until the group warms up and others wish to answer or offer thoughts first, and \n", - " (3) encouraging everyone in the group to participate in the best way that suits each person(*). \n", - " * One student/leader will be tasked with leading the discussion \"from behind\" by \n", - " (1) keeping an eye on who has the microphone and respectfully encouraging all to share it, \n", - " (2) asking along the way of answering the prompt if any others wish to contribute thoughts whether speaking or via chat/text (*), and \n", - " (3) keeping track of time (**).\n", - "\n", - "*Remember that not everyone wishes to contribute to discussions in the same manner. Not all may wish to speak, but we want to provide space such that all have the opportunity to participate as they wish. Consider giving a few minutes to answer prompts individually and then share. Some may wish to draw or text instead of speaking, etc. and ideally both assigned leaders in the group can foster all kinds of participation.\n", - "\n", - "**You will have 30 minutes to both watch the video and start engaging in discussion; at least one assigned leader will keep track of time. This doesn’t mean all the prompts will be answered, but rather they can all get group and individual reflections started.\n", - "\n", - "Below you will see the title of four (4) themes, corresponding videos and discussion prompts." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Climate Justice\n", - "\n", - "### What is Climate Justice?\n", - "\n", - "Climate justice is about economic equity, security and gender equality and allows us to address climate issues from deeper and more interconnected perspectives.\n", - "\n", - "Ideally, we would find a balance between the countries of the Global North that emit more greenhouse gasses and those of the Global South that are more vulnerable to climate change. With this vision in mind, climate justice calls for climate action on three fronts: reduction of greenhouse gas emissions, adaptation to climate change and payment for the losses and damages that it is already producing.\n", - "\n", - "It is important to understand that climate justice will only be complete when it encompasses these three items. That is, when there is new and additional support and financing for vulnerable communities, not only for loss and damage, but also for adaptation and mitigation.\n", - "\n", - "### About the speaker\n", - "José’s keywords: mitigation, climate change, human rights, and legal consultant\n", - "\n", - "On the web: [José's LinkedIn](https://www.linkedin.com/in/jdrodorue/) & [World's Youth for Climate Justice](https://www.wy4cj.org/latin-america)\n", - "\n", - "Recent interviews, talks, & presentation: [Plataforma Boliviana Frente al Cambio Climático: COP27 (Spanish)](https://www.facebook.com/cambioclimaticobolivia/videos/1534658383661019/) & [Escazú Agreement and Biodiversity Goals (Spanish)](https://www.youtube.com/watch?v=IgiiH5_7GA4)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video featuring José Daniel Rodríguez-Orúe" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title featuring José Daniel Rodríguez-Orúe\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', 'JoPEpqUxMBU'), ('Bilibili', 'BV1jW4y1Z7zb')]\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)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "### Discussion prompts\n", - "\n", - "* Veronica starts off the video sharing how she defines Climate justice. How do you view it? What might be advantages or disadvantages of Veronica’s definition?\n", - "* José talks about how climate change widens and deepens existing inequalities within and outside of political boundaries. Have you observed examples of this wider and deeper gap in your region or community? What are some examples of how to address this. These can be examples you have seen in effect or something that has not yet been done but that you could see helping.\n", - "* As you can see, climate justice is a scientific, political, socio economic and legal challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing injustices, sometimes it takes more than that. From the video and discussion in your group, what is one small action you might implement to contribute to climate justice? " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Equity in Climate and Climate Science" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is Equity in Climate?\n", - "\n", - "Equity is a broad topic that centers on recognizing not all people have the same needs and not all people face the same barriers. Equity is a process, a way of doing, the “how”.\n", - "\n", - "“Equity is achieved by eliminating structural barriers resulting from historical and present-day inequities and meeting individuals', groups', and organizations' unique needs. - Lily Zheng , DEI Deconstructed” \n", - "\n", - "### Interview summary & highlights\n", - "\n", - "In this short video, speaker Juliana Arbeláez tells us about her experience with equity from the lens of a climate scientist, advocate, and science communicator. She shares her view and definition of “equity” and how it plays a role in her career, professional work and generally in the things she does. She shares about an initiative she leads called “Climatewiki”, which is an incredible platform used to share in Spanish about the impact of climate change, in particular from the latinamerican lens. Additionally, Juliana shares inequities she has found as a climate scientists, steps she hs takin to address this, and how we might take positive action to support communities that have been impacted negatively by bad/inequitable practices such as harassment, sexual harassment, and others that happen in climate science. Lastly, Juliana shares some takeaways and what you could do to support equity in climate science and/or climate solutions from an equity lens.\n", - "\n", - "### About the speaker \n", - "\n", - "Juliana’s keywords: mitigation, climate change, water, and science inclusivity\n", - "\n", - "On the web: [Juliana's Website](http://www.julianaarbelaez.com/) & [Juliana's Instagram](https://www.instagram.com/climatewiki)\n", - "\n", - "Recent interviews, talks, & presentations: [Three concepts of Climate Change (Spanish)](https://www.instagram.com/reel/Cr_ubmGgi4i/?utm_source=ig_web_copy_link&igshid=MzRlODBiNWFlZA==)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video featuring Juliana Arbeláez " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title featuring Juliana Arbeláez \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', 'c5WfuNCnWy4'), ('Bilibili', 'BV11m4y1E72e')]\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)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Discussion prompts\n", - "\n", - "\n", - "* Juliana mentioned how she views equity. How do you view equity? What might be advantages or disadvantages of Juliana’s definition?\n", - "* What are good ways to bring reliable information to the people who need it?\n", - "* In many cultures, there are still many expectations regarding which jobs, behaviors, and other life choices are appropriate based on gender, background etc. When you consider your home country and/or the country where you currently live\n", - " * Have you observed any of these? \n", - " * Do you think they are changing? Is there anyone challenging them in particular? \n", - " * Is anything done to challenge them or do you have any ideas what could be done?\n", - "* Can you think of further examples of traditional/indigenous knowledge that helps or could help with addressing climate change?\n", - "* As you can see, equity in climate and climate science is a scientific, political, and socio economic challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing inequities, sometimes it takes more than that. From the video and discussion in your group, what is one small action you might implement to contribute to equity in climate and/or climate science?" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Open Climate Science\n", - "\n", - "### What is Open Climate Science?\n", - "\n", - "Open Climate Science applies the best practices of the open science movement to climate science research. Its main goal is to openly share data, models, and findings in a manner that benefits the scientific community and the public.\n", - "\n", - "As Lubia Vinhas from the National Institute for Space Research of Brazil (Instituto Nacional de Pesquisas Espaciais, INPE) notes, \"Open Science is necessary if we want to trust, audit, and reproduce results.\"\n", - "\n", - "### Interview summary & highlights\n", - "\n", - "Professor Lubia Vinhas is a senior researcher at INPE, the Brazilian Space Research Institute. She has expertise in Remote Sensing, Software Development, and Open Science. Today, she will share her extensive experience as a researcher in Earth Observation and discuss open science, along with the open remote sensing project she contributed to, called [Brazil Data Cube]([http://www.brazildatacube.org/en/home-page-2/](http://www.brazildatacube.org/en/home-page-2/)).\n", - "\n", - "Lubia’s keywords: deforestation, monitoring and dissemination, GIS\n", - "\n", - "On the web: [Lubia's GitHub](https://github.com/lubiavinhas)\n", - "\n", - "Recent interviews, talks, & presentations: [Meet Lúbia Vinhas (Portuguese)](https://youtu.be/UzD8wLdz0Ns)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video featuring Lubia Vinhas " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title featuring Lubia Vinhas \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', 'g2upXZxXlrc'), ('Bilibili', 'BV1hz4y177Fn')]\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)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Discussion prompts\n", - "\n", - "* How do you think open science can help your community to fight climate change?\n", - "* What prevents scientists from openly sharing all research findings?\n", - "* Open Science and Ethics. What are some examples of how climate data is (or is not) important to the community? How could data be managed to increase both access and accessibility?\n", - "* As you can see, open climate science is a scientific, political, and socio economic challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing inequities, sometimes it takes more than that. From the video and discussion in your group, what is one small little action you might implement to contribute to open climate science?" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Psychology of the Climate Crisis and Climate Science Communication\n", - "\n", - "### What is the Psychology of the Climate Crisis?\n", - "\n", - "The climate crisis is the result of human behavior and, therefore, the science of Human Behavior Psychology is central to our understanding of why we are here. It addresses the question of what it is about human thought and behavior and the structures and systems that we have created that have led to the current crisis, why we are not responding as if we're in an emergency, and what we can do to change that. \n", - "\n", - "### Talk summary\n", - "\n", - "Psychological and behavioral explanations for the climate crisis are often centered on the quirky or flawed ways in which human cognition works. This includes our tendency to prioritize immediate rewards and satisfaction over future rewards, our tendency to be overly optimistic, and our decreased sensitivity to threats that happen far away or far in the future. \n", - "This narrative is very problematic because it essentially justifies the climate and biodiversity crisis as an inevitable product of universal human nature. A more productive view focuses on how social norms and the perceived belief of others shape human behavior and how effective communication about climate change and our own beliefs and actions can influence the behavior of individuals, communities, industry and policy makers.\n", - "\n", - "### About the speaker\n", - "\n", - "Professor Clare Kelly is a cognitive neuroscientist, who has been making a push to bring Climate Science into the curriculum of all undergraduate students. Additionally, she has designed a course on the psychology of the climate crisis specifically to help students understand what features of human behavior brought about the climate crisis and what prevents us from addressing this challenge appropriately. \n", - "\n", - "Clare's keywords: psychology, collective behavior, communicating climate change\n", - "\n", - "On the web: [Clare's research](https://immalab.wordpress.com/clare-kelly/)\n", - "\n", - "Recent interviews, talks, & presentation: [How to be a scientist in a world on fire?](https://www.youtube.com/watch?v=c1hDOtG-5mM)\n", - "\n", - "Further readings:\n", - "* [Economic Doughnut](https://en.wikipedia.org/wiki/Doughnut_%28economic_model%29)\n", - "* [Rethinking academia in a time of climate crisis](https://elifesciences.org/articles/84991)\n", - "* The Climate Crisis Needs Attention from Cognitive Scientists ([Abridges summary, open access](https://osf.io/t8s4k/), [Full article, closed access](https://www-sciencedirect-com.ezproxy.cul.columbia.edu/science/article/pii/S1364661319302025?via%3Dihub))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video featuring Clare Kelly " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title featuring Clare Kelly\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', 'zeHOBxG61RU'), ('Bilibili', 'BV1Su4y1U7aK')]\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)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Discussion prompts\n", - "\n", - "* How did you think human behavior influences the climate crises before you listened to the interview? Did this change after you listened to the interview?\n", - "* What social groups influence your perception of climate change? Do you agree with their ideas? How do they influence your thoughts and beliefs?\n", - "* Are there any visual graphics, blogs, songs or other means of non-academic communication that you think are especially good or inspiring?\n", - "* As you can see, climate science communication and the psychology of it is a scientific, political, and socio economic challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing inequities, sometimes it takes more than that. From the video and discussion in your group, what is one small little action you might implement to contribute to climate science communication and decrease the stigma of the psychological implications of the climate crisis?" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "climatematch", - "language": "python", - "name": "climatematch" - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/professional_development/mentors.md b/book/_build/html/_sources/projects/professional_development/mentors.md deleted file mode 100644 index 8e01497b2..000000000 --- a/book/_build/html/_sources/projects/professional_development/mentors.md +++ /dev/null @@ -1,64 +0,0 @@ -# Mentor Meetings - - -Our mentors have several years of experience working in any climate-related discipline, including industry, academia, government, non-profits, journalism, and science communication. - -They will visit project groups to speak about their professional path, share career advice, and provide a networking opportunity for the students. - -Teaching Assistants are welcome to attend up to two meetings with mentors as part of their working hours. - - -## Suggested meeting structure (~60 minutes) - - -### Introduction: 10 minutes - -Every student introduces themselves, shares what brings them to Climatematch Academy, and how they hope to use what they experience during the course in the near future. This will help students make more specific connections by the end of the hour. - - -### Mentor's Journey and Lessons: 10 minutes - -The mentor talks about who they are, what they have done and still do, any lessons they have learned, and the message they wish to share with the group. - - -### Questions and Answers: 30 minutes - -These are some questions that can be used as prompts: - -* General career-related questions: - * In your own opinion, what qualifications and background are required to succeed in your area of work? - * What are the biggest obstacles and opportunities you see in your field right now? - * How important would you say that diversity, equity, and inclusion are in your field? - * How can one acquire the practical experience required to enter your field? - * What do you wish you had known when you started working in your field? -* Specific career-related questions (might not be relevant to all mentors): - * How do you go about explaining difficult topics in your field to the public or decision-makers? Are there any particular difficulties or concerns you have faced? - * Do you have any suggestions for successful methods to close the gap between climate research and climate action? - * Can you shed any light on how interdisciplinary climate science is and the significance of working with other disciplines? -* General climate questions: - * In your opinion, how can climate justice be actualised and what are the major challenges (if you agree that there are)? - * How do you anticipate the climate will change? - * Can you suggest other mitigation and adaptation measures especially for the traditionally under-represented regions of the world? - * Are there any international partnerships or groups that, in your opinion, are particularly crucial to advancing the study of climate science and tackling climate challenges? - * Can you offer any tips or techniques for efficiently presenting climate science to various audiences, including skeptics or individuals with little prior knowledge of the subject? - * What else should people, communities, and governments do in your opinion to lessen the effects of climate change and prepare for them? - * What practical steps can one take to foster collaboration between climate-related disciplines? How important is it in your opinion? - - -### Networking and Collaboration: 10 minutes - -Using the information shared in the meeting, what are some specific ways the group could connect further? - - -## Get the most out of your meetings with mentors - -What makes a great mentee? - -* Great mentees love asking questions. You are encouraged to ask the mentors questions! -* Great mentees are willing to learn, open-minded and responsive to different perspectives. -* They take initiatives and look out for advancing their career and upgrading their skills. -* They cherish the advice and time of their mentors, demonstrate respect by being punctual and show appreciation for their mentor’s guidance and support. -* Great mentees respect limits while acting professionally when speaking with mentors. -* They typically behave morally and honestly, acting with integrity. - -We suggest that you ask lots of questions, enjoy your time with your mentors and stay in touch with them after the course! \ No newline at end of file diff --git a/book/_build/html/_sources/projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.ipynb b/book/_build/html/_sources/projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.ipynb deleted file mode 100644 index 33788921e..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.ipynb +++ /dev/null @@ -1,523 +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/ClimateMatchAcademy/course-content/blob/main/projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# **The Impact of ENSO on Precipitation and Temperature**\n", - "\n", - "**Content creators:** Olawale Ikuyajolu & Patrick Orenstein\n", - "\n", - "**Content reviewers:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content editors:** Zane Mitrevica, Natalie Steinemann, Jenna Pearson, Chi Zhang, Ohad Zivan\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": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "**In this project** you will work with climate model output, reanalysis data, and Niño 3.4 indices from CMIP5/6, ERA5, NOAA, and HadISST to understand the historical and future impacts of El Niño Southern Oscillation (ENSO) events on rainfall and temperature. You will focus on variables like sea surface temperature, surface air temperature, and precipitation. You will also be able to investigate the relationships between these variables and how they affect community efforts to prepare for the impacts of El Niño phases.\n", - "\n", - "Recall from W1D1 that ENSO is a climate phenomena that originates in the tropical Pacific ocean but has global impacts on atmospheric circulation, temperature and precipitation. The two phases of ENSO are El Niño (warmer than average SSTs in the central and eastern tropical Pacific Ocean) and La Niña (cooler than average SSTs in the central and eastern tropical Pacific Ocean). The Niño 3.4 region is an area in the central and eastern Pacific Ocean that is often used for determining the phase of ENSO.\n", - "\n", - "You may also reference W1D5, W2D1, and W2D4 tutorials on CMIP6 and read more about the different CMIP6 scenarios [here](https://www.dkrz.de/en/communication/climate-simulations/cmip6-en/the-ssp-scenarios). Please see the Resources section at the bottom of this notebook for more information.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "XfKMYIRrudl9" - }, - "source": [ - "# Project Template\n", - "\n", - "![Project Template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/ENSO_template_map.svg)\n", - "\n", - "*Note: The dashed boxes are socio-economic questions.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# Data Exploration Notebook\n", - "## Project Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 675 - }, - "executionInfo": { - "elapsed": 4174, - "status": "error", - "timestamp": 1685417505725, - "user": { - "displayName": "Natalie Steinemann", - "userId": "07104505925817819178" - }, - "user_tz": 240 - }, - "id": "9nDg6MeVY1CX", - "outputId": "5f15997d-3064-4f72-9446-8a99c2ab2f74", - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# google colab installs\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)\n", - "# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils \"esmf<=8.3.1\" xesmf &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "\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", - "import xesmf as xe\n", - "from xmip.preprocessing import combined_preprocessing\n", - "from xarrayutils.plotting import shaded_line_plot\n", - "from datatree import DataTree\n", - "from xmip.postprocessing import _parse_metric\n", - "import cartopy.crs as ccrs\n", - "import pooch\n", - "import os\n", - "import tempfile" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "WJLrmNkvC8YW", - "tags": [] - }, - "outputs": [], - "source": [ - "# functions\n", - "\n", - "%matplotlib inline\n", - "\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", - "\n", - "def load_cmip6(source_id, variable_id, member_id, table_id): # load selected model\n", - " cat = col.search(\n", - " source_id=source_ids,\n", - " variable_id=variable_id,\n", - " member_id=member_id,\n", - " table_id=table_id,\n", - " grid_label=\"gn\",\n", - " experiment_id=[\n", - " \"historical\",\n", - " \"ssp126\",\n", - " \"ssp245\",\n", - " \"ssp585\",\n", - " ], # downloading the scenarios out of the total 5+historical\n", - " require_all_on=[\"source_id\"],\n", - " )\n", - "\n", - " kwargs = dict(\n", - " preprocess=combined_preprocessing,\n", - " xarray_open_kwargs=dict(use_cftime=True),\n", - " storage_options={\"token\": \"anon\"},\n", - " )\n", - " cat.esmcat.aggregation_control.groupby_attrs = [\"source_id\", \"experiment_id\"]\n", - " dt = cat.to_datatree(**kwargs)\n", - "\n", - " return dt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "def pooch_load(filelocation=None,filename=None,processor=None):\n", - " shared_location='/home/jovyan/shared/Data/Projects/ENSO' # this is different for each day\n", - " user_temp_cache=tempfile.gettempdir()\n", - " \n", - " if os.path.exists(os.path.join(shared_location,filename)):\n", - " file = os.path.join(shared_location,filename)\n", - " else:\n", - " file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "iYblWn8cZAGT" - }, - "source": [ - "## Dataset 1: Load CMIP6 Model of Your Choice\n", - "\n", - "Following W2D1 (Week 2 Day 1) tutorial notebooks:\n", - "\n", - " * We use the *CESM2* model (*source_id*) and ensemble member *r4i1p1f1* (*member_id*) in this template, but you are free to select any model and ensemble member. Make sure the *member_id* selected is available for your model. You can learn more about the *member_id* and other CMIP6 facets through the links at the end of the [CMIP Resource Bank](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md)\n", - " \n", - " * `load_cmip6` function load both historical and ssp585 (future: climate change)\n", - " \n", - "To learn more about CMIP, including additional ways to access CMIP data, please see our [CMIP Resource Bank](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md) and the [CMIP website](https://wcrp-cmip.org/). \n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 238 - }, - "executionInfo": { - "elapsed": 4571, - "status": "ok", - "timestamp": 1683591426696, - "user": { - "displayName": "Natalie Steinemann", - "userId": "07104505925817819178" - }, - "user_tz": 240 - }, - "id": "L0flXmexD8V1", - "outputId": "58ee3e7b-34b9-408b-e733-11462b31786f", - "tags": [] - }, - "outputs": [], - "source": [ - "# pick your model\n", - "\n", - "source_ids = \"CESM2\"\n", - "\n", - "dm_tas = load_cmip6(\n", - " source_ids, \"tas\", \"r4i1p1f1\", \"Amon\"\n", - ") # tas is atmoerhpere temprature\n", - "dm_pr = load_cmip6(source_ids, \"pr\", \"r4i1p1f1\", \"Amon\") # pr is precipitation rate\n", - "dm_sst = load_cmip6(\n", - " source_ids, \"tos\", \"r4i1p1f1\", \"Omon\"\n", - ") # tos is surface ocean temprature\n", - "print(\n", - " dm_tas.keys()\n", - ") # an example for one of the datatrees, you can duplicate this for the other DT" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# load cell areas for computing ocean surface temparuters means\n", - "\n", - "dt_ocean_area = load_cmip6(source_ids, \"areacello\", \"r4i1p1f1\", \"Ofx\")\n", - "dt_atmos_area = load_cmip6(source_ids, \"areacella\", \"r4i1p1f1\", \"fx\")\n", - "\n", - "dt_ocean_with_area = DataTree()\n", - "dt_atmos_with_area = DataTree()\n", - "\n", - "for model, subtree in dm_sst.items():\n", - " metric_ocean = dt_ocean_area[model][\"historical\"].ds[\"areacello\"]\n", - " dt_ocean_with_area[model] = subtree.map_over_subtree(_parse_metric, metric_ocean)\n", - "\n", - "for model, subtree in dm_pr.items():\n", - " metric_atmos = dt_atmos_area[model][\"historical\"].ds[\"areacella\"]\n", - " dt_atmos_with_area[model] = subtree.map_over_subtree(_parse_metric, metric_atmos)\n", - "\n", - "print(dt_ocean_with_area.keys())" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "W43m6TQBZrpe" - }, - "source": [ - "## Dataset 2: Load Observations\n", - "\n", - "We use the NOAA Extended Reconstructed Sea Surface Temperature (ERSST) v5 product, a widely used and trusted gridded compilation of historical data going back to 1854. Since the data is provided via an OPeNDAP server, we can load it directly without downloading anything.\n", - "\n", - "For precipitation, we are using CPC Merged Analysis of Precipitation (CMAP). We can download this dataset from the NOAA PSL, Boulder, Colorado, USA website at https://psl.noaa.gov\n", - "\n", - "For air temperature, we are using anomalies from NASA GISS Surface Temperature Analysis which we can also download from NOAA PSL, Boulder, Colorado, USA website at https://psl.noaa.gov" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 6590, - "status": "ok", - "timestamp": 1683591495321, - "user": { - "displayName": "Natalie Steinemann", - "userId": "07104505925817819178" - }, - "user_tz": 240 - }, - "id": "drh-swqCsb9k", - "outputId": "287ef7e3-cdba-4156-a928-0c4a970e1b1d", - "tags": [] - }, - "outputs": [], - "source": [ - "# Ocean surface temprature \n", - "filename_SST='sst.mnmean.nc'\n", - "url_SST = 'https://downloads.psl.noaa.gov/Datasets/noaa.ersst.v5/sst.mnmean.nc'\n", - "\n", - "do_sst = xr.open_dataset(pooch_load(url_SST,filename_SST), drop_variables=['time_bnds'])\n", - "\n", - "# Precipitation rate (notice the units in the plot below)\n", - "filename_prec_rate='precip.mon.mean.nc'\n", - "url_prec_rate='https://downloads.psl.noaa.gov/Datasets/cmap/enh/precip.mon.mean.nc'\n", - "do_pr = xr.open_dataset(pooch_load(url_prec_rate,filename_prec_rate))\n", - "\n", - "# Air Temperature Anomalies\n", - "filename_tas='air.2x2.1200.mon.anom.comb.nc'\n", - "url_tas='https://downloads.psl.noaa.gov/Datasets/gistemp/combined/1200km/air.2x2.1200.mon.anom.comb.nc'\n", - "do_tas = xr.open_dataset(pooch_load(url_tas,filename_tas))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "9UbbKMMQbI0C" - }, - "source": [ - "We can now visualize the content of the dataset.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 535 - }, - "executionInfo": { - "elapsed": 12662, - "status": "ok", - "timestamp": 1683591527629, - "user": { - "displayName": "Natalie Steinemann", - "userId": "07104505925817819178" - }, - "user_tz": 240 - }, - "id": "BlAQNu898z5s", - "outputId": "33077141-2735-44c1-b7b1-fb12c38abf2f", - "tags": [] - }, - "outputs": [], - "source": [ - "# code to print the shape, array names, etc of the dataset\n", - "\n", - "# select just a single model and experiment\n", - "hist_precip = dm_pr[\"CESM2\"][\"historical\"].ds.pr\n", - "\n", - "fig, ax_july2000 = plt.subplots(\n", - " ncols=1, nrows=1, figsize=[12, 6], subplot_kw={\"projection\": ccrs.Robinson()}\n", - ")\n", - "\n", - "hist_precip.sel(time=\"2000-07\").squeeze().plot(\n", - " ax=ax_july2000,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " cmap=\"magma\",\n", - " robust=True,\n", - ")\n", - "\n", - "ax_july2000.coastlines()\n", - "ax_july2000.set_title(\"July 2000\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 498 - }, - "executionInfo": { - "elapsed": 3227037, - "status": "ok", - "timestamp": 1683594776518, - "user": { - "displayName": "Natalie Steinemann", - "userId": "07104505925817819178" - }, - "user_tz": 240 - }, - "id": "pnM2BKLbUX1Y", - "outputId": "78b474f9-a78a-47a2-cbde-f2c3ddcb4d28", - "tags": [] - }, - "outputs": [], - "source": [ - "hist_sst = dm_sst[\"CESM2\"][\"historical\"].ds.tos\n", - "\n", - "fig, ax = plt.subplots(\n", - " ncols=1,\n", - " nrows=1,\n", - " figsize=[12, 6],\n", - " subplot_kw={\"projection\": ccrs.Robinson(central_longitude=180)},\n", - ")\n", - "\n", - "ax.coastlines()\n", - "ax.gridlines()\n", - "hist_sst.sel(time=\"2000-07\").squeeze().plot(\n", - " ax=ax,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-2,\n", - " vmax=30,\n", - " cmap=\"magma\",\n", - " robust=True,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "WB1Y9Sls74DO" - }, - "source": [ - "## Dataset 3: Oceanic Nino Index\n", - "\n", - "There are several indices used to identify ENSO in the tropical Pacific Ocean. These indices are based on SST anomalies averaged across a given region and are used to define El Niño and La Niña events. Two indices that you will explore in this project are the Nino 3.4 Index and the Oceanic Niño Index (ONI). Both of these indices are averaged over the same region in the tropical Pacific (5N-5S, 170W-120W), but use different running means and criteria for identifying El Niño and La Niña events (i.e. for ONI, SST anomalies must exceed +/- 0.5C for at least five consecutive months to be defined as an ENSO event, whereas for Nino 3.4, SST anomalies must exceed +/- 0.4C for at least six consecutive months). You can find additional information about these indices [here](https://climatedataguide.ucar.edu/climate-data/nino-sst-indices-nino-12-3-34-4-oni-and-tni). For now, we will download the ONI data that we used in W1D3." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "cL9IYv3oTtt5", - "tags": [] - }, - "outputs": [], - "source": [ - "# get El Nino data from W1D3 tutorial 7\n", - "filename_nino='t6_oceanic-nino-index.nc'\n", - "url_nino = \"https://osf.io/8rwxb/download/\"\n", - "oni = xr.open_dataset(pooch_load(url_nino,filename_nino))\n", - "print(oni.keys())\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "tRLz4CMRFPD8" - }, - "source": [ - "# Further Reading\n", - "\n", - "- \"El Niño & La Niña (El Niño-Southern Oscillation)\", NOAA/Climate.gov (https://www.climate.gov/enso)\n", - "- \"El Niño and La Niña\", OCHA (https://www.unocha.org/themes/el-ni%C3%B1o/el-ni%C3%B1o-and-la-ni%C3%B1a)\n", - "- \"How will climate change change El Nino and La Nina?\", NOAA, 2020 (https://research.noaa.gov/2020/11/09/new-research-volume-explores-future-of-enso-under-influence-of-climate-change/)\n", - "- L'Heureux, M., Karamperidou, C., DiNezio, P., Karnauskas, K., Anyamba, A. 2023. \"El Niño and La Niña: Local and global effects\". Climate Central (https://www.climatecentral.org/climate-matters/local-and-global-effects-of-el-nino-and-la-nina-2023)\n", - "- Kelly, M. 2023. \"In Years After El Niño, Global Economy Loses Trillions\" (https://home.dartmouth.edu/news/2023/05/years-after-el-nino-global-economy-loses-trillions)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "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": { - "provenance": [], - "toc_visible": true - }, - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/project-notebooks/Heatwaves.ipynb b/book/_build/html/_sources/projects/project-notebooks/Heatwaves.ipynb deleted file mode 100644 index a18c912c6..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/Heatwaves.ipynb +++ /dev/null @@ -1,530 +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/ClimateMatchAcademy/course-content/blob/main/projects/project-notebooks/Heatwaves.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# **Heatwaves: Assessing the Dynamic Interactions of the Atmosphere and Land**\n", - "\n", - "**Content creators:** Sara Shamekh, Ibukun Joyce Ogwu\n", - "\n", - "**Content reviewers:** Sloane Garelick, Grace Lindsay, Douglas Rao, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Sloane Garelick, Zane Mitrevica, Natalie Steinemann, 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": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"wx7tu\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "The atmosphere and land are entwined components of the Earth's system, constantly exchanging energy, mass, and momentum. Their interaction contributes to a variety of physical and biological processes. Understanding of the dynamic interactions between atmosphere and land is crucial for predicting and mitigating the impacts of climate change, such as land-use changes and hazards ranging from droughts, floods, and even fluctuation in agricultural production and products ([Jach et. al., 2022](https://esd.copernicus.org/articles/13/109/2022/); [Ogwu et. al. 2018](https://www.researchgate.net/publication/325142745_Economics_of_Soil_Fertility_Management_Practices_in_Nigeria); [Dirmeyer et. al. 2016](https://journals.ametsoc.org/view/journals/bams/99/6/bams-d-17-0001.1.xml)). \n", - "\n", - "Climate change is also expected to have a significant impact on cereal production around the world. Changes in temperature, precipitation patterns, and extreme weather events can all affect crop yields, as well as the timing and quality of harvests. For example, higher temperatures can lead to reduced yields for crops like wheat and maize, while changes in rainfall patterns can result in droughts or floods that can damage crops or delay planting. \n", - "\n", - "In order to better understand the relationship between climate change and cereal production, researchers have begun to explore the use of environmental monitoring data, including air temperature and soil moisture, to help identify trends and patterns in crop production. By collecting and analyzing this data over time, it may be possible to develop more accurate models and predictions of how climate change will affect cereal production in different regions of the world.\n", - "\n", - "However, it is important to note that while environmental monitoring data can provide valuable insights, there are many other factors that can affect cereal production, including soil quality, pests and diseases, and agricultural practices. Therefore, any efforts to correlate cereal production with climate change must take into account a wide range of factors and be based on robust statistical analyses in order to ensure accurate and reliable results.\n", - "\n", - "**In this project**, you will look into how specific climate variables represent and influence our changing climate. In particular,you will explore various climate variables from model data to develop a more comprehensive understanding of different drivers of heatwaves (periods during which the temperature exceeds the climatological average for a certain number of consecutive days over a region larger than a specified value). You will further use this data to understand land-atmosphere interactions, and there will also be an opportunity to relate the aforementioned climate variables to trends in cereal production." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adR8NLN_ZsZL" - }, - "source": [ - "# Project Template\n", - "\n", - "![Project Template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/heatwaves_template_map.svg)\n", - "\n", - "*Note: The dashed boxes are socio-economic questions.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# Data Exploration Notebook\n", - "## Project Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 20235, - "status": "ok", - "timestamp": 1683293733394, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - }, - "id": "9nDg6MeVY1CX", - "outputId": "f1cc097f-fa40-43aa-d254-baefb6df6819", - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# google colab installs\n", - "# !pip install condacolab\n", - "# import condacolab\n", - "# condacolab.install()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 147674, - "status": "ok", - "timestamp": 1683293891793, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - }, - "id": "EpndpMWDHH77", - "outputId": "6e3b8857-e146-49e3-d4fd-c6cb47a9f194", - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "# !mamba install xarray-datatree intake intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils \"esmf<=8.3.1\" xesmf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "CfMgDACC0Voh", - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import time\n", - "\n", - "tic = time.time()\n", - "\n", - "import pandas as pd\n", - "import intake\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "import xesmf as xe\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\n", - "\n", - "import cartopy.crs as ccrs\n", - "import random\n", - "import pooch\n", - "import os\n", - "import tempfile" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "def pooch_load(filelocation=None,filename=None,processor=None):\n", - " shared_location='/home/jovyan/shared/Data/Projects/Heatwaves' # this is different for each day\n", - " user_temp_cache=tempfile.gettempdir()\n", - " \n", - " if os.path.exists(os.path.join(shared_location,filename)):\n", - " file = os.path.join(shared_location,filename)\n", - " else:\n", - " file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)\n", - "\n", - " return file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "ArM5hVaCf8wg", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "# model_colors = {k:f\"C{ki}\" for ki, k in enumerate(source_ids)}\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "iYblWn8cZAGT" - }, - "source": [ - "## CMIP6: Near Surface Temperature\n", - "\n", - "You will utilize a CMIP6 dataset to examine temperature trends and heatwaves, applying the CMIP6 loading methods intreduced in W2D1. To learn more about CMIP, including additional ways to access CMIP data, please see our [CMIP Resource Bank](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md) and the [CMIP website](https://wcrp-cmip.org/). \n", - "\n", - "Specifically, in this project you will focus on near-surface temperature, which refers to the air temperature at the Earth's surface. In this study, you will analyze data from one model and examining its historical temperature records. However, we encourage you to explore other models and investigate intermodel variability, as you learned (or will learn) during your exploration of CMIP datasets in the W2D1 tutorials.\n", - "\n", - "After selecting your model, you will plot the near-surface air temperature for the entire globe." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "oz-UJ18zghZ_", - "tags": [] - }, - "outputs": [], - "source": [ - "# loading CMIP data\n", - "\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", - "# 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 = [\"MPI-ESM1-2-LR\"]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 89 - }, - "executionInfo": { - "elapsed": 7005, - "status": "ok", - "timestamp": 1683293952187, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - }, - "id": "wAueMLq6BS3D", - "outputId": "8270c2be-2dac-4ab2-ede6-b1ab2be10cff", - "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=\"tas\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"3hr\",\n", - " grid_label=\"gn\",\n", - " experiment_id=[\"historical\"], # add scenarios if interested in projection\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", - "dt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 277, - "status": "ok", - "timestamp": 1682958563198, - "user": { - "displayName": "Sara Shamekh", - "userId": "08043700600081860152" - }, - "user_tz": 240 - }, - "id": "s4zo8k7hIaXm", - "outputId": "4dad2531-2e75-4859-d3f3-37930b685323", - "tags": [] - }, - "outputs": [], - "source": [ - "# select just a single model and experiment\n", - "tas_historical = dt[\"MPI-ESM1-2-LR\"][\"historical\"].ds.tas\n", - "print(\"The time range is:\")\n", - "print(\n", - " tas_historical.time[0].data.astype(\"M8[h]\"),\n", - " \"to\",\n", - " tas_historical.time[-1].data.astype(\"M8[h]\"),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "1N5K9Y_PNB3Z" - }, - "source": [ - "Now it's time to plot the data. For this initial analysis, we will focus on a specific date and time. As you may have noticed, we are using 3-hourly data, which allows us to also examine the diurnal and seasonal cycles. It would be fascinating to explore how the amplitude of the diurnal and seasonal cycles varies by region and latitude. You can explore this later!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 610 - }, - "executionInfo": { - "elapsed": 4750, - "status": "ok", - "timestamp": 1682958530296, - "user": { - "displayName": "Sara Shamekh", - "userId": "08043700600081860152" - }, - "user_tz": 240 - }, - "id": "zUsAdeMT1XnI", - "outputId": "e02ed21f-08b2-47a1-f66d-431963ac016c", - "tags": [] - }, - "outputs": [], - "source": [ - "fig, ax_present = plt.subplots(\n", - " figsize=[12, 6], subplot_kw={\"projection\": ccrs.Robinson()}\n", - ")\n", - "\n", - "# plot a timestep for July 1, 2013\n", - "tas_present = tas_historical.sel(time=\"2013-07-01T00\").squeeze()\n", - "tas_present.plot(ax=ax_present, transform=ccrs.PlateCarree(), cmap=\"magma\", robust=True)\n", - "ax_present.coastlines()\n", - "ax_present.set_title(\"July, 1st 2013\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adHRNDL6EMx-" - }, - "source": [ - "### CMIP6: Precipitation and Soil Moisture (Optional)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "fJvuC3wf2PKm" - }, - "source": [ - "In addition to examining temperature trends, you can also load precipitation data or variables related to soil moisture. This is an optional exploration, but if you choose to do so, you can load regional precipitation data at the same time and explore how these two variables are related when analyzing regional temperature trends. This can provide insights into how changes in temperature and precipitation may be affecting the local environment." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "xqiXjDKC9G2M" - }, - "source": [ - "The relationship between soil moisture, vegetation, and temperature is an active field of research. To learn more about covariability of temperature and moisture, you can have a look at [Dong et al. (2022)](https://agupubs.onlinelibrary.wiley.com/doi/10.1029/2021GL097697) or [Humphrey et al. (2021)](https://www.nature.com/articles/s41586-021-03325-5). " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## World Bank Data: Cereal Production and Land Under Cereal Production\n", - "\n", - "Cereal production is a crucial component of global agriculture and food security. The World Bank collects and provides data on cereal production, which includes crops such as wheat, rice, maize, barley, oats, rye, sorghum, millet, and mixed grains. The data covers various indicators such as production quantity, area harvested, yield, and production value.\n", - "\n", - "The World Bank also collects data on land under cereals production, which refers to the area of land that is being used to grow cereal crops. This information can be valuable for assessing the productivity and efficiency of cereal production systems in different regions, as well as identifying potential areas for improvement. Overall, the World Bank's data on cereal production and land under cereals production is an important resource for policymakers, researchers, and other stakeholders who are interested in understanding global trends in agriculture and food security." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# code to retrieve and load the data\n", - "filename_cereal = 'data_cereal_land.csv'\n", - "url_cereal = 'https://raw.githubusercontent.com/Sshamekh/Heatwave/f85f43997e3d6ae61e5d729bf77cfcc188fbf2fd/data_cereal_land.csv'\n", - "ds_cereal_land = pd.read_csv(pooch_load(url_cereal,filename_cereal))\n", - "ds_cereal_land.head() " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "odsYWhF2xOL8" - }, - "source": [ - "### Hint for Q7: Heatwave Detection\n", - "\n", - "Question 7 asks you to detect heatwave. Below you can see a flowchart for detecting heatwaves. The flowchart includes three parameters that you need to set in adavance. These three parameters are:\n", - "1. **w-day:** the window (number of days) over which you detect the extreme (95 percentile) of temperature.\n", - "2. **E (km2):** the spatial extent of the heatwave.\n", - "3. **X (days):** the duration of heatwave. \n", - "\n", - "\n", - "![picture](https://raw.githubusercontent.com/Sshamekh/Heatwave/e7ae59ac394b0a9a040bcc4f58009ab478a3daa8/Heat_wave_detection_flewchart.jpg)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Hint for Q9: Correlation\n", - "For Question 9 you need to compute the correlation between two variables. You can use Pearson's correlation coefficient to evaluate the correlation between two variables. You can read about Pearsons correlation coefficient [on Wikipedia](https://en.wikipedia.org/wiki/Pearson_correlation_coefficient) and from [Scipy python library](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.pearsonr.html). You are also encouraged to plot the scatter plot between two variables to visually see their correlation. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Hint for Q12: Linear Regressions for Heatwave Detection\n", - "For Question 12, read the following article: [Rousi et al. (2022)](https://www.nature.com/articles/s41467-022-31432-y.pdf)\n", - "\n", - "For Question 12 you need to build the regession model. You can read abut regression models [on Wikipedia](https://en.wikipedia.org/wiki/Simple_linear_regression) and from [Scipy python library](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Hint for Q13: Data-Driven Approaches for Heatwave Detection\n", - "For Question 13, read the following articles: [Li et al. (2023)](https://agupubs.onlinelibrary.wiley.com/doi/pdfdirect/10.1029/2023GL103405) and [Jacques-Dumas et al. (2022)](https://www.frontiersin.org/articles/10.3389/fclim.2022.789641/full)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "e5KKmsTujjAg" - }, - "source": [ - "# Further Reading\n", - "\n", - "- Dirmeyer, P. A., Gochis, D. J., & Schultz, D. M. (2016). Land-atmosphere interactions: the LoCo perspective. Bulletin of the American Meteorological Society, 97(5), 753-771.\n", - "\n", - "- Ogwu I. J., Omotesho, O. A. and Muhammad-Lawal, A., (2018) Chapter 11: Economics of Soil Fertility Management Practices in Nigeria in the book by Obayelu, A. E. ‘Food Systems Sustainability and Environmental Policies in Modern Economies’ (pp. 1-371).Hershey, PA: IGI Global. doi:10.4018/978-1-5225-3631-4 \n", - "\n", - "- Jach, L., Schwitalla, T., Branch, O., Warrach-Sagi, K., and Wulfmeyer, V. (2022) Sensitivity of land–atmosphere coupling strength to changing atmospheric temperature and moisture over Europe, Earth Syst. Dynam., 13, 109–132, https://doi.org/10.5194/esd-13-109-2022\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "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": { - "provenance": [], - "toc_visible": true - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/project-notebooks/Ocean_acidification.ipynb b/book/_build/html/_sources/projects/project-notebooks/Ocean_acidification.ipynb deleted file mode 100644 index 8a27a3238..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/Ocean_acidification.ipynb +++ /dev/null @@ -1,461 +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/ClimateMatchAcademy/course-content/blob/main/projects/project-notebooks/Ocean_acidification.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# **Ocean Acidification**\n", - "\n", - "\n", - "**Content creators:** C. Gabriela Mayorga Adame, Lidia Krinova\n", - "\n", - "**Content reviewers:** Jenna Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Content editors:** Zane Mitrevica, Natalie Steinemann, Ohad Zivan, Chi Zhang, Jenna Pearson\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS, Google DeepMind" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Project Background\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(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', 'NAgrB8HxMMk'), ('Bilibili', 'BV1fM4y1x7g8')]\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": {}, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"n7wdy\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "Human activities release CO2 into the atmosphere, which leads to atmospheric warming and climate change. A portion of this CO2 released by human activities is absorbed into the oceans, which has a direct, chemical effect on seawater, known as ocean acidification. When CO2 combines with water in the ocean it forms carbonic acid, which makes the ocean more acidic and can have negative impacts on certain marine ecosystems (e.g., reduce the ability of calcifying organisms to form their shells and skeletons). The degree of ocean acidification is often expressed in terms of the pH of seawater, which is the measure of acidity or alkalinity such that a pH below 7 is considered acidic, and a pH greater than 7 is considered alkaline, or basic. Additional background information on ocean acidification can be found [here](https://coastadapt.com.au/ocean-acidification-and-its-effects). In this project, you will explore spatial and temporal patterns of and relationships between pH, CO2, and temperature to assess changes in ocean acidification and the impact on marine ecosystems.\n", - "\n", - "**In this project**, you will analyse ocean model and observational data from global databases to extract variables like pH, CO2, and temperature, and to investigate ocean acidification process in your region of interest. This project will also be an opportunity to investigate the relationships between these variables as well as their impact on the marine ecosystems." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "B2hG2V_2veFC" - }, - "source": [ - "# Project Template\n", - "\n", - "![Project Template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/ocean_acidification_template_map.svg)\n", - "\n", - "*Note: The dashed boxes are socio-economic questions.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# Data Exploration Notebook\n", - "## Project Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 6642, - "status": "ok", - "timestamp": 1684025369728, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - }, - "id": "drh-swqCsb9k", - "outputId": "c889805c-2e31-402d-9bfd-a6c97cfe8ed6", - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# google colab installs\n", - "\n", - "# !mamaba install netCDF4" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "9nDg6MeVY1CX", - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import random\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "import pooch\n", - "import pandas as pd\n", - "import os\n", - "import tempfile" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "def pooch_load(filelocation=None,filename=None,processor=None):\n", - " shared_location='/home/jovyan/shared/Data/Projects/Ocean_Acidification' # this is different for each day\n", - " user_temp_cache=tempfile.gettempdir()\n", - " \n", - " if os.path.exists(os.path.join(shared_location,filename)):\n", - " file = os.path.join(shared_location,filename)\n", - " else:\n", - " file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "iYblWn8cZAGT" - }, - "source": [ - "## NOAA Ocean pH and Acidity" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "W43m6TQBZrpe" - }, - "source": [ - "### Global surface ocean acidification indicators from 1750 to 2100 (NCEI Accession 0259391)\n", - "\n", - "This data package contains a hybrid surface ocean acidification (OA) data product that is produced based on three recent observational data products:\n", - "- Surface Ocean CO2 Atlas (SOCAT, version 2022)\n", - "- Global Ocean Data Analysis Product version 2 (GLODAPv2, version 2022)\n", - "- Coastal Ocean Data Analysis Product in North America (CODAP-NA, version 2021), and 14 Earth System Models from the sixth phase of the Coupled Model Intercomparison Project ([CMIP6](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md)).\n", - "\n", - "The trajectories of ten OA indicators are included in this data product:\n", - "- Fugacity of carbon dioxide\n", - "- pH on Total Scale\n", - "- Total hydrogen ion content\n", - "- Free hydrogen ion content\n", - "- Carbonate ion content\n", - "- Aragonite saturation state\n", - "- Calcite saturation state\n", - "- Revelle Factor\n", - "- Total dissolved inorganic carbon content\n", - "- Total alkalinity content\n", - "\n", - "These OA trajectories are provided under preindustrial conditions, historical conditions, and future Shared Socioeconomic Pathways: SSP1-1.9, SSP1-2.6, SSP2-4.5, SSP3-7.0, and SSP5-8.5 from 1750 to 2100 on a global surface ocean grid. These OA trajectories are improved relative to previous OA data products with respect to data quantity, spatial and temporal coverage, diversity of the underlying data and model simulations, and the provided SSPs over the 21st century.\n", - "\n", - "**Citation:** \n", - "Jiang, L.-Q., Dunne, J., Carter, B. R., Tjiputra, J. F., Terhaar, J., Sharp, J. D., et al. (2023). Global surface ocean acidification indicators from 1750 to 2100. Journal of Advances in Modeling Earth Systems, 15, e2022MS003563. https://doi.org/10.1029/2022MS003563\n", - "\n", - "**Dataset**: https://www.ncei.noaa.gov/data/oceans/ncei/ocads/metadata/0259391.html\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "xqiXjDKC9G2M" - }, - "source": [ - "We can load and visualize the **surface pH** as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 2788, - "status": "ok", - "timestamp": 1684025378922, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - }, - "id": "mZMo14eJs26r", - "outputId": "3efc4132-229b-4790-ef27-af53b2be5386", - "tags": [] - }, - "outputs": [], - "source": [ - "# code to retrieve and load the data\n", - "# url_SurfacepH= 'https://www.ncei.noaa.gov/data/oceans/ncei/ocads/data/0206289/Surface_pH_1770_2100/Surface_pH_1770_2000.nc' $ old CMIP5 dataset\n", - "filename_SurfacepH='pHT_median_historical.nc'\n", - "url_SurfacepH='https://www.ncei.noaa.gov/data/oceans/ncei/ocads/data/0259391/nc/median/pHT_median_historical.nc'\n", - "ds_pH = xr.open_dataset(pooch_load(url_SurfacepH,filename_SurfacepH))\n", - "ds_pH" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "S6fZBOG00xW6" - }, - "source": [ - "For those feeling adventurouts, there are also files of future projected changes under various scenarios (SSP1-1.9, SSP1-2.6, SSP2-4.5, SSP3-7.0, and SSP5-8.5, recall W2D1 tutorials): \n", - "* pHT_median_ssp119.nc \n", - "* pHT_median_ssp126.nc\n", - "* pHT_median_ssp245.nc \n", - "* pHT_median_ssp370.nc\n", - "* pHT_median_ssp585.nc\n", - "\n", - "To load them, replace the filename in the path/filename line above. These data were calculated from CMIP6 models. To learn more about CMIP please see our [CMIP Resource Bank](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md) and the [CMIP website](https://wcrp-cmip.org/). " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "pqD42yn7vOnG" - }, - "source": [ - "## Copernicus\n", - "\n", - "Copernicus is the Earth observation component of the European Union’s Space programme, looking at our planet and its environment to benefit all European citizens. It offers information services that draw from satellite Earth Observation and in-situ (non-space) data.\n", - "\n", - "The European Commission manages the Programme. It is implemented in partnership with the Member States, the European Space Agency (ESA), the European Organisation for the Exploitation of Meteorological Satellites (EUMETSAT), the European Centre for Medium-Range Weather Forecasts (ECMWF), EU Agencies and Mercator Océan.\n", - "\n", - "Vast amounts of global data from satellites and ground-based, airborne, and seaborne measurement systems provide information to help service providers, public authorities, and other international organisations improve European citizens' quality of life and beyond. The information services provided are free and openly accessible to users.\n", - "\n", - "**Source**: https://www.copernicus.eu/en/about-copernicus" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "k9F0UYYTv31x" - }, - "source": [ - "### ECMWF Atmospheric Composition Reanalysis: Carbon Dioxide (CO2)\n", - "\n", - "From this dataset we will use **CO2 column-mean molar fraction** from the Single-level chemical vertical integrals variables & **Sea Surface Temperature** from the Single-level meteorological variables (in case you need to download them direclty from the catalog). \n", - "\n", - "This dataset is part of the [ECMWF Atmospheric Composition Reanalysis focusing on long-lived greenhouse gases: carbon dioxide (CO2) and methane (CH4)](https://www.copernicus.eu/en/access-data/copernicus-services-catalogue/cams-global-ghg-reanalysis-egg4-monthly). The emissions and natural fluxes at the surface are crucial for the evolution of the long-lived greenhouse gases in the atmosphere. In this dataset the CO2 fluxes from terrestrial vegetation are modelled in order to simulate the variability across a wide range of scales from diurnal to inter-annual. The CH4 chemical loss is represented by a climatological loss rate and the emissions at the surface are taken from a range of datasets.\n", - "\n", - "Reanalysis combines model data with observations from across the world into a globally complete and consistent dataset using a model of the atmosphere based on the laws of physics and chemistry. This principle, called data assimilation, is based on the method used by numerical weather prediction centres and air quality forecasting centres, where every so many hours (12 hours at ECMWF) a previous forecast is combined with newly available observations in an optimal way to produce a new best estimate of the state of the atmosphere, called analysis, from which an updated, improved forecast is issued. Reanalysis works in the same way to allow for the provision of a dataset spanning back more than a decade. Reanalysis does not have the constraint of issuing timely forecasts, so there is more time to collect observations, and when going further back in time, to allow for the ingestion of improved versions of the original observations, which all benefit the quality of the reanalysis product.\n", - "\n", - "**Source & further information:** https://ads.atmosphere.copernicus.eu/cdsapp#!/dataset/cams-global-ghg-reanalysis-egg4-monthly?tab=overview\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "OcwO6XpY3rOS" - }, - "source": [ - "We can load and visualize the **sea surface temperature** and **CO2 concentration** (from [NOAA Global Monitoring Laboratory](https://gml.noaa.gov/ccgg/trends/gl_data.html)):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "rF3Z4CwmwE1K", - "tags": [] - }, - "outputs": [], - "source": [ - "filename_CO2= 'co2_mm_gl.csv'\n", - "url_CO2= 'https://gml.noaa.gov/webdata/ccgg/trends/co2/co2_mm_gl.csv'\n", - "ds_CO2 = pd.read_csv(pooch_load(url_CO2,filename_CO2),header=55)\n", - "\n", - "ds_CO2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# from W1D3 tutorial 6 we have Sea Surface Temprature from 1981 to the present:\n", - "# download the monthly sea surface temperature data from NOAA Physical System\n", - "# Laboratory. The data is processed using the OISST SST Climate Data Records\n", - "# from the NOAA CDR program.\n", - "# the data downloading may take 2-3 minutes to complete.\n", - "\n", - "filename_sst='sst.mon.mean.nc'\n", - "url_sst = \"https://osf.io/6pgc2/download/\"\n", - "\n", - "ds_SST = xr.open_dataset(pooch_load(url_sst,filename_sst))\n", - "ds_SST" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Hint for question 4:**\n", - "\n", - "Use the attached image (figure 5 in this [website](https://coastadapt.com.au/ocean-acidification-and-its-effects)) and this [mapping tool](https://mapper.obis.org/). Search for each species on the mapping tool to see the spatial global distribution." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "![effects of ocean acidifaction](https://coastadapt.com.au/sites/default/files/coastadapt_image/T2I3_Figure%205.jpg)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Further Reading\n", - "\n", - "- Understanding Ocean Acidification\", NOAA (https://www.fisheries.noaa.gov/insight/understanding-ocean-acidification)\n", - "- \"Ocean acidification and its effects\", CoastAdapt (https://coastadapt.com.au/ocean-acidification-and-its-effects)\n", - "- \"Scientists Pinpoint How Ocean Acidification Weakens Coral Skeletons\", WHOI (https://www.whoi.edu/press-room/news-release/scientists-identify-how-ocean-acidification-weakens-coral-skeletons/)\n", - "- \"Ocean acidification and reefs\", Smithonian Tropical Research Institute (https://stri.si.edu/story/ocean-acidification-and-reefs)\n", - "- Henry, Joseph, Joshua Patterson, and Lisa Krimsky. 2020. “Ocean Acidification: Calcifying Marine Organisms: FA220, 3/2020”. EDIS 2020 (2):4. https://doi.org/10.32473/edis-fa220-2020.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "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": { - "provenance": [], - "toc_visible": true - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/project-notebooks/Regional_precipitation_variability.ipynb b/book/_build/html/_sources/projects/project-notebooks/Regional_precipitation_variability.ipynb deleted file mode 100644 index 41fddfdf0..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/Regional_precipitation_variability.ipynb +++ /dev/null @@ -1,562 +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/ClimateMatchAcademy/course-content/blob/main/projects/project-notebooks/Regional_precipitation_variability.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# Regional Precipitation Variability and Extreme Events\n", - "\n", - "**Content creators:** Laura Paccini, Raphael Rocha\n", - "\n", - "**Content reviewers:** Marguerite Brown, Ohad Zivan, Jenna Pearson, Chi Zhang\n", - "\n", - "**Content editors:** Zane Mitrevica, Natalie Steinemann, Douglas Rao, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Project Background\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(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', '49XHRe61LI8'), ('Bilibili', 'BV1Au411L7fo')]\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": { - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"a53b4\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "**In this project**, you will explore rain gauge and satellite data from CHIRPS and NOAA Terrestrial Climate Data Records NDVI datasets to extract rain estimates and land surface reflectance, respectively. This data will enable identification of extreme events in your region of interest. Besides investigating the relationships between these variables, you are encouraged to study the impact of extreme events on changes in vegetation." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adR8NLN_ZsZL" - }, - "source": [ - "# Project Template\n", - "![Project Template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/precipitation_template_map.svg)\n", - "\n", - "*Note: The dashed boxes are socio-economic questions.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# Data Exploration Notebook\n", - "## Project Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "9nDg6MeVY1CX", - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import pandas as pd\n", - "import s3fs\n", - "import boto3\n", - "import botocore\n", - "import datetime" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "def pooch_load(filelocation=None,filename=None,processor=None):\n", - " shared_location='/home/jovyan/shared/Data/Projects/Precipitation' # this is different for each day\n", - " user_temp_cache=tempfile.gettempdir()\n", - " \n", - " if os.path.exists(os.path.join(shared_location,filename)):\n", - " file = os.path.join(shared_location,filename)\n", - " else:\n", - " file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "W43m6TQBZrpe" - }, - "source": [ - "## CHIRPS Version 2.0 Global Daily 0.25°\n", - "\n", - "The Climate Hazards Group InfraRed Precipitation with Station data (CHIRPS) is a high-resolution precipitation dataset developed by the Climate Hazards Group at the University of California, Santa Barbara. It combines satellite-derived precipitation estimates with ground-based station data to provide gridded precipitation data at a quasi-global scale between 50°S-50°N. \n", - "\n", - "Read more about CHIRPS here:\n", - "\n", - "* [The climate hazards infrared precipitation with stations—a new environmental record for monitoring extremes](https://www.nature.com/articles/sdata201566)\n", - "\n", - "* [Climate Hazard Group CHG Wiki](https://wiki.chc.ucsb.edu/CHIRPS_FAQ)\n", - "\n", - "* [Data storage location](https://data.chc.ucsb.edu/products/CHIRPS-2.0/global_daily/netcdf/p25/)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "tKj2wyLIrmMQ" - }, - "source": [ - "### Indices for Extreme Events\n", - "The Expert Team on Climate Change Detection and Indices ([ETCCDI]( http://etccdi.pacificclimate.org/list_27_indices.shtml)) has defined various indices that focus on different aspects such as duration or intensity of extreme events. The following functions provide examples of how to compute indices for each category. You can modify these functions to suit your specific needs or create your own custom functions. Here are some tips you can use:\n", - "\n", - "- Most of the indices require daily data, so in order to select a specific season you can just use xarray to subset the data. Example:\n", - "\n", - "`daily_precip_DJF = data_chirps.sel(time=data_chirps['time.season']=='DJF')`\n", - "\n", - "- A common threshold for a wet event is precipitation greater than or equal to 1mm/day, while a dry (or non-precipitating) event is defined as precipitation less than 1mm/day.\n", - "- Some of the indices are based on percentiles. You can define a base period climatology to calculate percentile thresholds, such as the 5th, 10th, 90th, and 95th percentiles, to determine extreme events." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "xPE5u-H0hZVS", - "tags": [] - }, - "outputs": [], - "source": [ - "def calculate_sdii_index(data):\n", - " \"\"\"\n", - " This function calculates the Simple Daily Intensity Index (SDII), which\n", - " represents the average amount of precipitation on wet days (days with\n", - " precipitation greater than or equal to 1mm) for each year in the input data.\n", - " The input data should be a Dataset with time coordinates, and the function\n", - " returns a Dataset with the SDII index values for each year in the data.\n", - " ----------\n", - " - data (xarray.Dataset): Input dataset containing daily precipitation data.\n", - " - period (str, optional): Period for which to calculate the SDII index.\n", - "\n", - " Returns:\n", - " -------\n", - " - xarray.Dataset: Dataset containing the SDII index for the given period.\n", - " \"\"\"\n", - " # calculate daily precipitation amount on wet days (PR >= 1mm)\n", - " wet_days = data.where(data >= 1)\n", - "\n", - " # group by year and calculate the sum precipitation on wet days\n", - " sum_wet_days_grouped = wet_days.groupby(\"time.year\").sum(dim=\"time\")\n", - "\n", - " # count number of wet days for each time step\n", - " w = wet_days.groupby(\"time.year\").count(dim=\"time\")\n", - "\n", - " # divide by the number of wet days to get SDII index\n", - " sdii = sum_wet_days_grouped / w\n", - "\n", - " return sdii" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "1EKC69d76nZg", - "tags": [] - }, - "outputs": [], - "source": [ - "def calculate_cdd_index(data):\n", - " \"\"\"\n", - " This function takes a daily precipitation dataset as input and calculates\n", - " the Consecutive Dry Days (CDD) index, which represents the longest sequence\n", - " of consecutive days with precipitation less than 1mm. The input data should\n", - " be a DataArray with time coordinates, and the function returns a DataArray\n", - " with the CDD values for each unique year in the input data.\n", - " Parameters:\n", - " ----------\n", - " - data (xarray.DataArray): The input daily precipitation data should be\n", - " a dataset (eg. for chirps_data the SataArray would be chirps_data.precip)\n", - " Returns:\n", - " -------\n", - " - cdd (xarray.DataArray): The calculated CDD index\n", - "\n", - " \"\"\"\n", - " # create a boolean array for dry days (PR < 1mm)\n", - " dry_days = data < 1\n", - " # initialize CDD array\n", - " cdd = np.zeros(len(data.groupby(\"time.year\")))\n", - " # get unique years as a list\n", - " unique_years = list(data.groupby(\"time.year\").groups.keys())\n", - " # iterate for each day\n", - " for i, year in enumerate(unique_years):\n", - " consecutive_trues = []\n", - " current_count = 0\n", - " for day in dry_days.sel(time=data[\"time.year\"] == year).values:\n", - " if day:\n", - " current_count += 1\n", - " else:\n", - " if current_count > 0:\n", - " consecutive_trues.append(current_count)\n", - " current_count = 0\n", - " if current_count > 0:\n", - " consecutive_trues.append(current_count)\n", - " # print(consecutive_trues)\n", - " # CDD is the largest number of consecutive days\n", - " cdd[i] = np.max(consecutive_trues)\n", - " # transform to dataset\n", - " cdd_da = xr.DataArray(cdd, coords={\"year\": unique_years}, dims=\"year\")\n", - " return cdd_da" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "rXy1foR4DuBY", - "tags": [] - }, - "outputs": [], - "source": [ - "# code to retrieve and load the data\n", - "\n", - "years=range(1981,2024) # the years you want. we want 1981 till 2023\n", - "file_paths=['https://data.chc.ucsb.edu/products/CHIRPS-2.0/global_daily/netcdf/p25/chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files\n", - "filenames=['chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files\n", - "\n", - "downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files\n", - "\n", - "#### open data as xarray\n", - "chirps_data = xr.open_mfdataset(\n", - " downloaded_files, combine=\"by_coords\"\n", - ") # open the files as one dataset" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "9UbbKMMQbI0C" - }, - "source": [ - "We can now visualize the content of the dataset.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 270 - }, - "id": "BlAQNu898z5s", - "outputId": "6c6260ce-fd88-4195-a327-6f9426991051", - "tags": [] - }, - "outputs": [], - "source": [ - "# code to print the shape, array names, etc of the dataset\n", - "chirps_data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "pSUjOHGqFPD7" - }, - "source": [ - "## NOAA Fundamental Climate Data Records (FCDR) AVHRR Land Bundle - Surface Reflectance and Normalized Difference Vegetation Index\n", - "\n", - "As we learned in the W1D3 tutorials, all the National Atmospheric and Oceanic Administration Climate Data Record (NOAA-CDR) datasets are available both at NOAA National Centers for Environmental Information (NCEI) and commercial cloud platforms. See the link [here](https://registry.opendata.aws/noaa-cdr-terrestrial/). We are accessing the data directly via the [Amazon Web Service (AWS) cloud storage space](https://noaa-cdr-ndvi-pds.s3.amazonaws.com/index.html).\n", - "\n", - "For this project we recommend using the Normalized Difference Vegetation Index (NDVI). It is one of the most commonly used remotely sensed indices. It measures the \"greeness\" of vegetation, and is useful in understanding vegetation density and assessing changes in plant health. For example, NDVI can be used to study the impacts of droughts, heatwaves, and insect infestations on plants covering Earth's surface. A good overview of this index from this particular sensor can be accessed [here](https://digitalcommons.unl.edu/nasapub/217/).\n", - "\n", - "Recall what we learned in W1D3 Tutorial 3, the data files on AWS are named systematically:\n", - "\n", - "> Sensor name: `AVHRR` \n", - "> Product category: `Land` \n", - "> Product version: `v005` \n", - "> Product code: `AVH13C1` \n", - "> Satellite platform: `NOAA-07` \n", - "> Date of the data: `19810624` \n", - "> Processing time: `c20170610041337` (*This will change for each file based on when the file was processed*) \n", - "> File format: `.nc` (*netCDR-4 format*)\n", - "\n", - "In other words, if we are looking for the data of a specific day, we can easily locate where the file might be. \n", - "\n", - "For example, if we want to find the AVHRR data for the day of *2002-03-12 (or March 12, 2002)*, you can use:\n", - "\n", - "`s3://noaa-cdr-ndvi-pds/data/2002/AVHRR-Land_v005_AVH13C1_*_20020312_c*.nc`\n", - "\n", - "The reasaon that we put `*` in the above directory is because we are not sure about what satellite platform this data is from and when the data was processed. The `*` is called a **wildcard**, and is used because we want *all* the files that contain our specific criteria, but do not want to have to specify all the other pieces of the filename we are not sure about yet. It should return all the data satisfying that initial criteria and you can refine further once you see what is available. Essentially, this first step helps to narrow down the data search. You can then use this to create datasets from the timeframe of your choosing.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# we can use the data from W1D3 tutorial 3\n", - "# to access the NDVI data from AWS S3 bucket, we first need to connect to s3 bucket\n", - "\n", - "fs = s3fs.S3FileSystem(anon=True)\n", - "client = boto3.client('s3', config=botocore.client.Config(signature_version=botocore.UNSIGNED)) # initialize aws s3 bucket client\n", - "date_sel = datetime.datetime(2001,1,1,0) \n", - "file_location = fs.glob('s3://noaa-cdr-ndvi-pds/data/'+\n", - " date_sel.strftime('%Y')+'/AVHRR-Land_v005_AVH13C1_*_c*.nc') # the files we want for a whole year\n", - "files_for_pooch=[pooch_load('http://s3.amazonaws.com/'+file,file) for file in file_location]\n", - "\n", - "ds = xr.open_mfdataset(files_for_pooch, combine=\"by_coords\") # open the file\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Alternative NDVI source: MODIS/Terra Vegetation Indices (MOD13C2) Version 6.1 L3 Global 0.05° CMG\n", - "\n", - "Global MODIS (Moderate Resolution Imaging Spectroradiometer) vegetation indices are designed to provide consistent spatial and temporal comparisons of vegetation conditions. Blue, red, and near-infrared reflectances, centered at 469-nanometers, 645-nanometers, and 858-nanometers, respectively, are used to determine the MODIS vegetation indices.\n", - "\n", - "The MODIS Normalized Difference Vegetation Index (NDVI) complements NOAA's Advanced Very High Resolution Radiometer (AVHRR) NDVI products providing continuity for time series applications over this rich historical archive.\n", - "\n", - "[Global MOD13C2 data](https://ladsweb.modaps.eosdis.nasa.gov/missions-and-measurements/products/MOD13C2#overview) are cloud-free spatial composites of the gridded 16-day 1-kilometer MOD13C2A2, and are provided as a level-3 product projected on a 0.05 degree (5600-meter) geographic Climate Modeling Grid (CMG).\n", - "These files have also been pre-processed to match the grid of the precipitation data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "years=range(2000,2024) # the NDVI data we have available \n", - "file_paths=['MODIS/NDVI_'+str(year)+'.nc' for year in years] # the format of the files\n", - "filenames=['MODIS/NDVI_'+str(year)+'.nc' for year in years] # the format of the files\n", - "\n", - "downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files\n", - "# load Data\n", - "modis_data = xr.open_mfdataset(downloaded_files,combine='by_coords')\n", - "modis_data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "GHPGv6DWBBBX" - }, - "source": [ - "\n", - "## Worldbank Data: Cereal Production\n", - "\n", - "Cereal production is a crucial component of global agriculture and food security. The [World Bank](https://databank.worldbank.org/metadataglossary/world-development-indicators/series/AG.PRD.CREL.MT) collects and provides data on cereal production, which includes crops such as wheat, rice, maize, barley, oats, rye, sorghum, millet, and mixed grains. The data covers various indicators such as production quantity, area harvested, yield, and production value.\n", - "\n", - "The World Bank also collects data on land under cereals production, which refers to the area of land that is being used to grow cereal crops. This information can be valuable for assessing the productivity and efficiency of cereal production systems in different regions, as well as identifying potential areas for improvement. Overall, the World Bank's data on cereal production and land under cereals production is an important resource for policymakers, researchers, and other stakeholders who are interested in understanding global trends in agriculture and food security." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 612 - }, - "id": "qVy0zpxFBLue", - "outputId": "c757c926-f19f-4b96-cbbb-d5ed4ea752d7", - "tags": [] - }, - "outputs": [], - "source": [ - "# code to retrieve and load the data\n", - "filename_cereal = 'data_cereal_land.csv'\n", - "url_cereal = 'https://raw.githubusercontent.com/Sshamekh/Heatwave/f85f43997e3d6ae61e5d729bf77cfcc188fbf2fd/data_cereal_land.csv'\n", - "ds_cereal_land = pd.read_csv(pooch_load(url_cereal,filename_cereal))\n", - "ds_cereal_land.head() " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "liZJJxW3BYx4", - "outputId": "2a0a20c0-8d71-461b-e366-038028d27a71", - "tags": [] - }, - "outputs": [], - "source": [ - "# example\n", - "ds_cereal_land[(ds_cereal_land[\"Country Name\"] == \"Brazil\")].reset_index(\n", - " drop=True\n", - ").iloc[0].transpose()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "fKb2AhYbmmWc" - }, - "source": [ - "\n", - "Now you are all set to address the questions you are interested in! Just be mindful of the specific coordinate names to avoid any issues. \n", - "\n", - "You can use the provided functions as examples to compute various indices for extreme events based on duration or intensity. Don't hesitate to modify them according to your specific needs or create your own custom functions.\n", - "\n", - "\n", - "Happy exploring and analyzing precipitation variability and extreme events in your project!\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "e5KKmsTujjAg" - }, - "source": [ - "# Further Reading\n", - "\n", - "- Anyamba, A. and Tucker, C.J., 2012. Historical perspective of AVHRR NDVI and vegetation drought monitoring. Remote sensing of drought: innovative monitoring approaches, 23, pp.20.[https://digitalcommons.unl.edu/nasapub/217/](https://digitalcommons.unl.edu/nasapub/217/)\n", - "- Zhang, X., Alexander, L., Hegerl, G.C., Jones, P., Tank, A.K., Peterson, T.C., Trewin, B. and Zwiers, F.W., 2011. Indices for monitoring changes in extremes based on daily temperature and precipitation data. Wiley Interdisciplinary Reviews: Climate Change, 2(6), pp.851-870.\n", - "- Schultz, P. A., and M. S. Halpert. \"Global correlation of temperature, NDVI and precipitation.\" Advances in Space Research 13.5 (1993): 277-280. \n", - "- Seneviratne, S.I. et al., 2021: Weather and Climate Extreme Events in a Changing Climate. In Climate Change 2021: The Physical Science Basis. Contribution of Working Group I to the Sixth Assessment Report of the Intergovernmental Panel on Climate Change [Masson-Delmotte, V. et al. (eds.)]. Cambridge University Press, Cambridge, United Kingdom and New York, NY, USA, pp. 1513–1766, https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-11/\n", - "- IPCC, 2021: Annex VI: Climatic Impact-driver and Extreme Indices [Gutiérrez J.M. et al.(eds.)]. In Climate Change 2021: The Physical Science Basis. Contribution of Working Group I to the Sixth Assessment Report of the Intergovernmental Panel on Climate Change [Masson-Delmotte, V. et al. (eds.)]. Cambridge University Press, Cambridge, United Kingdom and New York, NY, USA, pp. 2205–2214, https://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_AnnexVI.pdf" - ] - } - ], - "metadata": { - "colab": { - "provenance": [], - "toc_visible": true - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/project-notebooks/Sea_level_rise.ipynb b/book/_build/html/_sources/projects/project-notebooks/Sea_level_rise.ipynb deleted file mode 100644 index 457ba8aad..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/Sea_level_rise.ipynb +++ /dev/null @@ -1,415 +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/ClimateMatchAcademy/course-content/blob/main/projects/project-notebooks/Sea_level_rise.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# **Sea Level Rise**\n", - "\n", - "**Content creators:** Aakash Sane, Karsten Haustein\n", - "\n", - "**Content reviewers:** Brodie Pearson, Abigail Bodner, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Zane Mitrevica, Natalie Steinemann, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Project Background\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(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', 'FzXJ00pg34g'), ('Bilibili', 'BV1J14y197TT')]\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": {}, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"u7x62\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "Sea level, or Sea Surface Height [SSH], describes the vertical position of the interface between the atmosphere and the ocean. It varies at numerous timescales attributable to different physical factors, such as hourly tides, daily to monthly perturbations caused by currents and storms, and alterations spanning several decades to centuries due to thermal expansion of seawater and the reduction of mass resulting from glaciers and ice sheets. Read more: [NOAA 2022 Sea level rise technical report](https://oceanservice.noaa.gov/hazards/sealevelrise/sealevelrise-tech-report.html).\n", - "\n", - "**In this project**, you will work on sea level rise data from ECCO model (recall W1D2 tutorial 4 outputs) and tidal gauge datasets." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adR8NLN_ZsZL" - }, - "source": [ - "# Project Template\n", - "![Project Template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/sea_level_rise_template_map.svg)\n", - "\n", - "*Note: The dashed boxes are socio-economic questions.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# Data Exploration Notebook\n", - "## Project Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 11530, - "status": "ok", - "timestamp": 1684039748782, - "user": { - "displayName": "Aakash Sane", - "userId": "01630331402567153960" - }, - "user_tz": 240 - }, - "id": "9nDg6MeVY1CX", - "outputId": "a400990a-18a0-4a09-d07d-868dbbc84067", - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import random\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "import os\n", - "import pooch\n", - "import tempfile" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "def pooch_load(filelocation=None,filename=None,processor=None):\n", - " shared_location='/home/jovyan/shared/Data/Projects/Sea_Level' # this is different for each day\n", - " user_temp_cache=tempfile.gettempdir()\n", - " \n", - " if os.path.exists(os.path.join(shared_location,filename)):\n", - " file = os.path.join(shared_location,filename)\n", - " else:\n", - " file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "iYblWn8cZAGT" - }, - "source": [ - "## ECCO Sea Surface Height (SSH)\n", - "\n", - "In this project, you will analyse sea surface height (SSH) data using the ECCO reanalysis product which combines simulations and observations. ECCO stands for Estimating the Circulation and Climate of the Ocean and integrates observations with coupled ocean/sea-ice models. The netCDF data file contains SSH stored as monthly means from the year 1992 to 2017 on a 0.5 x 0.5 degree grid. Using the ECCO product, global and regional sea level obtained due to physical effects (such as thermal expansion of sea water, etc.) can be estimated. Further details about the dataset can be obtained [here](https://ecco-group.org/).\n", - "\n", - "The sea surface height variable is called 'SSH' in the data. It is a variable with three gridded dimensions: time, latitude, and longitude. The code below shows how to load the SSH dataset and provides plotting examples. One example plots the time-series at a particular latitude and longitude while another example plots a colormap on the global grid. Those examples should equip you to tackle many of the questions on the template, so go ahead and explore! \n", - "\n", - "Further resources about the dataset:\n", - "\n", - "- ECCO Consortium, Fukumori, I., Wang, O., Fenty, I., Forget, G., Heimbach, P., & Ponte, R. M. (DATE ACCESSED). ECCO Central Estimate (Version 4 Release 4). Retrieved from https://podaac.jpl.nasa.gov/dataset/ECCO_L4_GMSL_TIME_SERIES_MONTHLY_V4R4.\n", - "\n", - "- ECCO Consortium, Fukumori, I., Wang, O., Fenty, I., Forget, G., Heimbach, P., & Ponte, R. M. (2021, February 10). Synopsis of the ECCO Central Production Global Ocean and Sea-Ice State Estimate (Version 4 Release 4). https://doi.org/10.5281/zenodo.4533349\n", - "\n", - "- Forget, G., J.-M. Campin, P. Heimbach, C. N. Hill, R. M. Ponte, and C. Wunsch, 2015: ECCO version 4: An integrated framework for non-linear inverse modeling and global ocean state estimation. Geoscientific Model Development, 8. https://www.geosci-model-dev.net/8/3071/2015/\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 375 - }, - "executionInfo": { - "elapsed": 1616, - "status": "ok", - "timestamp": 1684040059226, - "user": { - "displayName": "Aakash Sane", - "userId": "01630331402567153960" - }, - "user_tz": 240 - }, - "id": "L0flXmexD8V1", - "outputId": "2b914b7c-7428-4934-e614-a31dbc9fac07", - "tags": [] - }, - "outputs": [], - "source": [ - "url_ECCO='~/shared/Data/Projects/Sea_Level/SEA_SURFACE_HEIGHT_mon_mean_1992-01-2017-12_ECCO_V4r4_latlon_0p50deg.nc'\n", - "ds=xr.open_dataset(url_ECCO)\n", - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 521 - }, - "executionInfo": { - "elapsed": 3394, - "status": "ok", - "timestamp": 1684040207001, - "user": { - "displayName": "Aakash Sane", - "userId": "01630331402567153960" - }, - "user_tz": 240 - }, - "id": "PlWal3F1nBn-", - "outputId": "277e3422-1a14-4bd5-9d7f-9271c4fe4610", - "tags": [] - }, - "outputs": [], - "source": [ - "ds[\"SSH\"][:, 200, 134].plot()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 505 - }, - "executionInfo": { - "elapsed": 2180, - "status": "ok", - "timestamp": 1684040259345, - "user": { - "displayName": "Aakash Sane", - "userId": "01630331402567153960" - }, - "user_tz": 240 - }, - "id": "siE27RESnpYu", - "outputId": "edbe201a-8198-4acc-c89e-ee96ee017d69", - "tags": [] - }, - "outputs": [], - "source": [ - "ds[\"SSH\"][100, :, :].plot.pcolormesh()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "m_p7kvscZcLF" - }, - "source": [ - "## Observations Dataset: Tidal Gauges\n", - "\n", - "Students can download any tidal gauge data of their choice from this **[website](https://uhslc.soest.hawaii.edu/data/)**\n", - "\n", - "It is recommended to download the NetCDF **'daily'** data for a particular location and it can be compared to the nearest latitude-longitude from the ECCO dataset. When you download the tidal gauge data, you can select a location, right click on the NetCDF of the data you want, copy link address and paste as the url below.\n", - "\n", - "The file will have the sea level stored as a variable called **'sea_level'**, which is a function of time. It can be fun to explore how close the tidal gauge data agree (or disagree) with the ECCO data!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "TZklQQmuZFTh", - "tags": [] - }, - "outputs": [], - "source": [ - "# students can download any tidal gauge data of their choice from this website:\n", - "# https://uhslc.soest.hawaii.edu/data/\n", - "# instructions: select a location, right click on the netcdf of the data you want, copy link address and paste as the url below" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "ZDR9zdIeFPD7", - "tags": [] - }, - "outputs": [], - "source": [ - "# data source-specific functions\n", - "url_choosen = \"https://uhslc.soest.hawaii.edu/data/netcdf/fast/daily/d825.nc\" # this is the link for \"Cuxhaven Germany\", change to your location\n", - "# example code after downloading tidal gauge data:\n", - "ds = xr.open_dataset(\n", - " pooch.retrieve(url_choosen, known_hash=None)\n", - ") # this is just an example, tidal gauge NetCDF file needs to be downloaded in order to load this.\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "e5KKmsTujjAg" - }, - "source": [ - "# Further Reading\n", - "\n", - "- 2022 Sea Level Rise Technical Report\n", - "https://oceanservice.noaa.gov/hazards/sealevelrise/sealevelrise-tech-report-sections.html\n", - "\n", - "- Oppenheimer, M., B.C. Glavovic , J. Hinkel, R. van de Wal, A.K. Magnan, A. Abd-Elgawad, R. Cai, M. Cifuentes-Jara, R.M. DeConto, T. Ghosh, J. Hay, F. Isla, B. Marzeion, B. Meyssignac, and Z. Sebesvari, 2019: Sea Level Rise and Implications for Low-Lying Islands, Coasts and Communities. In: IPCC Special Report on the Ocean and Cryosphere in a Changing Climate [H.-O. Pörtner, D.C. Roberts, V. Masson-Delmotte, P. Zhai, M. Tignor, E. Poloczanska, K. Mintenbeck, A. Alegría, M. Nicolai, A. Okem, J. Petzold, B. Rama, N.M. Weyer (eds.)]. Cambridge University Press, Cambridge, UK and New York, NY, USA, pp. 321-445. https://doi.org/10.1017/9781009157964.006. \n", - "\n", - "- Domingues, R., Goni, G., Baringer, M., &Volkov, D. (2018). What caused theaccelerated sea level changes along theU.S. East Coast during 2010–2015?Geophysical Research Letters,45,13,367–13,376. https://doi.org/10.1029/2018GL081183Received \n", - "\n", - "- Church, J.A., P.U. Clark, A. Cazenave, J.M. Gregory, S. Jevrejeva, A. Levermann, M.A. Merrifield, G.A. Milne, R.S. Nerem, P.D. Nunn, A.J. Payne, W.T. Pfeffer, D. Stammer and A.S. Unnikrishnan, 2013: Sea Level Change. In: Climate Change 2013: The Physical Science Basis. Contribution of Working Group I to the Fifth Assessment Report of the Intergovernmental Panel on Climate Change \n", - "[Stocker, T.F., D. Qin, G.-K. Plattner, M. Tignor, S.K. Allen, J. Boschung,\n", - "A. Nauels, Y. Xia, V. Bex and P.M. Midgley (eds.)]. Cambridge University Press, Cambridge, United Kingdom and New York, NY, USA. https://www.ipcc.ch/site/assets/uploads/2018/02/WG1AR5_Chapter13_FINAL.pdf \n", - "\n", - "- Gregory, J.M., Griffies, S.M., Hughes, C.W. et al. Concepts and Terminology for Sea Level: Mean, Variability and Change, Both Local and Global. Surv Geophys 40, 1251–1289 (2019). https://doi.org/10.1007/s10712-019-09525-z\n", - "\n", - "- Wang, J., Church, J. A., Zhang, X., Gregory, J. M., Zanna, L., & Chen, X. (2021). Evaluation of the Local Sea‐Level Budget at Tide Gauges Since 1958. Geophysical Research Letters, 48(20), e2021GL094502. https://doi.org/10.1029/2021GL094502 \n", - "\n", - "- Cazenave, A. and Cozannet, G.L. (2014), Sea level rise and its coastal impacts. Earth's Future, 2: 15-34. https://doi-org.ezproxy.princeton.edu/10.1002/2013EF000188\n", - "\n", - "- Mimura N. Sea-level rise caused by climate change and its implications for society. Proc Jpn Acad Ser B Phys Biol Sci. 2013;89(7):281-301. doi: 10.2183/pjab.89.281. PMID: 23883609; PMCID: PMC3758961. doi: [10.2183/pjab.89.281](https://www.jstage.jst.go.jp/article/pjab/89/7/89_PJA8907B-01/_article)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "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": { - "provenance": [] - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/project-notebooks/Surface_albedo_and_land_cover.ipynb b/book/_build/html/_sources/projects/project-notebooks/Surface_albedo_and_land_cover.ipynb deleted file mode 100644 index 96b0f234c..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/Surface_albedo_and_land_cover.ipynb +++ /dev/null @@ -1,882 +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/ClimateMatchAcademy/course-content/blob/main/projects/project-notebooks/Surface_albedo_and_land_cover.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# Changes in Land Cover: Albedo and Carbon Sequestration\n", - "\n", - "**Content creators:** Oz Kira, Julius Bamah\n", - "\n", - "**Content reviewers:** Yuhan Douglas Rao, Abigail Bodner\n", - "\n", - "**Content editors:** Zane Mitrevica, Natalie Steinemann, Jenna Pearson, Chi Zhang, Ohad Zivan\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": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Project Background\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(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', 'qHZJeZnvQ60'), ('Bilibili', 'BV1fh4y1j7LX')]\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": {}, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"w8ny7\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "The global radiative budget is affected by land cover (e.g., forests, grasslands, agricultural fields, etc.), as different classifications of land cover have different levels of reflectance, or albedo. Vegetation also sequesters carbon at the same time, potentially counteracting these radiative effects.\n", - "\n", - "In this project, you will evaluate the albedo change vs. carbon sequestration. In addition, you will track significant land cover changes, specifically the creation and abandonment of agricultural land. \n", - "\n", - "**In this project**, you will have the opportunity to explore terrestrial remote sensing (recall our W1D3 tutorial on remote sensing) and meteorological data from GLASS and ERA5. The datasets will provide information on reflectance, albedo, meteorological variables, and land cover changes in your region of interest. We encourage you to investigate the relationships between these variables and their impact on the global radiative budget. Moreover, you can track agricultural land abandonment and analyze its potential connection to climate change. This project aligns well with the topics covered in W2D3, which you are encouraged to explore further." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adR8NLN_ZsZL" - }, - "source": [ - "# Project Template\n", - "![Project Template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/albedo_template_map.svg)\n", - "\n", - "*Note: The dashed boxes are socio-economic questions.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# Data Exploration Notebook\n", - "## Project Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# google colab installs\n", - "# !pip install cartopy\n", - "# !pip install DateTime\n", - "# !pip install matplotlib\n", - "# !pip install pyhdf\n", - "# !pip install numpy\n", - "# !pip install pandas\n", - "# !pip install modis-tools" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "executionInfo": { - "elapsed": 84265, - "status": "error", - "timestamp": 1683550940548, - "user": { - "displayName": "Zane Mitrevica", - "userId": "10190758862467767060" - }, - "user_tz": -60 - }, - "id": "9nDg6MeVY1CX", - "outputId": "e631645b-2751-490a-e9ad-6db6e540eccd", - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import numpy as np\n", - "from netCDF4 import Dataset\n", - "import matplotlib.pyplot as plt\n", - "import cartopy.crs as ccrs\n", - "import pooch\n", - "import xarray as xr\n", - "import os\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", - "from xmip.utils import google_cmip_col\n", - "\n", - "from datatree import DataTree\n", - "from xmip.postprocessing import _parse_metric\n", - "\n", - "import cartopy.crs as ccrs\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import pandas as pd\n", - "from IPython.display import display, HTML, Markdown\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "def pooch_load(filelocation=None,filename=None,processor=None):\n", - " shared_location='/home/jovyan/shared/Data/Projects/Albedo' # this is different for each day\n", - " user_temp_cache=tempfile.gettempdir()\n", - " \n", - " if os.path.exists(os.path.join(shared_location,filename)):\n", - " file = os.path.join(shared_location,filename)\n", - " else:\n", - " file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Obtain Land and Atmospheric Variables from CMIP6" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here you will use the Pangeo cloud service to access CMIP6 data using the methods encountered in W1D5 and W2D1. To learn more about CMIP, including additional ways to access CMIP data, please see our [CMIP Resource Bank](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md) and the [CMIP website](https://wcrp-cmip.org/)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# open an intake catalog containing the Pangeo CMIP cloud data\n", - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ")\n", - "col" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "To see a list of CMIP6 variables and models please visit [the Earth System Grid Federation (ESGF) website](https://esgf-node.llnl.gov/search/cmip6/). Note that not all of these variables are hosted through the Pangeo cloud, but there are additional ways to access all the CMIP6 data [as described here](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md), including direct access through ESGF. \n", - "\n", - "You can see which variables and models are available within Pangeo using the sample code below, where we look for models having the variable 'pastureFrac' for the historical simulation: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "expts = [\"historical\"]\n", - "\n", - "query = dict(\n", - " experiment_id=expts,\n", - " table_id=\"Lmon\",\n", - " variable_id=[\"pastureFrac\"],\n", - " member_id=\"r1i1p1f1\",\n", - ")\n", - "\n", - "col_subset = col.search(require_all_on=[\"source_id\"], **query)\n", - "col_subset.df.groupby(\"source_id\")[\n", - " [\"experiment_id\", \"variable_id\", \"table_id\"]\n", - "].nunique()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Here we will download several variables from the GFDL-ESM4 historical CMIP6 simulation:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "import pandas as pd\n", - "from IPython.display import display, HTML, Markdown\n", - "\n", - "# Data as list of dictionaries\n", - "classification_system = [\n", - " {\n", - " \"Name\": \"gpp\",\n", - " \"Description\": \"Carbon Mass Flux out of Atmosphere due to Gross Primary Production on Land\",\n", - " },\n", - " {\n", - " \"Name\": \"npp\",\n", - " \"Description\": \"Carbon Mass Flux out of Atmosphere due to Net Primary Production on Land\",\n", - " },\n", - " {\n", - " \"Name\": \"nep\",\n", - " \"Description\": \"Carbon Mass Flux out of Atmophere due to Net Ecosystem Production on Land\",\n", - " },\n", - " {\n", - " \"Name\": \"nbp\",\n", - " \"Description\": \"Carbon Mass Flux out of Atmosphere due to Net Biospheric Production on Land\",\n", - " },\n", - " {\"Name\": \"treeFrac\", \"Description\": \"Land Area Percentage Tree Cover\"},\n", - " {\"Name\": \"grassFrac\", \"Description\": \"Land Area Percentage Natural Grass\"},\n", - " {\"Name\": \"cropFrac\", \"Description\": \"Land Area Percentage Crop Cover\"},\n", - " {\n", - " \"Name\": \"pastureFrac\",\n", - " \"Description\": \"Land Area Percentage Anthropogenic Pasture Cover\",\n", - " },\n", - " {\"Name\": \"rsus\", \"Description\": \"Surface Upwelling Shortwave Radiation\"},\n", - " {\"Name\": \"rsds\", \"Description\": \"Surface Downwelling Shortwave Radiation\"},\n", - " {\"Name\": \"tas\", \"Description\": \"Near-Surface Air Temperature\"},\n", - " {\"Name\": \"pr\", \"Description\": \"Precipitation\"},\n", - " {\n", - " \"Name\": \"areacella\",\n", - " \"Description\": \"Grid-Cell Area for Atmospheric Variables (all variabeles are on this grid however)\",\n", - " },\n", - "]\n", - "\n", - "df = pd.DataFrame(classification_system)\n", - "pd.set_option(\"display.max_colwidth\", None)\n", - "html = df.to_html(index=False)\n", - "title_md = \"### Table 1: CMIP6 Variables\"\n", - "display(Markdown(title_md))\n", - "display(HTML(html))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "There are different timescales on which carbon is released back into the atmosphere, and these are reflected in the different production terms. This is highlighted in the figure below (please note these numbers are quite outdated).\n", - "\n", - "![](https://archive.ipcc.ch/ipccreports/sres/land_use/images/1-2.gif)\n", - "\n", - "**Figure 1-2**: Global terrestrial carbon uptake. Plant (autotrophic) respiration releases CO2 to the atmosphere, reducing GPP to NPP and resulting in short-term carbon uptake. Decomposition (heterotrophic respiration) of litter and soils in excess of that resulting from disturbance further releases CO2 to the atmosphere, reducing NPP to NEP and resulting in medium-term carbon uptake. Disturbance from both natural and anthropogenic sources (e.g., harvest) leads to further release of CO2 to the atmosphere by additional heterotrophic respiration and combustion-which, in turn, leads to long-term carbon storage (adapted from Steffen et al., 1998). Credit: [IPCC](https://archive.ipcc.ch/ipccreports/sres/land_use/index.php?idp=24)\n", - "\n", - "Now you are ready to extract all the variables!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# get monthly land variables\n", - "\n", - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=\"GFDL-ESM4\",\n", - " variable_id=[\n", - " \"gpp\",\n", - " \"npp\",\n", - " \"nbp\",\n", - " \"treeFrac\",\n", - " \"grassFrac\",\n", - " \"cropFrac\",\n", - " \"pastureFrac\",\n", - " ], # No 'shrubFrac','baresoilFrac','residualFrac' in GFDL-ESM4\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Lmon\",\n", - " grid_label=\"gr1\",\n", - " experiment_id=[\"historical\"],\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_Lmon_variables = cat.to_datatree(**kwargs)\n", - "\n", - "# convert to dataset instead of datatree, remove extra singleton dimensions\n", - "ds_Lmon = dt_Lmon_variables[\"GFDL-ESM4\"][\"historical\"].to_dataset().squeeze()\n", - "ds_Lmon" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# get monthly 'extension' variables\n", - "\n", - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=\"GFDL-ESM4\",\n", - " variable_id=\"nep\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Emon\",\n", - " grid_label=\"gr1\",\n", - " experiment_id=[\"historical\"],\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_Emon_variables = cat.to_datatree(**kwargs)\n", - "\n", - "# convert to dataset instead of datatree, remove extra singleton dimensions\n", - "ds_Emon = dt_Emon_variables[\"GFDL-ESM4\"][\"historical\"].to_dataset().squeeze()\n", - "ds_Emon" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# get atmospheric variables\n", - "\n", - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=\"GFDL-ESM4\",\n", - " variable_id=[\"rsds\", \"rsus\", \"tas\", \"pr\"],\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Amon\",\n", - " grid_label=\"gr1\",\n", - " experiment_id=[\"historical\"],\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_Amon_variables = cat.to_datatree(**kwargs)\n", - "\n", - "# convert to dataset instead of datatree, remove extra singleton dimensions\n", - "ds_Amon = dt_Amon_variables[\"GFDL-ESM4\"][\"historical\"].to_dataset().squeeze()\n", - "ds_Amon" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# get atmospheric variables\n", - "\n", - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=\"GFDL-ESM4\",\n", - " variable_id=[\"areacella\"],\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"fx\",\n", - " grid_label=\"gr1\",\n", - " experiment_id=[\"historical\"],\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_fx_variables = cat.to_datatree(**kwargs)\n", - "\n", - "# convert to dataset instead of datatree, remove extra singleton dimensions\n", - "ds_fx = dt_fx_variables[\"GFDL-ESM4\"][\"historical\"].to_dataset().squeeze()\n", - "ds_fx" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since we are only using one model here, it is practical to extract the variables of interest into datarrays and put them in one compact dataset. In addition we need to calculate the surface albedo. Note, that you will learn more about surface albedo (and CMIP6 data) in W1D5." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# merge into single dataset. note, these are all on the 'gr1' grid.\n", - "ds = xr.Dataset()\n", - "\n", - "# add land variables\n", - "for var in ds_Lmon.data_vars:\n", - " ds[var] = ds_Lmon[var]\n", - "\n", - "# add extension variables\n", - "for var in ds_Emon.data_vars:\n", - " ds[var] = ds_Emon[var]\n", - "\n", - "# add atmopsheric variables\n", - "for var in ds_Amon.data_vars:\n", - " ds[var] = ds_Amon[var]\n", - "\n", - "# add grid cell area\n", - "for var in ds_fx.data_vars:\n", - " ds[var] = ds_fx[var]\n", - "\n", - "# drop unnecessary coordinates\n", - "ds = ds.drop_vars([\"member_id\", \"dcpp_init_year\", \"height\"])\n", - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# surface albedo is ratio of upwelling shortwave radiation (reflected) to downwelling shortwave radiation (incoming solar radiation).\n", - "ds[\"surf_albedo\"] = ds.rsus / ds.rsds\n", - "\n", - "# add attributes\n", - "ds[\"surf_albedo\"].attrs = {\"units\": \"Dimensionless\", \"long_name\": \"Surface Albedo\"}\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "iYblWn8cZAGT" - }, - "source": [ - "## Alternative Land Cover Approach: Global Land Surface Satellite (GLASS) Dataset\n", - "\n", - "The Global Land Surface Satellite (GLASS) datasets primarily based on NASA’s Advanced Very High Resolution Radiometer (AVHRR) long-term data record [(LTDR)](https://ltdr.modaps.eosdis.nasa.gov) and Moderate Resolution Imaging Spectroradiometer (MODIS) data, in conjunction with other satellite data and ancillary information. \n", - "\n", - "Currently, there are more than dozens of GLASS products are officially released, including leaf area index, fraction of green vegetation coverage, gross primary production, broadband albedo, land surface temperature, evapotranspiration, and so on. \n", - "\n", - "Here we provide you the datasets of GLASS from 1982 to 2015, a 34-year long annual dynamics of global land cover (GLASS-GLC) at 5 km resolution. In this datasets, there are 7 classes, including cropland, forest, grassland, shrubland, tundra, barren land, and snow/ice. \n", - "The annual global land cover map (5 km) is presented in a GeoTIFF file format named in the form of ‘GLASS-GLC_7classes_year’ with a WGS 84 projection. The relationship between the labels in the files and the 7 land cover classes is shown in the following table\n", - "\n", - "You can refer to this [paper](https://doi.pangaea.de/10.1594/PANGAEA.913496) for detailed description of this.ts\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Table 1 Classification system, with 7 land cover classes. From paper https://www.earth-syst-sci-data-discuss.net/essd-2019-23\n", - "import pandas as pd\n", - "from IPython.display import display, HTML, Markdown\n", - "\n", - "# Data as list of dictionaries\n", - "classification_system = [\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Rice paddy\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Greenhouse\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Other farmland\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Orchard\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Bare farmland\", \"Description\": \"\"},\n", - " {\n", - " \"Label\": 20,\n", - " \"Class\": \"Forest\",\n", - " \"Subclass\": \"Broadleaf, leaf-on\",\n", - " \"Description\": \"Tree cover≥10%; Height>5m; For mixed leaf, neither coniferous nor broadleaf types exceed 60%\",\n", - " },\n", - " {\n", - " \"Label\": 20,\n", - " \"Class\": \"Forest\",\n", - " \"Subclass\": \"Broadleaf, leaf-off\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 20,\n", - " \"Class\": \"Forest\",\n", - " \"Subclass\": \"Needle-leaf, leaf-on\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 20,\n", - " \"Class\": \"Forest\",\n", - " \"Subclass\": \"Needle-leaf, leaf-off\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 20,\n", - " \"Class\": \"Forest\",\n", - " \"Subclass\": \"Mixed leaf type, leaf-on\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 20,\n", - " \"Class\": \"Forest\",\n", - " \"Subclass\": \"Mixed leaf type, leaf-off\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 30,\n", - " \"Class\": \"Grassland\",\n", - " \"Subclass\": \"Pasture, leaf-on\",\n", - " \"Description\": \"Canopy cover≥20%\",\n", - " },\n", - " {\n", - " \"Label\": 30,\n", - " \"Class\": \"Grassland\",\n", - " \"Subclass\": \"Natural grassland, leaf-on\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 30,\n", - " \"Class\": \"Grassland\",\n", - " \"Subclass\": \"Grassland, leaf-off\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 40,\n", - " \"Class\": \"Shrubland\",\n", - " \"Subclass\": \"Shrub cover, leaf-on\",\n", - " \"Description\": \"Canopy cover≥20%; Height<5m\",\n", - " },\n", - " {\n", - " \"Label\": 40,\n", - " \"Class\": \"Shrubland\",\n", - " \"Subclass\": \"Shrub cover, leaf-off\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 70,\n", - " \"Class\": \"Tundra\",\n", - " \"Subclass\": \"Shrub and brush tundra\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 70,\n", - " \"Class\": \"Tundra\",\n", - " \"Subclass\": \"Herbaceous tundra\",\n", - " \"Description\": \"\",\n", - " },\n", - " {\n", - " \"Label\": 90,\n", - " \"Class\": \"Barren land\",\n", - " \"Subclass\": \"Barren land\",\n", - " \"Description\": \"Vegetation cover<10%\",\n", - " },\n", - " {\"Label\": 100, \"Class\": \"Snow/Ice\", \"Subclass\": \"Snow\", \"Description\": \"\"},\n", - " {\"Label\": 100, \"Class\": \"Snow/Ice\", \"Subclass\": \"Ice\", \"Description\": \"\"},\n", - " {\"Label\": 0, \"Class\": \"No data\", \"Subclass\": \"\", \"Description\": \"\"},\n", - "]\n", - "\n", - "df = pd.DataFrame(classification_system)\n", - "pd.set_option(\"display.max_colwidth\", None)\n", - "html = df.to_html(index=False)\n", - "title_md = \"### Table 1 GLASS classification system with 7 land cover classes. From [this paper](https://www.earth-syst-sci-data-discuss.net/essd-2019-23).\"\n", - "display(Markdown(title_md))\n", - "display(HTML(html))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# source of landuse data: https://doi.pangaea.de/10.1594/PANGAEA.913496\n", - "# the folder \"land-use\" has the data for years 1982 to 2015. choose the years you need and change the path accordingly\n", - "path_LandUse = os.path.expanduser(\n", - " \"~/shared/Data/Projects/Albedo/land-use/GLASS-GLC_7classes_1982.tif\"\n", - ")\n", - "ds_landuse = xr.open_dataset(path_LandUse).rename({\"x\": \"longitude\", \"y\": \"latitude\"})\n", - "# ds_landuse.band_data[0,:,:].plot() # how to plot the global data\n", - "ds_landuse" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Alternative Approach: ERA5-Land Monthly Averaged Data from 1950 to Present\n", - "\n", - "**[ERA5-Land](https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-land-monthly-means?tab=overview)** is a reanalysis dataset that offers an enhanced resolution compared to [ERA5](https://www.ecmwf.int/en/forecasts/dataset/ecmwf-reanalysis-v5), providing a consistent view of land variables over several decades. It is created by replaying the land component of the ECMWF ERA5 climate reanalysis, which combines model data and global observations to generate a complete and reliable dataset using the laws of physics. \n", - "\n", - "ERA5-Land focuses on the water and energy cycles at the surface level, offering a detailed record starting from 1950. The data used here is a post-processed subset of the complete ERA5-Land dataset. Monthly-mean averages have been pre-calculated to facilitate quick and convenient access to the data, particularly for applications that do not require sub-monthly fields. The native spatial resolution of the ERA5-Land reanalysis dataset is 9km on a reduced Gaussian grid (TCo1279). The data in the CDS has been regridded to a regular lat-lon grid of 0.1x0.1 degrees.\n", - "\n", - "### To Calculate Albedo Using ERA5-Land\n", - "ERA5 parameter [`Forecast albedo`](https://codes.ecmwf.int/grib/param-db/?id=243) provides is the measure of the reflectivity of the Earth's surface. It is the fraction of solar (shortwave) radiation reflected by Earth's surface, across the solar spectrum, for both direct and diffuse radiation. Values are between 0 and 1. Typically, snow and ice have high reflectivity with albedo values of 0.8 and above, land has intermediate values between about 0.1 and 0.4 and the ocean has low values of 0.1 or less. Radiation from the Sun (solar, or shortwave, radiation) is partly reflected back to space by clouds and particles in the atmosphere (aerosols) and some of it is absorbed. The rest is incident on the Earth's surface, where some of it is reflected. The portion that is reflected by the Earth's surface depends on the albedo. In the ECMWF Integrated Forecasting System (IFS), a climatological background albedo (observed values averaged over a period of several years) is used, modified by the model over water, ice and snow. Albedo is often shown as a percentage (%).\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# link for albedo data:\n", - "albedo_path = \"~/shared/Data/Projects/Albedo/ERA/albedo-001.nc\"\n", - "ds_albedo = xr.open_dataset(albedo_path)\n", - "ds_albedo # note the official variable name is fal (forecast albedo)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "for your convience, included below are preciptation and temprature ERA5 dataset for the same times as the Albedo dataset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "precp_path = \"~/shared/Data/Projects/Albedo/ERA/precipitation-002.nc\"\n", - "ds_precp = xr.open_dataset(precp_path)\n", - "ds_precp # the variable name is tp (total preciptation)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "tempr_path = \"~/shared/Data/Projects/Albedo/ERA/Temperature-003.nc\"\n", - "ds_tempr = xr.open_dataset(tempr_path)\n", - "ds_tempr # the variable name is t2m (temprature at 2m)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "e5KKmsTujjAg" - }, - "source": [ - "# Further Reading\n", - "- IPCC Special Report on climate change, desertification, land degradation, sustainable land management, food security, and greenhouse gas fluxes in terrestrial ecosystems, https://www.ipcc.ch/srccl/\n", - "\n", - "- Zhao, X., Wu, T., Wang, S., Liu, K., Yang, J. Cropland abandonment mapping at sub-pixel scales using crop phenological information and MODIS time-series images, Computers and Electronics in Agriculture, Volume 208,\n", - "2023,107763, ISSN 0168-1699,https://doi.org/10.1016/j.compag.2023.107763\n", - "\n", - "- Shani Rohatyn et al., Limited climate change mitigation potential through forestation of the vast dryland regions. Science 377,1436-1439 (2022).DOI:10.1126/science.abm9684\n", - "\n", - "- Hu, Y., Hou, M., Zhao, C., Zhen, X., Yao, L., Xu, Y. Human-induced changes of surface albedo in Northern China from 1992-2012, International Journal of Applied Earth Observation and Geoinformation, Volume 79, 2019, Pages 184-191, ISSN 1569-8432, https://doi.org/10.1016/j.jag.2019.03.018\n", - "\n", - "- Duveiller, G., Hooker, J. & Cescatti, A. The mark of vegetation change on Earth’s surface energy balance. Nat Commun 9, 679 (2018). https://doi.org/10.1038/s41467-017-02810-8\n", - "\n", - "- Yin, H., Brandão, A., Buchner, J., Helmers, D., Iuliano, B.G., Kimambo, N.E., Lewińska, K.E., Razenkova, E., Rizayeva, A., Rogova, N., Spawn, S.A., Xie, Y., Radeloff, V.C. Monitoring cropland abandonment with Landsat time series, Remote Sensing of Environment, Volume 246, 2020, 111873, ISSN 0034-4257,https://doi.org/10.1016/j.rse.2020.111873\n", - "\n", - "- Gupta, P., Verma, S., Bhatla, R.,Chandel, A. S., Singh, J., & Payra, S.(2020). Validation of surfacetemperature derived from MERRA‐2Reanalysis against IMD gridded data setover India.Earth and Space Science,7,e2019EA000910. https://doi.org/10.1029/2019EA000910\n", - "\n", - "- Cao, Y., S. Liang, X. Chen, and T. He (2015) Assessment of Sea Ice Albedo Radiative Forcing and Feedback over the Northern Hemisphere from 1982 to 2009 Using Satellite and Reanalysis Data. J. Climate, 28, 1248–1259, https://doi.org/10.1175/JCLI-D-14-00389.1.\n", - "\n", - "- Westberg, D. J., P. Stackhouse, D. B. Crawley, J. M. Hoell, W. S. Chandler, and T. Zhang (2013), An Analysis of NASA's MERRA Meteorological Data to Supplement Observational Data for Calculation of Climatic Design Conditions, ASHRAE Transactions, 119, 210-221. \n", - "https://www.researchgate.net/profile/Drury-Crawley/publication/262069995_An_Analysis_of_NASA's_MERRA_Meteorological_Data_to_Supplement_Observational_Data_for_Calculation_of_Climatic_Design_Conditions/links/5465225f0cf2052b509f2cc0/An-Analysis-of-NASAs-MERRA-Meteorological-Data-to-Supplement-Observational-Data-for-Calculation-of-Climatic-Design-Conditions.pdf\n", - "\n", - "- Södergren, A. H., & McDonald, A. J.. Quantifying the role of atmospheric and surface albedo on polar amplification using satellite observations and CMIP6 Model output. Journal of Geophysical Research: Atmospheres.(2022). 127, e2021JD035058. https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2021JD035058\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "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": { - "provenance": [] - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/project-notebooks/Surface_albedo_and_land_use.ipynb b/book/_build/html/_sources/projects/project-notebooks/Surface_albedo_and_land_use.ipynb deleted file mode 100644 index 60224bf31..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/Surface_albedo_and_land_use.ipynb +++ /dev/null @@ -1,2883 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# **Change in Earth's albedo and its dependence on land cover changes in the past 20 years**\n", - "\n", - "**Content creators:** Oz Kira, Julius Bamah\n", - "\n", - "**Content reviewers:** Yuhan Douglas Rao, Abigail Bodner\n", - "\n", - "**Content editors:** Zane Mitrevica, Natalie Steinemann, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "id": "umnBeSiJeqYo" - }, - "outputs": [], - "source": [ - "# @title #**Project background** \n", - "#This will be a short video introducing the content creator(s) and motivating the research direction of the template.\n", - "#The Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "The global radiative budget is affected by land cover. Regarding vegetation land cover (e.g., forests, grasslands, agricultural fields, etc.), vegetation sequesters carbon, which reduces the greenhouse effect but absorbs more radiation and reduces earth albedo, which counteracts carbon sequestration. \n", - "\n", - "In this project, we will evaluate the albedo change vs. carbon sequestration over the past years. In addition, we will track significant land use changes, specifically the creation and abandonment of agricultural land. \n", - "\n", - "**In this project**, you will have the opportunity to explore terrestrial remote sensing (recall our W1D3 tutorial on **remote sensing**) and meteorological data from GLASS and ERA5. The datasets will provide information on reflectance, albedo, meteorological variables, and land cover changes in your region of interest. We encourage you to investigate the relationships between these variables and their impact on the global radiative budget. Moreover, you can track agricultural land abandonment and analyze its potential connection to climate change. This project aligns well with the topics covered in W2D3, which you are encouraged to explore further." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adR8NLN_ZsZL" - }, - "source": [ - "# **Project template**\n", - "![template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/albedo_template_map.svg)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# **Data exploration notebook**\n", - "## Project setup\n", - "\n", - "Please run the following cells to install the necessary libarries into your Jupyter notebook!\n", - " " - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# google colab installs\n", - "# !pip install cartopy\n", - "# !pip install DateTime \n", - "# !pip install matplotlib\n", - "# !pip install pyhdf\n", - "# !pip install numpy\n", - "# !pip install pandas\n", - "# !pip install modis-tools" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "executionInfo": { - "elapsed": 84265, - "status": "error", - "timestamp": 1683550940548, - "user": { - "displayName": "Zane Mitrevica", - "userId": "10190758862467767060" - }, - "user_tz": -60 - }, - "id": "9nDg6MeVY1CX", - "outputId": "e631645b-2751-490a-e9ad-6db6e540eccd" - }, - "outputs": [], - "source": [ - "# the further information on the MODIS data can be found here : \n", - "#Import the libraries\n", - "import numpy as np\n", - "from netCDF4 import Dataset\n", - "import matplotlib.pyplot as plt\n", - "import cartopy.crs as ccrs\n", - "import pooch\n", - "import xarray as xr\n", - "import os\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "id": "iYblWn8cZAGT" - }, - "source": [ - "# **Global Land Surface Satellite (GLASS) Dataset**\n", - "\n", - "The Global Land Surface Satellite (GLASS) datasets primarily based on NASA’s Advanced Very High Resolution Radiometer (AVHRR) long-term data record [(LTDR)](https://ltdr.modaps.eosdis.nasa.gov) and Moderate Resolution Imaging Spectroradiometer (MODIS) data, in conjunction with other satellite data and ancillary information. \n", - "\n", - "Currently, there are more than dozens of GLASS products are officially released, including leaf area index, fraction of green vegetation coverage, gross primary production, broadband albedo, land surface temperature, evapotranspiration, and so on. \n", - "\n", - "Here we provide you the datasets of GLASS from 1982 to 2015, a 34-year long annual dynamics of global land cover (GLASS-GLC) at 5 km resolution. In this datasets, there are 7 classes, including cropland, forest, grassland, shrubland, tundra, barren land, and snow/ice. \r\n", - "The annual global land cover map (5 km) is presented in a GeoTIFF file format named in the form of ‘GLASS-GLC_7classes_year’ with a WGS 84 projection. The relationship between the labels in the files and the 7 land cover classes is shown in the following table\n", - "\n", - "You can refer to this [paper](https://doi.pangaea.de/10.1594/PANGAEA.913496) for detailed description of this.ts\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "### Table 1 GLASS classification system with 7 land cover classes. From [this paper](https://www.earth-syst-sci-data-discuss.net/essd-2019-23)." - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
LabelClassSubclassDescription
10CroplandRice paddy
10CroplandGreenhouse
10CroplandOther farmland
10CroplandOrchard
10CroplandBare farmland
20ForestBroadleaf, leaf-onTree cover≥10%; Height>5m; For mixed leaf, neither coniferous nor broadleaf types exceed 60%
20ForestBroadleaf, leaf-off
20ForestNeedle-leaf, leaf-on
20ForestNeedle-leaf, leaf-off
20ForestMixed leaf type, leaf-on
20ForestMixed leaf type, leaf-off
30GrasslandPasture, leaf-onCanopy cover≥20%
30GrasslandNatural grassland, leaf-on
30GrasslandGrassland, leaf-off
40ShrublandShrub cover, leaf-onCanopy cover≥20%; Height<5m
40ShrublandShrub cover, leaf-off
70TundraShrub and brush tundra
70TundraHerbaceous tundra
90Barren landBarren landVegetation cover<10%
100Snow/IceSnow
100Snow/IceIce
0No data
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Table 1 Classification system, with 7 land cover classes. From paper https://www.earth-syst-sci-data-discuss.net/essd-2019-23\n", - "import pandas as pd\n", - "from IPython.display import display, HTML, Markdown\n", - "# Data as list of dictionaries\n", - "classification_system = [\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Rice paddy\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Greenhouse\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Other farmland\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Orchard\", \"Description\": \"\"},\n", - " {\"Label\": 10, \"Class\": \"Cropland\", \"Subclass\": \"Bare farmland\", \"Description\": \"\"},\n", - " {\"Label\": 20, \"Class\": \"Forest\", \"Subclass\": \"Broadleaf, leaf-on\", \"Description\": \"Tree cover≥10%; Height>5m; For mixed leaf, neither coniferous nor broadleaf types exceed 60%\"},\n", - " {\"Label\": 20, \"Class\": \"Forest\", \"Subclass\": \"Broadleaf, leaf-off\", \"Description\": \"\"},\n", - " {\"Label\": 20, \"Class\": \"Forest\", \"Subclass\": \"Needle-leaf, leaf-on\", \"Description\": \"\"},\n", - " {\"Label\": 20, \"Class\": \"Forest\", \"Subclass\": \"Needle-leaf, leaf-off\", \"Description\": \"\"},\n", - " {\"Label\": 20, \"Class\": \"Forest\", \"Subclass\": \"Mixed leaf type, leaf-on\", \"Description\": \"\"},\n", - " {\"Label\": 20, \"Class\": \"Forest\", \"Subclass\": \"Mixed leaf type, leaf-off\", \"Description\": \"\"},\n", - " {\"Label\": 30, \"Class\": \"Grassland\", \"Subclass\": \"Pasture, leaf-on\", \"Description\": \"Canopy cover≥20%\"},\n", - " {\"Label\": 30, \"Class\": \"Grassland\", \"Subclass\": \"Natural grassland, leaf-on\", \"Description\": \"\"},\n", - " {\"Label\": 30, \"Class\": \"Grassland\", \"Subclass\": \"Grassland, leaf-off\", \"Description\": \"\"},\n", - " {\"Label\": 40, \"Class\": \"Shrubland\", \"Subclass\": \"Shrub cover, leaf-on\", \"Description\": \"Canopy cover≥20%; Height<5m\"},\n", - " {\"Label\": 40, \"Class\": \"Shrubland\", \"Subclass\": \"Shrub cover, leaf-off\", \"Description\": \"\"},\n", - " {\"Label\": 70, \"Class\": \"Tundra\", \"Subclass\": \"Shrub and brush tundra\", \"Description\": \"\"},\n", - " {\"Label\": 70, \"Class\": \"Tundra\", \"Subclass\": \"Herbaceous tundra\", \"Description\": \"\"},\n", - " {\"Label\": 90, \"Class\": \"Barren land\", \"Subclass\": \"Barren land\", \"Description\": \"Vegetation cover<10%\"},\n", - " {\"Label\": 100, \"Class\": \"Snow/Ice\", \"Subclass\": \"Snow\", \"Description\": \"\"},\n", - " {\"Label\": 100, \"Class\": \"Snow/Ice\", \"Subclass\": \"Ice\", \"Description\": \"\"},\n", - " {\"Label\": 0, \"Class\": \"No data\", \"Subclass\": \"\", \"Description\": \"\"}\n", - "]\n", - "\n", - "df = pd.DataFrame(classification_system)\n", - "pd.set_option('display.max_colwidth', None)\n", - "html = df.to_html(index=False)\n", - "title_md = \"### Table 1 GLASS classification system with 7 land cover classes. From [this paper](https://www.earth-syst-sci-data-discuss.net/essd-2019-23).\"\n", - "display(Markdown(title_md))\n", - "display(HTML(html))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## **Alternative Approach to Obtain Land Cover Data and Net Primary Production (NPP) Data from MODIS**\n", - "\n", - "MODIS (Moderate Resolution Imaging Spectroradiometer) is a key instrument aboard the Terra (originally known as EOS AM-1) and Aqua (originally known as EOS PM-1) satellites. Terra's orbit around the Earth is timed so that it passes from north to south across the equator in the morning, while Aqua passes south to north over the equator in the afternoon. Terra MODIS and Aqua MODIS are viewing the entire Earth's surface every 1 to 2 days, acquiring data in 36 spectral bands, or groups of wavelengths (see MODIS Technical Specifications). These data will improve our understanding of global dynamics and processes occurring on the land, in the oceans, and in the lower atmosphere. MODIS is playing a vital role in the development of validated, global, interactive Earth system models able to predict global change accurately enough to assist policy makers in making sound decisions concerning the protection of our environment (https://modis.gsfc.nasa.gov/data/).\n", - "\n", - "The following procedures must be ensured:\n", - "1. Register an account on register at NASA earth data portal: https://urs.earthdata.nasa.gov/users/new \n", - "2. pip install the following libraries into your Jupyter notebook\n", - "\n", - "The following links could help you in preprocessing the MODIS dataset \n", - "- https://www.earthdatascience.org/courses/use-data-open-source-python/multispectral-remote-sensing/modis-data-in-python/\n", - "- http://www.hdfeos.org/zoo/LAADS/MYD08_D3.A2009001.006.2015088160849.hdf.py\n", - "- https://www.moonbooks.org/Articles/How-to-read-a-MODIS-HDF-file-using-python-/\n", - "\n", - "Before running the code please read [this](https://amanbagrecha.github.io/post/rs_gis/download-modis-data-using-cmr-api-in-python/). \n", - "\n", - "The following papers could assist in processing of MODIS dataset: \n", - "- https://www.mdpi.com/2072-4292/8/7/554 \n", - "- https://www.tandfonline.com/doi/full/10.1080/01431161.2018.1430913\n", - "- https://www.mdpi.com/2072-4292/6/6/5368" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "## Alternative Approach to Obtain Land Cover Data and Net Primary Production (NPP) Data from MODIS\n", - "# #Import the libraries\n", - "\n", - "# from modis_tools.auth import ModisSession\n", - "# from modis_tools.resources import CollectionApi, GranuleApi\n", - "# from modis_tools.granule_handler import GranuleHandler\n", - "# from typing_extensions import Literal" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "## Alternative Approach to Obtain Land Cover Data and Net Primary Production (NPP) Data from MODIS\n", - "# #download_modis.py\n", - "# username = \"\" # Update this line with your username \n", - "# password = \"\" # Update this line with your password\n", - "# # 1) connect to earthdata\n", - "# session = ModisSession(username=username, password=password)\n", - "\n", - "# # 2) Query the MODIS catalog for collections\n", - "# collection_client = CollectionApi(session=session)\n", - "# collections = collection_client.query(short_name=\"\", version=\"\") # Collection short name + version\n", - "# # Query the selected collection for granules\n", - "# granule_client = GranuleApi.from_collection(collections[0], session=session)\n", - "\n", - "# # 3) Filter the selected granules via spatial and temporal parameters\n", - "# Israel_bbox = [] # format [x_min, y_min, x_max, y_max] # add min lon,min lat, max lon and max_lat input your preferred location\n", - "# Israel_granules = granule_client.query(start_date=\"\", end_date=\"\", bounding_box=Israel_bbox) #choose the start and end dates for the year-month-day you prefer\n", - "\n", - "# # 4) Download the granules\n", - "# GranuleHandler.download_from_granules(Israel_granules, session, threads=-1) \n", - "# #NB the file format will be downloaded in hdf \n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# **Gross Primary Production (GPP) Datasets**\n", - "\n", - "In the tutorial, you learned about Net primary production (NPP). Another similar key ecosystem process is Gross Primary Production (GPP), which is the total amount of carbon compounds produced by photosynthesis of plants in an ecosystem in a given period of time. NPP is equal to GPP minus energy used by primary producers for respiration. GPP is the amount of energy from light converted to chemical energy per unit of time, while NPP is a measure of the net CO2 sequestered by vegetation.\n", - "\n", - "Here we provide you the GPP datasets **VODCA2GPP** via [here](https://researchdata.tuwien.ac.at/records/1k7aj-bdz35) and this [paper](https://essd.copernicus.org/articles/14/1063/2022/#section6). This dataset estimates GPP based on VOD (Microwave Vegetation Optical Depth (VOD), a measure of the attenuation of microwave radiation caused by vegetation and thus relates to the total vegetation water content) using Generalized Additive Models. This VODCA2GPP is based on the period from 2007 to 2015 and uses VOD data from C-, X- and Ku-band and various GPP data sets. The data sets have different temporal coverage, which is summarized for VOD and GPP data in Table 2." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "### Table 2: Variable names, data sets, and additional information of VODCA2GPP datasets. [Reference](https://essd.copernicus.org/articles/14/1063/2022/#section6)" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
SensorTime period usedAECTC-band [GHz]X-band [GHz]Ku-band [GHz]Reference
AMSR-EJun 2002–Oct 201113:306.9310.6518.7Van der Schalie et al. (2017)
AMSR2Jul 2012–Dec 202013:306.93, 7.3010.6518.7Van der Schalie et al. (2017)
AMSR2Jul 2012–Aug 2017 (Ku-band)
SSM/I F08Jul 1987–Dec 199118:1519.35Owe et al. (2008)
SSM/I F11Dec 1991–May 199517:00–18:1519.35Owe et al. (2008)
SSM/I F13May 1995–Apr 200917:45–18:4019.35Owe et al. (2008)
TMIDec 1997–Apr 2015Asynchronous10.6519.35Owe et al. (2008), Van der Schalie et al. (2017)
WindSatFeb 2003–Jul 201218:006.810.718.7Owe et al. (2008), Van der Schalie et al. (2017)
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import pandas as pd\n", - "from IPython.display import display, HTML, Markdown\n", - "\n", - "# Data as list of dictionaries\n", - "data = [\n", - " {\"Sensor\": \"AMSR-E\", \"Time period used\": \"Jun 2002–Oct 2011\", \"AECT\": \"13:30\", \"C-band [GHz]\": \"6.93\", \"X-band [GHz]\": \"10.65\", \"Ku-band [GHz]\": \"18.7\", \"Reference\": \"Van der Schalie et al. (2017)\"},\n", - " {\"Sensor\": \"AMSR2\", \"Time period used\": \"Jul 2012–Dec 2020\", \"AECT\": \"13:30\", \"C-band [GHz]\": \"6.93, 7.30\", \"X-band [GHz]\": \"10.65\", \"Ku-band [GHz]\": \"18.7\", \"Reference\": \"Van der Schalie et al. (2017)\"},\n", - " {\"Sensor\": \"AMSR2\", \"Time period used\": \"Jul 2012–Aug 2017 (Ku-band)\", \"AECT\": \"\", \"C-band [GHz]\": \"\", \"X-band [GHz]\": \"\", \"Ku-band [GHz]\": \"\", \"Reference\": \"\"},\n", - " {\"Sensor\": \"SSM/I F08\", \"Time period used\": \"Jul 1987–Dec 1991\", \"AECT\": \"18:15\", \"C-band [GHz]\": \"\", \"X-band [GHz]\": \"\", \"Ku-band [GHz]\": \"19.35\", \"Reference\": \"Owe et al. (2008)\"},\n", - " {\"Sensor\": \"SSM/I F11\", \"Time period used\": \"Dec 1991–May 1995\", \"AECT\": \"17:00–18:15\", \"C-band [GHz]\": \"\", \"X-band [GHz]\": \"\", \"Ku-band [GHz]\": \"19.35\", \"Reference\": \"Owe et al. (2008)\"},\n", - " {\"Sensor\": \"SSM/I F13\", \"Time period used\": \"May 1995–Apr 2009\", \"AECT\": \"17:45–18:40\", \"C-band [GHz]\": \"\", \"X-band [GHz]\": \"\", \"Ku-band [GHz]\": \"19.35\", \"Reference\": \"Owe et al. (2008)\"},\n", - " {\"Sensor\": \"TMI\", \"Time period used\": \"Dec 1997–Apr 2015\", \"AECT\": \"Asynchronous\", \"C-band [GHz]\": \"\", \"X-band [GHz]\": \"10.65\", \"Ku-band [GHz]\": \"19.35\", \"Reference\": \"Owe et al. (2008), Van der Schalie et al. (2017)\"},\n", - " {\"Sensor\": \"WindSat\", \"Time period used\": \"Feb 2003–Jul 2012\", \"AECT\": \"18:00\", \"C-band [GHz]\": \"6.8\", \"X-band [GHz]\": \"10.7\", \"Ku-band [GHz]\": \"18.7\", \"Reference\": \"Owe et al. (2008), Van der Schalie et al. (2017)\"}\n", - "]\n", - "\n", - "# Convert list of dictionaries into a DataFrame\n", - "df = pd.DataFrame(data)\n", - "\n", - "# Set max_colwidth to None so that the full content of Description column is displayed\n", - "pd.set_option('display.max_colwidth', None)\n", - "\n", - "# Convert the DataFrame to HTML and hide the index\n", - "html = df.to_html(index=False)\n", - "\n", - "# Table title and link to paper in Markdown\n", - "title_md = \"### Table 2: Variable names, data sets, and additional information of VODCA2GPP datasets. [Reference](https://essd.copernicus.org/articles/14/1063/2022/#section6)\"\n", - "\n", - "# Display the title\n", - "display(Markdown(title_md))\n", - "\n", - "# Display the table\n", - "display(HTML(html))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## **Net Primary Production (NPP) Datasets**\n", - "\n", - "Alternatively, you can access the NPP data by downloading the MCD12Q1.061 MODIS Land Cover Type Yearly Global 500m using the instruction provided earlier. The description of this dataset can be viewed [here](https://lpdaac.usgs.gov/products/mcd12q1v061/)." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:        (lon: 1440, lat: 720, time: 1480)\n",
-       "Coordinates:\n",
-       "  * lon            (lon) float32 -179.9 -179.6 -179.4 ... 179.4 179.6 179.9\n",
-       "  * lat            (lat) float32 -89.88 -89.62 -89.38 ... 89.38 89.62 89.88\n",
-       "  * time           (time) datetime64[ns] 1988-02-02 1988-02-10 ... 2020-06-25\n",
-       "Data variables:\n",
-       "    gpi            (lat, lon) float32 ...\n",
-       "    crs            |S1 ...\n",
-       "    GPP            (time, lat, lon) float64 ...\n",
-       "    Uncertainties  (lat, lon) float32 ...\n",
-       "Attributes: (12/20)\n",
-       "    title:                    VODCA-based GPP estimate at 8-daily, 0.25 degre...\n",
-       "    geospatial_lon_min:       -179.875\n",
-       "    geospatial_lat_max:       89.875\n",
-       "    data_input:               VODCA (merged-frequency), 8-daily, 0.25deg\n",
-       "    created_with_software:    Python 2.7.11\n",
-       "    geospatial_lon_sampling:  0.25 degree\n",
-       "    ...                       ...\n",
-       "    training_data:            FLUXNET2015\n",
-       "    source:                   GAM_FLUXNET_VOD_dVOD_median_T2M\n",
-       "    date_created:             2021-05-11 07:09:43\n",
-       "    creater_url:              climers.geo.tuwien.ac.at\n",
-       "    geospatial_lon_max:       179.875\n",
-       "    Conventions:              CF-1.6
" - ], - "text/plain": [ - "\n", - "Dimensions: (lon: 1440, lat: 720, time: 1480)\n", - "Coordinates:\n", - " * lon (lon) float32 -179.9 -179.6 -179.4 ... 179.4 179.6 179.9\n", - " * lat (lat) float32 -89.88 -89.62 -89.38 ... 89.38 89.62 89.88\n", - " * time (time) datetime64[ns] 1988-02-02 1988-02-10 ... 2020-06-25\n", - "Data variables:\n", - " gpi (lat, lon) float32 ...\n", - " crs |S1 ...\n", - " GPP (time, lat, lon) float64 ...\n", - " Uncertainties (lat, lon) float32 ...\n", - "Attributes: (12/20)\n", - " title: VODCA-based GPP estimate at 8-daily, 0.25 degre...\n", - " geospatial_lon_min: -179.875\n", - " geospatial_lat_max: 89.875\n", - " data_input: VODCA (merged-frequency), 8-daily, 0.25deg\n", - " created_with_software: Python 2.7.11\n", - " geospatial_lon_sampling: 0.25 degree\n", - " ... ...\n", - " training_data: FLUXNET2015\n", - " source: GAM_FLUXNET_VOD_dVOD_median_T2M\n", - " date_created: 2021-05-11 07:09:43\n", - " creater_url: climers.geo.tuwien.ac.at\n", - " geospatial_lon_max: 179.875\n", - " Conventions: CF-1.6" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# gpp data is acquired from this work: https://essd.copernicus.org/articles/14/1063/2022/\n", - "url_GPP='https://researchdata.tuwien.ac.at/records/1k7aj-bdz35/files/VODCA2GPP_v1.nc?download=1'\n", - "ds_GPP=xr.open_dataset(pooch.retrieve(url_GPP,known_hash=None))\n", - "ds_GPP" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# **ERA5-Land monthly averaged data from 1950 to present**\n", - "\n", - "**[ERA5-Land](https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-land-monthly-means?tab=overview)** is a reanalysis dataset that offers an enhanced resolution compared to [ERA5](https://www.ecmwf.int/en/forecasts/dataset/ecmwf-reanalysis-v5), providing a consistent view of land variables over several decades. It is created by replaying the land component of the ECMWF ERA5 climate reanalysis, which combines model data and global observations to generate a complete and reliable dataset using the laws of physics. \n", - "\n", - "ERA5-Land focuses on the water and energy cycles at the surface level, offering a detailed record starting from 1950. The data used here is a post-processed subset of the complete ERA5-Land dataset. Monthly-mean averages have been pre-calculated to facilitate quick and convenient access to the data, particularly for applications that do not require sub-monthly fields. The native spatial resolution of the ERA5-Land reanalysis dataset is 9km on a reduced Gaussian grid (TCo1279). The data in the CDS has been regridded to a regular lat-lon grid of 0.1x0.1 degrees.\n", - "\n", - "## **To calculate albedo using ERA5-Land**\n", - "ERA5 parameter [`Forecast albedo`](https://codes.ecmwf.int/grib/param-db/?id=243) provides is the measure of the reflectivity of the Earth's surface. It is the fraction of solar (shortwave) radiation reflected by Earth's surface, across the solar spectrum, for both direct and diffuse radiation. Values are between 0 and 1. Typically, snow and ice have high reflectivity with albedo values of 0.8 and above, land has intermediate values between about 0.1 and 0.4 and the ocean has low values of 0.1 or less. Radiation from the Sun (solar, or shortwave, radiation) is partly reflected back to space by clouds and particles in the atmosphere (aerosols) and some of it is absorbed. The rest is incident on the Earth's surface, where some of it is reflected. The portion that is reflected by the Earth's surface depends on the albedo. In the ECMWF Integrated Forecasting System (IFS), a climatological background albedo (observed values averaged over a period of several years) is used, modified by the model over water, ice and snow. Albedo is often shown as a percentage (%).\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adHRNDL6EMx-" - }, - "source": [ - "## **Alternative Approach to Obtain Albedo Data from MERRA-2**\n", - "\n", - "MERRA-2 is a NASA satellite dataset that incorporates advances that facilitate the assimilation of modern hyperspectral radiance, microwave observations, and GPS-Radio Occultation datasets. It also includes NASA's ozone profile observations starting from late 2004, and improvements in the GEOS model and the GSI assimilation system. MERRA-2 maintains a similar spatial resolution to its predecessor, approximately 50 km in the latitudinal direction. It provides different kinds of information at different spatial resolutions than MODIS. MERRA-2 has a coarser spatial resolution than MODIS. While MODIS provides land cover data at a resolution of 500 meters, MERRA-2 offers meteorological data at a much coarser resolution of approximately 50 kilometers. \n", - "\n", - "Further background on the dataset could be found [here](https://gmao.gsfc.nasa.gov/reanalysis/MERRA-2/).\n", - "\n", - "Extra help on downloading MERRA-2 datasets:\n", - "- https://daac.gsfc.nasa.gov/information/howto?title=How%20to%20Access%20MERRA-2%20Data%20using%20OPeNDAP%20with%20Python3%20and%20Calculate%20Daily%2FWeekly%2FMonthly%20Statistics%20from%20Hourly%20Data%20\n", - "\n", - "- https://github.com/emilylaiken/merradownload\n", - "\n", - "- https://github.com/Open-Power-System-Data/weather_data/blob/master/download_merra2.ipynb\n", - "\n", - "- https://daac.gsfc.nasa.gov/information/howto?title=How%20to%20remotely%20access%20MERRA-2%20with%20Python3%20and%20calculate%20monthly%20average%20surface%20PM2.5%20for%20world%20countries" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:      (band: 1, longitude: 8016, latitude: 3229)\n",
-       "Coordinates:\n",
-       "  * band         (band) int64 1\n",
-       "  * longitude    (longitude) float64 -180.0 -180.0 -179.9 ... 179.9 180.0 180.0\n",
-       "  * latitude     (latitude) float64 85.0 84.96 84.91 ... -59.9 -59.94 -59.99\n",
-       "    spatial_ref  int64 ...\n",
-       "Data variables:\n",
-       "    band_data    (band, latitude, longitude) float64 ...
" - ], - "text/plain": [ - "\n", - "Dimensions: (band: 1, longitude: 8016, latitude: 3229)\n", - "Coordinates:\n", - " * band (band) int64 1\n", - " * longitude (longitude) float64 -180.0 -180.0 -179.9 ... 179.9 180.0 180.0\n", - " * latitude (latitude) float64 85.0 84.96 84.91 ... -59.9 -59.94 -59.99\n", - " spatial_ref int64 ...\n", - "Data variables:\n", - " band_data (band, latitude, longitude) float64 ..." - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# source of landuse data: https://doi.pangaea.de/10.1594/PANGAEA.913496\n", - "# the folder \"land-use\" has the data for years 1982 to 2015. choose the years you need and change the path accordingly \n", - "path_LandUse=os.path.expanduser('~/shared/Data/Projects/Albedo/land-use/GLASS-GLC_7classes_1982.tif')\n", - "ds_landuse=xr.open_dataset(path_LandUse).rename({'x':'longitude', 'y':'latitude'})\n", - "# ds_landuse.band_data[0,:,:].plot() # how to plot the global data\n", - "ds_landuse" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:    (longitude: 3600, latitude: 1801, time: 240)\n",
-       "Coordinates:\n",
-       "  * longitude  (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9\n",
-       "  * latitude   (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0\n",
-       "  * time       (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01\n",
-       "Data variables:\n",
-       "    fal        (time, latitude, longitude) float32 ...\n",
-       "Attributes:\n",
-       "    Conventions:  CF-1.6\n",
-       "    history:      2023-06-27 17:05:46 GMT by grib_to_netcdf-2.25.1: /opt/ecmw...
" - ], - "text/plain": [ - "\n", - "Dimensions: (longitude: 3600, latitude: 1801, time: 240)\n", - "Coordinates:\n", - " * longitude (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9\n", - " * latitude (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0\n", - " * time (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01\n", - "Data variables:\n", - " fal (time, latitude, longitude) float32 ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " history: 2023-06-27 17:05:46 GMT by grib_to_netcdf-2.25.1: /opt/ecmw..." - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# link for albedo data:\n", - "\n", - "albedo_path='~/shared/Data/Projects/Albedo/ERA/albedo-001.nc'\n", - "ds_albedo=xr.open_dataset(albedo_path)\n", - "ds_albedo # note the official variable name is fal (forecast albedo)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "for your convience, included below are preciptation and temprature ERA5 dataset for the same times as the Albedo dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:    (longitude: 3600, latitude: 1801, time: 240)\n",
-       "Coordinates:\n",
-       "  * longitude  (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9\n",
-       "  * latitude   (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0\n",
-       "  * time       (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01\n",
-       "Data variables:\n",
-       "    tp         (time, latitude, longitude) float32 ...\n",
-       "Attributes:\n",
-       "    Conventions:  CF-1.6\n",
-       "    history:      2023-06-27 17:02:16 GMT by grib_to_netcdf-2.25.1: /opt/ecmw...
" - ], - "text/plain": [ - "\n", - "Dimensions: (longitude: 3600, latitude: 1801, time: 240)\n", - "Coordinates:\n", - " * longitude (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9\n", - " * latitude (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0\n", - " * time (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01\n", - "Data variables:\n", - " tp (time, latitude, longitude) float32 ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " history: 2023-06-27 17:02:16 GMT by grib_to_netcdf-2.25.1: /opt/ecmw..." - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "precp_path='~/shared/Data/Projects/Albedo/ERA/precipitation-002.nc'\n", - "ds_precp=xr.open_dataset(precp_path)\n", - "ds_precp # the variable name is tp (total preciptation)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
<xarray.Dataset>\n",
-       "Dimensions:    (longitude: 3600, latitude: 1801, time: 240)\n",
-       "Coordinates:\n",
-       "  * longitude  (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9\n",
-       "  * latitude   (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0\n",
-       "  * time       (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01\n",
-       "Data variables:\n",
-       "    t2m        (time, latitude, longitude) float32 ...\n",
-       "Attributes:\n",
-       "    Conventions:  CF-1.6\n",
-       "    history:      2023-06-27 16:58:35 GMT by grib_to_netcdf-2.25.1: /opt/ecmw...
" - ], - "text/plain": [ - "\n", - "Dimensions: (longitude: 3600, latitude: 1801, time: 240)\n", - "Coordinates:\n", - " * longitude (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9\n", - " * latitude (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0\n", - " * time (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01\n", - "Data variables:\n", - " t2m (time, latitude, longitude) float32 ...\n", - "Attributes:\n", - " Conventions: CF-1.6\n", - " history: 2023-06-27 16:58:35 GMT by grib_to_netcdf-2.25.1: /opt/ecmw..." - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tempr_path='~/shared/Data/Projects/Albedo/ERA/Temperature-003.nc'\n", - "ds_tempr=xr.open_dataset(tempr_path)\n", - "ds_tempr # the variable name is t2m (temprature at 2m)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "e5KKmsTujjAg" - }, - "source": [ - "# **Further Reading**\n", - "- Zhao, X., Wu, T., Wang, S., Liu, K., Yang, J. Cropland abandonment mapping at sub-pixel scales using crop phenological information and MODIS time-series images, Computers and Electronics in Agriculture, Volume 208,\n", - "2023,107763, ISSN 0168-1699,https://doi.org/10.1016/j.compag.2023.107763\n", - "\n", - "- Shani Rohatyn et al., Limited climate change mitigation potential through forestation of the vast dryland regions.Science377,1436-1439(2022).DOI:10.1126/science.abm9684\n", - "\n", - "- Hu, Y., Hou, M., Zhao, C., Zhen, X., Yao, L., Xu, Y. Human-induced changes of surface albedo in Northern China from 1992-2012, International Journal of Applied Earth Observation and Geoinformation, Volume 79, 2019, Pages 184-191, ISSN 1569-8432, https://doi.org/10.1016/j.jag.2019.03.018\n", - "\n", - "- Duveiller, G., Hooker, J. & Cescatti, A. The mark of vegetation change on Earth’s surface energy balance. Nat Commun 9, 679 (2018). https://doi.org/10.1038/s41467-017-02810-8\n", - "\n", - "- Yin, H., Brandão, A., Buchner, J., Helmers, D., Iuliano, B.G., Kimambo, N.E., Lewińska, K.E., Razenkova, E., Rizayeva, A., Rogova, N., Spawn, S.A., Xie, Y., Radeloff, V.C. Monitoring cropland abandonment with Landsat time series, Remote Sensing of Environment, Volume 246, 2020, 111873, ISSN 0034-4257,https://doi.org/10.1016/j.rse.2020.111873\n", - "\n", - "- Gupta, P., Verma, S., Bhatla, R.,Chandel, A. S., Singh, J., & Payra, S.(2020). Validation of surfacetemperature derived from MERRA‐2Reanalysis against IMD gridded data setover India.Earth and Space Science,7,e2019EA000910. https://doi.org/10.1029/2019EA000910\n", - "\n", - "- Cao, Y., S. Liang, X. Chen, and T. He (2015) Assessment of Sea Ice Albedo Radiative Forcing and Feedback over the Northern Hemisphere from 1982 to 2009 Using Satellite and Reanalysis Data. J. Climate, 28, 1248–1259, https://doi.org/10.1175/JCLI-D-14-00389.1.\n", - "\n", - "- Westberg, D. J., P. Stackhouse, D. B. Crawley, J. M. Hoell, W. S. Chandler, and T. Zhang (2013), An Analysis of NASA's MERRA Meteorological Data to Supplement Observational Data for Calculation of Climatic Design Conditions, ASHRAE Transactions, 119, 210-221. \n", - "https://www.researchgate.net/profile/Drury-Crawley/publication/262069995_An_Analysis_of_NASA's_MERRA_Meteorological_Data_to_Supplement_Observational_Data_for_Calculation_of_Climatic_Design_Conditions/links/5465225f0cf2052b509f2cc0/An-Analysis-of-NASAs-MERRA-Meteorological-Data-to-Supplement-Observational-Data-for-Calculation-of-Climatic-Design-Conditions.pdf" - ] - } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/projects/project-notebooks/Wildfires_and_burnt_areas.ipynb b/book/_build/html/_sources/projects/project-notebooks/Wildfires_and_burnt_areas.ipynb deleted file mode 100644 index 22f576002..000000000 --- a/book/_build/html/_sources/projects/project-notebooks/Wildfires_and_burnt_areas.ipynb +++ /dev/null @@ -1,1245 +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/ClimateMatchAcademy/course-content/blob/main/projects/project-notebooks/Wildfires_and_burnt_areas.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "avjFjFXwWqyW" - }, - "source": [ - "# **Monitoring and Mapping Wildfires Using Satellite Data**\n", - "\n", - "\n", - "**Content creators:** Brittany Engle, Diana Cadillo\n", - "\n", - "**Content reviewers:** Yuhan Douglas Rao, Abigail Bodner, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Zane Mitrevica, Natalie Steinemann, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "umnBeSiJeqYo", - "tags": [] - }, - "outputs": [], - "source": [ - "# @title Project Background\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(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', '2CDVn6O_q34'), ('Bilibili', 'BV1GP411k7XA')]\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": {}, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"8w5da\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "DZbqRlQKXhnc" - }, - "source": [ - "**In this project**, you will be working with wildfire remote sensing data from Sentinel 2 to extract Burn Perimeters using multiple Burn Indices and other relevant information related to wildfires. By integrating this data with information from other global databases, you will have the opportunity to explore the connections between wildfires and their impact on both the ecosystem and society." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "adR8NLN_ZsZL" - }, - "source": [ - "# Project Template\n", - "\n", - "![Project Template](https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/projects/template-images/wildfires_template_map.svg)\n", - "\n", - "*Note: The dashed boxes are socio-economic questions.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "-uS_n9-3YJrZ" - }, - "source": [ - "# Data Exploration Notebook\n", - "## Project Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 17725, - "status": "ok", - "timestamp": 1683683352507, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - }, - "id": "bQIzYE55tlNc", - "outputId": "0e7aa8fe-b40a-4f0b-d7a5-0280b737c7a5", - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# installs\n", - "# !pip install gdal\n", - "# !pip install pandas\n", - "# !pip install geopandas" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "9nDg6MeVY1CX", - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import random\n", - "import numpy\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import geopandas as gpd\n", - "import os\n", - "import matplotlib\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "iYblWn8cZAGT" - }, - "source": [ - "## Satellite Data\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "x7UoFGkrhfvt" - }, - "source": [ - "\n", - "**Global Wildfire Information System (GWIS)** is a global, joint initiative created by the GEO and the Copernicus Work Programs. The goal of this program is to bring together sources at a regional and international level to provide a global, comprehensive understanding of fire regimes and their effects. \n", - "\n", - "The Globfire dataset uses the MODIS burned area product (MCD64A1) to determine the amount of burnt area per event ([Artés et al., 2019](\n", - "https://www.nature.com/articles/s41597-019-0312-2)). The MCD64A1 product that Globfire is built on top of combines imagery from the Terra and Aqua satellites with thermal anomalies to provide burnt area information ([Website](https://modis-land.gsfc.nasa.gov/burn.html), [MODIS C6 BA User Guide](https://modis-land.gsfc.nasa.gov/burn.html) & [User Guide](http://modis-fire.umd.edu/files/MODIS_C6_BA_User_Guide_1.2.pdf)). \n", - "\n", - "**Sentinel 2**\n", - "Launched by the European Space Agency in June of 2015 (S2-A) and March of 2017 (S2-B), the Copernicus Sentinel-2 mission combines two polar-orbiting satellites to monitor variability in land surface conditions. Together, they have a global revisit time of roughly 5 days. \n", - "\n", - "\n", - "\n", - "In the provided Project Template, we load the following datasets:\n", - "- [Global Wildfire Information Systems](https://gwis.jrc.ec.europa.eu/apps/country.profile/downloads)\n", - "- [Sentinel-2](https://sentinel.esa.int/web/sentinel/sentinel-data-access/sentinel-products/sentinel-2-data-products)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "W43m6TQBZrpe" - }, - "source": [ - "\n", - "## Global Wildfire Information Systems: Climate Action Large Wildfire Dataset\n", - "\n", - "\n", - "The Climate Action Large Wildfire Dataset is a filtered version of the Globfire dataset (created by GWIS, which you can access [here](https://gwis.jrc.ec.europa.eu/apps/country.profile/downloads)). \n", - "\n", - "\n", - "The resolution of this dataset is 500m. It has been pre-filtered to include only fires that are Class F or greater. Per the National Wildfire Coordinating Group, a Class F fire is defined as a fire that is 1,000 acres or greater, but less than 5,000 acres (note that a 2000m square region is roughly 1000 acres). For this dataset, all fires greater than 1,000 acres are included. Additional columns indicating area (acres), landcover number and landcover description, and country in which they are located within, were added. The landcover number and description were added using the Copernicus Global Land Cover Layers: CGLS-LC100 Collection 3 [User Guide](https://zenodo.org/record/3938963#.ZEeQEnZBwuU). \n", - "\n", - "Table Information: \n", - "ID: Globfire fire ID (unique to each fire)\n", - "\n", - "1. IDate: Globfire Initial (start) date of the fire\n", - "2. FDate: Globfire Final (end) date of the fire\n", - "3. Continent: Location of the fire \n", - "4. Area_acres: size of fire in acres \n", - "5. Landcover: land cover value from ESA, if the landcover of the fire cover is greater than 51%, then it is labeled as that landcover\n", - "6. LC_descrip: land cover description from ESA\n", - "7. Country: country the fire is located in" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 336 - }, - "executionInfo": { - "elapsed": 139, - "status": "error", - "timestamp": 1683683445493, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - }, - "id": "mZMo14eJs26r", - "outputId": "5c51fae7-88fd-43ce-e5ee-4ebd0d29846f", - "tags": [] - }, - "outputs": [], - "source": [ - "# code to retrieve and load the data\n", - "url_climateaction = \"~/shared/Data/Projects/Wildfires/ClimateAction_countries.shp\"\n", - "Dataset = gpd.read_file(url_climateaction) # need to update to OSF and pooch.retrieve" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "9UbbKMMQbI0C" - }, - "source": [ - "We can now visualize the content of the dataset.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 250 - }, - "executionInfo": { - "elapsed": 437, - "status": "ok", - "timestamp": 1682947558026, - "user": { - "displayName": "Brittany Engle", - "userId": "17478816758226363586" - }, - "user_tz": -120 - }, - "id": "BlAQNu898z5s", - "outputId": "a05d6f73-f667-4266-9c62-4175cf5d1c23", - "tags": [] - }, - "outputs": [], - "source": [ - "# code to print the shape, array names, etc of the dataset\n", - "Dataset.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 250 - }, - "executionInfo": { - "elapsed": 292045, - "status": "ok", - "timestamp": 1682947856705, - "user": { - "displayName": "Brittany Engle", - "userId": "17478816758226363586" - }, - "user_tz": -120 - }, - "id": "cW2w0nRcdC4_", - "outputId": "d9f88e88-6b5c-4340-d66c-384bb7fcdd40", - "tags": [] - }, - "outputs": [], - "source": [ - "# plot the dataset\n", - "Dataset.plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "wCxY5V_-iMGa" - }, - "source": [ - "Great work! Now you are all set to address the questions you are interested in! Good luck!" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "g1wMbOtxJ_B9" - }, - "source": [ - "\n", - "## Sentinel-2\n", - "\n", - "Each of the two satellites contain a Multi-Spectral Instrument (MSI) that houses 13 spectral bands, at various resolutions. The MSI uses a push-broom acquisition technique and measures in the Visible and Near Infrared (NIR) and the Short Wave Infrared (SWIR) domains. There are:\n", - "\n", - "- Four bands with 10m resolution: B2-Blue (490 nm), B3- Green (560 nm), B4- Red (665 nm) and Band 8- Near Infrared (NIR) (842 nm). \n", - "- Six bands with 20m resolution: B5, B6, B7 and B8A (705 nm, 740 nm, 783 nm and 865 nm respectively) Vegetation Red Edge bands, along with B11 and B12 (1610 nm and 2190 nm) SWIR bands. These bands are mostly used for vegetation characterisation, vegetation stress assessment and ice/cloud/snow detection. \n", - "- Three additional bands: B1 - Coastal Aerosol (443 nm), B9- Water Vapor (945 nm), and B10-SWIR-Cirrus (1375 nm) which are typically used for corrections of the atmosphere and clouds.\n", - "\n", - "\n", - "*[Sentinel-2](https://sentinel.esa.int/web/sentinel/missions/sentinel-2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "m3Eknl4wPjec", - "tags": [] - }, - "outputs": [], - "source": [ - "# view image\n", - "def showImage(Output):\n", - " plt.imshow(Output)\n", - " plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "8j0IP8SFFPD7", - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# data source-specific imports\n", - "\n", - "# root folder location of where the imagery is currently saved\n", - "rootFolder = '/home/jovyan/shared/Data/Projects/Wildfires'\n", - "\n", - "continet = \"Asia\"\n", - "\n", - "# import pre images\n", - "# pre_fire_paths = glob.glob(rootFolder + continet + id +\"/pre_fire_*.npy\")\n", - "pre_fire_paths = [\n", - " fileName\n", - " for fileName in os.listdir(os.path.join(rootFolder, continet))\n", - " if (fileName.endswith(\".npy\") & fileName.startswith(\"pre_fire_\"))\n", - "]\n", - "pre_fires_numpy = [\n", - " numpy.load(os.path.join(rootFolder, continet, x)).astype(int)\n", - " for x in pre_fire_paths\n", - "]\n", - "\n", - "# import post images\n", - "post_fire_paths = [\n", - " fileName\n", - " for fileName in os.listdir(os.path.join(rootFolder, continet))\n", - " if (fileName.endswith(\".npy\") & fileName.startswith(\"post_fire_\"))\n", - "]\n", - "post_fires_numpy = [\n", - " numpy.load(os.path.join(rootFolder, continet, x)).astype(int)\n", - " for x in post_fire_paths\n", - "]\n", - "\n", - "# import Pre-SCL Mask for cloud coverage\n", - "scl_fire_paths = [\n", - " fileName\n", - " for fileName in os.listdir(os.path.join(rootFolder, continet))\n", - " if (fileName.endswith(\".npy\") & fileName.startswith(\"scl_pre_fire_\"))\n", - "]\n", - "scl_fires_numpy = [\n", - " numpy.load(os.path.join(rootFolder, continet, x)) for x in scl_fire_paths\n", - "]\n", - "\n", - "# import Post-SCL Mask for cloud coverage\n", - "scl_fires_post_paths = [\n", - " fileName\n", - " for fileName in os.listdir(os.path.join(rootFolder, continet))\n", - " if (fileName.endswith(\".npy\") & fileName.startswith(\"scl_post_fire_\"))\n", - "]\n", - "scl_fires_post_numpy = [\n", - " numpy.load(os.path.join(rootFolder, continet, x)) for x in scl_fires_post_paths\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "8jyYEuF8Etpu", - "tags": [] - }, - "outputs": [], - "source": [ - "# print list of pre_fires\n", - "print(\"\\n\".join(pre_fire_paths))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "zI8yjtGvF0dT", - "tags": [] - }, - "outputs": [], - "source": [ - "# print list of post_fire\n", - "print(\"\\n\".join(post_fire_paths))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 832, - "status": "ok", - "timestamp": 1682948070869, - "user": { - "displayName": "Brittany Engle", - "userId": "17478816758226363586" - }, - "user_tz": -120 - }, - "id": "He-3ryXQft2-", - "outputId": "46d9ea1d-1b24-40b3-c8a6-20e2102b1889", - "tags": [] - }, - "outputs": [], - "source": [ - "# print list of SCL\n", - "print(\"\\n\".join(scl_fire_paths))\n", - "print(\"\\n\".join(scl_fires_post_paths))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "cvJxnr4ae1Mv", - "tags": [] - }, - "outputs": [], - "source": [ - "# view pre-fire satellite image that was taken right before the fire start date\n", - "showImage(\n", - " numpy.clip(pre_fires_numpy[2][:, :, [3, 2, 1]] / 10000 * 3.5, 0, 1)\n", - ") # RGB bands for Sentinel 2 are Bands: 4,3,2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "kdfXuqpRe1Hi", - "tags": [] - }, - "outputs": [], - "source": [ - "# view post-fire satellite image that was taken right before the fire start date\n", - "showImage(\n", - " numpy.clip(post_fires_numpy[0][:, :, [3, 2, 1]] / 10000 * 3.5, 0, 1)\n", - ") # RGB bands for Sentinel 2 are Bands: 4,3,2" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "pSUjOHGqFPD7" - }, - "source": [ - "### Sentinel-2: Vegetation Health & Burnt Areas\n", - "\n", - "[Sentinel-2 Imagery - Vegetation Health & Burnt Areas](https://drive.google.com/drive/folders/1u7UMz8gIkTPWUv6p5OhlE4jXaZAh-oP4?usp=sharing)\n", - "\n", - "Continents included:\n", - "\n", - "* Asia\n", - "* Africa\n", - "* Austrailia \n", - "* Europe\n", - "* North America\n", - "* South America\n", - "\n", - "\n", - "**Vegetation Health:** Vegetation indices define and monitor the health of vegetation using the radiance values of the visible and near-infrared channels. The Normalized Difference Vegetation Index (NDVI) is used to measure “greenness” of vegetation.\n", - "As one of the most widely used vegetation indexes, the NDVI takes advantage of how strongly Chlorophyll absorbs visible light and how well the leafs cellular structure reflects near-infrared. Its values range from +1.0 to -1.0, with areas of sand, rock, and snow typically having a value of 0.1 or less. Shrubs and spare vegetation are roughly 0.2 to 0.5, while higher NDVI values (0.6 to 0.9) indicate dense vegetation that is typically found in tropical forests. \n", - "\n", - "The NDVI can also be used to create the Vegetation Condition Index (VCI). The VCI depends on the current NDVI along with the extreme NDVI values within the dataset (NDVImax and NDVImin). Specifically, $$VCI = \\frac{NDVI-NDVImin}{NDVImax-NDVImin}\\times 100\\%$$ \n", - "\n", - "This number is then compared to the threshold to determine the drought severity. For this project, up to 3 months of pre-fire imagery will be used to determine current drought conditions.\n", - "\n", - "* [NDVI, the Foundation for Remote Sensing Phenology | U.S. Geological Survey](https://www.usgs.gov/special-topics/remote-sensing-phenology/science/ndvi-foundation-remote-sensing-phenology#overview)\n", - "* [Application of NDVI in Vegetation Monitoring using Sentinel -2 Data for Shrirampur Region of Maharashtra](https://www.researchgate.net/publication/349763642_Application_of_NDVI_in_Vegetation_Monitoring_using_Sentinel_-2_Data_for_Shrirampur_Region_of_Maharashtra)\n", - "\n", - "\n", - "**Burnt Area Severity:** Burn severity describes how the intensity of the fire affects the functioning of the ecosystem in which it occurred. The degree to which it alters the ecosystem is typically found using a burn index, which then (typically) classes the severity of the fire as: unburned, low severity, moderate severity, or high severity. One of the most common burn indices is the Normalized Burn Ratio (NBR). This index is designed to highlight burnt areas in fire zones. The formula is similar to NDVI, except that the formula combines the use of both near infrared (NIR) and shortwave infrared (SWIR) wavelengths. Healthy vegetation shows a very high reflectance in the NIR, and low reflectance in the SWIR portion of the spectrum - the opposite of what is seen in areas devastated by fire. Recently burnt areas demonstrate low reflectance in the NIR and high reflectance in the SWIR. The difference between the spectral responses of healthy vegetation and burnt areas reach their peak in the NIR and the SWIR regions of the spectrum. The difference between normalized burn ratios before and after a fire is called the dNBR, and is one of many useful indices. \n", - "\n", - "Specifically, the dNBR isolates the burned areas from the unburned areas, and subtracts the pre-fire imagery from the post-fire imagery. This removes any unchanged, and thus unburned, pixels as their values result in near zero. The results of the dNBR are based on burn severity, and correspond to the gradient of burn severity for every pixel. The dNBR has an unscaled range of -2.0 to +2.0 with burned areas tending to show more positively.\n", - "\n", - "* [Fire intensity, fire severity and burn severity: A brief review and suggested usage](https://www.researchgate.net/publication/228638145_Fire_intensity_fire_severity_and_burn_severity_A_brief_review_and_suggested_usage)\n", - "* [Quantifying burn severity in a heterogeneous landscape with a relative version of the delta Normalized Burn Ratio (RdNBR)](https://www.researchgate.net/publication/222816542_Quantifying_burn_severity_in_a_heterogeneous_landscape_with_a_relative_version_of_the_delta_Normalized_Burn_Ratio_RdNBR)\n", - "* [A methodology to estimate forest fires burned areas and burn severity degrees using Sentinel-2 data. Application to the October 2017 fires in the Iberian Peninsula](https://www.researchgate.net/publication/346200185_A_methodology_to_estimate_forest_fires_burned_areas_and_burn_severity_degrees_using_Sentinel-2_data_Application_to_the_October_2017_fires_in_the_Iberian_Peninsula)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "vwa934OAT6iF" - }, - "source": [ - "**SCL Mask**\n", - "Importing the SCL in order to mask out clouds form imagery" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "niyA5pvcUSMI", - "tags": [] - }, - "outputs": [], - "source": [ - "# compute SCL Mask to 0s and 1s, masking out clouds and bad pixels\n", - "def computeSCLMask(image):\n", - " rImage, cImage = image.shape\n", - " sclOutput = numpy.zeros((rImage, cImage))\n", - " for x in range(cImage):\n", - " for y in range(rImage):\n", - " sclOutput[y, x] = 1 if image[y, x] in [0, 1, 3, 8, 9, 11] else 0\n", - "\n", - " return sclOutput" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "executionInfo": { - "elapsed": 11126, - "status": "ok", - "timestamp": 1682948117052, - "user": { - "displayName": "Brittany Engle", - "userId": "17478816758226363586" - }, - "user_tz": -120 - }, - "id": "QQYUFF0GUtkB", - "outputId": "3e709486-1bbc-4e0d-fc87-895d0fdde3e7", - "tags": [] - }, - "outputs": [], - "source": [ - "# create Pre-fire and post-fire SCL masks\n", - "print(scl_fires_numpy[5])\n", - "pre_SCL_Mask = computeSCLMask(scl_fires_numpy[5])\n", - "post_SCL_Mask = computeSCLMask(scl_fires_post_numpy[0])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 435 - }, - "executionInfo": { - "elapsed": 1485, - "status": "ok", - "timestamp": 1682948355425, - "user": { - "displayName": "Brittany Engle", - "userId": "17478816758226363586" - }, - "user_tz": -120 - }, - "id": "EiSrzHD6IkHI", - "outputId": "8d2e4cbb-66ad-43e4-d507-759276117670", - "tags": [] - }, - "outputs": [], - "source": [ - "# view SCL imagery for image closests to the start fire date\n", - "# ------- Save SCL as colored image based on SCL classification\n", - "\n", - "# No Data (0) = black\n", - "# Saturated / Defective (1) = red\n", - "# Dark Area Pixels (2) = chocolate\n", - "# Cloud Shadows (3) = brown\n", - "# Vegetation (4) = lime\n", - "# Bare Soils (5) = yellow\n", - "# Water (6) = blue\n", - "# Clouds low probability / Unclassified (7) = aqua\n", - "# clouds medium probability (8) = darkgrey\n", - "# Clouds high probability (9) light grey\n", - "# Cirrus (10) = deepskyblue\n", - "# Snow / Ice (11) = magenta\n", - "# colors: https://matplotlib.org/3.1.1/gallery/color/named_colors.html#sphx-glr-gallery-color-named-colors-py\n", - "\n", - "\n", - "def showSCL(image):\n", - " cmap = matplotlib.colors.ListedColormap(\n", - " [\n", - " \"black\",\n", - " \"red\",\n", - " \"chocolate\",\n", - " \"brown\",\n", - " \"lime\",\n", - " \"yellow\",\n", - " \"blue\",\n", - " \"aqua\",\n", - " \"darkgrey\",\n", - " \"lightgrey\",\n", - " \"deepskyblue\",\n", - " \"magenta\",\n", - " ]\n", - " )\n", - " plt.imshow(image, cmap=cmap)\n", - " plt.show()\n", - "\n", - "\n", - "showSCL(scl_fires_numpy[5])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "S_3NQ6vSTmFs" - }, - "source": [ - "### Dataset-specific Functions: NDVI" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "gXVcj_lRKdsr", - "tags": [] - }, - "outputs": [], - "source": [ - "# this code computes the NDVI for an image\n", - "\"The NDVI can be computed on any image (pre or post).\"\n", - "\"Compute the NDVI on the pre-fire image\"\n", - "\n", - "# compute NDVI\n", - "def computeNDVI(image, mask):\n", - " r, c, ch = image.shape\n", - " ndviOutput = numpy.zeros((r, c))\n", - " for x in range(c):\n", - " for y in range(r):\n", - " if (image[y, x, 7] == 0 and image[y, x, 3] == 0) or mask[y, x] == 1:\n", - " ndviOutput[y, x] = numpy.nan\n", - " else:\n", - " ndviOutput[y, x] = (image[y, x, 7] - image[y, x, 3]) / (\n", - " image[y, x, 7] + image[y, x, 3]\n", - " )\n", - "\n", - " return ndviOutput" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "zggzwppiQ-NJ", - "tags": [] - }, - "outputs": [], - "source": [ - "# TA Code\n", - "computeNDVI_value = computeNDVI(pre_fires_numpy[2], pre_SCL_Mask)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "tdkDVJqnSdDM", - "tags": [] - }, - "outputs": [], - "source": [ - "# plot NDVI without remap\n", - "showImage(computeNDVI_value)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "RRayrsujOxOR", - "tags": [] - }, - "outputs": [], - "source": [ - "# use this code to remap the NDVI to specific colors for values\n", - "def remapNDVI(NDVI):\n", - " remapped = numpy.zeros((NDVI.shape[0], NDVI.shape[1]))\n", - " for x in range(remapped.shape[0]):\n", - " for y in range(remapped.shape[1]):\n", - " if numpy.isnan(NDVI[x, y]):\n", - " remapped[x, y] = numpy.nan\n", - " elif NDVI[x, y] <= -0.2:\n", - " remapped[x, y] = 1\n", - " elif NDVI[x, y] <= 0:\n", - " remapped[x, y] = 2\n", - " elif NDVI[x, y] <= 0.1:\n", - " remapped[x, y] = 3\n", - " elif NDVI[x, y] <= 0.2:\n", - " remapped[x, y] = 4\n", - " elif NDVI[x, y] <= 0.3:\n", - " remapped[x, y] = 5\n", - " elif NDVI[x, y] <= 0.4:\n", - " remapped[x, y] = 6\n", - " elif NDVI[x, y] <= 0.5:\n", - " remapped[x, y] = 7\n", - " elif NDVI[x, y] <= 0.6:\n", - " remapped[x, y] = 8\n", - " elif NDVI[x, y] <= 0.7:\n", - " remapped[x, y] = 9\n", - " elif NDVI[x, y] <= 0.8:\n", - " remapped[x, y] = 10\n", - " elif NDVI[x, y] <= 0.9:\n", - " remapped[x, y] = 11\n", - " elif NDVI[x, y] <= 1:\n", - " remapped[x, y] = 12\n", - " else:\n", - " remapped[x, y] = 13\n", - " return remapped" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "K2eiBdXiRPvY", - "tags": [] - }, - "outputs": [], - "source": [ - "# TA Code\n", - "NDVI_remap = remapNDVI(computeNDVI_value)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 435 - }, - "executionInfo": { - "elapsed": 498, - "status": "ok", - "timestamp": 1682947326729, - "user": { - "displayName": "Brittany Engle", - "userId": "17478816758226363586" - }, - "user_tz": -120 - }, - "id": "hPnDRc-1OxCl", - "outputId": "63471bb9-985f-4132-c977-67ce376a4c0f", - "tags": [] - }, - "outputs": [], - "source": [ - "# view remapped NDVI\n", - "def showNDVI(image):\n", - " cmap = matplotlib.colors.ListedColormap(\n", - " [\n", - " \"#000000\",\n", - " \"#a50026\",\n", - " \"#d73027\",\n", - " \"#f46d43\",\n", - " \"#fdae61\",\n", - " \"#fee08b\",\n", - " \"#ffffbf\",\n", - " \"#d9ef8b\",\n", - " \"#a6d96a\",\n", - " \"#66bd63\",\n", - " \"#1a9850\",\n", - " \"#006837\",\n", - " ]\n", - " )\n", - " plt.imshow(image, cmap=cmap)\n", - " plt.show()\n", - "\n", - "\n", - "showNDVI(NDVI_remap)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "dXWcBOWDbC5U" - }, - "source": [ - "### Dataset-specific Functions: VCI" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "G56c-vh2A3lK", - "tags": [] - }, - "outputs": [], - "source": [ - "# compute the SCL mask for all the SCLs and apply it to the pre_fire_NDVIs\n", - "pre_fires_scl = [computeSCLMask(x) for x in scl_fires_numpy]\n", - "pre_fires_NDVI = [computeNDVI(x[0], x[1]) for x in zip(pre_fires_numpy, pre_fires_scl)]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "7CuzHdG0TmDp", - "tags": [] - }, - "outputs": [], - "source": [ - "# compute for VCI\n", - "def computeVCI(for_ndvi_image, ndvi_dataset):\n", - " rImage, cImage = for_ndvi_image.shape\n", - " vciOutput = numpy.zeros((rImage, cImage))\n", - " ndvi_dataset.append(for_ndvi_image)\n", - " for x in range(cImage):\n", - " for y in range(rImage):\n", - " pixels = [z[y, x] for z in ndvi_dataset]\n", - " filtered_pixels = [f for f in pixels if not numpy.isnan(f)]\n", - " if len(filtered_pixels) == 0 or len(filtered_pixels) == 1:\n", - " vciOutput[y, x] = 1\n", - " elif numpy.isnan(for_ndvi_image[y, x]):\n", - " vciOutput[y, x] = 1\n", - " else:\n", - " max_val = max(filtered_pixels)\n", - " min_val = min(filtered_pixels)\n", - " if max_val == min_val:\n", - " vciOutput[y, x] = 1\n", - " else:\n", - " vciOutput[y, x] = (for_ndvi_image[y, x] - min_val) / (\n", - " max_val - min_val\n", - " )\n", - "\n", - " return vciOutput" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "XjZifXXBbu8i" - }, - "source": [ - "### VCI Drought Threshold\n", - "* image and more information: [Spatial and Temporal Variation of Drought Based onSatellite Derived Vegetation Condition Index in Nepal from 1982–2015](https://www.researchgate.net/publication/330521783_Spatial_and_Temporal_Variation_of_Drought_Based_on_Satellite_Derived_Vegetation_Condition_Index_in_Nepal_from_1982-2015)\n", - "\n", - "![droughtthreshold.png](data:image/png;base64,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)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "p9DC1xVqXT2Q", - "tags": [] - }, - "outputs": [], - "source": [ - "# compute the VCI for the last pre-fire to view the drought over the time period\n", - "last_pre_fire_NDVI = pre_fires_NDVI.pop(2)\n", - "last_pre_fire_vci = computeVCI(last_pre_fire_NDVI, pre_fires_NDVI)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 435 - }, - "executionInfo": { - "elapsed": 1157, - "status": "ok", - "timestamp": 1682947352963, - "user": { - "displayName": "Brittany Engle", - "userId": "17478816758226363586" - }, - "user_tz": -120 - }, - "id": "pJUGDcJ4X2hF", - "outputId": "2434882e-1539-484d-c150-0007a07b4462", - "tags": [] - }, - "outputs": [], - "source": [ - "# view the non-thresholded VCI\n", - "showImage(last_pre_fire_vci)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "V4nDV7XqYYve", - "tags": [] - }, - "outputs": [], - "source": [ - "# map specific colors to values to show the severity of the droughts\n", - "def remapVCI(vci):\n", - " remapped = numpy.zeros(vci.shape)\n", - " for x in range(remapped.shape[0]):\n", - " for y in range(remapped.shape[1]):\n", - " if vci[x, y] < 0.35:\n", - " remapped[x, y] = 1\n", - " elif vci[x, y] <= 0.50:\n", - " remapped[x, y] = 2\n", - " else:\n", - " remapped[x, y] = 3\n", - " return remapped" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "lTcBe37lTkpO", - "tags": [] - }, - "outputs": [], - "source": [ - "# define the VCI mapped/thresholded values\n", - "def showVCI(vci_image):\n", - " cmap = matplotlib.colors.ListedColormap([\"red\", \"yellow\", \"green\"])\n", - " plt.imshow(remapVCI(vci_image), cmap=cmap)\n", - " plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "DtkL94_pYkjr", - "tags": [] - }, - "outputs": [], - "source": [ - "# view the mapped VCI values\n", - "showVCI(last_pre_fire_vci)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "a6jUh4EhQjQH" - }, - "source": [ - "### Dataset-specific Functions: NBR and dNBR Code\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "oCg6utrpEm0m", - "tags": [] - }, - "outputs": [], - "source": [ - "# this code creates the NBR for each image then uses the NBR to create the dNBR. It can easily be updated for other burnt area indices\n", - "\n", - "\n", - "def computeFireMasks(pre_fire, post_fire):\n", - "\n", - " rows, columns, channels = pre_fire.shape\n", - " nbrPost = numpy.zeros((rows, columns))\n", - " nbrPre = numpy.zeros((rows, columns))\n", - " dnbr = numpy.zeros((rows, columns))\n", - "\n", - " for x in range(columns):\n", - " for y in range(rows):\n", - " nbrPost[y, x] = (post_fire[y, x, 7] - post_fire[y, x, 11]) / (\n", - " post_fire[y, x, 7] + post_fire[y, x, 11]\n", - " )\n", - " nbrPre[y, x] = (pre_fire[y, x, 7] - pre_fire[y, x, 11]) / (\n", - " pre_fire[y, x, 7] + pre_fire[y, x, 11]\n", - " )\n", - " dnbr[y, x] = nbrPre[y, x] - nbrPost[y, x]\n", - "\n", - " return dnbr" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "juY_OE_eGJ7j", - "tags": [] - }, - "outputs": [], - "source": [ - "# TA Code\n", - "# run computeFireMasks\n", - "dnbr = computeFireMasks(pre_fires_numpy[2], post_fires_numpy[0])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "5KedJ_WsLqj1", - "tags": [] - }, - "outputs": [], - "source": [ - "# this code applies a threshold to the dNBR to show the level of burn intensity (unburned, low severity, moderate severity, or high severity)\n", - "\n", - "\n", - "def remapDNBR(dnbr):\n", - " remapped = numpy.zeros((dnbr.shape[0], dnbr.shape[1]))\n", - " for x in range(remapped.shape[0]):\n", - " for y in range(remapped.shape[1]):\n", - " if numpy.isnan(dnbr[x, y]):\n", - " remapped[x, y] = numpy.nan\n", - " elif dnbr[x, y] <= -0.251:\n", - " remapped[x, y] = 1\n", - " elif dnbr[x, y] <= -0.101:\n", - " remapped[x, y] = 2\n", - " elif dnbr[x, y] <= 0.099:\n", - " remapped[x, y] = 3\n", - " elif dnbr[x, y] <= 0.269:\n", - " remapped[x, y] = 4\n", - " elif dnbr[x, y] <= 0.439:\n", - " remapped[x, y] = 5\n", - " elif dnbr[x, y] <= 0.659:\n", - " remapped[x, y] = 6\n", - " elif dnbr[x, y] <= 1.3:\n", - " remapped[x, y] = 7\n", - " else:\n", - " remapped[x, y] = 8\n", - " return remapped" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "Ymg-OHugHFDB", - "tags": [] - }, - "outputs": [], - "source": [ - "# TA Code\n", - "dnbr_remapped = remapDNBR(dnbr)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "WbuWTGW5M-2E" - }, - "source": [ - "### dNBR Threshold\n", - "* image and more information: [Normalized Burn Ratio (NBR) UN-SPIDER Knowledge Portal](https://un-spider.org/advisory-support/recommended-practices/recommended-practice-burn-severity/in-detail/normalized-burn-ratio)\n", - "\n", - "![threshold.png](data:image/png;base64,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)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "c0h3mIQrMbzV", - "tags": [] - }, - "outputs": [], - "source": [ - "# this code takes the above function (remapDNBR) where the dNBR threshold has been applied to the image'\n", - "# and applies a color coded map to each threshold as shown in the image above'\n", - "\n", - "\n", - "def showDNBR(dnbr):\n", - " cmap = matplotlib.colors.ListedColormap(\n", - " [\n", - " \"blue\",\n", - " \"teal\",\n", - " \"green\",\n", - " \"yellow\",\n", - " \"orange\",\n", - " \"red\",\n", - " \"purple\",\n", - " ]\n", - " )\n", - " plt.imshow(remapDNBR(dnbr), cmap=cmap)\n", - "\n", - "\n", - "showDNBR(dnbr_remapped)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "e5KKmsTujjAg" - }, - "source": [ - "# Further Reading\n", - "\n", - "\n", - "* [Forest ecosystems, disturbance, and climate change in Washington State, USA | US Forest Service Research and Development Fire Ecology and Monitoring at Yosemite](https://www.fs.usda.gov/research/treesearch/38936)\n", - "* [Fire Ecology and Monitoring at Yosemite](https://www.nps.gov/yose/learn/nature/fireecology.htm)\n", - "* [A Project for Monitoring Trends in Burn Severity | Fire Ecology | Full Text](https://fireecology.springeropen.com/articles/10.4996/fireecology.0301003)\n", - "* [The unequal vulnerability of communities of color to wildfire | PLOS ONE ](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0205825)\n", - "* [Fire Frequency, Area Burned, and Severity: A Quantitative Approach to Defining a Normal Fire Year](https://fireecology.springeropen.com/articles/10.4996/fireecology.0702051)\n", - "* [Identifying Key Drivers of Wildfires in the Contiguous US Using Machine Learning and Game Theory Interpretation - Wang - 2021 - Earth's Future - Wiley Online Library](https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2020EF001910)\n", - "* [Science, technology, and human factors in fire danger rating: the Canadian experience](https://www.researchgate.net/publication/237505534_Science_technology_and_human_factors_in_fire_danger_rating_the_Canadian_experience)\n", - "* [Wildfire Selectivity for Land Cover Type: Does Size Matter?](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0084760)\n", - "* [Vegetation, topography and daily weather influenced burn severity in central Idaho and western Montana forests](https://esajournals.onlinelibrary.wiley.com/doi/full/10.1890/ES14-00213.1)\n", - "\n", - "\n", - "Socio-economic effects of wildfires\n", - "\n", - "* Zhao, J. et al. (2020). Quantifying the Effects of Vegetation Restorations on the Soil Erosion Export and Nutrient Loss on the Loess Plateau. Front. Plant Sci. 11 [https://doi.org/10.3389/fpls.2020.573126](https://www.frontiersin.org/articles/10.3389/fpls.2020.573126/full)\n", - "* Amanda K. Hohner, Charles C. Rhoades, Paul Wilkerson, Fernando L. Rosario-Ortiz (2019). Wildfires alter forest watersheds and threaten drinking water quality. Accounts of Chemical Research. 52: 1234-1244. [https://doi.org/10.1021/acs.accounts.8b00670](https://doi.org/10.1021/acs.accounts.8b00670)\n", - "* Alan Buis (2021). The Climate Connections of a Record Fire Year in the U.S. West. [Link](https://climate.nasa.gov/explore/ask-nasa-climate/3066/the-climate-connections-of-a-record-fire-year-in-the-us-west/)\n", - "* Ian P. Davies ,Ryan D. Haugo,James C. Robertson,Phillip S. Levin (2018). The unequal vulnerability of communities of color to wildfire.PLoS ONE 13(11): e0205825. [https://doi.org/10.1371/journal.pone.0205825](https://doi.org/10.1371/journal.pone.0205825)\n", - "\n", - "\n", - "Wildfires and forest ecosystems\n", - "* [Controlled fires](https://smokeybear.com/es/about-wildland-fire/benefits-of-fire/prescribed-fires)\n", - "* [Argentina on fire: what the fire left us | Spanish (pdf)](https://farn.org.ar/wp-content/uploads/2020/12/DOC_ARGENTINA-INCENDIADA_links.pdf)\n", - "* [Forest fires and biological diversity](https://www.fao.org/3/y3582s/y3582s08.htm)\n", - "\n" - ] - } - ], - "metadata": { - "colab": { - "provenance": [], - "toc_visible": true - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/chapter_title.md b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/chapter_title.md deleted file mode 100644 index cc8934617..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Good Research Practices - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/further_reading.md b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/further_reading.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary.ipynb deleted file mode 100644 index ffbf526d1..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary.ipynb +++ /dev/null @@ -1,51 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "39cf544a", - "metadata": {}, - "source": [ - "# Day Summary" - ] - }, - { - "cell_type": "markdown", - "id": "3e482081", - "metadata": {}, - "source": [ - "In this tutorial, you’ve learned about how to construct a research project. You now know how to:\n", - "\n", - "- Identify a phenomenon and ask a good research question\n", - "- Do a literature review to determine what is already known about the phenomenon\n", - "- Choose a dataset to address your research question\n", - "- Form a good, testable hypothesis\n", - "- Draft and implement data analysis\n", - "- Interpret your results\n", - "- Communicate your findings to a broader audience\n", - "\n", - "Feel free to refer back to this section as you work on your own research projects for reminders about the scientific process and how to avoid pitfalls.\n" - ] - } - ], - "metadata": { - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Intro.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Intro.ipynb deleted file mode 100644 index d9067672e..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Intro.ipynb +++ /dev/null @@ -1,51 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "4439da88", - "metadata": {}, - "source": [ - "# Intro" - ] - }, - { - "cell_type": "markdown", - "id": "60f237f1", - "metadata": {}, - "source": [ - "## Overview" - ] - }, - { - "cell_type": "markdown", - "id": "077e2215", - "metadata": {}, - "source": [ - "This tutorial is all about the research process from concept to conclusion. We will walk you through the thinking process behind scientific research and some tools that will help you as you think through your own projects. The first half will focus on the process of planning a research project. In Step 1, we will walk you through how to ask a good research question. Step 2 will explain the goals of the literature review process. Step 3 will introduce you to the wide range of datasets used in climate science and give an introduction to when you might use some of them. Step 4 will explain how to develop a robust hypothesis based on the resources available.\n", - "\n", - "The second half will focus on data analysis and communicating your results. Step 5 will guide you through drafting the analysis, and at Step 6 we will implement a sample analysis. Step 7 will explain what to take into consideration when interpreting your results. Finally, Step 8 will talk you through how to communicate your conclusions to different audiences. We hope that after this tutorial, you will have a better understanding of how to complete research that is clearly motivated and rigorously supported.\n" - ] - } - ], - "metadata": { - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Outro.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Outro.ipynb deleted file mode 100644 index b9f606679..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Outro.ipynb +++ /dev/null @@ -1,41 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0e51c3ed", - "metadata": {}, - "source": [ - "# Outro" - ] - }, - { - "cell_type": "markdown", - "id": "32d634e1", - "metadata": {}, - "source": [ - "Now you have learned about doing climate research and presenting your results. These include many equity concerns, including possible impacts on populations in many parts of the world." - ] - } - ], - "metadata": { - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1.ipynb deleted file mode 100644 index da2ff2c75..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1.ipynb +++ /dev/null @@ -1,217 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial1.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 1: Finding a Phenomenon and Asking a Question About It \n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Dionessa Baton, Yuxin Zhou, Natalie Steinemann, Zane Mitrevica\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?\n", - "\n", - "# Demos\n", - "\n", - "In order to illustrate the process, we will use a sample research question about how the surface temperature of the earth depends on the CO$_2$ content of the atmosphere." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Finding a Phenomenon & Asking a Question about it\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', 'jI5FSM_v95s'), ('Bilibili', 'BV1oj411Z7Ur')]\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": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"y9fd4\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Activity: Asking Your Own Question\n", - "\n", - "Write down a phenomenon you would like to gain understanding about. Take 5 minutes to construct a question about the phenomenon. Discuss amongst your group to improve the question. For some inspiration:\n", - "\n", - "* Are there other aspects of the planet that may influence the average surface temperature?\n", - "* Are there other features of the planet that may be impacted by changes in the average surface temperature?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Make Sure to Avoid the Pitfalls!\n", - "
\n", - "Click here for a recap on pitfalls\n", - "\n", - "Question is too broad\n", - "
    \n", - "
  • Science advances one small step at a time. Narrowing the scope will help clarify your next steps
  • \n", - "
\n", - "\n", - "Question does not identify a precise aspect of the phenomenon\n", - "
    \n", - "
  • Clarity will help identify next steps in your research
  • \n", - "
  • If you are struggling to identify a precise aspect, you might need to learn more about the phenomenon. Look to the literature (Step 2)!
  • \n", - "
\n", - "\n", - "Question is about an analysis method\n", - "
    \n", - "
  • An analysis method is a tool, not the big picture
  • \n", - "
\n", - "\n", - "
" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial1", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2.ipynb deleted file mode 100644 index 11b96f991..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2.ipynb +++ /dev/null @@ -1,256 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial2.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 2: Doing a Literature Review\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou, Zane Mitrevica, Natalie Steinemann\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Doing a Literature Review\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', 'RXl5UmqDE_o'), ('Bilibili', 'BV1SX4y1a76j')]\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": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"tbx4f\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Activity: Understanding the Literature Review Process\n", - "\n", - "While a comprehensive literature review typically requires an extensive timeframe spanning months or even years, in the context of your Project Template, we will conduct a condensed literature review within two days. Instead of tasking you with reviewing the literature on our sample research topic, we will provide additional guidance on the process of conducting a literature review.\n", - "\n", - "During this timeframe, you will be introduced to the fundamental aspects and techniques of performing a literature review, enabling you to gain insights into the necessary steps and best practices. Although the review will be concise, it will equip you with the essential skills to navigate the literature effectively and lay the foundation for future in-depth literature reviews.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Equity in Literature Review\n", - "
\n", - "Click here for some points to consider when doing your literature review\n", - "\n", - "The choices we make as a collective have an impact on who is included and who is excluded in the scientific process. While there is no perfect solution to addressing inequity in the sciences, we can contribute by engaging in an ongoing conversation and being receptive to feedback regarding our impact. Here are some points to consider:\n", - "\n", - "* Which papers are you selecting for your review? Which papers are you citing? Are there overlooked studies with valuable results?\n", - "* Does your work relate to a phenomenon that affects a specific community? Have members of that community made observations or documented the phenomenon?\n", - "* Has your own experience informed you of equity concerns in the knowledge base that you are in a good position to address?\n", - "\n", - "Remember, perfection is not the goal. Every choice we make carries unintended consequences. By keeping equity in mind, we can remain open to constructive feedback and identify areas where we can make a positive impact. \n", - "\n", - "Here are some resources that may help you incorporate knowledge and understanding from underrepresented groups:\n", - "* [Global South Climate Database](https://www.carbonbrief.org/global-south-climate-database/) is made by scientists from the Global South, who make up only 10% of citations in Climate Science\n", - "* [Local Environmental Observer (LEO) network](https://www.leonetwork.org) contains observations of many weather events from Indigenous groups\n", - "* [Alaska Native Knowledge Network](https://uaf.edu/ankn/) is dedicated to Alaskan Native Knowledge\n", - "* [HSHK Knowledge Well](https://cdm16093.contentdm.oclc.org/digital/collection/p16093coll9) contains Native Hawaiian knowledge of local weather events\n", - "\n", - "Here is some reading relating to Arrhenius and his racism: \n", - "\n", - "College Chemistry Textbooks Aid and Abet Racial Disparity. Mona L. Becker and Melanie R. Nilsson. Journal of Chemical Education 2022 99 (5), 1847-1854. DOI: https://doi.org/10.1021/acs.jchemed.1c00968" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Tips for Efficiency\n", - "
\n", - "Click here for some pointers on reviewing literature efficiently\n", - "\n", - "There are many different strategies for reviewing literature efficiently. **[Here](https://www.science.org/content/article/how-seriously-read-scientific-paper)** are some descriptions of the processes that different researchers use. If you are new to a topic, we recommend you start by looking for a review paper, which will summarize the results of multiple studies and direct you to other papers worth reading.\n", - "\n", - "Here is one option for reading papers efficiently:\n", - "\n", - "* Start by reviewing the abstract and conclusions sections. This will help you determine the relevance of the paper's results to your research.\n", - "* Conduct a \"quick pass\" of the paper\n", - "
    \n", - "
  • Scan through the figures and diagrams.
  • \n", - "
  • Identify the references to these figures in the text and read the surrounding discussion.
  • \n", - "
  • Take note of any parts of the figures or discussion that you find difficult to understand.
  • \n", - "
\n", - "* Seek additional information to address the areas that you found challenging:\n", - "
    \n", - "
  • Refer to previous sections of the paper that describe the methods and analysis.
  • \n", - "
  • Explore other papers that cite or are cited by the paper you are reading.
  • \n", - "
  • Consult relevant textbooks or resources on the subject.
  • \n", - "
  • Seek guidance from professors or peers in your field.
  • \n", - "
\n", - "* If the paper seems extremely important, or if you are tasked with presenting it to a group, consider reading it in its entirety. To maximize your comprehension, you can\n", - "
    \n", - "
  • Summarize the main message of each paragraph in one sentence or less.
  • \n", - "
  • Create written descriptions or sketches of the phenomena discussed.
  • \n", - "
  • Identify the physical meaning and implications of terms and equations.
  • \n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial2", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3.ipynb deleted file mode 100644 index 7fdb2642d..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3.ipynb +++ /dev/null @@ -1,260 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial3.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 3: Identifying the Basic Ingredients\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou, Natalie Steinemann, Zane Mitrevica\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Basic Ingredients\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', 'zqwIZJe47Bg'), ('Bilibili', 'BV1WN41127UX')]\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": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"zyvwp\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Activity: Identifying Basic Ingredients\n", - "\n", - "Take 10 minutes to discuss the advantages and disadvantages of utilizing the following basic ingredients to explore the research question discussed in Video 1:\n", - "\n", - "\n", - "* Ice core data for CO2\n", - "\n", - "* Deep sea sediment data for sea surface temperature\n", - "\n", - "Can you think of alternative approaches that might work well?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Choosing Your Data\n", - "
\n", - "Click here for some pointers on how to choose your data\n", - "\n", - "Here are some questions to ask yourself when choosing the data to use:\n", - "\n", - "What physical processes must be included?\n", - "
    \n", - "
  • You don't want an approach that contains less than the bare minimum. For some phenomena, we know what the bare minimum is. For others, more research is needed...
  • \n", - "
  • If you are unsure about what physical processes are needed, check the literature!
\n", - "\n", - "What spatial and temporal resolution is necessary to capture the phenomenon?\n", - "
    \n", - "
  • GCMs can typically have a spatial resolution around 100km and time resolution of several hours.
  • \n", - "
  • For phenomena that require higher resolution, you can either
  • \n", - "
    • Use a more idealized model that resolves smaller scales
    • Implement a parameterization of the sub-gridscale features within the GCM.
    • \n", - "
\n", - "\n", - "What restrictions do I have for computational resources?\n", - "
    \n", - "
  • If you do not have access to large computational resources, you can still do research using smaller datasets or idealized models
  • \n", - "
\n", - "\n", - "Am I interested in looking at a particular time period or a specific physical location?\n", - "
    \n", - "
  • Reanalysis can be used for time periods after roughly the 1940s
  • \n", - "
  • Proxy data can be used for a wider historical and prehistorical data
  • \n", - "
  • Both reanalysis and proxy data can provide specific location information
  • \n", - "
  • Models can be designed to mimic the conditions of the location or time, for example:
    • \n", - "
    • GCMs (General Circulation Models or Global Climate Models) can be set according to parameters that resemble the time period
    • \n", - "
    • Energy balance models can capture some aspects of average temperature in other time periods
    • \n", - "
    • Radiative-convective equilibrium models can capture some phenomena in the tropics
    • \n", - "
    • Quasi-geostrophic models can capture some phenomena in the mid-latitudes (between ~30-60 degrees)
    • \n", - "
    • And many more!
    • \n", - "
    \n", - "
\n", - "\n", - "Am I interested in studying a feature of the phenomenon in isolation or interactions between multiple features?\n", - "\n", - "
    \n", - "
  • If you want to isolate a single aspect of the phenomenon, an idealized model may be more appropriate
  • \n", - "
  • If you want to study interactions between multiple features, either observational data or a more complex model may be appropriate
  • \n", - "
\n", - "\n", - "Am I trying to...\n", - "
    \n", - "
  • explain the theory behind the phenomenon? An idealized model may be appropriate
  • \n", - "
  • provide evidence to support or challenge a pre-existing hypothesis? Observational data or a more complex model may be appropriate
  • \n", - "
  • document the features of the phenomenon? Observational data may be appropriate
  • \n", - "
\n", - "\n", - "For more information on observational data: \n", - "* [NCAR's climate data guide](https://climatedataguide.ucar.edu/climate-data)\n", - "* [NCAR's guide on real-time weather data](https://weather.rap.ucar.edu/)\n", - "* [NOAA's guide on hydrological survey data](https://nauticalcharts.noaa.gov/data/hydrographic-survey-data.html)\n", - "* [USGS's guide on paleoclimate proxies](https://www.usgs.gov/programs/climate-research-and-development-program/science/paleoclimate-proxies)\n", - "* [Pangeo](https://pangeo.io/) hosts a few open-access datasets\n", - "\n", - "For more information on numerical modeling: \n", - "\n", - "* Atmospheric Model Hierarchies: Maher, P., Gerber, E. P., Medeiros, B., Merlis, T. M., Sherwood, S., Sheshadri, A., et al. (2019). Model hierarchies for understanding atmospheric circulation, Reviews of Geophysics, 57, 250– 280. https://doi.org/10.1029/2018RG000607\n", - "* Ocean Model Hierarchies: Hsu, T.-Y., Primeau, F., & Magnusdottir, G. (2022). A hierarchy of global ocean models coupled to CESM1. Journal of Advances in Modeling Earth Systems, 14, e2021MS002979. https://doi.org/10.1029/2021MS002979 " - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial3", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4.ipynb deleted file mode 100644 index 449ce46ae..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4.ipynb +++ /dev/null @@ -1,238 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial4.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 4: Formulating a Hypothesis\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou, Zane Mitrevica, Natalie Steinemann\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Formulating a Hypothesis\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', 'F71IbvrHv6s'), ('Bilibili', 'BV1tF411Q7Wz')]\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": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"v8zx6\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Activity: Understanding Hypothesis\n", - "\n", - "Take 5 minutes to discuss how a hypothesis differs from a research question." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Make Sure to Avoid the pitfalls!\n", - "
\n", - "Click here for a recap on pitfalls\n", - "\n", - "I don’t need a hypothesis, I will just play around with the model/data\n", - "
    \n", - "
  • A hypothesis will help to clarify your goals when presenting research. After all, \"I just played around with this model a lot\" isn't a very satisfying scientific result
  • \n", - "
  • However, we encourage you to explore and experiment with the model and the data, as this can help develop your intuition and understanding of the subject matter
  • \n", - "
  • Hypothesis formation is often an iterative process involving both the literature review and playing around with your model and data
  • \n", - "
\n", - "\n", - "My hypothesis doesn’t match my question (or vice versa)\n", - "
    \n", - "
  • This is a normal part of the process!
  • \n", - "
  • You can return to Step 1 and update your question / phenomenon / goals
  • \n", - "
\n", - "\n", - "I can’t write down a hypothesis\n", - "
    \n", - "
  • If you find it challenging to articulate a hypothesis, it may indicate that you lack ingredients and/or clarity on the hypothesis. Try returning to Step 2 to further your literature review, or continue playing around with your model or data.
  • \n", - "
\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorials 1-4 Summary\n", - "\n", - "Through tutorials 1-4, we worked through the preliminary steps of starting a research project.\n", - "\n", - "* We identified a phenomenon and formulated a question (Step 1)\n", - "* We did a review of the literature and determine what has already been studied about the phenomenon (Step 2)\n", - "* We determined what basic ingredients we need to investigate the phenomenon (Step 3)\n", - "* We used all of the above to formulate a testable hypothesis (Step 4)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Next Steps\n", - "\n", - "Tutorials 5-8 will illustrate the steps involved in data analysis, interpreting your results, and communicating your results to an audience. As you do your own research, feel free to return to this tutorial as a guide." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial4", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5.ipynb deleted file mode 100644 index 507c9ed5c..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5.ipynb +++ /dev/null @@ -1,295 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial5.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 5: Drafting the Analysis\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Yuxin Zhou, Marguerite Brown, Natalie Steinemann, Zane Mitrevica\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorials Objectives\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import seaborn as sns\n", - "import numpy as np\n", - "from scipy import interpolate\n", - "from scipy import stats" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Drafting the Analysis\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', 'F7ymmfcnG6w'), ('Bilibili', 'BV1Gh4y1f7jC')]\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": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"qxcmj\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Coding Exercise 1\n", - "\n", - "To explore the relationship between CO2 and temperature, you may want to make a scatter plot of the two variables, where the x-axis represents CO2 and the y-axis represents temperature. Then you can see if a linear regression model fits the data well.\n", - "\n", - "Before you do that, let's learn how to apply a linear regression model using generated data.\n", - "\n", - "If you aren't familiar with a linear regression model, it is simply a way of isolating a relationship between two variables (e.g. x and y). For example, each giraffe might have different running speeds. You might wonder if taller giraffes run faster than shorter ones. How do we describe the relationship between a giraffe's height and its running speed? A linear regression model will be able to provide us a mathematical equation:\n", - "\n", - "`speed = a * height + b`\n", - "\n", - "where a and b are the slope and intercept of the equation, respectively. Such an equation allows us to predict an unknown giraffe's running speed by simply plugging its height into the equation. Not all giraffes will fit the relationship and other factors might influence their speeds, such as health, diet, age, etc. However, because of its simplicity, linear regression models are usually first attempted by scientists to quantify the relationship between variables.\n", - "\n", - "For more information on linear regression models, see the [Wikipedia page](https://en.wikipedia.org/wiki/Linear_regression), especially the first figure on that page: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 614, - "status": "ok", - "timestamp": 1681841571307, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# set up a random number generator\n", - "rng = np.random.default_rng()\n", - "# x is one hundred random numbers between 0 and 1\n", - "x = rng.random(100)\n", - "# y is one hundred random numbers according to the relationship y = 1.6x + 0.5\n", - "y = 1.6 * x + rng.random(100)\n", - "\n", - "# plot\n", - "fig, ax = plt.subplots()\n", - "ax.scatter(x, y, color=\"gray\")\n", - "\n", - "# regression\n", - "res = stats.linregress(x, y) # ordinary least sqaure\n", - "\n", - "ax.plot(x, x * res.slope + res.intercept, color=\"k\")\n", - "ax.set_xlabel(\"x\")\n", - "ax.set_ylabel(\"y\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To get a sense of how our model fits the data, you can look at the regression results. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# summarize model\n", - "\n", - "print(\n", - " \"pearson (r^2) value: \"\n", - " + \"{:.2f}\".format(res.rvalue**2)\n", - " + \" \\nwith a p-value of: \"\n", - " + \"{:.2e}\".format(res.pvalue)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we know how to write codes to analyze the linear relationship between two variables, we're ready to move on to real world data!" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial5", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6.ipynb deleted file mode 100644 index 0ab4e61e7..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6.ipynb +++ /dev/null @@ -1,385 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial6.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 6: Implementing the Analysis\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Yuxin Zhou, Marguerite Brown, Zane Mitrevica, Natalie Steinemann\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorials Objectives\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Activity: Implement the Analysis\n", - "\n", - "In this tutorial, you will be implementing a linear regression model as outlined in Step 5 on real-world CO2 and temperature records.\n", - "\n", - "The CO2 and temperature records we will be analyzing are both examples of paleoclimate data (for more information, refer back to Step 3). The CO2 record (Bereiter et al., 2015) was generated by measuring the CO2 concentration in ancient air bubbles trapped inside ice from multiple ice cores retrieved from Antarctica. The temperature record (Shakun et al., 2015) is based on chemical analysis done on the shells of planktic foraminifera. The foraminifera shells were identified and picked from deep-sea sediments, and the temperature record combined multiple sea-surface temperature records from a range of sites globally.\n", - "\n", - "Why are we focusing on these two records specifically? The CO2 record from Antarctic ice core is the gold standard of air CO2 variability on glacial-interglacial time scales, and it has a temporal resolution unmatched by any other reconstruction methods. The temperature record comes from sediment cores all over the global ocean, and therefore is likely representative of the global surface ocean temperature variability. Polar air temperature records are also available from ice core studies, but such records may represent an exaggerated view of the global temperature because of polar amplification.\n", - "\n", - "If you would like to learn more, the data sources are listed at the bottom of the page.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 3940, - "status": "ok", - "timestamp": 1682775919083, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import seaborn as sns\n", - "import numpy as np\n", - "from scipy import interpolate\n", - "from scipy import stats\n", - "import os\n", - "import pooch\n", - "import tempfile" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# time series\n", - "# read SST data \"Shakun2015_SST.txt\"\n", - "filename_Shakun2015_SST = \"Shakun2015_SST.txt\"\n", - "url_Shakun2015_SST = \"https://osf.io/kmy5w/download\"\n", - "SST = pd.read_table(pooch_load(url_Shakun2015_SST, filename_Shakun2015_SST))\n", - "SST.set_index(\"Age\", inplace=True)\n", - "SST" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# read CO2 dataantarctica2015co2composite_cleaned.txt\n", - "filename_antarctica2015co2composite_cleaned = \"antarctica2015co2composite_cleaned.txt\"\n", - "url_antarctica2015co2composite_cleaned = \"https://osf.io/45fev/download\"\n", - "CO2 = pd.read_table(\n", - " pooch_load(\n", - " url_antarctica2015co2composite_cleaned,\n", - " filename_antarctica2015co2composite_cleaned,\n", - " )\n", - ")\n", - "CO2.set_index(\"age_gas_calBP\", inplace=True)\n", - "CO2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5037, - "status": "ok", - "timestamp": 1682775959771, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot\n", - "# set up two subplots in a grid of 2 rows and 1 column\n", - "# also make sure the two plots share the same x(time) axis\n", - "fig, axes = plt.subplots(2, 1, sharex=True)\n", - "# move the two subplots closer to each other\n", - "fig.subplots_adjust(hspace=-0.5)\n", - "axes[0].plot(SST.index, SST[\"SST stack\"], color=\"C4\")\n", - "axes[1].plot(CO2.index / 1000, CO2[\"co2_ppm\"], color=\"C1\")\n", - "\n", - "# beautification\n", - "# since sharex=True in plt.subplots(), this sets the x axis limit for both panels\n", - "axes[1].set_xlim((0, 805))\n", - "# axis labels\n", - "axes[1].set_xlabel(\"Age (ka BP)\")\n", - "axes[0].set_ylabel(r\"Sea Surface Temperature\" \"\\n\" \"detrended (°C)\", color=\"C4\")\n", - "axes[1].set_ylabel(r\"CO${}_\\mathrm{2}$ (ppm)\", color=\"C1\")\n", - "\n", - "# despine makes the plots look cleaner\n", - "sns.despine(ax=axes[0], top=True, right=False, bottom=True, left=True)\n", - "sns.despine(ax=axes[1], top=True, right=True, bottom=False, left=False)\n", - "# clean up top panel x axis ticks\n", - "axes[0].xaxis.set_ticks_position(\"none\")\n", - "# move top panel xlabel to the right side\n", - "axes[0].yaxis.set_label_position(\"right\")\n", - "# the following code ensures the subplots don't overlap\n", - "for ax in axes:\n", - " ax.set_zorder(10)\n", - " ax.set_facecolor(\"none\")\n", - "# color the axis\n", - "axes[0].spines[\"right\"].set_color(\"C4\")\n", - "axes[1].spines[\"left\"].set_color(\"C1\")\n", - "axes[0].tick_params(axis=\"y\", colors=\"C4\")\n", - "axes[1].tick_params(axis=\"y\", colors=\"C1\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we've taken a look at the two time series, let's make a scatter plot between them and fit a linear regression model through the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# in this code block, we will make a scatter plot of CO2 and temperature\n", - "# and fit a linear regression model through the data\n", - "\n", - "\n", - "def age_model_interp(CO2_age, CO2, SST_age):\n", - " \"\"\"\n", - " This helper function linearly interpolates CO2 data, which\n", - " have a very high temporal resolution, to temperature data,\n", - " which have a relatively low resolution\n", - " \"\"\"\n", - " f = interpolate.interp1d(CO2_age, CO2)\n", - " all_ages = f(SST_age)\n", - " return all_ages\n", - "\n", - "\n", - "# interpolate CO2 data to SST age\n", - "CO2_interpolated = age_model_interp(CO2.index / 1000, CO2[\"co2_ppm\"], SST.index)\n", - "\n", - "# plot\n", - "# set up two subplots in a grid of 2 rows and 1 column\n", - "# also make sure the two plots share the same x(time) axis\n", - "fig, ax = plt.subplots(1, 1, sharex=True)\n", - "\n", - "ax.scatter(CO2_interpolated, SST[\"SST stack\"], color=\"gray\")\n", - "\n", - "# regression\n", - "X = CO2_interpolated\n", - "y = SST[\"SST stack\"]\n", - "res = stats.linregress(X, y) # ordinary least sqaure\n", - "\n", - "x_fit = np.arange(180, 280)\n", - "# intercept\n", - "y_fit = x_fit * res.slope + res.intercept\n", - "ax.plot(x_fit, y_fit, color=\"k\")\n", - "\n", - "# beautification\n", - "# axis labels\n", - "ax.set_xlabel(r\"CO${}_\\mathrm{2}$ (ppm)\")\n", - "ax.set_ylabel(r\"Sea Surface Temperature\" \"\\n\" \"detrended (°C)\")\n", - "print(\n", - " \"pearson (r^2) value: \"\n", - " + \"{:.2f}\".format(res.rvalue**2)\n", - " + \" \\nwith a p-value of: \"\n", - " + \"{:.2e}\".format(res.pvalue)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Figure Making Through the Equity Lense\n", - "
\n", - "Click here for some information\n", - "Are the colors in your figure distinguishable for people with color-vision deficiencies?\n", - "\n", - "More readings on this topic:\n", - "\n", - "Contrast checker: https://www.color-blindness.com/coblis-color-blindness-simulator/\n", - "\n", - "Coloring for color blindness: https://davidmathlogic.com/colorblind\n", - "\n", - "Python-specific color palettes that are friendly to those with color-vision deficiency: https://seaborn.pydata.org/tutorial/color_palettes.html" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "CO2: Bereiter, B., Eggleston, S., Schmitt, J., Nehrbass-Ahles, C., Stocker, T.F., Fischer, H., Kipfstuhl, S., Chappellaz, J., 2015. Revision of the EPICA Dome C CO2 record from 800 to 600 kyr before present. Geophysical Research Letters 42, 542–549. https://doi.org/10.1002/2014GL061957\n", - "\n", - "Temperature: Shakun, J.D., Lea, D.W., Lisiecki, L.E., Raymo, M.E., 2015. An 800-kyr record of global surface ocean δ18O and implications for ice volume-temperature coupling. Earth and Planetary Science Letters 426, 58–68. https://doi.org/10.1016/j.epsl.2015.05.042\n", - "\n", - "\n" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial6", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7.ipynb deleted file mode 100644 index 3be0cb61c..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7.ipynb +++ /dev/null @@ -1,220 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial7.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 7: Interpreting the Results\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Yuxin Zhou, Samuel Akpan, Marguerite Brown, Natalie Steinemann, Zane Mitrevica\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorials Objectives\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Interpreting the Results\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', 'yswUuHU3Y_Y'), ('Bilibili', 'BV1h94y1B7xi')]\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": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"yje9x\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In Step 6, we created plots displaying the global CO2 levels and sea surface temperature data spanning the past 800 thousand years. Additionally, we attempted to fit both variables using a linear regression model. Nevertheless, it is crucial to bear in mind that correlation does not imply causation. The fact that global CO2 and sea surface temperature appear to co-vary does not automatically imply that one variable directly causes changes in the other. To establish causation, it is imperative to gather multiple lines of evidence. This underscores the importance of literature review in Step 2, as it aids in identifying corroborating evidence in climate research." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Quantifying the Uncertainty\n", - "
\n", - "Click here for some information\n", - "Look up \"linear regression model R squared\" and how it measures the uncertainty of a linear regression model. What does it say about how confident you can be about a linear relationship between CO2 and temperature?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Activity: Interpreting the Results Through the Lens of Equity\n", - "For the next 10 minutes, discuss what the results capture well in terms of the relationship between CO2 and temperature. Who is represented by this data, specifically the compiled temperature record, and who is not? Who generated these data? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Further readings\n", - "
\n", - "Click here for more readings on Interpreting the Results through the lens of equity\n", - "\n", - "Donovan, R. (2023), Climate journalism needs voices from the Global South, Eos, 104, https://doi.org/10.1029/2023EO230085\n", - "\n", - "Tandon, A. (2021), Analysis: The lack of diversity in climate-science research, Carbon Brief, [https://www.carbonbrief.org/analysis-the-lack-of-diversity-in-climate-science-research/](https://www.carbonbrief.org/analysis-the-lack-of-diversity-in-climate-science-research/)" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial7", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8.ipynb b/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8.ipynb deleted file mode 100644 index fe78648f0..000000000 --- a/book/_build/html/_sources/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8.ipynb +++ /dev/null @@ -1,237 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/W2D2_Tutorial8.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 8: Communicating Your Conclusions\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Yuxin Zhou, Natalie Steinemann, Marguerite Brown, Zane Mitrevica\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorials Objectives\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Communicating the Conclusion\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', 'XZfqyancNpk'), ('Bilibili', 'BV1494y1B7qs')]\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": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"9s6ub\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Activity: Communicating Your Conclusions\n", - "\n", - "For the next 20 minutes, break out into groups of 2 or 3 and pick one presentation format and discuss:\n", - "\n", - "* Who is the target audience of this format?\n", - "* What information is important to include?\n", - "\n", - "After this, come back together as a whole pod and discuss everyone's suggestions.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Equity in the Science Publishing\n", - "
\n", - "Click here for some information about equity and publishing\n", - "\n", - "There are aspects of our current research culture that perpetuate inequity in the publishing process. Academic institutions and funding agencies often place importance on publishing in peer-reviewed journals. However, they have some drawbacks, including\n", - "\n", - "* Accessibility\n", - "
  • Papers in these journals are often kept behind a paywall, making them less accessible to people without the backing of either a university or a company.
  • \n", - "
  • More and more journals offer the option of publishing open access, but at expense to the submitting authors: fees can often exceed 1000 USD.
  • \n", - "
  • \n", - "If you want to ensure accessibility, consider also releasing your results in other formats as well. For instance,\n", - "
    • Blog posts
    • \n", - "
    • Podcasts
    • \n", - "
    • Social media posts
    • \n", - "
    • Conferences
    \n", - "
  • If you know that your research contains results that are relevant to specific populations, it is valuable to find ways to communicate your results to them.
\n", - "* Peer Review as Gatekeeping\n", - "
  • At its best, the peer review process enforces scientific rigor.
  • \n", - "
  • At its worst, it can become a tool for enforcing pre-existing norms, including the biases of its reviewers.
  • \n", - "
  • REMEMBER: Bad experiences with reviewers and rejections does not mean that your research is bad. There are papers which went on to win Nobel prizes that experienced resistance and rejection during the peer review process BECAUSE they were introducing important new ideas.
  • \n", - "
  • Further Reading:
  • \n", - "
    • Campanario, J. M. (2009). Rejecting and resisting Nobel class discoveries: Accounts by Nobel Laureates. Scientometrics, 81(2), 549–565.
    • \n", - "
    • Bancroft, S. F., Ryoo, K., & Miles, M. (2022). Promoting equity in the peer review process of journal publication. Science Education, 106, 1232– 1248. https://doi.org/10.1002/sce.21733
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorials 5-8 Summary\n", - "\n", - "In this tutorial, we worked through how to analyze and present research.\n", - "\n", - "* We learned how to draft an analysis (Step 5)\n", - "* We implemented the analysis that we drafted (Step 6)\n", - "* We learned how to interpret the results of the analysis (Step 7)\n", - "* We learned about how to communicate the conclusions of our research (Step 8)\n" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "Projects_Tutorial8", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/Schedule/daily_schedules.md b/book/_build/html/_sources/tutorials/Schedule/daily_schedules.md deleted file mode 100644 index db4f673c8..000000000 --- a/book/_build/html/_sources/tutorials/Schedule/daily_schedules.md +++ /dev/null @@ -1,583 +0,0 @@ -# General Schedule - - -## 2023 course will run July 17-28, 2023 - - -## Course Overview - -The course will begin with Opening Ceremonies on Sunday, July 9th - -* 7:00 am UTC -* 3:00 pm UTC - -Tutorials, Projects and Professional Development activities will take place between July 17th and July 28th, 2023. - - -## Course Schedule for Timezones 2 & 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Course Schedule - Timezones 2 & 5 -
Week 1 - W1D1 - W1D2 - W1D3 - W1D4 - W1D5 -
Curriculum -

-(5 hours) -

Climate System Overview - Ocean-Atmosphere Reanalysis - Remote Sensing - Paleoclimate - Climate Modeling -
- - - - -
Projects & Professional Development -

-(3 hours) -

Session 1 -

- Tutorial on good research Practices -

Session 2 -

- Guided data exploration -

Session 3 -

-Literature review & question formulation -

Session 4 -

- Proposal writing, swaps & submission -

Session 5 -

- Drafting the analyses & task allocation -

- Impact Talk: -

- Climate Justice -

Impact Talk: -

Equity in Climate Science -

- -
-
Week 2 - W2D1 - W2D2 - W2D3 - W2D4 - W2D5 -
Curriculum -

-(5 hours) -

IPCC I: -

- Physical Basis -

Project Day - IPCC II & III: -

- Socioeconomic Basis -

Extremes & Vulnerability - Adaptation & Impact -
- - - - -
Projects & Professional Development -

-(3 hours) -

Session 6 -

- Implementation -

Session 7 -

- Implementation -

Session 8 -

- Implementation & result interpretation -

Session 9 -

- Presentation preparation & project submission -

Presentations -

- Closing ceremony -

Impact Talk: -

- Open Climate Science -

Career Panel - Impact Talk: -

- Climate Science Communication -

- -
- - -## Course Schedule for Timezones 1, 3 & 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Course Schedule - Timezones 1, 3 & 4 -
Week 1 - W1D1 - W1D2 - W1D3 - W1D4 - W1D5 -
Projects & Professional Development -

-(3 hours) -

No project time - Session 1 -

- Tutorial on good research Practices -

Session 2 -

- Guided data exploration -

Session 3 -

- Literature review & question formulation -

Session 4 -

- Proposal writing, swaps & submission -

- Impact Talk: -

- Climate Justice -

Impact Talk: -

- Equity in Climate Science -

-
Curriculum -

-(5 hours) -

Climate System Overview - Ocean-Atmosphere Reanalysis - Remote Sensing - Paleoclimate - Climate Modeling -
- - - - -
-
Week 2 - W2D1 - W2D2 - W2D3 - W2D4 - W2D5 -
Projects & Professional Development -

-(3 hours) -

Session 5 -

- Drafting the analyses & task allocation -

Session 6 -

- Implementation -

Session 7 -

- Implementation -

Session 8 -

- Implementation & result interpretation -

Session 9 -

- Presentation preparation & project submission -

- Impact Talk: -

- Open Climate Science -

- Career Panel -

- Impact Talk: -

- Climate Science Communication -

-
Curriculum -

-(5 hours) -

IPCC I: -

- Physical Basis -

Project Day - IPCC II & III: -

- Socioeconomic Basis -

Extremes & Vulnerability - Adaptation & Impact -
- - - - -
- - - - - Presentations -

- Closing ceremony -

- - - -## Daily Schedule - -These schedules refer to the time spent working on the course curriculum (5 hours each day). - - -### Curriculum Schedule - -All days (except W1D1 and W2D2) will follow this schedule for course time: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Time (Hour) - Component -
-0:30-0:00 - Keynote speaker -
0:00-0:15* - Pod discussion I -
0:15-1:35 - Tutorials I -
1:35-2:35 - Big break -
2:35-4:15 - Tutorials II -
4:15-4:25 - Pod discussion II -
4:25-4:30 - Reflections -
- - - -*Note that the synchronous coursework session starts at 0:00 with the first pod discussion. - -W1D1: The synchronous coursework session starts at -0:30 with 30 minutes for pod introductions. Students should watch the keynote lecture beforehand. - -W2D2: Following a keynote lecture in its usual slot, 0:00-3:30 will be spent working on the group project. At 3:30-4:30, there will be a live career panel as part of the Professional Development program. You can find more information about this day in the [Daily Guide for Projects](https://climatematchacademy.github.io/projects/docs/project_guidance.html#project-day-w2d2). - - -### Project Schedule - -In addition to curriculum time, each day will have 3 hours of project time. Check the [time slot widget](https://climatematchacademy.github.io/widgets/tz.html) to see when project time is scheduled for your slot. - -On W2D2 you will additionally be working on your group projects during the time usually allocated for tutorials. - - -### Professional Development Schedule - - -A series of professional development events (viewing and discussing four Impact Talks, a career panel, and two meetings with mentors) will take place during the 3-hour project time. Check the [time slot widget](https://climatematchacademy.github.io/widgets/tz.html) to see when project time is scheduled for your slot. - - -* Impact talks and discussions will take place during the first or last 30 minutes of Project Sessions 2, 3, 6 and 8. -* The career panel will take place during the last hour of the time usually allocated for tutorials on W2D2. -* Mentor meetings could take place on any day between July 19 and July 28. Your pod’s Teaching Assistant will tell you the exact times! - - -### W2D5: Final Day of the Course - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Time (Hour) - Component -
-4:00-(-1:00) - Projects (slots 1/3/4) -
-0:30-0:00 - Keynote speaker -
0:00-0:15* - Pod discussion I -
0:15-1:35 - Tutorials I -
1:35-2:35 - Big break -
2:35-4:15 - Tutorials II -
4:15-4:25 - Pod discussion II -
4:25-4:30 - Reflections -
4:30-4:45* - Short break -
4:45-5:15* - Course feedback survey -
5:15-6:15* - Project presentations (all slots) -
6:15-6:30* - Pod farewell -
- - -*Note that these events take place after the normal coursework time for slots 1/3/4. - -Course feedback survey: We will have a course completion survey for both students and teaching assistants. The link will be shared on discord. Please fill it out during this time! - -Pod farewell: This is just a chance for your pod to say goodbye to each other. No structure imposed here! - -Closing Ceremony / Graduation: We will do this all together on crowdcast on the Saturday after the course. - diff --git a/book/_build/html/_sources/tutorials/Schedule/schedule_intro.md b/book/_build/html/_sources/tutorials/Schedule/schedule_intro.md deleted file mode 100644 index 33e5a3bfd..000000000 --- a/book/_build/html/_sources/tutorials/Schedule/schedule_intro.md +++ /dev/null @@ -1 +0,0 @@ -# Schedule \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/Schedule/shared_calendars.md b/book/_build/html/_sources/tutorials/Schedule/shared_calendars.md deleted file mode 100644 index 5e442d53e..000000000 --- a/book/_build/html/_sources/tutorials/Schedule/shared_calendars.md +++ /dev/null @@ -1,15 +0,0 @@ -# Shared calendars - -We have five google calendars to help you see events in your local time! If you open the links below, they will be in -universal coordinated time (UTC). If you click at the bottom to add to your Google Calendar, you should see them in the time zone of your google -calendar (probably yours)! - -[Time slot 1](https://calendar.google.com/calendar/embed?src=c_abb890cbecf4f5b8bbb95197d6e767bb420bcc1c24dd1868a00a60e5c5e92f92%40group.calendar.google.com&ctz=UTC) - -[Time slot 2](https://calendar.google.com/calendar/embed?src=c_00f6933bbd8b72a22a8bcb1c76de8f07e7721571bd413251c88635e681702b1d%40group.calendar.google.com&ctz=UTC) - -[Time slot 3](https://calendar.google.com/calendar/embed?src=c_e9ef6949faa6ad7072beeaefb78e3a04d26ce75cccb92d01b8deb90774ad5223%40group.calendar.google.com&ctz=UTC) - -[Time slot 4](https://calendar.google.com/calendar/embed?src=c_3e32d348f312959b7a98edcfef9fb8bcffd8a9748cc5e99e483983b7ca1cb52f%40group.calendar.google.com&ctz=UTC) - -[Time slot 5](https://calendar.google.com/calendar/embed?src=c_7e197485198b40038110d8ab59f79592a3fd46bb9e5357b0140865d83a062268%40group.calendar.google.com&ctz=UTC) diff --git a/book/_build/html/_sources/tutorials/TechnicalHelp/Discord.md b/book/_build/html/_sources/tutorials/TechnicalHelp/Discord.md deleted file mode 100644 index f62e14e02..000000000 --- a/book/_build/html/_sources/tutorials/TechnicalHelp/Discord.md +++ /dev/null @@ -1,3 +0,0 @@ -# Using discord - -[Please click here for Discord Guide](https://docs.google.com/document/d/1a5l6QVhuqYnwFR090yDnQGhHSA3u2IEwOs0JZwkfyLo/edit?usp=sharing) diff --git a/book/_build/html/_sources/tutorials/TechnicalHelp/Jupyterbook.md b/book/_build/html/_sources/tutorials/TechnicalHelp/Jupyterbook.md deleted file mode 100644 index fc9416399..000000000 --- a/book/_build/html/_sources/tutorials/TechnicalHelp/Jupyterbook.md +++ /dev/null @@ -1,3 +0,0 @@ -# Using jupyterbook - -While you can see videos and the notebooks in this jupyterbook, you have to launch each page in an interactive environment in order to write or run code. diff --git a/book/_build/html/_sources/tutorials/TechnicalHelp/Links_Policy.md b/book/_build/html/_sources/tutorials/TechnicalHelp/Links_Policy.md deleted file mode 100644 index 30dec6bc8..000000000 --- a/book/_build/html/_sources/tutorials/TechnicalHelp/Links_Policy.md +++ /dev/null @@ -1,35 +0,0 @@ -# Quick links and policies - -## Quick links - -Course materials: [https://comptools.climatematch.io/](https://comptools.climatematch.io/) - -Portal: [https://portal.neuromatchacademy.org/](https://portal.neuromatchacademy.org/) - -Website: [https://academy.climatematch.io/](https://academy.climatematch.io/) - -Crowdcast: - -Code of Conduct: [https://github.com/NeuromatchAcademy/precourse/blob/main/CODE_OF_CONDUCT.md](https://github.com/NeuromatchAcademy/precourse/blob/main/CODE_OF_CONDUCT.md) - -Code of Conduct Violations Form: [https://airtable.com/shrezDSthWPlJ4Rpy](https://airtable.com/shrezDSthWPlJ4Rpy) - -Project Exemption Form: [https://airtable.com/shrupmgfGax5qeAuK](https://airtable.com/shrupmgfGax5qeAuK) - -Attendance Exemption Form: [https://airtable.com/shr7CB9qLcIVejpUd](https://airtable.com/shr7CB9qLcIVejpUd) - - - -## Policies - -### Coursework attendance policy - -Students who participate in this course will gain a certificate of completion for the coursework. Students are allowed to miss two days if necessary and if they communicate that with their teaching assistant. If there are exceptional circumstances that force a student to miss class for reasons completely beyond their control, such as severe illness, electricity blackouts, etc, they can request to get the certificate despite missing more than two days by filling out the attendance exemption form ([https://airtable.com/shr7CB9qLcIVejpUd](https://airtable.com/shr7CB9qLcIVejpUd)) **at least two days prior to the end of course**. Please note these requests may not be granted. - -### Projects attendance policy - -Projects are an integral part of the Neuromatch Academy experience. Students who participate in projects and miss no more than two days of projects work will gain a certificate of completion for the projects. - -If there are exceptional circumstances that make it difficult to attend the projects portion of the course, students can request to drop out of projects by filling out the project exemption form (). If their request is granted, the student can continue to attend the coursework sections and gain a coursework certificate if eligible (see above), but not participate in the projects work. - -If the student participates in projects but misses more than two days due to exceptional circumstances, they can request to get the projects certificate anyway by filling out the attendance exemption form ([https://airtable.com/shr7CB9qLcIVejpUd](https://airtable.com/shr7CB9qLcIVejpUd)) **at least two days prior to the end of course**. Please note these requests may not be granted. diff --git a/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_colab.md b/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_colab.md deleted file mode 100644 index 94e83a224..000000000 --- a/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_colab.md +++ /dev/null @@ -1,13 +0,0 @@ -# Using Google Colab - -If you have access to Google Colab, you can click the "Open in Colab" button at the top of each page to launch it in an interactive environment where you can write and run code. **Please note that we recommend JupyterHub if you can access it.** - -## Advice for using Colab -* Make a local copy to your Drive: otherwise changes you make (e.g. notes you take, code you write, etc) will not be saved -* Do not edit the same colab directly as a group. Unlike Google Docs, one person's version will overwrite another's. If your browser happens to be open, it can overwrite anything that has been done by others since the last version in your browser! -* Colab does not have version control! Use git for this if you want to collaborate (on a group project colab for example) -* If you wish to work collaboratively in a single colab notebook, make sure to take advantage of its revision history: `File` -> `Revision history`. While the gold standard for version control is git, colab offers an easy alternative to those not familiar with git. - * You can rename and revert to specific previous versions of the notebook by clicking on the three dots next your preferred revision in `Revision history`. - * Note that old revisions get removed! To maintain a saved version over an extended period of time, use `File` -> `Save and pin revision`. - -To learn the basics of Colab, please check out this Colab notebook: https://colab.research.google.com/notebooks/intro.ipynb diff --git a/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_jupyterhub.md b/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_jupyterhub.md deleted file mode 100644 index 986050d38..000000000 --- a/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_jupyterhub.md +++ /dev/null @@ -1,53 +0,0 @@ -# **Using JupyterHub** - -The JupyterHub is a cloud-based platform that provides a seamless coding environment able to interact with climate datasets and pre-installed python packages to be used in the course. - -Unlike Google Colab and Kaggle, in the JupyterHub there is no need to _!pip install_ any packages or download data from osf. These should all be available already in the JupyterHub environment. We hope this experience will provide flexibility as you explore projects and practice the new skills you acquire over the next two weeks. - -Note that if you live in a region with difficult access to the JupyterHub, the Climatematch Academy team has also subsetted datasets that can be loaded in Google Colab and Kaggle environments. - -To read more about what a JupyterHub is: [https://jupyterhub.readthedocs.io/en/stable/](https://jupyterhub.readthedocs.io/en/stable/) - -To read more about our collaborators at 2i2c that are providing this experience [https://2i2c.org/](https://2i2c.org/) - -## -### **STEPS:** - -1. You should have already opened a Github account and provided the Climatematch Academy team your username. This step is necessary for you to be added to the course Github Team which enables access to the JupyterHub. - -2. Click the Rocketship button found on top of every page containing a tutorial. - - JupyterHub icon - -3. You may need to wait a couple minutes until a node becomes available, especially in the first login of the day. - - JupyterHub waiting screen - - **Just in case, we recommend that you launch your first tutorial _before_ you begin watching the invited speaker’s video (or 30 minutes before you plan to start coding).** - -4. Once your server has started, you will find an interactive coding environment. - - - JupyterHub interactive coding environment - -5. We have preloaded datasets to the JupyterHub which are shared across all users. However, you will also have your own home directory where you can save notebooks and subsetted data you have analyzed. - -6. Note that other users will not be able to access your home directory. To collaborate over projects it is best practice to share code using git. - -## -### **USING JUPYTERHUB TO COLLABORATE ON PROJECTS** - -To help you share code, data, and plots, we have created a `shared-public` folder on JupyterHub. Each project group has a dedicated subfolder named after the group. **Work ONLY in your project group's folder!!!!** - -JupyterHub interactive coding environment - -Inside your group's folder, you will find a `dev.ipynb` notebook that you can use to develop code collaboratively. - -JupyterHub interactive coding environment - -For best practices: -* Only work in your group's folder!!!! -* Do not delete any code or data from this folder without the entire group's permission-- this cannot be restored!! -* One member can share their screen while the group works together on shared code. Note that it may take a few minutes for code to update so best to avoid multiple people updating code simultaneously. -* Alternatively, you can also each develop code in a notebook on your local folder. If there are code snippets you would like to share you can place in dev.ipynb, where other team members can copy over to their local notebook/folder. -* We recommend everyone to still maintain a local copy of each notebook-- just in case. \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_kaggle.md b/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_kaggle.md deleted file mode 100644 index 38f0f2f51..000000000 --- a/book/_build/html/_sources/tutorials/TechnicalHelp/Tutorial_kaggle.md +++ /dev/null @@ -1,46 +0,0 @@ -# Using Kaggle - -If you are in China or another region with difficult access to JupyterHub and Google Colab, you can use Kaggle as a substitute for launching an interactive coding environment where you can write and run code. **Please note that we recommend JupyterHub if you can access it.** - -## First use - -**1.** First, [sign in](https://www.kaggle.com/account/login) to your Kaggle account. If you don't have a Kaggle account, create one by registering [here](https://www.kaggle.com/account/login?phase=startRegisterTab&returnUrl=%2F). - -![Step 1](../static/kaggle_step1.png) - -**2.** Get your account phone-verified. This is necessary for accessing GPU/internet on kernels, as well as for collaborative work. To do this: -* click on your profile icon in the top right corner - -![Step 2](../static/kaggle_step2.png) -* select `Settings` and scroll down to the `Phone verification` section - -![Step 3](../static/kaggle_step3.png) -* enter your phone number and subsequently the code verification code received in a text message - -![Step 4](../static/kaggle_step4.png) - -## Accessing course notebooks -Click the kaggle button found on top of every page containing a jupyter notebook, such as [tutorial pages](https://comptools.climatematch.io/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.html). - -![Step 5](../static/kaggle_step5.png) ->**NOTE:** If you receive an error asocociated with `!pip install`, follow [this workaround](https://www.kaggle.com/product-feedback/63544). - -## Enabling internet access on kernels -To enable this, click on `Notebook options` in the right side bar of the kaggle notebook editor. Scroll down and toggle `Internet on`. -This will let you fetch data from an external online source or install a custom python package. If after the installation you experience any error when trying to import an installed module, make sure to restart the kernel after installing the module and then it should work. - -![Step 3.2](../static/kaggle_step6.png) - -## Enabling GPU access on kernels -Click on `Notebook options` in the right side bar of the kaggle notebook editor as above. Change `Accelerator` from **None** to **GPU**. - ->**NOTE:** A GPU is **NOT** required in the *Computational Tools for Climate Science* course! However, some advanced groups might design projects that benefit from GPU use. - -## Collaborating in kaggle -To share a notebook with your project teammates, add them as **collaborators** by clicking `Share` in the top right corner of the notebook editor when you have the notebook of interest open. Keep the notebook as *Private* and search your teammates by their kaggle username. You can give them access to `view` or `edit` your work. This is also where you can **enable comments** for your notebook. - -![Step 7](../static/kaggle_step7.png) - ->**NOTE:** Unlike in Colab, collaborators **CANNOT** edit the same version of a notebook simultaneously! Your edits will be accessible to collaborators only after you `Save version` -> `Save & Run All (Commit)`, but they will not get merged into *their* working version of the notebook automatically. Commits from separate notebook versions must be merged manually! - -To view your collaborators' work, open the **version history** by clicking on the number next to `Save Version` in the top right corner. Clicking on the three dots next to a specific version lets you view, rename, and pin it, as well as revert to it or compare it to another version. diff --git a/book/_build/html/_sources/tutorials/TechnicalHelp/tech_intro.md b/book/_build/html/_sources/tutorials/TechnicalHelp/tech_intro.md deleted file mode 100644 index 96d4403fb..000000000 --- a/book/_build/html/_sources/tutorials/TechnicalHelp/tech_intro.md +++ /dev/null @@ -1,5 +0,0 @@ -# Technical Help - -Wrench labeled neuromatch on top of a phone - -*Artwork by Daniela Buchwald* diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/chapter_title.md b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/chapter_title.md deleted file mode 100644 index 283253548..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Climate System Overview - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/further_reading.md b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/further_reading.md deleted file mode 100644 index a2b887692..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/further_reading.md +++ /dev/null @@ -1,11 +0,0 @@ -# Suggested Further Reading - -Introduction to the Climate System: -- https://scied.ucar.edu/learning-zone/earth-system/climate-system -- https://climate.nasa.gov/nasa_science/science/ -- https://www.ipcc.ch/site/assets/uploads/2018/03/TAR-01.pdf - -Introduction to Xarray -- https://foundations.projectpythia.org/core/xarray.html -- https://docs.xarray.dev/en/stable/# -- https://tutorial.xarray.dev/intro.html \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/.DS_Store b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/.DS_Store deleted file mode 100644 index 5008ddfcf..000000000 Binary files a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/.DS_Store and /dev/null differ diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary.ipynb deleted file mode 100644 index 6a873bcdb..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary.ipynb +++ /dev/null @@ -1,41 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "c57bdbdf", - "metadata": {}, - "source": [ - "# Day Summary" - ] - }, - { - "cell_type": "markdown", - "id": "af474117", - "metadata": {}, - "source": [ - "The tutorials today provided an overview of Earth’s climate system as well as an introduction to Xarray. You learned about long-term, natural forcings and feedbacks that influence Earth’s climate including Earth’s energy budget, orbital forcings and the carbon cycle and explored various processes within the atmospheric, oceanic and terrestrial components of Earth’s climate system. Additionally, you learned useful tools in Xarray for formatting, analyzing and interpreting climate data" - ] - } - ], - "metadata": { - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro.ipynb deleted file mode 100644 index 13bec3dbf..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro.ipynb +++ /dev/null @@ -1,155 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "409a30d2", - "metadata": {}, - "source": [ - "# Intro" - ] - }, - { - "cell_type": "markdown", - "id": "4dd4a51d", - "metadata": {}, - "source": [ - "## Overview" - ] - }, - { - "cell_type": "markdown", - "id": "869534f9", - "metadata": {}, - "source": [ - "Welcome to the first day of the Computational Tools for Climate Science course! During this first day, the videos will provide an overview of Earth’s climate system. You’ll learn about various aspects of Earth’s climate including different parts of the climate system, forcings and mechanisms that drive changes in the climate system and the importance of understanding past, present and future climate variability. You’ll begin by learning about the effect of incoming solar radiation and Earth’s energy budget on the climate. You’ll then explore various processes within the atmospheric, oceanic and terrestrial components of Earth’s climate system. Finally, you’ll investigate long-term, natural forcings and feedbacks that influence Earth’s climate, and will begin to think about these processes in the contest of past, present and future climate variability. \n", - "\n", - "Additionally, the notebooks in today’s tutorials will elaborate on the climate concepts introduced in the videos, but will primarily focus on introducing the Xarray Python package, which is commonly used to analyze large climate datasets and makes working with multi-dimensional arrays simple and efficient. Xarray introduces labels in the form of dimensions, coordinates and attributes on top of raw data array, and includes a large number of functions for advanced analytics and visualization with these data structures. Throughout the tutorials today, you’ll learn the basics of Xarray and apply some of these tools to climate datasets to further explore the climate system concepts introduced in the videos." - ] - }, - { - "cell_type": "markdown", - "id": "452816ee", - "metadata": {}, - "source": [ - "## Video 1: Climate Solutions for a Warming World" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "afe1b307", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Climate Solutions for a Warming World\n", - "\n", - "import ipywidgets as widgets # interactive display\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', 'RhEQhWTAOJ0'), ('Bilibili', 'BV1Eh4y1j7FB')]\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": "markdown", - "id": "168f8f55", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "source": [ - "## Slides" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c044d10e", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @markdown\n", - "from IPython.display import IFrame\n", - "link_id = \"ghmn5\"" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro.ipynb deleted file mode 100644 index f794f3abd..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro.ipynb +++ /dev/null @@ -1,41 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "bb42d526", - "metadata": {}, - "source": [ - "# Outro" - ] - }, - { - "cell_type": "markdown", - "id": "9c2120be", - "metadata": {}, - "source": [ - "Now that you’ve explored various components, forcings and processes of Earth’s climate system, we can start to use additional climate data from various sources to investigate variability in Earth’s climate on multiple spatial and temporal scales. " - ] - } - ], - "metadata": { - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.ipynb deleted file mode 100644 index 0d9900842..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.ipynb +++ /dev/null @@ -1,798 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial1.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 1: Creating DataArrays and Datasets to Assess Global Climate Data\n", - "\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS, Google DeepMind, NFDI4Earth!" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "\n", - "As you just learned in the Introduction to Climate video, variations in global climate involve various forcings, feedbacks, and interactions between multiple processes and systems. Because of this complexity, global climate datasets are often very large with multiple dimensions and variables.\n", - "\n", - "One useful computational tool for organizing, analyzing and interpreting large global datasets is [Xarray](https://xarray.pydata.org/en/v2023.05.0/getting-started-guide/why-xarray.html), an open source project and Python package that makes working with labelled multi-dimensional arrays simple and efficient.\n", - "\n", - "In this first tutorial, we will use the `DataArray` and `Dataset` objects, which are used to represent and manipulate spatial data, to practice organizing large global climate datasets and to understand variations in Earth's climate system." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Similar to `numpy`, `np`; `pandas`, `pd`; you may often encounter `xarray` imported within a shortened namespace as `xr`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "hide-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import numpy as np\n", - "import pandas as pd\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Introduction to Climate\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', 'mc-DkvYLdOA'), ('Bilibili', 'BV1Th4y1j7SS')]\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", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"4suf5\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Introducing the `DataArray` and `Dataset`\n", - "\n", - "[Xarray](https://xarray.pydata.org/en/v2023.05.0/getting-started-guide/why-xarray.html) expands on the capabilities on [NumPy](https://numpy.org/doc/stable/user/index.html#user) arrays, providing a lot of streamlined data manipulation. It is similar in that respect to [Pandas](https://pandas.pydata.org/docs/user_guide/index.html#user-guide), but whereas Pandas excels at working with tabular data, Xarray is focused on N-dimensional arrays of data (i.e. grids). Its interface is based largely on the netCDF data model (variables, attributes, and dimensions), but it goes beyond the traditional netCDF interfaces to provide functionality similar to netCDF-java's [Common Data Model (CDM)](https://docs.unidata.ucar.edu/netcdf-java/current/userguide/common_data_model_overview.html). " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Creation of a `DataArray` Object\n", - "\n", - "The `DataArray` is one of the basic building blocks of Xarray (see docs [here](http://xarray.pydata.org/en/stable/user-guide/data-structures.html#dataarray)). It provides a `numpy.ndarray`-like object that expands to provide two critical pieces of functionality:\n", - "\n", - "1. Coordinate names and values are stored with the data, making slicing and indexing much more powerful\n", - "2. It has a built-in container for attributes\n", - "\n", - "Here we'll initialize a `DataArray` object by wrapping a plain NumPy array, and explore a few of its properties." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Generate a Random Numpy Array\n", - "\n", - "For our first example, we'll just create a random array of \"temperature\" data in units of Kelvin:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 151, - "status": "ok", - "timestamp": 1681570301490, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "rand_data = 283 + 5 * np.random.randn(5, 3, 4)\n", - "rand_data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.2: Wrap the Array: First Attempt\n", - "\n", - "Now we create a basic `DataArray` just by passing our plain `data` as an input:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 154, - "status": "ok", - "timestamp": 1681570303856, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature = xr.DataArray(rand_data)\n", - "temperature" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Note two things:\n", - "\n", - "1. Xarray generates some basic dimension names for us (`dim_0`, `dim_1`, `dim_2`). We'll improve this with better names in the next example.\n", - "2. Wrapping the numpy array in a `DataArray` gives us a rich display in the notebook! (Try clicking the array symbol to expand or collapse the view)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.3: Assign Dimension Names\n", - "\n", - "Much of the power of Xarray comes from making use of named dimensions. So let's add some more useful names! We can do that by passing an ordered list of names using the keyword argument `dims`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 511, - "status": "ok", - "timestamp": 1679942484345, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature = xr.DataArray(rand_data, dims=[\"time\", \"lat\", \"lon\"])\n", - "temperature" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This is already an improvement over a NumPy array because we have names for each of the dimensions (or axes). Even better, we can associate arrays representing the values for the coordinates for each of these dimensions with the data when we create the `DataArray`. We'll see this in the next example." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Create a `DataArray` with Named Coordinates\n", - "\n", - "## Section 2.1: Make Time and Space Coordinates\n", - "\n", - "Here we will use [Pandas](https://foundations.projectpythia.org/core/pandas.html) to create an array of [datetime data](https://foundations.projectpythia.org/core/datetime.html), which we will then use to create a `DataArray` with a named coordinate `time`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 656, - "status": "ok", - "timestamp": 1679942588784, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "times_index = pd.date_range(\"2018-01-01\", periods=5)\n", - "times_index" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We'll also create arrays to represent sample longitude and latitude:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "lons = np.linspace(-120, -60, 4)\n", - "lats = np.linspace(25, 55, 3)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Section 2.1.1: Initialize the `DataArray` with Complete Coordinate Info\n", - "\n", - "When we create the `DataArray` instance, we pass in the arrays we just created:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 320, - "status": "ok", - "timestamp": 1679942603438, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature = xr.DataArray(\n", - " rand_data, coords=[times_index, lats, lons], dims=[\"time\", \"lat\", \"lon\"]\n", - ")\n", - "temperature" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Section 2.1.2: Set Useful Attributes\n", - "\n", - "We can also set some attribute metadata, which will help provide clear descriptions of the data. In this case, we can specify that we're looking at 'air_temperature' data and the units are 'kelvin'." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 445, - "status": "ok", - "timestamp": 1679942614596, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature.attrs[\"units\"] = \"kelvin\"\n", - "temperature.attrs[\"standard_name\"] = \"air_temperature\"\n", - "\n", - "temperature" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Section 2.1.3: Attributes Are Not Preserved by Default!\n", - "\n", - "Notice what happens if we perform a mathematical operaton with the `DataArray`: the coordinate values persist, but the attributes are lost. This is done because it is very challenging to know if the attribute metadata is still correct or appropriate after arbitrary arithmetic operations.\n", - "\n", - "To illustrate this, we'll do a simple unit conversion from Kelvin to Celsius:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 308, - "status": "ok", - "timestamp": 1679942626636, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature_in_celsius = temperature - 273.15\n", - "temperature_in_celsius" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We usually wish to keep metadata with our dataset, even after manipulating the data. For example it can tell us what the units are of a variable of interest. So when you perform operations on your data, make sure to check that all the information you want is carried over. If it isn't, you can add it back in following the instructions in the section before this. For an in-depth discussion of how Xarray handles metadata, you can find more information in the Xarray documents [here](http://xarray.pydata.org/en/stable/getting-started-guide/faq.html#approach-to-metadata)." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 3: The `Dataset`: a Container for `DataArray`s with Shared Coordinates\n", - "\n", - "Along with `DataArray`, the other key object type in Xarray is the `Dataset`, which is a dictionary-like container that holds one or more `DataArray`s, which can also optionally share coordinates (see docs [here](http://xarray.pydata.org/en/stable/user-guide/data-structures.html#dataset)).\n", - "\n", - "The most common way to create a `Dataset` object is to load data from a file (which we will practice in a later tutorial). Here, instead, we will create another `DataArray` and combine it with our `temperature` data.\n", - "\n", - "This will illustrate how the information about common coordinate axes is used." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 3.1: Create a Pressure `DataArray` Using the Same Coordinates\n", - "\n", - "For our next `DataArry` example, we'll create a random array of `pressure` data in units of hectopascal (hPa). This code mirrors how we created the `temperature` object above." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 335, - "status": "ok", - "timestamp": 1679942669187, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "pressure_data = 1000.0 + 5 * np.random.randn(5, 3, 4)\n", - "pressure = xr.DataArray(\n", - " pressure_data, coords=[times_index, lats,\n", - " lons], dims=[\"time\", \"lat\", \"lon\"]\n", - ")\n", - "pressure.attrs[\"units\"] = \"hPa\"\n", - "pressure.attrs[\"standard_name\"] = \"air_pressure\"\n", - "\n", - "pressure" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 3.2: Create a `Dataset` Object\n", - "\n", - "Each `DataArray` in our `Dataset` needs a name! \n", - "\n", - "The most straightforward way to create a `Dataset` with our `temperature` and `pressure` arrays is to pass a dictionary using the keyword argument `data_vars`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 322, - "status": "ok", - "timestamp": 1679942691730, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds = xr.Dataset(data_vars={\"Temperature\": temperature, \"Pressure\": pressure})\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Notice that the `Dataset` object `ds` is aware that both data arrays sit on the same coordinate axes." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 3.3: Access Data Variables and Coordinates in a `Dataset`\n", - "\n", - "We can pull out any of the individual `DataArray` objects in a few different ways.\n", - "\n", - "Using the \"dot\" notation:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 678, - "status": "ok", - "timestamp": 1679942736703, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.Pressure" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "... or using dictionary access like this:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 610, - "status": "ok", - "timestamp": 1679942746338, - "user": { - "displayName": "Yosmely Tamira Bermudez Gutierrez", - "userId": "07776907551108334395" - }, - "user_tz": 180 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds[\"Pressure\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We'll return to the `Dataset` object when we start loading data from files in later tutorials today." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this initial tutorial, the `DataArray` and `Dataset` objects were utilized to create and explore synthetic examples of climate data." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/xarray-intro.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial1", - "provenance": [ - { - "file_id": "1f2uyMuRNCH2LLG5u4Z4Tdb_OHLHB9saW", - "timestamp": 1679941598643 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - }, - "toc-autonumbering": false - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2.ipynb deleted file mode 100644 index d5d816fdd..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2.ipynb +++ /dev/null @@ -1,729 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial2.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 2: Selection, Interpolation and Slicing\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind!" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "In the previous tutorial, we learned how to use `Xarray` to create `DataArray` and `Dataset` objects. Global climate datasets can be very large with multiple variables, and DataArrays and Datasets are very useful tools for organizing, comparing and interpreting such data. However, sometimes we are not interested in examining a *global* dataset but wish to examine a specific time or location. For example, we might want to look at climate variables in a particular region of Earth, and potentially compare that to another region. In order to carry-out such analyses, it’s useful to be able to extract and compare subsets of data from a global dataset. \n", - "\n", - "In this tutorial, you will explore multiple computational tools in `Xarray` that allow you to select data from a specific spatial and temporal range. In particular, you will practice using:\n", - "\n", - "\n", - "* **`.sel()`:** select data based on coordinate values or date\n", - "* **`.interp()`:** interpolate to any latitude/longitude location to extract data\n", - "* **`slice()`:** to select a range (or slice) along one or more coordinates, we can pass a Python slice object to `.sel()`\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "from datetime import timedelta\n", - "import numpy as np\n", - "import pandas as pd\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Solar Radiation and Earth's Energy Budget\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', 'EX4BMd3ZItQ'), ('Bilibili', 'BV1rg4y1w7Yq')]\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", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"gh5us\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To explore these Xarray tools, first recreate the synthetic temperature and pressure DataArrays you generated in the previous tutorial, and combine these two DataArrays into a Dataset." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Subsetting and Selection by Coordinate Values\n", - "\n", - "Since Xarray allows us to label coordinates, you can select data based on coordinate names and values, rather than array indices. We'll explore this briefly here. First, we will recreate the temperature and pressure data from Tutorial 1." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# temperature data\n", - "rand_data = 283 + 5 * np.random.randn(5, 3, 4)\n", - "times_index = pd.date_range(\"2018-01-01\", periods=5)\n", - "lons = np.linspace(-120, -60, 4)\n", - "lats = np.linspace(25, 55, 3)\n", - "temperature = xr.DataArray(\n", - " rand_data, coords=[times_index, lats, lons], dims=[\"time\", \"lat\", \"lon\"]\n", - ")\n", - "temperature.attrs[\"units\"] = \"kelvin\"\n", - "temperature.attrs[\"standard_name\"] = \"air_temperature\"\n", - "\n", - "# pressure data\n", - "pressure_data = 1000.0 + 5 * np.random.randn(5, 3, 4)\n", - "pressure = xr.DataArray(\n", - " pressure_data, coords=[times_index, lats, lons], dims=[\"time\", \"lat\", \"lon\"]\n", - ")\n", - "pressure.attrs[\"units\"] = \"hPa\"\n", - "pressure.attrs[\"standard_name\"] = \"air_pressure\"\n", - "\n", - "# combinate temperature and pressure DataArrays into a Dataset called 'ds'\n", - "ds = xr.Dataset(data_vars={\"Temperature\": temperature, \"Pressure\": pressure})\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To refresh your memory from the previous tutorial, take a look at the DataArrays you created for temperature and pressure by clicking on those variables in the dataset above." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "## Section 1.1: NumPy-like Selection\n", - "\n", - "Suppose you want to extract all the spatial data for one single date: January 2, 2018. It's possible to achieve that with NumPy-like index selection:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 369, - "status": "ok", - "timestamp": 1681570689311, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "indexed_selection = temperature[\n", - " 1, :, :\n", - "] # index 1 along axis 0 is the time slice we want...\n", - "indexed_selection" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "However, notice that this requires us (the user) to have detailed knowledge of the order of the axes and the meaning of the indices along those axes. By having named coordinates in Xarray, we can avoid this issue." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.2: `.sel()`\n", - "\n", - "Rather than using a NumPy-like index selection, in Xarray, we can instead select data based on coordinate values using the `.sel()` method, which takes one or more named coordinate(s) as a keyword argument:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 14, - "status": "ok", - "timestamp": 1681570692916, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "named_selection = temperature.sel(time=\"2018-01-02\")\n", - "named_selection" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We got the same result as when we used the NumPy-like index selection, but \n", - "- we didn't have to know anything about how the array was created or stored\n", - "- our code is agnostic about how many dimensions we are dealing with\n", - "- the intended meaning of our code is much clearer!\n", - "\n", - "By using the .sel() method in Xarray, we can easily isolate data from a specific time. You can also isolate data from a specific coordinate. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Coding Exercises 1.2" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Write a line of code to select the temperature data from the coordinates 25,-120." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Write a line of code to select the temperature data from the coordinates 25,-120.\"\n", - ")\n", - "#################################################\n", - "\n", - "coordinate_selection = ...\n", - "coordinate_selection" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.3: Approximate Selection and Interpolation\n", - "\n", - "The spatial and temporal resolution of climate data often differs between datasets or a dataset may be incomplete. Therefore, with time and space data, we frequently want to sample \"near\" the coordinate points in our dataset. For example, we may want to analyze data from a specific coordinate or a specific time, but may not have a value from that specific location or date. In that case, we would want to use the data from the closest coordinate or time-step. Here are a few simple ways to achieve that.\n", - "\n", - "### Section 1.3.1: Nearest-neighbor Sampling\n", - "\n", - "Suppose we want to know the temperature from `2018-01-07`. However, the last day on our `time` axis is `2018-01-05`. We can therefore sample within two days of our desired date of `2018-01-07`. We can do this using the `.sel` method we used earlier, but with the added flexibility of performing [nearest neighbor sampling](https://docs.xarray.dev/en/stable/user-guide/indexing.html#nearest-neighbor-lookups) and specifying an optional tolerance. This is called an **inexact lookup** because we are not searching for a perfect match, although there may be one. Here the **tolerance** is the maximum distance away from our desired point Xarray will search for a nearest neighbor." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 321, - "status": "ok", - "timestamp": 1681570696404, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature.sel(time=\"2018-01-07\", method=\"nearest\", tolerance=timedelta(days=2))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Notice that the resulting data is from the date `2018-01-05`." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Section 1.3.2: Interpolation\n", - "\n", - "The latitude values of our dataset are 25ºN, 40ºN, 55ºN, and the longitude values are 120ºW, 100ºW, 80ºW, 60ºW. But suppose we want to extract a timeseries for Boulder, Colorado, USA (40°N, 105°W). Since `lon=-105` is _not_ a point on our longitude axis, this requires interpolation between data points.\n", - "\n", - "We can do this using the `.interp()` method (see the docs [here](http://xarray.pydata.org/en/stable/interpolation.html)), which works similarly to `.sel()`. Using `.interp()`, we can interpolate to any latitude/longitude location using an interpolation method of our choice. In the example below, you will linearly interpolate between known points." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 646, - "status": "ok", - "timestamp": 1681570700081, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remote-output" - ] - }, - "outputs": [], - "source": [ - "temperature.interp(lon=-105, lat=40, method=\"linear\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this case, we specified a linear interpolation method, yet one can choose other methods as well (e.g., nearest, cubic, quadratic). Note that the temperature values we extracted in the code cell above are not actual values in the dataset, but are instead calculated based on linear interpolations between values that are in the dataset." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.4: Slicing Along Coordinates\n", - "\n", - "Frequently we want to select a range (or _slice_) along one or more coordinate(s). For example, you may wish to only assess average annual temperatures in equatorial regions. We can achieve this by passing a Python [slice](https://docs.python.org/3/library/functions.html#slice) object to `.sel()`. The calling sequence for slice always looks like slice(start, stop[, step]), where step is optional. In this case, let's only look at values between 110ºW-70ºW and 25ºN-40ºN:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 21, - "status": "ok", - "timestamp": 1681570702748, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature.sel(\n", - " time=slice(\"2018-01-01\", \"2018-01-03\"), lon=slice(-110, -70), lat=slice(25, 45)\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.5: One More Selection Method: `.loc`\n", - "\n", - "All of these operations can also be done within square brackets on the `.loc` attribute of the `DataArray`:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 14, - "status": "ok", - "timestamp": 1681570706874, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature.loc['2018-01-02']" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This is sort of in between the NumPy-style selection\n", - "\n", - "```\n", - "temp[1,:,:]\n", - "```\n", - "\n", - "and the fully label-based selection using `.sel()`\n", - "\n", - "With `.loc`, we make use of the coordinate _values_, but lose the ability to specify the _names_ of the various dimensions. Instead, the slicing must be done in the correct order:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 315, - "status": "ok", - "timestamp": 1681570712906, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature.loc['2018-01-01':'2018-01-03', 25:45, -110:-70]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "One advantage of using `.loc` is that we can use NumPy-style slice notation like `25:45`, rather than the more verbose `slice(25,45)`. But of course that also works:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 365, - "status": "ok", - "timestamp": 1681570719989, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temperature.loc[\"2018-01-01\":\"2018-01-03\", slice(25, 45), -110:-70]" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "What _doesn't_ work is passing the slices in a different order to the dimensions of the dataset:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# This will generate an error\n", - "# temperature.loc[-110:-70, 25:45,'2018-01-01':'2018-01-03']" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we have explored the practical use of **`.sel()`** **`.interp()`** **`.loc()`:** and **slicing** techniques to extract data from specific spatial and temporal ranges. These methods are valuable when we are intereseted in only certain pieces of large datasets." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/xarray-intro.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial2", - "provenance": [ - { - "file_id": "1f2uyMuRNCH2LLG5u4Z4Tdb_OHLHB9saW", - "timestamp": 1679941598643 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3.ipynb deleted file mode 100644 index 997b8ce6f..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3.ipynb +++ /dev/null @@ -1,748 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial3.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 3: Opening and Plotting netCDF Data\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "Many global climate datasets are stored as [NetCDF](https://pro.arcgis.com/en/pro-app/latest/help/data/multidimensional/what-is-netcdf-data.htm) (network Common Data Form) files. NetCDF is a file format for storing multidimensional variables such as temperature, humidity, pressure, wind speed, and direction. These types of files also include metadata that gives you information about the variables and dataset itself.\n", - "\n", - "In this tutorial, we will import atmospheric pressure and temperature data stored in a NetCDF file. We will learn how to use various attributes of Xarray to import, analyze, interpret, and plot the data." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 975, - "status": "ok", - "timestamp": 1681571208838, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import numpy as np\n", - "import pandas as pd\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Atmospheric Climate Systems\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', '7yJM9MDLeoo'), ('Bilibili', 'BV1wz4y177xE')]\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", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"cnfwz\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Opening netCDF Data\n", - "\n", - "Xarray is closely linked with the netCDF data model, and it even treats netCDF as a 'first-class' file format. This means that Xarray can easily open netCDF datasets. However, these datasets need to follow some of Xarray's rules. One such rule is that coordinates must be 1-dimensional.\n", - "\n", - "Here we're getting the data from Project Pythia's custom library of example data, which we already imported above with from pythia_datasets import DATASETS. The DATASETS.fetch() method will automatically download and cache (store) our example data file NARR_19930313_0000.nc locally." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1064, - "status": "ok", - "timestamp": 1681571216216, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath = DATASETS.fetch(\"NARR_19930313_0000.nc\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Once we have a valid path to a data file that Xarray knows how to read, we can open it like this:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 891, - "status": "ok", - "timestamp": 1681571219656, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds = xr.open_dataset(filepath)\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. What are the dimensions of this dataset?\n", - "1. How many climate variables are in this dataset?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Subsetting the `Dataset`\n", - "\n", - "Our call to `xr.open_dataset()` above returned a `Dataset` object that we've decided to call `ds`. We can then pull out individual fields. First, let's assess the `isobaric1` values. **Isobaric** means characterized by constant or equal pressure. Let's look at the `isobaric1` values:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 268, - "status": "ok", - "timestamp": 1681571222970, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.isobaric1\n", - "# Recall that we can also use dictionary syntax like `ds['isobaric1']` to do the same thing" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The `isobaric1` coordinate contains 29 pressure values (in hPa) corresponding to different pressures of the atmosphere. Recall from the video that pressure decreases with height in the atmosphere. Therefore, in our dataset lower atmospheric pressure values will correspond to higher altitudes. For each isobaric pressure value, there is data for all other variables in the dataset at that same pressure level of the atmosphere:\n", - " - **Wind**: the u and v components of the wind describe the direction of wind movement along a pressure level of the atmosphere. The U wind component is parallel to the x-axis (i.e. longitude) and the V wind component is parallel to the y- axis (i.e. latitude). \n", - " - **Temperature**: temperatures on a specific atmospheric pressure level\n", - " - **Geopotential Height**: the height of a given point in the atmosphere in units proportional to the potential energy of unit mass (geopotential) at this height relative to sea level\n", - "\n", - "Let's explore this `Dataset` a bit further." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "`Datasets` also support much of the same subsetting operations as `DataArray`, but will perform the operation on all data. Let's subset all data from an atmospheric pressure of 1000 hPa (the typical pressure at sea level):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 143, - "status": "ok", - "timestamp": 1681571229281, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds_1000 = ds.sel(isobaric1=1000.0)\n", - "ds_1000" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can further subset to a single `DataArray` to isolate a specific climate measurement. Let's subset temperature from the atmospheric level at which the isobaric pressure is 1000 hPa:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 227, - "status": "ok", - "timestamp": 1681571232661, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds_1000.Temperature_isobaric" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.2: Aggregation Operations\n", - "\n", - "Not only can you use the named dimensions for manual slicing and indexing of data (as we saw in the last tutorial), but you can also use it to control aggregation operations (e.g., average, sum, standard deviation). Aggregation methods for Xarray objects operate over the named coordinate dimensions specified by keyword argument dim. \n", - "\n", - "First, let's try calculating the `std` (standard deviation) of the u component of the isobaric wind from our `Dataset`. The following code will calculate the standard deviation of all the `u-component_of_wind_isobaric` values at each isobaric level. In other words, we'll end up with one standard deviation value for each of the 29 isobaric levels. Note: because of the '-' present in the name, we cannot use dot notation to select this variable and must use a dictionary key style selection instead." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 161, - "status": "ok", - "timestamp": 1681571235929, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# get wind data\n", - "u_winds = ds[\"u-component_of_wind_isobaric\"]\n", - "\n", - "# take the standard deviation\n", - "u_winds.std(dim=[\"x\", \"y\"])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Side note: Recall that the U wind component is parallel to the x-axis (i.e. longitude) and the V wind component is parallel to the y- axis (i.e. latitude). A positive U wind comes from the west, and a negative U wind comes from the east. A positive V wind comes from the south, and a negative V wind comes from the north." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Next, let's try calculating the mean of the temperature profile (temperature as a function of pressure) over a specific region. For this exercise, we will calculate the temperature profile over Colorado, USA. The bounds of Colorado are:\n", - "\n", - "- x: -182km to 424km\n", - "- y: -1450km to -990km\n", - "\n", - "If you look back at the values for `x` and `y` in our dataset, the units for these values are kilometers (km). Remember that they are also the coordinates for the `lat` and `lon` variables in our dataset. The bounds for Colorado correspond to the coordinates 37°N to 41°N and 102°W to 109°W.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 149, - "status": "ok", - "timestamp": 1681571239494, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# get the temperature data\n", - "temps = ds.Temperature_isobaric\n", - "\n", - "# take just the spatial data we are interested in for Colorado\n", - "co_temps = temps.sel(x=slice(-182, 424), y=slice(-1450, -990))\n", - "\n", - "# take the average\n", - "prof = co_temps.mean(dim=[\"x\", \"y\"])\n", - "prof" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Plotting with Xarray\n", - "\n", - "Another major benefit of using labeled data structures is that they enable automated plotting with axis labels. \n", - "\n", - "## Section 2.1: Simple Visualization with `.plot()`\n", - "\n", - "Much like [Pandas](https://foundations.projectpythia.org/core/pandas.html), Xarray includes an interface to [Matplotlib](https://foundations.projectpythia.org/core/matplotlib.html) that we can access through the `.plot()` method of every `DataArray`.\n", - "\n", - "For quick and easy data exploration, we can just call `.plot()` without any modifiers:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 336, - "status": "ok", - "timestamp": 1681571243036, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "prof.plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Here Xarray has generated a line plot of the temperature data against the coordinate variable `isobaric`. Also, the metadata are used to auto-generate axis labels and units.\n", - "\n", - "Consider the following questions:\n", - "- What isobaric pressure corresponds to Earth's surface?\n", - "- How does temperature change with increasing altitude in the atmosphere?\n", - "\n", - "It might be a bit difficult to answer these questions with our current plot, so let's try customizing our figure to present the data clearer." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.2: Customizing the Plot\n", - "\n", - "As in Pandas, the `.plot()` method is mostly just a wrapper to Matplotlib, so we can customize our plot in familiar ways.\n", - "\n", - "In this air temperature profile example, we would like to make two changes:\n", - "- swap the axes so that we have isobaric levels on the y (vertical) axis of the figure (since isobaric levels correspond to altitude)\n", - "- make pressure decrease upward in the figure, so that up is up (since pressure decreases with altitude)\n", - "\n", - "We can do this by adding a few keyword arguments to our `.plot()`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 446, - "status": "ok", - "timestamp": 1681571246625, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "prof.plot(y=\"isobaric1\", yincrease=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 2.2" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. What isobaric pressure corresponds to Earth's surface?\n", - "2. Why do you think temperature generally decreases with height?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.3: Plotting 2D Data\n", - "\n", - "In the example above, the `.plot()` method produced a line plot.\n", - "\n", - "What if we call `.plot()` on a 2D array? Let's try plotting the temperature data from the 1000 hPa isobaric level (surface temperature) for all x and y values:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1089, - "status": "ok", - "timestamp": 1681571250322, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "temps.sel(isobaric1=1000).plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Xarray has recognized that the `DataArray` object calling the plot method has two coordinate variables, and generates a 2D plot using the `pcolormesh` method from Matplotlib.\n", - "\n", - "In this case, we are looking at air temperatures on the 1000 hPa isobaric surface over North America. Note you could improve this figure further by using [Cartopy](https://foundations.projectpythia.org/core/cartopy.html) to handle the map projection and geographic features." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 2.2: Climate Connection\n", - "\n", - "1. The map you made is showing temperature across the United States at the 1000 hPa level of the atmosphere. How do you think temperatures at the 500 hPa level would compare? What might be causing the spatial differences in temperature seen in the map?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "Xarray brings the joy of Pandas-style labeled data operations to N-dimensional data. As such, it has become a central workhorse in the geoscience community for analyzing gridded datasets. Xarray allows us to open self-describing NetCDF files and make full use of the coordinate axes, labels, units, and other metadata. By utilizing labeled coordinates, our code becomes simpler to write, easier to read, and more robust.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/xarray-intro.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial3", - "provenance": [ - { - "file_id": "1f2uyMuRNCH2LLG5u4Z4Tdb_OHLHB9saW", - "timestamp": 1679941598643 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4.ipynb deleted file mode 100644 index b1643ea95..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4.ipynb +++ /dev/null @@ -1,604 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "26038f28", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial4.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "id": "NJh_iuR-5DFi", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 4: Arithmetic and Aggregation Methods\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "id": "495977ba-44ab-489d-ad27-1ddba8228aec", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "id": "Lcbp0S4xhClA", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "As we just learned in the video, alongside the latitudinal temperature gradients set by solar radiation, the large-scale ocean circulation patterns are one of the main controls on global sea surface temperature (SST, or tos). The surface currents distort this meridional gradient and can transport heat globally. In this tutorial, we'll use a series of tools in Xarray to interpret sea surface temperature data. \n", - "\n", - "Specifically, we’ll import monthly SST data from the Community Earth System Model v2 (CESM2), which is a Global Climate Model. A climate model is a mathematical representation of Earth's climate system components and their interactions. Climate models are based on well-documented physical processes to simulate the transfer of energy and materials through the climate system. You'll learn more about climate models later this week and next week, but for now, we're going to be working with SST data produced from a climate model. \n", - "\n", - "To assess global variations in this SST dataset, we will practice using multiple attributes of Xarray:\n", - "\n", - "\n", - "* Arithmetic methods to convert temperatures from Celsius to Kelvin\n", - "* Aggregation methods to calculate mean, median, minimum and maximum values of the data.\n", - "\n", - "\n", - "Finally, we'll create a map of global mean annual SST to visualize spatial variations in SST.\n" - ] - }, - { - "cell_type": "markdown", - "id": "0af7bee1-3de3-453a-8ae8-bcd7910b4266", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06073287-7bdb-45b5-9cec-8cdf123adb49", - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ed6bcdfe-d18b-42a4-96d6-2f921d9ce3fd", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1712a218-1c6b-4ae9-9b89-5843bdde1d96", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Oceanic Climate Systems\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', 'E3UEWlak5Zs'), ('Bilibili', 'BV1gz4y177vk')]\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, - "id": "682c6f71-edc2-4088-bd74-fb526e667ba7", - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-input", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"hmqfr\"" - ] - }, - { - "cell_type": "markdown", - "id": "b3f4e108-f55e-4c25-a00d-99dc00ba849a", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Section 1: Arithmetic Operations\n", - "\n", - "Arithmetic operations with a single `DataArray` automatically apply over all array values (like NumPy). This process is called **vectorization**. First, let's open the monthly sea surface temperature (SST) data from the Community Earth System Model v2 (CESM2), which is a Global Climate Model." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7837f8bd-da89-4718-ab02-d5107576d2d6", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 303, - "status": "ok", - "timestamp": 1681569406112, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath = DATASETS.fetch(\"CESM2_sst_data.nc\")\n", - "ds = xr.open_dataset(filepath)\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "8cabb77f", - "metadata": { - "execution": {} - }, - "source": [ - "And look at the temeprature variable `tos`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cbe80157", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos" - ] - }, - { - "cell_type": "markdown", - "id": "6a185c07", - "metadata": { - "execution": {} - }, - "source": [ - "Note in the attributes that the units are 'degC'. One arithmetic operation we can do is to the convert the temperature from degrees Celsius to Kelvin:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "09542eab-998d-4b2d-807c-dccd5bd4329e", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 14, - "status": "ok", - "timestamp": 1681569533895, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos + 273.15" - ] - }, - { - "cell_type": "markdown", - "id": "6f35c8d6-b0e6-4371-ad80-e182ffcec51b", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "You may notice that there are a lot of NaN values in the DataArray for `tos`. NaN isn’t a bad thing and it just means there isn’t data for those coordinates. In this case, there's no `tos` data for areas with land since this dataset only contains SST values.\n", - "\n", - "\n", - "Just to practice another arithmetic operation, lets's square all values in `tos`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "78c1ffc2-45cb-40cc-962e-c76021d9ab1c", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 12, - "status": "ok", - "timestamp": 1681569537428, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos**2" - ] - }, - { - "cell_type": "markdown", - "id": "0bebb17b-6906-4ba7-a4ff-c07a9206e790", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Section 2: Aggregation Methods\n", - "\n", - "A very common step during data analysis is to summarize the data in question by computing aggregations like `sum()`, `mean()`, `median()`, `min()`, `max()` in which reduced data provide insight into the nature of the large dataset. For example, in the introductory video for this tutorial, we saw maps of the mean annual sea surface temperature and sea surface density. \n", - "\n", - "\n", - "The following table summarizes some other built-in xarray aggregations:\n", - "\n", - "| Aggregation | Description |\n", - "|--------------------------|---------------------------------|\n", - "| ``count()`` | Total number of items |\n", - "| ``mean()``, ``median()`` | Mean and median |\n", - "| ``min()``, ``max()`` | Minimum and maximum |\n", - "| ``std()``, ``var()`` | Standard deviation and variance |\n", - "| ``prod()`` | Compute product of elements |\n", - "| ``sum()`` | Compute sum of elements |\n", - "| ``argmin()``, ``argmax()``| Find index of minimum and maximum value |\n", - "\n", - "\n", - "Let's explore some of these aggregation methods.\n" - ] - }, - { - "cell_type": "markdown", - "id": "e6f15eca", - "metadata": { - "execution": {} - }, - "source": [ - "Compute the temporal minimum:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06e3bfff", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.min(dim=\"time\")" - ] - }, - { - "cell_type": "markdown", - "id": "01bfdf21", - "metadata": { - "execution": {} - }, - "source": [ - "Compute the spatial sum:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "400c3dab", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.sum(dim=[\"lat\", \"lon\"])" - ] - }, - { - "cell_type": "markdown", - "id": "e8bd66b3", - "metadata": { - "execution": {} - }, - "source": [ - "Compute the temporal median:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d397f30", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.median(dim=\"time\")" - ] - }, - { - "cell_type": "markdown", - "id": "a4d79093-f013-4821-84f8-3c223141046e", - "metadata": { - "execution": {} - }, - "source": [ - "Compute the mean SST:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "59b84034-7d42-4080-932f-0eefd165953d", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 297, - "status": "ok", - "timestamp": 1681569542731, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.mean()" - ] - }, - { - "cell_type": "markdown", - "id": "a75e0064-4363-4328-9a79-d87475ed1c81", - "metadata": { - "execution": {} - }, - "source": [ - "Because we specified no `dim` argument, the function was applied over all dimensions, computing the mean of every element of `tos` across time and space. It is possible to specify a dimension along which to compute an aggregation. For example, to calculate the mean in time for all locations (i.e. the global mean annual SST), specify the time dimension as the dimension along which the mean should be calculated:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a49b957e-ea24-414e-a422-c40a3723fbae", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 815, - "status": "ok", - "timestamp": 1681569338417, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.mean(dim=\"time\").plot(size=7, vmin=-2, vmax=32, cmap=\"coolwarm\")" - ] - }, - { - "cell_type": "markdown", - "id": "aVnchVimEp6k", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 2: Climate Connection\n", - "\n", - "Observe the spatial patterns in SST and consider the following in the context of the components of the ocean climate system we learned about in the video:\n", - "\n", - "1. Recall that upwelling commonly occurs off the west coast of continents, for example, in the eastern tropical Pacific off the west coast of South America. Do you see evidence for upwelling in this region? How do you think the mean SST in this region would change if you looked at a specific season rather than the annual mean? Would upwelling be more or less evident?\n" - ] - }, - { - "cell_type": "markdown", - "id": "9ac2925a-9b96-4b0a-b2b6-24f6b4151d4c", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we have explored the use of the CESM2 and have imported and analyzed monthly sea surface temperature (SST, or tos) data. We used arithmetic methods to convert SST from Celsius to Kelvin, and aggregation methods such as the mean, median, minimum, and maximum values of the data. To conclude, we visualized the spatial variations in SST by generating a map of the global mean annual SST. This tutorial has provided us with valuable insights into global variations in SST and how to manipulate and analyze such data using Xarray.\n" - ] - }, - { - "cell_type": "markdown", - "id": "de7bca95-3766-4bd0-b5dd-a82683f0732a", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "cell_type": "markdown", - "id": "5f41d4b4-5929-4418-b8d4-d8ef60326899", - "metadata": { - "execution": {} - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/computation-masking.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial4", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.ipynb deleted file mode 100644 index cb8823a2c..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.ipynb +++ /dev/null @@ -1,680 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "e5bddb1b", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial5.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "id": "BSjO7xX42sEH", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 5: Xarray Data Analysis and Climatology\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "id": "e90a481e-8dd8-4d05-a5a1-a612f89cd637", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "id": "z99xmBTDi3JS", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "Global climate can vary on long timescales, but it's also important to understand seasonal variations. For example, seasonal variations in precipitation associated with the migration of the [Intertropical Convergence Zone (ITCZ)](https://glossary.ametsoc.org/wiki/Intertropical_convergence_zone#:~:text=(Also%20called%20ITCZ%2C%20equatorial%20convergence,and%20Northern%20Hemispheres%2C%20respectively).) and monsoon systems occur in response to seasonal changes in temperature. In this tutorial, we will use data analysis tools in Xarray to explore the seasonal climatology of global temperature. Specifically, in this tutorial, we'll use the `groupby` operation in Xarray, which involves the following steps:\n", - "\n", - "- **Split**: group data by value (e.g., month).\n", - "- **Apply**: compute some function (e.g., aggregate) within the individual groups.\n", - "- **Combine**: merge the results of these operations into an output dataset." - ] - }, - { - "cell_type": "markdown", - "id": "0af7bee1-3de3-453a-8ae8-bcd7910b4266", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06073287-7bdb-45b5-9cec-8cdf123adb49", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2358, - "status": "ok", - "timestamp": 1681572562093, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "72e04965-e982-444d-b3da-4e1e639c6899", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "21725d4b-ee68-42aa-af76-70392b4ab6ac", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Terrestrial Temperature and Rainfall\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', 'SyvFyT3jVM8'), ('Bilibili', 'BV1ho4y1C7Eo')]\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, - "id": "1bfcf3bd-6805-4cfb-90c4-a9067f6ce91c", - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-input", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"9z6km\"" - ] - }, - { - "cell_type": "markdown", - "id": "8704803f-300d-4631-a2fa-f62d18726d1c", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Section 1: GroupBy: Split, Apply, Combine\n", - "\n", - "Simple aggregations (as we learned in the previous tutorial) can give useful summary of our dataset, but often we would prefer to aggregate conditionally on some coordinate labels or groups. Xarray provides the so-called `groupby` operation which enables the **split-apply-combine** workflow on Xarray DataArrays and Datasets. The split-apply-combine operation is illustrated in this figure from [Project Pythia](https://foundations.projectpythia.org/core/xarray/computation-masking.html):\n", - "\n", - "\"split-apply-combine\"\n", - "\n", - "- The **split** step involves breaking up and grouping an xarray Dataset or DataArray depending on the value of the specified group key.\n", - "- The **apply** step involves computing some function, usually an aggregate, transformation, or filtering, within the individual groups.\n", - "- The **combine** step merges the results of these operations into an output xarray Dataset or DataArray.\n", - "\n", - "We are going to use `groupby` to remove the seasonal cycle (\"climatology\") from our dataset, which will allow us to better observe long-term trends in the data. See the [xarray `groupby` user guide](https://xarray.pydata.org/en/stable/user-guide/groupby.html) for more examples of what `groupby` can take as an input." - ] - }, - { - "cell_type": "markdown", - "id": "9719db5b-e645-4815-b8df-d454fa7703e7", - "metadata": { - "execution": {} - }, - "source": [ - "Let's start by loading the same data that we used in the previous tutorial (monthly SST data from CESM2):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7837f8bd-da89-4718-ab02-d5107576d2d6", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 388, - "status": "ok", - "timestamp": 1681573026385, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath = DATASETS.fetch(\"CESM2_sst_data.nc\")\n", - "ds = xr.open_dataset(filepath)\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "713cc8d8-7374-4c5b-be61-aec4b5b0ffe6", - "metadata": { - "execution": {} - }, - "source": [ - "Then, let's select a gridpoint closest to a specified lat-lon (in this case let's select 50ºN, 310ºE), and plot a time series of SST at that point (recall that we learned this is Tutorial 2). The annual cycle will be quite pronounced. Note that we are using the `nearest` method (see Tutorial 2 for a refresher) to find the points in our datasets closest to the lat-lon values we specify. What this returns may not match these inputs exactly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c0348ee8-6e9b-4f50-a844-375ae00d2771", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 959, - "status": "ok", - "timestamp": 1681573031714, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.sel(\n", - " lon=310, lat=50, method=\"nearest\"\n", - ").plot() # time range is 2000-01-15 to 2014-12-15" - ] - }, - { - "cell_type": "markdown", - "id": "e732cd9b", - "metadata": { - "execution": {} - }, - "source": [ - "This plot is showing changes in monthly SST between 2000-01-15 to 2014-12-15. The annual cycle of SST change is apparent in this figure, but to understand the climatatology of this region, we need to calculate the average SST for each month over this time period. The first step is to split the data into groups based on month." - ] - }, - { - "cell_type": "markdown", - "id": "d1505625-cbcd-495b-a15f-8824e455415b", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Split\n", - "\n", - "Let's group data by month, i.e. all Januaries in one group, all Februaries in one group, etc.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6e4fb25e-165f-4350-a93d-46a344f2d175", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 160, - "status": "ok", - "timestamp": 1681572674597, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.groupby(ds.time.dt.month)" - ] - }, - { - "cell_type": "markdown", - "id": "5d176ad8-15f1-4ecc-ab3e-898cef3b4e18", - "metadata": { - "execution": {} - }, - "source": [ - "
\n", - "\n", - "In the above code, we are using the `.dt` [`DatetimeAccessor`](https://xarray.pydata.org/en/stable/generated/xarray.core.accessor_dt.DatetimeAccessor.html) to extract specific components of dates/times in our time coordinate dimension. For example, we can extract the year with `ds.time.dt.year`. See also the equivalent [Pandas documentation](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.dt.html).\n", - " \n", - "
" - ] - }, - { - "cell_type": "markdown", - "id": "ad273652-178c-4eda-80b6-6d39a11d6f1e", - "metadata": { - "execution": {} - }, - "source": [ - "Xarray also offers a more concise syntax when the variable you’re grouping on is already present in the dataset. This is identical to `ds.tos.groupby(ds.time.dt.month)`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c6990393-fb5f-4a10-b8e2-fd9c6917d9d2", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 215, - "status": "ok", - "timestamp": 1681572677175, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds.tos.groupby(\"time.month\")" - ] - }, - { - "cell_type": "markdown", - "id": "6b85dbf7-daf1-4889-8b3b-6991d290969f", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "## Section 1.2: Apply & Combine\n", - "\n", - "Now that we have groups defined, it’s time to “apply” a calculation to the group. These calculations can either be:\n", - "\n", - "- aggregation: reduces the size of the group\n", - "- transformation: preserves the group’s full size\n", - "\n", - "At then end of the apply step, xarray will automatically combine the aggregated/transformed groups back into a single object. \n", - "\n", - "\n", - "\n", - "### Section 1.2.1: Compute the Climatology\n", - "\n", - "\n", - "Let's calculate the climatology at every point in the dataset. To do so, we will use aggregation and will calculate the mean SST for each month:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7e568c2f-7143-4346-85ce-a430db03316e", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2695, - "status": "ok", - "timestamp": 1681572682188, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "tos_clim = ds.tos.groupby(\"time.month\").mean()\n", - "tos_clim" - ] - }, - { - "cell_type": "markdown", - "id": "2ef90862-aeb4-45b3-87fb-e9df8f197c81", - "metadata": { - "execution": {} - }, - "source": [ - "For every spatial coordinate, we now have a monthly mean SST for the time period 2000-01-15 to 2014-12-15.\n", - "\n", - "We can now plot the climatology at a specific point:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f908c377-67fa-449c-b8d1-82ba6a14baff", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 363, - "status": "ok", - "timestamp": 1681572685495, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "tos_clim.sel(lon=310, lat=50, method=\"nearest\").plot()" - ] - }, - { - "cell_type": "markdown", - "id": "f91dc01d", - "metadata": { - "execution": {} - }, - "source": [ - "Based on this plot, the climatology of this location is defined by cooler SST from December to April and warmer SST from June to October, with an annual SST range of ~8ºC. " - ] - }, - { - "cell_type": "markdown", - "id": "3d71dab2-5e20-40f6-af5e-8e446c387803", - "metadata": { - "execution": {} - }, - "source": [ - "#### Questions 1.2.1: Climate Connection\n", - "\n", - "1. Considering the latitude and longitude of this data, can you explain why we observe this climatology?\n", - "2. How do you think seasonal variations in SST would differ at the equator? What about at the poles? What about at 50ºS?" - ] - }, - { - "cell_type": "markdown", - "id": "d7c540b2-c707-4d51-8cc7-3ea51b8a505f", - "metadata": { - "execution": {} - }, - "source": [ - "### Section 1.2.2: Spatial Variations" - ] - }, - { - "cell_type": "markdown", - "id": "0e5dc34b-99bc-494b-9c04-ed8388ab2e6c", - "metadata": { - "execution": {} - }, - "source": [ - "We can now add a spatial dimension to this plot and look at the zonal mean climatology (the monthly mean SST at different latitudes):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22c61c11-2a48-4c6c-8009-6f20e0101237", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 584, - "status": "ok", - "timestamp": 1681572688734, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "tos_clim.mean(dim=\"lon\").transpose().plot.contourf(levels=12, cmap=\"turbo\")" - ] - }, - { - "cell_type": "markdown", - "id": "3411ebb7-9831-4e52-ab2e-7e4e7a1356ee", - "metadata": { - "execution": {} - }, - "source": [ - "This gives us helpful information about the mean SST for each month, but it's difficult to asses the range of monthly temperatures throughout the year using this plot.\n", - "\n", - "To better represent the range of SST, we can calculate and plot the difference between January and July climatologies:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19a2808b-81f9-40e5-ab31-d63bfce85eae", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1075, - "status": "ok", - "timestamp": 1681572692242, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "(tos_clim.sel(month=1) - tos_clim.sel(month=7)).plot(size=6, robust=True)" - ] - }, - { - "cell_type": "markdown", - "id": "ddf896bb", - "metadata": { - "execution": {} - }, - "source": [ - "#### Questions 1.2.1: Climate Connection\n", - "\n", - "1. What patterns do you observe in this map?\n", - "2. Why is there such an apparent difference between the Northern and Southern Hemisphere SST changes?\n", - "3. How does the migration of the ITCZ relate to seasonal changes in Northern vs. Southern Hemisphere temperatures?" - ] - }, - { - "cell_type": "markdown", - "id": "ee5f2987-d7e3-4b0d-a5ad-abfae5a98072", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we focused on exploring seasonal climatology in global temperature data using the split-apply-combine approach in Xarray. By utilizing the split-apply-combine approach, we gained insights into the seasonal climatology of temperature and precipitation data, enabling us to analyze and understand the seasonal variations associated with global climate patterns.\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "edf206e2-7eac-46b2-9037-dc8ba640a856", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "cell_type": "markdown", - "id": "1950bbe7-82a6-4b85-aa7f-01c29adfcc40", - "metadata": { - "execution": {} - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/computation-masking.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial5", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6.ipynb deleted file mode 100644 index f51d4dcc3..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6.ipynb +++ /dev/null @@ -1,554 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "330b2804", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial6.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "id": "s2ACfZ9jIXrv", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 6: Compute and Plot Temperature Anomalies\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "id": "c130f230-24c5-4ae4-8da8-e4b679e78dff", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "id": "LZmCPoGUjyUv", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "In the previous tutorials, we have explored global climate patterns and processes, focusing on the terrestrial, atmospheric and oceanic climate systems. We have understood that Earth's energy budget, primarily controlled by incoming solar radiation, plays a crucial role in shaping Earth's climate. In addition to these factors, there are other significant long-term climate forcings that can influence global temperatures. To gain insight into these forcings, we need to look into historical temperature data, as it offers a valuable point of comparison for assessing changes in temperature and understanding climatic influences.\n", - "\n", - "Recent and future temperature change is often presented as an anomaly relative to a past climate state or historical period. For example, past and future temperature changes relative to pre-industrial average temperature is a common comparison. \n", - "\n", - "In this tutorial, our objective is to deepen our understanding of these temperature anomalies. We will compute and plot the global temperature anomaly from 2000-01-15 to 2014-12-1, providing us with a clearer perspective on recent climatic changes." - ] - }, - { - "cell_type": "markdown", - "id": "0af7bee1-3de3-453a-8ae8-bcd7910b4266", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06073287-7bdb-45b5-9cec-8cdf123adb49", - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b4cabcfc-2cc0-450a-8e94-4f8e635213c5", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e941ab00-bac3-4fbb-a582-9a73da96b617", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Orbital Cycles\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', 'CdZkSWnfvYs'), ('Bilibili', 'BV1p8411D7ic')]\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, - "id": "a1ac91c8-11f3-4bb0-86ee-8eff1e61187c", - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"tcb2q\"" - ] - }, - { - "cell_type": "markdown", - "id": "266b8130-ca7d-4aec-a9a2-d7281ad64425", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Compute Anomaly\n", - "\n", - "First, let's load the same data that we used in the previous tutorial (monthly SST data from CESM2):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7837f8bd-da89-4718-ab02-d5107576d2d6", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 303, - "status": "ok", - "timestamp": 1681569406112, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath = DATASETS.fetch(\"CESM2_sst_data.nc\")\n", - "ds = xr.open_dataset(filepath)\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "9719db5b-e645-4815-b8df-d454fa7703e7", - "metadata": { - "execution": {} - }, - "source": [ - "We'll compute the climatology using xarray's `groupby` operation to split the SST data by month. Then, we'll remove this climatology from our original data to find the anomaly:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c9940df-5174-49bf-9117-eef1e14abec0", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 303, - "status": "ok", - "timestamp": 1681569588942, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# group all data by month\n", - "gb = ds.tos.groupby(\"time.month\")\n", - "\n", - "# take the mean over time to get monthly averages\n", - "tos_clim = gb.mean(dim=\"time\")\n", - "\n", - "# subtract this mean from all data of the same month\n", - "tos_anom = gb - tos_clim\n", - "tos_anom" - ] - }, - { - "cell_type": "markdown", - "id": "8c5d2ebe", - "metadata": { - "execution": {} - }, - "source": [ - "Let's try plotting the anomaly from a specific location:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "35fc2054-df48-4ea2-8433-632ba8755c61", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 970, - "status": "ok", - "timestamp": 1681569593750, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "tos_anom.sel(lon=310, lat=50, method=\"nearest\").plot()\n", - "plt.ylabel(\"tos anomaly\")" - ] - }, - { - "cell_type": "markdown", - "id": "c3c087dc-966d-48a0-bb99-ca63cf20ff05", - "metadata": { - "execution": {} - }, - "source": [ - "Next, let's compute and visualize the mean global anomaly over time. We need to specify both `lat` and `lon` dimensions in the `dim` argument to `mean()`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5d3abf06-a341-45ac-a3f2-76131016c0b3", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 661, - "status": "ok", - "timestamp": 1681569602365, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "unweighted_mean_global_anom = tos_anom.mean(dim=[\"lat\", \"lon\"])\n", - "unweighted_mean_global_anom.plot()\n", - "plt.ylabel(\"global mean tos anomaly\")" - ] - }, - { - "cell_type": "markdown", - "id": "7c7409af", - "metadata": { - "execution": {} - }, - "source": [ - "Notice that we called our variable `unweighted_mean_global_anom`. Next, we are going to compute the `weighted_mean_global_anom`. Why do we need to weight our data? Grid cells with the same range of degrees latitude and longitude are not necessarily same size. Specifically, grid cells closer to the equator are much larger than those near the poles, as seen in the figure below (Djexplo, 2011, CC-BY). \n", - "\n", - "\"area\n", - "\n", - "\n", - "Therefore, an operation which combines grid cells of different size is not scientifically valid unless each cell is weighted by the size of the grid cell. Xarray has a convenient [`.weighted()`](https://xarray.pydata.org/en/stable/user-guide/computation.html#weighted-array-reductions) method to accomplish this." - ] - }, - { - "cell_type": "markdown", - "id": "908bcc38-bf93-478c-99e4-8bbafeec1f21", - "metadata": { - "execution": {} - }, - "source": [ - "Let's first load the grid cell area data from another CESM2 dataset that contains the weights for the grid cells:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a5878de6-f3ab-43e0-8f0d-12ab51631450", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1450, - "status": "ok", - "timestamp": 1681569607108, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath2 = DATASETS.fetch(\"CESM2_grid_variables.nc\")\n", - "areacello = xr.open_dataset(filepath2).areacello\n", - "areacello" - ] - }, - { - "cell_type": "markdown", - "id": "8a73a748-46b4-4350-b167-32725eebaec8", - "metadata": { - "execution": {} - }, - "source": [ - "Let's calculate area-weighted mean global anomaly:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b8f7e3a5-0748-4395-95b0-0e31d0a5d4d1", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "weighted_mean_global_anom = tos_anom.weighted(\n", - " areacello).mean(dim=[\"lat\", \"lon\"])" - ] - }, - { - "cell_type": "markdown", - "id": "17da2e3a-3ca6-41f4-892e-b26021c492e6", - "metadata": { - "execution": {} - }, - "source": [ - "Let's plot both unweighted and weighted means:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "802c5e99-7223-49b5-a867-91d943075d52", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 985, - "status": "ok", - "timestamp": 1681569614744, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "unweighted_mean_global_anom.plot(size=7)\n", - "weighted_mean_global_anom.plot()\n", - "plt.legend([\"unweighted\", \"weighted\"])\n", - "plt.ylabel(\"global mean tos anomaly\")" - ] - }, - { - "cell_type": "markdown", - "id": "3c399f9f-83ad-403e-a092-75f3f47f0322", - "metadata": { - "execution": {} - }, - "source": [ - "## Questions 1: Climate Connection\n", - "\n", - "1. What is the significance of calculating area-weighted mean global temperature anomalies when assessing climate change? How are the weighted and unweighted SST means similar and different? \n", - "2. What overall trends do you observe in the global SST mean over this time? How does this magnitude and rate of temperature change compare to past temperature variations on longer timescales (refer back to the figures in the video)?\n" - ] - }, - { - "cell_type": "markdown", - "id": "bbbe7478-dd54-4bb1-9e82-226a655a26d0", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we focused on historical temperature changes. We computed and plotted the global temperature anomaly from 2000 to 2014. This helped us enhance our understanding of recent climatic changes and their potential implications for the future.\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "bc61da9e-deed-42b6-9dcc-05864e425a0b", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "cell_type": "markdown", - "id": "76f506e1-74ab-47a3-b0c1-2ed3ed659fdd", - "metadata": { - "execution": {} - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/computation-masking.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial6", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7.ipynb deleted file mode 100644 index a4c11824e..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7.ipynb +++ /dev/null @@ -1,562 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "9735141d", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial7.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "id": "5yJKHFT3Dnmu", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 7: Other Computational Tools in Xarray\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "id": "97bbc2d6-8eae-4e11-94e5-f7320fecd163", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "id": "y8yIi1WBkwHB", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "Thus far, we've learned about various climate processes in the videos, and we've explored tools in Xarray that are useful for analyzing and interpreting climate data. \n", - "\n", - "In this tutorial you'll continue using the SST data from CESM2 and practice using some additional computational tools in Xarray to resample your data, which can help with data comparison and analysis. The functions you will use are:\n", - "\n", - "- `resample`: Groupby-like functionality specifically for time dimensions. Can be used for temporal upsampling and downsampling. Additional information about resampling in Xarray can be found [here](https://xarray.pydata.org/en/stable/user-guide/time-series.html#resampling-and-grouped-operations).\n", - "- `rolling`: Useful for computing aggregations on moving windows of your dataset e.g. computing moving averages. Additional information about resampling in Xarray can be found [here](https://xarray.pydata.org/en/stable/user-guide/computation.html#rolling-window-operations).\n", - "- `coarsen`: Generic functionality for downsampling data. Additional information about resampling in Xarray can be found [here](https://xarray.pydata.org/en/stable/user-guide/computation.html#coarsen-large-arrays)." - ] - }, - { - "cell_type": "markdown", - "id": "0af7bee1-3de3-453a-8ae8-bcd7910b4266", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06073287-7bdb-45b5-9cec-8cdf123adb49", - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5c385e97-285f-45d4-88e2-26ee76b8d039", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2fd1ee75-9e23-4204-a896-9a08da3e794f", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Carbon Cycle and the Greenhouse Effect\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', 'y55CNZbTqw8'), ('Bilibili', 'BV1uV411T7RK')]\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, - "id": "c9027490-8086-41a3-9489-0f164b6375a2", - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-input", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"sb3n5\"" - ] - }, - { - "cell_type": "markdown", - "id": "3045c67e-21cd-4ef9-a49f-e12ae7db23cf", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Section 1: High-level Computation Functionality\n", - "\n", - "In this tutorial you will learn about several methods for dealing with the resolution of data. Here are some links for quick reference, and we will go into detail in each of them in the sections below.\n", - "\n", - "- `resample`: [Groupby-like functionality specifialized for time dimensions. Can be used for temporal upsampling and downsampling](https://xarray.pydata.org/en/stable/user-guide/time-series.html#resampling-and-grouped-operations)\n", - "- `rolling`: [Useful for computing aggregations on moving windows of your dataset e.g. computing moving averages](https://xarray.pydata.org/en/stable/user-guide/computation.html#rolling-window-operations)\n", - "- `coarsen`: [Generic functionality for downsampling data](https://xarray.pydata.org/en/stable/user-guide/computation.html#coarsen-large-arrays)\n", - "\n", - "First, let's load the same data that we used in the previous tutorial (monthly SST data from CESM2):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7837f8bd-da89-4718-ab02-d5107576d2d6", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath = DATASETS.fetch(\"CESM2_sst_data.nc\")\n", - "ds = xr.open_dataset(filepath)\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "eaf4dc7d-dfac-419e-a875-fc0c70fcd08c", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Resampling Data\n", - "\n", - "For upsampling or downsampling temporal resolutions, we can use the `resample()` method in Xarray. For example, you can use this function to downsample a dataset from hourly to 6-hourly resolution.\n", - "\n", - "Our original SST data is monthly resolution. Let's use `resample()` to downsample to annual frequency:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a9cfb76b-c4ab-441e-a474-c66b7af944ad", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 499, - "status": "ok", - "timestamp": 1681569618680, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# resample from a monthly to an annual frequency\n", - "tos_yearly = ds.tos.resample(time=\"AS\")\n", - "tos_yearly" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6927f5be-d313-4d03-bab8-d22b3cb13899", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 312, - "status": "ok", - "timestamp": 1681569621935, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# calculate the global mean of the resampled data\n", - "annual_mean = tos_yearly.mean()\n", - "annual_mean_global = annual_mean.mean(dim=[\"lat\", \"lon\"])\n", - "annual_mean_global.plot()" - ] - }, - { - "cell_type": "markdown", - "id": "a373cb9e", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "## Section 1.2: Moving Average\n", - "\n", - "The `rolling()` method allows for a rolling window aggregation and is applied along one dimension using the name of the dimension as a key (e.g. time) and the window size as the value (e.g. 6). We will use these values in the demonstration below.\n", - "\n", - "Let's use the `rolling()` function to compute a 6-month moving average of our SST data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "342acbf1-4eee-4d0d-bb52-b394ffcd556d", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 791, - "status": "ok", - "timestamp": 1681569626067, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# calculate the running mean\n", - "tos_m_avg = ds.tos.rolling(time=6, center=True).mean()\n", - "tos_m_avg" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0eb0cc4e-661a-4ab1-96ad-e096917ef104", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1333, - "status": "ok", - "timestamp": 1681569630104, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# calculate the global average of the running mean\n", - "tos_m_avg_global = tos_m_avg.mean(dim=[\"lat\", \"lon\"])\n", - "tos_m_avg_global.plot()" - ] - }, - { - "cell_type": "markdown", - "id": "0c719e22", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "## Section 1.3: Coarsening the Data\n", - "\n", - "The `coarsen()` function allows for block aggregation along multiple dimensions. \n", - "\n", - "Let's use the `coarsen()` function to take a block mean for every 4 months and globally (i.e., 180 points along the latitude dimension and 360 points along the longitude dimension). Although we know the dimensions of our data quite well, we will include code that finds the length of the latitude and longitude variables so that it could work for other datasets that had a different format." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "118df2c7", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# coarsen the data\n", - "coarse_data = ds.coarsen(time=4, lat=len(ds.lat), lon=len(ds.lon)).mean()\n", - "coarse_data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f0b9ef33", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "coarse_data.tos.plot()" - ] - }, - { - "cell_type": "markdown", - "id": "6f93092b", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.4: Compare the Resampling Methods\n", - "\n", - "Now that we've tried multiple resampling methods on different temporal resolutions, we can compare the resampled datasets to the original." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1517017a", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "original_global = ds.mean(dim=[\"lat\", \"lon\"])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "daf709a8", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "original_global.tos.plot(size=6)\n", - "coarse_data.tos.plot()\n", - "tos_m_avg_global.plot()\n", - "annual_mean_global.plot()\n", - "\n", - "\n", - "plt.legend(\n", - " [\n", - " \"original data (monthly)\",\n", - " \"coarsened (4 months)\",\n", - " \"moving average (6 months)\",\n", - " \"annually resampled (12 months)\",\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "f1d99f56-adcc-410f-811d-a2a71289513d", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1.4: Climate Connection\n", - "\n", - "1. What type of information can you obtain from each time series?\n", - "2. In what scenarios would you use different temporal resolutions?\n" - ] - }, - { - "cell_type": "markdown", - "id": "c18bb57b-63f2-4f9d-ac8d-32d0231d02fa", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "In this tutorial, we've explored Xarray tools to simplify and understand climate data better. Given the complexity and variability of climate data, tools like `resample`, `rolling`, and `coarsen` come in handy to make the data easier to compare and find long-term trends. You've also looked at valuable techniques like calculating moving averages. \n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "b438a488-b3c7-4f87-90db-2685d44c65fe", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "cell_type": "markdown", - "id": "a0db8d5a-8c2c-4019-96df-c15783b84cd1", - "metadata": { - "execution": {} - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/computation-masking.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial7", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8.ipynb deleted file mode 100644 index 99c040329..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8.ipynb +++ /dev/null @@ -1,494 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f8610814", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial8.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "id": "mVZDbCNcJlom", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 8: Masking with One Condition\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "id": "06c3e74f-762e-42d4-abbc-e3acb0b49cb9", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "id": "tfnrWLSylttw", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "One useful tool for assessing climate data is masking, which allows you to filter elements of a dataset according to a specific condition and create a \"masked array\" in which the elements not fulfilling the condition will not be shown. This tool is helpful if you wish to, for example, only look at data greater or less than a certain value, or from a specific temporal or spatial range. For instance, when analyzing a map of global precipitation, we could mask regions that contain a value of mean annual precipitation above or below a specific value or range of values in order to assess wet and dry seasons. \n", - "\n", - "In this tutorial you will learn how to mask data with one condition, and will apply this to your map of global SST." - ] - }, - { - "cell_type": "markdown", - "id": "0af7bee1-3de3-453a-8ae8-bcd7910b4266", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06073287-7bdb-45b5-9cec-8cdf123adb49", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1691, - "status": "ok", - "timestamp": 1681573592149, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "994efaf1-a38b-42f4-ac31-40b747e6b806", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7bc232cf-a917-49e3-93b9-77afb5fb3f20", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Climate Feedbacks\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', 'cx1DGGOBD74'), ('Bilibili', 'BV1pV411T7h5')]\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, - "id": "bc214dbf-b28f-44c4-bb53-8d8e852610e6", - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"zhb3c\"" - ] - }, - { - "cell_type": "markdown", - "id": "da76db37-e833-42c5-a740-5dcf0877b43c", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Section 1: Masking Data\n" - ] - }, - { - "cell_type": "markdown", - "id": "8a657ca8-fa2d-409c-9aaf-580828671018", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "Using the `xr.where()` or `.where()` method, elements of an xarray Dataset or xarray DataArray that satisfy a given condition or multiple conditions can be replaced/masked. To demonstrate this, we are going to use the `.where()` method on the `tos` DataArray that we've been using in the past few tutorials. " - ] - }, - { - "cell_type": "markdown", - "id": "59a59bef-b08c-4e0f-a48a-894565a962e7", - "metadata": { - "execution": {} - }, - "source": [ - "Let's load the same data that we used in the previous tutorial (monthly SST data from CESM2):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7837f8bd-da89-4718-ab02-d5107576d2d6", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4386, - "status": "ok", - "timestamp": 1681573597967, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath = DATASETS.fetch(\"CESM2_sst_data.nc\")\n", - "ds = xr.open_dataset(filepath)\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "386c7a1b-1a47-4f52-a42d-27fa997427d3", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Using `where` with One Condition" - ] - }, - { - "cell_type": "markdown", - "id": "a8d48b6b-a40e-469f-861f-83d943d70f03", - "metadata": { - "execution": {} - }, - "source": [ - "Let's say we want to analyze SST just from the last time in the dataset (2014-09-15). We can isolate this time using `.isel()`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac3e42eb-1852-4580-9c52-e7237135ed01", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 166, - "status": "ok", - "timestamp": 1681573604936, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "sample = ds.tos.sel(time='2014-09')\n", - "sample" - ] - }, - { - "cell_type": "markdown", - "id": "ccdd1fa6-93fd-490d-8b05-c222ddcf953a", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we have our `DataArray` from the desired time period, we can use another function, `.where()` to filter elements according to a condition. The conditional expression in `.where()` can be a `DataArray`, a `Dataset` or a function. Indexing methods on xarray objects generally return a subset of the original data. However, it is sometimes useful to select an object with the same shape as the original data, but with some elements masked. Unlike `.isel()` and `.sel()` that change the shape of the returned results, `.where()` preserves the shape of the original data. It accomplishes this by returning values from the original `DataArray` or `Dataset` if the `condition` is `True`, and fills in values (by default `nan`) wherever the `condition` is `False`. Additional information can be found in the [`.where()` documentation](http://xarray.pydata.org/en/stable/generated/xarray.DataArray.where.html). \n", - "\n", - "Let's use `.where()` to mask locations with temperature values greater than 0ºC. Note that the condition we supply to `.where()` are the regions we wish to preserve, not those we wish to mask. So if we are interested in masking temperature values that are above 0ºC, we will pass the condition to preserve those that are greater than or equal to 0ºC." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "61abc5b3-aadf-4a96-98a2-c9c36094a863", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 159, - "status": "ok", - "timestamp": 1681573607537, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# preserve temperatures greater than or equal to 0, mask those that are less than 0\n", - "masked_sample = sample.where(sample <= 0.0)\n", - "masked_sample" - ] - }, - { - "cell_type": "markdown", - "id": "09aeeee1-3924-4ccd-9b69-1be396c496b9", - "metadata": { - "execution": {} - }, - "source": [ - "Let's plot both our original sample, and the masked sample for September 15th, 2014. Note we are using a different colorbar for the right hand figure, where the range of values is much smaller, and the same colors on the left would not correspond to the same colors on the right." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eced16af", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "fig, axes = plt.subplots(ncols=2, figsize=(19, 6))\n", - "sample.plot(ax=axes[0])\n", - "masked_sample.plot(ax=axes[1])" - ] - }, - { - "cell_type": "markdown", - "id": "c9183d75-f932-4870-b9d9-7a9b9ce7fd99", - "metadata": { - "execution": {} - }, - "source": [ - "Notice how in the figure on the right, only the SST from the areas where SST is below 0ºC is shown and the other areas are white since these are now NaN values. Now let's assess how polar SST has changed over the time period recorded by the original dataset. To do so, we can run the same code but focus on the time 2000-09-15." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ca1e150f-c422-4f0c-8f64-9c734bcbdee3", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "sample_2 = ds.tos.sel(time=\"2000-09\")\n", - "masked_sample_2 = sample_2.where(sample_2 < 0.0)\n", - "fig, axes = plt.subplots(ncols=2, figsize=(19, 6))\n", - "masked_sample_2.plot(ax=axes[0])\n", - "masked_sample.plot(ax=axes[1])" - ] - }, - { - "cell_type": "markdown", - "id": "c60366bb-523c-4bf1-ad2d-3d8facc38b97", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1.1: Climate Connection\n", - "\n", - "1. What is the purpose of masking in the analysis of climate data?\n", - "2. Within the areas that are not masked, how does the distribution of SST compare between these maps?\n", - "3. The minimum sea ice extent in the Arctic typically occurs annually in September after spring has brought in more sunlight and warmer temperatures. Considering both plots of September SST above (from 2000 on the left and 2014 on the right), how might changes in the ice-albedo feedback be playing a role in what you observe? Please state any assumptions you would make in your answer." - ] - }, - { - "cell_type": "markdown", - "id": "4ce1373d-e4fc-437e-a445-13dd8fa5f22f", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we've explored the application of masking tools in the analysis of Sea Surface Temperature (SST) maps. Through masking, we've been able to focus our attention on areas where the SST is below 0°C. These are the regions where changes in the ice-albedo feedback mechanism are most evident in our present day. This has facilitated a more targeted analysis and clearer understanding of the data.\n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "2abd55dc-f7ee-4a32-8de6-c955ba3c1929", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "cell_type": "markdown", - "id": "4ce9e503-986e-4784-a522-631150e01fb2", - "metadata": { - "execution": {} - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/computation-masking.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial8", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9.ipynb b/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9.ipynb deleted file mode 100644 index 39f2a3ec2..000000000 --- a/book/_build/html/_sources/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9.ipynb +++ /dev/null @@ -1,528 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "8fdce2ee", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D1_ClimateSystemOverview/W1D1_Tutorial9.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "id": "GJtN30QLJnet", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 9: Masking with Multiple Conditions\n", - "\n", - "**Week 1, Day 1, Climate System Overview**\n", - "\n", - "**Content creators:** Sloane Garelick, Julia Kent\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "id": "8b65d43f-6bcb-443c-ba90-95749702309d", - "metadata": { - "execution": {} - }, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "id": "0KwcJyrEmsww", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In the previous tutorial, you masked data using one condition (areas where SST was above 0ºC). You can also mask data using multiple conditions. For example, you can mask data from regions outside a certain spatial area by providing constraints on the latitude and longitude. \n", - "\n", - "In this tutorial, you will practice masking data using multiple conditions in order to interpret SST in the tropical Pacific Ocean in the context of the El Niño Southern Oscillation (ENSO)." - ] - }, - { - "cell_type": "markdown", - "id": "0af7bee1-3de3-453a-8ae8-bcd7910b4266", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# **Setup**\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "06073287-7bdb-45b5-9cec-8cdf123adb49", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 521, - "status": "ok", - "timestamp": 1681573817272, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import numpy as np\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b389f92a-2998-494d-a58c-f582a91c6b95", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "51f0a30a-35f7-4b29-a1d6-5d242f6aefa7", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Past, Present, and Future Climate\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', 'I9X4XymeO4A'), ('Bilibili', 'BV1QF411X7rg')]\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, - "id": "af18aad1-ddc6-404c-bf27-978471fe2b70", - "metadata": { - "cellView": "form", - "execution": {}, - "pycharm": { - "name": "#%%\n" - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"dtgax\"" - ] - }, - { - "cell_type": "markdown", - "id": "4dd6b000-b079-461c-9a0e-8fd2bced814b", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Section 1: Using `.where()` with multiple conditions" - ] - }, - { - "cell_type": "markdown", - "id": "9719db5b-e645-4815-b8df-d454fa7703e7", - "metadata": { - "execution": {} - }, - "source": [ - "First, let's load the same data that we used in the previous tutorial (monthly SST data from CESM2):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7837f8bd-da89-4718-ab02-d5107576d2d6", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4331, - "status": "ok", - "timestamp": 1681573823172, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filepath = DATASETS.fetch(\"CESM2_sst_data.nc\")\n", - "ds = xr.open_dataset(filepath)\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "id": "538bd497-3059-4f6e-9c48-5104958f8528", - "metadata": { - "execution": {} - }, - "source": [ - "`.where()` allows us to mask using multiple conditions. To do this, we need to make sure each conditional expression is enclosed in `()`. To combine conditions, we use the `bit-wise and` (`&`) operator and/or the `bit-wise or` (`|`). Let's use `.where()` to isolate locations with temperature values **greater than 25 and less than 30**:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c9bf1c46-e7ed-43c1-8a45-e03d22295da1", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 624, - "status": "ok", - "timestamp": 1681573874480, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# take the last time step as our data\n", - "sample = ds.tos.isel(time=-1)\n", - "\n", - "# just keep data between 25-30 C\n", - "sample.where((sample > 25) & (sample < 30)).plot(size=6)" - ] - }, - { - "cell_type": "markdown", - "id": "e1047138", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Using `.where()` with a Custom Fill Value**" - ] - }, - { - "cell_type": "markdown", - "id": "74960d46", - "metadata": { - "execution": {} - }, - "source": [ - "`.where()` can take a second argument, which, if supplied, defines a fill value for the masked region. Below we fill masked regions with a constant `0`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "505bbd2d", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "sample.where((sample > 25) & (sample < 30), 0).plot(size=6)" - ] - }, - { - "cell_type": "markdown", - "id": "d016a386", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: Using `.where()` with Specific Coordinates**" - ] - }, - { - "cell_type": "markdown", - "id": "d1796fc8-039b-4c40-a6f4-b3a00c130770", - "metadata": { - "execution": {} - }, - "source": [ - "We can use coordinates to apply a mask as well. For example, we can use a mask to assess tropical Pacific SST associated with the El Niño Southern Oscillation (ENSO). As we learned in the video, ENSO is a climate phenomena that originates in the tropical Pacific ocean but has global impacts on atmospheric circulation, temperature and precipitation. The two phases of ENSO are El Niño (warmer than average SSTs in the central and eastern tropical Pacific Ocean) and La Niña (cooler than average SSTs in the central and eastern tropical Pacific Ocean). The Niño 3.4 region is an area in the centeral and eastern Pacific Ocean that is often used for determining the phase of ENSO. Below, we will use the `latitude` and `longitude` coordinates to mask everywhere outside of the [Niño 3.4 region](https://www.ncdc.noaa.gov/teleconnections/enso/indicators/sst/). Note in our data that we are in degrees East, so the values we input for `longitude` will be shifted compared to the figure below.\n", - "\n", - "![](https://www.ncdc.noaa.gov/monitoring-content/teleconnections/nino-regions.gif)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "090f1997-8dea-4eed-aa55-ab3a180ecdd5", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 728, - "status": "ok", - "timestamp": 1681573881072, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# input the conditions for the latitude and longitude values we wish to preserve\n", - "sample.where(\n", - " (sample.lat < 5) & (sample.lat > -5) & (sample.lon > 190) & (sample.lon < 240)\n", - ").plot(size=6)" - ] - }, - { - "cell_type": "markdown", - "id": "b3dab758", - "metadata": { - "execution": {} - }, - "source": [ - "Now let's look at a time series of the data from this masked region. Rather than specifying a certain time period, we can mask all areas outside of the Niño 3.4 region and then take the spatial mean to assess changes in Niño 3.4 SST over this time period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "aae12476-4802-42a2-993b-29da6c383535", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 567, - "status": "ok", - "timestamp": 1681573884614, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "nino = ds.tos.where(\n", - " (sample.lat < 5) & (sample.lat > -5) & (sample.lon > 190) & (sample.lon < 240)\n", - ")\n", - "\n", - "nino_mean = ds.tos.mean(dim=[\"lat\", \"lon\"])\n", - "nino_mean" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c12ef69c-b730-486c-9300-286cc2e338ae", - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "nino_mean.plot()" - ] - }, - { - "cell_type": "markdown", - "id": "4ee8f111-7662-496b-8493-7b08f9bfee2d", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 3: Climate Connection**" - ] - }, - { - "cell_type": "markdown", - "id": "c2468980", - "metadata": { - "execution": {} - }, - "source": [ - "1. What patterns (e.g. cycles, trends) do you observe in this SST time series for the Niño 3.4 region?\n", - "2. What do you think might be responsible for the patterns you observe? What about any trends?\n", - "3. Notice that we did not use a weighted mean. Do you think the results would be very different if we did weight the mean?" - ] - }, - { - "cell_type": "markdown", - "id": "5f6c15ba-b7d3-4ef9-a100-44057a2cefce", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "- Similar to NumPy, arithmetic operations are vectorized over a DataArray\n", - "- Xarray provides aggregation methods like `sum()` and `mean()`, with the option to specify which dimension over which the operation will be done\n", - "- `groupby` enables the convenient split-apply-combine workflow\n", - "- The `.where()` method allows for filtering or replacing of data based on one or more provided conditions" - ] - }, - { - "cell_type": "markdown", - "id": "2f1d8229-d6c0-49ac-bc34-06949ef71c3f", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**" - ] - }, - { - "cell_type": "markdown", - "id": "8b7b578b-11fd-4cfa-b430-6f019194b73a", - "metadata": { - "execution": {} - }, - "source": [ - "Code and data for this tutorial is based on existing content from [Project Pythia](https://foundations.projectpythia.org/core/xarray/computation-masking.html)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D1_Tutorial9", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title.md b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title.md deleted file mode 100644 index dd328b4ec..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# State of the Climate Ocean and Atmosphere Reanalysis - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading.md b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading.md deleted file mode 100644 index 5cc3b4edc..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading.md +++ /dev/null @@ -1,7 +0,0 @@ -# Suggested Further Reading - -- https://www.usgs.gov/programs/climate-research-and-development-program/science/paleoclimate-research -- http://www.met.reading.ac.uk/~gf905417/Publications_files/Ferrari_Ferreira_11.pdf -- https://agupubs.onlinelibrary.wiley.com/doi/epdf/10.1002/2016GL072475 -- https://www.nature.com/articles/s41467-020-18203-3 -- https://www.ncei.noaa.gov/access/ocean-carbon-acidification-data-system/oceans/ndp_108/ndp108.html diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary.ipynb deleted file mode 100644 index 7fa4f9840..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary.ipynb +++ /dev/null @@ -1,41 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "56915a50", - "metadata": {}, - "source": [ - "# Day Summary" - ] - }, - { - "cell_type": "markdown", - "id": "e96747c7", - "metadata": {}, - "source": [ - "Day 2 explored the complex interplay between the ocean and atmosphere within the climate system. You began the day with an exploration of SST variations during El Niño and La Niña events, utilizing Xarray tools and the CESM2 model data. You then worked with reanalysis data to explore the large-scale circulation of the ocean and atmosphere, and the changes in ocean heat storage over recent decades.\n" - ] - } - ], - "metadata": { - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro.ipynb deleted file mode 100644 index 9f9620a39..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro.ipynb +++ /dev/null @@ -1,145 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "59432924", - "metadata": {}, - "source": [ - "# Intro" - ] - }, - { - "cell_type": "markdown", - "id": "48f480d7", - "metadata": {}, - "source": [ - "## Overview" - ] - }, - { - "cell_type": "markdown", - "id": "9b1a8906", - "metadata": {}, - "source": [ - "Welcome to the second day of the Computational Tools for Climate Science course! Today we dive into scientific exploration of the modern ocean and atmosphere systems using reanalysis datasets, building on yesterday’s climate system overview. \n", - "\n", - "In the course of today's study, you will leverage computational tools and datasets such as Xarray, climate models (CESM2), and reanalysis dataset (ERA5), to explore the large-scale properties of the ocean and atmosphere, and their interactions. You will start by diagnosing anomalies of sea surface temperature (SST), their relation to El Niño and La Niña events, and their influence on global atmospheric circulation patterns and ocean dynamics. You will then examine how large-scale ocean currents are driven by both atmospheric flow (wind-driven circulation) and ocean density variations (thermohaline circulation). Finally, you will investigate how the heat stored within different layers of the ocean has changed over recent decades, and the consequent impacts on Earth's climate system. \n", - "\n", - "Throughout Day 2, you will learn about large-scale ocean and atmospheric circulation, and develop familiarity with computational tools for the analysis and interpretation of complex climate data. \n" - ] - }, - { - "cell_type": "markdown", - "id": "a79a31b2", - "metadata": {}, - "source": [ - "## Video 1: Oceans in Climate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bcd030a6", - "metadata": { - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @markdown\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', '6lqkFuLI0ms'), ('Bilibili', 'BV1Bh4y1Z7DK')]\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": "markdown", - "id": "8249df54", - "metadata": {}, - "source": [ - "## Slides" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "19237add", - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @markdown\n", - "from IPython.display import IFrame\n", - "link_id = \"2pxs6\"" - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro.ipynb deleted file mode 100644 index f4b1b1056..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro.ipynb +++ /dev/null @@ -1,41 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "59931dc6", - "metadata": {}, - "source": [ - "# Outro" - ] - }, - { - "cell_type": "markdown", - "id": "958dea05", - "metadata": {}, - "source": [ - "Today you have navigated through the large-scale structure of oceanic and atmospheric systems, utilizing reanalysis data and various computational tools to analyze and interpret ocean-atmospheric interactions. Tomorrow, you will transition your focus to remote sensing for climate applications, where you will also begin to explore the land system in addition to the ocean and atmosphere. " - ] - } - ], - "metadata": { - "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.10.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1.ipynb deleted file mode 100644 index c01b79a8c..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1.ipynb +++ /dev/null @@ -1,868 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/W1D2_Tutorial1.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Tutorial 1: Calculating ENSO with Xarray\n", - "\n", - "\n", - "**Week 1, Day 2, Ocean-Atmosphere Reanalysis**\n", - "\n", - "**Content creators:** Abigail Bodner, Momme Hell, Aurora Basinski\n", - "\n", - "**Content reviewers:** Yosemley Bermúdez, Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## ![project pythia](https://projectpythia.org/_static/images/logos/pythia_logo-blue-rtext.svg)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n", - "## ![CMIP.png](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/Art/CMIP.png?raw=true)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In this notebook (adapted from [Project Pythia](https://foundations.projectpythia.org/core/xarray/enso-xarray.html)), you will practice using multiple tools to examine sea surface temperature (SST) and explore variations in the climate system that occur during El Nino and La Nina events. You will learn to:\n", - "\n", - "1. Load Sea Surface Temprature data from the CESM2 model\n", - "2. Mask data using `.where()`\n", - "3. Compute climatologies and anomalies using `.groupby()`\n", - "4. Use `.rolling()` to compute moving average\n", - "5. Compute, normalize, and plot the Oceanic Niño Index\n", - "\n", - "After completing the tasks above, you should be able to plot [Oceanic Niño Index](https://climatedataguide.ucar.edu/climate-data/nino-sst-indices-nino-12-3-34-4-oni-and-tni) that looks similar to the figure below. The red and blue regions correspond to the phases of El Niño and La Niña respectively.\n", - "\n", - "![ONI index plot from NCAR Climate Data Guide](https://climatedataguide.ucar.edu/sites/default/files/styles/extra_large/public/2022-03/indices_oni_2_2_lg.png)\n", - "\n", - "Credit: [NCAR](https://climatedataguide.ucar.edu/sites/default/files/styles/extra_large/public/2022-03/indices_oni_2_2_lg.png)\n", - "\n", - "Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# !pip install pythia_datasets\n", - "# !pip install cartopy\n", - "# !pip install geoviews" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import cartopy.crs as ccrs\n", - "import matplotlib.pyplot as plt\n", - "import xarray as xr\n", - "from pythia_datasets import DATASETS\n", - "import cartopy.io.shapereader as shapereader\n", - "import pandas as pd\n", - "import matplotlib.dates as mdates\n", - "import geoviews as gv\n", - "import geoviews.feature as gf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: El Niño Southern Oscillation\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', 'pkvy9KJUAsA'), ('Bilibili', 'BV1p94y1B7d1')]\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-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"t65v8\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Introduction to El Niño Southern Oscillation (ENSO)\n", - "In W1D1 you practiced using `Xarray` to calculate a monthly climatology, climate anomalies, and a running average on monthly global Sea Surface Temperature (SST) data from the Community Earth System Model v2 (CESM2). You also used the `.where()` method to isolate SST data between **5ºN-5ºS and 190ºE-240ºE (or 170ºW-120ºW)**. This geographic region, known as the **Niño 3.4 region**, is in the tropical Pacific Ocean and is commonly used as a metric for determining the phase of the El Niño-Southern Oscillation (ENSO). ENSO is a recurring climate pattern involving changes in SST in the central and eastern tropical Pacific Ocean, which has two alternating phases:\n", - "\n", - "* **El Niño:** the phase of ENSO characterized by warmer than average SSTs in the central and eastern tropical Pacific Ocean, weakened east to west equatorial winds and increased rainfall in the eastern tropical Pacific. \n", - "* **La Niña:** the phase of ENSO which is characterized by cooler than average SSTs in the central and eastern tropical Pacific Ocean, stronger east to west equatorial winds and decreased rainfall in the eastern tropical Pacific.\n", - "\n", - "## Section 1.1: Tropical Pacific Climate Processes\n", - "To better understand the climate system processes that result in El Niño and La Niña events, let's first consider typical climate conditions in the tropical Pacific Ocean. Recall from W1D1, **trade winds** are winds that blow east to west just north and south of the equator (these are sometimes referred to as \"easterly\" winds since the winds are originating from the east and blowing toward the west). And as we discussed yesterday, the reason that the trade winds blow from east to west is related to Earth's rotation, which causes the winds in the Northern Hemisphere to curve to the right and winds in the Southern Hemisphere to curve to the left. This is known as the **Coriolis effect**. \n", - "\n", - "If Earth's rotation affects air movement, do you think it also influences surface ocean water movement? It does! As trade winds blow across the tropical Pacific Ocean, they move water because of friction at the ocean surface. But because of the Coriolis effect, surface water moves to the right of the wind direction in the Northern Hemisphere and to the left of the wind direction in the Southern Hemisphere. However, the speed and direction of water movement changes with depth. Ocean surface water moves at an angle to the wind, and the water under the surface water moves at a slightly larger angle, and the water below that turns at an even larger angle. The average direction of all this turning water is about a right angle from the wind direction. This average is known as **Ekman transport**. Since this process is driven by the trade winds, the strength of this ocean water transport varies in response to changes in the strength of the trade winds. \n", - "\n", - "\n", - "## Section 1.2: Ocean-Atmosphere Interactions During El Niño and La Niña\n", - "So, how does all of this relate to El Niño and La Niña? Changes in the strength of Pacific Ocean trade winds and the resulting impact on Ekman transport create variations in the tropical Pacific Ocean SST, which further results in changes to atmospheric circulation patterns and rainfall.\n", - "\n", - "During an El Niño event, ***easterly trade winds are weaker***. As a result, less warm surface water is transported to the west via Ekman transport, which causes a build-up of warm surface water in the eastern equatorial Pacific. This creates warmer than average SSTs in the eastern equatorial Pacific Ocean. The atmosphere responds to this warming with increased rising air motion and above-average rainfall in the eastern Pacific. In contrast, during a La Niña event, ***easterly trade winds are stronger***. As a result, more warm surface water is transported to the west via Ekman transport, and cool water from deeper in the ocean rises up in the eastern Pacific during a process known as upwelling. This creates cooler than average SSTs in the eastern equatorial Pacific Ocean. This cooling decreases rising air movement in the eastern Pacific, resulting in drier than average conditions. \n", - "\n", - "\n", - "In this tutorial, we'll examine SST temperatures to explore variations in the climate system that occur during El Niño and La Niña events. Specifically, we will plot and interpret CESM2 SST data from the Niño 3.4 region." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Calculate the Oceanic Niño Index" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this notebook, we are going to combine several topics and methods you've covered so far to compute the [Oceanic Niño Index](https://climatedataguide.ucar.edu/climate-data/nino-sst-indices-nino-12-3-34-4-oni-and-tni) using SST from the CESM2 submission to the [CMIP6 project](https://esgf-node.llnl.gov/projects/cmip6/). \n", - "\n", - "You will be working with CMIP6 data later in the week, particularly during W2D1. You can also learn more about CMIP, including additional methods to access CMIP data, please see our [CMIP Resource Bank](https://github.com/ClimateMatchAcademy/course-content/blob/main/tutorials/CMIP/CMIP_resource_bank.md) and the [CMIP website](https://wcrp-cmip.org/).\n", - "\n", - "To calculate the Oceanic Niño Index you will:\n", - "\n", - " 1. Select SST data from Niño 3.4 region of 5ºN-5ºS and 190ºE-240ºE (or 170ºW-120ºW) shown in the figure below.\n", - " \n", - " ![](https://www.ncdc.noaa.gov/monitoring-content/teleconnections/nino-regions.gif)\n", - " \n", - " 2. Compute the climatology (here from 2000-2014) for the Niño 3.4 region.\n", - " 3. Compute the monthly anomaly for the Niño 3.4 region.\n", - " 4. Compute the area-weighted mean of the anomalies for the Niño 3.4 region to obtain a time series.\n", - " 4. Smooth the time series of anomalies with a 3-month running mean.\n", - " \n", - "Here we will briefly move through each of these steps, and tomorrow you will learn about them in more detail." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.1: Open the SST Data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "First, open the SST and areacello datasets, and use Xarray's `merge` method to combine them into a single dataset:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5921, - "status": "ok", - "timestamp": 1682537726774, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# retrive (fetch) the SST data we are going to be working on\n", - "SST_path = DATASETS.fetch(\"CESM2_sst_data.nc\")\n", - "\n", - "# open the file we acquired with xarray\n", - "SST_data = xr.open_dataset(SST_path)\n", - "\n", - "# remember that one degree spatial cell is not constant around the globe, each is a different size in square km.\n", - "# we need to account for this when taking averages for example\n", - "\n", - "# fetch the weight for each grid cell\n", - "gridvars_path = DATASETS.fetch(\"CESM2_grid_variables.nc\")\n", - "\n", - "# open and save only the gridcell weights whose variable name is 'areacello'\n", - "# here the 'o' at the end refers to the area cells of the 'ocean' grid\n", - "areacello_data = xr.open_dataset(gridvars_path).areacello\n", - "\n", - "# merge the SST and weights into one easy to use dataset - ds stands for dataset\n", - "ds_SST = xr.merge([SST_data, areacello_data])\n", - "ds_SST" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Visualize the first time point in the early 2000s. You can check this on the indexes of the variable 'time' from the ds_SST above. Note that using the `plot` function of our dataarray will automatically include this as a title when we select just the first time index." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5137, - "status": "ok", - "timestamp": 1682537741323, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# define the plot size\n", - "fig = plt.figure(figsize=(12, 6))\n", - "\n", - "# asssign axis and define the projection - for a round plot\n", - "ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))\n", - "\n", - "# add coastlines - this will issue a download warning but that is ok\n", - "ax.coastlines()\n", - "\n", - "# add gridlines (lon and lat)\n", - "ax.gridlines()\n", - "\n", - "# plots the first time index (0) of SST (variable name 'tos') at the first time\n", - "ds_SST.tos.isel(time=0).plot(\n", - " ax=ax,\n", - " transform=ccrs.PlateCarree(), # give our axis a map projection\n", - " vmin=-2,\n", - " vmax=30, # define the temp range of the colorbarfrom -2 to 30C\n", - " cmap=\"coolwarm\", # choose a colormap\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Interactive Demo 2.1" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You can visualize what the next few times look like in the model by using the interactive sliderbar below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# a bit more complicated code that allows interactive plots\n", - "gv.extension(\"bokeh\") # load Bokeh\n", - "dataset_plot = gv.Dataset(\n", - " ds_SST.isel(time=slice(0, 10))\n", - ") # slice only the first 10 timepoint, as it is a time consuming task\n", - "images = dataset_plot.to(gv.Image, [\"longitude\", \"latitude\"], \"tos\", \"time\")\n", - "images.opts(\n", - " cmap=\"coolwarm\",\n", - " colorbar=True,\n", - " width=600,\n", - " height=400,\n", - " projection=ccrs.Robinson(),\n", - " clabel=\"Sea Surface Temperature [˚C]\",\n", - ") * gf.coastline" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.2: Select the Niño 3.4 Region\n", - "\n", - "You may have noticed that the `lon` for the SST data is organized between 0°–360°E." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ds_SST.lon" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This is different from how we typically use `longitude` (-180°–180°). How do we covert the value of longitude between two systems (0-360° v.s. -180°–180°)?\n", - "\n", - "Let's use `lon2` refer to the longitude system of `0°-360°` while `lon` refers to the system of `-180°–180°`. `0°-360°` is equivalent to `0–180°, -180°–0°`.\n", - "\n", - "In other words, `lon2=181°` is same as `lon=-179°`. Hence, in the western hemisphere, `lon2=lon+360`.\n", - "\n", - "Therefore, the Niño 3.4 region should be (-5°–5°, 190–240°) using the `lon2` system.\n", - "\n", - "Now that we have identified the longitude values we need to select, there are a couple ways to select the Niño 3.4 region. We will demonstrate how to use both below.\n", - "\n", - "1. `sel()`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 842, - "status": "ok", - "timestamp": 1682539230855, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# select just the Nino 3.4 region (note our longitude values are in degrees east) by slicing\n", - "tos_nino34_op1 = ds_SST.sel(lat=slice(-5, 5), lon=slice(190, 240))\n", - "tos_nino34_op1" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "2. Use `where()` and select all values within the bounds of interest" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 492, - "status": "ok", - "timestamp": 1682539239230, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# select just the Nino 3.4 region (note our longitude values are in degrees east) by boolean conditioning\n", - "tos_nino34_op2 = ds_SST.where(\n", - " (ds_SST.lat < 5) & (ds_SST.lat > -5) & (ds_SST.lon > 190) & (ds_SST.lon < 240),\n", - " drop=True,\n", - ") # use dataset where function. use boolean commands\n", - "tos_nino34_op2" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You can verify that `tos_nino34_op1` and `tos_nino34_op2` are the same by comparing the lat and lon indexes.\n", - "\n", - "We only need one of these, so let us choose the second option and set that to the variable we will use moving forward." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# SST in just the Nino 3.4 region\n", - "tos_nino34 = tos_nino34_op2" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's utilize the same code we used to plot the entire Earth, but this time focusing on the Niño 3.4 region slice only." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 797, - "status": "ok", - "timestamp": 1682539250576, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# define the figure size\n", - "fig = plt.figure(figsize=(12, 6))\n", - "\n", - "# assign axis and projection\n", - "ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))\n", - "\n", - "# add coastlines\n", - "ax.coastlines()\n", - "\n", - "# add gridlines (lon and lat)\n", - "ax.gridlines()\n", - "\n", - "# plot as above\n", - "tos_nino34.tos.isel(time=0).plot(\n", - " ax=ax, transform=ccrs.PlateCarree(), vmin=-2, vmax=30, cmap=\"coolwarm\"\n", - ")\n", - "\n", - "# make sure we see more areas of the earth and not only the square around Niño 3.4\n", - "ax.set_extent((120, 300, 10, -10))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.3: Compute the Climatology and Anomalies\n", - "\n", - "Now that we have selected our area, we can compute the monthly anomaly by first grouping all the data by month, then substracting the monthly climatology from each month." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# group the dataset by month\n", - "tos_nino34_mon = tos_nino34.tos.groupby(\"time.month\")\n", - "\n", - "# find the monthly climatology in the Nino 3.4 region\n", - "tos_nino34_clim = tos_nino34_mon.mean(dim=\"time\")\n", - "\n", - "# find the monthly anomaly in the Nino 3.4 region\n", - "tos_nino34_anom = tos_nino34_mon - tos_nino34_clim\n", - "\n", - "# take the area weighted average of anomalies in the Nino 3.4 region\n", - "tos_nino34_anom_mean = tos_nino34_anom.weighted(tos_nino34.areacello).mean(\n", - " dim=[\"lat\", \"lon\"]\n", - ")\n", - "tos_nino34_anom_mean" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.4: Smooth the Anomaly Time Series" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "ENSO occurs on interannual timescales (a few years or more). To isolate the variability of this longer-term phenomenon on the Niño 3.4 region, we can smooth out the fluctuations due to variability on shorter timescales. To achieve this, we will apply a 3-month running mean to our time series of SST anomalies." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# smooth using a centered 3 month running mean\n", - "oni_index = tos_nino34_anom_mean.rolling(time=3, center=True).mean()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 975, - "status": "ok", - "timestamp": 1682539376867, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# define the plot size\n", - "fig = plt.figure(figsize=(12, 6))\n", - "\n", - "# assign axis\n", - "ax = plt.axes()\n", - "\n", - "# plot the monhtly data on the assigned axis\n", - "tos_nino34_anom_mean.plot(ax=ax)\n", - "\n", - "# plot the smoothed data on the assigned axis\n", - "oni_index.plot(ax=ax)\n", - "\n", - "# add legend\n", - "ax.legend([\"monthly\", \"3-month running mean\"])\n", - "\n", - "# add ylabel\n", - "ax.set_ylabel(\"temprature anomalies\")\n", - "\n", - "# add xlabel\n", - "ax.set_xlabel(\"Year\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 3: Identify El Niño and La Niña Events" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We will highlight values in excess of $\\pm$0.5, roughly corresponding to El Niño (warm) and La Niña (cold) events." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1326, - "status": "ok", - "timestamp": 1682539414434, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "fig = plt.figure(figsize=(12, 6)) # assing figure size\n", - "\n", - "plt.fill_between( # plot with color in between\n", - " oni_index.time.data, # x values\n", - " oni_index.where(oni_index >= 0.5).data, # top boundary - y values above 0.5\n", - " 0.5, # bottom boundary - 0.5\n", - " color=\"red\", # color\n", - " alpha=0.9, # transparency value\n", - ")\n", - "plt.fill_between(\n", - " oni_index.time.data,\n", - " oni_index.where(oni_index <= -0.5).data,\n", - " -0.5,\n", - " color=\"blue\",\n", - " alpha=0.9,\n", - ")\n", - "\n", - "oni_index.plot(color=\"black\") # plot the smoothed data\n", - "plt.axhline(0, color=\"black\", lw=0.5) # add a black line at x=0\n", - "plt.axhline(\n", - " 0.5, color=\"black\", linewidth=0.5, linestyle=\"dotted\"\n", - ") # add a black line at x=0.5\n", - "plt.axhline(\n", - " -0.5, color=\"black\", linewidth=0.5, linestyle=\"dotted\"\n", - ") # add a black line at x=-0.5\n", - "plt.title(\"Oceanic Niño Index (ONI)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 3: \n", - "\n", - "Now that we've normalized the data and highlighted SST anomalies that correspond to El Niño (warm) and La Niña (cold) events, consider the following questions:\n", - "\n", - "1. How frequently do El Niño and La Niña events occur over the period of time studied here? \n", - "2. When were the strongest El Niño and La Niña events over this time period? \n", - "3. Considering the ocean-atmosphere interactions that cause El Niño and La Niña events, can you hypothesize potential reasons one El Niño or La Niña event may be stronger than others? \n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, we have learned to utilize a variety of Xarray tools to examine variations in SST during El Niño and La Niña events. We've practiced loading SST data from the CESM2 model, and masking data using the `.where()` function for focused analysis. We have also computed climatologies and anomalies using the `.groupby()` function, and learned to compute moving averages using the `.rolling()` function. Finally, we have calculated, normalized, and plotted the Oceanic Niño Index (ONI), enhancing our understanding of the El Niño Southern Oscillation (ENSO) and its impacts on global climate patterns." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "Data from this tutorial can be accessed [here](https://github.com/ProjectPythia/pythia-datasets)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D2_Tutorial1", - "provenance": [ - { - "file_id": "1WxQZGZjRjPv2YkhwRdEG4PGrU0tHGq9t", - "timestamp": 1680102521421 - } - ], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - }, - "toc-autonumbering": false, - "toc-showcode": false, - "toc-showmarkdowntxt": false, - "toc-showtags": false - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2.ipynb deleted file mode 100644 index 548beb464..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2.ipynb +++ /dev/null @@ -1,778 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/W1D2_Tutorial2.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 2: A Lot of Weather Makes Climate - Exploring the ERA5 Reanalysis**\n", - "\n", - "**Week 1, Day 2, Ocean-Atmosphere Reanalysis**\n", - "\n", - "__Content creators:__ Momme Hell\n", - "\n", - "**Content reviewers:** Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In the previous tutorial, we learned about ENSO, which is a specific atmosphere-ocean dynamical phenomena. You will now examine the atmosphere and the ocean systems more generally.\n", - "\n", - "In this tutorial, you will learn to work with reanalysis data. These data combine observations and models of the Earth system, and are a critical tool for weather and climate science. You will first utilize two methods to access a specific reanalysis dataset (ECMWF's ERA5; through [PO.DAAC](https://podaac.jpl.nasa.gov/) and through the web Copernicus API). You will then select and mask a region of interest, investigating how important climate variables change on medium length timescales (hours to months) within this region.\n", - "\n", - "By the end of this tutorial, you will be able to:\n", - "- Access and select reanalysis data of cliamtically-important variables\n", - "- Plot maps to explore changes on various time scales.\n", - "- Compute and compare timeseries of different variables from reanalysis data." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# !pip install pythia_datasets\n", - "# !pip install cartopy\n", - "# !pip install geoviews" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "both", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "from intake import open_catalog\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib\n", - "import xarray as xr\n", - "import fsspec\n", - "import numpy as np\n", - "\n", - "import boto3\n", - "import botocore\n", - "import datetime\n", - "import numpy as np\n", - "import os\n", - "import pooch\n", - "import tempfile\n", - "import geoviews as gv\n", - "import holoviews\n", - "from geoviews import Dataset as gvDataset\n", - "import geoviews.feature as gf\n", - "from geoviews import Image as gvImage\n", - "\n", - "from cartopy import crs as ccrs\n", - "from cartopy import feature as cfeature\n", - "\n", - "# import warnings\n", - "# # Suppress warnings issued by Cartopy when downloading data files\n", - "# warnings.filterwarnings('ignore')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: ECMWF Reanalysis\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', 'xn_SGxTm6LA'), ('Bilibili', 'BV1g94y1B7Yw')]\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": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: What is Reanalysis Data?\n", - "\n", - "**Reanalysis** refers to the process of combining historical observations from a variety of sources, such as weather stations, satellite measurments, and ocean buoys, with numerical models to create a comprehensive and consistent record of past weather and climate conditions. Reanalysis data is a useful tool to examine the Earth's climate system over a wide range of time scales, from seasonal through decadal to century-scale changes. \n", - "\n", - "There are multiple Earth system reanalysis products (e.g. MERRA-2, NCEP-NCAR, JRA-55C, [see extensive list here](https://climatedataguide.ucar.edu/climate-data/atmospheric-reanalysis-overview-comparison-tables)), and no single product fits all needs. For the purposes of this tutorial you will be using a product from the European Centre for Medium-Range Weather Forecasts (ECMWF) called **ECMWF Reanalysis v5 (ERA5)**. [This video](https://climate.copernicus.eu/climate-reanalysis) from the ECMWF provides you with a brief introduction to the ERA5 product." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Accessing ERA5 Data\n", - "\n", - "You will access the data through the an AWS S3 bucket of the data: [ECMWF ERA5 Reanalysis](https://registry.opendata.aws/ecmwf-era5/). To do this you need the name of the bucket \"era5-pds\", and the file location in the bucket. *Note: you can open the [AWS link](https://registry.opendata.aws/ecmwf-era5/) and find a guided tutorial on how to explore the S3 bucket.*\n", - "\n", - "Let's select a specific year and month to work with, March of 2018:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "era5_bucket = \"era5-pds\"\n", - "client = boto3.client(\n", - " \"s3\", config=botocore.client.Config(signature_version=botocore.UNSIGNED)\n", - ") # initialize aws s3 bucket client\n", - "date_sel = datetime.datetime(\n", - " 2018, 3, 1, 0\n", - ") # select a desired date and hours (midnight is zero)\n", - "prefix = date_sel.strftime(\"%Y/%m/\") # format the date to match the s3 bucket\n", - "metadata_file = \"main.nc\" # filename on the s3 bucket\n", - "metadata_key = prefix + metadata_file # file location and name on the s3 bucket\n", - "filepath = pooch_load(\n", - " filelocation=\"http://s3.amazonaws.com/\" + era5_bucket + \"/\" + metadata_key,\n", - " filename=metadata_file,\n", - ") # open the file\n", - "\n", - "ds_meta = xr.open_dataset(filepath) # open the file\n", - "ds_meta" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You just loaded an `xarray` dataset, as introduced at the first day. This dataset contains 19 variables covering the whole globe (-90 to +90 degrees in latitude, 0 to 360 degrees on longitude) along with their respective coordinates. With this dataset you have access to our best estimates of climate parameters with a temporal resolution of 1 hour and a spatial resolution of 1/4 degree (i.e. grid points near the Equator represent a ~25 km x 25 km region). This is a lot of data, but still just a fraction the data available through the [full ERA5 dataset](https://cds.climate.copernicus.eu/cdsapp#!/dataset/reanalysis-era5-land?tab=overview). \n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.2: Selecting Regions of Interest\n", - "The global ERA5 data over the entire time range is so large that even just one variable would be too large to store on your computer. Here you will apply a method to load a region (i.e., a spatial subset) of the data. In this first example, you will load *air surface temperature at 2 meters* data for a small region in the Northeastern United States. In later tutorials you will have the opportunity to select a region of your choice and to explore other climate variables. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# the order of the lat lon range has to follow the convention of the data set.\n", - "# for this dataset, longitude ranges from 0 to 360 degrees and\n", - "# latitude ranges from 90 degrees Northto 90 degrees South .\n", - "\n", - "# northeastern United States\n", - "lat_range = [55.2, 30.2] # from north to south\n", - "lon_range = [270, 295] # from west to east" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# note this can take several minutes to download\n", - "selected_vars = [\n", - " \"air_temperature_at_2_metres\",\n", - " \"northward_wind_at_10_metres\",\n", - " \"eastward_wind_at_10_metres\",\n", - " \"surface_air_pressure\",\n", - " \"sea_surface_temperature\",\n", - "] # the variables we want\n", - "s3_data_ptrn = (\n", - " \"{year}/{month}/data/{var}.nc\" # path and filename format for this S3 bucket\n", - ")\n", - "year_s3 = date_sel.strftime(\"%Y\") # extract the year\n", - "month_s3 = date_sel.strftime(\"%m\") # extract the month\n", - "ERA5_select = [] # initialize the dataset, will save a complicated check later\n", - "for var in selected_vars: # this will download 5 files of 500Mb each.\n", - " s3_data_key = s3_data_ptrn.format(\n", - " year=year_s3, month=month_s3, var=var\n", - " ) # variable specific key\n", - " print(\"Downloading %s from S3...\" % s3_data_key)\n", - " filepath = pooch_load(\n", - " filelocation=\"http://s3.amazonaws.com/\" + era5_bucket + \"/\" + s3_data_key,\n", - " filename=s3_data_key,\n", - " ) # open the file\n", - " ds_temp = xr.open_dataset(filepath) # retrieve the variable from the bucket\n", - " if (\n", - " ERA5_select\n", - " ): # check if the dataset is empty or not (first iteration of the loop)\n", - " ERA5_select = xr.merge(\n", - " [ERA5_select, ds_temp]\n", - " ) # if not empty, merge the new file\n", - " else:\n", - " ERA5_select = ds_temp # if empty, just assign the new file\n", - "\n", - "ERA5_allvars = ERA5_select.sel(lon=slice(lon_range[0], lon_range[1])).sel(\n", - " lat=slice(lat_range[0], lat_range[1])\n", - ")\n", - "ERA5_allvars" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The magnitude of the wind vector represents the wind speed \n", - "\n", - "\\begin{align}\n", - "||u|| = \\sqrt{u^2 + v^2}\n", - "\\end{align}\n", - "\n", - "which you will use later in the tutorial and discuss in more detail in tutorial 4. We will calculate that here and add it to our dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# compute ten meter wind speed\n", - "ERA5_allvars[\"wind_speed\"] = np.sqrt(\n", - " ERA5_allvars[\"northward_wind_at_10_metres\"] ** 2\n", - " + ERA5_allvars[\"eastward_wind_at_10_metres\"] ** 2\n", - ") # calculate the wind speed from the vectors\n", - "# name and units in the DataArray:\n", - "ERA5_allvars[\"wind_speed\"].attrs[\n", - " \"long_name\"\n", - "] = \"10-meter wind speed\" # assigning long name to the windspeed\n", - "ERA5_allvars[\"wind_speed\"].attrs[\"units\"] = \"m/s\" # assigning units\n", - "ERA5_allvars" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Plotting Spatial Maps of Reanalysis Data\n", - "First, let's plot the region's surface temperature for the first time step of the reanalysis dataset. To do this let's extract the air temperatre data from the dataset containing all the variables." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ds_surface_temp_2m = ERA5_allvars.air_temperature_at_2_metres" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We will be plotting this a little bit differently that you have previously plotted a map (and differently to how you will plot in most tutorials) so we can look at a few times steps interactively later. To do this we are using the package [geoviews](https://geoviews.org). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "holoviews.extension(\"bokeh\")\n", - "\n", - "dataset_plot = gvDataset(ds_surface_temp_2m.isel(time0=0)) # select the first time step\n", - "\n", - "# create the image\n", - "images = dataset_plot.to(\n", - " gvImage, [\"longitude\", \"latitude\"], [\"air_temperature_at_2_metres\"], \"hour\"\n", - ")\n", - "\n", - "# aesthetics, add coastlines etc.\n", - "images.opts(\n", - " cmap=\"coolwarm\",\n", - " colorbar=True,\n", - " width=600,\n", - " height=400,\n", - " projection=ccrs.PlateCarree(),\n", - " clabel=\"2m Air Temperature [K]\",\n", - ") * gf.coastline" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In the above figure, coastlines are shown as black lines. Most of the selected region is land, with some ocean (lower left) and a lake (top middle).\n", - "\n", - "Next, we will examine variability at two different frequencies using interactive plots:\n", - "\n", - "1. **Hourly variability** \n", - "2. **Daily variability** \n", - "\n", - "Note that in the previous tutorial you computed the monthly variability, or *climatology*, but here you only have one month of data loaded (March 2018). If you are curious about longer timescales you will visit this in the next tutorial!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# interactive plot of hourly frequency of surface temperature\n", - "# this cell may take a little longer as it contains several maps in a single plotting function\n", - "ds_surface_temp_2m_hour = ds_surface_temp_2m.groupby(\"time0.hour\").mean()\n", - "dataset_plot = gvDataset(\n", - " ds_surface_temp_2m_hour.isel(hour=slice(0, 12))\n", - ") # only the first 12 time steps, as it is a time consuming task\n", - "images = dataset_plot.to(\n", - " gvImage, [\"longitude\", \"latitude\"], [\"air_temperature_at_2_metres\"], \"hour\"\n", - ")\n", - "images.opts(\n", - " cmap=\"coolwarm\",\n", - " colorbar=True,\n", - " width=600,\n", - " height=400,\n", - " projection=ccrs.PlateCarree(),\n", - " clabel=\"2m Air Temperature [K]\",\n", - ") * gf.coastline" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# interactive plot of hourly frequency of surface temperature\n", - "# this cell may take a little longer as it contains several maps in a single plotting function holoviews.extension('bokeh')\n", - "ds_surface_temp_2m_day = ds_surface_temp_2m.groupby(\"time0.day\").mean()\n", - "dataset_plot = gvDataset(\n", - " ds_surface_temp_2m_day.isel(day=slice(0, 10))\n", - ") # only the first 10 time steps, as it is a time consuming task\n", - "images = dataset_plot.to(\n", - " gvImage, [\"longitude\", \"latitude\"], [\"air_temperature_at_2_metres\"], \"day\"\n", - ")\n", - "images.opts(\n", - " cmap=\"coolwarm\",\n", - " colorbar=True,\n", - " width=600,\n", - " height=400,\n", - " projection=ccrs.PlateCarree(),\n", - " clabel=\"Air Temperature [K]\",\n", - ") * gf.coastline" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Question 2\n", - "1. What differences do you notice between the hourly and daily interactive plots, and are there any interesting spatial patterns of these temperature changes?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 3: Plotting Timeseries of Reanalysis Data\n", - "\n", - "## Section 3.1: Surface Air Temperature Timeseries\n", - "\n", - "You have demonstrated that there are a lot of changes in surface temperature within a day and between days. It is crucial to understand this *temporal variability* in the data when performing climate analysis.\n", - "\n", - "Rather than plotting interactive spatial maps for different timescales, in this last section you will create a timeseries of surface air temperature from the data you have already examined to look at variability on longer than daily timescales. Instead of taking the mean in ***time*** to create *maps*, you will now take the mean in ***space*** to create *timeseries*.\n", - "\n", - "*Note that the spatially-averaged data will now only have a time coordinate coordinate, making it a timeseries (ts).*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# find weights (this is a regular grid so we can use cos(lat))\n", - "weights = np.cos(np.deg2rad(ds_surface_temp_2m.lat))\n", - "weights.name = \"weights\"\n", - "\n", - "# take the weighted spatial mean since the latitude range of the region of interest is large\n", - "ds_surface_temp_2m_ts = ds_surface_temp_2m.weighted(weights).mean([\"lon\", \"lat\"])\n", - "ds_surface_temp_2m_ts" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot the timeseries of surface temperature\n", - "\n", - "fig, ax = plt.subplots(1, 1, figsize=(10, 3))\n", - "\n", - "ax.plot(ds_surface_temp_2m_ts.time0, ds_surface_temp_2m_ts)\n", - "ax.set_ylabel(\"2m Air \\nTemperature (K)\")\n", - "ax.xaxis.set_tick_params(rotation=45)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 3.1\n", - "1. What is the dominant source of the high frequency (short timescale) variability? \n", - "2. What drives the lower frequency variability? \n", - "3. Would the ENSO variablity that you computed in the previous tutorial show up here? Why or why not?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 3.2: Comparing Timeseries of Multiple Variables\n", - "\n", - "Below you will calculate the timeseries of the surface air temperature which we just plotted, alongside timeseries of several other ERA5 variables for the same period and region: 10-meter wind speed, atmospheric surface pressure, and sea surface temperature. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "ERA5_allvars_ts = ERA5_allvars.weighted(weights).mean([\"lon\", \"lat\"])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "plot_vars = [\n", - " \"air_temperature_at_2_metres\",\n", - " \"wind_speed\",\n", - " \"surface_air_pressure\",\n", - " \"sea_surface_temperature\",\n", - "]\n", - "\n", - "fig, ax_list = plt.subplots(len(plot_vars), 1, figsize=(10, 13), sharex=True)\n", - "\n", - "for var, ax in zip(plot_vars, ax_list):\n", - "\n", - " ax.plot(ERA5_allvars_ts.time0, ERA5_allvars_ts[var])\n", - " ax.set_ylabel(\n", - " ERA5_allvars[var].attrs[\"long_name\"] + \": \" + ERA5_allvars[var].attrs[\"units\"],\n", - " fontsize=12,\n", - " )\n", - " ax.xaxis.set_tick_params(rotation=45)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "jp-MarkdownHeadingCollapsed": true, - "tags": [] - }, - "source": [ - "### Questions 3.2\n", - "\n", - "Which variable shows variability that is dominated by:\n", - "1. The diurnal cycle?\n", - "2. The synoptic [~5 day] scale?\n", - "3. A mix of these two timescales?\n", - "4. Longer timescales?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Bonus Section 1: Selecting a Different Spatial Region\n", - "\n", - "Define another spatial region, such as where you live, by selecting a longitude and latitude range of of your choosing. To find the longitude and latitude coordinates of your region, you can use [Google Earth view](https://earth.google.com/), and read the position of your cursor in the lower right corner.\n", - "\n", - "### Bonus Section 1.1: Note About the Geographic Coordinate System and the Coordinates Used in This Dataset\n", - "A point on Earth is described by latitude-longitude coordinates relative to the zero-meridian line going through Greenwich in London, UK (longitude = 0 degree) and the xero-latitude line along the equator (latitude = 0 degrees). Points east of Greenwich up to the *dateline* on the opposite side of the globe are referenced as 0 to +180 and points to the west of Greenwich are 0 to -180. -180 and +180 refer to the same longitude, the so-called *dateline* in the central pacific. \n", - "\n", - "However, our data is referenced in a slightly different way where longitude runs from 0 to 360 rather than -180 to +180. Longitude increases as you move east of Greenwich, until you reach Greenwich again (0 or 360 degrees), rather than stopping at the *dateline*. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, you learned how to access and process ERA5 reanalysis data. You are able to select specific regions within the reanalysis dataset and perform operations such as taking spatial and temporal averages.\n", - "\n", - "You also looked at different climate variables to distinguish idenitfy the variability present at different timescales.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "Data for this tutorial can be accessed [here](https://registry.opendata.aws/ecmwf-era5/)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D2_Tutorial2", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - }, - "toc-autonumbering": true - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.ipynb deleted file mode 100644 index 24d924d1a..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.ipynb +++ /dev/null @@ -1,757 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/W1D2_Tutorial3.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 3: Atmospheric Circulation\n", - "\n", - "**Week 1, Day 2, Ocean-Atmosphere Reanalysis**\n", - "\n", - "__Content creators:__ Momme Hell\n", - "\n", - "**Content reviewers:** Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "In the previous tutorial you examined atmospheric surface temperatures. Spatial variations in surface temperature created by uneven solar radiation (e.g., between the Equator and poles), are one of the main drivers of global-scale air movement. Other processes such as the Earth's rotation, storm tracks, and surface topography can also influence global wind patterns. \n", - "\n", - "By the end of this tutorial, you will be able to:\n", - "\n", - "- Describe the seasonal variations in surface winds.\n", - "- Calculate seasonal climatologies and create global maps.\n", - "- Compare statistics derived from these climatologies.\n", - "\n", - "In this tutorial, you will again utilize the monthly-mean surface wind fields from ERA5 over a 30-year period." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# !pip install pythia_datasets\n", - "# !pip install cartopy\n", - "# !pip install geoviews" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "from intake import open_catalog\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib\n", - "import os\n", - "import pooch\n", - "import tempfile\n", - "import boto3\n", - "import botocore\n", - "import numpy as np\n", - "import xarray as xr\n", - "import warnings\n", - "import datetime\n", - "from cartopy import crs as ccrs, feature as cfeature\n", - "\n", - "# Suppress warnings issued by Cartopy when downloading data files\n", - "warnings.filterwarnings(\"ignore\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# @title Plotting Functions\n", - "\n", - "\n", - "def set_projection_figure(projection=ccrs.PlateCarree(), figsize=(5, 4.5)):\n", - " # source:https://foundations.projectpythia.org/core/cartopy/cartopy.html\n", - "\n", - " projLccNY = projection # ccrs.LambertConformal(central_longitude=cLon, central_latitude=cLat)\n", - "\n", - " fig = plt.figure(figsize=figsize)\n", - " ax = plt.subplot(1, 1, 1, projection=projLccNY)\n", - "\n", - " format_axes(ax)\n", - " # ax.add_feature(cfeature.STATES)\n", - " # ax.add_feature(cfeature.RIVERS)\n", - " return fig, ax\n", - "\n", - "\n", - "def format_axes(ax):\n", - " ax.add_feature(cfeature.COASTLINE)\n", - " ax.add_feature(cfeature.LAKES, edgecolor=\"black\", facecolor=\"None\", alpha=0.3)\n", - " gl = ax.gridlines(\n", - " draw_labels=True, linewidth=1, color=\"black\", alpha=0.5, linestyle=\"--\"\n", - " )\n", - " gl.xlocator = matplotlib.ticker.MaxNLocator(7)\n", - " gl.ylocator = matplotlib.ticker.MaxNLocator(5)\n", - " gl.xlabels_top = False\n", - " gl.ylabels_left = False\n", - " # gl.xlines = False\n", - "\n", - "\n", - "# helping functions:\n", - "def geographic_lon_to_360(lon):\n", - " return 360 + lon\n", - "\n", - "\n", - "def inverted_geographic_lon_to_360(lon):\n", - " return lon - 180\n", - "\n", - "\n", - "def cbar_label(DD):\n", - " return DD.attrs[\"long_name\"] + \" [\" + DD.attrs[\"units\"] + \"]\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Figure Settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: The Wind Driven Circulation\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', 'zgwShu0xXYA'), ('Bilibili', 'BV1NN411U7Eb')]\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", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"ebz7w\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Surface Winds\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The large-scale atmospheric circulation significantly influences the climate we experience at different latitudes. The global atmospheric circulation is often depicted as a three-cell structure, as visualized [in this figure showing the surface winds](https://commons.wikimedia.org/wiki/File:Earth_Global_Circulation_-_en.svg):\n", - "\n", - "![Earth Global Circulation - en.svg](https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Earth_Global_Circulation_-_en.svg/740px-Earth_Global_Circulation_-_en.svg.png?20190829153037).\n", - "\n", - "\n", - "This schematic of atmospheric circulation cells reveal meridional (north-south) and zonal (east-west) components of the large-scale surface winds. \n", - "\n", - "Let's see if you are able to detect these large-scale patterns in reanalysis data!\n", - "For this you will load ERA5 wind data from [Pangeo catalog](https://pangeo.io/catalog.html)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Annual Mean Wind Speed\n", - "\n", - "You should start investigating this data by examining the global surface winds. These winds are represented as vectors, consisting of a zonal component denoted as `u10` and a meridional component denoted as `v10`. \n", - "\n", - "Recall from the previous tutorial that the magnitude of the wind vector represents the wind speed you will use later in the tutorial, given by:\n", - "\n", - "\\begin{align}\n", - "||u|| = \\sqrt{u^2 + v^2}\n", - "\\end{align}\n", - "\n", - "To examine long-term changes in the wind field you should visualize the zonal wind component $u$ and the meridional wind component $v$ with monthly-mean data. With the help of `xarray`, you can derive monthly means from higher-resolution data (such as those used in tutorial 2) using the `xr.resample('1M').mean('time')` function.\n", - "\n", - "For your convenience, we have already performed this step, and you can load the data using the following instructions:\n", - "\n", - "- The variable `si10` represents the wind speed in this dataset.\n", - "- To calculate the long-term mean, we selected 30 years of data ranging from 1980 to 2010.\n", - "\n", - "Let's grab the reanalysis data from before that we have prepocessed (noting naming convention changes):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# note this can take a few minutes to download\n", - "filename_era5_mm = \"ERA5_surface_winds_mm.nc\"\n", - "url_era5_mm = \"https://osf.io/3q4vs/download\"\n", - "\n", - "ERA5_mm = xr.open_dataset(pooch_load(url_era5_mm, filename_era5_mm)).sel(\n", - " time=slice(\"1980\", \"2010\")\n", - ") # select the timeslice during loading\n", - "ERA5_mm" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now take the annual mean zonal surface wind speed." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# take the time mean\n", - "ERA5_ANN = ERA5_mm.mean(\"time\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To visualize this data, we will be using some helper functions defined in the beginning of the tutorial just to set the map features and aesthetics. Please take a look at them if you are interested in seeing how they work." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# adjust colorlevels to weaker amplitudes\n", - "colorlevels_clim = np.arange(-10, 11, 1)\n", - "\n", - "var = \"u10\" # select our variable\n", - "fig, ax = set_projection_figure(\n", - " projection=ccrs.PlateCarree(), figsize=(9, 5.5)\n", - ") # same plot function as Part I\n", - "ax.set_title(\"Mean \" + var, loc=\"left\")\n", - "dataplot = ax.contourf(\n", - " ERA5_ANN.longitude,\n", - " ERA5_ANN.latitude,\n", - " ERA5_ANN[var],\n", - " levels=colorlevels_clim,\n", - " transform=ccrs.PlateCarree(),\n", - " cmap=plt.cm.coolwarm,\n", - ")\n", - "fig.colorbar(dataplot, orientation=\"vertical\", label=\"m/s\", shrink=0.55, pad=0.08)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In the zonal wind speed figure you created, there are two distinct wind bands between 35 to 65 degrees both north and south of the equator that blow from west to east (red, positive wind speeds). These mid-latitude wind bands are known as the *westerlies*. Additionally, you can see that winds predominantly blow from the east to the west (blue, negative wind speeds) in the tropics (less than 30° N/S), and are referred to as the *easterlies*.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Coding Exercise 1.1\n", - "Reproduce the previous figure, but modify it to plot **meridional wind** rather than **zonal wind**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Reproduce the previous figure, but modify it to plot meridional wind rather than zonal wind\"\n", - ")\n", - "#################################################\n", - "var = ...\n", - "fig, ax = set_projection_figure(projection=ccrs.PlateCarree(), figsize=(9, 5.5))\n", - "ax.set_title(\"Mean \" + var, loc=\"left\")\n", - "dataplot = ax.contourf(\n", - " ERA5_ANN.longitude,\n", - " ERA5_ANN.latitude,\n", - " ERA5_ANN[var],\n", - " levels=colorlevels_clim,\n", - " transform=ccrs.PlateCarree(),\n", - " cmap=plt.cm.coolwarm,\n", - ")\n", - "fig.colorbar(dataplot, orientation=\"vertical\", label=\"m/s\", shrink=0.55, pad=0.08)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "There are strong southward winds in the subtropics of the Northern Hemisphere (blue, negative wind speed), and northward winds in the subtropics of the Southern Hemisphere (red, positive wind speed). The meridional winds are strongest on the western side of the continents. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1.1\n", - "1. Among the three atmospheric \"cells\" (the Hadley Cell, Ferrel Cell, and Polar Cell) depicted in the figure from Section 1 above, which ones correspond to the zonal wind bands that we visualized in the first plot above? \n", - "2. How do the zonal and meridional winds compare in magnitude, longitude, and latitude?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.2 : Zonal-mean Wind Speed\n", - "\n", - "To examine the latitudinal variation in the surface winds, you can plot the zonal mean of the annual mean zonal and meridional winds:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots(figsize=(9, 5.5))\n", - "ERA5_ANN.mean(\"longitude\")[\"u10\"].plot(\n", - " label=\"zonal wind\", ax=ax\n", - ") # find the u10 mean value over the latitude\n", - "ERA5_ANN.mean(\"longitude\")[\"v10\"].plot(\n", - " label=\"meridional wind\", ax=ax\n", - ") # find the v10 mean value over the latitude\n", - "ax.legend() # add legend\n", - "ax.set_title(\"Annual mean, zonal mean winds\", loc=\"left\") # add title\n", - "ax.set_ylabel(\"wind speed (m/s)\")\n", - "ax.axhline(0, color=\"black\") # add a black line at x=0" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1.2\n", - "1. Considering the zonal-mean wind speed figure provided, what factors contribute to the noticeable disparities between the Northern and Southern Hemispheres in terms of wind patterns?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Monthly Climatology\n", - "\n", - "Now, you should examine how the zonal mean winds vary throughout the seasons. You will focus on the zonal wind component and create a special type of diagram called a Hoffmöller diagram. In this diagram, the horizontal axis represents latitude, while the vertical axis represents time.\n", - "\n", - "By using the Hoffmöller diagram, you can visualize how the average east-west winds change with each season.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# the groupby command regroups the data by month, such that all Januarys, all Februaries, .. and so on are taken the mean over\n", - "# note how we use several commands in one line. python perfom them by order. slice (long, u10), groupby, mean and lastely plot.\n", - "ERA5_mm.mean(\"longitude\")[\"u10\"].groupby(\"time.month\").mean().plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Coding Exercises 2\n", - "\n", - "Extend the above analysis to create a Hoffmöller diagram of the meridional winds." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Extend the above analysis to create a Hoffmöller diagram of the meridional winds.\"\n", - ")\n", - "#################################################\n", - "\n", - "ERA5_mm.mean(\"longitude\")[\"...\"].groupby(\"time.month\").mean().plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "*Note:*\n", - "- The winds in the Southern Hemisphere appear to be generally stronger compared to the Northern Hemisphere.\n", - "- The period between June and September shows strong meridional winds. These winds result from the seasonal variation of the Hadley cell. During the winter hemisphere in each respective hemisphere, the Hadley cell becomes much stronger, leading to the intensification of meridional winds." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Bonus exercise\n", - "\n", - "- Plot the global map for DJF and JJA of the zonal wind. What do you see when you compare the mid-latitudes? (you can also plot their difference!)\n", - "\n", - "- Plot trend of the zonal mean zonal wind in DJF\n", - "\n", - "\n", - "That is because the solar insulation leads to varying circulation patterns with seasons. \n", - "More about this you can find in [Global Physical Climatology](https://www.atmos.washington.edu/~dennis/gpc.html), \n", - "[The Atmospheric General Circulation](https://www.cambridge.org/us/academic/subjects/earth-and-environmental-science/atmospheric-science-and-meteorology/atmospheric-general-circulation?format=HB&isbn=9781108474245)\n", - "or the first few chapters of this evolving draft [Physics of Earth's Climate](https://climate-dynamics.org/wp-content/uploads/2017/04/Climate_Book.pdf)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# note, this codes takes a while to run\n", - "ERA5_season = ...\n", - "\n", - "var='u10'\n", - "season='DJF'\n", - "F, ax = set_projection_figure(projection = ccrs.PlateCarree(), figsize = (9, 5.5) )\n", - "ax.set_title('Zonal Wind DJF mean | '+ var , loc ='left')\n", - "dataplot = ...\n", - "_ = ... # colorbar\n", - "plt.show()\n", - "\n", - "\n", - "var='u10'\n", - "season='JJA'\n", - "F, ax = set_projection_figure(projection = ccrs.PlateCarree(), figsize = (9, 5.5) )\n", - "ax.set_title('Zonal Wind DJF mean | '+ var , loc ='left')\n", - "dataplot = ...\n", - "_ = ... # colorbar\n", - "plt.show()\n", - "\n", - "# difference:\n", - "var='u10'\n", - "pdata = ...\n", - "\n", - "F, ax = set_projection_figure(projection = ccrs.PlateCarree(), figsize = (9, 5.5) )\n", - "ax.set_title(... , loc ='left')\n", - "dataplot = ...\n", - "_ = ... # colorbar\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Additional Reading: Extra-tropical Storms\n", - "\n", - "In the wind speed figure, you can notice areas of strong winds over the Southern Ocean, North Pacific, and North Atlantic. These powerful winds are caused by weather systems known as extratropical storms or mid-latitude cyclones. These storms occur in the middle latitudes, between 30 and 60 degrees north or south of the equator. During winter, they are particularly strong over the Southern Ocean and the oceans in the Northern Hemisphere.\n", - "\n", - "Extratropical storms form when warm and cold air masses interact. They have a low-pressure center and produce winds that circulate counterclockwise in the Northern Hemisphere and clockwise in the Southern Hemisphere. These storms can be intense, bringing strong winds, heavy rain, snow, and sleet. They often lead to problems like flooding, power outages, and disruptions in transportation.\n", - "\n", - "The strength of these storms depends on factors such as the temperature difference between air masses, the speed of the jet stream, and the amount of moisture in the air. If you want to learn more about extratropical storms, you can refer to basic meteorology and atmospheric dynamics resources, or you can explore online sources such as the following:\n", - "\n", - "- Wikipedia: [Extratropical Cyclone](https://en.wikipedia.org/wiki/Extratropical_cyclone)\n", - "- Pressbooks: [Chapter 13 - Extratropical Cyclones](http://pressbooks-dev.oer.hawaii.edu/atmo/chapter/chapter-13-extratropical-cyclones/)\n", - "\n", - "Although an individual storm may last only a few days and doesn't create significant ocean currents, the continuous winds and the occurrence of multiple storms over a year can influence the development of ocean currents. These currents are a response to the persistent wind patterns." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "Within this tutorial, you analysed the global atmospheric circulation by using ERA5 reanalysis data. You explored the distribution of westerlies and easterlies across the globe, observed their seasonal variations. You observed that the strongest winds were found to occur over the Southern Ocean." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "Data from this tutorial can be accessed [here](https://registry.opendata.aws/ecmwf-era5/)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D2_Tutorial3", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - }, - "toc-autonumbering": true - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4.ipynb deleted file mode 100644 index 0131812a9..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4.ipynb +++ /dev/null @@ -1,688 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/W1D2_Tutorial4.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Tutorial 4: Oceanic Wind-driven Circulation\n", - "\n", - "**Week 1, Day 2: Ocean and Atmospheric Reanalysis**\n", - "\n", - "__Content creators:__ Abigail Bodner\n", - "\n", - "**Content reviewers:** Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "\n", - "The ocean's motion is driven by radiation from the sun, winds, and various sources & sinks of fresh water (precipitation, rivers, melting and freezing ice). In the previous tutorial, you quantified the surface winds around the world. The surface winds drags on the surface of the ocean which results in ocean transport, known as Ekman transport.\n", - "\n", - "In this tutorial you will use the [ECCO (Estimating the Circulation and Climate of the Ocean)](https://www.ecco-group.org) reanalysis data, to visualize the ocean's surface currents and to compare these currents against local atmospheric conditions.\n", - "\n", - "At the end of this tutorial you will be able to\n", - "\n", - "- Access and manipulate ocean reanalysis data\n", - "- Plot annual mean ocean surface currents and atmospheric surface winds\n", - "- Compare oceanic and atmospheric circulation patterns" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# !pip install pythia_datasets\n", - "# !pip install cartopy\n", - "# !pip install geoviews" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# from intake import open_catalog\n", - "import matplotlib.pyplot as plt\n", - "import matplotlib\n", - "import os\n", - "import pooch\n", - "import tempfile\n", - "import numpy as np\n", - "import xarray as xr\n", - "import warnings\n", - "from cartopy import crs as ccrs, feature as cfeature\n", - "\n", - "# suppress warnings issued by Cartopy when downloading data files\n", - "warnings.filterwarnings(\"ignore\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Ocean Wind-driven Circulation\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', 'k-rMUYEskHY'), ('Bilibili', 'BV1tW4y1o7DH')]\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", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"f8c5r\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Load Ocean & Atmosphere Reanalysis Data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Here you will load atmospheric near-surface winds (at 10-meter height), and then load the oceanic surface currents from ECCO reanalysis data\n", - "\n", - "*Note, each of these variables is a velocity with two components (zonal and meridional). These two velocity components must be loaded separately for each variable, so you will load four datasets.*\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "both", - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# load data: atmospheric 10m wind from ECCO\n", - "# wind in east/west direction labeled here as 'u'\n", - "fname_atm_wind_u = \"wind_evel_monthly_2016.nc\"\n", - "url_atm_wind_u = \"https://osf.io/ke9yp/download\"\n", - "atm_wind_u = xr.open_dataarray(pooch_load(url_atm_wind_u, fname_atm_wind_u))\n", - "atm_wind_u" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# wind in north/south direction labeled here as 'v'\n", - "fname_atm_wind_v = \"wind_nvel_monthly_2016.nc\"\n", - "url_atm_wind_v = \"https://osf.io/9zkgd/download\"\n", - "atm_wind_v = xr.open_dataarray(pooch_load(url_atm_wind_v, fname_atm_wind_v))\n", - "atm_wind_v" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# load data: oceanic surface current from ECCO\n", - "# current in east/west direction labeled here as 'u'\n", - "fname_ocn_surface_current_u = \"evel_monthly_2016.nc\"\n", - "url_ocn_surface_current_u = \"https://osf.io/ndx5a/download\"\n", - "ocn_surface_current_u = xr.open_dataarray(\n", - " pooch_load(url_ocn_surface_current_u, fname_ocn_surface_current_u)\n", - ")\n", - "ocn_surface_current_u" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# current in east/west direction labeled here as 'v'\n", - "fname_ocn_surface_current_v = \"nvel_monthly_2016.nc\"\n", - "url_ocn_surface_current_v = \"https://osf.io/qa9ex/download\"\n", - "ocn_surface_current_v = xr.open_dataarray(\n", - " pooch_load(url_ocn_surface_current_v, fname_ocn_surface_current_v)\n", - ")\n", - "ocn_surface_current_v" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Exploring the Reanalysis Data\n", - "\n", - "Let's examine the time (or temporal/output) frequency, which descibes the rate at which the reanalysis data is provided, for one of the ECCO variables (*atm_wind_u*). \n", - "\n", - "*Note that all the variables should have the same output frequency.*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "atm_wind_u.time" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 1.1\n", - "1. Why do you think the atmospheric reanalysis dataset from the previous tutorial (ERA5) has higher output frequency (hourly) than the ECCO ocean reanalysis dataset (daily)?\n", - "2. What can you infer about the role of these two systems at different timescales in the climate system?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# Section 2: Plotting the Annual Mean of Global Surface Wind Stress\n", - "\n", - "In this section you will create global maps displaying the annual mean of atmospheric 10m winds.\n", - "\n", - "First, you should compute the annual mean of the surface wind variables. You can do so by averaging over the time dimension using `.mean(dim='time')`. Since you have monthly data spanning only one year, `.mean(dim='time')` will give the annual mean for the year 2016.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# compute the annual mean of atm_wind_u\n", - "atm_wind_u_an_mean = atm_wind_u.mean(dim=\"time\")\n", - "atm_wind_u_an_mean" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# take the annual mean of atm_wind_stress_v\n", - "atm_wind_v_an_mean = atm_wind_v.mean(dim=\"time\")\n", - "atm_wind_v_an_mean" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You are now almost ready to plot! \n", - "\n", - "However, you currently have seperate zonal and meridional wind velocity components $(u,v)$. An effective way of visualizing the total surface wind stress is to create a global map of the *magnitude* and *direction* of the wind velocity vector. This type of plot is known as a vector field. A [vector](https://glossary.ametsoc.org/wiki/Vector) is a special mathematical quantity that has both magnitude and direction, just like the wind! The velocity components describe the intensity of wind blowing in the zonal ($u$) or meridional ($v$) directions. Specifically, wind can blow eastward (positive $u$) or westward (negative $u$), as well as northward (positive $v$) or southward (negative $v$).\n", - "\n", - "The total velocity vector is the *vector sum* of these two components and exhibits varying magnitude and direction. The magnitude ($||u||$) and direction ($θ$) of the total velocity vector can be determined using the following equations:\n", - "\n", - "\\begin{align}\n", - "||u|| = \\sqrt{u^2 + v^2}, \\ \\ \\ \\ \\theta = tan^{-1}(\\frac{v}{u})\n", - "\\end{align}\n", - "\n", - "When plotting a vector field using a computer, it is commonly referred to as a quiver plot. In our case, we will utilize a [quiver function created by Ryan Abernathey](https://rabernat.github.io/intro_to_physical_oceanography/07_ekman.html) that calculates the magnitude and direction of the total velocity vector based on the given zonal and meridional components.\n", - "\n", - "We will overlay the quiver plot on top of the annual mean ocean surface temperature (labeled here as theta)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "fname_surface_temp = \"surface_theta.nc\"\n", - "url_fname_surface_temp = \"https://osf.io/98ksr/download\"\n", - "ocn_surface_temp = xr.open_dataarray(\n", - " pooch.retrieve(url_fname_surface_temp, known_hash=None, fname=fname_surface_temp)\n", - ")\n", - "ocn_surface_temp" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# longitude ad latitude coordinates for plotting\n", - "lon = atm_wind_u_an_mean.longitude\n", - "lat = atm_wind_u_an_mean.latitude\n", - "\n", - "# calculate magnitude of total velocity\n", - "mag = (atm_wind_u_an_mean**2 + atm_wind_v_an_mean**2) ** 0.5\n", - "\n", - "# coarsen the grid so the arrows are distinguishable by only selecting\n", - "# some longitudes and latitudes defined by sampling_x and sampling_y.\n", - "slx = slice(None, None, 20)\n", - "sly = slice(None, None, 20)\n", - "sl2d = (sly, slx)\n", - "\n", - "fig, ax = plt.subplots(\n", - " figsize=(12, 6), subplot_kw={\"projection\": ccrs.Robinson(central_longitude=180)}\n", - ")\n", - "\n", - "c = ax.contourf(lon, lat, ocn_surface_temp, alpha=0.5)\n", - "\n", - "# plot quiver arrows indicating vector direction (winds are in blue, alpha is for opacity)\n", - "q = ax.quiver(\n", - " lon[slx],\n", - " lat[sly],\n", - " atm_wind_u_an_mean[sl2d],\n", - " atm_wind_v_an_mean[sl2d],\n", - " color=\"b\",\n", - " alpha=0.5,\n", - ")\n", - "\n", - "ax.quiverkey(q, 175, 95, 5, \"5 m/s\", coordinates=\"data\")\n", - "\n", - "fig.colorbar(c, label=\"Sea Surface Temperature (degC)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 3: Comparing Global Maps of Surface Currents and Winds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this section you will compute the annual mean of the ocean surface currents, similar to your above analyses of atmospheric winds, and you will create a global map that shows both of these variables simultaneously." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# take the annual mean of ocn_surface_current_u\n", - "ocn_surface_current_u_an_mean = ocn_surface_current_u.mean(dim=\"time\")\n", - "ocn_surface_current_u_an_mean" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# take the annual mean of ocn_surface_current_v\n", - "ocn_surface_current_v_an_mean = ocn_surface_current_v.mean(dim=\"time\")\n", - "ocn_surface_current_v_an_mean" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's add ocean surface currents to the previous plot above, using **red** quivers. Note the scale of the arrows for the ocean and atmosphere are very different." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# longitude ad latitude coordinates for plotting\n", - "lon = atm_wind_u_an_mean.longitude\n", - "lat = atm_wind_u_an_mean.latitude\n", - "\n", - "# calculate magnitude of total velocity\n", - "mag = (atm_wind_u_an_mean**2 + atm_wind_v_an_mean**2) ** 0.5\n", - "\n", - "# coarsen the grid so the arrows are distinguishable by only selecting\n", - "# some longitudes and latitudes defined by sampling_x and sampling_y.\n", - "slx = slice(None, None, 20)\n", - "sly = slice(None, None, 20)\n", - "sl2d = (sly, slx)\n", - "\n", - "# fig, ax = plt.subplots(**kwargs)\n", - "fig, ax = plt.subplots(\n", - " figsize=(12, 6), subplot_kw={\"projection\": ccrs.Robinson(central_longitude=180)}\n", - ")\n", - "\n", - "c = ax.contourf(lon, lat, ocn_surface_temp, alpha=0.5)\n", - "\n", - "# plot quiver arrows indicating vector direction (winds are in blue, alpha is for opacity)\n", - "q1 = ax.quiver(\n", - " lon[slx],\n", - " lat[sly],\n", - " atm_wind_u_an_mean[sl2d],\n", - " atm_wind_v_an_mean[sl2d],\n", - " color=\"b\",\n", - " alpha=0.5,\n", - ")\n", - "\n", - "# plot quiver arrows indicating vector direction (ocean currents are in red, alpha is for opacity)\n", - "q2 = ax.quiver(\n", - " lon[slx],\n", - " lat[sly],\n", - " ocn_surface_current_u_an_mean[sl2d],\n", - " ocn_surface_current_v_an_mean[sl2d],\n", - " color=\"r\",\n", - " alpha=0.5,\n", - ")\n", - "\n", - "ax.quiverkey(q1, 175, 95, 5, \"5 m/s\", coordinates=\"data\")\n", - "\n", - "ax.quiverkey(q2, 150, 95, 0.05, \"5 cm/s\", coordinates=\"data\")\n", - "\n", - "fig.colorbar(c, label=\"Sea Surface Temperature (degC)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Questions 3\n", - "\n", - "You may notice that the surface currents (red) are typically not aligned with the wind direction (blue). In fact, the surface ocean currents flow at an angle of approximately 45 degrees to the wind direction! \n", - "\n", - "The combination of [Coriolis force](https://en.wikipedia.org/wiki/Coriolis_force) and the friction between ocean layers causes the wind-driven currents to turn and weaken with depth, eventually dissapearing entirely at depth. The resulting current *profile* is called the **[Ekman Spiral](https://en.wikipedia.org/wiki/Ekman_spiral)**, and the depth over which the spiral is present is called the **Ekman layer**. While the shape of this spiral can vary in time and space, the depth-integrated transport of water within the Ekman layer is called [**Ekman transport**](https://en.wikipedia.org/wiki/Ekman_transport). Ekman transport is always *90 degrees to the right* of the wind in the Northern Hemisphere, and 90 degrees to the *left* of the wind in the Southern Hemisphere. Under certain wind patterns or near coastlines, Ekman transport can lead to **Ekman Pumping**, where water is upwelled or downwelled depending on the wind direction. This process is particularily important for coastal ecosystems that rely on this upwelling (which is often seasonal) to bring nutrient-rich waters near the surface. These nutrients fuel the growth of tiny marine plants that support the entire food chain, upon which coastal economies often rely. These tiny plants are also responsible for most of the oxygen we breathe!\n", - "\n", - "1. Do you observe a deflection of the surface currents relative to the wind? \n", - "2. Is this deflection the same in both the Northern and Southern Hemispheres?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this tutorial, you explored how atmospheric winds can shape ocean surface currents.\n", - "\n", - "You calculated the surface wind vector an assessed its influence on surface ocean currents called the wind-driven circulation.\n", - "\n", - "This circulation influences global climate (e.g., moving heat between latitudes) and biogeochemical cycles (e.g., by driving upwelling of nutrient rich water). In the next tutorial you will explore another mechanism for ocean movement, *density-driven circulation*.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "Data for this tutorial can be accessed [here](https://www.ecco-group.org/)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D2_Tutorial4", - "provenance": [], - "toc_visible": true - }, - "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.11.3" - }, - "toc-autonumbering": true - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5.ipynb deleted file mode 100644 index c4bb7c60a..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5.ipynb +++ /dev/null @@ -1,638 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/W1D2_Tutorial5.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 5: Thermohaline Circulation\n", - "\n", - "**Week 1, Day 2: Ocean and Atmospheric Reanalysis**\n", - "\n", - "__Content creators:__ Aurora Basinski\n", - "\n", - "**Content reviewers:** Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "In the previous tutorial, we discussed how the surface ocean's movement is driven by wind forcing. However, the ocean can also experience movement due to density differences. The large scale ocean movement driven by these density differences is known as the *thermohaline circulation*. The density of ocean water is influenced by temperature (thermo) and salinity (haline), and fluid motion occur in response to pressure gradients caused by these density variations.\n", - "\n", - "In this tutorial, we will use ocean surface data for 2014 to 2016 from the [Estimating the Circulation and Climate of the Ocean (ECCO)](https://www.ecco-group.org/) dataset to \n", - "* Plot sea surface salinity and temperature\n", - "* Understand the relationship between salinity, temperature, and ocean density\n", - "* Explore the difference between linear and non-linear *equations of state*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# !pip install seaborn\n", - "# !pip install cmocean\n", - "# !pip install cartopy\n", - "# !pip install geoviews" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2058, - "status": "error", - "timestamp": 1682626613201, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "import cartopy as cart\n", - "import cartopy.crs as ccrs\n", - "from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter\n", - "import cmocean\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import gsw" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Thermohaline Circulation\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', 'cgh6bC2uj58'), ('Bilibili', 'BV1uh4y1j7wN')]\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-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"vdeq6\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Plot Surface Temperature and Salinity\n", - "In the slides, we discovered that ocean flows can be driven by density variations in addition to wind-driven circulation. One example of a density-driven flow is the thermohaline circulation. Density in the ocean is influenced by two main factors: \n", - "1. Salinity (higher salinity leads to greater density) and \n", - "2. Temperature (lower temperature generally results in higher density),\n", - "3. Also, pressure affects density (higher pressure results in higher density), but it generally has a much smaller impact on ocean density than temperature and salinity. \n", - "\n", - "To develop a better understanding of how density varies across different regions, let's examine the average salinity and temperature at the ocean surface.\n", - "\n", - "First let's load the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# import preprocessed ecco data. This data is surface data that is monthly over the period 2014 to 2016.\n", - "filename_theta = \"surface_theta.nc\"\n", - "url_theta = \"https://osf.io/98ksr/download\"\n", - "\n", - "subset_theta = xr.open_dataset(pooch_load(url_theta, filename_theta))\n", - "subset_theta" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "filename_salt = \"surface_salt.nc\"\n", - "url_salt = \"https://osf.io/aufs2/download\"\n", - "\n", - "subset_salt = xr.open_dataset(pooch_load(url_salt, filename_salt))\n", - "subset_salt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# make land points NaN (not a number)\n", - "subset_theta = subset_theta.where(\n", - " subset_theta != 0\n", - ") # change anywhere that the value is zero to NaN\n", - "subset_salt = subset_salt.where(subset_salt != 0) # same\n", - "subset_theta = subset_theta.THETA # choose the variable to remove the dimension\n", - "subset_salt = subset_salt.SALT" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot Sea Surface Temprature - similar to plots we used in tutorials 2+3\n", - "fig, ax = plt.subplots(\n", - " subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n", - ") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n", - "p = subset_theta.plot(\n", - " vmin=0,\n", - " cmap=cmocean.cm.thermal,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"degree C\",\n", - " },\n", - " ax=ax,\n", - ")\n", - "ax.coastlines(color=\"grey\", lw=0.5)\n", - "ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax.add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax.set_title(\"Sea Surface Temperature (2014-2016 mean)\")\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot Sea Surface Salinity\n", - "fig, ax = plt.subplots(\n", - " subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n", - ") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n", - "p = subset_salt.plot(\n", - " cmap=cmocean.cm.haline,\n", - " vmin=30,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"psu\",\n", - " },\n", - " ax=ax,\n", - ")\n", - "ax.coastlines(color=\"grey\", lw=0.5)\n", - "ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax.add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax.set_title(\"Sea Surface Salinity (2014-2016 mean)\")\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Calculating Density from Salinity & Temperature\n", - "The equation relating ocean water density to other water properties is called the ***equation of state***. It is a non-linear function of temperature, salinity, and pressure. This can be expressed as $\\rho=\\rho(T,S,p)$. Here we will show two ways to calculate the density. \n", - "\n", - "The first is a *linear approximation* to the equation of state. We will then show how to calculate the full, non-linear equation of state using the `gsw` package" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.1: Linearized Equation of State\n", - "Here we take the linearized equation of state from equation 1.57 in Vallis' textbook [\"*Atmospheric and Oceanic Fluid Dynamics*\"](https://www.cambridge.org/core/books/atmospheric-and-oceanic-fluid-dynamics/41379BDDC4257CBE11143C466F6428A4)\n", - "\n", - "$$ \\rho=\\rho_0[1-\\beta_T(T-T_0)+\\beta_S(S-S_0)+\\beta_p(p-p_0)] $$\n", - "\n", - "In this equation, $\\rho_0\\simeq 1027$ is a reference density, $\\beta_T \\simeq 2*10^{-4}$/K is the thermal expansion coefficient, $\\beta_S \\simeq 7.6*10^{-4}$/ppt is the haline contraction coefficient, and $\\beta_p \\simeq 4.4*10^{-10}$/Pa is the compressibility coefficient. The values with $_0$ are reference values, and here we use $T_0=283$K and $S_0=35$. Since surface pressure rarely changes by more than a few percent, let's assume that the pressure at the surface is equal to the reference pressure at every point ($\\beta_p(p-p_0)=0$). *The non-linearities in the full equation of state (which we will use later) arise because, in reality, the $\\beta$ terms themselves vary with pressure, salinity, and temperature.*\n", - "\n", - "Let's now calculate a global map of surface density using this linear equation of state. Note that since we are using theta and salt *datasets*, our result will also be a dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "rho_linear = 1027 * (\n", - " 1 - 2e-4 * (subset_theta + 273.15 - 283) + 7.6e-4 * (subset_salt - 35)\n", - ")\n", - "rho_linear" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot linearized density\n", - "fig, ax = plt.subplots(\n", - " subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n", - ") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n", - "p = rho_linear.plot(\n", - " cmap=cmocean.cm.dense,\n", - " vmin=1021,\n", - " vmax=1029,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"kg/m$^3$\",\n", - " },\n", - " ax=ax,\n", - ")\n", - "ax.coastlines(color=\"grey\", lw=0.5)\n", - "ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax.add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax.set_title(\"Surface density from linear equation (2014-2016 mean)\")\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.2: Full Nonlinear Equation of State\n", - "The full, non-linear equation of state is more complicated than the linear equation we just used. It contains dozens of equations which are impractical to code in this tutorial. Fortunately packages exist to do this calculation!\n", - "\n", - "Here we will compute surface density from the full nonlinear equation in `python` using the `gsw` package which is a Python implementation of the [Thermodynamic Equation of Seawater 2010 (TEOS-10)](https://teos-10.github.io/GSW-Python/)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "CT = gsw.CT_from_pt(\n", - " subset_salt, subset_theta\n", - ") # get conservative temperature from potential temperature\n", - "rho_nonlinear = gsw.rho(subset_salt, CT, 0)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot density from full nonlinear equation\n", - "fig, ax = plt.subplots(\n", - " subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n", - ") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n", - "p = rho_nonlinear.plot(\n", - " cmap=cmocean.cm.dense,\n", - " vmin=1021,\n", - " vmax=1029,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"kg/m$^3$\",\n", - " },\n", - " ax=ax,\n", - ")\n", - "ax.coastlines(color=\"grey\", lw=0.5)\n", - "ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax.add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax.set_title(\"Surface density from nonlinear equation (2014-2016 mean)\")\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot difference between linear and non-linear equations of state\n", - "fig, ax = plt.subplots(\n", - " subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n", - ") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n", - "p = (rho_linear - rho_nonlinear).plot(\n", - " cmap=\"coolwarm\",\n", - " vmin=-3,\n", - " vmax=3,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"kg/m$^3$\",\n", - " },\n", - " ax=ax,\n", - ")\n", - "ax.coastlines(color=\"grey\", lw=0.5)\n", - "ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax.add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax.set_title(\"Linear minus non-linear equation of state (2014-2016 mean)\")\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Upon comparing the two equations of state, we observe that they are generally similar, but certain differences arise. These differences stem from the nonlinearity of the equation of state, where the haline contraction coefficient and thermal expansion coefficient are not constant as assumed in our linear equation of state.\n", - "\n", - "Irrespective of the method used to calculate density, we notice the presence of horizontal density variations (gradients) at the ocean surface. For instance, seawater tends to be less dense in the subtropics and denser near the poles. These density differences play a crucial role in driving ocean currents, as we discussed in the slides.\n", - "\n", - "These findings emphasize the significant density gradients in the ocean, which shape oceanic circulation patterns. The nonlinearity in the equation of state contributes to these density variations, which in turn also influences the movement of water masses and the formation of currents." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 2.2\n", - "\n", - "1. Considering the nonlinear equation of state and TEOS-10, how do changes in ocean salinity and temperature uniquely impact the haline contraction and thermal expansion coefficients, thereby affecting density and ocean currents?\n", - "2. One place that deep convection, a critical component of thermohaline circulation occurs, is in the North Atlantic Ocean to the south of Greenland. Based on the density maps you made, does it make sense that this would be an ideal location for a deepwater mass to form?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, you explored sea surface salinity and temperature data from 2014 to 2016, and how those contribute to surface density patterns through the equation of state. You also compared the linear and non-linear equation of state and analyzed their differences." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "Data for this tutorial can be accessed [here](https://www.ecco-group.org/)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D2_Tutorial5", - "provenance": [], - "toc_visible": true - }, - "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.11.3" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6.ipynb deleted file mode 100644 index 9f17a91e0..000000000 --- a/book/_build/html/_sources/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6.ipynb +++ /dev/null @@ -1,730 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/W1D2_Tutorial6.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial 6: Ocean Heat Content\n", - "\n", - "**Week 1, Day 2: Ocean and Atmospheric Reanalysis**\n", - "\n", - "__Content creators:__ Aurora Basinski\n", - "\n", - "**Content reviewers:** Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Brodie, Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Tutorial Objectives\n", - "In this tutorial, you will explore the ocean's vast heat capacity, which has a significant impact on the climate system. \n", - "\n", - "The ocean has a heat capacity that is approximately 1000 times greater than the entire atmosphere, due to the relatively large mass and specific heat capacity of water. This means that the ocean has a significant impact on Earth's thermal equilibrium state. *Ocean heat uptake* and *ocean carbon uptake* mitigates the effect of anthropogenic climate change by absorbing roughly 90% of the excess heat and 25% of human-emitted CO2. As you will see in this tutorial, ocean heat uptake largely occurs in the upper ocean as it is the region in contact with the atmosphere.\n", - "\n", - "The ocean's high heat capacity also facilitates meridional ocean heat transport from the equator to the poles, which acts in addition to the meridional *atmospheric* heat transport.\n", - "\n", - "Through this tutorial, you will explore the spatial distribution of heat in the ocean and how the ocean's heat content is changing over time. To do this, you will utilize the [Estimating the Circulation and Climate of the Ocean (ECCO)](https://www.ecco-group.org/) dataset." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# !pip install seaborn\n", - "# !pip install cmocean\n", - "# !pip install cartopy\n", - "# !pip install geoviews" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "import cartopy as cart\n", - "import cartopy.crs as ccrs\n", - "from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter\n", - "import cmocean\n", - "import os\n", - "import pooch\n", - "import tempfile\n", - "from scipy import integrate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "remove-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Ocean's Role in Climate\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', 'dPSYOC1blUg'), ('Bilibili', 'BV1gP411y7oj')]\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", - "remove-cell" - ] - }, - "outputs": [], - "source": [ - "# @title Tutorial slides\n", - "# @markdown These are the slides for the videos in all tutorials today\n", - "from IPython.display import IFrame\n", - "link_id = \"vyb68\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Vertical Distribution of Heat Within the Ocean\n", - "\n", - "First, let's load ECCO ocean temperature (`THETA`). This datasets contains the annual mean temperature over the period of 1992 to 2016." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# import preprocessed ECCO data. This data is full depth temperature data over 1992 to 2016 (annual mean)\n", - "# this file takes about 5 minutes to load\n", - "filename_theta_annual = \"theta_annual_mean.nc\"\n", - "url_theta_annual = \"https://osf.io/c8wqt/download\"\n", - "\n", - "theta_annual = xr.open_dataset(pooch_load(url_theta_annual, filename_theta_annual))\n", - "theta_annual = theta_annual.THETA\n", - "theta_annual = theta_annual.where(theta_annual != 0) # make land points equal to NaN\n", - "theta_annual" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# take the mean over the period 1992 to 1994\n", - "subset_theta = theta_annual.sel(year=slice(\"1992\", \"1994\")).mean(\"year\")\n", - "subset_theta" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# plot a zonal mean slice of this data. we take a mean just in longitudes by dividing the dA coordinate by the\n", - "fig, ax = plt.subplots(figsize=(8, 6))\n", - "(\n", - " ((subset_theta - 273.15) * subset_theta.dX).sum(\"longitude\")\n", - " / (subset_theta.dX.sum(\"longitude\"))\n", - ").plot(ax=ax)\n", - "ax.set_title(\"Global zonal mean of temperature (C)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Temperatures are warmest near the ocean's surface and close to the Equator, which suggests that heat is not distributed evenly within the ocean. **In this tutorial you will explore the spatial distribution of heat storage in the ocean (i.e., ocean heat content), and how this distribution is changing over time**. \n", - "\n", - "Heat content is typically measured in Joules, which is equivalent to the units kg$*$m$^2$/s$^2$. To determine the heat content within a specific depth range of the global ocean, i.e., between depth $z_1$ and the surface (height of 0), you can calculate a *volume integral* over the dimensions $x,y,$ and $z$. This integral can be written as:\n", - "$$\\iiint_{-z_1}^0 c_p \\cdot \\rho_0 \\cdot \\theta(x,y,z) dz dA$$\n", - "\n", - "Here, $dA$ represents the area integral over the $x$ and $y$ (lat, lon) coordinates. $\\rho_0$ is the reference density in units of kg/m$^3$ and $c_p$ is specific heat capacity in units of J/(kg$*$K)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "theta_area_int = (\n", - " (subset_theta * subset_theta.dA).sum(\"latitude\").sum(\"longitude\")\n", - ") # we take an area integral first at each depth level" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "rho = 1026 # kg/m^3\n", - "c_p = 3990 # J/(kg K)\n", - "\n", - "sns.set_style(style=\"whitegrid\")\n", - "fig, ax = plt.subplots(figsize=(8, 6))\n", - "ax.plot(\n", - " -subset_theta.Zu, (rho * c_p * theta_area_int * subset_theta.dZ).cumsum() / 10**27\n", - ")\n", - "ax.set_xlabel(\"Depth (m)\")\n", - "ax.set_ylabel(\"Heat content above this depth ($10^6$ ZJ)\")\n", - "ax.set_title(\"Global Ocean Heat Content above each depth\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You can see that much of the ocean's heat is concentrated in the upper ocean (where the line is steep), with less heat stored in the deepest ocean regions (where the line plateaus). At first glance, this seems consistent with the zonal mean plot you plotted earlier in the tutorial, where the upper ocean tends to be warmer than deeper waters. However, in the integral equation above, $\\theta$ is not the only depth-dependent term. The global ocean area ($A$) also varies with depth, with the area of the global ocean decreasing with depth until only a few deep trenches contain water at the greatest ocean depths.\n", - "\n", - "Let's explore whether the ocean heat content plot we just created is driven by temperature variations or global ocean area variations with depth. One way to do this is to calculate and plot an integral of the global ocean area between each depth and the surface (i.e., the volume of the ocean above a each depth): $Volume(z) = \\iiint_{-z_1}^0 dz dA$.\n", - "\n", - "If the volume as a function of depth looks similar to the heat content plot above, it would suggest that the smaller heat content of the deeper ocean (i.e., the plateau at large depths) is caused by the relatively small volume of water contained at these depths, rather than the vertical variations in temperature.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "area_of_ocean = (\n", - " (subset_theta * subset_theta.dA / subset_theta).sum(\"latitude\").sum(\"longitude\")\n", - ") # we take an area integral first at each depth level\n", - "\n", - "sns.set_style(style=\"whitegrid\")\n", - "fig, ax = plt.subplots(figsize=(8, 6))\n", - "ax.plot(-subset_theta.Zu, (area_of_ocean * subset_theta.dZ).cumsum())\n", - "ax.set_xlabel(\"Depth (m)\")\n", - "ax.set_ylabel(\"Volume of the global ocean above this depth (m$^3$)\")\n", - "ax.set_title(\"Global ocean volume above each depth\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Question 1\n", - "\n", - "1. Based on the last two plots, are depth-variations in ocean heat content primarily due to vertical changes in the temperature or area of the ocean?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Changes in Ocean Heat Content" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this section you will examine how the total (i.e., full-depth) heat content of the ocean has changed over time. You will also explore heat content changes within two specific upper-ocean layers: one above 700 m depth and another above 2000 m depth$^*$. By analyzing these near surface layers, you will identify whether changes in the ocean's heat content are evenly distributed through the water column.\n", - "\n", - "$^*$*Note: technically the grid of the data means you will be looking above 677 m and 1997 m respectively*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# this cell may take a while to run!\n", - "rho = 1026 # kg/m^3\n", - "c_p = 3990 # J/(kg K)\n", - "global_heat, years_to_plot, global_heat_upper2000, global_heat_upper700 = [], [], [], []\n", - "for year in theta_annual.year:\n", - " years_to_plot.append(int(year))\n", - " subset_theta_year = theta_annual.sel(year=int(year))\n", - " global_heat.append(\n", - " float(\n", - " rho\n", - " * c_p\n", - " * (subset_theta_year * subset_theta_year.dZ * subset_theta_year.dA)\n", - " .sum(\"Z\")\n", - " .sum(\"latitude\")\n", - " .sum(\"longitude\")\n", - " )\n", - " )\n", - " global_heat_upper2000.append(\n", - " float(\n", - " rho\n", - " * c_p\n", - " * (\n", - " (\n", - " subset_theta_year.where(subset_theta_year.Zu > -2000)\n", - " * subset_theta_year.dZ\n", - " * subset_theta_year.dA\n", - " )\n", - " .sum(\"Z\")\n", - " .sum(\"latitude\")\n", - " .sum(\"longitude\")\n", - " )\n", - " )\n", - " )\n", - " global_heat_upper700.append(\n", - " float(\n", - " rho\n", - " * c_p\n", - " * (\n", - " (\n", - " subset_theta_year.where(subset_theta_year.Zu > -700)\n", - " * subset_theta_year.dZ\n", - " * subset_theta_year.dA\n", - " )\n", - " .sum(\"Z\")\n", - " .sum(\"latitude\")\n", - " .sum(\"longitude\")\n", - " )\n", - " )\n", - " )\n", - "\n", - "# we now have lists, and list don't support math operations (-)\n", - "# we also divide the values by 10**21 to make them easier to read.\n", - "\n", - "heat_anom_fulldepth = [\n", - " (heat - global_heat[0]) / 10**21 for heat in global_heat\n", - "] # remove year 1992\n", - "heat_anom_upper2000 = [\n", - " (heat - global_heat_upper2000[0]) / 10**21 for heat in global_heat_upper2000\n", - "] # remove year 1992\n", - "heat_anom_upper700 = [\n", - " (heat - global_heat_upper700[0]) / 10**21 for heat in global_heat_upper700\n", - "] # remove year 1992\n", - "heat_anom_upper2000_700 = [\n", - " a - b for a, b in zip(heat_anom_upper2000, heat_anom_upper700)\n", - "] # difference series between 2000 to 700\n", - "heat_anom_upperfulldepth_2000 = [\n", - " a - b for a, b in zip(heat_anom_fulldepth, heat_anom_upper2000)\n", - "] # difference series between fulldepth to 2000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots(figsize=(8, 6))\n", - "sns.set_style(style=\"whitegrid\")\n", - "ax.plot(years_to_plot, heat_anom_fulldepth, \"k--\")\n", - "ax.plot(years_to_plot, heat_anom_upper700)\n", - "ax.plot(years_to_plot, heat_anom_upper2000_700)\n", - "ax.plot(years_to_plot, heat_anom_upperfulldepth_2000)\n", - "ax.set_xlabel(\"Time\")\n", - "ax.set_ylabel(\"Heat content change (ZJ)\")\n", - "ax.legend(\n", - " [\n", - " \"Full depth\",\n", - " \"Surface to 700 meters depth\",\n", - " \"700 to 2000 meters depth\",\n", - " \"Below 2000 meters depth\",\n", - " ]\n", - ")\n", - "ax.set_title(\"Change in heat over time\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Questions 2\n", - "\n", - "The volume of the ocean model in the reanalysis product does not change over time. Thus the *changes* in ocean heat content that you just calculated are caused by changes in the ocean's temperature. Most of the ocean's warming (heat gain) has been within the upper ocean (shallower than 700 m). The deeper ocean has also warmed, but not as substantially as near-surface waters.\n", - "\n", - "1. Based on this graph, what percentage of the ocean's heat gain since 1992 is contained within the top 2000 meters?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 3: Spatial Distribution of Ocean Heat Content" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You just saw that the ocean heat increase is concentrated near the ocean surface. **Now you will explore where that heat is stored as a function of latitude and longitude**. You can do this by creating a global map of ocean heat content in the upper 700 m of the ocean - which is essentially the same integral as above without the horizontal area integral: $\\int_{-700m}^0 c_p\\rho_0\\theta(x,y,z) dz$" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# first let's plot where heat is stored in the mean\n", - "fig, ax = plt.subplots(\n", - " subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n", - ") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n", - "\n", - "p = (\n", - " (\n", - " (rho * c_p * subset_theta.where(-subset_theta.Zu < 700) * subset_theta.dZ).sum(\n", - " \"Z\"\n", - " )\n", - " )\n", - ").plot(\n", - " vmin=7e11,\n", - " vmax=8.15e11,\n", - " cmap=cmocean.cm.thermal,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"\",\n", - " },\n", - " ax=ax,\n", - ")\n", - "ax.coastlines(color=\"grey\", lw=0.5)\n", - "ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax.add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax.set_title(\n", - " \"Ocean Heat Content of top 700 m per unit area, mean of 1992 to 1994, J m$^{-2}$\"\n", - ")\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The lower latitude ocean contains more heat than the higher latitudes. This finding is consistent with your previous plot of warmer waters near the Equator during this tutorial. \n", - "\n", - "*Note: the color scale of this figure was chosen to emphasize latitudinal differences in ocean heat conent. As a result, some regions with shallow water depth display as black on the plot due to their relatively low column-integrated ocean heat content ($<7 \\times 10^{11} J m^{-2}$). **These black regions do not have zero ocean heat content.***\n", - "\n", - "Now let's explore the spatial pattern of (full-depth) ocean heat content *rate of change* between 1992 and 2016." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "# we already defined an object that's the mean over years 1992 to 1994 (subset_theta)\n", - "# now define an object that's the mean over 2014 to 2016\n", - "subset_theta_future = theta_annual.sel(year=slice(\"2014\", \"2016\")).mean(\"year\")\n", - "\n", - "length_of_time_period = 24 * 60 * 60 * 365 * (2015 - 1993)\n", - "\n", - "full_depth_heat_content_change = (\n", - " rho * c_p * subset_theta_future * subset_theta_future.dZ\n", - ").sum(\"Z\") - (rho * c_p * subset_theta * subset_theta.dZ).sum(\"Z\")\n", - "upper_700m_heat_content_change = (\n", - " rho\n", - " * c_p\n", - " * subset_theta_future.where(-subset_theta.Zu < 700)\n", - " * subset_theta_future.dZ\n", - ").sum(\"Z\") - (\n", - " rho * c_p * subset_theta.where(-subset_theta.Zu < 700) * subset_theta.dZ\n", - ").sum(\n", - " \"Z\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "tags": [ - "remove-output" - ] - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots(\n", - " 1, 2, subplot_kw={\"projection\": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100\n", - ") # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html\n", - "(full_depth_heat_content_change / length_of_time_period).plot(\n", - " ax=ax[0],\n", - " vmin=-10,\n", - " vmax=10,\n", - " cmap=cmocean.cm.balance,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"\",\n", - " },\n", - ")\n", - "(upper_700m_heat_content_change / length_of_time_period).plot(\n", - " ax=ax[1],\n", - " vmin=-10,\n", - " vmax=10,\n", - " cmap=cmocean.cm.balance,\n", - " cbar_kwargs={\n", - " \"shrink\": 0.75,\n", - " \"orientation\": \"horizontal\",\n", - " \"extend\": \"both\",\n", - " \"pad\": 0.05,\n", - " \"label\": \"\",\n", - " },\n", - ")\n", - "ax[0].coastlines(color=\"grey\", lw=0.5)\n", - "ax[0].set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax[0].set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax[0].add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax[0].set_title(\n", - " \"Rate of change in full-depth ocean heat content \\n (2014-2016 minus 1992-1994); (J m$^{-2}$)/year\"\n", - ")\n", - "fig.tight_layout\n", - "ax[1].coastlines(color=\"grey\", lw=0.5)\n", - "ax[1].set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())\n", - "ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())\n", - "ax[0].set_ylabel(\"Latitude\")\n", - "ax[1].set_ylabel(\"\")\n", - "ax[0].set_xlabel(\"Longitude\")\n", - "ax[1].set_xlabel(\"Longitude\")\n", - "lon_formatter = LongitudeFormatter(zero_direction_label=True)\n", - "lat_formatter = LatitudeFormatter()\n", - "ax[1].add_feature(cart.feature.LAND, zorder=100, edgecolor=\"k\")\n", - "ax[1].set_title(\n", - " \"Rate of change in upper 700 m ocean heat content \\n (2014-2016 minus 1992-1994); (J m$^{-2}$)/year\"\n", - ")\n", - "fig.tight_layout" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "With these plots, you demonstrated that ocean heat gain is not evenly distributed across space. When comparing the two plots, you once again see that the upper ocean contains a large fraction of the warming (recall that Equatorial regions contribute more to the global mean than high-latitude regions becasue of their relatively large area)." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Summary\n", - "\n", - "In this tutorial, you have quantified the spatial patterns and temporal changes of the ocean's heat content. You showed that the upper layers of the ocean contain most of the ocean's heat content, due to their relatively large area (and hence volume) compared to the deepest ocean layers. These upper layers also experience a disproportionately large fraction of the ocean warming that has been observed in recent decades. You also found that heat content distribution varies by latitude and longitude, and is typically greater in the lower latitudes, and the ocean's heat gain over time is not uniformly distributed across different oceanic regions." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources\n", - "\n", - "Data for this tutorial can be accessed [here](https://www.ecco-group.org/)." - ] - } - ], - "metadata": { - "celltoolbar": "Tags", - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D2_Tutorial6", - "provenance": [], - "toc_visible": true - }, - "kernel": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "kernelspec": { - "display_name": "Python (climatematch)", - "language": "python", - "name": "climatematch" - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title.md b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title.md deleted file mode 100644 index 00147c0fb..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Remote Sensing Land Ocean and Atmosphere - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading.md b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading.md deleted file mode 100644 index 1ee0dfaff..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading.md +++ /dev/null @@ -1,11 +0,0 @@ -# Suggested Further Reading - -- National Research Council. (2004). Climate data records from environmental satellites: Interim report. National Academies Press. (https://nap.nationalacademies.org/read/10944/chapter/1) - -- Hollmann, R., Merchant, C. J., Saunders, R., Downy, C., Buchwitz, M., Cazenave, A., ... & Wagner, W. (2013). The ESA climate change initiative: Satellite data records for essential climate variables. Bulletin of the American Meteorological Society, 94(10), 1541-1552. (https://doi.org/10.1175/BAMS-D-11-00254.1) - -- Plummer, S., Lecomte, P., & Doherty, M. (2017). The ESA climate change initiative (CCI): A European contribution to the generation of the global climate observing system. Remote Sensing of Environment, 203, 2-8. (original link to the publisher website: https://doi.org/10.1016/j.rse.2017.07.014; open copy from ESA: https://climate.esa.int/media/documents/Plummer_ESA_CCI_RSE_article_2017.pdf) - -- Anderson, K., Ryan, B., Sonntag, W., Kavvada, A., & Friedl, L. (2017). Earth observation in service of the 2030 Agenda for Sustainable Development. Geo-spatial Information Science, 20(2), 77-96. (https://doi.org/10.1080/10095020.2017.1333230) - -- Committee on Earth Observing Satellites (2023). Use Cases for Climate Monitoring from Space (https://ceos.org/news/wgclimate-use-cases/). diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1.ipynb deleted file mode 100644 index 4352d97d9..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1.ipynb +++ /dev/null @@ -1,431 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 1: Introduction to Remote Sensing**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Dionessa Biton, Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "Today you will learn the basics of remote sensing, how to find remote sensing data, and how to use it for studying the climate across 8 tutorials.\n", - "\n", - "The first tutorial introduces the fundamental concepts of remote sensing technologies and data. Although you won't be doing any coding in this initial module, some compelling examples of how remote sensing data can be utilized to monitor our environment and society's diverse facets will be illustrated.\n", - "\n", - "By the end of this tutorial, you'll be able to:\n", - "\n", - "- Grasp key concepts of satellite remote sensing, including the electromagnetic spectrum, satellite orbits, and resolutions.\n", - "- Appreciate the value and benefits of satellite remote sensing for climate studies through selected examples." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: What is Remote Sensing\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: What is Remote Sensing\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: What is Remote Sensing\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: What is Remote Sensing?**\n", - "\n", - "Remote sensing is the technique of getting information from a distance (remotely). In daily life, photography is a very common format of remote sensing. In Earth and environmental science, sensors are often used on satellites in space or aircrafts in the sky to acquire information on topics such as agriculture, disaster response, and air pollution. \n", - "\n", - "There are many organizations involved in this work, including government agencies like [NASA](https://www.nasa.gov/) and [NOAA](https://www.noaa.gov/), private companies like [Planet](https://www.planet.com/) and [Maxar](https://www.maxar.com/), and various universities. They design and launch remote sensors on satellites and aircraft to monitor natural and human environments.\n", - "\n", - "These remote sensors offer a unique perspective of Earth and enable data-informed decision making about our planet's present and future state. For an example of the data these sensors can provide, this is the [Visible Infrared Imager Radiometer Suite (VIIRS)](https://www.nesdis.noaa.gov/current-satellite-missions/currently-flying/joint-polar-satellite-system/visible-infrared-imaging) onboard the [Suomi-NPP satellite](https://www.nasa.gov/mission_pages/NPP/main/index.html) launched in 2011. The image below is the first global image it captured on November 28, 2011.\n", - "\n", - "![The first global composite of data captured by VIIRS on November 28, 2011](https://eoimages.gsfc.nasa.gov/images/imagerecords/76000/76674/global_vir_2011328_lrg.jpg)\n", - "The first global composite of data captured by VIIRS on November 28, 2011. (Credit: [NASA Earth Observatory](https://eoimages.gsfc.nasa.gov/images/imagerecords/76000/76674/global_vir_2011328_lrg.jpg))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Electromagnetic Spectrum**\n", - "\n", - "The concept of the electromagnetic spectrum is at the core of remote sensing. \n", - "\n", - "* **Electromagnetic energy**, radiated or reflected by objects, travels as waves through the atmosphere and the void of space. These waves exhibit different [wavelengths](https://glossary.ametsoc.org/wiki/Wavelength) (the distance between successive wave crests) and [frequencies](https://glossary.ametsoc.org/wiki/Frequency); a shorter wavelength corresponds to a higher frequency. Certain waves, like radio, microwave, and infrared, possess longer wavelengths, whereas others, such as ultraviolet, x-rays, and gamma rays, possess much shorter wavelengths.\n", - "* Humans can only perceive visible light, situated in the middle of the spectrum that spans from longwave to shortwave radiation.\n", - "* Nonetheless, we can engineer sensors to capture all other forms of electromagnetic energy emitted or reflected by elements of the Earth system, enabling us to monitor and research the Earth system.\n", - "\n", - "![Diagram of the Electromagnetic Spectrum](https://www.earthdata.nasa.gov/s3fs-public/imported/EMS-Introduction_0.jpeg?VersionId=rSEKLCj0F2zuFCQ6hRTw6zaBBipH.UWY)\n", - "Diagram of the Electromagnetic Spectrum. (Credit: [NASA Science](https://www.earthdata.nasa.gov/s3fs-public/imported/EMS-Introduction_0.jpeg?VersionId=rSEKLCj0F2zuFCQ6hRTw6zaBBipH.UWY))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "**What is the connection between the electromagnetic spectrum and the study and monitoring of Earth?**\n", - "\n", - "Every element of Earth's system—land, water, air, and life—interacts with energy differently, reflecting, absorbing, or transmitting varying amounts depending on the wavelength. These energy interactions can be captured by strategically designed remote sensors, allowing us to analyze and understand these components.\n", - "\n", - "For instance,\n", - "- Snow possesses a high albedo, reflecting up to 90% of incoming solar radiation in the visible light wavelength. This high reflectivity accounts for snow's bright, white appearance to the human eye.\n", - "- Conversely, the ocean reflects only about 6% of incoming solar radiation, absorbing the remainder. This absorption makes the ocean appear darker, though its appearance can be influenced by other factors like surface waves, phytoplankton presence, and water quality.\n", - "- When solar energy is absorbed, it is typically re-emitted at longer wavelengths, such as infrared and thermal infrared. Thus, the ocean commonly re-emits absorbed solar energy as infrared radiation, which is utilized to monitor ocean temperatures.\n", - "These are processes we experience in our everyday life, even if we don't consciously recognize them. Have you ever wondered why most leaves are green, why the sky is blue, or why flowers come in such a variety of colors?\n", - "\n", - "The answers to these questions assist scientists in developing sensors to monitor vegetation health, air and water quality, detect wildfires, and many other crucial applications." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "*Want to learn more about electromagnetic spectrum? Take a [tour of the electromagnetic spectrum with NASA Science](https://science.nasa.gov/ems/)!*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "## **Section 1.2: Satellite Orbits**\n", - "\n", - "Satellites can occupy several types of orbits around Earth. The three common categories of orbits are:\n", - "\n", - "* **Low-Earth orbit** (approximately 160 to 2,000 km above Earth): This orbit is common for many Earth-observing satellites, including polar-orbiting satellites (e.g., [Terra](https://terra.nasa.gov/), [Aqua](https://aqua.nasa.gov/), [CloudSat](https://www.jpl.nasa.gov/missions/cloudsat), [CALIPSO](https://www-calipso.larc.nasa.gov/)). As the name suggests, polar-orbiting satellites travel from pole to pole, allowing Earth to rotate beneath them. This movement enables the onboard sensors to rapidly collect data across the entire globe, inclusive of the polar regions.\n", - "\n", - " ![Illustration of the A-train polar-orbiting satellites operated by NASA and partner organizations.](https://earthobservatory.nasa.gov/ContentFeature/OrbitsManeuver/images/atrain.jpg) \n", - " Illustration of the A-train polar-orbiting satellites operated by NASA. (Credit: [NASA](https://earthobservatory.nasa.gov/ContentFeature/OrbitsManeuver/images/atrain.jpg))\n", - "* **Medium-Earth orbit** (approximately 2,000 to 35,500 km above Earth): this type of orbit is often used by the [Global Positioning System (GPS)](https://en.wikipedia.org/wiki/Global_Positioning_System) satellites. \n", - "* **High-Earth orbit** (above 35,500 km above Earth): Satellites in this orbit are typically geostationary. They maintain a fixed position above a specific location on Earth's surface. NOAA, for instance, operates two geostationary satellites that provide observations of the western hemisphere every five minutes and targeted observations of severe weather events every 30 seconds.\n", - " \n", - " ![Satellite images of NOAA's GOES-West (on the left) and GOES-East (on the right) full disk data on the day of summer solitice of 2022.](https://live.staticflickr.com/65535/48127127191_911a25f659_b.jpg) |\n", - " -\n", - " Satellite images of NOAA's GOES-West (on the left) and GOES-East (on the right) full disk data on the day of summer solstice of 2022. (Credit: [NOAA](https://live.staticflickr.com/65535/48127127191_911a25f659_b.jpg) )\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.3: Resolution**\n", - "\n", - "Resolution plays a crucial role in determining how data from a sensor can be interpreted and utilized. This can vary depending on the design of the satellite's sensor and its orbit. Four types of resolution are important to consider for any dataset—radiometric, spatial, spectral, and temporal.\n", - "\n", - "\n", - "**Spatial resolution** is defined as the area on Earth's surface represented by each pixel within a remotely sensed image. Typically, a pixel representing a smaller area indicates a higher spatial resolution. The *fine* the resolution (the smaller the numerical value), the *more* detail can be discerned. In the image below, you can observe the difference in pixelation between a higher resolution 30 m/pixel image (left image), a medium resolution 100 m/pixel image (center image), and a coarser resolution 300 m/pixel image (right image).\n", - "\n", - "![Different Spatial Resolution](https://www.earthdata.nasa.gov/s3fs-public/2022-02/spatial_resolution.jpg?VersionId=CqYOXFpvK326WrJYS_34WAr8cIRuH9Mm) |\n", - "-\n", - "\n", - "(Credit: [NASA Earth Observatory](https://www.earthdata.nasa.gov/s3fs-public/2022-02/spatial_resolution.jpg?VersionId=CqYOXFpvK326WrJYS_34WAr8cIRuH9Mm))\n", - "\n", - "Consequently, the spatial resolution of remotely sensed data imposes constraints on the types of applications for which the data can be utilized. For instance, it would likely be inappropriate to use the right image above to map local roads, whereas the left image might be suitable for such an application.\n", - "\n", - "**Temporal resolution**, also frequently referred to as **revisiting frequency**, is the time it takes for a satellite to complete an orbit and revisit the same observation area. This parameter often depends on the satellite's orbit, the characteristics of the sensor, and the sensor's field of view from space.\n", - "\n", - "* For polar-orbiting satellites, temporal resolution can vary from 1 day to 16 days. The Moderate Resolution Imaging Spectroradiometer ([MODIS](https://modis.gsfc.nasa.gov/), spatial resolution ranging from 250 m/pixel to 1 km/pixel depending on wavelength) flying onboard NASA's Terra and Aqua satellite since 2000 has a temporal resolution of 1-2 days. Conversely, the Operational Land Imager ([OLI](https://landsat.gsfc.nasa.gov/satellites/landsat-8/spacecraft-instruments/operational-land-imager/), with a spatial resolution of 30 meter/pixel is featured on Landsat-8, a satellite jointly operated by NASA/USGS that has a narrower swath width and temporal resolution of 16 days.\n", - "\n", - "* Geostationary satellites maintain pace with Earth's rotation, allowing them to provide sub-hourly temporal resolution for remotely sensed data. For instance, the latest generation of geostationary satellites offers a temporal resolution of 5-15 minutes, while their predecessors provided a resolution of 0.5-3 hours. \n", - "\n", - "**Spectral resolution** represents a sensor's capability to distinguish finer, or more and narrower, wavelengths. The more wavelengths a sensor can distinguish, the more information we can obtain and the more applications we can apply the data to. Typically, **multispectral** remote sensors feature 3-10 spectral bands, while **hyperspectral** sensors have hundreds of spectral bands, enabling us to scrutinize Earth's objects in more detail.\n", - "\n", - "For instance, the Airborne Visible/Infrared Imaging Spectrometer ([AVIRIS](https://aviris.jpl.nasa.gov/)) shown below records data in 224 spectral channels. These sensors enable us to differentiate between various rock and mineral types, vegetation types, water quality, and other features.\n", - "\n", - "![Sample image of AVIRIS over a lake and evaporation pond.](https://www.earthdata.nasa.gov/s3fs-public/imported/avcubebig.gif?VersionId=vB8vyHe0veiLvzKN37vSwnXUpe4WpOHa) |\n", - "-\n", - "\n", - "(Credit: [NASA JPL](https://www.earthdata.nasa.gov/s3fs-public/imported/avcubebig.gif?VersionId=vB8vyHe0veiLvzKN37vSwnXUpe4WpOHa))\n", - "\n", - "**Radiometric resolution** quantifies the amount of information contained in each pixel and is often expressed as the number of bits representing the recorded energy. Each bit records an exponent of power 2. For instance, an 8-bit resolution equals $2^8$, implying that the sensor can utilize 256 potential digital values (0-255) to store information. The image below from NASA Earth Observatory illustrates how radiometric resolution affects the level of detail visible in remotely sensed data.\n", - "\n", - "![Illustration of the impact of radiometric resoultion on remotely sensed data.](https://www.earthdata.nasa.gov/s3fs-public/2022-02/radiometric_resolution.png?VersionId=SUfbvvyRgjUqC1C5CoB2Br52GvwKq9iZ) |\n", - "-\n", - "\n", - "Credit: [NASA](https://www.earthdata.nasa.gov/s3fs-public/2022-02/radiometric_resolution.png?VersionId=SUfbvvyRgjUqC1C5CoB2Br52GvwKq9iZ)\n", - "\n", - "As illustrated in the image above, the higher the radiometric resolution (right image), the more values are available to store information, providing better discrimination between even the slightest differences in energy.\n", - "\n", - "\n", - "_**\"Why can't we have the sensor with the best resolution of all four categories?\"**_\n", - "\n", - "This is a great question! Due to technology limitations, it is very difficult to have the \"perfect sensor\". If you're aiming for high spatial resolution, there's only a limited amount of energy in the area for that pixel. This implies that you'll need a longer exposure to capture enough energy to extract meaningful information from that area. The longer the exposure, the less frequently you can revisit the same place. However, we can overcome this issue by using a constellation of satellites equipped with identical sensors to minimize the gaps between revisits. An example of this approach is the Sentinel-2 satellite pairs used by the European Space Agency." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.3**\n", - "\n", - "1. Now you have learned about four different types of resolution. Imagine a specific subject that you would like to study or monitor. It could be monitoring crop health, studying the impact of a landslide on a city, or any other topic of interest. Can you describe what type of remotely sensed data would be necessary for your project? Try to be specific - how often would you need the data (e.g., every few minutes, daily, weekly, etc.)? What would be the ideal spatial resolution for your purposes?\n", - "\n", - "*Hint*: You can look at NASA's [Earthdata Data Pathfinders](https://www.earthdata.nasa.gov/learn/pathfinders) to see if you can find some inspirations." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial1_Solution_7d742a70.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# **Section 2: Example Use Cases**\n", - "\n", - "You've just completed a quick dive into the realm of satellite remote sensing and grasped some fundamental concepts. You might be wondering, _\"How can satellite data help answer some of my climate-related questions?\"_\n", - "\n", - "To illuminate this, we'll present six diverse examples of long-term satellite remote sensing data that track the dynamics of our land, ocean, and atmosphere. These animations are created using aggregated monthly satellite data, showcasing the fluidity of different Earth's components. As we proceed, you'll acquire computational skills to independently generate such animations.\n", - "\n", - "These animations are all generated by [NASA Earth Observatory](https://earthobservatory.nasa.gov/global-maps) using NASA satellite products. You can explore the dynamics of different components of the Earth system.\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: Land/Cryosphere – Snow Coverage**\n", - "\n", - "One of the most immediate effects of a warming planet is a reduction of snow coverage. Through long-term satellite data, we can accurately measure how the cryosphere has responded to changing temperature.\n", - "\n", - "For instance, we can answer questions such as:\n", - "\n", - "- Are there fewer days in which a region is covered by snow during the winter?\n", - "- Has the first day of snow coverage shifted for a specific region?\n", - "- Has the maximum snow coverage for a given region experienced any changes?\n", - "\n", - "The answers to these questions bear significant implications for local water availability, thereby influencing crucial areas such as agriculture, wildlife conservation, and energy consumption. \n", - "\n", - "![modis_snow](./asset/img/t1_modis_snow.gif \"segment\") |\n", - "-\n", - "\n", - "Credit: [NASA](https://earthobservatory.nasa.gov/global-maps/MOD10C1_M_SNOW)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: Land/Terrestrial Ecology – Vegetation Health**\n", - "\n", - "The global terrestrial ecosystem is highly regulated by the climatic conditions of different geographical regions. Long-term satellite data records allow us to map vegetation dynamics at relatively high spatial resolution (i.e., 1-5 km) frequently (i.e., daily to monthly). This data can help us answer questions about the impact of climate on ecosystems, both natural (e.g., forest and grassland) and human-modified (e.g., cropland) including:\n", - "\n", - "* Has the growing season of different ecosystems changed (e.g., lengthened or shortened) due to climate change?\n", - "* What's the impact of extreme events like drought, heatwave, wildfire, and flooding on different ecosystems?\n", - "* How much carbon does the ecosystem store?\n", - "\n", - "These applications have strong implications on communities through food security, culture activities, and other economic activities. \n", - "\n", - "![modis_ndvi](./asset/img/t1_modis_ndvi.gif \"segment\") |\n", - "-\n", - "\n", - "Credit: [NASA](https://earthobservatory.nasa.gov/global-maps/MOD_NDVI_M)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.3: Atmosphere – Cloud**\n", - "\n", - "Clouds are one of the most complex proceses of the climate system. With long-term satellite data, different aspects of this critical component can be studied. \n", - "\n", - "To study cloud processes, remotely sensed data can provide information about: \n", - "* When and where do clouds exist in the atmosphere?\n", - "* Physical properties of clouds (e.g., cloud height, cloud depth, cloud top temperature).\n", - "* Microphysical properties of clouds (e.g., cloud partical sizes).\n", - "\n", - "Clouds are one of the major sources of uncertainty in future climate projections. Satellite data is valuable to help us deepen our understanding of cloud processes to better incorporate the effects of clouds in climate models.\n", - "\n", - "![modis_cloud](./asset/img/t1_modis_cloud.gif \"segment\") |\n", - "-\n", - "\n", - "Cloud fraction, or the portion of a pixel covered by clouds. Credit: [NASA](https://earthobservatory.nasa.gov/global-maps/MODAL2_M_CLD_FR)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.4: Atmosphere – Rainfall**\n", - "\n", - "In addition to temperature change, rainfall is another important aspect of climate change which has notable impacts on society and natural systems, for example through droughts and floods.\n", - "\n", - "We can use remote sensing data to:\n", - "* Quantify the variations in rainfall rates across different regions over time. This information can support water resource planning and management to meet the needs of local communities.\n", - "* Investigate the frequency and potential causes of extreme rainfall events and examine their impacts on societal and natural systems. Examples include studying hurricanes and extreme rainfall events.\n", - "\n", - "![rainfall](./asset/img/t1_gpm_imerg_rainfall.gif \"segment\") |\n", - "-\n", - "\n", - "Credit: [NASA](https://earthobservatory.nasa.gov/global-maps/GPM_3IMERGM)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.5: Ocean – Sea Surface Temperature**\n", - "\n", - "Given that over 70% of the Earth's surface is covered by the ocean, the ocean plays a vital role in the functioning of the entire Earth system. Utilizing remotely sensed data, we can investigate changes in the physical ocean system and comprehend its impact on other interconnected systems.\n", - "\n", - "Here are some key points regarding the significance of sea surface temperature (SST) in this context:\n", - "- SST serves as a crucial indicator for monitoring global surface temperature changes. By analyzing SST data, we can gain insights into the overall warming or cooling trends of the Earth's surface.\n", - "- Monitoring SST is essential for studying large-scale ocean circulation and climate variability, such as the El Niño-Southern Oscillation (ENSO). Changes in SST patterns can provide valuable information about the occurrence and strength of ENSO events, which have significant impacts on global weather patterns.\n", - "- SST plays a pivotal role in the study and prediction of tropical cyclones. Warm SST provides the necessary energy for the formation and intensification of tropical cyclones, making SST data critical for understanding and forecasting these powerful storm systems.\n", - "\n", - "![modis_sst](./asset/img/t1_modis_sst.gif \"segment\") |\n", - "-\n", - "\n", - "Credit: [NASA](https://earthobservatory.nasa.gov/global-maps/MYD28M)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.6: Ocean/Marine Ecosystem – Chlorophyll**\n", - "\n", - "Similar to terrestrial ecosystems, remotely sensed data can be harnessed to monitor and study marine ecosystems. Within these ecosystems, **phytoplankton**, a diverse group of microorganisms, play a critical role in marine food webs, thus significantly impacting marine ecosystems and various human activities, including fisheries.\n", - "\n", - "Satellite data allows us to monitor changes in chlorophyll concentration, which serves as a proxy for the abundance of phytoplankton. This data enables exploration of important questions such as:\n", - "- How have phytoplankton populations changed in response to shifting sea surface temperatures in different ocean basins?\n", - "- By combining phytoplankton data with socioeconomic information, can we gain a comprehensive understanding of how the changing climate affects the fishing industry and the communities reliant on it.\n", - "\n", - "![modis_chl](./asset/img/t1_modis_chl.gif \"segment\") |\n", - "-\n", - "\n", - "Credit: [NASA](https://earthobservatory.nasa.gov/global-maps/MY1DMM_CHLORA)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you've explored the fundamental concepts of satellite remote sensing, equipping you with the knowledge to select appropriate remote sensing data for climate applications. Considerations such as spatial resolution and revisiting frequency were highlighted to ensure the optimal choice of data.\n", - "\n", - "You also delved into the potential applications of satellite remote sensing for climate studies across land, ocean, and atmosphere. Specifically, you examined how satellite data can be utilized to monitor and analyze snow coverage, vegetation health, cloud, temperature changes, rainfall patterns, sea surface temperature, and phytoplankton abundance. \n", - "\n", - "By understanding the capabilities and applications of satellite remote sensing, you are better equipped to leverage this technology for climate-related research, monitoring, and decision-making processes. This tutorial has laid the foundation for utilizing remote sensing data effectively in climate studies and emphasizes the vast potential it holds in advancing our understanding of Earth's climate system." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial1", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2.ipynb deleted file mode 100644 index a2ea4312f..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2.ipynb +++ /dev/null @@ -1,418 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 2: Exploring Satellite Climate Data Records**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will enhance your understanding of several key concepts and tools crucial in the field of satellite remote sensing for climate applications. Specifically, by the end of this session, you should be able to:\n", - "\n", - "- Grasp the principle of inter-satellite calibration, a critical step in creating reliable climate data records.\n", - "- Familiarize yourself with an array of long-term satellite remote sensing datasets that are tailored for climate applications, brought to you by three leading data providers: NOAA, NASA, and ESA.\n", - "- Navigate and utilize these datasets in your own climate-related studies or projects.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Video 1 Name\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Satellite Climate Data Records**\n", - "\n", - "You have already seen some examples of how satellite remote sensing data can be used for climate research and applications. But are all satellite data \"created equal\" for these purposes? There are a lot of considerations that need to be taken into account when using satellite data to monitor the long-term change of different components of the Earth system. In this section you will explore some of these considerations. Many of these are outlines in the definition of a climate data record given below.\n", - "\n", - "**Satellite Climate Data Records**\n", - "\n", - "In 2004, a committee convened by the US National Research Council defined a [***Climate Data Record (CDR)***](https://www.ncei.noaa.gov/products/climate-data-records) is \"a time series of measurements of sufficient length, consistency and continuity to determine climate variability and change.\" Although there are no specific number to determine the \"sufficient length\", the typical climate length is considered to be at least 30 years. To achieve a stable, consistent, and reliable satellite CDR, we need to carefully calibrate the raw satellite data. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Satellite Missions for Environmental Monitoring**\n", - "\n", - "When it comes to monitoring environmental and climate changes in a region using weather stations, we have confidence in the data quality due to regular inspections and maintenance of these stations and instruments. In North America and Europe, for instance, there are numerous weather stations that have been operating for over a century, providing reliable long-term data.\n", - "\n", - "In contrast, a single satellite mission has a **designed operational lifespan of 5-8 years**, and over time, the sensors on these satellites can deteriorate. While some satellites like Terra and Aqua have exceeded their designed lifespan and continue to operate successfully for more than 20 years, **relying on a single satellite for climate monitoring and applications is exceedingly challenging**, if not impossible.\n", - "\n", - "Thankfully, we have a range of satellite platforms at our disposal that operate continuously and carry similar remote sensors, making it feasible to utilize multiple satellites together for climate-related purposes. Since the 1970s, dozens of satellites, including both polar-orbiting and geostationary satellites, have been designed for weather and environmental monitoring. While not originally intended for climate studies, researchers have developed methods to merge data from various satellite platforms, enabling the creation of robust long-term time series of satellite data. Moreover, future satellite missions are being carefully designed to extend these data records further.\n", - "\n", - "The image below illustrates a timeline showcasing a selection of polar-orbiting satellite missions whose data are commonly employed to generate satellite Climate Data Records (CDRs). \n", - "\n", - "![satellite_timeline](./asset/img/t2_satellite_timeline.png)\n", - "\n", - "Credit: Douglas Rao" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The above figure shows the variety of satellite lifespans - some satellites only operated 3-5 years while there are a handful of satellite missions that operated for more than 15 years. Most importantly, we usually have at least two satellite missions operating during the same time period.\n", - "\n", - "The overlap among satellite missions is critical for generating satellite CDRs, as we can compare the data during the overlapping time period and account for the systematic differences between satellite missions.\n", - "\n", - "Meanwhile, there is significant technological advancement in remote sensors aboard different satellite missions. These different generations of remote sensors are identified by the solid grey lines in the figure. As indicated in the figure above, we have seen three major upgrades in sensor technologies. **NOTE: these sensor changes also need to be accounted for when creating satellite CDRs.**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Inter-satellite Calibration**\n", - "\n", - "As noted in the previous section, the change in satellite missions and remote sensors make it hard to use remotely sensed data \"as it is\" for climate applications. These changes often cause systematic differences in raw satellite data (see image below).\n", - "\n", - "This figure is exagerating the possible systematic differences between raw data collected by different satellite missions. Nonetheless, **these systematic differences can often cause large uncertainty for climate science when not addressed properly.**\n", - "\n", - "![t2_calibration](./asset/img/t2_calibration_pt1.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To address the differences that are caused by sensor and satellite changes, we often perform an **inter-satellite calibration** - which adjusts the raw data collected by different satellites to a pre-defined reference to remove or minimize the systematic difference between data. This pre-defined reference is usually determined using data during there perioud of time when the satellites overlap (see image below). But we can also use other high quality reference data like surface observations, theoretical bases, or other ancillary data. Click [here](https://www.eumetsat.int/inter-calibration) for more information on **inter-satellite calibration**.\n", - "\n", - "![t2_calibration_pt2](./asset/img/t2_calibration_pt2.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "A **well-calibrated multi-satellite date record** is often assessed by examining the differences between satellite data during the overlapping time period. Once we are confident that the differences are minimal or within an accepted range, the long term time series based on multiple satellites can be used for climate applications.\n", - "\n", - "The inter-satellite calibration step is the key to ensure that climate signals can be accurately reflected in the satellite data and not affected by the noise caused by change in satellite platforms and sensors. Therefore, when you are choosing satellite data for climate applications, you should be asking yourself a few questions:\n", - "\n", - "* Are the data that you are planning to use collected by the same sensor and satellite?\n", - "* If the data are from multiple satellites/sensors, are there steps to ensure the data are consistent across difference satellites/sensors?\n", - "* Can you find out how the inter-satellite calibration is done and what is the level of difference between satellites/sensors?\n", - "\n", - "These questions will help you determine if the remotely sensed data is appropriate for climate applications that you are interested in.\n", - "\n", - "![t2_calibration_pt3](./asset/img/t2_calibration_pt3.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2: Climate Connection**\n", - "\n", - "Assuming that you are interested in using remote sensing data to understand how the rainfall amount and frequency have changed for the region that you are in since 1990. There are three different satellite data that you can choose from:\n", - "\n", - "* _Option A_: Data from the most recent satellite missions designed to monitor global precipitation. The satellite has the most accurate sensor and the satellite was launched in 2014. \n", - "* _Option B_: Data from three different satellite missions that carry similar sensors (first satellite: 1985-1994; second satellite: 1992-2006; third satellite: 2003-present).\n", - "* _Option C_: Data from the three different satellite missions described in _Option B_ that has been calibrated using long term surface measurements of rainfall in your region. \n", - "\n", - "Can you choose the best data for your application? Why would you make this choice? Do you need more information to make the decision?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial2_Solution_1c4dc0c2.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Finding Satellite Climate Data Records**\n", - "\n", - "Finding the right satellite Climate Data Records (CDRs) for your desired application can be a challenge. In this section, we will explore satellite data from three major remote sensing data providers: the **National Atmospheric and Oceanic Administration (NOAA), the National Aeronautics and Space Administration (NASA), and the European Space Agency (ESA)**. While we won't cover the code to analyze the data in this tutorial, you will learn how to do that in the upcoming tutorials.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: NOAA Climate Data Records**\n", - "\n", - "The **National Atmospheric and Oceanic Administration (NOAA)** implemented the recommendation from the US National Research Council to develop satellite-based climate data records in the 2000s, and they have maintained a suite of operational CDRs that can be used to study different aspects of the changing climate system since then.\n", - "\n", - "All NOAA CDR data are available freely to the public via [NOAA National Centers for Environmental Information](https://www.ncei.noaa.gov/products/climate-data-records). Recently, the [NOAA Open Data Dissemination Program](https://www.noaa.gov/information-technology/open-data-dissemination) also made all NOAA CDRs available on three major commercial cloud service providers (i.e., Amazon Web Service, Google Cloud, and Microsoft Azure). The NOAA Climate Data Records (CDRs) are available to anyone interested in accessing the data and are typically free of charge.\n", - "\n", - "NOAA CDRs have two different categories with different purposes:\n", - "\n", - "* _Fundamental CDR (FCDR)_: This category consists of high-quality, low-level processed satellite sensor data, such as reflectance and brightness temperature. The FCDR datasets are carefully calibrated between satellites and sensors to ensure accuracy and consistency. These datasets are primarily used to assess and improve Earth system models (which you will learn about next week).\n", - "* _Thematic CDR_: Thematic CDRs provide valuable information for understanding climate processes and changes in various domains. The thematic CDRs are divided into terrestrial, atmospheric, and ocean categories to reflect the different components of the climate system.\n", - "\n", - "The table below lists a selection of thematic CDRs operates by NOAA. You can find out more about all NOAA CDRs by visiting the specific webpage of each CDR categories:\n", - "\n", - "* [Fundamental CDR](https://www.ncei.noaa.gov/products/climate-data-records/fundamental) - 16 datasets\n", - "* [Thematic CDR: Terrestrial](https://www.ncei.noaa.gov/products/climate-data-records/terrestrial) - 4 datasets\n", - "* [Thematic CDR: Atmospheric](https://www.ncei.noaa.gov/products/climate-data-records/atmospheric) - 18 datasets\n", - "* [Thematic CDR: Oceanic](https://www.ncei.noaa.gov/products/climate-data-records/oceanic) - 5 datasets" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "| Dataset | Category | Start Year | Frequency | Spatial Resolution | Example Application Areas |\n", - "|:--|:--:|:--:|:--:|:--:|:--|\n", - "|Leaf Area Index and FAPAR|Terrestrial|1981|Daily|0.05°| Vegetation status monitoring; Agriculture monitoring; Crop yield/food security|\n", - "|Normalized Difference Vegetation Index (NDVI)|Terrestrial|1981|Daily|0.05°|Vegetation status monitoring; Vegetation phenology study|\n", - "|Snow Cover Extent (Northern Hemisphere)|Terrestrial|1966|Weekly (prior 1999-06)

Daily (post 1999-06)|~190 km| Hydrology; Water resources; Snow-climate feedback|\n", - "|Aerosol Optical Thickness|Atmospheric|1981|Daily & Monthly|0.1°|Air quality; Aerosol-climate feedback|\n", - "|PATMOS-x Cloud Properties|Atmospheric|1979|Daily|0.1°|Cloud process; Cloud-climate feedback|\n", - "|Precipitation - PERSIANN|Atmospheric|1982|Daily|0.25°

(60°S–60°N)|Hydrology; Water resources; Extreme events|\n", - "|Sea Surface Temperature - Optimum Interpolation|Oceanic|1981|Daily|0.25°|Climate variability; Marine heatwave; Marine ecosystem|\n", - "|Sea Ice Concentration|Oceanic|1978|Daily & Monthly|25 km|Crosphere study; Wildlife conservation; Ocean/climate modeling|" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: ESA Climate Change Initiative**\n", - "\n", - "The **European Space Agency (ESA)** initiated a similar effort to develop consistent satellite-based long-term records to support the mission of climate monitoring for societal benefits in late 2010s. **[ESA Climate Change Initiative (CCI)](https://climate.esa.int/en/esa-climate/esa-cci/)** has established more than 26 projects to develop satellite-based CDRs and directly engage with downstream users.\n", - "\n", - "Through CCI, there is very strong emphasis on applications to support the monitoring of [**essential climate variables** (ECVs) defined by Global Climate Observing System (GCOS)](https://public.wmo.int/en/programmes/global-climate-observing-system/essential-climate-variables). An ECV is defined as \"a physical, chemical or biological variable or a group of linked variables that critically contributes to the characterization of Earth’ s climate.\"\n", - "\n", - "The table below lists a selection of ESA CCI datasets and their example application areas." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "| Dataset | Category | Duration | Frequency | Spatial Resolution | Example Application Areas |\n", - "|:--|:--:|:--:|:--:|:--:|:--|\n", - "|Sea Level|Oceanic|1992-2015|Monthly|0.25°|Sea level rise; Ocean modeling|\n", - "|Water Vapor|Atmospheric|1985-2019|Monthly|5°|Water vapor-climate feedback; Hydrology|\n", - "|Fire|Terrestrial|1981-2020|Monthly|0.05° (pixel dataset)

0.25° (grid dataset)|Ecosystem disturbance; Extreme events; Social impact|\n", - "|Land Cover|Terrestrial|1992-2020|Yearly|300 m|Terrestrial modeling|\n", - "|Soil Moisture|Terrestrial|1978-2021|Daily|0.25°|Hydrology; Ecosystem impacts; Extreme events|" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You may observe that some datasets do not span the typical duration necessary for climate studies (for instance, 30 years). This occurrence is influenced by a variety of factors such as:\n", - "\n", - "- Legacy sensors were not designed or capable of accurately capturing the ECVs of interest.\n", - "- The CCI project is executed in stages, initiating with the most recent satellite missions/sensors. However, plans are underway to incorporate older data from heritage satellite missions/sensors.\n", - "\n", - "Moreover, each ESA CCI project frequently offers different versions of ECV variables, each designed for specific applications. The specifications of these ECV variables might deviate from the table above if they represent a subset of the time period, utilizing data from the latest sensors. The table primarily provides information on the longest time record for each CCI.\n", - "\n", - "All ESA CCI data are openly accessible and free of charge to users without any restrictions. All these resources can be accessed via the [**ESA CCI Open Data Portal**](https://climate.esa.int/en/odp/#/dashboard).\n", - "\n", - "To further assist users in accessing and analyzing the CCI data, ESA has also developed the [**CCI Analysis Toolbox (Cate)**](https://climate.esa.int/en/explore/analyse-climate-data/). It is described as a \"cloud-enabled computing environment geared for scientists who need to analyze, process, and visualize ESA’s climate data and other spatiotemporal data.\"\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.3: NASA Earth System Data Records**\n", - "\n", - "Similar to other two satellite data providers, the **National Aeronautics and Space Administration (NASA)** also produces and distributes long-term satellite-based data records that may be suitable for different climate applications. NASA [Earth System Data Records (ESDRs)](https://www.earthdata.nasa.gov/esds/competitive-programs/measures?page=0) are defined as \"as a unified and coherent set of observations of a given parameter of the Earth system, which is optimized to meet specific requirements in addressing science questions.\"\n", - "\n", - "While NASA's ESDR does not specifically target climate, these records are often created to monitor and study various components of the climate system. For instance, surface temperature, global forest coverage change, atmospheric compositions, and ice sheet velocity are all areas of focus.\n", - "\n", - "The table below showcases a selection of NASA ESDRs datasets that nicely complement the satellite Climate Data Records (CDRs) offered by NOAA and ESA." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "| Dataset | Category | Duration | Frequency | Spatial Resolution | Example Application Areas |\n", - "|:--|:--:|:--:|:--:|:--:|:--|\n", - "|[Sulfur Dioxide](https://www.earthdata.nasa.gov/esds/competitive-programs/measures/multi-decadal-sulfur-dioxide)|Atmospheric|1978-2022|Daily|50 km|Atmospheric modeling; Air quality|\n", - "|[Ozone](https://disc.gsfc.nasa.gov/datasets/MSO3L3zm5_1/summary)|Atmospheric|1970-2013|Monthly|5°|Ozone monitoring; Air quality|\n", - "|[Sea Surface Height](https://podaac.jpl.nasa.gov/dataset/SEA_SURFACE_HEIGHT_ALT_GRIDS_L4_2SATS_5DAY_6THDEG_V_JPL2205)|Oceanic|1992-ongoing|5-Day|1/6°|Sea level rise; Ocean modeling|\n", - "|[GPCP Satellite-Gauge Combined Precipitation Data](https://disc.gsfc.nasa.gov/datasets/GPCPMON_3.2/summary)|Atmospheric|1983-2020|Daily & Monthly|0.5°|Hydrology; Extreme events|" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "If you've visited the linked NASA ESDR page above, you may have noticed that it appears less structured compared to the NOAA CDR program and the ESA CCI open data portal. This is partly because NASA operates different data centers for distinct application areas (e.g., atmosphere, snow/ice, land, etc.). However, you can always visit [**NASA's Earth Data Search**](https://search.earthdata.nasa.gov/search) – a comprehensive portal for accessing datasets provided by NASA's Earth science data system. To access the data, you'll be required to create a user account. Rest assured, registration for the NASA Earthdata system is free and open to anyone." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.3: Climate Connection**\n", - "Now that you have been introduced to three major sources of remote sensing data for climate applications, it's time to identify the dataset that best suits your requirements. In this exercise, you can choose one or more data providers (NASA, NOAA, ESA) and explore their satellite data to determine which one aligns best with your application needs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "### Step 1: Describe your application interest. Be as specific as you can, this\n", - "### will help you narrow down your search for the data\n", - "\"\"\"\n", - "\n", - "\"\"\"\n", - "### Step 2: Identify an ideal spatial and temporal resolution for your application\n", - "### (e.g., daiyl/weekly/monthly, 500 m/5 km/25 km/...?)\n", - "\"\"\"\n", - "\n", - "\"\"\"\n", - "### Step 3: Explore the data from one of the data providers to see if there is\n", - "### any data that can fit your application need and explain why\n", - "\"\"\"\n", - "\n", - "\"\"\"" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, we learned about \n", - "\n", - "* how **Inter-satellite calibration** is a critical step to produce a consistent remote sensing dataset for climate applications and allows us to use data from different satellites and sensors over different but overlappign time-periods.\n", - "* **major collections of satellite-based datasets** for climate applications, including NOAA Climate Data Records, ESA Climate Change Initiative, and NASA Earth System Data Records.\n", - "\n", - "In the upcoming tutorial, we will be transitioning towards exploring how to utilize computational tools to access publicly available remote sensing data for climate applications.\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial2", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3.ipynb deleted file mode 100644 index 02987dde9..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3.ipynb +++ /dev/null @@ -1,756 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 3: Visualizing Satellite CDR - Global Vegetation Mapping**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will acquire skills necessary for accessing and analyzing satellite remote sensing products, particularly in the context of climate applications. We will be using vegetation mapping as an example, and use long-term vegetation greeness data to demonstrate these skills.\n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Locate, access, and visualize vegetation greeness data (NDVI) from the cloud using `xarray` and `matplotlib`.\n", - "* Understand how to use quality flag information included in the datasets to filter out data that is not acceptable to use for climate analysis.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !pip install s3fs --quiet\n", - "# !pip install cartopy --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import s3fs\n", - "import numpy as np\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import datetime\n", - "import boto3\n", - "import botocore\n", - "import pooch\n", - "import os\n", - "import tempfile" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Video 1 Name\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=\"\", filename=\"\"):\n", - " shared_location = \"/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Satellite Monitoring of Vegetation Status**\n", - "\n", - "As we learned in the previous tutorial, all the **National Atmospheric and Oceanic Administration Climate Data Record (NOAA-CDR)** datasets are available both at NOAA National Centers for Environmental Information (NCEI) and commercial cloud platforms. Here, we are accessing the data directly via the **Amazon Web Service (AWS)**. You can find out information about the NOAA CDRs on AWS's Open Data Registry.\n", - "\n", - "* [NOAA Fundamental CDR on AWS](https://registry.opendata.aws/noaa-cdr-fundamental/) \n", - "* [NOAA Terrestrial CDR on AWS](https://registry.opendata.aws/noaa-cdr-terrestrial/) \n", - "* [NOAA Atmospheric CDR on AWS](https://registry.opendata.aws/noaa-cdr-atmospheric/) \n", - "* [NOAA Oceanic CDR on AWS](https://registry.opendata.aws/noaa-cdr-oceanic/) \n", - "\n", - "The index we will use in this tutorial is the **Normalized Difference Vegetation Index (NDVI)**. It is one of the most commonly used remotely sensed indices. It measures the \"greeness\" of vegetation, and is useful in understanding vegetation density and assessing changes in plant health. For example, NDVI can be used to study the impact of drought, heatwave, and insect infestation on plants covering Earth's surface." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Access NOAA NDVI CDR Data from AWS**\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "If we go to the [cloud storage space (or a S3 bucket)](https://noaa-cdr-ndvi-pds.s3.amazonaws.com/index.html#data/) that hosts NOAA NDVI CDR data, you will see the pattern of how the NOAA NDVI CDR is organized:\n", - "\n", - "`s3://noaa-cdr-ndvi-pds/data/1981/AVHRR-Land_v005_AVH13C1_NOAA-07_19810624_c20170610041337.nc`\n", - "\n", - "We can take advantage of the pattern to search for the data file systematically. \n", - "\n", - "> Parent directory: `s3://noaa-cdr-ndvi-pds/data/` \n", - "> Sub-directory for each year: `1981/` \n", - "> File name of each day: `AVHRR-Land_v005_AVH13C1_NOAA-07_19810624_c20170610041337.nc`\n", - "\n", - "The file name also has a clear pattern:\n", - "\n", - "> Sensor name: `AVHRR` \n", - "> Product category: `Land` \n", - "> Product version: `v005` \n", - "> Product code: `AVH13C1` \n", - "> Satellite platform: `NOAA-07` \n", - "> Date of the data: `19810624` \n", - "> Processing time: `c20170610041337` (*This will change for each file based on when the file was processed*) \n", - "> File format: `.nc` (*netCDR-4 format*)\n", - "\n", - "In other words, if we are looking for the data of a specific day, we can easily locate where the file might be. \n", - "\n", - "For example, if we want to find the AVHRR data for the day of *2002-03-12 (or March 12, 2002)*, you can use:\n", - "\n", - "`s3://noaa-cdr-ndvi-pds/data/2002/AVHRR-Land_v005_AVH13C1_*_20020312_c*.nc`\n", - "\n", - "The reasaon that we put `*` in the above directory is because we are not sure about what satellite platform this data is from and when the data was processed. The `*` is called a **wildcard**, and is used because we want *all* the files that contain our specific criteria, but do not want to have to specify all the other pieces of the filename we are not sure about yet. It should return all the data satisfying that initial criteria and you can refine further once you see what is available. Essentially, this first step helps to narrow down the data search." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# to access the NDVI data from AWS S3 bucket, we first need to connect to s3 bucket\n", - "fs = s3fs.S3FileSystem(anon=True)\n", - "\n", - "# we can now check to see if the file exist in this cloud storage bucket using the file name pattern we just described\n", - "date_sel = datetime.datetime(\n", - " 2002, 3, 12, 0\n", - ") # select a desired date and hours (midnight is zero)\n", - "\n", - "# automatic filename from data_sel. we use strftime (string format time) to get the text format of the file in question.\n", - "file_location = fs.glob(\n", - " \"s3://noaa-cdr-ndvi-pds/data/\"\n", - " + date_sel.strftime(\"%Y\")\n", - " + \"/AVHRR-Land_v005_AVH13C1_*\"\n", - " + date_sel.strftime(\"%Y%m%d\")\n", - " + \"_c*.nc\"\n", - ")\n", - "# now let's check if there is a file match the pattern of the date that we are interested in.\n", - "file_location" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 1.1**\n", - "\n", - "1. NDVI CDR data switched sensors on 2014 from AVHRR (the older generation sensor) to VIIRS (the newest generation sensor). Using the code above and the [list of data names](https://noaa-cdr-ndvi-pds.s3.amazonaws.com/index.html#data/) for VIIRS, find data from a day after 2014. You will need to modify string input into `glob()` to do so." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Choose identify the location of the NDVI CDR data on Amazon Web Service for a day after 2014.\"\n", - ")\n", - "#################################################\n", - "\n", - "# select a desired date and hours (midnight is zero)\n", - "exercise_date_sel = ...\n", - "\n", - "# automatic filename from data_sel. we use strftime (string format time) to get the text format of the file in question.\n", - "exercise_file_location = ...\n", - "\n", - "# now let's check if there is a file match the pattern of the date that we are interested in.\n", - "exercise_file_location" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial3_Solution_e65ad8b4.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Read NDVI CDR Data**\n", - "\n", - "Now that you have the location of the NDVI data for a specific date, you can read in the data using the python library `xarray` to open the [netCDF-4 file](https://pro.arcgis.com/en/pro-app/latest/help/data/multidimensional/what-is-netcdf-data.htm), a common data format used to store satellite and climate datasets.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# first, we need to open the connection to the file object of the selected date.\n", - "# we are still using the date of 2002-03-12 as the example here.\n", - "\n", - "# to keep up with previous tutorials (consistency), we are going to use boto3 and pooch to open the file.\n", - "# but note s3fs also has the ability to open files from s3 remotely.\n", - "\n", - "client = boto3.client(\n", - " \"s3\", config=botocore.client.Config(signature_version=botocore.UNSIGNED)\n", - ") # initialize aws s3 bucket client\n", - "\n", - "ds = xr.open_dataset(\n", - " pooch_load(\n", - " filelocation=\"http://s3.amazonaws.com/\" + file_location[0],\n", - " filename=file_location[0],\n", - " )\n", - ") # open the file\n", - "ds" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The output from the code block tells us that the NDVI data file of 2002-03-12 has dimensions of `3600x7200`. This makes sense for a dataset with the spatial resolution of 0.05°×0.05° that spans 180° of latitude and 360° of longitude. There is another dimension of the dataset named `time`. Since it is a daily data file, it only contains one value.\n", - "\n", - "Two main data variables are in this dataset are `NDVI` and `QA`.\n", - "\n", - "* `NDVI` is the variable that contains the value of Normalized Difference Vegetation Index (NDVI - ranges between -1 and 1) that can be used to measure the vegetation greeness. \n", - "* `QA` is the variable that indicates the quality of the NDVI values for each corresponding grid. It reflects whether the data is of high quality or should be discarded because of various reasons (e.g., bad sensor data, potentially contanminated by clouds).\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.3: Visualize NDVI CDR Data**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# examine NDVI values from the dataset\n", - "ndvi = ds.NDVI\n", - "ndvi" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "To visualize the raw data, we will will plot it using `matplotlib` by calling `.plot()` on our xarray `DataArray`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# figure settings:\n", - "# vmin & vmax: minimum and maximum values for the legend\n", - "# aspect: setting the aspect ratio of the figure, must be combined with `size`\n", - "# size: setting the overall size of the figure\n", - "\n", - "# to make plotting faster and less memory intesive we use coarsen to reduce the number of pixels\n", - "ndvi.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(\n", - " vmin=-0.1, vmax=1.0, aspect=1.8, size=5\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.4: Mask NDVI Data Using a Quality Flag**\n", - "\n", - "As stated earlier, there is also a variable `QA` that indicates the quality of the NDVI value for each grid cell. This quality information is very important when using satellite data to ensure the climate analysis is done using only the highest quality data.\n", - "\n", - "For NDVI CDR data, it has a complex quality flag system that is represented using a 16-bit system. Although when you explore the values of `QA`,= it appears to be normal numeric values, the QA value needs to be converted to binary values of 16 bits and recognize the quality flag based on the information listed in the table below. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "| Bit No. | Description | Value=1 | Value=0 |\n", - "|-:|:-|:-:|:-:|\n", - "|15|Flag to indicate if the pixel is in polar region|Yes|No|\n", - "|14|Flag to indicate BRDF-correction issues|Yes|No|\n", - "|13|Flag to indicate RH03 value is invalid|Yes|No|\n", - "|12|Flag to indicate AVHRR Channel 5 value is invalid|Yes|No|\n", - "|11|Flag to indicate AVHRR Channel 4 value is invalid|Yes|No|\n", - "|10|Flag to indicate AVHRR Channel 3 value is invalid|Yes|No|\n", - "| 9|Flag to indicate AVHRR Channel 2 value is invalid|Yes|No|\n", - "| 8|Flag to indicate AVHRR Channel 1 value is invalid|Yes|No|\n", - "| 7|Flag to indicate all 5 AVHRR Channels are valid|Yes|No|\n", - "| 6|Flag to indicate the pixel is at night (no visible channel data)|Yes|No|\n", - "| 5|Flag to indicate the pixel is over dense dark vegetation|Yes|No|\n", - "| 4|Flag to indicate the pixel is over sunglint (over ocean)|Yes|No|\n", - "| 3|Flag to indicate the pixel is over water|Yes|No|\n", - "| 2|Flag to indicate the pixel contains cloud shadow|Yes|No|\n", - "| 1|Flag to indicate the pixel is cloudy|Yes|No|\n", - "| 0|(Unused)|Yes|No|" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This shows the complex system to ensure that satellite CDR data is of high quality for climate applications. But how can we decifer the quality of a given pixel? \n", - "\n", - "Assuming that we have a grid with `QA=18`, when converted into a binary value with the length of 16 bits it becomes `0000000000010010`. That is, every `QA` value will be convereted into a list of 1's and 0's that is 16 numbers long. Converting our example above of 18 we have:\n", - "\n", - "|Bit15|Bit14|Bit13|Bit12|Bit11|Bit10|Bit9|Bit8|Bit7|Bit6|Bit5|Bit4|Bit3|Bit2|Bit1|Bit0|\n", - "|-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|-:|\n", - "|0|0|0|0|0|0|0|0|1|0|0|1|0|0|1|0|\n", - "|No|No|No|No|No|No|No|No|Yes|No|No|Yes|No|No|Yes|No|\n", - "\n", - "Note here that 1 is `True` and 0 is `False`. Interpreting the table above, for a quality flag of 18, the NDVI is retrieved from valid values of AVHRR channels (`Bit7=1`) and the grid is over dense dark vegetation (`Bit5=1`), but the grid is cloudy (`Bit1=1`). Therefore, the QA tells us that we should not use this grid since it is covered by clouds and does not reflect vegetation information on the land surface. \n", - "\n", - "If you are a little confused by how to convert to binary, that is ok! This is a skill that you can practice more in your projects. For this tutorial, we will define a function that will automate our selection process of avoiding cloudy data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# define a function to extract high quality NDVI data\n", - "def get_quality_info(QA):\n", - " \"\"\"\n", - " QA: the QA value read in from the NDVI data\n", - "\n", - " High quality NDVI should meet the following criteria:\n", - " Bit 7: 1 (All AVHRR channels have valid values)\n", - " Bit 2: 0 (The pixel is not covered by cloud shadow)\n", - " Bit 1: 0 (The pixel is not covered by cloud)\n", - "\n", - " Output:\n", - " True: high quality\n", - " False: low quality\n", - " \"\"\"\n", - " # unpack quality assurance flag for cloud (byte: 1)\n", - " cld_flag = (QA % (2**2)) // 2\n", - " # unpack quality assurance flag for cloud shadow (byte: 2)\n", - " cld_shadow = (QA % (2**3)) // 2**2\n", - " # unpack quality assurance flag for AVHRR values (byte: 7)\n", - " value_valid = (QA % (2**8)) // 2**7\n", - "\n", - " mask = (cld_flag == 0) & (cld_shadow == 0) & (value_valid == 1)\n", - "\n", - " return mask" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# get the quality assurance value from NDVI data\n", - "QA = ds.QA\n", - "\n", - "# create the high quality information mask\n", - "mask = get_quality_info(QA)\n", - "\n", - "# check the quality flag mask information\n", - "mask" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The output of the previous operation gives us a data array with logical values to indicate if a grid has high quality NDVI values or not. Now let's mask out the NDVI data array with this quality information to see if this will make a difference in the final map." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# use `.where` to only keep the NDVI values with high quality flag\n", - "ndvi_masked = ndvi.where(mask)\n", - "ndvi_masked" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As you may have noticed, a lot of the NDVI values in the masked data array becomes `nan` which means `not a number`. This means that the grid does not have a high quality NDVI value based on the QA value. Now, let's plot the map one more time to see the difference after the quality masking." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# re-plot the NDVI map using masked data\n", - "ndvi_masked.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(\n", - " vmin=-0.1, vmax=1.0, aspect=1.8, size=5\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Note the large difference after the quality mask was applied and you removed data that was compromised due to clouds. Since the NDVI value is calculated using the reflectance values of the red and near-infrared spectral band, this value is only useful for vegetation and surface monitoring when there are no clouds present. Thus, we always need to remove the grid with clouds in the data." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 1.4**\n", - "\n", - "You just learned how to use `xarray` and `matplotlib` to access NDVI CDR data from AWS and visualize it. Can you find a different date that you are interested in and visualize the high quality NDVI data of that day? Note the solution is just an example of a date that you could choose." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Access and plot NDVI for a date of your choosing.\"\n", - ")\n", - "#################################################\n", - "\n", - "# define the date of your interest YYYYMMDD (e.g., 20030701)\n", - "# select a desired date and hours (midnight is zero)\n", - "date_sel_exercise = ...\n", - "\n", - "# locate the data in the AWS S3 bucket\n", - "# hint: use the file pattern that we described\n", - "file_location_exercise = ...\n", - "\n", - "# open file connection to the file in AWS S3 bucket and Use xarray to open the NDVI CDR file\n", - "# open the file\n", - "ds_exercise = ...\n", - "\n", - "# get the QA value and extract the high quality data mask and Mask NDVI data to keep only high quality value\n", - "# hint: reuse the get_quality_info helper function we defined\n", - "ndvi_masked_exercise = ...\n", - "\n", - "# plot high quality NDVI data\n", - "# hint: use plot() function\n", - "ndvi_masked_exercise.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(\n", - " vmin=-0.1, vmax=1.0, aspect=1.8, size=5\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial3_Solution_0cc0bf14.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you successfully accessed and visualized one of the most commonly used remotely sensed climate datasets for land applications! In addition, you should now:\n", - "\n", - "* Understand the file organization pattern to help you identify the data that you are interested in.\n", - "* Understand thow to extract only the high quality data using quality flags provided with the datasets.\n", - "* Know how to apply a quality flag mask and plot the resulting data.\n", - "\n", - "In the next tutorial, you will explore how to perform time series analysis, including calculating a climatology and anomaly with precipitation data.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Data from this tutorial can be accessed [here](https://noaa-cdr-ndvi-pds.s3.amazonaws.com/index.html#data/)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial3", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4.ipynb deleted file mode 100644 index c2a2acabc..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4.ipynb +++ /dev/null @@ -1,942 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 4: Understanding Climatology Through Precipitation Data**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will explore the concept of a climatology, and learn how to leverage it using satellite precipitation data. You have already practiced how to calcuate a climatology using temperature data in the overview of the climate system day. That data spanned only 14 years, and typically you would want your data to span at least 30 years to calculate a climatology. Here you will use data spanning several decades to explore the seasonal cycle of precpitation at a specific location.\n", - "\n", - "Upon completing this tutorial, you'll be able to:\n", - "\n", - "- Comprehend the fundamentals of climatologies.\n", - "- Compute a climatology utilizing long-term satellite precipitation data.\n", - "- Create informative maps including features such as projections, coastlines, and other advanced plotting components.\n", - "\n", - "Throughout this tutorial, you'll employ NOAA's monthly precipitation climate data records as the primary resource to demonstrate the process of calculating a long-term climatology for climate analysis. Specifically, you'll use the [Global Precipitation Climatology Project (GPCP) Monthly Precipitation Climate Data Record (CDR)](https://www.ncei.noaa.gov/products/climate-data-records/precipitation-gpcp-monthly). As part of your investigation, you'll focus on a specific location, observing its data across the entire time duration covered by the GPCP monthly dataset." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !pip install s3fs --quiet\n", - "\n", - "# properly install cartopy in colab to avoid session crash\n", - "# !apt-get install libproj-dev proj-data proj-bin --quiet\n", - "# !apt-get install libgeos-dev --quiet\n", - "# !pip install cython --quiet\n", - "# !pip install cartopy --quiet\n", - "\n", - "# !apt-get -qq install python-cartopy python3-cartopy --quiet\n", - "# !pip uninstall -y shapely --quiet\n", - "# !pip install shapely --no-binary shapely --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import s3fs\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import boto3\n", - "import botocore\n", - "import pooch\n", - "import os\n", - "import tempfile" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Video 1 Name\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=\"\", filename=\"\"):\n", - " shared_location = \"/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Obtain Monthly Precipitation Data**\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this tutorial, the objective is to demonstrate how to calculate the long-term precipitation climatology using monthly precipitation climate data records from NOAA. \n", - "\n", - "You'll be utilizing the [Global Precipitation Climatology Project (GPCP) Monthly Precipitation Climate Data Record (CDR)](https://www.ncei.noaa.gov/products/climate-data-records/precipitation-gpcp-monthly). This dataset contains monthly satellite-gauge data and corresponding precipitation error estimates from January 1979 to the present, gridded at a 2.5°×2.5° resolution. *Satellite-gauge* means that the climate data record (CDR) is a compilation of precipitation data from multiple satellites and in-situ sources, combined into a final product that optimizes the advantages of each type of data.\n", - "\n", - "While a higher spatial resolution (1°×1°) at daily resolution exists for varied applications, we will restrict ourselves to the coarser resolution monthly data due to computational limitations. However, you are encouraged to delve into the daily higher resolution data for your specific project needs.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Access GPCP Monthly CDR Data on AWS**\n", - "\n", - "To perform analysis, we will need to access the monthly data files from AWS first. We will use the skills that we learned from last tutorial on accessing data from an AWS S3 bucket." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# connect to the AWS S3 bucket for the GPCP Monthly Precipitation CDR data\n", - "fs = s3fs.S3FileSystem(anon=True)\n", - "\n", - "# get the list of all data files in the AWS S3 bucket fit the data file pattern.\n", - "file_pattern = \"noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc\"\n", - "file_location = fs.glob(file_pattern)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "print(\"Total number of GPCP Monthly precipitation data files:\")\n", - "print(len(file_location))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We have more than 500 GPCP monthly precipitation CDR data files in the AWS S3 bucket. Each data file contains the data of each month globally starting from January 1979. Now, let's open a single data file to look at the data structure before we open all data files." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# first, open a client connection\n", - "client = boto3.client(\n", - " \"s3\", config=botocore.client.Config(signature_version=botocore.UNSIGNED)\n", - ") # initialize aws s3 bucket client\n", - "\n", - "# read single data file to understand the file structure\n", - "# ds_single = xr.open_dataset(pooch.retrieve('http://s3.amazonaws.com/'+file_location[0],known_hash=None )) # open the file\n", - "ds_single = xr.open_dataset(\n", - " pooch_load(\n", - " filelocation=\"http://s3.amazonaws.com/\" + file_location[0],\n", - " filename=file_location[0],\n", - " )\n", - ")\n", - "# check how many variables are inluded in one data file\n", - "ds_single.data_vars" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "From the information provided by `xarray`, there are a total of five data variables in this monthly data file, including `precip` for the monthly precipitation and `precip_error` for the monthly precipitation error.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# check the coordinates for the data file\n", - "ds_single.coords" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "All data is organized in three dimensions: `latitude`, `longitude`, and `time`. We want to create a three-dimensional data array for the monthly precipitation data across the entire data period (from January 1979 until present) so we must open all the available files" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# open all the monthly data files\n", - "# this process will take ~ 5 minute to complete due to the number of data files.\n", - "\n", - "# file_ob = [pooch.retrieve('http://s3.amazonaws.com/'+file,known_hash=None ) for file in file_location]\n", - "file_ob = [\n", - " pooch_load(filelocation=\"http://s3.amazonaws.com/\" + file, filename=file)\n", - " for file in file_location\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# using this function instead of 'open_dataset' will concatenate the data along the dimension we specify\n", - "ds = xr.open_mfdataset(file_ob, combine=\"nested\", concat_dim=\"time\")\n", - "ds" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In the above code, we used `combine='nested', concat_dim='time'` to combine all monthly precipitation data into one data array along the dimension of `time`. This command is very useful when reading in multiple data files of the same structure but covering different parts of the full data record.\n", - "\n", - "Since we are interested in the precipitation data globally at this moment, let's extract the entire data array of precipitation from the entire dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# examine the precipitation data variable\n", - "precip = ds.precip\n", - "precip" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As you can see, the data array has the dimensions of `time` `longitude` `latitude`. Before delving into further analysis, let's visualize the precipitation data to gain a better understanding of its patterns and characteristics. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Visualize GPCP Data Using Cartopy**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In previous tutorials, we've learned how to make simple visualization using `matplotlib` using `latitude` and `longitude` as the y-axis and x-axis." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# create simple map of the GPCP precipitation data using matplotlib\n", - "fig, ax = plt.subplots(figsize=(9, 6))\n", - "\n", - "# use the first month of data as an example\n", - "precip.sel(time=\"1979-01-01\").plot(ax=ax)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "From the figure, the boundary between land and ocean, especially for North and South America, can be observed vaguely. However, this visualization is not ideal as it requires some guesswork in identifying the specific regions. To overcome this limitation and enhance the visualization, we will employ `cartopy`, a library that offers advanced mapping features. With `cartopy`, we can incorporate additional elements such as coastlines, major grid markings, and specific map projections." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# visualize the precipitation data of a selected month using cartopy\n", - "\n", - "# select data for the month of interest\n", - "data = precip.sel(time=\"1979-01-01\", method=\"nearest\")\n", - "\n", - "# initate plot with the specific figure size\n", - "fig, ax = plt.subplots(subplot_kw={\"projection\": ccrs.Robinson()}, figsize=(9, 6))\n", - "\n", - "# add coastal lines to indicate land/ocean\n", - "ax.coastlines()\n", - "\n", - "# add major grid lines for latitude and longitute\n", - "ax.gridlines()\n", - "\n", - "# add the precipitation data with map projection transformation\n", - "# also specify the maximum and minumum value show on the map to increase the\n", - "# contrast in the map.\n", - "data.plot(\n", - " ax=ax,\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=0,\n", - " vmax=20,\n", - " cbar_kwargs=dict(shrink=0.5, label=\"GPCP Monthly Precipitation \\n(mm/day)\"),\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The updated map provides significant improvements, offering us a wealth of information to enhance our understanding of the GPCP monthly precipitation data. From the visualization, we can observe that regions such as the Amazon rainforest, the northern part of Australia, and other tropical areas exhibit higher levels of monthly precipitation in January 1979. These patterns align with our basic geographical knowledge, reinforcing the validity of the data and representation." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 1.2**\n", - "\n", - "Remember the GPCP also offers a data variable that documents the error of the monthly precipitation data used above. This error information is valuable for understanding the level of confidence we can place on the data. \n", - "\n", - "1. Generate the precipitation error for the same month (1979-01-01) using the examples provided above." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# select data for the month of interest\n", - "data = ...\n", - "\n", - "# initate plot with the specific figure size\n", - "fig, ax = plt.subplots(subplot_kw={\"projection\": ccrs.Robinson()}, figsize=(9, 6))\n", - "\n", - "# add coastal lines to indicate land/ocean\n", - "_ = ...\n", - "\n", - "# add grid lines for latitude and longitute\n", - "_ = ...\n", - "\n", - "# add the precipitation data for\n", - "_ = ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial4_Solution_0b5432a5.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2: Climate Connection**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Comment on the spatial pattern of the precipitation error provided by GPCP CDR data for this specific month. \n", - "2. Which areas have the highest errors? Why do you think this might be?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial4_Solution_246ba3ba.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Climatology**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "## **Section 2.1: Plot Time Series of Data at a Specific Location**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We have over 40 years of monthly precipitation data. Let's examine a specific location throughout the entire time span covered by the GPCP monthly data. For this purpose, we will focus on the data point located at (0°N, 0°E)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# select the entire time series for the grid that contains the location of (0N, 0E)\n", - "grid = ds.precip.sel(latitude=0, longitude=0, method=\"nearest\")\n", - "\n", - "# initate plot\n", - "fig, ax = plt.subplots(figsize=(9, 6))\n", - "\n", - "# plot the data\n", - "grid.plot(ax=ax)\n", - "\n", - "# remove the automatically generated title\n", - "ax.set_title(\"\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "From the time series plot, note a repeating pattern with a seasonal cycle (roughly the same ups and downs over the course of a year, for each year). In previous tutorials during the climate system overview you learned how to calculate climatology. We can apply this same calculation to the precipitation CDR data to investigate the annual cycle of precipitation at this location." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: Calculate the Climatology**\n", - "\n", - "As a refresher, a climatology typically employs a 30-year time period to use for the calculation. In this case, let's use the reference period of 1981-2010." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# first, let's extract the data for the time period that we want (1981-2010)\n", - "precip_30yr = ds.precip.sel(time=slice(\"1981-01-01\", \"2010-12-30\"))\n", - "precip_30yr" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we can use Xarray's `.groupby()` functionality to calculate the monthly climatology.\n", - "\n", - "Recall that `.groupby()` splits the data based on a specific criterion (in this case, the month of the year) and then applies a process (in our case, calculating the mean value across 30 years for that specific month) to each group before recombining the data together." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# use groupby to calculate monthly climatology (1981-2010)\n", - "precip_clim = precip_30yr.groupby(\"time.month\").mean(dim=\"time\")\n", - "precip_clim" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "With the resulting climatology data array, we can make a set of maps to visualize the monthly climatology from four different seasons." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# define the figure and each axis for the 2 rows and 2 columns\n", - "fig, axs = plt.subplots(\n", - " nrows=2, ncols=2, subplot_kw={\"projection\": ccrs.Robinson()}, figsize=(12, 8)\n", - ")\n", - "\n", - "# axs is a 2 dimensional array of `GeoAxes`. We will flatten it into a 1-D array\n", - "axs = axs.flatten()\n", - "\n", - "# loop over selected months (Jan, Apr, Jul, Oct)\n", - "for i, month in enumerate([1, 4, 7, 10]):\n", - "\n", - " # Draw the coastines and major gridline for each subplot\n", - " axs[i].coastlines()\n", - " axs[i].gridlines()\n", - "\n", - " # Draw the precipitation data\n", - " precip_clim.sel(month=month).plot(\n", - " ax=axs[i],\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=0,\n", - " vmax=15, # use the same range of max and min value\n", - " cbar_kwargs=dict(shrink=0.5, label=\"GPCP Climatology\\n(mm/day)\"),\n", - " )" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In the seasonal collection of the climatology map, we can observe a clear pattern of precipitation across the globe. The tropics exhibit a higher amount of precipitation compared to other regions. Additionally, the map illustrates the seasonal patterns of precipitation changes across different regions of the globe, including areas influenced by monsoons." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.2: Climate Connection**\n", - "\n", - "1. Do the tropics or high-latitudes recieve more precipitation all year round? Why do you think this is? Think back to the climate system overview tutorials on atmospheric circulation to help form your answer.\n", - "2. In the climate system overview tutorials you learned about Monsoon systems in places such as India, South-east Asia and East Africa where there are notable wet and dry seasons. Do you see evidence of say, the Indian monsoon, in these maps?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial4_Solution_c390720b.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now let's examine the climatology of the location we previously analyzed throughout the entire time series, specifically at (0°N, 0°E)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# initate plot with the specific figure size\n", - "fig, ax = plt.subplots(figsize=(9, 6))\n", - "\n", - "precip_clim.sel(latitude=0, longitude=0, method=\"nearest\").plot(ax=ax)\n", - "# Remove the automatically generated title\n", - "ax.set_title(\"\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "The monthly climatology time series for the point of interest demonstrates a noticeable seasonal pattern, with dry and rainy months observed in the region. Precipitation is typically more abundant between December and May, while August experiences the driest conditions throughout the year.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 2.1**\n", - "\n", - "As climate changes, the climatology of precipitation may also change. In fact, climate researchers recalculate climatology every 10 years. This allows climate scientists to monitor how the norms of our climate system change. In this exercise, you will visualize how the climatology of our dataset changes depending on the reference period used.\n", - "\n", - "1. Calculate the climatology for a different reference period (1991-2020) and compare it to the climatology that we just generated with reference period (1981-2010). Be sure to compare the two and note differences. Can you see why it is important to re-calculate this climatology?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# extract 30 year data for 1991-2020\n", - "precip_30yr_exercise = ...\n", - "\n", - "# calculate climatology for 1991-2020\n", - "precip_clim_exercise = ...\n", - "\n", - "# find difference in climatologies: (1981-2010) minues (1991-2020)\n", - "precip_diff_exercise = ...\n", - "\n", - "# Compare the climatology for four different seasons by generating the\n", - "# difference maps for January, April, July, and October with colorbar max and min = 1,-1\n", - "\n", - "# Define the figure and each axis for the 2 rows and 2 columns\n", - "fig, axs = plt.subplots(\n", - " nrows=2, ncols=2, subplot_kw={\"projection\": ccrs.Robinson()}, figsize=(12, 8)\n", - ")\n", - "\n", - "# axs is a 2 dimensional array of `GeoAxes`. We will flatten it into a 1-D array\n", - "axs = ...\n", - "\n", - "#Loop over selected months (Jan, Apr, Jul, Oct)\n", - "for i, month in enumerate([1, 4, 7, 10]):\n", - " ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial4_Solution_bfe45894.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "Climatologies provide valuable insight into typical weather patterns of a region. Key takeaways from the tutorial include:\n", - "\n", - "- A climatology pertains to the long-term average of various system attributes, such as temperature and precipitation, often spanning a duration of 30 years.\n", - "- Satellite climate data records offer valuable insights for calculating climatology on a global scale.\n", - "\n", - "By comparing the weather conditions of a specific day or month to the climatology, we can determine the extent to which they deviate from the norm. This concept of comparing against the climatology, or the norm, will be the focus of our next tutorial - the anomaly!" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Data from this tutorial can be accessed [here](https://noaa-cdr-precip-gpcp-monthly-pds.s3.amazonaws.com/index.html#data/)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial4", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5.ipynb deleted file mode 100644 index 9ac69756c..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5.ipynb +++ /dev/null @@ -1,804 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 5: Calculating Anomalies Using Precipitation Data**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will learn how to calculate climate anomalies using satellite climate data records.\n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Calculate an anomaly to a climatology.\n", - "* Calculate the rolling mean of the anomaly data to smooth the time series and extract long-term signals/patterns.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !pip install s3fs --quiet\n", - "\n", - "# properly install cartopy in colab to avoid session crash\n", - "# !apt-get install libproj-dev proj-data proj-bin --quiet\n", - "# !apt-get install libgeos-dev --quiet\n", - "# !pip install cython --quiet\n", - "# !pip install cartopy --quiet\n", - "\n", - "# !apt-get -qq install python-cartopy python3-cartopy --quiet\n", - "# !pip uninstall -y shapely --quiet\n", - "# !pip install shapely --no-binary shapely --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import s3fs\n", - "import xarray as xr\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import boto3\n", - "import botocore\n", - "import os\n", - "import pooch\n", - "import tempfile\n", - "import holoviews\n", - "from geoviews import Dataset as gvDataset\n", - "import geoviews.feature as gf\n", - "from geoviews import Image as gvImage" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Video 1 Name\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=\"\", filename=\"\"):\n", - " shared_location = \"/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: From Climatology to Anomaly**\n", - "\n", - "Building upon your knowledge of climatology from the last tutorial, you will now calculate the anomalies from this climatology. An **anomaly**, in the context of climate studies, represents a departure from standard climatological conditions. For example, if the normal January temperature of the city that you live in is 10 °C and the January temperature of this year is 15 °C. We usually say the temperature anomaly of January this year is 5 °C above normal/ the climatology. The anomaly is an essential tool in detecting changes in climate patterns and is frequently utilized in critical climate reports such as those generated by the [Intergovernmental Panel on Climate Change (IPCC)](https://www.ipcc.ch/).\n", - "\n", - "To calculate an anomaly, we first establish a reference period, usually a 30-year window, to define our climatology. In this process, it is crucial to use high-quality data and aggregate it to the desired spatial resolution and temporal frequency, such as weekly or monthly. The anomaly is then determined by subtracting this long-term average from a given observation, thus creating a useful metric for further climate analysis such as trend analysis.\n", - "\n", - "In this tutorial, we will employ the [CPCP monthly precipitation Climate Data Record (CDR)](https://disc.gsfc.nasa.gov/datasets/GPCPMON_3.2/summary) to compute a monthly anomaly time series. Furthermore, we will learn to calculate the rolling mean of the generated precipitation anomaly time series. This knowledge will be invaluable for our upcoming tutorial on climate variability." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Calculating the Monthly Anomaly**\n", - "\n", - "To calculate anomaly, you first need to calculate the monthly climatology. Since you already learned how to do this during last tutorial, we will fast forward this step. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# connect to the AWS S3 bucket for the GPCP Monthly Precipitation CDR data\n", - "fs = s3fs.S3FileSystem(anon=True)\n", - "\n", - "# get the list of all data files in the AWS S3 bucket\n", - "file_pattern = \"noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc\"\n", - "file_location = fs.glob(file_pattern)\n", - "\n", - "# open connection to all data files\n", - "client = boto3.client(\n", - " \"s3\", config=botocore.client.Config(signature_version=botocore.UNSIGNED)\n", - ") # initialize aws s3 bucket client\n", - "file_ob = [\n", - " pooch_load(filelocation=\"http://s3.amazonaws.com/\" + file, filename=file)\n", - " for file in file_location\n", - "]\n", - "\n", - "# open all the monthly data files and concatenate them along the time dimension\n", - "# this process will take ~ 1 minute to complete due to the number of data files\n", - "ds = xr.open_mfdataset(file_ob, combine=\"nested\", concat_dim=\"time\")\n", - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate climatology using `.sel()` and `.groupby()` directly.\n", - "precip_clim = (\n", - " ds.precip.sel(time=slice(\"1981-01-01\", \"2010-12-01\"))\n", - " .groupby(\"time.month\")\n", - " .mean(dim=\"time\")\n", - ")\n", - "precip_clim" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we have the monthly precipitation climatology. How can we calculate the monthly anomaly?\n", - "\n", - "As we learned before - let's use `.groupby()` from `xarray`. We can split the entire time period based on the month of the year and then subtract the climatology of that specific month from the monthly value and recombine the value together." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# use `.groupby()` to calculate the monthly anomaly\n", - "precip_anom = ds.precip.groupby(\"time.month\") - precip_clim\n", - "precip_anom" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You may have noticed that there is an additional coordinate in the anomaly dataset. The additional coordinate is `month` which is a direct outcome because of the `.groupby()` action we just performed.\n", - "\n", - "If you want to save the data for future use, you can write the data out to a netCDF file using `.to_netcdf()`. It will automatically carry all the coordinates, dimensions, and relevant information into the netCDF file." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# an example of how to export the GPCP monthly anomaly data comparing to the climatology period of 1981-2010.\n", - "# precip_anom.to_netcdf('t5_gpcp-monthly-anomaly_1981-2010.nc')" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Examining the Anomaly**\n", - "\n", - "First, let's take a look at the geospatial pattern of the monthly anomaly of a selected month – January of 1979." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# initate plot\n", - "fig = plt.figure(figsize=(9, 6))\n", - "\n", - "# set map projection\n", - "ax = plt.axes(projection=ccrs.Robinson())\n", - "\n", - "# add coastal lines to indicate land/ocean\n", - "ax.coastlines()\n", - "\n", - "# add grid lines for latitude and longitude\n", - "ax.gridlines()\n", - "\n", - "# add the precipitation data for\n", - "precip_anom.sel(time=\"1979-01-01\").plot(\n", - " ax=ax,\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-8,\n", - " vmax=8,\n", - " cmap=\"BrBG\",\n", - " cbar_kwargs=dict(shrink=0.5, label=\"Monthly Anomaly \\n(mm/day)\"),\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "From the map of this monthly anomaly, we can see the spatial pattern of how precipitation for the January of 1979 has departed from the 30-year normal. Part of the Amazon saw notable increase of precipitation during this month as well as the northeast coast of the United States. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Interactive Demo 1.2\n", - "\n", - "In the interactive demo below (make sure to run the code) you will be able to scroll through the anomaly for a few months in 1979 to see how it changes from month to month during this year." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "holoviews.extension(\"bokeh\")\n", - "dataset_plot = gvDataset(\n", - " precip_anom.isel(time=slice(0, 10))\n", - ") # only the first 10, as it is a time consuming task\n", - "images = dataset_plot.to(gvImage, [\"longitude\", \"latitude\"], [\"precip\"], \"time\")\n", - "images.opts(\n", - " cmap=\"BrBG\",\n", - " colorbar=True,\n", - " width=600,\n", - " height=400,\n", - " projection=ccrs.Robinson(),\n", - " clim=(-8, 8),\n", - " clabel=\"Monthly Anomaly \\n(mm/day)\",\n", - ") * gf.coastline" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To visualize the changes in the precipitation anomaly over many months, we can also take a look at the time series of a selected grid. We will use the same point (0°N, 0°E) that we used as an example in the last tutorial." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# set up two subplots that share the x-axis to compare monthly precipitation and monthly anomaly\n", - "fig, axs = plt.subplots(2, sharex=True)\n", - "fig.suptitle(\"GPCP Monthly Precipitaion v.s. Monthly Anomaly\")\n", - "axs[0].plot(ds.time, ds.precip.sel(latitude=0, longitude=0, method=\"nearest\"))\n", - "axs[0].set_ylabel(\"Precip (mm/day)\")\n", - "axs[1].plot(\n", - " precip_anom.time, precip_anom.sel(latitude=0, longitude=0, method=\"nearest\")\n", - ")\n", - "axs[1].set_ylabel(\"Anomaly (mm/day)\")\n", - "axs[1].set_xlabel(\"Time\")\n", - "\n", - "# add horizontal line of y=0 for the anomaly subplot\n", - "axs[1].axhline(y=0, color=\"k\", linestyle=\"-\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Note that, unlike the upper panel showing precipitation values, the lower panel displaying the monthly anomaly not exhibit distinct seasonal cycles. This discrepancy highlights one of the advantages of utilizing anomaly data for climate analysis. By removing the repetitive patterns induced by seasonality or other stable factors, we can effectively isolate the specific signals in the data that are of interest, such as climate variability or climate trends. This approach allows for a clearer focus on the desired climate-related patterns without the interference of predictable seasonal variations." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Anomaly Analysis**\n", - "\n", - "In this section, we are going to explore a few different analyses on the anomaly data: \n", - "\n", - "- Calculating rolling mean\n", - "- Calculating global mean\n", - "\n", - "You have already practiced using these tools during the last two days or material, here we will focus on applying them to a much longer satellite data record than you have encountered previously." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: Rolling Mean**\n", - "\n", - "The monthly anomaly time series often contains noisy data that may obscure the patterns associated with large-scale climate variability. To mitigate this noise and enhance the visibility of underlying patterns, we can apply a rolling mean technique using the `.rolling()` function. This approach involves smoothing the monthly time series to facilitate the identification of climate variability." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate 12-month rolling mean for the selected location\n", - "grid_month = precip_anom.sel(latitude=0, longitude=0, method=\"nearest\")\n", - "grid_rolling = grid_month.rolling(time=12, center=True).mean()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# create the time series plot of monthly anomaly\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "grid_month.plot(label=\"Monthly Anomaly\", ax=ax)\n", - "grid_rolling.plot(color=\"k\", label=\"12-mon rolling mean\", ax=ax)\n", - "ax.axhline(y=0, color=\"y\", linestyle=\"-\")\n", - "ax.set_ylabel(\"Precipitation Anomaly (mm/day)\")\n", - "ax.legend()\n", - "ax.set_xlabel(\"Time\")\n", - "# remove the automatically generated title\n", - "ax.set_title(\"\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As you can see, the 12-month rolling mean removes the high-frequency variations of monthly precipitation anomaly data, allowing the slower-changing patterns of precipitation to become more apparent." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Coding Exercises 2.1\n", - "\n", - "1. Calculate the 24-month rolling mean for the same grid and compare the three different time series (monthly anomaly, 12-month rolling mean, 24-month rolling mean)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Compare monthly anomaly with 12-month and 24-month rolling mean.\"\n", - ")\n", - "#################################################\n", - "\n", - "# calculate 24-month rolling mean\n", - "grid_rolling_24m = ...\n", - "\n", - "# plot all three time series together with different colors\n", - "fig, ax = ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial5_Solution_ebd7c176.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 2.1\n", - "\n", - "1. What are the major differences you notice between the 12 and 24 month rolling averages?\n", - "2. What would generally dictate the window size to use in a rolling average of a satellite derived climate variable such as precipitation anomalies?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial5_Solution_25e66bca.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: Global Mean**\n", - "\n", - "When examining global-scale changes, it is common to aggregate global mean values from all grid cells. However, it is important to note that despite each grid having the same resolution of `2.5°×2.5°`, they represent different areas on the Earth's surface. Specifically, the same grid covers larger spatial areas in the tropics compared to the polar regions as discussed in the climate system overview day.\n", - "\n", - "To address this issue, it is necessary to weight the values based on their respective surface areas. Unlink the model data you used previously, where you had the grid cell area available as a variable, for our gridded observations we will use weights based on the cosine of the latitude as this function takes into account the decreasing area towards the poles." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate the weights using the latitude coordinates\n", - "weights = np.cos(np.deg2rad(precip_anom.latitude))\n", - "weights.name = \"weights\"\n", - "weights" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate weighted global monthly mean\n", - "anom_weighted = precip_anom.weighted(weights)\n", - "global_weighted_mean = anom_weighted.mean((\"latitude\", \"longitude\"))\n", - "global_weighted_mean" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# create the time series plot of global weighted monthly anomaly\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "global_weighted_mean.plot(label=\"Monthly anomaly\", ax=ax)\n", - "global_weighted_mean.rolling(time=12, center=True).mean((\"latitude\", \"longitude\")).plot(\n", - " color=\"k\", label=\"12-mon rolling mean\", ax=ax\n", - ")\n", - "ax.axhline(y=0, color=\"y\", linestyle=\"-\")\n", - "ax.set_ylabel(\"Precipitation Anomaly (mm/day)\")\n", - "ax.legend()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Coding Exercises 2.2\n", - "\n", - "1. Plot the 12-month rolling average of the difference between the global weighted and unweighted mean time series.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Compare global weighted and unweighted mean time series.\"\n", - ")\n", - "#################################################\n", - "\n", - "# calculate unweighted global mean\n", - "global_unweighted_mean = ...\n", - "\n", - "# calculate different between weighted and unweighted global mean\n", - "global_diff = global_weighted_mean - global_unweighted_mean\n", - "\n", - "# plot the time series of the difference\n", - "fig, ax = ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial5_Solution_15f88aa8.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Questions 2.2\n", - "\n", - "1. Give one example of why the weighted mean might be *higher* than the unweighted mean, as in the 2000-2004 period." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial5_Solution_7c6157c7.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you learned how to calculate a climate anomaly using satellite derived precipitation data. \n", - "\n", - "* The anomaly allows us to look at the signals that may be covered by the seasonal cycle pattern (e.g., temperature/precipitation seasonal cycle).\n", - "* The anomaly data can be further smoothed using rolling mean to reveal longer-term signals at annual or decade time scale.\n", - "\n", - "We will use the anomaly concept to study climate variability in the next tutorial.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Data from this tutorial can be accessed [here](https://noaa-cdr-precip-gpcp-monthly-pds.s3.amazonaws.com/index.html#data/)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial5", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6.ipynb deleted file mode 100644 index 62b1f448a..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6.ipynb +++ /dev/null @@ -1,684 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 6: Large Scale Climate Variability - ENSO**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will build upon the introduction to El Niño-Southern Oscillation (ENSO) from Day 1 and 2. ENSO is recognized as one of the most influential large-scale climate variabilities that impact weather and climate patterns.\n", - "\n", - "By the end of this tutorial, you will:\n", - "\n", - "- Enhance your comprehension of the concept of ENSO and the three distinct phases associated with it.\n", - "- Utilize satellite-derived sea surface temperature (SST) data to compute an index for monitoring ENSO.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !apt-get install libproj-dev proj-data proj-bin --quiet\n", - "# !apt-get install libgeos-dev --quiet\n", - "# !pip install cython --quiet\n", - "# !pip install cartopy --quiet\n", - "\n", - "# !apt-get -qq install python-cartopy python3-cartopy --quiet\n", - "# !pip uninstall -y shapely --quiet\n", - "# !pip install shapely --no-binary shapely --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import xarray as xr\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import os\n", - "import requests\n", - "import tarfile\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import holoviews\n", - "from geoviews import Dataset as gvDataset\n", - "import geoviews.feature as gf\n", - "from geoviews import Image as gvImage" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Video 1 Name\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=\"\", filename=\"\"):\n", - " shared_location = \"/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: El Niño-Southern Oscillation (ENSO)**\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As you learned in Day 1 and 2, one of the most significant large-scale climate variabilities is El Niño-Southern Oscillation (ENSO). ENSO can change the global atmospheric circulation, which in turn, influences temperature and precipitation across the globe.\n", - "\n", - "Despite being a single climate phenomenon, ENSO exhibits three distinct phases:\n", - "\n", - "- El Niño: A warming of the ocean surface, or above-average sea surface temperatures, in the central and eastern tropical Pacific Ocean.\n", - "- La Niña: A cooling of the ocean surface, or below-average sea surface temperatures, in the central and eastern tropical Pacific Ocean.\n", - "- Neutral: Neither El Niño or La Niña. Often tropical Pacific SSTs are generally close to average. \n", - "\n", - "In Day 2, you practiced utilizing a variety of Xarray tools to examine variations in sea surface temperature (SST) during El Niño and La Niña events by calculating the [Oceanic Niño Index (ONI)](https://climatedataguide.ucar.edu/climate-data/nino-sst-indices-nino-12-3-34-4-oni-and-tni) from reanalysis data over the time period 2000-2014.\n", - "\n", - "In contrast to previous days, in this tutorial you will use satellite-based SST data to monitor ENSO over a longer time period starting in 1981." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Calculate SST Anomaly**\n", - "\n", - "[Optimum Interpolation Sea Surface Temperature (OISST)](https://www.ncei.noaa.gov/products/optimum-interpolation-sst) is a long-term Climate Data Record that incorporates observations from different platforms (satellites, ships, buoys and Argo floats) into a regular global grid. OISST data is originally produced at daily and 1/4° spatial resolution. To avoid the large amount of data processing of daily data, we use the monthly aggregated OISST SST data provided by [NOAA Physical Systems Laboratory](https://psl.noaa.gov/). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# download the monthly sea surface temperature data from NOAA Physical System\n", - "# Laboratory. The data is processed using the OISST SST Climate Data Records\n", - "# from the NOAA CDR program.\n", - "# the data downloading may take 2-3 minutes to complete.\n", - "# filename=sst.mon.mean.nc\n", - "url_sst = \"https://osf.io/6pgc2/download/\"\n", - "filename = \"sst.mon.mean.nc\"\n", - "\n", - "# we divide the data into small chunks to allow for easier memory manangement. this is all done automatically, no need for you to do anything\n", - "ds = xr.open_dataset(\n", - " pooch_load(filelocation=url_sst, filename=filename),\n", - " chunks={\"time\": 25, \"latitude\": 200, \"longitude\": 200},\n", - ")\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The monthly OISST data is available starting from September of 1981. We will use the Niño 3.4 (5N-5S, 170W-120W) region to monitor the ENSO as identified in the map below provided by NOAA Climate portal.\n", - "\n", - "![Location of four different nino regions ](https://www.climate.gov/sites/default/files/Fig3_ENSOindices_SST_large.png)\n", - "\n", - "Credit: [NOAA](https://www.climate.gov/sites/default/files/Fig3_ENSOindices_SST_large.png)\n", - "\n", - "The data is only available in full years starting 1982, so we will use 1982-2011 as the climatology period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# get 30-year climatology from 1982-2011\n", - "sst_30yr = ds.sst.sel(time=slice(\"1982-01-01\", \"2011-12-01\"))\n", - "\n", - "# calculate monthly climatology\n", - "sst_clim = sst_30yr.groupby(\"time.month\").mean()\n", - "sst_clim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# calculate monthly anomaly\n", - "sst_anom = ds.sst.groupby(\"time.month\") - sst_clim\n", - "sst_anom" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now, we can take a look at the SST anomaly of a given month. We use January of 1998 to show the specific change of SST during that time period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "sst = sst_anom.sel(time=\"1998-01-01\")\n", - "\n", - "# initate plot\n", - "fig, ax = plt.subplots(\n", - " subplot_kw={\"projection\": ccrs.Robinson(central_longitude=180)}, figsize=(9, 6)\n", - ")\n", - "\n", - "# focus on the ocean with the central_longitude=180\n", - "ax.coastlines()\n", - "ax.gridlines()\n", - "sst.plot(\n", - " ax=ax,\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-3,\n", - " vmax=3,\n", - " cmap=\"RdBu_r\",\n", - " cbar_kwargs=dict(shrink=0.5, label=\"OISST Anomaly (degC)\"),\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Interactive Demo 1.1**\n", - "\n", - "Use the slider bar below to explore maps of the anomalies through the year in 1998." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# note this code takes a while to load. probably an hour\n", - "# holoviews.extension('bokeh')\n", - "\n", - "# dataset_plot = gvDataset(sst_anom.sel(time=slice('1998-01-01','1998-12-01'))) # taking only 12 months\n", - "# images = dataset_plot.to(gvImage, ['lon', 'lat'], ['sst'], 'time')\n", - "# images.opts(cmap='RdBu_r', colorbar=True, width=600, height=400,projection=ccrs.Robinson(),\n", - "# clim=(-3,3),clabel ='OISST Anomaly (degC)') * gf.coastline" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Monitoring ENSO with Oceanic Niño Index**\n", - "\n", - "As you learned in Day 2, the [Oceanic Niño Index (ONI)](https://climatedataguide.ucar.edu/climate-data/nino-sst-indices-nino-12-3-34-4-oni-and-tni) is a common index used to monitor ENSO. It is calculated using the Niño 3.4 region (5N-5S, 170W-120W) and by applying a 3-month rolling mean to the mean SST anomalies in that region." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You may have noticed that the `lon` for the SST data from [NOAA Physical Systems Laboratory](https://psl.noaa.gov/) is organized between 0°–360°E. Just as in Tutorial 1 of Day 2, we find that the region to subset with our dataset is (-5°–5°, 190–240°)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# extract SST data from the Nino 3.4 region\n", - "sst_nino34 = sst_anom.sel(lat=slice(-5, 5), lon=slice(190, 240))\n", - "sst_nino34" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# calculate the mean values for the Nino 3.4 region\n", - "nino34 = sst_nino34.mean(dim=[\"lat\", \"lon\"])\n", - "\n", - "# Pplot time series for Nino 3.4 mean anomaly\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "nino34.plot(ax=ax)\n", - "ax.set_ylabel(\"Nino3.4 Anomaly (degC)\")\n", - "ax.axhline(y=0, color=\"k\", linestyle=\"dashed\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The ONI is defined as the 3-month rolling mean of the monthly regional average of the SST anomaly for the Nino 3.4 region. We can use `.rolling()` to calculate the ONI value for each month from the OISST monthly anomaly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# calculate 3-month rolling mean of Nino 3.4 anomaly for the ONI\n", - "oni = nino34.rolling(time=3, center=True).mean()\n", - "\n", - "# generate time series plot\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "nino34.plot(label=\"Nino 3.4\", ax=ax)\n", - "oni.plot(color=\"k\", label=\"ONI\", ax=ax)\n", - "ax.set_ylabel(\"Anomaly (degC)\")\n", - "ax.axhline(y=0, color=\"k\", linestyle=\"dashed\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The different phases of ENSO are nominally defined based on a threshold of $\\pm$ 0.5 with the ONI index. \n", - "\n", - "- [El Niño](https://glossary.ametsoc.org/wiki/El_niño) [ONI values higher than 0.5]: surface waters in the east-central tropical Pacific are at least 0.5 degrees Celsius *warmer than normal*.\n", - "- [La Niña](https://glossary.ametsoc.org/wiki/La_niña) [ONI values lower than -0.5]: surface waters ub the west tropical Pacific are at least 0.5 degrees Celsius *cooler than normal*.\n", - "\n", - "The neutral phase is when ONI values are in between these two thresholds. We can make the ONI plot that is used by NOAA and other organizations to monitor ENSO phases." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# set up the plot size\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "\n", - "# create the filled area when ONI values are above 0.5 for El Nino\n", - "ax.fill_between(\n", - " oni.time.data,\n", - " oni.where(oni >= 0.5).data,\n", - " 0.5,\n", - " color=\"red\",\n", - " alpha=0.9,\n", - ")\n", - "\n", - "# create the filled area when ONI values are below -0.5 for La Nina\n", - "ax.fill_between(\n", - " oni.time.data,\n", - " oni.where(oni <= -0.5).data,\n", - " -0.5,\n", - " color=\"blue\",\n", - " alpha=0.9,\n", - ")\n", - "\n", - "# create the time series of ONI\n", - "oni.plot(color=\"black\", ax=ax)\n", - "\n", - "# add the threshold lines on the plot\n", - "ax.axhline(0, color=\"black\", lw=0.5)\n", - "ax.axhline(0.5, color=\"red\", linewidth=0.5, linestyle=\"dotted\")\n", - "ax.axhline(-0.5, color=\"blue\", linewidth=0.5, linestyle=\"dotted\")\n", - "ax.set_title(\"Oceanic Niño Index\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "From the plot, we can see the historical ENSO phases swing from El Nino to La Nina events. The major ENSO events like 1997-1998 shows up very clearly on the ONI plot. \n", - "\n", - "We will use the ONI data to perform analysis to understand the impact of ENSO on precipitation. So you can export the ONI time series into a netCDF file for future use via `.to_netcdf()`. For our purposes, we will download a dataset that has been previously saved in the next tutorial. If you wanted to save the data when working on your own computer, this is the code you could use." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# oni.to_netcdf('t6_oceanic-nino-index.nc')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 1.2**\n", - "\n", - "As we learned here, ENSO is monitored using the anomaly of SST data for a specific region (e.g., Nino 3.4). We also learned previously that the reference periods used to calculate climatolgies are updated regularly to reflect the most up to date 'normal'.\n", - "\n", - "1. Compare the ONI time series calculated using two different climatology reference periods (1982-2011 v.s. 1991-2020). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Compare the ONI time series calculated using two different climatology reference periods (1982-2011 v.s. 1991-2020).\"\n", - ")\n", - "#################################################\n", - "# select data from 1991-2020.\n", - "sst_30yr_later = ...\n", - "\n", - "# calculate climatology\n", - "sst_clim_later = ...\n", - "\n", - "# calculate anomaly\n", - "sst_anom_later = ...\n", - "\n", - "# calculate mean over Nino 3.4 region\n", - "nino34_later = ...\n", - "\n", - "# compute 3 month rolling mean\n", - "oni_later = ...\n", - "\n", - "# compare the two ONI time series and visualize the difference as a time series plot\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "oni.plot(color=\"k\", label=\"ONI (1982-2011)\", ax=ax)\n", - "oni_later.plot(color=\"r\", label=\"ONI (1991-2020)\", ax=ax)\n", - "ax.set_ylabel(\"Anomaly (degC)\")\n", - "ax.axhline(y=0, color=\"k\", linestyle=\"dashed\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial6_Solution_8cb0da04.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2: Climate Connection**\n", - "\n", - "1. What is the main difference you note about this plot?\n", - "2. What does this tell you about the climatology calculated from 1982-2011 versus 1991-2020?\n", - "3. Why is it important to use appropriate climatologies when finding anomalies?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial6_Solution_d4b4c3d0.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you revisted the foundational principles of ENSO and explored how satellite data can be employed to track this phenomenon. \n", - "- As one of the most potent climate influences on Earth, ENSO has the capacity to alter global atmospheric circulation with impacts around the world.\n", - "- You observed the three phases of ENSO by utilizing SST data gathered from satellites and calculating the Oceanic Niño Index.\n", - "\n", - "In the forthcoming tutorial, we will utilize the ONI, calculated in this session, to evaluate the influence of ENSO on precipitation in select regions. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Data from this tutorial can be accessed [here](https://www.ncei.noaa.gov/products/optimum-interpolation-sst)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial6", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7.ipynb deleted file mode 100644 index 1636e6a06..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7.ipynb +++ /dev/null @@ -1,769 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 7: Impact of Climate Variability - Precipitation**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, the primary goal is to understand how to utilize satellite data to investigate the effects of large-scale climate variability on precipitation.\n", - "\n", - "Upon the completion of this tutorial, you will be able to:\n", - "\n", - "- Comprehend the influence of the El Niño-Southern Oscillation (ENSO) on precipitation and its geographical distribution.\n", - "- Compute Pearson's correlation coefficient, a statistical measure used to determine the relationship between two time series.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# properly install cartopy in colab to avoid session crash\n", - "# !apt-get install libproj-dev proj-data proj-bin --quiet\n", - "# !apt-get install libgeos-dev --quiet\n", - "# !pip install cython --quiet\n", - "# !pip install cartopy --quiet\n", - "\n", - "# !apt-get -qq install python-cartopy python3-cartopy --quiet\n", - "# !pip uninstall -y shapely --quiet\n", - "# !pip install shapely --no-binary shapely --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import xarray as xr\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import os\n", - "import requests\n", - "import pooch\n", - "import tempfile\n", - "from scipy import stats" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Video 1 Name\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=\"\", filename=\"\"):\n", - " shared_location = \"/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: ENSO and precipitation**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As discussed in previous tutorials, ENSO oscillates irregularly between El Niño and La Niña phases every two to seven years. These shifts often prompt predictable changes in ocean surface temperature and disrupt wind and rainfall patterns across the tropics, leading to a cascade of global side effects.\n", - "\n", - "In this context, we will be utilizing satellite data to scrutinize the influence of ENSO on precipitation patterns. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Get ENSO Index Oceanic Niño Index (ONI)**\n", - "\n", - "In last tutorial, we generated the Oceanic Niño Index (ONI) using the OISST Climate Data Records. Now we just read the ONI value using the climatology of 1982-2011.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# download't6_oceanic-nino-index.nc'\n", - "\n", - "url_nino = \"https://osf.io/8rwxb/download/\"\n", - "filename_nino = \"t6_oceanic-nino-index\"\n", - "oni = xr.open_dataset(pooch_load(filelocation=url_nino, filename=filename_nino))\n", - "oni" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# plot the oni timeseries we just downloaded\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "oni.sst.plot(ax=ax)\n", - "ax.set_ylabel(\"Oceanic Nino Index\")\n", - "ax.axhline(y=0, linestyle=\"dashed\", color=\"k\")\n", - "ax.axhline(y=0.5, linestyle=\"dotted\", color=\"r\")\n", - "ax.axhline(y=-0.5, linestyle=\"dotted\", color=\"b\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Get Precipitation Anomaly Data**\n", - "\n", - "In tutorial 5, we created the monthly anomaly data of precipitation globally using the GPCP Monthly Precipitation Climate Data Records. Here, we read in the anomaly data and look at one specific month (e.g., 1998-01-01)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# download file 't5_gpcp-monthly-anomaly_1981-2010.nc'\n", - "url_precip = \"https://osf.io/vhdcg/download/\"\n", - "filename_precip = \"t5_gpcp-monthly-anomaly_1981-2010.nc\"\n", - "precip = xr.open_dataset(pooch_load(filelocation=url_precip, filename=filename_precip))\n", - "precip" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# select just data from 1998\n", - "data = precip.sel(time=\"1998-01-01\")\n", - "\n", - "# initate plot\n", - "fig = plt.figure(figsize=(9, 6))\n", - "ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))\n", - "ax.coastlines()\n", - "ax.gridlines()\n", - "data.precip.plot(\n", - " ax=ax,\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-10,\n", - " vmax=10,\n", - " cmap=\"BrBG\",\n", - " cbar_kwargs=dict(shrink=0.5, label=\"Precip Anomaly (mm/day)\"),\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.3: Spatial Pattern**\n", - "\n", - "Let's look at one specific ENSO event - the **1997/1998 El Niño** and see how the spatial pattern of the precipitation evolves. The 1997/1998 El Niño is one of the most significant ENSO events that started in May of 1997 and ended April of 1998.\n", - "\n", - "Let's examine the seasonal precipitation anomaly pattern during this time period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# define the figure and each axis for the 2 rows and 2 columns\n", - "fig, axs = plt.subplots(\n", - " nrows=2,\n", - " ncols=2,\n", - " subplot_kw={\"projection\": ccrs.Robinson(central_longitude=180)},\n", - " figsize=(12, 7.5),\n", - " sharex=True,\n", - " sharey=True,\n", - ")\n", - "\n", - "# axs is a 2 dimensional array of `GeoAxes`. We will flatten it into a 1-D array\n", - "axs = axs.flatten()\n", - "\n", - "# loop over selected months (Jan, Apr, Jul, Oct)\n", - "for i, month in enumerate([\"1997-07-01\", \"1997-10-01\", \"1998-01-01\", \"1998-04-01\"]):\n", - "\n", - " # draw the coastines and major gridline for each subplot\n", - " axs[i].coastlines()\n", - " axs[i].gridlines()\n", - "\n", - " # draw the precipitation anomaly data\n", - " precip.precip.sel(time=month).plot(\n", - " ax=axs[i],\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-10,\n", - " vmax=10, # use the same range of max and min value\n", - " cmap=\"BrBG\",\n", - " cbar_kwargs=dict(shrink=0.4, label=\"Precip anomaly\\n(mm/day)\"),\n", - " )" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this series of four monthly maps, notice the shifts in precipitation patterns across the tropics and various land regions.\n", - "\n", - "In particular there are large increases and decreases in precipitation over the tropical ocean, where ENSO is actively monitored. In the Nino 3.4 region, the intensification of the El Niño phase from (which is characterized by warmer SSTs over the central and eastern Pacific) occurs alongside an increase in rainfall shown here (more blue ares near the equator).\n", - "\n", - "In addition to these changes, there are also rainfall patterns in regions such as in North and South America, with the Amazon as a notable example. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Correlation Analysis**\n", - "\n", - "Beyond visual inspection, we can also quantify the correlation between the ENSO (ONI) and the precipitation anomaly for a region of our interest.\n", - "\n", - "Let's use Niño 3.4 region as an example to calculate the correlation berween precipitation and ONI." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# extract precipitation data for the Nino 3.4 region & the same time period with ONI data\n", - "precip_nino34 = precip.sel(\n", - " latitude=slice(-5, 5),\n", - " longitude=slice(190, 240),\n", - " time=slice(\"1981-09-01\", \"2022-12-01\"),\n", - ")\n", - "precip_nino34" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# calculate regional mean of the precipitation anomaly\n", - "precip_nino34_mean = precip_nino34.mean((\"latitude\", \"longitude\"))\n", - "\n", - "# extract ONI value for the common period (ending at 2022-12-01)\n", - "nino34 = oni.sel(time=slice(\"1981-09-01\", \"2022-12-01\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# set up two subplots that share the x-axis to compare precipitation anomaly and ONI index\n", - "fig, axs = plt.subplots(2, sharex=True)\n", - "fig.suptitle(\"GPCP Precipitaion Anomaly v.s. Oceanic Nino Index\")\n", - "axs[0].plot(precip_nino34_mean.time, precip_nino34_mean.precip)\n", - "axs[0].set_ylabel(\"Precip (mm/day)\")\n", - "axs[0].axhline(y=0, color=\"k\", linestyle=\"dashed\")\n", - "axs[1].plot(nino34.time, nino34.sst)\n", - "axs[1].set_ylabel(\"ONI (degC)\")\n", - "axs[1].set_xlabel(\"Time\")\n", - "axs[1].axhline(y=0, color=\"k\", linestyle=\"dashed\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "From theses two time series, a pattern exists of a synchronized change in the precipitation anomaly and ONI. Now, we can generate a scatter plot to further examine this relationship." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# set up scatter plot\n", - "fig, ax = plt.subplots(figsize=(7, 7))\n", - "fig.suptitle(\"GPCP Precipitaion Anomaly v.s. Oceanic Nino Index\")\n", - "ax.scatter(nino34.sst, precip_nino34_mean.precip, alpha=0.6)\n", - "\n", - "# add horizontal and vertical lines of 0 values\n", - "ax.axhline(y=0, linestyle=\"dashed\", color=\"k\", alpha=0.6)\n", - "ax.axvline(x=0, linestyle=\"dashed\", color=\"k\", alpha=0.6)\n", - "ax.axvline(x=0.5, linestyle=\"dashed\", color=\"r\", alpha=0.6) # El Nino threshold\n", - "ax.axvline(x=-0.5, linestyle=\"dashed\", color=\"b\", alpha=0.6) # La Nina threshold\n", - "ax.set_xlabel(\"ONI (degC)\")\n", - "ax.set_ylabel(\"Precipitation Anomaly (mm/day)\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The scatter plot unveils a nonlinear relationship between precipitation anomalies and the ONI across different ENSO phases:\n", - "\n", - "- During the La Niña phase (i.e., when ONI values fall below -0.5/ the blue line), the Niño 3.4 region typically experiences below-average precipitation.\n", - "- In contrast, during the El Niño phase (i.e., when ONI values rise above 0.5/ the red line), the Nino 3.4 region is inclined towards above-average precipitation.\n", - "\n", - "Although the overall relationship is nonlinear, we are only interested in the data during different ENSO phases (ONI above and below 0.5). Looking at this data separately, visually a linear fit seems appropriate. For your projects, you should check this is so by looking at the distribution of the **residuals of the linear fit**. The residuals are the difference between a dataset predicted by the linear model you will find during the regression process and the true data. If the fit is good, there should be no relationship between these two (i.e. the distribution of residuals should have little to no correlation with your data. For simplicity, we skip this step here.\n", - "\n", - "After you separate our data, you can look at the correlation coefficient and the associated p-value. This tells us how strongly related changes in the ONI are related to changes in precipitatoin anomalies. It is a value between -1 and 1, where the sign indicates whether the relationship is positive or negative, and the the absolute value tells us how strong the correlation. An absolute value of the correlatin coefficient closer to 1 indicates a stronger correlation. A low p-value will then assure us that likelihood of the correlation we find being purely due to chance is very low.\n", - "\n", - "First let us separate our data into El Niño and La Niña phases by using the ONI as a threshold." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# El Nino Data, logically index to keep ONI values above 0.5\n", - "el_nino_sst = nino34.sst[nino34.sst > 0.5]\n", - "el_nino_precip = precip_nino34_mean.precip[nino34.sst > 0.5]\n", - "\n", - "# La Nina Data, logically index to keep ONI values below -0.5\n", - "la_nina_sst = nino34.sst[nino34.sst < -0.5]\n", - "la_nina_precip = precip_nino34_mean.precip[nino34.sst < -0.5]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# set up scatter plot for just El Nino and La Nina phases\n", - "fig, ax = plt.subplots(figsize=(7, 7))\n", - "fig.suptitle(\"GPCP Precipitaion Anomaly v.s. Oceanic Nino Index\")\n", - "ax.scatter(el_nino_sst, el_nino_precip, c=\"r\", alpha=0.6)\n", - "ax.scatter(la_nina_sst, la_nina_precip, c=\"b\", alpha=0.6)\n", - "\n", - "# add horizontal and vertical lines of 0 values\n", - "ax.axhline(y=0, linestyle=\"dashed\", color=\"k\", alpha=0.6)\n", - "ax.axvline(x=0, linestyle=\"dashed\", color=\"k\", alpha=0.6)\n", - "ax.axvline(x=0.5, linestyle=\"dashed\", color=\"r\", alpha=0.6) # El Nino threshold\n", - "ax.axvline(x=-0.5, linestyle=\"dashed\", color=\"b\", alpha=0.6) # La Nina threshold\n", - "ax.set_xlabel(\"ONI (degC)\")\n", - "ax.set_ylabel(\"Precipitation Anomaly (mm/day)\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now find the linear correlation coefficient using [SciPy stats package](https://docs.scipy.org/doc/scipy/tutorial/stats.html)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# correlation for El Nino data\n", - "el_nino_r, el_nino_p = stats.pearsonr(el_nino_sst, el_nino_precip)\n", - "\n", - "print(\"El Nino - Corr Coef: \" + str(el_nino_r) + \", p-val: \" + str(el_nino_p))\n", - "\n", - "# correlation for La Nina data\n", - "la_nina_r, la_nina_p = stats.pearsonr(la_nina_sst, la_nina_precip)\n", - "\n", - "print(\"La Nina - Corr Coef: \" + str(la_nina_r) + \", p-val: \" + str(la_nina_p))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 2: Climate Connection**\n", - "\n", - "1. Note that the correlation during La Niña phases is low with a higher p-value (less significant) than the correlation coefficient during El Niño phases. Explain what this means.\n", - "2. Do the differences in correlation coefficients between phases line up with the time series above? Explain why." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial7_Solution_601f5869.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Coding Exercises 2**\n", - "\n", - "1. Choose a region of your interest to examine the relationship between ENSO (using ONI data) and precipitation anomaly globally. It will be interesting to see if the figures you make line up with your expectations from the maps we have made in the beginning of the tutorial. Will they be more or less correlated that the Niño 3.4 region? In the example code we will use Italy, but you can change this to be whatever region you are interested in." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Examine the relationship between ENSO and precipitation anomaly in a region of your choice.\"\n", - ")\n", - "#################################################\n", - "\n", - "# define region of interest for the precipitation anomaly\n", - "italy_lon = [...]\n", - "italy_lat = [...]\n", - "\n", - "# calculate regional mean time series\n", - "precip_nino34_italy = precip.sel(\n", - " latitude=slice(...),\n", - " longitude=slice(...),\n", - " time=slice(\"1981-09-01\", \"2022-12-01\"),\n", - ").mean(dim=(...))\n", - "\n", - "# plot the time series of precipitation anomaly and ONI for the same time period on different subplots\n", - "fig, axs = plt.subplots(2, sharex=True)\n", - "fig.suptitle(\"GPCP Precipitaion Anomaly v.s. Oceanic Nino Index\")\n", - "axs[0].plot(precip_nino34_italy.time, precip_nino34_italy.precip)\n", - "axs[0].set_ylabel(\"Precip (mm/day)\")\n", - "axs[0].axhline(y=0, color=\"k\", linestyle=\"dashed\")\n", - "axs[1].plot(nino34.time, nino34.sst)\n", - "axs[1].set_ylabel(\"ONI (degC)\")\n", - "axs[1].set_xlabel(\"Time\")\n", - "axs[1].axhline(y=0, color=\"k\", linestyle=\"dashed\")\n", - "\n", - "# El Nino Data, logically index to keep ONI values above 0.5\n", - "italy_el_nino_sst = ...\n", - "italy_el_nino_precip = ...\n", - "\n", - "# La Nina Data, logically index to keep ONI values below -0.5\n", - "italy_la_nina_sst = ...\n", - "italy_la_nina_precip = ...\n", - "\n", - "# correlation for El Nino data\n", - "italy_el_nino_r, italy_el_nino_p = ...\n", - "\n", - "print(\n", - " \"El Nino - Corr Coef: \" + str(italy_el_nino_r) + \", p-val: \" + str(italy_el_nino_p)\n", - ")\n", - "\n", - "# correlation for La Nina data\n", - "italy_la_nina_r, italy_la_nina_p = ...\n", - "\n", - "print(\n", - " \"La Nina - Corr Coef: \" + str(italy_la_nina_r) + \", p-val: \" + str(italy_la_nina_p)\n", - ")\n", - "\n", - "# plot scatter plot between precipitation and ONI\n", - "fig, ax = plt.subplots(figsize=(7, 7))\n", - "fig.suptitle(\"GPCP Precipitaion Anomaly v.s. Oceanic Nino Index\")\n", - "ax.scatter(italy_el_nino_sst, italy_el_nino_precip, c=\"r\", alpha=0.6)\n", - "ax.scatter(italy_la_nina_sst, italy_la_nina_precip, c=\"b\", alpha=0.6)\n", - "\n", - "# add horizontal and vertical lines of 0 values\n", - "ax.axhline(y=0, linestyle=\"dashed\", color=\"k\", alpha=0.6)\n", - "ax.axvline(x=0, linestyle=\"dashed\", color=\"k\", alpha=0.6)\n", - "ax.axvline(x=0.5, linestyle=\"dashed\", color=\"r\", alpha=0.6) # El Nino threshold\n", - "ax.axvline(x=-0.5, linestyle=\"dashed\", color=\"b\", alpha=0.6) # La Nina threshold\n", - "ax.set_xlabel(\"ONI (degC)\")\n", - "ax.set_ylabel(\"Precipitation Anomaly (mm/day)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial7_Solution_1f48249e.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you've acquired skills to evaluate the connection between precipitation and large-scale climate variability by analyzing the Oceanic Nino Index (ONI) and precipitation data.\n", - "\n", - "- You've discovered that the during ENSO, precipitation patterns in the tropics are altered.\n", - "- You have used Pearson's correlation coefficient to investigate potential correlations. However, it's critical to further scrutinize these correlations with physical explanations to ensure that any detected signals are valid.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Data from this tutorial can be accessed for OISST [here](https://www.ncei.noaa.gov/products/optimum-interpolation-sst) and precipitation [here](https://noaa-cdr-precip-gpcp-monthly-pds.s3.amazonaws.com/index.html#data/)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial7", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8.ipynb b/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8.ipynb deleted file mode 100644 index f880abc3e..000000000 --- a/book/_build/html/_sources/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8.ipynb +++ /dev/null @@ -1,940 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 8: Comparing Satellite Products With In Situ Data**\n", - "\n", - "**Week 1, Day 3, Remote Sensing**\n", - "\n", - "**Content creators:** Douglas Rao\n", - "\n", - "**Content reviewers:** Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {}, - "jp-MarkdownHeadingCollapsed": true - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, our primary focus will be on the 'Verification of Satellite Data'. Building on our previous modules where we explored various climate applications of satellite data, we will now delve into the critical task of assessing the quality and reliability of such data.\n", - "\n", - "By the end of this tutorial, you will learn how to use land-based observations to validate satellite climate data. In this process you will:\n", - "\n", - "* Learn how to access the gridded climate data derived from station observations from AWS.\n", - "* Learn how to convert monthly total values to a daily rate.\n", - "* Learn how to correctly evaluate satellite data against land-based observations." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !pip install s3fs --quiet\n", - "\n", - "# properly install cartopy in colab to avoid session crash\n", - "# !apt-get install libproj-dev proj-data proj-bin --quiet\n", - "# !apt-get install libgeos-dev --quiet\n", - "# !pip install cython --quiet\n", - "# !pip install cartopy --quiet\n", - "\n", - "# !apt-get -qq install python-cartopy python3-cartopy --quiet\n", - "# !pip uninstall -y shapely --quiet\n", - "# !pip install shapely --no-binary shapely --quiet" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 128816, - "status": "ok", - "timestamp": 1681872600523, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "import s3fs\n", - "import xarray as xr\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import boto3\n", - "import botocore\n", - "from scipy import stats" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 325, - "status": "ok", - "timestamp": 1681872600844, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Video 1 Name\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Video 1 Name\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=\"\", filename=\"\"):\n", - " shared_location = \"/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Evaluating Satellite Data with Observations**\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Satellite data is frequently cross-verified against observations deemed reliable to evaluate its quality. Station-based observations and derived data are typically regarded as a reliable reference. When it comes to oceanic data, measurements taken by ships, buoys, drifters, or gliders are often used as a benchmark to assess the quality of satellite data.\n", - "\n", - "In this tutorial, we will be using the nClimGrid dataset, a gridded climate dataset produced by NOAA. This dataset provides daily and monthly temperature and precipitation data, leveraging all available station observations. However, it's important to note that this dataset is exclusive to the United States. We have selected this dataset due to its public availability on AWS. You are encouraged to explore other station data for the evaluation of satellite data in your projects." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Accesing nClimGrid - a station based gridded climate data**\n", - "\n", - "The nClimGrid-monthly dataset is a gridded dataset derived from spatially interpolating data from the [Global Historical Climatology Network (GHCN)](https://www.ncei.noaa.gov/products/land-based-station/global-historical-climatology-network-daily). The dataset includes monthly precipitation, monthly temperature average, monthly temperature maximum and monthly temperature minimum. The dataset provides monthly values in a approximate 5x5 km lat/lon grid for the Continental United States. Data is available from 1895 to the present via NOAA NCEI or AWS. We will be accessing the data via AWS directly.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4091, - "status": "ok", - "timestamp": 1681872604932, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# connect to the AWS S3 bucket for the nClimGrid Monthly Precipitation data\n", - "\n", - "# read in the monthly precipitation data from nClimGrid on AWS\n", - "client = boto3.client(\n", - " \"s3\", config=botocore.client.Config(signature_version=botocore.UNSIGNED)\n", - ") # initialize aws s3 bucket client\n", - "\n", - "file_nclimgrid = \"noaa-nclimgrid-monthly-pds/nclimgrid_prcp.nc\"\n", - "ds = xr.open_dataset(\n", - " pooch_load(\n", - " filelocation=\"http://s3.amazonaws.com/\" + file_nclimgrid,\n", - " filename=file_nclimgrid,\n", - " )\n", - ")\n", - "ds" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The nClimGrid dataset is available from `1895-01-01` until present. Since our GPCP data is only available between `1979-01-01` and `2022-12-01`, extract only the data from that time period from the nClimGrid monthly data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 16, - "status": "ok", - "timestamp": 1681872604932, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "prcp_obs = ds.sel(time=slice(\"1979-01-01\", \"2022-12-31\"))\n", - "prcp_obs" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "From the information about the precipitation data from nClimGird monthly dataset, we know it is the monthly total precipitation, which is the total amount of rainfall that a location receives for the entire month with the unit of `millimeter`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 461, - "status": "ok", - "timestamp": 1681872605381, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "prcp_obs.prcp" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "However, the GPCP satellite precipitation variable is the daily precipitation rate with the unit of `mm/day`. This variable quantifies the average amount of precipitation in a day for a given location in a month. \n", - "\n", - "To convert from the total amount to the precipitation rate, we just need to divide the amount by the number of days within a month (e.g., 31 days for January). We can use `.days_in_month` to achieve that." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 64910, - "status": "ok", - "timestamp": 1681872670287, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# calculate precipitation rate from nClimGrid\n", - "obs_rate = prcp_obs.prcp / prcp_obs.time.dt.days_in_month\n", - "obs_rate" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4538, - "status": "ok", - "timestamp": 1681872674818, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# generate the map of precipitation rate from nClimGrid monthly data\n", - "obs_rate[0].plot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this quick map, we can see the value range of the precipitation rate appears to be reasonable compared to the GPCP monthly precipitation CDR data (0-20 mm/day)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Read GPCP Monthly Precipitation Data**\n", - "\n", - "Now we are ready to compare our land-based observations to the monthly GPCP satellite from AWS public data catalog." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 186915, - "status": "ok", - "timestamp": 1681872861713, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# get the list of all data files in the AWS S3 bucket\n", - "fs = s3fs.S3FileSystem(anon=True)\n", - "file_pattern = \"noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc\"\n", - "file_location = fs.glob(file_pattern)\n", - "\n", - "# open connection to all data files\n", - "file_ob = [\n", - " pooch_load(filelocation=\"http://s3.amazonaws.com/\" + file, filename=file)\n", - " for file in file_location\n", - "]\n", - "\n", - "# open all the monthly data files and concatenate them along the time dimension.\n", - "# this process will take ~ 1 minute to complete due to the number of data files.\n", - "ds_gpcp = xr.open_mfdataset(file_ob, combine=\"nested\", concat_dim=\"time\")\n", - "ds_gpcp" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 18, - "status": "ok", - "timestamp": 1681872861715, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# get the GPCP precipitation rate\n", - "prcp_sat = ds_gpcp.precip\n", - "prcp_sat" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.3: Spatial Pattern**\n", - "\n", - "Now, let's take a quick look at the spatial pattern between these two datasets for a selected month (e.g., 1979-01-01)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 10612, - "status": "ok", - "timestamp": 1681872872311, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# set up the geographical region for continental US\n", - "central_lat = 37.5\n", - "central_lon = -96\n", - "extent = [-120, -70, 21, 50]\n", - "central_lon = np.mean(extent[:2])\n", - "central_lat = np.mean(extent[2:])\n", - "\n", - "# extract sat and obs data for the month of 1979-01-01\n", - "sat = prcp_sat.sel(time=\"1979-01-01\")\n", - "obs = obs_rate.sel(time=\"1979-01-01\")\n", - "\n", - "# initate plot for North America using two suplots\n", - "fig, axs = plt.subplots(\n", - " 2,\n", - " subplot_kw={\"projection\": ccrs.AlbersEqualArea(central_lon, central_lat)},\n", - " figsize=(9, 12),\n", - " sharex=True,\n", - " sharey=True,\n", - ")\n", - "axs[0].set_extent(extent)\n", - "axs[0].coastlines()\n", - "axs[0].set_title(\"GPCP Monthly\")\n", - "sat.plot(\n", - " ax=axs[0],\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=0,\n", - " vmax=15,\n", - " cbar_kwargs=dict(shrink=0.5, label=\"GPCP Precipitation (mm/day)\"),\n", - ")\n", - "axs[1].set_extent(extent)\n", - "axs[1].coastlines()\n", - "axs[1].set_title(\"nClimGrid Monthly\")\n", - "obs.plot(\n", - " ax=axs[1],\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=0,\n", - " vmax=15,\n", - " cbar_kwargs=dict(shrink=0.5, label=\"nClimGrid Precipitation (mm/day)\"),\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Overall, we have a similar spatial pattern but with widely different spatial resolution (i.e., 5km v.s. 2.5°). " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.4: Time series comparison**\n", - "\n", - "Let's use New York City as an example, we can examine the time series of the satellite and observation-based dataset to evaluate the performance.\n", - "\n", - "The latitute and longitute of NYC is `(40.71°N, 74.01°W)`. We will use it to extract the time series from GPCP and nClimGrid using the `nearest` method you discussed in Day 1 due to the differing resolutions of each dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 19, - "status": "ok", - "timestamp": 1681872872312, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# note that GPCP data is stored as 0-360 degree for the longitude, so the longitude should be using (360 - lon)\n", - "sat = prcp_sat.sel(longitude=285.99, latitude=40.71, method=\"nearest\")\n", - "obs = obs_rate.sel(lon=-74.01, lat=40.71, method=\"nearest\") # precipitation rate\n", - "obs_total = prcp_obs.sel(lon=-74.01, lat=40.71, method=\"nearest\") # total amount" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 7721, - "status": "ok", - "timestamp": 1681872942720, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# let's look at the comparison between the precipitation rate from nClimGrid and satellite CDR\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "obs.plot(label=\"nClimGrid Monthly Precipitation Rate\", ax=ax)\n", - "sat.plot(color=\"k\", alpha=0.6, label=\"GPCP Monthly Precipitation Rate\", ax=ax)\n", - "ax.set_ylabel(\"nClimGrid v.s. GPCP (New York City) (mm/day)\")\n", - "ax.legend()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we are going to zoom in to a few years to see how the data compares." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1508, - "status": "ok", - "timestamp": 1681872944214, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "obs.sel(time=slice(\"2011-01-01\", \"2015-12-01\")).plot(label=\"nClimGrid\", ax=ax)\n", - "sat.sel(time=slice(\"2011-01-01\", \"2015-12-01\")).plot(\n", - " marker=\"o\", label=\"GPCP Monthly\", ax=ax\n", - ")\n", - "ax.legend()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We see a great alignment in the precipitation rate between the nClimGrid and GPCP data when we look at the details over this small chosen window. However, we cannot zoom in to every location for all times to confirm they are a good match. We can use statistics to quantify the relationship between these two datasets for as in a automated fashion, and will do so in the next section." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.5: Quantify the Difference**\n", - "\n", - "One way to more robustly compare the datasets is through a scatterplot. The data would ideally follow the 1:1 line, which would suggest that they are very closely matched. Let's make this plot and observe how our data compares to one another:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5, - "status": "ok", - "timestamp": 1681872944214, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# make sure that both observation and satellite data are for the samte time period\n", - "sat = sat.sel(time=slice(\"1979-01-01\", \"2022-12-01\"))\n", - "obs = obs.sel(time=slice(\"1979-01-01\", \"2022-12-01\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 20565, - "status": "ok", - "timestamp": 1681872964775, - "user": { - "displayName": "Yuhan (Douglas) Rao", - "userId": "14858740632129213276" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# plot the scatter plot between nClimGrid and GPCP monthly precipitation CDR\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "fig.suptitle(\"GPCP Precipitaion v.s. nClimGrid\")\n", - "ax.scatter(sat, obs, alpha=0.6)\n", - "# Add 1:1 line\n", - "y_lim = (0, 15)\n", - "x_lim = (0, 15)\n", - "ax.plot((0, 15), (0, 15), \"r-\")\n", - "ax.set_ylim(y_lim)\n", - "ax.set_xlim(x_lim)\n", - "ax.set_xlabel(\"GPCP Precipitation (mm/day)\")\n", - "ax.set_ylabel(\"nClimGrid (mm/day)\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "By eye, there appears to be a stong correlation between the satellite data and the observations for NYC, with much of the data following the 1:1 line plotted in red. As in the last tutorial, we can calculate the correlation coefficient and corresponding p-value." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "r, p = stats.pearsonr(sat, obs)\n", - "print(\"Corr Coef: \" + str(r) + \", p-val: \" + str(p))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As we expected, the data are significantly correlated." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 1.5**\n", - "\n", - "1. Sometimes, we are more interested in the difference among the anomaly data rather than the total data. Using the same location, compare the anomaly data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "#################################################\n", - "# Students: Fill in missing code (...) and comment or remove the next line\n", - "raise NotImplementedError(\n", - " \"Student exercise: Compare the anomaly of precipitation rate for NYC.\"\n", - ")\n", - "#################################################\n", - "\n", - "# calculate climatology for the 1981-2010 period for both GPCP and nClimGrid\n", - "sat_clim = ...\n", - "obs_clim = ...\n", - "\n", - "# calculate anomaly of the NYC time series for both GPCP and nClimGrid\n", - "sat_clim_anom = ...\n", - "obs_clim_anom = ...\n", - "\n", - "# plot time series and scatter plot between two time series\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "obs_clim_anom.sel(time=slice(\"2011-01-01\", \"2015-12-01\")).plot(\n", - " label=\"nClimGrid anomaly\", ax=ax\n", - ")\n", - "sat_clim_anom.sel(time=slice(\"2011-01-01\", \"2015-12-01\")).plot(\n", - " marker=\"o\", label=\"GPCP Monthly anomaly\", ax=ax\n", - ")\n", - "ax.legend()\n", - "\n", - "# plot the scatter plot between nClimGrid and GPCP monthly precipitation CDR\n", - "fig, ax = plt.subplots(figsize=(12, 6))\n", - "fig.suptitle(\"GPCP Precipitaion v.s. nClimGrid\")\n", - "ax.scatter(sat_clim_anom, obs_clim_anom, alpha=0.6)\n", - "# Add 1:1 line\n", - "y_lim = (0, 15)\n", - "x_lim = (0, 15)\n", - "ax.plot((0, 15), (0, 15), \"r-\")\n", - "ax.set_ylim(y_lim)\n", - "ax.set_xlim(x_lim)\n", - "ax.set_xlabel(\"GPCP Precipitation anomaly (mm/day)\")\n", - "ax.set_ylabel(\"nClimGrid anomaly (mm/day)\")\n", - "\n", - "# calculate and print correlation coefficient and p-value\n", - "r, p = ...\n", - "print(\"Corr Coef: \" + str(r) + \", p-val: \" + str(p))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/solutions/W1D3_Tutorial8_Solution_f42422ae.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you explored how to use station-based observations within the U.S. to evaluate satellite precipitation data. While this isn't a global comparison, the methodology can be applied to other station or observation data you may wish to utilize.\n", - "\n", - "When carrying out these comparisons, remember the following key points:\n", - "\n", - "- Ensure that both the satellite data and the observations represent the same quantity (for example, total precipitation amount versus precipitation rate).\n", - "- Comparisons should be made for the same geolocation (or very near to it) and the same time period.\n", - "- Be aware of potential spatial scale effects. Satellite data measures over a large area, whereas observations may be narrowly focused, particularly for elements that exhibit substantial spatial variability. This can lead to considerable uncertainty in the satellite data.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Resources" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Data from this tutorial can be accessed [here](https://noaa-cdr-precip-gpcp-monthly-pds.s3.amazonaws.com/index.html#data/) and [here](https://www.ncei.noaa.gov/products/land-based-station/global-historical-climatology-network-daily)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D3_Tutorial8", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/chapter_title.md b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/chapter_title.md deleted file mode 100644 index d6181f3e6..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Paleoclimate - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/further_reading.md b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/further_reading.md deleted file mode 100644 index 6a497dfed..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/further_reading.md +++ /dev/null @@ -1,18 +0,0 @@ -# Suggested Further Reading - -General overview of paleoclimate: -- https://www.usgs.gov/programs/climate-research-and-development-program/science/paleoclimate-research -- https://www.ncei.noaa.gov/news/what-is-paleoclimatology - -IPCC Information from Paleoclimate Archives: -- https://www.ipcc.ch/site/assets/uploads/2018/02/WG1AR5_Chapter05_FINAL.pdf - -Major climate variations in earth’s history: -- https://www.climate.gov/news-features/climate-qa/whats-hottest-earths-ever-been - -Modern climate changes in the context of paleoclimate: -- https://www.ncei.noaa.gov/news/climate-change-context-paleoclimate -- https://pubs.usgs.gov/fs/2010/3021/pdf/fs2010-3021.pdf - -Delta-18O information: -- https://earthobservatory.nasa.gov/features/Paleoclimatology_OxygenBalance \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.ipynb deleted file mode 100644 index f3ec619f4..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.ipynb +++ /dev/null @@ -1,596 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 1: Paleoclimate Proxies**\n", - "\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you'll learn about different types of paleoclimate proxies (physical characteristics of the environment that can stand in for direct measurements), the file type they come in, and how to convert these files to more usable formats.\n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Understand some types of paleoclimate proxies and archives that exist\n", - "* Create a global map of locations of proxy paleoclimate records in a specific data network " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import os\n", - "import pandas as pd\n", - "import numpy as np\n", - "import pooch # to donwload the PAGES2K data\n", - "import matplotlib.pyplot as plt\n", - "import tempfile\n", - "import lipd\n", - "import cartopy.crs as ccrs\n", - "import cartopy.feature as cfeature\n", - "import cartopy.io.shapereader as shapereader" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Helper functions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Helper functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "# Convert the PAGES2K LiDP files into a pandas.DataFrame\n", - "\n", - "# Function to convert the PAGES2K LiDP files in a pandas.DataFrame\n", - "def lipd2df(\n", - " lipd_dirpath,\n", - " pkl_filepath=None,\n", - " col_str=[\n", - " \"paleoData_pages2kID\",\n", - " \"dataSetName\",\n", - " \"archiveType\",\n", - " \"geo_meanElev\",\n", - " \"geo_meanLat\",\n", - " \"geo_meanLon\",\n", - " \"year\",\n", - " \"yearUnits\",\n", - " \"paleoData_variableName\",\n", - " \"paleoData_units\",\n", - " \"paleoData_values\",\n", - " \"paleoData_proxy\",\n", - " ],\n", - "):\n", - " \"\"\"\n", - " Convert a bunch of PAGES2k LiPD files to a `pandas.DataFrame` to boost data loading.\n", - "\n", - " If `pkl_filepath` isn't `None`, save the DataFrame as a pikle file.\n", - "\n", - " Parameters:\n", - " ----------\n", - " lipd_dirpath: str\n", - " Path of the PAGES2k LiPD files\n", - " pkl_filepath: str or None\n", - " Path of the converted pickle file. Default: `None`\n", - " col_str: list of str\n", - " Name of the variables to extract from the LiPD files\n", - "\n", - " Returns:\n", - " -------\n", - " df: `pandas.DataFrame`\n", - " Converted Pandas DataFrame\n", - " \"\"\"\n", - "\n", - " # Save the current working directory for later use, as the LiPD utility will change it in the background\n", - " work_dir = os.getcwd()\n", - " # LiPD utility requries the absolute path\n", - " lipd_dirpath = os.path.abspath(lipd_dirpath)\n", - " # Load LiPD files\n", - " lipds = lipd.readLipd(lipd_dirpath)\n", - " # Extract timeseries from the list of LiDP objects\n", - " ts_list = lipd.extractTs(lipds)\n", - " # Recover the working directory\n", - " os.chdir(work_dir)\n", - " # Create an empty pandas.DataFrame with the number of rows to be the number of the timeseries (PAGES2k records),\n", - " # and the columns to be the variables we'd like to extract\n", - " df_tmp = pd.DataFrame(index=range(len(ts_list)), columns=col_str)\n", - " # Loop over the timeseries and pick those for global temperature analysis\n", - " i = 0\n", - " for ts in ts_list:\n", - " if (\n", - " \"paleoData_useInGlobalTemperatureAnalysis\" in ts.keys()\n", - " and ts[\"paleoData_useInGlobalTemperatureAnalysis\"] == \"TRUE\"\n", - " ):\n", - " for name in col_str:\n", - " try:\n", - " df_tmp.loc[i, name] = ts[name]\n", - " except:\n", - " df_tmp.loc[i, name] = np.nan\n", - " i += 1\n", - " # Drop the rows with all NaNs (those not for global temperature analysis)\n", - " df = df_tmp.dropna(how=\"all\")\n", - " # Save the dataframe to a pickle file for later use\n", - " if pkl_filepath:\n", - " save_path = os.path.abspath(pkl_filepath)\n", - " print(f\"Saving pickle file at: {save_path}\")\n", - " df.to_pickle(save_path)\n", - " return df" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Introduction to PAGES2k**\n", - "\n", - "As we've now seen from introductory video, there are various types of [paleoclimate archives and proxies](http://wiki.linked.earth/Climate_Proxy) that can be used to reconstruct past changes in Earth's climate. For example:\n", - "\n", - "- **Sediment Cores**: Sediments deposited in layers within lakes and oceans serve as a record of climate variations over time. Various proxies for past climate are preserved in sediment cores including, pollen, microfossils, charcoal, microscopic organisms, organic molecules, etc.\n", - "- **Ice Cores**: Similarly to sediment cores, ice cores capture past climate changes in layers of ice accumulated over time. Common proxies for reconstructing past climate in ice cores include water isotopes, greenhouse gas concentrations of air bubbles in the ice, and dust.\n", - "- **Corals**: Corals form annual growth bands within their carbonate skeletons, recording temperature changes over time. Scientists analyze the chemical composition of each layer to reconstruct temperature and salinity. Corals typically preserve relatively short paleoclimate records, but they provide very high-resolution reconstructions (monthly and seasonal) and are therefore valuable for understanding past changes in short-term phenomena.\n", - "- **Speleothems**: These are cave formations that result from the deposition of minerals from groundwater. As the water flows into the cave, thin layers of minerals (e.g., calcium carbonate), are deposited. The thickness and chemical composition of speleothem layers can be used to reconstruct climate changes in the past.\n", - "- **Tree Rings**: Each year, trees add a new layer of growth, known as a tree ring. These rings record changes in temperature and precipitation. Proxy measurements of tree rings include thickness and isotopes, which reflect annual variability in moisture and temperature.\n", - "\n", - "There are many existing paleoclimate reconstructions spanning a variety of timescales and from global locations. Given the temporal and spatial vastness of existing paleoclimate records, it can be challenging to know what paleoclimate data already exists and where to find it. One useful solution is compiling all existing paleoclimate records for a single climate variable (temperature, greenhouse gas concentration, precipitation, etc.) and over a specific time period (Holocene to present, the past 800,000 years, etc.). \n", - "\n", - "One example of this is the **PAGES2k network**, which is a community-sourced database of temperature-sensitive proxy records. The database consists of 692 records from 648 locations, that are from a variety of archives (e.g., trees, ice, sediment, corals, speleothems, etc.) and span the Common Era (1 CE to present, i.e., the past ~2,000 years). You can read more about the PAGES2k network, in [PAGES 2k Consortium (2017)](https://www.nature.com/articles/sdata201788).\n", - "\n", - "In this tutorial, we will explore the types of proxy records in the PAGES2k network and create a map of proxy record locations." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Get PAGES2k LiPD Files**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The PAGES2k network is stored in a specific file format known as [Linked Paleo Data format (LiPD)](http://wiki.linked.earth/Linked_Paleo_Data). LiPD files contain time series information in addition to supporting metadata (e.g., root metadata, location). Pyleoclim (and its dependency package LiPD) leverages this additional information using LiPD-specific functionality.\n", - "\n", - "Data stored in the .lpd format can be loaded directly as an Lipd object. If the data_path points to one LiPD file, `lipd.readLipd.()` will load the specific record, while if data_path points to a folder of lipd files, `lipd.readLipd.()` will load the full set of records. This function to read in the data is imbedded in the helper function above used to read the data in and convert it to a more usable format.\n", - "\n", - "The first thing we need to do it to download the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# Set the name to save the PAGES2K data\n", - "fname = \"pages2k_data\"\n", - "\n", - "# Download the datae\n", - "lipd_file_path = pooch.retrieve(\n", - " url=\"https://ndownloader.figshare.com/files/8119937\",\n", - " known_hash=None,\n", - " path=\"./\",\n", - " fname=fname,\n", - " processor=pooch.Unzip(),\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we can use our helpfer function `lipd_2df()` to convert the LiPD files to a [Pandas dataframe](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html).\n", - "\n", - "NOTE: when you run some of the next code cell to convert the Lipd files to a DataFrame, you will get some error messages. This is fine and the code will still accomplish what it needs to do. The code will also take a few minutes to run, so if it's taking longer than you'd expect, that's alright!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 139313, - "status": "ok", - "timestamp": 1680670246822, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# convert all the lipd files into a DataFrame\n", - "fname = \"pages2k_data\"\n", - "\n", - "pages2k_data = lipd2df(lipd_dirpath=os.path.join(\".\", f\"{fname}.unzip\", \"LiPD_Files\"))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The PAGES2k data is now stored as a dataframe and we can view the data to understand different attributes it contains." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 628, - "status": "ok", - "timestamp": 1680670283233, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# print the top few rows of the PAGES2K data\n", - "pages2k_data.head()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: Plotting a Map of Proxy Reconstruction Locations**\n", - "\n", - "Now that we have converted the data into a Pandas dataframe, we can plot the PAGES2k network on a map to understand the spatial distribution of the temperature records and the types of proxies that were measured." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Before generating the plot, we have to define the colours and the marker types that we want to use in the plot. We also need to set a list with the different `archive_type` names that appear in the data frame." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5407, - "status": "ok", - "timestamp": 1680670611982, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# list of markers and colors for the different archive_type\n", - "markers = [\"p\", \"p\", \"o\", \"v\", \"d\", \"*\", \"s\", \"s\", \"8\", \"D\", \"^\"]\n", - "colors = [\n", - " np.array([1.0, 0.83984375, 0.0]),\n", - " np.array([0.73828125, 0.71484375, 0.41796875]),\n", - " np.array([1.0, 0.546875, 0.0]),\n", - " np.array([0.41015625, 0.41015625, 0.41015625]),\n", - " np.array([0.52734375, 0.8046875, 0.97916667]),\n", - " np.array([0.0, 0.74609375, 1.0]),\n", - " np.array([0.25390625, 0.41015625, 0.87890625]),\n", - " np.array([0.54296875, 0.26953125, 0.07421875]),\n", - " np.array([1, 0, 0]),\n", - " np.array([1.0, 0.078125, 0.57421875]),\n", - " np.array([0.1953125, 0.80078125, 0.1953125]),\n", - "]\n", - "\n", - "# create the plot\n", - "\n", - "fig = plt.figure(figsize=(10, 5))\n", - "ax = fig.add_subplot(1, 1, 1, projection=ccrs.Robinson())\n", - "\n", - "# add plot title\n", - "ax.set_title(f\"PAGES2k Network (n={len(pages2k_data)})\", fontsize=20, fontweight=\"bold\")\n", - "\n", - "# set the base map\n", - "# ----------------\n", - "ax.set_global()\n", - "\n", - "# add coast lines\n", - "ax.coastlines()\n", - "\n", - "# add land fratures using gray color\n", - "ax.add_feature(cfeature.LAND, facecolor=\"gray\", alpha=0.3)\n", - "\n", - "# add gridlines for latitude and longitude\n", - "ax.gridlines(edgecolor=\"gray\", linestyle=\":\")\n", - "\n", - "\n", - "# plot the different archive types\n", - "# -------------------------------\n", - "\n", - "# extract the name of the different archive types\n", - "archive_types = pages2k_data.archiveType.unique()\n", - "\n", - "# plot the archive_type using a forloop\n", - "for i, type_i in enumerate(archive_types):\n", - " df = pages2k_data[pages2k_data[\"archiveType\"] == type_i]\n", - " # count the number of appearances of the same archive_type\n", - " count = df[\"archiveType\"].count()\n", - " # generate the plot\n", - " ax.scatter(\n", - " df[\"geo_meanLon\"],\n", - " df[\"geo_meanLat\"],\n", - " marker=markers[i],\n", - " c=colors[i],\n", - " edgecolor=\"k\",\n", - " s=50,\n", - " transform=ccrs.Geodetic(),\n", - " label=f\"{type_i} (n = {count})\",\n", - " )\n", - "# add legend to the plot\n", - "ax.legend(\n", - " scatterpoints=1,\n", - " bbox_to_anchor=(0, -0.4),\n", - " loc=\"lower left\",\n", - " ncol=3,\n", - " fontsize=15,\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Questions 3" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You have just plotted the global distribution and temperature proxy type of the 692 records in the PAGES2k network!\n", - "\n", - "1. Which temperature proxy is the most and least abundant in this database?\n", - "2. In what region do you observe the most and least temperature records? Why might this be the case?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial1_Solution_3ad7aebe.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you explored the PAGES2K network, which offers an extensive collection of proxy temperature reconstructions spanning the last 2,000 years. You surveyed various types of paleoclimate proxies and archives available, in addition to crafting a global map pinpointing the locations of the PAGES2k proxy records. As you advance throughout this module, you will extract and meticulously analyze the temperature timelines embedded within reconstructions such as those shown here." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on existing notebooks from LinkedEarth that [convert LiPD files to a Pandas dataframe](https://github.com/LinkedEarth/notebooks/blob/master/PAGES2k/01.lipd2df.ipynb) and [create a map of the PAGES2k network](https:///github.com/LinkedEarth/notebooks/blob/master/PAGES2k/02.plot_map.ipynb).\n", - "\n", - "The following data is used in this tutorial:\n", - "\n", - "\n", - "* PAGES2k Consortium. A global multiproxy database for temperature reconstructions of the Common Era. Sci Data 4, 170088 (2017). https://doi.org/10.1038/sdata.2017.88" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D4_Tutorial1", - "provenance": [ - { - "file_id": "1lHuVrVtAW4fQzc0dFdlZuwY0i71KWw_t", - "timestamp": 1677637469824 - } - ], - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.ipynb deleted file mode 100644 index c7e96bd12..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.ipynb +++ /dev/null @@ -1,692 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 2: Reconstructing Past Changes in Ocean Climate**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": { - "image-2.png": { - "image/png": "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" - }, - "image-3.png": { - "image/png": "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" - }, - "image.png": { - "image/png": "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" - } - }, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In the previous days, you learned about the El Niño–Southern Oscillation (ENSO), and have explored how satellite data can be employed to track this phenomenon during the instrumental period. In this tutorial, you will explore how oxygen isotopes of corals can record changes in temperature associated with the phase of ENSO even further back in time.\n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Understand the types of marine proxies that are used to reconstruct past climate\n", - "* Create a stacked plot and warming stripe to visualize ENSO temperature reconstructions\n", - "\n", - "\n", - "\n", - "### **An Overview of Isotopes in Paleoclimate**\n", - "\n", - "In this tutorial, and many of the remaining tutorials in 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", - "\n", - "![image-3.png](attachment:image-3.png)\n", - "\n", - "Credit: [NASA Climate Science Investigations](https://www.ces.fau.edu/nasa/module-3/how-is-temperature-measured/isotopes.php)\n", - "\n", - "![image-2.png](attachment:image-2.png)\n", - "\n", - "Credit: [NASA Climate Science Investigations](https://www.ces.fau.edu/nasa/module-3/how-is-temperature-measured/isotopes.php)\n", - "\n", - "Changes in the ratio of the heavy to light isotope can reflect changes in different climate variables, depending on geographic location and the material being measured. The ratio represented in delta notation (δ) and in units of per mille (‰), and is calculated using the equation below (the same applies to the ratio of the heavy and light hydrogen isotopes):\n", - "\n", - "\n", - "![image.png](attachment:image.png)\n", - "\n", - "The terminology for discussing δ18O and δD can be a bit confusing and there are multiple ways to reference the same trends in the data. The most common terms used to describe isotopic compositions are **\"depleted\"** and **\"enriched\"**. These terms refer to the relative amout of the heavy isotopes. Therefore, a \"more depleted\" isotopic value is more depleted in the heavy isotope (i.e., there is less of the heavy isotope), whereas a \"more enriched\" isotopic value is more enriched in the heavy isotope (i.e., there is more of the heavy isotope). Other terms that are sometimes used to describe whether isotopes are depleted or enriched are **\"more negative\"** or **\"more positive\"**. Isotopic values can be both positive and negative, so using \"more negative\" and \"more positive\" can be a bit confusing. For example, if we have isotopic values are of -15‰ and -9‰, the value of -9‰ is \"more enriched\" (i.e., has more of the heavy isotope) or \"more positive\" (i.e., is closer to zero and positive values) than -15‰. Finally, the terms **\"smaller\"** or **\"larger\"** isotopic values can also be used to reference isotopes.\n", - "\n", - "Additional information about the use of isotopes in paleoclimate can be found [here](https://earthobservatory.nasa.gov/features/Paleoclimatology_OxygenBalance).\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import pandas as pd\n", - "import numpy as np\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import cartopy\n", - "import pyleoclim as pyleo\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import cartopy.feature as cfeature\n", - "from matplotlib import patches" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Assessing Variability Related to El Niño Using Pyleoclim Series\n", - "\n", - "ENSO is a recurring climate pattern involving changes in SST in the central and eastern tropical Pacific Ocean. As we learned in the introductory video, oxygen isotopes ([δ18O](https://en.wikipedia.org/wiki/Δ18O)) of corals are a commonly used proxy for reconstructing changes in tropical Pacific SST and ENSO. Long-lived corals are well-suited for studying paleo-ENSO variability because they store decades to centuries of sub-annually resolved proxy information in the tropical Pacific. The oxygen isotopes of corals are useful for studying ENSO because they record changes in sea-surface temperature (SST), with more positive values of δ18O corresponding to colder SSTs, and vice-versa.\n", - "\n", - "One approach for detecting ENSO from coral isotope data is applying a 2- to 7-year bandpass filter to the δ18O records to highlight ENSO-related variability and compare (quantitatively) the bandpassed coral records to the Oceanic Niño Index (ONI) you learned about in Day 2 and Day 3. While we won't be going into this amount of detail, you may utilize the methods sections of these papers as a guide: [Cobb et al.(2003)](https://www.nature.com/articles/nature01779), [Cobb et al.(2013)](https://www.science.org/doi/10.1126/science.1228246). In this tutorial we will be looking at the δ18O records and comparing to a plot of the ONI without this band-pass filtering, in part to highlight why the filtering is needed." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 1.1: Load coral oxygen isotope proxy reconstructions\n", - "\n", - "The two coral records we'll look at are from [Palmyra Atoll](https://en.wikipedia.org/wiki/Palmyra_Atoll) and [Line Islands](https://en.wikipedia.org/wiki/Line_Islands), both of which are in the tropical central Pacific Ocean.\n", - "\n", - "Let's plot these approximate locations as well as the Niño 3.4 region you are familiar with from the first three days." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# select data for the month of interest\n", - "# data = precip.sel(time='1979-01-01', method='nearest')\n", - "\n", - "# initate plot with the specific figure size\n", - "fig = plt.figure(figsize=(9, 6))\n", - "\n", - "# set base map projection\n", - "ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))\n", - "\n", - "# add background image to show land and sea\n", - "ax.stock_img()\n", - "\n", - "# add coastlines\n", - "ax.add_feature(cfeature.COASTLINE)\n", - "\n", - "# add in rectangle showing Nino 3.4 region\n", - "rectangle = patches.Rectangle(\n", - " (170, -5),\n", - " 50,\n", - " 10,\n", - " transform=ccrs.Geodetic(),\n", - " edgecolor=\"k\",\n", - " facecolor=\"none\",\n", - " linewidth=3,\n", - ")\n", - "ax.add_patch(rectangle)\n", - "\n", - "rx, ry = rectangle.get_xy()\n", - "cx = rx + rectangle.get_width() / 2.0\n", - "cy = ry + rectangle.get_height() / 2.0\n", - "\n", - "# add labels\n", - "ax.annotate(\n", - " \"Nino 3.4\",\n", - " (cx - 10, cy),\n", - " color=\"w\",\n", - " transform=ccrs.PlateCarree(),\n", - " weight=\"bold\",\n", - " fontsize=10,\n", - " ha=\"center\",\n", - " va=\"center\",\n", - ")\n", - "\n", - "# add the proxy locations\n", - "ax.scatter(\n", - " [-162.078333], [5.883611], transform=ccrs.Geodetic(), s=50, marker=\"v\", color=\"w\"\n", - ")\n", - "ax.scatter([-157.2], [1.7], transform=ccrs.Geodetic(), s=50, marker=\"v\", color=\"w\")\n", - "\n", - "# add labels\n", - "ax.annotate(\n", - " \"Palmyra Atoll\",\n", - " (-170, 10),\n", - " color=\"w\",\n", - " transform=ccrs.Geodetic(),\n", - " weight=\"bold\",\n", - " fontsize=10,\n", - " ha=\"center\",\n", - " va=\"center\",\n", - ")\n", - "\n", - "ax.annotate(\n", - " \"Line Islands\",\n", - " (-144, -1),\n", - " color=\"w\",\n", - " transform=ccrs.Geodetic(),\n", - " weight=\"bold\",\n", - " fontsize=10,\n", - " ha=\"center\",\n", - " va=\"center\",\n", - ")\n", - "\n", - "# change the map view to zoom in on central Pacific\n", - "ax.set_extent((120, 300, -25, 25), crs=ccrs.PlateCarree())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To analyze and visualize paleoclimate proxy time series, we will be using [Pyleoclim](https://pyleoclim-util.readthedocs.io/en/latest/). Pycleoclim is specifically designed for the analysis of paleoclimate data. The package is designed around object-oriented `Series`, which can be directly manipulated for plotting and time series-appropriate analysis and operation. \n", - "\n", - "The `Series` object describes the fundamentals of a time series. To create a Pyleoclim `Series`, we first need to load the data set, and then specify values for its various properties:\n", - "\n", - "* `time`: Time values for the time series\n", - "* `value`: Paleo values for the time series\n", - "* `time_name` (optional): Name of the time vector, (e.g., 'Time', 'Age'). This is used to label the x-axis on plots\n", - "* `time_unit` (optional): The units of the time axis (e.g., 'years')\n", - "* `value_name` (optional): The name of the paleo variable (e.g., 'Temperature')\n", - "* `value_unit` (optional): The units of the paleo variable (e.g., 'deg C')\n", - "* `label` (optional): Name of the time series (e.g., 'Nino 3.4')\n", - "* `clean_ts` (optional): If True (default), remove NaNs and set an increasing time axis\n", - "\n", - "A common data format for datasets downloaded from the NOAA Paleoclimate Database is a templated text file, which contains helpful data and metadata. \n", - "\n", - "Take a look at our two datasets [here](https://www.ncei.noaa.gov/pub/data/paleo/coral/east_pacific/palmyra_2003.txt) and [here](https://www.ncei.noaa.gov/pub/data/paleo/coral/east_pacific/cobb2013-fan-modsplice-noaa.txt).\n", - "\n", - "The functionality in python allows us to ignore all of the information at the beginning of the text files, and we can load the data directly into a `pandas.DataFrame` using `.read_csv()`.\n", - "\n", - "### Section 1.1.1: Load Palmyra coral data" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1031, - "status": "ok", - "timestamp": 1681584691666, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# download the data using the url\n", - "filename_Palmyra = \"palmyra_2003.txt\"\n", - "url_Palmyra = (\n", - " \"https://www.ncei.noaa.gov/pub/data/paleo/coral/east_pacific/palmyra_2003.txt\"\n", - ")\n", - "data_path = pooch_load(\n", - " filelocation=url_Palmyra, filename=filename_Palmyra\n", - ") # open the file\n", - "\n", - "# from the data set, we only want the data related to Modern Living Coral.\n", - "# this data is between row 6190 and 7539 of the dataset\n", - "rows = [int(row) for row in np.linspace(6190, 7539, 7539 - 6190 + 1)]\n", - "\n", - "# use pandas to read in the csv file\n", - "palmyra = pd.read_csv(\n", - " data_path,\n", - " skiprows=lambda x: x\n", - " not in rows, # number of rows to skip based on definition of rows above\n", - " sep=\"\\s+\", # how the data values are seperated (delimited) : '\\s+' = space\n", - " encoding=\"ISO-8859-1\",\n", - " names=[\"CalendarDate\", \"d180\"],\n", - " header=None,\n", - ")\n", - "\n", - "palmyra.head()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we have the data in a dataframe, we can pull the relevant columns of this datframe into a `Series` object in Pyleoclim, which will allow us to organize the relevant metadata so that we can get a well-labeled, publication-quality plot:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_palmyra = pyleo.Series(\n", - " time=palmyra[\"CalendarDate\"],\n", - " value=palmyra[\"d180\"],\n", - " time_name=\"Calendar date\",\n", - " time_unit=\"Years\",\n", - " value_name=r\"$d18O$\",\n", - " value_unit=\"per mille\",\n", - " label=\"Palmyra Coral\",\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Since we want to compare datasets based on different measurements (coral δ18O and the ONI, i.e., a temperature anomaly), it's helpful to standardize the data by removing it's estimated mean and dividing by its estimated standard deviation. Thankfully Pyleoclim has a [function](https://pyleoclim-util.readthedocs.io/en/v0.7.4/core/ui.html#pyleoclim.core.ui.Series.standardize) to do that for us." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "palmyra_stnd = ts_palmyra.standardize()\n", - "palmyra_stnd" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### Section 1.1.2: Load Line Island coral data\n", - "\n", - "We will repeat these steps for the other dataset." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# Download the data using the url\n", - "filename_cobb2013 = \"cobb2013-fan-modsplice-noaa.txt\"\n", - "url_cobb2013 = \"https://www.ncei.noaa.gov/pub/data/paleo/coral/east_pacific/cobb2013-fan-modsplice-noaa.txt\"\n", - "data_path2 = pooch_load(\n", - " filelocation=url_cobb2013, filename=filename_cobb2013\n", - ") # open the file\n", - "\n", - "# From the data set, we only want the data related to Modern Living Coral.\n", - "# So this data is between row 6190 and 7539 of the dataset\n", - "rows = [int(row) for row in np.linspace(127, 800, 800 - 127 + 1)]\n", - "line = pd.read_csv(\n", - " data_path2,\n", - " skiprows=lambda x: x not in rows,\n", - " sep=\"\\s+\",\n", - " encoding=\"ISO-8859-1\",\n", - " names=[\"age\", \"d18O\"],\n", - " header=None,\n", - ")\n", - "\n", - "line.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_line = pyleo.Series(\n", - " time=line[\"age\"],\n", - " value=line[\"d18O\"],\n", - " time_name=\"Calendar date\",\n", - " time_unit=\"Years\",\n", - " value_name=r\"$d18O$\",\n", - " value_unit=\"per mille\",\n", - " label=\"Line Island Coral\",\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "line_stnd = ts_line.standardize()\n", - "line_stnd" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Plot the Data Using Multiseries\n", - "\n", - "We will utilize the built in features of a [multiseries](https://pyleoclim-util.readthedocs.io/en/latest/core/api.html#multipleseries-pyleoclim-multipleseries) object to plot our coral proxy data side by side. To create a `pyleo.MultipleSeries`, we first create a list with our `pyleo.Series` objects and then pass this into a `pyleo.MultipleSeries`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# combine into a list\n", - "nino_comparison = [palmyra_stnd, line_stnd]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# create multiseries\n", - "nino = pyleo.MultipleSeries(nino_comparison, name=\"El Nino Comparison\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 942, - "status": "ok", - "timestamp": 1681584722114, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# plot the time series of both datasets\n", - "fig, ax = nino.stackplot(time_unit=\"year\", xlim=[1960, 2000], colors=[\"b\", \"g\"])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Questions 2: Climate Connection\n", - "\n", - "Recall that as SST becomes colder, δ18O becomes more positive, and vice versa. Compare the figure below of the ONI to the time series of coral δ18O you plotted above and answer the questions below.\n", - "\n", - "![](https://climatedataguide.ucar.edu/sites/default/files/styles/extra_large/public/2022-03/indices_oni_2_2_lg.png?itok=Zew3VK_4)\n", - "\n", - "Credit: [UCAR](https://climatedataguide.ucar.edu/sites/default/files/styles/extra_large/public/2022-03/indices_oni_2_2_lg.png?itok=Zew3VK_4)\n", - "\n", - "1. Do the ENSO events recorded by the ONI agree with the coral data?\n", - "2. What are some considerations you can think of when comparing proxies such as this to the ONI?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial2_Solution_dc5499b0.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1.3: Make Warming Stripes Plot**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can also make a warming stripe for this data `Series` using the [`.stripes()`](https://pyleoclim-util.readthedocs.io/en/latest/core/api.html#pyleoclim.core.multipleseries.MultipleSeries.stripes) method, where darker red stripes indicate a warmer eastern Pacific and possibly an El Niño phase, and darker blue stripes indicate a cooler eastern Pacific and possibly La Niña phase. Can you see the trend present in the data?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 409, - "status": "ok", - "timestamp": 1681584728212, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "fig, ax = nino.stripes(\n", - " ref_period=(1960, 1990), time_unit=\"year\", show_xaxis=True, cmap=\"RdBu\"\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, we discovered how oxygen isotopes within corals serve as a valuable archive, recording changes in temperature associated with ENSO phases.\n", - "\n", - "During our explorations, \n", - "- We ventured into the study of proxy-based coral δ18O records, gaining insights into the rich historical climate data encapsulated within these marine structures.\n", - "- We compared these records to noted ENSO events over a few decades, offering us a glimpse into the dynamic nature of this influential climate phenomenon." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on existing notebooks from LinkedEarth that uses the `Pyleoclim` package to [assess variability in the El Nino](https://github.com/LinkedEarth/PyleoTutorials/blob/main/notebooks/L0_a_quickstart.ipynb). \n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "\n", - "* Cobb,K., et al., Highly Variable El Niño–Southern Oscillation Throughout the Holocene.Science 339, 67-70(2013). https://doi.org/10.1126/science.1228246 accessible [here]( https://www.ncei.noaa.gov/pub/data/paleo/coral/east_pacific/palmyra_2003.txt)\n", - "\n", - "* Cobb, K., Charles, C., Cheng, H. et al. El Niño/Southern Oscillation and tropical Pacific climate during the last millennium. Nature 424, 271–276 (2003). https://doi.org/10.1038/nature01779 accessible [here]( https://www.ncei.noaa.gov/pub/data/paleo/coral/east_pacific/cobb2013-fan-modsplice-noaa.txt)" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [ - "WFp2yBJuVoRr", - "DZbqRlQKXhnc" - ], - "include_colab_link": true, - "name": "W1D4_Tutorial2", - "provenance": [ - { - "file_id": "1lHuVrVtAW4fQzc0dFdlZuwY0i71KWw_t", - "timestamp": 1677637469824 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.ipynb deleted file mode 100644 index a66ad530c..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.ipynb +++ /dev/null @@ -1,683 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 3: Reconstructing Past Changes in Terrestrial Climate**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, we’ll explore the Euro2K proxy network, which is a subset of PAGES2K, the database we explored in the first tutorial. We will specifically focus on interpreting temperature change over the past 2,000 years as recorded by proxy records from tree rings, speleothems, and lake sediments. To analyze these datasets, we will group them by archive and create time series plots to assess temperature variations.\n", - "\n", - "During this tutorial you will:\n", - "\n", - "* Plot temperature records based on three different terrestrial proxies\n", - "* Assess similarities and differences between the temperature records\n", - "\n", - "\n", - "\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import pyleoclim as pyleo\n", - "import pandas as pd\n", - "import numpy as np\n", - "import os\n", - "import pooch\n", - "import tempfile\n", - "import matplotlib.pyplot as plt\n", - "import cartopy\n", - "import cartopy.crs as ccrs\n", - "import cartopy.feature as cfeature" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Loading Terrestrial Paleoclimate Records\n", - "\n", - "First, we need to download the data. Similar to Tutorial 1, the data is stored as a LiPD file, and we will be using Pyleoclim to format and interpret the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# set the name to save the Euro2k data\n", - "fname = \"euro2k_data\"\n", - "\n", - "# download the data\n", - "lipd_file_path = pooch.retrieve(\n", - " url=\"https://osf.io/7ezp3/download/\",\n", - " known_hash=None,\n", - " path=\"./\",\n", - " fname=fname,\n", - " processor=pooch.Unzip(),\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# the LiPD object can be used to load datasets stored in the LiPD format.\n", - "# in this first case study, we will load an entire library of LiPD files:\n", - "d_euro = pyleo.Lipd(os.path.join(\".\", f\"{fname}.unzip\", \"Euro2k\"))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Temperature Reconstructions" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Before plotting, let's narrow the data down a bit. We can filter all of the data so that we only keep reconstructions of temperature from terrestrial archives (e.g. tree rings, speleothems and lake sediments). This is accomplished with the function below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "def filter_data(dataset, archive_type, variable_name):\n", - " \"\"\"\n", - " Return a MultipleSeries object with the variable record (variable_name) for a given archive_type and coordinates.\n", - " \"\"\"\n", - " # Create a list of dictionary that can be iterated upon using Lipd.to_tso method\n", - " ts_list = dataset.to_tso()\n", - " # Append the correct indices for a given value of archive_type and variable_name\n", - " indices = []\n", - " lat = []\n", - " lon = []\n", - " for idx, item in enumerate(ts_list):\n", - " # Check that it is available to avoid errors on the loop\n", - " if \"archiveType\" in item.keys():\n", - " # If it's a archive_type, then proceed to the next step\n", - " if item[\"archiveType\"] == archive_type:\n", - " if item[\"paleoData_variableName\"] == variable_name:\n", - " indices.append(idx)\n", - " print(indices)\n", - " # Create a list of LipdSeries for the given indices\n", - " ts_list_archive_type = []\n", - " for indice in indices:\n", - " ts_list_archive_type.append(pyleo.LipdSeries(ts_list[indice]))\n", - "\n", - " # save lat and lons of proxies\n", - " lat.append(ts_list[indice][\"geo_meanLat\"])\n", - " lon.append(ts_list[indice][\"geo_meanLon\"])\n", - "\n", - " return pyleo.MultipleSeries(ts_list_archive_type), lat, lon" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In the function above, the [`Lipd.to_tso`](https://pyleoclim-util.readthedocs.io/en/latest/core/api.html#pyleoclim.core.lipd.Lipd.to_tso) method is used to obtain a list of dictionaries that can be iterated upon. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_list = d_euro.to_tso()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Dictionaries are native to Python and can be explored as shown below. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# look at available entries for just one time-series\n", - "ts_list[0].keys()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# print relevant information for all entries\n", - "for idx, item in enumerate(ts_list):\n", - " print(str(idx) + \": \" + item[\"dataSetName\"] + \": \" + item[\"paleoData_variableName\"])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now let's use our pre-defined function to create a new list that only has temperature reconstructions based on proxies from **lake sediments**:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 163, - "status": "ok", - "timestamp": 1680674812384, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "ms_euro_lake, euro_lake_lat, euro_lake_lon = filter_data(\n", - " d_euro, \"lake sediment\", \"temperature\"\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "And a new list that only has temperature reconstructions based on proxies from **tree rings**:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 187, - "status": "ok", - "timestamp": 1680674816989, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "ms_euro_tree, euro_tree_lat, euro_tree_lon = filter_data(d_euro, \"tree\", \"temperature\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "And finally, a new list that only has temperature information based on proxies from **speleothems**:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 200, - "status": "ok", - "timestamp": 1680674825774, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "ms_euro_spel, euro_spel_lat, euro_spel_lon = filter_data(d_euro, \"speleothem\", \"d18O\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Coding Exercises 2\n", - "\n", - "Using the coordinate information output from the `filter_data()` function, make a plot of the locations of the proxies using the markers and colors from Tutorial 1. Note that data close together may not be very visible." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# initate plot with the specific figure size\n", - "fig = plt.figure(figsize=(9, 6))\n", - "\n", - "# set base map projection\n", - "ax = plt.axes(projection=ccrs.Robinson())\n", - "\n", - "ax.set_global()\n", - "\n", - "# add land fratures using gray color\n", - "ax.add_feature(cfeature.LAND, facecolor=\"k\")\n", - "\n", - "# add coastlines\n", - "ax.add_feature(cfeature.COASTLINE)\n", - "\n", - "# add the proxy locations\n", - "# Uncomment and complete following line\n", - "# ax.scatter(\n", - "# ...,\n", - "# ...,\n", - "# transform=ccrs.Geodetic(),\n", - "# label=...,\n", - "# s=50,\n", - "# marker=\"d\",\n", - "# color=[0.52734375, 0.8046875, 0.97916667],\n", - "# edgecolor=\"k\",\n", - "# zorder=2,\n", - "# )\n", - "# ax.scatter(\n", - "# ...,\n", - "# ...,\n", - "# transform=ccrs.Geodetic(),\n", - "# label=...,\n", - "# s=50,\n", - "# marker=\"p\",\n", - "# color=[0.73828125, 0.71484375, 0.41796875],\n", - "# edgecolor=\"k\",\n", - "# zorder=2,\n", - "# )\n", - "# ax.scatter(\n", - "# ...,\n", - "# ...,\n", - "# transform=ccrs.Geodetic(),\n", - "# label=...,\n", - "# s=50,\n", - "# marker=\"8\",\n", - "# color=[1, 0, 0],\n", - "# edgecolor=\"k\",\n", - "# zorder=2,\n", - "# )\n", - "\n", - "# change the map view to zoom in on central Pacific\n", - "ax.set_extent((0, 360, 0, 90), crs=ccrs.PlateCarree())\n", - "\n", - "ax.legend(\n", - " scatterpoints=1,\n", - " bbox_to_anchor=(0, -0.4),\n", - " loc=\"lower left\",\n", - " ncol=3,\n", - " fontsize=15,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial3_Solution_733e0c12.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Since we are going to compare temperature datasets based on different terrestrial climate archives (lake sediments, tree rings and speleothems), the quantitative values of the measurements in each record will differ (i.e., the lake sediment and tree ring data are temperature in degrees C, but the speleothem data is oxygen isotopes in per mille). Therefore, to more easily and accurately compare temperature between the records, it's helpful to standardize the data as we did in tutorial 2. The `.standardize()` function removes the estimated mean of the time series and divides by its estimated standard deviation." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# standardize the data\n", - "spel_stnd = ms_euro_spel.standardize()\n", - "lake_stnd = ms_euro_lake.standardize()\n", - "tree_stnd = ms_euro_tree.standardize()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we can use Pyleoclim functions to create three stacked plots of this data with lake sediment records on top, tree ring reconstructions in the middle and speleothem records on the bottom. \n", - "\n", - "\n", - "Note that the colors used for the time series in each plot are the default colors generated by the function, so the corresponding colors in each of the three plots are not relevant." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4905, - "status": "ok", - "timestamp": 1680674844494, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# note the x axis is years before present, so read from left to right moving back in time\n", - "\n", - "ax = lake_stnd.stackplot(\n", - " label_x_loc=1.7,\n", - " xlim=[0, 2000],\n", - " v_shift_factor=1,\n", - " figsize=[9, 5],\n", - " time_unit=\"yrs BP\",\n", - ")\n", - "ax[0].suptitle(\"Lake Cores\", y=1.2)\n", - "\n", - "ax = tree_stnd.stackplot(\n", - " label_x_loc=1.7,\n", - " xlim=[0, 2000],\n", - " v_shift_factor=1,\n", - " figsize=[9, 5],\n", - " time_unit=\"yrs BP\",\n", - ")\n", - "ax[0].suptitle(\"Tree Rings\", y=1.2)\n", - "\n", - "# recall d18O is a proxy for SST, and that more positive d18O means colder SST\n", - "ax = spel_stnd.stackplot(\n", - " label_x_loc=1.7,\n", - " xlim=[0, 2000],\n", - " v_shift_factor=1,\n", - " figsize=[9, 5],\n", - " time_unit=\"yrs BP\",\n", - ")\n", - "ax[0].suptitle(\"Speleothems\", y=1.2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Questions 2" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Using the plots we just made (and recalling that all of these records are from Europe), let's make some inferences about the temperature data over the past 2,000 years:\n", - "\n", - "1. Recall that δ18O is a proxy for SST, and that more positive δ18O means colder SST. Do the temperature records based on a single proxy type record similar patterns?\n", - "2. Do the three proxy types collectively record similar patterns? \n", - "3. What might be causing the more frequent variations in temperature?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial3_Solution_cb5cb2f4.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, we explored how to use the Euro2k proxy network to investigate changes in temperature over the past 2,000 years from tree rings, speleothems, and lake sediments. To analyze these diverse datasets, we categorized them based on their archive type and constructed time series plots." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on an existing notebook from LinkedEarth that provides instruction on [working with LiPD files](https://github.com/LinkedEarth/PyleoTutorials/blob/main/notebooks/L1_working_with_LiPD.ipynb). \n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "* Euro2k database: PAGES2k Consortium., Emile-Geay, J., McKay, N. et al. A global multiproxy database for temperature reconstructions of the Common Era. Sci Data 4, 170088 (2017). https://doi.org/10.1038/sdata.2017.88" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D4_Tutorial3", - "provenance": [ - { - "file_id": "1lHuVrVtAW4fQzc0dFdlZuwY0i71KWw_t", - "timestamp": 1677637469824 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.ipynb deleted file mode 100644 index 4dc1ad31f..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.ipynb +++ /dev/null @@ -1,486 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 4: Reconstructing Past Changes in Atmospheric Climate**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, we’ll analyze δD and atmospheric CO2 data from the EPICA Dome C ice core. Recall from the video that δD and δ18O measurements on ice cores record past changes in temperature, and that measurements of CO2 trapped in ice cores can be used to reconstruction past changes in Earth's atmospheric composition.\n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Plot δD and CO2 records from the EPICA Dome C ice core\n", - "* Assess changes in temperature and atmospheric greenhouse gas concentration over the past 800,000 years \n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# Import libraries\n", - "import pandas as pd\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import pyleoclim as pyleo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 1: Exploring past variations in atmospheric CO2\n", - "\n", - "As we learned in the video, paleoclimatologists can reconstruct past changes in atmospheric composition by measuring gases trapped in layers of ice from ice cores retrieved from polar regions and high elevation mountain glaciers. We'll specifically be focusing on paleoclimate records produced from the [EPICA Dome C](https://en.wikipedia.org/wiki/Dome_C) ice core from Antarctica.\n", - "\n", - "![](https://media.springernature.com/full/springer-static/image/art%3A10.1038%2Fncomms8850/MediaObjects/41467_2015_Article_BFncomms8850_Fig1_HTML.jpg?as=webp)\n", - "\n", - "Credit: [Conway et al 2015, *Nature Communications*](https://www.nature.com/articles/ncomms8850)\n", - "\n", - "\n", - "Let's start by downloading the data for the composite CO2 record for EPICA Dome C in Antarctica:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 853, - "status": "ok", - "timestamp": 1680729021239, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# donwload the data using the url\n", - "filename_antarctica2015 = \"antarctica2015co2composite.txt\"\n", - "url_antarctica2015 = \"https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/antarctica2015co2composite.txt\"\n", - "\n", - "data_path = pooch_load(\n", - " filelocation=url_antarctica2015, filename=filename_antarctica2015\n", - ") # open the file\n", - "\n", - "co2df = pd.read_csv(data_path, skiprows=137, sep=\"\\t\")\n", - "\n", - "co2df.head()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Next, we can store this data as a `Series` in Pyleoclim:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_co2 = pyleo.Series(\n", - " time=co2df[\"age_gas_calBP\"] / 1000,\n", - " value=co2df[\"co2_ppm\"],\n", - " time_name=\"Age\",\n", - " time_unit=\"kyr BP\",\n", - " value_name=r\"$CO_2$\",\n", - " value_unit=\"ppm\",\n", - " label=\"EPICA Dome C CO2\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can now plot age vs. CO2 from EPICA Dome C:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 800, - "status": "ok", - "timestamp": 1680729048261, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "ts_co2.plot(color=\"C1\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Notice that the x-axis is plotted with present-day (0 kyr) on the left and the past (800 kyr) on the right. This is a common practice when plotting paleoclimate time series data.\n", - "\n", - "These changes in CO2 are tracking glacial-interglacial cycles (Ice Ages) over the past 800,000 years. Recall that these Ice Ages occur as a result of changes in the orbital cycles of Earth: eccentricity (100,000 year cycle), obliquity (40,000 year cycle) and precession (21,000 year cycle). Can you observe them in the graph above?" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2: Exploring the relationship between δD and atmospheric CO2" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To investigate the relationship between glacial cycles, atmospheric CO2 and temperature, we can compare CO2 to a record of hydrogen isotopic values (δD) of ice cores, which is a proxy for temperature in this case. Remember, when interpreting isotopic measurements of ice cores, a more depleted δD value indicates cooler temperatures, and a more enriched δD value indicates warmer temperatures. This is the opposite relationship we have looked at previously with δ18O, not because we are looking at a different isotope, but because we are not looking at the isotopic composition of ice rather than the isotopic composition of the ocean.\n", - "\n", - "Let's download the EPICA Dome C δD data, store it as a `Series`, and plot the data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1120, - "status": "ok", - "timestamp": 1680729854978, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# donwload the data using the url\n", - "filename_edc3deuttemp2007 = \"edc3deuttemp2007.txt\"\n", - "url_edc3deuttemp2007 = \"https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/epica_domec/edc3deuttemp2007.txt\"\n", - "data_path = pooch_load(\n", - " filelocation=url_edc3deuttemp2007, filename=filename_edc3deuttemp2007\n", - ") # open the file\n", - "\n", - "dDdf = pd.read_csv(data_path, skiprows=91, encoding=\"unicode_escape\", sep=\"\\s+\")\n", - "# remove nan values\n", - "dDdf.dropna(inplace=True)\n", - "\n", - "dDdf.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "dDts = pyleo.Series(\n", - " time=dDdf[\"Age\"] / 1000,\n", - " value=dDdf[\"Deuterium\"],\n", - " time_name=\"Age\",\n", - " time_unit=\"kyr BP\",\n", - " value_name=r\"$\\delta D$\",\n", - " value_unit=\"\\u2030\",\n", - " label=r\"EPICA Dome C $\\delta D$\",\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 588, - "status": "ok", - "timestamp": 1680729931069, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "dDts.plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "When we observe the δD data, we see very similar patterns as in the atmospheric CO2 data. To more easily compare the two records, we can plot the two series side by side by putting them into a `MultipleSeries` object. Since the δD and CO2 values have different units, we can first standardize the series and then plot the data. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 690, - "status": "ok", - "timestamp": 1680730119909, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# combine series\n", - "ms = pyleo.MultipleSeries([dDts, ts_co2])\n", - "\n", - "# standarize series and plot\n", - "ms.standardize().plot()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we can more easily compare the timing and magnitude of changes in CO2 and δD at EPICA Dome C over the past 800,000 years. During glacial periods, δD was more depleted (cooler temperatures) and atmospheric CO2 was lower. During interglacial periods, δD was more enriched (warmer temperatures) and atmospheric CO2 was higher." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Questions 2: Climate Connection**\n", - "\n", - "1. Why do δD, CO2 and glacial cycles covary so closely?\n", - "2. Can you identify glacial and interglacial periods? Today, are we in an interglacial or glacial period?\n", - "3. Do the cooling and warming periods of the cycles happen at the same rate?\n", - "4. What climate forcings do you think are driving these cycles?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial4_Solution_d4549d29.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, we dove into the captivating world of paleoclimatology, focusing on the analysis of hydrogen isotopes (δD) and atmospheric CO2 data from the EPICA Dome C ice core. This involved understanding how δD and δ18O measurements from ice cores can enlighten us about past temperature changes, and how trapped CO2 in these ice cores can help us reconstruct shifts in Earth's atmospheric composition.\n", - "\n", - "By the end of the tutorial, you should be comfortable with plotting δD and CO2 records from the EPICA Dome C ice core and assessing changes in temperature and atmospheric greenhouse gas concentrations over the past 800,000 years. In the next tutorial, we'll introduce various paleoclimate data analysis tools. \n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on an existing notebook from LinkedEarth that [explores EPICA Dome C paleoclimate records](https://github.com/LinkedEarth/PaleoBooks/blob/master/notebooks/EpicaDomeC_explore.ipynb). \n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "* Jouzel, J., et al. Orbital and Millennial Antarctic Climate Variability over the Past 800,000 Years, Science (2007). https://doi.org/10.1126/science.1141038. \n", - "* Lüthi, D., Le Floch, M., Bereiter, B. et al. High-resolution carbon dioxide concentration record 650,000–800,000 years before present. Nature 453, 379–382 (2008). https://doi.org/10.1038/nature06949.\n", - "* Bereiter, B. et al., Revision of the EPICA Dome C CO2 record from 800 to 600 kyr before present, Geoph. Res. Let. (2014). https://doi.org/10.1002/2014GL061957. " - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D4_Tutorial4", - "provenance": [ - { - "file_id": "1MbCIbSJ0zMd-fjaWsarE_hpKOo770sz-", - "timestamp": 1680541609255 - }, - { - "file_id": "1lHuVrVtAW4fQzc0dFdlZuwY0i71KWw_t", - "timestamp": 1677637469824 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.ipynb deleted file mode 100644 index e7aa103e8..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.ipynb +++ /dev/null @@ -1,993 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 5: Paleoclimate Data Analysis Tools**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will explore various computational analyses for interpreting paleoclimate data and understand why these methods are useful. A common issue in paleoclimate is the presence of uneven time spacing between consecutive observations. `Pyleoclim` includes several methods that can deal with uneven sampling effectively, but there are certain applications and analyses for which it's ncessary to place the records on a uniform time axis. In this tutorial you'll learn a few ways to do this with `Pyleoclim`. Additionally, we will explore another useful paleoclimate data analysis tool, Principal Component Analysis (PCA), which allows us to identify a common signal between various paleoclimate reconstructions. \n", - "\n", - "By the end of this tutorial you'll be able to perform the following data analysis techniques on proxy-based climate reconstructions:\n", - "\n", - "* Interpolation\n", - "* Binning \n", - "* Principal component analysis\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import pandas as pd\n", - "import cartopy\n", - "import pyleoclim as pyleo\n", - "import matplotlib.pyplot as plt\n", - "import pooch\n", - "import os\n", - "import tempfile" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Load the sample dataset for analysis**\n", - "\n", - "For this tutorial, we are going to use an example dataset to practice the various data analysis techniques. The dataset we'll be using is a record of hydrogen isotopes of leaf waxes (δDwax) from Lake Tanganyika in East Africa [(Tierney et al., 2008)](https://www.science.org/doi/10.1126/science.1160485?url_ver=Z39.88-2003&rfr_id=ori:rid:crossref.org&rfr_dat=cr_pub%20%200pubmed). Recall from the video that δDwax is a proxy that is typically thought to record changes in the amount of precipitation in the tropics via the amount effect. In the previous tutorial, we looked at δD data from high-latitude ice cores. In that case, δD was a proxy for temperature, but in the tropics, δD more commonly reflects rainfall amount, as explained in the introductory video.\n", - "\n", - "Let's first read the data from a .csv file." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "filename_tang = \"tanganyika_dD.csv\"\n", - "url_tang = \"https://osf.io/sujvp/download/\"\n", - "tang_dD = pd.read_csv(pooch_load(filelocation=url_tang, filename=filename_tang))\n", - "tang_dD.head()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can now create a `Series` in Pyleoclim and assign names to different variables so that we can easily plot the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 736, - "status": "ok", - "timestamp": 1681484071869, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "ts_tang = pyleo.Series(\n", - " time=tang_dD[\"Age\"],\n", - " value=tang_dD[\"dD_IVonly\"],\n", - " time_name=\"Age\",\n", - " time_unit=\"yr BP\",\n", - " value_name=\"dDwax\",\n", - " value_unit=\"per mille\",\n", - " label=\"Lake Tanganyika dDprecip\",\n", - ")\n", - "\n", - "ts_tang.plot(color=\"C1\", invert_yaxis=True)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You may notice that the y-axis is inverted. When we're plotting δD data, we typically invert the y-axis because more negative (\"depleted\") values suggest increased rainfall, whereas more positive (\"enriched\") values suggest decreased rainfall." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Uniform Time-Sampling of the Data**\n", - "There are a number of different reasons we might want to assign new values to our data. For example, if the data is not evenly spaced, we might need to resample in order to use a sepcific data analysis technique or to more easily compare to other data of a different sampling resolution. \n", - "\n", - "First, let's check whether our data is already evenly spaced using the `.is_evenly_spaced()` method:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 138, - "status": "ok", - "timestamp": 1681484075182, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "ts_tang.is_evenly_spaced()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Our data is not evenly spaced. There are a few different methods available in `pyleoclim` to place the data on a uniform axis, and in this tutorial, we'll explore two methods: interpolating and binning. In general, these methods use the available data near a chosen time to estimate what the value was at that time, but each method differs in which nearby data points it uses and how it uses them.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: Interpolation**\n", - "To start out, let's try using interpolation to evenly space our data. Interpolation projects the data onto an evenly spaced time axis with a distance between points (step size) of our choosing. There are a variety of different methods by which the data can be interpolated, these being: `linear`, `nearest`, `zero`, `slinear`, `quadratic`, `cubic`, `previous`, and `next`. More on these and their associated key word arguments can be found in the [documentation](https://pyleoclim-util.readthedocs.io/en/latest/core/api.html#pyleoclim.core.series.Series.interp). By default, the function `.interp()` implements linear interpolation:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "tang_linear = ts_tang.interp() # default method = 'linear'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 167, - "status": "ok", - "timestamp": 1681484080381, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# check whether or not the series is now evenly spaced\n", - "tang_linear.is_evenly_spaced()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we've interpolated our data, let's compare the original dataset to the linearly interpolated dataset we just created." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 443, - "status": "ok", - "timestamp": 1681484174043, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots() # assign a new plot axis\n", - "ts_tang.plot(ax=ax, label=\"Original\", invert_yaxis=True)\n", - "tang_linear.plot(ax=ax, label=\"Linear\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Notice there are only some minor differences between the original and linearly interpolated data.\n", - "\n", - "You can print the data in the original and interpolated time series to see the difference in the ages between the two datasets. The interpolated dataset is now evenly spaced with a δD value every ~290 years." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_tang" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "tang_linear" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's compare a few of the different interpolation methods (e.g., quadratic, next, zero) with one another just to see how they are similar and different:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots() # assign a new plot axis\n", - "ts_tang.plot(ax=ax, label=\"original\", invert_yaxis=True)\n", - "for method in [\"linear\", \"quadratic\", \"next\", \"zero\"]:\n", - " ts_tang.interp(method=method).plot(\n", - " ax=ax, label=method, alpha=0.9\n", - " ) # plot all the method we want" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The methods can produce slightly different results, but mostly reproduce the same overall trend. In this case, the quadractic method may be less appropriate than the other methods." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: Binning**\n", - "Another option for resampling our data onto a uniform time axis is binning. Binning is when a set of time intervals is defined and data is grouped or binned with other data in the same interval, then all those points in a \"bin\" are averaged to get a data value for that bin. The defaults for binning pick a bin size at the coarsest time spacing present in the dataset and average data over a uniform sequence of such intervals. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "tang_bin = (\n", - " ts_tang.bin()\n", - ") # default settings pick the coarsest time spacing in the data as the binning period" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 457, - "status": "ok", - "timestamp": 1681484224785, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots() # assign a new plot axis\n", - "ts_tang.plot(ax=ax, label=\"Original\", invert_yaxis=True)\n", - "tang_bin.plot(ax=ax, label=\"Binned\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Again, notice that although there are some minor differences between the original and binned data, the records still capture the same overall trend." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Coding Exercises 2.2**\n", - "\n", - "\n", - "1. Experiment with different bin sizes to see how this affects the resampling. You can do so by adding `bin_size = ` to `ts_tang.bin()`. Try a bin size of 500 years and 1,000 years and plot both of them on the same graph as the original data and the binned data using the default bin size." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# bin size of 500\n", - "tang_bin_500 = ...\n", - "\n", - "# bin size of 1000\n", - "tang_bin_1000 = ...\n", - "\n", - "# plot\n", - "fig, ax = plt.subplots() # assign a new plot axis\n", - "_ = ...\n", - "_ = ...\n", - "_ = ...\n", - "_ = ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial5_Solution_6e830e26.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: Principal Component Analysis (PCA)**\n", - "Large datasets, such as global climate datasets, are often difficult to interpret due to their multiple dimensions. Although tools such as Xarray help us to organize large, multidimensional climate datasets, it can still sometimes be difficult to interpret certain aspects of such data. Principal Component Analysis (PCA) is a tool for reducing the dimensionality of such datasets and increasing interpretability with minimal modification or loss of data. In other words, PCA allows us to reduce the number of variables of a dataset, while preserving as much information as possible.\n", - "\n", - "The first step in PCA is to calculate a matrix that summarizes how the variables in a dataset all relate to one another. This matrix is then broken down into new uncorrelated variables that are linear combinations or mixtures of the initial variables. These new variables are the **principal components**. The initial dimensions of the dataset determines the number of principal components calculated. Most of the information within the initial variables is compressed into the first components. Additional details about PCA and the calculations involved can be found [here](https://builtin.com/data-science/step-step-explanation-principal-component-analysis).\n", - "\n", - "Applied to paleoclimate, PCA can reduce the dimensionality of large paleoclimate datasets with multiple variables and can help us identify a common signal between various paleoclimate reconstructions. An example of a study that applies PCA to paleoclimate is [Otto-Bliesner et al., 2014](https://www.science.org/doi/full/10.1126/science.1259531). This study applies PCA to rainfall reconstructions from models and proxies from throughout Africa to determine common climate signals in these reconstructions.\n", - "\n", - "In this section, we will calculate the PCA of four δD paleoclimate records from Africa to assess common climate signals in the four records. In order to calculate the PCA of multiple paleoclimate time series, all of the records need to be on a common time-step. To do so, we can apply the resampling tools we've learned in this tutorial." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "So far, we've been looking at δD data from Lake Tanganyika in tropical East Africa. Let's compare this δD record to other existing δD records from lake and marine sediment cores in tropical Africa from the Gulf of Aden [(Tierney and deMenocal, 2017)](https://doi.org/10.1126/science.1240411), Lake Bosumtwi [(Shanahan et al., 2015)](https://doi.org/10.1038/ngeo2329), and the West African Margin [(Tierney et al., 2017)](https://doi.org/10.1126/sciadv.1601503).\n", - "\n", - "First, let's load these datasets:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 484, - "status": "ok", - "timestamp": 1681484228855, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# Gulf of Aden\n", - "filename_aden = \"aden_dD.csv\"\n", - "url_aden = \"https://osf.io/gm2v9/download/\"\n", - "aden_dD = pd.read_csv(pooch_load(filelocation=url_aden, filename=filename_aden))\n", - "aden_dD.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 370, - "status": "ok", - "timestamp": 1681484235076, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# Lake Bosumtwi\n", - "filename_Bosumtwi = \"bosumtwi_dD.csv\"\n", - "url_Bosumtwi = \"https://osf.io/mr7d9/download/\"\n", - "bosumtwi_dD = pd.read_csv(\n", - " pooch_load(filelocation=url_Bosumtwi, filename=filename_Bosumtwi)\n", - ")\n", - "bosumtwi_dD.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 354, - "status": "ok", - "timestamp": 1681484237400, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# GC27 (West African Margin)\n", - "filename_GC27 = \"gc27_dD.csv\"\n", - "url_GC27 = \"https://osf.io/k6e3a/download/\"\n", - "gc27_dD = pd.read_csv(pooch_load(filelocation=url_GC27, filename=filename_GC27))\n", - "gc27_dD.head()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Next, let's convert each dataset into a `Series` in Pyleoclim." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_tanganyika = pyleo.Series(\n", - " time=tang_dD[\"Age\"],\n", - " value=tang_dD[\"dD_IVonly\"],\n", - " time_name=\"Age\",\n", - " time_unit=\"yr BP\",\n", - " value_name=\"dDwax\",\n", - " label=\"Lake Tanganyika\",\n", - ")\n", - "ts_aden = pyleo.Series(\n", - " time=aden_dD[\"age_calBP\"],\n", - " value=aden_dD[\"dDwaxIVcorr\"],\n", - " time_name=\"Age\",\n", - " time_unit=\"yr BP\",\n", - " value_name=\"dDwax\",\n", - " label=\"Gulf of Aden\",\n", - ")\n", - "ts_bosumtwi = pyleo.Series(\n", - " time=bosumtwi_dD[\"age_calBP\"],\n", - " value=bosumtwi_dD[\"d2HleafwaxC31ivc\"],\n", - " time_name=\"Age\",\n", - " time_unit=\"yr BP\",\n", - " value_name=\"dDwax\",\n", - " label=\"Lake Bosumtwi\",\n", - ")\n", - "ts_gc27 = pyleo.Series(\n", - " time=gc27_dD[\"age_BP\"],\n", - " value=gc27_dD[\"dDwax_iv\"],\n", - " time_name=\"Age\",\n", - " time_unit=\"yr BP\",\n", - " value_name=\"dDwax\",\n", - " label=\"GC27\",\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now let's set up a `MultipleSeries` using Pyleoclim with all four δD datasets. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_list = [ts_tanganyika, ts_aden, ts_bosumtwi, ts_gc27]\n", - "ms_africa = pyleo.MultipleSeries(ts_list, label=\"African dDwax\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can now create a stackplot with all four δD records:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 756, - "status": "ok", - "timestamp": 1681484266500, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "fig, ax = ms_africa.stackplot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "By creating a stackplot, we can visually compare between the datasets. However, the four δD records aren't the same resolution and don't span the same time interval.\n", - "\n", - "To better compare the records and assess a common trend, we can use PCA. First, we can use [`.common_time()`] to place the records on a shared time axis with a common sampling frequency. This function takes the argument `method`, which can be either `bin`, `interp`, and `gdkernel`. The binning and interpolation methods are what we just covered in the previous section. Let's set the time step to 500 years, the method to `interp`, and standarize the data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1048, - "status": "ok", - "timestamp": 1681484350993, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "africa_ct = ms_africa.common_time(method=\"interp\", step=0.5).standardize()\n", - "fig, ax = africa_ct.stackplot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We now have standardized δD records that are the same sampling resolution and span the same time interval. Note this meant trimming the longer time series down to around 20,000 years in length.\n", - "\n", - "We can now apply PCA which will allow us to quantitatively identify a common signal between the four δD paleoclimate reconstructions through the [`.pca`](https://pyleoclim-util.readthedocs.io/en/latest/core/api.html#pyleoclim.core.multipleseries.MultipleSeries.pca) method. Note that this line of code may take a few minutes to run." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "africa_PCA = africa_ct.pca()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The result is an object containing multiple outputs, and with two plotting methods attached to it. The two outputs we'll look at are pctvar (the variance) and pcs (the principal components). \n", - "\n", - "First, let's print the percentage of variance accounted for by each mode, which is saved as pctvar:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 224, - "status": "ok", - "timestamp": 1681484449770, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "print(africa_PCA.pctvar.round())" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This means that 97% of the variance in the four paleoclimate records is explained by the first principal component. The number of datasets in the PCA constrains the number of principal components that can be defined, which is why we only have four components in this example.\n", - "\n", - "We can now look at the principal component of the first mode of variance. Let's create a new series for the first mode of variance and plot it against the original datasets:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "africa_pc1 = africa_PCA.pcs" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "africa_mode1 = pyleo.Series(\n", - " time=africa_ct.series_list[0].time,\n", - " value=africa_PCA.pcs[:, 0],\n", - " label=r\"$PC_1$\",\n", - " value_name=\"PC1\",\n", - " time_name=\"age\",\n", - " time_unit=\"yr BP\",\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1026, - "status": "ok", - "timestamp": 1681484506972, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "fig, ax1 = plt.subplots()\n", - "\n", - "ax1.set_ylabel(\"dDwax\")\n", - "ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis\n", - "ax2.set_ylabel(\"PC1\") # we already handled the x-label with ax1\n", - "\n", - "# plt.plot(mode1.time,pc1_scaled)\n", - "africa_mode1.plot(color=\"black\", ax=ax2, invert_yaxis=True)\n", - "africa_ct.plot(ax=ax1, linewidth=0.5)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The original δD records are shown in the colored lines, and the first principal component (PC1) time series is shown in black. \n", - "\n", - "## **Questions 3: Climate Connection**\n", - " \n", - "\n", - "1. How do the original time series compare to the PC1 time series? Do they record similar trends?\n", - "2. Which original δD record most closely resembles the PC1 time series? Which is the most different?\n", - "3. What changes in climate does the PC1 time series record over the past 20,000 years? *Hint: remember that more depleted (more negative) δD suggests increased rainfall.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial5_Solution_b2ed69d2.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you explored a variety of computational techniques for analyzing paleoclimate data. You learned how to handle irregular data and place these records on a uniform time axis using interpolation and binning. \n", - "\n", - "You then explored Principal Component Analysis (PCA), a method that reveals common signals across various paleoclimate reconstructions. To effectively utilize PCA, it's essential to have all records on the same sampling resolution and same time-step, which can be achieved using the resampling tools you learned in this tutorial.\n", - "\n", - "For your practical example, we used a dataset of hydrogen isotopes of leaf waxes (δDwax) from Lake Tanganyika in East Africa to further enhance your understanding of the discussed techniques, equipping you to better analyze and understand the complexities of paleoclimate data." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on existing notebooks from LinkedEarth for [anlayzing LiPD datasets](https://github.com/LinkedEarth/paleoHackathon/blob/main/notebooks/PaleoHack-nb03_EDA.ipynb) and [resampling data with `Pyleoclim`](https://github.com/LinkedEarth/PyleoTutorials/blob/main/notebooks/L1_uniform_time_sampling.ipynb).\n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "* Tierney, J.E., et al. 2008. Northern Hemisphere Controls on Tropical Southeast African Climate During the Past 60,000 Years. Science, Vol. 322, No. 5899, pp. 252-255, 10 October 2008. https://doi.org/10.1126/science.1160485.\n", - "* Tierney, J.E., and deMenocal, P.. 2013. Abrupt Shifts in Horn of Africa Hydroclimate Since the Last Glacial Maximum. Science, 342(6160), 843-846. https://doi.org/10.1126/science.1240411.\n", - "* Tierney, J.E., Pausata, F., deMenocal, P. 2017. Rainfall Regimes of the Green Sahara. Science Advances, 3(1), e1601503. https://doi.org/10.1126/sciadv.1601503. \n", - "* Shanahan, T.M., et al. 2015. The time-transgressive termination of the African Humid Period. Nature Geoscience, 8(2), 140-144. https://doi.org/10.1038/ngeo2329." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W1D4_Tutorial5", - "provenance": [ - { - "file_id": "1l594NT5i1ubNU9d5esRFZvwj87ivhusI", - "timestamp": 1680610931501 - }, - { - "file_id": "1lHuVrVtAW4fQzc0dFdlZuwY0i71KWw_t", - "timestamp": 1677637469824 - } - ], - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.ipynb deleted file mode 100644 index 44a668c95..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.ipynb +++ /dev/null @@ -1,631 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 6: Spectral Analysis of Paleoclimate Data**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will manipulate paleoclimate proxy datasets using previously learned computational tools, and apply spectral analysis to further interpret the data.\n", - "\n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Interpret the LR04 benthic δ18O curve and how it records temperature\n", - "* Perform various spectral analysis methods to assess dominant spectral powers in the LR04 data\n", - "* Interpret variations in glacial-interglacial cycles recorded by the LR04 δ18O record\n", - "\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import pandas as pd\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "import cartopy\n", - "import pyleoclim as pyleo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Plotting the LR04 δ18O benthic stack**\n", - "\n", - "We will be analyzing a δ18O data from [Lisiecki, L. E., and Raymo, M. E. (2005)](https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2004PA001071), a stack of 57 globally distributed records of δ18O from benthic foraminifera that spans the past ~5 million years. As we learned from the introductory video, δ18O of foraminifera records temperature due to differences in the isotopic composition of the ocean during glacial and interglacial periods. The δ18O of the ocean (and forams) is more depleted (takes on a smaller values) during interglacials and more enriched (takes on a larger value) during glacials." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's start by importing the data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 388, - "status": "ok", - "timestamp": 1681085788186, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# Donwload the data\n", - "filename_LR04 = \"LR04.csv\"\n", - "url_LR04 = (\n", - " \"https://raw.githubusercontent.com/LinkedEarth/PyleoTutorials/main/data/LR04.csv\"\n", - ")\n", - "lr04_data = pd.read_csv(\n", - " pooch_load(filelocation=url_LR04, filename=filename_LR04), skiprows=4\n", - ")\n", - "lr04_data.head()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can now create a `Series` object containing the data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_lr04 = pyleo.Series(\n", - " time=lr04_data[\"Time (ka)\"],\n", - " value=lr04_data[\"Benthic d18O (per mil) \"],\n", - " time_name=\"Age\",\n", - " time_unit=\"kyr BP\",\n", - " value_name=\"Benthic d18O (per mil)\",\n", - " value_unit=\"\\u2030\",\n", - " label=\"LR04\",\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This record spans the past ~5 million years (5,000 kyr), but we're going to focus in on the past 1 million years (1,000 kyr), so let's create a time slice of just this time period, and plot the time series." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1136, - "status": "ok", - "timestamp": 1681085794552, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "lr04_slice = ts_lr04.slice([0, 1000])\n", - "fig, ax = plt.subplots() # assign a new plot axis\n", - "lr04_slice.plot(ax=ax, legend=False, invert_yaxis=True)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Questions 2**\n", - "\n", - "1. What patterns do you observe in the record?\n", - "2. Does the amplitude of the glacial-interglacial cycles vary over time?\n", - "3. At what frequency do these glacial-interglacial cycles occur?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial6_Solution_0a26d704.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "# **Section 2: Spectral analysis of the LRO4 δ18O benthic stack**\n", - "\n", - "To better assess the dominant temporal patterns in this record, you can use spectral analysis. As you learned in the introductory video, spectral analysis is a useful data analysis tool in paleoclimate because it allows us to discover underlying periodicities in time series data and can help establish quantitative relationships between forcings and climate variations.\n", - "\n", - "Let's explore various spectral analysis methods and apply them to the LR04 record to interpret changes in the frequency of glacial-interglacial cycles.\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Section 2.1: Spectral Density\n", - "\n", - "Pyleoclim enables five methods to estimate the [spectral density](https://glossary.ametsoc.org/wiki/Spectral_density), which will be our main interest in this tutorial:\n", - "\n", - "* **Basic Periodogram**, which uses a Fourier transform. The method has various windowing available to reduce variance.\n", - "* **Welch's periodogram**, a variant of the basic periodogram, which uses Welch's method of overlapping segments. The periodogram is computed on each segment and averaged together.\n", - "* **Multi-taper method (MTM)**, which attempts to reduce the variance of spectral estimates by using a small set of tapers rather than the unique data taper or spectral window.\n", - "* **Lomb-Scargle periodogram**, an inverse approach designed for unevenly-spaced datasets. Several windows are available and Welch's segmentation can also be used with this method.\n", - "* **Weighted wavelet Z-transform (WWZ)**, a wavelet-based method also made for unevenly-spaced datasets.\n", - "\n", - "\n", - "All of these methods are available through [`Series.spectral()`](https://pyleoclim-util.readthedocs.io/en/latest/core/api.html#pyleoclim.core.series.Series.spectral) by changing the `method` argument. In this tutorial, we'll focus on Lomb-Scargle and Weighted wavelet Z-transform in more detail. For additional information on the other methods, refer to this notebook from [Pyleoclim](https://github.com/LinkedEarth/PyleoTutorials/blob/main/notebooks/L2_spectral_analysis.ipynb).\n", - "\n", - "To get a sense of how the estimates of the spectral density using each of these methods compare, we can plot them on the same graph below. Note we must first interpolate to an even grid and then standardize before estimating the spectral density." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "\n", - "# basic periodogram\n", - "lr04_slice.interp(step=0.5).standardize().spectral(method=\"periodogram\").plot(\n", - " ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label=\"periodogram\"\n", - ")\n", - "# Welch's periodogram\n", - "lr04_slice.interp(step=0.5).standardize().spectral(method=\"welch\").plot(\n", - " ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label=\"welch\"\n", - ")\n", - "# Multi-taper Method\n", - "lr04_slice.interp(step=0.5).standardize().spectral(method=\"mtm\").plot(\n", - " ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label=\"mtm\"\n", - ")\n", - "# Lomb-Scargle periodogram\n", - "lr04_slice.interp(step=0.5).standardize().spectral(method=\"lomb_scargle\").plot(\n", - " ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label=\"lomb_scargle\"\n", - ")\n", - "# weighted wavelet Z-transform (WWZ)\n", - "lr04_slice.interp(step=0.5).standardize().spectral(method=\"wwz\").plot(\n", - " ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label=\"wwz\"\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Which method should you choose? The Lomb-Scargle periodogram is the default method in Pyleoclim, and is a good choice for many applications because: (1) it works with unevenly-spaced timeseries which are often encountered in paleoclimate data, (2) it seems to give consistent results over parameter ranges, (3) doesn't require interpolation, limiting timeseries manipulation, and (4) it is fairly fast to compute. We will choose this estimate to analyze." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# Lomb-Scargle periodogram\n", - "lr04_ls_sd = lr04_slice.interp(step=0.5).standardize().spectral(method=\"lomb_scargle\")\n", - "\n", - "lr04_ls_sd.plot(xlim=[1000, 5], ylim=[0.001, 1000], label=\"lomb_scargle\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Section 2.2: Significance Testing" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Note that there are few peaks that seem more dominant than others, but which of these peaks are significant? That is, do they stand out more than peaks would from a random time series? To figure that out, we can use the method `signif_test`. Pyleoclim generates many *surrogates* of the time series using an AR(1) (Autoregressive Process of order 1 - i.e. a random process). These surrogates serve to identify the probability of a peak not just being from random noise and the likelihood that the peak of the same magnitude would be unlikely to be present in a random dataset. The default number of surrogates generated is 200, and the larger this value, the more smooth and precise our results are." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 81823, - "status": "ok", - "timestamp": 1680893282423, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "lr04_ls_sd_sig = lr04_ls_sd.signif_test()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "lr04_ls_sd_sig.plot(xlabel=\"Period [kyrs]\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The variable `lr04_ls_sd_sig` [PSD object](https://pyleoclim-util.readthedocs.io/en/latest/core/api.html#pyleoclim.core.psds.PSD) contains the significant frequencies of the significant peaks from the spectral density of the LR04 data. We can now create the same plot of spectral power, but with only the significant peaks. \n", - "\n", - "NOTE: For this figure, we will plot the x-axis a bit differently. In the previous plot, the x-axis was the \"period\" but this time the x-axis will be \"frequency\", which is the inverse of the period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 722, - "status": "ok", - "timestamp": 1680891379240, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "ax.plot(lr04_ls_sd_sig.frequency, lr04_ls_sd_sig.amplitude)\n", - "ax.set_xlim([0.005, 0.07])\n", - "ax.set_ylim([0, 200])\n", - "ax.set_xlabel(\"Frequency [1/kyr]\")\n", - "ax.set_ylabel(\"Spectra Amplitude\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The largest spectral powers in the data occur at a frequencies of ~0.01 and ~0.025, as well as a smaller peak at ~0.042, which correspond to 100 kyr, 40 kyr, and 23 kyr, respectively. Do those periodicities sound familiar? \n", - "\n", - "These are the cycles of **eccentricity, obliquity and precession**. The presence of spectral powers in the LR04 data at the eccentricity, obliquity and precession frequencies highlights the influence of orbital forcings on glacial-interglacial cycles." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "## Section 2.3: Wavelet Analysis\n", - "\n", - "Another related tool we can use to learn more about the climate variability recorded in the data is wavelet analysis. This method allows us to \"unfold\" a spectrum and look at its evolution over time. In other words, wavelet analysis can help us determine changes in the spectral power over time. For additional details about wavelet analysis, refer to [this guide](https://paos.colorado.edu/research/wavelets/bams_79_01_0061.pdf).\n", - "\n", - "There are several ways to access this functionality in Pyleoclim, but here we use `summary_plot`, which stacks together the timeseries itself in the upper panel, its scalogram (a plot of the magnitude of the wavelet power) in the middle, and the power spectral density (PSD, which we plotted earlier in this tutorial) obtained from summing the wavelet coefficients over time to the right.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# create a scalogram\n", - "scal = lr04_slice.interp(step=0.5).standardize().wavelet()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1623, - "status": "ok", - "timestamp": 1680893485411, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# make plot\n", - "lr04_slice.summary_plot(\n", - " psd=lr04_ls_sd_sig, scalogram=scal, time_lim=[0, 1000], psd_label=\"Amplitude\"\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this wavelet spectrum, the age of the record is on the x-axis, the period is on the y-axis, and the color represents the amplitude of that power spectrum, with yellow indicating a higher power and purple indicating a lower power. The time series on top is the original LR04 δ18O data, and the plot on the right is the spectral analysis and significance test figure we created earlier in this tutorial." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.3: Climate Connection**\n", - "\n", - "1. In the spectral analysis above, the 100 kyr and 40 kyr period are the most dominant. Here, we further see that over the past 1 million years, the 100 kyr cycle is the strongest (as seen by the yellow color at the 100 kyr scale), followed by the 40 kyr cycle (as seen by the light purple color at the 40 kyr scale). You may notice an absence of much color at the 23 kyr scale. What does this suggest about the influence of precession on glacial-interglacial cycles on this timescale?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial6_Solution_b7a922f8.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial you learned how to analyze paleoclimate proxy datasets using spectral and wavelet analysis. You were introduced to several spectral analysis methods, identified significant spectral peaks in the spectral density, and looked at the wavelet transform, it's evolution over time. By the end, you were able to determine the influence of various periods, like the 100 kyr and 40 kyr orbital cycles, on glacial-interglacial cycles." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on existing notebooks from LinkedEarth for [spectral analysis](https://github.com/LinkedEarth/PyleoTutorials/blob/main/notebooks/L2_spectral_analysis.ipynb) and [wavelet analysis](https://github.com/LinkedEarth/PyleoTutorials/blob/main/notebooks/L2_wavelet_analysis.ipynb).\n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "* Lisiecki, L. E., and Raymo, M. E. (2005), A Pliocene-Pleistocene stack of 57 globally distributed benthic δ18O records, Paleoceanography, 20, PA1003, https://doi.org/10.1029/2004PA001071." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D4_Tutorial6", - "provenance": [ - { - "file_id": "1lHxPiW5pAZnz1G_A4X6vods12ol89pRP", - "timestamp": 1680556755464 - }, - { - "file_id": "1lHuVrVtAW4fQzc0dFdlZuwY0i71KWw_t", - "timestamp": 1677637469824 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.ipynb deleted file mode 100644 index 6dabc1afc..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.ipynb +++ /dev/null @@ -1,583 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 7: Assessing Climate Forcings**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Mauro Tripaldi, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will use data analysis tools and climate concepts you've learned today, and on previous days, to assess the forcings of climate variations observed in paleoclimate records. \n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Plot and interpret temperature reconstructions from speleothem oxygen isotopes\n", - "* Generate and plot time series of solar insolation\n", - "* Assess the orbital forcings on monsoon intensity over the past 400,000 years using spectral analysis" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 7892, - "status": "ok", - "timestamp": 1681252345527, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# imports\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import pandas as pd\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "\n", - "import cartopy.crs\n", - "import pyleoclim as pyleo\n", - "\n", - "from climlab import constants as const\n", - "from climlab.solar.orbital import OrbitalTable\n", - "from climlab.solar.insolation import daily_insolation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Understanding Climate Forcings**\n", - "\n", - "A common task in paleoclimatology is to relate a proxy record (or several of them) to the particular forcing(s) that is thought to dominate that particular record (e.g., based on the proxy, location, etc.). We've already spent some time in earlier tutorials learning about the influence of Earth's orbital configuration on glacial-interglacial cycles. In this tutorial, we'll assess the the climate forcings of monsoon intensity over the past 400,000 years. \n", - "\n", - "Recall from the video that monsoons are seasonal changes in the direction of strongest wind and precipitation that are primarily driven by variations in seasonal insolation. Land and the ocean have different abilities to hold onto heat. Land cools and warms much faster than the ocean does due to high heat capacity. This temperature difference leads to a pressure difference that drives atmospheric circulations called monsoons. \n", - "\n", - "* **Summer (Northern Hemisphere)**: land is warmer than the ocean, so the winds blow towards the land, resulting in heavy rainfall over land.\n", - "* **Winter (Northern Hemisphere)**: land is cooler than the ocean, so the winds blow away from the land, resulting in heavy rainfall over the ocean and decreased rainfall over land.\n", - " \n", - "\n", - "On longer timescales, changes in insolation and the mean climate state can drive changes in monsoon intensity. To assess these long-term changes, we can analyze paleoclimate reconstructions from monsoon regions such as India, Southeast Asia or Africa. δ18O records from speleothems in Chinese caves are broadly interpreted to reflect continental-scale monsoon circulations. \n", - "\n", - "In this tutorial we'll plot and analyze a composite of three δ18O speleothem records from multiple caves in China (Sanbao, Hulu, and Dongge caves) from [Cheng et al. (2016)](https://hwww.nature.com/articles/nature18591). We will then assess the relationship between the climate signals recorded by the speleothem δ18O and solar insolation." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "First, we can download and plot the speleothem oxygen isotope data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 927, - "status": "ok", - "timestamp": 1681252746094, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# download the data from the url\n", - "filename_Sanbao_composite = \"Sanbao_composite.csv\"\n", - "url_Sanbao_composite = \"https://raw.githubusercontent.com/LinkedEarth/paleoHackathon/main/data/Orbital_records/Sanbao_composite.csv\"\n", - "data = pd.read_csv(\n", - " pooch_load(filelocation=url_Sanbao_composite, filename=filename_Sanbao_composite)\n", - ")\n", - "\n", - "# create a pyleo.Series\n", - "d18O_data = pyleo.Series(\n", - " time=data[\"age\"] / 1000,\n", - " time_name=\"Age\",\n", - " time_unit=\"kyr BP\",\n", - " value=-data[\"d18O\"],\n", - " value_name=r\"$\\delta^{18}$O\",\n", - " value_unit=\"\\u2030\",\n", - ")\n", - "d18O_data.plot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "You may notice that in the figure we just made, the δ18O values on the y-axis is plotted with more positive values up, whereas in previous tutorials, we've plotted isotopic data with more negative values up (since more negative/\"depleted\" suggests warmer temperatures or increased rainfall). However, the pre-processed δ18O data that we're using in this tutorial was multipled by -1, so now a more positive/\"enriched\" value suggests warmer temperatures or increased rainfall. In other words, in this figure, upward on the y-axis is increased monsoon intensity and downward on the y-axis is decreased monsoon intensity." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's apply what we learned in the previous tutorial to perform spectral analysis on the speleothem oxygen isotope data. Recall from the previous tutorial that spectral analysis can help us identify dominant cyclicities in the data, which can be useful for assessing potential climate forcings.\n", - "\n", - "Here we'll use the Weighted Wavelet Z-Transform (WWZ) method you learned about in the previous tutorial:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# standardize the data\n", - "d18O_stnd = d18O_data.interp(step=0.5).standardize() # save it for future use" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate the WWZ spectral analysis\n", - "d18O_wwz = d18O_stnd.spectral(method=\"wwz\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1575, - "status": "ok", - "timestamp": 1681252948290, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# plot WWZ results\n", - "d18O_wwz.plot(xlim=[100, 5], ylim=[0.001, 1000])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## Coding Exercises 1\n", - "\n", - "1. The dominant spectral power is at ~23,000 years. This suggests a link between monsoon intensity and orbital precession! Is this peak significant? Use the skills you learned in the last tutorial to test the significance of this peak at the 95% confidence level. For this exercise, input `number = 5` as the default value which will take a long time to run.\n", - "\n", - "note: if you have time, change the number to `30`. it will take about 5-10 minutes to run " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# perform significance test with 5 surrogates\n", - "d18O_wwz_sig = ...\n", - "\n", - "# plot the results\n", - "_ = ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial7_Solution_9d3f401b.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "# **Section 2: Constructing Insolation Curves**\n", - "\n", - "To further explore and confirm the relationship between monsoon intensity and orbital precession, let's take a look at insolation data and compare this to the speleothem δ18O records from Asia. Recall that insolation is controlled by variations in Earth's orbital cycles (eccentricity, obliquity, precession), so by comparing the δ18O record to insolation, we can assess the influence of orbital variations on δ18O and monsoon intensity. \n", - "\n", - "To compute solar insolation, we can use the package [`climlab`](https://climlab.readthedocs.io/en/latest/index.html) by Brian Rose. Let's create a time series over the past 400,000 years of changes in summer insolation at 31.67ºN, which is the latitude of Sanbao, one of the caves from which the speleothem records were produced.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# specify time interval and units\n", - "kyears = np.linspace(-400, 0, 1001)\n", - "\n", - "# subset of orbital parameters for specified time\n", - "orb = OrbitalTable.interp(kyear=kyears)\n", - "days = np.linspace(0, const.days_per_year, 365)\n", - "\n", - "# generate insolation at Sanbao latitude (31.67)\n", - "Qsb = daily_insolation(31.67, days, orb)\n", - "\n", - "# julian days 152-243 are JJA\n", - "Qsb_jja = np.mean(Qsb[:, 151:243], axis=1)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we can store this data as a `Series` in Pyleoclim and plot the data versus time:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 540, - "status": "ok", - "timestamp": 1681253008796, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "ts_qsb = pyleo.Series(\n", - " time=-kyears,\n", - " time_name=\"Age\",\n", - " time_unit=\"ky BP\",\n", - " value=Qsb_jja,\n", - " value_name=\"JJA Insolation\",\n", - " value_unit=r\"$W.m^{-2}$\",\n", - ")\n", - "\n", - "ts_qsb.plot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Next, let's plot and compare the speleothem δ18O data and the solar insolation data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 819, - "status": "ok", - "timestamp": 1681253013959, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# standardize the insolation data\n", - "ts_qsb_stnd = ts_qsb.standardize()\n", - "\n", - "# create a MultipleSeries of the speleothem d18O record and insolation data\n", - "compare = [d18O_stnd, ts_qsb_stnd]\n", - "ms_compare = pyleo.MultipleSeries(compare, time_unit=\"kyr BP\", name=None)\n", - "\n", - "# create a stackplot to compare the data\n", - "ms_compare.stackplot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "By visually comparing the time series of the two records, we can see similarites at orbital scales. To confirm this, we can use spectral analysis to determine the dominant spectral power of the insolation data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate the WWZ spectral analysis\n", - "psd_wwz = ts_qsb_stnd.spectral(method=\"wwz\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 602, - "status": "ok", - "timestamp": 1681253046710, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "psd_wwz.plot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 2: Climate Connection**\n", - "\n", - "1. What is the dominant spectral power in summer insolation at 31ºN latitude? How does this compare to the speleothem data?\n", - "2. Why might there be a relationship between solar insolation and monsoon intensity? What does the common spectral power in both the insolation and δ18O records suggest about the climate forcings driving monsoon intensity in this region?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial7_Solution_dac5ad95.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you've gained valuable insights into the complex world of paleoclimatology and climate forcings. Here's a recap of what you've learned:\n", - "* You've discovered how to plot and interpret temperature reconstructions derived from speleothem oxygen isotopes. \n", - "* You've assessed the likely impact of orbital forcings on monsoon intensity over the past 400,000 years using spectral analysis. \n", - "* By comparing the δ18O record to insolation, you've developed a deeper understanding of the relationship between solar insolation and monsoon intensity." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on an existing notebook from LinkedEarth that explore [forcing and responses in paleoclimate data](https://github.com/LinkedEarth/paleoHackathon/blob/main/notebooks/PaleoHack-nb04_Forcing%26Response.ipynb).\n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "* Cheng, H., Edwards, R., Sinha, A. et al. The Asian monsoon over the past 640,000 years and ice age terminations. Nature 534, 640–646 (2016). https://doi.org/10.1038/nature18591" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D4_Tutorial7", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.ipynb deleted file mode 100644 index df63e16f7..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.ipynb +++ /dev/null @@ -1,681 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 8: Paleoclimate Models**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Rieke Schäfer, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "So far today, we've been focusing on how proxy-based reconstructions can be used to understand past variations in Earth's climate sytem. However, another useful tool in paleoclimate is the use of climate models. \n", - "\n", - "In this tutorial, you'll explore data from the [Paleoclimate Modelling Intercomparison Project 3 (PMIP3)](https://www.nature.com/articles/nclimate1456). More specifically, you'll be analyzing global mean surface temperature (GMST) data from simulations for the past 1,000 years. \n", - "\n", - "You'll also compare the PMIP3 GMST data to a proxy-based reconstruction of temperature from Lake Tanganyika in East Africa [(Tierney et al., 2010)](https://www.nature.com/articles/ngeo865). Through this proxy-model comparison, you'll be able to assess the differences and similarities between the two datasets. \n", - "\n", - "\n", - "By the end of this tutorial you will be able to:\n", - "\n", - "* Plot time series of paleoclimate model simulations\n", - "* Compare and interpret proxy-based reconstructions of climate to paleoclimate model simulations of climate\n", - "\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import pandas as pd\n", - "import numpy as np\n", - "import xarray as xr\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import cartopy\n", - "import pyleoclim as pyleo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "# **Section 1: Load Proxy-Based Temperature Reconstructions**\n", - "\n", - "The proxy record we'll be analyzing in this tutorial is a 1,000 year-long lake surface temperature reconstruction from [Tierney et al., 2010](https://https://doi.org/10.1038/ngeo865). This record is from Lake Taganyika in equatorial East Africa and is based on the [TEX86 ratio](https://en.wikipedia.org/wiki/TEX86), which is a temperature proxy derived from the distribution of the isoprenoid glycerol dialkyl glycerol tetraether (iGDGT) of archaeal membrane lipids. The organisms producing these iGDGT compounds alter the structure of the compound in response to changes in temperature, so by measuring changes in the ratio of the different compounds, we can infer past changes in temperature. \n", - "\n", - "Let's start by loading the proxy data, saving it as a `Series` in Pyleoclim, and plotting a time series. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "filename_tang = \"tang_sst.csv\"\n", - "url_tang = \"https://osf.io/p8tx3/download\"\n", - "proxy_temp = pd.read_csv(pooch_load(filelocation=url_tang, filename=filename_tang))\n", - "proxy_temp.head()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 696, - "status": "ok", - "timestamp": 1681255526502, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "proxy_t = pyleo.Series(\n", - " time=proxy_temp[\"Year\"],\n", - " value=proxy_temp[\"LST\"],\n", - " time_name=\"Time\",\n", - " time_unit=\"yrs\",\n", - " value_name=\"Surface Temperature\",\n", - " value_unit=\"ºC\",\n", - " label=\"Lake Tanganyika Surface Temperature\",\n", - ")\n", - "\n", - "proxy_t.plot(color=\"C1\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 1**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's make some initial observations about the data:\n", - "\n", - "\n", - "1. What is the overall temperature trend over the past 2,000 years? Where are the major increases or decrease in temperature? \n", - "2. What could be the cause of these shifts in lake surface temperature? \n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial8_Solution_ecac74a9.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Last Millenium PMIP3 GMST Data**\n", - "\n", - "We can now load GMST anomaly data from the PMIP3 simulations for the past 1,000 years ([Braconnot et al., 2012](https://doi.org/10.1038/nclimate1456) and [PAGES 2k-PMIP3 group, 2015](https://cp.copernicus.org/articles/11/1673/2015/)). The anomalies are computed compared to the mean of the time series over the full length of temporal overlap between simulations.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 437, - "status": "ok", - "timestamp": 1681255552933, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# load the raw data 'PMIP3_GMST.txt'\n", - "filename_PMIP3 = \"PMIP3_GMST.txt\"\n", - "url_PMIP3 = \"https://osf.io/gw2m5/download\"\n", - "df = pd.read_table(pooch_load(filelocation=url_PMIP3, filename=filename_PMIP3))\n", - "\n", - "# display the raw data\n", - "df" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Note that the data file includes several ensemble members for [Community Earth System Model (CESM)](https://www.cesm.ucar.edu/) and [Goddard Institute for Space Studies (GISS)](https://www.giss.nasa.gov/) simulations. Ensembles are essentially groups of climate model simulations used for climate projections, or in this case, reconstructions. You will learn about this in much more detail on W1D5: Climate Modeling.\n", - "\n", - "For now, we can replace these with their ensemble mean series.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# create a new pandas.DataFrame to store the processed data\n", - "df_new = df.copy()\n", - "\n", - "# remove the data columns for CESM and GISS ensemble members\n", - "for i in range(10):\n", - " df_new = df_new.drop([f\"CESM_member_{i+1}\"], axis=1)\n", - "\n", - "df_new = df_new.drop([\"GISS-E2-R_r1i1p127.1\"], axis=1)\n", - "df_new = df_new.drop([\"GISS-E2-R_r1i1p127\"], axis=1)\n", - "df_new = df_new.drop([\"GISS-E2-R_r1i1p121\"], axis=1)\n", - "\n", - "# calculate the ensemble mean for CESM and GISS, and add the results into the table\n", - "df_new[\"CESM\"] = df[\n", - " [\n", - " \"CESM_member_1\",\n", - " \"CESM_member_2\",\n", - " \"CESM_member_3\",\n", - " \"CESM_member_4\",\n", - " \"CESM_member_5\",\n", - " \"CESM_member_6\",\n", - " \"CESM_member_7\",\n", - " \"CESM_member_8\",\n", - " \"CESM_member_9\",\n", - " \"CESM_member_10\",\n", - " ]\n", - "].mean(axis=1)\n", - "\n", - "df_new[\"GISS\"] = df[\n", - " [\n", - " \"GISS-E2-R_r1i1p127.1\",\n", - " \"GISS-E2-R_r1i1p127\",\n", - " \"GISS-E2-R_r1i1p121\",\n", - " ]\n", - "].mean(axis=1)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 257, - "status": "ok", - "timestamp": 1681255705870, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# display the processed data\n", - "df_new" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In our new dataframe, you can now see that the ensemble members for CESM and GISS are now replaced with one ensemble mean for each model simulation.\n", - "\n", - "\n", - "\n", - "Now we can create a Pyleoclim `Series` object for each simulated GMST time series, which will allow us to easily plot the time series for each simulation and perform data analysis using various built-in tools." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# store each pyleoclim.Series() object into a dictionary\n", - "ts_dict = {}\n", - "for name in df_new.columns[1:]:\n", - " ts_dict[name] = pyleo.Series(\n", - " time=df_new[\"Year\"].values, # the time axis\n", - " value=df_new[name].values, # the value axis\n", - " label=name, # optional metadata: the nickname of the series\n", - " time_name=\"Time\", # optional metadata: the name of the time axis\n", - " time_unit=\"yrs\", # optional metadata: the unit of the time axis\n", - " value_name=\"GMST anomaly\", # optional metadata: the name of the value axis\n", - " value_unit=\"ºC\", # optional metadata: the unit of the value axis\n", - " )" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can now plot each simulation. For example, let's plot the CCSM4 GMST anomaly:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 616, - "status": "ok", - "timestamp": 1681255723006, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "ts_dict[\"CCSM4\"].plot()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "But what if we wanted to plot all of the PMIP3 time series at once? We can do that using the `MultipleSeries` object in Pyleoclim, which takes a list of `Series` objects as input. To do so, we have to convert the dictionary of `Series` into a list and then create a `MultipleSeries` object." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ts_list = [\n", - " v for k, v in ts_dict.items()\n", - "] # a pythonic way to convert the pyleo.Series items in the dictionary to a list\n", - "ms_pmip = pyleo.MultipleSeries(ts_list)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can now plot all PMIP3 simulation time series at once:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 928, - "status": "ok", - "timestamp": 1681255736092, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "ms_pmip.plot(\n", - " lgd_kwargs={\n", - " \"bbox_to_anchor\": (1.25, 1), # move the legend to the right side\n", - " }\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Note that like the paleo proxy data we have looked at, these model simulations are also referred to as reconstructions as they are attempts to recreate past climates.\n", - "\n", - "The reconstructed GMST anomalies from all of the PMIP3 simulations follow the same overall trend of relatively stable, long-term temperature from 800-1800 AD, followed by an increase in temperature over the past 200 years. What do you think is driving this recent warming trend?\n", - "\n", - "Despite the long-term similarities, there are also noticeable differences between the GMST time series from each simulation. \n", - "\n", - "## **Questions 2: Climate Connection**\n", - "\n", - "1. How are the GMST anomalies from each simulation different? What could be causing these differences?\n", - "4. How do we know which simulation is the most accurate and reliable?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial8_Solution_233de275.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: Proxy-Model Comparisons**\n", - "\n", - "Proxy-based reconstructions of climate variables in the past can provide direct measurements of temperature, precipitation, greenhouse gas concentration, etc. Comparing proxy paleoclimate records with paleoclimate model simulations can help to clarify the interpretation of the proxy record and also help to improve the ability of climate models to simulate past variations in climate.\n", - "\n", - "Here, we'll compare the proxy-based Lake Tanganyika surface temperature reconstruction we downloaded and plotted at the beginning of the tutorial, with the GMST anomaly PMIP3 simulations. But first, we need to standardize the Lake Tanganyika data since we're comparing the data to the GMST anomaly." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# standardize the proxy data\n", - "proxy_stnd = proxy_t.standardize()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1414, - "status": "ok", - "timestamp": 1681255872349, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "fig, ax = ms_pmip.plot(\n", - " lgd_kwargs={\n", - " \"bbox_to_anchor\": (1.25, 1), # move the legend to the right side\n", - " }\n", - ")\n", - "\n", - "ax.set_ylabel(\"GMST anomaly (ºC)\")\n", - "ax1 = ax.twinx() # create a second axes that shares the same x-axis\n", - "ax1.set_ylabel(\"Tanganyika Surface Temperature Anomaly (ºC)\")\n", - "\n", - "proxy_stnd.plot(ax=ax1, color=\"black\")\n", - "ax.set_xlim(xmin=850, xmax=2000)\n", - "ax.set_ylim(ymin=-4, ymax=2)\n", - "ax1.set_ylim(ymin=-4, ymax=2)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 3: Climate Connection**\n", - "\n", - "How do the model simulated GMST and proxy-based surface temperature compare?\n", - "\n", - "\n", - "1. Is there more variability in the proxy or model temperatures? What might be causing this?\n", - "2. Are the long-term trends over the last millenium in the simulated GMST anomaly and proxy-based surface temperature record similar or different?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial8_Solution_743a99c5.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This is just one simplified example of a proxy-model comparison. Larger-scale proxy-model comparisons can help to identify spatial patterns of temperature change and assess forcing mechanisms of paleoclimate variations. In W2D1, you'll spend more time exploring climate models." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you explored the role of climate models in paleoclimate research, particularly focusing on data from PMIP3. You learned to analyze and plot time series of paleoclimate model simulations, specifically GMST anomaly data from the past 1,000 years. This data reveals a trend of relatively stable global mean surface temperature anomalies from 800-1800 AD, followed by a noticeable rise in temperature over the last two centuries.\n", - "\n", - "Furthermore, you have learned to compare this model data with proxy-based reconstructions. Using the example of temperature data from Lake Tanganyika in East Africa, we've assessed the differences and similarities between the model and proxy data. This process not only enhances our interpretation of the proxy record but also improves our understanding of how well climate models simulate past climate variations.\n", - "\n", - "In the next and final tutorial for today, you'll explore another tool for assessing past climate variability using both proxies and models." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Code for this tutorial is based on existing notebooks from LinkedEarth that explore [paleoclimate model-data comparisons](https://github.com/LinkedEarth/paleoHackathon/blob/main/notebooks/PaleoHack-nb08_Model-DataConfrontationInTimeDomain.ipynb) using [PMIP3 model simulations](https://github.com/LinkedEarth/paleoHackathon/blob/main/notebooks/PaleoHack-nb07_Model-DataConfrontationInFrequencyDomain.ipynb).\n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "* Braconnot, P., Harrison, S., Kageyama, M. et al. Evaluation of climate models using palaeoclimatic data. Nature Clim Change 2, 417–424 (2012). https://doi.org/10.1038/nclimate1456\n", - "* Tierney, J., Mayes, M., Meyer, N. et al. Late-twentieth-century warming in Lake Tanganyika unprecedented since AD 500. Nature Geosci 3, 422–425 (2010). https://doi.org/10.1038/ngeo865" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D4_Tutorial8", - "provenance": [ - { - "file_id": "1wFhubLDgjU4HN94QSHyc9zBzHAzgN2Cw", - "timestamp": 1679502090432 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.ipynb b/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.ipynb deleted file mode 100644 index b4dcf980c..000000000 --- a/book/_build/html/_sources/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.ipynb +++ /dev/null @@ -1,486 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 9: Paleoclimate Reanalysis Products**\n", - "**Week 1, Day 4, Paleoclimate**\n", - "\n", - "**Content creators:** Sloane Garelick\n", - "\n", - "**Content reviewers:** Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan \n", - "\n", - "**Content editors:** Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "As we discussed in the video, proxies and models both have advantages and limitations for reconstructing past changes in Earth's climate system. One approach for combining the strengths of both paleoclimate proxies and models is data assimilation. This is the same approach used in Day 2, except instead of simulations of Earth's recent past, we are using a simulation that spans many thousands of years back in time and is constrained by proxies, rather than modern instrumental measurements. The results of this process are called reanalysis products.\n", - "\n", - "In this tutorial, we'll look at paleoclimate reconstructions from the Last Glacial Maximum Reanalysis (LGMR) product from [Osman et al. (2021)](https://www.nature.com/articles/s41586-021-03984-4), which contains temperature for the past 24,000 years.\n", - "\n", - "\n", - "During this tutorial you will:\n", - "\n", - "* Plot a time series of the paleoclimate reconstruction\n", - "* Create global maps and zonal mean plots of temperature anomalies \n", - "* Assess how and why LGM to present temperature anomalies vary with latitude\n", - "\n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# Setup" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import numpy as np\n", - "import xarray as xr\n", - "import matplotlib.pyplot as plt\n", - "\n", - "import cartopy.crs as ccrs\n", - "import cartopy.util as cutil" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Load the LGMR Paleoclimate Reconstruction**\n", - "\n", - "This dataset contains a reconstruction of surface air temperature (SAT) from the product [Last Glacial Maximum Reanalysis (LGMR)](https://www.ncdc.noaa.gov/paleo/study/33112). Note that this data starts from 100 years before present and goes back in time to ~24,000 BP. The period of time from ~21,000 to 18,000 years ago is referred to as the Last Glacial Maximum (LGM). The LGM was the most recent glacial period in Earth's history. During this time, northern hemisphere ice sheets were larger, global sea level was lower, atmospheric CO2 was lower, and global mean temperature was cooler. (Note: if you are interested in looking at data for the present to last millenium, that reanalyses product is available [here](https://www.ncei.noaa.gov/access/paleo-search/study/27850).)\n", - "\n", - "We will calculate the global mean temperature from the LGM to 100 years before present from a paleoclimate data assimilation to asses how Earth's climate varied over the past 24,000 years.\n", - "\n", - "First let's download the paleoclimate data assimilation reconstruction for surface air temperature (SAT). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1997, - "status": "ok", - "timestamp": 1681256682525, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "filename_LGMR_SAT_climo = \"LGMR_SAT_climo.nc\"\n", - "url_LGMR_SAT_climo = \"https://www.ncei.noaa.gov/pub/data/paleo/reconstructions/osman2021/LGMR_SAT_climo.nc\"\n", - "\n", - "ds = xr.open_dataset(\n", - " pooch_load(filelocation=url_LGMR_SAT_climo, filename=filename_LGMR_SAT_climo)\n", - ")\n", - "ds" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Plotting the Temperature Time Series**\n", - "\n", - "Now that the data is loaded, we can plot a time series of the temperature data to assess global changes. However, the dimensions of the `sat_mean` variable are age-lat-lon, so we first need to weight the data and calculate a global mean." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 143, - "status": "ok", - "timestamp": 1681256741486, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# assign weights\n", - "weights = np.cos(np.deg2rad(ds.lat))\n", - "\n", - "# calculate the global mean surface temperature\n", - "sat_global_mean = ds.sat.weighted(weights).mean(dim=[\"lat\", \"lon\"])\n", - "sat_global_mean" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we calculated our global mean, we can plot the results as a time series to assess global changes in temperature over the past 24,000 years:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 559, - "status": "ok", - "timestamp": 1681256745162, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# plot the global mean surface temperature since the LGM\n", - "f, ax1 = plt.subplots(1, 1, figsize=(12, 6))\n", - "ax1.plot(ds[\"age\"], sat_global_mean, linewidth=3)\n", - "\n", - "ax1.set_xlim(ds[\"age\"].max().values, ds[\"age\"].min().values)\n", - "ax1.set_ylabel(\"Global Mean SAT for LGM ($^\\circ$C)\", fontsize=16)\n", - "ax1.set_xlabel(\"Age (yr BP)\", fontsize=16)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.1: Climate Connection**\n", - "1. How has global temperature varied over the past 24,000 years?\n", - "2. What climate forcings may have contributed to the increase in temperature ~17,000 years ago? " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial9_Solution_ace0594e.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Plotting a Temperature Anomaly Map**\n", - "\n", - "The reanalysis contains *spatial* reconstructions, so we can also make figures showing spatial temperature anomalies for different time periods (i.e., the change in temperature between two specified times). The anomaly that we'll interpret is the difference between global temperature from 18,000 to 21,000 years ago (i.e. \"LGM\") and 100 to 1,000 years ago (i.e. \"modern\") . First, we'll calculate the average temperatures for each time period." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate the LGM (18,000-21,000 year) mean temperature\n", - "lgm = ds.sat.sel(age=slice(\"18000\", \"21000\"), lon=slice(0, 357.5), lat=slice(-90, 90))\n", - "lgm_mean = lgm.mean(dim=\"age\")\n", - "\n", - "# calculate the \"modern\" (100-1000 year) mean temperature\n", - "modern = ds.sat.sel(age=slice(\"100\", \"1000\"), lon=slice(0, 357.5), lat=slice(-90, 90))\n", - "modern_mean = modern.mean(dim=\"age\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we can calculate the anomaly and create a map to visualize the change in temperature from the LGM to present in different parts on Earth." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "sat_change = modern_mean - lgm_mean" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# make a map of changes\n", - "fig, ax = plt.subplots(figsize=(12, 8), subplot_kw={\"projection\": ccrs.Robinson()})\n", - "ax.set_global()\n", - "sat_change.plot(\n", - " ax=ax,\n", - " transform=ccrs.PlateCarree(),\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " cmap=\"Reds\",\n", - " vmax=30,\n", - " cbar_kwargs={\"orientation\": \"horizontal\", \"label\": \"$\\Delta$SAT ($^\\circ$C)\"},\n", - ")\n", - "ax.coastlines()\n", - "ax.set_title(f\"Modern - LGM SAT ($^\\circ$C)\", loc=\"center\", fontsize=16)\n", - "ax.gridlines(color=\"k\", linewidth=1, linestyle=(0, (1, 5)))\n", - "ax.spines[\"geo\"].set_edgecolor(\"black\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Before we interpret this data, another useful way to visualize this data is through a plot of zonal mean temperature (the average temperature for all locations at a single latitude). Once we calculate this zonal mean, we can create a plot of LGM to present temperature anomalies versus latitude." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "zonal_mean = sat_change.mean(dim=\"lon\")\n", - "latitude = ds.lat" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# Make a zonal mean figure of the changes\n", - "fig, ax1 = plt.subplots(1, 1)\n", - "ax1.plot(zonal_mean, latitude)\n", - "ax1.axvline(x=0, color=\"gray\", alpha=1, linestyle=\":\", linewidth=2)\n", - "ax1.set_ylim(-90, 90)\n", - "ax1.set_xlabel(\"$\\Delta$T ($^\\circ$C)\")\n", - "ax1.set_ylabel(\"Latitude ($^\\circ$)\")\n", - "ax1.set_title(\n", - " f\"Zonal-mean $\\Delta$T ($^\\circ$C) changes\", # ohad comment: same changes\n", - " loc=\"center\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.1: Climate Connection**\n", - "\n", - "Looking at both the map and zonal mean plot, consider the following questions: \n", - "\n", - "1. How does the temperature anomaly vary with latitude? \n", - "2. What might be causing spatial differences in the temperature anomaly?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D4_Paleoclimate/solutions/W1D4_Tutorial9_Solution_59159894.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this last tutorial of this day, you explored the intersection of paleoclimate proxies and models through reanalysis products, specifically analyzing the Last Glacial Maximum Reanalysis (LGMR) from Osman et al. (2021).\n", - "\n", - "Through this tutorial, you've learned a range of new skills and knowledge:\n", - "- Interpreting Paleoclimate Reconstructions: You have learned how to decode and visualize the time series of a paleoclimate reconstruction of surface air temprature from a reanalysis product in order to enhance your understanding of the temperature variations from the Last Glacial Maximum to the present day.\n", - "- Constructing Global Temperature Anomaly Maps: You've acquired the ability to construct and understand global maps that represent temperature anomalies, providing a more holistic view of the Earth's climate during the Last Glacial Maximum.\n", - "- Examining Latitude's Role in Temperature Variations: You've explored how temperature anomalies from the Last Glacial Maximum to the present day vary by latitude and pondered the reasons behind these variations, enriching your understanding of latitudinal effects on global climate patterns." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "The code for this notebook is based on [code available from Erb et al. (2022)](https://github.com/Holocene-Reconstruction/Holocene-code) and workflow presented during the [Paleoclimate Data Assimilation Workshop 2022](https://github.com/michaelerb/da-workshop).\n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "* Matthew B. Osman, Jessica E. Tierney, Jiang Zhu, Robert Tardif, Gregory J. Hakim, Jonathan King, Christopher J. Poulsen. 2021. Globally resolved surface temperatures since the Last Glacial Maximum. Nature, 599, 239-244. http://doi.org/10.1038/s41586-021-03984-4.\n", - "* King, J. M., Tierney, J., Osman, M., Judd, E. J., & Anchukaitis, K. J. (2023). DASH: A MATLAB Toolbox for Paleoclimate Data Assimilation. Geoscientific Model Development, preprint. https://doi.org/10.5194/egusphere-2023-68." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D4_Tutorial9", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/chapter_title.md b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/chapter_title.md deleted file mode 100644 index f0a4b7e0c..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Climate Modeling - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/further_reading.md b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/further_reading.md deleted file mode 100644 index 5da41aeac..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/further_reading.md +++ /dev/null @@ -1,3 +0,0 @@ -# Suggested Further Reading - -Today’s lectures and tutorials were inspired by The Climate Laboratory, Brian Rose, 2022. If you want further information or context on any of today’s topics, this The Climate Laboratory likely contains that information or links to other appropriate readings. diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.ipynb deleted file mode 100644 index 41ee32449..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.ipynb +++ /dev/null @@ -1,870 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.ipynb)   \"Open\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 1 : A Simple Greenhouse Model**\n", - "\n", - "**Week 1, Day 5, Climate Modeling**\n", - "\n", - "**Content creators:** Jenna Pearson\n", - "\n", - "**Content reviewers:** Dionessa Biton, Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial students will learn about blackbody radiation and greenhouse models for energy emitted from Earth.\n", - "\n", - "By the end of this tutorial students will be able to:\n", - "\n", - "- Understand what an emission temperature is, and how to find it given observed outgoing longwave radiation.\n", - "- Modify the blackbody radiation model to include the greenhouse effect.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# imports\n", - "import holoviews as hv\n", - "import panel as pn\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Speaker Introduction\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Speaker Introduction\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 2: A Simple Greenhouse Model\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 2: A Simple Greenhouse Model\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 2: A Simple Greenhouse Model\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1 : A Radiating Earth**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1 Planck's Law**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "All objects with a temperature emit **[electromagnetic radiation](https://www.noaa.gov/jetstream/satellites/electromagnetic-waves)**. This energy travels through space in the form of waves. In the lecture we discussed that blackbody radiation is a model of how Earth loses radiative energy to space. Although this is not a perfect model for Earth, we will use it as a basis to understand Earth's energy balance throughout tutorials 1-4. If we suppose Earth behaves as a perfect blackbody, then it emits energy at all wavelengths according to **[Planck's Law](https://glossary.ametsoc.org/wiki/Planck%27s_radiation_law)**:\n", - "\n", - "\\begin{align}\n", - "B(\\lambda,T) = \\frac{2 h c^2}{\\lambda^5}\\frac{1}{e^{hc/(\\kappa T)}-1}\n", - "\\end{align}\n", - "\n", - "where $h = 6.626075 \\times 10^{-34} J s$ is Planck's constant, $c= 2.99792 \\times 108 m s^{-1}$ is the speed of light, and $\\kappa = 1.3804 \\times 10^{23} W K^{-1}$ is Boltzmann's constant.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Interactive Demo 1.1**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "This interactive demo will allow you to visualize how to blackbody curve changes as Earth warms and cools relative to it's current surface temperature of about 288K. Use the slide bar to adjust the emission temperature. Give the code few seconds to replot before choosing a new temperature.\n", - "\n", - "No need to worry about understanding the code here - this is conceptual.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Make sure you execute this cell to enable the widget!\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " Make sure you execute this cell to enable the widget!\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @markdown Make sure you execute this cell to enable the widget!\n", - "\n", - "hv.extension(\"bokeh\")\n", - "\n", - "# define constants used in Planck's Law\n", - "h = 6.626075e-34 # J s\n", - "c = 2.99792e8 # m s^-1\n", - "k = 1.3804e-23 # W K^-1\n", - "\n", - "\n", - "# define the function for Planck's Law depedent on wavelength (lambda) and temeprature (T)\n", - "def planck(wavelength, temperature):\n", - " a = 2.0 * h * c**2\n", - " b = h * c / (wavelength * k * temperature)\n", - " intensity = a / ((wavelength**5) * (np.exp(b) - 1.0))\n", - "\n", - " lpeak = (2.898 * 1e-3) / temperature\n", - "\n", - " return intensity\n", - "\n", - "\n", - "def update_plot(emiss_temp):\n", - " # generate x-axis in increments from 1um to 100 micrometer in 1 nm increments\n", - " # starting at 1 nm to avoid wav = 0, which would result in division by zero.\n", - " wavelengths = np.arange(1e-6, 50e-6, 1e-9)\n", - "\n", - " # get the blackbody curve and peak emission wavelength for 288 K\n", - " intensity288 = planck(wavelengths, 288)\n", - "\n", - " # get the blackbody curve and peak emission wavelength for selected temperature\n", - " intensity = planck(wavelengths, emiss_temp)\n", - "\n", - " # # get the intensity at peak wavelength to limit the lines\n", - " # Ipeak,_ = planck(lpeak,emission_temperature)\n", - " # Ipeak288,_ = planck(lpeak288,288)\n", - "\n", - " # curves output\n", - " vary = zip(wavelengths * 1e6, intensity)\n", - " init_val = zip(wavelengths * 1e6, intensity288)\n", - "\n", - " # Specified individually\n", - " list_of_curves = [\n", - " hv.Curve(init_val, label=\"T=\" + str(emiss_temp) + \"K\").opts(ylim=(0, 1.0e7)),\n", - " hv.Curve(vary, label=\"T=288K\").opts(ylim=(0, 1.0e7)),\n", - " ]\n", - "\n", - " bb_plot = hv.Overlay(list_of_curves).opts(\n", - " height=300,\n", - " width=600,\n", - " xlabel=\"Wavelength (μm)\",\n", - " ylabel=\"B(λ,T) (W/(m³ steradian)\",\n", - " title=\"Spectral Radiance\",\n", - " )\n", - "\n", - " return bb_plot\n", - "\n", - "\n", - "emiss_temp_widget = pn.widgets.IntSlider(\n", - " name=\"Emission Temperature\", value=288, start=250, end=300\n", - ")\n", - "bound_plot = pn.bind(update_plot, emiss_temp=emiss_temp_widget)\n", - "\n", - "pn.Row(emiss_temp_widget, bound_plot)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.1: Climate Connection**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Recall from Tutorial 1 on Week 1 Day 3 the **electromagnetic spectrum** (shown below), which displays the different wavelengths of electromagnetic energy. According to our model and noting that 1 micrometer = $10^{-6}$ meters, with a surface temperature of 288K what type of radiation does Earth primarily emit at?\n", - "\n", - "![Diagram of the Electromagnetic Spectrum](https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/EM_spectrumrevised.png/1920px-EM_spectrumrevised.png)\n", - "Diagram of the Electromagnetic Spectrum. (Credit: [Wikipedia](https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/EM_spectrumrevised.png/1920px-EM_spectrumrevised.png))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial1_Solution_d8ea9414.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: The Stefan-Boltzmann Law**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "If we integrate Planck's Law over all wavelengths and outward angles of emission, the total **outgoing longwave radiation (OLR)** for a given **emission temperature** ($\\mathbf{T}$) follows the **[Stefan-Boltzmann Law](https://glossary.ametsoc.org/wiki/Stefan-boltzmann_law)**.\n", - "\n", - "\\begin{align}\n", - "OLR = \\sigma T^4\n", - "\\end{align}\n", - "\n", - "Where the [Stefan-Boltzmann constant](https://glossary.ametsoc.org/wiki/Stefan-boltzmann_constant) $\\sigma = 5.67 \\times 10^{-8} W m^{-2} K^{-4}$.\n", - "\n", - "Rearranging the equation above, we can solve for the emission temperature of Earth, $T$.\n", - "\n", - "\\begin{align}\n", - "T = \\sqrt[4]{\\frac{OLR}{\\sigma}}\n", - "\\end{align}\n", - "\n", - "Using $OLR = 239 W m^{-2}$, we can calcuate this using python.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 33, - "status": "ok", - "timestamp": 1681268100158, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - "sigma = 5.67e-8 # W m^-2 K^-4\n", - "\n", - "# define the outgoing longwave radiation based on observations from the IPCC AR6 Figure 7.2\n", - "OLR = 239 # W m^-2\n", - "\n", - "# plug into equation\n", - "T = (OLR / sigma) ** (1 / 4)\n", - "\n", - "# display answer\n", - "print(\"Emission Temperature: \", T, \"K or\", T - 273, \"C\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2: Climate Connection**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. How does this compare to the actual global mean surface temperature of ~288 $K$ / 15 $C$?\n", - "2. Using $T = 288 K$ would you expect the corresponding outgoing longwave radiation to be higher or lower than the observed 239 $W m^{-2}$?\n", - "3. What could be accounted for in this model to make it more realistic?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial1_Solution_c67198fd.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 1.2**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. By modifying the code above and solving for OLR, find the outgoing longwave radiation expected for the observed surface temperature of $288 K$. This should help you answer Question 2 above.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 31, - "status": "ok", - "timestamp": 1681268100161, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - "sigma = ...\n", - "\n", - "# define the global mean surface temperature based on observations\n", - "T = ...\n", - "\n", - "# plug into equation\n", - "OLR = ...\n", - "\n", - "# display answer\n", - "print(\"OLR: \", OLR, \"W m^2\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 27, - "status": "ok", - "timestamp": 1681268100162, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial1_Solution_a2d0f592.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2 : The Greenhouse Effect**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The expected surface temperature using the blackbody radiation model is much colder than we observe it to be. In this model we assumed there is nothing that lies between Earth's surface and space that interacts with Earth's emitted radiation. From the initial lecture on the global energy budget we know this is not true. Earth has an atmosphere, and within it are many gases that interact with radiation in the infrared range at which Earth primarily emits. The effect of these gases on radiation, called the **[greenhouse effect](https://glossary.ametsoc.org/wiki/Greenhouse_effect#:~:text=As%20used%20in%20the%20field,absorb%20and%20emit%20infrared%20radiation.)**, is what warms earth to a habitable temperature.\n", - "\n", - "The gases that are responsible for this ([carbon dioxide](https://glossary.ametsoc.org/wiki/Carbon_dioxide), [water vapor](https://glossary.ametsoc.org/wiki/Water_vapor), [methane](https://glossary.ametsoc.org/wiki/Methane), [ozone](https://glossary.ametsoc.org/wiki/Ozone), [nitrous oxide](https://glossary.ametsoc.org/wiki/Nitrous_oxide), and [chloroflourocarbons](https://glossary.ametsoc.org/wiki/Chlorofluorocarbons)) are termed **[greenhouse gases](https://glossary.ametsoc.org/wiki/Greenhouse_gases)**. The figure below shows the contributions to the global surface air temperature change relative to 1750. We can see that all of these gases have contributed positively, that is towards warming Earth. Also note that the total curve tracks the volcano curve quite well until around the 1850s when industrialization took hold. The total and volcanic curves begin to deviate here, and after the mid 1900s the total curve begins tracking the total anthropogenic curve instead.\n", - "\n", - "![Attributed global surface air temperature change (GSAT)](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_Figure_7_8.png) \n", - "Figure 7.8 | Attributed global surface air temperature change (GSAT) from 1750 to 2019 produced using the two-layer emulator (Supplementary Material 7.SM.2), forced with ERF derived in this chapter (displayed in Figure 2.10) and climate response constrained to assessed ranges for key climate metrics described in Cross-Chapter Box 7.1. The results shown are the medians from a 2237-member ensemble that encompasses uncertainty in forcing and climate response (year-2019 best estimates and uncertainties are shown in Figure 7.7 for several components). Temperature contributions are expressed for carbon dioxide (CO2), methane (CH4), nitrous oxide (N2O), other well-mixed greenhouse gases (WMGHGs), ozone (O3), aerosols, and other anthropogenic forcings, as well as total anthropogenic, solar, volcanic, and total forcing. Shaded uncertainty bands showvery likely (5–95%)ranges. Further details on data sources and processing are available in the chapter data table (Table 7.SM.14). (Credit [IPCC](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_Figure_7_8.png))\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As shown above, greenhouse gases are incredibly important for regulating Earth's energy balance and temperature. A first approach is to model the greenhouse effect on outgoing longwave radiation (OLR) to space by adding a transmissivity coefficient. The **transmissivity coeficient (**$\\mathbf{\\tau}$**)** is the fraction of\n", - "the radiation emitted from Earth that actually makes it to space. This coefficient $\\mathbf{\\tau}$ is a number that lies between 0 and 1, and represents the _effects_ of all the greenhouse gases on radiation, rather than including them explicity in the model. This approach is called a **[parametrization](https://glossary.ametsoc.org/wiki/Parameterization)**.\n", - "\n", - "Applying this to the original model for blackbody radiation, the modified model is\n", - "\n", - "\\begin{align}\n", - "OLR = \\tau \\sigma T^4\n", - "\\end{align}\n", - "\n", - "Using $OLR = 239 W m^{-2}$ and $T = 288 K$, we can estimate $\\tau$.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 22, - "status": "ok", - "timestamp": 1681268100163, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - "sigma = 5.67e-8 # W m^-2 K^-4\n", - "\n", - "# define the outgoing longwave radiation based on observations from the IPCC AR6 Figure 7.2\n", - "OLR = 239 # W m^-2\n", - "\n", - "# define the emission temperature based on observtions of global mean surface temperature\n", - "T = 288 # K\n", - "\n", - "# plug into equation\n", - "tau = OLR / (sigma * T**4) # unitless number between 0 and 1\n", - "\n", - "# display answer\n", - "print(\"Transmissivity Coefficient: \", tau)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.1: Climate Connection**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. For a generic planet, what could be said about the planet's atmosphere when $\\tau$ is close to 1? Close to 0? Use the OLR seen at the top of the atmosphere in your answer.\n", - "2. In terms of energy received from the sun, what does only modifying the _OLR_ to account for the greenhouse effect imply? Are there any greenhouse gases you think would make this implication problematic?\n", - "3. Is there any other part of the atmosphere aside from greenhouse gases that we have not discussed that would also affect $\\tau$?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial1_Solution_517af88a.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 2.1**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Using list comprehension, calculate the OLR for three values of $\\tau = 0.2,0.6114,0.8$. Then plot this on a bar chat to compare. This should help you answer question 1 above. Hint: what is [list comprehension](https://foundations.projectpythia.org/foundations/quickstart.html#lists)?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 401, - "status": "ok", - "timestamp": 1681268104208, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - "sigma = ...\n", - "\n", - "# define the emission temperature based on observtions of global mean surface temperature\n", - "T = ...\n", - "\n", - "# define values of tau\n", - "tau = ...\n", - "\n", - "# get values of OLR from tau using list comprehension\n", - "OLR = ...\n", - "\n", - "# convert tau to list of strings using list comprehension so we can create a categorical plot\n", - "tau = ...\n", - "\n", - "fig, ax = plt.subplots()\n", - "_ = ...\n", - "ax.set_xlabel(\"Transmissivity\")\n", - "ax.set_ylabel(\"Outgoing Longwave Radiation ($W m^{-2}$)\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 5, - "status": "ok", - "timestamp": 1681268133545, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial1_Solution_381e1993.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Bonus: Blackbody Radiation Coding Exercise**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "By defining a function for Planck's Law, plot the blackbody radiation curve for the sun, assuming an emission temperature of 5800K. Underlay an approximation of the visible range from the electromagnetic spectrum. This exercise should help you understand why we see in color as well as why the sun's radiation headed towards Earth is called incoming shortwave radiation.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# define the emission temperature of the sun\n", - "T_sun = ...\n", - "\n", - "\n", - "# define constants used in Planck's Law\n", - "h = 6.626075e-34 # J s\n", - "c = 2.99792e8 # m s^-1\n", - "k = 1.3804e-23 # W K^-1\n", - "\n", - "\n", - "# define the function for Planck's Law that returns the intensity as well\n", - "# as the peak wavelength defined by Wien's Law\n", - "def planck(wavelength, temperature):\n", - " ...\n", - " intensity = ...\n", - " lpeak = ...\n", - " return intensity, lpeak\n", - "\n", - "\n", - "# generate x-axis in increments from 1um to 100 micrometer in 1 nm increments\n", - "# starting at 1 nm to avoid wav = 0, which would result in division by zero.\n", - "wavelengths = np.arange(1e-7, 4e-6, 1e-9)\n", - "\n", - "# intensity and peak radiating wavelength at different temperatures\n", - "intensity, lpeak = planck(wavelengths, T_sun)\n", - "\n", - "# get the intensity at peak wavelength to limit the lines\n", - "Ipeak, _ = planck(lpeak, T_sun)\n", - "\n", - "# plot an approximation of the visible range by defining a dictionary with\n", - "# wavelength ranges and colors\n", - "rainbow_dict = {\n", - " (0.4, 0.44): \"#8b00ff\",\n", - " (0.44, 0.46): \"#4b0082\",\n", - " (0.46, 0.5): \"#0000ff\",\n", - " (0.5, 0.57): \"#00ff00\",\n", - " (0.57, 0.59): \"#ffff00\",\n", - " (0.59, 0.62): \"#ff7f00\",\n", - " (0.62, 0.75): \"#ff0000\",\n", - "}\n", - "for wv_range, rgb in rainbow_dict.items():\n", - " plt.axvspan(*wv_range, color=rgb, ec=\"none\")\n", - "\n", - "fig, ax = plt.subplots()\n", - "# add in wiens law\n", - "_ = ...\n", - "\n", - "# plot intensity curve\n", - "_ = ...\n", - "\n", - "ax.set_xlabel(\"Wavelength ($\\mu m$)\", fontsize=20, labelpad=30)\n", - "ax.set_ylabel(\"$B_\\lambda(\\lambda,T)$ $(W/(m^3 steradian)$\", fontsize=20)\n", - "\n", - "ax.set_title(\"Spectral Radiance\")\n", - "\n", - "# add legend\n", - "ax.legend(bbox_to_anchor=(0.5, 0.5))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial1_Solution_a0030ab7.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, we've learned about the principles of blackbody and greenhouse radiation models, which are crucial to understanding Earth's energy emission. We explored the concept of emission temperature and how it's calculated using observed outgoing longwave radiation. We discovered that the simple blackbody model needs to be augmented by considering the greenhouse effect to accurately represent Earth's observed surface temperature. This led us to incorporate the transmissivity coefficient, a representation of greenhouse gases' impact, into our model.\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D5_Tutorial1", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.ipynb deleted file mode 100644 index 2818c3aa7..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.ipynb +++ /dev/null @@ -1,629 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.ipynb)   \"Open\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 2 : Energy Balance**\n", - "\n", - "**Week 1, Day 5, Climate Modeling**\n", - "\n", - "**Content creators:** Jenna Pearson\n", - "\n", - "**Content reviewers:** Dionessa Biton, Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial students will learn about the components that define energy balance, including insolation and albedo.\n", - "\n", - "By the end of this tutorial students will be able to:\n", - "\n", - "- Calculate the albedo of Earth based on observations.\n", - "- Define and find the equilibrium temperature under the assumption of energy balance.\n", - "- Understand the relationship between transmissivity and equilibrium temperature.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import xarray as xr # used to manipulate data and open datasets\n", - "import numpy as np # used for algebra and array operations\n", - "import matplotlib.pyplot as plt # used for plotting" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Energy Balance\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Energy Balance\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Energy Balance\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1 : A Radiating Sun**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Incoming Solar Radiation (Insolation) and Albedo ($\\alpha$)**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Just as Earth emits radiation, so does the sun. The incoming solar radiation, called **[insolation](https://glossary.ametsoc.org/wiki/Insolation)**. From the 'All Sky' Energy budget shown below, this is observed to be $Q = 340 W m^{-2}$.\n", - "\n", - "Some of this radiation is reflected back to space (for example off of ice and snow or clouds).\n", - "\n", - "From the 'All Sky' energy budget below, the amount reflected back is $F_{ref} = 100 W m^{-2}$.\n", - "\n", - "![Global Mean Energy Budget](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_Figure_7_2.png)\n", - "Figure 7.2 | Schematic representation of the global mean energy budget of the Earth (upper panel), and its equivalent without considerations of cloud effects (lower panel). Numbers indicate best estimates for the magnitudes of the globally averaged energy balance components in W m–2 together with their uncertainty ranges in parentheses (5–95% confidence range), representing climate conditions at the beginning of the 21st century. Note that the cloud-free energy budget shown in the lower panel is not the one that Earth would achieve in equilibrium when no clouds could form. It rather represents the global mean fluxes as determined solely by removing the clouds but otherwise retaining the entire atmospheric structure. This enables the quantification of the effects of clouds on the Earth energy budget and corresponds to the way clear-sky fluxes are calculated in climate models. Thus, the cloud-free energy budget is not closed and therefore the sensible and latent heat fluxes are not quantified in the lower panel. Figure adapted from Wild et al. (2015, 2019). (Credit: [IPCC AR6 Report](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_Figure_7_2.png))\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The _fraction_ of reflected radiation is captured by the **albedo (**$\\mathbf{\\alpha}$**)**\n", - "\n", - "\\begin{align}\n", - "\\alpha = \\frac{F\\_{ref}}{Q}\n", - "\\end{align}\n", - "\n", - "Albedo is a unitless number between 0 and 1. We can use this formula to find the albedo of Earth.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 17, - "status": "ok", - "timestamp": 1681355999731, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define the observed insolation based on observations from the IPCC AR6 Figure 7.2\n", - "Q = 340 # W m^-2\n", - "\n", - "# define the observed reflected radiation based on observations from the IPCC AR6 Figure 7.2\n", - "F_ref = 100 # W m^-2\n", - "\n", - "# plug into equation\n", - "alpha = F_ref / Q # unitless number between 0 and 1\n", - "\n", - "# display answer\n", - "print(\"Albedo: \", alpha)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.1: Climate Connection**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Keeping insolation ($Q$) constant, what does a low albedo imply? What about a high albedo?\n", - "2. There are two components to albedo, the reflected radiation in the numerator and the insolation in the denomenator. Do you think one or both of these have changed over Earth's history?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial2_Solution_daefe4d6.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2 : Absorbed Shortwave Radiation (ASR)**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The **absorbed shortwave radiation (ASR)** is the amount of this isolation that is _not_ reflected, and actually makes it to Earth's surface. Thus,\n", - "\n", - "\\begin{align}\n", - "ASR = Q-F\\_{ref} = (1-\\alpha)Q\n", - "\\end{align}\n", - "\n", - "From observations, we can esimate the absorbed shortwave radiation.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# plug into equation\n", - "ASR = (1 - alpha) * Q\n", - "\n", - "# display answer\n", - "print(\"Absorbed Shortwave Radiation: \", ASR, \" W m^-2\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2: Climate Connection**\n", - "\n", - "1. Compare the value of ASR to the observed OLR of $239 W m^{-2}$. Is it more or less? What do you think this means?\n", - "2. Does this model take into account any effects of gases in that atmosphere on the incoming shortwave radiation that makes it to Earth's surface? Are there any greenhouse gases you think are important and should be included in more complex models?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial2_Solution_826838b2.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2 : Energy Balance**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: Equilibrium Temperature**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Energy Balance is achieved when radiation absorbed by Earth's surface (ASR) is equal to longwave radiation going out to space (OLR). That is\n", - "\n", - "\\begin{align}\n", - "ASR = OLR\n", - "\\end{align}\n", - "\n", - "By substituting into the equations from previous sections, we can find the surface temperature of Earth needed to maintain this balance. This is called the **equilibrium temperature (** $\\mathbf{T_{eq}}$ **)**.\n", - "\n", - "Recall $OLR = \\tau\\sigma T^4$ and $ASR = (1-\\alpha)Q$. The **equilibrium temperature** is the temperature the system would have if energy balance was perfectly reached. Assuming energy balance, we will call the emission temperature denoted previously the equilibrium temperature ($T_{eq}$) instead. Thus,\n", - "\n", - "\\begin{align}\n", - "(1-\\alpha)Q = ASR = OLR = \\tau\\sigma T\\_{eq}^4\n", - "\\end{align}\n", - "\n", - "Solving for $T_{eq}$ we find\n", - "\n", - "\\begin{align}\n", - "T\\_{eq} = \\sqrt[4]{\\frac{(1-\\alpha)Q}{\\tau\\sigma}}\n", - "\\end{align}\n", - "\n", - "Let's calculate what this should be for Earth using observations:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 236, - "status": "ok", - "timestamp": 1681356054176, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - "sigma = 5.67e-8 # W m^-2 K^-4\n", - "\n", - "# define transmissivity (calculated previously from observations in tutorial 1)\n", - "tau = 0.6127 # unitless number between 0 and 1\n", - "\n", - "# plug into equation\n", - "T_eq = (((1 - alpha) * Q) / (tau * sigma)) ** (1 / 4)\n", - "\n", - "# display answer\n", - "print(\"Equilibrium Temperature: \", T_eq, \"K or\", T_eq - 273, \"C\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3 : Climate Change Scenario**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.1: Increasing Greenhouse Gas Concentrations**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Assume due to the increasing presence of greenhouse gases in the the atmosphere, that $\\tau$ decreases to $0.57$.\n", - "\n", - "We can then use our climate model and python to find the new equilibrium temperature.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4, - "status": "ok", - "timestamp": 1681356085750, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define transmissivity (assupmtion in this case)\n", - "tau_2 = 0.57 # unitless number between 0 and 1\n", - "\n", - "# plug into equation\n", - "T_eq_2 = (((1 - alpha) * Q) / (tau_2 * sigma)) ** (1 / 4)\n", - "\n", - "# display answer\n", - "print(\"New Equilibrium Temperature: \", T_eq_2, \"K or\", T_eq_2 - 273, \"C\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 3.1: Climate Connection**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Does a reduction in the transmissivity, $\\tau$, imply a decrease or increase in OLR?\n", - "2. How does the new equilibrium temperature compare to that calculated previously? Why do you think this is?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial2_Solution_79b144ab.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 3.1**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Plot the equilibrium temperature as a function of $\\tau$, for $\\tau$ ranging from zero to one.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# define the observed insolation based on observations from the IPCC AR6 Figure 7.2\n", - "Q = ...\n", - "\n", - "# define the observed reflected radiation based on observations from the IPCC AR6 Figure 7.2\n", - "F_ref = ...\n", - "\n", - "# define albedo\n", - "alpha = ...\n", - "\n", - "# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - "sigma = ...\n", - "\n", - "\n", - "# define a function that returns the equilibrium temperature and takes argument tau\n", - "def get_eqT(tau):\n", - " return ...\n", - "\n", - "\n", - "# define tau as an array extending from 0 to 1 with spacing interval 0.01\n", - "tau = ...\n", - "\n", - "# use list comprehension to obtain the equilibrium temperature as a function of tau\n", - "eqT = ...\n", - "\n", - "fig, ax = plt.subplots()\n", - "# Plot tau vs. eqT\n", - "_ = ...\n", - "ax.set_xlabel(...)\n", - "ax.set_ylabel(...)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 5, - "status": "ok", - "timestamp": 1681356100692, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial2_Solution_3fa7479c.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, you explored the fundamentals of Earth's energy balance. You learned how to calculate Earth's albedo $\\mathbf{\\alpha}$ and how absorbed shortwave radiation contributes to energy balance. You also discovered the concept of equilibrium temperature and it's relationship to energy balance. The tutorial also highlighted the impact of increasing greenhouse gases on the equilibrium temperature.\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D5_Tutorial2", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.ipynb deleted file mode 100644 index 17e949de9..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.ipynb +++ /dev/null @@ -1,1131 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 3 : A Zero-Dimensional Energy Balance Model**\n", - "\n", - "\n", - "**Week 1, Day 5, Climate Modeling**\n", - "\n", - "**Content creators:** Jenna Pearson\n", - "\n", - "**Content reviewers:** Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Agustina Pesce, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial students will learn about the heat capacity of the atmosphere and oceans, how this related to temperature changes over time, and set up their first climate model.\n", - "\n", - "By the end of this tutorial students will be able to:\n", - "* Calculate the heat capacity of the ocean and atmosphere.\n", - "* Create and run a time-dependent model of the change in global mean surface temperature in response to energy imbalances.\n", - "* Describe the influence of transmissivity and albedo on the equilibrium temperature from this model.\n", - "* Bonus: What equilibrium climate sensitivity is and how to find it using the model." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "import xarray as xr # used to manipulate data and open datasets\n", - "import numpy as np # used for algeba and array operations\n", - "import matplotlib.pyplot as plt # used for plotting" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: A Zero-Dimensional Energy Balance Model\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: A Zero-Dimensional Energy Balance Model\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: A Zero-Dimensional Energy Balance Model\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1 : Building the Model**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1 : Moving Forward in Time**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "One of the crucial things missing from the simple model we have looked at so far is it's ability to change with time. As the composition of the atmosphere (among other things) changes with time, in response, so does the energy balance and global mean surface temperature. This is shown by the thick black lines in the figure below, where the time series of observed global mean surface air temperature change from the 1850-1900 reference period is plotted. Figures like this are called 'hockey stick' figures due to their shape: a relatively stable period followed by a steep increase. In order to incorporate this into our model, we need to include a mathetmatical representation of how the change in energy relates to a change in temperature over time.\n", - "\n", - "![Observerd and simulated change in temparture](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_Figure_3_4.png)\n", - "Figure 3.4 | Observed and simulated time series of the anomalies in annual and global mean surface air temperature (GSAT). All anomalies are differences from the 1850–1900 time-mean of each individual time series. The reference period 1850–1900 is indicated by grey shading. (a) Single simulations from CMIP6 models (thin lines) and the multi-model mean (thick red line). Observational data (thick black lines) are from the Met Office Hadley Centre/Climatic Research Unit dataset (HadCRUT5), and are blended surface temperature (2 m air temperature over land and sea surface temperature over the ocean). All models have been subsampled using the HadCRUT5 observational data mask. Vertical lines indicate large historical volcanic eruptions. CMIP6 models which are marked with an asterisk are either tuned to reproduce observed warming directly, or indirectly by tuning equilibrium climate sensitivity. Inset: GSAT for each model over the reference period, not masked to any observations. (b) Multi-model means of CMIP5 (blue line) and CMIP6 (red line) ensembles and associated 5th to 95th percentile ranges (shaded regions). Observational data are HadCRUT5, Berkeley Earth, National Oceanic and Atmospheric Administration NOAAGlobalTemp-Interim and Kadow et al. (2020). Masking was done as in (a). CMIP6 historical simulations were extended with SSP2-4.5 simulations for the period 2015–2020 and CMIP5 simulations were extended with RCP4.5 simulations for the period 2006–2020. All available ensemble members were used (see Section 3.2). The multi-model means and percentiles were calculated solely from simulations available for the whole time span (1850–2020). Figure is updated from Bock et al. (2020), their Figures 1 and 2. CC BY 4.0https://creativecommons.org/licenses/by/4.0/. Further details on data sources and processing are available in the chapter data table (Table 3.SM.1). (Credit [IPCC Report AR6](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_Figure_3_4.png))\n", - "\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can represent the change in temperature over time as the net heat input or loss from radiation ($ASR-OLR$) multiplied by the heat capacity of the Earth system.\n", - "\n", - "As we learned in Day 2 of this week, the heat capacity of a medium is its ability to increase in temperature given an input of heat. Not all components of the Earth system (for example land, ocean, atmosphere) have the same heat capacity.\n", - "\n", - "Mathematically, the rate of change of global mean surface temperature ($T$) over time is given as\n", - "\n", - "\\begin{align}\n", - "\\text{rate of change of }T = \\frac{1}{\\text{heat capacity}}\\cdot (\\text{energy flux in - energy flux out}) = \\frac{1}{C} \\cdot ASR - OLR\n", - "\\end{align}\n", - "\n", - "where $C$ is the heat capacity of the Earth system. Note here that when $ASR > OLR$, then the system is gaining heat. Conversely when $ASR < OLR$, then the system is losing heat over time.\n", - "\n", - "To calculate the heat capacity for the Earth system, we will assume the it is a combination of atmosphere and ocean only, that is $C = C_{oc} + C_{atmo}$. \n", - "\n", - "Generally, the heat capacity of a medium is the specific heat of that medium times the total mass.\n", - "\n", - "For the atmosphere we have $C_{atm} = c_{atm} \\cdot \\frac{W_{atm}}{g} $ where $c_{atm}$ is the specific heat of the atmosphere, $W_{atm}$ is the weight of a column of air, and $g$ is the acceleration due to gravity.\n", - "\n", - "For the ocean we have $C_{oc} = c_{oc} \\cdot \\rho_{oc} \\cdot d_{oc}$ where $c_{oc}$ is the specific heat of the ocean, $\\rho_{oc}$ is the density of seawater, and $d_{oc}$ is a representative depth of the ocean. \n", - "\n", - "We will use these definitions to find the heat capacities of the atmosphere and ocean and to refresh what we learned in Day 2." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# heat capacity of the ocean\n", - "c_oc = 3850 # specific heat of seawater in J/kg/K\n", - "rho_oc = 1025 # average density of seawater in kg/m3\n", - "d_oc = 70 # depth of water in m (here representative of the mized layer)\n", - "C_oc = c_oc * rho_oc * d_oc # heat capacity of the ocean\n", - "\n", - "# heat capacity of the atmosphere\n", - "c_atm = 1004 # specific heat of the atmosphere at constant pressure in J/kg/K\n", - "W_atm = 100000 # weight (pressure) of atmospheric column in Pa\n", - "g = 9.81 # acceleration due to gravity in m/s^2\n", - "C_atm = c_atm * (W_atm / g) # heat capacity of the atmosphere\n", - "\n", - "# total heat capacity\n", - "C = C_oc + C_atm\n", - "\n", - "# print results.\n", - "\n", - "print(\"Ocean Heat Capactiy: \", C_oc, \" J m^-2K^-2\")\n", - "print(\"Atmosphere Heat Capacity: \", C_atm, \" J m^-2K^-2\")\n", - "print(\"Total Heat Capactiy: \", C, \" J m^-2K^-2\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercises 1.1**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Calculate the depth of the ocean needed for the ocean to have the same heat capacity at the atmosphere." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 308, - "status": "ok", - "timestamp": 1681356188649, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# heat capacity of the atmosphere\n", - "c_atm = 1004 # specific heat of the atmosphere at constant pressure in J/kg/K\n", - "W_atm = 100000 # weight (pressure) of atmospheric column in Pa\n", - "g = 9.81 # height of atmosphere in m (representative of )\n", - "C_atm = c_atm * (W_atm / g) # heat capacity of the atmosphere\n", - "\n", - "# find the depth of the ocean for equivalent atmospheric heat capacity\n", - "c_oc = 3850 # specific heat of seawater in J/kg/K\n", - "rho_oc = 1025 # average density of seawater in kg/m3\n", - "\n", - "d_oc = ...\n", - "d_oc" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 310, - "status": "ok", - "timestamp": 1681356188952, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_18e8e5d1.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.1: Climate Connection**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. In your own words, describe what the answer to your coding exercise means." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_e2b68dd6.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2 : The Numerical Model**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Knowing the heat capacity, and the descriptions of $OLR$ and $ASR$ from previous tutorials, we can write the equation\n", - "\n", - "\\begin{align}\n", - "\\text{rate of change }T = \\frac{\\text{change in }T}{\\text{change in time}}=\\frac{dT}{dt}= \\frac{1}{C}(ASR - OLR)\n", - "\\end{align}\n", - "\n", - "Numerically, we can use this equation to compute the global mean surface temperature after a small interval of time by adding on the amount of energy gained or lost multiplied by the time interval itself. \n", - "\n", - "The particular method of numerically defining the time and temperature intervals (changes) is called **discretization**, and the way we have chosen to do this is called the **Euler method**. The exact details of this method are beyond the scope of this tutorial, and we will use the method without further elaboration.\n", - "\n", - "The Euler method assumes we can use $\\text{change in }T = T_{n+1} - T_{n}$ and $\\text{change in t} = t_{n+1} - t_{n}$ where $t$ is time. Thus, if we know the time interval and the current temperature ($T_n$), we can predict the temperature at the end of our time interval, ($T_{n+1}$)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# define the time interval, currently one year expressed in seconds\n", - "dt = 60.0 * 60.0 * 24.0 * 365.0\n", - "\n", - "# define albedo\n", - "alpha = 0.2941 # unitless number between 0 and 1 (calculated previously from observations in tutorial 2)\n", - "\n", - "# define transmissivity (calculated previously from observations in tutorial 1)\n", - "tau = 0.6127 # unitless number between 0 and 1\n", - "\n", - "\n", - "# define a function for absorbed shortwave radiation (ASR)\n", - "def ASR(alpha, Q):\n", - " return (1 - alpha) * Q\n", - "\n", - "\n", - "# define a function for outgoing longwave raditation (OLR)\n", - "def OLR(tau, T):\n", - " # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - " sigma = 5.67e-8 # W m^-2 K^-4\n", - "\n", - " return tau * sigma * T**4\n", - "\n", - "\n", - "# create a function to find the new tempeature based on the previous using Euler's method.\n", - "def step_forward(T, alpha, tau, dt):\n", - "\n", - " # define the observed insolation based on observations from the IPCC AR6 Figure 7.2\n", - " Q = 340 # W m^-2\n", - "\n", - " # find the new temperature using forward Euler method\n", - " T_new = T + dt / C * (ASR(alpha, Q) - OLR(tau, T))\n", - "\n", - " return T_new" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can now use a loop to apply this function many times over by specifying an initial temperature and a time interval. Note we will be using [lists](https://docs.python.org/3/tutorial/datastructures.html) to do so." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 6, - "status": "ok", - "timestamp": 1681356197368, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define the number of timesteps (currently years) to run the model\n", - "numtsteps = 15\n", - "\n", - "# for converting number of seconds in a year\n", - "sec_2_yr = 3.154e7\n", - "\n", - "# set the intial temperature (initial condition)\n", - "T_series = [288]\n", - "\n", - "# set the initial time to 0\n", - "t_series = [0]\n", - "\n", - "# run the model\n", - "for n in range(numtsteps):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " t_series.append((n + 1) * dt / sec_2_yr)\n", - "\n", - " # calculate and append the new temperature using our pre-defined function\n", - " T_series.append(step_forward(T_series[n], alpha=alpha, tau=tau, dt=dt))\n", - "\n", - "# display the temeprature time series\n", - "print(T_series)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 177, - "status": "ok", - "timestamp": 1681356200832, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# dispay the time series\n", - "print(t_series)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 921, - "status": "ok", - "timestamp": 1681356201977, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# plot the results\n", - "fig, ax = plt.subplots()\n", - "ax.plot(t_series, T_series)\n", - "ax.set_xlabel(\"Years\")\n", - "ax.set_ylabel(\"Global mean temperature (K)\");" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Do you think the time step (interval) we have used will affect the solution? If so, how?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_ebecb32e.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.2**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Using a for loop, run the model for 15 years with two different three intervals ($dt$) of a half year, 1 year and 5 years and plot the results. Note you will have to change the number of timesteps used when changing dt so that the model runs for the same amount of time. Plot your results on the same figure." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 165, - "status": "error", - "timestamp": 1681356207569, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# one year expressed in seconds\n", - "one_yr = 60.0 * 60.0 * 24.0 * 365.0\n", - "\n", - "# legend labels\n", - "labels = [\"dt = half-year\", \"dt = one year\", \"dt = five years\"]\n", - "\n", - "# define the number of timesteps (years) to run the model\n", - "numtsteps = np.array([10, 5, 1]) * 3\n", - "\n", - "# for converting number of seconds in a year\n", - "sec_2_yr = ...\n", - "\n", - "fig, ax = plt.subplots()\n", - "# loop through each choice of time step\n", - "for dd, dt_2 in enumerate([one_yr * 0.5, one_yr, one_yr * 5]):\n", - "\n", - " # set the intial temperature (initial condition)\n", - " ...\n", - "\n", - " # set the initial time to 0\n", - " ...\n", - "\n", - " # run the model\n", - " for n in range(numtsteps[dd]):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " ...\n", - "\n", - " # calculate and append the new temperature using our pre-defined function\n", - " ...\n", - "\n", - " ax.plot(t_series, T_series, label=labels[dd])\n", - "\n", - "ax.set_xlabel(\"Years\")\n", - "ax.set_ylabel(\"Global mean temperature (K)\")\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 1096, - "status": "ok", - "timestamp": 1681356209279, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_93ba61b7.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Revisiting the Climate Change Scenario from Tutorial 2**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: Enhanced Greenhouse Effect**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In tutorial 2 we looked at how changing the transmissivity ($\\tau$) affected the equilibrium temperature. Now we can use our time-dependent model to investigate this more fully. Reuse the model, this time setting $\\tau=0.57$" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 942, - "status": "ok", - "timestamp": 1681356214169, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# define transmissivity (calculated previously from observations)\n", - "tau_2 = 0.57 # unitless number between 0 and 1\n", - "\n", - "# define the number of timesteps (currently years) to run the model\n", - "numtsteps = 15\n", - "\n", - "# set the intial temperature (initial condition)\n", - "T_series = [288]\n", - "\n", - "# set the initial time to 0\n", - "t_series = [0]\n", - "\n", - "# run the model\n", - "for n in range(numtsteps):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " t_series.append((n + 1) * dt / sec_2_yr)\n", - "\n", - " # calculate and append the new temperature using our pre-defined function\n", - " T_series.append(step_forward(T_series[n], alpha=alpha, tau=tau_2, dt=dt))\n", - "\n", - "fig, ax = plt.subplots()\n", - "ax.plot(t_series, T_series)\n", - "\n", - "ax.set_xlabel(\"Years\")\n", - "ax.set_ylabel(\"Global mean temperature (K)\");" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.1**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. How does the long-term temperature here compare to the value you found from tutorial 2?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_325a6a9b.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Bonus Coding Exercise: Equilibrium Climate Sensitivity**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Here we define the **[equilibrium climate sensitivity](https://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_AnnexVII.pdf)** as the long-term global warming (equilibrium temperature increase) caused by a doubling of carbon dioxide above its pre-industrial concentration. The impact of a doubling of carbon dioxide on these energy flows is measured by a [radiative forcing](https://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_AnnexVII.pdf). Here a positive radiation forcing leads to warming, and a negative radiative forcing leads to cooling. \n", - "\n", - "The equilibrium climate sensitivity depends on a number of things, including physics and feedbacks of the model used. In the following exercise, you will calculate the equilibrium climate sensitivity of *our* model. \n", - "\n", - "1. Write a function called step_forward() as from above, and then create another function that adds in a radiative forcing to the difference between ASR and OLR and call it step_forward_forced(). Make sure both functions output the energy balance of the model. Consistent with the [IPCC AR6](https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-7/#Effective), use an effective radiative forcing of 3.93 $Wm^2$, where *effective* means the climate system, but not the surface temperature, has been allowed to adjust." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# define your functions and constants\n", - "\n", - "# define albedo\n", - "alpha = 0.2941 # unitless number between 0 and 1 (calculated previously from observations in tutorial 2)\n", - "\n", - "# define transmissivity (calculated previously from observations in tutorial 1)\n", - "tau = 0.6127 # unitless number between 0 and 1\n", - "\n", - "# effective radiative forcing for a doubling of CO2\n", - "F = 3.93 # W/m^2\n", - "\n", - "# define the time interval, one year expressed in seconds\n", - "dt = 60.0 * 60.0 * 24.0 * 365.0\n", - "\n", - "# for converting number of seconds in a year\n", - "sec_2_yr = 3.154e7\n", - "\n", - "\n", - "# create a function to find the new tempeature based on the previous using Euler's method.\n", - "def step_forward(T, alpha, tau, dt):\n", - "\n", - " # define the observed insolation based on observations from the IPCC AR6 Figure 7.2\n", - " ...\n", - "\n", - " # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - " ...\n", - "\n", - " Ftoa = ...\n", - "\n", - " T_new = ...\n", - "\n", - " return ...\n", - "\n", - "\n", - "# create a function to find the new tempeature based on the previous using Euler's method.\n", - "def step_forward_forced(T, alpha, tau, dt):\n", - "\n", - " # define the observed insolation based on observations from the IPCC AR6 Figure 7.2\n", - " ...\n", - "\n", - " # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - " ...\n", - "\n", - " Ftoa = ...\n", - "\n", - " T_new = ...\n", - "\n", - " return ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_5fbec7ab.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "2. Using an initial temperature of 288K, run the model to equilibrium. Make sure your model is in equilbrium by checking that the energy balance is near zero." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# run the model to equilibrium without forcing and begining with T(0) = 288K\n", - "\n", - "# define the number of timesteps (years) to run the model\n", - "numtsteps = 40\n", - "\n", - "# set the intial temperature (initial condition)\n", - "T_series = [288]\n", - "\n", - "# set the initial time to 0\n", - "t_series = [0]\n", - "\n", - "# run the model\n", - "for n in range(numtsteps):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " t_series.append(...)\n", - "\n", - " # calculate and append the new temperature using our pre-defined function and get energy balance\n", - " ...\n", - " T_series.append(...)\n", - "\n", - "print(...)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_3060955e.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "3. Run the forced model equilibrium using the unforced equilibrium temperature as your inital condition and the step_forward_forced() function you wrote above." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# define the number of timesteps (years) to run the model\n", - "numtsteps = 40\n", - "\n", - "# set initial condition (temperature) to the equilibrium value from the last run without forcing\n", - "T_series_forced = [T_series[-1]]\n", - "\n", - "# set the initial time to 0\n", - "t_series_forced = [0]\n", - "\n", - "# run the model\n", - "for n in range(numtsteps):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " t_series_forced.append(...)\n", - "\n", - " # calculate and append the new temperature using our pre-defined function and get energy balance\n", - " ...\n", - " T_series_forced.append(...)\n", - "\n", - "print(...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# run the model to equilibrium without forcing and begining with T(0) = 288K\n", - "\n", - "# define the number of timesteps (years) to run the model\n", - "numtsteps = 40\n", - "\n", - "# set initial condition (temperature) to the equilibrium value from the last run without forcing\n", - "T_series_forced = [T_series[-1]]\n", - "\n", - "# set the initial time to 0\n", - "t_series_forced = [0]\n", - "\n", - "# run the model\n", - "for n in range(numtsteps):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " t_series_forced.append((n + 1) * dt / sec_2_yr)\n", - "\n", - " # calculate and append the new temperature using our pre-defined function and get energy balance\n", - " T_new_forced, Ftoa_forced = step_forward_forced(\n", - " T_series_forced[n], alpha=alpha, tau=tau, dt=dt\n", - " )\n", - " T_series_forced.append(T_new_forced)\n", - "\n", - "print(Ftoa_forced)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "4. Plot the temperature curve from the forced simulation as a function of time." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# plot the time series\n", - "fig, ax = plt.subplots()\n", - "...\n", - "\n", - "ax.set_xlabel(\"Years\")\n", - "ax.set_ylabel(\"Global mean temperature (K)\");" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# plot the time series\n", - "fig, ax = plt.subplots()\n", - "ax.plot(t_series_forced, T_series_forced)\n", - "\n", - "ax.set_xlabel(\"Years\")\n", - "ax.set_ylabel(\"Global mean temperature (K)\");" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "5. Subtract the intial temperature used for your forced simulation from the final temperature after running to equilibrium to get the equilibrium climate sensitivty." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate equilibrium climate sensitivity\n", - "print(\"Equilibrium Climate Sensitivity: \", ...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# calculate equilibrium climate sensitivity\n", - "print(\"Equilibrium Climate Sensitivity: \", T_series_forced[-1] - T_series_forced[0])" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Bonus Questions: Climate Connection**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. How does this compare to the IPCC AR6 estimate of [equilibrium climate sensitivity of 2-5 K](https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-7/#Climate)? Is it higher or lower? Note here it is a temperature difference, so the units of C in the report and K found here are interchangeable. \n", - "2. In your own words, describes what this implies with respect to global mean temperatures in our models versus those in used in the IPCC report.\n", - "2. What do you think could be missing in our model?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial3_Solution_7805150d.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you explored the relationship between the heat capacity of the atmosphere and oceans and temperature changes over time. You learned how to calculate the heat capacity of these components and used this knowledge to develop a climate model. This model simulates the change in global mean surface temperature in response to energy imbalances. You explored the effects of transmissivity on the equilibrium temperature and discussed equilibrium climate sensitivity. " - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D5_Tutorial3", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.ipynb deleted file mode 100644 index bebdd2a85..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.ipynb +++ /dev/null @@ -1,910 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 4: Climate Feedbacks**\n", - "\n", - "\n", - "**Week 1, Day 5, Climate Modeling**\n", - "\n", - "**Content creators:** Jenna Pearson, Brodie Pearson, and Abigail Bodner\n", - "\n", - "**Content reviewers:** Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Agustina Pesce, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial students will learn about climate feedbacks, in particular the Planck and ice-albedo feedbacks. Students will also learn about how variations in the insolation over time can affect the equilibrium temperature of Earth.\n", - "\n", - "By the end of this tutorial students will be able to:\n", - "* Apply a temperature-dependent albedo within their existing climate model.\n", - "* Understand the impact of insolation changes on the equilibrium temperature of Earth." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1179, - "status": "ok", - "timestamp": 1682069447180, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import xarray as xr # used to manipulate data and open datasets\n", - "import numpy as np # used for algeba and array operations\n", - "import matplotlib.pyplot as plt # used for plotting\n", - "from scipy.optimize import (\n", - " brentq,\n", - ") # used for numerical root-finding to get the equilibria" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure ettings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure ettings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 517, - "status": "ok", - "timestamp": 1682069448933, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure ettings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Climate Feedbacks\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Climate Feedbacks\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Climate Feedbacks\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Ice-Albedo Feedback**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Temperature Dependent Albedo**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Our current model only contains one feedback, the 'Planck feedback' also called the 'Planck temperature response'. This feedback encapsulates that a warming of Earth leads to the planet emitting more energy (see Planck's law from Tutorial 1). In reality, there are many [climate feedbacks](https://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_AnnexVII.pdf) that contribute to the Earth's net temperature change due to an energy imbalance. In this tutorial we will focus on incorporating an **ice-albedo feedback** into our model.\n", - "\n", - "When earth's surface warms, snow and ice melt. This lowers the **albedo (**$\\mathbf{\\alpha}$**)**, because less solar radiation is reflected off Earth's surface. This lower albedo causes the climate to warm even more than if the albedo had stayed the same, increasing the snow and ice melt. This is referred to as a **positive feedback**. Positive feedbacks amplify the changes that are already occurring. This particular feedback is referred to as the **ice-albedo feedback**.\n", - "\n", - "A simple way to parameterize ice-albedo feedback in our model is through a temperature dependent albedo, such as the one defined below (see the tutorial lecture slides for an explanation of why we use this function).\n", - "\n", - "\\begin{align}\n", - "\\alpha = \\left\\{\n", - " \\begin{array}{cl}\n", - " 0.1 & T \\gt 300 K \\\\\n", - " 0.1 + (0.7-0.1) \\cdot \\frac{(T-300)^2}{(240-300)^2} & 240 \\le T \\le 300 \\\\\n", - " 0.7 & T \\lt 240\n", - " \\end{array}\n", - " \\right.\n", - "\\end{align}\n", - "\n", - "Using this new temperature-dependent albedo, we can plot the graphs of absorbed shortwave radiation (ASR) and outgoing longwave radiation (OLR):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 912, - "status": "ok", - "timestamp": 1681699458086, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# create a array ot temperatures to evaluates the ASR and OLR at\n", - "T = np.arange(200, 360, 2, dtype=np.float64)\n", - "\n", - "# create empty arrays to fill with values later\n", - "ASR_vals = np.zeros_like(T)\n", - "\n", - "# define the slope of the ramp function\n", - "m = (0.7 - 0.3) / (280 - 250)\n", - "\n", - "# define the observed insolation based on observations from the IPCC AR6 Figure 7.2\n", - "Q = 340 # W m^-2\n", - "\n", - "# define transmissivity (calculated previously from observations in tutorial 1)\n", - "tau = 0.6127 # unitless number between 0 and 1\n", - "\n", - "# define a function for absorbed shortwave radiation (ASR)\n", - "def ASR(Q, T):\n", - " # define function for albedo\n", - " if T >= 300: # temperature of very warm and ice free earth.\n", - " alpha = 0.1 # average albedo of land and sea without ice\n", - " elif T > 240: # temperature of Earth to sustain permafrost and sea ice everywhere.\n", - " alpha = 0.1 + (0.7 - 0.1) * (T - 300) ** 2 / (240 - 300) ** 2\n", - " else:\n", - " alpha = 0.7 # average albedo of land and sea ice\n", - " return (1 - alpha) * Q\n", - "\n", - "\n", - "# define a function for outgoing longwave raditation (OLR)\n", - "def OLR(tau, T):\n", - " # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation\n", - " sigma = 5.67e-8 # W m^-2 K^-4\n", - "\n", - " return tau * sigma * T**4\n", - "\n", - "\n", - "# calculate OLR for different values of T\n", - "OLR_vals = OLR(tau, T)\n", - "\n", - "# calculate ASR for different values of T\n", - "for tt, temp in enumerate(T):\n", - " ASR_vals[tt] = ASR(Q, temp)\n", - "\n", - "# make plots\n", - "fig, ax = plt.subplots()\n", - "ax.plot(T, ASR_vals, label=\"Absorbed Shortwave Radiation (ASR)\", lw=3)\n", - "ax.plot(T, OLR_vals, label=\"Outgoing Longwave Radiation (OLR)\", lw=3)\n", - "\n", - "ax.set_title(\"\", fontsize=16)\n", - "ax.set_xlabel(\"Temperature (K)\", fontsize=14)\n", - "ax.set_ylabel(\"Radiative Flux\", fontsize=14)\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.1: Climate Connection**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. How many times do the graphs of ASR and OLR intersect?\n", - "2. What does this intersection mean in terms of Earth's energy (im)balance?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial4_Solution_62453f2c.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Multiple Equilibria From Graphs**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "**Equilibrium temperatures** are solutions to the model equation when the rate of change of temperature is zero. There are two types of equilibrium solutions: *stable* and *unstable*.\n", - "\n", - " - A *stable equilibrium* temperature is a solution that the model asymptotes to (moves towards) over time. \n", - " - An *unstable equilibrium* temperature is a solution that the model diverges (moves away) from over time. The only time the model will stay at this equilibrium is if it starts *exactly* at the unstable equilibrium temperature. \n", - " \n", - "We can now incorporate the temperature-dependent albedo we defined above into our time-dependent model from Tutorial 3, to investigate the impact of the ice-albedo feedback on the long-term behavior temperature." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2, - "status": "ok", - "timestamp": 1682069593068, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - } - }, - "outputs": [], - "source": [ - "# create a function to find the new temperature based on the previous using Euler's method.\n", - "def step_forward(T, tau, Q, dt):\n", - "\n", - " # define the heat capacity (calculated in Tutorial 3)\n", - " C = 286471954.64 # J m^-2K^-2\n", - "\n", - " T_new = T + dt / C * (ASR(Q, T) - OLR(tau, T))\n", - "\n", - " return T_new" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let us explore how our model behaves under a variety of initial temperatures. We can use a `for` loop compare different initial temperatures." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1690, - "status": "ok", - "timestamp": 1682069718713, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - } - }, - "outputs": [], - "source": [ - "dt = 60.0 * 60.0 * 24.0 * 365.0 # time interval, one year expressed in seconds\n", - "\n", - "fig, ax = plt.subplots()\n", - "for init_temp in T: # suite of intial temperatures in K\n", - " numtsteps = 40 # number of years to run the model\n", - "\n", - " # for converting number of seconds in a year\n", - " sec_2_yr = 3.154e7\n", - "\n", - " # set the intial temperature (initial condition)\n", - " T_series = [init_temp]\n", - "\n", - " # set the initial time to 0\n", - " t_series = [0]\n", - "\n", - " # run the model\n", - " for n in range(numtsteps):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " t_series.append((n + 1) * dt / sec_2_yr)\n", - "\n", - " # calculate and append the new temperature using our pre-defined function\n", - " T_series.append(step_forward(T_series[n], tau=tau, Q=Q, dt=dt))\n", - "\n", - " # make plot\n", - " ax.plot(t_series, T_series)\n", - "\n", - "ax.set_title(\"Time Evolution of Temperature\", fontsize=16)\n", - "ax.set_xlabel(\"Time (years)\", fontsize=14)\n", - "ax.set_ylabel(\"Temperature (C)\", fontsize=14)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2**\n", - "\n", - "1. How many stable equilibria can you find on the figure above? Estimate their values.\n", - "2. What do these values represent on the figure you made in Part 1?\n", - "3. There is an unstable equilibrium state within this model. What is it's value?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial4_Solution_3004ccb5.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.3: Finding Equilibria Numerically & Determining Convergence or Divergence**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To verify the equilibrium solutions we identified graphically in the previous section, we can use python to find the exact values (i.e., where the rate of change in temperature is zero). That is find the temperatures that satisfy \n", - "\n", - "\\begin{align}\n", - "0 = ASR-OLR.\n", - "\\end{align}\n", - "\n", - "To aid us, we will use [`brentq`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.brentq.html#scipy-optimize-brentq), a *root-finding function* from the scipy package." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2, - "status": "ok", - "timestamp": 1682069900203, - "user": { - "displayName": "Ohad Zivan", - "userId": "06528534325719580785" - }, - "user_tz": -120 - } - }, - "outputs": [], - "source": [ - "# create function to find the forcing at the top of the atmosphere\n", - "def Ftoa(T):\n", - " return ASR(Q, T) - OLR(tau, T)\n", - "\n", - "\n", - "# it requires a function and two end-points be input as arguments\n", - "# it will look for a zero of the function between those end-points\n", - "Teq1 = brentq(\n", - " Ftoa, 200.0, 240.0\n", - ") # these ranges are from the intersections of the graphs of ASR and OLR\n", - "Teq2 = brentq(Ftoa, 240.0, 280.0)\n", - "Teq3 = brentq(Ftoa, 280.0, 320.0)\n", - "\n", - "print(Teq1, Teq2, Teq3)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To assess the stability of these equilibria, we can plot the difference in ASR and OSR. This is the same function (`Ftoa`) that we calculated in the previous cell, but we will recaclulate it below for plotting purposes." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1877, - "status": "ok", - "timestamp": 1681699462185, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# we've already calculated ASR and OLR above\n", - "fig, ax = plt.subplots()\n", - "F = ASR_vals - OLR_vals\n", - "ax.plot(T, F, color=\"k\", linewidth=3)\n", - "\n", - "# find positive values and fill with red\n", - "pos_ind1 = T <= Teq1\n", - "ax.fill_between(T[pos_ind1], 0, F[pos_ind1], color=\"red\")\n", - "\n", - "pos_ind2 = (T >= Teq2) & (T <= Teq3)\n", - "ax.fill_between(T[pos_ind2], 0, F[pos_ind2], color=\"red\")\n", - "\n", - "# find negative values and fill with blue\n", - "neg_ind1 = (T >= Teq1) & (T <= Teq2)\n", - "ax.fill_between(T[neg_ind1], 0, F[neg_ind1], color=\"blue\")\n", - "\n", - "neg_ind2 = T >= Teq3\n", - "ax.fill_between(T[neg_ind2], 0, F[neg_ind2], color=\"blue\")\n", - "\n", - "# plot vertical lines/names at equilibrium temperatures\n", - "ax.axvline(x=Teq1, color=\"k\", ls=\":\")\n", - "ax.axvline(x=Teq2, color=\"k\", ls=\":\")\n", - "ax.axvline(x=Teq3, color=\"k\", ls=\":\")\n", - "\n", - "ax.annotate(\n", - " \"$T_{eq1}$\",\n", - " xy=(Teq1 - 5, -340),\n", - " xytext=(Teq1 - 5, -340),\n", - " rotation=90,\n", - " annotation_clip=False,\n", - ")\n", - "ax.annotate(\n", - " \"$T_{eq2}$\",\n", - " xy=(Teq2 - 5, -340),\n", - " xytext=(Teq2 - 5, -340),\n", - " rotation=90,\n", - " annotation_clip=False,\n", - ")\n", - "ax.annotate(\n", - " \"$T_{eq3}$\",\n", - " xy=(Teq3 - 5, -340),\n", - " xytext=(Teq3 - 5, -340),\n", - " rotation=90,\n", - " annotation_clip=False,\n", - ")\n", - "\n", - "# plot arrows/text to show stability of equilibrium points\n", - "ax.annotate(\n", - " \"\",\n", - " xy=(232, -50),\n", - " xytext=(200, -50),\n", - " arrowprops=dict(facecolor=\"black\", arrowstyle=\"-|>\"),\n", - ")\n", - "\n", - "ax.annotate(\n", - " \"\",\n", - " xy=(242.5, -50),\n", - " xytext=(233, -50),\n", - " arrowprops=dict(facecolor=\"black\", arrowstyle=\"<|-\"),\n", - ")\n", - "\n", - "ax.annotate(\n", - " \"\",\n", - " xy=(305.5, -50),\n", - " xytext=(243.5, -50),\n", - " arrowprops=dict(facecolor=\"black\", arrowstyle=\"-|>\"),\n", - ")\n", - "\n", - "ax.annotate(\n", - " \"\",\n", - " xy=(358, -50),\n", - " xytext=(307, -50),\n", - " arrowprops=dict(facecolor=\"black\", arrowstyle=\"<|-\"),\n", - ")\n", - "\n", - "\n", - "ax.annotate(\"convergence\", xy=(358, -160), xytext=(307, -160), rotation=90)\n", - "\n", - "ax.annotate(\"divergence\", xy=(305.5, -160), xytext=(243.5, -160), rotation=90)\n", - "\n", - "ax.annotate(\"convergence\", xy=(242.5, -160), xytext=(233, -160), rotation=90)\n", - "\n", - "\n", - "ax.set_xlabel(\"Temperature (K)\", fontsize=14)\n", - "ax.set_ylabel(\"ASR-OLR\", fontsize=14);" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The red regions represent conditions where the Earth would warm, because the energy absorbed by the Earth system is greater than the energy emitted or reflected back into space. \n", - "\n", - "The blue regions represent conditions where the Earth would cool, because the outgoing radiation is larger than the absorbed radiation.\n", - "\n", - "For example, if Earth started at an initial temperature below $T_{eq1}$ (in the left red region), it will move to the right on the $x$-axis, towards the $T_{eq1}$ equilibrium state. Conversely, if Earth started between $T_{eq1}$ and $T_{eq1}$ (the left blue region), the temperature would decrease, moving left on the $x$-axis until it reaches $T_{eq1}$. Thus $T_{eq1}$ is a *stable* equilibrium as the temperature curves will tend to this point after a long time." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.3**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Identify the stable and unstable equilibria from this graph. Do these agree with the figure you made in Section 1.2?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial4_Solution_9c698981.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Changing Insolation**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: Effect on the Number Equilibrium Solutions**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "During Day 1 of this week, you learned that insolation (the amount of radiation Earth receives from the sun at the top of the atmosphere) fluctuates with time. Over Earth's history, the insolation has sometimes been lower, and sometimes been higher, than the currently observed $340 W m^{-2}$.\n", - "\n", - "These insolation changes directly affect the ASR, causing Earth to warm or cool depending on whether it receives more or less insolation respectively. To look at the effect that changing insolation has on Earth's equilibrium state(s), we can re-plot ASR as a function of temperature for several different insolation values (including the temperature-dependent albedo), alongside the OLR." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# define the observed insolation\n", - "Q_vals = [220, 340, 420] # W m^-2\n", - "\n", - "fig, ax = plt.subplots()\n", - "for Q_2 in Q_vals:\n", - " # calculate ASR and OLR for different values of T\n", - " for tt, temp in enumerate(T):\n", - "\n", - " ASR_vals[tt] = ASR(Q_2, temp)\n", - "\n", - " # make plots\n", - " ax.plot(T, ASR_vals, lw=3, label=\"ASR for Q = \" + str(Q_2) + \" $W$ $m^{-2}$\")\n", - "\n", - "# note we calculated OLR previously, and it does not depend on Q\n", - "ax.plot(T, OLR_vals, lw=3, label=\"OLR\")\n", - "\n", - "ax.set_title(\"\", fontsize=16)\n", - "ax.set_xlabel(\"Temperature (K)\", fontsize=14)\n", - "ax.set_ylabel(\"Radiative Flux\", fontsize=14)\n", - "ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "As we increase or decrease the insolation, the number of intersections between ASR and OLR can change! This means the number of equilibrium solutions for our model will also change." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.1**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. How many stable equilibrium solutions are there when $Q=220$ $W$ $m^{-2}$? Warm (ice-free) or cold (completely-frozen) state(s)?\n", - "2. For $Q=420$ $W$ $m^{-2}$? Warm or cold equilibrium state(s)?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial4_Solution_66fe91b4.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: Effect on Equilibrium Temperatures**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To understand how this effect translates to different equilibrium temperatures of our model over time, we will apply a range of insolation values to our model. Let us first start off with a very cold Earth, at 220 K, and warm the Earth by steadily increasing the insolation above our present day 340 $W$ $m^{-2}$ value." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1740, - "status": "ok", - "timestamp": 1681699463921, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# these are the values of insolation we will use\n", - "insolation_vals = np.arange(340, 500, 3)\n", - "\n", - "# initial temperature we will use\n", - "init_temp = 220 # K\n", - "\n", - "fig, ax = plt.subplots()\n", - "\n", - "for i, insolation in enumerate(insolation_vals): # suite of initial temperatures in K\n", - "\n", - " numtsteps = 100 # number of years to run the model\n", - "\n", - " # for converting number of seconds in a year\n", - " sec_2_yr = 3.154e7\n", - "\n", - " # set the intial temperature (initial condition)\n", - " T_series = [init_temp]\n", - "\n", - " # set the initial time to 0\n", - " t_series = [0]\n", - "\n", - " # run the model\n", - " for n in range(numtsteps):\n", - "\n", - " # calculate and append the time since running the model, dependent on dt and the numtsteps\n", - " t_series.append((n + 1) * dt / sec_2_yr)\n", - "\n", - " # calculate and append the new temperature using our pre-defined function\n", - " T_series.append(step_forward(T_series[n], tau=tau, Q=insolation, dt=dt))\n", - "\n", - " # make plot\n", - " colors = plt.cm.coolwarm(np.linspace(0, 1, insolation_vals.shape[0]))\n", - " if (\n", - " insolation == 385\n", - " ): # This is just to highlight a particularly interesting insolation value\n", - " ax.plot(t_series, T_series, color=colors[i], linestyle=\"dashed\")\n", - " else:\n", - " ax.plot(t_series, T_series, color=colors[i])\n", - "\n", - "ax.set_ylabel(\"Temperature (K)\", fontsize=14)\n", - "ax.set_xlabel(\"Years\", fontsize=14)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.2: Climate Connection**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Noting the dashed blue lines, at approximately what temperature do you note a rapid transition from cold to warm equilibrium states? How do these compare to your equation for albedo?\n", - "2. How would you interpret the rapid transition in equilibrium temperatures with changing insolation (the big gap in the figure) using the ASR & OLR vs. temperature plot that you made in Section 2.1?\n", - "3. BONUS: How does the time-varying behavior of the reddest (warm-state) lines relate to the ice-albedo feedback?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial4_Solution_8600cb05.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you learned about stable and unstable equilibria, identifying them from graphs and preciselt calculating them. You also incorporated an ice-albedo feedback into your model to observe its effects on equilibrium solutions under varying insolation." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D5_Tutorial4", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.ipynb deleted file mode 100644 index d514151c8..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.ipynb +++ /dev/null @@ -1,1124 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 5: Radiative Equilibrium**\n", - "\n", - "\n", - "**Week 1, Day 5, Climate Modeling**\n", - "\n", - "**Content creators:** Jenna Pearson\n", - "\n", - "**Content reviewers:** Yunlong Xu, Will Gregory, Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina Duplex, Ohad Zivan, Chi Zhang\n", - "\n", - "**Content editors:** Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial students will run a one-dimensional radiative equilibrium model that predicts the global mean atmospheric temperature as a function of height. Much of the code shown here was taken from [The Climate Laboratory](https://brian-rose.github.io/ClimateLaboratoryBook/home.html) by Brian Rose. Students are encouraged to visit this website for more tutorials and background on these models.\n", - "\n", - "By the end of this tutorial students will be able to:\n", - "* Implement a 1-D model that predicts atmospheric temperature as a function of height using the python package `climlab`.\n", - "* Understand how this model builds off of the energy balance models developed in the previous tutorials." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 161558, - "status": "ok", - "timestamp": 1682124783292, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# note the conda install takes quite a while, but conda is REQUIRED to properly download the dependencies (that are not just python packages)\n", - "# !pip install condacolab &> /dev/null # need to use conda installation of climlab, pip won't work. condacolab is a workaround\n", - "# import condacolab\n", - "# condacolab.install()\n", - "# !mamba install -c anaconda cftime xarray numpy &> /dev/null # for decoding time variables when opening datasets\n", - "# !mamba install -c conda-forge metpy climlab &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 10496, - "status": "ok", - "timestamp": 1682124802202, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# imports\n", - "import xarray as xr # used to manipulate data and open datasets\n", - "import numpy as np # used for algebra/arrays\n", - "import urllib.request # used to download data from the internet\n", - "import climlab # one of the models we are using\n", - "import matplotlib.pyplot as plt # used for plotting\n", - "import metpy # used to make Skew T Plots of temperature and pressure\n", - "from metpy.plots import SkewT # plotting function used widely in climate science\n", - "import pooch\n", - "import os\n", - "import tempfile" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 418, - "status": "ok", - "timestamp": 1682124802617, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Radiative Equilibrium\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Radiative Equilibrium\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 382, - "status": "ok", - "timestamp": 1682124802996, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Radiative Equilibrium\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Setting up the Radiative Equilibrium Model Using Climlab**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "The energy balance model we used earlier today was *zero-dimensional*, yielding only the global mean surface temperature. We might ask, is it possible to construct a similar, *one-dimensional*, model for an *atmospheric column* to estimate the global mean temperature *profile* (i.e., including the height/$z$ dimension). Additionally, can we explicitly include the effects of different gases in this model, rather than just parametrizing their collective effects through a single parameter $\\tau$? **The answer is yes, we can!**\n", - "\n", - "This model is too complex to construct from scratch, as we did in the previous tutorials. Instead, we will use a model already available within the python package [climlab](https://climlab.readthedocs.io/en/latest/intro.html). \n", - " \n", - "The model we will first use is a radiative equilbrium model. **Radiative equilibrium models** consider different layers of the atmosphere. Each of these layers absorbs and emits radiation depending on its constituent gases, allowing the model to calculate the radiation budget for each layer as radiative energy is transferred between atmospheric layers, the Earth's surface, and space. **Radiative equilibrium** is reached when each layer gains energy at the same rate as it loses energy. In this tutorial you will analyze the temperature profile of this new model once it has reached equilibrium.\n", - "\n", - "To set up this model, we will need information about some of the mean properties of the atmosphere. We are going to download water vapor data from the Community Earth System Model, a global climate model that we will go into detail on in the next tutorial, to use a variable called [specific humidity](https://glossary.ametsoc.org/wiki/Specific_humidity). **Specific humidity** is the mass of water vapor per mass of a unit block of air. This is useful because water vapor is an important greenhouse gas." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 121302, - "status": "ok", - "timestamp": 1682124999876, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "filename_sq = \"cpl_1850_f19-Q-gw-only.cam.h0.nc\"\n", - "url_sq = \"https://osf.io/c6q4j/download/\"\n", - "\n", - "ds = xr.open_dataset(\n", - " pooch_load(filelocation=url_sq, filename=filename_sq)\n", - ") # ds = dataset\n", - "ds" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# the specific humidity is stored in a variable called Q\n", - "ds.Q" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "ds.time" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "however, we want an annual average profile:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5500, - "status": "ok", - "timestamp": 1680830700022, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# take global, annual average using a weighting (ds.gw) that is calculated based on the model grid - and is similar, but not identical, to a cosine(latitude) weighting\n", - "\n", - "weight_factor = ds.gw / ds.gw.mean(dim=\"lat\")\n", - "Qglobal = (ds.Q * weight_factor).mean(dim=(\"lat\", \"lon\", \"time\"))\n", - "# print specific humidity profile\n", - "Qglobal" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we have a global mean water vapor profile, we can define a model that has the same vertical levels as this water vapor data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 148, - "status": "ok", - "timestamp": 1680831446236, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "# use 'lev=Qglobal.lev' to create an identical vertical grid to water vapor data\n", - "mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)\n", - "mystate" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To model the absorption and emission of different gases within each atmospheric layer, we use the **[Rapid Radiative Transfer Model](https://climlab.readthedocs.io/en/latest/api/climlab.radiation.RRTMG.html)**, which is contained within the `RRTMG` module. We must first initialize our model using the water vapor ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 3619, - "status": "ok", - "timestamp": 1680831453423, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "radmodel = climlab.radiation.RRTMG(\n", - " name=\"Radiation (all gases)\", # give our model a name!\n", - " state=mystate, # give our model an initial condition!\n", - " specific_humidity=Qglobal.values, # tell the model how much water vapor there is\n", - " albedo=0.25, # this the SURFACE shortwave albedo\n", - " timestep=climlab.constants.seconds_per_day, # set the timestep to one day (measured in seconds)\n", - ")\n", - "radmodel" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's explore this initial state. Here `Ts` is the initial global mean surface temperature, and `Tatm` is the initial global mean air temperature profile." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 115, - "status": "ok", - "timestamp": 1680831456021, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "radmodel.state" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "One of the perks of using this model is it's ability to incorporate the radiative effects of individual greenhouse gases in different parts of the radiation spectrum, rather than using a bulk reduction in transmission of outgoing longwave radiation (as in our previous models).\n", - "\n", - "Let's display 'absorber_vmr', which contains the **volume mixing ratio**'s of each gas used in the radiative transfer model (these are pre-defined; and do not include the water vapor we used as a model input above). The volume mixing ratio describes the fraction of molecules in the air that are a given gas. For example, $21\\%$ of air is oxygen and so it's volumn mixing ratio is 0.21." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 158, - "status": "ok", - "timestamp": 1680831467961, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "radmodel.absorber_vmr" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To look at carbon dioxide (`CO2`) in a more familiar unit, parts per million (by volume), we can convert and print the new value." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 125, - "status": "ok", - "timestamp": 1680831471172, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "radmodel.absorber_vmr[\"CO2\"] * 1e6" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can also look at all the available diagnostics of our model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 287, - "status": "ok", - "timestamp": 1680831473662, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "diag_ds = climlab.to_xarray(radmodel.diagnostics)\n", - "diag_ds" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "For example to look at OLR," - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 158, - "status": "ok", - "timestamp": 1680831477856, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "outputs": [], - "source": [ - "radmodel.OLR" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Note. the OLR is currently 0 as we have not ran the model forward in time, so it has not calculated any radiation components." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 1: Climate Connection**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Why do you think all gases, except ozone and water vapor, are represented by single values in the model?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial5_Solution_57426c01.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Coding Exercises 1**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. On the same graph, plot the annual mean specific humidity profile and ozone profiles." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "# multiply Qglobal by 1000 to put in units of grams water vapor per kg of air\n", - "_ = ...\n", - "# multiply by 1E6 to get units of ppmv = parts per million by volume\n", - "_ = ...\n", - "\n", - "# pressure decreases logarithmically with height in the atmosphere\n", - "# invert the axis so the largest value of pressure is lowest\n", - "ax.invert_yaxis()\n", - "# set y axis to a log scale\n", - "_ = ...\n", - "\n", - "ax.set_ylabel(\"Pressure (hPa)\")\n", - "ax.set_xlabel(\"Specific humidity (g/kg)\")\n", - "\n", - "# turn on the grid lines\n", - "_ = ...\n", - "\n", - "# turn on legend\n", - "_ = ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 2400, - "status": "ok", - "timestamp": 1680831485188, - "user": { - "displayName": "Abigail Bodner", - "userId": "16617086768288510233" - }, - "user_tz": 240 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial5_Solution_8eaf5c15.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Getting Data to Compare to the Model**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Before we run our model forward, we will download a reanalysis product from NCEP to get a sense of what the real global mean atmospheric temperature profile looks like. We will compare this profile to our model runs later." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 979, - "status": "ok", - "timestamp": 1682125086037, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "filename_ncep_air = \"air.mon.1981-2010.ltm.nc\"\n", - "url_ncep_air = \"https://osf.io/w6cd5/download/\"\n", - "ncep_air = xr.open_dataset(\n", - " pooch_load(filelocation=url_ncep_air, filename=filename_ncep_air)\n", - ") # ds = dataset\n", - "\n", - "# this is the long term monthly means (note only 12 time steps)\n", - "ncep_air.air" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 7, - "status": "ok", - "timestamp": 1680662820551, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# need to take the average over space and time\n", - "# the grid cells are not the same size moving towards the poles, so we weight by the cosine of latitude to compensate for this\n", - "coslat = np.cos(np.deg2rad(ncep_air.lat))\n", - "weight = coslat / coslat.mean(dim=\"lat\")\n", - "\n", - "Tglobal = (ncep_air.air * weight).mean(dim=(\"lat\", \"lon\", \"time\"))\n", - "Tglobal" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Below we will define two helper funcitons to visualize the profiles output from our model with a *SkewT* plot. This is common way to plot atmospheric temperature in climate science, and the `metpy` package has a built in function to make this easier.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# to setup the skewT and plot observations\n", - "def make_skewT():\n", - " fig = plt.figure(figsize=(9, 9))\n", - " skew = SkewT(fig, rotation=30)\n", - " skew.plot(\n", - " Tglobal.level,\n", - " Tglobal,\n", - " color=\"black\",\n", - " linestyle=\"-\",\n", - " linewidth=2,\n", - " label=\"Observations\",\n", - " )\n", - " skew.ax.set_ylim(1050, 10)\n", - " skew.ax.set_xlim(-90, 45)\n", - " # Add the relevant special lines\n", - " # skew.plot_dry_adiabats(linewidth=1.5, label = 'dry adiabats')\n", - " # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')\n", - " # skew.plot_mixing_lines()\n", - " skew.ax.legend()\n", - " skew.ax.set_xlabel(\"Temperature (degC)\", fontsize=14)\n", - " skew.ax.set_ylabel(\"Pressure (hPa)\", fontsize=14)\n", - " return skew" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# to add a model derived profile to the skewT figure\n", - "def add_profile(skew, model, linestyle=\"-\", color=None):\n", - " line = skew.plot(\n", - " model.lev,\n", - " model.Tatm - climlab.constants.tempCtoK,\n", - " label=model.name,\n", - " linewidth=2,\n", - " )[0]\n", - " skew.plot(\n", - " 1000,\n", - " model.Ts - climlab.constants.tempCtoK,\n", - " \"o\",\n", - " markersize=8,\n", - " color=line.get_color(),\n", - " )\n", - " skew.ax.legend()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2544, - "status": "ok", - "timestamp": 1680662823964, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "skew = make_skewT()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "SkewT (also known as SkewT-logP) plots are generally used for much [more complex reasons](https://www.weather.gov/source/zhu/ZHU_Training_Page/convective_parameters/skewt/skewtinfo.html) than we will use here. However, one of the benefits of this plot that we will utilize is the fact that pressure decreases approximately logarithmically with height. Thus, with a *logP* axis, we are showing information that is roughly linear in height, making the plots more intuitive. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: Running the Radiative Equilibrium Model Forward in Time**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can run this model over many time steps, just like the simple greenhouse model, but now we can examine the behavior of the temperature profile rather than just the surface temperature. \n", - "\n", - "There is no need to write out a function to step our model forward - `climlab` already has this feature. We will use this function to run our model to equilibrium (i.e., until OLR is balanced by ASR)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# take a single step forward to the diagnostics are updated and there is some energy imbalance\n", - "radmodel.step_forward()\n", - "\n", - "# run the model to equilibrium (the difference between ASR and OLR is a very small number)\n", - "while np.abs(radmodel.ASR - radmodel.OLR) > 0.001:\n", - " radmodel.step_forward()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 7, - "status": "ok", - "timestamp": 1680662825783, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# check the energy budget to make sure we are really at equilibrium\n", - "radmodel.ASR - radmodel.OLR" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now let's can compare this to observations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2330, - "status": "ok", - "timestamp": 1680662828107, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "skew = make_skewT()\n", - "add_profile(skew, radmodel)\n", - "skew.ax.set_title(\"Pure Radiative Equilibrium\", fontsize=18);" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 3: Climate Connection**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. The profile from our model does not match observations well. Can you think of one component we might be missing?\n", - "2. What effect do you think the individual gases play in determining this profile and why?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial5_Solution_4724967d.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Coding Exercises 3**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Create a second model called 'Radiation (no H20)' that lacks water vapor. Then re-create the plot above, but add on this extra profile without water vapor." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# make an exact clone of our existing model\n", - "radmodel_noH2O = climlab.process_like(radmodel)\n", - "# change the name of our new model\n", - "radmodel_noH2O.name = ...\n", - "\n", - "# set the water vapor profile to all zeros\n", - "radmodel_noH2O.specific_humidity *= 0.0\n", - "\n", - "# run the model to equilibrium\n", - "radmodel_noH2O.step_forward()\n", - "while np.abs(radmodel_noH2O.ASR - radmodel_noH2O.OLR) > 0.01:\n", - " radmodel_noH2O.step_forward()\n", - "\n", - "# create skewT plot\n", - "skew = make_skewT()\n", - "\n", - "# add profiles for both models to plot\n", - "for model in [...]:\n", - " ..." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 5291, - "status": "ok", - "timestamp": 1680662833394, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial5_Solution_5eb5cfa0.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you've learned how to use the python package `climlab` to construct a one-dimensional radiative equilibrium model, and run it forward in time to predict the global mean atmospheric temperature profile. You've also visualized these results through SkewT plots." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data from this tutorial can be accessed for specific humidity [here](http://thredds.atmos.albany.edu:8080/thredds/fileServer/CESMA/cpl_1850_f19/concatenated/cpl_1850_f19.cam.h0.nc) and reanalysis temperature [here](https://downloads.psl.noaa.gov/Datasets/ncep.reanalysis/Monthlies/pressure/air.mon.1981-2010.ltm.nc)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D5_Tutorial5", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.ipynb deleted file mode 100644 index a8b1abfc3..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.ipynb +++ /dev/null @@ -1,763 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 6: Radiative Convective Equilibrium**\n", - "\n", - "\n", - "**Week 1, Day 5, Climate Modeling**\n", - "\n", - "**Content creators:** Jenna Pearson\n", - "\n", - "**Content reviewers:** Yunlong Xu, Will Gregory, Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina Duplex, Ohad Zivan, Chi Zhang\n", - "\n", - "**Content editors:** Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "Building on the understanding of a one-dimensional radiative balance model from previous tutorial, in this tutorial students will learn about **radiative-convective-equilibrium**. Much of the code shown here was taken from [The Climate Laboratory](https://brian-rose.github.io/ClimateLaboratoryBook/home.html) by Brian Rose. Students are encouraged to visit this website for more tutorials and background on these models.\n", - "\n", - "By the end of this tutorial students will be able to:\n", - "* Implement a radiative-convective equilibrium model using the python package `climlab`.\n", - "* Understand how this model builds off the one-dimensional radiative balance model used in the previous tutorials." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 161558, - "status": "ok", - "timestamp": 1682124783292, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# note the conda install takes quite a while, but conda is REQUIRED to properly download the dependencies (that are not just python packages)\n", - "# !pip install condacolab &> /dev/null # need to use conda installation of climlab, pip won't work. condacolab is a workaround\n", - "# import condacolab\n", - "# condacolab.install()\n", - "# !mamba install -c anaconda cftime xarray numpy &> /dev/null # for decoding time variables when opening datasets\n", - "# !mamba install -c conda-forge metpy climlab &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 10496, - "status": "ok", - "timestamp": 1682124802202, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import xarray as xr # used to manipulate data and open datasets\n", - "import numpy as np # used for algebra/arrays\n", - "import urllib.request # used to download data from the internet\n", - "import climlab # one of the models we are using\n", - "import matplotlib.pyplot as plt # used for plotting\n", - "import metpy # used to make Skew T Plots of temperature and pressure\n", - "from metpy.plots import SkewT # plotting function used widely in climate science\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "from IPython.display import HTML\n", - "from matplotlib import animation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plotting functions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Plotting functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 5, - "status": "ok", - "timestamp": 1682124802203, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Plotting functions\n", - "\n", - "# make the videos at the end of the tutorial\n", - "plt.rcParams[\"animation.html\"] = \"jshtml\"\n", - "\n", - "# these three functions are used to make videos at the end of the tutorial\n", - "\n", - "\n", - "def initial_figure(model):\n", - " with plt.ioff(): # will hide the inital figure which will plot separate from the video otherwise\n", - " fig = plt.figure(figsize=(6, 6))\n", - " lines = []\n", - "\n", - " skew = SkewT(fig, rotation=30)\n", - " # plot the observations\n", - " skew.plot(\n", - " Tglobal.level,\n", - " Tglobal,\n", - " color=\"black\",\n", - " linestyle=\"-\",\n", - " linewidth=2,\n", - " label=\"Observations\",\n", - " )\n", - " lines.append(\n", - " skew.plot(\n", - " model.lev,\n", - " model.Tatm - climlab.constants.tempCtoK,\n", - " linestyle=\"-\",\n", - " linewidth=2,\n", - " color=\"C0\",\n", - " label=\"RC model (all gases)\",\n", - " )[0]\n", - " )\n", - " skew.ax.legend()\n", - " skew.ax.set_ylim(1050, 10)\n", - " skew.ax.set_xlim(-60, 75)\n", - " # Add the relevant special lines\n", - " skew.plot_dry_adiabats(linewidth=1.5, label=\"dry adiabats\")\n", - " # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')\n", - " skew.ax.set_xlabel(\"Temperature ($^\\circ$C)\", fontsize=14)\n", - " skew.ax.set_ylabel(\"Pressure (hPa)\", fontsize=14)\n", - " lines.append(\n", - " skew.plot(\n", - " 1000,\n", - " model.Ts - climlab.constants.tempCtoK,\n", - " \"o\",\n", - " markersize=8,\n", - " color=\"C0\",\n", - " )[0]\n", - " )\n", - "\n", - " return fig, lines\n", - "\n", - "\n", - "def animate(day, model, lines):\n", - " lines[0].set_xdata(np.array(model.Tatm) - climlab.constants.tempCtoK)\n", - " lines[1].set_xdata(np.array(model.Ts) - climlab.constants.tempCtoK)\n", - " # lines[2].set_xdata(np.array(model.q)*1E3)\n", - " # lines[-1].set_text('Day {}'.format(int(model.time['days_elapsed'])))\n", - " # This is kind of a hack, but without it the initial frame doesn't appear\n", - " if day != 0:\n", - " model.step_forward()\n", - " return lines\n", - "\n", - "\n", - "# to setup the skewT and plot observations\n", - "def make_basic_skewT():\n", - " fig = plt.figure(figsize=(9, 9))\n", - " skew = SkewT(fig, rotation=30)\n", - " skew.plot(\n", - " Tglobal.level,\n", - " Tglobal,\n", - " color=\"black\",\n", - " linestyle=\"-\",\n", - " linewidth=2,\n", - " label=\"Observations\",\n", - " )\n", - " skew.ax.set_ylim(1050, 10)\n", - " skew.ax.set_xlim(-90, 45)\n", - " # Add the relevant special lines\n", - " # skew.plot_dry_adiabats(linewidth=1.5, label = 'dry adiabats')\n", - " # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')\n", - " # skew.plot_mixing_lines()\n", - " skew.ax.legend()\n", - " skew.ax.set_xlabel(\"Temperature (degC)\", fontsize=14)\n", - " skew.ax.set_ylabel(\"Pressure (hPa)\", fontsize=14)\n", - " return skew\n", - "\n", - "\n", - "# to setup the skewT and plot observations\n", - "def make_skewT():\n", - " fig = plt.figure(figsize=(9, 9))\n", - " skew = SkewT(fig, rotation=30)\n", - " skew.plot(\n", - " Tglobal.level,\n", - " Tglobal,\n", - " color=\"black\",\n", - " linestyle=\"-\",\n", - " linewidth=2,\n", - " label=\"Observations\",\n", - " )\n", - " skew.ax.set_ylim(1050, 10)\n", - " skew.ax.set_xlim(-90, 45)\n", - " # Add the relevant special lines\n", - " skew.plot_dry_adiabats(linewidth=1.5, label=\"dry adiabats\")\n", - " # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')\n", - " # skew.plot_mixing_lines()\n", - " skew.ax.legend()\n", - " skew.ax.set_xlabel(\"Temperature (degC)\", fontsize=14)\n", - " skew.ax.set_ylabel(\"Pressure (hPa)\", fontsize=14)\n", - " return skew\n", - "\n", - "\n", - "# to add a model derived profile to the skewT figure\n", - "def add_profile(skew, model, linestyle=\"-\", color=None):\n", - " line = skew.plot(\n", - " model.lev,\n", - " model.Tatm - climlab.constants.tempCtoK,\n", - " label=model.name,\n", - " linewidth=2,\n", - " )[0]\n", - " skew.plot(\n", - " 1000,\n", - " model.Ts - climlab.constants.tempCtoK,\n", - " \"o\",\n", - " markersize=8,\n", - " color=line.get_color(),\n", - " )\n", - " skew.ax.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Radiative-Convective Equilibrium\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Radiative-Convective Equilibrium\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Radiative-Convective Equilibrium\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Reproducing Data from the Last Tutorial's One-dimensional Radiative Equilibrium Model Using Climlab**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "filename_sq = \"cpl_1850_f19-Q-gw-only.cam.h0.nc\"\n", - "url_sq = \"https://osf.io/c6q4j/download/\"\n", - "ds = xr.open_dataset(\n", - " pooch_load(filelocation=url_sq, filename=filename_sq)\n", - ") # ds = dataset\n", - "\n", - "filename_ncep_air = \"air.mon.1981-2010.ltm.nc\"\n", - "url_ncep_air = \"https://osf.io/w6cd5/download/\"\n", - "ncep_air = xr.open_dataset(\n", - " pooch_load(filelocation=url_ncep_air, filename=filename_ncep_air)\n", - ") # ds = dataset\n", - "\n", - "# take global, annual average\n", - "weight_factor = ds.gw / ds.gw.mean(dim=\"lat\")\n", - "Qglobal = (ds.Q * weight_factor).mean(dim=(\"lat\", \"lon\", \"time\"))\n", - "\n", - "# use 'lev=Qglobal.lev' to create an identical vertical grid to water vapor data\n", - "mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)\n", - "\n", - "radmodel = climlab.radiation.RRTMG(\n", - " name=\"Radiation (all gases)\", # give our model a name!\n", - " state=mystate, # give our model an initial condition!\n", - " specific_humidity=Qglobal.values, # tell the model how much water vapor there is\n", - " albedo=0.25, # this the SURFACE shortwave albedo\n", - " timestep=climlab.constants.seconds_per_day, # set the timestep to one day (measured in seconds)\n", - ")\n", - "\n", - "# need to take the average over space and time\n", - "# the grid cells are not the same size moving towards the poles, so we weight by the cosine of latitude to compensate for this\n", - "coslat = np.cos(np.deg2rad(ncep_air.lat))\n", - "weight = coslat / coslat.mean(dim=\"lat\")\n", - "\n", - "Tglobal = (ncep_air.air * weight).mean(dim=(\"lat\", \"lon\", \"time\"))\n", - "\n", - "# take a single step forward to the diagnostics are updated and there is some energy imbalance\n", - "radmodel.step_forward()\n", - "\n", - "# run the model to equilibrium (the difference between ASR and OLR is a very small number)\n", - "while np.abs(radmodel.ASR - radmodel.OLR) > 0.001:\n", - " radmodel.step_forward()\n", - "\n", - "skew = make_basic_skewT()\n", - "add_profile(skew, radmodel)\n", - "skew.ax.set_title(\"Pure Radiative Equilibrium\", fontsize=18);" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Radiative-Convective Equilibrium**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "From the plot you just made, one of the largest differences between observations and the pure radiation model with all gases lies in the lower atmosphere, where the surface air temperature is 20 degrees too warm and the 200 hPa pressure surface is 40 degrees too cold. What could be the issue?\n", - "\n", - "One thing we have not included in our model yet is dynamics (motion of the air). The model's temperature profile is what's known as **statically unstable** (note this definition of stability is different than that used in the previous tutorials).\n", - "\n", - "Here **static** means not due to wind, and **unstable** means the atmosphere wants to adjust to a different state because the surface air is relatively light and wants to rise into upper layers of the atmosphere. As the air rises, it creates **convective turbulence** (similar to boiling water, where convective circulation is introduced from heating water from below). The rising air, and the resultant turbulence, mixes the atmospheric column. This mixing often occurs across the **troposphere**, which is roughly the lowest 10km of the atmosphere. Most of the weather we experience lies in the troposphere. \n", - "\n", - "When air rises [adiabatically](httphttps://forecast.weather.gov/glossary.php?word=adiabatics://), it expands and cools due to the lower pressure. The *rate* of cooling depends on whether the air is saturated with water vapor. When rising air is unsaturated, it cools following the dry adiabats. If the air saturates, it cools at a lesser rate denoted by the moist adiabats (we did not have time to discuss these moisture effects in the mini-lecture). \n", - "\n", - "To identify unstable atmospheric layers, let's take another look at the SkewT plot, but this time we will plot the dry adiabats. We can then compare the rates of cooling of our model to these adiabats." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1707, - "status": "ok", - "timestamp": 1680662835097, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "skew = make_skewT()\n", - "add_profile(skew, radmodel)\n", - "skew.ax.set_title(\"Pure Radiative Equilibrium\", fontsize=18)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "\n", - "Near the surface, the reanalysis temperature profile is steeper than the dry adiabats. In these layers vertical motion is inhibited, and the surface conditions are considered stable. However, the model profile is shallower than the dry adiabats. In the model, the surface air is *statically unstable*, which would lead to convective mixing if this physical process was included in the model (the model currently only includes radiative processes). **In this tutorial we will see whether including convective mixing in our model can bring the model closer to the reanalysis temperature profile.**\n", - "\n", - "\n", - "To build a radiative-convective model we can take the radiative model we have already made and couple it to a convective model. Here the term **couple** implies there is communication between the models such that their effects are both incorporated into the final product, which in our case is the temperature profile." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# restate the model here for ease of coding\n", - "\n", - "# make a model on same vertical domain as the water vapor data\n", - "mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)\n", - "\n", - "# create the radiation model\n", - "rad = climlab.radiation.RRTMG(\n", - " name=\"Radiation (net)\",\n", - " state=mystate,\n", - " specific_humidity=Qglobal.values,\n", - " timestep=climlab.constants.seconds_per_day,\n", - " albedo=0.25, # surface albedo, tuned to give reasonable ASR for reference cloud-free model\n", - ")\n", - "\n", - "# create the convection model\n", - "conv = climlab.convection.ConvectiveAdjustment(\n", - " name=\"Convection\",\n", - " state=mystate,\n", - " adj_lapse_rate=6.5, # the adiabatic lapse rate of the atmopshere\n", - " timestep=rad.timestep, # same timestep as radiation model\n", - ")\n", - "# couple the two components\n", - "rcm = climlab.couple([rad, conv], name=\"Radiative-Convective Model\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now let's run the radiation part to equilibrium, which should give us the same profile as in the previous section. Once we get this *radiative equilibrium* profile we will add convective mixing physics to the model and continue running it until it reaches *radiative-convective equilibrium*.\n", - "\n", - "The new model does not actually resolve the actual vertical motion and mixing that occurs in convection. Instead, the model includes a *parameterization* for convection which automatically mixes regions of the atmospheric column that are statically unstable." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 8446, - "status": "ok", - "timestamp": 1680662843889, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# run JUST the radiative component to equilibrium\n", - "for n in range(1000):\n", - " rcm.subprocess[\"Radiation (net)\"].step_forward()\n", - "\n", - "# compute diagnostics\n", - "rcm.compute_diagnostics()\n", - "\n", - "# plot the resulting profile (our initial condition once we turn on the physics)\n", - "fig, lines = initial_figure(rcm)\n", - "\n", - "# this animation can take a while\n", - "animation.FuncAnimation(fig, animate, 50, fargs=(rcm, lines))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Adding convective mixing to the initially unstable temperature profile leads to an instant mixing of air throughout the lower atmosphere, moving the profile towards the observations. The balance at play is between radiative process that warm the surface and cool the troposphere (lower atmosphere) as well as convection which moves heat away from the surface, leading to a colder surface and warmer troposphere. Note the differences in surface versus tropospheric temperatures in the new versus old equilibrium profiles." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 2: Climate Connection**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. The static instability was removed in the first time step! In reality, which process do you think changes temperature faster, convection or radiation?\n", - "2. What do you think the next step would be to move towards a more realistic climate model?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial6_Solution_c4ff6bad.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Coding Exercises 2**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Recreate the video above except using an isothermal atmosphere (uniform temperature profile) set to the surface temprature (rcm.state.Ts). Does the equilbrium profile look any different than the one you made before?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 16, - "status": "ok", - "timestamp": 1680662920103, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# set initial temperature profile to be the surface temperature (isothermal)\n", - "rcm.state.Tatm[:] = rcm.state.Ts\n", - "\n", - "# compute diagnostics\n", - "_ = ...\n", - "\n", - "# plot initial data\n", - "fig, lines = initial_figure(rcm)\n", - "\n", - "# make animation - this animation can take a while\n", - "# animation.FuncAnimation(fig, animate, 50, fargs=(rcm, lines))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 2089, - "status": "ok", - "timestamp": 1680662922186, - "user": { - "displayName": "Jenna Pearson", - "userId": "05648130581702734913" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial6_Solution_46d5cbad.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you explored the concept of radiative-convective equilibrium, learning to implement a Python model using the `climlab` package. You learned the limitations of a pure radiation model and the necessity to include atmospheric dynamics such as convection. Through coupling a radiation model with a convective model, you have simulated a more realistic atmospheric temperature profile. Even though the model does not directly resolve the vertical motion during convection, it incorporates a parameterization to automatically account for mixing in statically unstable regions. By the end of the tutorial, you could comprehend how this model expands on the previous energy balance models from tutorials 1-4." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data from this tutorial can be accessed for specific humidity [here](http://thredds.atmos.albany.edu:8080/thredds/fileServer/CESMA/cpl_1850_f19/concatenated/cpl_1850_f19.cam.h0.nc) and reanalysis temperature [here](https://downloads.psl.noaa.gov/Datasets/ncep.reanalysis/Monthlies/pressure/air.mon.1981-2010.ltm.nc)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D5_Tutorial6", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.ipynb b/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.ipynb deleted file mode 100644 index 475fbe07e..000000000 --- a/book/_build/html/_sources/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.ipynb +++ /dev/null @@ -1,819 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "af12530d", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 7: Introduction to Earth System Models**\n", - "\n", - "\n", - "**Week 1, Day 5, Climate Modeling**\n", - "\n", - "**Content creators:** Brodie Pearson, Jenna Pearson, Julius Busecke, and Tom Nicholas\n", - "\n", - "**Content reviewers:** Yunlong Xu, Will Gregory, Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina Duplex, Ohad Zivan, Chi Zhang\n", - "\n", - "**Content editors:** Abigail Bodner, Ohad Zivan, Chi Zhang\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial students will learn how to load, visualize, and manipulate data from an Earth System Model (ESM) to explore the spatial variations in each component of the surface heat flux.\n", - "\n", - "By the end of this tutorial students will be able to:\n", - "* Load data from the Community Earth System Model (CESM)\n", - "* Analyze the zonal-mean surface energy budget of a realistic climate model (i.e., the budget at each latitude)\n", - "* Link variations in different surface heat flux to physical differences in the air-surface conditions across regions.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 148771, - "status": "ok", - "timestamp": 1682000677034, - "user": { - "displayName": "Wesley Banfield", - "userId": "15738596203150760123" - }, - "user_tz": -120 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# note the conda install takes quite a while, but conda or mamba is REQUIRED to properly download the dependencies\n", - "# !pip install condacolab &> /dev/null\n", - "# import condacolab\n", - "# condacolab.install()\n", - "\n", - "# crucial to install all packages in one line, otherwise code will fail.\n", - "# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils &> /dev/null" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 521, - "status": "error", - "timestamp": 1682000677547, - "user": { - "displayName": "Wesley Banfield", - "userId": "15738596203150760123" - }, - "user_tz": -120 - } - }, - "outputs": [], - "source": [ - "# imports\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", - "from xmip.utils import google_cmip_col\n", - "\n", - "from datatree import DataTree\n", - "from xmip.postprocessing import _parse_metric\n", - "\n", - "import cartopy.crs as ccrs\n", - "import pooch" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: The Community Earth System Model (CESM)**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Throughout today's tutorials, we have been working with increasingly complex climate models. In this final tutorial we will look at data from the most complex type of climate model, an Earth System Model (ESM). These ESMs include the physical processes typical of General Circulation Models (GCMs), but also include chemical and biological changes within the climate system (e.g. changes in vegetation, biomes, atmospheric $CO_2$).\n", - "\n", - "The [Community Earth System Model](https://www.cesm.ucar.edu/models/cesm2) (**CESM**) is the specific ESM that we will analyze here in prepartion for next week where you will look at many ESM data sets simultaneously. We will be analyzing a **historical simulation** of CESM, which covers the period 1850 to 2015 using the historicallly observed forcing of the climate system.\n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Finding & opening CMIP6 data with xarray**\n", - "\n", - "Massive projects like CMIP6 can contain millions of datasets. For most practical applications we only need a subset of the data. To do this, we need to specify exactly which data sets we need. The naming conventions of CMIP6 data sets are standardized across all models and experiments, which allows us to load multiple related data sets with efficient code.\n", - "\n", - "In order to load a CMIP6 dataset the following information must be specified:\n", - "1. ***variable_id***: The variable(s) of interest \n", - " * in CMIP6 SST is called *tos*\n", - "2. ***source_id***: The CMIP6 model(s) that we want data from \n", - "3. ***table_id***: The origin system and output frequency desired of the variable(s) \n", - " * We use *Omon* - data from the ocean model at monthly resolution\n", - "4. ***grid_id***: The grid that we want the data to be on\n", - " * We use *gn* which is data on the model's *native* grid, some models also provide *gr* (*regridded* data) and other grid options\n", - "5. ***experiment_id***: The CMIP6 experiments that we want to analyze\n", - " * We will load three experiments: *historical*, *ssp126* and *ssp585*. We'll discuss these more in the next few tutorials\n", - "6. ***member_id***: this distinguishes simulations if the same model is run repeatedly for an experiment\n", - " * We use *r1i1p1f1* for now, but will explore this in a later tutorial\n", - "\n", - "Each of these terms is called a *facet* in CMIP vocabulary.\n", - "\n", - "Once you have defined the facets of interest you need to somehow search and retrieve the datasets that contain these facets. \n", - "\n", - "There are many ways to do this, but here we will show a workflow using an [intake-esm](https://intake-esm.readthedocs.io/en/stable/) catalog object based on a CSV file that is maintained by the pangeo community.\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "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", - "col" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We just loaded the full collection of Pangeo cloud datasets into an intake catalog, and defined a list of 5 example models ('source_ids') for this demonstration. There are many more to test out! You could run `col.df['source_id'].unique()` in a new cell to get a list of all available models\n", - "\n", - "Now we will create a subset according to the provided facets using the `.search()` method, and finally open the [zarr stores]() in the cloud into xarray datasets. \n", - "\n", - " The data returned are xarray datasets which contain [dask arrays](https://docs.dask.org/en/stable/array.html). These are 'lazy', meaning the actual data will only be loaded when a computation is performed. What is loaded here is only the metadata, which enables us to inspect the data (e.g. the dimensionality/variable units) without loading in GBs or TBs of data!\n", - "\n", - "A subtle but important step in the opening stage is the use of a preprocessing function! By passing `preprocess=combined_preprocessing` we apply crowdsourced fixes from the [xMIP](https://github.com/jbusecke/xmip) package to each dataset. This ensures consistent naming of dimensions (and other convienient things - see [here](https://cmip6-preprocessing.readthedocs.io/en/latest/tutorial.html) for more)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 8712, - "status": "ok", - "timestamp": 1681772839862, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=\"CESM2\",\n", - " variable_id=[\n", - " \"hfls\",\n", - " \"hfss\",\n", - " \"rlds\",\n", - " \"rlus\",\n", - " \"rsds\",\n", - " \"rsus\",\n", - " \"tas\",\n", - " \"rsdt\",\n", - " \"rsut\",\n", - " \"rlut\",\n", - " ],\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Amon\",\n", - " grid_label=\"gn\",\n", - " experiment_id=[\"historical\", \"hist-nat\"],\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)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Checking the CMIP6 datasets**\n", - "\n", - "We now have a \"[datatree](https://xarray-datatree.readthedocs.io/en/latest/quick-overview.html)\" containing the data we searched for. A datatree is a high-level container of xarray data, useful for organizing many related datasets together. You can think of a single `DataTree` object as being like a (nested) dictionary of `xarray.Dataset` objects. Each dataset in the tree is known as a \"node\" or \"group\", and we can also have empty nodes. You can explore the nodes of the tree and its contents interactively in a similar way to how you can explore the contents of an `xarray.Dataset`. Click on the arrows to expand the information about the datatree below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1263, - "status": "ok", - "timestamp": 1681700860145, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "dt" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Each group in the tree is stored under a corresponding `name`, and we can select nodes via their name. The real usefulness of a datatree comes from having many groups at different depths, analogous to how one might store files in nested directories (e.g. `day1/experiment1/data.txt`, `day1/experiment2/data.txt` etc.). \n", - "\n", - "In our case the particular datatree object has different CMIP models and different experiments stored at distinct levels of the tree. This is useful because we can select just one experiment for one model, or all experiments for one model, or all experiments for all models!\n", - "\n", - "We can also apply xarray operations (e.g. taking the average using the `.mean()` method) over all the data in a tree at once, just by calling that same method on the `DataTree` object. We can even map custom functions over all nodes in the tree using [`dt.map_over_subtree(my_function)`](https://xarray-datatree.readthedocs.io/en/latest/generated/datatree.map_over_subtree.html#datatree-map-over-subtree).\n", - "\n", - "All the operations below can be accomplished without using datatrees, but it saves us many lines of code as we don't have to use `for` loops over all our the different datasets. For more information about datatree see the [documentation here](https://xarray-datatree.readthedocs.io/en/latest/index.html).\n", - "\n", - "Now, let's pull out relevant CESM2 datasets from the datatree; the *historical* simulation (human & natural forcing) and the *hist-nat* simulation (natural forcing only)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 9, - "status": "ok", - "timestamp": 1681701678408, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# the historical including anthropogenic forcing\n", - "hist_dt = dt[\"CESM2\"][\"historical\"]\n", - "hist_dt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 209, - "status": "ok", - "timestamp": 1681701679742, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# the historical run without anthropogenic forcing\n", - "hist_nat = dt[\"CESM2\"][\"hist-nat\"]\n", - "hist_nat" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Surface Energy Balance**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "Up until this point we have been analyzing budgets at the top of the atmosphere. Now we will move to Earth's surface, where we will run into both familiar and unfamiliar terminology. \n", - "\n", - "The first two terms we will analyze define the radiative component of the surface energy budget: shortwave and longwave radiation. For each of these terms, there is an upwelling and downwelling component. This is because, for example, some of the downwelling shortwave radiation is reflected back upwards due to the surface albedo. Similarly, some upwelling longwave radiation from Earth is absorbed by the atmosphere and re-emitted back towards the surface. The net radiative flux is given as \n", - "\n", - "\\begin{align}\n", - "R_{net} = [R_{\\uparrow S} - R_{\\downarrow S}] + [R_{\\uparrow L} - R_{\\downarrow L}]\n", - "\\end{align}\n", - "\n", - "where the arrows indicate up(down)welling and the $S$ and $L$ are shortwave and longwave. Note that in keeping with the rest of the variables we will look at, the net radiation is defined so that a positive value refers to an upward flux of energy from the ocean or land to the atmosphere. That is, positive indicates heat transport upwards and away from the surface.\n", - "\n", - "We will also be looking at latent and sensible heat. **[Sensible heat](https://glossary.ametsoc.org/wiki/Sensible_heat)** is the heat transferred due to a temperature difference between touching materials, for example between the air and the land or ocean surface. In this case, if the surface air is warmer than the land/ocean then heat is transferred from the air to the land/ocean (which is a downward or negative sensible heat flux), with an opposite-direction transfer if the air was colder than the land/ocean.\n", - "\n", - "**[Latent heat](https://glossary.ametsoc.org/wiki/Latent_heat)** is due to evaporation and condensation of water, as these phase changes absorb and release heat respectively. Here 'latent' means hidden, in that the energy is stored in molecules and there is no temperature change sensed through a thermometer even though a heat transfer takes place.\n", - "\n", - "While these are not the only terms that comprise the surface energy budget (i.e. geothermal heating, latent heat of fusion for melting ice or snow, biological processes) these are typically the dominant terms that set the global patterns.\n", - "\n", - "Let's take a look at the `long_name` of some variables we just downloaded.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 353, - "status": "ok", - "timestamp": 1681701687079, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "(\n", - " hist_dt.hfls.long_name,\n", - " hist_dt.hfss.long_name,\n", - " hist_dt.rlds.long_name,\n", - " hist_dt.rlus.long_name,\n", - " hist_dt.rsds.long_name,\n", - " hist_dt.rsus.long_name,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# predefine heat fluxes for each experiement, take annual means\n", - "\n", - "# model output variables (.squeeze() removes singleton dimensions)\n", - "hist_am_latent_heat_flux = hist_dt.ds.hfls.mean(dim=\"time\").squeeze()\n", - "hist_am_sensible_heat_flux = hist_dt.ds.hfss.mean(dim=\"time\").squeeze()\n", - "hist_am_downwelling_longwave_flux = hist_dt.ds.rlds.mean(dim=\"time\").squeeze()\n", - "hist_am_upwelling_longwave_flux = hist_dt.ds.rlus.mean(dim=\"time\").squeeze()\n", - "hist_am_downwelling_shortwave_flux = hist_dt.ds.rsds.mean(dim=\"time\").squeeze()\n", - "hist_am_upwelling_shortwave_flux = hist_dt.ds.rsus.mean(dim=\"time\").squeeze()\n", - "\n", - "# derived ariables\n", - "hist_am_net_shortwave_heat_flux = (\n", - " hist_am_upwelling_shortwave_flux - hist_am_downwelling_shortwave_flux\n", - ")\n", - "hist_am_net_longwave_heat_flux = (\n", - " hist_am_upwelling_longwave_flux - hist_am_downwelling_longwave_flux\n", - ")\n", - "hist_am_net_heat_flux = (\n", - " hist_am_net_shortwave_heat_flux\n", - " + hist_am_net_longwave_heat_flux\n", - " + hist_am_latent_heat_flux\n", - " + hist_am_sensible_heat_flux\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now we will plot the annual mean over the historical time period 1850-2015." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 99914, - "status": "ok", - "timestamp": 1681701792787, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "fig, ([ax_latent, ax_shortwave], [ax_sensible, ax_longwave]) = plt.subplots(\n", - " ncols=2, nrows=2, figsize=[12, 6], subplot_kw={\"projection\": ccrs.Robinson()}\n", - ")\n", - "\n", - "# plot surface latent heat flux the first month of the historical period\n", - "hist_am_latent_heat_flux.plot(\n", - " ax=ax_latent,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-300,\n", - " vmax=300,\n", - " cmap=\"coolwarm\",\n", - " robust=True,\n", - " cbar_kwargs={\"label\": \"$W/m^2$\"},\n", - ")\n", - "ax_latent.coastlines()\n", - "ax_latent.set_title(\"Latent Heat Flux\")\n", - "\n", - "# Repeat for sensible heat flux\n", - "hist_am_sensible_heat_flux.plot(\n", - " ax=ax_sensible,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-150,\n", - " vmax=150,\n", - " cmap=\"coolwarm\",\n", - " robust=True,\n", - " cbar_kwargs={\"label\": \"$W/m^2$\"},\n", - ")\n", - "ax_sensible.coastlines()\n", - "ax_sensible.set_title(\"Sensible Heat Flux\")\n", - "\n", - "# Repeat for net shortwave radiative heat flux\n", - "hist_am_net_shortwave_heat_flux.plot(\n", - " ax=ax_shortwave,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-300,\n", - " vmax=300,\n", - " cmap=\"coolwarm\",\n", - " robust=True,\n", - " cbar_kwargs={\"label\": \"$W/m^2$\"},\n", - ")\n", - "ax_shortwave.coastlines()\n", - "ax_shortwave.set_title(\"Net Upward Shortwave Flux\")\n", - "\n", - "# Repeat for net longwave radiative heat flux\n", - "hist_am_net_longwave_heat_flux.plot(\n", - " ax=ax_longwave,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-150,\n", - " vmax=150,\n", - " cmap=\"coolwarm\",\n", - " robust=True,\n", - " cbar_kwargs={\"label\": \"$W/m^2$\"},\n", - ")\n", - "ax_longwave.coastlines()\n", - "ax_longwave.set_title(\"Net Upward Longwave Flux\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 2: Climate Connection**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. What do you think causes the large spatial variations of the sensible heat flux between strong positive, weak, and strong negative fluxes? Consider different surface types in your answer." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial7_Solution_0b61029d.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: Surface Energy Budget by Latitude**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We can also calculate a *zonal average* which allows us to compare the contributions of each of these fluxes to the net heat flux by latitude (similar to the plot in the last lecture that considered the RCE model prediction as a function of latitude).\n", - "\n", - "To calculate a spatial average of a gridded data set, we often have to weight the data based on the size of the area it is describing. Fortunately, CESM data is on a regular latitude-longitude grid, which means that grid cells at a specific latitude have the same area as all the other grid cells at that latitude. This makes a zonal average easy, because at each latitude we can simply calculate the mean of all data at that latitude. \n", - "\n", - "*Note: Our averaging would have required area-weighting if we were calculating a global mean (as you did in previous Tutorials) or if you had irregularly gridded data (which we will encounter on W2D1)!*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# find the zonal means (.squeeze() removes singleton dimensions)\n", - "hist_azm_latent_heat_flux = hist_am_latent_heat_flux.mean(dim=\"x\").squeeze()\n", - "hist_azm_sensible_heat_flux = hist_am_sensible_heat_flux.mean(dim=\"x\").squeeze()\n", - "hist_azm_net_shortwave_flux = hist_am_net_shortwave_heat_flux.mean(dim=\"x\").squeeze()\n", - "hist_azm_net_longwave_flux = hist_am_net_longwave_heat_flux.mean(dim=\"x\").squeeze()\n", - "hist_azm_net_heat_flux = hist_am_net_heat_flux.mean(dim=\"x\").squeeze()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 34008, - "status": "ok", - "timestamp": 1681701864340, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "lat = hist_am_latent_heat_flux.lat[0, :]\n", - "\n", - "fig = plt.figure(figsize=(8, 5))\n", - "\n", - "plt.plot(lat, hist_azm_latent_heat_flux, label=\"Latent Heat\")\n", - "plt.plot(lat, hist_azm_sensible_heat_flux, label=\"Sensible Heat\")\n", - "plt.plot(lat, hist_azm_net_shortwave_flux, label=\"Shortwave\")\n", - "plt.plot(lat, hist_azm_net_longwave_flux, label=\"Longwave\")\n", - "plt.plot(lat, hist_azm_net_heat_flux, lw=3, color=\"k\", label=\"Net\")\n", - "plt.plot(lat, 0 * lat, color=\"black\")\n", - "\n", - "plt.title(\"Components of Annual Surface Energy Budget (+ up)\")\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 3: Climate Connection**" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "1. Describe the dominant balance in the tropics (30S to 30N).\n", - "2. What about for the polar regions (above 60N and below 60S).\n", - "3. What do you think causes the dip in latent heat near the equator?\n", - "4. Is there symmetry in the longwave radiation in the high southern and northern latitudes? What about for sensible heat?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial7_Solution_2686b960.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 167, - "status": "ok", - "timestamp": 1680721111796, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "source": [ - "# **Bonus Question: Climate Connection**\n", - "\n", - "5. Hypothetically, imagine this plot showed that the net heat flux was:\n", - " - Negative 100 $W m^{-2}$ between 45$^oN$ to 45$^oS$ (i.e., 90 degrees of latitude centered on the Equator) and,\n", - " - Positive 100 $W m^{-2}$ between 45$^oN$ to 90$^oN$ and between 45$^oS$ to 90$^oS$\n", - "\n", - " Would you expect Earth to warm, cool, or remain the same temperature? Why? \n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 908, - "status": "ok", - "timestamp": 1680721148129, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W1D5_ClimateModeling/solutions/W1D5_Tutorial7_Solution_f826474d.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you learned to identify and access specific CMIP6 datasets, which is vital for handling the vast datasets generated by climate models. You analyzed data from a CESM simulation, focusing on how shortwave/longwave radiation, sensible and latent heat, contribute to the surface energy budget. This tutorial also explored the *zonal-mean* surface energy budget, elucidating how different surface heat flux components vary with latitude due to physical differences in air-surface conditions across regions." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data from this tutorial can be accessed [here](https://storage.googleapis.com/cmip6/pangeo-cmip6.json)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W1D5_Tutorial7", - "provenance": [], - "toc_visible": true - }, - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title.md b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title.md deleted file mode 100644 index 4b8353258..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Future Climate - IPCC I Physical Basis - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading.md b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading.md deleted file mode 100644 index f515e7703..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading.md +++ /dev/null @@ -1,3 +0,0 @@ -# Suggested Further Reading - -If you would like further context about the goals, design, and scope of CMIP6, you should read Overview of the Coupled Model Intercomparison Project Phase 6 (CMIP6) experimental design and Organization, Eyring et al., 2016 (DOI:10.5194/gmd-9-1937-2016) \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1.ipynb deleted file mode 100644 index 738fd311e..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1.ipynb +++ /dev/null @@ -1,850 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "id": "d266ae7f", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial_1.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 1: Creating Maps of CMIP6 Earth System Model (ESM) Projections**\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, Agustina Pesce, 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" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "Earth System Models (ESMs) provide physically-based projections of how Earth's climate could change in the coming years, decades, and centuries at both global and local scales. In the following tutorial you will:\n", - "\n", - "- Revisit how to load ESM data from the CMIP6 experiments, and \n", - "- Create maps showing projected future changes in sea surface temperature (SST)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !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 cartopy nc-time-axis cf_xarray xarrayutils \"esmf<=8.3.1\" xesmf &> /dev/null\n", - "# # For xesmf install we need to pin \"esmf<=8.3.1\". More context here: https://github.com/pangeo-data/xESMF/issues/246" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2, - "status": "ok", - "timestamp": 1683928271799, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "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", - "import xesmf as xe\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\n", - "\n", - "import cartopy.crs as ccrs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Recap of Earth System Models\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Recap of Earth System Models\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Recap of Earth System Models\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "## **Section 1.1: Loading CMIP6 SST Data with `xarray`**\n", - "\n", - "As a reminder, these ESMs simulate several systems (ocean, atmosphere, cryosphere, land) that are coupled to each other, and each system has its own variables, physics, and discretizations (grid & timestep).\n", - "\n", - "“EarthSystemModel”\n", - "\n", - "Atmospheric Model Schematic (Credit: [Wikipedia](https://upload.wikimedia.org/wikipedia/commons/7/73/AtmosphericModelSchematic.png))\n", - "\n", - "Let's repeat the CMIP6 loading method that we learned in Tutorial 6 on last week's Climate Modelling day (Day 5).\n", - "\n", - " **Although we will only work with monthly SST (ocean) data today, the methods introduced can easily be applied/extended to load and analyze other CMIP6 variables, including from other components of the Earth system.**\n", - "\n", - "As a reminder, the *facets* that have to be specified for CMIP6, along with the facet choice(s) we make in this tutorial, are:\n", - "1. **variable_id**: *tos* = sea surface temperature\n", - "2. **source_id**: The CMIP6 model(s) that we want data from \n", - "3. **table_id**: *Omon* (ocean monthly output)\n", - "4. **grid_id**: *gn* = data on the model's *native* grid\n", - "5. **experiment_id**: *ssp585* (we'll discuss experiments later today)\n", - "6. **member_id**: *r1i1p1f1* for now\n", - "\n", - "Now, let's repeat our CMIP6 loading method from the previous tutorial.\n", - "\n", - "*Note: today we will start by using only use one model, **TaiESM1**, which stands for **Taiwan Earth System Model version 1**, and a single experiment, **ssp585** which is a high-emissions future scenario. In later tutorials you will work with 5 distinct CMIP6 models (**source_id**), and two additional experiments (**experiment_id**). **TaiESM1** was developed by modifying the Community Earth System Model (**CESM**) version 1.2.2 to include different parameterizations (i.e., physics). As a result, the **TaiESM1** model output is distinct from the **CESM** output you used in previous tutorials/days.*\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 6561, - "status": "ok", - "timestamp": 1683910891406, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# open an intake catalog containing the Pangeo CMIP cloud data\n", - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ")\n", - "\n", - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=\"TaiESM1\",\n", - " variable_id=\"tos\",\n", - " member_id=\"r1i1p1f1\",\n", - " table_id=\"Omon\",\n", - " grid_label=\"gn\",\n", - " experiment_id=\"ssp585\",\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)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We now have a \"datatree\" containing the data we searched for. A datatree is a high-level container of xarray data, useful for organizing many related datasets together. You can think of a single `DataTree` object as being like a (nested) dictionary of `xarray.Dataset` objects. Each dataset in the tree is known as a \"node\" or \"group\", and we can also have empty nodes. *This `DataTree` object may seem complicated when we load only one dataset, but it will prove to be very useful in later tutorials where you will work with multiple models, experiments, and ensemble members* \n", - "\n", - "You can explore the nodes of the tree and its contents interactively in a similar way to how you can explore the contents of an `xarray.Dataset`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1011, - "status": "ok", - "timestamp": 1683910899038, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "dt" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we have the model datasets organized within thie datatree (`dt`) we can plot the datasets. Let's start by plotting a map of SST from the `TaiESM1` CMIP6 model in July 2023. \n", - "\n", - "*Note that CMIP6 experiments were run several years ago, so the cut-off between **past** (observed forcing) and **future** (scenario-based/projected forcing) was at the start of 2015. This means that July 2023 is about 8 years into the CMIP6 **future** and so it is unlikely to look exactly like Earth's current SST state.*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 11488, - "status": "ok", - "timestamp": 1683910911990, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "\n", - "# select just a single model (TaiESM1) and experiment (ssp585) to plot\n", - "sst_ssp585 = dt[\"TaiESM1\"][\"ssp585\"].ds.tos\n", - "\n", - "fig, (ax_present) = plt.subplots(\n", - " ncols=1, nrows=1, figsize=[8, 4], subplot_kw={\"projection\": ccrs.Robinson()}\n", - ")\n", - "\n", - "# select the model data for July 2023\n", - "sst_present = sst_ssp585.sel(time=\"2023-07\").squeeze()\n", - "\n", - "# plot the model data\n", - "sst_present.plot(\n", - " ax=ax_present,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-10,\n", - " vmax=30,\n", - " cmap=\"magma\",\n", - " robust=True,\n", - ")\n", - "ax_present.coastlines()\n", - "ax_present.set_title(\"July 2023\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.1**\n", - "\n", - "Now that we can plot maps of CMIP6 data, let's look at some projected future changes using this data!\n", - "\n", - "In this coding exercise your goals are to: \n", - "1. Create a map of the projected sea surface temperature in July 2100 under the SSP5-8.5 high-emissions scenario (we'll discuss scenarios in the next mini-lecture) using data from the *TaiESM1* CMIP6 model.\n", - "2. Create a map showing how this sea surface temperature projection is different from the current (July 2023) sea surface temperature in this model\n", - "3. Plot a similar map for this model that shows how *January* 2100 is different from *January* 2023\n", - "\n", - "To get you started, we have provided code to load the required data set into a variable called *sst_ssp585*, and we have plotted the current (July 2023) sea surface temperature from this data set.\n", - "\n", - "*Note: differences between two snapshots of SST are not the same as the **anomalies** that you encountered earlier in the course, which were the difference relative to the average during a reference period.*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 163, - "status": "error", - "timestamp": 1683910918443, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# %matplotlib inline\n", - "\n", - "# select just a single model and experiment\n", - "sst_ssp585 = dt[\"TaiESM1\"][\"ssp585\"].ds.tos\n", - "\n", - "fig, ([ax_present, ax_future], [ax_diff_july, ax_diff_jan]) = plt.subplots(\n", - " ncols=2, nrows=2, figsize=[12, 6], subplot_kw={\"projection\": ccrs.Robinson()}\n", - ")\n", - "\n", - "# plot a timestep for 2023\n", - "sst_present = sst_ssp585.sel(time=\"2023-07\").squeeze()\n", - "sst_present.plot(\n", - " ax=ax_present,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-10,\n", - " vmax=30,\n", - " cmap=\"magma\",\n", - " robust=True,\n", - ")\n", - "ax_present.coastlines()\n", - "ax_present.set_title(\"July 2023\")\n", - "\n", - "# repeat for 2100\n", - "# complete the following line to extract data for July 2100\n", - "sst_future = ...\n", - "_ = ...\n", - "ax_future.coastlines()\n", - "ax_future.set_title(\"July 2100\")\n", - "\n", - "# now find the difference between July 2100 and July 2023\n", - "# complete the following line to extract the July difference\n", - "sst_difference_july = ...\n", - "_ = ...\n", - "ax_diff_july.coastlines()\n", - "ax_diff_july.set_title(\"2100 vs. 2023 Difference (July)\")\n", - "\n", - "# finally, find the difference between January of the two years used above\n", - "# complete the following line to extract the January difference\n", - "sst_difference_jan = ...\n", - "_ = ...\n", - "ax_diff_jan.coastlines()\n", - "ax_diff_jan.set_title(\"2100 vs. 2023 Difference (January)\")\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 36973, - "status": "ok", - "timestamp": 1683910956791, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_1_Solution_55810c8f.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "## **Questions 1.1: Climate Connection**\n", - "\n", - "1. *Comparing only the top two panels*, how is the July SST projected to change in this particular model simulation? Do these changes agree with the map of July change that you plotted in the bottom left, and are these changes easier to see in this bottom map?\n", - "2. In what ways are the July and January maps similar or dissimilar, and can you think of any physical explanations for these (dis)similarities?\n", - "3. Why do you think the color bar axes vary? (i.e., the top panels say \"*Sea Surface Temperature [$^oC$]*\" while the bottom panels say \"*tos*\")\n", - "\n", - "Many of the changes seen in the maps are a result of a changing climate under this high-emissions scenarios. However, keep in mind that these are differences between two months that are almost 80 years apart, so some of the changes are due to weather/synoptic differences between these particular months.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_1_Solution_edfd8cc7.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.2: Horizontal Regridding**\n", - "\n", - "Many CMIP6 models use distinct spatial grids, we call this the model's *native grid*. \n", - "\n", - "You are likely familiar with the *regular latitude-longitude* grid where we separate the planet into boxes that have a fixed latitude and longitude span like this image we saw in the tutorial:\n", - "\n", - "\"Lat_Lon_Grid\"\n", - "\n", - "Let's look at the grid used for the ocean component of the *TaiESM1* CMIP6 model:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1822, - "status": "ok", - "timestamp": 1683910973589, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# create a scatter plot with a symbol at the center of each ocean grid cell in TaiESM1\n", - "plt.scatter(x=sst_ssp585.lon, y=sst_ssp585.lat, s=0.1)\n", - "plt.ylabel(\"Latitude\")\n", - "plt.xlabel(\"Longitude\")\n", - "plt.title(\"Grid cell locations in TaiESM1\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 1.2**\n", - "\n", - "1. How would this plot look for a *regular latitude-longitude* grid like the globe image shown above and in the slides? In what ways is the TaiESM1 grid different from this regular grid?\n", - "2. Can you think of a reason the Northern and Southern hemisphere ocean grids differ?*\n", - "\n", - "**Hint: from an oceanographic context, how are the North and South poles different from each other?*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_1_Solution_319c2307.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "If you want to compare spatial maps from different models/observations, e.g. plot a map averaged over several models or the bias of this map relative to observations, you must first ensure the data from all the models (and observations) is on the same spatial grid. This is where regridding becomes essential!\n", - "\n", - "> Regridding is applied lazily, but it is still taking time to compute *when* it is applied. So if you want to compare for example the mean over time of several models it is often much quicker to compute the mean in time over the native grid and then regrid the result of that, instead of regridding each timestep and then calculating the mean!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 190, - "status": "ok", - "timestamp": 1683912424678, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# define a 'target' grid. This is simply a regular lon/lat grid that we will interpolate our data on\n", - "ds_target = xr.Dataset(\n", - " {\n", - " \"lat\": ([\"lat\"], np.arange(-90, 90, 1.0), {\"units\": \"degrees_north\"}),\n", - " \"lon\": ([\"lon\"], np.arange(0, 360, 1.0), {\"units\": \"degrees_east\"}),\n", - " }\n", - ") # you can try to modify the parameters above to e.g. just regrid onto a region or make the resolution coarser etc\n", - "ds_target" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 9588, - "status": "ok", - "timestamp": 1683912434512, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# define the regridder object (from our source dataarray to the target)\n", - "regridder = xe.Regridder(\n", - " sst_ssp585, ds_target, \"bilinear\", periodic=True\n", - ") # this takes some time to calculate a weight matrix for the regridding\n", - "regridder" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 3184, - "status": "ok", - "timestamp": 1683912437684, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# now we can apply the regridder to our data\n", - "sst_ssp585_regridded = regridder(sst_ssp585) # this is a lazy operation!\n", - "# so it does not slow us down significantly to apply it to the full data!\n", - "# we can work with this array just like before and the regridding will only be\n", - "# applied to the parts that we later load into memory or plot.\n", - "sst_ssp585_regridded" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 191, - "status": "ok", - "timestamp": 1683912440448, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# compare the shape to the original array\n", - "sst_ssp585" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.3: Visually Comparing Data with Different Map Projections**\n", - "\n", - "Let's use the code from above to plot a map of the model data on its original (*native*) grid, and a map of the model data after it is regridded." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 21337, - "status": "ok", - "timestamp": 1683912463177, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "fig, ([ax_regridded, ax_native]) = plt.subplots(\n", - " ncols=2, figsize=[12, 3], subplot_kw={\"projection\": ccrs.Robinson()}\n", - ")\n", - "\n", - "# Native grid data\n", - "sst_future = sst_ssp585.sel(time=\"2100-07\").squeeze()\n", - "sst_future.plot(\n", - " ax=ax_native,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-10,\n", - " vmax=30,\n", - " cmap=\"magma\",\n", - " robust=True,\n", - ")\n", - "ax_native.coastlines()\n", - "ax_native.set_title(\"July 2100 Native Grid\")\n", - "\n", - "# Regridded data\n", - "sst_future_regridded = sst_ssp585_regridded.sel(time=\"2100-07\").squeeze()\n", - "sst_future_regridded.plot(\n", - " ax=ax_regridded,\n", - " x=\"lon\",\n", - " y=\"lat\",\n", - " transform=ccrs.PlateCarree(),\n", - " vmin=-10,\n", - " vmax=30,\n", - " cmap=\"magma\",\n", - " robust=True,\n", - ")\n", - "ax_regridded.coastlines()\n", - "ax_regridded.set_title(\"July 2100 Regridded\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 1.3**\n", - "\n", - "1. Is this what you expected to see after regridding the data?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_1_Solution_f9a48a4e.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In Tutorial 1 you have: \n", - "\n", - "* Loaded and manipulated data from a CMIP6 model under a high-emissions future scenario experiment\n", - "* Created maps of future projected changes in the Earth system using CMIP6 data\n", - "* Converted/regridded CMIP6 model data onto a desired grid. This is a critical processing step that allows us to directly compare data from different models and/or observations \n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data for this tutorial can be accessed [here](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial_1", - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2.ipynb deleted file mode 100644 index e1fa670d2..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2.ipynb +++ /dev/null @@ -1,551 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "id": "914d3f25", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial_2.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 2: Time Series, Global Averages, and Scenario Comparison**\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" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "In this tutorial, we will expand to look at data from **three** CMIP6/ScenarioMIP experiments (*historical*, *SSP1-2.6* and *SSP5-8.5*). Our aim will be to calculate the global mean SST for these 3 experiments, taking into account the spatially-varying size of the model's grid cells (i.e., calculating a *weighted* mean).\n", - "\n", - "By the end of this tutorial, you'll be able to:\n", - "\n", - "- Load and analyze CMIP6 SST data from different experiments.\n", - "- Understand the difference between historical and future emission scenarios.\n", - "- Calculate the global mean SST from gridded model data.\n", - "- Apply the concept of weighted mean to account for varying grid cell sizes in Earth System Models." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n", - "\n", - " \n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 90386, - "status": "ok", - "timestamp": 1683927956198, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !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 xmip 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": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 2: Future Climate Scenarios\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 2: Future Climate Scenarios\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 2: Future Climate Scenarios\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Load CMIP6 SST Data from Several Experiments Using `xarray`**\n", - "\n", - "In the last tutorial we loaded data from the *SSP5-8.5* (high-emissions projection) experiment of one CMIP6 model called *TaiESM1*. \n", - "\n", - "Let's expand on this by using data from **three** experiments \n", - "* *historical*: a simulation of 1850-2015 using observed forcing, \n", - "* *SSP1-2.6*: a future, low-emissions scenario, and \n", - "* *SSP5-8.5*: a future, high-emissions scenario.\n", - "\n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 12915, - "status": "ok", - "timestamp": 1683927997892, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# open an intake catalog containing the Pangeo CMIP cloud data\n", - "col = intake.open_esm_datastore(\n", - " \"https://storage.googleapis.com/cmip6/pangeo-cmip6.json\"\n", - ")\n", - "\n", - "# pick the experiments you require\n", - "experiment_ids = [\"historical\", \"ssp126\", \"ssp585\"]\n", - "\n", - "# from the full `col` object, create a subset using facet search\n", - "cat = col.search(\n", - " source_id=\"TaiESM1\",\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)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Coding Exercise 1.1**\n", - "\n", - "In this tutorial and the following tutorials we will be looking at the global mean sea surface temperature. To calculate this global mean, we need to know the horizontal area of every ocean grid cell in all the models we are using. \n", - "\n", - "Write code to load this ocean-grid area data using the previously shown method for SST data, noting that:\n", - "* We now need a variable called *areacello* (area of cells in the ocean) \n", - "* This variable is stored in table_id *Ofx* (it is from the ocean model and is fixed/constant in time) \n", - "* A model's grid does not change between experiments so you only need to get grid data from the *historical* experiment for each model\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 313, - "status": "error", - "timestamp": 1683928000559, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "cat_area = col.search(\n", - " source_id=\"TaiESM1\",\n", - " # Add the appropriate variable_id\n", - " variable_id=\"areacello\",\n", - " member_id=\"r1i1p1f1\",\n", - " # Add the appropriate table_id\n", - " table_id=\"Ofx\",\n", - " grid_label=\"gn\",\n", - " # Add the appropriate experiment_id\n", - " experiment_id=[\"historical\"],\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", - "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)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 4330, - "status": "ok", - "timestamp": 1683928007010, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_2_Solution_c1386992.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Global Mean Sea Surface Temperature (GMSST)**\n", - "\n", - "The data files above contain spatial maps of the sea surface temperature for every month of each experiment's time period. For the rest of today's tutorials, we're going to focus on the global mean sea surface temperature, rather than maps, as a way to visualize the ocean's changing temperature at a global scale$^*$.\n", - "\n", - "The global mean of a property can be calculated by integrating that variable over the surface area of Earth covered by the system (ocean, atmosphere etc.) and dividing by the total surface area of that system. For Sea Surface Temperature, $SST(x,y)$, the global mean ($GMSST$) can be written as an integral over the surface of the ocean ($S_{ocean}$):\n", - "\n", - "\\begin{equation}\n", - "GMSST = \\frac{\\iint_{S_{ocean}}SST(x,y) dxdy}{\\iint_{S_{ocean}} dxdy}\n", - "\\end{equation}\n", - "\n", - "where $x$ and $y$ are horizontal coordinates (i.e. longitude and latitude). This formulation works if $SST(x,y)$ is a [spatially-continuous function](https://en.wikipedia.org/wiki/Continuous_or_discrete_variable), but in a global model we only know the SST of *discrete* grid cells rather than a *continuous* SST field. Integrals are only defined for continuous variables, we must instead use a summation over the grid cells (summation is the discrete equivalent of integration):\n", - "\n", - "\\begin{equation}\n", - "GMSST = \\frac{ \\sum_{i,j} SST(i,j) A(i,j)}{\\sum_{i,j} A(i,j)}\n", - "\\end{equation}\n", - "\n", - "where $(i,j)$ represent the indices of the 2D spatial SST data from a CMIP6 model, and $A$ denotes the area of each ocean grid cell, which can vary between cells/locations, as you saw in the last tutorial where *TaiESM1* had irregularly-gridded output. This calculation is essentially a *weighted mean* of the SST across the model cells, where the weighting accounts for the varying area of cells - that is, larger cells should contribute more the global mean than smaller cells.\n", - "\n", - "$^*$*Note: we could alternatively look at ocean heat content, which depends on temperature at all depths, but it is a more intensive computation that would take too long to calculate in these tutorials.*" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 2.1**\n", - "\n", - "Complete the following code so that it calculates and plots a timeseries of global mean sea surface temperature from the *TaiESM1* model for both the *historical* experiment and the two future projection experiments, *SSP1-2.6* (low emissions) and *SSP5-8.5* (high emissions). \n", - "\n", - "As you complete this exercise this, consider the following questions:\n", - "* In the first function, what `xarray` operation is the following line doing, and why is it neccessary?\n", - "```\n", - "return ds.weighted(ds.areacello.fillna(0)).mean(['x', 'y'], keep_attrs=True)\n", - "```\n", - "* How would your time series plot might change if you instead used took a simple mean of all the sea surface temperatures across all grid cells? (Perhaps your previous maps could provide some help here) \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 296, - "status": "error", - "timestamp": 1683928013844, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "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", - "# average every dataset in the tree globally\n", - "dt_gm = ...\n", - "\n", - "for experiment in [\"historical\", \"ssp126\", \"ssp585\"]:\n", - " da = ...\n", - " _ = ...\n", - "plt.title(\"Global Mean SST from TaiESM1\")\n", - "plt.ylabel(\"Global Mean SST [$^\\circ$C]\")\n", - "plt.xlabel(\"Year\")\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 31727, - "status": "ok", - "timestamp": 1683928048744, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_2_Solution_58e712bd.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Question 1.1: Climate Connection**\n", - "\n", - "1. Is this plot what you expected? If so, explain what you expected, and why, from the historical experiment, and the SSP1-2.6 and SSP5-8.5 scenarios (see below for a potentially useful figure).\n", - "\n", - "For context, here is [Figure TS.4](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_TS_Figure_4.png) from the Technical Summary of the [IPCC Sixth Assessment Report](https://www.ipcc.ch/assessment-report/ar6/), which shows how several elements of forcing differ between experiments (including *historical* and *SSP* experiments). In the video above we saw the $CO_2$ panel of this figure:\n", - "\n", - "\"Experiment_Forcing\"\n", - "\n", - "Figure TS.4 | The climate change cause–effect chain: The intent of this figure is to illustrate the process chain starting from anthropogenic emissions, to changes in atmospheric concentration, to changes in Earth’s energy balance (‘forcing’), to changes in global climate and ultimately regional climate and climatic impact-drivers. Shown is the core set of five Shared Socio-economic Pathway (SSP) scenarios as well as emissions and concentration ranges for the previous Representative Concentration Pathway (RCP) scenarios in year 2100; carbon dioxide (CO2) emissions (GtCO2yr–1), panel top left; methane (CH4) emissions (middle) and sulphur dioxide (SO2), nitrogen oxide (NOx) emissions (all in Mt yr–1), top right; concentrations of atmospheric CO2(ppm) and CH4 (ppb), second row left and right; effective radiative forcing for both anthropogenic and natural forcings (W m–2), third row; changes in global surface air temperature (°C) relative to 1850–1900, fourth row; maps of projected temperature change (°C) (left) and changes in annual-mean precipitation (%) (right) at a global warming level (GWL) of 2°C relative to 1850–1900 (see also Figure TS.5), bottom row. Carbon cycle and non-CO2 biogeochemical feedbacks will also influence the ultimate response to anthropogenic emissions (arrows on the left). {1.6.1, Cross-Chapter Box 1.4, 4.2.2, 4.3.1, 4.6.1, 4.6.2}\n", - "\n", - "Credit: [IPCC](https://www.ipcc.ch/report/ar6/wg1/downloads/figures/IPCC_AR6_WGI_TS_Figure_4.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_2_Solution_b0a7a57f.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In tutorial 2, you diagnosed changes at a global scale by calculating global mean timeseries with CMIP6 model mapped data. You then synthesized and compared global mean SST evolution in various CMIP6 experiments, spanning Earth's recent past and several future scenarios. \n", - "\n", - "We started by loading CMIP6 SST data from three different scenarios: *historical*, *SSP1-2.6* (low-emissions future), and *SSP5-8.5* (high-emissions future). This process expanded our understanding of model outputs. We then focused on calculating global mean SST, by taking into account the spatially-discrete and irregularly-gridded nature of this model's grid cells through a weighted mean. This weighted mean approach yielded the global mean SST, providing a holistic view of the Earth's changing sea surface temperatures under multiple future climate scenarios.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data for this tutorial can be accessed [here](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial_2", - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3.ipynb deleted file mode 100644 index e191e41f3..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3.ipynb +++ /dev/null @@ -1,676 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial_3.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 3: Multi-model Ensembles**\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" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "In this tutorial, we will analyze datafrom five different CMIP6 models developed by various institutions around the world, focusing on their *historical* simulations and low-emission projections (*SSP1-2.6*). By the end of this tutorial, you will be able to \n", - "- Load CMIP6 Sea Surface Temperature (SST) data from multiple models;\n", - "- Calculate the SST anomalies, and recall the concept of temperature anomaly in relation to a base period" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n", - "\n", - " \n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 100078, - "status": "ok", - "timestamp": 1683926800928, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !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": {}, - "executionInfo": { - "elapsed": 4018, - "status": "ok", - "timestamp": 1683926879380, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "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": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "# model_colors = {k:f\"C{ki}\" for ki, k in enumerate(source_ids)}\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Helper functions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Helper functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "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)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 3: Why so many Earth System Models?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 3: Why so many Earth System Models?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 3: Why so many Earth System Models?\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Load CMIP6 SST Data from Five Models and Three Experiments**\n", - "In the previous section, you compared how a single CMIP6 model (*TaiESM1*) simulated past temperature, and how it projected temperature would change under a low-emissions scenario and a high-emissions scenario (*historical*, *SSP1-2.6* and *SSP5-8.5* experiments respectively). \n", - "\n", - "Now we will start to analyze a **multi-model ensemble** that consists of data from multiple CMIP6 models. For now, we will focus on just the historical simulation and the low-emissions projection.\n", - "\n", - "Your multi-model ensemble will consist of:\n", - "\n", - "* **Five** different CMIP6 models developed by institutions from a variety of countries: \n", - " * *TaiESM1* (Research Center for Environmental Changes, Taiwan),\n", - " * *IPSL-CM6A-LR* (Institut Pierre Simon Laplace, France),\n", - " * *GFDL-ESM4* (NOAA Geophysical Fluid Dynamics Laboratory, USA), \n", - " * *ACCESS-CM2* (CSIRO and ARCCSS, Australia), and \n", - " * *MPI-ESM1-2-LR* (Max Planck Institute, Germany). \n", - "\n", - "Note that these are only a subset of the dozens of models, institutes, countries, and experiments that contribute to CMIP6, as discussed in the previous W2D1 Tutorial 2 video. Some of the abbreviations in the model names refer to institutes (*MPI/GFDL*), while some refer to the complexity and version of the model (e.g., Earth System or Climate Model [*ESM/CM*] and low- or high-resolution [*LR/HR*]). There are often several models from a single institute with each having a distinct level of complexity." - ] - }, - { - "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 models and three experiments\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": 11206, - "status": "ok", - "timestamp": 1683162582065, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "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)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4341, - "status": "ok", - "timestamp": 1683162592002, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "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)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's first reproduce the previous tutorial's timeseries of Global Mean SST from *TaiESM1* through the historical experiment and two future emissions scenarios" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 23501, - "status": "ok", - "timestamp": 1683162622054, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# average every dataset in the tree globally\n", - "dt_gm = dt_with_area.map_over_subtree(global_mean)\n", - "\n", - "for experiment in [\"historical\", \"ssp126\", \"ssp585\"]:\n", - " da = dt_gm[\"TaiESM1\"][experiment].ds.tos\n", - " da.plot(label=experiment)\n", - "plt.title(\"Global Mean SST from TaiESM1\")\n", - "plt.ylabel(\"Global Mean SST [$^\\circ$C]\")\n", - "plt.xlabel(\"Year\")\n", - "plt.legend()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.1: Combine Past Data and Future Data, and Remove Seasonal Oscillations, and plot all 5 of the CMIP6 models we just loaded**\n", - "\n", - "* The historical and projected data are separate time series. Complete the `xr.concat` function to combine the historical and projected data into a single continuous time series for each model.\n", - "* The previous timeseries oscillated very rapidly due to Earth's seasonal cycles. Finish the `xarray` `resample` function so that it smooths the monthly data with a one-year running mean. This will make it easier to distinguish the long-term changes in sea surface temperature.\n", - "* Note: this code is already set up to use all 5 of the CMIP6 models you just loaded, as it loops through and plots each model in the DataTree [`dt.keys()`]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 169, - "status": "error", - "timestamp": 1682723761601, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "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].tos)\n", - "\n", - " # for each of the models, concatenate its historical and future data\n", - " da_combined = ...\n", - " # plot annual averages\n", - " ...\n", - "\n", - "\n", - "_ = ...\n", - "\n", - "plt.title(\"Global Mean SST from five CMIP6 models (annually smoothed)\")\n", - "plt.ylabel(\"Global Mean SST [$^\\circ$C]\")\n", - "plt.xlabel(\"Year\")\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 81780, - "status": "ok", - "timestamp": 1683162775542, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_3_Solution_a8a2e784.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Question 1.1**\n", - "\n", - "1. Why do you think the global mean temperature varies so much between models?* \n", - "\n", - "**If you get stuck here, reflect on the videos from earlier today and the tutorials/videos from the Climate Modelling day for inspiration.*" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_3_Solution_23243afa.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.2**\n", - "\n", - "As you just saw, the global mean SST varies between climate models. This is not surprising given the slight differences in physics, numerics, and discretization between each model.\n", - "\n", - "When we are looking at future projections, we care about how the model's *change* relative to their equilibrium/previous state. To do this, we typically subtract a historical reference period from the timeseries, which creates a new timeseries which we call the temperature *anomaly* relative to that period. **Recall that you already calculated and used *anomalies* earlier in the course (e.g., on W1D1).**\n", - "\n", - "**Modify the following code to recreate the previous multi-model figure, but now instead plot the global mean sea surface temperature (GMSST) *anomaly* relative the 1950-1980 base period (i.e., subtract the 1950-1980 mean GMSST of each model from that model's timeseries)**\n", - "\n", - "*Hint: you will need to use `ds.sel` to select data during the base period ([see here](https://docs.xarray.dev/en/stable/user-guide/indexing.html#indexing-with-dimension-names) under \"Indexing with dimension names\" for a helpful example) along with the averaging operator, `mean()`.*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 130, - "status": "error", - "timestamp": 1682723868376, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - } - }, - "outputs": [], - "source": [ - "# calculate anomaly to reference period\n", - "def datatree_anomaly(dt):\n", - " dt_out = DataTree()\n", - " for model, subtree in dt.items():\n", - " # find the temporal average over the desired reference period\n", - " ref = ...\n", - " dt_out[model] = ...\n", - " return dt_out\n", - "\n", - "\n", - "dt_gm_anomaly = datatree_anomaly(dt_gm)\n", - "\n", - "_ = ...\n", - "\n", - "plt.title(\"Global Mean SST Anomaly from five CMIP6 models (base period: 1950 to 1980)\")\n", - "plt.ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "plt.xlabel(\"Year\")\n", - "plt.legend()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 72588, - "status": "ok", - "timestamp": 1683163084117, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_3_Solution_cccfcaec.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 1.2: Climate Connection**\n", - "\n", - "1. How does this figure compare to the previous one where the reference period was not subtracted?\n", - "2. This figure uses the reference period of 1950-1980 for its anomaly calculation. How does the variability across models 100 years before the base period (1850) compare to the variability 100 years after the base period (2080)? Why do you think this is?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_3_Solution_a59e8ac4.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "\n", - "In this tutorial, we expanded on the previous examination of a single CMIP6 model (*TaiESM1*), to instead work with multi-model ensemble comprising five different CMIP6 models (*TaiESM1*, *IPSL-CM6A-LR*, *GFDL-ESM4*, *ACCESS-CM2*, and *MPI-ESM1-2-LR*) developed by institutions around the world. We demonstrated the importance of anomalizing each of these models relative to a base period when calculating changes in the simulated Earth system. If variables are not anomalized, these absolute values can differ significantly between models due to the diversity of models (i.e., their distinct physics, numerics and discretization)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data for this tutorial can be accessed [here](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial_3", - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4.ipynb deleted file mode 100644 index a7842e60c..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4.ipynb +++ /dev/null @@ -1,604 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial_4.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 4: Quantifying Uncertainty in Projections**\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" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In the previous tutorial, we constructed a *multi-model ensemble* using data from a diverse set of five CMIP6 models. We showed that the projections differ between models due to their distinct physics, numerics and discretizations. In this tutorial, we will calculate the uncertainty associated with future climate projections by utilizing this variability across CMIP6 models. We will establish a *likely* range of projections as defined by the IPCC. \n", - "\n", - "By the end of this tutorial, you will be able to \n", - "- apply IPCC confidence levels to climate model data\n", - "- quantify the uncertainty associated with CMIP6/ScenarioMIP projections.\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n", - "\n", - " \n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 21927, - "status": "ok", - "timestamp": 1683930403085, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "colab" - ] - }, - "outputs": [], - "source": [ - "# !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": {}, - "executionInfo": { - "elapsed": 3609, - "status": "ok", - "timestamp": 1683930517522, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "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": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 738, - "status": "ok", - "timestamp": 1683930525181, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "# %matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Helper functions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Helper functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 2, - "status": "ok", - "timestamp": 1683930525501, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "hide-input" - ] - }, - "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": "markdown", - "metadata": {}, - "source": [ - "## Video 4: Quantifying Uncertainty in Projections\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 4: Quantifying Uncertainty in Projections\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 443, - "status": "ok", - "timestamp": 1683930528231, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 4: Quantifying Uncertainty in Projections\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Loading CMIP6 Data from Various Models & Experiments**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "First, lets load the datasets that we used in the previous tutorial, which spanned 5 models. We will use three CMIP6 experiments, adding the high-emissions (*SSP5-8.5*) future scenario to the *historical* and *SSP1-2.6* experiments used in the last tutorial.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5674, - "status": "ok", - "timestamp": 1683930535902, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "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 models and three experiments\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": 50598, - "status": "ok", - "timestamp": 1683930589572, - "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", - "for experiment in [\"historical\", \"ssp126\", \"ssp585\"]:\n", - " da = dt_gm[\"TaiESM1\"][experiment].ds.tos\n", - "# da.plot(label=experiment)\n", - "# plt.title('Global Mean SST from TaiESM1')\n", - "# plt.ylabel('Global Mean SST [$^\\circ$C]')\n", - "# plt.xlabel('Year')\n", - "# plt.legend()\n", - "\n", - "# plot_historical_ssp126_combined(dt_gm)\n", - "\n", - "dt_gm_anomaly = datatree_anomaly(dt_gm)\n", - "\n", - "# plot_historical_ssp126_combined(dt_gm_anomaly)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Quantifying Uncertainty in a CMIP6 Multi-model Ensemble**\n", - "\n", - "Let's create a multi-model ensemble containing data from multiple CMIP6 models, which we can use to quantify our confidence in future projected sea surface temperature change under low- and high-emissions scenarios. \n", - "\n", - "**Your goal in this tutorial is to create a *likely* range of future projected conditions. The IPCC uncertainty language defines the *likely* range as the middle 66% of model results (ignoring the upper 17% and lower 17% of results)**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 2.1**\n", - "\n", - "Complete the following code to display multi-model ensemble data with IPCC uncertainty bands:\n", - "\n", - "\n", - "1. The multi-model mean temperature\n", - "2. Shading to display the *likely* range of temperatures for the CMIP6 historical and projected data (include both *SSP1-2.6* and *SSP5-8.5*). *da_upper* and *da_lower* are the boundaries of this shaded region\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 4, - "status": "error", - "timestamp": 1683930589572, - "user": { - "displayName": "Brodie Pearson", - "userId": "05269028596972519847" - }, - "user_tz": 420 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "\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", - " )\n", - " datasets.append(\n", - " annual_sst.sel(time=slice(None, \"2100\")).load()\n", - " ) # the french model has a long running member for ssp126\n", - " da = xr.concat(datasets, dim=\"source_id\", join=\"override\").squeeze()\n", - " x = da.time.data\n", - " # Calculate the lower bound of the likely range\n", - " da_lower = ...\n", - " # Calculate the upper bound of the likely range\n", - " da_upper = ...\n", - " # plt.fill_between(range(x), da_lower, da_upper, alpha=0.5, color=color)\n", - " # Calculate the multi-model mean at each time within each experiment\n", - " _ = ...\n", - "plt.title(\n", - " \"Global Mean SST Anomaly from five-member CMIP6 ensemble (base period: 1950 to 1980)\"\n", - ")\n", - "plt.ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "plt.xlabel(\"Year\")\n", - "plt.legend()\n", - "\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_4_Solution_5a678182.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.1: Climate Connection**\n", - "\n", - "1. What does this figure tell you about how the multi-model uncertainty compares to projected physical changes in the global mean SST? \n", - "2. Is this the same for both scenarios?\n", - "3. For a 5-model ensemble like this, how do the *likely* ranges specifically relate to the 5 individual model temperatures at a given time?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_4_Solution_0effd963.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, we have quantified the uncertainty of future climate projections by analyzing variability across a multi-model CMIP6 ensemble. We learned to apply the IPCC's confidence levels to establish a *likely* range of projections, which refers to the middle 66% of model results. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data for this tutorial can be accessed [here](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial_4", - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5.ipynb deleted file mode 100644 index d9ed68d73..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5.ipynb +++ /dev/null @@ -1,570 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial_5.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "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\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\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", - "- 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)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**\n", - "\n", - " \n", - "\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": [ - "# !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": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "# model_colors = {k:f\"C{ki}\" for ki, k in enumerate(source_ids)}\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Helper functions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Helper functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "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": "markdown", - "metadata": {}, - "source": [ - "## Video 5: Internal Climate Variability\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 5: Internal Climate Variability\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 5: Internal Climate Variability\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "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 center carried out multiple simulations of the model for many of the CMIP6 experiments.\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." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.1**\n", - "\n", - "Complete the following code to:\n", - "\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", - " 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", - " 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", - "# 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):\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\")\n", - "\n", - "\n", - "plt.figure()\n", - "_ = ...\n", - "\n", - "plt.title(\"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\")\n", - "plt.ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "plt.xlabel(\"Year\")\n", - "plt.legend()" - ] - }, - { - "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/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_5_Solution_ffdc4568.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 1.2**\n", - "\n", - "Complete the following code to:\n", - "\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." - ] - }, - { - "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": [ - "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", - "\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", - " _ = ...\n", - "\n", - " # calculate the mean across ensemble members and plot\n", - " _ = ...\n", - "plt.title(\"Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble\")\n", - "plt.ylabel(\"Global Mean SST Anomaly [$^\\circ$C]\")\n", - "plt.xlabel(\"Year\")\n", - "plt.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/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_5_Solution_3c1a09b1.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "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](./img/W2D1_Tutorial_5_Insert_Figure.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_5_Solution_6d329709.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\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." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data for this tutorial can be accessed [here](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial_5", - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6.ipynb deleted file mode 100644 index b36008e13..000000000 --- a/book/_build/html/_sources/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6.ipynb +++ /dev/null @@ -1,563 +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/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/W2D1_Tutorial_6.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "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" - ] - }, - { - "attachments": {}, - "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." - ] - }, - { - "attachments": {}, - "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": [ - "# !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": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Figure settings\n", - "import ipywidgets as widgets # interactive display\n", - "\n", - "%config InlineBackend.figure_format = 'retina'\n", - "plt.style.use(\n", - " \"https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle\"\n", - ")\n", - "# model_colors = {k:f\"C{ki}\" for ki, k in enumerate(source_ids)}\n", - "%matplotlib inline" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Helper functions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Helper functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "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": "markdown", - "metadata": {}, - "source": [ - "## Video 6: Historical Context for Future Projections\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 6: Historical Context for Future Projections\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 6: Historical Context for Future Projections\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "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" - ] - }, - { - "attachments": {}, - "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)" - ] - }, - { - "attachments": {}, - "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": [ - "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", - " 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", - " plt.fill_between(range(len(x)), da_lower, da_upper, alpha=0.5, color=color)\n", - " da.mean(\"source_id\").plot(\n", - " color=color,\n", - " label=experiment,\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 = ...\n", - "# calculate anomaly for observations\n", - "sst_obs_gm_anomaly = ...\n", - "\n", - "# coarsen, trim and calculate mean then plot observations\n", - "_ = ...\n", - "plt.ylabel(\"Global Mean SST with respect to 1950-1980\")\n", - "plt.xlabel(\"Year\")\n", - "plt.legend()\n", - "\n", - "plt.show()" - ] - }, - { - "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/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_6_Solution_df5c4f05.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "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", - "![](./img/W2D1_Tutorial_6_Insert_Figure.png)\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/NeuromatchAcademy/course-content/tree/main/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/solutions/W2D1_Tutorial_6_Solution_7818edff.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "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." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data for this tutorial can be accessed [here](https://gallery.pangeo.io/repos/pangeo-gallery/cmip6/index.html)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "machine_shape": "hm", - "name": "W2D1_Tutorial_6", - "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.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/chapter_title.md b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/chapter_title.md deleted file mode 100644 index cc8934617..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Good Research Practices - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/further_reading.md b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/further_reading.md deleted file mode 100644 index a1095fc4f..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/further_reading.md +++ /dev/null @@ -1,3 +0,0 @@ -# Suggested Further Reading - -We have included a number of suggested readings throughout the tutorial. Please check them out if you are interested! \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.ipynb deleted file mode 100644 index d2f093e9b..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.ipynb +++ /dev/null @@ -1,234 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "6eb0ed17", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 1: Finding a Phenomenon and Asking a Question About It** \n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?\n", - "\n", - "# **Demos**\n", - "\n", - "In order to illustrate the process, we will use a sample research question about how the surface temperature of the earth depends on the CO$_2$ content of the atmosphere." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "###### Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "####### Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######## Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######### Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########## Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########### Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "############ Video 1: Identifying a Question\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Identifying a Question\n", - "#Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Activity: Asking Your Own Question**\n", - "\n", - "Write down a phenomenon you would like to gain understanding about. Take 5 minutes to construct a question about the phenomenon. Discuss amongst your group to improve the question. For some inspiration:\n", - "\n", - "* Are there other aspects of the planet that may influence the average surface temperature?\n", - "* Are there other features of the planet that may be impacted by changes in the average surface temperature?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Make Sure to Avoid the Pitfalls!**\n", - "
\n", - "Click here for a recap on pitfalls\n", - "\n", - "Question is too broad\n", - "
    \n", - "
  • Science advances one small step at a time. Narrowing the scope will help clarify your next steps
  • \n", - "
\n", - "\n", - "Question does not identify a precise aspect of the phenomenon\n", - "
    \n", - "
  • Clarity will help identify next steps in your research
  • \n", - "
  • If you are struggling to identify a precise aspect, you might need to learn more about the phenomenon. Look to the literature (Step 2)!
  • \n", - "
\n", - "\n", - "Question is about an analysis method\n", - "
    \n", - "
  • An analysis method is a tool, not the big picture
  • \n", - "
\n", - "\n", - "
" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial1", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial2.ipynb deleted file mode 100644 index f115ecade..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial2.ipynb +++ /dev/null @@ -1,266 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "1244544e", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial2.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 2: Doing a Literature Review** \n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "###### Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "####### Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######## Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######### Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########## Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########### Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "############ Video 2: Doing a Literature Review\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 2: Doing a Literature Review\n", - "#Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Activity: Understanding the Literature Review Process**\n", - "\n", - "While a comprehensive literature review typically requires an extensive timeframe spanning months or even years, in the context of your Project Template, we will conduct a condensed literature review within two days. Instead of tasking you with reviewing the literature on our sample research topic, we will provide additional guidance on the process of conducting a literature review.\n", - "\n", - "During this timeframe, you will be introduced to the fundamental aspects and techniques of performing a literature review, enabling you to gain insights into the necessary steps and best practices. Although the review will be concise, it will equip you with the essential skills to navigate the literature effectively and lay the foundation for future in-depth literature reviews.\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Equity in Literature Review**\n", - "
\n", - "Click here for some points to consider when doing your literature review\n", - "\n", - "The choices we make as a collective have an impact on who is included and who is excluded in the scientific process. While there is no perfect solution to addressing inequity in the sciences, we can contribute by engaging in an ongoing conversation and being receptive to feedback regarding our impact. Here are some points to consider:\n", - "\n", - "* Which papers are you selecting for your review? Which papers are you citing? Are there overlooked studies with valuable results?\n", - "* Does your work relate to a phenomenon that affects a specific community? Have members of that community made observations or documented the phenomenon?\n", - "* Has your own experience informed you of equity concerns in the knowledge base that you are in a good position to address?\n", - "\n", - "Remember, perfection is not the goal. Every choice we make carries unintended consequences. By keeping equity in mind, we can remain open to constructive feedback and identify areas where we can make a positive impact. \n", - "\n", - "Here are some resources that may help you incorporate knowledge and understanding from underrepresented groups:\n", - "* [Global South Climate Database](https://www.carbonbrief.org/global-south-climate-database/) is made by scientists from the Global South, who make up only 10% of citations in Climate Science\n", - "* [Local Environmental Observer (LEO) network](https://www.leonetwork.org) contains observations of many weather events from Indigenous groups\n", - "* [Alaska Native Knowledge Network](https://uaf.edu/ankn/) is dedicated to Alaskan Native Knowledge\n", - "* [HSHK Knowledge Well](https://cdm16093.contentdm.oclc.org/digital/collection/p16093coll9) contains Native Hawaiian knowledge of local weather events\n", - "\n", - "Here is some reading relating to Arrhenius and his racism: \n", - "\n", - "College Chemistry Textbooks Aid and Abet Racial Disparity. Mona L. Becker and Melanie R. Nilsson. Journal of Chemical Education 2022 99 (5), 1847-1854. DOI: https://doi.org/10.1021/acs.jchemed.1c00968" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Tips for Efficiency**\n", - "
\n", - "Click here for some pointers on reviewing literature efficiently\n", - "\n", - "There are many different strategies for reviewing literature efficiently. **[Here](https://www.science.org/content/article/how-seriously-read-scientific-paper)** are some descriptions of the processes that different researchers use. If you are new to a topic, we recommend you start by looking for a review paper, which will summarize the results of multiple studies and direct you to other papers worth reading.\n", - "\n", - "Here is one option for reading papers efficiently:\n", - "\n", - "* Start by reviewing the abstract and conclusions sections. This will help you determine the relevance of the paper's results to your research.\n", - "* Conduct a \"quick pass\" of the paper\n", - "
    \n", - "
  • Scan through the figures and diagrams.
  • \n", - "
  • Identify the references to these figures in the text and read the surrounding discussion.
  • \n", - "
  • Take note of any parts of the figures or discussion that you find difficult to understand.
  • \n", - "
\n", - "* Seek additional information to address the areas that you found challenging:\n", - "
    \n", - "
  • Refer to previous sections of the paper that describe the methods and analysis.
  • \n", - "
  • Explore other papers that cite or are cited by the paper you are reading.
  • \n", - "
  • Consult relevant textbooks or resources on the subject.
  • \n", - "
  • Seek guidance from professors or peers in your field.
  • \n", - "
\n", - "* If the paper seems extremely important, or if you are tasked with presenting it to a group, consider reading it in its entirety. To maximize your comprehension, you can\n", - "
    \n", - "
  • Summarize the main message of each paragraph in one sentence or less.
  • \n", - "
  • Create written descriptions or sketches of the phenomena discussed.
  • \n", - "
  • Identify the physical meaning and implications of terms and equations.
  • \n", - "
" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial2", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial3.ipynb deleted file mode 100644 index 04c4345d1..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial3.ipynb +++ /dev/null @@ -1,277 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "ce2da94e", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial3.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 3: Identifying the Basic Ingredients**\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "###### Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "####### Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######## Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######### Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########## Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########### Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "############ Video 3: Identifying the Basic Ingredients\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 3: Identifying the Basic Ingredients\n", - "#Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# **Activity: Identifying Basic Ingredients**\n", - "\n", - "Take 10 minutes to discuss the advantages and disadvantages of utilizing the following basic ingredients to explore the research question discussed in Video 1:\n", - "\n", - "\n", - "* Ice core data for CO2\n", - "\n", - "* Deep sea sediment data for sea surface temperature\n", - "\n", - "Can you think of alternative approaches that might work well?\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Choosing Your Data**\n", - "
\n", - "Click here for some pointers on how to choose your data\n", - "\n", - "Here are some questions to ask yourself when choosing the data to use:\n", - "\n", - "What physical processes must be included?\n", - "
    \n", - "
  • You don't want an approach that contains less than the bare minimum. For some phenomena, we know what the bare minimum is. For others, more research is needed...
  • \n", - "
  • If you are unsure about what physical processes are needed, check the literature!
\n", - "\n", - "What spatial and temporal resolution is necessary to capture the phenomenon?\n", - "
    \n", - "
  • GCMs can typically have a spatial resolution around 100km and time resolution of several hours.
  • \n", - "
  • For phenomena that require higher resolution, you can either
  • \n", - "
    • Use a more idealized model that resolves smaller scales
    • Implement a parameterization of the sub-gridscale features within the GCM.
    • \n", - "
\n", - "\n", - "What restrictions do I have for computational resources?\n", - "
    \n", - "
  • If you do not have access to large computational resources, you can still do research using smaller datasets or idealized models
  • \n", - "
\n", - "\n", - "Am I interested in looking at a particular time period or a specific physical location?\n", - "
    \n", - "
  • Reanalysis can be used for time periods after roughly the 1940s
  • \n", - "
  • Proxy data can be used for a wider historical and prehistorical data
  • \n", - "
  • Both reanalysis and proxy data can provide specific location information
  • \n", - "
  • Models can be designed to mimic the conditions of the location or time, for example:
    • \n", - "
    • GCMs (General Circulation Models or Global Climate Models) can be set according to parameters that resemble the time period
    • \n", - "
    • Energy balance models can capture some aspects of average temperature in other time periods
    • \n", - "
    • Radiative-convective equilibrium models can capture some phenomena in the tropics
    • \n", - "
    • Quasi-geostrophic models can capture some phenomena in the mid-latitudes (between ~30-60 degrees)
    • \n", - "
    • And many more!
    • \n", - "
    \n", - "
\n", - "\n", - "Am I interested in studying a feature of the phenomenon in isolation or interactions between multiple features?\n", - "\n", - "
    \n", - "
  • If you want to isolate a single aspect of the phenomenon, an idealized model may be more appropriate
  • \n", - "
  • If you want to study interactions between multiple features, either observational data or a more complex model may be appropriate
  • \n", - "
\n", - "\n", - "Am I trying to...\n", - "
    \n", - "
  • explain the theory behind the phenomenon? An idealized model may be appropriate
  • \n", - "
  • provide evidence to support or challenge a pre-existing hypothesis? Observational data or a more complex model may be appropriate
  • \n", - "
  • document the features of the phenomenon? Observational data may be appropriate
  • \n", - "
\n", - "\n", - "For more information on observational data: \n", - "* [NCAR's climate data guide](https://climatedataguide.ucar.edu/climate-data)\n", - "* [NCAR's guide on real-time weather data](https://weather.rap.ucar.edu/)\n", - "* [NOAA's guide on hydrological survey data](https://nauticalcharts.noaa.gov/data/hydrographic-survey-data.html)\n", - "* [USGS's guide on paleoclimate proxies](https://www.usgs.gov/programs/climate-research-and-development-program/science/paleoclimate-proxies)\n", - "* [Pangeo](https://pangeo.io/) hosts a few open-access datasets\n", - "\n", - "For more information on numerical modeling: \n", - "\n", - "* Atmospheric Model Hierarchies: Maher, P., Gerber, E. P., Medeiros, B., Merlis, T. M., Sherwood, S., Sheshadri, A., et al. (2019). Model hierarchies for understanding atmospheric circulation, Reviews of Geophysics, 57, 250– 280. https://doi.org/10.1029/2018RG000607\n", - "* Ocean Model Hierarchies: Hsu, T.-Y., Primeau, F., & Magnusdottir, G. (2022). A hierarchy of global ocean models coupled to CESM1. Journal of Advances in Modeling Earth Systems, 14, e2021MS002979. https://doi.org/10.1029/2021MS002979 " - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial3", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial4.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial4.ipynb deleted file mode 100644 index a149ae62d..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial4.ipynb +++ /dev/null @@ -1,255 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "c058d800", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial4.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 4: Formulating a Hypothesis**\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "###### Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "####### Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######## Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######### Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########## Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########### Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "############ Video 4: Formulating a Hypothesis\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 4: Formulating a Hypothesis\n", - "#Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In Tutorials 1-4, you will learn about the process of research design. This includes how to\n", - "\n", - "1. Identify a phenomenon and formulate a research question surrounding it\n", - "2. Efficiently review existing literature and knowledge about the phenomenon\n", - "3. Identify what is needed to study the phenomenon\n", - "4. Formulate a testable hypothesis regarding the phenomenon\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Activity: Understanding Hypothesis**\n", - "\n", - "Take 5 minutes to discuss how a hypothesis differs from a research question." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Make Sure to Avoid the pitfalls!**\n", - "
\n", - "Click here for a recap on pitfalls\n", - "\n", - "I don’t need a hypothesis, I will just play around with the model/data\n", - "
    \n", - "
  • A hypothesis will help to clarify your goals when presenting research. After all, \"I just played around with this model a lot\" isn't a very satisfying scientific result
  • \n", - "
  • However, we encourage you to explore and experiment with the model and the data, as this can help develop your intuition and understanding of the subject matter
  • \n", - "
  • Hypothesis formation is often an iterative process involving both the literature review and playing around with your model and data
  • \n", - "
\n", - "\n", - "My hypothesis doesn’t match my question (or vice versa)\n", - "
    \n", - "
  • This is a normal part of the process!
  • \n", - "
  • You can return to Step 1 and update your question / phenomenon / goals
  • \n", - "
\n", - "\n", - "I can’t write down a hypothesis\n", - "
    \n", - "
  • If you find it challenging to articulate a hypothesis, it may indicate that you lack ingredients and/or clarity on the hypothesis. Try returning to Step 2 to further your literature review, or continue playing around with your model or data.
  • \n", - "
\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorials 1-4 Summary**\n", - "\n", - "Through tutorials 1-4, we worked through the preliminary steps of starting a research project.\n", - "\n", - "* We identified a phenomenon and formulated a question (Step 1)\n", - "* We did a review of the literature and determine what has already been studied about the phenomenon (Step 2)\n", - "* We determined what basic ingredients we need to investigate the phenomenon (Step 3)\n", - "* We used all of the above to formulate a testable hypothesis (Step 4)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Next Steps**\n", - "\n", - "Tutorials 5-8 will illustrate the steps involved in data analysis, interpreting your results, and communicating your results to an audience. As you do your own research, feel free to return to this tutorial as a guide." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial4", - "provenance": [ - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial5.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial5.ipynb deleted file mode 100644 index 9dbbca310..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial5.ipynb +++ /dev/null @@ -1,300 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "2206eacd", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial5.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 5: Drafting the Analysis**\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorials Objectives**\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import seaborn as sns\n", - "import numpy as np\n", - "from scipy import interpolate\n", - "from scipy import stats" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "###### Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "####### Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######## Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######### Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########## Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########### Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "############ Video 6: Drafting the Analysis\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 6: Drafting the Analysis\n", - "#Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Coding Exercise 1**\n", - "\n", - "To explore the relationship between CO2 and temperature, you may want to make a scatter plot of the two variables, where the x-axis represents CO2 and the y-axis represents temperature. Then you can see if a linear regression model fits the data well.\n", - "\n", - "Before you do that, let's learn how to apply a linear regression model using generated data.\n", - "\n", - "If you aren't familiar with a linear regression model, it is simply a way of isolating a relationship between two variables (e.g. x and y). For example, each giraffe might have different running speeds. You might wonder if taller giraffes run faster than shorter ones. How do we describe the relationship between a giraffe's height and its running speed? A linear regression model will be able to provide us a mathematical equation:\n", - "\n", - "`speed = a * height + b`\n", - "\n", - "where a and b are the slope and intercept of the equation, respectively. Such an equation allows us to predict an unknown giraffe's running speed by simply plugging its height into the equation. Not all giraffes will fit the relationship and other factors might influence their speeds, such as health, diet, age, etc. However, because of its simplicity, linear regression models are usually first attempted by scientists to quantify the relationship between variables.\n", - "\n", - "For more information on linear regression models, see the [Wikipedia page](https://en.wikipedia.org/wiki/Linear_regression), especially the first figure on that page: " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 614, - "status": "ok", - "timestamp": 1681841571307, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# set up a random number generator\n", - "rng = np.random.default_rng()\n", - "# x is one hundred random numbers between 0 and 1\n", - "x = rng.random(100)\n", - "# y is one hundred random numbers according to the relationship y = 1.6x + 0.5\n", - "y = 1.6*x + rng.random(100)\n", - "\n", - "# plot\n", - "plt.scatter(x, y, color='gray')\n", - "\n", - "# regression\n", - "res = stats.linregress(x,y) # ordinary least sqaure\n", - "\n", - "plt.plot(x, x*res.slope+res.intercept, color='k')\n", - "plt.xlabel('x')\n", - "plt.ylabel('y')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "To get a sense of how our model fits the data, you can look at the regression results. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - " # summarize model\n", - "\n", - "print('pearson (r^2) value: ' +'{:.2f}'.format(res.rvalue**2)+' \\nwith a p-value of: '+'{:.2e}'.format(res.pvalue))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we know how to write codes to analyze the linear relationship between two variables, we're ready to move on to real world data!" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial5", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial6.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial6.ipynb deleted file mode 100644 index d1d299326..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial6.ipynb +++ /dev/null @@ -1,334 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "1e474128", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial6.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 6: Implementing the Analysis**\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorials Objectives**\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Activity: Implement the Analysis**\n", - "\n", - "In this tutorial, you will be implementing a linear regression model as outlined in Step 5 on real-world CO2 and temperature records.\n", - "\n", - "The CO2 and temperature records we will be analyzing are both examples of paleoclimate data (for more information, refer back to Step 3). The CO2 record (Bereiter et al., 2015) was generated by measuring the CO2 concentration in ancient air bubbles trapped inside ice from multiple ice cores retrieved from Antarctica. The temperature record (Shakun et al., 2015) is based on chemical analysis done on the shells of planktic foraminifera. The foraminifera shells were identified and picked from deep-sea sediments, and the temperature record combined multiple sea-surface temperature records from a range of sites globally.\n", - "\n", - "Why are we focusing on these two records specifically? The CO2 record from Antarctic ice core is the gold standard of air CO2 variability on glacial-interglacial time scales, and it has a temporal resolution unmatched by any other reconstruction methods. The temperature record comes from sediment cores all over the global ocean, and therefore is likely representative of the global surface ocean temperature variability. Polar air temperature records are also available from ice core studies, but such records may represent an exaggerated view of the global temperature because of polar amplification.\n", - "\n", - "If you would like to learn more, the data sources are listed at the bottom of the page.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 3940, - "status": "ok", - "timestamp": 1682775919083, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import seaborn as sns\n", - "import numpy as np\n", - "from scipy import interpolate\n", - "from scipy import stats\n", - "import os\n", - "import pooch" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# time series\n", - "# read SST data \"Shakun2015_SST.txt\"\n", - "url_Shakun2015_SST = \"https://osf.io/kmy5w/download\"\n", - "SST = pd.read_table(pooch.retrieve(url_Shakun2015_SST, known_hash=None))\n", - "SST.set_index('Age', inplace=True)\n", - "SST" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# read CO2 dataantarctica2015co2composite_cleaned.txt\n", - "url_antarctica2015co2composite_cleaned = \"https://osf.io/45fev/download\"\n", - "CO2 = pd.read_table(pooch.retrieve(url_antarctica2015co2composite_cleaned, known_hash=None))\n", - "CO2.set_index('age_gas_calBP', inplace=True)\n", - "CO2" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 5037, - "status": "ok", - "timestamp": 1682775959771, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# plot\n", - "# set up two subplots in a grid of 2 rows and 1 column\n", - "# also make sure the two plots share the same x(time) axis\n", - "fig, axes = plt.subplots(2, 1, sharex=True)\n", - "# move the two subplots closer to each other\n", - "fig.subplots_adjust(hspace=-0.5)\n", - "axes[0].plot(SST.index, SST['SST stack'], color='C4')\n", - "axes[1].plot(CO2.index/1000, CO2['co2_ppm'], color='C1')\n", - "\n", - "# beautification\n", - "# since sharex=True in plt.subplots(), this sets the x axis limit for both panels\n", - "axes[1].set_xlim((0, 805))\n", - "# axis labels\n", - "axes[1].set_xlabel('Age (ka BP)')\n", - "axes[0].set_ylabel(r'Sea Surface Temperature'\n", - " '\\n'\n", - " 'detrended (°C)',\n", - " color='C4')\n", - "axes[1].set_ylabel(r'CO${}_\\mathrm{2}$ (ppm)',\n", - " color='C1')\n", - "# despine makes the plots look cleaner\n", - "sns.despine(ax=axes[0], top=True, right=False, bottom=True, left=True)\n", - "sns.despine(ax=axes[1], top=True, right=True, bottom=False, left=False)\n", - "# clean up top panel x axis ticks\n", - "axes[0].xaxis.set_ticks_position('none')\n", - "# move top panel xlabel to the right side\n", - "axes[0].yaxis.set_label_position('right')\n", - "# the following code ensures the subplots don't overlap\n", - "for ax in axes:\n", - " ax.set_zorder(10)\n", - " ax.set_facecolor('none')\n", - "# color the axis\n", - "axes[0].spines['right'].set_color('C4')\n", - "axes[1].spines['left'].set_color('C1')\n", - "axes[0].tick_params(axis='y', colors='C4')\n", - "axes[1].tick_params(axis='y', colors='C1')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we've taken a look at the two time series, let's make a scatter plot between them and fit a linear regression model through the data." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "# in this code block, we will make a scatter plot of CO2 and temperature\n", - "# and fit a linear regression model through the data\n", - "\n", - "def age_model_interp(CO2_age, CO2, SST_age):\n", - " '''\n", - " This helper function linearly interpolates CO2 data, which\n", - " have a very high temporal resolution, to temperature data,\n", - " which have a relatively low resolution\n", - " '''\n", - " f = interpolate.interp1d(CO2_age, CO2)\n", - " all_ages = f(SST_age)\n", - " return all_ages\n", - "\n", - "# interpolate CO2 data to SST age\n", - "CO2_interpolated = age_model_interp(CO2.index/1000, CO2['co2_ppm'], SST.index)\n", - "\n", - "# plot\n", - "# set up two subplots in a grid of 2 rows and 1 column\n", - "# also make sure the two plots share the same x(time) axis\n", - "fig, ax = plt.subplots(1, 1, sharex=True)\n", - "\n", - "ax.scatter(CO2_interpolated, SST['SST stack'], color='gray')\n", - "\n", - "# regression\n", - "X = CO2_interpolated\n", - "y = SST['SST stack']\n", - "res = stats.linregress(X,y) # ordinary least sqaure\n", - "\n", - "x_fit = np.arange(180, 280)\n", - "# intercept\n", - "y_fit = x_fit * res.slope +res.intercept\n", - "ax.plot(x_fit, y_fit, color='k')\n", - "\n", - "# beautification\n", - "# axis labels\n", - "ax.set_xlabel(r'CO${}_\\mathrm{2}$ (ppm)')\n", - "ax.set_ylabel(r'Sea Surface Temperature'\n", - " '\\n'\n", - " 'detrended (°C)')\n", - "print('pearson (r^2) value: ' +'{:.2f}'.format(res.rvalue**2)+' \\nwith a p-value of: '+'{:.2e}'.format(res.pvalue))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Figure Making Through the Equity Lense**\n", - "
\n", - "Click here for some information\n", - "Are the colors in your figure distinguishable for people with color-vision deficiencies?\n", - "\n", - "More readings on this topic:\n", - "\n", - "Contrast checker: https://www.color-blindness.com/coblis-color-blindness-simulator/\n", - "\n", - "Coloring for color blindness: https://davidmathlogic.com/colorblind\n", - "\n", - "Python-specific color palettes that are friendly to those with color-vision deficiency: https://seaborn.pydata.org/tutorial/color_palettes.html" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "Data from the following sources are used in this tutorial:\n", - "\n", - "CO2: Bereiter, B., Eggleston, S., Schmitt, J., Nehrbass-Ahles, C., Stocker, T.F., Fischer, H., Kipfstuhl, S., Chappellaz, J., 2015. Revision of the EPICA Dome C CO2 record from 800 to 600 kyr before present. Geophysical Research Letters 42, 542–549. https://doi.org/10.1002/2014GL061957\n", - "\n", - "Temperature: Shakun, J.D., Lea, D.W., Lisiecki, L.E., Raymo, M.E., 2015. An 800-kyr record of global surface ocean δ18O and implications for ice volume-temperature coupling. Earth and Planetary Science Letters 426, 58–68. https://doi.org/10.1016/j.epsl.2015.05.042\n", - "\n", - "\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial6", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial7.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial7.ipynb deleted file mode 100644 index e166ed931..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial7.ipynb +++ /dev/null @@ -1,237 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "47fa5b8a", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial7.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 7: Interpreting the Results**\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorials Objectives**\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "###### Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "####### Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######## Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######### Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########## Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########### Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "############ Video 1: Interpreting the Results\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Interpreting the Results\n", - "#Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In Step 6, we created plots displaying the global CO2 levels and sea surface temperature data spanning the past 800 thousand years. Additionally, we attempted to fit both variables using a linear regression model. Nevertheless, it is crucial to bear in mind that correlation does not imply causation. The fact that global CO2 and sea surface temperature appear to co-vary does not automatically imply that one variable directly causes changes in the other. To establish causation, it is imperative to gather multiple lines of evidence. This underscores the importance of literature review in Step 2, as it aids in identifying corroborating evidence in climate research." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Quantifying the Uncertainty**\n", - "
\n", - "Click here for some information\n", - "Look up \"linear regression model R squared\" and how it measures the uncertainty of a linear regression model. What does it say about how confident you can be about a linear relationship between CO2 and temperature?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Activity: Interpreting the Results Through the Lens of Equity**\n", - "For the next 10 minutes, discuss what the results capture well in terms of the relationship between CO2 and temperature. Who is represented by this data, specifically the compiled temperature record, and who is not? Who generated these data? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Further readings**\n", - "
\n", - "Click here for more readings on Interpreting the Results through the lens of equity\n", - "\n", - "Donovan, R. (2023), Climate journalism needs voices from the Global South, Eos, 104, https://doi.org/10.1029/2023EO230085\n", - "\n", - "Tandon, A. (2021), Analysis: The lack of diversity in climate-science research, Carbon Brief, [https://www.carbonbrief.org/analysis-the-lack-of-diversity-in-climate-science-research/](https://www.carbonbrief.org/analysis-the-lack-of-diversity-in-climate-science-research/)" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial7", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial8.ipynb b/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial8.ipynb deleted file mode 100644 index beef67b77..000000000 --- a/book/_build/html/_sources/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial8.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "664c1add", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial8.ipynb)   \"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 8: Communicating Your Conclusions**\n", - "\n", - "**Good Research Practices**\n", - "\n", - "**Content creators:** Marguerite Brown, Yuxin Zhou\n", - "\n", - "**Content reviewers:** Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorials Objectives**\n", - "\n", - "In Tutorials 5-8, you will learn about the research process. This includes how to\n", - "\n", - "5. Draft analyses of data to test a hypothesis\n", - "6. Implement analysis of data\n", - "7. Interpret results in the context of existing knowledge\n", - "8. Communicate your results and conclusions\n", - "\n", - "By the end of these tutorials you will be able to:\n", - "\n", - "* Understand the principles of good research practices\n", - "* Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "##### Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "###### Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "####### Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######## Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "######### Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########## Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "########### Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "############ Video 1: Communicating Your Conclusions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Communicating Your Conclusions\n", - "#Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Activity: Communicating Your Conclusions**\n", - "\n", - "For the next 20 minutes, break out into groups of 2 or 3 and pick one presentation format and discuss:\n", - "\n", - "* Who is the target audience of this format?\n", - "* What information is important to include?\n", - "\n", - "After this, come back together as a whole pod and discuss everyone's suggestions.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Equity in the Science Publishing**\n", - "
\n", - "Click here for some information about equity and publishing\n", - "\n", - "There are aspects of our current research culture that perpetuate inequity in the publishing process. Academic institutions and funding agencies often place importance on publishing in peer-reviewed journals. However, they have some drawbacks, including\n", - "\n", - "* Accessibility\n", - "
  • Papers in these journals are often kept behind a paywall, making them less accessible to people without the backing of either a university or a company.
  • \n", - "
  • More and more journals offer the option of publishing open access, but at expense to the submitting authors: fees can often exceed 1000 USD.
  • \n", - "
  • \n", - "If you want to ensure accessibility, consider also releasing your results in other formats as well. For instance,\n", - "
    • Blog posts
    • \n", - "
    • Podcasts
    • \n", - "
    • Social media posts
    • \n", - "
    • Conferences
    \n", - "
  • If you know that your research contains results that are relevant to specific populations, it is valuable to find ways to communicate your results to them.
\n", - "* Peer Review as Gatekeeping\n", - "
  • At its best, the peer review process enforces scientific rigor.
  • \n", - "
  • At its worst, it can become a tool for enforcing pre-existing norms, including the biases of its reviewers.
  • \n", - "
  • REMEMBER: Bad experiences with reviewers and rejections does not mean that your research is bad. There are papers which went on to win Nobel prizes that experienced resistance and rejection during the peer review process BECAUSE they were introducing important new ideas.
  • \n", - "
  • Further Reading:
  • \n", - "
    • Campanario, J. M. (2009). Rejecting and resisting Nobel class discoveries: Accounts by Nobel Laureates. Scientometrics, 81(2), 549–565.
    • \n", - "
    • Bancroft, S. F., Ryoo, K., & Miles, M. (2022). Promoting equity in the peer review process of journal publication. Science Education, 106, 1232– 1248. https://doi.org/10.1002/sce.21733
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorials 5-8 Summary**\n", - "\n", - "In this tutorial, we worked through how to analyze and present research.\n", - "\n", - "* We learned how to draft an analysis (Step 5)\n", - "* We implemented the analysis that we drafted (Step 6)\n", - "* We learned how to interpret the results of the analysis (Step 7)\n", - "* We learned about how to communicate the conclusions of our research (Step 8)\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D2_Tutorial8", - "provenance": [ - { - "file_id": "108RRAFBnnKvDTfEDC0Fm5qHZez32HB69", - "timestamp": 1680091091012 - }, - { - "file_id": "1WfT8oN22xywtecNriLptqi1SuGUSoIlc", - "timestamp": 1680037587733 - } - ], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title.md b/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title.md deleted file mode 100644 index ec8f9f7ef..000000000 --- a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title.md +++ /dev/null @@ -1,7 +0,0 @@ -# Future Climate - IPCC II & III Socio-Economic Basis - - ````{div} full-height - art relevant to chapter contents -```` - -*Artwork by Sloane Garelick* \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading.md b/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading.md deleted file mode 100644 index cc972adcd..000000000 --- a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading.md +++ /dev/null @@ -1,81 +0,0 @@ -# **Tutorial 2 Further Reading** - -## **IAM Model Summary** -The economy model in most IAMs is a capital accumulation model. -- Capital combines with a laboring population and technology to generate productivity ($Y$) that is hindered by climate damage. -- A savings fraction of production drives capital accumulation, while the rest is consumed. Welfare is determined by consumption. -- Climate action is formulated by a mitigation rate, $\mu$, which along with the savings rate are the two control parameters in the model. -- These are used to maximize welfare. - -The climate model in DICE could be improved (c.f. [this study](https://www3.nd.edu/~nmark/Climate/DICE-simplified_2019.pdf)). We only summarize here how it interacts with the economy model: -- Productivity generates industrial emissions, $$E_\mathrm{ind}=(1-\mu)\sigma Y,$$ where the $1-\mu$ factor accounts for reduced carbon intensity of production, $\sigma$, via supply-side mitigation measures (e.g. increased efficiency). -- The productivity $Y$ rather than output production ($Q$) see model is used here because damages aren't included. -- Namely, the emissions produced in the process of capital production occur before climate change has a chance to inflict damage on the produced output. -- These emissions combine with natural emissions to drive the temperature changes appearing in the damage function, closing the economy-climate loop. - -Here are a list of variables used: -- $K$ capital -- $Y$ productivity -- $Q$ production -- $A$ technology conversion -- $S$ savings rate -- $\mu$ mitigation rate -- $\Lambda$ mitigation cost -- $\Omega$ damage fraction of productivity -- $\sigma$ carbon intensity of production -- $E$ emissions - -## **Exogeneous Control Variables** -There are two exogeneous variables in the model: -- mitigation (emissions reduction) rate $\mu_t$, and -- the savings rate $S_t$. - -There exists a mitigation cost associated with a specific mitigation rate, presented as a fraction of productivity, $\Lambda_t=\theta_1\mu^{\theta_2}$. This implies that increased mitigation efforts correspond to elevated costs. - -The savings rate $S_t$ extracts a portion of the total production to invest, thereby boosting capital. The rest of the production is then allocated for consumption. - -## **Economy Model Summary** -The essence of the economy model in DICE is a capital accumulation model. Existing capital depreciates at rate $\delta$ and new capital arises through investment, -$$K_{t+1}=(1-\delta)K_t+I_t$$ -where the invested capital $I=SQ$ is determined by a chosen fraction $S$ of the production $Q$ that is "saved" rather than consumed. Production is given as the productivity $Y$ reduced by damages and mitigation cost, $$Q=(1-\Omega)(1-\Lambda)Y.$$ Productivity, $$Y=A K^\gamma L^{1-\gamma},$$ -is determined by the technology conversion $A$ operating on a combination of capital $K$ and labor $L$ whose relative contributions are set by the capital elasticity parameter $\gamma$. Labor is population which set to saturate over the 2nd half of the 21st century. Technology conversion is only weakly sigmoidal in time, deviating slightly from linear growth. - -The remaining production is consumed $$C:=(1-S)Q$$ producing utility $$U(C,L)=Lu(c)=Lu(C/L),$$ using the isoelastic utility function, $$u(c)=\frac{(c+1)^{1-\alpha}-1}{1-\alpha}.$$ The overall value of a projected future is then $$V=\sum_{t=1}^{\infty}\gamma^t U(C_t,L_t),$$ where $\gamma=1/(1+\rho)$ for discount rate $\rho$ and we use the population level utility function $U(C,L)=Lu(C/L)$. - - -Here are a list of variables used: -- $K$ capital -- $Y$ productivity -- $Q$ production -- $A$ technology conversion -- $S$ savings rate -- $\mu$ mitigation rate -- $\Lambda$ mitigation cost -- $\Omega$ damage fraction of productivity -- $\sigma$ carbon intensity of production -- $E$ emissions - -## **Optimal Planning** -The unconstrained problem aims to maximize $V$ within the bounds of $\mu_t$ and $S_t$ time courses (while considering constraints on $\mu$ and $S$). Why is there a "sweet spot"? Increasing savings boosts investment and productivity, but higher production leads to emissions, resulting in increased temperature and damages that reduce production. Mitigation costs counterbalance this effect, creating a trade-off. As a result, there typically exists a meaningful joint time series of $\mu_t$ and $S_t$ that maximizes $V$. Due to the discount factor $\gamma$, $V$ depends on the future consumption sequence (non-invested production) within a few multiples of the horizon, approximately $1/(1-\gamma)$ time steps into the future. - -Constrained formulations introduce an additional constraint to limit industrial emissions below a certain threshold. - -## **Social Cost of Carbon** -A definition for the social cost of carbon (SCC) is - -- *the decrease in aggregate consumption in that year that would change the current...value of social welfare by the same amount as a one unit increase in carbon emissions in that year.* ([Newbold, Griffiths, Moore, Wolverton, & Kopits, 2013](https://www.worldscientific.com/doi/abs/10.1142/S2010007813500012)). - -The $SCC$ quantifies how much consumption is lost with increased emissions, using changes in welfare to make the connection. In technical terms: - -- the marginal value with respect to emissions relative to the marginal value with respect to consumption, $$SCC_t\propto\frac{\partial V/\partial E_t}{\partial V/\partial C_t}=\frac{\partial C_t}{\partial E_t}.$$ -This is usually expressed by multiplying by a proportionality factor of $-1000$ that converts the units to 2010 US dollars per tonne of CO2. - -# **Tutorial 4 Further Reading** - -## **Vectorization Methods for Creating Word Clouds** - -Let's write down what they compute by denoting the index, $d$, over the $D$ documents and the index, $w$, over the $W$ words in the vocabulary (the list of all the words found in all the tweets, which we'll call documents): -- term frequency, $\mathrm{tf}(w,d)$. The frequency of a word $w$ in a document $d$ is $$\mathrm{tf}(w,d):=\frac{n(w,d)}{n(d)},$$ where $n(w,d)$ is the number of times term $w$ is in document $d$ and $n(d)=\sum_{w=1}^W n(w,d)$ is the total number of words in document $d$. The term frequency over all the documents is then, $$\mathrm{tf}(w):=\frac{\sum_{d=1}^D n(d)\mathrm{tf}(w,d)}{N},$$ where the denominator $N=\sum_{d=1}^D n(d)$ is just the total word count across all documents. -- term frequency-inverse document frequency, $\mathrm{Tfidf}(w,d):=\mathrm{tf}(w,d)\mathrm{idf}(w)$. Here, $$\mathrm{idf}(w)=\frac{\log(D+1)}{\log(n(w)+1)+1},$$ where $n(w)$ is the number of documents in which term $t$ appears, i.e. $n(w,d)>0$. Idf is like an inverse document frequency. The `sklearn` package then uses $$\mathrm{Tfidf}(w)=\frac{1}{D}\sum_{d=1}^D \frac{\mathrm{Tfidf}(w,d)}{||\mathrm{Tfidf}(\cdot,d)||},$$ where $||\vec{x}||=\sqrt{\sum_{i=1}^Nx^2_i}$ is the Euclidean norm. - -$\mathrm{Tfidf}$ aims to add more discriminability to frequency as a word relevance metric by downweighting words that appear in many documents since these common words are less discriminative. \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1.ipynb b/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1.ipynb deleted file mode 100644 index 5b80d84ed..000000000 --- a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1.ipynb +++ /dev/null @@ -1,1098 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0881f688", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/W2D3_Tutorial1.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "1380c3b2-590b-4271-9b2a-4c9830aab5ca", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 1:**\n", - "\n", - "**Week 2, Day 3: IPCC Socio-economic Basis**\n", - "\n", - "**Content creators:** Maximilian Puelma Touzel\n", - "\n", - "**Content reviewers:** Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina DuplexLaura Paccini, Sloane Garelick, Abigail Bodner, Manisha Sinha, Agustina Pesce, Dionessa Biton, Cheng Zhang, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "EQcat4kN0AyT", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "During the first week of the course, you learned about types of climate data from measurements, proxies and models, and computational tools for assessing past, present and future climate variability recorded by this data. During day one of this week, you began to explore climate model data from Earth System Models (ESMs) simulations conducted for the recent Climate Model Intercomparison Project (CMIP6) that are presented in the report from the Intergovernmental Panel on Climate Changes (IPCC). However, the dominant source of uncertainty in those projections arise from how human society responds: e.g. how our emissions reduction and renewable energy technologies develop, how coherent our global politics are, how our consumption grows etc. For these reasons, in addition to understanding the physical basis of the climate variations projected by these models, it's also important to assess the current and future socioeconomic impact of climate change and what aspects of human activity are driving emissions. This day's tutorials focus on the socioeconomic projections regarding the future of climate change and are centered around the Shared Socioeconomic Pathways (SSP) framework used by the IPCC.\n", - "\n", - "In this first tutorial, you will see how society can be represented by inter-related socio-economic variables and thier projections into the future. This tutorial will provide insights into the pressing socioeconomic issues related to climate change, such as resource scarcity, population dynamics, and the potential impacts of unchecked resource extraction. In particular, you will see some socioeconomic projections of the Integrated Assessment Modelling (IAM) used by the IPCC, and the influence of shared socio-economic pathways on these projections. In the bulk of the tutorial, you will use the `World3` model, a tool developed in the 1970s to analyze potential economic and population scenarios. You will use it to learn about nonlinear, coupled dynamics of various aggregated world system variables and how this model informs modern day climate challenges." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "M1V4fv311VyL", - "metadata": { - "execution": {}, - "tags": [] - }, - "source": [ - "# **Setup**\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8zsv1T3Z1h0m", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1958, - "status": "ok", - "timestamp": 1682540361880, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "from IPython.display import Math\n", - "from IPython.display import display, HTML, Image\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import numpy as np\n", - "from ipywidgets import interact\n", - "import ipywidgets as widgets\n", - "import pooch\n", - "import os\n", - "import tempfile\n", - "import urllib\n", - "from pyworld3 import World3\n", - "from pyworld3.utils import plot_world_variables" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0d638867-ebd9-4bcd-9470-3f900632d26a", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "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", - "sns.set_style(\"ticks\", {\"axes.grid\": False})\n", - "%matplotlib inline\n", - "display(HTML(\"\"))\n", - "params = {\"lines.linewidth\": \"3\"}\n", - "plt.rcParams.update(params)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Helper functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "NRizLOHHmofT", - "metadata": { - "cellView": "form", - "execution": {}, - "executionInfo": { - "elapsed": 240, - "status": "ok", - "timestamp": 1682540400735, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "\n", - "def get_IPCC_data(var_name, path):\n", - " IAMdf = pd.read_excel(path)\n", - " IAMdf.drop(\n", - " IAMdf.tail(2).index, inplace=True\n", - " ) # excel file has 2 trailing rows of notes\n", - " IAMdf.drop(\n", - " [\"Model\", \"Region\", \"Variable\", \"Unit\", \"Notes\"], axis=1, inplace=True\n", - " ) # remove columns we won't need\n", - "\n", - " # The data is in wideform (years are columns).\n", - " # Longform (year of each datum as a column) is more convenient.\n", - " # To collapse it to longform we'll use the `pd.wide_to_long` method that requires the following reformatting\n", - " IAMdf.rename(\n", - " columns=dict(\n", - " zip(IAMdf.columns[1:], [var_name + str(y) for y in IAMdf.columns[1:]])\n", - " ),\n", - " inplace=True,\n", - " ) # add 'pop' to the year columns to tell the method which columns to map\n", - " IAMdf.index = IAMdf.index.set_names([\"id\"]) # name index\n", - " IAMdf = IAMdf.reset_index() # make index a column\n", - " IAMdf = pd.wide_to_long(IAMdf, [var_name], i=\"id\", j=\"year\")\n", - "\n", - " IAMdf = IAMdf.reset_index().drop(\"id\", axis=1) # do some post mapping renaming\n", - " IAMdf.year = IAMdf.year.apply(int) # turn year data from string to int\n", - " if var_name == \"pop\":\n", - " IAMdf[var_name] = 1e6 * IAMdf[var_name] # pop is in millions\n", - " elif var_name == \"CO2\":\n", - " IAMdf[var_name] = 1e6 * IAMdf[var_name] # CO2 is in Mt CO2/yr\n", - " elif var_name == \"forcing\":\n", - " IAMdf = IAMdf # forcing in W/m2\n", - " return IAMdf\n", - "\n", - "\n", - "def run_and_plot(world3, nri_factor=1, new_lifetime_industrial_capital=14):\n", - " # nonrenewable resources initial [resource units]\n", - " world3.init_world3_constants(\n", - " nri=nri_factor * 1e12, alic1=14, alic2=new_lifetime_industrial_capital\n", - " )\n", - " world3.init_world3_variables()\n", - " world3.set_world3_table_functions()\n", - " world3.set_world3_delay_functions()\n", - " world3.run_world3(fast=False)\n", - "\n", - " # select model variables to plot\n", - " variables = [\n", - " world3.nrfr,\n", - " world3.iopc,\n", - " world3.fpc,\n", - " world3.pop,\n", - " world3.ppolx,\n", - " world3.d,\n", - " world3.cdr,\n", - " ]\n", - " variable_labels = [\n", - " \"Resource\", # nonrenewable resource fraction remaining (NRFR)\n", - " \"Industry\", # industrial output per capita [dollars/person-year] (IOPC)\n", - " \"Food\", # food production per capita [vegetable-equivalent kilograms/person-year] (FPC)\n", - " \"Population\", # population [persons] (POP)\n", - " \"Pollution\", # index of persistent pollution (PPOLX)\n", - " # (fraction of peristent pollution in 1970 = 1.36e8 pollution units)\n", - " \"Deaths\",\n", - " \"Deathrate\\n/1000\",\n", - " ]\n", - " variable_limits = [\n", - " [0, 1],\n", - " [0, 1e3],\n", - " [0, 1e3],\n", - " [0, 16e9],\n", - " [0, 32],\n", - " [0, 5e8],\n", - " [0, 250],\n", - " ] # y axis ranges\n", - "\n", - " plot_world_variables(\n", - " world3.time,\n", - " variables,\n", - " variable_labels,\n", - " variable_limits,\n", - " img_background=None, # ./img/fig7-7.png\",\n", - " figsize=[4 + len(variables), 7],\n", - " title=\"initial non-renewable resources=\" + str(nri_factor) + \"*1e12\",\n", - " grid=True,\n", - " )\n", - "\n", - " # overlay an SSP projection\n", - " scenario_name = \"SSP2-Baseline\"\n", - " pop_path = pooch.retrieve(\"https://osf.io/download/ed9aq/\", known_hash=None)\n", - " IAMpopdf = get_IPCC_data(\"pop\", pop_path)\n", - " year_data = IAMpopdf.loc[IAMpopdf.Scenario == scenario_name, \"year\"]\n", - " var_data = IAMpopdf.loc[IAMpopdf.Scenario == scenario_name, \"pop\"]\n", - " axs = plt.gcf().axes\n", - " axs[variable_labels.index(\"Population\")].plot(\n", - " year_data, var_data, \"r--\", label=scenario_name\n", - " )\n", - " axs[variable_labels.index(\"Population\")].legend(frameon=False)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Title\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d6b41597-ce2d-40ec-ac52-db2e86baa6b6", - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Title\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "52b595d0-c860-4d9e-8fe3-648b042c96a6", - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "# helper functions\n", - "\n", - "\n", - "def pooch_load(filelocation=None, filename=None, processor=None):\n", - " shared_location = \"/home/jovyan/shared/Data/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis\" # this is different for each day\n", - " user_temp_cache = tempfile.gettempdir()\n", - "\n", - " if os.path.exists(os.path.join(shared_location, filename)):\n", - " file = os.path.join(shared_location, filename)\n", - " else:\n", - " file = pooch.retrieve(\n", - " filelocation,\n", - " known_hash=None,\n", - " fname=os.path.join(user_temp_cache, filename),\n", - " processor=processor,\n", - " )\n", - "\n", - " return file" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "iA4F5e7vrud2", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Exploring the IPCC's Socioeconomic Scenarios**\n", - "\n", - "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 to 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. In other words, IAMs are models that link human economic activity with climate change. \n", - "\n", - "Let's start by investigating some IAM model output, which will prepare you to explore `World3` (which gives similar socioeconomic output) later in this tutorial.\n", - "\n", - "All data from the main simulations of the IAMs used in the IPCC reports is freely available for viewing [here](https://tntcat.iiasa.ac.at/SspDb/dsd). The simulations are labeled by both the Shared Socioeconomic Pathway (SSP1, SSP2, SSP3, SSP4, and SSP5) and the forcing level (greenhouse gas forcing of 2.6, 7.0, 8.5 W m2 etc. by 2100). The 5 SSPS are: \n", - "- SSP1: Sustainability (Taking the Green Road)\n", - "- SSP2: Middle of the Road\n", - "- SSP3: Regional Rivalry (A Rocky Road)\n", - "- SSP4: Inequality (A Road divided)\n", - "- SSP5: Fossil-fueled Development (Taking the Highway)\n", - "You will learn more about how these 5 SSPs were determined in future tutorials.\n", - "\n", - "In previous days, you have looked at climate model data for projections of sea surface temperature change under different SSPs. We saw that applying different greenhouse gas forcings to a climate model affects global temperature projections and also influences other parts of the climate system, such as precipitation. In this section, we will take a look at the modelled socio-economic impacts associated with such changes to the physical climate system.\n", - "\n", - "It is possible to download the IAM data if you provide an email address, but for this tutorial the following files have already been downloaded:\n", - "\n", - "- Climate forcing\n", - "- World population\n", - "- Total CO2 emissions\n", - "\n", - "Since the files all have the same name, `iamc_db.xlsx`, we have added '_forcing', '_pop', and '_CO2' to differentiate the files and have stored them in our OSF repository. \n", - "\n", - "Let's load and plot this data to explore the forcing, population and CO2 emissions across the different SSP scenarios. You can utilize the pre-defined plotting function from above." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "MxYat-fh2ka9", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 7367, - "status": "ok", - "timestamp": 1682540448015, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "var_names = [\"forcing\", \"pop\", \"CO2\"]\n", - "filenames = [\"iamc_db_forcing.xlsx\", \"iamc_db_pop.xlsx\", \"iamc_db_CO2.xlsx\"]\n", - "paths = [\n", - " \"https://osf.io/download/tkrf7/\",\n", - " \"https://osf.io/download/ed9aq/\",\n", - " \"https://osf.io/download/gcb79/\",\n", - "]\n", - "files = [pooch_load(path, filename) for path, filename in zip(paths, filenames)]\n", - "axis_size = 4\n", - "fig, ax = plt.subplots(\n", - " 1, len(var_names), figsize=(axis_size * len(var_names), axis_size)\n", - ")\n", - "for ax_idx, var_name in enumerate(var_names):\n", - " data_df = get_IPCC_data(var_name, files[ax_idx])\n", - " sns.lineplot(\n", - " ax=ax[ax_idx], data=data_df, x=\"year\", y=var_name, hue=\"Scenario\"\n", - " ) # plot the data" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "2eKbbM-g6Vai", - "metadata": { - "execution": {} - }, - "source": [ - "The projections in the plots you just created show changes in climate forcing (left), population (middle) and CO2 emissions (right) across the five different SSP scenarios computed at thier baseline forcing level (different for each scenario), which are each represented by a distinct color in each plot.\n", - "\n", - "The projections for each SSP are created by optimizing economic activity within the constraint of a given level of greenhouse gas forcing at 2100. This activity drives distinct temperature changes via the emissions it produces, which are inputted into a socioeconomic model component to compute economic damages. These damages feedback into the model to limit emissions-producing economic activity. The forcing constraint ensures the amount of emissions produced is consistent for that particular scenario. In other words, the projected temperature change under different scenarios is fed to a socioeconomic model component in order to assess the socioeconomic impacts resulting from the temperature change associated with each SSP.\n", - "\n", - "Not every variable in IAMs is endogenous (i.e. determined by other variables in the model). Some variables, like population or technology growth, are exogeneous (i.e. variables whose time course is given to the model). In this case, the time course of population and economic growth, are derived from simple growth models. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "874e058f", - "metadata": { - "execution": {} - }, - "source": [ - "### **Question 1**\n", - "\n", - "1. Having watched the video on the limits of growth, why might the continued growth in both population and economy not be assured?" - ] - }, - { - "cell_type": "markdown", - "id": "34448cce-14a6-43a1-b568-9f85dac5ed7c", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial1_Solution_b081dd60.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "45de06d8", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: World Models and `World3`**\n", - "In this section you will take a step back from IAMs and use another model class, *world models*, to first explore how socioeconomic system variables like population, capital and pollution co-vary. You've already seen world models in the video for this tutorial, but let's recap what they are and why they are interesting." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "UU_Vc35qk0hl", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "World models are computational models that incorporate natural physical limits in the economy. For example, world models can help to assess the impact of an economy based on growth-oriented extraction of a finite resource. All variables in world model are endogeneous. Recall that endogeneous variables determined by other variables in the model, rather than being given to the model. Therefore, world models are self-contained and simply run as a dynamical system: given an initial condition (a value for all variables) and the equations describing rates of change of the variables, they output the subsequent time series of these variables. The important variables in a world model are similar to those of Integrated Assessment Models: capital, production, population, pollution etc. \n", - "\n", - "`World3` is a world model that was developed in the 1970s and doesn't have an explicit climate component (perhaps its developers were unaware of climate change at the time, as many were back then). However, `World3` does have a *pollution* variable that is driven by industrial activity, and this pollution negatively impacts food production and directly increases mortality rates via health effects. If we were developing `World3` today with our knowledge of human-driven climate change, we would add greenhouse gas emissions as a component of the pollution variable, which is the place in `World3` representing the damaging waste of our industrial activity. \n", - "\n", - "The reason we are looking at `World3` here in this first tutorial, is that:\n", - "1. `World3` is an instructive world model of the resource depletion and pollution problem. It is essential to understand the forcings, feedbacks and results associated with these problems because they directly contribute to climate change. More specifically, understanding these problems helps us understand the socioeconomic forces driving the emissions that are the source of the climate change problem.\n", - "2. World models provide an alternative modelling tradition not steeped in the neoclassical economics on which IAMs are based. This provides some diversity in perspective.\n", - "\n", - "*Note: the model in `World3` is not only wrong (i.e. missing many variables), but is a poor idealization. In other words, the `World3` model is not necessarily qualitatively predictive because it is missing some determining variables/model features (e.g. technology innovation/adaptation). It is thus almost certainly not predictive, but is still useful for thinking about 'world systems' because it includes important relationships between some key natural and socio-economic variables that we will look at here. In later tutorials, we will learn about similr critiques of elements of IAMs (e.g. for lacking important variables).*" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "TxRZr3mHIPhb", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: A Complete Map of `World3`**\n", - "\n", - "Now that we have a basic understanding of World3, we can start to explore some more specific components and interactions of the model. \n", - "\n", - "Welcome to World3! Here is a stock-flow diagram of the full model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "65f67f6e", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2203, - "status": "ok", - "timestamp": 1682540473951, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "display(Image(url=\"https://osf.io/download/hzrsn/\", width=1000, unconfined=True))\n", - "# copyrighted image from the textbook:\n", - "# Meadows, D.L.; Behrens, W.W.; Meadows, D.L.; Naill, R.F.; Randers, J.; Zahn, E.K.O. The Dynamics of Growth in a Finite World; Wright-Allen Press: Cambridge, MA, USA, 1974.\n", - "# Source: https://www.mdpi.com/sustainability/sustainability-07-09864/article_deploy/html/images/sustainability-07-09864-g001.png\n", - "# Alternate image from the precursor model: Jay Forrester's world dynamic model: https://petterholdotme.files.wordpress.com/2022/04/world-dynamics.png" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "6014eee7", - "metadata": { - "execution": {} - }, - "source": [ - "### **Question 2.1**\n", - "1. Increase the width of this image to 3000. \n", - "2. Scroll around the larger image you just created to see what words you find in the node labels of the different parts of the model. Suggest a category label for each quadrant of the model." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4ea502f7", - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "#################################################\n", - "## TODO for students: details of what they should do ##\n", - "# Fill out function and remove\n", - "raise NotImplementedError(\"1. Increase the width of this image to 3000.\")\n", - "#################################################\n", - "\n", - "display(Image(url=\"https://osf.io/download/hzrsn/\", width=..., unconfined=True))" - ] - }, - { - "cell_type": "markdown", - "id": "c927cce9", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial1_Solution_3637d20e.py)\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "id": "7f840990-ce82-4a7a-b700-51a40e48177e", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial1_Solution_8b3d4f01.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "5b59aa71", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: A Sub-region of the Map of `World3`**\n", - "\n", - "Here is a reduced diagram containing only some major variables in the model and their couplings:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d218991e", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 603, - "status": "ok", - "timestamp": 1682540490373, - "user": { - "displayName": "Sloane Garelick", - "userId": "04706287370408131987" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "display(Image(url=\"https://osf.io/download/h3mj2/\", width=250))\n", - "# modified from another copyrighted image from Limits To Growth (1972, page 97)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "l87rJWT5pwnG", - "metadata": { - "execution": {} - }, - "source": [ - "This image can be used to follow a *pathway* describing the flow of model variable dependencies to gain insight into how the model works (note this use of the word 'pathway' is distinct from that in 'socioeconomic pathways'). When a pathway comes back to itself, this is a termed a feedback pathway (or feedback loop) by which changes can be amplified or attenuated by the way the model couples distinct variables. Recall from W1D1 that there are two types of feedbacks: positives feedbacks (change in variable A causes a change in variable B, which in turn causes a change in variable A in the same direction as the initial change) and negative feedbaks (change in variable A causes a change in variable B, which in turn causes a change in variable A in the opposite direction as the initial change). \n", - "\n", - "Let's look at some important feedback pathways in the model that appear in this image (also see pg. 95 of [Limits of growth](http://www.donellameadows.org/wp-content/userfiles/Limits-to-Growth-digital-scan-version.pdf)): \n", - "- The two positive feedback loops involving births and investment generate the exponential growth behavior of population and capital, respectively.\n", - " - Investment drives industrial capital which drives industrial output which drives investment.\n", - " - Population drives births drives population.\n", - "- The two negative feedback loops involving deaths and depreciation tend to regulate this exponential growth.\n", - " - Industrial capital drives up depreciation which lowers industrial capital.\n", - " - Population drives deaths which lowers population.\n", - "\n", - "There is a clear and intricate web of dependencies between these various factors. Changes in one area, such as industrial investment, can have cascading effects through this system, ultimately influencing population size, health, and wellbeing. This underscores the interconnected nature of socio-economic systems and the environment." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "bea33392", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 2.2**\n", - "Based on the model variable dependancy pathway described above and in the image, can you describe a: \n", - "1. *Positive* feedback loop? \n", - "2. *Negative* feedback loop? " - ] - }, - { - "cell_type": "markdown", - "id": "94cbd780-6a62-44a3-ab81-1504b4ec0e42", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial1_Solution_9c4840e8.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "ead3ede2", - "metadata": { - "execution": {} - }, - "source": [ - "### A note on exponential growth in a bounded system\n", - "Consider a bounded system undergoing only positive feedback leading to exponential growth. The characteristic duration of growth until the system state reaches the system boundary is only weakly sensitive to the size of the boundary. For example, in the context of exponential resource-driven economic growth on Earth, reaching the boundary means exhausting its accessible physical resources. Ten times more or less of the starting amount of accessible resources only changes the time at which those resources are exhausted by a factor of 2 up or down, respectively. \n", - "\n", - "Physics demands that behind the exponential extraction of resources is an exponential use of an energy resource. In recent times on Earth, this has been fossil fuels, which are non-renewable. Legitimate concerns of peak oil in the late 1990s were quelled by the Shale revolution in the United States and other technological advances in oil and gas exploration and exploitation. These have increased (by a factor between 2 and 4) the total amount of known reserves that can be profitably exploited. While this increase is significant on an linear scale, it is negligible on an exponential scale. Looking forward, the largest estimates for how much larger accessible oil and gas reserves will be are within an order of magnitude of current reserves. Presuming resource-driven growth economics continues, whatever accessible oil and gass is left will then be exhausted within a short period of time (e.g. within a century). \n", - "\n", - "Exponential growth in a bounded system will often slow as it reaches the boundary because of boundary-sized feedback effects. In our case, demand growth for fossil fuels is starting to slow with the development of renewable energy sources. There still substantial uncertainty about how these feedbacks will play out. Some questions to consider: \n", - "- whether the transition to renewable energy sources can happen before we exhaust the associated non-renewable resources. \n", - "- Once transitioned, whether the non-renewable resource use (e.g. of rare-earth metals) needed to sustain the renewable energy sector is sustainable in a growth-based economics\n", - "- Once transitioned, whether this renewable energy resource might not slow, but instead accelerate the extraction of all non-renewable resources (see [Jevon's paradox](https://en.wikipedia.org/wiki/Jevons_paradox))." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "Hf3NItAL2qYj", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: Working with `pyworld3`**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "fef13943", - "metadata": { - "execution": {} - }, - "source": [ - "In this section you will use a `python` implementation of the `World3` called `pyworld3`. This model is openly accessible [here](https://github.com/cvanwynsberghe/pyworld3).\n", - "\n", - "We have pre-defined a plotting function that also runs `pyworld3`, that you will use in this section. The plotting function has two inputs: \n", - "- **nri_factor**: the initial amount of non-renewable resources. For example, this could include coal, natural gas and oil.\n", - "- **new_lifetime_industrial_capital**: a perturbed value of the lifetime of industrial capital to which the system will be perturbed at the perturbation year. For example, this variable could be used to represent a transition from fossil fuel-burning power plants to lower-emitting technologies.\n", - "\n", - "In addition, you need to set the end year of the simulations you wish to conduct. In this example, you should stop the simulations at 2100, which is also when most IPCC Earth System Model projections end." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "860dbb98", - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "maxyear = 2100" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "58291cec", - "metadata": { - "execution": {} - }, - "source": [ - "In this section, you will use `pyworld3` to assess changes associated with three different scenarios:\n", - "1. **Business-As-Usual (BAU)**: assumes continued growth based on historical trends and specified amount of non-renewable resources \n", - "2. **Abundant Resources (BAU3)**: same as BAU but with triple the amount of initial non-renewable resources \n", - "3. **BAU3 with Active Cap on Production**: same as BAU3 but a step decrease in the lifetime of industrial capital, by imposing a reduction from 14 to 8 years in 2025.\n", - "\n", - "For each scenario, you will plot and assess changes in multiple variables:\n", - "- **Death rate**: number of deaths per 1000 people\n", - "- **Deaths**: number of deaths\n", - "- **Pollution**: index of persistent pollution (fraction of peristent pollution in 1970 = 1.36e8 pollution units)\n", - "- **Population**: population (people)\n", - "- **Food**: food production per capita (vegetable-equivalent kilograms/person-year)\n", - "- **Industry**: industrial output per capita (dollars/person-year)\n", - "- **Resource**: nonrenewable resource fraction remaining (of 1e12 resource units). This includes all nonrenewable resources (e.g. ecosystems).\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "0f3c6305", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.1: Original (Business-As-Usual - *BAU*) Scenario**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "a7f9ca83", - "metadata": { - "execution": {} - }, - "source": [ - "The Business-As-Usual (*BAU*) scenario assumes continued growth based on historical trends. In this scenario there is specified amount of accessible, remaining non-renewable resources (normalized to 1 in the plots)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f646a99e", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 6633, - "status": "ok", - "timestamp": 1681919663027, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "world3 = World3(year_max=maxyear) # default value for nri_factor is 1\n", - "run_and_plot(world3)\n", - "# plt.savefig(\"world3_timeseries_case_1.png\",transparent=True,bbox_inches=\"tight\",dpi=300)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "b4c58f02", - "metadata": { - "execution": {} - }, - "source": [ - "Initially, industrial production (rising orange), food per capita (rising green) and population (rising red) experience growth. However, as non-renewable resources start rapidly decline (falling blue), industrial production begins to decline (falling orange). This decline subsequently causes a decrease in food production (falling green), which causes an increase in the death rate (rising pink) and a decline in population (falling red) during the latter half of the 21st century. This scenario is resource-constrained because the collapse in growth that occured in the middle of the 21st century was initially driven by a decline in available resources.\n", - "\n", - "For comparison, the red dashed line represents the population projection for the IPCC baseline scenario of SSP2, a 'Middle of the road' scenario in which current trends continue (effecively the business-as-usual SSP scenario). Note the difference with the population projection of `world3`'s BAU scenario. While a priori unclear, the origin of this discrepancy likely arises from the different values that were chosen for the many parameters as well as which components and interactions were assumed when designing a world model or IAM. One obvious difference is the assumption of continued economic growth (decoupled from resource use) in SSP2. The large prediction uncertainty inherent in this modelling activity limits its predictive power. However, characteristic mechanisms (e.g. feedback pathways) are shared across these very different models and imply characteristic phenomena (e.g. population saturation)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "2d246e29", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.2: *BAU3* - An Abundant Resource Scenario**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "5379aa24", - "metadata": { - "execution": {} - }, - "source": [ - "The previous scenario was resource-constrained, as the collapse in growth was driven by the limited available resources in the middle of the 21st century. In this section you will create a scenario that is not purely resource-constrained by initializing the `pyworld3` with triple the initial non-renewable resources of the *BAU* scenario. As such, let's call this new scenario *BAU3*." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "dbc89d11-1d85-453d-8a9a-ef9fde94c0f7", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 3.2**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "fabc9999", - "metadata": { - "execution": {} - }, - "source": [ - "To create the *BAU3* scenario you will need to triple the initial resources (`nri_factor`). Tripling the initial resources could represent the effect of increased efficiency in resource extraction via approaches such as changes in crop yields (as has been observed over recent decades), or the \"learning-by-doing\" effect that productivity is achieved through practice and innovations (as seen in the economics of many energy technologies). \n", - "\n", - "**Based on the input parameters of the `run_and_plot()` function discussed above, run the *BAU3* scenario and plot the output.** " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "79521d33", - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "run_and_plot(world3, nri_factor=3)\n", - "# plt.savefig(\"world3_timeseries_case_2.png\",transparent=True,bbox_inches=\"tight\",dpi=300)" - ] - }, - { - "cell_type": "markdown", - "id": "53b96171", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 5525, - "status": "ok", - "timestamp": 1681919668522, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial1_Solution_cf331b68.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "588eee43", - "metadata": { - "execution": {} - }, - "source": [ - "Notice that the decline in industrial production (orange) still occurs in this scenario, but it is delayed by a few decades due to the larger initial resource pool (blue). However, unlike the previous case that was resource-constrained, the extended period of exponential industrial growth (orange) in this scenario leads to a significant increase in pollution (purple). As a result, the population crash (red), which is now driven by both increased pollution (purple) and diminishing resources (blue), is faster and more substantial than the *BAU* scenario's population crash.\n", - "\n", - "In this BAU3 scenario, the population growth and crash more closely resembles the population projection for the IPCC baseline scenario of SSP2 than the BAU scenario, but there is still a contrast between the two population projections. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "7db71fa7", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.3: *BAU3* with an Active Cap on Production**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "04b5cc26", - "metadata": { - "execution": {} - }, - "source": [ - "In the BAU and BAU3 scenarios, we assessed the impact of changes in initial resource availability (`nri_factor`). However, another important variable to consider is the lifetime of industrial capital (`new_lifetime_industrial_capital`). Economic growth is likely to result in increaesd energy demand, but it's essential to find a way to avoid high levels of climate warming while also meeting the growing world energy demands. To do so would require rapidly transforming current capital infrastructure in our energy system so that it relies on technologies that produce significantly less greenhouse gas emissions. For further details of IAM transitioning with reductions in lifetime capital see [Rozenberg et al. *Environ. Res. Lett.* (2015)](https://iopscience.iop.org/article/10.1088/1748-9326/10/9/095006/pdf).\n", - "\n", - "In this section, you will assess the effects of reducing the lifetime of industrial capital. We will use the same BAU3 scenario with triple the initial resources, but will adjust the `new_lifetime_industrial_capital` variable to reflect a reduced lifetime of industrial capital. Specifically, this scenario turn down production abruptly via a step decrease in the lifetime of industrial capital, by imposing a reduction from 14 to 8 years in 2025." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "51ed70f5", - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 10307, - "status": "ok", - "timestamp": 1681919678822, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "world3 = World3(pyear=2025, year_max=2100)\n", - "run_and_plot(world3, nri_factor=3, new_lifetime_industrial_capital=8)\n", - "# plt.savefig(\"world3_timeseries_case_3.png\",transparent=True,bbox_inches=\"tight\",dpi=300)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "8551873d", - "metadata": { - "execution": {} - }, - "source": [ - "Notice that by reducing production (orange), pollution levels are also reduced (purple), which in turn limits the decline in population to a plateau (red). This approach preserves a significant amount of non-renewable resource (blue). However, over time, the asymptotic death rate (pink) gradually increases, approaching that of the BAU3 scenario without the reduced production. As a result, the population plateau is not sustained, and the population continues to decline slowly beyond the year 2100." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "759bcdbd", - "metadata": { - "execution": {} - }, - "source": [ - "Additionally, dropping industrial output (as we did in this scenario) negatively impacts our ability to develop new technologies, e.g. those needed for decarbonization (c.f. the article [Decarbonizing the downturn: Addressing climate change in an age of stagnation by Copley, 2022](https://journals.sagepub.com/doi/full/10.1177/10245294221120986). This stagnation scenario is a central challenge faced in the narrative of Shared Socio-economic Pathway 3 (SSP3 *Regional Rivary*)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "d55e6087", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 3.3:**\n", - "1. What scenarios might lead to a drop in the lifetime of industrial capital?\n", - "2. What are some important features of the world, society, and/or economy that are missing in this model?" - ] - }, - { - "cell_type": "markdown", - "id": "7ecc0363-7b2a-4b9b-a5b1-f3989a4bae6f", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial1_Solution_4f5777c0.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "1e328e57", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.4: Validity and Limitations of `pyworld3`**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "a1498d51", - "metadata": { - "execution": {} - }, - "source": [ - "Validity analyses for `pyworld3` are presented in the `pyworld3` github repository. For example, shown below is the `pyworld3` standard run simulation output (shown in the same colors we've been using throughout this tutorial) compared to the original World3 model output (shown in black):" - ] - }, - { - "cell_type": "markdown", - "id": "36924236-12d2-4063-b59f-60242179b300", - "metadata": { - "execution": {} - }, - "source": [ - "![results](https://github.com/cvanwynsberghe/pyworld3/raw/main/img/result_standard_run.png)|\n", - "-" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "5680c6c0", - "metadata": { - "execution": {} - }, - "source": [ - "Overall, the `pyworld3` simulation output replicates well the original World3 simulation.\n", - "\n", - "Note that there are limitations to the `world3` model that are important to remember:\n", - "\n", - "- There is no spatial structure. Spatial structure is important, as it allows for distinct regional solutions that aid or hinder global cooperation\n", - "- The model ignores technology innovation, including innovations in adaptation and mitigation\n", - "- There is an *ad hoc* relationship between economic growth, investment in health services, and changes in life expectancy\n", - "- The model only includes a monolithic non-renewable resource (e.g. doesn't break down the resource into renewable and non-renewable classes)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "95af03ec-7548-429c-97ac-eb111e88add4", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you explored a socio-economic model based on resource extraction. This is the conceptual basis of the world models within IAMs used in IPCC projections. \n", - "\n", - "You examined this interplay through `World3`, a *World model* which is a class of model similar to IAMs. You followed several variable dependency pathways within this model to identify some positive and negative feedback loops, and then you used this model to simulate 3 future scenarios which varied in their amount of initially available non-renewable resources and the lifetime of capital. Through these simulations you explored the factors driving current population growth, and its future projected decline or stabilization. In particular, you found rapid resource consumption can have negative impacts by exhausting these resources and/or by increasing pollution and reducing human health, thus highlighting the potential threats of unregulated resource extraction on a finite planet.\n", - "\n", - "Finally, you learned about some of the limitations of models like `World3`, as they don't include some important natural and socio-economic variables. By exploring these complex concepts, you are now better equipped to engage with discussions on climate change, resource management, and sustainable economic growth." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "41e7e135", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "The data for the IAMs used in this tutorial, as well as the main simulations of the IAMs used in the IPCC reports can be accessed h[here](https://tntcat.iiasa.ac.at/SspDb/dsd). \n", - "\n", - "The `pyworld3` model and data used in this tutorial can be accessed [here](https://github.com/cvanwynsberghe/pyworld3)." - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D3_Tutorial1", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2.ipynb b/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2.ipynb deleted file mode 100644 index 4e754898a..000000000 --- a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2.ipynb +++ /dev/null @@ -1,1187 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/W2D3_Tutorial2.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial 2: Transition Goals and Integrated Assessment Models**\n", - "\n", - "**Week 2, Day 3: IPCC Socio-economic Basis**\n", - "\n", - "**Content creators:** Maximilian Puelma Touzel\n", - "\n", - "**Content reviewers:** Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina DuplexLaura Paccini, Sloane Garelick, Abigail Bodner, Manisha Sinha, Agustina Pesce, Dionessa Biton, Cheng Zhang, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Content editors:** Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Production editors:** Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan\n", - "\n", - "**Our 2023 Sponsors:** NASA TOPS and Google DeepMind" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Tutorial Objectives**\n", - "\n", - "In this tutorial, you will learn about the Dynamic Integrated Climate-Economy (DICE) model, a cornerstone in the history of climate economics. This is one the first 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.\n", - "\n", - "You will explore the inner workings of the DICE model, starting with the foundational principles of economics: *utility* and *welfare* functions. You will also learn how these functions aggregate and weight the satisfaction derived from consumption across different societal groups. You will also learn how the these functions incorporate uncertain future utility into decision-making through *discount rates*. Valuing future states of the world allows the DICE model to place a value on its projections of future scenarios.\n", - "\n", - "Later in the tutorial you will learn about damage functions, which combine climatological and economic knowledge to estimate how climate changes will affect economic productivity and the resultant well-being of society.\n", - "\n", - "Finally, you will diagnose optimal planning within the DICE model, determining the best strategies for savings and emissions reduction rates (where _best_ is with respect to a chosen utility and welfare function). \n", - "\n", - "The overall objective of this tutorial is to provide a technical understanding of how parameters related to the distribution of value in society impact the optimal climate policy within a relatively simple IAM." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Setup**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1460, - "status": "ok", - "timestamp": 1682429063027, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "# imports\n", - "from IPython.display import display, HTML\n", - "import seaborn as sns\n", - "import matplotlib.pyplot as plt\n", - "import pandas as pd\n", - "import numpy as np\n", - "import dicelib # https://github.com/mptouzel/PyDICE" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Figure settings\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "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\n", - "sns.set_style(\"ticks\", {\"axes.grid\": False})\n", - "params = {\"lines.linewidth\": \"3\"}\n", - "plt.rcParams.update(params)\n", - "display(HTML(\"\"))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Helper functions\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "code_folding": [ - 0 - ], - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Helper functions\n", - "\n", - "\n", - "def plot_future_returns(gamma, random_seed):\n", - " fig, ax = plt.subplots(1, 2, figsize=(8, 4))\n", - " np.random.seed(random_seed)\n", - " undiscounted_utility_time_series = np.random.rand(time_steps)\n", - " ax[0].plot(undiscounted_utility_time_series)\n", - "\n", - " discounted_utility_time_series = undiscounted_utility_time_series * np.power(\n", - " gamma, np.arange(time_steps)\n", - " )\n", - " ax[0].plot(discounted_utility_time_series)\n", - "\n", - " cumulsum_discounted_utility_time_series = np.cumsum(discounted_utility_time_series)\n", - " ax[1].plot(\n", - " cumulsum_discounted_utility_time_series * (1 - gamma),\n", - " color=\"C1\",\n", - " label=r\"discounted on $1/(1-\\gamma)=$\"\n", - " + \"\\n\"\n", - " + r\"$\"\n", - " + str(round(1 / (1 - gamma)))\n", - " + \"$-step horizon\",\n", - " )\n", - " cumulsum_undiscounted_utility_time_series = np.cumsum(\n", - " undiscounted_utility_time_series\n", - " )\n", - " ax[1].plot(\n", - " cumulsum_undiscounted_utility_time_series\n", - " / cumulsum_undiscounted_utility_time_series[-1],\n", - " label=\"undiscounted\",\n", - " color=\"C0\",\n", - " )\n", - " ax[1].axvline(1 / (1 - gamma), ls=\"--\", color=\"k\")\n", - "\n", - " ax[0].set_ylabel(\"utility at step t\")\n", - " ax[0].set_xlim(0, time_steps)\n", - " ax[0].set_xlabel(\"time steps into the future\")\n", - " ax[1].legend(frameon=False)\n", - " ax[1].set_ylabel(\"future return (normalized)\")\n", - " ax[1].set_xlabel(\"time steps into the future\")\n", - " ax[1].set_xlim(0, time_steps)\n", - " fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Video 1: Title\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "cellView": "form", - "execution": {}, - "tags": [ - "hide-input" - ] - }, - "outputs": [], - "source": [ - "# @title Video 1: Title\n", - "# Tech team will add code to format and display the video" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 1: Background on IAM Economics and the DICE Model**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The [Dynamic Integrated Climate-Economy (DICE)](https://www3.nd.edu/~nmark/Climate/DICE-simplified_2019.pdf) was the first prominent Integrated Assessment Model (IAM), a class of models economists use to inform policy decisions. Recall that IAMs couple a climate model to an economic model, allowing us to evaluate the two-way coupling between economic productivity and climate change severity. DICE is too idealized to be predictive, like `world3`, but DICE is still useful as a sandbox for exploring climate policy ideas, which is how we will use it here.\n", - "\n", - "Let's begin with a brief description of IAMs and the DICE model:\n", - "\n", - "- DICE is a fully aggregated (i.e., non-spatial) model, but otherwise contains the essence of many key components of more complex IAMs. \n", - "- Unlike `world3`, which we encountered in Tutorial 1, the world models used in IAMs usually have *exogeneous* (externally set) times series for variables, in addition to fixed world system parameters. These exogeneous 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 time series of these exogeneous 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 exogeneous variables over some fixed time window. In DICE, there are two exogeneous parameters:\n", - " - **$\\mu(t)$**: time-dependent mitigation rate (i.e. emissions reduction), which limits warming-caused damages\n", - " - **$S(t)$**: savings rate, which drives capital investment \n", - "- The choices for the standard values of the parameters used in the DICE models have been critisized, and updated versions have been analyzed and proposed ([Hansel et al. 2020](https://www.nature.com/articles/s41558-020-0833-x);[Barrage & Nordhaus 2023](https://www.nber.org/papers/w31112)). Here, we look at the standard DICE2016 version of the model.\n", - "\n", - "All DICE models (and 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. To understand this approach and how it is used in the DICE model, it is important to begin with a brief overview of some fundamental concepts. One such 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)." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 1.1: Utility**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "**Utility**, or economic value, is the total degree of satisfaction someone gets from using a product or service. In the context of socioeconomic climate impacts, utility of a state of the world for an individual is quantified by the consumption conferred (i.e. capital consumed; you can think of money as a placeholder for capital). \n", - "\n", - "Reducing value to consumption may seem restrictive, and it is, but it's how most economists see the world (not all! c.f. [Hüttel, Balderjahn, & Hoffmann,*Welfare Beyond Consumption: The Benefits of Having Less* Ecological Economics (2020)](https://www.sciencedirect.com/science/article/abs/pii/S0921800919318683)). That said, economists don't think utility is identical to consumption. Let's work through the assumptions in a standard presentation of the economics that links the two." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Section 1.1.1: Utilities at Different Levels of Consumption**\n", - "It's natural that the utility of consumption is relative to the level of consumption. A crude illustration here is that the value of a meal is higher to those who haven't eaten recently than for those who have. Thus, we assume units of consumption at low values confer more utility than those at high values. In other words:\n", - "\n", - "- **A unit of consumption has less value to an individual, the more that individual tends to consume overall**\n", - "\n", - "The one parameter for the utility function is **elasticity** ($\\alpha$), which is the measure of a variable's sensitivity to change in another variable, in this case, how utility changes with consumption. \n", - "\n", - "We can plot the utility function for different values of elasticity to assess how the sensitivity of utility to changes in comsumption varies with different elasticity values." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 2277, - "status": "ok", - "timestamp": 1682429066684, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "c = np.linspace(0, 10, 1000)\n", - "for alpha in [0, 0.1, 0.5, 1.0, 1.45]:\n", - " if alpha == 1:\n", - " ax.plot(c, np.log(1 + c), label=r\"$\\alpha=\" + str(alpha) + \"$\")\n", - " elif alpha == 1.45:\n", - " ax.plot(\n", - " c,\n", - " ((c + 1) ** (1 - alpha) - 1) / (1 - alpha),\n", - " label=r\"$\\alpha=\" + str(alpha) + \"$(DICE)\",\n", - " )\n", - " else:\n", - " ax.plot(\n", - " c,\n", - " ((c + 1) ** (1 - alpha) - 1) / (1 - alpha),\n", - " label=r\"$\\alpha=\" + str(alpha) + \"$\",\n", - " )\n", - "\n", - "ax.plot([0, 10], [0, 10], \"k--\")\n", - "ax.legend(frameon=False)\n", - "ax.set_xlabel(\"consumption, c\")\n", - "ax.set_ylabel(\"utility, u(c)\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The plot you just made shows the relationship between consumption and utility for four different values of elasticity. For all values of elasticity, as consumption increases, the utility also increases, as we discussed above. However, let's make some observations about how changes in elasticity affect this relationship. For lower elasticity values (i.e. $\\alpha$ = 1 shown in blue) an increase in consumption results in a stronger increase in utility. In constrast, for high elasticity values (i.e. $\\alpha$ = 1.45 shown in red), such as what is used in the DICE model, an increase in consumption results in only a smaller increase in utility." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "#### **Questions 1.1.1**\n", - "1. What do you think the function looks like for $\\alpha=0$?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_6aa285a9.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Section 1.1.2: Utilities Over a Population**\n", - "In the case that individuals are of the same type, i.e. a population of such individuals, we assume that \n", - "* **Utilities of individuals of the same type sum**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Section 1.1.3: Utilities Over Time**\n", - "Since our actions now affect those in the future (the socalled *intertemporal choice problem*), we can't decide what is best to do at each time point by looking only at how it affects the world at that time. We need to incorporate utilities from the future into our value definition to know what is best to do now. How should we combine these? \n", - "\n", - "Economists and decision theorists generally operate under the assumption that the value of a unit of utility decreases as it is received further into the future. This assumption is based on the recognition of the inherent uncertainty surrounding future events and the finite probability that they may not materialize. In other words:\n", - "* **Utilities in the near future are valued more than those in the far future**\n", - "\n", - "This devaluation of the future is called *temporal discounting*. You can imagine that there is a lot of debate about how and even whether to do this in climate policy design! \n", - "\n", - "The standard approach to incorporate temporal discounting into the model is to multiply the utilities of future benefits and costs by a **discount factor** ($\\gamma$ ('gamma'), which is a number just less than 1, e.g. 0.95). The discount factor is raised to the power of time (in years) into the future to give the discount rate at that future time: \n", - "- after 1 year $(0.95)^1=0.95$\n", - "- after 2 years $(0.95)^2=0.90$\n", - "- after 10 years $(0.95)$10$=0.60$\n", - "\n", - "The _return_ is the sum of future utilities, which is taken as the value of that future projection. If these utilies are discounted, their sum is called the _discounted return_. The following code will show an illustration of the effect of temporal discounting on future utilities and the return up to a given number of time steps into the future for a discount factor of $\\gamma$ = 0.95." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "tags": [] - }, - "outputs": [], - "source": [ - "time_steps = 300\n", - "gamma = 0.95\n", - "random_seed = 1\n", - "plot_future_returns(gamma, random_seed)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In both plots, the blue lines are undiscounted case (i.e. without the effect of temporal discounting) and the orange lines are the discounted case (i.e. including the effect of temporal discounting). \n", - "\n", - "The figure on the left shows utility at each time step. In both the undiscounted scenario (blue) and the discounted scenario (orange), projected utilities are variable and uncertain. Notice that in the unsidcounted case, the average size of these utilities stays the same. In contrast, in the discounted case the typical size of utility rapidly decreases to zero, reflecting the effect of temporal discounting (i.e. the devaluation of utilities in the far future). \n", - "\n", - "The figure on the right shows changes in return (i.e. the cumulative sum of future utilities) over time. The black dashed line shows the effective time horizon beyond which rewards are ignored in the discounted case for this chosen value of the discount factor, $\\gamma$ (this time is set by the natural convention of when the return gets to a fraction ($1-1/e\\approx0.64$) of the final value). Beyond the time horizon, the future discounted return (orange) reaches saturation, and no additional utility from further time steps contributes to the overall value. In contrast, in the undiscounted case (blue), all future times are equally important, and the return grows linearly with the maximum time considered for computing utilities. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 2: Damage Functions**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now that we have familiarized ourselves with some of the main components of IAMs and the DICE model, we can begin to explore another important component: the **damage function**. The damage function is a central model component that connects climate and socio-economic processes in integrated assessment models.\n", - "\n", - "Damage functions are the objects in IAMs that dictate how changes in temperature affect production (e.g. through direct weather-related damages). They play a crucial role in determining the model's projections.\n", - "\n", - "The standard form is a deterministic continuous function that maps changes in temperature, $\\Delta T$, to the fraction of productivity that is destroyed by climate change every year, $\\Omega$. The standard parametrization is a quadratic dependence \n", - "$$\\Omega=a \\times (\\Delta T)^2$$\n", - "where $a$ is some small constant (e.g. 0.001) whose value is set by regression of GDP and temperature over geographic and historical variation. Let's plot this function. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 805, - "status": "ok", - "timestamp": 1682429069667, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots()\n", - "T = np.linspace(0, 4, 1000)\n", - "a1DICE = 0.00236\n", - "a2 = 2.00\n", - "for a1 in [a1DICE, 1e-2, 1e-1]:\n", - " ax.plot(\n", - " T,\n", - " a1 * (T**a2),\n", - " label=r\"$a_1=\" + str(a1) + \"$\" + (\"(DICE2023)\" if a1 == a1DICE else \"\"),\n", - " )\n", - "ax.legend(frameon=False)\n", - "ax.set_xlabel(\"temperature change, $\\Delta T$\")\n", - "ax.set_ylabel(\"fraction productivity destroyed\")\n", - "ax.set_ylim(0, 0.5)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Observe how larger temperature changes lead to a larger fraction of productivity destroyed due to the damages caused by that temperature. The damage at a given temperature scales linearly with the parameter $a_1$, and exponentially with the parameters $a_2$." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "There are at least two fundamental problems with damage functions (for more see [*The appallingly bad neoclassical economics of climate change* by S. Keen in *Globalizations* (2020)](https://www.tandfonline.com/doi/full/10.1080/14747731.2020.1807856)):\n", - "1. As mathematical model objects, they are likely too simple to be useful predictors in characterizing climate damages in sufficient complexity. \n", - "2. They arise from a poorly validated model-fitting procedure. In particular, it relies on ad hoc functional forms and the relevance of historical and geographical variability to future variability." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Questions 2**\n", - "1. Pick an assumption that is made about the relationship between temperature and economic damage in arriving at a conventional damage function (e.g. that it is: _deterministic_, _continuous_, _constant in time_, _functional_ (instead of dynamical), ...) and explain why you think that assumption might be unrealistic for a specific sector of the economy or a specific region of the planet.\n", - "2. Can you think of a specific way that temperature variation might cause variation in GDP that could have been significant in structuring the historical and/or geographical covariation of the two variables? How about a causal relationship that will not have been significant in historical or geographic variation up to now, but is likely to be significant as temperatures continue to rise and we experience more extreme climates? " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_6a1be695.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Despite these problems highlighting a pressing need to improve how we formulate climate damages, damage functions allow economists within the neoclassical paradigm to start seriously considering the damaging effects of climate change. After a few decades of economists using overly optimistic damage functions that downplayed the damaging effects of climate change, current research on damage functions is striving to incorporate more realism and better estimation.\n", - "\n", - "For more contemporary damage functions see [van der Wijst et al. *Nat. Clim. Change* (2023)](https://www.nature.com/articles/s41558-023-01636-1). Note that even this modern publication is hindered by the [McNamara Fallacy](https://en.wikipedia.org/wiki/McNamara_fallacy) of leaving out things that are hard to measure. The authors state: \"The climate change impacts did not include potential losses originated in ecosystems or in the health sector. This is motivated by the difficulty in addressing the non-market dimension of those impacts with a ‘market-transaction-based’ model such as CGE. Also, catastrophic events were not considered, even though some ‘extremes’ (riverine floods) were included.\"" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.1: IAM Model Summary** \n", - "\n", - "We've now explored both the utility function and damage function components of IAMs. Before we move on to actually running the DICE model, let's summarize what we've learned so far about IAMs, specifically regarding the economy and climate models:\n", - "\n", - "The economy model in most IAMs is a capital accumulation model. \n", - "- Capital ($K$) combines with a laboring population and technology to generate productivity ($Y$) that is hindered by climate damage. \n", - "- A savings rate, $S$, drives capital accumulation, while the rest is consumed. Welfare is determined by consumption.\n", - "- Climate action is formulated by a mitigation rate, $\\mu$, which along with the savings rate, $S$, are the two exogeneous control parameters in the model and are used to maximize welfare.\n", - "\n", - "The climate model in DICE interacts with the economy model via the following equation: \n", - "$$E_\\mathrm{ind}=(1-\\mu)\\sigma Y,$$ \n", - "- Productivity ($Y$) generates industrial emissions ($E_\\mathrm{ind}$), where the $1-\\mu$ factor accounts for a reduction of the carbon intensity of production, $\\sigma$, via supply-side mitigation measures (e.g. increased efficiency). \n", - "- The productivity $Y$ rather than output production ($Q$) is used here because damages aren't included. \n", - "- Damages aren't included because the emissions produced in the process of capital production occur before climate change has a chance to inflict damage on the produced output. \n", - "- These industrial emissions combine with natural emissions to drive the temperature changes appearing in the damage function, closing the economy-climate loop. " - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 2.2: Optimal Planning**\n", - "The goal of the model is to maximize the overall value of a projected future, $V$, within the bounds of mitigation rate, $\\mu$, and savings rate, $S$, time courses (while considering constraints on $\\mu$ and $S$). This approach is known as **optimal planning**. But why does this \"sweet spot\" in which overall value is maximized exist? Increasing savings boosts investment and productivity, but higher production leads to higher emissions, resulting in increased temperature and damages that reduce production. Mitigation costs counterbalance this effect, creating a trade-off. As a result, there typically exists a meaningful joint time series of $\\mu_t$ and $S_t$ that maximizes $V$. Due to the discount factor $\\gamma$, $V$ depends on the future consumption sequence (non-invested production) within a few multiples of the time horizon, approximately $1/(1-\\gamma)$ time steps into the future." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "We gone over many variables so far in this tutorial. Here is a list of variables used fore easier reference:\n", - "- $K$ capital\n", - "- $Y$ productivity\n", - "- $S$ savings rate\n", - "- $\\mu$ mitigation rate\n", - "- $E$ emissions\n", - "- $\\sigma$ carbon intensity of production\n", - "- $Q$ production\n", - "- $\\gamma$ discount factor\n", - "- $V$ value\n", - "\n", - "If you'd like to explore the mathematical equations behind these models in more detail, please refer to the information in the \"Further Reading\" section for this day." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Section 3: DICE Simulations**\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Now, let's move to the DICE model that gives us some control over our emissions and consumption to see the effect of varying the parameters arising from the above design choices.\n", - "\n", - "I've forked an existing `Python` implementation of the [DICE2016 model](https://github.com/hazem2410/PyDICE) and refactored it into a class (defined in [`dicelib.py`](https://github.com/mptouzel/PyDICE/blob/master/dicelib.py)) and made a few other changes to make it easier to vary parameters. We'll use that [forked version](https://github.com/mptouzel/PyDICE/) in this tutorial.\n", - "Note that the DICE model was recently updated ([DICE2023](https://www.nber.org/papers/w31112)).\n", - "\n", - "The model equations are described in a [document](https://github.com/hazem2410/PyDICE/blob/master/PyDICE2016.pdf) associated with the exising `Python` implementation." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.1: Case 1 Standard Run**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's run the standard run of the DICE model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 72615, - "status": "ok", - "timestamp": 1682429142278, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "dice_std = dicelib.DICE() # create an instance of the model\n", - "dice_std.init_parameters()\n", - "dice_std.init_variables()\n", - "controls_start_std, controls_bounds_std = dice_std.get_control_bounds_and_startvalue()\n", - "dice_std.optimize_controls(controls_start_std, controls_bounds_std);" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Before assessing the results, let's first check that the optimal control solution is within the bounds we set. To do so, let's assess the mitigation rate and savings rate:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 757, - "status": "ok", - "timestamp": 1682429143004, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots(1, 2)\n", - "max_year = 2100\n", - "TT = dice_std.TT\n", - "NT = dice_std.NT\n", - "upp, low = zip(*controls_bounds_std[:NT])\n", - "ax[0].plot(TT, dice_std.optimal_controls[:NT], label=\"optimal\")\n", - "ax[0].plot(TT, upp, \"k--\", label=\"bounds\")\n", - "ax[0].plot(TT, low, \"k--\")\n", - "ax[0].set_ylabel(\"mitigation rate\")\n", - "ax[0].set_xlim(2000, max_year)\n", - "ax[0].legend(frameon=False)\n", - "upp, low = zip(*controls_bounds_std[NT:])\n", - "ax[1].plot(TT, dice_std.optimal_controls[NT:])\n", - "ax[1].plot(TT, upp, \"k--\")\n", - "ax[1].plot(TT, low, \"k--\")\n", - "ax[1].set_ylabel(\"savings rate\")\n", - "ax[1].set_xlabel(\"year\")\n", - "ax[1].set_xlim(2000, max_year)\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 3.1**\n", - "1. Please change `max_year` to 2500 in the cell above to see what happens after 2100. What does the mitigation rate do?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "fig, ax = plt.subplots(1, 2)\n", - "max_year = ...\n", - "TT = dice_std.TT\n", - "NT = dice_std.NT\n", - "upp, low = zip(*controls_bounds_std[:NT])\n", - "ax[0].plot(TT, dice_std.optimal_controls[:NT], label=\"optimal\")\n", - "ax[0].plot(TT, upp, \"k--\", label=\"bounds\")\n", - "ax[0].plot(TT, low, \"k--\")\n", - "ax[0].set_ylabel(\"mitigation rate\")\n", - "# Set limits\n", - "_ = ...\n", - "ax[0].legend(frameon=False)\n", - "upp, low = zip(*controls_bounds_std[NT:])\n", - "ax[1].plot(TT, dice_std.optimal_controls[NT:])\n", - "ax[1].plot(TT, upp, \"k--\")\n", - "ax[1].plot(TT, low, \"k--\")\n", - "ax[1].set_ylabel(\"savings rate\")\n", - "ax[1].set_xlabel(\"year\")\n", - "# Set limits\n", - "_ = ...\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_6358a4c5.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_79cb322d.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "\n", - "The model incorporates the effects of negative emission technologies by allowing the mitigation rate (via the bounds) to exceed 1 around the year 2140. It is worth noting that the solution explicitly utilizes this feature and would do so even before 2100 if permitted. The decision to include this behavior was made by the modellers who realized that it enabled feasible solutions for the higher forcing SSP scenarios that were previously unattainable.\n", - "\n", - "At the time, there was a lively debate surrounding this decision, although it was largely in favor of allowing mitigation rates greater than 1. As a result, such rates have become a standard feature in many models for high forcing regimes. However, it is important to acknowledge that there have been arguments against this practice, as discussed in [Anderson & Peters, 2006](https://DOI:10.1126/science.aah45).\n", - "\n", - "In the final two tutorials, we will explore sociological aspects such as these.\n", - "\n", - "Now, let's examine the remaining variables of the DICE model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 1122, - "status": "ok", - "timestamp": 1682429144121, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "dice_std.roll_out(dice_std.optimal_controls)\n", - "dice_std.plot_run(\"standard run\")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "In this plot, the mitigation rate we looked at earlier is now referred to as the \"Em rate\" (orange line), which closely follows the patter of the carbon price (green line). Similarly, the rate of CO2 emissions (gray line) aligns with the industrial emissions (red line). Cumulative emissions (pink line) reach their peak around 2090, considering that negative emission technologies (NETs) are not employed until 2140." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.2: Case 2 Damage Functions**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The rate at which we increase our mitigation efforts in the standard scenario depends on the projected damage caused by climate change (brown line in the plot above), which is determined by the parameters of the damage function. The question is, how responsive is our response to these parameters?" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 3.2**\n", - "Change the strength of the nonlinearity in the damage function by changing the exponent from 2 to 3." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "for a3 in [2, 3]:\n", - " dice = dicelib.DICE()\n", - " dice.init_parameters(a3=a3)\n", - " dice.init_variables()\n", - " controls_start, controls_bounds = dice.get_control_bounds_and_startvalue()\n", - " dice.optimize_controls(controls_start, controls_bounds)\n", - " dice.roll_out(dice.optimal_controls)\n", - " dice.plot_run(\"damage function exponent, a3=\" + str(a3))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 144928, - "status": "ok", - "timestamp": 1682429289045, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_8b4fd015.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 3.2**\n", - "1. What are the main differences between these two projections?" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_7b92403d.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "IAMs model climate damages as affecting productivity only in the year in which they occur. What if the negative effects on productivity persist into the future? A persistence time can be added to damages such that damage incurred in one year can continue affecting productivity into following years (c.f. [Schultes et al. *Environ. Res. Lett.* (2021)](https://iopscience.iop.org/article/10.1088/1748-9326/ac27ce/pdf); [Hansel et al. *Nat. Clim. Change* (2020)](https://eprints.lse.ac.uk/105699/1/Climate_economics_support_for_the_UN_climate_targets_2.pdf)). These effects are not negligible, but are absent from current IAMs used by the IPCC." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.3: Case 3 Discount Rate**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "The value definition includes exponential temporal discounting (i.e. devaluation of utilities over time) at a rate of r = 1.5% per year so that utility obtained $t$ years into the future is scaled down by $1/(1+r)^t$. What if we set this rate lower so that we don't down scale as quickly (i.e. utilities have more value for longer) and incorporate more in the value definition of what happens in the future when we make decisions?" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Coding Exercise 3.3**\n", - "Change the discount rate from 1.5% to 0.5% (c.f. [Arrow et al. *Science* (2013)](https://www.science.org/doi/10.1126/science.1235665))." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {} - }, - "outputs": [], - "source": [ - "for prstp in [0.015, 0.005]:\n", - " dice = dicelib.DICE()\n", - " dice.init_parameters(prstp=prstp)\n", - " dice.init_variables()\n", - " controls_start, controls_bounds = dice.get_control_bounds_and_startvalue()\n", - " dice.optimize_controls(controls_start, controls_bounds)\n", - " dice.roll_out(dice.optimal_controls)\n", - " dice.plot_run(\"discount rate, r=\" + str(prstp))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {}, - "executionInfo": { - "elapsed": 148005, - "status": "ok", - "timestamp": 1682429437045, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_a6832e60.py)\n", - "\n", - "*Example output:*\n", - "\n", - "Solution hint\n", - "\n", - "Solution hint\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 3.3**\n", - "1. How are the differences in these two sets of projections consistent with the change in the discount rate? " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_3b8be0b9.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "## **Section 3.4: Case 4 the Utility Function**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "These models use an elasticity of consumption when defining the utility function that serves as the basis for the value definition. Recall that elasticity describes the sensitivity of utility to changes in comsumption. Here, the elasticity parameter is the exponent called `elasmu`." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "Let's vary this elasticity exponent:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "execution": {}, - "executionInfo": { - "elapsed": 117793, - "status": "ok", - "timestamp": 1682429554834, - "user": { - "displayName": "Maximilian Puelma Touzel", - "userId": "09308600515315501700" - }, - "user_tz": 240 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "for elasmu in [1.45, 2.0]:\n", - " dice = dicelib.DICE()\n", - " dice.init_parameters(elasmu=elasmu)\n", - " dice.init_variables()\n", - " controls_start, controls_bounds = dice.get_control_bounds_and_startvalue()\n", - " dice.optimize_controls(controls_start, controls_bounds)\n", - " dice.roll_out(dice.optimal_controls)\n", - " dice.plot_run(\"elasticity exponent, elasmu=\" + str(elasmu))" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "### **Questions 3.4**\n", - "1. How are the differences in these two sets of projections consistent with the change in the elasticity? " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "execution": {} - }, - "source": [ - "[*Click for solution*](https://github.com/ClimateMatchAcademy/course-content/tree/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/solutions/W2D3_Tutorial2_Solution_5a417149.py)\n", - "\n" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Summary**\n", - "In this tutorial, you've gained a foundational understanding of the DICE model, a basic Integrated Assessment Model in climate economics. You've learned how utility and welfare functions quantify societal satisfaction and balance the needs of different groups and near and far futures. You now understand the role of damage functions in relating climatic changes to economic impacts, giving you insight into the economic implications of climate change. Lastly, you've explored how the DICE model navigates the challenges of economic growth and climate mitigation through optimal planning. These insights equip you to participate more effectively in dialogues and decisions about our climate future." - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": { - "execution": {} - }, - "source": [ - "# **Resources**\n", - "\n", - "The Python implementation of DICE used in this tutorial can be accessed [here](https://github.com/mptouzel/PyDICE/).\n" - ] - } - ], - "metadata": { - "colab": { - "collapsed_sections": [], - "include_colab_link": true, - "name": "W2D3_Tutorial2", - "provenance": [], - "toc_visible": true - }, - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} \ No newline at end of file diff --git a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3.ipynb b/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3.ipynb deleted file mode 100644 index 1d7c08ddc..000000000 --- a/book/_build/html/_sources/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3.ipynb +++ /dev/null @@ -1,72 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "id": "ed664fc2", - "metadata": { - "execution": {} - }, - "source": [ - "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/W2D3_Tutorial3.ipynb)   \"Open" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "53e42e1c", - "metadata": { - "execution": {}, - "vscode": { - "languageId": "plaintext" - } - }, - "source": [ - "# **Tutorial 3: IAMs and SSPs**" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "27636b92", - "metadata": { - "execution": {} - }, - "source": [ - "\n ", "image/jpeg": "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"}}], "tabbable": null, "tooltip": null}}, "2066909fe1894172bd5a98a1ec643fe6": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "c30c4a6ce3ed4f15bff50a3685584538": {"model_name": "OutputModel", "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_2066909fe1894172bd5a98a1ec643fe6", "msg_id": "", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Video available at https://www.bilibili.com/video/BV1jW4y1Z7zb\n"}, {"output_type": "display_data", "metadata": {}, "data": {"text/plain": "<__main__.PlayVideo at 0x10814ee30>", "text/html": "\n \n "}}], "tabbable": null, "tooltip": null}}, "86a38b0f5caf478ba5f7b1c32b5db355": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "84669c364e584c2bbc68057db4093b29": {"model_name": "TabModel", "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "TabModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "TabView", "box_style": "", "children": ["IPY_MODEL_330cde236db84adcb517e2242f19fb15", "IPY_MODEL_c30c4a6ce3ed4f15bff50a3685584538"], "layout": "IPY_MODEL_86a38b0f5caf478ba5f7b1c32b5db355", "selected_index": 0, "tabbable": null, "titles": ["Youtube", "Bilibili"], "tooltip": null}}, "44717c1b272a4a1784354046b8cda019": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "2dd9e41f5d464a8690a0541fd459b14d": {"model_name": "OutputModel", "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_44717c1b272a4a1784354046b8cda019", "msg_id": "", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Video available at https://youtube.com/watch?v=c5WfuNCnWy4\n"}, {"output_type": "display_data", "metadata": {}, "data": {"text/plain": "", "text/html": "\n \n ", "image/jpeg": "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REQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREBERAREQEREH//Z"}}], "tabbable": null, "tooltip": null}}, "63047b65e7e9411e8aaabad2e502c9df": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "9ca62b8d2f5c4ce8b5a060aa842ff0ca": {"model_name": "OutputModel", "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_63047b65e7e9411e8aaabad2e502c9df", "msg_id": "", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Video available at https://www.bilibili.com/video/BV11m4y1E72e\n"}, {"output_type": "display_data", "metadata": {}, "data": {"text/plain": "<__main__.PlayVideo at 0x108013ca0>", "text/html": "\n \n "}}], "tabbable": null, "tooltip": null}}, "0976a96c8146424185f284f81192cb79": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "451fa1a96bbb4d5cb0ada1a059d7a9da": {"model_name": "TabModel", "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "TabModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "TabView", "box_style": "", "children": ["IPY_MODEL_2dd9e41f5d464a8690a0541fd459b14d", "IPY_MODEL_9ca62b8d2f5c4ce8b5a060aa842ff0ca"], "layout": "IPY_MODEL_0976a96c8146424185f284f81192cb79", "selected_index": 0, "tabbable": null, "titles": ["Youtube", "Bilibili"], "tooltip": null}}, "6d253ac1c8464680a3cd0954e4e9ae2f": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "afccf5bc5c6145df827ae3db12ab5bc8": {"model_name": "OutputModel", "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_6d253ac1c8464680a3cd0954e4e9ae2f", "msg_id": "", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Video available at https://youtube.com/watch?v=g2upXZxXlrc\n"}, {"output_type": "display_data", "metadata": {}, "data": {"text/plain": "", "text/html": "\n \n ", "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEABALDBoYFhoaGRoeHRsfIicmIiEiICcnKicqLycxMC0nLS01PVBCNThLOS0tRGFFS1NWW11bMkFlbWRYbFBZW1cBERISGRYZLRoaLVc2LTZXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV//AABEIAWgB4AMBIgACEQEDEQH/xAAbAAABBQEBAAAAAAAAAAAAAAAAAQIDBAUGB//EAEYQAAEDAgMEBgYHBwMFAAMBAAEAAhEDIQQSMQVBUWETInGBkdEGMlKhscEUFnKS0uHwFSMzQlNisoKi8RckNENjJYPCB//EABkBAQEBAQEBAAAAAAAAAAAAAAABAgMEBf/EACERAQEBAQACAgMBAQEAAAAAAAABEQISIQMxE0FRYSIy/9oADAMBAAIRAxEAPwDz9CEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBCEIBC2/qtX9ul4u/CpaHohiHkgPo2E3c7j9nmpsXHPoXU/ULF/1KH3n/hUeJ9CMVTYXl9EgRo583MezzTUc0hag2FVzZczAeZd5J7vR2sNXU/F3kmxnyjIQtf6u1vap+LvJOb6NViJz0/F3knlDyjGQt1vopiCJz0vvO/Co3ejVYGOkoze2Z02MaZU2L5RjIWufR2t7dPxd5J9H0ZrveGh9KTxLvJU1ioW+z0RxJBOakAOLnfhTPqriIBzU783eSmmxhoW2fRavPrU+2XfhTHejlYaup+LvJNh5RjoWu70erCJfTvzd5KCrsiozVzD2E+SbDyjPQrztlVBHWYZ5nyWrhPQvE1qQqtqUQ0zq582JHs8ldNjnELTZsOqSRmZbmfJPqej9VuXr0zm4F1u2yaayULad6M1hq+iI16xtab2Q70YrCZqUrEjV14G7qpqsVC0/2FVkjNTntd5KQejtUxFSkSd0v/CpqayELcf6LVmug1aOkzmf+GdU8+iNeAekowf7nfhVVgIW8PROvMdJRn7TvwplT0Yrt/npG02c7yQ1iIWuPRysf5qfi7ySO9H6w/mp+LvJTyieUZKFpnYVX2meJ8k+l6P1nTDqYHEk+SeUNjJQtj6uVvapxxl3ko/2FVz5M1Oe08Y4JsXWWhdLjfQjFUKZqOqUSAQLOfNzG9qzf2HV9pnifJazWb1J9sxC1BsKr7TPE+SX6v1txYe93kmVPyc/1lIWsz0erOnrMHaXeSX6uVrS6mJ/uPhos2yNeUZCFrH0ere1TPefJN/YVX26fi7yVnv6ZvfM/bLQtVuwKp0fT8XeSe30brkxmp+LvJa8an5eP6x0Lp/qLi+hFXpKAaYtmfNzHsoreg2KZS6V1ShlMQMz5v8A6VMb2OYQtY+j1aYzU/F3kl+rtb2qfi7yV8Ov4x+XiftkIWsfR6t7VPxd5Jh2HV9pnifJPGrPk5v7ZiFp/sOr7TPE+S1qXoFi3Na4VKEOAIlz94n2VLManUv05ZC6v/p/jP6mH+8/8KP+n+M/qYf7z/wqK5RC6v8A6f4v+ph/vP8Awo+oGL/qYf7z/wAKmjlELqj6A4v+pQ+8/wDCmH0Exf8AUofef+FXR0SubN9d32fmFTVzZvru+yfiFxbbIVPbI/7ap/p/yCuKrtUfuH/6f8gtX6Y6+nNS1zesCef/AAmlgERoFIZGgVarVcPWAuuX28x7hOhsnZjEKNlVpHPgn0DJNzE7lVT0HkXvdTNDSZgTaVG1jRJk9k2Qx/gpqG1cP1QGgl1kuAtXb3/BT5hrvUeFZ+9a/gb35LfHX9blW2PzS3nbxukNXI0NHxT6LACSoKom40BhXqlQuJneqtefDkpnvUNTtUiQ2qQ5smYjTzVBwMB24WmBNlfpMk3MDVR18rQXEy4Gfne3NaKotGUHSSdQZ7l2mwf/AAKfY/8AycuHr1w7M6+bS1hu3dy7b0dJOz6Z3w//ADcq3w5gkEg2Hy5JWVgCM0OE6JaWAxFVwOUjtt7lp4f0eJ9dx7AI+KuVcZgxRDi4XJ3yU6nTfUvTY4u3wOe8rpcPsWiyOqCedytBlJrdB7lcXHL09i1nkZob23K0aPo+0QXkk9sD3ea2i+P+Ew1D+gVVxDRwFKmLNHgnmmwbgndIeXgUknighfTb7IVWrhGO1sY1Cvk81GTzCoyXbJInK4O5Gyp1sG9oJc0gDfFvFbrnEaQo3Yhw3N8Vm8RPGOba0anThxUpqENsIHJbDqNN93U2g8QSqr9mCZa8djvMeSxeKz41lBjjckxyTsOxhqhx1Lh3KfEUKlPcTIN23A7TuUGFANRpF/3jRPePMeKmWHuOp9Iz/wBq/wC03/JcfTrDMus9KHRhD9tvxXF4isAIB113z3rrvrE752tER7P5pZb2HU6KjhmuAPs/3WnzU7ZmCCeI5RquVl/rPjE03tJJuJMgfqUlSWm51vEIBygToBYQjpwQDAsdbrMlLSPqGYIHHrKMUoOqkfVDhax5poK9HxzHHvorQVawbW5253QN54BVg5IasWAXX05zddLidq0nOZSaSKTYk7zGio7W2l0xAAim31R8ysR1W++UpcY+az5SOtvXSaQf1KRxUTHTYSpbrpO3K8mZglLZTjTspHYZ3RFzXNJ0ib/BZ67xZzqu52VdxhhFKn9hvwC4Jgh0OJkc+K7+l6jfsj4Lz22vZ8fOHoSpEdQkKVNKKY5ROUrlE5RHPq5sz1z9k/JU1c2Weu77J+IWGmyFV2sYw7z9n/IK2FU2s2cO8ccv+QWr9MdfTlq1cneqtRhFzZW67xTzSOsCRJkSeSrMY95LjljeSdOaxPThCUusdCBF1MxwDREzrokqg6NJzRo1tu0lRtk6kKi1SfJvpwU30kaWngqnRuiQ63A2UXRumSmajRmTr2f8JcxbwWeX2F5unGsZuniY2cK8bzruIUVZ4uN0myqUnwR80VC4+NuyTdMDSJKWrVAEEBPYCGzIBKjcwE3VDmgEC5JG7d2KliqfVJO828PyVpzi1pA3DXyVLENGQCDfn8kP2z3sEEz2LvPRof8AYUex3+blxFOkHWcLcRqu79H6eXBUhwDv8ituvK6ykBpZG+LprAQf5fD80lRs3IHvWm0rnQhpneoA3k3xKI5DxKYHPHP4pA3n8UmQ8B4lBb2+KuBcvNLlPFRlqMnEwgHA8VE5p4+5PLB7RTDT4uCojLDv+Cr1XEblbLRxaoKjZ3jwQVOkIOnuCeK5j/hOdTI4dxUZB5x4oF+kcY9ySi5j3NlrZztuI1kcE1pH9x7j5KXDT0jJB9YceKIselrZwkf/AEb81ylDDZZJ6x7vC66v0pg4dsmP3gufsuXICsAMuaeQm/kudZ6Waj81spjfuCdQaAXG7RGp7QoKcuqCbAbrK1IAvop9RyptQmS2DzsdOSabC8ADjr4IrkiACBPbMcVH0jSwmDaZJPYNe9a5skZvOla4G0TzmFKI0Nj+t6rvykWF92ijhz3yDA3rU6TxWy0DS0agFIQRZpuU9jAdxI0tvVl2HaB6scVdZUgw5XEtPVMGNfzUbntPq5r8dFq0qQyFsa8Tx/JVKtMAtY4TOhiyxLLcbR4fDuD4do0a6+EqTE1jlBYJAN+9OBJm1o10Kkp0oboY3cLKbdashmCwrawc8veImWggdhSVCLbu+O+P0VNVf+7cCSGRoJE8p71nOpOrP6rcjNJjhyCt9tSRIamZ4DTcld5T9UdgXFUMMWCLEcIg6azx5LtwFl04CEpSI2E0pyaUDConKUqJyDnlb2Yeu77J+SqKzs8/vP8ASVhpuhV9psc6g8MEuMQO8KyFFi63R0y/WI3xv4rbFcs/ZVY1M5Y46SCBdT/QK0ACm4AK7S2+x9TIxjnG1wRHvV12NjRjnHg26z4ufhGDX2bVIjonkezeO/j4qt+yq7SYov8ACV0rNqg/+uprEQCfAFI/a7GmCx+kzLI/yVxfCMBmCr76NQdrSh2AxE2pvjk0roG7YYYinUM6Xp+PrKYbQH9KoON6dv8AcrieEcw/ZtVxvRq9zSkZsus1w/c1CPskLpf2owtz9HULYmYb+JIzabCJ6OpH+j4ZpRfGMRmCrhxii+PsnyTjgq39Kp9w+S6Gnj2n+R47cvmpPpzfZd4BMTwjljhK2nQ1fuO8lH9Er69DVnnTd5Lrf2gzg7wKjO1aXtR3FT0eEctVw9UQTSqncf3brdwCq1cJUdpSqN3XY4TbsXYu2tRj1vc7yTDtSj7f+13krE8I4puz6gIlr4+w6x5LtNjNjC0xBEZrOsfWOqSptSg3Wp/td5K3RqtewOaZaRIOirUmK7DEz8SlcWka+8qH9q0P6n+13kl/amH/AKg8HeS6ePX8Xz5/qRsbnHxKUN5nxTBtKh/UHgfJL+0KH9RvgfJPHr+Hnz/TiEsHihmOw5N6jfA+SsDG4X22K5f4efP9VspSGmf0VYq4/DxAfT9yruxlE6Pp+IUy/wAPPn+jIUwt4j3hP+k0fbp+LUv0ij7dLxanv+HlEBA1uExzW8+9W+mo+1S8Wo6Wj7VPxai+UZ5ZwlRPkCAD8PmtXpKXtU/FqDUo+1T8WpqbGRczbxKmw38RmouFodNQ9ql4tTmVqJIh1OZtBbM8k9/w2Mr0xcBh6c76g/xcuOpVyCNBG9ek4qlTcAKjWOAMjMARPeq30bCn/wBdD7rPJYLjielhjnaSbcY5J1Wu3JAOY9vvXafRcL/TofdYl+iYX+nQ+6xLNYnM/rhcV1gyDJi973j8lcw5hoDhB+MLr/o2G9ij4MS9DQ9ml4NTKtk/rkKuHJdBe4giQALSOHuUtHBtytmZjrRv5LrBSoezS8GpQyiNBT8GqZU8f9cw0AaCItJ3pwdOotxK6VnRZhm6KOYalqdATpR8GrN4tJxP65ioTIM2+Kc6DwtouhLaHCl4NStw9E6MpHsa1T8dXx/1zVNzskvE8z7lZNam+iBnIM8DPy/QW+7C0jrTYf8ASE36FR/pM+6FqTDw/wBcq4kQJvu1JMJjqhA4HXXfPvXWfQKGvRU/uhH0Oh/Tp+ATDw/1ytOoSQIjrcrrtyqBwmGF+jp+AV8pmNc84RCEI2E1ycmlAxyiepXKJyDnpVnZ/wDFHYfgqqt7N/if6SstN1qp7ZE4Wr2D/IK4zRU9skDC1p0y/MLTLkXNzSA4m2/8goajDlAaAWm+a40HG0K1Ro03Tre0SRGmoUPqOcGSTwJsI3/kjmMlgAXSd9zbgL8eKtUKJbBLnCRaSQe1U6bnfzGNxsAY381YpVSAGtkDdOnYrFh5rBroZUyk631jSTI+KlJc5sGrUubQ/XlE8ioBhIOYvuJmARHJHSguaOqYnrHj3FSs30HBzGkNqPEz/MR4qahiahs17tNczoHeq7wDBcQDewOvvkfmpGVTBAa2BoAPfKItiq7e9x3esfenjFODfXcSNbmPyWeMLUk2gdonu3qZwdlJgG0afNQWPpbnce8lK5riDFzyhQMaIBJnsPyUjasTlAHOPNTBFWJZ6xHYZKBWLiOsSApMVLmCI14D3cFWytaAASSAd2661ypKjxMGTB17V1eyv/GpfZ+a45xMjKBm4Zt3Jdns0zh6Z/tVOXLVKd0zIrb23TMi+pL6fNs9oGtTsqnaxLkTTxQZUsKfIjImmIISZVYyIDE1cQZUZVPkQWKaYr5EhYrOVJkTUxWyIyqxkRkV1MV8qsbOZ+/pfbb8UFinwDP31P7Q+Kz1fVa4n/UbmO9UdqzzTCvbQJhscSqEu4+5eXienr+S/wDRciMiSTxSNMb5XRzOyJMiJ/uUjHti90XEWRJkUpc0GxJHNJ0oiPyUMQlqaWq7Qp9Jo3tO5Nr1m0nZS1rrbwmr4/tSLU0sCnqVmkerBi0CE3OA0EsmeZHvWtTEBYEhYOCkdUaf5Y/1IL2yYB5TdXUQ5BwRlCmlsAEGeMhI1rTvI8ETDaDeu37Q+K6eVgU2MzNyzOZu8cVvBef5vuPT8P1SoQhcHciQpUhQMKiepXKF6DnirOzz+9HY74FVipsF/Fb3/ArLTom6BU9ticLVHED/ACCuN0VTbH/i1fs/MLTLkKLqbZ8kANEnxsSmNaQTA3bjw3pppkxLXE87xzRysNbTBcTmnTTUK/hWNmBJGgJB/wCO5V8CHA6taJ1m09hWqRnbeJ4iDfjotSOvPKjjady53ulUHVgAcuhW1Wp9WHQW9l1WGFa4OADSN2+O33q2JefbOwzsx+PHuCvNwpbDmlxEzpKioMyEuYQY1kWj9Srga0iHS2YmJgnmEwxEa8G4mez80xzgDa/Ij4FSVIbdo7ZE+OttEMxoiZANv5N3l5rnZjnmJm0idQAe+6R7XAxbtBm6t06wLQZEHl+ap1qpzOcCD2A+Cv6az0YXGCLk8eaifWEjNfsUIfJkDdJiNON1FVrk6D3wfhokZXQA0+rMb+S6zZhnD0jES0WXE0sXUAs609v68F2uyf8AxqN56gutLGM5ibkSVMSyf5/ckOIpe07she/cjxZtPypshVcZiabYu5xPOwWdjMXABadRpOixfkkdOfitbhcBqUjajToud+kgNBse247EdO2R42H6jULn+Z0/BHSGxi3YhkHePFc/TxrjZxgK30oFw033X93kn5j8DTNVuk3VSpj2iY3TvCoV6zYOQRz+Kz3VCDKzfmv6anwc/tuftIA3AaOJPyVmjiGv0LT2GVzYdNxeeafTeWBrhqTFufFWfLUvw8/p0+VODVjUMS9hLdTMXuAN0K2MeQNdy6zuVw6+KxdyKfAs/fM7VmtxDiJDirmzajziKcm0n4Fb6/8ANrnz/wCpGxtF0Bvf8lnl6n23iMnR2mc3yWczEk/+s+I+a5fHP+Xf5P8A0slyQJ9SmW0y90Aj+XX3qGhWa434StaxlSKVmHc7TXhvVnD0W5hGpkiRpG/nuV4U7QTP638Vz67z6defj37ZQwbt8Tw1KmZgmgDNqdx/JXINxeJ4KjXxDmAMAFhGhlZ8rWvHmJc4YHCTobNiBz7VkV8I9suJaQeE/O/BaDKoLJJE3huoVfEn/S2NPOVefVTr3FBlXLvUzaueBI5BRdA10/8ACgbT4EdhXbZXHMXzTEesO+QkLP1KrVGPG/ySOD40M6W94U1VgNvuPeE9zQP5T4LKcT47p+IUtLFOA1sEGlhR+8Zr6w3c10C5zBVJrU7i7mnun8l0a8/zfb0fD9BCELi7BNKcmlAxyiepSonIOdKmwX8VnaoFLhD+9Z9oLLTpGaBVtrf+NV+z8wrLNB2BVtqGMPU7B/kFplyO8jNbmeZ8FDWqkHKLn7oPbxUj2A1d5AAJzSN24cb+4qcjQBoJEXIAlKxVShVcHAPNi7ytK2mhrYymI36z3rMdc6CTMbrRyUIeWAwYG+RHhorOmuesXqNVzyc1yN8QVPTpA3sOQG/5rMZjGydQbW3mytDFiwdVa3dBA052WpSX37NrUG03umCDIk7jv7EjKwaAMwMW0Hj2qLHY2mWZGkuvruHMKgxjnuimC7sQrUruJcIcS2dLkdyhe8CbSBz5pzNn1mtE1GNnW5Jjgq78NUHVs6NAD71LKxurlOqW243HBPqdds8OCp0GOLoJ8BmV8YUmCXutvDEzUtZwo8LJOhvEe8Lbp4SQ3ogcwnMYufJOxWDfmpgFo3OIFxe9xda8U8mY3A1CBDAf7QZPbOi7DZrMtCk3g0BY1DZr7EkHkXuG7/haufo6dMO6piJ4GEsXnXO4hsE8VnyXAZRPOf1Cu4yvrJnW6yelLW2N+O5deu2eOMOxD7BryARrBHvssutXzGBMDfrKmrVR1p1KjDSBcEnQATrwXG12NIlpg8PgnstrFxqbqKo+IQ2XEz47kE+ctHGd828E+jiHA6do3FVqrtzTZOouO9BarGDN8s9um73hNcTGeTB747UrRLXa3VcP6oa4mLoH0qwmxAPKymq1J9aSe38lmZZupn1nHfw17EF7pi6M1+/5q20AMvA5hZuFrCCCZ3/8K1Rqi41PPWNyupjQpdR51giT5+/3LX2UT07JPHhwKxGEAAgw4xpbjM+IWhg6uVwcHaeBtwXad+scOvj3qVp+kTv4Uf3f/wArPwwMguBAkG41WvUxGbo3gAmDG+DaRH61UVVzXwI19X5gHzTjr1h3z71Dj3vqNyuyt32vPAT+tFXoDJeZ1iIPZ2XlMqMc1xEFNZVyn5HQreMNbCYnLdwgwbucSYnc3wRW2haQ+N4Gvis1taeq42kd3dvKji/6hZ8Y15VrnHuDDfU2gyTzkKCni5MkE7jLp8VRqtLba2BB4ckUsTueCRxkyOzyTxhrUe6RmY6TN4j4KGvVa6JM2gg2KodIWuBa4a23Kfpw5vWBB4jfxUw1GWxoe79dyjfQBEzBT6VRoIBjvEe8KetS3iHDlu5R5Les4ptqvYIc2Rx3J4Of1fAqRgvqI0IJUGKw5pmYIBuND4EIgdUfv63HNf4qIML9Gx2JzcRMmAlFUtMgTy/NRVrZmDcK1NxIgO0BmdeFl065nZVcOxFMZY1gAngeK6Zef5Ltej45kCEIXN0CaUspEDConqVyhcg5xS4X+Kz7Q+KhUmG/iM+0PistOmZoOwKvtVwGHfIJFpjXUKy3Qdihxwmi8Hh8wtMuXx5aGB0dTger1rwYI5dqpVccG/3Dd1j+gt9jWxBAItPONEOpMJ3Dlu+C34anXOuSxGPLrCA33qMio/8AlcZ4ArsTg6e4MBk/yjuTzRbAc93ZFvzVnEYv/P6crhtj13n1Mv2jC08P6Mu/nJ7oHvW7SfB6jM0cIA8VepYm3WAB4AytZIm1kYb0fp0+sQO11/irjMOzcS/ss3xU2Iouddzur7NkFr8sU2+7zhVmhmGpzLw0f2iSqm0aOFDr5gQPUaTB7VNT2ZWmSQJ53Chr7PbTMOBcTexPin2fTKJAPUEcrrY2MHgFzycvNSYPZ4Ik02tHEyT8VPVpAkDOSBqB+SSIifXqF5yuhvCyiyHMeslc1rSYabbio3YiIkDuUtb55S9M2mDfhrzVPH4shgLtLQN+loCbiazZkxGnZ3rO2zXDqBDDGkW36frsWLW5GHjcTqXExJtwVRlXM60RumZ8UlJ8G/W4owo617AKNHhwB60gcQPfKc3EBreJ081Vc9rXOOpneoS+8m8oJnQTm9yUsI0Jum4frW3rcwmyczQTKasmsmhQc421Wnh9lvN3DVbuB2c1tostVtEWhZvTc4cu3Z7mgiNQsbG4F7ZOoXoNTDghZG0sECFJ0t5cI1xGqnqEOiwgW8SrGMwZBNrKq6AIBt2R3rbmaDcXgK9ScMoAETN5vZUqdHNc6KZ7yIDRp2GERoUKgHExzV+jWP8AzuWPh6ljOiv4duYW6w07kGxQxJ6pMkAW3b7q0K5faOqTwk6XnesltV0BukDXjN1PSe4Xb+rXXTmuXfLXNMkS6LWDuI5hVajGw62nM8QE/wCk1nN6wcRrcWgA3TKWIFjlaI4ADtv2FdZXLEDQQbbj3pJkjcpHNFvGNQexNfcb53/ruV1MIxmaB8be9I7qlzTMi0G10dGZ1g9qc/rC50G890KGGGxvFtyYYI1i9lYFJu9rTEH1r67gkcxmaQCBvuPLkpaqFhH8xtwv8U9r40JEcDeeXvVpmCY6MtQAyBlcLjv/AFuRV2bVbH7uRyv3lTVxCa03ygw3WDrN9EfTbBrmyPgqppjnbtE74RlET4eKupgqMbMi3BI4OaRBSgydw7QlcDMSPFLTF7Y7pxDJAnrXAj+VdKub2PTIxDTIIg3DmncV0i4d/bvx9CUIQsthIUJCgY5ROUhUT1BzcqbCfxGfaHxVdWMDetT+0PistOlabBQbQJ6F8cB8QpafqjsCg2l/49Ts+YWmWRhnuk26un53Uz2gWzHS+mqrNqhmkwBAaL7v1fdKquqF181uA+E71vUnTRNYeqHGx/WinpiTpbeXXPvWXSY2bzPGTPvur7Kxb1RG7cPGU1fteAp7xmU1OkHCGty85We3FaaAqTp3XgxPL3q6vhrTo0AxpHid6UyNPElZgxcOuey6ndi2Fl9f1qprPhjRfXDRdNbXa8xY94WZ01wnNxRaTFyYPFFvK5jAQ0QQRNxMLOOJhpOnHkrf04WkTvvF1VxNRjnA5GTFoF51klXWZFT6VmMk62tITHVTAk37U/E4fPJzX4WP52WfUouGptuKi6rbSrwSXGSSqVau1zYJMjWZsO/tUWNfnOSZcdfNVqjAOrJjTXUrKqjXZXk27/kirXmd0+9PMA6TuVavryVCVdTwVmhhnVA2AqzTEStnZrHR1fipa1zNO2bgIrAO4SuspU4AWZgcKc+d25a7Vztd5MSsTw5RgoJUVLnVfENzAp4CQoY5/F4YtERouYx1HK4wu7xbZC5raWHs6y3zXPrlgtqHLE9impOkGVXLSFI58CAFtyWcNma7WZ3K9hZLjeB3rLogmDJtunVadF+mX5oNCmetDo4eKt0qYgDQ6b7rLFWctr6b1oUqrdAt8sdNKhSqOJayJjcY5j5JtTOww5sRxaIvH67kmCr5Hetl7teS0q+PY6nqZBW3LGYxwJ00HPhp8U4gQZb1ptfwnwTm02x1XNIi4IMix5dqrlhBu12nBaZSsLTALnC+kCOZUzKAh4DmuMw0QATBkEXVdtEuFhfT9H9aKzRwDnHrZhwdCUim9sHQnfKA6Jt3fFX6uzCNagaCd/Hcq30Vm6pmIgmZHu7OEqaYhp1CNSd/IiymG0nB4h3YO28QoOidpY6Xm1wT27ktCnUJEFsWsSLid6YLGIxbarAC3rA3Nr9ypPZvBjcLLRoYJ+ppscOAgXm/DgfFLUpzZ1AMtqLCbb9OKKyZdfikEx+itWhgXAyWMe3+9wgDkZt+adX2fQEuzhnJhn46qGI9hD/uOxrvkujWJsanTbWdlLiQ06gcR4rZe4AEmwC5dfbtx9HIVfC42lWE0qjXiAbHSdJ4KdZaKmlKmoGuUL1K5ROUHMqzs/8AjU/tD4qqCrOA/jU/tD4rLTo6Z6o7Aq21nRh6mp00+0FPS9UdgUG1P4D+4+DgtM1z+HpF5iIaRfie08LqQ0YPZrx8e1I2oMxI0GvlzSZpcMs+I1ngqykomR1rHQkBTtkiSQI3dyqyZtrfNx1N/wBFSyQJBuIJ37vy9yqyp2lpMk6m07oUdWplJtpfsTS9wLcoPaYjhPbZRV6jjaJN/wBR+tQla02nWieM68ArDq4Nwd5kHfyCogyO2J5p41MCbm3CSss+S9SqlxiY4iNeCuhtvVG8GxmfBY1N3WNrA37VZOI6nVnW3mVpryaTqzQOsOrpEz+j5KGriiCQwWN5PYqfTB5aDPHWbi1rc1LmNiN+4dyazesJUaYb6xHE24acVDWrbsogjf8AHRSDEmfmsGoXVKzgXODRvGv6srWZ7VtptMZmGL7viqeewvJVvEAtaQXZtdRqJVakJEDnvWXRHUJ+arEjcLjipnOtdU6huYQStYXmAuj2VRhgCw9lCXFdXgaYACz06cReoNVkCFHTc0bwpS4FYdRKc0KObJrsUGaqKtZCl6ElZ9Ta7Gb1GNvt4FaxLV6vRWHtGkIKu/toHVqr13ioJCI43ENNOo7dKiNUky64WptigYzcCscOmy6RwsyrlOsTAtHCPmpqcgyqjL6alPa7M4cBuVRp0ZJEWK0WAWJJ6wGtwsxhEgbhIPON6ttqE2vewSDVo05aDNp4T3q8zDU5aM4ggkQCdOcrOwjHWbJMjQBbGFwYI03i958e9dJXKxFh6lIScrszQCBa8jSwWjhcK4taahgweqJAvx5qTD4SnTu0X4m6kJyyTGUA8SSFL0SM92Fqh0NFvand8U5mErNlxqDiRf4q8yoS7cWnnpZJmygAmRpJtHCU8qeLBNUukFxcNIN++/6sq7WB9hO/cujxLGEDM2SdB7yquz6zQKggDK6LCOwczZa8mfFlOoll8rgNxBjSRJUGWS7NfW43K9jKgcT1iXN5QN3mqGe97netz6YqZuKc0QCRI+JMn3IbjKhgZ3ag66/qEzpBEDUb5mf1CSIgRe4OnA8f1ZZxdBrnKWiRMa8hqkaZdABBtbkXae9IIlwAFmnib8ZHJObD5aYYI9bKL3Av4qK3dm4M0yS43iI75kqTaryMNVIuQx3wKqbHccz2yYDRvnebrQxNEVGOYdHAjxC5dfbrz9OK9H8bVaTQo5GvqGQ914hptHd8V3NMnKM0ZoExpO+Fzex9gtpYjO6pmLCcoiJsOtP+pdKo0VIhIUDXKJ6kconoOYCs4H+NT+0PiqoVjCfxaf22/ELDTpKeg7E4iUynoFICtMmdGOA8EGkPZHgFIlCoh+jM9hv3Qj6Mz2G/dCnQoIDhWHVjfBNOz6P9NvgrUpZVFL9m0f6Y96aNmUb/ALrX+53mtCUImKI2VR9j/c7zSjZlH2T953mrqEFL9l0ZnKd/8x36p7cBTGkjvVtISiYzcXhKRHWJAG+fmsHGbLaJqUKxFt958FoekdUOpZGm4cC6OA3GFhMoVKoIoPJB9cEQBzn9SjUisKFSrSqOMHK4gEDWBJPvWVUMBbb8Q+iBTaRkG6NZ1JOuqyMQZsiq3S6gwqtQ3UwpX1U9NlPKXFuYgneYVDNnPMujWy3qdCqGyPiFTwtBsSGtExoAFpUi0EQ3rcbys10kV8tWZcfetDDYh1rqviANTrzJJUDXkGxUxuOgZVkKtiWTqqtHaTR1XCHDdcz7krsW6sXNYMoaJJOvYFMa1XrMaTHzRTpsBu0k8iHDxBUVemW7iVFTxz2G9OR2/krIy1hWpxHRO/2j4lQuq5Qf3bwOwfJRDF5x/CKno5m2hKM3GVG1GEDfqufcLnKOxdMcMAazjrJA5W/NYYwRcXcBMFamfpjr6QMqjNmFuSma5rjw7lXBLCWkCfn2qxTpSJMdyrmtF8brncRv3q1h3FxGvdxVB0gjUj9SrmFrBg/X64eKg6HZnWd/K6I/5W/QZlLt4MHsP6hc9sYtvULrkRaIAXUNoujQ+C1rNhrXHM6Ra0fNDw13rc7bjPFP6E8ClFIqIgyFrm5A1rRrb4AJ5cQRF51vHyUnRJHUU0VsQKhdLCyIjrTrxhUHUK7agLQwiI32N5PvK1Po3b8UdHHJXS8sJtGs573vYb6CLXEadw9yrfQKpcJY6JvGviumypCwq+djPhHLUsLVGb92/l1Tx58pUrqLiRLKg1nqmeIJXR5Cjoyn5KfjjAFAsiWuOmjfHTt/UKLI9jC0NLiTEwdMsD3rpejKMhTzXwZuwaZHSOdMmBflK10xohPWLdakwxlENJIFzqeKkSJUUJpSppQNKiepXKF5QcyFPg/4tP7bfiq4U+DP76n9tvxCw06Sn6o7AngqKmeqOxSBaZPlCbKWVQ4FKmoQOIlDBCSUsoHApZTJQgfKVMCVEOSOSSh2iDHxdMtktuCNN99e7XxVHFYzoqJFEBu90CDdbGJAiJFiDbXUG6z9qYZ1RhiTaI7UVyld5eJJudBCp4gEK/XBY9uZsEbiosZVDiQbGLREFGmc4mIlR0j1o3GydVB00TCICDdwzYEcgpX4dxggnuUGyq3SAT2eC3GUxCxft159sP6JBmDParFOlJkhaRo8lHWGWwu8+qPn2K6uI9mk53EWkx4CFLtGWvbU3gQezn2FWNn0Q0xrAACt42iHMmO7ks61jKr4cu00UTcCeHvKu0gaYiCWbnASQPZIF+9SOxlP2wO2yumK7KGW0K7QwsXOqipYinrOY/2tLvgFLVc94hrXMB1c6xA5Dj2qVWZiG/unu9pziOyYB8AFy9ZxEgEydYK67akCkQLACAOAAXM06QxNejSYP4lzNoAnMfBpWuXPtSrUy1zQfZaSOZCnwwE8lDi6wqVnuGjnW7BYe6FPSpyfitOSYkED5J1Km54knqyAJ17R2JlKkCXXiJ7zwUlJ2aBBtcu8xvQauzsG8lgDgASBPCToV6DTfAA4LhdlveXta3XWeELoNm4OpTqueXHKRGU3k2vM8verGa3OlTXV+RWXtSjUqNApPLSOB8N45qxD+gLSc1ToyJ0l2XXxVRazE6p4cub2Nha7K0vD8uU6yB/kVcxFOuaxc3NFssOhojiNIO9avOMytnMoa5OU93xTK4eYyOA49nK2qWubd6y0hSJJQshyJTUqKdKEiECoSIQLKJSIQKkKEhKBrlE9SEqJ6g5kKXC/xaf22/EKEKWgf3jPtN+IWWnSU9B2J4UbDYdgT5WmT0JspZVD0SmyllA5KmyiUDgUspoKJQPRKbKJRDkFIhBCWu0EELHx20Sys5mXqiASDe/LxWticRlBgSb740WLiS+pUD+iLQRlcZaRl14/JFjN2vXpuENLSTe0E9/A+SxMmTNvtp3hblXAR1r5TvJPdvVLE0mhrSLGBb5qNMh44qJ4hWagDjaSoqmmiBtR5bQpuaS0h79Oxvkup2Y9tam10kSNxIvv965vEt/7Ona/Su+C0vRmt+6cPZd7jfzU6+m+L7dD9EZvLj2vd5pMjGA5WgdghAqKCs+bLGvRIsYIy4wtNzJaqGz2hoV5tYDmEMZGIqPYZboE+ji51U+LLTIA1Wc+iW3CrTVp15SvqSFnUq3FXGCbqM2M3bzsuFqHl8THzWJs9wo4XEYuILmjDUJ1ktGd3cB4krb2/TNSh0TBL6r2MaOJmfgCsD0jqsD6eFpGaWGbkkfzPN6jvG3cunH08/yfbIngrlCXE9ZVKYvdTNcQRC05tKi2Q4+1+ip8NQyTHW0tJuAfyVSm6GtBEg6HmrbXkQBLncBf5WUVrYLHufUa1lEMZIlv8x7F1wENjeuRwDKoyOccsuAsYNzC6bCknMHGSwxM62nxuFYzVhk7z+vBF53Qm5NwnxKXLfUrTJXFwNo7wntKiDDAufch7CQQHkaQYFkEwqDj7im19O9JRaWthzi48SEVjYdqlEKEJFlo5CREoHIlNSygWUJspZUCoSIQKkKEioaVE8qQqJ6g5lPpnrN7R8VHKVpuO1ZadMw2HYE7MoGusOwJwetMpwUsqDMnByCaUoKiDkZlRNKWVEHJQ5BLKWVGHJZQPBSpoKVA4FCbKVBDXpyCeSznsNMdUy0kDKefBaj9LKgaeZ1zf9aKChVpn1ZJEQATAkCwKwK9A5iXTa0cDw9y6evQgEyBHJc9UpVH5naze/Du3o0zScsRqU36NUcM8WVhzQwFrmy72rj3Kxhq1XqtsWD2rWQU6v8A49IRfO8/BN2NUbTr5dBUEZTrI0+a0MRSGSkC2/Xgd+vYsHH0jTqTN9QQdIVXcdmEwaqtsrHivTDrZhZw4FWK7DFjC549Mupw4tuEv0grG6WrTf1yXs8O9aNOrQLSS9wO7rFMXcWBWAu4gdqixW0abQBck6ANN0n0ikADTZmfxIPxKioYfM8udc/DkrjWaAS7+XLKvsNgEzotCpKVPM8NmN5PADUrLNVdr44YWga3/tdLKHIkQ6p3C3fzXBtaSY1K2/SjEGtiQRZjRlYODR8zqsZhAnWe4hdJ9PL1dq03DQ4A34p9GlTcA8vaCSCKbQ6Bfee7cm4S1yLHWJBU4qNc8dGHWOpgaKpiaJJzWBdMbxzWts2rleXjebX52WZi8Y6oGteAC20ix71Ns6s1ph7S4GIbzlB1mG2hQeXBzQHHUEC60aDGZQWtgcNFx/7YYWNFQRBBJygRHswBZbND0qwQAGdzf/1u+QKsZrXdkdM7rXTnublJJBaBNr6KlT9IMI7TEMHbLfip242hVBDa1N4Ijq1GnXsKrJ2HxNN/VZOk6bv0UGuxjspc6TB0J38gkoYOmw5mAi0akiJlOfQBdmMzb3T5lX0k3PZ7MQwvLA4Fw1CjxGMpA5c7cwNwDJFt6qY6iGMqPZIe+Bqd5uQsPCDNUcRoXGOyYHuAWbfeNyetdKKo4pekHFU26J4UXFnpBxSdK3j8VBKaVUWembx9xR0zePuKqpFBb6ZvH3FHTN4+4qohRV0VAdClzKCkLKUBcr3Zca8T5SFPDU6FfOp4q5Ub1LU1KgeujLOd6PVdz6Z73D5Jh2BiItkP+pdQELXjDWV9Dqger7wgYep7DvBahqcE9oJ1TBkmhUGrD4I6N/su8CtkABOTBhzGtkoetshRvptOrQe5MGUHpwcrz6NP2Qs6uQ15AsPyUEoKUFVw9OD0FgFLKhD07MgllEqIOS5kEhUNRvC3cnZkhKCJ1AFtyViYzBZHGCRImALELYxWMp0W5qjw0c9T2Deue2j6VAgto0+WZ/yATF1Cx7S4GsZFzB8lm1XjWb8FAdpVHiC4xwFgqtV86FMVqY7HvFKgWnKSHiRr1XQLrFxDnEybz4q86ThqRd/K+oPEMPmnU6c0XvMWFpA9yCvsus6lUzg8i3iF1tGs14BBXGU7ugePBdJs4x3rPTpxcaFWgHKs5kbleabJCxZlernrFRjSVfpANbATW01K1iWrerTgbJMR1KeX+d93chub5qai0AF7rhug4ncFXqguJJuTqo49e/Tn8fhc4MarKpYWAcwvzXVOoaqJ2GbrCs6c7y59mHtbSyWlh3XtN78pWw7By7SxU+D2TNRoc4hrnNBA7VqVm8snb1I0ywzOdod3kLPp1yBO9a3pjiGHFClT9Wi0M7+HdZYTTZdY42pn183rXTQyfVPcUy3A+Ke1aQ0yLGycHKZtxBuE11D2fAqYHUqzm+q4t7DHwVyjtfEM9WvU73E/FZoKeFFdFgNt16jiKtTM1rXP9Vou0TuAVrZTIAHBc9gakPI9puXuJBPuBXUbPbZYz3rc+l4VmSW5m5hqJEjuUoXJ1qFOviMQXiYdA01FvkVb2Kzo69RrXOyi0FxIty0QdCkSAqLF4gUqbqhE5RpxO4KxFevjz0zaFJofV1dJgMbxJ46W5qzXBA18Fzmx9qOy1eipF9cy+o90Ryi88gFZr4jEZhNUid2UZVucXr6bnUk9rlTFOpmZkcCr9GqHtDhoVyu1MfWByFraZGWx6xM/BT+jW0SarqT46zcze0G/iCPBYvNiWyutoaFTMUOH3qZoXm6+1gq4hrSG3Ljo1olx7lWxuIrUxTeWNYw1GtIJl0E62sFdoWxB/up+9rvzVfaINXB1x/M3TtBWpzs1N94dW9YqB6c2pna1/tAHxEprl0ZacphJKiFcc1Iyu0cV0RPTYB2qRVunbxR07faRFiUsqvnG5NJTRO6ooi8lR1Jyuy6wY7UtMENGa5gSee9TVw5ZGNfFV3d8ArjsaCYpjOeP8o79/couiklzoLjrZZtXFQVE4VFb6IcB4I6JvAeAU8jFYVE8VFP0TeA8Eoot4BPIxBnTg9TdA3gjoG8PinkYidVABJIAFyTuXPbR9JYltAf63D4DzTvSjHtb+4p9rz8GrmJXTmM0uIxL6jsz3Fx4kyq1UqRyieFpEQMG/b7pT2tid5TDrKsNqtgydwvF53qVqJWMe7DVcxjK+m4TwIe0+8tVVldxZ0c2lWsGS9uIZJP7lztfYe1/waVnNMFZXVqiwOMTBW9gGkABc8zEhrgcvatzA7SonV2U8HWWLHTmxtsUocFXpVmkSCCORU4aDqsO3PRxeOKfQl7g1up93NRlgA0CmqO6FmX/ANjx1v7W+z2lFvZ1RwMNb6o058SmuCgpVFI+oowHKE00ytjabBL3tb2lZuK9IqYEU2l54nqjz9ys5tS9SNim2FlbT9IG0+rQcHVAZzC4bHxKwcZtWtWkOdDfZbYd/HvVVoXXnj+uXXyfqHXJuSSbknU80pCAhdXIAJ6QJ4RD2FPlRgqSbII6zf5h3pgKlBV6lhqcSAOVySpVQbPE1B3rrcIIasTD0wHNhoF+9b1D1QsV0jnWGrSc/NRecz8xjtPDtV7YgJc9xBBJJIIIi8/NbKUBRTgVU2rP0aqRchpcO0X+SsyklVlyfodVzYirwLJ/3fmugeKbHlzWjq6TMT2cAosPs2jh3k0mBpfzPG4EnsTqtFkOcAC7WT5Jvt15uRibVritXc4jLa19Vk0WuONpNpkh2ZsEbuJ8Fdxbf3unWMAAWElbeyNjNov6ZxzVHC1rNnh3K2sdOjwup7PmrEqnhXdYd6t715+vtYZXqGm+lUDHPguBDRJgjzAQ+viarS1tKnSa4EHO7M6DyFlZppzik+krOpUOia2nM5RExCRylrHrFQuXSM08FKqg2hR9sDtBHxTxjqP9an98LQspYUbMRTdo9p7HAqZpnRBYZonKvVxTKYAJlx0aLuPcqznVKvrHo2ey09Y9rvJS0xYrY1rTlaC9/st3dp3KB1N1T+KbewPV7+Pen06TWCGgAck9ZtawrQAICChCgEISogATgkSqAVTauOGHouqfzaNHE/q6uQuJ9Jto9LWytPUp9UczvP64LfM2lY1eqXuJcZJMkpgTHFAK7OZTdRv0TpTXFVERUZUhTYUVo+jVLpMYynr0jKrD30nLLLCLGxGoXR+grW/tBuYSQx5byNr+EqP00wjaWPqBoADg10DS4v7wVFYCEIQOY8tu0kdhhXKG18QzSq7sMH4qlCv7H2c7FV2UW2k9Y7mtGrj2BMXa6DZe0qjaFTF4jKabOrSbEdJV3DsG/wDJYtbb2Ie4ucWyTJ6v5p/pDtFlWo2lQthqAyUgNDxqdrlkKZF8qvO2xX3VI7APJQ1cdWf61V5/1Ee4KuiFcibSpQEAJVUCc0JApGhEACISpQqEFk9NShEOCdKYEpKBQVewVTVvw+Cz1LRfBBRY2sKOu0f8rbYbLFwRHSDTu81sNK5V0iXMlzKOVR2rtIUGWg1HeqPmeSQqfG7Uo0AekeAQJyi7vBYmK9KbHoWd7/Iea5urULnOJMkzJ70xp0C1jOtzZm0HPxVKpXeSA7fo224bty3dsN/dOLZB4g6rjGOho+38lcdtF7WhmreErpedmk6/SGs4kOc8z2qHC7Tr0iOjquEbpkeBskq1i+SQANwCrQsWGunwHpi9hHS0mu5tOU+BldXs3bVHFD927rb2Os4d2/tC8vhSUqzmODmEhzTII4rHXEqyvX2PT8wWbgsWK1KnUFs7QeyRopalWxC4tpKpuVC4p2abpIXRhxJqPGjz3Eo+kVPbPifNY/7Tfwb4HzR+038G+B8132Me2x0795ntKBWdy93ksf8Aab+DfA+aP2m/g3wPmmw9t+htGuyzHR2BvkpztnFCJqG+nVZ5Lm2bWqN0DPCUrNrvDsxYx/JwcQe26bye3W4PaWJe9maoGscT1nMbFhJ3BdO1k3kC03O7ivNX+k1d1Rr3MpHL6rcrso7pVl/ppiiCMlESZJDXSeA9bQLn1NblegSlXntP0zxLRAZR72v/ABJ/14xX9Oh91/4ljxq69ACVef8A14xX9Oh91/4kfXnFf06H3X/iTxqa9BShee/XnFf06H3X/iS/XnFf06H3X/iTxprr9u7RFCi6D13Wby5rz+o5Mx23a1dwLw23AHzVM4t3Ae9dOfUS+1glK0qp9IPJKMQ4cFrWVsphVf6S7gEfSDwCaYnypCFB9IPAI6c8k0xu+idTLtHDni4t8WkfGFq//wCjUgMTQdvdTj7rj+JcdTxT2uDmnK5pBBGoIMgq5tfbdXGVBUqhgcGhvVBAtN7k3uosVsqTKo+nPJHTHkiJ2tldLi//AMfhPo4tisQ0GqRrTpbmdp39/Jc5s7absPWbVaym9zTIDwSJ3GARomYnH1KtR9Socz3mXHiUUEJIUXTHkjpjyTRLCVQ9MeSOmPJNE6UKv0x5JenPJNRYCkaqf0g8Al+lO4BXRcQqn0p3AI+lO4BNFtKFT+lO4BH0p3AJpi6lKo/S3cAl+mO4D3ppi2E4FUfpTuAS/S3cB700x0GEfIEnTj7rb9yusxlQDWe0fILlqO06jNA3wPmpf2zV9ll9bHzU9LG/i9rVGZYy3nUdnPmsjEPNVxc8kk/qAqdbab3xIbbSAfNR/TXcB71BaGDZz8V0ezfRnC1aDKjukzGZh/AkcFyQxz+Dff5rTwfpViKNMU2spECdQ6b/AOpKOl+qWE/+ms+v+SV3ophT/U+/+SwPrpifYo/df+JH10xPsUfuv/Em9f1fTe+qWEiP3n3/AMkn1Qwn/wBPv/ksL66Yn2KP3X/iR9dMT7FH7r/xKez03fqjhP8A6ff/ACSfVHCf/T7/AOSw/rpifYo/df8AiR9dMT7FH7r/AMSex2WDwbKNNtNmbK3STJ1lTdGJXDfXPE+xR+678SX66Yn2KP3X/iWfFddyhcL9c8T7FH7r/wASPrnifYo/dd+JXE1zqEIWkCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQCEIQf/Z"}}], "tabbable": null, "tooltip": null}}, "919ac8a1b1b5464b945f9821019b36f5": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "6a7f30fc764548ca8a28a6cefcd20aa7": {"model_name": "OutputModel", "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_919ac8a1b1b5464b945f9821019b36f5", "msg_id": "", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Video available at https://www.bilibili.com/video/BV1hz4y177Fn\n"}, {"output_type": "display_data", "metadata": {}, "data": {"text/plain": "<__main__.PlayVideo at 0x108011270>", "text/html": "\n \n "}}], "tabbable": null, "tooltip": null}}, "6bbdc17abcde4e8ea62a4ce229b50f85": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "61789f6bcf0345babefa64aaebe7677b": {"model_name": "TabModel", "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "TabModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "TabView", "box_style": "", "children": ["IPY_MODEL_afccf5bc5c6145df827ae3db12ab5bc8", "IPY_MODEL_6a7f30fc764548ca8a28a6cefcd20aa7"], "layout": "IPY_MODEL_6bbdc17abcde4e8ea62a4ce229b50f85", "selected_index": 0, "tabbable": null, "titles": ["Youtube", "Bilibili"], "tooltip": null}}, "9c7b706d987f4cedaa17d6303043b0ee": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "3cdd675773a242a7ad744b3a94d3a6ee": {"model_name": "OutputModel", "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_9c7b706d987f4cedaa17d6303043b0ee", "msg_id": "", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Video available at https://youtube.com/watch?v=zeHOBxG61RU\n"}, {"output_type": "display_data", "metadata": {}, "data": {"text/plain": "", "text/html": "\n \n ", "image/jpeg": "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"}}], "tabbable": null, "tooltip": null}}, "3aa5b7ecaf86426d9c0d01205c6f5d6e": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "4ee12c200e1b43c6a107d56a5b820877": {"model_name": "OutputModel", "model_module": "@jupyter-widgets/output", "model_module_version": "1.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/output", "_model_module_version": "1.0.0", "_model_name": "OutputModel", "_view_count": null, "_view_module": "@jupyter-widgets/output", "_view_module_version": "1.0.0", "_view_name": "OutputView", "layout": "IPY_MODEL_3aa5b7ecaf86426d9c0d01205c6f5d6e", "msg_id": "", "outputs": [{"output_type": "stream", "name": "stdout", "text": "Video available at https://www.bilibili.com/video/BV1Su4y1U7aK\n"}, {"output_type": "display_data", "metadata": {}, "data": {"text/plain": "<__main__.PlayVideo at 0x108052470>", "text/html": "\n \n "}}], "tabbable": null, "tooltip": null}}, "e9fdea23690d4774b3bdb966a6e967d9": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"_model_module": "@jupyter-widgets/base", "_model_module_version": "2.0.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "2.0.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border_bottom": null, "border_left": null, "border_right": null, "border_top": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null}}, "af7e6eb1ddf54c348c5eb4cea239ac4f": {"model_name": "TabModel", "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "state": {"_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "2.0.0", "_model_name": "TabModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "2.0.0", "_view_name": "TabView", "box_style": "", "children": ["IPY_MODEL_3cdd675773a242a7ad744b3a94d3a6ee", "IPY_MODEL_4ee12c200e1b43c6a107d56a5b820877"], "layout": "IPY_MODEL_e9fdea23690d4774b3bdb966a6e967d9", "selected_index": 0, "tabbable": null, "titles": ["Youtube", "Bilibili"], "tooltip": null}}}, "version_major": 2, "version_minor": 0} - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Impact Talks#

-

How we do research or work on projects can be as important or more than the research and projects themselves. “Impact talks” were created to put an emphasis on the “how” and its implications when it comes to Climate Science and the current Climate crisis.

-

In this activity, you will listen to four pre-recorded ~15 minutes talks and interviews with practitioners on selected topics followed by live discussion within student project groups, for a total time of 30 minutes (~15’ videos + ~15’ discussion).

-

These interviews with practitioners in the field are designed to spark reflections and discussions among students about important topics that may not always be on the forefront of everyone’s mind when thinking about Climate Science and Climate Change.

-
-

Guidance for discussions#

-

All talks will be watched in the first or the last half hour of the respective project slots and will be followed by a discussion within the project groups.

-
    -
  • These discussions will be an opportunity for students not only to delve deeper into the topics, but also to hone their leadership skills - all/most will get to lead the discussion, whether leading “from the front of from behind”

  • -
  • For each talk, please decide during “pod introduction” who will be the two leaders:

    -
      -
    • One student/leader will be tasked with leading the discussion “from the front” by -(1) reading out loud and putting on the chat the prompt being addressed, -(2) answering discussion prompts at first until the group warms up and others wish to answer or offer thoughts first, and -(3) encouraging everyone in the group to participate in the best way that suits each person(*).

    • -
    • One student/leader will be tasked with leading the discussion “from behind” by -(1) keeping an eye on who has the microphone and respectfully encouraging all to share it, -(2) asking along the way of answering the prompt if any others wish to contribute thoughts whether speaking or via chat/text (*), and -(3) keeping track of time (**).

    • -
    -
  • -
-

*Remember that not everyone wishes to contribute to discussions in the same manner. Not all may wish to speak, but we want to provide space such that all have the opportunity to participate as they wish. Consider giving a few minutes to answer prompts individually and then share. Some may wish to draw or text instead of speaking, etc. and ideally both assigned leaders in the group can foster all kinds of participation.

-

**You will have 30 minutes to both watch the video and start engaging in discussion; at least one assigned leader will keep track of time. This doesn’t mean all the prompts will be answered, but rather they can all get group and individual reflections started.

-

Below you will see the title of four (4) themes, corresponding videos and discussion prompts.

-
-
-

Climate Justice#

-
-

What is Climate Justice?#

-

Climate justice is about economic equity, security and gender equality and allows us to address climate issues from deeper and more interconnected perspectives.

-

Ideally, we would find a balance between the countries of the Global North that emit more greenhouse gasses and those of the Global South that are more vulnerable to climate change. With this vision in mind, climate justice calls for climate action on three fronts: reduction of greenhouse gas emissions, adaptation to climate change and payment for the losses and damages that it is already producing.

-

It is important to understand that climate justice will only be complete when it encompasses these three items. That is, when there is new and additional support and financing for vulnerable communities, not only for loss and damage, but also for adaptation and mitigation.

-
-
-

About the speaker#

-

José’s keywords: mitigation, climate change, human rights, and legal consultant

-

On the web: José’s LinkedIn & World’s Youth for Climate Justice

-

Recent interviews, talks, & presentation: Plataforma Boliviana Frente al Cambio Climático: COP27 (Spanish) & Escazú Agreement and Biodiversity Goals (Spanish)

-
-
-

Video featuring José Daniel Rodríguez-Orúe#

-
-
-
# @title featuring José Daniel Rodríguez-Orúe
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-    self.id = id
-    if source == 'Bilibili':
-      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
-    elif source == 'Osf':
-      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
-    super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-  tab_contents = []
-  for i, video_id in enumerate(video_ids):
-    out = widgets.Output()
-    with out:
-      if video_ids[i][0] == 'Youtube':
-        video = YouTubeVideo(id=video_ids[i][1], width=W,
-                             height=H, fs=fs, rel=0)
-        print(f'Video available at https://youtube.com/watch?v={video.id}')
-      else:
-        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
-                          height=H, fs=fs, autoplay=False)
-        if video_ids[i][0] == 'Bilibili':
-          print(f'Video available at https://www.bilibili.com/video/{video.id}')
-        elif video_ids[i][0] == 'Osf':
-          print(f'Video available at https://osf.io/{video.id}')
-      display(video)
-    tab_contents.append(out)
-  return tab_contents
-
-
-video_ids = [('Youtube', 'JoPEpqUxMBU'), ('Bilibili', 'BV1jW4y1Z7zb')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-  tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
-
-
-
-

Discussion prompts#

-
    -
  • Veronica starts off the video sharing how she defines Climate justice. How do you view it? What might be advantages or disadvantages of Veronica’s definition?

  • -
  • José talks about how climate change widens and deepens existing inequalities within and outside of political boundaries. Have you observed examples of this wider and deeper gap in your region or community? What are some examples of how to address this. These can be examples you have seen in effect or something that has not yet been done but that you could see helping.

  • -
  • As you can see, climate justice is a scientific, political, socio economic and legal challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing injustices, sometimes it takes more than that. From the video and discussion in your group, what is one small action you might implement to contribute to climate justice?

  • -
-
-
-
-

Equity in Climate and Climate Science#

-
-

What is Equity in Climate?#

-

Equity is a broad topic that centers on recognizing not all people have the same needs and not all people face the same barriers. Equity is a process, a way of doing, the “how”.

-

“Equity is achieved by eliminating structural barriers resulting from historical and present-day inequities and meeting individuals’, groups’, and organizations’ unique needs. - Lily Zheng , DEI Deconstructed”

-
-
-

Interview summary & highlights#

-

In this short video, speaker Juliana Arbeláez tells us about her experience with equity from the lens of a climate scientist, advocate, and science communicator. She shares her view and definition of “equity” and how it plays a role in her career, professional work and generally in the things she does. She shares about an initiative she leads called “Climatewiki”, which is an incredible platform used to share in Spanish about the impact of climate change, in particular from the latinamerican lens. Additionally, Juliana shares inequities she has found as a climate scientists, steps she hs takin to address this, and how we might take positive action to support communities that have been impacted negatively by bad/inequitable practices such as harassment, sexual harassment, and others that happen in climate science. Lastly, Juliana shares some takeaways and what you could do to support equity in climate science and/or climate solutions from an equity lens.

-
-
-

About the speaker#

-

Juliana’s keywords: mitigation, climate change, water, and science inclusivity

-

On the web: Juliana’s Website & Juliana’s Instagram

-

Recent interviews, talks, & presentations: Three concepts of Climate Change (Spanish)

-
-
-

Video featuring Juliana Arbeláez#

-
-
-
# @title featuring Juliana Arbeláez 
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-    self.id = id
-    if source == 'Bilibili':
-      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
-    elif source == 'Osf':
-      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
-    super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-  tab_contents = []
-  for i, video_id in enumerate(video_ids):
-    out = widgets.Output()
-    with out:
-      if video_ids[i][0] == 'Youtube':
-        video = YouTubeVideo(id=video_ids[i][1], width=W,
-                             height=H, fs=fs, rel=0)
-        print(f'Video available at https://youtube.com/watch?v={video.id}')
-      else:
-        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
-                          height=H, fs=fs, autoplay=False)
-        if video_ids[i][0] == 'Bilibili':
-          print(f'Video available at https://www.bilibili.com/video/{video.id}')
-        elif video_ids[i][0] == 'Osf':
-          print(f'Video available at https://osf.io/{video.id}')
-      display(video)
-    tab_contents.append(out)
-  return tab_contents
-
-
-video_ids = [('Youtube', 'c5WfuNCnWy4'), ('Bilibili', 'BV11m4y1E72e')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-  tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
-
-
-
-

Discussion prompts#

-
    -
  • Juliana mentioned how she views equity. How do you view equity? What might be advantages or disadvantages of Juliana’s definition?

  • -
  • What are good ways to bring reliable information to the people who need it?

  • -
  • In many cultures, there are still many expectations regarding which jobs, behaviors, and other life choices are appropriate based on gender, background etc. When you consider your home country and/or the country where you currently live

    -
      -
    • Have you observed any of these?

    • -
    • Do you think they are changing? Is there anyone challenging them in particular?

    • -
    • Is anything done to challenge them or do you have any ideas what could be done?

    • -
    -
  • -
  • Can you think of further examples of traditional/indigenous knowledge that helps or could help with addressing climate change?

  • -
  • As you can see, equity in climate and climate science is a scientific, political, and socio economic challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing inequities, sometimes it takes more than that. From the video and discussion in your group, what is one small action you might implement to contribute to equity in climate and/or climate science?

  • -
-
-
-
-

Open Climate Science#

-
-

What is Open Climate Science?#

-

Open Climate Science applies the best practices of the open science movement to climate science research. Its main goal is to openly share data, models, and findings in a manner that benefits the scientific community and the public.

-

As Lubia Vinhas from the National Institute for Space Research of Brazil (Instituto Nacional de Pesquisas Espaciais, INPE) notes, “Open Science is necessary if we want to trust, audit, and reproduce results.”

-
-
-

Interview summary & highlights#

-

Professor Lubia Vinhas is a senior researcher at INPE, the Brazilian Space Research Institute. She has expertise in Remote Sensing, Software Development, and Open Science. Today, she will share her extensive experience as a researcher in Earth Observation and discuss open science, along with the open remote sensing project she contributed to, called Brazil Data Cube.

-

Lubia’s keywords: deforestation, monitoring and dissemination, GIS

-

On the web: Lubia’s GitHub

-

Recent interviews, talks, & presentations: Meet Lúbia Vinhas (Portuguese)

-
-
-

Video featuring Lubia Vinhas#

-
-
-
# @title featuring Lubia Vinhas 
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-    self.id = id
-    if source == 'Bilibili':
-      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
-    elif source == 'Osf':
-      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
-    super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-  tab_contents = []
-  for i, video_id in enumerate(video_ids):
-    out = widgets.Output()
-    with out:
-      if video_ids[i][0] == 'Youtube':
-        video = YouTubeVideo(id=video_ids[i][1], width=W,
-                             height=H, fs=fs, rel=0)
-        print(f'Video available at https://youtube.com/watch?v={video.id}')
-      else:
-        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
-                          height=H, fs=fs, autoplay=False)
-        if video_ids[i][0] == 'Bilibili':
-          print(f'Video available at https://www.bilibili.com/video/{video.id}')
-        elif video_ids[i][0] == 'Osf':
-          print(f'Video available at https://osf.io/{video.id}')
-      display(video)
-    tab_contents.append(out)
-  return tab_contents
-
-
-video_ids = [('Youtube', 'g2upXZxXlrc'), ('Bilibili', 'BV1hz4y177Fn')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-  tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
-
-
-
-

Discussion prompts#

-
    -
  • How do you think open science can help your community to fight climate change?

  • -
  • What prevents scientists from openly sharing all research findings?

  • -
  • Open Science and Ethics. What are some examples of how climate data is (or is not) important to the community? How could data be managed to increase both access and accessibility?

  • -
  • As you can see, open climate science is a scientific, political, and socio economic challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing inequities, sometimes it takes more than that. From the video and discussion in your group, what is one small little action you might implement to contribute to open climate science?

  • -
-
-
-
-

Psychology of the Climate Crisis and Climate Science Communication#

-
-

What is the Psychology of the Climate Crisis?#

-

The climate crisis is the result of human behavior and, therefore, the science of Human Behavior Psychology is central to our understanding of why we are here. It addresses the question of what it is about human thought and behavior and the structures and systems that we have created that have led to the current crisis, why we are not responding as if we’re in an emergency, and what we can do to change that.

-
-
-

Talk summary#

-

Psychological and behavioral explanations for the climate crisis are often centered on the quirky or flawed ways in which human cognition works. This includes our tendency to prioritize immediate rewards and satisfaction over future rewards, our tendency to be overly optimistic, and our decreased sensitivity to threats that happen far away or far in the future. -This narrative is very problematic because it essentially justifies the climate and biodiversity crisis as an inevitable product of universal human nature. A more productive view focuses on how social norms and the perceived belief of others shape human behavior and how effective communication about climate change and our own beliefs and actions can influence the behavior of individuals, communities, industry and policy makers.

-
-
-

About the speaker#

-

Professor Clare Kelly is a cognitive neuroscientist, who has been making a push to bring Climate Science into the curriculum of all undergraduate students. Additionally, she has designed a course on the psychology of the climate crisis specifically to help students understand what features of human behavior brought about the climate crisis and what prevents us from addressing this challenge appropriately.

-

Clare’s keywords: psychology, collective behavior, communicating climate change

-

On the web: Clare’s research

-

Recent interviews, talks, & presentation: How to be a scientist in a world on fire?

-

Further readings:

- -
-
-

Video featuring Clare Kelly#

-
-
-
# @title featuring Clare Kelly
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-    self.id = id
-    if source == 'Bilibili':
-      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
-    elif source == 'Osf':
-      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
-    super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-  tab_contents = []
-  for i, video_id in enumerate(video_ids):
-    out = widgets.Output()
-    with out:
-      if video_ids[i][0] == 'Youtube':
-        video = YouTubeVideo(id=video_ids[i][1], width=W,
-                             height=H, fs=fs, rel=0)
-        print(f'Video available at https://youtube.com/watch?v={video.id}')
-      else:
-        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
-                          height=H, fs=fs, autoplay=False)
-        if video_ids[i][0] == 'Bilibili':
-          print(f'Video available at https://www.bilibili.com/video/{video.id}')
-        elif video_ids[i][0] == 'Osf':
-          print(f'Video available at https://osf.io/{video.id}')
-      display(video)
-    tab_contents.append(out)
-  return tab_contents
-
-
-video_ids = [('Youtube', 'zeHOBxG61RU'), ('Bilibili', 'BV1Su4y1U7aK')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-  tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
-
-
-
-

Discussion prompts#

-
    -
  • How did you think human behavior influences the climate crises before you listened to the interview? Did this change after you listened to the interview?

  • -
  • What social groups influence your perception of climate change? Do you agree with their ideas? How do they influence your thoughts and beliefs?

  • -
  • Are there any visual graphics, blogs, songs or other means of non-academic communication that you think are especially good or inspiring?

  • -
  • As you can see, climate science communication and the psychology of it is a scientific, political, and socio economic challenge impacting everyone. Sometimes, awareness starts a snowball effect in addressing inequities, sometimes it takes more than that. From the video and discussion in your group, what is one small little action you might implement to contribute to climate science communication and decrease the stigma of the psychological implications of the climate crisis?

  • -
-
-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/professional_development/mentors.html b/book/_build/html/projects/professional_development/mentors.html deleted file mode 100644 index 38fadf0b3..000000000 --- a/book/_build/html/projects/professional_development/mentors.html +++ /dev/null @@ -1,1157 +0,0 @@ - - - - - - - - - - - - Mentor Meetings — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Mentor Meetings#

-

Our mentors have several years of experience working in any climate-related discipline, including industry, academia, government, non-profits, journalism, and science communication.

-

They will visit project groups to speak about their professional path, share career advice, and provide a networking opportunity for the students.

-

Teaching Assistants are welcome to attend up to two meetings with mentors as part of their working hours.

-
-

Suggested meeting structure (~60 minutes)#

-
-

Introduction: 10 minutes#

-

Every student introduces themselves, shares what brings them to Climatematch Academy, and how they hope to use what they experience during the course in the near future. This will help students make more specific connections by the end of the hour.

-
-
-

Mentor’s Journey and Lessons: 10 minutes#

-

The mentor talks about who they are, what they have done and still do, any lessons they have learned, and the message they wish to share with the group.

-
-
-

Questions and Answers: 30 minutes#

-

These are some questions that can be used as prompts:

-
    -
  • General career-related questions:

    -
      -
    • In your own opinion, what qualifications and background are required to succeed in your area of work?

    • -
    • What are the biggest obstacles and opportunities you see in your field right now?

    • -
    • How important would you say that diversity, equity, and inclusion are in your field?

    • -
    • How can one acquire the practical experience required to enter your field?

    • -
    • What do you wish you had known when you started working in your field?

    • -
    -
  • -
  • Specific career-related questions (might not be relevant to all mentors):

    -
      -
    • How do you go about explaining difficult topics in your field to the public or decision-makers? Are there any particular difficulties or concerns you have faced?

    • -
    • Do you have any suggestions for successful methods to close the gap between climate research and climate action?

    • -
    • Can you shed any light on how interdisciplinary climate science is and the significance of working with other disciplines?

    • -
    -
  • -
  • General climate questions:

    -
      -
    • In your opinion, how can climate justice be actualised and what are the major challenges (if you agree that there are)?

    • -
    • How do you anticipate the climate will change?

    • -
    • Can you suggest other mitigation and adaptation measures especially for the traditionally under-represented regions of the world?

    • -
    • Are there any international partnerships or groups that, in your opinion, are particularly crucial to advancing the study of climate science and tackling climate challenges?

    • -
    • Can you offer any tips or techniques for efficiently presenting climate science to various audiences, including skeptics or individuals with little prior knowledge of the subject?

    • -
    • What else should people, communities, and governments do in your opinion to lessen the effects of climate change and prepare for them?

    • -
    • What practical steps can one take to foster collaboration between climate-related disciplines? How important is it in your opinion?

    • -
    -
  • -
-
-
-

Networking and Collaboration: 10 minutes#

-

Using the information shared in the meeting, what are some specific ways the group could connect further?

-
-
-
-

Get the most out of your meetings with mentors#

-

What makes a great mentee?

-
    -
  • Great mentees love asking questions. You are encouraged to ask the mentors questions!

  • -
  • Great mentees are willing to learn, open-minded and responsive to different perspectives.

  • -
  • They take initiatives and look out for advancing their career and upgrading their skills.

  • -
  • They cherish the advice and time of their mentors, demonstrate respect by being punctual and show appreciation for their mentor’s guidance and support.

  • -
  • Great mentees respect limits while acting professionally when speaking with mentors.

  • -
  • They typically behave morally and honestly, acting with integrity.

  • -
-

We suggest that you ask lots of questions, enjoy your time with your mentors and stay in touch with them after the course!

-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.html b/book/_build/html/projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.html deleted file mode 100644 index 71250d767..000000000 --- a/book/_build/html/projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.html +++ /dev/null @@ -1,1578 +0,0 @@ - - - - - - - - - - - - The Impact of ENSO on Precipitation and Temperature — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

The Impact of ENSO on Precipitation and Temperature#

-

Content creators: Olawale Ikuyajolu & Patrick Orenstein

-

Content reviewers: Marguerite Brown, Yuxin Zhou

-

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

-

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

-

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

-

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

-

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

-

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

-
-
-

Project Template#

-

Project Template

-

Note: The dashed boxes are socio-economic questions.

-
-
-

Data Exploration Notebook#

-
-

Project Setup#

-
-
-
# google colab installs
-
-# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# install all packages in one call (+ use mamba instead of conda)
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils "esmf<=8.3.1" xesmf &> /dev/null
-
-
-
-
-
-
-
# imports
-
-import time
-
-tic = time.time()
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-import xesmf as xe
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-import cartopy.crs as ccrs
-import pooch
-import os
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 7
-      3 import time
-      5 tic = time.time()
-----> 7 import intake
-      8 import numpy as np
-      9 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-
-
# functions
-
-%matplotlib inline
-
-col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)  # open an intake catalog containing the Pangeo CMIP cloud data
-
-
-def load_cmip6(source_id, variable_id, member_id, table_id):  # load selected model
-    cat = col.search(
-        source_id=source_ids,
-        variable_id=variable_id,
-        member_id=member_id,
-        table_id=table_id,
-        grid_label="gn",
-        experiment_id=[
-            "historical",
-            "ssp126",
-            "ssp245",
-            "ssp585",
-        ],  # downloading the scenarios out of the total 5+historical
-        require_all_on=["source_id"],
-    )
-
-    kwargs = dict(
-        preprocess=combined_preprocessing,
-        xarray_open_kwargs=dict(use_cftime=True),
-        storage_options={"token": "anon"},
-    )
-    cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-    dt = cat.to_datatree(**kwargs)
-
-    return dt
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 3
-      1 # functions
-----> 3 get_ipython().run_line_magic('matplotlib', 'inline')
-      5 col = intake.open_esm_datastore(
-      6     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      7 )  # open an intake catalog containing the Pangeo CMIP cloud data
-     10 def load_cmip6(source_id, variable_id, member_id, table_id):  # load selected model
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/interactiveshell.py:2417, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
-   2415     kwargs['local_ns'] = self.get_local_scope(stack_depth)
-   2416 with self.builtin_trap:
--> 2417     result = fn(*args, **kwargs)
-   2419 # The code below prevents the output from being displayed
-   2420 # when using magics with decodator @output_can_be_silenced
-   2421 # when the last Python token in the expression is a ';'.
-   2422 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/magics/pylab.py:99, in PylabMagics.matplotlib(self, line)
-     97     print("Available matplotlib backends: %s" % backends_list)
-     98 else:
----> 99     gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
-    100     self._show_matplotlib_backend(args.gui, backend)
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/interactiveshell.py:3588, in InteractiveShell.enable_matplotlib(self, gui)
-   3567 def enable_matplotlib(self, gui=None):
-   3568     """Enable interactive matplotlib and inline figure support.
-   3569 
-   3570     This takes the following steps:
-   (...)
-   3586         display figures inline.
-   3587     """
--> 3588     from matplotlib_inline.backend_inline import configure_inline_support
-   3590     from IPython.core import pylabtools as pt
-   3591     gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/matplotlib_inline/__init__.py:1
-----> 1 from . import backend_inline, config  # noqa
-      2 __version__ = "0.1.6"  # noqa
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/matplotlib_inline/backend_inline.py:6
-      1 """A matplotlib backend for publishing figures via display_data"""
-      3 # Copyright (c) IPython Development Team.
-      4 # Distributed under the terms of the BSD 3-Clause License.
-----> 6 import matplotlib
-      7 from matplotlib import colors
-      8 from matplotlib.backends import backend_agg
-
-ModuleNotFoundError: No module named 'matplotlib'
-
-
-
-
-
-
-
# helper functions
-
-def pooch_load(filelocation=None,filename=None,processor=None):
-    shared_location='/home/jovyan/shared/Data/Projects/ENSO' # this is different for each day
-    user_temp_cache=tempfile.gettempdir()
-    
-    if os.path.exists(os.path.join(shared_location,filename)):
-        file = os.path.join(shared_location,filename)
-    else:
-        file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)
-
-    return file
-
-
-
-
-
-
-

Dataset 1: Load CMIP6 Model of Your Choice#

-

Following W2D1 (Week 2 Day 1) tutorial notebooks:

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

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

  • -
-

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

-
-
-
# pick your model
-
-source_ids = "CESM2"
-
-dm_tas = load_cmip6(
-    source_ids, "tas", "r4i1p1f1", "Amon"
-)  # tas is atmoerhpere temprature
-dm_pr = load_cmip6(source_ids, "pr", "r4i1p1f1", "Amon")  # pr is precipitation rate
-dm_sst = load_cmip6(
-    source_ids, "tos", "r4i1p1f1", "Omon"
-)  # tos is surface ocean temprature
-print(
-    dm_tas.keys()
-)  # an example for one of the datatrees, you can duplicate this for the other DT
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 5
-      1 # pick your model
-      3 source_ids = "CESM2"
-----> 5 dm_tas = load_cmip6(
-      6     source_ids, "tas", "r4i1p1f1", "Amon"
-      7 )  # tas is atmoerhpere temprature
-      8 dm_pr = load_cmip6(source_ids, "pr", "r4i1p1f1", "Amon")  # pr is precipitation rate
-      9 dm_sst = load_cmip6(
-     10     source_ids, "tos", "r4i1p1f1", "Omon"
-     11 )  # tos is surface ocean temprature
-
-NameError: name 'load_cmip6' is not defined
-
-
-
-
-
-
-
# load cell areas for computing ocean surface temparuters means
-
-dt_ocean_area = load_cmip6(source_ids, "areacello", "r4i1p1f1", "Ofx")
-dt_atmos_area = load_cmip6(source_ids, "areacella", "r4i1p1f1", "fx")
-
-dt_ocean_with_area = DataTree()
-dt_atmos_with_area = DataTree()
-
-for model, subtree in dm_sst.items():
-    metric_ocean = dt_ocean_area[model]["historical"].ds["areacello"]
-    dt_ocean_with_area[model] = subtree.map_over_subtree(_parse_metric, metric_ocean)
-
-for model, subtree in dm_pr.items():
-    metric_atmos = dt_atmos_area[model]["historical"].ds["areacella"]
-    dt_atmos_with_area[model] = subtree.map_over_subtree(_parse_metric, metric_atmos)
-
-print(dt_ocean_with_area.keys())
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 3
-      1 # load cell areas for computing ocean surface temparuters means
-----> 3 dt_ocean_area = load_cmip6(source_ids, "areacello", "r4i1p1f1", "Ofx")
-      4 dt_atmos_area = load_cmip6(source_ids, "areacella", "r4i1p1f1", "fx")
-      6 dt_ocean_with_area = DataTree()
-
-NameError: name 'load_cmip6' is not defined
-
-
-
-
-
-
-

Dataset 2: Load Observations#

-

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

-

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

-

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

-
-
-
# Ocean surface temprature 
-filename_SST='sst.mnmean.nc'
-url_SST = 'https://downloads.psl.noaa.gov/Datasets/noaa.ersst.v5/sst.mnmean.nc'
-
-do_sst = xr.open_dataset(pooch_load(url_SST,filename_SST), drop_variables=['time_bnds'])
-
-# Precipitation rate (notice the units in the plot below)
-filename_prec_rate='precip.mon.mean.nc'
-url_prec_rate='https://downloads.psl.noaa.gov/Datasets/cmap/enh/precip.mon.mean.nc'
-do_pr = xr.open_dataset(pooch_load(url_prec_rate,filename_prec_rate))
-
-# Air Temperature Anomalies
-filename_tas='air.2x2.1200.mon.anom.comb.nc'
-url_tas='https://downloads.psl.noaa.gov/Datasets/gistemp/combined/1200km/air.2x2.1200.mon.anom.comb.nc'
-do_tas = xr.open_dataset(pooch_load(url_tas,filename_tas))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 5
-      2 filename_SST='sst.mnmean.nc'
-      3 url_SST = 'https://downloads.psl.noaa.gov/Datasets/noaa.ersst.v5/sst.mnmean.nc'
-----> 5 do_sst = xr.open_dataset(pooch_load(url_SST,filename_SST), drop_variables=['time_bnds'])
-      7 # Precipitation rate (notice the units in the plot below)
-      8 filename_prec_rate='precip.mon.mean.nc'
-
-NameError: name 'xr' is not defined
-
-
-
-
-

We can now visualize the content of the dataset.

-
-
-
# code to print the shape, array names, etc of the dataset
-
-# select just a single model and experiment
-hist_precip = dm_pr["CESM2"]["historical"].ds.pr
-
-fig, ax_july2000 = plt.subplots(
-    ncols=1, nrows=1, figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-)
-
-hist_precip.sel(time="2000-07").squeeze().plot(
-    ax=ax_july2000,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    cmap="magma",
-    robust=True,
-)
-
-ax_july2000.coastlines()
-ax_july2000.set_title("July 2000")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 4
-      1 # code to print the shape, array names, etc of the dataset
-      2 
-      3 # select just a single model and experiment
-----> 4 hist_precip = dm_pr["CESM2"]["historical"].ds.pr
-      6 fig, ax_july2000 = plt.subplots(
-      7     ncols=1, nrows=1, figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-      8 )
-     10 hist_precip.sel(time="2000-07").squeeze().plot(
-     11     ax=ax_july2000,
-     12     x="lon",
-   (...)
-     16     robust=True,
-     17 )
-
-NameError: name 'dm_pr' is not defined
-
-
-
-
-
-
-
hist_sst = dm_sst["CESM2"]["historical"].ds.tos
-
-fig, ax = plt.subplots(
-    ncols=1,
-    nrows=1,
-    figsize=[12, 6],
-    subplot_kw={"projection": ccrs.Robinson(central_longitude=180)},
-)
-
-ax.coastlines()
-ax.gridlines()
-hist_sst.sel(time="2000-07").squeeze().plot(
-    ax=ax,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-2,
-    vmax=30,
-    cmap="magma",
-    robust=True,
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 1
-----> 1 hist_sst = dm_sst["CESM2"]["historical"].ds.tos
-      3 fig, ax = plt.subplots(
-      4     ncols=1,
-      5     nrows=1,
-      6     figsize=[12, 6],
-      7     subplot_kw={"projection": ccrs.Robinson(central_longitude=180)},
-      8 )
-     10 ax.coastlines()
-
-NameError: name 'dm_sst' is not defined
-
-
-
-
-
-
-

Dataset 3: Oceanic Nino Index#

-

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

-
-
-
# get El Nino data from W1D3 tutorial 7
-filename_nino='t6_oceanic-nino-index.nc'
-url_nino = "https://osf.io/8rwxb/download/"
-oni = xr.open_dataset(pooch_load(url_nino,filename_nino))
-print(oni.keys())
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 4
-      2 filename_nino='t6_oceanic-nino-index.nc'
-      3 url_nino = "https://osf.io/8rwxb/download/"
-----> 4 oni = xr.open_dataset(pooch_load(url_nino,filename_nino))
-      5 print(oni.keys())
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
-

Further Reading#

- -
-
-

Resources#

-

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

-

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

-

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

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/Heatwaves.html b/book/_build/html/projects/project-notebooks/Heatwaves.html deleted file mode 100644 index a058b3fdc..000000000 --- a/book/_build/html/projects/project-notebooks/Heatwaves.html +++ /dev/null @@ -1,1518 +0,0 @@ - - - - - - - - - - - - Heatwaves: Assessing the Dynamic Interactions of the Atmosphere and Land — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Heatwaves: Assessing the Dynamic Interactions of the Atmosphere and Land#

-

Content creators: Sara Shamekh, Ibukun Joyce Ogwu

-

Content reviewers: Sloane Garelick, Grace Lindsay, Douglas Rao, Chi Zhang, Ohad Zivan

-

Content editors: Sloane Garelick, Zane Mitrevica, Natalie Steinemann, Ohad Zivan, Chi Zhang

-

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

-

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

-
-
-
# @title Tutorial slides
-# @markdown These are the slides for the videos in all tutorials today
-from IPython.display import IFrame
-link_id = "wx7tu"
-
-
-
-
-

The atmosphere and land are entwined components of the Earth’s system, constantly exchanging energy, mass, and momentum. Their interaction contributes to a variety of physical and biological processes. Understanding of the dynamic interactions between atmosphere and land is crucial for predicting and mitigating the impacts of climate change, such as land-use changes and hazards ranging from droughts, floods, and even fluctuation in agricultural production and products (Jach et. al., 2022; Ogwu et. al. 2018; Dirmeyer et. al. 2016).

-

Climate change is also expected to have a significant impact on cereal production around the world. Changes in temperature, precipitation patterns, and extreme weather events can all affect crop yields, as well as the timing and quality of harvests. For example, higher temperatures can lead to reduced yields for crops like wheat and maize, while changes in rainfall patterns can result in droughts or floods that can damage crops or delay planting.

-

In order to better understand the relationship between climate change and cereal production, researchers have begun to explore the use of environmental monitoring data, including air temperature and soil moisture, to help identify trends and patterns in crop production. By collecting and analyzing this data over time, it may be possible to develop more accurate models and predictions of how climate change will affect cereal production in different regions of the world.

-

However, it is important to note that while environmental monitoring data can provide valuable insights, there are many other factors that can affect cereal production, including soil quality, pests and diseases, and agricultural practices. Therefore, any efforts to correlate cereal production with climate change must take into account a wide range of factors and be based on robust statistical analyses in order to ensure accurate and reliable results.

-

In this project, you will look into how specific climate variables represent and influence our changing climate. In particular,you will explore various climate variables from model data to develop a more comprehensive understanding of different drivers of heatwaves (periods during which the temperature exceeds the climatological average for a certain number of consecutive days over a region larger than a specified value). You will further use this data to understand land-atmosphere interactions, and there will also be an opportunity to relate the aforementioned climate variables to trends in cereal production.

-
-
-

Project Template#

-

Project Template

-

Note: The dashed boxes are socio-economic questions.

-
-
-

Data Exploration Notebook#

-
-

Project Setup#

-
-
-
# google colab installs
-# !pip install condacolab
-# import condacolab
-# condacolab.install()
-
-
-
-
-
-
-
# !mamba install xarray-datatree intake intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils "esmf<=8.3.1" xesmf
-
-
-
-
-
-
-
# imports
-import time
-
-tic = time.time()
-
-import pandas as pd
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-import xesmf as xe
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-import cartopy.crs as ccrs
-import random
-import pooch
-import os
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[4], line 6
-      2 import time
-      4 tic = time.time()
-----> 6 import pandas as pd
-      7 import intake
-      8 import numpy as np
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-
-
-
# helper functions
-
-def pooch_load(filelocation=None,filename=None,processor=None):
-    shared_location='/home/jovyan/shared/Data/Projects/Heatwaves' # this is different for each day
-    user_temp_cache=tempfile.gettempdir()
-    
-    if os.path.exists(os.path.join(shared_location,filename)):
-        file = os.path.join(shared_location,filename)
-    else:
-        file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)
-
-    return file
-
-
-
-
-
-
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-# model_colors = {k:f"C{ki}" for ki, k in enumerate(source_ids)}
-%matplotlib inline
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[6], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-

CMIP6: Near Surface Temperature#

-

You will utilize a CMIP6 dataset to examine temperature trends and heatwaves, applying the CMIP6 loading methods intreduced in W2D1. To learn more about CMIP, including additional ways to access CMIP data, please see our CMIP Resource Bank and the CMIP website.

-

Specifically, in this project you will focus on near-surface temperature, which refers to the air temperature at the Earth’s surface. In this study, you will analyze data from one model and examining its historical temperature records. However, we encourage you to explore other models and investigate intermodel variability, as you learned (or will learn) during your exploration of CMIP datasets in the W2D1 tutorials.

-

After selecting your model, you will plot the near-surface air temperature for the entire globe.

-
-
-
# loading CMIP data
-
-col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)  # open an intake catalog containing the Pangeo CMIP cloud data
-
-# pick our five example models
-# There are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-source_ids = ["MPI-ESM1-2-LR"]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 3
-      1 # loading CMIP data
-----> 3 col = intake.open_esm_datastore(
-      4     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      5 )  # open an intake catalog containing the Pangeo CMIP cloud data
-      7 # pick our five example models
-      8 # There are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-      9 source_ids = ["MPI-ESM1-2-LR"]
-
-NameError: name 'intake' is not defined
-
-
-
-
-
-
-
# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id=source_ids,
-    variable_id="tas",
-    member_id="r1i1p1f1",
-    table_id="3hr",
-    grid_label="gn",
-    experiment_id=["historical"],  # add scenarios if interested in projection
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt = cat.to_datatree(**kwargs)
-dt
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # from the full `col` object, create a subset using facet search
-----> 2 cat = col.search(
-      3     source_id=source_ids,
-      4     variable_id="tas",
-      5     member_id="r1i1p1f1",
-      6     table_id="3hr",
-      7     grid_label="gn",
-      8     experiment_id=["historical"],  # add scenarios if interested in projection
-      9     require_all_on=[
-     10         "source_id"
-     11     ],  # make sure that we only get models which have all of the above experiments
-     12 )
-     14 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     15 kwargs = dict(
-     16     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     17     xarray_open_kwargs=dict(
-   (...)
-     22     },  # anonymous/public authentication to google cloud storage
-     23 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-
-
# select just a single model and experiment
-tas_historical = dt["MPI-ESM1-2-LR"]["historical"].ds.tas
-print("The time range is:")
-print(
-    tas_historical.time[0].data.astype("M8[h]"),
-    "to",
-    tas_historical.time[-1].data.astype("M8[h]"),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # select just a single model and experiment
-----> 2 tas_historical = dt["MPI-ESM1-2-LR"]["historical"].ds.tas
-      3 print("The time range is:")
-      4 print(
-      5     tas_historical.time[0].data.astype("M8[h]"),
-      6     "to",
-      7     tas_historical.time[-1].data.astype("M8[h]"),
-      8 )
-
-NameError: name 'dt' is not defined
-
-
-
-
-

Now it’s time to plot the data. For this initial analysis, we will focus on a specific date and time. As you may have noticed, we are using 3-hourly data, which allows us to also examine the diurnal and seasonal cycles. It would be fascinating to explore how the amplitude of the diurnal and seasonal cycles varies by region and latitude. You can explore this later!

-
-
-
fig, ax_present = plt.subplots(
-    figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-)
-
-# plot a timestep for July 1, 2013
-tas_present = tas_historical.sel(time="2013-07-01T00").squeeze()
-tas_present.plot(ax=ax_present, transform=ccrs.PlateCarree(), cmap="magma", robust=True)
-ax_present.coastlines()
-ax_present.set_title("July, 1st 2013")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 1
-----> 1 fig, ax_present = plt.subplots(
-      2     figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-      3 )
-      5 # plot a timestep for July 1, 2013
-      6 tas_present = tas_historical.sel(time="2013-07-01T00").squeeze()
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

CMIP6: Precipitation and Soil Moisture (Optional)#

-

In addition to examining temperature trends, you can also load precipitation data or variables related to soil moisture. This is an optional exploration, but if you choose to do so, you can load regional precipitation data at the same time and explore how these two variables are related when analyzing regional temperature trends. This can provide insights into how changes in temperature and precipitation may be affecting the local environment.

-

The relationship between soil moisture, vegetation, and temperature is an active field of research. To learn more about covariability of temperature and moisture, you can have a look at Dong et al. (2022) or Humphrey et al. (2021).

-
-
-
-

World Bank Data: Cereal Production and Land Under Cereal Production#

-

Cereal production is a crucial component of global agriculture and food security. The World Bank collects and provides data on cereal production, which includes crops such as wheat, rice, maize, barley, oats, rye, sorghum, millet, and mixed grains. The data covers various indicators such as production quantity, area harvested, yield, and production value.

-

The World Bank also collects data on land under cereals production, which refers to the area of land that is being used to grow cereal crops. This information can be valuable for assessing the productivity and efficiency of cereal production systems in different regions, as well as identifying potential areas for improvement. Overall, the World Bank’s data on cereal production and land under cereals production is an important resource for policymakers, researchers, and other stakeholders who are interested in understanding global trends in agriculture and food security.

-
-
-
# code to retrieve and load the data
-filename_cereal = 'data_cereal_land.csv'
-url_cereal = 'https://raw.githubusercontent.com/Sshamekh/Heatwave/f85f43997e3d6ae61e5d729bf77cfcc188fbf2fd/data_cereal_land.csv'
-ds_cereal_land = pd.read_csv(pooch_load(url_cereal,filename_cereal))
-ds_cereal_land.head() 
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 4
-      2 filename_cereal = 'data_cereal_land.csv'
-      3 url_cereal = 'https://raw.githubusercontent.com/Sshamekh/Heatwave/f85f43997e3d6ae61e5d729bf77cfcc188fbf2fd/data_cereal_land.csv'
-----> 4 ds_cereal_land = pd.read_csv(pooch_load(url_cereal,filename_cereal))
-      5 ds_cereal_land.head() 
-
-NameError: name 'pd' is not defined
-
-
-
-
-
-

Hint for Q7: Heatwave Detection#

-

Question 7 asks you to detect heatwave. Below you can see a flowchart for detecting heatwaves. The flowchart includes three parameters that you need to set in adavance. These three parameters are:

-
    -
  1. w-day: the window (number of days) over which you detect the extreme (95 percentile) of temperature.

  2. -
  3. E (km2): the spatial extent of the heatwave.

  4. -
  5. X (days): the duration of heatwave.

  6. -
-

picture

-
-
-

Hint for Q9: Correlation#

-

For Question 9 you need to compute the correlation between two variables. You can use Pearson’s correlation coefficient to evaluate the correlation between two variables. You can read about Pearsons correlation coefficient on Wikipedia and from Scipy python library. You are also encouraged to plot the scatter plot between two variables to visually see their correlation.

-
-
-

Hint for Q12: Linear Regressions for Heatwave Detection#

-

For Question 12, read the following article: Rousi et al. (2022)

-

For Question 12 you need to build the regession model. You can read abut regression models on Wikipedia and from Scipy python library.

-
-
-

Hint for Q13: Data-Driven Approaches for Heatwave Detection#

-

For Question 13, read the following articles: Li et al. (2023) and Jacques-Dumas et al. (2022)

-
-
-
-
-

Further Reading#

-
    -
  • Dirmeyer, P. A., Gochis, D. J., & Schultz, D. M. (2016). Land-atmosphere interactions: the LoCo perspective. Bulletin of the American Meteorological Society, 97(5), 753-771.

  • -
  • Ogwu I. J., Omotesho, O. A. and Muhammad-Lawal, A., (2018) Chapter 11: Economics of Soil Fertility Management Practices in Nigeria in the book by Obayelu, A. E. ‘Food Systems Sustainability and Environmental Policies in Modern Economies’ (pp. 1-371).Hershey, PA: IGI Global. doi:10.4018/978-1-5225-3631-4

  • -
  • Jach, L., Schwitalla, T., Branch, O., Warrach-Sagi, K., and Wulfmeyer, V. (2022) Sensitivity of land–atmosphere coupling strength to changing atmospheric temperature and moisture over Europe, Earth Syst. Dynam., 13, 109–132, https://doi.org/10.5194/esd-13-109-2022

  • -
-
-
-

Resources#

-

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

-

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

-

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

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/Ocean_acidification.html b/book/_build/html/projects/project-notebooks/Ocean_acidification.html deleted file mode 100644 index d16825662..000000000 --- a/book/_build/html/projects/project-notebooks/Ocean_acidification.html +++ /dev/null @@ -1,1454 +0,0 @@ - - - - - - - - - - - - Ocean Acidification — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Ocean Acidification#

-

Content creators: C. Gabriela Mayorga Adame, Lidia Krinova

-

Content reviewers: Jenna Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

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

-

Our 2023 Sponsors: NASA TOPS, Google DeepMind

-
-
-
# @title Project Background
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-    def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-        self.id = id
-        if source == "Bilibili":
-            src = f"https://player.bilibili.com/player.html?bvid={id}&page={page}"
-        elif source == "Osf":
-            src = f"https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render"
-        super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-    tab_contents = []
-    for i, video_id in enumerate(video_ids):
-        out = widgets.Output()
-        with out:
-            if video_ids[i][0] == "Youtube":
-                video = YouTubeVideo(
-                    id=video_ids[i][1], width=W, height=H, fs=fs, rel=0
-                )
-                print(f"Video available at https://youtube.com/watch?v={video.id}")
-            else:
-                video = PlayVideo(
-                    id=video_ids[i][1],
-                    source=video_ids[i][0],
-                    width=W,
-                    height=H,
-                    fs=fs,
-                    autoplay=False,
-                )
-                if video_ids[i][0] == "Bilibili":
-                    print(
-                        f"Video available at https://www.bilibili.com/video/{video.id}"
-                    )
-                elif video_ids[i][0] == "Osf":
-                    print(f"Video available at https://osf.io/{video.id}")
-            display(video)
-        tab_contents.append(out)
-    return tab_contents
-
-
-video_ids = [('Youtube', 'NAgrB8HxMMk'), ('Bilibili', 'BV1fM4y1x7g8')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-    tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # @title Project Background
-----> 3 from ipywidgets import widgets
-      4 from IPython.display import YouTubeVideo
-      5 from IPython.display import IFrame
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
# @title Tutorial slides
-# @markdown These are the slides for the videos in all tutorials today
-from IPython.display import IFrame
-link_id = "n7wdy"
-
-
-
-
-

Human activities release CO2 into the atmosphere, which leads to atmospheric warming and climate change. A portion of this CO2 released by human activities is absorbed into the oceans, which has a direct, chemical effect on seawater, known as ocean acidification. When CO2 combines with water in the ocean it forms carbonic acid, which makes the ocean more acidic and can have negative impacts on certain marine ecosystems (e.g., reduce the ability of calcifying organisms to form their shells and skeletons). The degree of ocean acidification is often expressed in terms of the pH of seawater, which is the measure of acidity or alkalinity such that a pH below 7 is considered acidic, and a pH greater than 7 is considered alkaline, or basic. Additional background information on ocean acidification can be found here. In this project, you will explore spatial and temporal patterns of and relationships between pH, CO2, and temperature to assess changes in ocean acidification and the impact on marine ecosystems.

-

In this project, you will analyse ocean model and observational data from global databases to extract variables like pH, CO2, and temperature, and to investigate ocean acidification process in your region of interest. This project will also be an opportunity to investigate the relationships between these variables as well as their impact on the marine ecosystems.

-
-
-

Project Template#

-

Project Template

-

Note: The dashed boxes are socio-economic questions.

-
-
-

Data Exploration Notebook#

-
-

Project Setup#

-
-
-
# google colab installs
-
-# !mamaba install netCDF4
-
-
-
-
-
-
-
# imports
-
-import random
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-import pooch
-import pandas as pd
-import os
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[4], line 4
-      1 # imports
-      3 import random
-----> 4 import numpy as np
-      5 import matplotlib.pyplot as plt
-      6 import xarray as xr
-
-ModuleNotFoundError: No module named 'numpy'
-
-
-
-
-
-
-
# helper functions
-
-def pooch_load(filelocation=None,filename=None,processor=None):
-    shared_location='/home/jovyan/shared/Data/Projects/Ocean_Acidification' # this is different for each day
-    user_temp_cache=tempfile.gettempdir()
-    
-    if os.path.exists(os.path.join(shared_location,filename)):
-        file = os.path.join(shared_location,filename)
-    else:
-        file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)
-
-    return file
-
-
-
-
-
-
-

NOAA Ocean pH and Acidity#

-
-

Global surface ocean acidification indicators from 1750 to 2100 (NCEI Accession 0259391)#

-

This data package contains a hybrid surface ocean acidification (OA) data product that is produced based on three recent observational data products:

-
    -
  • Surface Ocean CO2 Atlas (SOCAT, version 2022)

  • -
  • Global Ocean Data Analysis Product version 2 (GLODAPv2, version 2022)

  • -
  • Coastal Ocean Data Analysis Product in North America (CODAP-NA, version 2021), and 14 Earth System Models from the sixth phase of the Coupled Model Intercomparison Project (CMIP6).

  • -
-

The trajectories of ten OA indicators are included in this data product:

-
    -
  • Fugacity of carbon dioxide

  • -
  • pH on Total Scale

  • -
  • Total hydrogen ion content

  • -
  • Free hydrogen ion content

  • -
  • Carbonate ion content

  • -
  • Aragonite saturation state

  • -
  • Calcite saturation state

  • -
  • Revelle Factor

  • -
  • Total dissolved inorganic carbon content

  • -
  • Total alkalinity content

  • -
-

These OA trajectories are provided under preindustrial conditions, historical conditions, and future Shared Socioeconomic Pathways: SSP1-1.9, SSP1-2.6, SSP2-4.5, SSP3-7.0, and SSP5-8.5 from 1750 to 2100 on a global surface ocean grid. These OA trajectories are improved relative to previous OA data products with respect to data quantity, spatial and temporal coverage, diversity of the underlying data and model simulations, and the provided SSPs over the 21st century.

-

Citation: -Jiang, L.-Q., Dunne, J., Carter, B. R., Tjiputra, J. F., Terhaar, J., Sharp, J. D., et al. (2023). Global surface ocean acidification indicators from 1750 to 2100. Journal of Advances in Modeling Earth Systems, 15, e2022MS003563. https://doi.org/10.1029/2022MS003563

-

Dataset: https://www.ncei.noaa.gov/data/oceans/ncei/ocads/metadata/0259391.html

-

We can load and visualize the surface pH as follows:

-
-
-
# code to retrieve and load the data
-# url_SurfacepH= 'https://www.ncei.noaa.gov/data/oceans/ncei/ocads/data/0206289/Surface_pH_1770_2100/Surface_pH_1770_2000.nc' $ old CMIP5 dataset
-filename_SurfacepH='pHT_median_historical.nc'
-url_SurfacepH='https://www.ncei.noaa.gov/data/oceans/ncei/ocads/data/0259391/nc/median/pHT_median_historical.nc'
-ds_pH = xr.open_dataset(pooch_load(url_SurfacepH,filename_SurfacepH))
-ds_pH
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 5
-      3 filename_SurfacepH='pHT_median_historical.nc'
-      4 url_SurfacepH='https://www.ncei.noaa.gov/data/oceans/ncei/ocads/data/0259391/nc/median/pHT_median_historical.nc'
-----> 5 ds_pH = xr.open_dataset(pooch_load(url_SurfacepH,filename_SurfacepH))
-      6 ds_pH
-
-NameError: name 'xr' is not defined
-
-
-
-
-

For those feeling adventurouts, there are also files of future projected changes under various scenarios (SSP1-1.9, SSP1-2.6, SSP2-4.5, SSP3-7.0, and SSP5-8.5, recall W2D1 tutorials):

-
    -
  • pHT_median_ssp119.nc

  • -
  • pHT_median_ssp126.nc

  • -
  • pHT_median_ssp245.nc

  • -
  • pHT_median_ssp370.nc

  • -
  • pHT_median_ssp585.nc

  • -
-

To load them, replace the filename in the path/filename line above. These data were calculated from CMIP6 models. To learn more about CMIP please see our CMIP Resource Bank and the CMIP website.

-
-
-
-

Copernicus#

-

Copernicus is the Earth observation component of the European Union’s Space programme, looking at our planet and its environment to benefit all European citizens. It offers information services that draw from satellite Earth Observation and in-situ (non-space) data.

-

The European Commission manages the Programme. It is implemented in partnership with the Member States, the European Space Agency (ESA), the European Organisation for the Exploitation of Meteorological Satellites (EUMETSAT), the European Centre for Medium-Range Weather Forecasts (ECMWF), EU Agencies and Mercator Océan.

-

Vast amounts of global data from satellites and ground-based, airborne, and seaborne measurement systems provide information to help service providers, public authorities, and other international organisations improve European citizens’ quality of life and beyond. The information services provided are free and openly accessible to users.

-

Source: https://www.copernicus.eu/en/about-copernicus

-
-

ECMWF Atmospheric Composition Reanalysis: Carbon Dioxide (CO2)#

-

From this dataset we will use CO2 column-mean molar fraction from the Single-level chemical vertical integrals variables & Sea Surface Temperature from the Single-level meteorological variables (in case you need to download them direclty from the catalog).

-

This dataset is part of the ECMWF Atmospheric Composition Reanalysis focusing on long-lived greenhouse gases: carbon dioxide (CO2) and methane (CH4). The emissions and natural fluxes at the surface are crucial for the evolution of the long-lived greenhouse gases in the atmosphere. In this dataset the CO2 fluxes from terrestrial vegetation are modelled in order to simulate the variability across a wide range of scales from diurnal to inter-annual. The CH4 chemical loss is represented by a climatological loss rate and the emissions at the surface are taken from a range of datasets.

-

Reanalysis combines model data with observations from across the world into a globally complete and consistent dataset using a model of the atmosphere based on the laws of physics and chemistry. This principle, called data assimilation, is based on the method used by numerical weather prediction centres and air quality forecasting centres, where every so many hours (12 hours at ECMWF) a previous forecast is combined with newly available observations in an optimal way to produce a new best estimate of the state of the atmosphere, called analysis, from which an updated, improved forecast is issued. Reanalysis works in the same way to allow for the provision of a dataset spanning back more than a decade. Reanalysis does not have the constraint of issuing timely forecasts, so there is more time to collect observations, and when going further back in time, to allow for the ingestion of improved versions of the original observations, which all benefit the quality of the reanalysis product.

-

Source & further information: https://ads.atmosphere.copernicus.eu/cdsapp#!/dataset/cams-global-ghg-reanalysis-egg4-monthly?tab=overview

-

We can load and visualize the sea surface temperature and CO2 concentration (from NOAA Global Monitoring Laboratory):

-
-
-
filename_CO2= 'co2_mm_gl.csv'
-url_CO2= 'https://gml.noaa.gov/webdata/ccgg/trends/co2/co2_mm_gl.csv'
-ds_CO2 = pd.read_csv(pooch_load(url_CO2,filename_CO2),header=55)
-
-ds_CO2
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 3
-      1 filename_CO2= 'co2_mm_gl.csv'
-      2 url_CO2= 'https://gml.noaa.gov/webdata/ccgg/trends/co2/co2_mm_gl.csv'
-----> 3 ds_CO2 = pd.read_csv(pooch_load(url_CO2,filename_CO2),header=55)
-      5 ds_CO2
-
-NameError: name 'pd' is not defined
-
-
-
-
-
-
-
# from W1D3 tutorial 6 we have Sea Surface Temprature from 1981 to the present:
-# download the monthly sea surface temperature data from NOAA Physical System
-# Laboratory. The data is processed using the OISST SST Climate Data Records
-# from the NOAA CDR program.
-# the data downloading may take 2-3 minutes to complete.
-
-filename_sst='sst.mon.mean.nc'
-url_sst = "https://osf.io/6pgc2/download/"
-
-ds_SST = xr.open_dataset(pooch_load(url_sst,filename_sst))
-ds_SST
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 10
-      7 filename_sst='sst.mon.mean.nc'
-      8 url_sst = "https://osf.io/6pgc2/download/"
----> 10 ds_SST = xr.open_dataset(pooch_load(url_sst,filename_sst))
-     11 ds_SST
-
-NameError: name 'xr' is not defined
-
-
-
-
-

Hint for question 4:

-

Use the attached image (figure 5 in this website) and this mapping tool. Search for each species on the mapping tool to see the spatial global distribution.

-

effects of ocean acidifaction

-
-
-
-
-

Further Reading#

- -
-
-

Resources#

-

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

-

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

-

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

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/Regional_precipitation_variability.html b/book/_build/html/projects/project-notebooks/Regional_precipitation_variability.html deleted file mode 100644 index b7e1a303a..000000000 --- a/book/_build/html/projects/project-notebooks/Regional_precipitation_variability.html +++ /dev/null @@ -1,1634 +0,0 @@ - - - - - - - - - - - - Regional Precipitation Variability and Extreme Events — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Regional Precipitation Variability and Extreme Events#

-

Content creators: Laura Paccini, Raphael Rocha

-

Content reviewers: Marguerite Brown, Ohad Zivan, Jenna Pearson, Chi Zhang

-

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

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-
# @title Project Background
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-    def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-        self.id = id
-        if source == "Bilibili":
-            src = f"https://player.bilibili.com/player.html?bvid={id}&page={page}"
-        elif source == "Osf":
-            src = f"https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render"
-        super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-    tab_contents = []
-    for i, video_id in enumerate(video_ids):
-        out = widgets.Output()
-        with out:
-            if video_ids[i][0] == "Youtube":
-                video = YouTubeVideo(
-                    id=video_ids[i][1], width=W, height=H, fs=fs, rel=0
-                )
-                print(f"Video available at https://youtube.com/watch?v={video.id}")
-            else:
-                video = PlayVideo(
-                    id=video_ids[i][1],
-                    source=video_ids[i][0],
-                    width=W,
-                    height=H,
-                    fs=fs,
-                    autoplay=False,
-                )
-                if video_ids[i][0] == "Bilibili":
-                    print(
-                        f"Video available at https://www.bilibili.com/video/{video.id}"
-                    )
-                elif video_ids[i][0] == "Osf":
-                    print(f"Video available at https://osf.io/{video.id}")
-            display(video)
-        tab_contents.append(out)
-    return tab_contents
-
-
-video_ids = [('Youtube', '49XHRe61LI8'), ('Bilibili', 'BV1Au411L7fo')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-    tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # @title Project Background
-----> 3 from ipywidgets import widgets
-      4 from IPython.display import YouTubeVideo
-      5 from IPython.display import IFrame
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
# @title Tutorial slides
-# @markdown These are the slides for the videos in all tutorials today
-from IPython.display import IFrame
-link_id = "a53b4"
-
-
-
-
-

In this project, you will explore rain gauge and satellite data from CHIRPS and NOAA Terrestrial Climate Data Records NDVI datasets to extract rain estimates and land surface reflectance, respectively. This data will enable identification of extreme events in your region of interest. Besides investigating the relationships between these variables, you are encouraged to study the impact of extreme events on changes in vegetation.

-
-
-

Project Template#

-

Project Template

-

Note: The dashed boxes are socio-economic questions.

-
-
-

Data Exploration Notebook#

-
-

Project Setup#

-
-
-
# imports
-
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-import pooch
-import os
-import tempfile
-import pandas as pd
-import s3fs
-import boto3
-import botocore
-import datetime
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 3
-      1 # imports
-----> 3 import numpy as np
-      4 import matplotlib.pyplot as plt
-      5 import xarray as xr
-
-ModuleNotFoundError: No module named 'numpy'
-
-
-
-
-
-
-
# helper functions
-
-def pooch_load(filelocation=None,filename=None,processor=None):
-    shared_location='/home/jovyan/shared/Data/Projects/Precipitation' # this is different for each day
-    user_temp_cache=tempfile.gettempdir()
-    
-    if os.path.exists(os.path.join(shared_location,filename)):
-        file = os.path.join(shared_location,filename)
-    else:
-        file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)
-
-    return file
-
-
-
-
-
-
-

CHIRPS Version 2.0 Global Daily 0.25°#

-

The Climate Hazards Group InfraRed Precipitation with Station data (CHIRPS) is a high-resolution precipitation dataset developed by the Climate Hazards Group at the University of California, Santa Barbara. It combines satellite-derived precipitation estimates with ground-based station data to provide gridded precipitation data at a quasi-global scale between 50°S-50°N.

-

Read more about CHIRPS here:

- -
-

Indices for Extreme Events#

-

The Expert Team on Climate Change Detection and Indices (ETCCDI) has defined various indices that focus on different aspects such as duration or intensity of extreme events. The following functions provide examples of how to compute indices for each category. You can modify these functions to suit your specific needs or create your own custom functions. Here are some tips you can use:

-
    -
  • Most of the indices require daily data, so in order to select a specific season you can just use xarray to subset the data. Example:

  • -
-

daily_precip_DJF = data_chirps.sel(time=data_chirps['time.season']=='DJF')

-
    -
  • A common threshold for a wet event is precipitation greater than or equal to 1mm/day, while a dry (or non-precipitating) event is defined as precipitation less than 1mm/day.

  • -
  • Some of the indices are based on percentiles. You can define a base period climatology to calculate percentile thresholds, such as the 5th, 10th, 90th, and 95th percentiles, to determine extreme events.

  • -
-
-
-
def calculate_sdii_index(data):
-    """
-    This function calculates the Simple Daily Intensity Index (SDII), which
-    represents the average amount of precipitation on wet days (days with
-    precipitation greater than or equal to 1mm) for each year in the input data.
-    The input data should be a Dataset with time coordinates, and the function
-    returns a Dataset with the SDII index values for each year in the data.
-    ----------
-    - data (xarray.Dataset): Input dataset containing daily precipitation data.
-    - period (str, optional): Period for which to calculate the SDII index.
-
-    Returns:
-    -------
-        - xarray.Dataset: Dataset containing the SDII index for the given period.
-    """
-    # calculate daily precipitation amount on wet days (PR >= 1mm)
-    wet_days = data.where(data >= 1)
-
-    # group by year and calculate the sum precipitation on wet days
-    sum_wet_days_grouped = wet_days.groupby("time.year").sum(dim="time")
-
-    # count number of wet days for each time step
-    w = wet_days.groupby("time.year").count(dim="time")
-
-    # divide by the number of wet days to get SDII index
-    sdii = sum_wet_days_grouped / w
-
-    return sdii
-
-
-
-
-
-
-
def calculate_cdd_index(data):
-    """
-    This function takes a daily precipitation dataset as input and calculates
-    the Consecutive Dry Days (CDD) index, which represents the longest sequence
-    of consecutive days with precipitation less than 1mm. The input data should
-    be a DataArray with time coordinates, and the function returns a DataArray
-    with the CDD values for each unique year in the input data.
-    Parameters:
-    ----------
-      - data (xarray.DataArray): The input daily precipitation data should be
-      a dataset (eg. for chirps_data the SataArray would be chirps_data.precip)
-    Returns:
-    -------
-      - cdd (xarray.DataArray): The calculated CDD index
-
-    """
-    # create a boolean array for dry days (PR < 1mm)
-    dry_days = data < 1
-    # initialize CDD array
-    cdd = np.zeros(len(data.groupby("time.year")))
-    # get unique years as a list
-    unique_years = list(data.groupby("time.year").groups.keys())
-    # iterate for each day
-    for i, year in enumerate(unique_years):
-        consecutive_trues = []
-        current_count = 0
-        for day in dry_days.sel(time=data["time.year"] == year).values:
-            if day:
-                current_count += 1
-            else:
-                if current_count > 0:
-                    consecutive_trues.append(current_count)
-                    current_count = 0
-        if current_count > 0:
-            consecutive_trues.append(current_count)
-        # print(consecutive_trues)
-        # CDD is the largest number of consecutive days
-        cdd[i] = np.max(consecutive_trues)
-    # transform to dataset
-    cdd_da = xr.DataArray(cdd, coords={"year": unique_years}, dims="year")
-    return cdd_da
-
-
-
-
-
-
-
# code to retrieve and load the data
-
-years=range(1981,2024) # the years you want. we want 1981 till 2023
-file_paths=['https://data.chc.ucsb.edu/products/CHIRPS-2.0/global_daily/netcdf/p25/chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files
-filenames=['chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files
-
-downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files
-
-#### open data as xarray
-chirps_data = xr.open_mfdataset(
-    downloaded_files, combine="by_coords"
-)  # open the files as one dataset
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 7
-      4 file_paths=['https://data.chc.ucsb.edu/products/CHIRPS-2.0/global_daily/netcdf/p25/chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files
-      5 filenames=['chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files
-----> 7 downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files
-      9 #### open data as xarray
-     10 chirps_data = xr.open_mfdataset(
-     11     downloaded_files, combine="by_coords"
-     12 )  # open the files as one dataset
-
-Cell In[7], line 7, in <listcomp>(.0)
-      4 file_paths=['https://data.chc.ucsb.edu/products/CHIRPS-2.0/global_daily/netcdf/p25/chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files
-      5 filenames=['chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files
-----> 7 downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files
-      9 #### open data as xarray
-     10 chirps_data = xr.open_mfdataset(
-     11     downloaded_files, combine="by_coords"
-     12 )  # open the files as one dataset
-
-Cell In[4], line 5, in pooch_load(filelocation, filename, processor)
-      3 def pooch_load(filelocation=None,filename=None,processor=None):
-      4     shared_location='/home/jovyan/shared/Data/Projects/Precipitation' # this is different for each day
-----> 5     user_temp_cache=tempfile.gettempdir()
-      7     if os.path.exists(os.path.join(shared_location,filename)):
-      8         file = os.path.join(shared_location,filename)
-
-NameError: name 'tempfile' is not defined
-
-
-
-
-

We can now visualize the content of the dataset.

-
-
-
# code to print the shape, array names, etc of the dataset
-chirps_data
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # code to print the shape, array names, etc of the dataset
-----> 2 chirps_data
-
-NameError: name 'chirps_data' is not defined
-
-
-
-
-
-
-
-

NOAA Fundamental Climate Data Records (FCDR) AVHRR Land Bundle - Surface Reflectance and Normalized Difference Vegetation Index#

-

As we learned in the W1D3 tutorials, all the National Atmospheric and Oceanic Administration Climate Data Record (NOAA-CDR) datasets are available both at NOAA National Centers for Environmental Information (NCEI) and commercial cloud platforms. See the link here. We are accessing the data directly via the Amazon Web Service (AWS) cloud storage space.

-

For this project we recommend using the Normalized Difference Vegetation Index (NDVI). It is one of the most commonly used remotely sensed indices. It measures the “greeness” of vegetation, and is useful in understanding vegetation density and assessing changes in plant health. For example, NDVI can be used to study the impacts of droughts, heatwaves, and insect infestations on plants covering Earth’s surface. A good overview of this index from this particular sensor can be accessed here.

-

Recall what we learned in W1D3 Tutorial 3, the data files on AWS are named systematically:

-
-

Sensor name: AVHRR
-Product category: Land
-Product version: v005
-Product code: AVH13C1
-Satellite platform: NOAA-07
-Date of the data: 19810624
-Processing time: c20170610041337 (This will change for each file based on when the file was processed)
-File format: .nc (netCDR-4 format)

-
-

In other words, if we are looking for the data of a specific day, we can easily locate where the file might be.

-

For example, if we want to find the AVHRR data for the day of 2002-03-12 (or March 12, 2002), you can use:

-

s3://noaa-cdr-ndvi-pds/data/2002/AVHRR-Land_v005_AVH13C1_*_20020312_c*.nc

-

The reasaon that we put * in the above directory is because we are not sure about what satellite platform this data is from and when the data was processed. The * is called a wildcard, and is used because we want all the files that contain our specific criteria, but do not want to have to specify all the other pieces of the filename we are not sure about yet. It should return all the data satisfying that initial criteria and you can refine further once you see what is available. Essentially, this first step helps to narrow down the data search. You can then use this to create datasets from the timeframe of your choosing.

-
-
-
# we can use the data from W1D3 tutorial 3
-# to access the NDVI data from AWS S3 bucket, we first need to connect to s3 bucket
-
-fs = s3fs.S3FileSystem(anon=True)
-client = boto3.client('s3', config=botocore.client.Config(signature_version=botocore.UNSIGNED)) # initialize aws s3 bucket client
-date_sel = datetime.datetime(2001,1,1,0) 
-file_location = fs.glob('s3://noaa-cdr-ndvi-pds/data/'+
-                        date_sel.strftime('%Y')+'/AVHRR-Land_v005_AVH13C1_*_c*.nc') # the files we want for a whole year
-files_for_pooch=[pooch_load('http://s3.amazonaws.com/'+file,file) for file in file_location]
-
-ds = xr.open_mfdataset(files_for_pooch, combine="by_coords")  # open the file
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 4
-      1 # we can use the data from W1D3 tutorial 3
-      2 # to access the NDVI data from AWS S3 bucket, we first need to connect to s3 bucket
-----> 4 fs = s3fs.S3FileSystem(anon=True)
-      5 client = boto3.client('s3', config=botocore.client.Config(signature_version=botocore.UNSIGNED)) # initialize aws s3 bucket client
-      6 date_sel = datetime.datetime(2001,1,1,0) 
-
-NameError: name 's3fs' is not defined
-
-
-
-
-
-
-
-

Alternative NDVI source: MODIS/Terra Vegetation Indices (MOD13C2) Version 6.1 L3 Global 0.05° CMG#

-

Global MODIS (Moderate Resolution Imaging Spectroradiometer) vegetation indices are designed to provide consistent spatial and temporal comparisons of vegetation conditions. Blue, red, and near-infrared reflectances, centered at 469-nanometers, 645-nanometers, and 858-nanometers, respectively, are used to determine the MODIS vegetation indices.

-

The MODIS Normalized Difference Vegetation Index (NDVI) complements NOAA’s Advanced Very High Resolution Radiometer (AVHRR) NDVI products providing continuity for time series applications over this rich historical archive.

-

Global MOD13C2 data are cloud-free spatial composites of the gridded 16-day 1-kilometer MOD13C2A2, and are provided as a level-3 product projected on a 0.05 degree (5600-meter) geographic Climate Modeling Grid (CMG). -These files have also been pre-processed to match the grid of the precipitation data.

-
-
-
years=range(2000,2024) # the NDVI data we have available 
-file_paths=['MODIS/NDVI_'+str(year)+'.nc' for year in years] # the format of the files
-filenames=['MODIS/NDVI_'+str(year)+'.nc'  for year in years] # the format of the files
-
-downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files
-# load Data
-modis_data = xr.open_mfdataset(downloaded_files,combine='by_coords')
-modis_data
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 5
-      2 file_paths=['MODIS/NDVI_'+str(year)+'.nc' for year in years] # the format of the files
-      3 filenames=['MODIS/NDVI_'+str(year)+'.nc'  for year in years] # the format of the files
-----> 5 downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files
-      6 # load Data
-      7 modis_data = xr.open_mfdataset(downloaded_files,combine='by_coords')
-
-Cell In[10], line 5, in <listcomp>(.0)
-      2 file_paths=['MODIS/NDVI_'+str(year)+'.nc' for year in years] # the format of the files
-      3 filenames=['MODIS/NDVI_'+str(year)+'.nc'  for year in years] # the format of the files
-----> 5 downloaded_files=[ pooch_load(fpath,fname) for (fpath,fname) in zip(file_paths,filenames)] # download all of the files
-      6 # load Data
-      7 modis_data = xr.open_mfdataset(downloaded_files,combine='by_coords')
-
-Cell In[4], line 5, in pooch_load(filelocation, filename, processor)
-      3 def pooch_load(filelocation=None,filename=None,processor=None):
-      4     shared_location='/home/jovyan/shared/Data/Projects/Precipitation' # this is different for each day
-----> 5     user_temp_cache=tempfile.gettempdir()
-      7     if os.path.exists(os.path.join(shared_location,filename)):
-      8         file = os.path.join(shared_location,filename)
-
-NameError: name 'tempfile' is not defined
-
-
-
-
-

-
-

Worldbank Data: Cereal Production#

-

Cereal production is a crucial component of global agriculture and food security. The World Bank collects and provides data on cereal production, which includes crops such as wheat, rice, maize, barley, oats, rye, sorghum, millet, and mixed grains. The data covers various indicators such as production quantity, area harvested, yield, and production value.

-

The World Bank also collects data on land under cereals production, which refers to the area of land that is being used to grow cereal crops. This information can be valuable for assessing the productivity and efficiency of cereal production systems in different regions, as well as identifying potential areas for improvement. Overall, the World Bank’s data on cereal production and land under cereals production is an important resource for policymakers, researchers, and other stakeholders who are interested in understanding global trends in agriculture and food security.

-
-
-
# code to retrieve and load the data
-filename_cereal = 'data_cereal_land.csv'
-url_cereal = 'https://raw.githubusercontent.com/Sshamekh/Heatwave/f85f43997e3d6ae61e5d729bf77cfcc188fbf2fd/data_cereal_land.csv'
-ds_cereal_land = pd.read_csv(pooch_load(url_cereal,filename_cereal))
-ds_cereal_land.head() 
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 4
-      2 filename_cereal = 'data_cereal_land.csv'
-      3 url_cereal = 'https://raw.githubusercontent.com/Sshamekh/Heatwave/f85f43997e3d6ae61e5d729bf77cfcc188fbf2fd/data_cereal_land.csv'
-----> 4 ds_cereal_land = pd.read_csv(pooch_load(url_cereal,filename_cereal))
-      5 ds_cereal_land.head() 
-
-NameError: name 'pd' is not defined
-
-
-
-
-
-
-
# example
-ds_cereal_land[(ds_cereal_land["Country Name"] == "Brazil")].reset_index(
-    drop=True
-).iloc[0].transpose()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # example
-----> 2 ds_cereal_land[(ds_cereal_land["Country Name"] == "Brazil")].reset_index(
-      3     drop=True
-      4 ).iloc[0].transpose()
-
-NameError: name 'ds_cereal_land' is not defined
-
-
-
-
-

Now you are all set to address the questions you are interested in! Just be mindful of the specific coordinate names to avoid any issues.

-

You can use the provided functions as examples to compute various indices for extreme events based on duration or intensity. Don’t hesitate to modify them according to your specific needs or create your own custom functions.

-

Happy exploring and analyzing precipitation variability and extreme events in your project!

-
-
-
-

Further Reading#

-
    -
  • Anyamba, A. and Tucker, C.J., 2012. Historical perspective of AVHRR NDVI and vegetation drought monitoring. Remote sensing of drought: innovative monitoring approaches, 23, pp.20.https://digitalcommons.unl.edu/nasapub/217/

  • -
  • Zhang, X., Alexander, L., Hegerl, G.C., Jones, P., Tank, A.K., Peterson, T.C., Trewin, B. and Zwiers, F.W., 2011. Indices for monitoring changes in extremes based on daily temperature and precipitation data. Wiley Interdisciplinary Reviews: Climate Change, 2(6), pp.851-870.

  • -
  • Schultz, P. A., and M. S. Halpert. “Global correlation of temperature, NDVI and precipitation.” Advances in Space Research 13.5 (1993): 277-280.

  • -
  • Seneviratne, S.I. et al., 2021: Weather and Climate Extreme Events in a Changing Climate. In Climate Change 2021: The Physical Science Basis. Contribution of Working Group I to the Sixth Assessment Report of the Intergovernmental Panel on Climate Change [Masson-Delmotte, V. et al. (eds.)]. Cambridge University Press, Cambridge, United Kingdom and New York, NY, USA, pp. 1513–1766, https://www.ipcc.ch/report/ar6/wg1/chapter/chapter-11/

  • -
  • IPCC, 2021: Annex VI: Climatic Impact-driver and Extreme Indices [Gutiérrez J.M. et al.(eds.)]. In Climate Change 2021: The Physical Science Basis. Contribution of Working Group I to the Sixth Assessment Report of the Intergovernmental Panel on Climate Change [Masson-Delmotte, V. et al. (eds.)]. Cambridge University Press, Cambridge, United Kingdom and New York, NY, USA, pp. 2205–2214, https://www.ipcc.ch/report/ar6/wg1/downloads/report/IPCC_AR6_WGI_AnnexVI.pdf

  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/Sea_level_rise.html b/book/_build/html/projects/project-notebooks/Sea_level_rise.html deleted file mode 100644 index 1c3db8627..000000000 --- a/book/_build/html/projects/project-notebooks/Sea_level_rise.html +++ /dev/null @@ -1,1410 +0,0 @@ - - - - - - - - - - - - Sea Level Rise — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Sea Level Rise#

-

Content creators: Aakash Sane, Karsten Haustein

-

Content reviewers: Brodie Pearson, Abigail Bodner, Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-
# @title Project Background
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-    def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-        self.id = id
-        if source == "Bilibili":
-            src = f"https://player.bilibili.com/player.html?bvid={id}&page={page}"
-        elif source == "Osf":
-            src = f"https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render"
-        super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-    tab_contents = []
-    for i, video_id in enumerate(video_ids):
-        out = widgets.Output()
-        with out:
-            if video_ids[i][0] == "Youtube":
-                video = YouTubeVideo(
-                    id=video_ids[i][1], width=W, height=H, fs=fs, rel=0
-                )
-                print(f"Video available at https://youtube.com/watch?v={video.id}")
-            else:
-                video = PlayVideo(
-                    id=video_ids[i][1],
-                    source=video_ids[i][0],
-                    width=W,
-                    height=H,
-                    fs=fs,
-                    autoplay=False,
-                )
-                if video_ids[i][0] == "Bilibili":
-                    print(
-                        f"Video available at https://www.bilibili.com/video/{video.id}"
-                    )
-                elif video_ids[i][0] == "Osf":
-                    print(f"Video available at https://osf.io/{video.id}")
-            display(video)
-        tab_contents.append(out)
-    return tab_contents
-
-
-video_ids = [('Youtube', 'FzXJ00pg34g'), ('Bilibili', 'BV1J14y197TT')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-    tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # @title Project Background
-----> 3 from ipywidgets import widgets
-      4 from IPython.display import YouTubeVideo
-      5 from IPython.display import IFrame
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
# @title Tutorial slides
-# @markdown These are the slides for the videos in all tutorials today
-from IPython.display import IFrame
-link_id = "u7x62"
-
-
-
-
-

Sea level, or Sea Surface Height [SSH], describes the vertical position of the interface between the atmosphere and the ocean. It varies at numerous timescales attributable to different physical factors, such as hourly tides, daily to monthly perturbations caused by currents and storms, and alterations spanning several decades to centuries due to thermal expansion of seawater and the reduction of mass resulting from glaciers and ice sheets. Read more: NOAA 2022 Sea level rise technical report.

-

In this project, you will work on sea level rise data from ECCO model (recall W1D2 tutorial 4 outputs) and tidal gauge datasets.

-
-
-

Project Template#

-

Project Template

-

Note: The dashed boxes are socio-economic questions.

-
-
-

Data Exploration Notebook#

-
-

Project Setup#

-
-
-
# imports
-import random
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-import os
-import pooch
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 3
-      1 # imports
-      2 import random
-----> 3 import numpy as np
-      4 import matplotlib.pyplot as plt
-      5 import xarray as xr
-
-ModuleNotFoundError: No module named 'numpy'
-
-
-
-
-
-
-
# helper functions
-
-def pooch_load(filelocation=None,filename=None,processor=None):
-    shared_location='/home/jovyan/shared/Data/Projects/Sea_Level' # this is different for each day
-    user_temp_cache=tempfile.gettempdir()
-    
-    if os.path.exists(os.path.join(shared_location,filename)):
-        file = os.path.join(shared_location,filename)
-    else:
-        file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)
-
-    return file
-
-
-
-
-
-
-

ECCO Sea Surface Height (SSH)#

-

In this project, you will analyse sea surface height (SSH) data using the ECCO reanalysis product which combines simulations and observations. ECCO stands for Estimating the Circulation and Climate of the Ocean and integrates observations with coupled ocean/sea-ice models. The netCDF data file contains SSH stored as monthly means from the year 1992 to 2017 on a 0.5 x 0.5 degree grid. Using the ECCO product, global and regional sea level obtained due to physical effects (such as thermal expansion of sea water, etc.) can be estimated. Further details about the dataset can be obtained here.

-

The sea surface height variable is called ‘SSH’ in the data. It is a variable with three gridded dimensions: time, latitude, and longitude. The code below shows how to load the SSH dataset and provides plotting examples. One example plots the time-series at a particular latitude and longitude while another example plots a colormap on the global grid. Those examples should equip you to tackle many of the questions on the template, so go ahead and explore!

-

Further resources about the dataset:

-
    -
  • ECCO Consortium, Fukumori, I., Wang, O., Fenty, I., Forget, G., Heimbach, P., & Ponte, R. M. (DATE ACCESSED). ECCO Central Estimate (Version 4 Release 4). Retrieved from https://podaac.jpl.nasa.gov/dataset/ECCO_L4_GMSL_TIME_SERIES_MONTHLY_V4R4.

  • -
  • ECCO Consortium, Fukumori, I., Wang, O., Fenty, I., Forget, G., Heimbach, P., & Ponte, R. M. (2021, February 10). Synopsis of the ECCO Central Production Global Ocean and Sea-Ice State Estimate (Version 4 Release 4). https://doi.org/10.5281/zenodo.4533349

  • -
  • Forget, G., J.-M. Campin, P. Heimbach, C. N. Hill, R. M. Ponte, and C. Wunsch, 2015: ECCO version 4: An integrated framework for non-linear inverse modeling and global ocean state estimation. Geoscientific Model Development, 8. https://www.geosci-model-dev.net/8/3071/2015/

  • -
-
-
-
url_ECCO='~/shared/Data/Projects/Sea_Level/SEA_SURFACE_HEIGHT_mon_mean_1992-01-2017-12_ECCO_V4r4_latlon_0p50deg.nc'
-ds=xr.open_dataset(url_ECCO)
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 2
-      1 url_ECCO='~/shared/Data/Projects/Sea_Level/SEA_SURFACE_HEIGHT_mon_mean_1992-01-2017-12_ECCO_V4r4_latlon_0p50deg.nc'
-----> 2 ds=xr.open_dataset(url_ECCO)
-      3 ds
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
ds["SSH"][:, 200, 134].plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 ds["SSH"][:, 200, 134].plot()
-
-NameError: name 'ds' is not defined
-
-
-
-
-
-
-
ds["SSH"][100, :, :].plot.pcolormesh()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 ds["SSH"][100, :, :].plot.pcolormesh()
-
-NameError: name 'ds' is not defined
-
-
-
-
-
-
-

Observations Dataset: Tidal Gauges#

-

Students can download any tidal gauge data of their choice from this website

-

It is recommended to download the NetCDF ‘daily’ data for a particular location and it can be compared to the nearest latitude-longitude from the ECCO dataset. When you download the tidal gauge data, you can select a location, right click on the NetCDF of the data you want, copy link address and paste as the url below.

-

The file will have the sea level stored as a variable called ‘sea_level’, which is a function of time. It can be fun to explore how close the tidal gauge data agree (or disagree) with the ECCO data!

-
-
-
# students can download any tidal gauge data of their choice from this website:
-# https://uhslc.soest.hawaii.edu/data/
-# instructions: select a location, right click on the netcdf of the data you want, copy link address and paste as the url below
-
-
-
-
-
-
-
# data source-specific functions
-url_choosen = "https://uhslc.soest.hawaii.edu/data/netcdf/fast/daily/d825.nc"  # this is the link for "Cuxhaven Germany", change to your location
-# example code after downloading tidal gauge data:
-ds = xr.open_dataset(
-    pooch.retrieve(url_choosen, known_hash=None)
-)  # this is just an example, tidal gauge NetCDF file needs to be downloaded in order to load this.
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 4
-      2 url_choosen = "https://uhslc.soest.hawaii.edu/data/netcdf/fast/daily/d825.nc"  # this is the link for "Cuxhaven Germany", change to your location
-      3 # example code after downloading tidal gauge data:
-----> 4 ds = xr.open_dataset(
-      5     pooch.retrieve(url_choosen, known_hash=None)
-      6 )  # this is just an example, tidal gauge NetCDF file needs to be downloaded in order to load this.
-      7 ds
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
-

Further Reading#

-
    -
  • 2022 Sea Level Rise Technical Report -https://oceanservice.noaa.gov/hazards/sealevelrise/sealevelrise-tech-report-sections.html

  • -
  • Oppenheimer, M., B.C. Glavovic , J. Hinkel, R. van de Wal, A.K. Magnan, A. Abd-Elgawad, R. Cai, M. Cifuentes-Jara, R.M. DeConto, T. Ghosh, J. Hay, F. Isla, B. Marzeion, B. Meyssignac, and Z. Sebesvari, 2019: Sea Level Rise and Implications for Low-Lying Islands, Coasts and Communities. In: IPCC Special Report on the Ocean and Cryosphere in a Changing Climate [H.-O. Pörtner, D.C. Roberts, V. Masson-Delmotte, P. Zhai, M. Tignor, E. Poloczanska, K. Mintenbeck, A. Alegría, M. Nicolai, A. Okem, J. Petzold, B. Rama, N.M. Weyer (eds.)]. Cambridge University Press, Cambridge, UK and New York, NY, USA, pp. 321-445. https://doi.org/10.1017/9781009157964.006.

  • -
  • Domingues, R., Goni, G., Baringer, M., &Volkov, D. (2018). What caused theaccelerated sea level changes along theU.S. East Coast during 2010–2015?Geophysical Research Letters,45,13,367–13,376. https://doi.org/10.1029/2018GL081183Received

  • -
  • Church, J.A., P.U. Clark, A. Cazenave, J.M. Gregory, S. Jevrejeva, A. Levermann, M.A. Merrifield, G.A. Milne, R.S. Nerem, P.D. Nunn, A.J. Payne, W.T. Pfeffer, D. Stammer and A.S. Unnikrishnan, 2013: Sea Level Change. In: Climate Change 2013: The Physical Science Basis. Contribution of Working Group I to the Fifth Assessment Report of the Intergovernmental Panel on Climate Change -[Stocker, T.F., D. Qin, G.-K. Plattner, M. Tignor, S.K. Allen, J. Boschung, -A. Nauels, Y. Xia, V. Bex and P.M. Midgley (eds.)]. Cambridge University Press, Cambridge, United Kingdom and New York, NY, USA. https://www.ipcc.ch/site/assets/uploads/2018/02/WG1AR5_Chapter13_FINAL.pdf

  • -
  • Gregory, J.M., Griffies, S.M., Hughes, C.W. et al. Concepts and Terminology for Sea Level: Mean, Variability and Change, Both Local and Global. Surv Geophys 40, 1251–1289 (2019). https://doi.org/10.1007/s10712-019-09525-z

  • -
  • Wang, J., Church, J. A., Zhang, X., Gregory, J. M., Zanna, L., & Chen, X. (2021). Evaluation of the Local Sea‐Level Budget at Tide Gauges Since 1958. Geophysical Research Letters, 48(20), e2021GL094502. https://doi.org/10.1029/2021GL094502

  • -
  • Cazenave, A. and Cozannet, G.L. (2014), Sea level rise and its coastal impacts. Earth’s Future, 2: 15-34. https://doi-org.ezproxy.princeton.edu/10.1002/2013EF000188

  • -
  • Mimura N. Sea-level rise caused by climate change and its implications for society. Proc Jpn Acad Ser B Phys Biol Sci. 2013;89(7):281-301. doi: 10.2183/pjab.89.281. PMID: 23883609; PMCID: PMC3758961. doi: 10.2183/pjab.89.281

  • -
-
-
-

Resources#

-

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

-

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

-

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

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/Surface_albedo_and_land_cover.html b/book/_build/html/projects/project-notebooks/Surface_albedo_and_land_cover.html deleted file mode 100644 index c63c0f7ad..000000000 --- a/book/_build/html/projects/project-notebooks/Surface_albedo_and_land_cover.html +++ /dev/null @@ -1,2073 +0,0 @@ - - - - - - - - - - - - Changes in Land Cover: Albedo and Carbon Sequestration — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Changes in Land Cover: Albedo and Carbon Sequestration#

-

Content creators: Oz Kira, Julius Bamah

-

Content reviewers: Yuhan Douglas Rao, Abigail Bodner

-

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

-

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

-

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

-
-
-
# @title Project Background
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-    def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-        self.id = id
-        if source == "Bilibili":
-            src = f"https://player.bilibili.com/player.html?bvid={id}&page={page}"
-        elif source == "Osf":
-            src = f"https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render"
-        super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-    tab_contents = []
-    for i, video_id in enumerate(video_ids):
-        out = widgets.Output()
-        with out:
-            if video_ids[i][0] == "Youtube":
-                video = YouTubeVideo(
-                    id=video_ids[i][1], width=W, height=H, fs=fs, rel=0
-                )
-                print(f"Video available at https://youtube.com/watch?v={video.id}")
-            else:
-                video = PlayVideo(
-                    id=video_ids[i][1],
-                    source=video_ids[i][0],
-                    width=W,
-                    height=H,
-                    fs=fs,
-                    autoplay=False,
-                )
-                if video_ids[i][0] == "Bilibili":
-                    print(
-                        f"Video available at https://www.bilibili.com/video/{video.id}"
-                    )
-                elif video_ids[i][0] == "Osf":
-                    print(f"Video available at https://osf.io/{video.id}")
-            display(video)
-        tab_contents.append(out)
-    return tab_contents
-
-
-video_ids = [('Youtube', 'qHZJeZnvQ60'), ('Bilibili', 'BV1fh4y1j7LX')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-    tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # @title Project Background
-----> 3 from ipywidgets import widgets
-      4 from IPython.display import YouTubeVideo
-      5 from IPython.display import IFrame
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
# @title Tutorial slides
-# @markdown These are the slides for the videos in all tutorials today
-from IPython.display import IFrame
-link_id = "w8ny7"
-
-
-
-
-

The global radiative budget is affected by land cover (e.g., forests, grasslands, agricultural fields, etc.), as different classifications of land cover have different levels of reflectance, or albedo. Vegetation also sequesters carbon at the same time, potentially counteracting these radiative effects.

-

In this project, you will evaluate the albedo change vs. carbon sequestration. In addition, you will track significant land cover changes, specifically the creation and abandonment of agricultural land.

-

In this project, you will have the opportunity to explore terrestrial remote sensing (recall our W1D3 tutorial on remote sensing) and meteorological data from GLASS and ERA5. The datasets will provide information on reflectance, albedo, meteorological variables, and land cover changes in your region of interest. We encourage you to investigate the relationships between these variables and their impact on the global radiative budget. Moreover, you can track agricultural land abandonment and analyze its potential connection to climate change. This project aligns well with the topics covered in W2D3, which you are encouraged to explore further.

-
-
-

Project Template#

-

Project Template

-

Note: The dashed boxes are socio-economic questions.

-
-
-

Data Exploration Notebook#

-
-

Project Setup#

-
-
-
# google colab installs
-# !pip install cartopy
-# !pip install DateTime
-# !pip install matplotlib
-# !pip install pyhdf
-# !pip install numpy
-# !pip install pandas
-# !pip install modis-tools
-
-
-
-
-
-
-
# imports
-import numpy as np
-from netCDF4 import Dataset
-import matplotlib.pyplot as plt
-import cartopy.crs as ccrs
-import pooch
-import xarray as xr
-import os
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-from xmip.utils import google_cmip_col
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-import cartopy.crs as ccrs
-import pooch
-import os
-import tempfile
-import pandas as pd
-from IPython.display import display, HTML, Markdown
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[4], line 2
-      1 # imports
-----> 2 import numpy as np
-      3 from netCDF4 import Dataset
-      4 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'numpy'
-
-
-
-
-
-
-
# helper functions
-
-def pooch_load(filelocation=None,filename=None,processor=None):
-    shared_location='/home/jovyan/shared/Data/Projects/Albedo' # this is different for each day
-    user_temp_cache=tempfile.gettempdir()
-    
-    if os.path.exists(os.path.join(shared_location,filename)):
-        file = os.path.join(shared_location,filename)
-    else:
-        file = pooch.retrieve(filelocation,known_hash=None,fname=os.path.join(user_temp_cache,filename),processor=processor)
-
-    return file
-
-
-
-
-
-
-

Obtain Land and Atmospheric Variables from CMIP6#

-

Here you will use the Pangeo cloud service to access CMIP6 data using the methods encountered in W1D5 and W2D1. To learn more about CMIP, including additional ways to access CMIP data, please see our CMIP Resource Bank and the CMIP website.

-
-
-
# open an intake catalog containing the Pangeo CMIP cloud data
-col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)
-col
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 2
-      1 # open an intake catalog containing the Pangeo CMIP cloud data
-----> 2 col = intake.open_esm_datastore(
-      3     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      4 )
-      5 col
-
-NameError: name 'intake' is not defined
-
-
-
-
-

To see a list of CMIP6 variables and models please visit the Earth System Grid Federation (ESGF) website. Note that not all of these variables are hosted through the Pangeo cloud, but there are additional ways to access all the CMIP6 data as described here, including direct access through ESGF.

-

You can see which variables and models are available within Pangeo using the sample code below, where we look for models having the variable ‘pastureFrac’ for the historical simulation:

-
-
-
expts = ["historical"]
-
-query = dict(
-    experiment_id=expts,
-    table_id="Lmon",
-    variable_id=["pastureFrac"],
-    member_id="r1i1p1f1",
-)
-
-col_subset = col.search(require_all_on=["source_id"], **query)
-col_subset.df.groupby("source_id")[
-    ["experiment_id", "variable_id", "table_id"]
-].nunique()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 10
-      1 expts = ["historical"]
-      3 query = dict(
-      4     experiment_id=expts,
-      5     table_id="Lmon",
-      6     variable_id=["pastureFrac"],
-      7     member_id="r1i1p1f1",
-      8 )
----> 10 col_subset = col.search(require_all_on=["source_id"], **query)
-     11 col_subset.df.groupby("source_id")[
-     12     ["experiment_id", "variable_id", "table_id"]
-     13 ].nunique()
-
-NameError: name 'col' is not defined
-
-
-
-
-

Here we will download several variables from the GFDL-ESM4 historical CMIP6 simulation:

-
-
-
import pandas as pd
-from IPython.display import display, HTML, Markdown
-
-# Data as list of dictionaries
-classification_system = [
-    {
-        "Name": "gpp",
-        "Description": "Carbon Mass Flux out of Atmosphere due to Gross Primary Production on Land",
-    },
-    {
-        "Name": "npp",
-        "Description": "Carbon Mass Flux out of Atmosphere due to Net Primary Production on Land",
-    },
-    {
-        "Name": "nep",
-        "Description": "Carbon Mass Flux out of Atmophere due to Net Ecosystem Production on Land",
-    },
-    {
-        "Name": "nbp",
-        "Description": "Carbon Mass Flux out of Atmosphere due to Net Biospheric Production on Land",
-    },
-    {"Name": "treeFrac", "Description": "Land Area Percentage Tree Cover"},
-    {"Name": "grassFrac", "Description": "Land Area Percentage Natural Grass"},
-    {"Name": "cropFrac", "Description": "Land Area Percentage Crop Cover"},
-    {
-        "Name": "pastureFrac",
-        "Description": "Land Area Percentage Anthropogenic Pasture Cover",
-    },
-    {"Name": "rsus", "Description": "Surface Upwelling Shortwave Radiation"},
-    {"Name": "rsds", "Description": "Surface Downwelling Shortwave Radiation"},
-    {"Name": "tas", "Description": "Near-Surface Air Temperature"},
-    {"Name": "pr", "Description": "Precipitation"},
-    {
-        "Name": "areacella",
-        "Description": "Grid-Cell Area for Atmospheric Variables (all variabeles are on this grid however)",
-    },
-]
-
-df = pd.DataFrame(classification_system)
-pd.set_option("display.max_colwidth", None)
-html = df.to_html(index=False)
-title_md = "### Table 1: CMIP6 Variables"
-display(Markdown(title_md))
-display(HTML(html))
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 import pandas as pd
-      2 from IPython.display import display, HTML, Markdown
-      4 # Data as list of dictionaries
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-

There are different timescales on which carbon is released back into the atmosphere, and these are reflected in the different production terms. This is highlighted in the figure below (please note these numbers are quite outdated).

-

-

Figure 1-2: Global terrestrial carbon uptake. Plant (autotrophic) respiration releases CO2 to the atmosphere, reducing GPP to NPP and resulting in short-term carbon uptake. Decomposition (heterotrophic respiration) of litter and soils in excess of that resulting from disturbance further releases CO2 to the atmosphere, reducing NPP to NEP and resulting in medium-term carbon uptake. Disturbance from both natural and anthropogenic sources (e.g., harvest) leads to further release of CO2 to the atmosphere by additional heterotrophic respiration and combustion-which, in turn, leads to long-term carbon storage (adapted from Steffen et al., 1998). Credit: IPCC

-

Now you are ready to extract all the variables!

-
-
-
# get monthly land variables
-
-# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id="GFDL-ESM4",
-    variable_id=[
-        "gpp",
-        "npp",
-        "nbp",
-        "treeFrac",
-        "grassFrac",
-        "cropFrac",
-        "pastureFrac",
-    ],  # No 'shrubFrac','baresoilFrac','residualFrac' in GFDL-ESM4
-    member_id="r1i1p1f1",
-    table_id="Lmon",
-    grid_label="gr1",
-    experiment_id=["historical"],
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_Lmon_variables = cat.to_datatree(**kwargs)
-
-# convert to dataset instead of datatree, remove extra singleton dimensions
-ds_Lmon = dt_Lmon_variables["GFDL-ESM4"]["historical"].to_dataset().squeeze()
-ds_Lmon
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 4
-      1 # get monthly land variables
-      2 
-      3 # from the full `col` object, create a subset using facet search
-----> 4 cat = col.search(
-      5     source_id="GFDL-ESM4",
-      6     variable_id=[
-      7         "gpp",
-      8         "npp",
-      9         "nbp",
-     10         "treeFrac",
-     11         "grassFrac",
-     12         "cropFrac",
-     13         "pastureFrac",
-     14     ],  # No 'shrubFrac','baresoilFrac','residualFrac' in GFDL-ESM4
-     15     member_id="r1i1p1f1",
-     16     table_id="Lmon",
-     17     grid_label="gr1",
-     18     experiment_id=["historical"],
-     19     require_all_on=[
-     20         "source_id"
-     21     ],  # make sure that we only get models which have all of the above experiments
-     22 )
-     24 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     25 kwargs = dict(
-     26     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     27     xarray_open_kwargs=dict(
-   (...)
-     32     },  # anonymous/public authentication to google cloud storage
-     33 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-
-
# get monthly 'extension' variables
-
-# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id="GFDL-ESM4",
-    variable_id="nep",
-    member_id="r1i1p1f1",
-    table_id="Emon",
-    grid_label="gr1",
-    experiment_id=["historical"],
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_Emon_variables = cat.to_datatree(**kwargs)
-
-# convert to dataset instead of datatree, remove extra singleton dimensions
-ds_Emon = dt_Emon_variables["GFDL-ESM4"]["historical"].to_dataset().squeeze()
-ds_Emon
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 4
-      1 # get monthly 'extension' variables
-      2 
-      3 # from the full `col` object, create a subset using facet search
-----> 4 cat = col.search(
-      5     source_id="GFDL-ESM4",
-      6     variable_id="nep",
-      7     member_id="r1i1p1f1",
-      8     table_id="Emon",
-      9     grid_label="gr1",
-     10     experiment_id=["historical"],
-     11     require_all_on=[
-     12         "source_id"
-     13     ],  # make sure that we only get models which have all of the above experiments
-     14 )
-     16 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     17 kwargs = dict(
-     18     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     19     xarray_open_kwargs=dict(
-   (...)
-     24     },  # anonymous/public authentication to google cloud storage
-     25 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-
-
# get atmospheric variables
-
-# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id="GFDL-ESM4",
-    variable_id=["rsds", "rsus", "tas", "pr"],
-    member_id="r1i1p1f1",
-    table_id="Amon",
-    grid_label="gr1",
-    experiment_id=["historical"],
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_Amon_variables = cat.to_datatree(**kwargs)
-
-# convert to dataset instead of datatree, remove extra singleton dimensions
-ds_Amon = dt_Amon_variables["GFDL-ESM4"]["historical"].to_dataset().squeeze()
-ds_Amon
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 4
-      1 # get atmospheric variables
-      2 
-      3 # from the full `col` object, create a subset using facet search
-----> 4 cat = col.search(
-      5     source_id="GFDL-ESM4",
-      6     variable_id=["rsds", "rsus", "tas", "pr"],
-      7     member_id="r1i1p1f1",
-      8     table_id="Amon",
-      9     grid_label="gr1",
-     10     experiment_id=["historical"],
-     11     require_all_on=[
-     12         "source_id"
-     13     ],  # make sure that we only get models which have all of the above experiments
-     14 )
-     16 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     17 kwargs = dict(
-     18     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     19     xarray_open_kwargs=dict(
-   (...)
-     24     },  # anonymous/public authentication to google cloud storage
-     25 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-
-
# get atmospheric variables
-
-# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id="GFDL-ESM4",
-    variable_id=["areacella"],
-    member_id="r1i1p1f1",
-    table_id="fx",
-    grid_label="gr1",
-    experiment_id=["historical"],
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_fx_variables = cat.to_datatree(**kwargs)
-
-# convert to dataset instead of datatree, remove extra singleton dimensions
-ds_fx = dt_fx_variables["GFDL-ESM4"]["historical"].to_dataset().squeeze()
-ds_fx
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 4
-      1 # get atmospheric variables
-      2 
-      3 # from the full `col` object, create a subset using facet search
-----> 4 cat = col.search(
-      5     source_id="GFDL-ESM4",
-      6     variable_id=["areacella"],
-      7     member_id="r1i1p1f1",
-      8     table_id="fx",
-      9     grid_label="gr1",
-     10     experiment_id=["historical"],
-     11     require_all_on=[
-     12         "source_id"
-     13     ],  # make sure that we only get models which have all of the above experiments
-     14 )
-     16 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     17 kwargs = dict(
-     18     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     19     xarray_open_kwargs=dict(
-   (...)
-     24     },  # anonymous/public authentication to google cloud storage
-     25 )
-
-NameError: name 'col' is not defined
-
-
-
-
-

Since we are only using one model here, it is practical to extract the variables of interest into datarrays and put them in one compact dataset. In addition we need to calculate the surface albedo. Note, that you will learn more about surface albedo (and CMIP6 data) in W1D5.

-
-
-
# merge into single dataset. note, these are all on the 'gr1' grid.
-ds = xr.Dataset()
-
-# add land variables
-for var in ds_Lmon.data_vars:
-    ds[var] = ds_Lmon[var]
-
-# add extension variables
-for var in ds_Emon.data_vars:
-    ds[var] = ds_Emon[var]
-
-# add atmopsheric variables
-for var in ds_Amon.data_vars:
-    ds[var] = ds_Amon[var]
-
-# add grid cell area
-for var in ds_fx.data_vars:
-    ds[var] = ds_fx[var]
-
-# drop unnecessary coordinates
-ds = ds.drop_vars(["member_id", "dcpp_init_year", "height"])
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # merge into single dataset. note, these are all on the 'gr1' grid.
-----> 2 ds = xr.Dataset()
-      4 # add land variables
-      5 for var in ds_Lmon.data_vars:
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
# surface albedo is ratio of upwelling shortwave radiation (reflected) to downwelling shortwave radiation (incoming solar radiation).
-ds["surf_albedo"] = ds.rsus / ds.rsds
-
-# add attributes
-ds["surf_albedo"].attrs = {"units": "Dimensionless", "long_name": "Surface Albedo"}
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 # surface albedo is ratio of upwelling shortwave radiation (reflected) to downwelling shortwave radiation (incoming solar radiation).
-----> 2 ds["surf_albedo"] = ds.rsus / ds.rsds
-      4 # add attributes
-      5 ds["surf_albedo"].attrs = {"units": "Dimensionless", "long_name": "Surface Albedo"}
-
-NameError: name 'ds' is not defined
-
-
-
-
-
-
-

Alternative Land Cover Approach: Global Land Surface Satellite (GLASS) Dataset#

-

The Global Land Surface Satellite (GLASS) datasets primarily based on NASA’s Advanced Very High Resolution Radiometer (AVHRR) long-term data record (LTDR) and Moderate Resolution Imaging Spectroradiometer (MODIS) data, in conjunction with other satellite data and ancillary information.

-

Currently, there are more than dozens of GLASS products are officially released, including leaf area index, fraction of green vegetation coverage, gross primary production, broadband albedo, land surface temperature, evapotranspiration, and so on.

-

Here we provide you the datasets of GLASS from 1982 to 2015, a 34-year long annual dynamics of global land cover (GLASS-GLC) at 5 km resolution. In this datasets, there are 7 classes, including cropland, forest, grassland, shrubland, tundra, barren land, and snow/ice. -The annual global land cover map (5 km) is presented in a GeoTIFF file format named in the form of ‘GLASS-GLC_7classes_year’ with a WGS 84 projection. The relationship between the labels in the files and the 7 land cover classes is shown in the following table

-

You can refer to this paper for detailed description of this.ts

-
-
-
# Table 1 Classification system, with 7 land cover classes. From paper https://www.earth-syst-sci-data-discuss.net/essd-2019-23
-import pandas as pd
-from IPython.display import display, HTML, Markdown
-
-# Data as list of dictionaries
-classification_system = [
-    {"Label": 10, "Class": "Cropland", "Subclass": "Rice paddy", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Greenhouse", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Other farmland", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Orchard", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Bare farmland", "Description": ""},
-    {
-        "Label": 20,
-        "Class": "Forest",
-        "Subclass": "Broadleaf, leaf-on",
-        "Description": "Tree cover≥10%; Height>5m; For mixed leaf, neither coniferous nor broadleaf types exceed 60%",
-    },
-    {
-        "Label": 20,
-        "Class": "Forest",
-        "Subclass": "Broadleaf, leaf-off",
-        "Description": "",
-    },
-    {
-        "Label": 20,
-        "Class": "Forest",
-        "Subclass": "Needle-leaf, leaf-on",
-        "Description": "",
-    },
-    {
-        "Label": 20,
-        "Class": "Forest",
-        "Subclass": "Needle-leaf, leaf-off",
-        "Description": "",
-    },
-    {
-        "Label": 20,
-        "Class": "Forest",
-        "Subclass": "Mixed leaf type, leaf-on",
-        "Description": "",
-    },
-    {
-        "Label": 20,
-        "Class": "Forest",
-        "Subclass": "Mixed leaf type, leaf-off",
-        "Description": "",
-    },
-    {
-        "Label": 30,
-        "Class": "Grassland",
-        "Subclass": "Pasture, leaf-on",
-        "Description": "Canopy cover≥20%",
-    },
-    {
-        "Label": 30,
-        "Class": "Grassland",
-        "Subclass": "Natural grassland, leaf-on",
-        "Description": "",
-    },
-    {
-        "Label": 30,
-        "Class": "Grassland",
-        "Subclass": "Grassland, leaf-off",
-        "Description": "",
-    },
-    {
-        "Label": 40,
-        "Class": "Shrubland",
-        "Subclass": "Shrub cover, leaf-on",
-        "Description": "Canopy cover≥20%; Height<5m",
-    },
-    {
-        "Label": 40,
-        "Class": "Shrubland",
-        "Subclass": "Shrub cover, leaf-off",
-        "Description": "",
-    },
-    {
-        "Label": 70,
-        "Class": "Tundra",
-        "Subclass": "Shrub and brush tundra",
-        "Description": "",
-    },
-    {
-        "Label": 70,
-        "Class": "Tundra",
-        "Subclass": "Herbaceous tundra",
-        "Description": "",
-    },
-    {
-        "Label": 90,
-        "Class": "Barren land",
-        "Subclass": "Barren land",
-        "Description": "Vegetation cover<10%",
-    },
-    {"Label": 100, "Class": "Snow/Ice", "Subclass": "Snow", "Description": ""},
-    {"Label": 100, "Class": "Snow/Ice", "Subclass": "Ice", "Description": ""},
-    {"Label": 0, "Class": "No data", "Subclass": "", "Description": ""},
-]
-
-df = pd.DataFrame(classification_system)
-pd.set_option("display.max_colwidth", None)
-html = df.to_html(index=False)
-title_md = "### Table 1 GLASS classification system with 7 land cover classes. From [this paper](https://www.earth-syst-sci-data-discuss.net/essd-2019-23)."
-display(Markdown(title_md))
-display(HTML(html))
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[15], line 2
-      1 # Table 1 Classification system, with 7 land cover classes. From paper https://www.earth-syst-sci-data-discuss.net/essd-2019-23
-----> 2 import pandas as pd
-      3 from IPython.display import display, HTML, Markdown
-      5 # Data as list of dictionaries
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-
-
-
# source of landuse data: https://doi.pangaea.de/10.1594/PANGAEA.913496
-# the folder "land-use" has the data for years 1982 to 2015. choose the years you need and change the path accordingly
-path_LandUse = os.path.expanduser(
-    "~/shared/Data/Projects/Albedo/land-use/GLASS-GLC_7classes_1982.tif"
-)
-ds_landuse = xr.open_dataset(path_LandUse).rename({"x": "longitude", "y": "latitude"})
-# ds_landuse.band_data[0,:,:].plot() # how to plot the global data
-ds_landuse
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 3
-      1 # source of landuse data: https://doi.pangaea.de/10.1594/PANGAEA.913496
-      2 # the folder "land-use" has the data for years 1982 to 2015. choose the years you need and change the path accordingly
-----> 3 path_LandUse = os.path.expanduser(
-      4     "~/shared/Data/Projects/Albedo/land-use/GLASS-GLC_7classes_1982.tif"
-      5 )
-      6 ds_landuse = xr.open_dataset(path_LandUse).rename({"x": "longitude", "y": "latitude"})
-      7 # ds_landuse.band_data[0,:,:].plot() # how to plot the global data
-
-NameError: name 'os' is not defined
-
-
-
-
-
-
-

Alternative Approach: ERA5-Land Monthly Averaged Data from 1950 to Present#

-

ERA5-Land is a reanalysis dataset that offers an enhanced resolution compared to ERA5, providing a consistent view of land variables over several decades. It is created by replaying the land component of the ECMWF ERA5 climate reanalysis, which combines model data and global observations to generate a complete and reliable dataset using the laws of physics.

-

ERA5-Land focuses on the water and energy cycles at the surface level, offering a detailed record starting from 1950. The data used here is a post-processed subset of the complete ERA5-Land dataset. Monthly-mean averages have been pre-calculated to facilitate quick and convenient access to the data, particularly for applications that do not require sub-monthly fields. The native spatial resolution of the ERA5-Land reanalysis dataset is 9km on a reduced Gaussian grid (TCo1279). The data in the CDS has been regridded to a regular lat-lon grid of 0.1x0.1 degrees.

-
-

To Calculate Albedo Using ERA5-Land#

-

ERA5 parameter Forecast albedo provides is the measure of the reflectivity of the Earth’s surface. It is the fraction of solar (shortwave) radiation reflected by Earth’s surface, across the solar spectrum, for both direct and diffuse radiation. Values are between 0 and 1. Typically, snow and ice have high reflectivity with albedo values of 0.8 and above, land has intermediate values between about 0.1 and 0.4 and the ocean has low values of 0.1 or less. Radiation from the Sun (solar, or shortwave, radiation) is partly reflected back to space by clouds and particles in the atmosphere (aerosols) and some of it is absorbed. The rest is incident on the Earth’s surface, where some of it is reflected. The portion that is reflected by the Earth’s surface depends on the albedo. In the ECMWF Integrated Forecasting System (IFS), a climatological background albedo (observed values averaged over a period of several years) is used, modified by the model over water, ice and snow. Albedo is often shown as a percentage (%).

-
-
-
# link for albedo data:
-albedo_path = "~/shared/Data/Projects/Albedo/ERA/albedo-001.nc"
-ds_albedo = xr.open_dataset(albedo_path)
-ds_albedo  # note the official variable name is fal (forecast albedo)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 3
-      1 # link for albedo data:
-      2 albedo_path = "~/shared/Data/Projects/Albedo/ERA/albedo-001.nc"
-----> 3 ds_albedo = xr.open_dataset(albedo_path)
-      4 ds_albedo  # note the official variable name is fal (forecast albedo)
-
-NameError: name 'xr' is not defined
-
-
-
-
-

for your convience, included below are preciptation and temprature ERA5 dataset for the same times as the Albedo dataset

-
-
-
precp_path = "~/shared/Data/Projects/Albedo/ERA/precipitation-002.nc"
-ds_precp = xr.open_dataset(precp_path)
-ds_precp  # the variable name is tp (total preciptation)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[18], line 2
-      1 precp_path = "~/shared/Data/Projects/Albedo/ERA/precipitation-002.nc"
-----> 2 ds_precp = xr.open_dataset(precp_path)
-      3 ds_precp  # the variable name is tp (total preciptation)
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
tempr_path = "~/shared/Data/Projects/Albedo/ERA/Temperature-003.nc"
-ds_tempr = xr.open_dataset(tempr_path)
-ds_tempr  # the variable name is t2m (temprature at 2m)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[19], line 2
-      1 tempr_path = "~/shared/Data/Projects/Albedo/ERA/Temperature-003.nc"
-----> 2 ds_tempr = xr.open_dataset(tempr_path)
-      3 ds_tempr  # the variable name is t2m (temprature at 2m)
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
-
-

Further Reading#

- -
-
-

Resources#

-

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

-

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

-

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

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/Surface_albedo_and_land_use.html b/book/_build/html/projects/project-notebooks/Surface_albedo_and_land_use.html deleted file mode 100644 index 16786d635..000000000 --- a/book/_build/html/projects/project-notebooks/Surface_albedo_and_land_use.html +++ /dev/null @@ -1,3755 +0,0 @@ - - - - - - - - Change in Earth’s albedo and its dependence on land cover changes in the past 20 years — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -
-

Change in Earth’s albedo and its dependence on land cover changes in the past 20 years

-

Content creators: Oz Kira, Julius Bamah

-

Content reviewers: Yuhan Douglas Rao, Abigail Bodner

-

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

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-
# @title #**Project background** 
-#This will be a short video introducing the content creator(s) and motivating the research direction of the template.
-#The Tech team will add code to format and display the video
-
-
-
-
-

The global radiative budget is affected by land cover. Regarding vegetation land cover (e.g., forests, grasslands, agricultural fields, etc.), vegetation sequesters carbon, which reduces the greenhouse effect but absorbs more radiation and reduces earth albedo, which counteracts carbon sequestration.

-

In this project, we will evaluate the albedo change vs. carbon sequestration over the past years. In addition, we will track significant land use changes, specifically the creation and abandonment of agricultural land.

-

In this project, you will have the opportunity to explore terrestrial remote sensing (recall our W1D3 tutorial on remote sensing) and meteorological data from GLASS and ERA5. The datasets will provide information on reflectance, albedo, meteorological variables, and land cover changes in your region of interest. We encourage you to investigate the relationships between these variables and their impact on the global radiative budget. Moreover, you can track agricultural land abandonment and analyze its potential connection to climate change. This project aligns well with the topics covered in W2D3, which you are encouraged to explore further.

-
-
-

Project template

-

template

-
-
-

Data exploration notebook

-
-

Project setup

-

Please run the following cells to install the necessary libarries into your Jupyter notebook!

-
-
-
# google colab installs
-# !pip install cartopy
-# !pip install DateTime 
-# !pip install matplotlib
-# !pip install pyhdf
-# !pip install numpy
-# !pip install pandas
-# !pip install modis-tools
-
-
-
-
-
-
-
# the further information on the MODIS data can be found here : 
-#Import the libraries
-import numpy as np
-from netCDF4 import Dataset
-import matplotlib.pyplot as plt
-import cartopy.crs as ccrs
-import pooch
-import xarray as xr
-import os
-
-
-
-
-
-
-
-

Global Land Surface Satellite (GLASS) Dataset

-

The Global Land Surface Satellite (GLASS) datasets primarily based on NASA’s Advanced Very High Resolution Radiometer (AVHRR) long-term data record (LTDR) and Moderate Resolution Imaging Spectroradiometer (MODIS) data, in conjunction with other satellite data and ancillary information.

-

Currently, there are more than dozens of GLASS products are officially released, including leaf area index, fraction of green vegetation coverage, gross primary production, broadband albedo, land surface temperature, evapotranspiration, and so on.

-

Here we provide you the datasets of GLASS from 1982 to 2015, a 34-year long annual dynamics of global land cover (GLASS-GLC) at 5 km resolution. In this datasets, there are 7 classes, including cropland, forest, grassland, shrubland, tundra, barren land, and snow/ice. -The annual global land cover map (5 km) is presented in a GeoTIFF file format named in the form of ‘GLASS-GLC_7classes_year’ with a WGS 84 projection. The relationship between the labels in the files and the 7 land cover classes is shown in the following table

-

You can refer to this paper for detailed description of this.ts

-
-
-
# Table 1 Classification system, with 7 land cover classes. From paper https://www.earth-syst-sci-data-discuss.net/essd-2019-23
-import pandas as pd
-from IPython.display import display, HTML, Markdown
-# Data as list of dictionaries
-classification_system = [
-    {"Label": 10, "Class": "Cropland", "Subclass": "Rice paddy", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Greenhouse", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Other farmland", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Orchard", "Description": ""},
-    {"Label": 10, "Class": "Cropland", "Subclass": "Bare farmland", "Description": ""},
-    {"Label": 20, "Class": "Forest", "Subclass": "Broadleaf, leaf-on", "Description": "Tree cover≥10%; Height>5m; For mixed leaf, neither coniferous nor broadleaf types exceed 60%"},
-    {"Label": 20, "Class": "Forest", "Subclass": "Broadleaf, leaf-off", "Description": ""},
-    {"Label": 20, "Class": "Forest", "Subclass": "Needle-leaf, leaf-on", "Description": ""},
-    {"Label": 20, "Class": "Forest", "Subclass": "Needle-leaf, leaf-off", "Description": ""},
-    {"Label": 20, "Class": "Forest", "Subclass": "Mixed leaf type, leaf-on", "Description": ""},
-    {"Label": 20, "Class": "Forest", "Subclass": "Mixed leaf type, leaf-off", "Description": ""},
-    {"Label": 30, "Class": "Grassland", "Subclass": "Pasture, leaf-on", "Description": "Canopy cover≥20%"},
-    {"Label": 30, "Class": "Grassland", "Subclass": "Natural grassland, leaf-on", "Description": ""},
-    {"Label": 30, "Class": "Grassland", "Subclass": "Grassland, leaf-off", "Description": ""},
-    {"Label": 40, "Class": "Shrubland", "Subclass": "Shrub cover, leaf-on", "Description": "Canopy cover≥20%; Height<5m"},
-    {"Label": 40, "Class": "Shrubland", "Subclass": "Shrub cover, leaf-off", "Description": ""},
-    {"Label": 70, "Class": "Tundra", "Subclass": "Shrub and brush tundra", "Description": ""},
-    {"Label": 70, "Class": "Tundra", "Subclass": "Herbaceous tundra", "Description": ""},
-    {"Label": 90, "Class": "Barren land", "Subclass": "Barren land", "Description": "Vegetation cover<10%"},
-    {"Label": 100, "Class": "Snow/Ice", "Subclass": "Snow", "Description": ""},
-    {"Label": 100, "Class": "Snow/Ice", "Subclass": "Ice", "Description": ""},
-    {"Label": 0, "Class": "No data", "Subclass": "", "Description": ""}
-]
-
-df = pd.DataFrame(classification_system)
-pd.set_option('display.max_colwidth', None)
-html = df.to_html(index=False)
-title_md = "### Table 1 GLASS classification system with 7 land cover classes. From [this paper](https://www.earth-syst-sci-data-discuss.net/essd-2019-23)."
-display(Markdown(title_md))
-display(HTML(html))
-
-
-
-
-
-

System Message: WARNING/2 (/home/yuda/code/climatematch/course-content/book/projects/project-notebooks/Surface_albedo_and_land_use.ipynb, line 1)

-

Non-consecutive header level increase; 0 to 3 [myst.header]

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LabelClassSubclassDescription
10CroplandRice paddy
10CroplandGreenhouse
10CroplandOther farmland
10CroplandOrchard
10CroplandBare farmland
20ForestBroadleaf, leaf-onTree cover≥10%; Height>5m; For mixed leaf, neither coniferous nor broadleaf types exceed 60%
20ForestBroadleaf, leaf-off
20ForestNeedle-leaf, leaf-on
20ForestNeedle-leaf, leaf-off
20ForestMixed leaf type, leaf-on
20ForestMixed leaf type, leaf-off
30GrasslandPasture, leaf-onCanopy cover≥20%
30GrasslandNatural grassland, leaf-on
30GrasslandGrassland, leaf-off
40ShrublandShrub cover, leaf-onCanopy cover≥20%; Height<5m
40ShrublandShrub cover, leaf-off
70TundraShrub and brush tundra
70TundraHerbaceous tundra
90Barren landBarren landVegetation cover<10%
100Snow/IceSnow
100Snow/IceIce
0No data
-
-
-

Alternative Approach to Obtain Land Cover Data and Net Primary Production (NPP) Data from MODIS

-

MODIS (Moderate Resolution Imaging Spectroradiometer) is a key instrument aboard the Terra (originally known as EOS AM-1) and Aqua (originally known as EOS PM-1) satellites. Terra’s orbit around the Earth is timed so that it passes from north to south across the equator in the morning, while Aqua passes south to north over the equator in the afternoon. Terra MODIS and Aqua MODIS are viewing the entire Earth’s surface every 1 to 2 days, acquiring data in 36 spectral bands, or groups of wavelengths (see MODIS Technical Specifications). These data will improve our understanding of global dynamics and processes occurring on the land, in the oceans, and in the lower atmosphere. MODIS is playing a vital role in the development of validated, global, interactive Earth system models able to predict global change accurately enough to assist policy makers in making sound decisions concerning the protection of our environment (https://modis.gsfc.nasa.gov/data/).

-

The following procedures must be ensured:

-
    -
  1. Register an account on register at NASA earth data portal: https://urs.earthdata.nasa.gov/users/new

  2. -
  3. pip install the following libraries into your Jupyter notebook

  4. -
-

The following links could help you in preprocessing the MODIS dataset

-
    -
  • https://www.earthdatascience.org/courses/use-data-open-source-python/multispectral-remote-sensing/modis-data-in-python/

  • -
  • http://www.hdfeos.org/zoo/LAADS/MYD08_D3.A2009001.006.2015088160849.hdf.py

  • -
  • https://www.moonbooks.org/Articles/How-to-read-a-MODIS-HDF-file-using-python-/

  • -
-

Before running the code please read this.

-

The following papers could assist in processing of MODIS dataset:

-
    -
  • https://www.mdpi.com/2072-4292/8/7/554

  • -
  • https://www.tandfonline.com/doi/full/10.1080/01431161.2018.1430913

  • -
  • https://www.mdpi.com/2072-4292/6/6/5368

  • -
-
-
-
## Alternative Approach to Obtain Land Cover Data and Net Primary Production (NPP) Data from MODIS
-# #Import the libraries
-
-# from modis_tools.auth import ModisSession
-# from modis_tools.resources import CollectionApi, GranuleApi
-# from modis_tools.granule_handler import GranuleHandler
-# from typing_extensions import Literal
-
-
-
-
-
-
-
## Alternative Approach to Obtain Land Cover Data and Net Primary Production (NPP) Data from MODIS
-# #download_modis.py
-# username = ""  # Update this line with your username 
-# password = ""  # Update this line with your password
-# # 1) connect to earthdata
-# session = ModisSession(username=username, password=password)
-
-# # 2) Query the MODIS catalog for collections
-# collection_client = CollectionApi(session=session)
-# collections = collection_client.query(short_name="", version="") # Collection short name + version
-# # Query the selected collection for granules
-# granule_client = GranuleApi.from_collection(collections[0], session=session)
-
-# # 3) Filter the selected granules via spatial and temporal parameters
-# Israel_bbox = [] # format [x_min, y_min, x_max, y_max] # add min lon,min lat, max lon and max_lat input your preferred location
-# Israel_granules = granule_client.query(start_date="", end_date="", bounding_box=Israel_bbox)   #choose the start and end dates for the year-month-day you prefer
-
-# # 4) Download the granules
-# GranuleHandler.download_from_granules(Israel_granules, session, threads=-1) 
-# #NB the file format will be downloaded in hdf 
-
-
-
-
-
-
-
-

Gross Primary Production (GPP) Datasets

-

In the tutorial, you learned about Net primary production (NPP). Another similar key ecosystem process is Gross Primary Production (GPP), which is the total amount of carbon compounds produced by photosynthesis of plants in an ecosystem in a given period of time. NPP is equal to GPP minus energy used by primary producers for respiration. GPP is the amount of energy from light converted to chemical energy per unit of time, while NPP is a measure of the net CO2 sequestered by vegetation.

-

Here we provide you the GPP datasets VODCA2GPP via here and this paper. This dataset estimates GPP based on VOD (Microwave Vegetation Optical Depth (VOD), a measure of the attenuation of microwave radiation caused by vegetation and thus relates to the total vegetation water content) using Generalized Additive Models. This VODCA2GPP is based on the period from 2007 to 2015 and uses VOD data from C-, X- and Ku-band and various GPP data sets. The data sets have different temporal coverage, which is summarized for VOD and GPP data in Table 2.

-
-
-
import pandas as pd
-from IPython.display import display, HTML, Markdown
-
-# Data as list of dictionaries
-data = [
-    {"Sensor": "AMSR-E", "Time period used": "Jun 2002–Oct 2011", "AECT": "13:30", "C-band [GHz]": "6.93", "X-band [GHz]": "10.65", "Ku-band [GHz]": "18.7", "Reference": "Van der Schalie et al. (2017)"},
-    {"Sensor": "AMSR2", "Time period used": "Jul 2012–Dec 2020", "AECT": "13:30", "C-band [GHz]": "6.93, 7.30", "X-band [GHz]": "10.65", "Ku-band [GHz]": "18.7", "Reference": "Van der Schalie et al. (2017)"},
-    {"Sensor": "AMSR2", "Time period used": "Jul 2012–Aug 2017 (Ku-band)", "AECT": "", "C-band [GHz]": "", "X-band [GHz]": "", "Ku-band [GHz]": "", "Reference": ""},
-    {"Sensor": "SSM/I F08", "Time period used": "Jul 1987–Dec 1991", "AECT": "18:15", "C-band [GHz]": "", "X-band [GHz]": "", "Ku-band [GHz]": "19.35", "Reference": "Owe et al. (2008)"},
-    {"Sensor": "SSM/I F11", "Time period used": "Dec 1991–May 1995", "AECT": "17:00–18:15", "C-band [GHz]": "", "X-band [GHz]": "", "Ku-band [GHz]": "19.35", "Reference": "Owe et al. (2008)"},
-    {"Sensor": "SSM/I F13", "Time period used": "May 1995–Apr 2009", "AECT": "17:45–18:40", "C-band [GHz]": "", "X-band [GHz]": "", "Ku-band [GHz]": "19.35", "Reference": "Owe et al. (2008)"},
-    {"Sensor": "TMI", "Time period used": "Dec 1997–Apr 2015", "AECT": "Asynchronous", "C-band [GHz]": "", "X-band [GHz]": "10.65", "Ku-band [GHz]": "19.35", "Reference": "Owe et al. (2008), Van der Schalie et al. (2017)"},
-    {"Sensor": "WindSat", "Time period used": "Feb 2003–Jul 2012", "AECT": "18:00", "C-band [GHz]": "6.8", "X-band [GHz]": "10.7", "Ku-band [GHz]": "18.7", "Reference": "Owe et al. (2008), Van der Schalie et al. (2017)"}
-]
-
-# Convert list of dictionaries into a DataFrame
-df = pd.DataFrame(data)
-
-# Set max_colwidth to None so that the full content of Description column is displayed
-pd.set_option('display.max_colwidth', None)
-
-# Convert the DataFrame to HTML and hide the index
-html = df.to_html(index=False)
-
-# Table title and link to paper in Markdown
-title_md = "### Table 2: Variable names, data sets, and additional information of VODCA2GPP datasets. [Reference](https://essd.copernicus.org/articles/14/1063/2022/#section6)"
-
-# Display the title
-display(Markdown(title_md))
-
-# Display the table
-display(HTML(html))
-
-
-
-
-
-

System Message: WARNING/2 (/home/yuda/code/climatematch/course-content/book/projects/project-notebooks/Surface_albedo_and_land_use.ipynb, line 1)

-

Non-consecutive header level increase; 0 to 3 [myst.header]

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SensorTime period usedAECTC-band [GHz]X-band [GHz]Ku-band [GHz]Reference
AMSR-EJun 2002–Oct 201113:306.9310.6518.7Van der Schalie et al. (2017)
AMSR2Jul 2012–Dec 202013:306.93, 7.3010.6518.7Van der Schalie et al. (2017)
AMSR2Jul 2012–Aug 2017 (Ku-band)
SSM/I F08Jul 1987–Dec 199118:1519.35Owe et al. (2008)
SSM/I F11Dec 1991–May 199517:00–18:1519.35Owe et al. (2008)
SSM/I F13May 1995–Apr 200917:45–18:4019.35Owe et al. (2008)
TMIDec 1997–Apr 2015Asynchronous10.6519.35Owe et al. (2008), Van der Schalie et al. (2017)
WindSatFeb 2003–Jul 201218:006.810.718.7Owe et al. (2008), Van der Schalie et al. (2017)
-
-
-

Net Primary Production (NPP) Datasets

-

Alternatively, you can access the NPP data by downloading the MCD12Q1.061 MODIS Land Cover Type Yearly Global 500m using the instruction provided earlier. The description of this dataset can be viewed here.

-
-
-
# gpp data is acquired from this work: https://essd.copernicus.org/articles/14/1063/2022/
-url_GPP='https://researchdata.tuwien.ac.at/records/1k7aj-bdz35/files/VODCA2GPP_v1.nc?download=1'
-ds_GPP=xr.open_dataset(pooch.retrieve(url_GPP,known_hash=None))
-ds_GPP
-
-
-
-
-
Downloading data from 'https://researchdata.tuwien.ac.at/records/1k7aj-bdz35/files/VODCA2GPP_v1.nc?download=1' to file '/home/yuda/.cache/pooch/6e247026b602773579622b33be872c40-VODCA2GPP_v1.nc'.
-
-
-
---------------------------------------------------------------------------
-KeyboardInterrupt                         Traceback (most recent call last)
-Cell In[8], line 3
-      1 # gpp data is acquired from this work: https://essd.copernicus.org/articles/14/1063/2022/
-      2 url_GPP='https://researchdata.tuwien.ac.at/records/1k7aj-bdz35/files/VODCA2GPP_v1.nc?download=1'
-----> 3 ds_GPP=xr.open_dataset(pooch.retrieve(url_GPP,known_hash=None))
-      4 ds_GPP
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/pooch/core.py:239, in retrieve(url, known_hash, fname, path, processor, downloader, progressbar)
-    236 if downloader is None:
-    237     downloader = choose_downloader(url, progressbar=progressbar)
---> 239 stream_download(url, full_path, known_hash, downloader, pooch=None)
-    241 if known_hash is None:
-    242     get_logger().info(
-    243         "SHA256 hash of downloaded file: %s\n"
-    244         "Use this value as the 'known_hash' argument of 'pooch.retrieve'"
-   (...)
-    247         file_hash(str(full_path)),
-    248     )
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/pooch/core.py:803, in stream_download(url, fname, known_hash, downloader, pooch, retry_if_failed)
-    799 try:
-    800     # Stream the file to a temporary so that we can safely check its
-    801     # hash before overwriting the original.
-    802     with temporary_file(path=str(fname.parent)) as tmp:
---> 803         downloader(url, tmp, pooch)
-    804         hash_matches(tmp, known_hash, strict=True, source=str(fname.name))
-    805         shutil.move(tmp, str(fname))
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/pooch/downloaders.py:226, in HTTPDownloader.__call__(self, url, output_file, pooch, check_only)
-    224     progress = self.progressbar
-    225     progress.total = total
---> 226 for chunk in content:
-    227     if chunk:
-    228         output_file.write(chunk)
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/requests/models.py:816, in Response.iter_content.<locals>.generate()
-    814 if hasattr(self.raw, "stream"):
-    815     try:
---> 816         yield from self.raw.stream(chunk_size, decode_content=True)
-    817     except ProtocolError as e:
-    818         raise ChunkedEncodingError(e)
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/urllib3/response.py:628, in HTTPResponse.stream(self, amt, decode_content)
-    626 else:
-    627     while not is_fp_closed(self._fp):
---> 628         data = self.read(amt=amt, decode_content=decode_content)
-    630         if data:
-    631             yield data
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/urllib3/response.py:567, in HTTPResponse.read(self, amt, decode_content, cache_content)
-    564 fp_closed = getattr(self._fp, "closed", False)
-    566 with self._error_catcher():
---> 567     data = self._fp_read(amt) if not fp_closed else b""
-    568     if amt is None:
-    569         flush_decoder = True
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/urllib3/response.py:533, in HTTPResponse._fp_read(self, amt)
-    530     return buffer.getvalue()
-    531 else:
-    532     # StringIO doesn't like amt=None
---> 533     return self._fp.read(amt) if amt is not None else self._fp.read()
-
-File /usr/lib/python3.8/http/client.py:459, in HTTPResponse.read(self, amt)
-    456 if amt is not None:
-    457     # Amount is given, implement using readinto
-    458     b = bytearray(amt)
---> 459     n = self.readinto(b)
-    460     return memoryview(b)[:n].tobytes()
-    461 else:
-    462     # Amount is not given (unbounded read) so we must check self.length
-    463     # and self.chunked
-
-File /usr/lib/python3.8/http/client.py:503, in HTTPResponse.readinto(self, b)
-    498         b = memoryview(b)[0:self.length]
-    500 # we do not use _safe_read() here because this may be a .will_close
-    501 # connection, and the user is reading more bytes than will be provided
-    502 # (for example, reading in 1k chunks)
---> 503 n = self.fp.readinto(b)
-    504 if not n and b:
-    505     # Ideally, we would raise IncompleteRead if the content-length
-    506     # wasn't satisfied, but it might break compatibility.
-    507     self._close_conn()
-
-File /usr/lib/python3.8/socket.py:669, in SocketIO.readinto(self, b)
-    667 while True:
-    668     try:
---> 669         return self._sock.recv_into(b)
-    670     except timeout:
-    671         self._timeout_occurred = True
-
-File /usr/lib/python3.8/ssl.py:1241, in SSLSocket.recv_into(self, buffer, nbytes, flags)
-   1237     if flags != 0:
-   1238         raise ValueError(
-   1239           "non-zero flags not allowed in calls to recv_into() on %s" %
-   1240           self.__class__)
--> 1241     return self.read(nbytes, buffer)
-   1242 else:
-   1243     return super().recv_into(buffer, nbytes, flags)
-
-File /usr/lib/python3.8/ssl.py:1099, in SSLSocket.read(self, len, buffer)
-   1097 try:
-   1098     if buffer is not None:
--> 1099         return self._sslobj.read(len, buffer)
-   1100     else:
-   1101         return self._sslobj.read(len)
-
-KeyboardInterrupt: 
-
-
-
-
-
-
-
-

ERA5-Land monthly averaged data from 1950 to present

-

ERA5-Land is a reanalysis dataset that offers an enhanced resolution compared to ERA5, providing a consistent view of land variables over several decades. It is created by replaying the land component of the ECMWF ERA5 climate reanalysis, which combines model data and global observations to generate a complete and reliable dataset using the laws of physics.

-

ERA5-Land focuses on the water and energy cycles at the surface level, offering a detailed record starting from 1950. The data used here is a post-processed subset of the complete ERA5-Land dataset. Monthly-mean averages have been pre-calculated to facilitate quick and convenient access to the data, particularly for applications that do not require sub-monthly fields. The native spatial resolution of the ERA5-Land reanalysis dataset is 9km on a reduced Gaussian grid (TCo1279). The data in the CDS has been regridded to a regular lat-lon grid of 0.1x0.1 degrees.

-
-

To calculate albedo using ERA5-Land

-

ERA5 parameter Forecast albedo provides is the measure of the reflectivity of the Earth’s surface. It is the fraction of solar (shortwave) radiation reflected by Earth’s surface, across the solar spectrum, for both direct and diffuse radiation. Values are between 0 and 1. Typically, snow and ice have high reflectivity with albedo values of 0.8 and above, land has intermediate values between about 0.1 and 0.4 and the ocean has low values of 0.1 or less. Radiation from the Sun (solar, or shortwave, radiation) is partly reflected back to space by clouds and particles in the atmosphere (aerosols) and some of it is absorbed. The rest is incident on the Earth’s surface, where some of it is reflected. The portion that is reflected by the Earth’s surface depends on the albedo. In the ECMWF Integrated Forecasting System (IFS), a climatological background albedo (observed values averaged over a period of several years) is used, modified by the model over water, ice and snow. Albedo is often shown as a percentage (%).

-
-
-

Alternative Approach to Obtain Albedo Data from MERRA-2

-

MERRA-2 is a NASA satellite dataset that incorporates advances that facilitate the assimilation of modern hyperspectral radiance, microwave observations, and GPS-Radio Occultation datasets. It also includes NASA’s ozone profile observations starting from late 2004, and improvements in the GEOS model and the GSI assimilation system. MERRA-2 maintains a similar spatial resolution to its predecessor, approximately 50 km in the latitudinal direction. It provides different kinds of information at different spatial resolutions than MODIS. MERRA-2 has a coarser spatial resolution than MODIS. While MODIS provides land cover data at a resolution of 500 meters, MERRA-2 offers meteorological data at a much coarser resolution of approximately 50 kilometers.

-

Further background on the dataset could be found here.

-

Extra help on downloading MERRA-2 datasets:

-
    -
  • https://daac.gsfc.nasa.gov/information/howto?title=How%20to%20Access%20MERRA-2%20Data%20using%20OPeNDAP%20with%20Python3%20and%20Calculate%20Daily%2FWeekly%2FMonthly%20Statistics%20from%20Hourly%20Data%20

  • -
  • https://github.com/emilylaiken/merradownload

  • -
  • https://github.com/Open-Power-System-Data/weather_data/blob/master/download_merra2.ipynb

  • -
  • https://daac.gsfc.nasa.gov/information/howto?title=How%20to%20remotely%20access%20MERRA-2%20with%20Python3%20and%20calculate%20monthly%20average%20surface%20PM2.5%20for%20world%20countries

  • -
-
-
-
# source of landuse data: https://doi.pangaea.de/10.1594/PANGAEA.913496
-# the folder "land-use" has the data for years 1982 to 2015. choose the years you need and change the path accordingly 
-path_LandUse=os.path.expanduser('~/shared/Data/Projects/Albedo/land-use/GLASS-GLC_7classes_1982.tif')
-ds_landuse=xr.open_dataset(path_LandUse).rename({'x':'longitude', 'y':'latitude'})
-# ds_landuse.band_data[0,:,:].plot() # how to plot the global data
-ds_landuse
-
-
-
-
-
- - - - - - - - - - - - - - -
<xarray.Dataset>
-Dimensions:      (band: 1, longitude: 8016, latitude: 3229)
-Coordinates:
-  * band         (band) int64 1
-  * longitude    (longitude) float64 -180.0 -180.0 -179.9 ... 179.9 180.0 180.0
-  * latitude     (latitude) float64 85.0 84.96 84.91 ... -59.9 -59.94 -59.99
-    spatial_ref  int64 ...
-Data variables:
-    band_data    (band, latitude, longitude) float64 ...
-
-
-
-
# link for albedo data:
-
-albedo_path='~/shared/Data/Projects/Albedo/ERA/albedo-001.nc'
-ds_albedo=xr.open_dataset(albedo_path)
-ds_albedo # note the official variable name is fal (forecast albedo)
-
-
-
-
-
- - - - - - - - - - - - - - -
<xarray.Dataset>
-Dimensions:    (longitude: 3600, latitude: 1801, time: 240)
-Coordinates:
-  * longitude  (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9
-  * latitude   (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0
-  * time       (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01
-Data variables:
-    fal        (time, latitude, longitude) float32 ...
-Attributes:
-    Conventions:  CF-1.6
-    history:      2023-06-27 17:05:46 GMT by grib_to_netcdf-2.25.1: /opt/ecmw...
-
-

for your convience, included below are preciptation and temprature ERA5 dataset for the same times as the Albedo dataset

-
-
-
precp_path='~/shared/Data/Projects/Albedo/ERA/precipitation-002.nc'
-ds_precp=xr.open_dataset(precp_path)
-ds_precp # the variable name is tp (total preciptation)
-
-
-
-
-
- - - - - - - - - - - - - - -
<xarray.Dataset>
-Dimensions:    (longitude: 3600, latitude: 1801, time: 240)
-Coordinates:
-  * longitude  (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9
-  * latitude   (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0
-  * time       (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01
-Data variables:
-    tp         (time, latitude, longitude) float32 ...
-Attributes:
-    Conventions:  CF-1.6
-    history:      2023-06-27 17:02:16 GMT by grib_to_netcdf-2.25.1: /opt/ecmw...
-
-
-
-
tempr_path='~/shared/Data/Projects/Albedo/ERA/Temperature-003.nc'
-ds_tempr=xr.open_dataset(tempr_path)
-ds_tempr # the variable name is t2m (temprature at 2m)
-
-
-
-
-
- - - - - - - - - - - - - - -
<xarray.Dataset>
-Dimensions:    (longitude: 3600, latitude: 1801, time: 240)
-Coordinates:
-  * longitude  (longitude) float32 0.0 0.1 0.2 0.3 ... 359.6 359.7 359.8 359.9
-  * latitude   (latitude) float32 90.0 89.9 89.8 89.7 ... -89.8 -89.9 -90.0
-  * time       (time) datetime64[ns] 2001-01-01 2001-02-01 ... 2020-12-01
-Data variables:
-    t2m        (time, latitude, longitude) float32 ...
-Attributes:
-    Conventions:  CF-1.6
-    history:      2023-06-27 16:58:35 GMT by grib_to_netcdf-2.25.1: /opt/ecmw...
-
-
-
-
-

Further Reading

-
    -
  • Zhao, X., Wu, T., Wang, S., Liu, K., Yang, J. Cropland abandonment mapping at sub-pixel scales using crop phenological information and MODIS time-series images, Computers and Electronics in Agriculture, Volume 208, -2023,107763, ISSN 0168-1699,https://doi.org/10.1016/j.compag.2023.107763

  • -
  • Shani Rohatyn et al., Limited climate change mitigation potential through forestation of the vast dryland regions.Science377,1436-1439(2022).DOI:10.1126/science.abm9684

  • -
  • Hu, Y., Hou, M., Zhao, C., Zhen, X., Yao, L., Xu, Y. Human-induced changes of surface albedo in Northern China from 1992-2012, International Journal of Applied Earth Observation and Geoinformation, Volume 79, 2019, Pages 184-191, ISSN 1569-8432, https://doi.org/10.1016/j.jag.2019.03.018

  • -
  • Duveiller, G., Hooker, J. & Cescatti, A. The mark of vegetation change on Earth’s surface energy balance. Nat Commun 9, 679 (2018). https://doi.org/10.1038/s41467-017-02810-8

  • -
  • Yin, H., Brandão, A., Buchner, J., Helmers, D., Iuliano, B.G., Kimambo, N.E., Lewińska, K.E., Razenkova, E., Rizayeva, A., Rogova, N., Spawn, S.A., Xie, Y., Radeloff, V.C. Monitoring cropland abandonment with Landsat time series, Remote Sensing of Environment, Volume 246, 2020, 111873, ISSN 0034-4257,https://doi.org/10.1016/j.rse.2020.111873

  • -
  • Gupta, P., Verma, S., Bhatla, R.,Chandel, A. S., Singh, J., & Payra, S.(2020). Validation of surfacetemperature derived from MERRA‐2Reanalysis against IMD gridded data setover India.Earth and Space Science,7,e2019EA000910. https://doi.org/10.1029/2019EA000910

  • -
  • Cao, Y., S. Liang, X. Chen, and T. He (2015) Assessment of Sea Ice Albedo Radiative Forcing and Feedback over the Northern Hemisphere from 1982 to 2009 Using Satellite and Reanalysis Data. J. Climate, 28, 1248–1259, https://doi.org/10.1175/JCLI-D-14-00389.1.

  • -
  • Westberg, D. J., P. Stackhouse, D. B. Crawley, J. M. Hoell, W. S. Chandler, and T. Zhang (2013), An Analysis of NASA’s MERRA Meteorological Data to Supplement Observational Data for Calculation of Climatic Design Conditions, ASHRAE Transactions, 119, 210-221. -https://www.researchgate.net/profile/Drury-Crawley/publication/262069995_An_Analysis_of_NASA’s_MERRA_Meteorological_Data_to_Supplement_Observational_Data_for_Calculation_of_Climatic_Design_Conditions/links/5465225f0cf2052b509f2cc0/An-Analysis-of-NASAs-MERRA-Meteorological-Data-to-Supplement-Observational-Data-for-Calculation-of-Climatic-Design-Conditions.pdf

  • -
-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/projects/project-notebooks/Wildfires_and_burnt_areas.html b/book/_build/html/projects/project-notebooks/Wildfires_and_burnt_areas.html deleted file mode 100644 index 8d18edb0e..000000000 --- a/book/_build/html/projects/project-notebooks/Wildfires_and_burnt_areas.html +++ /dev/null @@ -1,2200 +0,0 @@ - - - - - - - - - - - - Monitoring and Mapping Wildfires Using Satellite Data — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Monitoring and Mapping Wildfires Using Satellite Data#

-

Content creators: Brittany Engle, Diana Cadillo

-

Content reviewers: Yuhan Douglas Rao, Abigail Bodner, Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-
# @title Project Background
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-    def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-        self.id = id
-        if source == "Bilibili":
-            src = f"https://player.bilibili.com/player.html?bvid={id}&page={page}"
-        elif source == "Osf":
-            src = f"https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render"
-        super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-    tab_contents = []
-    for i, video_id in enumerate(video_ids):
-        out = widgets.Output()
-        with out:
-            if video_ids[i][0] == "Youtube":
-                video = YouTubeVideo(
-                    id=video_ids[i][1], width=W, height=H, fs=fs, rel=0
-                )
-                print(f"Video available at https://youtube.com/watch?v={video.id}")
-            else:
-                video = PlayVideo(
-                    id=video_ids[i][1],
-                    source=video_ids[i][0],
-                    width=W,
-                    height=H,
-                    fs=fs,
-                    autoplay=False,
-                )
-                if video_ids[i][0] == "Bilibili":
-                    print(
-                        f"Video available at https://www.bilibili.com/video/{video.id}"
-                    )
-                elif video_ids[i][0] == "Osf":
-                    print(f"Video available at https://osf.io/{video.id}")
-            display(video)
-        tab_contents.append(out)
-    return tab_contents
-
-
-video_ids = [('Youtube', '2CDVn6O_q34'), ('Bilibili', 'BV1GP411k7XA')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-    tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # @title Project Background
-----> 3 from ipywidgets import widgets
-      4 from IPython.display import YouTubeVideo
-      5 from IPython.display import IFrame
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
# @title Tutorial slides
-# @markdown These are the slides for the videos in all tutorials today
-from IPython.display import IFrame
-link_id = "8w5da"
-
-
-
-
-

In this project, you will be working with wildfire remote sensing data from Sentinel 2 to extract Burn Perimeters using multiple Burn Indices and other relevant information related to wildfires. By integrating this data with information from other global databases, you will have the opportunity to explore the connections between wildfires and their impact on both the ecosystem and society.

-
-
-

Project Template#

-

Project Template

-

Note: The dashed boxes are socio-economic questions.

-
-
-

Data Exploration Notebook#

-
-

Project Setup#

-
-
-
# installs
-# !pip install gdal
-# !pip install pandas
-# !pip install geopandas
-
-
-
-
-
-
-
# imports
-import random
-import numpy
-import matplotlib.pyplot as plt
-import pandas as pd
-import geopandas as gpd
-import os
-import matplotlib
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[4], line 3
-      1 # imports
-      2 import random
-----> 3 import numpy
-      4 import matplotlib.pyplot as plt
-      5 import pandas as pd
-
-ModuleNotFoundError: No module named 'numpy'
-
-
-
-
-
-
-

Satellite Data#

-

Global Wildfire Information System (GWIS) is a global, joint initiative created by the GEO and the Copernicus Work Programs. The goal of this program is to bring together sources at a regional and international level to provide a global, comprehensive understanding of fire regimes and their effects.

-

The Globfire dataset uses the MODIS burned area product (MCD64A1) to determine the amount of burnt area per event (Artés et al., 2019). The MCD64A1 product that Globfire is built on top of combines imagery from the Terra and Aqua satellites with thermal anomalies to provide burnt area information (Website, MODIS C6 BA User Guide & User Guide).

-

Sentinel 2 -Launched by the European Space Agency in June of 2015 (S2-A) and March of 2017 (S2-B), the Copernicus Sentinel-2 mission combines two polar-orbiting satellites to monitor variability in land surface conditions. Together, they have a global revisit time of roughly 5 days.

-

In the provided Project Template, we load the following datasets:

- -

-
-
-

Global Wildfire Information Systems: Climate Action Large Wildfire Dataset#

-

The Climate Action Large Wildfire Dataset is a filtered version of the Globfire dataset (created by GWIS, which you can access here).

-

The resolution of this dataset is 500m. It has been pre-filtered to include only fires that are Class F or greater. Per the National Wildfire Coordinating Group, a Class F fire is defined as a fire that is 1,000 acres or greater, but less than 5,000 acres (note that a 2000m square region is roughly 1000 acres). For this dataset, all fires greater than 1,000 acres are included. Additional columns indicating area (acres), landcover number and landcover description, and country in which they are located within, were added. The landcover number and description were added using the Copernicus Global Land Cover Layers: CGLS-LC100 Collection 3 User Guide.

-

Table Information: -ID: Globfire fire ID (unique to each fire)

-
    -
  1. IDate: Globfire Initial (start) date of the fire

  2. -
  3. FDate: Globfire Final (end) date of the fire

  4. -
  5. Continent: Location of the fire

  6. -
  7. Area_acres: size of fire in acres

  8. -
  9. Landcover: land cover value from ESA, if the landcover of the fire cover is greater than 51%, then it is labeled as that landcover

  10. -
  11. LC_descrip: land cover description from ESA

  12. -
  13. Country: country the fire is located in

  14. -
-
-
-
# code to retrieve and load the data
-url_climateaction = "~/shared/Data/Projects/Wildfires/ClimateAction_countries.shp"
-Dataset = gpd.read_file(url_climateaction)  # need to update to OSF and pooch.retrieve
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 3
-      1 # code to retrieve and load the data
-      2 url_climateaction = "~/shared/Data/Projects/Wildfires/ClimateAction_countries.shp"
-----> 3 Dataset = gpd.read_file(url_climateaction)  # need to update to OSF and pooch.retrieve
-
-NameError: name 'gpd' is not defined
-
-
-
-
-

We can now visualize the content of the dataset.

-
-
-
# code to print the shape, array names, etc of the dataset
-Dataset.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 2
-      1 # code to print the shape, array names, etc of the dataset
-----> 2 Dataset.head()
-
-NameError: name 'Dataset' is not defined
-
-
-
-
-
-
-
# plot the dataset
-Dataset.plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # plot the dataset
-----> 2 Dataset.plot()
-
-NameError: name 'Dataset' is not defined
-
-
-
-
-

Great work! Now you are all set to address the questions you are interested in! Good luck!

-

-
-
-

Sentinel-2#

-

Each of the two satellites contain a Multi-Spectral Instrument (MSI) that houses 13 spectral bands, at various resolutions. The MSI uses a push-broom acquisition technique and measures in the Visible and Near Infrared (NIR) and the Short Wave Infrared (SWIR) domains. There are:

-
    -
  • Four bands with 10m resolution: B2-Blue (490 nm), B3- Green (560 nm), B4- Red (665 nm) and Band 8- Near Infrared (NIR) (842 nm).

  • -
  • Six bands with 20m resolution: B5, B6, B7 and B8A (705 nm, 740 nm, 783 nm and 865 nm respectively) Vegetation Red Edge bands, along with B11 and B12 (1610 nm and 2190 nm) SWIR bands. These bands are mostly used for vegetation characterisation, vegetation stress assessment and ice/cloud/snow detection.

  • -
  • Three additional bands: B1 - Coastal Aerosol (443 nm), B9- Water Vapor (945 nm), and B10-SWIR-Cirrus (1375 nm) which are typically used for corrections of the atmosphere and clouds.

  • -
-

*Sentinel-2

-
-
-
# view image
-def showImage(Output):
-    plt.imshow(Output)
-    plt.show()
-
-
-
-
-
-
-
# data source-specific imports
-
-# root folder location of where the imagery is currently saved
-rootFolder = '/home/jovyan/shared/Data/Projects/Wildfires'
-
-continet = "Asia"
-
-# import pre images
-# pre_fire_paths = glob.glob(rootFolder + continet + id +"/pre_fire_*.npy")
-pre_fire_paths = [
-    fileName
-    for fileName in os.listdir(os.path.join(rootFolder, continet))
-    if (fileName.endswith(".npy") & fileName.startswith("pre_fire_"))
-]
-pre_fires_numpy = [
-    numpy.load(os.path.join(rootFolder, continet, x)).astype(int)
-    for x in pre_fire_paths
-]
-
-# import post images
-post_fire_paths = [
-    fileName
-    for fileName in os.listdir(os.path.join(rootFolder, continet))
-    if (fileName.endswith(".npy") & fileName.startswith("post_fire_"))
-]
-post_fires_numpy = [
-    numpy.load(os.path.join(rootFolder, continet, x)).astype(int)
-    for x in post_fire_paths
-]
-
-# import Pre-SCL Mask for cloud coverage
-scl_fire_paths = [
-    fileName
-    for fileName in os.listdir(os.path.join(rootFolder, continet))
-    if (fileName.endswith(".npy") & fileName.startswith("scl_pre_fire_"))
-]
-scl_fires_numpy = [
-    numpy.load(os.path.join(rootFolder, continet, x)) for x in scl_fire_paths
-]
-
-# import Post-SCL Mask for cloud coverage
-scl_fires_post_paths = [
-    fileName
-    for fileName in os.listdir(os.path.join(rootFolder, continet))
-    if (fileName.endswith(".npy") & fileName.startswith("scl_post_fire_"))
-]
-scl_fires_post_numpy = [
-    numpy.load(os.path.join(rootFolder, continet, x)) for x in scl_fires_post_paths
-]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 12
-      6 continet = "Asia"
-      8 # import pre images
-      9 # pre_fire_paths = glob.glob(rootFolder + continet + id +"/pre_fire_*.npy")
-     10 pre_fire_paths = [
-     11     fileName
----> 12     for fileName in os.listdir(os.path.join(rootFolder, continet))
-     13     if (fileName.endswith(".npy") & fileName.startswith("pre_fire_"))
-     14 ]
-     15 pre_fires_numpy = [
-     16     numpy.load(os.path.join(rootFolder, continet, x)).astype(int)
-     17     for x in pre_fire_paths
-     18 ]
-     20 # import post images
-
-NameError: name 'os' is not defined
-
-
-
-
-
-
-
# print list of pre_fires
-print("\n".join(pre_fire_paths))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # print list of pre_fires
-----> 2 print("\n".join(pre_fire_paths))
-
-NameError: name 'pre_fire_paths' is not defined
-
-
-
-
-
-
-
# print list of post_fire
-print("\n".join(post_fire_paths))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # print list of post_fire
-----> 2 print("\n".join(post_fire_paths))
-
-NameError: name 'post_fire_paths' is not defined
-
-
-
-
-
-
-
# print list of SCL
-print("\n".join(scl_fire_paths))
-print("\n".join(scl_fires_post_paths))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # print list of SCL
-----> 2 print("\n".join(scl_fire_paths))
-      3 print("\n".join(scl_fires_post_paths))
-
-NameError: name 'scl_fire_paths' is not defined
-
-
-
-
-
-
-
# view pre-fire satellite image that was taken right before the fire start date
-showImage(
-    numpy.clip(pre_fires_numpy[2][:, :, [3, 2, 1]] / 10000 * 3.5, 0, 1)
-)  # RGB bands for Sentinel 2 are Bands: 4,3,2
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 3
-      1 # view pre-fire satellite image that was taken right before the fire start date
-      2 showImage(
-----> 3     numpy.clip(pre_fires_numpy[2][:, :, [3, 2, 1]] / 10000 * 3.5, 0, 1)
-      4 )  # RGB bands for Sentinel 2 are Bands: 4,3,2
-
-NameError: name 'numpy' is not defined
-
-
-
-
-
-
-
# view post-fire satellite image that was taken right before the fire start date
-showImage(
-    numpy.clip(post_fires_numpy[0][:, :, [3, 2, 1]] / 10000 * 3.5, 0, 1)
-)  # RGB bands for Sentinel 2 are Bands: 4,3,2
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 3
-      1 # view post-fire satellite image that was taken right before the fire start date
-      2 showImage(
-----> 3     numpy.clip(post_fires_numpy[0][:, :, [3, 2, 1]] / 10000 * 3.5, 0, 1)
-      4 )  # RGB bands for Sentinel 2 are Bands: 4,3,2
-
-NameError: name 'numpy' is not defined
-
-
-
-
-
-

Sentinel-2: Vegetation Health & Burnt Areas#

-

Sentinel-2 Imagery - Vegetation Health & Burnt Areas

-

Continents included:

-
    -
  • Asia

  • -
  • Africa

  • -
  • Austrailia

  • -
  • Europe

  • -
  • North America

  • -
  • South America

  • -
-

Vegetation Health: Vegetation indices define and monitor the health of vegetation using the radiance values of the visible and near-infrared channels. The Normalized Difference Vegetation Index (NDVI) is used to measure “greenness” of vegetation. -As one of the most widely used vegetation indexes, the NDVI takes advantage of how strongly Chlorophyll absorbs visible light and how well the leafs cellular structure reflects near-infrared. Its values range from +1.0 to -1.0, with areas of sand, rock, and snow typically having a value of 0.1 or less. Shrubs and spare vegetation are roughly 0.2 to 0.5, while higher NDVI values (0.6 to 0.9) indicate dense vegetation that is typically found in tropical forests.

-

The NDVI can also be used to create the Vegetation Condition Index (VCI). The VCI depends on the current NDVI along with the extreme NDVI values within the dataset (NDVImax and NDVImin). Specifically, $\(VCI = \frac{NDVI-NDVImin}{NDVImax-NDVImin}\times 100\%\)$

-

This number is then compared to the threshold to determine the drought severity. For this project, up to 3 months of pre-fire imagery will be used to determine current drought conditions.

- -

Burnt Area Severity: Burn severity describes how the intensity of the fire affects the functioning of the ecosystem in which it occurred. The degree to which it alters the ecosystem is typically found using a burn index, which then (typically) classes the severity of the fire as: unburned, low severity, moderate severity, or high severity. One of the most common burn indices is the Normalized Burn Ratio (NBR). This index is designed to highlight burnt areas in fire zones. The formula is similar to NDVI, except that the formula combines the use of both near infrared (NIR) and shortwave infrared (SWIR) wavelengths. Healthy vegetation shows a very high reflectance in the NIR, and low reflectance in the SWIR portion of the spectrum - the opposite of what is seen in areas devastated by fire. Recently burnt areas demonstrate low reflectance in the NIR and high reflectance in the SWIR. The difference between the spectral responses of healthy vegetation and burnt areas reach their peak in the NIR and the SWIR regions of the spectrum. The difference between normalized burn ratios before and after a fire is called the dNBR, and is one of many useful indices.

-

Specifically, the dNBR isolates the burned areas from the unburned areas, and subtracts the pre-fire imagery from the post-fire imagery. This removes any unchanged, and thus unburned, pixels as their values result in near zero. The results of the dNBR are based on burn severity, and correspond to the gradient of burn severity for every pixel. The dNBR has an unscaled range of -2.0 to +2.0 with burned areas tending to show more positively.

- -

SCL Mask -Importing the SCL in order to mask out clouds form imagery

-
-
-
# compute SCL Mask to 0s and 1s, masking out clouds and bad pixels
-def computeSCLMask(image):
-    rImage, cImage = image.shape
-    sclOutput = numpy.zeros((rImage, cImage))
-    for x in range(cImage):
-        for y in range(rImage):
-            sclOutput[y, x] = 1 if image[y, x] in [0, 1, 3, 8, 9, 11] else 0
-
-    return sclOutput
-
-
-
-
-
-
-
# create Pre-fire and post-fire SCL masks
-print(scl_fires_numpy[5])
-pre_SCL_Mask = computeSCLMask(scl_fires_numpy[5])
-post_SCL_Mask = computeSCLMask(scl_fires_post_numpy[0])
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 2
-      1 # create Pre-fire and post-fire SCL masks
-----> 2 print(scl_fires_numpy[5])
-      3 pre_SCL_Mask = computeSCLMask(scl_fires_numpy[5])
-      4 post_SCL_Mask = computeSCLMask(scl_fires_post_numpy[0])
-
-NameError: name 'scl_fires_numpy' is not defined
-
-
-
-
-
-
-
# view SCL imagery for image closests to the start fire date
-# -------  Save SCL as colored image based on SCL classification
-
-# No Data (0) = black
-# Saturated / Defective (1) = red
-# Dark Area Pixels (2) = chocolate
-# Cloud Shadows (3) = brown
-# Vegetation (4) = lime
-# Bare Soils (5) = yellow
-# Water (6) = blue
-# Clouds low probability / Unclassified (7) = aqua
-# clouds medium probability (8) = darkgrey
-# Clouds high probability (9) light grey
-# Cirrus (10) = deepskyblue
-# Snow / Ice (11) = magenta
-#  colors: https://matplotlib.org/3.1.1/gallery/color/named_colors.html#sphx-glr-gallery-color-named-colors-py
-
-
-def showSCL(image):
-    cmap = matplotlib.colors.ListedColormap(
-        [
-            "black",
-            "red",
-            "chocolate",
-            "brown",
-            "lime",
-            "yellow",
-            "blue",
-            "aqua",
-            "darkgrey",
-            "lightgrey",
-            "deepskyblue",
-            "magenta",
-        ]
-    )
-    plt.imshow(image, cmap=cmap)
-    plt.show()
-
-
-showSCL(scl_fires_numpy[5])
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 40
-     36     plt.imshow(image, cmap=cmap)
-     37     plt.show()
----> 40 showSCL(scl_fires_numpy[5])
-
-NameError: name 'scl_fires_numpy' is not defined
-
-
-
-
-
-
-

Dataset-specific Functions: NDVI#

-
-
-
# this code computes the NDVI for an image
-"The NDVI can be computed on any image (pre or post)."
-"Compute the NDVI on the pre-fire image"
-
-# compute NDVI
-def computeNDVI(image, mask):
-    r, c, ch = image.shape
-    ndviOutput = numpy.zeros((r, c))
-    for x in range(c):
-        for y in range(r):
-            if (image[y, x, 7] == 0 and image[y, x, 3] == 0) or mask[y, x] == 1:
-                ndviOutput[y, x] = numpy.nan
-            else:
-                ndviOutput[y, x] = (image[y, x, 7] - image[y, x, 3]) / (
-                    image[y, x, 7] + image[y, x, 3]
-                )
-
-    return ndviOutput
-
-
-
-
-
-
-
# TA Code
-computeNDVI_value = computeNDVI(pre_fires_numpy[2], pre_SCL_Mask)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[19], line 2
-      1 # TA Code
-----> 2 computeNDVI_value = computeNDVI(pre_fires_numpy[2], pre_SCL_Mask)
-
-NameError: name 'pre_fires_numpy' is not defined
-
-
-
-
-
-
-
# plot NDVI without remap
-showImage(computeNDVI_value)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[20], line 2
-      1 # plot NDVI without remap
-----> 2 showImage(computeNDVI_value)
-
-NameError: name 'computeNDVI_value' is not defined
-
-
-
-
-
-
-
# use this code to remap the NDVI to specific colors for values
-def remapNDVI(NDVI):
-    remapped = numpy.zeros((NDVI.shape[0], NDVI.shape[1]))
-    for x in range(remapped.shape[0]):
-        for y in range(remapped.shape[1]):
-            if numpy.isnan(NDVI[x, y]):
-                remapped[x, y] = numpy.nan
-            elif NDVI[x, y] <= -0.2:
-                remapped[x, y] = 1
-            elif NDVI[x, y] <= 0:
-                remapped[x, y] = 2
-            elif NDVI[x, y] <= 0.1:
-                remapped[x, y] = 3
-            elif NDVI[x, y] <= 0.2:
-                remapped[x, y] = 4
-            elif NDVI[x, y] <= 0.3:
-                remapped[x, y] = 5
-            elif NDVI[x, y] <= 0.4:
-                remapped[x, y] = 6
-            elif NDVI[x, y] <= 0.5:
-                remapped[x, y] = 7
-            elif NDVI[x, y] <= 0.6:
-                remapped[x, y] = 8
-            elif NDVI[x, y] <= 0.7:
-                remapped[x, y] = 9
-            elif NDVI[x, y] <= 0.8:
-                remapped[x, y] = 10
-            elif NDVI[x, y] <= 0.9:
-                remapped[x, y] = 11
-            elif NDVI[x, y] <= 1:
-                remapped[x, y] = 12
-            else:
-                remapped[x, y] = 13
-    return remapped
-
-
-
-
-
-
-
# TA Code
-NDVI_remap = remapNDVI(computeNDVI_value)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[22], line 2
-      1 # TA Code
-----> 2 NDVI_remap = remapNDVI(computeNDVI_value)
-
-NameError: name 'computeNDVI_value' is not defined
-
-
-
-
-
-
-
# view remapped NDVI
-def showNDVI(image):
-    cmap = matplotlib.colors.ListedColormap(
-        [
-            "#000000",
-            "#a50026",
-            "#d73027",
-            "#f46d43",
-            "#fdae61",
-            "#fee08b",
-            "#ffffbf",
-            "#d9ef8b",
-            "#a6d96a",
-            "#66bd63",
-            "#1a9850",
-            "#006837",
-        ]
-    )
-    plt.imshow(image, cmap=cmap)
-    plt.show()
-
-
-showNDVI(NDVI_remap)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[23], line 23
-     19     plt.imshow(image, cmap=cmap)
-     20     plt.show()
----> 23 showNDVI(NDVI_remap)
-
-NameError: name 'NDVI_remap' is not defined
-
-
-
-
-
-
-

Dataset-specific Functions: VCI#

-
-
-
# compute the SCL mask for all the SCLs and apply it to the pre_fire_NDVIs
-pre_fires_scl = [computeSCLMask(x) for x in scl_fires_numpy]
-pre_fires_NDVI = [computeNDVI(x[0], x[1]) for x in zip(pre_fires_numpy, pre_fires_scl)]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[24], line 2
-      1 # compute the SCL mask for all the SCLs and apply it to the pre_fire_NDVIs
-----> 2 pre_fires_scl = [computeSCLMask(x) for x in scl_fires_numpy]
-      3 pre_fires_NDVI = [computeNDVI(x[0], x[1]) for x in zip(pre_fires_numpy, pre_fires_scl)]
-
-NameError: name 'scl_fires_numpy' is not defined
-
-
-
-
-
-
-
# compute for VCI
-def computeVCI(for_ndvi_image, ndvi_dataset):
-    rImage, cImage = for_ndvi_image.shape
-    vciOutput = numpy.zeros((rImage, cImage))
-    ndvi_dataset.append(for_ndvi_image)
-    for x in range(cImage):
-        for y in range(rImage):
-            pixels = [z[y, x] for z in ndvi_dataset]
-            filtered_pixels = [f for f in pixels if not numpy.isnan(f)]
-            if len(filtered_pixels) == 0 or len(filtered_pixels) == 1:
-                vciOutput[y, x] = 1
-            elif numpy.isnan(for_ndvi_image[y, x]):
-                vciOutput[y, x] = 1
-            else:
-                max_val = max(filtered_pixels)
-                min_val = min(filtered_pixels)
-                if max_val == min_val:
-                    vciOutput[y, x] = 1
-                else:
-                    vciOutput[y, x] = (for_ndvi_image[y, x] - min_val) / (
-                        max_val - min_val
-                    )
-
-    return vciOutput
-
-
-
-
-
-
-

VCI Drought Threshold#

- -

droughtthreshold.png

-
-
-
# compute the VCI for the last pre-fire to view the drought over the time period
-last_pre_fire_NDVI = pre_fires_NDVI.pop(2)
-last_pre_fire_vci = computeVCI(last_pre_fire_NDVI, pre_fires_NDVI)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[26], line 2
-      1 # compute the VCI for the last pre-fire to view the drought over the time period
-----> 2 last_pre_fire_NDVI = pre_fires_NDVI.pop(2)
-      3 last_pre_fire_vci = computeVCI(last_pre_fire_NDVI, pre_fires_NDVI)
-
-NameError: name 'pre_fires_NDVI' is not defined
-
-
-
-
-
-
-
# view the non-thresholded VCI
-showImage(last_pre_fire_vci)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[27], line 2
-      1 # view the non-thresholded VCI
-----> 2 showImage(last_pre_fire_vci)
-
-NameError: name 'last_pre_fire_vci' is not defined
-
-
-
-
-
-
-
# map specific colors to values to show the severity of the droughts
-def remapVCI(vci):
-    remapped = numpy.zeros(vci.shape)
-    for x in range(remapped.shape[0]):
-        for y in range(remapped.shape[1]):
-            if vci[x, y] < 0.35:
-                remapped[x, y] = 1
-            elif vci[x, y] <= 0.50:
-                remapped[x, y] = 2
-            else:
-                remapped[x, y] = 3
-    return remapped
-
-
-
-
-
-
-
# define the VCI mapped/thresholded values
-def showVCI(vci_image):
-    cmap = matplotlib.colors.ListedColormap(["red", "yellow", "green"])
-    plt.imshow(remapVCI(vci_image), cmap=cmap)
-    plt.show()
-
-
-
-
-
-
-
# view the mapped VCI values
-showVCI(last_pre_fire_vci)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[30], line 2
-      1 # view the mapped VCI values
-----> 2 showVCI(last_pre_fire_vci)
-
-NameError: name 'last_pre_fire_vci' is not defined
-
-
-
-
-
-
-

Dataset-specific Functions: NBR and dNBR Code#

-
-
-
# this code creates the NBR for each image then uses the NBR to create the dNBR. It can easily be updated for other burnt area indices
-
-
-def computeFireMasks(pre_fire, post_fire):
-
-    rows, columns, channels = pre_fire.shape
-    nbrPost = numpy.zeros((rows, columns))
-    nbrPre = numpy.zeros((rows, columns))
-    dnbr = numpy.zeros((rows, columns))
-
-    for x in range(columns):
-        for y in range(rows):
-            nbrPost[y, x] = (post_fire[y, x, 7] - post_fire[y, x, 11]) / (
-                post_fire[y, x, 7] + post_fire[y, x, 11]
-            )
-            nbrPre[y, x] = (pre_fire[y, x, 7] - pre_fire[y, x, 11]) / (
-                pre_fire[y, x, 7] + pre_fire[y, x, 11]
-            )
-            dnbr[y, x] = nbrPre[y, x] - nbrPost[y, x]
-
-    return dnbr
-
-
-
-
-
-
-
# TA Code
-# run computeFireMasks
-dnbr = computeFireMasks(pre_fires_numpy[2], post_fires_numpy[0])
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[32], line 3
-      1 # TA Code
-      2 # run computeFireMasks
-----> 3 dnbr = computeFireMasks(pre_fires_numpy[2], post_fires_numpy[0])
-
-NameError: name 'pre_fires_numpy' is not defined
-
-
-
-
-
-
-
# this code applies a threshold to the dNBR to show the level of burn intensity (unburned, low severity, moderate severity, or high severity)
-
-
-def remapDNBR(dnbr):
-    remapped = numpy.zeros((dnbr.shape[0], dnbr.shape[1]))
-    for x in range(remapped.shape[0]):
-        for y in range(remapped.shape[1]):
-            if numpy.isnan(dnbr[x, y]):
-                remapped[x, y] = numpy.nan
-            elif dnbr[x, y] <= -0.251:
-                remapped[x, y] = 1
-            elif dnbr[x, y] <= -0.101:
-                remapped[x, y] = 2
-            elif dnbr[x, y] <= 0.099:
-                remapped[x, y] = 3
-            elif dnbr[x, y] <= 0.269:
-                remapped[x, y] = 4
-            elif dnbr[x, y] <= 0.439:
-                remapped[x, y] = 5
-            elif dnbr[x, y] <= 0.659:
-                remapped[x, y] = 6
-            elif dnbr[x, y] <= 1.3:
-                remapped[x, y] = 7
-            else:
-                remapped[x, y] = 8
-    return remapped
-
-
-
-
-
-
-
# TA Code
-dnbr_remapped = remapDNBR(dnbr)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[34], line 2
-      1 # TA Code
-----> 2 dnbr_remapped = remapDNBR(dnbr)
-
-NameError: name 'dnbr' is not defined
-
-
-
-
-
-
-

dNBR Threshold#

- -

threshold.png

-
-
-
# this code takes the above function (remapDNBR) where the dNBR threshold has been applied to the image'
-# and applies a color coded map to each threshold as shown in the image above'
-
-
-def showDNBR(dnbr):
-    cmap = matplotlib.colors.ListedColormap(
-        [
-            "blue",
-            "teal",
-            "green",
-            "yellow",
-            "orange",
-            "red",
-            "purple",
-        ]
-    )
-    plt.imshow(remapDNBR(dnbr), cmap=cmap)
-
-
-showDNBR(dnbr_remapped)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[35], line 20
-      6     cmap = matplotlib.colors.ListedColormap(
-      7         [
-      8             "blue",
-   (...)
-     15         ]
-     16     )
-     17     plt.imshow(remapDNBR(dnbr), cmap=cmap)
----> 20 showDNBR(dnbr_remapped)
-
-NameError: name 'dnbr_remapped' is not defined
-
-
-
-
-
-
-
-
-

Further Reading#

- -

Socio-economic effects of wildfires

-
    -
  • Zhao, J. et al. (2020). Quantifying the Effects of Vegetation Restorations on the Soil Erosion Export and Nutrient Loss on the Loess Plateau. Front. Plant Sci. 11 https://doi.org/10.3389/fpls.2020.573126

  • -
  • Amanda K. Hohner, Charles C. Rhoades, Paul Wilkerson, Fernando L. Rosario-Ortiz (2019). Wildfires alter forest watersheds and threaten drinking water quality. Accounts of Chemical Research. 52: 1234-1244. https://doi.org/10.1021/acs.accounts.8b00670

  • -
  • Alan Buis (2021). The Climate Connections of a Record Fire Year in the U.S. West. Link

  • -
  • Ian P. Davies ,Ryan D. Haugo,James C. Robertson,Phillip S. Levin (2018). The unequal vulnerability of communities of color to wildfire.PLoS ONE 13(11): e0205825. https://doi.org/10.1371/journal.pone.0205825

  • -
-

Wildfires and forest ecosystems

- -
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/reports/Ocean_acidification.log b/book/_build/html/reports/Ocean_acidification.log deleted file mode 100644 index 3d9fbdd00..000000000 --- a/book/_build/html/reports/Ocean_acidification.log +++ /dev/null @@ -1,45 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -# from W1D3 tutorial 6 we have Sea Surface Temprature from 1981 to the present: -# download the monthly sea surface temperature data from NOAA Physical System -# Laboratory. The data is processed using the OISST SST Climate Data Records -# from the NOAA CDR program. -# the data downloading may take 2-3 minutes to complete. - -url_sst = "https://osf.io/6pgc2/download/" -ds_SST = xr.open_dataset(pooch.retrieve(url_sst,known_hash=None)) -ds_SST -------------------- - diff --git a/book/_build/html/reports/Regional_precipitation_variability.log b/book/_build/html/reports/Regional_precipitation_variability.log deleted file mode 100644 index 4daf3b860..000000000 --- a/book/_build/html/reports/Regional_precipitation_variability.log +++ /dev/null @@ -1,43 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -# Code to retrieve and load the data - -years=range(1981,2024) # the years you want. we want 1981 till 2023 -files=['https://data.chc.ucsb.edu/products/CHIRPS-2.0/global_daily/netcdf/p25/chirps-v2.0.'+str(year)+'.days_p25.nc' for year in years] # the format of the files -downloaded_files=[pooch.retrieve(file,known_hash=None) for file in files] # download all of the files -#### open data as xarray -chirps_data = xr.open_mfdataset(downloaded_files,combine='by_coords') # open the files as one dataset -------------------- - diff --git a/book/_build/html/reports/Surface_albedo_and_land_use.log b/book/_build/html/reports/Surface_albedo_and_land_use.log deleted file mode 100644 index 0bc41143a..000000000 --- a/book/_build/html/reports/Surface_albedo_and_land_use.log +++ /dev/null @@ -1,40 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -# gpp data is acquired from this work: https://essd.copernicus.org/articles/14/1063/2022/ -url_GPP='https://researchdata.tuwien.ac.at/records/1k7aj-bdz35/files/VODCA2GPP_v1.nc?download=1' -ds_GPP=xr.open_dataset(pooch.retrieve(url_GPP,known_hash=None)) -ds_GPP -------------------- - diff --git a/book/_build/html/reports/W1D2_Tutorial2.log b/book/_build/html/reports/W1D2_Tutorial2.log deleted file mode 100644 index ac74bddb4..000000000 --- a/book/_build/html/reports/W1D2_Tutorial2.log +++ /dev/null @@ -1,39 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -['# note this can take several minutes to download', "selected_vars = ['air_temperature_at_2_metres', 'northward_wind_at_10_metres', 'eastward_wind_at_10_metres',", " 'surface_air_pressure','sea_surface_temperature'] # the variables we want", "s3_data_ptrn = '{year}/{month}/data/{var}.nc' # path and filename format for this S3 bucket", "year_s3 = date_sel.strftime('%Y') # extract the year"] -... -[' ERA5_select=xr.merge([ERA5_select,ds_temp]) # if not empty, merge the new file', ' else:', ' ERA5_select=ds_temp #if empty, just assign the new file', '', 'ERA5_allvars = ERA5_select.sel(lon= slice(lon_range[0] , lon_range[1])).sel(lat = slice(lat_range[0] , lat_range[1]))'] -------------------- - diff --git a/book/_build/html/reports/W1D2_Tutorial3.log b/book/_build/html/reports/W1D2_Tutorial3.log deleted file mode 100644 index 7cd7dfd45..000000000 --- a/book/_build/html/reports/W1D2_Tutorial3.log +++ /dev/null @@ -1,41 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -# note this can take a few minutes to download -url_era5_mm = "https://osf.io/3q4vs/download" # contains only one file: 'ERA5_surface_winds_mm.nc' -ERA5_mm=xr.open_dataset(pooch.retrieve(url_era5_mm, - known_hash=None)).sel(time=slice('1980', '2010')) # select the timeslice during loading -ERA5_mm -------------------- - diff --git a/book/_build/html/reports/W1D2_Tutorial6.log b/book/_build/html/reports/W1D2_Tutorial6.log deleted file mode 100644 index 943f47d2a..000000000 --- a/book/_build/html/reports/W1D2_Tutorial6.log +++ /dev/null @@ -1,42 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -# import preprocessed ECCO data. This data is full depth temperature data over 1992 to 2016 (annual mean) -# this file takes about 5 minutes to load -url_theta = "https://osf.io/c8wqt/download" -theta_annual= xr.open_dataset(pooch.retrieve(url_theta, known_hash=None)) -theta_annual=theta_annual.THETA -theta_annual=theta_annual.where(theta_annual != 0) #make land points equal to NaN -------------------- - diff --git a/book/_build/html/reports/W1D3_Tutorial6.log b/book/_build/html/reports/W1D3_Tutorial6.log deleted file mode 100644 index 1a57ae563..000000000 --- a/book/_build/html/reports/W1D3_Tutorial6.log +++ /dev/null @@ -1,39 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -['# Option 1: Download data', '# Download the monthly sea surface temperature data from NOAA Physical System', '# Laboratory. The data is processed using the OISST SST Climate Data Records', '# from NOAA CDR program.', '# The data downloading may take 2-3 minutes to complete.'] -... -[' fid.write(r.content)', ' print(f"Download {fname} completed!")', '', '## Option 2: Use the data stored in the workspace', "#url = 'asset/data/sst.mon.mean.nc'"] -------------------- - diff --git a/book/_build/html/reports/W1D4_Tutorial1.log b/book/_build/html/reports/W1D4_Tutorial1.log deleted file mode 100644 index f711ce26e..000000000 --- a/book/_build/html/reports/W1D4_Tutorial1.log +++ /dev/null @@ -1,40 +0,0 @@ -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 730, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 96, in ensure_async - result = await obj - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_client/channels.py", line 230, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/jupyter_cache/executors/utils.py", line 51, in single_nb_execution - executenb( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 1204, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 84, in wrapped - return just_run(coro(*args, **kwargs)) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/util.py", line 62, in just_run - return loop.run_until_complete(coro) - File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete - return future.result() - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 663, in async_execute - await self.async_execute_cell( - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 949, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 754, in _async_poll_for_reply - await self._async_handle_timeout(timeout, cell) - File "/home/yuda/code/climatematch/course-content/venv/lib/python3.8/site-packages/nbclient/client.py", line 801, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -# convert all the lipd files into a DataFrame -fname = "pages2k_data" - -pages2k_data = lipd2df(lipd_dirpath=os.path.join(".", f"{fname}.unzip", "LiPD_Files")) -------------------- - diff --git a/book/_build/html/reports/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.err.log b/book/_build/html/reports/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.err.log deleted file mode 100644 index 6b1774a4d..000000000 --- a/book/_build/html/reports/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.err.log +++ /dev/null @@ -1,36 +0,0 @@ -Traceback (most recent call last): - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/nbclient/client.py", line 778, in _async_poll_for_reply - msg = await ensure_async(self.kc.shell_channel.get_msg(timeout=new_timeout)) - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/jupyter_core/utils/__init__.py", line 182, in ensure_async - result = await obj - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/jupyter_client/channels.py", line 315, in get_msg - raise Empty -_queue.Empty - -During handling of the above exception, another exception occurred: - -Traceback (most recent call last): - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/jupyter_cache/executors/utils.py", line 58, in single_nb_execution - executenb( - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/nbclient/client.py", line 1305, in execute - return NotebookClient(nb=nb, resources=resources, km=km, **kwargs).execute() - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/jupyter_core/utils/__init__.py", line 166, in wrapped - return loop.run_until_complete(inner) - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete - return future.result() - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/nbclient/client.py", line 705, in async_execute - await self.async_execute_cell( - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/nbclient/client.py", line 1001, in async_execute_cell - exec_reply = await self.task_poll_for_reply - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/nbclient/client.py", line 802, in _async_poll_for_reply - error_on_timeout_execute_reply = await self._async_handle_timeout(timeout, cell) - File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/nbclient/client.py", line 852, in _async_handle_timeout - raise CellTimeoutError.error_from_timeout_and_cell( -nbclient.exceptions.CellTimeoutError: A cell timed out while it was being executed, after 60 seconds. -The message was: Cell execution timed out. -Here is a preview of the cell contents: -------------------- -# take the time mean -ERA5_ANN = ERA5_mm.mean("time") -------------------- - diff --git a/book/_build/html/search.html b/book/_build/html/search.html deleted file mode 100644 index e00f1f7de..000000000 --- a/book/_build/html/search.html +++ /dev/null @@ -1,982 +0,0 @@ - - - - - - - - - - Search - Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - -
- -
- -
-
- - -
-

Search

- - - -
-
- - - - -
- -
- -
-
-
- -
- -
- -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/searchindex.js b/book/_build/html/searchindex.js deleted file mode 100644 index 199682bd6..000000000 --- a/book/_build/html/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -Search.setIndex({"docnames": ["projects/README", "projects/docs/continuing_your_project_after_the_course", "projects/docs/datasets_overview", "projects/docs/project_guidance", "projects/professional_development/README", "projects/professional_development/career_features", "projects/professional_development/career_panels", "projects/professional_development/impact_talks", "projects/professional_development/mentors", "projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature", "projects/project-notebooks/Heatwaves", "projects/project-notebooks/Ocean_acidification", "projects/project-notebooks/Regional_precipitation_variability", "projects/project-notebooks/Sea_level_rise", "projects/project-notebooks/Surface_albedo_and_land_cover", "projects/project-notebooks/Wildfires_and_burnt_areas", "tutorials/Projects_GoodResearchPractices/chapter_title", "tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary", "tutorials/Projects_GoodResearchPractices/student/Projects_Intro", "tutorials/Projects_GoodResearchPractices/student/Projects_Outro", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8", "tutorials/Schedule/daily_schedules", "tutorials/Schedule/schedule_intro", "tutorials/Schedule/shared_calendars", "tutorials/TechnicalHelp/Discord", "tutorials/TechnicalHelp/Jupyterbook", "tutorials/TechnicalHelp/Links_Policy", "tutorials/TechnicalHelp/Tutorial_colab", "tutorials/TechnicalHelp/Tutorial_jupyterhub", "tutorials/TechnicalHelp/Tutorial_kaggle", "tutorials/TechnicalHelp/tech_intro", "tutorials/W1D1_ClimateSystemOverview/chapter_title", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8", "tutorials/W1D4_Paleoclimate/chapter_title", "tutorials/W1D4_Paleoclimate/further_reading", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9", "tutorials/W1D5_ClimateModeling/chapter_title", "tutorials/W1D5_ClimateModeling/further_reading", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial4", "tutorials/W2D4_ClimateResponse-Extremes&Variability/chapter_title", "tutorials/W2D4_ClimateResponse-Extremes&Variability/further_reading", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial1", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial2", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial3", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial4", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial5", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial6", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial7", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial8", "tutorials/W2D5_ClimateResponse-AdaptationImpact/chapter_title", "tutorials/W2D5_ClimateResponse-AdaptationImpact/further_reading", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial1", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial2", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial3", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial4", "tutorials/intro", "tutorials/prereqs/ClimateScience"], "filenames": ["projects/README.md", "projects/docs/continuing_your_project_after_the_course.md", "projects/docs/datasets_overview.md", "projects/docs/project_guidance.md", "projects/professional_development/README.md", "projects/professional_development/career_features.md", "projects/professional_development/career_panels.md", "projects/professional_development/impact_talks.ipynb", "projects/professional_development/mentors.md", "projects/project-notebooks/ENSO_impact_on_precipitation_and_temperature.ipynb", "projects/project-notebooks/Heatwaves.ipynb", "projects/project-notebooks/Ocean_acidification.ipynb", "projects/project-notebooks/Regional_precipitation_variability.ipynb", "projects/project-notebooks/Sea_level_rise.ipynb", "projects/project-notebooks/Surface_albedo_and_land_cover.ipynb", "projects/project-notebooks/Wildfires_and_burnt_areas.ipynb", "tutorials/Projects_GoodResearchPractices/chapter_title.md", "tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Intro.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Outro.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7.ipynb", "tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8.ipynb", "tutorials/Schedule/daily_schedules.md", "tutorials/Schedule/schedule_intro.md", "tutorials/Schedule/shared_calendars.md", "tutorials/TechnicalHelp/Discord.md", "tutorials/TechnicalHelp/Jupyterbook.md", "tutorials/TechnicalHelp/Links_Policy.md", "tutorials/TechnicalHelp/Tutorial_colab.md", "tutorials/TechnicalHelp/Tutorial_jupyterhub.md", "tutorials/TechnicalHelp/Tutorial_kaggle.md", "tutorials/TechnicalHelp/tech_intro.md", "tutorials/W1D1_ClimateSystemOverview/chapter_title.md", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8.ipynb", "tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title.md", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading.md", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5.ipynb", "tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title.md", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading.md", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7.ipynb", "tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8.ipynb", "tutorials/W1D4_Paleoclimate/chapter_title.md", "tutorials/W1D4_Paleoclimate/further_reading.md", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.ipynb", "tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.ipynb", "tutorials/W1D5_ClimateModeling/chapter_title.md", "tutorials/W1D5_ClimateModeling/further_reading.md", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.ipynb", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.ipynb", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.ipynb", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.ipynb", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.ipynb", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.ipynb", "tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.ipynb", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title.md", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading.md", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1.ipynb", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2.ipynb", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3.ipynb", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4.ipynb", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5.ipynb", "tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6.ipynb", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title.md", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading.md", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1.ipynb", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2.ipynb", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3.ipynb", "tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial4.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/chapter_title.md", "tutorials/W2D4_ClimateResponse-Extremes&Variability/further_reading.md", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial1.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial2.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial3.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial4.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial5.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial6.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial7.ipynb", "tutorials/W2D4_ClimateResponse-Extremes&Variability/student/W2D4_Tutorial8.ipynb", "tutorials/W2D5_ClimateResponse-AdaptationImpact/chapter_title.md", "tutorials/W2D5_ClimateResponse-AdaptationImpact/further_reading.md", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial1.ipynb", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial2.ipynb", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial3.ipynb", "tutorials/W2D5_ClimateResponse-AdaptationImpact/student/W2D5_Tutorial4.ipynb", "tutorials/intro.ipynb", "tutorials/prereqs/ClimateScience.md"], "titles": ["Projects", "Climatematch Impact Scholars program", "Project materials", "Daily guide for projects", "Professional Development", "Career Features", "Career Panels", "Impact Talks", "Mentor Meetings", "The Impact of ENSO on Precipitation and Temperature", "Heatwaves: Assessing the Dynamic Interactions of the Atmosphere and Land", "Ocean Acidification", "Regional Precipitation Variability and Extreme Events", "Sea Level Rise", "Changes in Land Cover: Albedo and Carbon Sequestration", "Monitoring and Mapping Wildfires Using Satellite Data", "Good Research Practices", "Day Summary", "Intro", "Outro", "Tutorial 1: Finding a Phenomenon and Asking a Question About It", "Tutorial 2: Doing a Literature Review", "Tutorial 3: Identifying the Basic Ingredients", "Tutorial 4: Formulating a Hypothesis", "Tutorial 5: Drafting the Analysis", "Tutorial 6: Implementing the Analysis", "Tutorial 7: Interpreting the Results", "Tutorial 8: Communicating Your Conclusions", "General Schedule", "Schedule", "Shared calendars", "Using discord", "Using jupyterbook", "Quick links and policies", "Using Google Colab", "Using JupyterHub", "Using Kaggle", "Technical Help", "Climate System Overview", "Day Summary", "Intro", "Outro", "Tutorial 1: Creating DataArrays and Datasets to Assess Global Climate Data", "Tutorial 2: Selection, Interpolation and Slicing", "Tutorial 3: Opening and Plotting netCDF Data", "Tutorial 4: Arithmetic and Aggregation Methods", "Tutorial 5: Xarray Data Analysis and Climatology", "Tutorial 6: Compute and Plot Temperature Anomalies", "Tutorial 7: Other Computational Tools in Xarray", "Tutorial 8: Masking with One Condition", "Tutorial 9: Masking with Multiple Conditions", "State of the Climate Ocean and Atmosphere Reanalysis", "Suggested Further Reading", "Day Summary", "Intro", "Outro", "Tutorial 1: Calculating ENSO with Xarray", "Tutorial 2: A Lot of Weather Makes Climate - Exploring the ERA5 Reanalysis", "Tutorial 3: Atmospheric Circulation", "Tutorial 4: Oceanic Wind-driven Circulation", "Tutorial 5: Thermohaline Circulation", "Tutorial 6: Ocean Heat Content", "Remote Sensing Land Ocean and Atmosphere", "Suggested Further Reading", "Tutorial 1: Introduction to Remote Sensing", "Tutorial 2: Exploring Satellite Climate Data Records", "Tutorial 3: Visualizing Satellite CDR - Global Vegetation Mapping", "Tutorial 4: Understanding Climatology Through Precipitation Data", "Tutorial 5: Calculating Anomalies Using Precipitation Data", "Tutorial 6: Large Scale Climate Variability - ENSO", "Tutorial 7: Impact of Climate Variability - Precipitation", "Tutorial 8: Comparing Satellite Products With In Situ Data", "Paleoclimate", "Suggested Further Reading", "Tutorial 1: Paleoclimate Proxies", "Tutorial 2: Reconstructing Past Changes in Ocean Climate", "Tutorial 3: Reconstructing Past Changes in Terrestrial Climate", "Tutorial 4: Reconstructing Past Changes in Atmospheric Climate", "Tutorial 5: Paleoclimate Data Analysis Tools", "Tutorial 6: Spectral Analysis of Paleoclimate Data", "Tutorial 7: Assessing Climate Forcings", "Tutorial 8: Paleoclimate Models", "Tutorial 9: Paleoclimate Reanalysis Products", "Climate Modeling", "Suggested Further Reading", "Tutorial 1 : A Simple Greenhouse Model", "Tutorial 2 : Energy Balance", "Tutorial 3 : A Zero-Dimensional Energy Balance Model", "Tutorial 4: Climate Feedbacks", "Tutorial 5: Radiative Equilibrium", "Tutorial 6: Radiative Convective Equilibrium", "Tutorial 7: Introduction to Earth System Models", "Future Climate - IPCC I Physical Basis", "Suggested Further Reading", "Tutorial 1: Creating Maps of CMIP6 Earth System Model (ESM) Projections", "Tutorial 2: Time Series, Global Averages, and Scenario Comparison", "Tutorial 3: Multi-model Ensembles", "Tutorial 4: Quantifying Uncertainty in Projections", "Tutorial 5: Internal Climate Variability", "Tutorial 6: Synthesising & Interpreting Diverse Data Sources", "Future Climate - IPCC II & III Socio-Economic Basis", "Tutorial 2 Further Reading", "Tutorial 1:", "Tutorial 2: Transition Goals and Integrated Assessment Models", "Tutorial 3: IAMs and SSPs", "Tutorial 4: Public Opinion on the Climate Emergency and Why it Matters", "Climate Response - Extremes & Variability", "Suggested Further Reading", "Tutorial 1: Distributions", "Tutorial 2: What is an Extreme Event? Empirical Return Levels", "Tutorial 3: Extreme Value Analysis - the GEV Distribution", "Tutorial 4: Return Levels Using Normal and GEV Distributions", "Tutorial 5: Non-stationarity in Historical Records", "Tutorial 6: Scenario-dependence of Future Changes in Extremes", "Tutorial 7: Non-Stationarity in the EVT-framework", "Tutorial 8: Thresholds", "Climate Response - Adaptation Impact", "Suggested Further Reading", "Tutorial 1: Linear and Logistic Regression", "Tutorial 2: Regression and Decision Trees on the Dengue Fever Dataset", "Tutorial 3: Logistic Regression and ANN on the Remote Sensing Crop Dataset", "Tutorial 4: Exploring other applications", "Introduction", "Prerequisites and preparatory materials for Computational Tools for Climate Science"], "terms": {"welcom": [0, 1, 3, 8, 40, 54, 102, 118, 119, 120, 123], "climatematch": [0, 3, 6, 8, 33, 35, 105, 107, 122, 123], "academi": [0, 1, 3, 6, 8, 33, 35, 63, 123], "everi": [0, 1, 3, 8, 11, 15, 21, 35, 36, 44, 45, 46, 48, 60, 64, 66, 67, 70, 71, 78, 95, 96, 97, 98, 99, 102, 103, 105, 109, 111, 123], "dai": [0, 1, 2, 7, 9, 10, 11, 12, 13, 14, 15, 21, 25, 33, 35, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 54, 56, 57, 58, 59, 60, 61, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "you": [0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 35, 36, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "spend": [0, 3, 81], "3": [0, 6, 7, 10, 11, 12, 13, 14, 15, 18, 23, 25, 27, 30, 52, 60, 67, 68, 69, 77, 80, 82, 85, 90, 95, 97, 98, 99, 108, 109, 111, 112, 114, 115, 123], "hour": [0, 3, 6, 7, 8, 11, 22, 28, 57, 64, 66, 69, 105, 115, 123], "work": [0, 1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 17, 21, 22, 23, 27, 28, 33, 34, 35, 36, 40, 42, 43, 45, 48, 53, 56, 57, 58, 64, 69, 74, 76, 79, 89, 90, 91, 94, 95, 96, 98, 103, 107, 109, 113, 118, 119, 121, 122, 123], "profession": [0, 1, 3, 5, 6, 7, 8, 122], "develop": [0, 3, 6, 7, 9, 10, 12, 13, 15, 18, 23, 35, 52, 54, 58, 60, 63, 64, 65, 73, 80, 82, 87, 89, 94, 96, 97, 102, 105, 113, 115, 118, 122], "activ": [0, 1, 3, 4, 6, 7, 10, 11, 28, 64, 70, 103, 118, 120, 122], "give": [0, 3, 7, 18, 36, 42, 44, 46, 56, 59, 66, 68, 79, 85, 89, 90, 102, 103, 105, 109, 119, 120, 122], "an": [0, 1, 2, 3, 4, 7, 9, 10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 23, 24, 25, 27, 32, 33, 34, 35, 36, 39, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 53, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 76, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 108, 110, 111, 112, 113, 114, 115, 118, 119, 122, 123], "opportun": [0, 1, 3, 6, 7, 8, 10, 11, 14, 15, 57, 123], "appli": [0, 1, 3, 7, 10, 14, 15, 24, 40, 45, 48, 49, 50, 56, 57, 64, 66, 67, 68, 69, 71, 75, 78, 79, 80, 85, 87, 88, 91, 94, 95, 96, 97, 98, 99, 102, 105, 114, 118, 119, 120, 121], "your": [0, 1, 2, 3, 6, 7, 10, 11, 12, 13, 14, 17, 18, 19, 21, 23, 24, 25, 26, 28, 30, 34, 35, 36, 42, 43, 48, 49, 55, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 78, 82, 85, 87, 88, 91, 94, 95, 96, 97, 105, 108, 110, 112, 114, 115, 118, 119, 120, 121, 122, 123], "newli": [0, 11], "acquir": [0, 3, 8, 35, 56, 64, 66, 70, 82], "knowledg": [0, 3, 7, 8, 15, 20, 21, 22, 23, 24, 25, 26, 27, 43, 64, 67, 68, 82, 87, 99, 102, 103, 119, 122, 123], "real": [0, 3, 22, 24, 25, 89, 91, 118, 119, 121], "climat": [0, 1, 3, 4, 5, 6, 8, 9, 10, 11, 13, 14, 18, 19, 21, 22, 26, 28, 35, 36, 39, 41, 43, 52, 53, 55, 58, 59, 60, 61, 63, 64, 66, 68, 73, 74, 84, 101, 102, 103, 107, 108, 109, 110, 111, 112, 115, 118, 120, 121], "data": [0, 2, 3, 6, 7, 17, 18, 20, 21, 23, 24, 25, 26, 27, 28, 35, 36, 39, 40, 41, 43, 45, 47, 50, 52, 53, 54, 55, 58, 60, 61, 63, 69, 74, 76, 77, 80, 82, 85, 86, 87, 88, 98, 102, 107, 108, 109, 111, 112, 122, 123], "one": [0, 1, 2, 3, 7, 8, 9, 10, 12, 14, 15, 20, 21, 26, 27, 34, 36, 42, 43, 44, 45, 46, 48, 49, 50, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 76, 78, 80, 81, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "topic": [0, 2, 3, 4, 7, 8, 14, 21, 25, 56, 64, 84, 105, 107, 122, 123], "depth": [0, 21, 42, 56, 59, 61, 64, 87, 91, 95, 107, 120, 123], "It": [0, 3, 7, 10, 11, 12, 13, 14, 15, 42, 43, 44, 45, 49, 56, 57, 60, 64, 65, 66, 68, 69, 70, 86, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "confid": [0, 26, 65, 67, 80, 86, 97, 109, 113], "can": [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21, 22, 23, 24, 26, 27, 28, 32, 33, 34, 35, 36, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "By": [0, 3, 10, 15, 20, 21, 22, 23, 24, 25, 26, 27, 43, 44, 46, 57, 58, 61, 64, 66, 67, 68, 69, 71, 74, 75, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "togeth": [0, 3, 6, 15, 27, 28, 35, 65, 67, 68, 76, 79, 86, 91, 94, 105, 109, 115], "4": [0, 1, 2, 6, 7, 9, 10, 11, 12, 13, 14, 15, 18, 20, 21, 22, 30, 42, 50, 57, 58, 60, 65, 68, 69, 70, 74, 75, 76, 78, 79, 80, 81, 82, 85, 86, 87, 89, 90, 91, 94, 95, 96, 98, 99, 108, 109, 110, 112, 114, 115, 122, 123], "6": [0, 2, 9, 10, 11, 13, 14, 15, 18, 26, 27, 28, 46, 48, 49, 50, 56, 59, 60, 65, 66, 67, 68, 70, 71, 74, 75, 76, 77, 78, 80, 81, 82, 85, 86, 87, 88, 89, 91, 93, 94, 95, 96, 97, 98, 102, 103, 105, 107, 108, 109, 110, 111, 112, 114, 115, 118, 119, 120, 123], "peer": [0, 3, 6, 21, 27], "from": [0, 1, 2, 3, 7, 9, 10, 12, 13, 15, 18, 21, 23, 25, 26, 35, 36, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 61, 63, 64, 65, 67, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 89, 91, 94, 98, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "pod": [0, 2, 7, 27, 28, 119, 121], "learn": [0, 3, 4, 5, 8, 9, 10, 11, 12, 14, 15, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 34, 39, 40, 42, 43, 44, 45, 46, 48, 49, 50, 54, 56, 57, 58, 64, 65, 66, 67, 68, 69, 71, 74, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 97, 98, 99, 102, 103, 105, 111, 112, 113, 114, 115, 118, 119, 121, 122, 123], "engag": [0, 3, 7, 21, 65, 102, 119], "self": [0, 4, 7, 9, 11, 12, 13, 14, 15, 44, 47, 94, 97, 102, 105, 123], "direct": [0, 3, 6, 7, 11, 12, 13, 14, 15, 21, 44, 47, 56, 59, 68, 74, 80, 81, 91, 102, 103, 115, 118, 120], "find": [0, 2, 3, 4, 7, 9, 12, 17, 21, 23, 27, 28, 35, 42, 45, 46, 47, 48, 56, 57, 58, 60, 61, 64, 66, 67, 69, 70, 74, 85, 86, 87, 94, 96, 102, 105, 108, 109, 113, 115, 118, 120, 122, 123], "meaning": [0, 3, 64, 101, 103, 119], "problem": [0, 58, 101, 102, 103, 118, 119, 120, 123], "ask": [0, 1, 3, 7, 8, 10, 17, 18, 22, 65, 89, 105, 123], "question": [0, 1, 4, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 21, 22, 23, 24, 25, 26, 27, 28, 66, 121, 122, 123], "ar": [0, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 24, 25, 27, 33, 35, 36, 43, 44, 45, 46, 47, 48, 49, 50, 54, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "well": [0, 2, 3, 10, 11, 12, 14, 15, 21, 22, 24, 26, 27, 36, 39, 43, 45, 48, 50, 59, 65, 68, 75, 79, 81, 85, 89, 90, 91, 95, 102, 103, 105, 110, 112, 113, 114, 115, 118, 119, 120, 122, 123], "defin": [0, 3, 7, 9, 10, 11, 12, 13, 14, 15, 46, 50, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "answer": [0, 3, 4, 7, 44, 49, 64, 67, 75, 85, 86, 87, 89, 91, 108, 112, 121], "put": [0, 3, 7, 12, 14, 66, 77, 89], "concept": [0, 3, 7, 13, 18, 40, 64, 65, 67, 68, 69, 80, 85, 86, 90, 95, 96, 98, 102, 103, 107, 118, 123], "practic": [0, 3, 7, 8, 10, 14, 20, 21, 22, 23, 24, 25, 26, 27, 28, 35, 42, 43, 45, 48, 50, 56, 66, 67, 68, 69, 77, 78, 91, 102, 103, 118, 119, 121, 122, 123], "connect": [0, 1, 3, 4, 8, 12, 14, 15, 64, 66, 68, 71, 101, 103], "physic": [0, 3, 10, 11, 12, 13, 14, 21, 22, 28, 45, 58, 64, 65, 69, 70, 74, 87, 90, 91, 94, 95, 96, 97, 98, 99, 102, 107, 113, 122], "phenomena": [0, 3, 9, 21, 22, 50, 57, 74, 98, 102], "socio": [0, 1, 3, 7, 9, 10, 11, 12, 13, 14, 15, 95, 99, 102, 103, 105, 113, 122], "econom": [0, 1, 3, 7, 9, 10, 11, 12, 13, 14, 15, 64, 95, 99, 102, 105, 113, 122], "impact": [0, 2, 3, 5, 10, 11, 12, 13, 14, 15, 19, 20, 21, 28, 50, 54, 56, 60, 61, 65, 66, 69, 80, 85, 86, 87, 88, 95, 98, 99, 102, 103, 110, 112, 113, 115, 118, 119, 120, 122], "everyth": 0, "need": [0, 3, 7, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 26, 35, 42, 44, 46, 47, 50, 56, 57, 64, 65, 66, 67, 68, 69, 71, 74, 75, 76, 78, 81, 82, 85, 86, 87, 89, 90, 91, 94, 95, 96, 102, 103, 105, 109, 113, 114, 115, 118, 119, 120, 121, 122, 123], "know": [0, 3, 17, 22, 24, 27, 42, 43, 44, 48, 66, 71, 74, 81, 85, 87, 95, 103, 109, 118, 120, 121, 123], "about": [0, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 35, 39, 40, 42, 43, 44, 45, 46, 48, 50, 54, 56, 58, 59, 61, 64, 65, 66, 67, 69, 71, 74, 75, 76, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 93, 94, 96, 97, 98, 99, 102, 103, 105, 108, 109, 111, 113, 115, 118, 119, 120, 121, 122, 123], "daili": [0, 13, 15, 57, 59, 64, 65, 66, 67, 69, 71, 108, 109, 110, 113, 122], "schedul": [0, 6, 122, 123], "task": [0, 3, 7, 21, 28, 56, 57, 68, 71, 80, 120], "us": [0, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 18, 20, 21, 22, 23, 24, 25, 26, 27, 39, 40, 41, 43, 44, 45, 46, 47, 48, 54, 56, 58, 59, 60, 63, 65, 69, 70, 71, 74, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 91, 94, 96, 97, 98, 101, 102, 103, 105, 108, 109, 110, 112, 113, 114, 115, 118, 119, 121, 122, 123], "tip": [0, 3, 8, 12], "resourc": [0, 1, 3, 12, 18, 21, 22, 64, 65, 107, 122, 123], "found": [0, 3, 7, 11, 15, 21, 35, 36, 48, 49, 58, 61, 75, 78, 87, 101, 102, 105, 109, 112, 113, 114], "guid": [0, 4, 15, 18, 22, 23, 28, 31, 46, 57, 75, 79, 105, 123], "we": [0, 1, 3, 7, 8, 9, 10, 11, 12, 14, 15, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 34, 35, 36, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 54, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "also": [0, 1, 3, 7, 9, 10, 11, 12, 14, 15, 25, 27, 35, 36, 42, 43, 44, 46, 48, 50, 55, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 74, 75, 79, 81, 82, 85, 86, 88, 89, 91, 94, 95, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "provid": [0, 1, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21, 22, 24, 35, 39, 40, 42, 45, 46, 47, 50, 57, 58, 59, 64, 65, 66, 67, 69, 71, 74, 76, 81, 82, 91, 94, 95, 98, 99, 102, 103, 105, 108, 111, 112, 113, 114, 115, 118, 119, 120, 123], "rang": [0, 5, 7, 10, 11, 12, 13, 14, 15, 18, 25, 43, 46, 47, 49, 56, 57, 58, 61, 64, 65, 66, 67, 70, 71, 74, 79, 81, 82, 85, 86, 87, 88, 90, 95, 97, 98, 99, 102, 105, 108, 109, 110, 111, 113, 115, 118, 120], "materi": [0, 33, 45, 68, 75, 85, 91, 103, 122], "help": [0, 2, 3, 7, 8, 10, 11, 12, 18, 20, 21, 23, 30, 35, 42, 46, 47, 48, 49, 58, 64, 65, 66, 67, 75, 76, 77, 78, 79, 80, 81, 85, 95, 96, 102, 105, 108, 119, 120, 121, 122, 123], "get": [0, 1, 2, 3, 7, 9, 10, 12, 14, 24, 33, 34, 36, 44, 47, 60, 64, 66, 67, 68, 69, 71, 75, 78, 79, 85, 87, 88, 90, 91, 94, 95, 96, 97, 99, 103, 108, 109, 110, 111, 113, 115, 118, 119, 123], "start": [0, 2, 3, 7, 8, 14, 15, 21, 23, 28, 35, 41, 42, 43, 46, 54, 58, 65, 67, 69, 70, 77, 78, 79, 81, 82, 85, 88, 94, 95, 96, 102, 103, 105, 108, 110, 114, 115, 118, 119, 122, 123], "other": [0, 3, 5, 7, 8, 9, 10, 11, 12, 14, 15, 20, 21, 22, 24, 25, 26, 27, 28, 34, 35, 42, 43, 44, 45, 47, 49, 56, 57, 58, 60, 64, 65, 66, 67, 68, 69, 71, 75, 78, 79, 80, 84, 85, 87, 91, 94, 102, 103, 105, 108, 110, 112, 113, 114, 115, 118, 119, 120, 122], "space": [0, 7, 11, 12, 14, 15, 43, 45, 57, 59, 61, 63, 64, 65, 66, 75, 78, 79, 81, 85, 86, 88, 89, 90, 113, 115, 120], "new": [0, 3, 7, 9, 11, 12, 13, 21, 27, 35, 57, 63, 71, 73, 74, 76, 78, 79, 81, 82, 85, 86, 87, 88, 89, 90, 91, 96, 101, 102, 105, 107, 108, 114, 119, 120, 122], "skill": [0, 3, 4, 7, 8, 21, 35, 64, 66, 67, 70, 80, 82, 110, 123], "idea": [0, 3, 7, 27, 103, 108, 118, 120], "person": [0, 3, 6, 7, 34, 102], "life": [0, 3, 7, 11, 64, 102], "after": [0, 1, 3, 4, 7, 8, 9, 10, 13, 15, 18, 22, 23, 27, 28, 35, 36, 42, 49, 56, 66, 70, 85, 87, 88, 94, 96, 97, 98, 99, 103, 105, 109, 113, 115, 118, 119], "cours": [0, 1, 2, 3, 4, 6, 7, 8, 10, 33, 35, 40, 43, 54, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "If": [0, 3, 20, 21, 22, 23, 24, 25, 27, 30, 33, 34, 35, 36, 42, 44, 56, 57, 58, 61, 64, 65, 66, 68, 69, 70, 74, 75, 76, 84, 85, 87, 90, 93, 94, 95, 96, 97, 98, 99, 102, 103, 105, 110, 115, 118, 119, 120, 122, 123], "would": [0, 1, 3, 7, 8, 10, 12, 20, 25, 35, 43, 44, 45, 46, 48, 49, 50, 57, 60, 61, 64, 65, 67, 68, 71, 79, 85, 86, 88, 90, 91, 93, 94, 95, 96, 98, 101, 102, 103, 105, 108, 109, 110, 111, 114, 115, 119, 120, 121, 123], "like": [0, 3, 9, 10, 11, 20, 25, 35, 42, 44, 45, 48, 50, 56, 58, 59, 64, 65, 69, 74, 79, 80, 81, 84, 85, 87, 89, 91, 93, 94, 97, 98, 99, 101, 102, 103, 105, 109, 113, 114, 115, 118, 119, 120, 122, 123], "continu": [0, 1, 3, 12, 23, 33, 48, 58, 65, 90, 95, 96, 102, 103, 120, 121], "two": [0, 1, 3, 7, 8, 9, 10, 15, 21, 24, 25, 28, 33, 35, 42, 43, 44, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 75, 77, 78, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 101, 102, 103, 105, 108, 109, 110, 113, 114, 115, 118, 119, 120, 122], "week": [0, 1, 3, 9, 28, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122], "encourag": [0, 3, 5, 6, 7, 8, 10, 12, 14, 23, 67, 71, 89, 90, 121], "scholar": [0, 3], "program": [0, 5, 6, 11, 15, 28, 52, 65, 69, 73, 105, 122], "veri": [1, 3, 7, 12, 14, 15, 23, 25, 42, 43, 45, 50, 59, 64, 65, 66, 67, 69, 70, 71, 74, 76, 77, 88, 89, 90, 94, 96, 102, 115, 120], "short": [1, 3, 7, 14, 15, 28, 57, 74, 102, 111], "period": [1, 3, 10, 12, 14, 15, 22, 34, 42, 43, 46, 47, 49, 50, 56, 57, 58, 60, 61, 65, 67, 68, 69, 70, 71, 74, 75, 77, 78, 79, 82, 87, 91, 94, 95, 96, 97, 98, 99, 102, 109, 112, 114, 115], "time": [1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20, 22, 25, 28, 30, 34, 43, 45, 46, 47, 48, 49, 50, 57, 58, 59, 61, 64, 65, 66, 68, 69, 70, 74, 75, 76, 77, 79, 80, 81, 85, 88, 90, 91, 94, 96, 97, 98, 99, 101, 102, 105, 109, 112, 113, 114, 118, 119, 120, 121, 122, 123], "scientif": [1, 3, 7, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 47, 54, 85, 86, 87, 88, 99, 113, 118, 119, 123], "discoveri": [1, 4, 27], "To": [1, 3, 9, 10, 11, 21, 24, 26, 34, 35, 36, 42, 43, 45, 46, 47, 49, 50, 56, 57, 58, 60, 61, 64, 65, 66, 67, 68, 69, 71, 75, 76, 77, 78, 79, 80, 81, 87, 88, 89, 90, 91, 94, 95, 96, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "take": [1, 3, 6, 7, 8, 9, 10, 11, 12, 15, 18, 20, 21, 22, 23, 28, 34, 35, 43, 44, 46, 47, 48, 50, 56, 57, 58, 59, 60, 61, 64, 66, 67, 68, 69, 71, 74, 75, 78, 79, 80, 81, 86, 89, 90, 91, 94, 95, 97, 98, 99, 102, 103, 105, 108, 109, 111, 112, 113, 115, 118, 119, 120, 123], "project": [1, 7, 8, 17, 18, 21, 23, 34, 36, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 81, 82, 91, 93, 95, 96, 101, 102, 103, 105, 113, 115, 122, 123], "next": [1, 3, 20, 26, 27, 34, 35, 36, 42, 43, 44, 45, 47, 56, 57, 58, 59, 65, 66, 67, 68, 69, 70, 71, 74, 76, 77, 78, 80, 81, 89, 90, 91, 94, 99, 108, 109, 110, 113, 115, 118, 119, 120], "level": [1, 2, 3, 11, 12, 14, 15, 26, 44, 46, 58, 61, 64, 65, 67, 80, 82, 89, 90, 91, 94, 95, 96, 97, 101, 102, 108, 112, 113, 114, 118, 119, 120, 121], "collabor": [1, 3, 34], "2i2c": [1, 35], "abl": [1, 3, 9, 20, 21, 22, 23, 24, 25, 26, 27, 35, 43, 49, 56, 57, 58, 59, 64, 65, 66, 67, 68, 70, 74, 75, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 108, 111, 112, 113, 114, 115, 118, 119, 120, 123], "select": [1, 3, 4, 7, 9, 10, 12, 13, 15, 21, 36, 44, 46, 49, 58, 59, 64, 65, 66, 67, 68, 69, 70, 71, 75, 85, 91, 94, 96, 102, 103, 105, 109, 113, 115, 119, 120, 121, 123], "student": [1, 2, 3, 4, 5, 6, 7, 8, 13, 28, 33, 43, 58, 66, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 102, 123], "group": [1, 2, 3, 4, 6, 7, 8, 12, 13, 15, 20, 21, 27, 28, 34, 35, 36, 46, 47, 56, 64, 65, 67, 76, 78, 81, 91, 94, 103, 107, 112, 115, 119], "comput": [1, 3, 9, 10, 12, 14, 15, 22, 36, 40, 42, 43, 45, 54, 55, 57, 59, 60, 64, 65, 67, 68, 69, 70, 78, 79, 80, 81, 87, 90, 91, 94, 95, 101, 102, 103, 105, 107, 108, 109, 110, 111, 113, 114, 118, 119, 120], "5": [1, 9, 10, 11, 12, 13, 14, 15, 18, 20, 21, 23, 25, 26, 30, 42, 50, 56, 57, 58, 59, 61, 65, 66, 67, 69, 70, 74, 75, 76, 77, 79, 80, 81, 82, 85, 86, 87, 88, 90, 91, 94, 95, 97, 99, 102, 103, 108, 109, 110, 111, 113, 114, 115, 118, 120, 121, 122, 123], "month": [1, 3, 9, 15, 21, 46, 47, 48, 56, 57, 58, 67, 68, 69, 70, 71, 75, 91, 94, 95, 120], "end": [1, 3, 8, 9, 15, 20, 21, 22, 23, 24, 25, 26, 27, 33, 44, 46, 56, 57, 58, 59, 64, 65, 66, 68, 69, 70, 71, 74, 75, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 121], "part": [1, 3, 5, 6, 8, 9, 10, 11, 13, 14, 19, 21, 23, 28, 33, 40, 58, 67, 68, 75, 82, 85, 88, 89, 90, 94, 98, 99, 102, 105, 111, 113, 114, 115, 118, 123], "thank": 1, "our": [1, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "partnership": [1, 8, 11], "fresh": [1, 59], "ey": [1, 7, 64, 71, 105], "cmip": [1, 9, 10, 11, 13, 14, 91, 94, 95, 96, 97, 98, 99], "have": [1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 15, 18, 19, 21, 22, 24, 25, 27, 28, 30, 32, 34, 35, 36, 42, 43, 44, 45, 46, 47, 49, 55, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 77, 78, 80, 81, 82, 85, 86, 87, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 111, 113, 114, 115, 118, 119, 120, 121, 122, 123], "showcas": [1, 3, 5, 64, 65], "feedback": [1, 3, 14, 21, 28, 39, 40, 42, 49, 65, 87, 95, 102], "experienc": [1, 3, 27, 64, 115], "research": [1, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 34, 52, 63, 64, 65, 67, 73, 81, 87, 96, 103, 107, 113, 122, 123], "similar": [1, 3, 15, 42, 47, 50, 56, 59, 60, 61, 64, 65, 71, 76, 77, 78, 81, 89, 90, 91, 94, 102, 105, 109, 113, 115, 118, 120], "each": [1, 3, 4, 6, 7, 9, 10, 11, 12, 13, 14, 15, 21, 24, 25, 28, 32, 34, 35, 42, 44, 46, 47, 48, 50, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "submit": [1, 3, 27], "ani": [1, 3, 6, 7, 8, 9, 10, 12, 13, 15, 21, 25, 28, 35, 36, 42, 43, 44, 49, 50, 57, 64, 65, 70, 84, 85, 86, 87, 89, 90, 94, 97, 98, 99, 105, 109, 111, 113, 115, 118, 119, 120, 122, 123], "size": [1, 3, 15, 45, 46, 47, 48, 50, 56, 64, 66, 67, 68, 69, 75, 76, 78, 89, 90, 91, 95, 102, 103, 105, 108, 109, 110, 111, 113, 114, 115, 119, 120], "understand": [1, 3, 7, 9, 10, 11, 12, 15, 18, 20, 22, 24, 25, 26, 27, 40, 42, 46, 47, 48, 49, 56, 57, 60, 64, 65, 66, 69, 70, 74, 75, 77, 78, 81, 82, 85, 86, 88, 89, 90, 95, 98, 102, 103, 105, 108, 110, 112, 118, 119, 120, 121, 122, 123], "member": [1, 6, 9, 11, 21, 35, 81, 85, 87, 94, 97, 98, 99, 108, 119], "dedic": [1, 3, 21, 35, 123], "eventu": [1, 59, 120], "public": [1, 7, 8, 10, 11, 14, 27, 35, 65, 71, 75, 91, 94, 95, 96, 97, 98, 99, 103, 118, 121], "should": [1, 3, 8, 12, 13, 28, 30, 35, 36, 45, 56, 58, 59, 65, 66, 70, 71, 77, 79, 85, 86, 90, 93, 95, 102, 103, 105, 119, 121, 123], "acknowledg": [1, 103], "all": [1, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 18, 23, 24, 25, 28, 35, 36, 42, 43, 44, 45, 46, 47, 50, 56, 57, 58, 59, 64, 65, 66, 67, 68, 69, 71, 74, 75, 76, 78, 79, 81, 82, 85, 86, 87, 89, 90, 91, 94, 95, 97, 98, 99, 101, 102, 103, 105, 108, 109, 113, 115, 119, 120, 123], "contribut": [1, 3, 7, 10, 12, 13, 21, 58, 60, 61, 63, 65, 82, 85, 86, 88, 91, 95, 96, 98, 101, 102, 103, 105, 107, 113, 118, 119], "made": [1, 21, 44, 60, 65, 70, 71, 76, 79, 80, 88, 90, 103, 105, 109, 120, 122], "dure": [1, 3, 4, 5, 7, 8, 10, 13, 21, 27, 28, 40, 45, 53, 58, 61, 64, 65, 67, 68, 69, 70, 75, 76, 77, 78, 79, 82, 88, 90, 94, 96, 102, 109, 112, 113, 115, 120, 122, 123], "teach": [1, 2, 8, 28, 33, 118], "assist": [1, 2, 8, 28, 33, 64, 65, 123], "join": [1, 6, 9, 10, 11, 12, 13, 14, 15, 25, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 97, 99, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "team": [1, 3, 9, 12, 35, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "equal": [1, 7, 12, 44, 49, 60, 61, 64, 65, 86, 96, 97, 98, 99, 103, 110, 118], "thei": [1, 3, 4, 5, 7, 8, 9, 15, 27, 30, 33, 36, 44, 56, 58, 60, 64, 65, 67, 68, 70, 71, 74, 75, 78, 79, 81, 98, 101, 102, 103, 105, 109, 110, 111, 112, 113, 115, 119, 120, 121, 123], "mani": [1, 3, 7, 10, 11, 13, 15, 19, 21, 22, 43, 44, 64, 65, 67, 68, 74, 75, 79, 82, 85, 87, 88, 89, 91, 94, 97, 98, 99, 101, 102, 103, 105, 108, 109, 113, 118, 119, 120], "case": [1, 3, 11, 35, 42, 43, 44, 45, 46, 59, 63, 67, 74, 76, 77, 78, 81, 86, 90, 91, 102, 105, 108, 110, 111, 112, 113, 120], "success": [1, 3, 8, 64, 118], "juli": [1, 3, 6, 9, 10, 46, 67, 94, 107, 122, 123], "27": [1, 14, 15, 61, 78, 86, 91, 105, 113, 115, 119, 120], "2023": [1, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122], "slot": [1, 3, 6, 7, 28, 30], "28": [1, 14, 64, 91, 105, 114, 115, 120], "upon": [1, 59, 60, 67, 68, 69, 70, 76, 120], "submiss": [1, 28, 56], "slide": [1, 3, 10, 11, 12, 13, 14, 15, 60, 85, 88, 94], "9": [1, 6, 9, 10, 11, 12, 13, 14, 15, 28, 56, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 85, 87, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "indic": [1, 9, 10, 15, 23, 43, 59, 64, 65, 66, 67, 68, 70, 75, 76, 77, 79, 86, 87, 91, 95, 99, 105, 109, 112, 114, 118, 119, 120], "number": [1, 10, 12, 14, 15, 36, 40, 45, 60, 64, 65, 66, 67, 68, 71, 74, 75, 78, 79, 80, 85, 86, 87, 89, 90, 98, 101, 102, 103, 105, 108, 109, 111, 113, 114, 118, 119, 120, 122, 123], "peopl": [1, 2, 3, 7, 8, 25, 27, 35, 102], "who": [1, 3, 7, 8, 10, 12, 20, 21, 22, 23, 24, 25, 26, 27, 33, 65, 103, 105, 123], "plan": [1, 3, 6, 18, 35, 64, 65, 105, 109], "extend": [1, 9, 34, 58, 60, 61, 65, 86, 87, 94, 102, 108, 111, 114, 115], "whether": [1, 3, 7, 61, 66, 70, 75, 78, 88, 90, 102, 103, 118, 120], "either": [1, 3, 22, 27, 46, 78, 87, 108, 120], "both": [1, 7, 9, 12, 13, 14, 15, 22, 23, 25, 26, 28, 42, 47, 49, 54, 56, 58, 59, 60, 61, 64, 65, 66, 71, 75, 78, 80, 81, 82, 86, 87, 89, 90, 91, 94, 95, 97, 98, 102, 103, 105, 107, 108, 110, 114, 115, 118, 119, 120], "so": [1, 3, 10, 11, 12, 13, 14, 35, 42, 44, 46, 48, 49, 50, 56, 57, 58, 59, 66, 67, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 89, 90, 91, 94, 95, 98, 102, 103, 105, 111, 112, 113, 115, 118, 119, 120, 123], "pleas": [1, 3, 7, 9, 10, 11, 13, 14, 28, 31, 33, 34, 36, 49, 56, 58, 103, 105, 115, 119, 120, 123], "discuss": [1, 3, 4, 6, 14, 20, 21, 22, 23, 26, 27, 28, 42, 56, 57, 60, 68, 70, 71, 75, 78, 82, 85, 87, 90, 91, 94, 96, 98, 102, 103, 105, 107, 109, 111, 114, 119, 120, 121], "thi": [1, 2, 3, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 32, 33, 34, 35, 36, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "them": [1, 3, 4, 5, 7, 8, 11, 12, 14, 18, 25, 27, 30, 36, 48, 56, 58, 61, 64, 68, 71, 76, 77, 78, 79, 80, 85, 88, 102, 105, 108, 109, 110, 111, 118, 120, 121, 123], "befor": [1, 3, 7, 15, 24, 25, 35, 42, 58, 67, 68, 74, 76, 77, 79, 82, 85, 89, 90, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 109, 111, 113, 114, 115, 118, 119, 120, 121, 122, 123], "form": [1, 2, 3, 11, 14, 15, 17, 33, 40, 44, 58, 60, 64, 67, 74, 75, 85, 86, 99, 103, 118, 123], "access": [1, 3, 7, 9, 10, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 34, 35, 44, 52, 56, 58, 59, 60, 61, 65, 68, 69, 70, 71, 75, 79, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 113, 115, 118, 119, 120, 121, 123], "until": [1, 7, 35, 57, 61, 67, 71, 85, 88, 89, 90, 91, 102, 103, 113], "ground": [1, 11, 12, 113], "propos": [1, 3, 28, 103], "solid": [1, 65], "preliminari": [1, 23], "analysi": [1, 3, 9, 10, 11, 14, 17, 18, 20, 21, 23, 26, 27, 45, 48, 49, 54, 56, 57, 58, 65, 66, 67, 69, 74, 75, 77, 80, 81, 107, 108, 112, 113, 118, 119, 120], "august": [1, 67], "31": [1, 71, 80, 105, 113, 115], "detail": [1, 3, 13, 14, 43, 48, 56, 57, 64, 71, 75, 78, 79, 81, 85, 87, 89, 99, 102, 103, 105, 113, 122, 123], "The": [1, 2, 3, 6, 7, 8, 10, 11, 12, 13, 14, 15, 18, 21, 25, 26, 28, 35, 39, 43, 44, 45, 46, 48, 49, 50, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 81, 82, 84, 86, 88, 89, 90, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "post": [1, 3, 14, 15, 27, 65, 102, 105], "here": [1, 3, 7, 9, 11, 12, 13, 14, 15, 20, 21, 22, 23, 25, 26, 27, 28, 31, 36, 42, 43, 44, 48, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 78, 79, 80, 81, 82, 85, 87, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "soon": [1, 123], "strongest": [1, 56, 58, 79, 80], "directli": [1, 3, 9, 12, 26, 34, 65, 66, 68, 71, 74, 75, 87, 88, 90, 94, 102, 113, 119, 120], "build": [1, 10, 42, 54, 56, 68, 69, 71, 89, 90, 118, 119, 120, 121, 123], "support": [1, 3, 5, 7, 8, 9, 18, 22, 44, 59, 61, 64, 65, 74, 94, 97, 105, 114, 119, 122, 123], "analys": [1, 3, 10, 11, 13, 24, 25, 26, 27, 28, 43, 58, 59, 68, 78, 102, 115, 122], "conduct": [1, 9, 10, 11, 13, 14, 21, 33, 102, 105, 113, 115, 123], "follow": [1, 3, 5, 7, 9, 10, 11, 12, 14, 15, 22, 25, 28, 36, 42, 44, 45, 46, 56, 57, 58, 59, 66, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 87, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 110, 111, 112, 115, 118, 119, 120, 121, 122, 123], "clear": [1, 3, 42, 66, 67, 86, 102, 105], "focu": [1, 3, 9, 10, 12, 18, 40, 49, 55, 58, 65, 67, 68, 69, 71, 76, 79, 88, 95, 96, 99, 102, 105, 108, 109, 122], "phenomenon": [1, 3, 17, 21, 22, 23, 56, 69, 75, 112], "its": [1, 2, 3, 7, 10, 11, 13, 14, 21, 24, 27, 28, 34, 42, 56, 59, 64, 67, 70, 71, 74, 75, 76, 79, 86, 87, 88, 89, 91, 94, 96, 98, 99, 102, 103, 105, 108, 109, 110, 115, 118, 119, 120], "review": [1, 3, 9, 10, 11, 12, 13, 14, 15, 17, 18, 20, 22, 23, 24, 25, 26, 27, 28, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "roll": [1, 48, 56, 69], "basi": [1, 3, 12, 13, 28, 85, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 113], "aim": [1, 3, 4, 64, 95, 101, 105], "back": [1, 3, 9, 11, 14, 17, 25, 27, 42, 44, 46, 47, 67, 75, 76, 82, 86, 88, 91, 99, 102, 109], "within": [1, 3, 7, 14, 15, 21, 22, 39, 40, 42, 43, 46, 49, 53, 54, 56, 57, 58, 59, 64, 65, 71, 74, 75, 78, 85, 88, 89, 91, 94, 97, 98, 101, 102, 103, 105, 108, 109, 112, 113, 115, 119], "decemb": [1, 46, 67], "invit": [1, 3, 6, 35], "present": [1, 7, 8, 11, 19, 21, 23, 25, 27, 28, 40, 44, 46, 47, 49, 57, 59, 64, 65, 66, 67, 71, 74, 75, 76, 77, 78, 79, 82, 88, 101, 102, 103, 105, 114, 115, 119], "workshop": [1, 82], "more": [1, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20, 22, 24, 25, 26, 27, 28, 33, 35, 42, 44, 45, 46, 49, 50, 56, 57, 58, 60, 61, 64, 65, 66, 67, 68, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 99, 101, 102, 103, 105, 107, 108, 109, 110, 112, 113, 115, 118, 119, 120, 121, 122, 123], "academ": [1, 7, 27], "stai": [1, 8, 88, 103, 113, 118], "tune": [1, 87, 90, 118], "been": [2, 3, 7, 12, 14, 15, 23, 34, 49, 61, 65, 69, 73, 78, 81, 87, 88, 91, 97, 98, 99, 102, 103, 105, 113, 115, 118, 119, 120], "match": [2, 3, 12, 23, 43, 46, 57, 66, 71, 89, 105], "base": [2, 3, 6, 7, 9, 10, 11, 12, 14, 15, 18, 21, 25, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 59, 60, 61, 65, 66, 67, 68, 69, 74, 75, 76, 77, 78, 79, 80, 82, 85, 86, 87, 88, 89, 91, 94, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 113, 114, 118, 119, 120, 122], "joint": [2, 15, 101, 103], "prefer": [2, 3, 34, 46, 114], "assign": [2, 3, 7, 56, 57, 78, 79, 82, 105, 109, 115, 118, 119], "seven": [2, 3, 70], "portal": [2, 15, 33, 65, 69], "s": [2, 3, 7, 9, 10, 11, 12, 13, 14, 15, 21, 22, 24, 25, 27, 28, 34, 35, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 54, 56, 57, 58, 59, 60, 61, 63, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 86, 87, 88, 89, 91, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "tell": [2, 3, 7, 28, 42, 66, 69, 70, 89, 90, 97, 102, 105, 109], "first": [2, 3, 7, 12, 18, 24, 28, 35, 40, 43, 44, 45, 46, 47, 48, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 87, 88, 89, 90, 91, 94, 95, 96, 97, 102, 103, 105, 108, 109, 110, 118, 119, 120], "In": [2, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 42, 43, 44, 45, 46, 47, 48, 49, 50, 54, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "section": [2, 3, 9, 13, 17, 21, 33, 36, 122, 123], "These": [2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 19, 28, 35, 43, 44, 46, 49, 57, 58, 59, 60, 61, 64, 65, 67, 70, 74, 75, 77, 78, 79, 88, 91, 101, 102, 103, 105, 109, 110, 113, 115, 118, 123], "includ": [2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 19, 20, 21, 22, 23, 24, 25, 26, 27, 39, 40, 44, 48, 56, 64, 65, 66, 67, 71, 74, 78, 81, 85, 86, 87, 88, 89, 90, 91, 94, 95, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 114, 115, 118, 119, 120, 122, 123], "brief": [2, 3, 15, 26, 57, 103], "background": [2, 3, 4, 7, 8, 11, 12, 13, 14, 15, 74, 75, 89, 90, 123], "introductori": [2, 3, 45, 74, 75, 78, 79], "video": [2, 3, 10, 11, 12, 13, 14, 15, 22, 32, 35, 42, 44, 45, 47, 48, 50, 57, 59, 60, 123], "except": [2, 3, 15, 28, 33, 74, 82, 89, 90, 98, 115, 120, 123], "heatwav": [2, 12, 64, 65, 66, 115, 118, 122], "enso": [2, 3, 50, 57, 64, 75], "precipit": [2, 3, 14, 46, 49, 50, 59, 65, 66, 69, 74, 78, 80, 81, 95, 102, 109, 111, 112, 113, 118, 119], "temperatur": [2, 3, 11, 12, 14, 20, 22, 24, 25, 26, 42, 43, 44, 45, 46, 49, 50, 54, 56, 58, 59, 61, 65, 67, 68, 69, 70, 71, 74, 75, 77, 78, 79, 80, 85, 87, 89, 90, 91, 94, 96, 97, 99, 101, 102, 103, 109, 112, 113, 114, 115, 118, 119], "map": [2, 3, 11, 14, 44, 45, 46, 49, 56, 58, 60, 61, 64, 67, 68, 69, 70, 71, 75, 76, 91, 95, 99, 103, 105, 118], "explor": [2, 3, 4, 5, 6, 21, 22, 23, 24, 28, 35, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 53, 54, 55, 56, 58, 60, 61, 64, 66, 67, 68, 69, 71, 74, 75, 76, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 98, 99, 103, 105, 107, 108, 109, 110, 111, 113, 118, 122], "notebook": [2, 3, 32, 34, 35, 40, 42, 56, 74, 75, 76, 77, 78, 79, 80, 81, 82, 105, 113, 120], "some": [2, 3, 7, 8, 12, 14, 18, 20, 21, 22, 25, 26, 27, 36, 40, 42, 44, 45, 46, 48, 49, 57, 58, 59, 61, 64, 65, 67, 74, 75, 76, 78, 80, 81, 86, 89, 90, 91, 94, 95, 96, 99, 102, 103, 105, 107, 109, 113, 115, 118, 119, 120, 123], "further": [2, 3, 7, 8, 23, 27, 40, 44, 56, 65, 66, 67, 68, 70, 75, 78, 79, 80, 85, 87, 99, 102, 103, 105, 112, 119], "read": [2, 3, 7, 21, 25, 27, 35, 44, 57, 61, 67, 70, 74, 75, 76, 78, 103, 105, 119, 123], "recommend": [2, 3, 12, 13, 21, 34, 35, 36, 65, 105, 123], "left": [2, 15, 25, 49, 56, 57, 58, 59, 74, 76, 77, 88, 94, 95, 99, 102, 103, 108, 110, 120], "side": [2, 25, 36, 44, 57, 58, 70, 75, 77, 81, 101, 103, 108], "panel": [2, 3, 12, 13, 25, 28, 68, 79, 85, 86, 94, 95, 99, 102, 107], "click": [2, 13, 20, 21, 22, 23, 25, 26, 27, 30, 31, 34, 35, 36, 42, 43, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "titl": [2, 3, 7, 10, 11, 12, 13, 14, 15, 25, 47, 56, 58, 59, 60, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "below": [2, 7, 9, 10, 11, 13, 14, 30, 43, 47, 48, 49, 50, 56, 57, 61, 64, 65, 66, 68, 69, 70, 75, 76, 79, 85, 86, 87, 88, 89, 90, 91, 94, 95, 97, 98, 99, 101, 102, 105, 110, 111, 113, 114, 115, 123], "sea": [2, 9, 11, 14, 22, 25, 26, 44, 45, 49, 54, 56, 57, 59, 60, 65, 69, 75, 82, 87, 88, 94, 96, 97, 99, 102, 112, 113, 114, 119], "rise": [2, 56, 65, 70, 81, 90, 102, 103, 112, 119], "region": [2, 3, 7, 8, 9, 10, 11, 13, 14, 15, 35, 36, 43, 44, 45, 46, 49, 50, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 77, 80, 87, 88, 90, 91, 94, 95, 97, 99, 103, 105, 115, 118, 123], "variabl": [2, 3, 9, 10, 11, 13, 15, 24, 25, 26, 40, 41, 43, 44, 45, 46, 47, 48, 56, 58, 59, 60, 63, 64, 65, 66, 67, 68, 71, 74, 76, 77, 78, 79, 81, 82, 89, 90, 91, 94, 95, 96, 97, 102, 103, 108, 109, 110, 111, 112, 113, 114, 115, 118, 120, 123], "extrem": [2, 10, 15, 21, 28, 64, 65, 103, 107, 108, 111, 112, 114, 115, 118, 120, 122], "event": [2, 6, 9, 10, 15, 21, 28, 30, 53, 54, 64, 65, 69, 70, 75, 103, 105, 107, 110, 111, 112, 113, 114, 115, 118, 120, 122], "chang": [2, 3, 7, 8, 9, 10, 11, 12, 13, 15, 20, 26, 34, 36, 40, 44, 45, 46, 47, 49, 50, 53, 54, 56, 57, 58, 60, 63, 64, 66, 67, 68, 69, 70, 73, 74, 78, 79, 80, 81, 82, 85, 89, 90, 91, 94, 95, 96, 97, 99, 101, 102, 103, 105, 107, 109, 110, 111, 112, 115, 118, 119, 120, 121, 122], "earth": [2, 6, 7, 10, 11, 12, 13, 14, 15, 20, 22, 25, 39, 40, 41, 42, 43, 44, 45, 47, 54, 56, 57, 58, 61, 63, 64, 66, 68, 69, 73, 74, 77, 80, 81, 82, 86, 87, 88, 89, 95, 99, 102, 115, 123], "albedo": [2, 49, 64, 87, 89, 90, 91], "depend": [2, 3, 14, 15, 20, 46, 58, 59, 61, 64, 67, 74, 75, 87, 89, 90, 91, 95, 97, 98, 99, 101, 102, 103, 105, 114, 118, 120, 123], "land": [2, 15, 45, 55, 57, 60, 61, 65, 66, 67, 68, 70, 71, 74, 75, 76, 80, 87, 88, 91, 94, 115, 118], "cover": [2, 10, 12, 15, 56, 57, 64, 65, 66, 67, 68, 78, 91, 95, 113, 115, 118, 120, 122, 123], "past": [2, 3, 13, 26, 40, 47, 49, 57, 74, 78, 79, 80, 81, 82, 94, 95, 99, 102, 107, 113, 118, 122], "20": [2, 3, 12, 13, 14, 15, 27, 59, 63, 65, 67, 71, 74, 78, 79, 85, 86, 87, 89, 90, 91, 105, 109, 110, 111, 113, 114, 115, 118, 119, 120], "year": [2, 3, 8, 9, 12, 13, 14, 15, 21, 26, 46, 56, 57, 58, 59, 61, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 87, 88, 94, 95, 96, 97, 98, 99, 101, 102, 103, 108, 109, 110, 111, 112, 113, 114, 115, 119], "monitor": [2, 7, 10, 11, 12, 14, 63, 64, 67, 70, 115, 122], "wildfir": [2, 64, 122], "satellit": [2, 11, 12, 57, 63, 67, 68, 69, 70, 75, 118, 120], "ocean": [2, 12, 13, 14, 22, 25, 28, 39, 40, 45, 47, 50, 52, 53, 55, 57, 58, 60, 65, 66, 67, 68, 71, 74, 77, 79, 80, 87, 91, 94, 95], "acidif": [2, 52], "assess": [2, 3, 11, 12, 13, 14, 15, 43, 44, 45, 47, 49, 50, 59, 65, 66, 71, 76, 77, 78, 79, 81, 82, 85, 88, 95, 102, 105, 107, 108, 110, 111, 113, 114, 115, 119, 122], "dynam": [2, 14, 54, 57, 58, 60, 64, 75, 90, 96, 102, 103, 119, 123], "interact": [2, 6, 9, 22, 32, 34, 35, 36, 42, 45, 54, 55, 57, 58, 64, 66, 67, 70, 71, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "atmospher": [2, 9, 12, 13, 15, 20, 22, 28, 39, 40, 44, 47, 50, 53, 54, 55, 57, 60, 61, 65, 66, 67, 69, 80, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 118, 122], "compon": [3, 10, 11, 12, 14, 28, 39, 40, 41, 44, 45, 46, 58, 59, 60, 64, 65, 67, 85, 86, 87, 89, 90, 91, 94, 102, 103, 114], "design": [3, 7, 12, 14, 15, 20, 21, 22, 23, 36, 64, 65, 75, 79, 93, 99, 102, 103, 109, 120, 123], "through": [3, 9, 14, 18, 20, 21, 22, 23, 24, 27, 44, 45, 49, 55, 56, 57, 60, 61, 64, 65, 68, 69, 71, 78, 79, 81, 82, 85, 87, 88, 89, 90, 91, 95, 96, 98, 101, 102, 103, 105, 108, 109, 113, 115, 118, 119, 120, 122, 123], "entir": [3, 10, 35, 56, 57, 59, 61, 64, 67, 68, 71, 76, 86, 105, 115], "process": [3, 7, 10, 11, 12, 14, 17, 18, 20, 22, 23, 24, 25, 26, 27, 39, 40, 41, 42, 45, 47, 48, 57, 58, 59, 64, 65, 66, 67, 68, 69, 70, 71, 79, 80, 81, 82, 85, 87, 90, 91, 94, 95, 99, 101, 103, 105, 109, 111, 114, 115, 119, 121, 123], "comprehens": [3, 10, 15, 21, 57, 64, 65, 69, 85, 86, 112, 119, 123], "journei": [3, 108], "ideat": 3, "outcom": [3, 68, 113, 118, 119, 120], "condens": [3, 21, 91], "frame": [3, 74, 90, 105, 109, 112], "just": [3, 4, 9, 10, 12, 13, 23, 28, 35, 42, 44, 45, 49, 50, 56, 57, 58, 59, 60, 61, 64, 66, 67, 68, 69, 70, 71, 74, 76, 78, 79, 80, 81, 86, 88, 89, 90, 91, 94, 98, 101, 102, 103, 105, 109, 112, 118, 119, 120, 123], "three": [3, 6, 7, 10, 11, 13, 15, 34, 36, 58, 64, 65, 67, 68, 69, 75, 76, 80, 85, 87, 90, 91, 95, 97, 99, 102, 110, 111, 112, 113, 115, 118, 120], "fellow": 3, "collect": [3, 7, 10, 11, 12, 15, 21, 64, 65, 67, 74, 76, 89, 91, 105, 113, 118, 120, 123], "singl": [3, 9, 10, 11, 14, 22, 34, 43, 44, 45, 46, 56, 57, 65, 67, 69, 74, 76, 82, 87, 89, 90, 91, 94, 96, 105, 109, 110, 119, 120], "On": [3, 7, 28, 80, 89, 110, 119], "good": [3, 7, 12, 15, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 70, 71, 79, 103, 110, 118, 119, 122, 123], "mock": 3, "len": [3, 7, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 27, 47, 48, 57, 67, 74, 99, 102, 105, 109, 114, 115, 119, 120], "equiti": [3, 8, 19, 20, 22, 23, 24, 28], "eight": 3, "those": [3, 4, 7, 11, 13, 25, 34, 43, 45, 47, 49, 58, 60, 68, 74, 78, 79, 87, 88, 97, 98, 99, 102, 103, 105, 109, 111, 119, 120, 122, 123], "geograph": [3, 12, 44, 56, 64, 67, 70, 71, 75, 103], "interest": [3, 4, 5, 10, 11, 12, 14, 15, 22, 36, 42, 43, 44, 49, 56, 58, 64, 65, 66, 67, 68, 70, 71, 75, 79, 82, 88, 91, 102, 105, 113, 119, 121], "teammat": [3, 36], "familiar": [3, 24, 34, 44, 54, 65, 75, 79, 89, 91, 94, 103, 123], "yourselv": 3, "dataset": [3, 10, 11, 12, 17, 18, 22, 35, 40, 43, 45, 46, 47, 48, 49, 50, 54, 56, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 75, 76, 79, 81, 82, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 115], "hand": [3, 49, 65, 119], "examin": [3, 10, 43, 54, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 69, 70, 71, 82, 89, 96, 99, 102, 103, 105, 108, 112, 114, 115, 120], "spatial": [3, 10, 11, 12, 14, 15, 22, 41, 42, 43, 44, 45, 49, 50, 56, 58, 63, 65, 66, 67, 68, 69, 74, 81, 82, 91, 94, 95, 102, 103, 120], "tempor": [3, 11, 12, 15, 22, 25, 41, 43, 45, 48, 49, 57, 59, 61, 64, 65, 68, 74, 79, 81, 96, 103, 115], "distribut": [3, 9, 11, 49, 58, 65, 70, 74, 79, 81, 94, 97, 103, 105, 109, 112, 113, 114, 115, 118, 119, 120, 123], "global": [3, 7, 9, 10, 13, 21, 22, 25, 26, 43, 44, 45, 46, 47, 48, 49, 50, 54, 56, 57, 58, 60, 61, 63, 64, 65, 67, 69, 70, 71, 74, 76, 78, 79, 81, 82, 85, 86, 87, 89, 90, 91, 94, 96, 97, 98, 102, 103, 105, 107, 112, 113, 114, 115, 118], "local": [3, 9, 10, 13, 21, 30, 34, 35, 44, 59, 64, 94, 105, 112, 120], "scale": [3, 11, 12, 14, 25, 41, 45, 53, 54, 55, 57, 58, 59, 60, 61, 64, 67, 68, 70, 71, 79, 80, 81, 89, 94, 95, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 122], "social": [3, 7, 27, 65, 103, 105], "perform": [3, 21, 42, 43, 44, 57, 58, 65, 66, 67, 68, 69, 71, 78, 79, 80, 81, 91, 105, 111, 115, 118, 123], "literatur": [3, 17, 18, 20, 22, 23, 26, 28, 107, 119], "sens": [3, 7, 12, 14, 15, 24, 28, 55, 60, 63, 65, 66, 67, 68, 69, 70, 71, 79, 89, 91, 103, 110, 113, 118, 122], "open": [3, 8, 9, 10, 12, 14, 21, 22, 27, 28, 30, 34, 35, 36, 42, 45, 57, 63, 65, 66, 67, 68, 71, 75, 77, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 105, 109, 110, 122], "field": [3, 4, 5, 6, 7, 8, 10, 14, 21, 44, 58, 59, 64, 65, 95, 103, 119], "devis": 3, "specif": [3, 4, 7, 8, 10, 12, 13, 14, 21, 22, 25, 26, 27, 34, 36, 43, 44, 45, 46, 47, 48, 49, 56, 57, 59, 61, 64, 65, 66, 68, 69, 70, 74, 75, 76, 77, 81, 82, 87, 89, 90, 91, 97, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 115, 118, 119, 120, 121], "testabl": [3, 17, 20, 21, 22, 23], "hypothesi": [3, 17, 18, 20, 21, 22, 24, 25, 26, 27, 105], "accordingli": [3, 14], "swap": [3, 28, 44], "receiv": [3, 36, 71, 85, 88, 103, 105, 120], "For": [3, 7, 9, 10, 11, 12, 13, 14, 15, 20, 22, 24, 26, 27, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 57, 58, 60, 64, 65, 66, 67, 68, 69, 70, 74, 75, 78, 79, 80, 81, 85, 87, 88, 89, 91, 94, 95, 96, 97, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "rest": [3, 14, 65, 91, 95, 101, 103], "evid": [3, 22, 26, 45, 49, 67], "against": [3, 14, 44, 59, 67, 71, 78, 98, 99, 103, 109, 110, 111, 118, 119, 120], "throughout": [3, 40, 46, 54, 58, 67, 74, 75, 78, 85, 90, 91, 102, 123], "last": [3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 28, 34, 43, 44, 49, 50, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 82, 85, 86, 87, 88, 89, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "prepar": [3, 8, 9, 28, 102, 122, 123], "stori": [3, 11], "meet": [3, 7, 28, 64, 65, 66, 102, 105, 123], "megapod": 3, "list": [3, 10, 12, 14, 15, 25, 42, 57, 61, 65, 66, 67, 68, 71, 74, 75, 76, 81, 85, 86, 87, 91, 96, 97, 99, 101, 103, 105, 109, 111, 120, 123], "applic": [3, 12, 14, 15, 49, 55, 64, 65, 66, 67, 71, 78, 79, 91, 105, 110, 118, 120], "come": [3, 7, 25, 27, 42, 44, 48, 64, 65, 71, 74, 91, 94, 102, 103, 110, 119, 123], "templat": [3, 21, 75], "load": [3, 10, 11, 12, 13, 14, 15, 35, 42, 46, 47, 48, 49, 50, 56, 57, 58, 60, 61, 69, 74, 91, 98, 102, 111], "jupyt": [3, 36, 120, 123], "own": [3, 5, 7, 8, 12, 17, 18, 21, 23, 35, 65, 69, 87, 94, 109, 115, 119, 121, 122, 123], "compos": 3, "green": [3, 14, 15, 64, 78, 102, 103, 105, 120], "yellow": [3, 15, 79], "red": [3, 12, 15, 56, 58, 59, 66, 69, 70, 71, 75, 82, 87, 88, 102, 103, 115, 118, 120], "accord": [3, 12, 22, 49, 85, 91, 120], "difficulti": [3, 8, 103], "divid": [3, 12, 61, 65, 69, 71, 75, 76, 95, 102, 105, 109, 119], "relat": [3, 4, 5, 6, 8, 10, 15, 21, 46, 54, 56, 60, 64, 65, 68, 70, 78, 79, 80, 87, 88, 91, 94, 96, 97, 102, 103, 105, 107, 109, 111, 118, 119, 120, 121], "borderless": 3, "issu": [3, 7, 11, 12, 43, 56, 64, 66, 68, 78, 90, 94, 95, 98, 102, 105, 115, 119], "dash": [3, 9, 10, 11, 12, 13, 14, 15, 69, 70, 82, 88, 102, 103], "border": 3, "sever": [3, 8, 9, 13, 14, 15, 22, 33, 48, 56, 57, 58, 64, 65, 67, 78, 79, 80, 81, 85, 88, 94, 96, 102, 103, 109, 112, 115, 121], "wai": [3, 7, 8, 9, 10, 11, 14, 24, 27, 42, 43, 44, 56, 57, 59, 60, 61, 71, 75, 78, 79, 81, 82, 86, 87, 88, 89, 91, 94, 95, 102, 103, 110, 113, 114, 118, 119, 120, 123], "must": [3, 9, 10, 22, 36, 43, 44, 59, 66, 67, 79, 89, 91, 94, 95, 96, 97, 98, 99], "let": [3, 24, 25, 36, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 66, 67, 68, 70, 71, 75, 76, 77, 78, 79, 80, 81, 82, 86, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "relev": [3, 4, 8, 15, 21, 27, 68, 75, 76, 89, 90, 91, 101, 103, 105, 113, 119, 120, 121], "appreci": [3, 8, 64, 118], "box": [3, 9, 10, 11, 12, 13, 14, 15, 85, 94, 95, 99, 113, 115], "addit": [3, 7, 9, 10, 11, 14, 15, 21, 28, 41, 47, 48, 49, 55, 56, 60, 61, 64, 66, 67, 68, 70, 74, 75, 78, 79, 94, 99, 101, 102, 103, 105, 113, 118, 119, 120, 123], "highli": [3, 64, 75, 123], "consid": [3, 7, 11, 21, 27, 44, 45, 46, 49, 56, 58, 60, 64, 65, 82, 85, 89, 90, 91, 95, 99, 101, 102, 103, 109, 112, 113, 115, 118, 120], "advis": [3, 119], "conclus": [3, 18, 21, 24, 25, 26, 119], "possibl": [3, 10, 19, 43, 45, 65, 75, 78, 89, 102, 105, 109, 111, 113, 114, 118, 119, 120, 123], "sourc": [3, 7, 11, 13, 14, 15, 25, 36, 41, 42, 47, 57, 58, 59, 64, 65, 67, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 87, 94, 98, 102, 122], "report": [3, 12, 13, 14, 63, 68, 86, 87, 95, 99, 102, 107, 113], "studi": [3, 8, 10, 12, 20, 21, 22, 23, 25, 54, 56, 64, 65, 66, 68, 75, 76, 78, 81, 101, 105, 107, 119, 122, 123], "trustworthi": 3, "countri": [3, 7, 12, 15, 96], "contin": [3, 15, 45, 58], "scienc": [3, 4, 6, 8, 12, 13, 14, 15, 18, 20, 21, 25, 26, 28, 36, 40, 52, 54, 57, 63, 64, 65, 73, 75, 77, 78, 89, 90, 98, 103, 105, 107, 111, 113, 118, 119, 120], "do": [3, 7, 8, 10, 12, 14, 17, 19, 22, 23, 24, 28, 34, 35, 36, 42, 43, 44, 45, 46, 47, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 81, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 102, 103, 105, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "lot": [3, 8, 23, 42, 45, 65, 66, 95, 98, 103, 105], "experi": [3, 4, 6, 7, 8, 9, 10, 14, 15, 21, 23, 27, 33, 35, 36, 58, 60, 61, 64, 67, 70, 78, 90, 91, 94, 98, 102, 103, 113, 115, 118, 119, 120, 123], "strongli": [3, 15, 70], "extens": [3, 7, 14, 21, 56, 57, 68, 69, 74, 85], "enough": [3, 64, 123], "structur": [3, 7, 15, 28, 40, 44, 55, 58, 65, 67, 75, 81, 86, 102, 103, 105, 115, 120], "option": [3, 4, 12, 21, 27, 36, 42, 43, 50, 56, 65, 75, 78, 81, 91, 105, 110, 114, 120, 123], "keep": [3, 7, 21, 36, 42, 50, 66, 70, 76, 86, 91, 94, 98, 99, 108, 118], "go": [3, 8, 9, 11, 13, 45, 46, 47, 48, 49, 56, 57, 66, 68, 71, 75, 76, 78, 79, 86, 89, 95, 96, 97, 98, 99, 111], "stick": [3, 87], "achiev": [3, 7, 43, 56, 65, 71, 78, 86, 102, 114, 120], "pick": [3, 9, 10, 25, 27, 74, 78, 95, 96, 97, 99, 103, 105], "most": [3, 7, 9, 10, 11, 12, 13, 14, 15, 42, 49, 57, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122], "right": [3, 7, 8, 13, 15, 25, 36, 49, 56, 57, 59, 65, 76, 77, 79, 81, 88, 95, 102, 103, 105, 108, 110, 119, 120, 123], "awai": [3, 7, 43, 80, 88, 90, 91], "without": [3, 9, 10, 14, 15, 27, 35, 44, 61, 65, 68, 75, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 114, 115, 120, 123], "flow": [3, 54, 59, 60, 74, 87, 102, 105], "suggest": [3, 15, 27, 61, 64, 71, 78, 79, 80, 102, 108, 114, 115, 119], "than": [3, 7, 9, 10, 11, 12, 14, 15, 22, 24, 33, 43, 45, 47, 49, 50, 56, 57, 58, 59, 60, 61, 65, 67, 68, 69, 70, 71, 74, 75, 77, 78, 79, 80, 82, 85, 88, 89, 90, 91, 95, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 113, 114, 115, 119, 120, 123], "branch": [3, 10], "out": [3, 4, 7, 9, 10, 11, 12, 13, 14, 15, 27, 28, 33, 34, 42, 43, 44, 47, 56, 65, 66, 68, 71, 78, 79, 86, 87, 89, 91, 96, 97, 98, 99, 102, 103, 107, 111, 113, 115, 118, 119, 120, 122, 123], "beyond": [3, 6, 11, 33, 42, 70, 87, 102, 103, 113], "howev": [3, 10, 14, 23, 24, 27, 35, 36, 43, 44, 49, 56, 57, 59, 60, 61, 64, 65, 67, 68, 70, 71, 78, 80, 81, 82, 89, 90, 94, 99, 102, 103, 109, 110, 112, 113, 114, 115, 118, 119, 121], "friendli": [3, 25], "expert": [3, 12, 113, 119], "consult": [3, 7, 21, 119], "brainstorm": [3, 119, 121], "search": [3, 9, 10, 11, 12, 14, 36, 43, 65, 66, 91, 94, 95, 96, 97, 98, 99, 105], "code": [3, 9, 10, 11, 12, 13, 14, 25, 32, 33, 34, 35, 36, 42, 44, 45, 46, 47, 48, 49, 50, 56, 60, 64, 65, 74, 75, 77, 79, 81, 82, 88, 91, 115, 121, 122, 123], "regular": [3, 14, 57, 65, 69, 91, 94, 99], "visit": [3, 8, 9, 10, 11, 13, 14, 57, 65, 89, 90], "make": [3, 4, 7, 8, 9, 10, 11, 14, 21, 24, 27, 33, 34, 36, 40, 43, 44, 48, 49, 50, 56, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 76, 79, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 99, 101, 102, 103, 105, 108, 110, 111, 113, 114, 115, 118, 119, 120, 121, 123], "subsequ": [3, 36, 102], "averag": [3, 9, 10, 12, 20, 22, 43, 44, 46, 47, 50, 56, 57, 58, 59, 60, 67, 68, 69, 70, 71, 78, 79, 82, 86, 87, 88, 89, 90, 91, 94, 96, 97, 98, 99, 103, 115, 119], "45": [3, 13, 28, 43, 57, 59, 89, 90, 91, 103, 105, 119], "60": [3, 14, 22, 42, 43, 58, 60, 61, 65, 78, 87, 88, 90, 91, 103, 105, 112], "minut": [3, 7, 11, 20, 22, 23, 26, 27, 28, 35, 57, 58, 61, 64, 67, 68, 69, 71, 74, 78, 80, 105, 115, 120], "As": [3, 6, 7, 10, 12, 15, 23, 42, 44, 45, 50, 56, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 77, 79, 82, 85, 87, 88, 90, 94, 95, 96, 99, 101, 103, 108, 110, 111, 113, 114, 115, 118, 119, 120, 123], "progress": [3, 105], "might": [3, 7, 8, 12, 18, 20, 22, 24, 36, 43, 44, 49, 50, 64, 65, 66, 67, 68, 74, 76, 78, 80, 81, 82, 89, 91, 95, 99, 102, 103, 105, 121], "priorit": [3, 7], "junior": 3, "summon": 3, "senior": [3, 6, 7], "when": [3, 4, 7, 8, 9, 10, 11, 12, 13, 18, 21, 22, 23, 28, 36, 42, 43, 46, 47, 49, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 77, 78, 85, 86, 87, 88, 89, 90, 91, 94, 96, 97, 102, 103, 105, 110, 111, 112, 115, 118, 119, 120], "sinc": [3, 9, 13, 14, 25, 34, 43, 44, 45, 49, 56, 57, 59, 60, 61, 64, 65, 66, 67, 68, 71, 75, 76, 77, 78, 80, 81, 82, 87, 88, 98, 101, 102, 103, 105, 109, 114, 115, 119], "arriv": [3, 103], "unannounc": 3, "busi": [3, 6, 105], "stop": [3, 43, 57, 102, 105], "what": [3, 5, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 20, 21, 22, 23, 26, 27, 35, 42, 43, 44, 46, 47, 48, 49, 50, 56, 58, 59, 61, 65, 66, 68, 69, 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 97, 99, 101, 102, 103, 105, 110, 111, 113, 115, 118, 119, 120, 121, 122, 123], "were": [3, 7, 11, 15, 25, 27, 42, 56, 58, 64, 65, 74, 79, 80, 82, 84, 87, 91, 94, 98, 102, 103, 105, 112, 114, 115, 118, 119, 120, 122], "resum": 3, "leav": [3, 64, 103, 115], "discord": [3, 28, 122, 123], "channel": [3, 15, 64, 66], "set": [3, 10, 12, 15, 20, 21, 22, 23, 24, 25, 26, 27, 36, 45, 56, 57, 58, 65, 74, 75, 76, 78, 79, 88, 101, 123], "asid": [3, 85], "necessari": [3, 7, 21, 22, 33, 35, 36, 64, 65, 66, 68, 120], "goal": [3, 7, 15, 18, 21, 23, 70, 93, 94, 97, 119], "simplifi": [3, 48, 81], "alreadi": [3, 7, 17, 23, 35, 42, 44, 46, 57, 58, 61, 65, 67, 68, 74, 78, 80, 88, 89, 90, 96, 102, 113, 115, 119, 120], "broken": [3, 78], "among": [3, 7, 58, 65, 71, 87, 105, 113], "reason": [3, 33, 56, 66, 71, 78, 82, 89, 90, 94, 102, 119], "becaus": [3, 7, 12, 24, 25, 27, 42, 43, 44, 45, 56, 58, 60, 65, 66, 68, 75, 77, 78, 79, 88, 89, 90, 91, 101, 102, 103, 105, 109, 113, 115, 119, 123], "share": [3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 25, 28, 35, 36, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 95, 99, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120, 121], "motiv": [3, 18, 103, 123], "vari": [3, 10, 13, 26, 46, 56, 58, 59, 60, 61, 64, 67, 79, 82, 85, 88, 91, 94, 95, 96, 98, 102, 103, 105, 110, 114, 115, 118, 119, 120, 123], "even": [3, 10, 21, 42, 44, 56, 57, 64, 75, 79, 88, 90, 91, 103, 105, 111, 120], "becom": [3, 27, 35, 44, 58, 66, 68, 75, 94, 103, 112, 114], "commun": [3, 6, 8, 9, 13, 14, 15, 17, 18, 21, 23, 24, 25, 26, 28, 33, 44, 45, 56, 64, 74, 77, 81, 89, 90, 94, 105, 121], "much": [3, 42, 43, 44, 47, 49, 58, 60, 61, 64, 68, 71, 78, 79, 80, 81, 85, 89, 90, 94, 96, 101, 102, 105, 109, 110, 111, 118, 119], "role": [3, 7, 14, 47, 49, 59, 60, 64, 81, 82, 98, 103, 109, 118, 119, 120], "pursu": 3, "second": [3, 18, 50, 54, 56, 64, 65, 78, 81, 85, 87, 88, 89, 90, 95, 109, 110, 113, 118, 120], "which": [3, 7, 9, 10, 11, 12, 13, 14, 15, 21, 25, 27, 35, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 87, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "implement": [3, 7, 11, 17, 18, 24, 26, 27, 28, 60, 65, 78, 89, 90, 95, 98, 102, 103, 111, 112, 114, 118, 120, 121], "interpret": [3, 15, 17, 18, 23, 24, 25, 27, 28, 39, 42, 43, 44, 45, 48, 50, 54, 55, 56, 64, 66, 76, 77, 78, 79, 80, 81, 82, 88, 98, 108, 119, 120, 122], "embed": [3, 74], "seri": [3, 6, 12, 13, 14, 25, 28, 45, 46, 48, 50, 61, 65, 66, 68, 69, 70, 74, 76, 77, 78, 79, 80, 81, 87, 96, 99, 101, 102, 103, 107, 108, 112, 114, 115, 118, 119, 120, 123], "talk": [3, 8, 18, 28, 105], "mentor": [3, 5, 28], "career": [3, 7, 8, 28], "mondai": 3, "17th": [3, 28, 123], "pm": [3, 28, 56, 69], "everyon": [3, 5, 7, 27, 35], "30": [3, 7, 9, 14, 15, 22, 28, 35, 50, 56, 57, 58, 60, 61, 64, 65, 67, 68, 69, 80, 82, 85, 89, 90, 91, 94, 105, 112, 113, 115, 119], "tutori": [3, 6, 9, 10, 11, 12, 13, 14, 15, 17, 18, 28, 35, 36, 39, 40, 84, 117, 122, 123], "same": [3, 7, 9, 10, 11, 14, 25, 34, 36, 43, 44, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 67, 68, 70, 71, 74, 75, 77, 78, 79, 81, 82, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 109, 112, 113, 114, 118, 119, 120], "while": [3, 8, 10, 12, 13, 15, 21, 32, 34, 35, 56, 58, 59, 61, 64, 65, 67, 69, 71, 74, 75, 78, 89, 90, 91, 94, 96, 101, 102, 103, 108, 109, 110, 114, 115, 118, 119, 120, 123], "differ": [3, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 18, 21, 23, 24, 25, 40, 42, 43, 44, 46, 47, 48, 49, 50, 54, 56, 58, 59, 60, 61, 65, 66, 67, 68, 69, 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 102, 105, 108, 109, 110, 111, 112, 114, 120, 121, 122], "wish": [3, 7, 8, 34, 42, 43, 49, 50, 71, 102], "inform": [3, 7, 8, 9, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 25, 26, 27, 28, 42, 44, 46, 48, 49, 63, 64, 65, 66, 67, 68, 71, 73, 74, 75, 76, 78, 79, 84, 89, 91, 99, 102, 103, 113, 114, 115, 118, 119, 120, 122], "watch": [3, 4, 7, 11, 12, 13, 14, 15, 28, 35, 47, 102, 123], "One": [3, 7, 13, 15, 35, 42, 44, 45, 60, 61, 64, 71, 74, 75, 82, 87, 89, 98, 102, 103, 110, 111, 115, 119, 120], "block": [3, 25, 42, 48, 66, 89], "facilit": [3, 14, 49, 61, 68], "lead": [3, 7, 10, 11, 14, 58, 59, 60, 65, 70, 71, 80, 87, 88, 90, 101, 102, 103, 112, 115], "front": [3, 7, 15], "behind": [3, 7, 18, 22, 27, 82, 102, 103, 119], "leadership": [3, 7], "least": [3, 7, 9, 25, 33, 65, 67, 69, 74, 103, 111, 120], "onc": [3, 12, 35, 44, 61, 65, 66, 81, 82, 89, 90, 91, 102, 109, 111, 118], "appoint": 3, "associ": [3, 6, 42, 46, 50, 68, 69, 70, 75, 78, 87, 97, 101, 102, 103, 105, 109, 111, 114, 115, 118, 119], "respons": [3, 8, 15, 46, 50, 56, 58, 59, 60, 64, 80, 81, 85, 87, 88, 95, 103, 105, 112, 122], "timezon": [3, 6], "tuesdai": [3, 6], "18th": 3, "am": [3, 22, 28], "point": [3, 21, 43, 44, 46, 47, 48, 56, 57, 60, 61, 64, 67, 68, 71, 74, 78, 88, 91, 103, 108, 109, 110, 111, 115, 118, 119, 120], "introduc": [3, 8, 18, 21, 27, 40, 57, 64, 65, 77, 79, 90, 94, 98, 101, 105, 111, 113, 114, 115, 123], "themselv": [3, 7, 8, 60], "wednesdai": 3, "19th": 3, "interview": [3, 4], "justic": [3, 8, 28], "prompt": [3, 8, 70], "15": [3, 6, 7, 10, 11, 13, 14, 15, 28, 42, 45, 46, 47, 49, 60, 61, 64, 65, 66, 67, 68, 70, 71, 74, 75, 76, 78, 80, 85, 86, 87, 89, 91, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "agre": [3, 7, 8, 13, 75, 88, 94, 99, 119], "decid": [3, 7, 44, 103, 120], "remain": [3, 21, 75, 91, 101, 102, 103, 105, 112, 113, 114, 115, 119], "dirti": 3, "try": [3, 10, 22, 23, 36, 42, 44, 47, 64, 74, 78, 94, 96, 97, 99, 108, 118, 119, 120, 121], "being": [3, 7, 8, 9, 10, 12, 21, 65, 69, 70, 75, 78, 79, 91, 94, 97, 102, 103, 105, 108, 111, 118], "done": [3, 7, 8, 25, 34, 42, 43, 50, 65, 66, 69, 87, 105, 114, 118], "why": [3, 5, 7, 25, 44, 46, 47, 57, 59, 64, 65, 67, 68, 69, 70, 74, 75, 77, 78, 80, 82, 85, 86, 88, 89, 91, 94, 95, 101, 102, 103, 108, 112, 113, 115, 119, 123], "reusabl": 3, "adapt": [3, 7, 8, 14, 28, 56, 86, 102, 114, 118, 119, 120, 121, 122], "later": [3, 10, 42, 45, 56, 57, 58, 60, 74, 88, 89, 91, 94, 99, 102, 103, 115], "Be": [3, 65, 67, 71], "lookout": 3, "hypothes": [3, 56], "rememb": [3, 7, 21, 27, 44, 56, 67, 71, 77, 78, 102, 109, 121, 123], "wrangl": 3, "thu": [3, 15, 48, 61, 64, 66, 68, 86, 87, 88, 89, 102, 103, 105, 109, 111], "far": [3, 7, 48, 56, 78, 81, 87, 103, 119], "gener": [3, 7, 8, 14, 22, 24, 25, 26, 43, 44, 45, 48, 49, 57, 58, 60, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 76, 78, 79, 80, 85, 87, 89, 91, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 119, 120, 122, 123], "q1": [3, 59], "plot": [3, 9, 10, 13, 14, 15, 24, 25, 26, 35, 45, 46, 48, 49, 50, 56, 58, 61, 66, 68, 69, 70, 71, 76, 77, 78, 80, 81, 85, 86, 87, 88, 89, 91, 94, 95, 97, 98, 99, 102, 103, 105, 109, 110, 111, 112, 113, 114, 115, 119], "notic": [3, 9, 10, 42, 43, 45, 47, 49, 50, 56, 57, 58, 59, 60, 65, 66, 67, 68, 69, 70, 77, 78, 79, 80, 81, 102, 103, 108, 109, 119], "pattern": [3, 10, 11, 45, 46, 47, 50, 54, 56, 57, 58, 59, 60, 61, 64, 66, 67, 68, 69, 75, 76, 77, 79, 81, 82, 91, 112, 113, 118, 119, 120], "across": [3, 6, 9, 11, 14, 35, 44, 45, 56, 58, 60, 61, 64, 65, 67, 69, 70, 78, 90, 91, 95, 96, 97, 98, 101, 102, 103, 105, 108, 112, 115, 119, 120], "globe": [3, 10, 56, 57, 58, 64, 67, 69, 94, 115], "over": [3, 7, 9, 10, 11, 12, 14, 15, 25, 34, 35, 42, 44, 45, 46, 47, 49, 50, 53, 54, 56, 57, 58, 59, 60, 61, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 99, 101, 102, 105, 109, 110, 111, 112, 113, 114, 118, 120], "mean": [3, 7, 9, 11, 13, 14, 21, 27, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 60, 61, 66, 67, 69, 70, 71, 75, 76, 78, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "q2": [3, 59], "observ": [3, 6, 7, 11, 14, 21, 22, 45, 46, 47, 49, 50, 57, 58, 59, 60, 61, 63, 64, 65, 67, 68, 69, 74, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 94, 95, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "trend": [3, 10, 11, 12, 15, 46, 47, 48, 50, 58, 64, 68, 75, 78, 81, 102, 112, 115, 119, 120], "doe": [3, 7, 11, 15, 20, 21, 26, 27, 34, 44, 46, 47, 49, 56, 60, 61, 64, 65, 66, 69, 78, 79, 80, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 108, 110, 114, 115, 118, 119, 120, 123], "result": [3, 7, 9, 10, 13, 14, 15, 17, 18, 19, 21, 23, 24, 25, 27, 28, 43, 46, 49, 50, 56, 58, 59, 60, 61, 66, 67, 74, 77, 78, 79, 80, 81, 82, 85, 87, 89, 90, 94, 97, 101, 103, 105, 109, 110, 111, 112, 113, 114, 115, 120], "align": [3, 14, 57, 58, 59, 65, 67, 71, 85, 86, 87, 88, 91, 103, 110, 118, 119], "expect": [3, 7, 10, 70, 71, 74, 85, 91, 94, 95, 102, 103, 105, 109, 110, 111, 114, 119, 123], "q3": 3, "choos": [3, 10, 12, 14, 17, 43, 56, 57, 60, 65, 66, 70, 78, 79, 85, 113, 118, 120], "subcontin": 3, "appropri": [3, 7, 22, 42, 64, 65, 69, 70, 75, 78, 84, 95, 119, 121], "choic": [3, 7, 13, 21, 43, 57, 64, 65, 70, 79, 87, 94, 98, 103, 109, 113, 119], "how": [3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 49, 54, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122, 123], "compar": [3, 13, 14, 15, 36, 43, 44, 47, 49, 50, 56, 58, 60, 61, 65, 67, 68, 69, 70, 75, 76, 77, 78, 79, 80, 81, 85, 86, 87, 88, 90, 91, 95, 96, 97, 98, 99, 102, 105, 108, 110, 111, 112, 113, 114, 115, 118], "address": [3, 5, 7, 12, 13, 15, 17, 21, 65, 68, 102, 103, 109, 113, 115, 118, 119, 120, 121], "q4": 3, "mai": [3, 4, 5, 7, 9, 10, 11, 20, 21, 22, 23, 24, 25, 33, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 61, 65, 66, 67, 68, 69, 70, 71, 75, 76, 78, 79, 80, 82, 94, 103, 105, 109, 110, 111, 113, 115, 118, 119, 120, 122, 123], "numer": [3, 11, 13, 22, 57, 64, 65, 66, 86, 96, 97, 98, 110, 118, 119, 120], "feel": [3, 11, 17, 23, 108, 109, 110, 111, 115], "free": [3, 9, 11, 12, 17, 23, 65, 86, 88, 90, 108, 109, 110, 111, 114, 115, 120, 123], "seek": [3, 21, 123], "reliabl": [3, 7, 10, 14, 65, 71, 81, 118], "onlin": [3, 4, 5, 15, 36, 58, 123], "argument": [3, 42, 43, 44, 45, 47, 50, 78, 79, 86, 88, 103, 110], "thursdai": 3, "20th": 3, "between": [3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 22, 24, 25, 26, 28, 42, 43, 46, 49, 50, 53, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 75, 76, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 110, 112, 114, 115, 118, 119, 123], "now": [3, 8, 9, 10, 12, 14, 15, 17, 19, 24, 25, 41, 42, 45, 46, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 88, 89, 90, 91, 94, 95, 96, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "path": [3, 4, 8, 9, 10, 11, 12, 13, 14, 15, 25, 44, 57, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "offer": [3, 7, 8, 11, 14, 27, 34, 46, 47, 64, 65, 67, 74, 75, 122, 123], "advic": [3, 8], "network": [3, 6, 21, 44, 71, 74, 76, 118], "exact": [3, 28, 87, 88, 89, 119], "sure": [3, 9, 10, 12, 14, 25, 34, 36, 42, 50, 56, 66, 67, 68, 71, 85, 87, 89, 91, 94, 95, 96, 97, 99, 109, 118, 120, 123], "yourself": [3, 22, 65, 120, 123], "known": [3, 8, 11, 17, 43, 56, 58, 59, 60, 74, 89, 90, 91, 94, 102, 103, 105, 112, 118, 120], "ha": [3, 6, 7, 9, 11, 12, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 34, 35, 42, 44, 45, 47, 49, 50, 54, 56, 57, 59, 60, 61, 64, 65, 66, 67, 68, 69, 75, 76, 79, 82, 85, 87, 88, 89, 91, 94, 97, 98, 99, 101, 102, 103, 105, 109, 110, 113, 114, 115, 118, 119, 120, 123], "determin": [3, 9, 12, 15, 17, 21, 23, 50, 56, 59, 61, 64, 65, 67, 68, 70, 78, 79, 80, 86, 89, 101, 102, 103, 109, 110, 111, 114, 115, 118, 120], "aspect": [3, 12, 20, 21, 22, 27, 40, 64, 65, 66, 78, 99, 102, 103, 108], "current": [3, 5, 7, 13, 14, 15, 27, 44, 45, 54, 58, 60, 74, 85, 87, 88, 89, 90, 94, 101, 102, 103, 108, 110, 113, 120], "debat": [3, 103], "keyword": [3, 7, 42, 43, 44, 113, 114], "tomorrow": [3, 55, 56], "up": [3, 5, 7, 8, 15, 21, 25, 26, 44, 46, 56, 57, 64, 66, 67, 68, 69, 70, 71, 78, 80, 87, 91, 96, 98, 102, 103, 105, 109, 119, 122, 123], "complet": [3, 7, 11, 14, 18, 28, 33, 56, 64, 67, 68, 69, 70, 71, 76, 88, 94, 95, 96, 97, 98, 99, 110, 113, 118, 120, 122], "origin": [3, 9, 11, 47, 48, 49, 50, 56, 63, 65, 69, 78, 79, 85, 91, 94, 103, 109, 112, 114], "situat": [3, 64, 118], "hint": [3, 11, 64, 66, 78, 85, 94, 96, 108, 110, 119], "paper": [3, 14, 21, 27, 75, 105, 120, 121], "revisit": [3, 15, 64, 94, 123], "step": [3, 7, 8, 9, 12, 18, 20, 21, 25, 26, 27, 43, 45, 46, 50, 56, 57, 58, 65, 66, 68, 70, 75, 76, 78, 79, 80, 87, 89, 90, 91, 94, 97, 101, 102, 103, 105, 110, 111, 112, 113, 114, 115, 119, 120], "effici": [3, 8, 10, 12, 20, 22, 23, 40, 42, 91, 101, 102, 103, 105, 118], "min": [3, 15, 45, 67, 70, 82, 105, 114, 115], "initi": [3, 7, 8, 10, 12, 15, 57, 63, 64, 66, 67, 68, 71, 78, 81, 85, 87, 88, 89, 90, 98, 102, 105, 108, 114, 118, 120], "few": [3, 7, 22, 35, 42, 43, 44, 49, 56, 57, 58, 60, 61, 64, 65, 68, 71, 74, 75, 78, 79, 85, 91, 101, 102, 103, 105, 109, 115, 120], "wa": [3, 12, 15, 25, 43, 45, 50, 61, 65, 66, 77, 78, 79, 80, 82, 86, 87, 89, 90, 91, 94, 96, 99, 102, 103, 105, 107, 108, 110, 113, 115, 118, 119, 120], "anyth": [3, 7, 9, 34, 43, 69, 109, 123], "weird": 3, "intrigu": 3, "yesterdai": [3, 54, 56], "particularli": [3, 8, 14, 56, 58, 66, 71, 81, 88, 110, 112, 118, 119, 123], "excit": [3, 123], "engin": [3, 64, 99, 109, 118, 120, 123], "googl": [3, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 30, 35, 36, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "baidu": 3, "look": [3, 8, 10, 11, 12, 14, 20, 21, 22, 24, 25, 26, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 61, 64, 66, 67, 68, 69, 70, 71, 75, 76, 77, 78, 79, 80, 81, 82, 87, 88, 89, 90, 91, 94, 95, 96, 102, 103, 105, 108, 110, 112, 113, 115, 118, 120, 121, 123], "onli": [3, 7, 10, 14, 15, 21, 35, 36, 43, 44, 45, 49, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 75, 76, 78, 79, 81, 85, 87, 88, 89, 90, 91, 94, 95, 96, 97, 99, 101, 102, 103, 105, 109, 110, 113, 115, 118, 119, 120, 123], "abstract": [3, 21], "promis": 3, "ones": [3, 24, 58, 105, 109], "whole": [3, 12, 27, 57, 87, 103, 105], "pool": [3, 102], "per": [3, 15, 61, 75, 76, 78, 79, 89, 101, 102, 103, 105, 115, 123], "skim": 3, "1h": 3, "h": [3, 7, 10, 11, 12, 13, 14, 15, 25, 47, 75, 80, 85, 99, 102], "note": [3, 7, 9, 10, 11, 12, 13, 14, 15, 21, 28, 33, 34, 35, 36, 42, 43, 44, 45, 46, 49, 50, 56, 58, 59, 60, 61, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 99, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "common": [3, 12, 15, 42, 44, 45, 47, 64, 66, 68, 69, 70, 74, 75, 76, 77, 78, 80, 89, 101, 105, 115], "doc": [3, 34, 42, 43], "especi": [3, 7, 8, 24, 35, 67, 120], "write": [3, 5, 20, 23, 24, 28, 32, 34, 36, 43, 44, 68, 87, 89, 95, 101, 121], "down": [3, 12, 20, 23, 36, 65, 66, 67, 76, 78, 91, 94, 101, 102, 103, 105, 115, 119, 121], "import": [3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21, 26, 27, 36, 40, 42, 44, 45, 46, 47, 57, 59, 60, 61, 64, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 121, 122, 123], "close": [3, 7, 8, 13, 28, 44, 61, 69, 71, 76, 77, 78, 85, 86, 101, 102, 103, 112, 119], "edu": [3, 9, 11, 12, 13], "domain": [3, 15, 65, 90, 103, 119], "vpn": 3, "full": [3, 7, 10, 14, 15, 44, 46, 57, 61, 67, 69, 74, 81, 91, 94, 95, 96, 97, 99, 102, 105, 115, 119, 121, 122], "version": [3, 9, 11, 13, 15, 34, 36, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 65, 66, 94, 96, 97, 103, 105], "preprint": [3, 82], "server": [3, 9, 35], "arxiv": 3, "biorxiv": 3, "could": [3, 7, 8, 28, 44, 48, 49, 64, 66, 69, 81, 85, 86, 87, 90, 91, 94, 95, 99, 101, 102, 103, 105, 109, 110, 111, 113, 114, 115, 118, 119, 120, 121], "turn": [3, 14, 56, 59, 60, 69, 89, 90, 102, 119], "someon": [3, 103], "univers": [3, 6, 7, 12, 13, 27, 30, 64, 107], "There": [3, 5, 9, 10, 14, 15, 21, 27, 57, 58, 64, 65, 66, 74, 78, 79, 86, 88, 89, 91, 96, 101, 102, 103, 105, 107, 110, 112, 115, 119, 123], "too": [3, 20, 57, 89, 90, 95, 103], "loud": [3, 7], "better": [3, 10, 18, 42, 46, 48, 56, 60, 64, 67, 78, 79, 98, 102, 103, 110, 114, 118, 119, 120, 121], "fridai": 3, "21st": [3, 11, 86, 101, 102, 113], "via": [3, 4, 7, 9, 12, 56, 65, 66, 69, 71, 78, 91, 94, 97, 101, 102, 103, 105, 109, 111, 113, 120, 122, 123], "airtabl": [3, 33], "converg": [3, 46, 115, 120], "outlin": [3, 25, 65], "inspir": [3, 4, 5, 6, 7, 20, 64, 84, 96, 107, 120], "respect": [3, 7, 8, 11, 12, 15, 24, 42, 56, 57, 58, 61, 68, 79, 87, 88, 91, 96, 99, 101, 102, 103, 118, 120], "ten": [3, 11, 57, 102], "simpl": [3, 12, 40, 42, 43, 46, 67, 87, 88, 89, 95, 97, 98, 99, 102, 103, 111, 114, 120], "rule": [3, 44], "pai": 3, "attent": [3, 7, 49], "figur": [3, 9, 10, 11, 14, 21, 24, 44, 46, 47, 49, 50, 56, 57, 58, 61, 65, 74, 75, 76, 79, 80, 82], "specifi": [3, 10, 12, 42, 43, 44, 45, 46, 47, 48, 50, 66, 67, 75, 80, 82, 85, 87, 91, 94, 102, 114, 119, 120], "overal": [3, 10, 12, 47, 64, 66, 70, 71, 78, 81, 101, 102, 103, 105, 112, 118, 119, 120], "paragraph": [3, 21], "c": [3, 9, 10, 11, 12, 13, 14, 15, 25, 49, 50, 56, 59, 60, 61, 63, 65, 68, 70, 74, 75, 76, 77, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 110, 112, 113, 114, 115, 118, 120], "scheme": 3, "describ": [3, 13, 14, 15, 21, 24, 44, 57, 58, 59, 64, 65, 66, 75, 85, 87, 89, 91, 102, 103, 105, 108, 111, 112, 113, 119, 120], "context": [3, 21, 24, 25, 26, 27, 45, 50, 64, 66, 68, 70, 73, 84, 93, 94, 95, 102, 103, 118, 119, 123], "gap": [3, 7, 8, 64, 88, 119, 122], "fill": [3, 28, 33, 43, 49, 58, 66, 68, 69, 70, 71, 88, 102, 119, 120, 122], "identifi": [3, 9, 10, 11, 12, 15, 17, 20, 21, 23, 25, 26, 61, 65, 66, 67, 69, 77, 78, 79, 80, 81, 88, 90, 91, 102, 105, 112, 115, 118, 119, 120], "descript": [3, 14, 15, 21, 42, 45, 66, 87, 103, 105, 118, 119, 120], "posit": [3, 4, 7, 13, 15, 20, 21, 22, 23, 24, 25, 26, 27, 44, 57, 58, 59, 64, 70, 75, 76, 78, 80, 85, 87, 88, 91, 102, 105, 108, 118, 120], "neg": [3, 7, 11, 44, 58, 59, 70, 75, 78, 80, 87, 88, 91, 102, 103, 105, 108, 119, 120], "potenti": [3, 10, 12, 14, 43, 44, 47, 56, 60, 64, 66, 70, 71, 80, 95, 99, 102, 103, 105, 108, 113, 114, 115, 118, 119, 120, 121], "signific": [3, 8, 10, 14, 47, 58, 60, 61, 64, 65, 67, 69, 70, 80, 102, 103, 112, 113, 120], "societ": [3, 64, 65, 103], "bullet": 3, "coher": [3, 65, 102], "don": [3, 12, 22, 23, 25, 36, 61, 64, 78, 91, 102, 103, 105, 123], "t": [3, 7, 10, 12, 13, 14, 22, 23, 24, 25, 36, 42, 43, 45, 58, 60, 61, 64, 65, 71, 74, 75, 77, 78, 79, 82, 85, 86, 87, 88, 89, 90, 91, 97, 98, 99, 101, 102, 103, 105, 109, 112, 113, 115, 118, 119, 120, 121, 123], "worri": [3, 85], "thought": [3, 7, 78, 80], "unfamiliar": [3, 91], "approach": [3, 12, 15, 22, 46, 64, 68, 75, 79, 82, 85, 95, 102, 103, 105, 109, 110, 111, 114, 119, 121, 123], "alwai": [3, 6, 7, 43, 59, 65, 66, 110], "reveal": [3, 58, 68, 78, 81, 120], "never": 3, "heard": 3, "return": [3, 7, 9, 10, 11, 12, 13, 14, 15, 23, 25, 42, 44, 46, 47, 49, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 102, 103, 105, 108, 110, 112, 113, 114, 118, 119, 120], "mind": [3, 7, 8, 12, 21, 26, 94, 99], "effort": [3, 9, 10, 65, 101, 102, 103, 113, 123], "had": [3, 8, 48, 68, 88, 91, 95, 114, 118], "polish": 3, "languag": [3, 97, 105], "polit": [3, 7, 102, 105], "kind": [3, 7, 90, 105, 115, 121], "grade": 3, "requir": [3, 8, 12, 14, 21, 22, 36, 43, 65, 67, 79, 88, 89, 90, 91, 94, 95, 102, 110, 111, 114, 115, 120, 122, 123], "badg": 3, "certif": [3, 33], "24th": 3, "probabl": [3, 15, 30, 69, 79, 103, 108, 109, 110, 111, 112, 113, 114, 115, 118, 123], "refin": [3, 12, 66], "littl": [3, 7, 8, 57, 66, 70, 105, 110, 113], "rough": [3, 105], "tool": [3, 11, 14, 18, 20, 27, 36, 39, 40, 42, 43, 45, 46, 49, 53, 54, 55, 56, 57, 65, 68, 69, 77, 79, 80, 81, 102, 105, 118, 119, 121], "tackl": [3, 8, 13], "toward": [3, 56, 65, 68, 70, 80, 85, 88, 89, 90, 91, 99, 108, 110, 115, 121], "discourag": 3, "usual": [3, 6, 24, 28, 42, 46, 65, 68, 101, 103, 120], "great": [3, 6, 8, 15, 64, 71, 107, 108, 109, 110, 111, 123], "A": [3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 22, 23, 24, 26, 28, 36, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 59, 61, 63, 64, 65, 67, 69, 70, 74, 75, 76, 78, 79, 80, 82, 88, 91, 94, 95, 97, 101, 103, 107, 108, 110, 114, 118, 119, 120], "piec": [3, 12, 42, 43, 66], "see": [3, 7, 8, 9, 10, 11, 12, 13, 14, 24, 28, 30, 32, 33, 42, 43, 45, 46, 56, 57, 58, 61, 64, 65, 66, 67, 68, 69, 70, 71, 75, 77, 78, 79, 80, 81, 85, 87, 88, 90, 91, 94, 95, 96, 99, 101, 102, 103, 105, 108, 113, 114, 115, 118, 119, 120, 123], "alloc": [3, 28, 101], "ta": [3, 9, 10, 14, 15, 91], "toolkit": 3, "difficult": [3, 8, 21, 33, 35, 36, 44, 46, 64, 78], "otherwis": [3, 34, 86, 90, 91, 103, 110], "complic": [3, 56, 57, 60, 94, 123], "scratch": [3, 89, 122], "exist": [3, 7, 9, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 58, 60, 64, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 88, 89, 90, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "long": [3, 11, 14, 39, 40, 46, 47, 48, 57, 58, 64, 65, 66, 67, 68, 69, 75, 80, 81, 87, 88, 89, 95, 96, 97, 99, 109, 111], "term": [3, 9, 11, 14, 21, 26, 39, 40, 46, 47, 48, 56, 58, 60, 61, 64, 65, 66, 67, 68, 69, 74, 75, 80, 81, 85, 87, 88, 89, 90, 91, 94, 96, 97, 101, 102, 105, 111, 118, 120], "25th": [3, 6], "absolut": [3, 70, 74, 96, 105, 119], "ok": [3, 56, 66], "Then": [3, 24, 46, 47, 85, 89, 109, 114, 115, 118, 120], "think": [3, 7, 18, 22, 40, 44, 45, 46, 50, 56, 59, 67, 75, 77, 81, 85, 86, 87, 89, 90, 91, 94, 96, 102, 103, 110, 112, 113, 115, 119, 120, 121], "affect": [3, 9, 10, 14, 15, 21, 56, 60, 64, 65, 78, 85, 87, 88, 99, 102, 103, 110, 115, 119], "limit": [3, 8, 14, 25, 64, 67, 79, 82, 85, 90, 101, 103, 105, 108, 109, 113, 115, 119, 120], "particular": [3, 7, 8, 10, 12, 13, 22, 43, 70, 80, 87, 88, 91, 94, 102, 103, 105, 107, 110, 113, 115, 118, 120], "suit": [3, 7, 12, 64, 65, 75, 88, 119], "somebodi": 3, "run": [3, 9, 15, 24, 32, 34, 36, 48, 49, 56, 57, 58, 61, 68, 74, 78, 80, 87, 88, 90, 91, 94, 96, 97, 99, 102, 105, 113, 115, 119, 120, 123], "somedai": 3, "i": [3, 7, 9, 10, 11, 12, 13, 14, 15, 22, 23, 28, 42, 44, 45, 46, 47, 48, 57, 58, 61, 64, 65, 67, 70, 71, 74, 75, 76, 79, 81, 82, 88, 89, 91, 94, 95, 96, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 113, 118, 119, 120], "e": [3, 9, 10, 11, 13, 14, 22, 24, 25, 34, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 82, 85, 86, 87, 88, 89, 91, 94, 95, 96, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 114, 118, 119, 120], "valid": [3, 14, 44, 47, 66, 67, 70, 71, 99, 103, 105], "effect": [3, 7, 8, 9, 11, 13, 14, 15, 21, 40, 56, 59, 61, 64, 68, 70, 71, 78, 82, 86, 89, 90, 95, 98, 101, 102, 103, 110, 112, 113, 114, 115, 120], "exampl": [3, 7, 9, 10, 11, 12, 13, 14, 22, 24, 25, 34, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 60, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 80, 81, 85, 86, 87, 88, 89, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 110, 111, 113, 114, 118, 119, 120, 122], "creat": [3, 7, 10, 12, 14, 15, 21, 26, 35, 36, 43, 45, 49, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 74, 75, 76, 78, 79, 80, 81, 82, 85, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 118, 119, 120], "proxi": [3, 22, 64, 76, 77, 78, 79, 80, 82, 99, 102, 122], "paleoclim": [3, 22, 25, 28, 52, 73, 77, 80, 99, 122], "reconstruct": [3, 9, 25, 78, 80, 99], "hydrogen": [3, 11, 75, 77, 78], "isotop": [3, 74, 76, 77, 78, 79, 80, 123], "\u03b4d": [3, 75, 78], "rainfal": [3, 9, 10, 56, 65, 70, 71, 78, 80, 108, 111, 113], "amount": [3, 11, 12, 15, 58, 64, 65, 67, 69, 71, 75, 78, 86, 87, 88, 101, 102, 105, 107, 108, 109, 113, 118, 119, 120], "factor": [3, 10, 11, 13, 15, 24, 47, 58, 60, 64, 65, 68, 101, 102, 103, 105, 113, 118, 119], "ensur": [3, 10, 14, 25, 27, 64, 65, 66, 70, 71, 91, 94, 95, 96, 97, 98, 99, 102, 109, 118, 119, 120, 121, 123], "signal": [3, 65, 68, 70, 78, 80], "valu": [3, 10, 12, 14, 15, 25, 42, 44, 45, 46, 48, 49, 56, 58, 60, 61, 64, 66, 67, 68, 69, 70, 71, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 96, 99, 101, 102, 103, 105, 107, 108, 109, 111, 112, 113, 114, 115, 120], "record": [3, 4, 7, 10, 11, 14, 15, 25, 26, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 63, 64, 66, 67, 68, 69, 70, 74, 75, 77, 78, 79, 80, 81, 102, 109, 110, 113, 114], "closest": [3, 15, 43, 46], "modern": [3, 10, 54, 73, 75, 82, 99, 102, 103, 105], "measur": [3, 8, 11, 12, 14, 15, 25, 26, 44, 57, 61, 64, 65, 66, 70, 71, 74, 75, 76, 77, 81, 82, 87, 89, 90, 101, 102, 103, 105, 108, 112, 115, 118, 119, 120, 122], "site": [3, 9, 13, 25, 73, 94, 97, 105], "remov": [3, 14, 15, 34, 43, 46, 47, 58, 60, 61, 65, 66, 67, 68, 69, 70, 71, 75, 76, 77, 81, 86, 90, 91, 102, 105, 109, 114, 115, 119, 120], "domin": [3, 57, 79, 80, 91, 102], "keynot": [3, 28], "futur": [3, 6, 7, 8, 9, 11, 13, 15, 21, 40, 47, 64, 65, 68, 69, 80, 94, 97, 98, 101, 102, 103, 115, 118, 122], "frontier": 3, "dr": [3, 6], "paul": [3, 15, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 107], "behren": [3, 102], "around": [3, 10, 22, 23, 56, 59, 64, 69, 75, 78, 85, 96, 102, 103, 105, 110, 111, 113, 119, 123], "avail": [3, 7, 9, 10, 11, 12, 13, 14, 15, 18, 25, 35, 47, 57, 64, 65, 66, 67, 68, 69, 71, 74, 76, 78, 79, 82, 85, 87, 89, 91, 94, 96, 97, 99, 102, 105, 108, 109, 110, 111, 113, 123], "live": [3, 4, 6, 7, 11, 28, 35, 57, 68, 75, 103], "panelist": [3, 5], "00": [3, 28, 43, 103], "utc": [3, 28, 30], "14": [3, 6, 10, 11, 14, 15, 22, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 81, 85, 87, 88, 89, 90, 91, 94, 95, 96, 97, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "21": [3, 14, 61, 67, 71, 77, 78, 82, 85, 87, 89, 91, 105, 107, 109, 112, 113, 114, 115, 118, 119], "26th": 3, "reconven": 3, "struggl": [3, 20], "someth": [3, 7, 105, 109, 121], "stuck": [3, 96], "curriculum": [3, 7, 122], "shift": [3, 50, 64, 70, 77, 78, 81, 99, 105, 110, 112], "surround": [3, 20, 21, 22, 23, 103, 105], "mitig": [3, 7, 8, 10, 14, 61, 68, 101, 102, 103, 113, 122], "strategi": [3, 21, 103, 105], "ecosystem": [3, 11, 14, 15, 59, 65, 102, 103, 108, 118], "27th": 3, "psycholog": 3, "crisi": [3, 5], "moment": [3, 67, 108, 112, 113], "28th": [3, 28, 105], "tie": 3, "loos": 3, "slideshow": 3, "At": [3, 27, 28, 46, 59, 61, 79, 103, 111], "copi": [3, 13, 34, 35, 63, 81], "edit": [3, 34, 36, 107, 123], "add": [3, 10, 14, 30, 36, 42, 46, 56, 57, 58, 59, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "name": [3, 9, 10, 11, 12, 13, 14, 15, 35, 43, 44, 48, 56, 57, 58, 59, 60, 64, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "bottom": [3, 9, 25, 30, 56, 76, 94, 95, 99], "non": [3, 7, 8, 11, 12, 13, 15, 60, 87, 95, 101, 102, 103, 105, 115, 120], "theme": [3, 7, 9], "seem": [3, 21, 61, 70, 79, 94, 103, 112, 120], "imposs": [3, 65], "format": [3, 12, 14, 23, 25, 27, 39, 44, 48, 57, 60, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 123], "often": [3, 7, 9, 11, 14, 23, 27, 42, 43, 46, 47, 50, 58, 59, 64, 65, 67, 68, 69, 70, 71, 78, 79, 90, 91, 94, 96, 102, 109, 110, 111, 113, 115, 118, 119], "refer": [3, 9, 10, 12, 14, 17, 21, 25, 28, 47, 48, 56, 57, 58, 59, 60, 61, 64, 65, 67, 68, 69, 71, 75, 79, 81, 82, 87, 88, 90, 91, 94, 96, 97, 98, 99, 103, 105, 109, 112, 113, 114, 115, 120, 123], "elev": [3, 77, 101], "pitch": 3, "poster": 3, "confer": [3, 27, 103, 105], "advoc": [3, 7], "polici": [3, 7, 10, 103, 105, 113], "govern": [3, 8, 64, 105, 121, 123], "Or": 3, "accident": 3, "investor": 3, "chanc": [3, 28, 70, 101, 103, 108, 109, 111, 122], "secur": [3, 7, 10, 12, 14, 64, 65], "million": [3, 79, 89, 91, 102], "dollar": [3, 101, 102], "fund": [3, 27], "kei": [3, 9, 12, 15, 42, 44, 46, 48, 57, 64, 65, 67, 71, 74, 76, 78, 85, 96, 97, 98, 99, 102, 103, 105, 119], "art": 3, "act": [3, 8, 61], "plai": [3, 7, 23, 47, 49, 60, 64, 89, 90, 102, 103, 109, 110], "music": 3, "instrument": [3, 15, 65, 75, 82], "etc": [3, 7, 9, 12, 13, 14, 15, 24, 33, 34, 46, 57, 64, 65, 74, 80, 81, 91, 94, 95, 102, 114, 115, 123], "where": [3, 7, 11, 12, 14, 15, 21, 24, 34, 35, 36, 43, 55, 56, 57, 59, 60, 61, 64, 66, 67, 68, 69, 70, 71, 74, 75, 81, 85, 87, 88, 90, 91, 94, 95, 96, 98, 99, 101, 103, 105, 109, 110, 113, 115, 118, 119, 120, 123], "rehears": 3, "crucial": [3, 8, 10, 11, 12, 26, 47, 57, 60, 64, 65, 68, 85, 87, 91, 103, 105, 109, 112, 118, 119, 123], "sound": [3, 79], "WILL": 3, "annoi": 3, "sai": [3, 8, 26, 28, 49, 67, 68, 94, 109, 111, 113], "tenth": 3, "want": [3, 5, 7, 12, 13, 22, 24, 27, 34, 42, 43, 49, 57, 58, 64, 66, 67, 68, 69, 74, 75, 78, 81, 84, 89, 90, 91, 94, 97, 98, 99, 105, 113, 115, 118, 119, 120, 123], "secret": 3, "professor": [3, 7, 21], "rel": [3, 7, 11, 12, 13, 14, 15, 25, 44, 47, 57, 59, 61, 64, 74, 75, 81, 85, 87, 90, 94, 95, 96, 99, 101, 103, 105, 112, 113, 115, 118, 119, 123], "larg": [3, 22, 40, 42, 43, 45, 53, 54, 55, 57, 58, 60, 61, 64, 65, 66, 68, 70, 71, 78, 87, 91, 102, 103, 105, 107, 113, 119, 120], "intro": [3, 34, 117, 123], "small": [3, 7, 20, 57, 61, 69, 71, 79, 87, 89, 90, 103, 105, 113, 120], "previou": [3, 11, 21, 34, 43, 46, 47, 48, 49, 50, 57, 58, 59, 60, 61, 65, 66, 67, 69, 70, 71, 75, 78, 79, 80, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 105, 108, 110, 112, 113, 114, 115, 118, 119, 120, 121, 123], "anecdot": 3, "magic": [3, 9, 94, 97, 105], "audienc": [3, 8, 17, 18, 23, 27, 118, 123], "listen": [3, 7], "passiv": 3, "bore": 3, "grab": [3, 58], "smart": 3, "happen": [3, 7, 34, 42, 77, 102, 103, 111, 113, 120, 121], "normal": [3, 15, 23, 28, 56, 65, 66, 68, 69, 102, 103, 105, 108, 112, 113, 118, 119, 120, 123], "true": [3, 9, 10, 12, 14, 25, 46, 48, 49, 56, 57, 58, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 77, 78, 79, 85, 91, 94, 95, 96, 97, 98, 99, 102, 105, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "main": [3, 7, 10, 21, 45, 57, 58, 60, 66, 67, 68, 69, 70, 71, 79, 80, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "logic": [3, 66, 70], "did": [3, 7, 23, 50, 76, 89, 90, 91, 102, 103, 109, 110, 113, 114, 118, 119], "innov": [3, 12, 102], "comparison": [3, 12, 47, 48, 75, 102, 105, 110, 113, 114, 120], "el": [3, 9, 50, 53, 54, 64, 70], "ni\u00f1o": [3, 9, 50, 53, 54, 64], "southern": [3, 9, 46, 50, 58, 59, 64, 70, 75, 91, 94], "oscil": [3, 9, 50, 64, 70, 75], "g": [3, 11, 12, 13, 14, 22, 24, 34, 43, 44, 46, 48, 50, 57, 58, 59, 64, 65, 66, 68, 69, 70, 71, 74, 75, 76, 78, 80, 87, 89, 91, 94, 96, 99, 101, 102, 103, 105, 109, 114, 118], "resolut": [3, 12, 14, 15, 22, 25, 43, 48, 57, 58, 65, 66, 67, 68, 69, 71, 74, 77, 78, 91, 94, 96, 113, 115], "suffici": [3, 65, 103, 123], "That": [3, 7, 58, 66, 67, 79, 86, 88, 91, 103, 123], "hear": 3, "furthermor": [3, 68, 81], "takeawai": [3, 7, 67, 118], "highlight": [3, 14, 15, 56, 64, 68, 75, 79, 86, 88, 102, 103, 123], "order": [3, 10, 11, 12, 13, 15, 20, 32, 42, 43, 49, 50, 57, 58, 78, 79, 82, 87, 91, 102, 105, 109, 118], "got": [3, 43], "dream": 3, "big": [3, 20, 28, 88], "evolv": [3, 58, 70, 105], "given": [3, 9, 12, 44, 48, 49, 58, 59, 64, 65, 66, 68, 69, 71, 74, 76, 85, 87, 89, 91, 96, 97, 98, 101, 102, 103, 105, 109, 110, 111, 113, 114, 115, 118, 119, 120], "screen": [3, 35], "graphic": [3, 7, 88, 123], "meant": [3, 78, 114, 122], "told": 3, "10": [3, 9, 10, 11, 12, 13, 14, 15, 21, 22, 25, 26, 27, 52, 56, 57, 58, 59, 60, 61, 63, 64, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 87, 88, 89, 90, 91, 93, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "greet": 3, "round": [3, 56, 67, 78, 103, 112, 113, 115, 118], "call": [3, 7, 9, 10, 11, 12, 13, 14, 15, 43, 44, 45, 46, 47, 57, 58, 59, 60, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "zoom": [3, 71, 75, 76], "institut": [3, 7, 11, 27, 81, 96, 105, 113, 115], "area": [3, 8, 9, 10, 12, 14, 21, 45, 47, 49, 50, 56, 58, 61, 64, 65, 67, 68, 69, 71, 91, 95, 96, 97, 98, 99, 102, 107, 115, 120, 122], "subject": [3, 8, 21, 23, 64, 115], "fact": [3, 26, 59, 67, 89], "hi": [3, 21], "m": [3, 9, 10, 12, 13, 14, 22, 25, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 63, 64, 65, 66, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 91, 95, 102, 105, 107, 120], "jonni": 3, "wiggli": 3, "caterpillar": 3, "phd": 3, "notr": 3, "dame": 3, "pari": 3, "relationship": [3, 9, 10, 11, 12, 14, 24, 26, 60, 70, 71, 79, 80, 86, 87, 102, 103, 114, 119, 120, 123], "moistur": [3, 58, 65, 74, 90, 115], "storm": [3, 13, 64, 109, 111, 112], "my": [3, 23, 64], "bike": 3, "ride": 3, "40": [3, 13, 14, 15, 43, 67, 71, 77, 79, 87, 88, 90, 113], "speak": [3, 7, 8], "approxim": [3, 59, 60, 61, 64, 71, 75, 85, 88, 89, 101, 103, 115], "miss": [3, 33, 43, 58, 66, 68, 69, 70, 71, 87, 89, 99, 102, 109, 119, 120], "realli": [3, 89, 111, 120, 123], "anyon": [3, 7, 65, 119], "hardest": 3, "surpris": [3, 96, 119], "techniqu": [3, 8, 15, 21, 43, 48, 64, 68, 78, 105, 118, 119], "immedi": [3, 7, 64], "place": [3, 6, 27, 28, 35, 60, 64, 67, 78, 91, 102, 103, 105, 120], "fall": [3, 70, 102, 108, 110, 118], "outsid": [3, 4, 6, 7, 50, 123], "room": [3, 11], "email": [3, 102, 123], "sent": [3, 120], "hard": [3, 65, 103, 105], "cutoff": 3, "mark": [3, 14, 67, 87], "primarili": [3, 14, 40, 47, 61, 65, 80, 85, 113, 123], "again": [3, 57, 58, 61, 78, 99, 115, 118], "floor": 3, "pictur": [3, 20, 99], "oppos": 3, "technic": [3, 13, 61, 95, 101, 103, 105, 121], "concis": [3, 21, 46], "rambl": 3, "avoid": [3, 12, 17, 35, 43, 66, 67, 68, 69, 70, 71, 76, 85, 102], "anoth": [3, 13, 34, 36, 42, 43, 44, 45, 47, 49, 57, 59, 61, 64, 66, 71, 78, 79, 81, 82, 87, 90, 102, 103, 105, 110, 112, 118, 123], "constraint": [3, 11, 50, 64, 101, 102, 103], "encompass": [4, 7, 85, 105], "four": [4, 7, 15, 28, 59, 64, 67, 70, 78, 103, 105, 109, 113, 115], "attend": [4, 8, 123], "enabl": [4, 9, 12, 21, 35, 44, 46, 50, 64, 65, 79, 85, 86, 91, 94, 97, 103, 105, 114, 119], "expand": [4, 6, 42, 90, 91, 95, 96], "broaden": 4, "percept": [4, 7, 105], "reflect": [4, 7, 14, 15, 28, 64, 65, 66, 69, 74, 75, 78, 80, 86, 88, 91, 96, 102, 103, 105, 110], "view": [4, 7, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 28, 36, 42, 57, 64, 74, 75, 76, 82, 95, 102, 112], "pathwai": [4, 5, 11, 95, 99, 102, 113, 122], "brows": [4, 5], "profil": [4, 14, 36, 44, 59, 89, 90], "practition": [4, 5, 7], "perspect": [4, 7, 8, 10, 12, 47, 64, 102, 119], "foster": [4, 7, 8], "insid": [4, 25, 35], "variou": [4, 8, 10, 11, 12, 15, 39, 40, 41, 42, 43, 44, 48, 55, 57, 59, 64, 65, 66, 67, 70, 71, 74, 75, 77, 78, 79, 81, 95, 96, 99, 102, 105, 108, 113, 114, 118, 119, 120], "spotlight": 4, "divers": [4, 8, 11, 15, 26, 64, 76, 96, 97, 102], "action": [4, 5, 7, 8, 68, 101, 103, 105], "fix": [5, 10, 14, 64, 91, 94, 95, 96, 97, 98, 99, 103, 109, 114, 123], "tailor": [5, 65, 109, 119], "book": [5, 10, 123], "speaker": [5, 28, 35], "volunt": [5, 6], "cma": [5, 6, 10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "pace": [5, 64, 123], "bring": [6, 7, 8, 15, 44, 58, 59, 90, 105, 111, 123], "varieti": [6, 10, 56, 57, 64, 65, 69, 74, 78, 88, 96, 119, 120], "sector": [6, 102, 103], "stage": [6, 65, 91], "uniqu": [6, 7, 10, 12, 15, 60, 64, 74, 79, 91, 96, 97, 99, 105, 109], "moder": [6, 12, 14, 15, 64], "q": [6, 11, 59, 86, 87, 88, 89, 90, 101, 103, 113, 114, 115], "particip": [6, 7, 33, 103, 121], "w2d2": [6, 28], "reserv": [6, 102], "8": [6, 9, 10, 11, 12, 13, 14, 15, 18, 23, 24, 25, 26, 28, 43, 61, 63, 64, 65, 66, 67, 68, 69, 70, 74, 75, 76, 77, 78, 79, 80, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 118, 119, 120, 123], "1": [6, 7, 10, 11, 13, 14, 15, 18, 21, 22, 25, 30, 36, 63, 101, 107, 122, 123], "2": [6, 7, 10, 13, 14, 18, 20, 22, 23, 24, 25, 26, 27, 30, 36, 49, 53, 54, 63, 99, 107, 108, 110, 111, 112, 114, 122, 123], "although": [6, 21, 43, 48, 58, 64, 65, 66, 70, 78, 85, 94, 103], "target": [6, 27, 49, 64, 65, 94, 119, 120], "zone": [6, 15, 30, 46], "lie": [6, 108], "shipra": 6, "jain": 6, "former": 6, "execut": [6, 10, 65, 85, 96, 97, 99, 105, 115, 119], "committe": [6, 63, 65], "young": 6, "system": [6, 7, 10, 11, 12, 14, 22, 28, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52, 53, 54, 55, 56, 58, 59, 61, 63, 64, 66, 67, 68, 69, 81, 82, 86, 87, 88, 89, 95, 103, 105, 113, 118, 121, 122], "scientist": [6, 7, 11, 21, 24, 64, 65, 67, 74, 119], "mpho": 6, "sadiki": 6, "digit": [6, 64], "africa": [6, 15, 67, 78, 80, 81], "ya\u00edtza": 6, "luna": 6, "cruz": 6, "chief": 6, "offic": [6, 87], "nasa": [6, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "mission": [6, 15], "directori": [6, 12, 35, 66, 74, 91], "top": [6, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 34, 35, 36, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "steven": 6, "ramag": 6, "ceo": [6, 63], "r\u00e9seau": 6, "advisor": 6, "unit": [6, 9, 12, 13, 14, 42, 43, 44, 45, 57, 58, 61, 68, 71, 75, 77, 80, 81, 87, 89, 91, 94, 101, 102, 103, 115, 119, 120, 123], "nation": [6, 7, 12, 15, 63, 65, 66, 87, 113], "sheila": 6, "saia": 6, "director": 6, "north": [6, 7, 11, 15, 44, 56, 57, 58, 59, 60, 65, 67, 70, 71, 94], "carolina": 6, "state": [6, 11, 13, 15, 44, 47, 49, 57, 58, 61, 64, 66, 68, 71, 80, 88, 89, 90, 94, 96, 102, 103, 120], "faten": 6, "attig": 6, "bahar": 6, "carthag": 6, "water": [6, 7, 11, 13, 14, 15, 56, 59, 60, 61, 64, 65, 66, 69, 74, 85, 87, 89, 90, 91, 115], "energi": [6, 10, 14, 22, 39, 40, 44, 45, 47, 64, 85, 88, 89, 90, 95, 102, 123], "food": [6, 10, 12, 14, 59, 64, 65, 102], "nexu": 6, "emphasi": [7, 65], "implic": [7, 13, 21, 25, 47, 64, 85, 98, 103, 105, 115, 120, 121], "pre": [7, 12, 14, 15, 22, 27, 35, 47, 65, 76, 80, 87, 88, 89, 102, 120, 122, 123], "total": [7, 9, 11, 14, 45, 59, 61, 67, 71, 85, 87, 95, 101, 102, 103, 105, 109, 119, 120], "spark": 7, "forefront": 7, "half": [7, 18, 87, 101, 102, 110, 113], "delv": [7, 64, 67, 71, 99, 105, 108, 119, 123], "deeper": [7, 56, 61, 80, 105, 108, 119], "hone": 7, "introduct": [7, 18, 28, 39, 42, 57, 69, 105, 107, 123], "leader": 7, "chat": [7, 85, 122, 123], "warm": [7, 11, 56, 58, 61, 64, 69, 77, 80, 81, 85, 87, 88, 90, 91, 95, 99, 102, 103, 113], "best": [7, 11, 21, 27, 35, 57, 64, 65, 85, 86, 103, 113, 118], "microphon": 7, "respectfulli": 7, "along": [7, 13, 15, 42, 44, 45, 48, 57, 67, 68, 71, 94, 96, 101, 103, 105, 108, 113, 123], "text": [7, 15, 21, 36, 66, 75, 87, 88, 105, 120], "track": [7, 14, 58, 64, 69, 75, 77, 85, 105, 122], "manner": 7, "Not": [7, 24, 44, 87, 102, 123], "individu": [7, 8, 42, 44, 46, 58, 85, 87, 89, 97, 103, 120], "draw": [7, 11, 67, 70, 108, 109, 111], "instead": [7, 9, 14, 21, 42, 43, 44, 57, 67, 82, 85, 86, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 109, 111, 113, 114, 118, 123], "ideal": [7, 22, 60, 64, 65, 67, 71, 102, 103], "doesn": [7, 23, 43, 58, 79, 90, 102], "rather": [7, 43, 45, 50, 57, 58, 61, 71, 77, 79, 82, 85, 86, 89, 95, 97, 98, 99, 101, 102, 103, 114, 115, 119, 122], "correspond": [7, 15, 44, 49, 56, 58, 64, 66, 67, 71, 75, 76, 79, 85, 86, 91, 101, 105, 109, 111, 112, 113, 120], "gender": 7, "allow": [7, 10, 11, 24, 33, 43, 44, 46, 48, 49, 50, 56, 64, 65, 67, 68, 69, 75, 78, 79, 81, 85, 87, 89, 91, 94, 102, 103, 105, 109, 113, 120], "interconnect": [7, 64, 102, 120], "balanc": [7, 14, 22, 61, 85, 88, 89, 90, 95, 103, 120], "emit": [7, 61, 64, 85, 86, 88, 89, 91, 102], "greenhous": [7, 11, 14, 74, 77, 81, 89, 102, 113], "gass": [7, 102], "south": [7, 15, 21, 26, 44, 45, 56, 57, 58, 59, 60, 67, 70, 94], "vulner": [7, 15, 28, 108, 109, 110, 111, 112, 113, 114, 115], "With": [7, 43, 57, 58, 61, 64, 67], "vision": [7, 25], "reduct": [7, 13, 64, 86, 89, 101, 102, 103], "ga": [7, 14, 74, 77, 81, 89, 102, 113], "emiss": [7, 11, 85, 86, 89, 94, 95, 96, 97, 101, 102, 103, 113, 118], "payment": 7, "loss": [7, 11, 15, 78, 87, 103, 115], "damag": [7, 10, 101, 102], "produc": [7, 11, 44, 45, 58, 65, 69, 71, 77, 78, 80, 81, 85, 101, 102, 103, 120], "item": [7, 9, 45, 76, 81, 85, 95, 96, 97, 98, 99, 105], "financ": 7, "human": [7, 11, 14, 15, 61, 64, 91, 98, 99, 102, 115, 118, 120], "legal": 7, "web": [7, 12, 57, 64, 65, 66, 102, 105], "linkedin": 7, "world": [7, 8, 11, 12, 19, 24, 25, 59, 69, 77, 80, 96, 103, 105, 107, 112, 115, 118, 119, 121], "youth": 7, "recent": [7, 9, 10, 11, 12, 13, 14, 15, 47, 53, 54, 59, 60, 61, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "plataforma": 7, "boliviana": 7, "frent": 7, "al": [7, 10, 11, 12, 13, 14, 15, 22, 25, 75, 76, 77, 78, 80, 81, 82, 86, 87, 93, 102, 103, 105, 107], "cambio": 7, "clim\u00e1tico": 7, "cop27": 7, "spanish": [7, 15], "escaz\u00fa": 7, "agreement": [7, 99], "biodivers": 7, "ipywidget": [7, 10, 11, 12, 13, 14, 15, 47, 59, 60, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "widget": [7, 10, 11, 12, 13, 14, 15, 28, 47, 59, 60, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "ipython": [7, 9, 10, 11, 12, 13, 14, 15, 47, 59, 60, 90, 94, 97, 102, 103, 105], "displai": [7, 9, 10, 11, 12, 13, 14, 15, 26, 42, 47, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "youtubevideo": [7, 11, 12, 13, 14, 15, 47, 59, 60], "ifram": [7, 10, 11, 12, 13, 14, 15, 47, 59, 60], "class": [7, 11, 12, 13, 14, 15, 27, 33, 44, 47, 102, 103, 118, 119, 120, 123], "playvideo": [7, 11, 12, 13, 14, 15, 47], "def": [7, 9, 10, 11, 12, 13, 14, 15, 25, 47, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "__init__": [7, 9, 11, 12, 13, 14, 15, 47, 94, 97, 105], "id": [7, 11, 12, 13, 14, 15, 47, 102, 105], "page": [7, 9, 10, 11, 12, 13, 14, 15, 24, 25, 32, 34, 35, 36, 47, 65, 74, 81, 102, 115], "width": [7, 11, 12, 13, 14, 15, 47, 56, 57, 64, 68, 69, 85, 102, 103, 105], "400": [7, 11, 12, 13, 14, 15, 47, 56, 57, 68, 69, 80], "height": [7, 11, 12, 14, 15, 24, 44, 47, 56, 57, 59, 61, 64, 65, 68, 69, 85, 87, 89, 105, 112, 113, 114, 119, 120], "300": [7, 11, 12, 13, 14, 15, 47, 56, 64, 65, 75, 85, 88, 91, 102, 103, 120], "kwarg": [7, 9, 10, 11, 12, 13, 14, 15, 47, 59, 91, 94, 95, 96, 97, 98, 99, 105, 115], "bilibili": [7, 11, 12, 13, 14, 15, 47], "src": [7, 11, 12, 13, 14, 15, 47], "f": [7, 10, 11, 12, 13, 14, 15, 22, 25, 27, 47, 58, 74, 76, 78, 81, 82, 86, 87, 88, 96, 98, 99, 101, 102, 103, 120], "http": [7, 9, 10, 11, 12, 13, 14, 15, 21, 22, 25, 26, 27, 33, 34, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52, 56, 57, 58, 59, 60, 61, 63, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 117, 118, 119, 120], "player": [7, 11, 12, 13, 14, 15, 47], "com": [7, 9, 10, 11, 12, 13, 14, 15, 25, 33, 34, 47, 52, 57, 66, 67, 68, 69, 70, 71, 74, 79, 80, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "html": [7, 11, 12, 13, 14, 15, 25, 47, 52, 58, 60, 61, 90, 102, 103, 105, 117], "bvid": [7, 11, 12, 13, 14, 15, 47], "elif": [7, 11, 12, 13, 14, 15, 47, 88, 102, 103, 105], "osf": [7, 9, 11, 12, 13, 14, 15, 25, 35, 47, 58, 59, 60, 61, 69, 70, 76, 78, 81, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "mfr": [7, 11, 12, 13, 14, 15, 47], "ca": [7, 11, 12, 13, 14, 15, 47], "io": [7, 9, 11, 12, 13, 14, 15, 25, 33, 35, 47, 58, 59, 60, 61, 69, 70, 74, 76, 78, 81, 89, 90, 102, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 117, 119, 120, 123], "render": [7, 11, 12, 13, 14, 15, 47], "url": [7, 11, 12, 13, 14, 15, 47, 74, 75, 76, 77, 80, 102, 105], "download": [7, 9, 11, 12, 13, 14, 15, 25, 35, 44, 47, 56, 57, 58, 59, 60, 61, 69, 70, 74, 75, 76, 77, 78, 80, 81, 82, 89, 90, 91, 102, 105, 108, 109, 110, 111, 112, 113, 119, 120], "26mode": [7, 11, 12, 13, 14, 15, 47], "super": [7, 11, 12, 13, 14, 15, 47], "display_video": [7, 11, 12, 13, 14, 15, 47], "video_id": [7, 11, 12, 13, 14, 15, 47], "w": [7, 10, 11, 12, 13, 14, 15, 25, 43, 44, 47, 63, 71, 75, 80, 85, 86, 87, 88, 91, 95, 101, 102, 107, 118], "fs": [7, 11, 12, 13, 14, 15, 47, 66, 67, 68, 71, 73], "tab_cont": [7, 11, 12, 13, 14, 15, 47], "enumer": [7, 10, 11, 12, 13, 14, 15, 47, 67, 70, 74, 76, 87, 88, 96, 98, 99, 102, 105, 110], "output": [7, 9, 11, 12, 13, 14, 15, 46, 47, 59, 66, 67, 68, 69, 70, 71, 76, 78, 80, 85, 86, 87, 89, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 110, 111, 113, 114, 118, 119, 120, 122], "0": [7, 9, 10, 11, 13, 14, 15, 25, 28, 42, 43, 44, 47, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "youtub": [7, 11, 12, 13, 14, 15, 47], "print": [7, 9, 10, 11, 12, 13, 14, 15, 25, 47, 57, 67, 70, 71, 74, 76, 78, 85, 86, 87, 88, 89, 94, 97, 105, 111, 113, 114, 115, 118, 119, 120, 123], "v": [7, 10, 11, 12, 13, 14, 15, 44, 47, 56, 57, 58, 59, 68, 69, 70, 71, 74, 75, 81, 101, 103, 107, 114], "els": [7, 8, 9, 10, 11, 12, 13, 14, 15, 25, 47, 57, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 88, 89, 90, 94, 97, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120, 121], "autoplai": [7, 11, 12, 13, 14, 15, 47], "fals": [7, 9, 11, 12, 13, 14, 15, 25, 44, 47, 49, 58, 66, 79, 88, 94, 97, 102, 103, 105, 113, 115, 119, 120], "www": [7, 9, 11, 12, 13, 14, 15, 25, 26, 47, 52, 73, 75, 77, 82, 102, 107, 117], "append": [7, 11, 12, 13, 14, 15, 47, 61, 76, 87, 88, 90, 96, 97, 98, 99, 105, 111, 113, 120], "jopepquxmbu": 7, "bv1jw4y1z7zb": 7, "730": [7, 11, 12, 13, 14, 15, 47], "410": [7, 11, 12, 13, 14, 15, 47], "tab": [7, 11, 12, 13, 14, 15, 47, 105], "children": [7, 11, 12, 13, 14, 15, 47], "set_titl": [7, 9, 10, 11, 12, 13, 14, 15, 47, 58, 60, 61, 67, 68, 69, 71, 74, 82, 85, 88, 89, 90, 91, 94, 105, 113, 114, 115, 118, 119, 120], "veronica": 7, "off": [7, 14, 45, 86, 88, 89, 90, 94, 101, 103, 105, 118, 120], "she": 7, "advantag": [7, 15, 22, 34, 43, 66, 67, 68, 82, 98, 123], "disadvantag": [7, 22], "definit": [7, 65, 75, 87, 90, 101, 103], "widen": [7, 105, 112], "deepen": [7, 47, 64], "inequ": [7, 21, 27, 102], "boundari": [7, 56, 67, 97, 98, 102, 118], "wider": [7, 22, 110], "seen": [7, 15, 44, 47, 65, 74, 79, 85, 94, 97, 98, 99, 102, 113, 114, 118, 119, 120], "yet": [7, 12, 43, 66, 90], "challeng": [7, 8, 21, 22, 23, 42, 65, 74, 102, 103, 110, 112, 115, 121, 123], "sometim": [7, 43, 49, 56, 71, 75, 78, 88, 110, 123], "awar": [7, 42, 71, 123], "snowbal": 7, "injustic": 7, "broad": [7, 20], "center": [7, 12, 48, 50, 56, 58, 64, 65, 66, 68, 69, 75, 82, 91, 94, 96, 98, 102, 108, 119, 120], "recogn": [7, 44, 64, 66, 69, 119, 120], "face": [7, 8, 102, 121], "barrier": 7, "elimin": 7, "histor": [7, 9, 10, 11, 12, 14, 22, 47, 57, 69, 71, 75, 87, 91, 95, 96, 97, 98, 102, 103, 115, 118], "organ": [7, 11, 42, 43, 56, 64, 66, 67, 69, 74, 75, 78, 81, 91, 93, 94, 105, 123], "lili": 7, "zheng": 7, "dei": 7, "deconstruct": 7, "her": 7, "thing": [7, 42, 44, 45, 74, 87, 90, 91, 103, 111], "climatewiki": 7, "incred": [7, 85], "platform": [7, 12, 35, 65, 66, 69, 107, 113, 115, 123], "latinamerican": 7, "addition": [7, 26, 28, 39, 40, 58, 67, 78, 89, 102, 112, 113, 120], "hs": 7, "takin": 7, "bad": [7, 15, 27, 45, 66, 103], "inequit": 7, "harass": 7, "sexual": 7, "lastli": [7, 103, 114], "solut": [7, 21, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "inclus": [7, 8, 64, 115], "websit": [7, 9, 10, 11, 13, 14, 15, 33, 56, 63, 89, 90], "instagram": 7, "c5wfuncnwy4": 7, "bv11m4y1e72": 7, "mention": [7, 105, 123], "cultur": [7, 27, 64], "still": [7, 8, 22, 35, 42, 57, 66, 74, 78, 94, 102, 103, 105, 118], "regard": [7, 20, 21, 22, 23, 64, 71, 102, 103, 105, 123], "job": [7, 118], "behavior": [7, 88, 89, 102, 103, 110], "home": [7, 9, 10, 11, 12, 13, 14, 15, 25, 35, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "Is": [7, 59, 80, 81, 85, 86, 87, 91, 94, 95, 97], "tradit": [7, 42, 102, 120, 123], "indigen": [7, 21], "movement": [7, 44, 56, 58, 59, 60, 64], "Its": [7, 15, 42], "openli": [7, 11, 65, 102, 105], "model": [7, 10, 11, 12, 13, 14, 22, 23, 24, 25, 26, 28, 42, 44, 45, 53, 54, 56, 57, 61, 64, 65, 68, 70, 78, 82, 86, 88, 93, 95, 107, 108, 109, 110, 111, 112, 113, 114, 115, 121, 122], "benefit": [7, 11, 36, 44, 64, 65, 89, 103], "brazil": [7, 12], "instituto": 7, "nacion": 7, "de": [7, 13, 14], "pesquisa": 7, "espaciai": 7, "inp": 7, "trust": [7, 9], "audit": 7, "reproduc": [7, 58, 78, 87, 96, 119, 120], "brazilian": 7, "expertis": 7, "remot": [7, 12, 14, 15, 28, 55, 63, 65, 66, 67, 68, 69, 70, 71, 118, 122], "softwar": [7, 123], "todai": [7, 10, 11, 12, 13, 14, 15, 39, 40, 42, 54, 55, 64, 77, 80, 81, 84, 89, 91, 94, 95, 96, 98, 99, 102, 112, 113], "cube": 7, "deforest": 7, "dissemin": [7, 65], "gi": 7, "github": [7, 35, 60, 61, 94, 95, 98, 102, 103, 105, 114, 115, 123], "l\u00fabia": 7, "portugues": 7, "g2upxzxxlrc": 7, "bv1hz4y177fn": 7, "fight": 7, "prevent": [7, 9, 94, 97, 105, 119, 120], "ethic": [7, 121], "manag": [7, 10, 11, 14, 64, 102, 105, 120], "increas": [7, 44, 56, 57, 61, 67, 68, 70, 75, 78, 80, 81, 82, 87, 88, 101, 102, 103, 107, 110, 112, 114, 115, 118, 119, 120], "therefor": [7, 10, 25, 43, 44, 47, 56, 65, 66, 74, 75, 76, 86, 102, 105, 110, 113, 114, 118, 119, 120], "central": [7, 9, 13, 15, 44, 50, 56, 57, 69, 70, 75, 76, 102, 103, 105, 111, 113], "led": [7, 85, 108], "respond": [7, 56, 64, 102], "re": [7, 24, 25, 42, 44, 45, 46, 64, 66, 67, 77, 78, 79, 80, 81, 88, 89, 91, 95, 102, 103, 105, 108, 111, 123], "emerg": 7, "explan": [7, 70, 88, 94], "quirki": 7, "flaw": 7, "cognit": 7, "tendenc": 7, "reward": [7, 103], "satisfact": [7, 103], "overli": [7, 103], "optimist": [7, 103], "decreas": [7, 44, 56, 61, 68, 70, 78, 80, 81, 86, 88, 89, 101, 102, 103, 112, 115, 119, 120], "sensit": [7, 10, 74, 102, 103, 120], "threat": [7, 102], "narr": [7, 102, 105], "problemat": [7, 85], "essenti": [7, 12, 21, 61, 63, 64, 65, 66, 68, 78, 81, 94, 95, 102, 111, 118, 123], "justifi": 7, "inevit": 7, "product": [7, 9, 11, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 74, 75, 76, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122], "natur": [7, 11, 14, 39, 40, 45, 52, 64, 75, 77, 78, 80, 81, 82, 91, 95, 101, 102, 103, 105, 107, 118], "focus": [7, 11, 14, 25, 42, 46, 47, 56, 71, 77, 81, 91, 95, 96, 105, 108, 112, 113, 118, 119, 120, 123], "norm": [7, 27, 67, 101, 108, 110], "perceiv": [7, 64], "belief": 7, "shape": [7, 9, 12, 15, 47, 49, 59, 60, 67, 68, 69, 70, 71, 87, 88, 94, 108, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "influenc": [7, 9, 10, 15, 20, 24, 39, 40, 47, 54, 56, 58, 59, 60, 64, 65, 67, 69, 70, 79, 80, 87, 95, 98, 102, 110, 112, 118, 119], "industri": [7, 8, 47, 64, 85, 87, 101, 102, 103, 113, 121], "maker": [7, 8, 121], "neuroscientist": 7, "push": [7, 15], "undergradu": 7, "brought": [7, 49, 65], "fire": [7, 15, 65], "doughnut": 7, "rethink": 7, "academia": [7, 8], "abridg": 7, "articl": [7, 10, 52, 102], "zehobxg61ru": 7, "bv1su4y1u7ak": 7, "crise": 7, "visual": [7, 9, 10, 11, 12, 15, 40, 45, 47, 56, 58, 59, 65, 68, 69, 70, 75, 78, 80, 82, 85, 89, 91, 95, 98, 105, 108, 109, 110, 111, 112, 113, 114, 118, 123], "blog": [7, 27], "song": 7, "stigma": 7, "disciplin": [8, 123], "profit": [8, 102], "journal": [8, 11, 14, 15, 21, 22, 26, 27], "hope": [8, 18, 35], "messag": [8, 21, 36, 74, 105, 120], "opinion": 8, "qualif": 8, "succe": 8, "biggest": 8, "obstacl": 8, "enter": [8, 36], "explain": [8, 18, 22, 46, 65, 70, 78, 95, 103], "decis": [8, 64, 65, 103, 118, 121], "concern": [8, 19, 21, 102, 113], "method": [8, 10, 11, 14, 20, 21, 25, 44, 46, 47, 49, 50, 56, 57, 60, 65, 67, 68, 71, 75, 76, 78, 79, 80, 87, 88, 91, 94, 95, 102, 105, 109, 110, 111, 115, 118, 121, 122], "shed": 8, "light": [8, 15, 64, 75, 79, 85, 90], "interdisciplinari": [8, 12, 107], "actualis": 8, "major": [8, 44, 64, 65, 67, 68, 69, 70, 73, 81, 102, 120], "anticip": [8, 111], "tradition": 8, "under": [8, 9, 11, 12, 56, 59, 86, 88, 91, 94, 95, 96, 97, 102, 103, 105, 109, 113, 115, 118, 123], "repres": [8, 10, 11, 12, 20, 21, 22, 23, 24, 25, 26, 27, 42, 46, 57, 58, 61, 64, 65, 66, 68, 71, 75, 79, 82, 85, 86, 87, 88, 89, 95, 98, 99, 102, 105, 108, 109, 111, 113, 115, 118, 119, 120], "intern": [8, 11, 14, 15, 105, 119], "advanc": [8, 11, 12, 14, 20, 22, 36, 40, 64, 65, 67, 74, 78, 102, 107, 123], "skeptic": 8, "prior": [8, 33, 65, 123], "lessen": [8, 102], "mente": 8, "love": [8, 105], "willing": 8, "upgrad": [8, 65], "cherish": 8, "demonstr": [8, 15, 48, 49, 56, 57, 61, 66, 67, 91, 96, 105], "punctual": 8, "show": [8, 13, 15, 44, 46, 57, 58, 59, 60, 61, 65, 66, 67, 68, 69, 75, 82, 85, 88, 89, 91, 94, 95, 97, 99, 102, 103, 109, 111, 113, 118, 119, 120], "guidanc": [8, 21], "typic": [8, 14, 15, 21, 22, 44, 49, 56, 59, 61, 64, 65, 67, 70, 71, 74, 78, 91, 96, 101, 103, 110, 111, 119], "behav": [8, 85, 88, 110, 118], "moral": 8, "honestli": 8, "integr": [8, 11, 13, 14, 15, 33, 59, 61, 85, 95, 102, 113, 114, 121, 122, 123], "enjoi": [8, 123], "touch": [8, 91], "content": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "creator": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "olawal": 9, "ikuyajolu": 9, "patrick": 9, "orenstein": 9, "marguerit": [9, 12, 20, 21, 22, 23, 24, 25, 26, 27], "brown": [9, 12, 15, 20, 21, 22, 23, 24, 25, 26, 27, 103], "yuxin": [9, 20, 21, 22, 23, 24, 25, 26, 27], "zhou": [9, 20, 21, 22, 23, 24, 25, 26, 27], "editor": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 36, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "zane": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27], "mitrevica": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27], "natali": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27], "steinemann": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27], "jenna": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "pearson": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "chi": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "zhang": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "ohad": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "zivan": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "weslei": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "banfield": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "sponsor": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "deepmind": [9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "reanalysi": [9, 13, 14, 22, 28, 53, 54, 55, 56, 58, 60, 61, 69, 89, 90, 122], "cmip5": [9, 11, 87], "era5": [9, 54, 58, 59], "noaa": [9, 13, 22, 52, 67, 68, 69, 71, 73, 75, 77, 82, 96], "hadisst": [9, 99], "surfac": [9, 15, 20, 22, 25, 26, 44, 45, 49, 54, 56, 61, 65, 66, 68, 69, 70, 75, 81, 82, 85, 86, 87, 88, 89, 90, 94, 96, 97, 99, 102, 112, 113, 114, 115], "air": [9, 10, 11, 14, 25, 44, 56, 58, 64, 65, 74, 82, 85, 87, 89, 90, 91, 95, 113, 114, 115], "investig": [9, 10, 11, 12, 14, 23, 40, 41, 54, 57, 58, 64, 67, 70, 75, 76, 77, 87, 88, 102, 105, 112, 113], "phase": [9, 11, 50, 56, 69, 70, 75, 91, 93, 115], "recal": [9, 11, 12, 13, 14, 44, 45, 46, 56, 58, 61, 67, 75, 76, 77, 78, 80, 85, 86, 96, 102, 103, 105, 108, 120], "w1d1": [9, 28, 56, 96, 102], "tropic": [9, 11, 15, 22, 45, 50, 64, 67, 68, 69, 70, 75, 78, 91], "pacif": [9, 45, 50, 57, 58, 69, 70, 75, 76], "circul": [9, 13, 22, 45, 50, 53, 54, 56, 61, 64, 67, 69, 80, 90, 91], "warmer": [9, 46, 49, 50, 56, 61, 69, 70, 75, 77, 80, 90, 91, 115], "sst": [9, 11, 25, 45, 46, 47, 48, 49, 50, 53, 54, 64, 70, 75, 76, 91, 97, 98], "eastern": [9, 45, 50, 56, 69, 70, 75], "la": [9, 50, 53, 54, 69, 70, 75], "ni\u00f1a": [9, 50, 53, 54, 69, 70, 75], "cooler": [9, 46, 50, 56, 69, 75, 77, 80, 82], "w1d5": [9, 14, 28, 81], "w2d1": [9, 10, 11, 14, 28, 56, 81, 91, 96], "w2d4": [9, 28], "scenario": [9, 10, 11, 48, 94, 96, 97, 103, 110, 115, 118], "colab": [9, 10, 11, 14, 35, 36, 67, 68, 70, 71, 119, 120], "instal": [9, 10, 11, 14, 15, 35, 36, 66, 67, 68, 69, 70, 71, 89, 90, 91, 94, 95, 96, 97, 98, 99, 113, 114, 115, 120, 123], "pip": [9, 10, 14, 15, 35, 36, 66, 67, 68, 69, 70, 71, 89, 90, 91, 94, 95, 96, 97, 98, 99, 113, 114, 115, 120], "condacolab": [9, 10, 89, 90, 91, 94, 95, 96, 97, 98, 99, 113, 114, 115], "dev": [9, 13, 35, 67, 68, 69, 70, 71, 89, 90, 91, 94, 95, 96, 97, 98, 99], "null": [9, 89, 90, 91, 94, 95, 96, 97, 98, 99, 119], "packag": [9, 11, 35, 36, 40, 42, 57, 60, 70, 74, 75, 80, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 105, 110, 114, 119, 123], "mamba": [9, 10, 89, 90, 91, 94, 95, 96, 97, 98, 99, 114], "conda": [9, 89, 90, 91, 94, 95, 96, 97, 98, 99], "xarrai": [9, 10, 11, 12, 13, 14, 39, 40, 42, 43, 45, 47, 49, 50, 53, 54, 57, 58, 66, 67, 68, 69, 70, 71, 78, 81, 82, 86, 87, 88, 89, 90, 96, 97, 98, 111, 113, 115, 120, 122, 123], "datatre": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "intak": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99, 114], "esm": [9, 10, 91, 95, 96, 97, 98, 99, 102, 114], "gcsf": [9, 10, 91, 94, 95, 96, 97, 98, 99], "xmip": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99, 114], "aiohttp": [9, 10, 91, 94, 95, 96, 97, 98, 99], "cartopi": [9, 10, 14, 44, 58, 60, 61, 66, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 81, 82, 91, 94, 112, 113, 114, 115, 123], "nc": [9, 10, 11, 12, 13, 14, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 82, 89, 90, 91, 94, 95, 96, 97, 98, 99, 113, 115, 120], "axi": [9, 10, 24, 25, 43, 44, 56, 58, 67, 68, 70, 75, 76, 77, 78, 79, 80, 81, 85, 88, 89, 91, 94, 95, 96, 97, 98, 99, 102, 105, 108, 109, 111, 113, 114, 115, 118, 119, 120], "cf_xarrai": [9, 10, 91, 94, 95, 96, 97, 98, 99, 114], "xarrayutil": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99, 114], "esmf": [9, 10, 94], "xesmf": [9, 10, 94], "tic": [9, 10, 94, 95, 96, 97, 98, 99], "numpi": [9, 10, 11, 12, 13, 14, 15, 45, 50, 66, 68, 69, 70, 71, 74, 75, 76, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "np": [9, 10, 11, 12, 13, 14, 25, 42, 43, 57, 58, 66, 68, 69, 70, 71, 74, 75, 76, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "matplotlib": [9, 10, 11, 12, 13, 14, 15, 42, 44, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "pyplot": [9, 10, 11, 12, 13, 14, 15, 42, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "plt": [9, 10, 11, 12, 13, 14, 15, 25, 42, 47, 48, 49, 56, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "xr": [9, 10, 11, 12, 13, 14, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 81, 82, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 111, 113, 115, 120], "xe": [9, 10, 94], "preprocess": [9, 10, 14, 60, 61, 91, 94, 95, 96, 97, 98, 99, 112, 114], "combined_preprocess": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "shaded_line_plot": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "postprocess": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "_parse_metr": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "cr": [9, 10, 14, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 80, 82, 91, 94, 112, 113, 115], "ccr": [9, 10, 14, 56, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 82, 91, 94, 112, 113, 115], "pooch": [9, 10, 11, 12, 13, 14, 15, 25, 58, 59, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 91, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "os": [9, 10, 11, 12, 13, 14, 15, 25, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 91, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "tempfil": [9, 10, 11, 12, 13, 14, 25, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "modulenotfounderror": [9, 10, 11, 12, 13, 14, 15, 59, 60, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "traceback": [9, 10, 11, 12, 13, 14, 15, 59, 60, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "cell": [9, 10, 11, 12, 13, 14, 15, 43, 47, 56, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "line": [9, 10, 11, 12, 13, 14, 15, 26, 43, 44, 56, 57, 58, 59, 60, 61, 65, 66, 67, 68, 69, 70, 71, 74, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "7": [9, 10, 11, 12, 13, 14, 15, 18, 27, 28, 45, 46, 47, 58, 60, 61, 66, 67, 68, 69, 71, 74, 75, 76, 77, 78, 79, 81, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 115, 118, 119, 120, 123], "No": [9, 10, 11, 12, 13, 14, 15, 28, 59, 60, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "modul": [9, 10, 11, 12, 13, 14, 15, 36, 59, 60, 64, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122], "function": [9, 10, 11, 12, 13, 14, 25, 40, 42, 44, 45, 46, 49, 56, 57, 58, 59, 60, 61, 64, 66, 67, 68, 69, 70, 71, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 91, 95, 101, 105, 108, 109, 110, 111, 112, 115, 118, 119, 123], "inlin": [9, 10, 94, 95, 96, 97, 98, 99, 102, 103, 105, 118, 119, 120], "col": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "open_esm_datastor": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "storag": [9, 10, 12, 14, 53, 61, 66, 91, 94, 95, 96, 97, 98, 99], "googleapi": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "pangeo": [9, 10, 11, 13, 14, 22, 58, 91, 94, 95, 96, 97, 98, 99, 107, 113, 115], "json": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99, 105], "catalog": [9, 10, 11, 14, 58, 71, 91, 94, 95, 96, 97, 98, 99], "contain": [9, 10, 11, 12, 13, 14, 15, 21, 22, 27, 35, 36, 44, 45, 47, 49, 57, 60, 61, 64, 66, 67, 68, 74, 75, 78, 79, 82, 84, 88, 89, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 110, 113, 119, 120], "cloud": [9, 10, 11, 12, 13, 14, 15, 35, 65, 66, 86, 90, 91, 94, 95, 96, 97, 98, 99, 113, 115], "load_cmip6": 9, "source_id": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "variable_id": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "member_id": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "table_id": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "cat": [9, 10, 14, 91, 94, 95, 96, 97, 99], "grid_label": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "gn": [9, 10, 91, 94, 95, 96, 97, 98, 99], "experiment_id": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "ssp126": [9, 91, 95, 96, 97, 98, 99, 113, 115], "ssp245": [9, 113, 115], "ssp585": [9, 91, 94, 95, 96, 97, 98, 99, 113, 115], "require_all_on": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "dict": [9, 10, 14, 67, 68, 69, 70, 71, 88, 91, 94, 95, 96, 97, 98, 99, 102, 105, 113, 115, 120], "xarray_open_kwarg": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "use_cftim": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "storage_opt": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "token": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99, 105], "anon": [9, 10, 12, 14, 66, 67, 68, 71, 91, 94, 95, 96, 97, 98, 99], "esmcat": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "aggregation_control": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "groupby_attr": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "dt": [9, 10, 46, 71, 87, 88, 91, 94, 95, 96, 97, 98, 99], "to_datatre": [9, 10, 14, 91, 94, 95, 96, 97, 98, 99], "get_ipython": [9, 10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "run_line_mag": [9, 10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "file": [9, 10, 11, 12, 13, 14, 25, 34, 42, 44, 56, 57, 58, 61, 66, 67, 68, 69, 70, 71, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 91, 94, 95, 97, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "librari": [9, 10, 15, 44, 66, 67, 76, 77, 94, 97, 98, 99, 105, 109, 115, 118, 119, 120], "framework": [9, 13, 94, 97, 102, 105, 119, 122], "python": [9, 10, 25, 35, 36, 40, 42, 43, 58, 60, 66, 67, 68, 69, 70, 71, 75, 76, 81, 85, 86, 88, 89, 90, 94, 97, 102, 103, 105, 114, 118, 122, 123], "lib": [9, 94, 97, 105], "python3": [9, 67, 68, 69, 70, 71, 94, 97, 105], "core": [9, 22, 25, 58, 64, 74, 76, 77, 78, 94, 95, 97, 105, 123], "interactiveshel": [9, 94, 97, 105], "py": [9, 15, 94, 97, 103, 105, 115], "2417": [9, 94, 97, 105], "magic_nam": [9, 94, 97, 105], "_stack_depth": [9, 94, 97, 105], "2415": [9, 94, 97, 105], "local_n": [9, 94, 97, 105], "get_local_scop": [9, 94, 97, 105], "stack_depth": [9, 94, 97, 105], "2416": [9, 94, 97, 105], "builtin_trap": [9, 94, 97, 105], "fn": [9, 94, 97, 105], "arg": [9, 94, 97, 105, 120], "2419": [9, 94, 97, 105], "2420": [9, 94, 97, 105], "decod": [9, 82, 89, 90, 94, 97, 105], "output_can_be_silenc": [9, 94, 97, 105], "2421": [9, 94, 97, 105], "express": [9, 11, 49, 50, 60, 64, 85, 87, 88, 94, 97, 101, 105, 123], "2422": [9, 94, 97, 105], "getattr": [9, 94, 97, 105], "magic_output_can_be_silenc": [9, 94, 97, 105], "pylab": [9, 94, 97, 105], "99": [9, 21, 71, 94, 97, 105, 111], "pylabmag": [9, 94, 97, 105], "97": [9, 10, 78, 94, 97, 102, 105], "backend": [9, 94, 97, 105], "backends_list": [9, 94, 97, 105], "98": [9, 94, 97, 105], "gui": [9, 94, 97, 105], "shell": [9, 11, 25, 94, 97, 105], "enable_matplotlib": [9, 94, 97, 105], "lower": [9, 44, 57, 60, 61, 68, 69, 74, 76, 77, 79, 82, 85, 86, 87, 88, 90, 94, 97, 98, 102, 103, 105, 110, 111, 114, 115, 119, 120], "isinst": [9, 94, 97, 105], "str": [9, 12, 70, 71, 74, 76, 85, 88, 94, 97, 102, 103, 105, 118, 120], "100": [9, 13, 14, 15, 60, 61, 64, 77, 79, 80, 82, 85, 86, 88, 91, 94, 96, 97, 102, 103, 105, 108, 109, 110, 111, 113, 114, 115, 118], "_show_matplotlib_backend": [9, 94, 97, 105], "3588": [9, 94, 97, 105], "3567": [9, 94, 97, 105], "none": [9, 10, 11, 12, 13, 14, 25, 36, 58, 59, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 89, 90, 94, 97, 99, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "3568": [9, 94, 97, 105], "3569": [9, 94, 97, 105], "3570": [9, 94, 97, 105], "3586": [9, 94, 97, 105], "3587": [9, 94, 97, 105], "matplotlib_inlin": [9, 94, 97, 105], "backend_inlin": [9, 94, 97, 105], "configure_inline_support": [9, 94, 97, 105], "3590": [9, 94, 97, 105], "pylabtool": [9, 94, 97, 105], "pt": [9, 94, 97, 105], "3591": [9, 94, 97, 105], "find_gui_and_backend": [9, 94, 97, 105], "pylab_gui_select": [9, 94, 97, 105], "config": [9, 10, 12, 57, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 114, 115], "noqa": [9, 94, 97, 105], "__version__": [9, 94, 97, 105], "publish": [9, 63, 94, 97, 105], "display_data": [9, 94, 97, 105], "copyright": [9, 94, 97, 102, 105], "bsd": [9, 94, 97, 105], "claus": [9, 94, 97, 105], "licens": [9, 87, 94, 97, 105], "color": [9, 15, 25, 49, 56, 58, 59, 60, 61, 64, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 81, 82, 85, 88, 89, 90, 91, 94, 97, 98, 99, 102, 103, 105, 108, 110, 112, 113, 115, 118, 119, 120], "backend_agg": [9, 94, 97, 105], "helper": [9, 10, 11, 12, 13, 14, 25, 58, 66, 67, 68, 69, 70, 71, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 105, 108, 109, 110, 111, 112, 115, 119, 120], "pooch_load": [9, 10, 11, 12, 13, 14, 25, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "fileloc": [9, 10, 11, 12, 13, 14, 25, 57, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "filenam": [9, 10, 11, 12, 13, 14, 15, 25, 57, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "processor": [9, 10, 11, 12, 13, 14, 25, 58, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "shared_loc": [9, 10, 11, 12, 13, 14, 25, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "jovyan": [9, 10, 11, 12, 13, 14, 15, 25, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "user_temp_cach": [9, 10, 11, 12, 13, 14, 25, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "gettempdir": [9, 10, 11, 12, 13, 14, 25, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "retriev": [9, 10, 11, 12, 13, 14, 15, 25, 57, 58, 59, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 91, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "known_hash": [9, 10, 11, 12, 13, 14, 25, 58, 59, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "fname": [9, 10, 11, 12, 13, 14, 25, 58, 59, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 102, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "cesm2": [9, 45, 46, 47, 48, 49, 50, 53, 54, 56, 91], "ensembl": [9, 10, 11, 13, 14, 81, 85, 87, 94, 99, 108, 111, 113, 115, 119], "r4i1p1f1": [9, 98], "facet": [9, 10, 14, 64, 91, 94, 95, 96, 97, 99], "link": [9, 12, 13, 14, 15, 28, 30, 44, 48, 57, 63, 65, 74, 80, 84, 91, 102, 103, 123], "bank": [9, 11, 12, 14, 56], "dm_ta": 9, "amon": [9, 14, 91], "atmoerhper": 9, "tempratur": [9, 11, 14, 56, 60, 82, 90], "dm_pr": 9, "pr": [9, 12, 14, 113], "rate": [9, 11, 15, 47, 59, 61, 64, 71, 77, 87, 88, 89, 90, 99, 101, 102, 120], "dm_sst": 9, "tos": [9, 45, 46, 47, 48, 49, 50, 56, 91, 94, 95, 96, 97, 98, 99], "omon": [9, 91, 94, 95, 96, 97, 98, 99], "duplic": [9, 109, 111, 113], "nameerror": [9, 10, 11, 12, 13, 14, 15, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "11": [9, 10, 11, 12, 14, 15, 58, 60, 61, 63, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "temparut": 9, "dt_ocean_area": 9, "areacello": [9, 47, 56, 95, 96, 97, 98, 99], "ofx": [9, 95, 96, 97, 98, 99], "dt_atmos_area": 9, "areacella": [9, 14], "fx": [9, 14], "dt_ocean_with_area": 9, "dt_atmos_with_area": 9, "subtre": [9, 95, 96, 97, 98, 99], "metric_ocean": 9, "ds": [9, 10, 12, 13, 14, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 66, 67, 68, 69, 71, 82, 89, 90, 91, 94, 95, 96, 97, 98, 99], "map_over_subtre": [9, 91, 95, 96, 97, 98, 99], "metric_atmo": 9, "ersst": 9, "v5": [9, 57], "wide": [9, 10, 11, 15, 18, 57, 71, 89, 90, 118, 123], "grid": [9, 11, 12, 13, 14, 25, 42, 44, 47, 56, 57, 59, 61, 65, 66, 67, 68, 69, 79, 89, 90, 91, 94, 95, 99, 102, 103, 105, 108, 109, 110, 111, 114, 115, 119, 120], "compil": [9, 26, 67, 74, 105], "1854": [9, 21], "opendap": 9, "cpc": 9, "merg": [9, 14, 36, 46, 56, 57, 65], "cmap": [9, 10, 15, 45, 46, 56, 57, 58, 60, 61, 68, 69, 70, 75, 82, 91, 94, 115, 118, 120], "psl": 9, "boulder": [9, 43], "colorado": [9, 43, 44], "usa": [9, 12, 13, 15, 43, 44, 96, 102], "gov": [9, 11, 13, 52, 73, 75, 77, 82], "anomali": [9, 15, 54, 66, 67, 71, 75, 81, 87, 94, 96, 97, 98, 99, 114, 119], "giss": [9, 81], "filename_sst": [9, 11], "mnmean": 9, "url_sst": [9, 11, 69], "do_sst": 9, "open_dataset": [9, 11, 13, 14, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 60, 61, 66, 67, 69, 70, 71, 82, 89, 90, 99, 113, 115, 120], "drop_vari": 9, "time_bnd": 9, "filename_prec_r": 9, "precip": [9, 12, 67, 68, 70, 71, 75, 108, 109, 110, 113], "mon": [9, 11, 68, 69, 89, 90], "url_prec_r": 9, "enh": 9, "do_pr": 9, "filename_ta": 9, "2x2": 9, "1200": 9, "anom": [9, 96], "comb": 9, "url_ta": 9, "gistemp": 9, "combin": [9, 11, 12, 13, 14, 15, 25, 42, 43, 47, 50, 56, 57, 59, 64, 65, 66, 67, 68, 71, 75, 77, 78, 82, 87, 101, 103, 107, 108, 109, 110, 111, 112, 115, 119], "1200km": 9, "do_ta": 9, "arrai": [9, 12, 15, 40, 43, 44, 45, 49, 65, 66, 67, 70, 74, 86, 87, 88, 89, 90, 91, 94, 105, 108, 111, 113, 114, 118, 119, 120], "hist_precip": 9, "fig": [9, 10, 25, 49, 56, 57, 58, 59, 60, 61, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "ax_july2000": 9, "subplot": [9, 10, 25, 49, 57, 58, 59, 60, 61, 67, 68, 69, 70, 71, 78, 79, 82, 85, 86, 87, 88, 89, 91, 94, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "ncol": [9, 49, 67, 70, 74, 76, 91, 94], "nrow": [9, 67, 70, 91, 94], "figsiz": [9, 10, 49, 56, 57, 58, 59, 60, 61, 67, 68, 69, 70, 71, 74, 75, 76, 82, 89, 90, 91, 94, 102, 103, 105, 113, 115, 118, 119, 120], "12": [9, 10, 11, 12, 14, 15, 46, 47, 48, 56, 57, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 81, 82, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 122, 123], "subplot_kw": [9, 10, 59, 60, 61, 67, 69, 70, 71, 82, 91, 94, 115], "robinson": [9, 10, 56, 59, 67, 68, 69, 70, 74, 75, 76, 82, 91, 94, 115, 123], "sel": [9, 10, 12, 44, 46, 47, 49, 56, 57, 58, 61, 67, 68, 69, 70, 71, 75, 82, 94, 96, 97, 98, 99, 113, 115], "2000": [9, 12, 46, 47, 49, 56, 61, 64, 65, 68, 69, 75, 76, 81, 103], "07": [9, 10, 12, 43, 63, 66, 70, 79, 94, 102], "squeez": [9, 10, 14, 91, 94, 97, 98, 99], "ax": [9, 10, 25, 42, 43, 44, 49, 56, 57, 58, 59, 60, 61, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "x": [9, 10, 12, 13, 14, 15, 24, 25, 44, 56, 57, 58, 61, 64, 65, 67, 68, 70, 75, 76, 77, 78, 79, 81, 82, 85, 88, 91, 94, 95, 96, 97, 98, 99, 101, 102, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "lon": [9, 14, 42, 43, 44, 45, 46, 47, 48, 50, 56, 57, 58, 59, 61, 69, 71, 76, 82, 89, 90, 91, 94, 99, 115], "y": [9, 12, 13, 14, 15, 22, 24, 25, 44, 56, 57, 61, 66, 67, 68, 69, 70, 71, 76, 78, 79, 80, 82, 89, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 118, 119, 120], "lat": [9, 14, 42, 43, 44, 45, 46, 47, 48, 50, 56, 57, 59, 61, 69, 71, 76, 82, 89, 90, 91, 94, 99, 115], "transform": [9, 10, 12, 46, 56, 58, 67, 68, 69, 70, 71, 74, 75, 76, 79, 80, 82, 91, 94, 102, 105, 115, 118], "platecarre": [9, 10, 56, 57, 58, 60, 61, 67, 68, 69, 70, 71, 75, 76, 82, 91, 94, 115], "magma": [9, 10, 94], "robust": [9, 10, 18, 44, 46, 65, 91, 94, 118], "coastlin": [9, 10, 56, 57, 58, 59, 60, 61, 67, 68, 69, 70, 71, 74, 75, 76, 82, 91, 94, 115], "16": [9, 10, 12, 14, 15, 64, 65, 66, 67, 68, 69, 70, 71, 75, 78, 80, 82, 85, 87, 88, 89, 91, 94, 96, 97, 99, 105, 108, 109, 111, 113, 114, 115, 118, 119, 120, 123], "17": [9, 10, 14, 15, 66, 67, 68, 70, 71, 74, 76, 78, 82, 85, 87, 89, 91, 94, 96, 97, 99, 105, 107, 108, 109, 111, 113, 115, 118, 119, 120], "hist_sst": 9, "central_longitud": [9, 56, 58, 59, 69, 70, 75], "180": [9, 25, 48, 56, 57, 58, 59, 60, 61, 66, 69, 70, 75], "gridlin": [9, 56, 58, 67, 68, 69, 70, 74, 82, 119, 120], "vmin": [9, 45, 56, 60, 61, 66, 67, 68, 69, 70, 71, 91, 94, 115], "vmax": [9, 45, 56, 60, 61, 66, 67, 68, 69, 70, 71, 82, 91, 94, 115], "oni": [9, 56, 69, 75], "5n": [9, 69], "5s": [9, 69], "170w": [9, 69], "120w": [9, 69], "criteria": [9, 12, 66], "exce": [9, 10, 14, 27, 103], "5c": 9, "five": [9, 10, 30, 64, 67, 79, 87, 95, 97, 99, 102], "consecut": [9, 10, 12, 78, 113], "wherea": [9, 42, 64, 71, 75, 78, 80], "4c": 9, "six": [9, 15, 64], "w1d3": [9, 11, 12, 14, 28], "filename_nino": [9, 70], "t6_ocean": [9, 69, 70], "url_nino": [9, 70], "8rwxb": [9, 70], "ocha": 9, "unocha": 9, "org": [9, 10, 11, 13, 14, 15, 21, 22, 25, 26, 27, 33, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 58, 63, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 99, 107, 113], "nina": [9, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 64, 65, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "2020": [9, 11, 14, 15, 65, 67, 69, 87, 103, 107, 112], "09": [9, 49, 70], "volum": [9, 14, 25, 61, 89], "l": [9, 10, 11, 12, 13, 14, 15, 21, 25, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 63, 79, 91, 101, 102, 107], "heureux": 9, "karamperid": 9, "dinezio": 9, "p": [9, 10, 12, 13, 14, 15, 22, 25, 60, 61, 63, 70, 71, 74, 76, 78, 81, 107, 109, 115, 118], "karnauska": 9, "k": [9, 10, 12, 13, 14, 15, 25, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 60, 61, 63, 68, 69, 70, 71, 74, 75, 76, 81, 82, 85, 86, 87, 88, 91, 96, 98, 99, 101, 102, 103, 108, 110, 113, 114, 115, 118, 119], "anyamba": [9, 12], "climatecentr": 9, "matter": [9, 15, 23], "kelli": 9, "economi": [9, 10, 59, 102, 103, 108], "lose": [9, 43, 85, 87, 89], "trillion": 9, "dartmouth": 9, "05": [9, 25, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 59, 60, 61, 65, 66, 113, 114, 120], "simul": [9, 10, 11, 13, 14, 25, 45, 81, 82, 87, 90, 91, 94, 95, 96, 98, 99, 102, 108, 109, 110, 111, 113, 115, 118, 119, 123], "multi": [9, 10, 11, 13, 14, 15, 40, 42, 65, 79, 87, 98, 99, 113, 115, 120, 122], "analyz": [9, 10, 11, 12, 13, 14, 24, 25, 27, 35, 39, 40, 42, 43, 44, 45, 46, 48, 49, 55, 60, 61, 64, 65, 66, 67, 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 91, 94, 95, 96, 97, 98, 102, 103, 105, 108, 112, 113, 114, 115, 120], "galleri": [9, 10, 11, 13, 14, 15], "sara": 10, "shamekh": 10, "ibukun": 10, "joyc": 10, "ogwu": 10, "sloan": [10, 16, 20, 21, 22, 23, 24, 25, 26, 27, 38, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 62, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 92, 94, 95, 96, 97, 98, 99, 100, 102, 103, 105, 106, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122], "garelick": [10, 16, 20, 21, 22, 23, 24, 25, 26, 27, 38, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 62, 72, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 92, 94, 95, 96, 97, 98, 99, 100, 102, 103, 105, 106, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122], "grace": [10, 118, 119, 120, 121], "lindsai": [10, 118, 119, 120, 121], "dougla": [10, 12, 14, 15, 64, 65, 66, 67, 68, 69, 70, 71], "rao": [10, 12, 14, 15, 64, 65, 66, 67, 68, 69, 70, 71], "markdown": [10, 11, 12, 13, 14, 15, 85, 122], "link_id": [10, 11, 12, 13, 14, 15], "wx7tu": 10, "entwin": 10, "constantli": 10, "exchang": 10, "mass": [10, 13, 14, 44, 58, 60, 61, 87, 89, 108], "momentum": 10, "Their": 10, "biolog": [10, 15, 65, 91], "predict": [10, 11, 24, 64, 68, 70, 87, 89, 91, 98, 102, 103, 113, 118, 119, 120, 122], "hazard": [10, 12, 13, 108, 121], "drought": [10, 12, 64, 66, 118, 122], "flood": [10, 58, 64, 103, 108, 109, 118], "fluctuat": [10, 56, 88, 111], "agricultur": [10, 12, 14, 64, 65], "jach": 10, "et": [10, 11, 12, 13, 14, 15, 22, 25, 75, 76, 77, 78, 80, 81, 82, 86, 87, 93, 102, 103, 105, 107], "2022": [10, 11, 13, 14, 21, 22, 27, 65, 70, 71, 82, 84, 102, 105, 108, 109, 110, 111, 112, 114], "2018": [10, 13, 14, 15, 42, 43, 57, 73], "dirmey": 10, "2016": [10, 59, 60, 61, 80, 93, 107], "weather": [10, 11, 12, 15, 21, 22, 58, 64, 65, 67, 69, 90, 94, 103, 107, 118, 119, 120], "crop": [10, 12, 14, 64, 65, 102, 118], "yield": [10, 12, 65, 89, 95, 102, 111, 120], "qualiti": [10, 11, 15, 64, 65, 68, 71, 75, 114, 115], "harvest": [10, 12, 14], "higher": [10, 15, 22, 44, 58, 59, 60, 61, 64, 67, 68, 69, 70, 77, 79, 85, 87, 88, 101, 103, 105, 110, 119, 120], "reduc": [10, 11, 14, 45, 46, 66, 78, 79, 101, 102, 103, 105, 113, 120], "wheat": [10, 12], "maiz": [10, 12], "delai": [10, 102], "plant": [10, 12, 14, 15, 59, 66, 102, 109], "begun": 10, "environment": [10, 12, 21, 63, 64, 66, 96, 105, 107, 118], "accur": [10, 64, 65, 76, 81, 85, 108, 118, 119], "valuabl": [10, 12, 21, 27, 43, 45, 47, 48, 64, 65, 67, 74, 75, 80, 105, 108, 112], "insight": [10, 11, 21, 45, 46, 47, 64, 67, 75, 80, 102, 103, 105, 108, 112, 119, 120, 122], "pest": 10, "diseas": [10, 119], "account": [10, 15, 27, 35, 36, 56, 64, 65, 68, 78, 85, 86, 90, 95, 101, 102, 103, 105, 118, 123], "statist": [10, 58, 70, 71, 105, 107, 108, 109, 112, 118, 120, 122], "driver": [10, 12, 15, 58, 95], "climatolog": [10, 11, 12, 14, 47, 57, 66, 69, 70, 71, 99, 103, 107], "certain": [10, 11, 43, 49, 50, 59, 60, 64, 78, 101, 110, 111, 118], "larger": [10, 47, 56, 68, 75, 79, 81, 82, 88, 95, 102, 103, 105, 108, 119], "aforement": 10, "panda": [10, 11, 12, 14, 15, 42, 44, 46, 74, 75, 76, 77, 78, 79, 80, 81, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120, 123], "pd": [10, 11, 12, 14, 15, 25, 42, 43, 57, 66, 67, 68, 71, 74, 75, 76, 77, 78, 79, 80, 81, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "random": [10, 11, 13, 15, 43, 79, 103, 108, 109, 111, 113, 118, 119, 120], "inlinebackend": [10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 114, 115], "figure_format": [10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 114, 115], "retina": [10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 114, 115], "style": [10, 43, 44, 61, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "raw": [10, 12, 40, 65, 66, 67, 68, 69, 70, 71, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "githubusercont": [10, 12, 66, 67, 68, 69, 70, 71, 79, 80, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "climatematchacademi": [10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "mplstyle": [10, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "model_color": [10, 96, 98, 99], "ki": [10, 96, 98, 99], "util": [10, 14, 22, 42, 44, 46, 53, 55, 56, 57, 58, 59, 61, 64, 65, 67, 68, 69, 70, 71, 74, 75, 78, 82, 89, 91, 97, 98, 101, 102, 108, 109, 110, 111, 113, 114, 115], "intreduc": 10, "intermodel": 10, "test": [10, 24, 25, 26, 27, 80, 91, 96, 97, 99, 105, 115, 119, 120], "df": [10, 14, 74, 81, 91, 96, 97, 99, 105, 109, 111, 113, 119], "mpi": [10, 96, 97, 98, 99, 113, 115], "esm1": [10, 96, 97, 98, 99, 113, 115], "lr": [10, 96, 97, 98, 99], "object": [10, 14], "subset": [10, 12, 14, 35, 49, 57, 65, 69, 76, 80, 91, 94, 95, 96, 97, 99, 105, 119], "r1i1p1f1": [10, 14, 91, 94, 95, 96, 97, 98, 99], "3hr": 10, "abov": [10, 11, 12, 14, 15, 23, 33, 36, 42, 43, 44, 46, 49, 50, 56, 57, 58, 59, 61, 64, 65, 66, 67, 68, 69, 70, 74, 75, 76, 77, 79, 85, 87, 88, 89, 90, 91, 94, 95, 96, 97, 99, 102, 103, 105, 108, 109, 112, 113, 114, 115, 118, 119, 120], "convert": [10, 14, 45, 66, 71, 74, 78, 81, 85, 87, 88, 89, 91, 94, 95, 96, 97, 98, 99, 101, 105], "sub": [10, 14, 22, 64, 66, 75, 91, 94, 95, 96, 97, 98, 99], "index": [10, 14, 15, 25, 42, 43, 44, 45, 49, 65, 66, 74, 75, 91, 94, 95, 96, 97, 98, 99, 101, 102, 105, 108, 109, 111, 112, 113, 114, 115, 119, 120], "anonym": [10, 14, 91, 94, 95, 96, 97, 98, 99], "authent": [10, 14, 91, 94, 95, 96, 97, 98, 99, 105], "22": [10, 14, 15, 78, 85, 86, 87, 89, 91, 96, 97, 99, 105, 109, 112, 113, 114, 115, 118, 119, 120], "23": [10, 12, 14, 15, 78, 79, 80, 85, 86, 87, 89, 91, 96, 97, 99, 105, 107, 113, 114, 115, 118, 119, 120], "tas_histor": 10, "astyp": [10, 15, 105, 113, 115, 118], "m8": 10, "date": [10, 12, 13, 15, 43, 46, 57, 65, 66, 69, 75, 105], "hourli": [10, 13, 48, 57, 59, 64], "diurnal": [10, 11, 57], "season": [10, 12, 45, 46, 49, 57, 58, 59, 64, 67, 68, 70, 74, 80], "cycl": [10, 14, 39, 46, 47, 50, 57, 59, 67, 68, 77, 79, 80, 95, 96], "fascin": [10, 119], "amplitud": [10, 58, 79], "latitud": [10, 13, 14, 22, 42, 43, 44, 46, 47, 48, 50, 56, 57, 58, 59, 61, 66, 67, 68, 69, 70, 71, 74, 78, 80, 82, 89, 90, 94, 95, 99, 115], "ax_pres": [10, 94], "timestep": [10, 87, 89, 90, 94], "2013": [10, 13, 14, 63, 65, 75, 78, 101, 103], "tas_pres": 10, "01t00": [10, 43], "1st": 10, "environ": [10, 11, 14, 32, 34, 35, 36, 63, 64, 65, 74, 102, 103, 107, 123], "veget": [10, 11, 14, 65, 91, 102, 119], "covari": [10, 77, 103, 114, 115], "dong": 10, "humphrei": 10, "2021": [10, 11, 12, 13, 15, 26, 65, 82, 103, 105, 107], "rice": [10, 12, 14], "barlei": [10, 12], "oat": [10, 12], "rye": [10, 12], "sorghum": [10, 12], "millet": [10, 12], "mix": [10, 12, 14, 57, 85, 89, 90], "grain": [10, 12], "quantiti": [10, 11, 12, 59, 71, 103, 105], "grow": [10, 12, 64, 102, 103], "improv": [10, 11, 12, 20, 42, 44, 65, 67, 81, 101, 103, 110, 113, 115, 119], "policymak": [10, 12, 109], "stakehold": [10, 12, 121], "filename_cer": [10, 12], "data_cereal_land": [10, 12], "csv": [10, 11, 12, 75, 78, 79, 80, 81, 91, 105, 108, 109, 110, 111, 112, 114, 119], "url_cer": [10, 12], "sshamekh": [10, 12], "f85f43997e3d6ae61e5d729bf77cfcc188fbf2fd": [10, 12], "ds_cereal_land": [10, 12], "read_csv": [10, 11, 12, 75, 77, 78, 79, 80, 81, 105, 108, 109, 110, 111, 112, 114, 119], "head": [10, 12, 15, 74, 75, 77, 78, 79, 81, 85, 105, 123], "flowchart": 10, "paramet": [10, 12, 14, 22, 57, 64, 65, 74, 79, 80, 89, 94, 101, 102, 103, 108, 110, 111, 112, 113, 114, 115, 118, 120], "adav": 10, "window": [10, 48, 68, 71, 79, 103], "95": [10, 59, 80, 85, 86, 102, 103, 108, 111], "percentil": [10, 12, 87, 108, 110], "km": [10, 14, 44, 56, 57, 64, 65, 71, 115], "extent": [10, 49, 65, 67, 71, 108], "durat": [10, 12, 65, 67, 102, 105, 123], "coeffici": [10, 60, 70, 71, 79, 85, 114, 118, 120], "evalu": [10, 13, 14, 69, 70, 81, 88, 98, 102, 103, 112, 114, 115, 118, 121], "wikipedia": [10, 24, 58, 85, 94, 115, 123], "scipi": [10, 70, 71, 88, 108, 109, 110, 111, 112, 113, 114, 115, 123], "scatter": [10, 24, 25, 70, 71, 74, 75, 76, 94, 118, 119, 120], "rousi": 10, "regess": 10, "abut": 10, "13": [10, 12, 13, 14, 15, 57, 58, 66, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 80, 81, 85, 87, 89, 90, 91, 94, 95, 96, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 123], "li": [10, 85, 90], "jacqu": 10, "duma": 10, "gochi": 10, "d": [10, 11, 13, 14, 15, 25, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 63, 66, 67, 70, 74, 75, 76, 77, 89, 99, 101, 102, 103, 118, 123], "j": [10, 11, 12, 13, 14, 15, 25, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 61, 63, 76, 77, 78, 81, 82, 85, 87, 88, 95, 99, 102, 120], "schultz": [10, 12], "loco": 10, "bulletin": [10, 63], "american": [10, 63], "meteorolog": [10, 11, 14, 58, 63, 107, 113, 115], "societi": [10, 13, 15, 63, 64, 99, 102, 103, 108], "753": 10, "771": 10, "omotesho": 10, "o": [10, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 71, 74, 75, 76, 77, 80, 89, 90, 102, 109, 110, 114, 115, 119, 120], "muhammad": 10, "lawal": 10, "chapter": [10, 12, 58, 63, 85, 87, 95, 99, 113, 123], "fertil": 10, "nigeria": 10, "obayelu": 10, "sustain": [10, 14, 63, 88, 102], "pp": [10, 12, 13, 78], "371": 10, "hershei": 10, "pa": [10, 60, 87], "igi": 10, "doi": [10, 11, 13, 14, 15, 21, 22, 25, 26, 27, 52, 63, 74, 75, 76, 77, 78, 79, 80, 81, 82, 93, 107], "4018": 10, "978": [10, 107], "5225": 10, "3631": 10, "schwitalla": 10, "warrach": 10, "sagi": 10, "wulfmey": 10, "coupl": [10, 11, 13, 22, 25, 35, 56, 90, 93, 94, 99, 102, 103, 105, 113], "strength": [10, 56, 58, 64, 82, 103, 118, 120], "europ": [10, 15, 65, 76, 108, 109, 110, 111, 115], "syst": [10, 14], "109": [10, 44], "132": 10, "5194": [10, 82, 93, 107], "esd": 10, "gabriela": 11, "mayorga": 11, "adam": 11, "lidia": 11, "krinova": 11, "abigail": [11, 13, 14, 15, 56, 59, 85, 86, 87, 88, 89, 90, 91, 102, 103, 105], "bodner": [11, 13, 14, 15, 56, 59, 85, 86, 87, 88, 89, 90, 91, 102, 103, 105], "nagrb8hxmmk": 11, "bv1fm4y1x7g8": 11, "n7wdy": 11, "releas": [11, 13, 14, 27, 91, 118], "co2": [11, 14, 25, 26, 61, 77, 85, 87, 89, 95, 101, 102, 103, 113], "portion": [11, 14, 15, 33, 64, 101, 115], "absorb": [11, 14, 15, 61, 64, 87, 88, 89, 91], "chemic": [11, 15, 21, 25, 65, 74, 91], "seawat": [11, 13, 60, 87], "marin": [11, 59, 65, 75, 78, 122], "abil": [11, 43, 66, 80, 81, 82, 87, 89, 102, 105, 109, 112, 115, 119, 120], "calcifi": 11, "skeleton": [11, 74], "degre": [11, 12, 13, 14, 15, 22, 45, 47, 50, 56, 57, 58, 59, 60, 69, 71, 76, 90, 91, 103, 108, 109, 110, 111, 115], "alkalin": 11, "greater": [11, 12, 15, 49, 50, 60, 61, 88, 103, 105], "basic": [11, 23, 34, 40, 42, 58, 64, 67, 79, 102, 103, 105, 118, 121, 123], "databas": [11, 15, 21, 74, 75, 76, 113, 115], "extract": [11, 12, 14, 15, 43, 46, 57, 64, 66, 67, 68, 69, 70, 71, 74, 94, 101, 102, 105, 112, 114], "mamaba": 11, "netcdf4": [11, 14, 120], "ocean_acidif": 11, "hybrid": 11, "oa": 11, "atla": [11, 99], "socat": 11, "glodapv2": 11, "coastal": [11, 13, 15, 59, 67, 68, 112], "america": [11, 15, 44, 45, 65, 67, 70, 71], "codap": 11, "na": 11, "sixth": [11, 12, 95, 107], "intercomparison": [11, 81, 93, 99, 102, 113], "cmip6": [11, 13, 56, 87, 93, 98, 102, 115], "trajectori": [11, 113], "fugac": 11, "ion": [11, 123], "aragonit": 11, "satur": [11, 15, 90, 101, 102, 103], "calcit": 11, "revel": 11, "dissolv": 11, "inorgan": 11, "preindustri": 11, "condit": [11, 12, 14, 15, 22, 56, 57, 59, 64, 67, 68, 86, 87, 88, 89, 90, 91, 97, 102, 113, 115, 118, 119], "socioeconom": [11, 28, 64, 99, 103, 113], "ssp1": [11, 95, 96, 97, 98, 99, 102, 113, 115], "ssp2": [11, 87, 102, 113, 115], "ssp3": [11, 102], "ssp5": [11, 94, 95, 96, 97, 99, 102, 113, 115], "coverag": [11, 14, 15, 65, 123], "underli": [11, 68, 79, 119], "ssp": [11, 95, 99, 102, 103, 113, 115], "centuri": [11, 13, 57, 65, 75, 81, 86, 94, 101, 102, 113], "citat": [11, 21], "jiang": [11, 82], "dunn": 11, "carter": 11, "b": [11, 12, 13, 14, 15, 22, 24, 25, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 59, 61, 63, 65, 70, 75, 77, 82, 85, 87, 99, 102, 105, 118], "r": [11, 13, 14, 15, 21, 25, 26, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 59, 63, 69, 70, 71, 75, 77, 78, 80, 102, 103, 105, 107, 109, 118, 119], "tjiputra": 11, "terhaar": 11, "sharp": 11, "e2022ms003563": 11, "1029": [11, 13, 14, 22, 26, 60, 79], "2022ms003563": 11, "ocad": 11, "metadata": [11, 42, 44, 74, 75, 81, 91, 105], "url_surfaceph": 11, "0206289": 11, "surface_ph_1770_2100": 11, "surface_ph_1770_2000": 11, "old": [11, 34, 90], "filename_surfaceph": 11, "pht_median_histor": 11, "median": [11, 45, 85, 113, 123], "ds_ph": 11, "adventurout": 11, "pht_median_ssp119": 11, "pht_median_ssp126": 11, "pht_median_ssp245": 11, "pht_median_ssp370": 11, "pht_median_ssp585": 11, "replac": [11, 49, 50, 81, 105, 109, 111, 113, 114], "calcul": [11, 12, 43, 44, 45, 46, 47, 48, 57, 58, 59, 61, 66, 70, 71, 75, 78, 80, 81, 82, 85, 86, 87, 88, 89, 91, 94, 95, 96, 97, 98, 99, 103, 105, 108, 111, 112, 113, 114, 115, 118, 119, 120], "european": [11, 15, 57, 63, 64, 65], "union": 11, "programm": 11, "planet": [11, 20, 64, 85, 88, 94, 102, 103], "citizen": 11, "servic": [11, 12, 14, 15, 63, 65, 66, 102, 103], "situ": [11, 67], "commiss": 11, "agenc": [11, 15, 27, 64, 65], "esa": [11, 15, 63], "organis": [11, 113], "exploit": [11, 102], "eumetsat": 11, "centr": [11, 57, 87, 113], "medium": [11, 14, 15, 57, 64, 87], "forecast": [11, 14, 57, 64, 120], "eu": 11, "mercat": 11, "oc\u00e9an": 11, "vast": [11, 14, 61, 64, 74, 91], "airborn": [11, 64], "seaborn": [11, 25, 102, 103, 105, 108, 110, 111, 112, 113, 114, 115, 120], "author": [11, 27, 103, 105, 115], "user": [11, 15, 35, 43, 46, 65, 105], "en": [11, 35, 105], "column": [11, 15, 25, 61, 67, 70, 74, 75, 81, 87, 89, 90, 102, 105, 108, 109, 110, 111, 115, 118, 119], "molar": 11, "fraction": [11, 14, 57, 61, 64, 85, 86, 89, 101, 102, 103, 105, 115], "vertic": [11, 13, 44, 58, 70, 87, 88, 89, 90, 108, 119], "direclti": 11, "gase": [11, 77, 85, 86, 89, 90], "methan": [11, 85, 95], "ch": [11, 12, 13, 14, 15, 73], "flux": [11, 14, 86, 87, 88, 91], "evolut": [11, 79, 88, 95, 99, 115], "terrestri": [11, 12, 14, 39, 40, 47, 65, 66, 122], "inter": [11, 99, 102], "annual": [11, 14, 43, 45, 46, 48, 49, 61, 67, 68, 74, 75, 87, 89, 90, 91, 95, 96, 98, 107, 108, 109, 110, 111, 112, 113, 114, 115], "taken": [11, 15, 25, 58, 65, 71, 89, 90, 103, 105, 114, 118], "consist": [11, 12, 14, 57, 58, 61, 65, 66, 74, 79, 87, 91, 96, 102, 103, 105, 113, 114, 115, 120], "law": [11, 14, 88, 123], "chemistri": [11, 21, 122], "principl": [11, 20, 21, 22, 23, 24, 25, 26, 27, 65, 69, 85, 103, 118], "assimil": [11, 82], "optim": [11, 64, 65, 67, 88, 102], "estim": [11, 12, 13, 15, 57, 59, 60, 61, 67, 75, 76, 78, 79, 85, 86, 87, 88, 89, 102, 103, 109, 110, 111, 113, 114, 115, 118, 119, 120], "updat": [11, 15, 23, 35, 67, 69, 87, 89, 90, 102, 103, 120], "provis": 11, "span": [11, 13, 21, 26, 59, 64, 65, 66, 67, 74, 78, 79, 82, 87, 94, 95, 97, 99, 122], "decad": [11, 13, 14, 53, 54, 57, 61, 67, 68, 75, 94, 102, 103, 107, 113], "ingest": 11, "ad": [11, 15, 35, 43, 44, 59, 78, 81, 85, 87, 90, 97, 99, 102, 103, 105, 108, 114, 118, 120], "cdsapp": 11, "cam": [11, 89, 90], "ghg": 11, "egg4": 11, "monthli": [11, 13, 45, 46, 47, 48, 49, 50, 56, 57, 59, 60, 64, 65, 69, 70, 74, 89, 91, 94, 96], "overview": [11, 12, 39, 42, 43, 44, 45, 46, 47, 48, 49, 50, 67, 68, 73, 93, 103, 122, 123], "concentr": [11, 25, 61, 64, 65, 74, 77, 81, 87, 95, 114, 118], "laboratori": [11, 69, 84, 89, 90, 96], "filename_co2": 11, "co2_mm_gl": 11, "url_co2": 11, "gml": 11, "webdata": 11, "ccgg": 11, "ds_co2": 11, "header": [11, 75, 105], "55": [11, 42, 43, 57, 58, 120], "1981": [11, 12, 65, 66, 67, 68, 69, 70, 71, 89, 90], "oisst": [11, 69, 70], "cdr": [11, 12, 65, 68, 69, 71, 102], "6pgc2": [11, 69], "ds_sst": [11, 56], "attach": [11, 78], "imag": [11, 12, 14, 15, 56, 57, 65, 68, 69, 75, 94, 99, 102, 118, 122, 123], "speci": 11, "fisheri": [11, 64], "coastadapt": 11, "au": [11, 113], "pinpoint": [11, 74], "weaken": [11, 56, 59], "coral": [11, 74, 107], "whoi": 11, "press": [11, 12, 13, 63, 102, 103, 107], "reef": 11, "smithonian": 11, "stri": 11, "si": 11, "henri": 11, "joseph": 11, "joshua": 11, "patterson": 11, "lisa": 11, "krimski": 11, "fa220": 11, "edi": 11, "32473": 11, "laura": [12, 105, 108, 109, 110, 111, 112, 113, 114, 115], "paccini": [12, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115], "raphael": 12, "rocha": 12, "49xhre61li8": 12, "bv1au411l7fo": 12, "a53b4": 12, "rain": [12, 58, 111], "gaug": [12, 65, 67], "identif": [12, 68, 122], "besid": [12, 115], "s3f": [12, 66, 67, 68, 71], "boto3": [12, 57, 66, 67, 68, 71], "botocor": [12, 57, 66, 67, 68, 71], "datetim": [12, 14, 42, 57, 66, 105, 113, 123], "infrar": [12, 15, 64, 66, 85], "station": [12, 57, 65, 112], "high": [12, 14, 15, 25, 57, 61, 64, 65, 66, 67, 68, 74, 77, 78, 80, 86, 91, 94, 95, 96, 97, 99, 102, 103, 105, 111, 112, 113, 118, 119, 120], "california": 12, "santa": 12, "barbara": 12, "deriv": [12, 14, 15, 58, 68, 69, 71, 80, 81, 85, 89, 90, 91, 102, 103, 105, 111, 112, 115, 123], "quasi": [12, 22], "50": [12, 15, 46, 47, 65, 71, 74, 75, 76, 88, 90, 105, 109, 111, 112, 114, 120], "n": [12, 13, 14, 15, 25, 42, 43, 44, 58, 61, 65, 67, 68, 70, 71, 74, 76, 81, 87, 88, 90, 101, 102, 103, 107, 108, 109, 110, 111, 113, 119, 120], "chg": [12, 105], "wiki": [12, 121], "locat": [12, 13, 15, 22, 43, 45, 46, 47, 49, 50, 57, 60, 64, 66, 68, 71, 75, 76, 80, 82, 94, 95, 110, 111, 112, 113, 114, 115, 120], "detect": [12, 15, 58, 64, 68, 70, 75, 122], "etccdi": 12, "intens": [12, 15, 58, 59, 80, 85, 95, 101, 103, 105], "categori": [12, 64, 65, 66, 102, 105, 118, 119, 120], "modifi": [12, 14, 44, 58, 64, 66, 85, 94, 96, 102, 109, 114], "custom": [12, 36, 91], "daily_precip_djf": 12, "data_chirp": 12, "djf": [12, 58], "threshold": [12, 69, 70, 101, 105, 107, 110, 118], "wet": [12, 49, 67, 115], "1mm": 12, "dry": [12, 49, 67, 89, 90, 115], "less": [12, 14, 15, 21, 22, 27, 45, 49, 50, 56, 58, 60, 61, 64, 65, 66, 70, 75, 78, 86, 88, 101, 102, 103, 105, 109, 111, 115, 119], "5th": [12, 87, 108], "10th": 12, "90th": [12, 111], "95th": [12, 87, 108], "calculate_sdii_index": 12, "sdii": 12, "input": [12, 42, 46, 50, 66, 80, 81, 87, 88, 89, 102, 118, 119, 120], "coordin": [12, 14, 15, 30, 40, 44, 45, 46, 59, 61, 67, 68, 76, 95, 115], "wet_dai": 12, "sum": [12, 44, 45, 50, 59, 61, 79, 103, 105, 119, 120], "sum_wet_days_group": 12, "groupbi": [12, 14, 47, 48, 50, 56, 57, 58, 67, 68, 69, 105, 115], "dim": [12, 42, 43, 44, 45, 46, 47, 48, 50, 56, 59, 67, 68, 69, 70, 82, 89, 90, 91, 97, 98, 99, 111, 113], "count": [12, 45, 74, 101, 105, 108], "calculate_cdd_index": 12, "cdd": 12, "longest": [12, 65], "sequenc": [12, 43, 78, 101, 103, 105, 110, 111], "dataarrai": [12, 43, 44, 45, 46, 49, 50, 56, 57, 66, 94, 111, 113], "eg": 12, "chirps_data": 12, "sataarrai": 12, "boolean": [12, 56, 119], "dry_dai": 12, "zero": [12, 15, 57, 60, 61, 66, 75, 78, 85, 86, 88, 89, 103, 108, 110, 113, 118, 123], "unique_year": 12, "iter": [12, 23, 57, 76, 87, 105, 120], "consecutive_tru": 12, "current_count": 12, "largest": [12, 79, 89, 90, 102, 108, 113], "max": [12, 15, 45, 67, 70, 82, 96, 108, 110, 113, 114, 115, 119, 120], "cdd_da": 12, "coord": [12, 42, 43, 67, 111, 113], "2024": 12, "till": 12, "file_path": 12, "chc": 12, "ucsb": 12, "global_daili": 12, "netcdf": [12, 13, 42, 66, 68, 69], "p25": 12, "v2": [12, 45, 56], "days_p25": 12, "downloaded_fil": 12, "fpath": 12, "zip": [12, 15, 57, 61, 85, 97, 98, 99, 102, 103, 114], "open_mfdataset": [12, 67, 68, 71], "by_coord": 12, "listcomp": [12, 102], "administr": [12, 65, 66, 87], "ncei": [12, 52, 66, 71, 73, 75, 77, 82], "commerci": [12, 65, 66], "amazon": [12, 65, 66, 67, 68, 70], "aw": [12, 57, 68, 71], "commonli": [12, 40, 45, 56, 59, 64, 65, 66, 75, 78, 109, 120], "greeness": [12, 66], "densiti": [12, 45, 54, 59, 61, 66, 87, 105, 108, 109, 110, 112, 113, 114, 115], "health": [12, 24, 66, 102, 103, 115, 119], "insect": [12, 66], "infest": [12, 66], "sensor": [12, 64, 65, 66], "systemat": [12, 65, 66, 109], "v005": [12, 66], "avh13c1": [12, 66], "19810624": [12, 66], "c20170610041337": [12, 66], "netcdr": [12, 66], "word": [12, 44, 56, 66, 78, 79, 80, 87, 102, 103, 108, 112], "easili": [12, 15, 43, 44, 66, 76, 77, 78, 81, 94, 119], "2002": [12, 66], "03": [12, 14, 43, 66], "march": [12, 15, 57, 66], "s3": [12, 57, 66, 67, 68, 71], "land_v005_avh13c1_": [12, 66], "_20020312_c": [12, 66], "reasaon": [12, 66], "wildcard": [12, 66], "satisfi": [12, 23, 49, 66, 88], "narrow": [12, 20, 64, 65, 66, 76], "timefram": [12, 21, 112], "bucket": [12, 57, 66, 67, 68, 71], "s3filesystem": [12, 66, 67, 68, 71], "client": [12, 57, 66, 67, 68, 71], "signature_vers": [12, 57, 66, 67, 68, 71], "unsign": [12, 57, 66, 67, 68, 71], "date_sel": [12, 57, 66], "2001": [12, 107], "file_loc": [12, 66, 67, 68, 71], "glob": [12, 15, 66, 67, 68, 71, 105, 115], "strftime": [12, 57, 66], "_c": [12, 66, 114], "files_for_pooch": 12, "amazonaw": [12, 57, 66, 67, 68, 71], "spectroradiomet": [12, 14, 64], "blue": [12, 15, 56, 58, 59, 64, 69, 70, 75, 87, 88, 102, 103, 105, 118, 119, 120, 123], "469": 12, "nanomet": 12, "645": 12, "858": 12, "complement": [12, 65], "radiomet": [12, 14, 64], "rich": [12, 42, 59, 75], "archiv": [12, 73, 74, 75, 76, 105, 114], "composit": [12, 64, 65, 74, 75, 77, 79, 80, 87], "kilomet": [12, 44], "mod13c2a2": 12, "5600": 12, "meter": [12, 57, 59, 61, 64, 85], "ndvi_": 12, "modis_data": 12, "reset_index": [12, 102, 105], "drop": [12, 14, 33, 56, 74, 81, 102, 105, 114, 118, 119, 120], "iloc": [12, 112], "transpos": [12, 46, 112, 118], "hesit": 12, "happi": [12, 123], "tucker": 12, "2012": [12, 14, 81], "digitalcommon": 12, "unl": 12, "nasapub": 12, "217": 12, "alexand": 12, "hegerl": 12, "jone": 12, "tank": 12, "peterson": 12, "trewin": 12, "zwier": 12, "2011": [12, 47, 64, 69, 70, 71, 115], "wilei": [12, 14, 15, 52, 107], "851": 12, "870": 12, "halpert": 12, "correl": [12, 26, 71, 105], "1993": [12, 61], "277": [12, 43], "280": [12, 22, 25, 88], "seneviratn": [12, 107], "intergovernment": [12, 13, 68, 102, 107], "masson": [12, 13, 107], "delmott": [12, 13, 107], "ed": [12, 13], "cambridg": [12, 13, 102, 107], "kingdom": [12, 13], "york": [12, 13, 71], "ny": [12, 13], "1513": 12, "1766": 12, "ipcc": [12, 13, 14, 28, 68, 73, 85, 86, 87, 88, 95, 97, 98, 99, 103, 105, 113], "ar6": [12, 85, 86, 87, 88, 99, 113], "wg1": [12, 99, 113], "annex": 12, "vi": 12, "guti\u00e9rrez": 12, "2205": 12, "2214": 12, "ipcc_ar6_wgi_annexvi": 12, "pdf": [12, 13, 14, 15, 52, 63, 73, 108, 109, 110, 111, 112, 113, 114, 115], "aakash": 13, "sane": 13, "karsten": 13, "haustein": 13, "brodi": [13, 59, 61, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99], "fzxj00pg34g": 13, "bv1j14y197tt": 13, "u7x62": 13, "interfac": [13, 42, 44, 105, 119], "timescal": [13, 14, 46, 47, 56, 57, 59, 74, 79, 80], "attribut": [13, 14, 40, 43, 44, 45, 67, 74, 85, 105, 107, 112, 118, 119], "tide": [13, 112], "perturb": [13, 102], "caus": [13, 26, 44, 56, 58, 59, 60, 61, 64, 65, 76, 81, 82, 87, 88, 91, 95, 102, 103, 105, 112, 120], "alter": [13, 15, 69, 70, 81, 115], "due": [13, 14, 33, 56, 60, 61, 64, 65, 66, 67, 68, 70, 71, 78, 79, 80, 86, 87, 88, 90, 91, 94, 96, 97, 98, 101, 102, 103, 111, 112, 113, 115, 118, 120], "thermal": [13, 15, 60, 61, 64], "expans": [13, 60], "glacier": [13, 77], "ic": [13, 14, 15, 22, 25, 49, 59, 65, 74, 77, 78, 80, 82, 86, 91], "sheet": [13, 65, 82], "w1d2": [13, 28], "sea_level": 13, "stand": [13, 56, 74, 79, 94, 110, 119, 120], "store": [13, 42, 43, 44, 54, 57, 61, 64, 66, 71, 74, 75, 76, 77, 80, 81, 89, 91, 95, 99, 102, 105, 109, 111, 113, 120], "1992": [13, 14, 61, 65], "2017": [13, 15, 63, 74, 76, 78, 107], "obtain": [13, 48, 56, 64, 76, 79, 86, 103, 109, 113, 118], "dimens": [13, 14, 40, 43, 44, 45, 46, 47, 48, 50, 59, 60, 61, 66, 67, 68, 71, 78, 82, 89, 91, 96, 103], "longitud": [13, 14, 42, 43, 44, 46, 47, 48, 50, 56, 57, 58, 59, 61, 66, 67, 68, 69, 70, 71, 74, 91, 94, 95, 115], "colormap": [13, 56, 120], "equip": [13, 21, 64, 78, 102, 103], "ahead": 13, "consortium": [13, 74, 76], "fukumori": 13, "wang": [13, 14, 15], "fenti": 13, "forget": 13, "heimbach": 13, "pont": 13, "podaac": 13, "jpl": [13, 64], "ecco_l4_gmsl_time_series_monthly_v4r4": 13, "februari": [13, 46, 58], "synopsi": 13, "5281": 13, "zenodo": [13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "4533349": 13, "campin": 13, "hill": 13, "wunsch": 13, "2015": [13, 14, 15, 25, 61, 65, 71, 77, 78, 81, 86, 87, 91, 94, 95, 102, 115], "linear": [13, 24, 25, 26, 43, 70, 78, 89, 101, 102, 109, 112, 114, 119, 120], "invers": [13, 79, 101, 105, 111], "geoscientif": [13, 82], "geosci": [13, 81], "net": [13, 14, 87, 88, 90, 91, 103, 113], "3071": 13, "url_ecco": 13, "sea_surface_height_mon_mean_1992": 13, "01": [13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 67, 68, 69, 70, 71, 75, 79, 86, 89, 105], "12_ecco_v4r4_latlon_0p50deg": 13, "200": [13, 69, 79, 81, 88, 90, 112, 113, 114], "134": 13, "pcolormesh": [13, 44], "nearest": [13, 46, 47, 67, 68, 71, 75, 78, 115, 118], "fun": [13, 114, 115], "disagre": 13, "uhslc": 13, "soest": 13, "hawaii": 13, "instruct": [13, 42, 58, 76, 102, 123], "url_choosen": 13, "fast": [13, 68, 79, 102], "d825": 13, "cuxhaven": 13, "germani": [13, 96, 108, 109, 110, 111, 113, 115], "oceanservic": 13, "sealevelris": 13, "tech": [13, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "oppenheim": 13, "glavov": 13, "hinkel": 13, "van": [13, 103, 107, 123], "wal": 13, "magnan": 13, "abd": 13, "elgawad": 13, "cai": 13, "cifuent": 13, "jara": 13, "deconto": 13, "ghosh": [13, 107], "hai": 13, "isla": 13, "marzeion": 13, "meyssignac": 13, "z": [13, 15, 61, 79, 80, 89], "sebesvari": 13, "2019": [13, 14, 15, 22, 65, 85, 86], "low": [13, 14, 15, 25, 58, 61, 64, 65, 66, 70, 86, 95, 96, 97, 99, 103, 120], "ly": 13, "island": 13, "coast": [13, 45, 68, 74], "special": [13, 14, 58, 59, 89, 90], "cryospher": [13, 94], "p\u00f6rtner": 13, "robert": [13, 82, 105, 107], "zhai": [13, 107], "tignor": 13, "poloczanska": 13, "mintenbeck": 13, "alegr\u00eda": 13, "nicolai": 13, "okem": 13, "petzold": 13, "rama": 13, "weyer": 13, "uk": [13, 52, 57, 107], "321": 13, "445": 13, "1017": 13, "9781009157964": 13, "006": 13, "domingu": 13, "goni": 13, "baring": 13, "volkov": 13, "theacceler": 13, "theu": 13, "east": [13, 44, 50, 56, 57, 58, 59, 67, 69, 78, 81], "2010": [13, 58, 60, 65, 67, 68, 70, 71, 73, 81, 89, 90, 101, 115], "geophys": [13, 14, 22, 25, 96], "letter": [13, 25], "367": 13, "376": 13, "2018gl081183receiv": 13, "church": 13, "u": [13, 15, 44, 57, 58, 59, 71, 101, 103], "clark": 13, "cazenav": [13, 63], "gregori": [13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91], "jevrejeva": 13, "levermann": 13, "merrifield": 13, "miln": 13, "nerem": 13, "nunn": 13, "payn": 13, "pfeffer": 13, "stammer": 13, "unnikrishnan": 13, "fifth": 13, "stocker": [13, 25], "qin": 13, "plattner": 13, "allen": [13, 102], "boschung": 13, "nauel": 13, "xia": 13, "bex": 13, "midglei": 13, "asset": [13, 73], "upload": [13, 73], "02": [13, 43, 73], "wg1ar5_chapter13_fin": 13, "griffi": 13, "hugh": 13, "terminolog": [13, 75, 91], "surv": 13, "geophi": 13, "1251": 13, "1289": 13, "1007": [13, 107], "s10712": 13, "019": 13, "09525": 13, "zanna": 13, "chen": [13, 14], "budget": [13, 14, 39, 40, 47, 85, 86, 89], "1958": 13, "48": [13, 74, 120], "e2021gl094502": 13, "2021gl094502": 13, "cozannet": 13, "2014": [13, 46, 47, 49, 56, 60, 61, 65, 66, 69, 77, 78, 99, 113, 115], "34": [13, 14, 15, 85, 91, 105, 115], "ezproxi": 13, "princeton": 13, "1002": [13, 25, 27, 52, 77, 107], "2013ef000188": 13, "mimura": 13, "proc": 13, "jpn": 13, "acad": 13, "ser": 13, "phy": 13, "biol": 13, "sci": [13, 14, 15, 74, 76, 119], "89": 13, "281": [13, 43], "301": 13, "2183": 13, "pjab": 13, "pmid": 13, "23883609": 13, "pmcid": 13, "pmc3758961": 13, "oz": 14, "kira": 14, "juliu": [14, 91, 94, 95, 96, 97, 98, 99], "bamah": 14, "yuhan": [14, 15], "qhzjeznvq60": 14, "bv1fh4y1j7lx": 14, "w8ny7": 14, "radi": [14, 22, 85, 87, 88, 91, 95], "forest": [14, 15, 64, 65, 119], "grassland": [14, 64], "classif": [14, 15, 118, 120, 121], "sequest": 14, "counteract": 14, "vs": [14, 46, 77, 86, 88, 94, 118, 119, 120], "creation": [14, 65], "abandon": 14, "moreov": [14, 65, 99, 112], "w2d3": [14, 28], "pyhdf": 14, "modi": [14, 15, 64], "google_cmip_col": [14, 91], "encount": [14, 42, 68, 79, 91, 94, 103, 108, 110, 120], "feder": 14, "esgf": 14, "host": [14, 22, 66], "sampl": [14, 18, 20, 21, 42, 49, 50, 105, 108, 109, 110, 111, 118, 119, 120], "pasturefrac": 14, "expt": 14, "queri": 14, "lmon": 14, "col_subset": 14, "nuniqu": 14, "gfdl": [14, 96, 97, 99], "esm4": [14, 96, 97, 99], "dictionari": [14, 42, 44, 76, 81, 85, 91, 94, 105, 120, 123], "classification_system": 14, "gpp": 14, "gross": 14, "primari": [14, 67, 70, 71], "npp": [14, 64], "nep": 14, "atmopher": 14, "nbp": 14, "biospher": 14, "treefrac": 14, "percentag": [14, 61, 78, 105, 118, 120], "tree": [14, 74, 76, 91, 94, 95, 96, 97, 98, 99, 118], "grassfrac": 14, "grass": 14, "cropfrac": 14, "anthropogen": [14, 61, 85, 91, 95, 102, 107, 118], "pastur": 14, "rsu": [14, 91], "upwel": [14, 45, 56, 59, 91], "shortwav": [14, 15, 64, 85, 87, 88, 89, 90, 91], "radiat": [14, 40, 45, 47, 58, 59, 64, 87, 88, 89, 90, 91, 115], "rsd": [14, 91], "downwel": [14, 59, 91], "Near": [14, 15, 90, 113], "variabel": 14, "datafram": [14, 74, 75, 81, 105, 109, 111, 112, 113, 115, 119], "set_opt": 14, "max_colwidth": [14, 105], "to_html": 14, "title_md": 14, "tabl": [14, 15, 45, 65, 66, 81, 85, 87, 99], "quit": [14, 46, 48, 85, 89, 90, 91], "outdat": 14, "uptak": [14, 61], "autotroph": 14, "respir": 14, "decomposit": 14, "heterotroph": 14, "litter": 14, "soil": [14, 15, 65], "excess": [14, 56, 61], "disturb": [14, 15, 65], "combust": 14, "steffen": 14, "1998": [14, 69, 70], "credit": [14, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 64, 65, 69, 75, 77, 85, 86, 87, 94, 95], "readi": [14, 24, 59, 71, 118, 119], "shrubfrac": 14, "baresoilfrac": 14, "residualfrac": 14, "gr1": 14, "dt_lmon_vari": 14, "extra": [14, 89, 123], "singleton": [14, 91], "ds_lmon": 14, "to_dataset": 14, "18": [14, 15, 65, 66, 67, 68, 70, 71, 75, 76, 77, 78, 80, 82, 85, 87, 89, 90, 91, 107, 109, 113, 114, 115, 118, 119], "19": [14, 15, 28, 49, 57, 67, 68, 71, 74, 78, 87, 89, 91, 105, 109, 113, 114, 115, 118, 119], "24": [14, 15, 61, 68, 78, 82, 85, 87, 88, 89, 105, 113, 114, 115, 119, 123], "25": [14, 28, 42, 43, 50, 57, 61, 65, 69, 75, 78, 81, 85, 86, 87, 89, 90, 91, 105, 108, 109, 110, 111, 113, 115, 123], "26": [14, 15, 65, 78, 86, 89, 91, 105, 110, 113, 115, 119, 120], "32": [14, 15, 45, 102, 105, 115], "33": [14, 91, 105, 115], "emon": 14, "dt_emon_vari": 14, "ds_emon": 14, "dt_amon_vari": 14, "ds_amon": 14, "dt_fx_variabl": 14, "ds_fx": 14, "datarrai": 14, "compact": 14, "var": [14, 45, 57, 58, 108], "data_var": [14, 42, 43, 67, 113], "atmopsher": [14, 90], "unnecessari": 14, "drop_var": 14, "dcpp_init_year": 14, "ratio": [14, 15, 66, 75, 81, 89, 120], "incom": [14, 40, 47, 64, 85], "solar": [14, 40, 45, 47, 58, 64, 80, 85, 88, 115], "surf_albedo": 14, "attr": [14, 42, 43, 57, 58, 115], "dimensionless": 14, "long_nam": [14, 57, 58, 91], "avhrr": [14, 66], "ltdr": 14, "conjunct": 14, "ancillari": [14, 65], "dozen": [14, 60, 65, 96], "offici": 14, "leaf": [14, 15, 65, 78, 119], "broadband": 14, "evapotranspir": 14, "1982": [14, 15, 65, 69, 70], "glc": 14, "cropland": [14, 64], "shrubland": 14, "tundra": 14, "barren": 14, "snow": [14, 15, 58, 65, 86, 88, 91], "geotiff": 14, "glc_7classes_year": 14, "wg": 14, "84": 14, "label": [14, 15, 25, 40, 42, 43, 44, 46, 58, 59, 60, 61, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 81, 82, 85, 87, 88, 89, 90, 91, 96, 97, 99, 102, 103, 105, 108, 110, 112, 113, 114, 115, 118, 119, 120], "shown": [14, 15, 49, 56, 57, 64, 70, 74, 76, 78, 85, 86, 87, 89, 90, 94, 95, 99, 102, 103, 115], "ts": [14, 57, 74, 89, 90, 95], "essd": 14, "subclass": 14, "paddi": 14, "farmland": 14, "orchard": 14, "bare": [14, 15, 22], "broadleaf": 14, "5m": 14, "neither": [14, 69], "conifer": 14, "nor": 14, "type": [14, 15, 42, 44, 48, 58, 59, 64, 67, 74, 75, 76, 85, 87, 88, 91, 102, 103, 114, 118, 119, 120, 122], "needl": 14, "canopi": 14, "shrub": [14, 15], "70": [14, 43, 64, 71, 75, 87], "brush": 14, "herbac": 14, "90": [14, 57, 59, 60, 61, 64, 76, 82, 88, 89, 90, 91, 94, 103, 105, 112, 113, 120], "landus": 14, "pangaea": 14, "1594": 14, "913496": 14, "folder": [14, 15, 35, 74], "path_landus": 14, "expandus": 14, "glc_7classes_1982": 14, "tif": 14, "ds_landus": 14, "renam": [14, 34, 36, 102, 105, 113, 115], "band_data": 14, "enhanc": [14, 47, 56, 65, 67, 68, 69, 78, 81, 82, 114], "replai": 14, "ecmwf": [14, 57], "quick": [14, 21, 44, 48, 64, 71], "conveni": [14, 47, 50, 58, 102, 115], "nativ": [14, 21, 76, 91, 94, 105], "9km": 14, "gaussian": [14, 118], "tco1279": 14, "cd": 14, "regrid": [14, 91], "1x0": 14, "spectrum": [14, 15, 79, 85, 89, 123], "diffus": 14, "intermedi": 14, "sun": [14, 59, 85, 88, 107], "partli": [14, 65], "particl": 14, "aerosol": [14, 15, 65, 85], "incid": 14, "IFS": 14, "albedo_path": 14, "era": [14, 74, 76], "001": [14, 79, 80, 89, 90, 103], "ds_albedo": 14, "fal": 14, "convienc": 14, "precipt": 14, "precp_path": 14, "002": 14, "ds_precp": 14, "tp": 14, "tempr_path": 14, "003": 14, "ds_tempr": 14, "t2m": 14, "2m": [14, 57], "desertif": 14, "degrad": 14, "srccl": 14, "zhao": [14, 15], "wu": 14, "liu": 14, "yang": [14, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "pixel": [14, 15, 64, 65, 66], "phenolog": [14, 15, 65], "electron": 14, "208": 14, "107763": 14, "issn": 14, "0168": 14, "1699": 14, "1016": [14, 25, 63], "compag": 14, "shani": 14, "rohatyn": 14, "dryland": 14, "377": 14, "1436": 14, "1439": 14, "1126": [14, 75, 77, 78], "abm9684": 14, "hu": 14, "hou": 14, "zhen": 14, "yao": 14, "xu": [14, 85, 86, 87, 88, 89, 90, 91], "induc": [14, 68, 120], "northern": [14, 46, 56, 58, 59, 65, 67, 78, 80, 82, 91, 94], "china": [14, 36, 80], "geoinform": 14, "79": 14, "184": 14, "191": 14, "1569": 14, "8432": 14, "jag": 14, "018": 14, "duveil": 14, "hooker": 14, "cescatti": 14, "nat": [14, 91, 103], "679": 14, "1038": [14, 74, 75, 76, 77, 78, 80, 81, 82, 107], "s41467": [14, 52], "017": 14, "02810": 14, "yin": 14, "brand\u00e3o": 14, "buchner": 14, "helmer": 14, "iuliano": 14, "kimambo": 14, "lewi\u0144ska": 14, "razenkova": 14, "rizayeva": 14, "rogova": 14, "spawn": 14, "xie": 14, "radeloff": 14, "landsat": [14, 64], "246": [14, 94], "111873": 14, "0034": 14, "4257": 14, "rse": [14, 63], "gupta": [14, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61], "verma": 14, "bhatla": 14, "chandel": 14, "singh": 14, "payra": 14, "surfacetemperatur": 14, "merra": [14, 57], "2reanalysi": 14, "imd": 14, "setov": 14, "india": [14, 67, 80], "e2019ea000910": 14, "2019ea000910": 14, "cao": 14, "liang": 14, "he": 14, "forc": [14, 33, 39, 40, 41, 42, 47, 59, 60, 77, 79, 81, 82, 85, 87, 88, 91, 94, 95, 99, 102, 103, 123], "hemispher": [14, 46, 56, 58, 59, 64, 65, 78, 80, 82, 94], "2009": [14, 27], "1248": [14, 27], "1259": 14, "1175": [14, 63], "jcli": 14, "00389": 14, "westberg": 14, "stackhous": 14, "crawlei": 14, "hoell": 14, "chandler": 14, "supplement": [14, 105], "ashra": 14, "transact": [14, 103], "119": 14, "210": 14, "221": 14, "researchg": 14, "druri": 14, "262069995_an_analysis_of_nasa": 14, "s_merra_meteorological_data_to_supplement_observational_data_for_calculation_of_climatic_design_condit": 14, "5465225f0cf2052b509f2cc0": 14, "s\u00f6dergren": 14, "mcdonald": 14, "quantifi": [14, 15, 24, 59, 61, 64, 70, 86, 98, 101, 103], "polar": [14, 15, 25, 49, 58, 64, 65, 66, 68, 77, 91, 105], "amplif": [14, 25], "127": [14, 75], "e2021jd035058": 14, "agupub": [14, 52], "onlinelibrari": [14, 52], "2021jd035058": 14, "brittani": 15, "engl": 15, "diana": 15, "cadillo": 15, "2cdvn6o_q34": 15, "bv1gp411k7xa": 15, "8w5da": 15, "burn": [15, 102], "perimet": 15, "multipl": [15, 21, 22, 25, 26, 35, 41, 42, 43, 45, 48, 49, 56, 58, 65, 67, 75, 78, 80, 91, 94, 95, 96, 97, 98, 101, 102, 103, 105, 111, 114, 119, 120], "gdal": 15, "geopanda": 15, "gpd": 15, "gwi": 15, "geo": [15, 63, 82], "copernicu": [15, 57], "regim": [15, 78, 103], "globfir": 15, "mcd64a1": 15, "art\u00e9": 15, "built": [15, 42, 45, 75, 81, 89, 118, 119, 120], "imageri": 15, "terra": [15, 64, 65], "aqua": [15, 64, 65], "c6": 15, "ba": 15, "launch": [15, 32, 34, 35, 36, 64, 65], "june": [15, 46, 58], "s2": 15, "orbit": [15, 39, 47, 65, 77, 79, 80], "roughli": [15, 22, 56, 61, 67, 89, 90, 113, 115], "filter": [15, 46, 49, 50, 66, 75, 76], "500m": 15, "000": [15, 64, 74, 76, 77, 78, 79, 80, 81, 82, 105, 109], "acr": 15, "2000m": 15, "squar": [15, 26, 43, 45, 56, 114, 118, 119], "1000": [15, 25, 27, 42, 43, 44, 61, 77, 78, 79, 80, 82, 89, 90, 99, 101, 102, 103, 108, 109, 110, 111, 112, 113, 114, 115], "landcov": 15, "layer": [15, 54, 59, 61, 74, 77, 85, 87, 89, 90, 120], "cgl": 15, "lc100": 15, "idat": 15, "fdate": 15, "final": [15, 18, 40, 45, 54, 56, 66, 67, 75, 76, 81, 87, 90, 91, 94, 98, 99, 102, 103, 105, 108, 110, 111, 118, 119, 120, 122, 123], "area_acr": 15, "51": [15, 74, 108, 109, 110, 111], "lc_descrip": 15, "url_climateact": 15, "climateaction_countri": 15, "shp": 15, "read_fil": 15, "luck": 15, "spectral": [15, 64, 66, 80, 85], "msi": 15, "hous": 15, "band": [15, 58, 64, 66, 74, 75, 85, 97, 98, 108, 111, 120], "broom": 15, "acquisit": 15, "visibl": [15, 64, 66, 68, 76, 85, 115, 120], "nir": 15, "wave": [15, 64, 85, 123], "swir": 15, "10m": [15, 59], "b2": 15, "490": 15, "nm": [15, 85], "b3": 15, "560": 15, "b4": 15, "665": 15, "842": 15, "20m": 15, "b5": 15, "b6": [15, 120], "b7": 15, "b8a": 15, "705": 15, "740": 15, "783": 15, "865": 15, "edg": [15, 122], "b11": [15, 120], "b12": 15, "1610": 15, "2190": 15, "mostli": [15, 44, 78], "characteris": 15, "stress": [15, 115], "b1": [15, 120], "443": 15, "b9": 15, "vapor": [15, 65, 85, 89, 90], "945": 15, "b10": [15, 120], "cirru": 15, "1375": 15, "correct": [15, 42, 43, 66, 76, 118, 120], "showimag": 15, "imshow": [15, 105, 118], "root": [15, 74, 88, 119], "save": [15, 34, 35, 36, 56, 57, 68, 69, 74, 76, 78, 80, 81, 91, 101, 103, 109, 115, 118, 119], "rootfold": 15, "continet": 15, "asia": [15, 67, 80], "pre_fire_path": 15, "pre_fire_": 15, "npy": 15, "listdir": 15, "endswith": 15, "startswith": 15, "pre_fires_numpi": 15, "int": [15, 61, 63, 75, 90, 102, 105, 118, 120], "post_fire_path": 15, "post_fire_": 15, "post_fires_numpi": 15, "scl": 15, "mask": [15, 56, 57, 87, 99, 105, 119], "scl_fire_path": 15, "scl_pre_fire_": 15, "scl_fires_numpi": 15, "scl_fires_post_path": 15, "scl_post_fire_": 15, "scl_fires_post_numpi": 15, "pre_fir": 15, "post_fir": 15, "clip": 15, "10000": 15, "rgb": [15, 85], "austrailia": 15, "radianc": [15, 85], "chlorophyl": 15, "cellular": 15, "sand": 15, "rock": [15, 64], "spare": 15, "dens": [15, 60, 66], "ndvimax": 15, "ndvimin": 15, "frac": [15, 59, 85, 86, 87, 88, 95, 101, 105, 119], "foundat": [15, 21, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 58, 64, 69, 103, 118, 123], "geolog": 15, "survei": [15, 22, 28, 74], "shrirampur": 15, "maharashtra": 15, "occur": [15, 45, 46, 49, 56, 58, 60, 61, 70, 77, 79, 88, 90, 101, 102, 103, 105, 109, 115, 118, 120], "unburn": 15, "formula": [15, 86, 103, 111], "wavelength": [15, 64, 85], "healthi": 15, "opposit": [15, 57, 77, 91, 102], "devast": 15, "reach": [15, 57, 86, 88, 89, 90, 102, 103, 115], "peak": [15, 79, 80, 85, 102, 103], "isol": [15, 22, 24, 43, 44, 49, 50, 56, 68, 86, 98], "subtract": [15, 47, 68, 87, 96, 99], "unchang": 15, "gradient": [15, 45, 60], "unscal": 15, "tend": [15, 60, 61, 88, 102, 103, 105, 110], "usag": [15, 105], "heterogen": 15, "landscap": [15, 105], "delta": [15, 73, 75, 77, 80, 82, 101, 103], "rdnbr": 15, "methodolog": [15, 71], "octob": [15, 46, 67, 78, 107], "iberian": 15, "peninsula": 15, "0s": 15, "1s": 15, "computesclmask": 15, "rimag": 15, "cimag": 15, "scloutput": 15, "pre_scl_mask": 15, "post_scl_mask": 15, "black": [15, 56, 57, 58, 61, 69, 78, 81, 82, 87, 88, 89, 90, 91, 102, 103, 110], "defect": 15, "dark": [15, 66], "chocol": 15, "shadow": [15, 66], "lime": 15, "unclassifi": 15, "darkgrei": 15, "grei": [15, 60, 61, 65, 87, 115], "deepskyblu": 15, "magenta": 15, "named_color": 15, "sphx": 15, "glr": 15, "showscl": 15, "listedcolormap": [15, 118], "lightgrei": 15, "36": [15, 105, 115], "37": [15, 44, 71, 105, 115], "computendvi": 15, "ndvioutput": 15, "nan": [15, 45, 49, 60, 61, 66, 74, 75, 77, 119], "computendvi_valu": 15, "remap": 15, "remapndvi": 15, "isnan": 15, "ndvi_remap": 15, "showndvi": 15, "000000": 15, "a50026": 15, "d73027": 15, "f46d43": 15, "fdae61": 15, "fee08b": 15, "ffffbf": 15, "d9ef8b": 15, "a6d96a": 15, "66bd63": 15, "1a9850": 15, "006837": 15, "pre_fire_ndvi": 15, "pre_fires_scl": 15, "pre_fires_ndvi": 15, "computevci": 15, "for_ndvi_imag": 15, "ndvi_dataset": 15, "vcioutput": 15, "filtered_pixel": 15, "max_val": 15, "min_val": 15, "variat": [15, 42, 45, 47, 53, 54, 56, 58, 60, 61, 64, 68, 69, 73, 74, 76, 79, 80, 81, 82, 88, 91, 102, 103, 118, 122], "onsatellit": 15, "nepal": 15, "last_pre_fire_ndvi": 15, "pop": [15, 102], "last_pre_fire_vci": 15, "remapvci": 15, "35": [15, 28, 58, 60, 64, 105, 115], "showvci": 15, "vci_imag": 15, "computefiremask": 15, "row": [15, 25, 67, 70, 74, 75, 85, 95, 102, 109, 112, 118, 119], "nbrpost": 15, "nbrpre": 15, "remapdnbr": 15, "251": 15, "101": [15, 105], "099": 15, "269": 15, "439": 15, "659": 15, "dnbr_remap": 15, "un": 15, "spider": 15, "showdnbr": 15, "teal": 15, "orang": [15, 102, 103], "purpl": [15, 79, 102], "washington": [15, 112, 114], "ecolog": [15, 103], "yosemit": 15, "unequ": [15, 108], "plo": 15, "ONE": 15, "frequenc": [15, 48, 57, 59, 64, 65, 68, 78, 79, 91, 101, 105, 107], "quantit": [15, 75, 76, 78, 79, 123], "contigu": 15, "machin": [15, 105, 118, 119, 120, 121], "game": 15, "theori": [15, 22, 103], "technolog": [15, 64, 65, 101, 102, 103, 105], "danger": 15, "canadian": 15, "topographi": [15, 58], "idaho": 15, "western": [15, 56, 58, 64], "montana": 15, "restor": [15, 35], "eros": 15, "export": [15, 68, 69], "nutrient": [15, 59], "loess": 15, "plateau": [15, 61, 102], "3389": 15, "fpl": 15, "573126": 15, "amanda": 15, "hohner": 15, "charl": [15, 75], "rhoad": 15, "wilkerson": 15, "fernando": 15, "rosario": 15, "ortiz": 15, "watersh": 15, "threaten": 15, "drink": 15, "52": 15, "1234": 15, "1244": 15, "1021": [15, 21, 60], "ac": [15, 21, 52], "8b00670": 15, "alan": 15, "bui": 15, "west": [15, 44, 45, 56, 57, 58, 59, 69, 78], "ian": 15, "davi": 15, "ryan": [15, 59, 63], "haugo": 15, "jame": 15, "robertson": 15, "phillip": 15, "levin": 15, "e0205825": 15, "1371": 15, "pone": 15, "0205825": 15, "control": [15, 33, 34, 44, 45, 47, 78, 80, 103, 118, 120], "argentina": 15, "artwork": [16, 37, 38, 51, 62, 72, 83, 92, 100, 106, 116], "ve": [17, 25, 41, 44, 48, 49, 56, 64, 65, 67, 70, 74, 78, 80, 81, 82, 85, 88, 89, 102, 103, 105, 109, 112, 113, 120], "construct": [17, 20, 21, 76, 82, 89, 97, 109, 111, 119], "draft": [17, 18, 25, 26, 27, 28, 58], "broader": 17, "remind": [17, 94, 113, 115, 120], "pitfal": 17, "walk": 18, "consider": [18, 64, 65, 71, 75, 86], "clearli": [18, 69], "rigor": [18, 27], "popul": [19, 27, 64, 101, 102], "dionessa": [20, 64, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 102, 103, 105, 118, 119, 120, 121], "baton": 20, "sherri": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "mi": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 118], "maria": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "gonzalez": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "nahid": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "hasan": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "beatriz": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "cosenza": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "mural": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "katrina": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "dobson": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82], "cheng": [20, 21, 22, 23, 24, 25, 26, 27, 75, 80, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "formul": [20, 21, 22, 28, 95, 101, 103], "illustr": [20, 23, 42, 46, 65, 67, 95, 103, 123], "co": [20, 22, 24, 25, 26, 57, 68, 82, 89, 90, 99, 102, 105, 114], "_2": 20, "ji5fsm_v95": [], "bv1oj411z7ur": [], "y9fd4": [], "gain": [20, 21, 33, 46, 47, 61, 64, 67, 75, 80, 87, 89, 102, 103, 105, 110, 112, 118, 119, 120], "amongst": 20, "featur": [20, 22, 44, 58, 60, 61, 64, 67, 68, 69, 73, 74, 75, 76, 89, 102, 103, 118], "recap": [20, 23, 80, 102], "scope": [20, 87, 93], "clarifi": [20, 23, 81], "precis": [20, 79, 120], "clariti": [20, 23, 97, 98, 99, 123], "rxl5umqde_o": [], "bv1sx4y1a76j": [], "tbx4f": [], "fundament": [21, 64, 65, 66, 67, 75, 86, 103, 118, 122, 123], "navig": [21, 55, 65, 103, 105], "lai": 21, "exclud": [21, 105], "perfect": [21, 43, 64, 85, 110], "ongo": [21, 65], "convers": [21, 42, 64, 87, 88, 101, 112, 119], "recept": 21, "cite": 21, "overlook": [21, 115], "document": [21, 22, 42, 45, 46, 49, 63, 67, 78, 91, 101, 103, 105, 110, 119, 120], "carri": [21, 42, 43, 65, 68, 71, 98], "unintend": 21, "consequ": [21, 54, 64, 108], "incorpor": [21, 64, 65, 67, 69, 85, 87, 88, 89, 90, 102, 103, 109, 112, 113, 114, 122], "underrepres": 21, "leo": 21, "alaska": 21, "alaskan": 21, "hshk": 21, "hawaiian": 21, "arrheniu": 21, "racism": 21, "colleg": [21, 123], "textbook": [21, 60, 102, 105], "aid": [21, 26, 88, 102], "abet": 21, "racial": 21, "dispar": [21, 58], "mona": 21, "becker": 21, "melani": 21, "nilsson": 21, "educ": [21, 27], "1847": 21, "jcheme": 21, "1c00968": 21, "pointer": [21, 22], "summar": [21, 45, 78, 101, 103, 120], "worth": [21, 103, 113, 114], "pass": [21, 42, 43, 49, 75, 91], "scan": 21, "diagram": [21, 58, 64, 85, 102], "entireti": 21, "maxim": [21, 101, 103], "sentenc": 21, "written": [21, 61, 95, 105], "sketch": 21, "equat": [21, 24, 46, 47, 56, 57, 58, 59, 61, 70, 75, 85, 86, 87, 88, 91, 95, 102, 103, 105, 115, 118, 123], "zqwizje47bg": [], "bv1wn41127ux": [], "zyvwp": [], "deep": [22, 25, 60, 61], "sediment": [22, 25, 74, 76, 78], "altern": [22, 34, 35, 56, 95, 102, 110, 114, 123], "minimum": [22, 45, 49, 66, 71, 105], "unsur": 22, "check": [22, 28, 34, 42, 56, 57, 66, 67, 70, 76, 78, 87, 89, 103, 105, 107, 110, 119, 123], "captur": [22, 26, 64, 65, 74, 78, 86, 105, 115, 118, 119, 120], "gcm": [22, 91], "100km": 22, "resolv": [22, 75, 82, 90], "smaller": [22, 49, 60, 61, 64, 75, 79, 95, 103], "scalesimpl": 22, "parameter": [22, 88, 90, 94], "gridscal": 22, "restrict": [22, 65, 67, 103], "1940": 22, "prehistor": 22, "mimic": 22, "resembl": [22, 78, 102], "convect": [22, 60], "equilibrium": [22, 61, 96], "geostroph": 22, "mid": [22, 58, 85, 99, 115], "And": [22, 45, 56, 76, 110, 111], "complex": [22, 42, 48, 53, 54, 64, 66, 78, 80, 86, 89, 91, 96, 102, 103, 118, 119, 120], "ncar": [22, 56, 57], "hydrolog": [22, 65], "usg": [22, 52, 64, 73], "hierarchi": 22, "maher": 22, "gerber": 22, "medeiro": 22, "merli": 22, "sherwood": 22, "sheshadri": 22, "57": [22, 60, 79, 85, 86, 87, 105, 120], "250": [22, 64, 85, 88, 102, 105], "2018rg000607": 22, "hsu": 22, "primeau": 22, "magnusdottir": 22, "cesm1": 22, "e2021ms002979": 22, "2021ms002979": 22, "f71ibvrhv6": [], "bv1tf411q7wz": [], "v8zx6": [], "isn": [23, 42, 45, 71, 74, 105], "intuit": [23, 89], "involv": [23, 42, 46, 56, 64, 68, 75, 77, 78, 102, 110, 111, 119, 123], "vice": [23, 75, 108], "versa": [23, 75, 108], "articul": 23, "lack": [23, 26, 89, 102, 110], "ingredi": 23, "sn": [25, 61, 102, 103, 105, 108, 110, 111, 112, 113, 114, 115, 120], "interpol": [25, 65, 69, 71, 79, 94, 105], "stat": [25, 70, 71, 108, 109, 110, 111, 112, 113, 114, 115], "f7ymmfcng6w": [], "bv1gh4y1f7jc": [], "qxcmj": [], "regress": [24, 25, 26, 70, 103, 121, 123], "fit": [24, 25, 26, 57, 65, 67, 70, 103, 108, 110, 111, 112, 113, 114, 115], "aren": [24, 78, 97, 98, 99, 101, 103, 121], "simpli": [24, 91, 94, 102, 105, 118, 119], "giraff": 24, "speed": [24, 44, 56, 57, 85, 105, 113, 123], "wonder": [24, 64], "taller": 24, "faster": [24, 66, 80, 90, 102, 105], "shorter": [24, 56, 64, 119], "mathemat": [24, 42, 45, 59, 87, 103, 105, 107, 118, 123], "slope": [24, 25, 88, 114], "intercept": [24, 25, 114], "Such": [24, 105], "unknown": 24, "plug": [24, 85, 86], "diet": 24, "ag": [24, 25, 75, 77, 78, 79, 80, 82, 102], "simplic": [24, 70], "attempt": [24, 26, 79, 81], "rng": [], "default_rng": [], "hundr": 64, "6x": [], "grai": [25, 74, 76, 82, 103, 105], "linregress": 25, "ordinari": [25, 123], "sqaur": 25, "set_xlabel": [25, 56, 61, 68, 70, 71, 79, 82, 85, 86, 87, 88, 89, 90, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "set_ylabel": [25, 56, 57, 58, 61, 68, 69, 70, 71, 78, 79, 81, 82, 85, 86, 87, 88, 89, 90, 103, 105, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "2f": [25, 113, 114, 115, 120], "rvalu": 25, "nwith": 25, "2e": [25, 60, 123], "pvalu": 25, "move": [24, 25, 56, 57, 59, 76, 81, 88, 89, 90, 91, 103, 115, 118], "bereit": [25, 77], "ancient": 25, "bubbl": [25, 74], "trap": [25, 77], "antarctica": [25, 77], "shakun": 25, "planktic": 25, "foraminifera": [25, 79], "antarct": [25, 77], "gold": [25, 34], "standard": [25, 34, 44, 45, 68, 75, 76, 77, 78, 79, 80, 81, 91, 99, 102, 108, 110, 112, 113, 118, 120, 122, 123], "glacial": [25, 77, 78, 79, 80, 82, 99], "interglaci": [25, 77, 79, 80], "unmatch": 25, "exagger": 25, "w2d1_futureclim": 25, "ipcciphysicalbasi": 25, "shakun2015_sst": 25, "txt": [25, 75, 77, 81, 91, 105], "filename_shakun2015_sst": 25, "url_shakun2015_sst": 25, "kmy5w": 25, "read_tabl": [25, 81], "set_index": [25, 108, 109, 110, 111, 112, 114], "inplac": [25, 77, 102], "dataantarctica2015co2composite_clean": 25, "filename_antarctica2015co2composite_clean": 25, "antarctica2015co2composite_clean": 25, "url_antarctica2015co2composite_clean": 25, "45fev": 25, "age_gas_calbp": [25, 77], "sharex": [25, 57, 68, 70, 71, 113], "closer": [25, 47, 70, 75, 90, 105], "subplots_adjust": [25, 120], "hspace": 25, "stack": [25, 75, 76], "c4": 25, "co2_ppm": [25, 77], "c1": [25, 77, 78, 81, 97, 98, 99, 103, 105, 112, 113, 115], "beautif": 25, "set_xlim": [25, 71, 79, 81, 82, 89, 90, 103, 105, 108, 110, 111, 113, 114, 115], "805": 25, "ka": [25, 79], "bp": [25, 76, 77, 78, 79, 80, 82], "detrend": 25, "_": [25, 58, 67, 78, 80, 85, 86, 89, 90, 94, 95, 96, 97, 98, 99, 103, 105, 108, 111, 112, 114, 118, 119], "mathrm": [25, 101, 103, 105], "ppm": [25, 77, 95], "despin": 25, "cleaner": [25, 95, 98], "clean": [25, 99, 119], "tick": [25, 102, 103, 105, 118, 120], "xaxi": [25, 57], "set_ticks_posit": 25, "xlabel": [25, 56, 79, 85, 94, 95, 96, 97, 98, 99, 108, 114], "yaxi": [25, 120], "set_label_posit": 25, "overlap": [25, 65, 79, 81], "set_zord": 25, "set_facecolor": [25, 115], "spine": [25, 82, 120], "set_color": 25, "tick_param": [25, 120], "age_model_interp": 25, "co2_ag": 25, "sst_age": 25, "linearli": [25, 43, 78, 103], "interp1d": 25, "all_ag": 25, "co2_interpol": 25, "x_fit": 25, "arang": [25, 58, 85, 88, 94, 103, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120], "y_fit": 25, "distinguish": [25, 57, 59, 64, 91, 96], "defici": 25, "contrast": [25, 56, 65, 67, 69, 70, 98, 102, 103, 110], "checker": 25, "blind": 25, "cobli": 25, "davidmathlog": 25, "colorblind": 25, "palett": 25, "pydata": 25, "color_palett": 25, "eggleston": 25, "schmitt": 25, "nehrbass": 25, "ahl": 25, "fischer": 25, "kipfstuhl": 25, "chappellaz": 25, "revis": [25, 34, 77], "epica": [25, 77], "dome": [25, 77], "800": [25, 26, 74, 75, 77, 81], "600": [25, 56, 57, 68, 69, 77, 85, 105, 112], "kyr": [25, 77, 79, 80], "42": [25, 107], "542": 25, "549": [25, 27], "2014gl061957": [25, 77], "lea": 25, "lisiecki": [25, 79], "raymo": [25, 79], "\u03b418o": 25, "planetari": 25, "426": 25, "58": 25, "68": [25, 82], "epsl": 25, "042": [25, 79], "samuel": 26, "akpan": 26, "yswuuhu3y_i": [], "bv1h94y1b7xi": [], "yje9x": [], "thousand": [26, 82], "nevertheless": [26, 109], "bear": [26, 64], "impli": [26, 64, 85, 86, 87, 90, 101, 102, 111, 113, 114], "causat": 26, "appear": [26, 58, 64, 65, 66, 71, 74, 90, 101, 102, 103, 105, 110, 112, 120], "automat": [26, 36, 44, 45, 46, 56, 66, 67, 68, 69, 90], "establish": [26, 65, 68, 79, 97, 103, 114], "imper": 26, "gather": [26, 69], "underscor": [26, 102], "corrobor": 26, "donovan": 26, "voic": 26, "eo": 26, "104": 26, "2023eo230085": 26, "tandon": 26, "carbon": [26, 39, 52, 61, 64, 74, 77, 85, 87, 89, 95, 103, 118], "carbonbrief": 26, "xzfqyancnpk": [], "bv1494y1b7q": [], "9s6ub": [], "break": [27, 28, 46, 102, 119], "perpetu": 27, "drawback": 27, "kept": 27, "paywal": 27, "compani": [27, 64, 121], "expens": [27, 115], "fee": 27, "usd": 27, "instanc": [27, 42, 49, 60, 64, 65, 103, 109, 110, 111, 112, 114, 115, 118, 119, 120], "podcast": 27, "media": [27, 63, 105], "gatekeep": 27, "enforc": 27, "worst": [27, 113], "bias": [27, 119, 120], "reject": 27, "went": 27, "win": 27, "nobel": 27, "prize": 27, "resist": 27, "campanario": 27, "laureat": 27, "scientometr": 27, "81": [27, 87], "565": 27, "bancroft": 27, "ryoo": 27, "mile": 27, "promot": 27, "106": 27, "1232": 27, "sce": 27, "21733": 27, "begin": [28, 35, 40, 55, 57, 58, 59, 70, 75, 81, 85, 86, 87, 88, 91, 95, 102, 103, 109, 111, 113, 118, 119, 123], "ceremoni": 28, "sundai": 28, "9th": 28, "w1d4": 28, "session": [28, 65, 67, 68, 69, 70, 71, 105], "ii": 28, "iii": 28, "spent": [28, 80], "synchron": [28, 70], "coursework": 28, "lectur": [28, 84, 85, 88, 90, 91, 94, 99, 123], "beforehand": [28, 123], "farewel": 28, "goodby": 28, "impos": [28, 64, 102, 105, 115], "graduat": 28, "crowdcast": [28, 33], "saturdai": 28, "comptool": 33, "neuromatchacademi": 33, "precours": [33, 123], "violat": 33, "shrezdsthwplj4rpi": 33, "exempt": 33, "shrupmgfgax5qeauk": 33, "shr7cb9qlcivejpud": 33, "circumst": 33, "ill": 33, "electr": [33, 118], "blackout": 33, "request": [33, 69, 70, 89, 90, 105], "despit": [33, 68, 69, 81, 103], "grant": 33, "neuromatch": [33, 117, 123], "elig": 33, "anywai": 33, "button": [34, 35, 36, 123], "jupyterhub": [34, 36], "drive": [34, 40, 57, 59, 60, 77, 80, 81, 101, 102, 103, 105, 119], "unlik": [34, 35, 36, 49, 68, 79, 94, 102, 103, 113, 115, 123], "overwrit": 34, "browser": 34, "git": [34, 35], "histori": [34, 36, 73, 82, 86, 88, 99, 103], "easi": [34, 44, 56, 91, 119], "revert": [34, 36], "dot": [34, 36, 42, 44, 56, 69, 70, 118, 120], "maintain": [34, 35, 64, 65, 86, 91], "pin": [34, 36, 94], "ipynb": [34, 35], "seamless": 35, "kaggl": 35, "flexibl": [35, 43], "readthedoc": 35, "stabl": [35, 65, 68, 81, 87, 88, 90, 105, 112, 119], "usernam": [35, 36], "rocketship": 35, "wait": [35, 120], "node": [35, 91, 94, 102, 119, 120], "login": 35, "preload": 35, "subfold": 35, "delet": [35, 120], "permiss": 35, "cannot": [35, 36, 44, 71, 87, 109, 112], "simultan": [35, 36, 59, 91], "snippet": 35, "substitut": [36, 86], "sign": [36, 70, 99, 110, 111, 120, 123], "regist": 36, "phone": 36, "verifi": [36, 56, 71, 88, 119], "icon": 36, "corner": [36, 57, 123], "scroll": [36, 68, 102], "verif": [36, 71], "error": [36, 43, 67, 74, 76, 118, 119, 120], "asococi": 36, "workaround": [36, 89, 90], "bar": [36, 69, 85, 94, 105, 119, 120], "toggl": 36, "fetch": [36, 44, 45, 46, 47, 48, 49, 50, 56], "extern": [36, 103], "restart": 36, "acceler": [36, 87, 102], "NOT": 36, "privat": [36, 64, 105], "comment": [36, 43, 58, 66, 67, 68, 69, 70, 71, 82, 105, 114, 115], "commit": 36, "separ": [36, 59, 70, 90, 94, 96, 105, 114, 119, 120], "manual": [36, 44], "daniela": 37, "buchwald": 37, "ucar": 75, "nasa_sci": [], "tar": [], "projectpythia": 58, "ll": [40, 42, 43, 44, 45, 46, 47, 48, 56, 64, 65, 67, 74, 75, 76, 77, 78, 79, 80, 81, 82, 91, 94, 95, 99, 101, 102, 103, 105, 123], "mechan": [40, 49, 59, 81, 102, 115, 123], "contest": 40, "elabor": [40, 87], "dimension": [40, 42, 44, 67, 70, 78, 89, 91, 119, 120], "analyt": 40, "rheqhwtaoj0": [], "bv1eh4y1j7fb": [], "ghmn5": [], "julia": [42, 43, 44, 45, 46, 47, 48, 49, 50, 123], "kent": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 123], "yosm": [42, 74, 75, 76, 77, 78, 79, 80, 81, 82, 114], "berm\u00fadez": [42, 56, 74, 75, 76, 77, 78, 79, 80, 81, 82, 112, 114], "younkap": [42, 43, 44, 45, 46, 47, 48, 49, 50, 64, 65, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "duplex": [42, 43, 44, 45, 46, 47, 48, 49, 50, 64, 65, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "danika": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61], "Will": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91], "nfdi4earth": 42, "rose": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 80, 84, 89, 90], "tyle": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "clyne": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "banihirw": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "camron": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "grover": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "ford": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "morlei": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "eroglu": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "kailyn": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "zacharia": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "v2023": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "8065851": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "manipul": [42, 45, 59, 75, 79, 86, 87, 88, 89, 90, 91, 94, 108, 109, 110, 111, 120, 123], "shorten": [42, 64], "namespac": 42, "capabl": [42, 64, 65], "streamlin": 42, "excel": [42, 102, 113], "tabular": 42, "goe": [42, 82, 120], "java": 42, "cdm": 42, "ndarrai": [42, 120], "critic": [42, 57, 60, 64, 65, 68, 70, 71, 94, 115, 121], "slice": [42, 44, 56, 57, 58, 59, 61, 67, 68, 69, 70, 71, 79, 82, 97, 98, 99, 113, 115], "power": [42, 58, 64, 79, 80, 102, 103, 109, 118, 119], "plain": [42, 119], "properti": [42, 54, 60, 64, 65, 75, 89, 95], "kelvin": [42, 43, 45], "rand_data": [42, 43], "283": [42, 43, 60], "randn": [42, 43, 118], "287": [], "30004238": [], "279": 43, "96462419": [], "289": [], "33818326": [], "278": [], "55649813": [], "284": [], "84648505": [], "286": [], "94349482": [], "291": [], "64248331": [], "68039147": [], "276": 75, "93814958": [], "275": [], "88810895": [], "6641585": [], "288": [85, 86, 87], "78296891": [], "87602307": [], "282": [], "19735444": [], "15916874": [], "20651612": [], "285": 71, "6367308": [], "51659197": [], "271": 75, "78601119": [], "27884725": [], "80188567": [], "66941914": [], "272": [], "4363261": [], "2552918": [], "33233858": [], "45682368": [], "35047637": [], "34909696": [], "29046385": [], "27226777": [], "290": 78, "43069201": [], "19238873": [], "07894087": [], "83400145": [], "03288116": [], "41329217": [], "6262076": [], "27608622": [], "04108469": [], "26128117": [], "64851454": [], "40605777": [], "14655877": [], "67599442": [], "81273162": [], "49158461": [], "77403377": [], "07082354": [], "16456344": [], "67027": [], "72843928": [], "00417952": [], "80208031": [], "11202527": [], "17215298": [], "482837": [], "49580517": [], "39131902": [], "21226121": [], "21512917": [], "lt": [43, 88], "dim_0": 42, "dim_1": 42, "dim_2": 42, "gt": [43, 88], "dim_2xarrai": [], "dataarraydim_0": [], "5dim_1": [], "3dim_2": [], "4287": [], "2arrai": 43, "symbol": [42, 94], "collaps": [42, 102], "lonxarrai": [], "dataarraytim": 43, "5lat": [], "3lon": [], "times_index": [42, 43], "date_rang": [42, 43], "datetimeindex": 43, "04": [43, 70, 102], "dtype": [43, 88], "datetime64": 43, "ns": 43, "freq": 43, "linspac": [42, 43, 75, 80, 88, 103, 105, 110, 112, 113, 114, 115, 118], "120": [42, 43, 56, 60, 61, 71, 75, 113], "float64": 88, "80": [94, 99, 110, 114, 119], "0xarrai": [], "05arrai": 43, "x27": 43, "000000000": 43, "02t00": 43, "03t00": 43, "04t00": 43, "05t00": 43, "float6425": [], "0arrai": [], "timepandasindexpandasindex": 43, "latpandasindexpandasindex": [], "float64index": [], "lonpandasindexpandasindex": [], "air_temperatur": [42, 43], "standard_nam": [42, 43], "air_temperaturexarrai": 43, "kelvinstandard_nam": 43, "operaton": 42, "persist": [42, 58, 102, 103], "lost": [42, 87, 101], "arbitrari": 42, "arithmet": [42, 50], "oper": [42, 43, 46, 47, 50, 57, 61, 64, 65, 66, 75, 86, 87, 88, 91, 94, 95, 96, 101, 103, 113, 118, 123], "celsiu": [42, 45, 69], "temperature_in_celsiu": 42, "273": [42, 45, 60, 61, 85, 86], "15004238": [], "81462419": [], "18818326": [], "40649813": [], "69648505": [], "79349482": [], "49248331": [], "53039147": [], "78814958": [], "73810895": [], "5141585": [], "63296891": [], "72602307": [], "04735444": [], "00916874": [], "05651612": [], "4867308": [], "36659197": [], "36398881": [], "12884725": [], "65188567": [], "51941914": [], "7136739": [], "1052918": [], "18233858": [], "30682368": [], "20047637": [], "19909696": [], "14046385": [], "12226777": [], "28069201": [], "04238873": [], "92894087": [], "68400145": [], "88288116": [], "26329217": [], "4762076": [], "12608622": [], "89108469": [], "11128117": [], "49851454": [], "25605777": [], "99655877": [], "52599442": [], "66273162": [], "34158461": [], "62403377": [], "92082354": [], "01456344": [], "52027": [], "57843928": [], "85417952": [], "65208031": [], "96202527": [], "02215298": [], "332837": [], "34580517": [], "24131902": [], "06226121": [], "06512917": [], "414": [], "815": [], "406": [], "333": [], "062": [], "065arrai": [], "handl": [42, 44, 78, 91, 105, 120], "hold": [42, 64, 80, 85, 115, 118], "dataarri": 42, "hectopasc": 42, "hpa": [42, 43, 44, 89, 90], "mirror": 42, "pressure_data": [42, 43], "air_pressur": [42, 43], "1005": [], "2463415": [], "987": [], "19230793": [], "1004": 87, "95175743": [], "13482413": [], "999": 111, "3662821": [], "61526526": [], "1001": 80, "06100777": [], "55600907": [], "46302004": [], "30072169": [], "05290865": [], "1010": [], "96602342": [], "55542882": [], "998": [], "0574432": [], "40775914": [], "993": [], "66134368": [], "997": [], "51294951": [], "3559693": [], "994": [], "94831033": [], "992": [], "45051202": [], "57219364": [], "70049775": [], "01416121": [], "13215414": [], "996": [], "92593195": [], "94954424": [], "995": [], "88661979": [], "48297269": [], "71305511": [], "14083899": [], "63047121": [], "12851258": [], "46026687": [], "92623891": [], "01555232": [], "64461369": [], "13413944": [], "15806582": [], "80136734": [], "57063699": [], "1003": [], "46873919": [], "29717551": [], "60949284": [], "79764901": [], "00004094": [], "81007592": [], "89718899": [], "07826515": [], "46388603": [], "00962637": [], "05717419": [], "55038162": [], "96795674": [], "7536812": [], "9720689": [], "85551332": [], "92468525": [], "1006": [], "41823127": [], "73033254": [], "51145841": [], "air_pressurexarrai": [], "41": [44, 107, 110], "005e": [], "1e": [85, 103, 113], "006e": [], "5arrai": [], "hpastandard_nam": [], "straightforward": [42, 122], "5xarrai": [], "datasetdimens": [], "4coordin": [], "float64287": [], "2unit": [], "air_temperaturearrai": [], "float641": [], "5unit": [], "air_pressurearrai": [], "sit": 42, "pull": [42, 44, 75, 91, 105, 109], "notat": [42, 43, 44, 75, 85, 86, 87, 88], "synthet": [42, 43], "agustina": [43, 44, 45, 46, 47, 48, 49, 50, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 88, 94, 102, 103, 105, 108, 109, 110, 111, 113, 114], "pesc": [43, 44, 45, 46, 47, 48, 49, 50, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 87, 88, 94, 102, 103, 105, 108, 109, 110, 111, 113, 114], "interp": [43, 78, 79, 80], "timedelta": 43, "ex4bmd3zitq": [], "bv1rg4y1w7yq": [], "recreat": [43, 81, 90, 96], "pressur": [43, 44, 57, 58, 60, 80, 87, 89, 90], "briefli": [43, 56], "011e": [], "002e": [], "7xarrai": [], "1unit": [], "41182637": [], "62028429": [], "78000434": [], "72283686": [], "44622269": [], "84301883": [], "6063566": [], "01807061": [], "9710587": [], "78407615": [], "87094757": [], "46465961": [], "87526182": [], "41027491": [], "61643234": [], "12913177": [], "52283971": [], "37558863": [], "33168792": [], "274": [], "45441381": [], "63731757": [], "07465172": [], "78077824": [], "15253592": [], "17088002": [], "85758136": [], "89060368": [], "22191127": [], "18414648": [], "19591064": [], "79316695": [], "3198091": [], "30891342": [], "32945551": [], "5937767": [], "21486096": [], "06421134": [], "81757823": [], "12617404": [], "62130106": [], "24320773": [], "79592909": [], "33860985": [], "11962959": [], "97568798": [], "292": 43, "37060028": [], "268": [], "69065567": [], "17389425": [], "89832067": [], "90615743": [], "0051514": [], "75853059": [], "97461411": [], "74796435": [], "11353983": [], "28124967": [], "92563363": [], "92636582": [], "38054537": [], "13592907": [], "7unit": [], "61295845": [], "20074276": [], "92215883": [], "13767004": [], "41774151": [], "93934719": [], "72201801": [], "45744828": [], "52773053": [], "991": [], "13791261": [], "49768303": [], "02239286": [], "66046549": [], "14984368": [], "20835963": [], "985": [], "86454789": [], "986": [], "62521813": [], "93030952": [], "17583236": [], "13519211": [], "00345807": [], "03890585": [], "75094524": [], "24274852": [], "43291068": [], "34617831": [], "16180596": [], "77007606": [], "15540963": [], "6731428": [], "07066565": [], "73989296": [], "882602": [], "50177778": [], "63467495": [], "71218834": [], "57408264": [], "57330558": [], "58502816": [], "988": [], "36247054": [], "51155295": [], "82063313": [], "62255982": [], "84078686": [], "82762904": [], "84936396": [], "1012": [], "5375731": [], "96063377": [], "68977647": [], "1008": [], "24508268": [], "8961985": [], "60806233": [], "23135713": [], "22619812": [], "03793115": [], "65424561": [], "33607845": [], "1009": [], "4172285": [], "80699499": [], "66952968": [], "refresh": [43, 46, 67, 87, 123], "memori": [43, 66, 69, 94, 123], "suppos": [43, 85, 120], "januari": [43, 46, 58, 67, 68, 69, 71, 94, 107], "indexed_select": 43, "dataarraylat": [], "4279": [], "02arrai": [], "named_select": 43, "didn": 43, "agnost": 43, "deal": [43, 48, 78, 109, 111, 113], "intend": [43, 65], "clearer": [43, 44, 47, 49, 68], "rais": [43, 58, 66, 68, 69, 70, 71, 102, 103, 119], "notimplementederror": [43, 58, 66, 68, 69, 70, 71, 102], "coordinate_select": 43, "incomplet": [43, 119], "frequent": [43, 56, 64, 65, 68, 71, 76, 108, 109], "desir": [43, 49, 57, 65, 66, 68, 91, 94, 96, 115], "earlier": [43, 61, 66, 79, 80, 89, 94, 96, 103, 108, 118, 119], "toler": 43, "inexact": 43, "lookup": 43, "maximum": [43, 45, 64, 66, 67, 71, 78, 82, 99, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 120], "distanc": [43, 64, 78], "4286": [], "1arrai": [], "25\u00ban": 43, "40\u00ban": 43, "55\u00ban": 43, "120\u00baw": [43, 56], "100\u00baw": 43, "80\u00baw": 43, "60\u00baw": 43, "But": [43, 56, 65, 66, 81, 103, 118, 120], "timeseri": [43, 70, 74, 79, 95, 96, 98, 99, 108, 112, 115], "105": 43, "similarli": [43, 74, 91, 103, 109, 110, 114], "2438198": [], "9124014": [], "9429696": [], "65774875": [], "80462679": [], "int64": 43, "5279": [], "8arrai": [], "105arrai": 43, "int6440arrai": 43, "cubic": [43, 78], "quadrat": [43, 78, 103, 114], "actual": [43, 85, 86, 90, 91, 95, 98, 103, 110, 118, 119, 120], "equatori": [43, 56, 61, 81], "110\u00baw": 43, "70\u00baw": 43, "110": [43, 111, 113], "3lat": [], "2lon": [], "2288": [], "03arrai": [], "bracket": 43, "sort": [43, 109, 111, 113], "temp": [43, 44, 56, 88], "fulli": [43, 87, 103, 118], "verbos": 43, "intereset": 43, "multidimension": [44, 78], "humid": [44, 78, 89, 90, 115, 118], "wind": [44, 54, 56, 57, 60, 70, 80, 90, 115], "itself": [44, 79, 87, 102, 109, 115], "pythia_dataset": 44, "7yjm9mdleoo": [], "bv1wz4y177x": [], "treat": 44, "cach": 44, "narr_19930313_0000": 44, "filepath": [44, 45, 46, 47, 48, 49, 50, 57], "time1": [], "isobaric1": 44, "29": [44, 105, 114, 115, 120], "float32": [], "125": [], "117e": [], "084e": [], "714": [], "324e": [], "343e": [], "component_of_wind_isobar": 44, "lambertconformal_project": [], "int32": [], "geopotential_height_isobar": [], "temperature_isobar": 44, "originating_or_generating_cent": [], "originating_or_generating_subcent": [], "grib_table_vers": [], "131": [], "generating_process_or_model": [], "convent": [57, 58, 91, 98, 103, 110, 111, 118], "cf": [], "iosp": [], "gribcollect": [], "v3": [], "featuretyp": [], "translat": [88, 105, 115], "geospatial_lat_min": [], "753308882144761": [], "geospatial_lat_max": [], "46": [85, 107], "8308828962289": [], "geospatial_lon_min": [], "153": [], "88242040519995": [], "geospatial_lon_max": [], "666108129242815xarrai": [], "1isobaric1": [], "29y": [], "119x": [], "268coordin": [], "13standard_nam": [], "timelong_nam": [], "grib": [], "time_coordinateaxistyp": [], "timearrai": [], "13t00": [], "float32100": [], "150": [59, 91], "975": [], "03unit": [], "hpalong_nam": [], "isobar": 44, "surfaceposit": [], "downgrib_level_typ": [], "100_coordinateaxistyp": [], "pressure_coordinatezisposit": [], "downarrai": [], "175": 59, "225": [], "350": [], "450": [], "500": [44, 64, 65, 67, 78, 81, 88, 109, 111, 114, 120], "550": [], "650": [77, 112], "700": 61, "725": [], "750": [], "775": [], "825": [], "850": 81, "875": [], "900": [], "925": [], "950": [], "1standard_nam": [], "projection_y_coordinateunit": [], "km_coordinateaxistyp": [], "geoyarrai": [], "116548e": [], "084085e": [], "051622e": [], "019159e": [], "986696e": [], "954233e": [], "921770e": [], "889307e": [], "856844e": [], "824381e": [], "791918e": [], "759455e": [], "726992e": [], "694529e": [], "662066e": [], "629603e": [], "597140e": [], "564677e": [], "532214e": [], "499751e": [], "467288e": [], "434825e": [], "402362e": [], "369899e": [], "337436e": [], "304973e": [], "272510e": [], "240047e": [], "207584e": [], "175121e": [], "142658e": [], "110195e": [], "077732e": [], "045269e": [], "012806e": [], "980343e": [], "947880e": [], "915417e": [], "882954e": [], "850491e": [], "818028e": [], "785565e": [], "753102e": [], "720639e": [], "688176e": [], "655713e": [], "623250e": [], "590787e": [], "558324e": [], "525861e": [], "493398e": [], "460935e": [], "428472e": [], "396009e": [], "363546e": [], "331083e": [], "298620e": [], "266157e": [], "233694e": [], "201231e": [], "168768e": [], "136305e": [], "103842e": [], "071379e": [], "038916e": [], "006453e": [], "739901e": [], "415271e": [], "090641e": [], "766011e": [], "441381e": [], "116751e": [], "792121e": [], "467491e": [], "142861e": [], "818231e": [], "493601e": [], "168971e": [], "844341e": [], "519711e": [], "195081e": [], "870451e": [], "545821e": [], "221191e": [], "896561e": [], "571931e": [], "247301e": [], "922671e": [], "598041e": [], "273411e": [], "948781e": [], "624151e": [], "299521e": [], "748907e": [], "502608e": [], "256308e": [], "000744e": [], "236293e": [], "482593e": [], "728893e": [], "297519e": [], "622149e": [], "946779e": [], "271409e": [], "596039e": [], "920669e": [], "245299e": [], "569930e": [], "894559e": [], "219189e": [], "543820e": [], "868449e": [], "193079e": [], "517709e": [], "842339e": [], "166970e": [], "491600e": [], "816229e": [], "140859e": [], "292e": [], "03standard_nam": [], "projection_x_coordinateunit": [], "geoxarrai": [], "3324": [], "4707": [], "3292": [], "0078": [], "3259": [], "5447": [], "5278": [], "2246": [], "5310": [], "6875": [], "5343": [], "1504": [], "surfaceunit": [], "1descript": [], "windgrid_map": [], "lambertconformal_projectiongrib_variable_id": [], "var_7": [], "33_l100grib1_cent": [], "7grib1_subcent": [], "15grib1_tablevers": [], "131grib1_paramet": [], "33grib1_level_typ": [], "100grib1_level_desc": [], "924868": [], "grid_mapping_nam": [], "lambert_conformal_coniclatitude_of_projection_origin": [], "000003814697266longitude_of_central_meridian": [], "107": [], "00000762939453standard_parallel": [], "000003814697266earth_radiu": [], "6367470": [], "0_coordinatetransformtyp": [], "projection_coordinateaxistyp": [], "geox": [], "geoi": [], "degrees_northlong_nam": [], "coordinatestandard_nam": [], "latitude_coordinateaxistyp": [], "31892": [], "degrees_eastlong_nam": [], "longitude_coordinateaxistyp": [], "geopotenti": 44, "gpmdescript": [], "heightgrid_map": [], "7_l100grib1_cent": [], "7grib1_level_typ": [], "34_l100grib1_cent": [], "34grib1_level_typ": [], "kdescript": [], "temperaturegrid_map": [], "11_l100grib1_cent": [], "11grib1_level_typ": [], "time1pandasindexpandasindex": [], "isobaric1pandasindexpandasindex": [], "ypandasindexpandasindex": [], "3116": [], "548095703125": [], "3084": [], "085205078125": [], "3051": [], "6220703125": [], "3019": [], "1591796875": [], "2986": [], "6962890625": [], "2954": [], "233154296875": [], "2921": [], "770263671875": [], "2889": [], "30712890625": [], "2856": [], "84423828125": [], "2824": [], "381103515625": [], "421": [], "9189453125": [], "454": [], "3819580078125": [], "486": [], "8449401855469": [], "519": [], "3079223632812": [], "551": [], "7709350585938": [], "584": [], "2339477539062": [], "616": [], "6969604492188": [], "649": [], "1599731445312": [], "681": [], "6229248046875": [], "0859375": [], "length": [48, 57, 65, 66, 78, 81, 105, 109, 118, 119], "xpandasindexpandasindex": [], "470703125": [], "0078125": [], "544677734375": [], "3227": [], "081787109375": [], "3194": [], "61865234375": [], "3162": [], "15576171875": [], "3129": [], "692626953125": [], "3097": [], "229736328125": [], "3064": [], "7666015625": [], "3032": [], "3037109375": [], "5050": [], "9833984375": [], "5083": [], "44677734375": [], "5115": [], "90966796875": [], "5148": [], "37255859375": [], "5180": [], "83544921875": [], "5213": [], "298828125": [], "5245": [], "76171875": [], "224609375": [], "150390625": [], "ncep": [57, 89], "projectgrib_table_vers": [], "131generating_process_or_model": [], "6histori": [], "v3featuretyp": [], "gridhistori": [], "cfgridwriter2": [], "datasetscan": [], "a_221_19930313_0000_000": [], "grb": [], "04t23": [], "043zgeospatial_lat_min": [], "753308882144761geospatial_lat_max": [], "8308828962289geospatial_lon_min": [], "88242040519995geospatial_lon_max": [], "666108129242815": [], "character": [44, 56, 65, 70, 103], "constant": [44, 50, 56, 60, 80, 85, 86, 87, 88, 89, 90, 95, 103, 110, 112, 115], "syntax": [44, 46], "grib_level_typ": [], "_coordinateaxistyp": [], "_coordinatezisposit": [], "downxarrai": [], "29100": [], "altitud": 44, "parallel": 44, "proport": [44, 105, 110], "bit": [44, 50, 56, 57, 64, 66, 75, 76, 79, 105], "ds_1000": 44, "1y": [113, 115], "float321": [], "052e": [], "311e": [], "grid_map": [], "grib_variable_id": [], "11_l100": [], "grib1_cent": [], "grib1_subcent": [], "grib1_tablevers": [], "grib1_paramet": [], "grib1_level_typ": [], "grib1_level_desc": [], "surfacexarrai": [], "saw": [44, 45, 61, 68, 94, 95, 96, 99, 102, 120], "deviat": [44, 45, 65, 67, 75, 76, 85, 101, 108, 110, 112, 113, 118, 120, 123], "std": [44, 45, 108, 110, 112, 113], "u_wind": 44, "673963": [], "212325": [], "556413": [], "254429": [], "372146": [], "472462": [], "091969": [], "846294": [], "195834": [], "936979": [], "93888": [], "060708": [], "972139": [], "722328": [], "853286": [], "257241": [], "679721": [], "4516497": [], "2352104": [], "039894": [], "883371": [], "7821493": [], "7088237": [], "6865997": [], "7247376": [], "745023": [], "6859775": [], "5107226": [], "972262": [], "03xarrai": [], "298": [], "674": [], "56": [105, 120], "47": 74, "745": [], "686": [], "511": [], "972arrai": [], "exercis": [44, 65, 123], "bound": [44, 56, 97, 98, 101, 103], "182km": 44, "424km": 44, "1450km": 44, "990km": 44, "102": 44, "co_temp": 44, "182": 44, "424": [44, 75, 81], "1450": 44, "990": 44, "prof": 44, "215": [], "078": [], "76935": [], "243": [80, 88], "82663": [], "83487": [], "216": [], "10933": [], "219": [], "99902": [], "224": 64, "66118": [], "228": [], "80576": [], "234": [], "88701": [], "238": [], "78503": [], "242": 88, "66309": [], "44807": [], "249": [], "26636": [], "84995": [], "253": [], "37354": [], "257": [], "0429": [], "259": [], "08398": [], "260": [], "97955": [], "262": [], "98364": [], "264": [], "82138": [], "266": [], "5198": [], "22467": [], "7471": [], "18216": [], "66815": [], "13037": [], "54718": [], "97675": [], "29215": [], "autom": [44, 66, 71], "line2d": [], "0x166543af0": [], "auto": 44, "wrapper": 44, "upward": [44, 80, 91], "yincreas": 44, "0x1678ac2b0": [], "quadmesh": [], "0x1678d3820": [], "joi": 44, "workhors": 44, "geoscienc": [44, 78], "simpler": [44, 114], "easier": [44, 48, 61, 69, 89, 94, 96, 103, 111, 123], "alongsid": [45, 57, 70, 88, 99], "latitudin": [45, 58, 61, 82], "distort": 45, "meridion": [45, 58, 59, 61], "transport": [45, 56, 58, 59, 61, 91], "heat": [45, 53, 54, 59, 80, 86, 87, 88, 90, 91, 95, 107, 115, 123], "represent": [45, 67, 85, 86, 87, 98, 105, 119, 123], "transfer": [45, 89, 91], "e3uewlak5z": [], "bv1gz4y177vk": [], "vector": [45, 50, 57, 58, 59, 75, 105, 111, 119, 123], "cesm2_sst_data": [45, 46, 47, 48, 49, 50, 56], "nicholashalp": [], "anaconda3": [], "env": [], "431": [], "serializationwarn": [], "new_var": [], "decode_cf_vari": [], "d2": [], "360": [48, 56, 57, 58, 66, 69, 71, 76, 88, 94], "88": [74, 76], "87": 109, "86": [], "356": [], "357": 82, "358": 88, "359": [], "lat_bnd": [], "lon_bnd": [], "activity_id": [], "branch_method": [], "branch_time_in_child": [], "674885": [], "branch_time_in_par": [], "219000": [], "case_id": [], "972": [], "sub_experiment_id": [], "tracking_id": [], "hdl": [], "14100": [], "2975ffd3": [], "1d7b": [], "47e3": [], "961a": [], "33f212ea4eb2": [], "variant_info": [], "1850": [85, 87, 91, 95, 96, 113], "variant_label": [], "r11i1p1f1xarrai": [], "180d2": [], "2lat": [], "180lon": [], "360coordin": [], "object2000": [], "tbound": [], "time_bndsstandard_nam": [], "timetitl": [], "timetyp": [], "doublearrai": [], "cftime": [89, 90, 115], "datetimenoleap": [], "has_year_zero": [], "2003": [65, 75, 115], "2004": [63, 65, 68], "2005": [79, 99, 115], "2006": [65, 87, 103], "2007": 77, "2008": [77, 78], "5axi": [], "ybound": [], "lat_bndslong_nam": [], "latitudestandard_nam": [], "latitudeunit": [], "degrees_northarrai": [], "85": [], "83": 99, "82": [], "78": [], "77": [63, 115], "76": [], "75": [60, 61, 85, 90, 115], "74": 71, "73": 113, "72": [110, 113], "71": [71, 113], "69": [], "67": [75, 80, 85], "66": 97, "65": 58, "64": [88, 103], "63": 105, "62": [85, 105], "61": [105, 115], "59": 85, "54": 120, "53": 120, "49": 74, "44": 85, "43": 99, "39": [105, 113], "38": [105, 113, 115], "float640": [], "xbound": [], "lon_bndslong_nam": [], "longitudestandard_nam": [], "longitudeunit": [], "degrees_eastarrai": [], "boundsunit": [], "degrees_north": 94, "degrees_east": 94, "720": [], "cell_measur": [], "areacellocell_method": [], "meancom": [], "1x1": [], "percent": [60, 110, 111, 118], "chosen": [61, 71, 78, 87, 101, 102, 103, 122], "quot": [], "float": [61, 69, 115, 120], "shelv": [], "conserv": [60, 64, 65, 123], "prognost": [], "monid": [], "toslong_nam": [], "temperaturemipt": [], "omonout_nam": [], "tosprov": [], "isd": [], "realm": 64, "oceanstandard_nam": [], "sea_surface_temperaturetim": [], "timetime_label": [], "meantime_titl": [], "meantitl": [], "temperaturetyp": [], "realunit": [], "degcvariable_id": [], "11664000": [], "cftimeindex": [], "06": 65, "08": 58, "calendar": 75, "noleap": [], "351": [], "352": [], "353": [], "354": [], "355": [], "2activity_id": [], "cmipbranch_method": [], "standardbranch_time_in_child": [], "0branch_time_in_par": [], "0case_id": [], "972cesm_casenam": [], "e21": [], "bhist": [], "f09_g17": [], "011contact": [], "cesm_cmip6": [], "educreation_d": [], "02t04": [], "58zdata_specs_vers": [], "29experi": [], "initialis": [], "earli": [56, 123], "historicalexternal_vari": [], "areacelloforcing_index": [], "1frequenc": [], "monfurther_info_url": [], "furtherinfo": [], "es": [], "r11i1p1f1grid": [], "gx1v7": [], "displac": [], "pole": [46, 47, 58, 60, 61, 64, 68, 89, 90, 94, 115], "384x320": [], "latxlon": [], "180x360": [], "regriddinggrid_label": [], "grinitialization_index": [], "1institut": [], "mesa": [], "80305": [], "usainstitution_id": [], "ncarlicens": [], "creativ": [], "sharealik": [], "creativecommon": 87, "pcmdi": [], "llnl": [], "termsofus": [], "proper": 123, "further_info_url": [], "warranti": [], "merchant": 63, "purpos": [49, 57, 64, 65, 67, 69, 88, 115], "liabil": [], "aris": [60, 101, 102, 103, 123], "suppli": [49, 50, 101, 103], "neglig": [102, 103], "fullest": [], "permit": 103, "mip_era": [], "cmip6model_doi_url": [], "5065": [], "d67h1h0vnominal_resolut": [], "degreeparent_activity_id": [], "cmipparent_experiment_id": [], "picontrolparent_mip_era": [], "cmip6parent_source_id": [], "cesm2parent_time_unit": [], "0001": [], "00parent_variant_label": [], "r1i1p1f1physics_index": [], "1product": [], "outputrealization_index": [], "11realm": [], "oceansourc": [], "cam6": [], "9x1": [], "finit": [102, 103], "192": [], "mb": [], "pop2": [], "320x384": [], "sea_ic": [], "cice5": [], "clm5": [], "mam4": [], "atmoschem": [], "landic": [], "cism2": [], "ocnbgchem": [], "marbl": [], "cesm2source_typ": [], "aogcm": [], "bgcsub_experi": [], "nonesub_experiment_id": [], "nonetable_id": [], "omontracking_id": [], "33f212ea4eb2variable_id": [], "tosvariant_info": [], "biogeochemistri": [], "r11i1p1f1": [], "temepratur": [45, 85, 87], "cell_method": [], "time_label": [], "time_titl": [], "degc": [45, 59, 69, 70, 89, 90, 115], "tosxarrai": [], "180lat": [], "3552": [], "3553": [], "3554": [], "35495": [], "3551": [], "36005": [], "36014": [], "36023": [], "35986": [], "35992": [], "36447": [], "36453": [], "3646": [], "3643": [], "36435": [], "3644": [], "40677": [], "40674": [], "4067": [], "40695": [], "4069": [], "40683": [], "41296": [], "41293": [], "41306": [], "413": [], "41772": [], "41766": [], "4177": [], "39386": [], "39383": [], "3938": [], "39407": [], "394": [], "39392": [], "39935": [], "39932": [], "39948": [], "39944": [], "39938": [], "40372": [], "40375": [], "4037": [], "360nan": [], "4arrai": [], "2213385": [], "2209656": [], "220537": [], "2221622": [], "221913": [], "2216525": [], "203904": [], "203617": [], "2032912": [], "2045207": [], "2043478": [], "2041442": [], "1881146": [], "1879027": [], "1876712": [], "188714": [], "1885312": [], "1883302": [], "0388296": [], "0389647": [], "0390673": [], "038165": [], "0383828": [], "0386322": [], "0173173": [], "0173445": [], "0173297": [], "0169601": [], "0171173": [], "0172386": [], "000791": [], "0007784": [], "0007539": [], "000933": [], "000896": [], "0008452": [], "0839543": [], "0841148": [], "0842566": [], "0832636": [], "0834875": [], "0837412": [], "064733": [], "0648024": [], "0648358": [], "0642793": [], "0644639": [], "0646174": [], "0494578": [], "0494475": [], "0494263": [], "049596": [], "0495603": [], "0495107": [], "varianc": [45, 78, 79, 108, 123], "prod": 45, "element": [45, 49, 64, 67, 71, 75, 95, 102, 105, 112, 113, 114, 119, 123], "argmin": 45, "argmax": [45, 120], "8083605": [], "8083031": [], "8082187": [], "8083988": [], "8083944": [], "8083915": [], "8025414": [], "8024837": [], "8024155": [], "8026428": [], "8026177": [], "8025846": [], "7984415": [], "7983989": [], "7983514": [], "7985678": [], "7985296": [], "7984871": [], "799": [], "798arrai": [], "603767": [], "607702": [], "603976": [], "599373": [], "595119": [], "94": 63, "595716": [], "598177": [], "600670": [], "597825": [], "591869": [], "590507": [], "597189": [], "605954": [], "609151": [], "606868": [], "602329": [], "599465": [], "601205": [], "605144": [], "608588": [], "604046": [], "598927": [], "597519": [], "603876": [], "612424": [], "615765": [], "612615": [], "606310": [], "602034": [], "600784": [], "602013": [], "603142": [], "598850": [], "591917": [], "589234": [], "596162": [], "602942": [], "607196": [], "604928": [], "601735": [], "599011": [], "599490": [], "600801": [], "602786": [], "598867": [], "594081": [], "593736": [], "598995": [], "607285": [], "611901": [], "609562": [], "603527": [], "600215": [], "601372": [], "604144": [], "605376": [], "601256": [], "595245": [], "594002": [], "600490": [], "611878": [], "616563": [], "613050": [], "605734": [], "600808": [], "600898": [], "603930": [], "605644": [], "599917": [], "592048": [], "590082": [], "596950": [], "607701": [], "610844": [], "609509": [], "603380": [], "599838": [], "600334": [], "604386": [], "607848": [], "602155": [], "594949": [], "593815": [], "598365": [], "608730": [], "612056": [], "609922": [], "603077": [], "600134": [], "602821": [], "606152": [], "610257": [], "604685": [], "596858": [], "592894": [], "599944": [], "609764": [], "614610": [], "611434": [], "605606": [], "603790": [], "605750": [], "609250": [], "612935": [], "609645": [], "601706": [], "598896": [], "605349": [], "614671": [], "618686": [], "615895": [], "609438": [], "605399": [], "606126": [], "607942": [], "609680": [], "604814": [], "595841": [], "591908": [], "595638": [], "604798": [], "611327": [], "609765": [], "603727": [], "600970": [], "602514": [], "606303": [], "609225": [], "603724": [], "595944": [], "594477": [], "597807": [], "607379": [], "611808": [], "610112": [], "604733": [], "605488": [], "610048": [], "612655": [], "608906": [], "602349": [], "601754": [], "609220": [], "619367": [], "623783": [], "619949": [], "613369": [], "610190": [], "611091": [], "614213": [], "615665": [], "611722": [], "606259": [], "605970": [], "611463": [], "619794": [], "626036": [], "623085": [], "616295": [], "611886": [], "611881": [], "614420": [], "616853": [], "610375": [], "603471": [], "602108": [], "608094": [], "617450": [], "623508": [], "619830": [], "612033": [], "608737": [], "610105": [], "613692": [], "616360": [], "611735": [], "606512": [], "604249": [], "608777": [], "00xarrai": [], "1806": [], "038e": [], "077e": [], "04e": [], "065e": [], "042e": [], "088e": [], "7648907": [], "7648032": [], "7647004": [], "7650614": [], "7650102": [], "7649589": [], "7590305": [], "7589546": [], "7588665": [], "7591925": [], "7591486": [], "759095": [], "7536805": [], "753602": [], "7535168": [], "753901": [], "753833": [], "7537591": [], "754": [], "754arrai": [], "250171": [], "25arrai": [], "coolwarm": [45, 56, 57, 58, 60, 88, 91, 110, 120], "0x15e4ed450": [], "conclud": [45, 113, 118], "migrat": 46, "intertrop": 46, "itcz": 46, "monsoon": [46, 67, 80], "aggreg": [46, 48, 50, 64, 68, 69, 101, 102, 103, 113], "syvfyt3jvm8": [], "bv1ho4y1c7eo": [], "condition": 46, "workflow": [46, 50, 82, 91, 115], "gridpoint": [46, 108, 109, 110, 111], "50\u00ban": 46, "310\u00bae": 46, "pronounc": 46, "exactli": [46, 88, 91, 94, 110], "310": [46, 47], "0x15922c9a0": [], "appar": [46, 68, 115], "climatatolog": 46, "dataarraygroupbi": [], "datetimeaccessor": 46, "equival": [46, 56, 61, 86, 87, 95, 102], "ident": [46, 64, 89, 90, 98, 103, 113], "preserv": [46, 49, 50, 74, 78, 102], "tos_clim": [46, 47], "780786": [], "7806879": [], "7805718": [], "7809757": [], "7809196": [], "7808627": [], "7745041": [], "7744206": [], "7743237": [], "7746699": [], "7746259": [], "7745715": [], "7691481": [], "7690798": [], "7690052": [], "7693441": [], "7692841": [], "7692183": [], "7605034": [], "7603971": [], "7602727": [], "760718": [], "7606541": [], "7605885": [], "754429": [], "7543423": [], "7542424": [], "7546079": [], "7545592": [], "7545002": [], "7492164": [], "7491481": [], "7490735": [], "7494118": [], "749352": [], "7492864": [], "7711829": [], "7710832": [], "7709652": [], "771375": [], "7713183": [], "7712609": [], "7648666": [], "7647841": [], "764688": [], "7650297": [], "7649866": [], "764933": [], "759478": [], "7594113": [], "7593385": [], "7596704": [], "7596116": [], "759547": [], "12lat": [], "76arrai": [], "int641": [], "12arrai": [], "monthpandasindexpandasindex": [], "int64index": [], "0x15993b370": [], "april": [46, 67, 70], "8\u00bac": 46, "50\u00ba": 46, "zonal": [46, 59, 61, 82, 91], "contourf": [46, 58, 59], "turbo": 46, "contour": [], "quadcontourset": [], "0x15999df60": [], "ass": [46, 56, 82], "0x159af63b0": [], "understood": 47, "cdzkswnfvy": 47, "bv1p8411d7ic": 47, "split": [47, 50, 67, 68, 105, 119], "gb": [47, 91], "tos_anom": 47, "01402271": [], "01401699": [], "01401365": [], "01406252": [], "01404929": [], "01403356": [], "01544118": [], "01544452": [], "01545036": [], "01544762": [], "01544333": [], "01544082": [], "01638114": [], "01639009": [], "01639986": [], "01635301": [], "01636171": [], "01637125": [], "01727951": [], "01713443": [], "01698065": [], "0176847": [], "01755834": [], "01742125": [], "01738632": [], "01729178": [], "01719618": [], "01766801": [], "01757407": [], "01748013": [], "01693726": [], "01687264": [], "01680505": [], "01709175": [], "01704252": [], "01699162": [], "01506376": [], "01491845": [], "01476002": [], "0154525": [], "0153321": [], "0152024": [], "0142287": [], "01412642": [], "0140208": [], "01452136": [], "01442564": [], "01432812": [], "01320827": [], "01314461": [], "01307786": [], "0133611": [], "01331258": [], "01326215": [], "12xarrai": [], "01345": [], "01341": [], "01336": [], "01331": [], "01326arrai": [], "ylabel": [47, 56, 85, 94, 95, 96, 97, 98, 99, 108, 109, 112, 114, 115, 118], "unweighted_mean_global_anom": 47, "weighted_mean_global_anom": 47, "weight": [47, 50, 56, 57, 68, 75, 79, 80, 82, 87, 89, 90, 91, 94, 95, 96, 97, 98, 99, 103, 115, 118, 119, 120], "necessarili": [47, 102, 115, 118], "djexplo": 47, "cc": [47, 87], "BY": [47, 87], "unless": 47, "accomplish": [47, 49, 74, 76, 91, 109, 115], "filepath2": 47, "cesm2_grid_vari": [47, 56], "64800": [], "tarea": [], "m2": 102, "areacelloxarrai": [], "sumcom": [], "tareadescript": [], "hfsso": [], "downward": [80, 91], "onto": [78, 80, 94, 114], "fxid": [], "areacellolong_nam": [], "variablesmipt": [], "ofxout_nam": [], "areacelloprov": [], "cell_areatime_label": [], "nonetime_titl": [], "fieldtitl": [], "variablestyp": [], "m2variable_id": [], "unweight": [47, 68], "legend": [47, 48, 56, 58, 61, 66, 68, 69, 71, 74, 76, 79, 81, 85, 87, 88, 89, 90, 91, 95, 96, 97, 98, 99, 102, 103, 105, 108, 110, 111, 112, 113, 114, 115, 118, 120], "magnitud": [47, 57, 58, 59, 77, 79, 86, 102, 105, 112], "longer": [47, 56, 57, 64, 68, 69, 74, 78, 80, 103, 105, 108, 111, 113, 119], "upsampl": 48, "downsampl": 48, "y55cnzbtqw8": [], "bv1uv411t7rk": [], "tos_yearli": 48, "AS": 48, "dataarrayresampl": [], "__resample_dim__": [], "201": [], "annual_mean": 48, "annual_mean_glob": 48, "0x167979d20": [], "tos_m_avg": 48, "nanarrai": [], "tos_m_avg_glob": 48, "0x167ac4790": [], "coarse_data": 48, "179": 56, "45d2": [], "1lon": [], "1coordin": [], "0axi": [], "float64180": [], "5long_nam": [], "float64179": [], "float3214": [], "3cell_measur": [], "tosarrai": [], "20783": [], "059945": [], "987619": [], "263633": [], "205384": [], "146358": [], "397846": [], "167561": [], "980403": [], "219498": [], "251431": [], "57055": [], "421645": [], "329005": [], "621992": [], "444487": [], "262134": [], "549099": [], "4083185": [], "3046465": [], "0x167b45b70": [], "tri": 48, "original_glob": 48, "0x167b0edd0": [], "handi": 48, "fulfil": 49, "cx1dggobd74": [], "bv1pv411t7h5": [], "isel": [49, 50, 56, 57, 68, 115], "1lat": [], "object2014": [], "00axi": [], "default": [49, 74, 75, 76, 78, 79, 80, 102, 105, 119, 120], "wherev": 49, "0\u00bac": [49, 50], "masked_sampl": 49, "6132288": [], "6125063": [], "611589": [], "6145128": [], "6141783": [], "6138089": [], "597154": [], "5969657": [], "5967476": [], "5973103": [], "5972834": [], "5972393": [], "5958687": [], "5960269": [], "5961952": [], "5955368": [], "5956477": [], "5957516": [], "595": [], "596": [], "596arrai": [], "septemb": [49, 58, 69], "15th": 49, "colorbar": [49, 56, 57, 58, 59, 67, 68, 69, 115, 118], "0x13f7cac80": [], "white": [49, 64], "sample_2": 49, "masked_sample_2": 49, "0x13f976fb0": [], "arctic": 49, "spring": 49, "sunlight": [49, 115], "assumpt": [49, 86, 102, 103, 109, 113, 118], "i9x4xymeo4a": [], "bv1qf411x7rg": [], "enclos": 50, "wise": 50, "0x15d5b81c0": [], "0x15d827730": [], "everywher": [50, 88], "190": [50, 56, 65, 69, 70], "240": [50, 56, 69, 70, 88], "0x15d826140": [], "nino": [50, 56, 69, 70, 75], "nino_mean": 50, "209291": [], "301911": [], "214222": [], "105894": [], "005788": [], "019834": [], "077742": [], "13642": [], "069463": [], "929279": [], "897242": [], "054486": [], "260762": [], "336": [], "282292": [], "175469": [], "108064": [], "149008": [], "241707": [], "3227625": [], "2158785": [], "095403": [], "062266": [], "211877": [], "413039": [], "491661": [], "417534": [], "269154": [], "168515": [], "139109": [], "168024": [], "194587": [], "093594": [], "930419": [], "867279": [], "030324": [], "189877": [], "290011": [], "236619": [], "161484": [], "097381": [], "108655": [], "139499": [], "186226": [], "093977": [], "981357": [], "973224": [], "097": [], "292091": [], "400722": [], "345691": [], "20365": [], "125706": [], "152941": [], "218176": [], "247176": [], "150201": [], "008736": [], "97948": [], "132178": [], "400193": [], "510438": [], "42778": [], "255584": [], "13967": [], "141772": [], "2131405": [], "253482": [], "118695": [], "933494": [], "887242": [], "048874": [], "301898": [], "37586": [], "34444": [], "200206": [], "116828": [], "128504": [], "223874": [], "305338": [], "171358": [], "001766": [], "975079": [], "082166": [], "326112": [], "40438": [], "354157": [], "193055": [], "123794": [], "187033": [], "265439": [], "362049": [], "230915": [], "046692": [], "953421": [], "11934": [], "350437": [], "464493": [], "389748": [], "25258": [], "209855": [], "255964": [], "338332": [], "425071": [], "347628": [], "160796": [], "094667": [], "24654": [], "46593": [], "560417": [], "494721": [], "342759": [], "247713": [], "264827": [], "307555": [], "348459": [], "233938": [], "022779": [], "930207": [], "017997": [], "233578": [], "387215": [], "350467": [], "208364": [], "143466": [], "179803": [], "2689905": [], "337748": [], "208286": [], "025201": [], "990665": [], "069036": [], "294299": [], "398544": [], "358639": [], "289998": [], "232027": [], "2498": [], "357119": [], "418483": [], "33024": [], "175936": [], "1619215": [], "337633": [], "576431": [], "68036": [], "590141": [], "43527": [], "360472": [], "381661": [], "455142": [], "4893055": [], "396512": [], "267952": [], "261142": [], "390419": [], "586492": [], "733391": [], "663939": [], "504151": [], "400374": [], "40027": [], "460021": [], "517276": [], "364817": [], "202337": [], "170254": [], "311132": [], "531329": [], "6739": [], "587329": [], "403834": [], "3262615": [], "3584585": [], "442886": [], "505671": [], "396822": [], "27391": [], "220645": [], "327209": [], "18014": [], "33arrai": [], "0x15dbffb80": [], "met": [52, 87, 114], "gf905417": 52, "publications_fil": 52, "ferrari_ferreira_11": 52, "epdf": 52, "2016gl072475": 52, "020": 52, "18203": 52, "ndp_108": 52, "ndp108": 52, "interplai": [53, 102], "began": [53, 99, 102], "dive": [54, 64, 118], "leverag": [54, 64, 67, 71, 74], "diagnos": [54, 95, 98, 103], "driven": [54, 56, 60, 61, 80, 102, 103], "thermohalin": 54, "6lqkfuli0m": [], "bv1bh4y1z7dk": [], "2pxs6": [], "transit": [55, 65, 88, 102], "momm": [56, 57, 58], "hell": [56, 57, 58], "aurora": [56, 60, 61], "basinski": [56, 60, 61], "yosemlei": [56, 112], "geoview": [57, 68, 69], "shaperead": 74, "mdate": [], "gv": 56, "gf": [56, 57, 68, 69, 113, 114, 115], "pkvy9kjuasa": [], "bv1p94y1b7d1": [], "5\u00ban": 56, "5\u00ba": 56, "190\u00bae": 56, "240\u00bae": 56, "170\u00baw": 56, "metric": [56, 68, 85, 95, 96, 97, 98, 99, 101, 105, 118, 119, 120], "recur": [56, 75], "stronger": [56, 58, 70, 103, 110, 120], "trade": [56, 101, 103], "blow": [56, 58, 59, 80], "easterli": [56, 58], "rotat": [56, 57, 58, 64, 88, 89, 90, 105, 119, 120, 123], "curv": [56, 79, 85, 87, 88, 109, 115], "corioli": [56, 59, 123], "friction": [56, 59], "angl": [56, 59, 85], "slightli": [56, 57, 78, 101, 112], "ekman": [56, 59], "weaker": [56, 58], "motion": [56, 59, 60, 90, 123], "cool": [56, 64, 69, 77, 80, 85, 87, 88, 90, 91, 115], "drier": 56, "retriv": 56, "sst_path": 56, "sst_data": 56, "gridvars_path": 56, "gridcel": 56, "whose": [56, 65, 101, 102, 103], "areacello_data": 56, "asssign": 56, "warn": [56, 115, 120], "colorbarfrom": 56, "30c": 56, "mpl": [], "geocollect": [], "geoquadmesh": [], "0x16387a410": [], "181": 56, "runtimewarn": [], "invalid": 66, "buffer": [], "sliderbar": 56, "bokeh": [56, 57, 68, 69, 85], "dataset_plot": [56, 57, 68, 69], "timepoint": 56, "consum": [56, 57, 68, 101, 103], "opt": [56, 57, 68, 69, 85], "clabel": [56, 57, 68, 69], "degrees_eastxarrai": [], "3600": [], "covert": 56, "lon2": 56, "henc": [56, 61], "tos_nino34_op1": 56, "193": [], "236": [], "237": [], "239": [82, 85, 86], "10lon": [], "50coordin": [], "float64190": [], "194": [], "195": [], "196": [], "197": [], "198": [], "199": [], "202": 112, "203": 63, "204": [], "205": 107, "206": [], "207": [], "209": [], "211": [], "212": [], "213": [], "214": [], "218": [], "220": 88, "222": [], "223": [], "226": [], "227": [], "229": [], "230": [], "231": [], "232": 88, "233": 88, "235": [], "90000": [], "tos_nino34_op2": 56, "command": [56, 58, 67, 105, 109, 113], "233e": [], "0long_nam": [], "float3228": [], "63cell_measur": [], "256025": [], "15772": [], "057854": [], "77648": [], "707312": [], "583513": [], "947252": [], "849726": [], "748089": [], "461096": [], "447067": [], "423643": [], "604124": [], "518108": [], "423113": [], "094604": [], "086039": [], "157152": [], "053625": [], "940416": [], "840393": [], "746756": [], "579597": [], "118896": [], "316456": [], "217098": [], "137907": [], "38955": [], "240423": [], "860712": [], "787766": [], "727234": [], "68722": [], "01865": [], "059557": [], "066883": [], "22752": [], "158993": [], "10271": [], "485212": [], "45709": [], "41093": [], "723951": [], "64461": [], "570702": [], "337622": [], "346348": [], "344204": [], "212313": [], "136517": [], "067299": [], "119303": [], "17158": [], "17856": [], "014107": [], "9657": [], "918253": [], "160896": [], "242203": [], "042742": [], "253191": [], "214586": [], "205938": [], "537773": [], "626368": [], "471653": [], "873777": [], "819756": [], "793085": [], "265177": [], "25255": [], "158524": [], "728104": [], "645485": [], "56212": [], "747778": [], "701273": [], "655407": [], "253344": [], "176163": [], "104733": [], "627005": [], "582062": [], "522951": [], "82321": [], "737165": [], "669386": [], "450716": [], "425608": [], "367132": [], "780058": [], "769499": [], "78821": [], "061314": [], "029993": [], "031322": [], "100246": [], "051643": [], "008482": [], "678553": [], "685179": [], "702488": [], "583574": [], "560463": [], "518036": [], "542961": [], "569714": [], "62616": [], "10cell_method": [], "areacelloarrai": [], "23271986e": [], "23422552e": [], "forward": [56, 68, 90, 102, 103, 118, 123], "tos_nino34": 56, "set_ext": [56, 71, 75, 76], "set_oper": [], "133": [], "intersect": [82, 88], "substract": 56, "tos_nino34_mon": 56, "tos_nino34_clim": 56, "tos_nino34_anom": 56, "tos_nino34_anom_mean": 56, "09020297": [], "94682973": [], "87016881": [], "67314576": [], "58964472": [], "42163337": [], "1045906": [], "03671601": [], "10723412": [], "17852147": [], "03699046": [], "037018": [], "18047598": [], "13209794": [], "18591605": [], "23601163": [], "40335283": [], "41607813": [], "56452047": [], "71568734": [], "94604367": [], "54824442": [], "64511469": [], "71039068": [], "68536358": [], "59079579": [], "06137074": [], "42683044": [], "28220138": [], "01182272": [], "50274312": [], "31489676": [], "3469001": [], "74364307": [], "1627902": [], "25649891": [], "34426791": [], "36370234": [], "04569948": [], "06573344": [], "83853623": [], "44441816": [], "9501292": [], "29584973": [], "02383247": [], "30428051": [], "42201282": [], "49855477": [], "48539399": [], "51069788": [], "39988395": [], "32679855": [], "06415625": [], "16908221": [], "07204665": [], "55496837": [], "65673466": [], "57821731": [], "65645898": [], "64569495": [], "83701739": [], "75305036": [], "68472177": [], "46625659": [], "27632608": [], "16300001": [], "6672963": [], "97958267": [], "00201317": [], "34717404": [], "34564208": [], "56877085": [], "43570676": [], "91709921": [], "60461385": [], "44474806": [], "39675869": [], "34406608": [], "19599503": [], "22287623": [], "27117913": [], "64625193": [], "58092378": [], "67215087": [], "69564098": [], "71416747": [], "51178696": [], "60251519": [], "50095793": [], "2258347": [], "02674856": [], "04463503": [], "11126012": [], "14102328": [], "3094833": [], "28171968": [], "29325428": [], "38412098": [], "42648494": [], "75224687": [], "00070393": [], "25250361": [], "5257914": [], "62650835": [], "6208905": [], "74093494": [], "82211019": [], "049507": [], "12185874": [], "92467515": [], "41653586": [], "11950453": [], "51565086": [], "44916468": [], "64657781": [], "17301426": [], "60500161": [], "81257123": [], "8883486": [], "78451": [], "76460858": [], "71103114": [], "78661373": [], "20402363": [], "07531219": [], "83626328": [], "55763762": [], "53099864": [], "38395764": [], "43226824": [], "52907282": [], "55885613": [], "05034929": [], "66684363": [], "06911014": [], "35993651": [], "32698891": [], "49531353": [], "58532671": [], "64840056": [], "83827156": [], "04578151": [], "13088586": [], "39856479": [], "74717953": [], "7443611": [], "53452867": [], "35453215": [], "67649088": [], "10747709": [], "56691606": [], "78958853": [], "3695489": [], "26843057": [], "38747462": [], "45266686": [], "80075567": [], "32577243": [], "74048293": [], "65214002": [], "56080466": [], "18142003": [], "47276929": [], "02291112": [], "19411324": [], "45835808": [], "6191515": [], "69644142": [], "77052278": [], "04589795": [], "7001528": [], "70409135": [], "70546689": [], "41115269": [], "13565225": [], "16707414": [], "35186853": [], "63483198": [], "71539748": [], "46310973": [], "9468": [], "8702": [], "6731": [], "5896": [], "3519": [], "6348": [], "7154": [], "4631arrai": [], "interannu": 56, "oni_index": 56, "monhtli": 56, "cold": [56, 58, 88, 90], "fill_between": [56, 69, 88, 97, 99, 113], "alpha": [56, 58, 59, 69, 70, 71, 74, 78, 82, 87, 88, 97, 99, 101, 103, 105, 109, 110, 112, 113, 115, 118, 120], "transpar": [56, 102, 120], "axhlin": [56, 58, 68, 69, 70], "lw": [56, 60, 61, 69, 88, 91, 108, 110, 112, 113, 115], "linewidth": [56, 58, 69, 75, 78, 82, 88, 89, 90, 102, 103, 120], "linestyl": [56, 58, 68, 69, 70, 74, 82, 88, 89, 90, 112, 114, 115, 119, 120], "po": 57, "daac": 57, "api": [57, 105], "cliamtic": 57, "open_catalog": [], "fsspec": [], "holoview": [57, 68, 69, 85], "gvdataset": [57, 68, 69], "gvimag": [57, 68, 69], "cfeatur": [58, 74, 75, 76], "suppress": [], "filterwarn": [115, 120], "ignor": [75, 97, 102, 103, 105, 115, 120], "w1d2_stateoftheclimateoceanandatmospherereanalysi": 58, "xn_sgxtm6la": [], "bv1g94y1b7yw": [], "buoi": [57, 69, 71], "jra": 57, "55c": 57, "era5_bucket": 57, "midnight": [57, 66], "prefix": 57, "metadata_fil": 57, "metadata_kei": 57, "ds_meta": 57, "254": 85, "cast": [], "flat_num_dates_ns_int": [], "flat_num_d": [], "_ns_per_time_delta": [], "721": [], "744": [], "time0": 57, "1440": [], "lon_ocean": [], "lat_ocean": [], "361": [], "nv": [], "sea_surface_temperatur": 57, "sea_surface_wave_mean_period": [], "air_temperature_at_2_metres_1hour_maximum": [], "dew_point_temperature_at_2_metr": [], "significant_height_of_wind_and_swell_wav": [], "sea_surface_wave_from_direct": [], "lwe_thickness_of_surface_snow_amount": [], "snow_dens": [], "eastward_wind_at_10_metr": 57, "integral_wrt_time_of_surface_direct_downwelling_shortwave_flux_in_air_1hour_accumul": [], "air_temperature_at_2_metr": 57, "northward_wind_at_10_metr": 57, "tilt": [], "forecastsxarrai": [], "721time1": [], "744time0": [], "744lon": [], "1440lon_ocean": [], "720lat_ocean": [], "361nv": [], "2coordin": [], "float3290": [], "0standard_nam": [], "latitudelong_nam": [], "31t23": [], "00standard_nam": [], "timebound": [], "time1_boundsarrai": [], "01t01": [], "01t02": [], "31t21": [], "31t22": [], "float320": [], "8standard_nam": [], "longitudelong_nam": [], "0000e": [], "5000e": [], "5925e": [], "5950e": [], "5975e": [], "5standard_nam": [], "sea_surface_temperatureunit": [], "klong_nam": [], "temperaturenameecmwf": [], "temperatureshortnameecmwf": [], "sstnamecdm": [], "sea_surface_temperature_surface_superchunks": [], "product_typ": [], "772450560": [], "sea_surface_wave_mean_periodunit": [], "slong_nam": [], "periodnameecmwf": [], "periodshortnameecmwf": [], "mwpnamecdm": [], "mean_wave_periodproduct_typ": [], "analysis_superchunks": [], "193380480": [], "air_temperatureunit": [], "metr": [], "processingnameecmwf": [], "processingshortnameecmwf": [], "mx2tnamecdm": [], "air_temperature_superchunks": [], "dew_point_temperatureunit": [], "dewpoint": [], "2dnamecdm": [], "2_metre_dewpoint_temperature_surface_superchunks": [], "significant_height_of_wind_and_swell_wavesunit": [], "mlong_nam": [], "swellnameecmwf": [], "swellshortnameecmwf": [], "swhnamecdm": [], "significant_height_of_combined_wind_waves_and_swellproduct_typ": [], "sea_surface_wave_from_directionunit": [], "truelong_nam": [], "directionnameecmwf": [], "directionshortnameecmwf": [], "mwdnamecdm": [], "mean_wave_directionproduct_typ": [], "northward_wind_at_100_metr": [], "northward_windunit": [], "1long_nam": [], "componentnameecmwf": [], "componentshortnameecmwf": [], "100vnamecdm": [], "100_metre_v_wind_component_surface_superchunks": [], "surface_air_pressur": 57, "surface_air_pressureunit": [], "palong_nam": [], "pressurenameecmwf": [], "pressureshortnameecmwf": [], "spnamecdm": [], "surface_pressure_surface_superchunks": [], "air_temperature_at_2_metres_1hour_minimum": [], "mn2tnamecdm": [], "minimum_temperature_at_2_metres_since_previous_post": [], "processing_surface_1_hour_2_superchunks": [], "air_pressure_at_mean_sea_level": [], "air_pressure_at_mean_sea_levelunit": [], "mslnamecdm": [], "mean_sea_level_pressure_surface_superchunks": [], "time1_bound": [], "_superchunks": [], "1488": [], "precipitation_amount_1hour_accumul": [], "precipitation_amountunit": [], "precipitationnameecmwf": [], "precipitationshortnameecmwf": [], "tpnamecdm": [], "total_precipitation_1hour_accumulation_superchunks": [], "eastward_wind_at_100_metr": [], "eastward_windunit": [], "100unamecdm": [], "100_metre_u_wind_component_surface_superchunks": [], "lwe_thickness_of_surface_snow_amountunit": [], "equivalentlong_nam": [], "depthnameecmwf": [], "depthshortnameecmwf": [], "sdnamecdm": [], "snow_depth_surface_superchunks": [], "snow_densityunit": [], "kg": [60, 61, 87, 89], "3long_nam": [], "densitynameecmwf": [], "densityshortnameecmwf": [], "rsnnamecdm": [], "snow_density_surface_superchunks": [], "10unamecdm": [], "10_metre_u_wind_component_surface_superchunks": [], "integral_wrt_time_of_surface_direct_downwelling_shortwave_flux_in_airunit": [], "2long_nam": [], "downwardsnameecmwf": [], "downwardsshortnameecmwf": [], "ssrdnamecdm": [], "surface_solar_radiation_downwards_surface_1_hour_accumulation_superchunks": [], "2tnamecdm": [], "2_metre_temperature_surface_superchunks": [], "10vnamecdm": [], "10_metre_v_wind_component_surface_superchunks": [], "time0pandasindexpandasindex": [], "lon_oceanpandasindexpandasindex": [], "lat_oceanpandasindexpandasindex": [], "reanalysisinstitut": [], "ecmwftilt": [], "northeastern": 57, "northto": 57, "lat_rang": 57, "lon_rang": 57, "270": 57, "295": 57, "selected_var": 57, "s3_data_ptrn": 57, "year_s3": 57, "month_s3": 57, "era5_select": 57, "500mb": 57, "s3_data_kei": 57, "ds_temp": 57, "empti": [57, 74, 88, 91, 94, 120], "loop": [57, 67, 70, 74, 76, 87, 88, 91, 96, 101, 102, 103, 108, 120], "era5_allvar": 57, "294": [], "101lat": [], "100time0": [], "744coordin": [], "float32270": [], "293": 86, "float3255": [], "25standard_nam": [], "2_metre_temperature_surfaceproduct_typ": [], "7514400": [], "10_metre_v_wind_component_surfaceproduct_typ": [], "10_metre_u_wind_component_surfaceproduct_typ": [], "surface_pressure_surfaceproduct_typ": [], "sea_surface_temperature_surfaceproduct_typ": [], "sqrt": [57, 58, 59, 85, 86, 101, 119], "wind_spe": 57, "windspe": 57, "312": [], "625": [], "188": [], "051": [], "938": [], "081": [], "float322": [], "562": [95, 98], "625standard_nam": [], "analysisarrai": [], "3125": [], "375": [], "8125": [], "5625": [], "1875": [], "0625": [], "9375": [], "4375": [], "125standard_nam": [], "float324": [], "918": [], "081long_nam": [], "speedunit": [], "sarrai": [], "0509453": [], "937996": [], "9176085": [], "440703": [], "2534695": [], "100305": [], "9750197": [], "8875804": [], "4764516": [], "5124688": [], "565547": [], "9632096": [], "826307": [], "5379925": [], "6940327": [], "7563846": [], "6255388": [], "8795335": [], "8460054": [], "715248": [], "597502": [], "8130124": [], "820688": [], "7987065": [], "7289014": [], "6596155": [], "5639043": [], "1908875": [], "9585156": [], "666858": [], "5286894": [], "46044": [], "3251624": [], "2504597": [], "214002": [], "1883926": [], "402148": [], "2756577": [], "1500187": [], "2715976": [], "5693505": [], "3454356": [], "2655964": [], "138708": [], "3823898": [], "7507102": [], "83739": [], "0963137": [], "08604": [], "6904054": [], "6882267": [], "8013668": [], "4502869": [], "444701": [], "0065033": [], "1405861": [], "4032383": [], "5586603": [], "1942332": [], "5515182": [], "7217686": [], "8981166": [], "0238547": [], "0783343": [], "1551924": [], "6055136": [], "6918793": [], "9338393": [], "396376": [], "2596397": [], "0561366": [], "3341026": [], "420411": [], "577885": [], "5021696": [], "366062": [], "75126": [], "8042455": [], "2194102": [], "281036": [], "342708": [], "9381647": [], "9295104": [], "3758223": [], "2337334": [], "2703688": [], "4482787": [], "2143476": [], "7164142": [], "8675175": [], "993158": [], "081207": [], "temperatr": 57, "ds_surface_temp_2m": 57, "previous": [57, 67, 68, 69, 77, 79, 86, 87, 88, 95, 103, 111, 114, 115, 118, 120], "aesthet": [57, 58, 109, 110, 111, 113], "lake": [57, 58, 74, 76, 78, 81], "middl": [57, 58, 64, 76, 79, 95, 97, 102, 113, 115], "curiou": [57, 123], "ds_surface_temp_2m_hour": 57, "ds_surface_temp_2m_dai": 57, "deg2rad": [57, 68, 82, 89, 90, 99], "ds_surface_temp_2m_t": 57, "50006": [], "35764": [], "87677": [], "5952": [], "4943": [], "9675": [], "86908": [], "75427": [], "41376": [], "45053": [], "05713": [], "0686": [], "22162": [], "12436": [], "70013": [], "05222": [], "06696": [], "28363": [], "44287": [], "59558": [], "39676": [], "39044": [], "12787": [], "8426": [], "65915": [], "00055": [], "58325": [], "45718": [], "92526": [], "7492": [], "52008": [], "10675": [], "77393": [], "05627": [], "90598": [], "7608": [], "73077": [], "68564": [], "36688": [], "8352": [], "11157": [], "43033": [], "6232": [], "90982": [], "89868": [], "06982": [], "66443": [], "08206": [], "64908": [], "0606": [], "52676": [], "29584": [], "76395": [], "6208": [], "43384": [], "98157": [], "8111": [], "49487": [], "4361": [], "416": [], "59146": [], "8614": [], "99466": [], "6748": [], "1274": [], "57687": [], "91495": [], "29205": [], "4062": [], "50934": [], "0772": [], "4959": [], "12637": [], "23624": [], "6013": [], "36816": [], "7143": [], "5017": [], "23486": [], "78656": [], "63855": [], "0742": [], "99597": [], "99887": [], "23325": [], "51315": [], "6349": [], "2901": [], "53876": [], "97327": [], "28406": [], "63364": [], "70068": [], "75153": [], "24133": [], "67795": [], "26294": [], "45438": [], "93088": [], "68942": [], "1127": [], "90347": [], "73663": [], "22888": [], "00787": [], "7534": [], "70288": [], "62845": [], "95892": [], "08832": [], "98087": [], "5735": [], "76312": [], "19974": [], "50092": [], "9146": [], "99585": [], "22217": [], "85812": [], "63348": [], "54462": [], "16473": [], "04742": [], "23807": [], "24103": [], "46927": [], "9454": [], "27707": [], "89728": [], "28577": [], "06635": [], "49167": [], "672": [], "81036": [], "1632": [], "96744": [], "8162": [], "57697": [], "06226": [], "81845": [], "71075": [], "29214": [], "19946": [], "1113": [], "8169": [], "73218": [], "41278": [], "40903": [], "5325": [], "9501": [], "99554": [], "89883": [], "40936": [], "6588": [], "94028": [], "19858": [], "30576": [], "6813": [], "4537": [], "11212": [], "9709": [], "37708": [], "10385": [], "971": [], "57086": [], "45255": [], "31818": [], "90744": [], "77197": [], "5315": [], "35675": [], "58307": [], "9867": [], "25528": [], "94757": [], "28214": [], "0863": [], "35034": [], "5043": [], "464": [], "43115": [], "25912": [], "97134": [], "6389": [], "38873": [], "64902": [], "30243": [], "67123": [], "5237": [], "37814": [], "93982": [], "70587": [], "2028": [], "13675": [], "03543": [], "17917": [], "06662": [], "53296": [], "84476": [], "54846": [], "74603": [], "85608": [], "98886": [], "94135": [], "0804": [], "74182": [], "20242": [], "83017": [], "71338": [], "9342": [], "74506": [], "3823": [], "1159": [], "30905": [], "08002": [], "85522": [], "74496": [], "8333": [], "5385": [], "67282": [], "84833": [], "3686": [], "49005": [], "7978": [], "03284": [], "3925": [], "65652": [], "33487": [], "744279": [], "3arrai": [], "00arrai": [], "ntemperatur": 57, "set_tick_param": 57, "era5_allvars_t": 57, "plot_var": 57, "ax_list": 57, "fontsiz": [57, 74, 75, 76, 82, 85, 88, 89, 90, 105, 118, 119, 120], "synopt": [57, 94], "cursor": 57, "meridian": [57, 115], "greenwich": 57, "london": [57, 107], "xero": 57, "datelin": 57, "referenc": 57, "idenitfi": 57, "uneven": [58, 78], "set_projection_figur": 58, "projlccni": 58, "lambertconform": 58, "clon": 58, "central_latitud": 58, "clat": 58, "format_ax": 58, "add_featur": [58, 60, 61, 74, 75, 76], "river": [58, 59], "edgecolor": [58, 60, 61, 74, 75, 76], "facecolor": [58, 74, 75, 76, 88, 120], "gl": 58, "draw_label": 58, "xlocat": 58, "ticker": 58, "maxnloc": 58, "ylocat": 58, "xlabels_top": 58, "ylabels_left": 58, "xline": 58, "geographic_lon_to_360": 58, "inverted_geographic_lon_to_360": 58, "cbar_label": 58, "dd": [58, 87], "zgwshu0xxya": [], "bv1nn411u7eb": [], "significantli": [58, 64, 71, 94, 96, 102, 105, 119], "depict": 58, "schemat": [58, 86, 94], "denot": [58, 86, 90, 95, 101, 111], "u10": 58, "v10": 58, "resampl": [58, 78, 96, 109, 111, 113, 115], "1m": 58, "si10": 58, "1980": [58, 96, 97, 98, 99], "prepocess": 58, "filename_era5_mm": 58, "era5_surface_winds_mm": 58, "url_era5_mm": 58, "3q4v": 58, "era5_mm": 58, "timeslic": 58, "gmt": [], "grib_to_netcdf": [], "ecmw": [], "1440latitud": [], "721time": [], "312coordin": [], "8unit": [], "longitudearrai": [], "0unit": [], "latitudearrai": [], "01long_nam": [], "323930880": [], "longitudepandasindexpandasindex": [], "latitudepandasindexpandasindex": [], "mar": [], "bin": [67, 68, 69, 70, 71, 105, 108, 110, 112, 113, 115, 119, 120], "param": [102, 103, 111], "data2": [], "adaptor": [], "1680823531": [], "8173223": [], "20789": [], "8c45a562": [], "7507": [], "4913": [], "ad58": [], "8ecc93ff0549": [], "tmp": [], "1680823400": [], "1174533": [], "era5_ann": 58, "adjust": [58, 65, 85, 87, 90, 102, 105, 110, 115, 120], "colorlevel": 58, "colorlevels_clim": 58, "loc": [58, 74, 76, 82, 102, 105, 110, 111, 112, 113, 114, 115, 119, 120], "dataplot": 58, "cm": [58, 59, 60, 61, 88, 96, 110, 115, 118, 119], "orient": [58, 60, 61, 75, 82, 102, 115], "shrink": [58, 60, 61, 67, 68, 69, 70, 71, 115, 120], "pad": [58, 60, 61, 115], "0x15e3e4b80": [], "distinct": [58, 65, 68, 69, 91, 94, 96, 97, 98, 102, 105, 115], "westerli": 58, "predominantli": 58, "strong": [58, 64, 65, 70, 91, 115, 120, 123], "southward": [58, 59], "subtrop": [58, 60], "northward": [58, 59], "hadlei": [58, 87], "ferrel": 58, "0x15ea2be80": [], "hoffm\u00f6ller": 58, "horizont": [58, 60, 61, 68, 70, 82, 95, 98, 115, 119], "regroup": 58, "perfom": 58, "0x15ec6da20": [], "winter": [58, 64, 80], "intensif": [58, 64, 70], "jja": [58, 80], "insul": 58, "era5_season": 58, "pdata": 58, "atlant": [58, 60], "extratrop": 58, "cyclon": [58, 64], "counterclockwis": 58, "clockwis": 58, "heavi": [58, 75, 80, 108], "sleet": 58, "outag": 58, "disrupt": [58, 70], "jet": [58, 105], "stream": 58, "pressbook": 58, "occurr": [58, 64, 65, 105, 118], "sink": 59, "melt": [59, 88, 91], "freez": 59, "drag": 59, "ecco": [59, 60, 61], "rmuyeskhi": [], "bv1tw4y1o7dh": [], "veloc": [59, 65], "fname_atm_wind_u": 59, "wind_evel_monthly_2016": 59, "url_atm_wind_u": 59, "ke9yp": 59, "atm_wind_u": 59, "open_dataarrai": [59, 115], "fname_atm_wind_v": 59, "wind_nvel_monthly_2016": 59, "url_atm_wind_v": 59, "9zkgd": 59, "atm_wind_v": 59, "fname_ocn_surface_current_u": 59, "evel_monthly_2016": 59, "url_ocn_surface_current_u": 59, "ndx5a": 59, "ocn_surface_current_u": 59, "fname_ocn_surface_current_v": 59, "nvel_monthly_2016": 59, "url_ocn_surface_current_v": 59, "qa9ex": 59, "ocn_surface_current_v": 59, "descib": 59, "infer": [59, 76, 81], "atm_wind_u_an_mean": 59, "atm_wind_stress_v": 59, "atm_wind_v_an_mean": 59, "almost": [59, 94, 102, 123], "seper": [59, 75], "eastward": 59, "westward": 59, "exhibit": [59, 64, 67, 68, 69, 71, 108, 110, 113], "\u03b8": 59, "theta": [59, 60, 61], "tan": 59, "quiver": 59, "abernathei": 59, "overlai": [59, 85, 99, 102, 110, 114, 115], "fname_surface_temp": 59, "surface_theta": [59, 60], "url_fname_surface_temp": 59, "98ksr": [59, 60], "ocn_surface_temp": 59, "mag": 59, "coarsen": [59, 66, 97, 98, 99], "arrow": [59, 88, 91, 95, 103], "sampling_x": 59, "sampling_i": 59, "slx": 59, "sly": 59, "sl2d": 59, "opac": 59, "quiverkei": 59, "ocn_surface_current_u_an_mean": 59, "ocn_surface_current_v_an_mean": 59, "dissapear": 59, "spiral": 59, "pump": 59, "particularili": 59, "reli": [59, 65, 102, 103, 109, 114, 123], "fuel": [59, 102], "growth": [59, 74, 101, 103], "tini": 59, "chain": [59, 95], "oxygen": [59, 76, 80, 89], "breath": 59, "deflect": 59, "biogeochem": [59, 95], "thermo": 60, "halin": 60, "fluid": [60, 96], "cmocean": [60, 61, 115], "cart": [60, 61], "longitudeformatt": [60, 61], "latitudeformatt": [60, 61], "gsw": 60, "cgh6bc2uj58": [], "bv1uh4y1j7wn": [], "discov": [60, 70, 75, 79, 80, 85, 86], "filename_theta": 60, "url_theta": 60, "subset_theta": [60, 61], "filename_salt": 60, "surface_salt": 60, "url_salt": 60, "aufs2": 60, "subset_salt": 60, "anywher": 60, "salt": 60, "dpi": [60, 61, 102], "rabernat": [60, 61], "research_computing_2018": [60, 61], "cbar_kwarg": [60, 61, 67, 68, 69, 70, 71, 82, 91], "set_xtick": [60, 61, 105, 118, 120], "set_ytick": [60, 61, 118, 120], "lon_formatt": [60, 61], "zero_direction_label": [60, 61], "lat_formatt": [60, 61], "zorder": [60, 61, 76, 105], "tight_layout": [60, 61, 103, 120], "psu": 60, "rho": [60, 61, 101], "valli": 60, "rho_0": [60, 61], "beta_t": 60, "t_0": 60, "beta_": 60, "s_0": 60, "beta_p": 60, "p_0": 60, "simeq": 60, "1027": 60, "ppt": 60, "contract": 60, "compress": [60, 78, 105, 108], "_0": 60, "rare": [60, 102, 105, 115], "assum": [60, 65, 66, 85, 86, 87, 102, 103, 109, 112, 115, 118], "realiti": [60, 88, 90], "beta": [60, 118], "rho_linear": 60, "6e": 60, "impract": 60, "fortun": [60, 91, 109], "thermodynam": [60, 123], "teo": 60, "ct": 60, "ct_from_pt": 60, "rho_nonlinear": 60, "minu": [60, 61, 67], "stem": 60, "irrespect": 60, "presenc": [60, 64, 78, 79, 86], "denser": 60, "emphas": [60, 61, 64, 118], "therebi": [60, 64, 101], "greenland": 60, "deepwat": 60, "capac": [61, 69, 80, 87, 88, 115, 120], "upper": [61, 68, 79, 86, 90, 97, 98, 110, 113, 123], "contact": 61, "dpsyoc1blug": [], "bv1gp411y7oj": [], "filename_theta_annu": 61, "theta_annual_mean": 61, "url_theta_annu": 61, "c8wqt": 61, "theta_annu": 61, "1994": [61, 65], "da": [61, 95, 96, 97, 98, 99], "dx": 61, "warmest": 61, "evenli": [61, 78], "joul": 61, "z_1": 61, "iiint_": 61, "c_p": 61, "cdot": [61, 87, 88, 101], "dz": 61, "theta_area_int": 61, "1026": 61, "3990": 61, "set_styl": [61, 102, 103, 105], "whitegrid": 61, "zu": 61, "cumsum": [61, 103, 105], "zj": 61, "steep": [61, 87, 102], "deepest": 61, "glanc": 61, "trench": 61, "greatest": 61, "area_of_ocean": 61, "677": 61, "1997": [61, 69, 70], "global_heat": 61, "years_to_plot": 61, "global_heat_upper2000": 61, "global_heat_upper700": 61, "subset_theta_year": 61, "math": [61, 102], "heat_anom_fulldepth": 61, "heat_anom_upper2000": 61, "heat_anom_upper700": 61, "heat_anom_upper2000_700": 61, "heat_anom_upperfulldepth_2000": 61, "fulldepth": 61, "shallow": [61, 90], "substanti": [61, 71, 102], "graph": [61, 77, 78, 79, 89], "int_": 61, "700m": 61, "7e11": 61, "15e11": 61, "conent": 61, "subset_theta_futur": 61, "length_of_time_period": 61, "365": [61, 80, 87, 88], "full_depth_heat_content_chang": 61, "upper_700m_heat_content_chang": 61, "becasu": 61, "disproportion": 61, "uniformli": 61, "council": [63, 65, 113], "interim": [63, 87], "nap": 63, "nationalacademi": 63, "10944": 63, "hollmann": 63, "saunder": 63, "downi": 63, "buchwitz": 63, "wagner": 63, "1541": 63, "1552": 63, "bam": 63, "00254": 63, "plummer": 63, "lecomt": 63, "doherti": 63, "cci": [63, 65], "014": 63, "plummer_esa_cci_rse_article_2017": 63, "anderson": [63, 103], "sonntag": 63, "kavvada": 63, "friedl": 63, "2030": [63, 113], "agenda": 63, "96": [63, 71], "1080": 63, "10095020": 63, "1333230": 63, "wgclimat": 63, "biton": [64, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 102, 103, 105, 118, 119, 120, 121], "won": [64, 65, 75, 89, 90, 102, 119, 120, 121, 123], "compel": 64, "grasp": [64, 65, 123], "photographi": 64, "aircraft": 64, "sky": [64, 86], "disast": [64, 118], "pollut": [64, 102, 113], "maxar": 64, "viir": [64, 66], "onboard": 64, "suomi": 64, "novemb": [64, 107], "observatori": 64, "travel": [64, 85], "void": 64, "crest": 64, "radio": 64, "microwav": 64, "possess": [64, 110], "ultraviolet": 64, "rai": 64, "gamma": [64, 101, 103], "longwav": [64, 85, 86, 87, 88, 89, 91], "nonetheless": [64, 65], "transmit": 64, "strateg": 64, "bright": [64, 65], "remaind": 64, "absorpt": [64, 89], "darker": [64, 75, 120], "though": [64, 90, 91, 103, 113], "phytoplankton": 64, "everydai": 64, "conscious": 64, "ever": [64, 73], "flower": [64, 123], "tour": 64, "occupi": 64, "160": [64, 88], "cloudsat": 64, "calipso": 64, "beneath": 64, "rapidli": [64, 96, 102, 103], "train": [64, 118, 119], "gp": 64, "geostationari": [64, 65], "solstic": 64, "fine": [64, 74], "discern": 64, "coarser": [64, 67, 94], "inappropri": 64, "road": [64, 102], "suitabl": [64, 65, 110], "characterist": [64, 67, 74, 102], "fly": [64, 105], "oli": 64, "jointli": 64, "swath": 64, "latest": [64, 65], "predecessor": 64, "finer": 64, "multispectr": 64, "hyperspectr": [64, 120], "scrutin": [64, 70], "spectromet": 64, "differenti": [64, 102, 123], "miner": [64, 74], "expon": [64, 103], "256": 64, "255": [64, 78, 105], "discrimin": [64, 101, 105], "slightest": 64, "exposur": 64, "overcom": [64, 67, 120], "constel": 64, "minim": [64, 65, 78, 120], "sentinel": [64, 120], "pair": [64, 105, 120], "imagin": [64, 91, 103], "landslid": 64, "citi": [64, 68, 71, 112, 113, 119], "weekli": [64, 65, 68], "earthdata": [64, 65], "pathfind": 64, "illumin": 64, "anim": [64, 90], "fluiditi": 64, "proce": [64, 76, 99, 115], "independ": [64, 118, 119, 120, 123], "fewer": [64, 105, 114], "wildlif": [64, 65], "consumpt": [64, 101, 102], "regul": [64, 85, 102, 115], "lengthen": 64, "proces": 64, "microphys": 64, "partic": 64, "uncertainti": [64, 65, 71, 85, 86, 98, 102, 103, 108, 109, 111, 119], "notabl": [64, 67, 68, 70], "hurrican": 64, "vital": [64, 91], "comprehend": [64, 67, 70, 90], "serv": [64, 74, 75, 79, 103, 105, 108, 115, 118], "pivot": 64, "har": 64, "microorgan": 64, "abund": [64, 67, 74], "basin": 64, "fish": 64, "reliant": 64, "laid": 64, "conven": 65, "carefulli": [65, 118, 122], "inspect": [65, 70, 91, 112, 114, 115, 119, 120], "mainten": 65, "lifespan": 65, "deterior": 65, "exceed": [65, 109, 110, 111, 113, 118], "successfulli": [65, 66, 120], "exceedingli": 65, "thankfulli": [65, 75, 119], "dispos": 65, "feasibl": [65, 103], "1970": [65, 102], "timelin": [65, 74], "emploi": [65, 67, 68, 69, 75, 103, 111, 114, 119], "importantli": 65, "meanwhil": 65, "aboard": 65, "exager": 65, "properli": [65, 67, 68, 70, 71, 89, 90, 91], "perioud": 65, "theoret": 65, "accept": [65, 66], "nois": [65, 68, 79, 118], "1990": [65, 75, 102, 112], "1985": [65, 113], "third": [65, 95, 112], "aeronaut": 65, "upcom": [65, 68, 99, 112, 118], "freeli": [65, 102, 108, 109, 110, 111], "microsoft": 65, "azur": 65, "charg": 65, "fcdr": 65, "accuraci": [65, 114, 118, 119, 120], "themat": 65, "webpag": 65, "fapar": 65, "statu": 65, "ndvi": [65, 119, 120], "1966": 65, "1999": 65, "optic": [65, 123], "thick": [65, 74, 87, 110], "patmo": 65, "1979": [65, 67, 68, 71, 75], "persiann": 65, "optimum": [65, 69], "1978": 65, "crospher": 65, "late": [65, 81, 102, 115], "downstream": 65, "ecv": 65, "gco": 65, "yearli": 65, "legaci": 65, "underwai": 65, "older": [65, 66], "heritag": 65, "toolbox": [65, 82], "cate": 65, "gear": 65, "spatiotempor": 65, "esdr": 65, "unifi": 65, "nice": [65, 105], "sulfur": 65, "dioxid": [65, 77, 85, 87, 89, 95, 118], "ozon": [65, 85, 89], "gpcp": [65, 68, 70], "1983": 65, "assur": [65, 66, 70, 102], "registr": 65, "daiyl": 65, "overlappign": 65, "publicli": 65, "quiet": [66, 67, 68, 69, 70, 71], "w1d3_remotesensinglandoceanandatmospher": [66, 67, 68, 69, 70, 71], "registri": 66, "land_v005_avh13c1_noaa": 66, "07_19810624_c20170610041337": 66, "parent": 66, "data_sel": 66, "string": [66, 85, 102, 105, 119], "switch": [66, 122], "newest": 66, "exercise_date_sel": 66, "exercise_file_loc": 66, "3600x7200": 66, "qa": [66, 73], "discard": 66, "contanmin": 66, "intes": 66, "highest": [66, 67, 108, 109, 113], "binari": [66, 67, 68, 69, 70, 71, 118, 120], "ye": [66, 89, 118], "brdf": 66, "rh03": 66, "night": [66, 109], "sunglint": 66, "cloudi": 66, "unus": 66, "decif": 66, "0000000000010010": 66, "converet": 66, "bit15": 66, "bit14": 66, "bit13": 66, "bit12": 66, "bit11": 66, "bit10": 66, "bit9": 66, "bit8": 66, "bit7": 66, "bit6": 66, "bit5": 66, "bit4": 66, "bit3": 66, "bit2": 66, "bit1": 66, "bit0": 66, "confus": [66, 75, 118], "get_quality_info": 66, "unpack": [66, 87], "byte": 66, "cld_flag": 66, "cld_shadow": 66, "value_valid": 66, "ndvi_mask": 66, "compromis": 66, "yyyymmdd": 66, "20030701": 66, "date_sel_exercis": 66, "file_location_exercis": 66, "ds_exercis": 66, "reus": [66, 87, 98], "ndvi_masked_exercis": 66, "thow": 66, "calcuat": [67, 85], "precpit": 67, "crash": [67, 68, 70, 71, 102], "apt": [67, 68, 69, 70, 71], "libproj": [67, 68, 69, 70, 71], "proj": [67, 68, 69, 70, 71], "libgeo": [67, 68, 69, 70, 71], "cython": [67, 68, 69, 70, 71], "qq": [67, 68, 69, 70, 71, 110, 114, 115], "uninstal": [67, 68, 69, 70, 71], "ourselv": [67, 103], "file_pattern": [67, 68, 71], "gpcp_v02r03_monthly_": [67, 68, 71], "ds_singl": 67, "inlud": 67, "precip_error": 67, "file_ob": [67, 68, 71], "concaten": [67, 68, 71, 96, 98], "nest": [67, 68, 71, 91, 94], "concat_dim": [67, 68, 71], "vagu": 67, "guesswork": 67, "init": [67, 68, 69, 70, 71, 75, 76, 87, 90, 111], "longitut": [67, 71], "minumum": 67, "mm": [67, 68, 70, 71, 108, 109, 110, 111, 112, 113, 114], "wealth": [67, 107], "rainforest": 67, "australia": [67, 96], "reinforc": 67, "0n": 67, "0e": 67, "repeat": [67, 75, 91, 94, 98, 109, 110, 113, 114, 119, 120], "precip_30yr": 67, "criterion": [67, 114], "recombin": [67, 68], "precip_clim": [67, 68], "geoax": [67, 70], "flatten": [67, 70, 114, 115, 120], "jan": [67, 70, 107], "apr": [67, 70], "jul": [67, 70], "oct": [67, 70], "coastin": [67, 70], "reciev": 67, "indian": 67, "raini": 67, "driest": 67, "recalcul": 67, "1991": [67, 69, 112], "precip_30yr_exercis": 67, "precip_clim_exercis": 67, "precip_diff_exercis": 67, "pertain": 67, "smooth": [68, 79, 96], "departur": 68, "cpcp": 68, "invalu": [68, 119], "precip_anom": 68, "to_netcdf": [68, 69], "t5_gpcp": [68, 70], "anomaly_1981": [68, 70], "geospati": 68, "brbg": [68, 70], "depart": 68, "northeast": 68, "clim": [68, 69, 81, 103, 105], "suptitl": [68, 70, 71, 76, 115, 118], "precipitaion": [68, 70, 71], "discrep": [68, 102, 115], "repetit": 68, "interfer": 68, "noisi": 68, "obscur": 68, "grid_month": 68, "grid_rol": 68, "slower": 68, "grid_rolling_24m": 68, "dictat": [68, 103], "unlink": 68, "cosin": [68, 89, 90], "anom_weight": 68, "global_weighted_mean": 68, "global_unweighted_mean": 68, "global_diff": 68, "influenti": [69, 75, 119], "tarfil": 69, "neutral": [69, 105], "ship": [69, 71], "argo": 69, "chunk": [69, 99, 105], "manang": 69, "sst_30yr": 69, "sst_clim": 69, "sst_anom": 69, "rdbu_r": 69, "slider": 69, "sst_nino34": 69, "nino34": [69, 70], "pplot": 69, "nino3": 69, "nomin": 69, "ub": 69, "swing": 69, "climatolgi": 69, "regularli": 69, "sst_30yr_lat": 69, "sst_clim_lat": 69, "sst_anom_lat": 69, "nino34_lat": 69, "oni_lat": 69, "versu": [69, 71, 80, 82, 87, 90, 105, 108], "revist": 69, "potent": 69, "forthcom": 69, "irregularli": [70, 91, 95], "cascad": [70, 102], "url_precip": 70, "vhdcg": 70, "filename_precip": 70, "sharei": [70, 71], "berween": 70, "precip_nino34": 70, "precip_nino34_mean": 70, "theses": 70, "axvlin": [70, 82, 88, 103, 105], "unveil": 70, "nonlinear": [70, 102, 103, 119], "inclin": 70, "residu": 70, "skip": [70, 75], "precipitatoin": 70, "correlatin": 70, "likelihood": [70, 79, 115], "pure": [70, 89, 90, 102], "el_nino_sst": 70, "el_nino_precip": 70, "la_nina_sst": 70, "la_nina_precip": 70, "el_nino_r": 70, "el_nino_p": 70, "pearsonr": [70, 71], "corr": [70, 71, 120], "coef": [70, 71, 118], "val": [70, 71], "la_nina_r": 70, "la_nina_p": 70, "itali": 70, "whatev": [70, 102], "italy_lon": 70, "italy_lat": 70, "precip_nino34_itali": 70, "italy_el_nino_sst": 70, "italy_el_nino_precip": 70, "italy_la_nina_sst": 70, "italy_la_nina_precip": 70, "italy_el_nino_r": 70, "italy_el_nino_p": 70, "italy_la_nina_r": 70, "italy_la_nina_p": 70, "correctli": [71, 114, 118, 119, 120], "cross": [71, 85, 95, 99, 105, 115], "deem": [71, 115, 119], "drifter": 71, "glider": 71, "benchmark": 71, "exclus": 71, "ghcn": 71, "5x5": 71, "continent": [71, 80], "1895": 71, "file_nclimgrid": 71, "nclimgrid_prcp": 71, "prcp_ob": 71, "nclimgird": 71, "millimet": 71, "prcp": 71, "days_in_month": 71, "obs_rat": 71, "ds_gpcp": 71, "prcp_sat": 71, "central_lat": 71, "central_lon": 71, "sat": [71, 82], "ob": [71, 108, 109, 110, 111], "suplot": 71, "albersequalarea": 71, "5km": 71, "latitut": 71, "nyc": 71, "obs_tot": 71, "marker": [71, 74, 75, 76, 112, 114, 115, 120], "confirm": [71, 80], "fashion": 71, "robustli": 71, "scatterplot": 71, "samt": 71, "y_lim": 71, "x_lim": 71, "set_ylim": [71, 79, 81, 82, 89, 90, 103, 105, 110, 111, 113, 114, 115, 119], "stong": 71, "sat_clim": 71, "obs_clim": 71, "sat_clim_anom": 71, "obs_clim_anom": 71, "geoloc": 71, "narrowli": 71, "paleoclimatolog": [73, 77, 80], "wg1ar5_chapter05_fin": 73, "hottest": [73, 115], "pub": [73, 75, 77, 82], "3021": 73, "fs2010": 73, "18o": 73, "earthobservatori": 73, "paleoclimatology_oxygenbal": 73, "zahra": [74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "khodakaramimaghsoud": [74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "usabl": 74, "donwload": [74, 77, 79], "lidp": 74, "lipd2df": 74, "lipd_dirpath": 74, "pkl_filepath": 74, "col_str": 74, "paleodata_pages2kid": 74, "datasetnam": [74, 76], "archivetyp": [74, 76], "geo_meanelev": 74, "geo_meanlat": [74, 76], "geo_meanlon": [74, 76], "yearunit": 74, "paleodata_variablenam": [74, 76], "paleodata_unit": 74, "paleodata_valu": 74, "paleodata_proxi": 74, "bunch": 74, "boost": [74, 101, 103], "pikl": 74, "pickl": 74, "work_dir": 74, "getcwd": 74, "requri": 74, "abspath": 74, "readlipd": 74, "ts_list": [74, 76, 78, 81], "extractt": 74, "recov": [74, 118], "chdir": 74, "df_tmp": [74, 105], "paleodata_useinglobaltemperatureanalysi": 74, "dropna": [74, 77, 119], "save_path": 74, "to_pickl": 74, "w1d4_paleoclim": [74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90], "deposit": 74, "pollen": 74, "microfossil": 74, "charcoal": 74, "microscop": 74, "molecul": [74, 89, 91, 123], "accumul": [74, 101, 103], "dust": 74, "salin": 74, "speleothem": [74, 76, 80], "cave": [74, 80], "groundwat": 74, "thin": [74, 87], "calcium": 74, "ring": [74, 76], "holocen": [74, 75], "692": 74, "648": 74, "ce": 74, "2k": [74, 81, 87, 88], "paleo": [74, 75, 77, 81, 82, 99], "pyleoclim": [74, 76, 77, 78, 79, 80, 81], "lpd": 74, "data_path": [74, 75, 77], "imbed": 74, "pages2k_data": 74, "lipd_file_path": [74, 76], "ndownload": 74, "figshar": 74, "8119937": 74, "unzip": [74, 76], "helpfer": 74, "lipd_2df": 74, "alright": 74, "lipd_fil": 74, "colour": 74, "archive_typ": [74, 76], "83984375": 74, "73828125": [74, 76], "71484375": [74, 76], "41796875": [74, 76], "546875": 74, "41015625": 74, "52734375": [74, 76], "8046875": [74, 76], "97916667": [74, 76], "74609375": 74, "25390625": 74, "87890625": 74, "54296875": 74, "26953125": 74, "07421875": 74, "078125": 74, "57421875": 74, "1953125": 74, "80078125": 74, "add_subplot": 74, "fontweight": [74, 120], "bold": [74, 75, 120], "set_glob": [74, 76, 82], "fratur": [74, 76], "forloop": 74, "type_i": 74, "geodet": [74, 75, 76], "scatterpoint": [74, 76], "bbox_to_anchor": [74, 76, 81, 85], "craft": 74, "meticul": 74, "linkedearth": [74, 75, 76, 77, 78, 79, 80, 81], "multiproxi": [74, 76], "170088": [74, 76], "sdata": [74, 76], "\u03b4": [75, 76, 77, 80], "proton": 75, "neutron": 75, "lighter": 75, "heavier": [75, 108], "deuterium": [75, 77], "mill": [75, 76, 78], "deplet": [75, 77, 78, 79, 80, 102], "enrich": [75, 77, 78, 79, 80, 82], "amout": 75, "pyleo": [75, 76, 77, 78, 79, 80, 81], "patch": [75, 120], "colder": [75, 76, 85, 90, 91], "bandpass": 75, "cobb": 75, "atol": 75, "stock_img": 75, "rectangl": 75, "170": 75, "add_patch": 75, "rx": 75, "ry": 75, "get_xi": 75, "cx": 75, "get_width": 75, "cy": 75, "get_height": 75, "annot": [75, 88, 120], "va": 75, "162": 75, "078333": 75, "883611": 75, "157": 75, "144": [75, 78, 120], "pycleoclim": 75, "time_nam": [75, 77, 78, 79, 80, 81], "time_unit": [75, 76, 77, 78, 79, 80, 81], "value_nam": [75, 77, 78, 79, 80, 81], "value_unit": [75, 77, 78, 79, 80, 81], "deg": 75, "clean_t": 75, "filename_palmyra": 75, "palmyra_2003": 75, "url_palmyra": 75, "east_pacif": 75, "6190": 75, "7539": 75, "skiprow": [75, 77, 79], "lambda": [75, 85, 101, 105], "sep": [75, 77, 105], "delimit": 75, "encod": [75, 77], "iso": 75, "8859": 75, "calendard": 75, "d180": 75, "datfram": 75, "ts_palmyra": 75, "d18o": [75, 76, 79, 80], "palmyra_stnd": 75, "filename_cobb2013": 75, "cobb2013": 75, "fan": 75, "modsplic": 75, "url_cobb2013": 75, "data_path2": 75, "ts_line": 75, "line_stnd": 75, "multipleseri": [75, 76, 77, 78, 80, 81], "nino_comparison": 75, "stackplot": [75, 76, 78, 80], "xlim": [75, 76, 79, 80, 114, 115], "1960": [75, 112], "ref_period": 75, "show_xaxi": 75, "rdbu": 75, "ventur": 75, "encapsul": [75, 88], "glimps": 75, "339": 75, "1228246": 75, "millennium": 75, "nature01779": 75, "euro2k": 76, "pages2k": 76, "lipd": [76, 78], "euro2k_data": 76, "7ezp3": 76, "d_euro": 76, "filter_data": 76, "variable_nam": 76, "to_tso": 76, "idx": [76, 110], "lipdseri": 76, "ts_list_archive_typ": 76, "entri": [76, 105, 109, 115, 123], "ms_euro_lak": 76, "euro_lake_lat": 76, "euro_lake_lon": 76, "ms_euro_tre": 76, "euro_tree_lat": 76, "euro_tree_lon": 76, "ms_euro_spel": 76, "euro_spel_lat": 76, "euro_spel_lon": 76, "uncom": [76, 113, 114, 115, 120], "spel_stnd": 76, "lake_stnd": 76, "tree_stnd": 76, "label_x_loc": 76, "v_shift_factor": 76, "yr": [76, 78, 81, 82, 95, 102], "categor": [76, 85], "emil": 76, "geai": 76, "mckai": 76, "paleoclimatologist": 77, "mountain": 77, "conwai": 77, "filename_antarctica2015": 77, "antarctica2015co2composit": 77, "url_antarctica2015": 77, "icecor": 77, "co2df": 77, "137": 77, "ts_co2": 77, "co_2": [77, 91, 95], "eccentr": [77, 79, 80], "obliqu": [77, 79, 80], "precess": [77, 79, 80], "filename_edc3deuttemp2007": 77, "edc3deuttemp2007": 77, "url_edc3deuttemp2007": 77, "epica_domec": 77, "dddf": 77, "91": 77, "unicode_escap": 77, "ddt": 77, "u2030": [77, 79, 80], "ms": 77, "standar": [77, 78], "dove": 77, "captiv": 77, "enlighten": 77, "comfort": [77, 123], "jouzel": 77, "millenni": 77, "1141038": 77, "l\u00fcthi": 77, "le": [77, 88], "floch": 77, "453": 77, "379": 77, "382": 77, "nature06949": 77, "geoph": 77, "ncessari": 78, "wax": 78, "tanganyika": [78, 81], "tiernei": [78, 81, 82], "filename_tang": [78, 81], "tanganyika_dd": 78, "url_tang": [78, 81], "sujvp": 78, "tang_dd": 78, "ts_tang": 78, "dd_ivonli": 78, "ddwax": 78, "ddprecip": 78, "invert_yaxi": [78, 79, 89], "invert": [78, 89], "sepcif": 78, "is_evenly_spac": 78, "nearbi": 78, "slinear": 78, "tang_linear": 78, "minor": 78, "quadract": 78, "interv": [78, 80, 86, 87, 88, 113], "coarsest": 78, "tang_bin": 78, "bin_siz": 78, "tang_bin_500": 78, "tang_bin_1000": 78, "modif": [78, 115], "matrix": [78, 94, 109, 118, 120], "uncorrel": 78, "mixtur": 78, "otto": [78, 107], "bliesner": 78, "gulf": 78, "aden": 78, "demenoc": 78, "bosumtwi": 78, "shanahan": 78, "african": 78, "margin": [78, 101], "filename_aden": 78, "aden_dd": 78, "url_aden": 78, "gm2v9": 78, "filename_bosumtwi": 78, "bosumtwi_dd": 78, "url_bosumtwi": 78, "mr7d9": 78, "gc27": 78, "filename_gc27": 78, "gc27_dd": 78, "url_gc27": 78, "k6e3a": 78, "ts_tanganyika": 78, "ts_aden": 78, "age_calbp": 78, "ddwaxivcorr": 78, "ts_bosumtwi": 78, "d2hleafwaxc31ivc": 78, "ts_gc27": 78, "age_bp": 78, "ddwax_iv": 78, "ms_africa": 78, "common_tim": 78, "gdkernel": 78, "africa_ct": 78, "trim": [78, 99], "africa_pca": 78, "pctvar": 78, "pc": 78, "mode": [78, 105, 123], "constrain": [78, 82, 85, 101, 102], "africa_pc1": 78, "africa_mode1": 78, "series_list": 78, "pc_1": 78, "pc1": 78, "ax1": [78, 81, 82, 120], "ax2": [78, 120], "twinx": [78, 81], "instanti": 78, "mode1": 78, "pc1_scale": 78, "irregular": 78, "anlayz": 78, "southeast": [78, 80], "vol": 78, "322": 78, "5899": 78, "252": 78, "1160485": 78, "abrupt": 78, "horn": 78, "hydroclim": 78, "342": 78, "6160": 78, "843": 78, "846": 78, "1240411": 78, "pausata": 78, "sahara": 78, "e1601503": 78, "sciadv": 78, "1601503": 78, "transgress": 78, "termin": [78, 80], "140": [78, 113], "ngeo2329": 78, "foram": 79, "filename_lr04": 79, "url_lr04": 79, "pyleotutori": 79, "lr04_data": 79, "ts_lr04": 79, "mil": 79, "lr04_slice": 79, "periodogram": 79, "fourier": 79, "welch": 79, "variant": 79, "segment": [79, 112], "taper": 79, "mtm": 79, "lomb": 79, "scargl": 79, "unevenli": 79, "wwz": [79, 80], "ylim": [79, 80, 85, 108, 110, 114, 115], "lomb_scargl": 79, "fairli": [79, 121], "lr04_ls_sd": 79, "signif_test": 79, "surrog": [79, 80], "autoregress": 79, "lr04_ls_sd_sig": 79, "psd": 79, "005": [79, 103], "spectra": 79, "025": [79, 115], "unfold": 79, "summary_plot": 79, "scalogram": 79, "scal": 79, "time_lim": 79, "psd_label": 79, "absenc": 79, "pliocen": 79, "pleistocen": 79, "paleoceanographi": 79, "pa1003": 79, "2004pa001071": 79, "mauro": 80, "tripaldi": 80, "climlab": 80, "const": 80, "orbitalt": 80, "daily_insol": 80, "configur": [80, 105], "summer": 80, "chines": 80, "broadli": 80, "sanbao": 80, "hulu": 80, "dongg": 80, "filename_sanbao_composit": 80, "sanbao_composit": 80, "url_sanbao_composit": 80, "paleohackathon": 80, "orbital_record": 80, "d18o_data": 80, "cyclic": 80, "wavelet": 80, "d18o_stnd": 80, "d18o_wwz": 80, "d18o_wwz_sig": 80, "brian": [80, 84, 89, 90], "67\u00ban": 80, "kyear": 80, "orb": 80, "days_per_year": 80, "qsb": 80, "julian": 80, "152": 80, "qsb_jja": 80, "151": 80, "ts_qsb": 80, "ky": 80, "ts_qsb_stnd": 80, "ms_compar": 80, "similarit": 80, "psd_wwz": 80, "31\u00ban": 80, "edward": 80, "sinha": [80, 102, 103, 105], "asian": 80, "640": 80, "534": 80, "646": 80, "nature18591": 80, "riek": 81, "sch\u00e4fer": 81, "sytem": 81, "taganyika": 81, "tex86": 81, "isoprenoid": 81, "glycerol": 81, "dialkyl": 81, "tetraeth": 81, "igdgt": 81, "archaeal": 81, "membran": 81, "lipid": 81, "compound": [81, 123], "tang_sst": 81, "p8tx3": 81, "proxy_temp": 81, "proxy_t": 81, "lst": 81, "\u00bac": 81, "braconnot": 81, "pmip3_gmst": 81, "filename_pmip3": 81, "url_pmip3": 81, "gw2m5": 81, "cesm": [81, 94], "goddard": 81, "df_new": 81, "cesm_member_": 81, "e2": 81, "r_r1i1p127": 81, "r_r1i1p121": 81, "cesm_member_1": 81, "cesm_member_2": 81, "cesm_member_3": 81, "cesm_member_4": 81, "cesm_member_5": 81, "cesm_member_6": 81, "cesm_member_7": 81, "cesm_member_8": 81, "cesm_member_9": 81, "cesm_member_10": 81, "ts_dict": 81, "nicknam": 81, "ccsm4": 81, "keyerror": 81, "ms_pmip": 81, "lgd_kwarg": 81, "1800": 81, "proxy_stnd": 81, "xmin": 81, "xmax": 81, "ymin": [81, 108], "ymax": [81, 108], "harrison": 81, "kageyama": 81, "palaeoclimat": 81, "417": 81, "nclimate1456": 81, "may": 81, "meyer": 81, "twentieth": 81, "unpreced": [81, 99], "422": 81, "425": 81, "ngeo865": 81, "osman": 82, "lgm": [82, 99], "cutil": 82, "ago": [82, 94], "millenium": 82, "reanalys": [82, 99], "filename_lgmr_sat_climo": 82, "lgmr_sat_climo": 82, "url_lgmr_sat_climo": 82, "osman2021": 82, "sat_mean": 82, "sat_global_mean": 82, "circ": [82, 90, 95, 96, 97, 98], "18000": 82, "21000": 82, "lgm_mean": 82, "modern_mean": 82, "sat_chang": 82, "set_edgecolor": 82, "zonal_mean": 82, "holist": [82, 95, 99], "ponder": 82, "erb": 82, "matthew": 82, "jessica": 82, "zhu": 82, "tardif": 82, "hakim": 82, "jonathan": 82, "king": 82, "christoph": 82, "poulsen": 82, "599": 82, "244": 82, "s41586": 82, "021": 82, "03984": 82, "judd": 82, "anchuka": 82, "matlab": [82, 123], "eguspher": 82, "peter": [85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 107, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "ohu": [85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "derick": [85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "temfack": [85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "yunlong": [85, 86, 87, 88, 89, 90, 91], "peizhen": [85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "outgo": [85, 87, 88, 89], "hv": 85, "pn": 85, "electromagnet": [85, 123], "hc": 85, "kappa": 85, "626075": 85, "99792": 85, "108": 85, "3804": 85, "288k": [85, 87], "replot": 85, "conceptu": [85, 102], "626075e": 85, "99792e8": 85, "3804e": 85, "deped": 85, "exp": [85, 114, 118], "lpeak": 85, "898": 85, "update_plot": 85, "emiss_temp": 85, "increment": 85, "1um": 85, "micromet": 85, "wav": 85, "divis": 85, "50e": 85, "intensity288": 85, "ipeak": 85, "emission_temperatur": 85, "ipeak288": 85, "lpeak288": 85, "1e6": [85, 89, 102], "init_v": 85, "list_of_curv": 85, "0e7": 85, "bb_plot": 85, "\u03bcm": 85, "\u03bb": 85, "m\u00b3": 85, "steradian": 85, "emiss_temp_widget": 85, "intslid": 85, "bound_plot": 85, "bind": 85, "outward": 85, "olr": [85, 86, 87, 88, 89, 90], "mathbf": [85, 86, 88], "sigma": [85, 86, 87, 88, 101, 103], "rearrang": 85, "solv": [85, 86, 120, 121, 123], "67e": [85, 86, 87, 88], "80251510194708": 85, "19748489805292": 85, "realist": [85, 90, 91], "ellipsi": [85, 87, 119], "noth": [85, 123], "habit": 85, "nitrou": 85, "oxid": [85, 95], "chloroflourocarbon": 85, "1750": 85, "volcano": 85, "took": [85, 95, 105], "volcan": [85, 87, 113], "1900": [85, 87, 95, 113], "gsat": [85, 87], "emul": 85, "supplementari": 85, "sm": [85, 87, 99], "erf": 85, "2237": 85, "ch4": [85, 95], "n2o": 85, "wmghg": 85, "o3": 85, "shade": [85, 87, 97, 98, 105, 113, 115], "showveri": 85, "transmiss": [85, 86, 87, 88, 89], "coefici": 85, "tau": [85, 86, 87, 88, 89], "explic": 85, "parametr": [85, 89, 103], "observt": 85, "unitless": [85, 86, 87, 88], "6126957827090973": 85, "said": [85, 103], "6114": 85, "5800k": 85, "underlai": 85, "t_sun": 85, "wien": 85, "4e": 85, "rainbow_dict": 85, "8b00ff": 85, "4b0082": 85, "0000ff": [85, 118], "00ff00": 85, "ffff00": 85, "ff7f00": 85, "ff0000": [85, 118], "wv_rang": 85, "axvspan": [85, 105], "ec": 85, "mu": [85, 101, 103], "labelpad": 85, "b_": 85, "augment": 85, "algebra": [86, 89, 90, 118, 122], "340": [86, 87, 88], "f_": 86, "ref": [86, 96, 97, 98, 99], "parenthes": 86, "sole": [86, 87, 103, 114], "retain": 86, "quantif": 86, "sensibl": [86, 91, 110], "latent": [86, 91, 105], "wild": 86, "f_ref": 86, "29411764705882354": 86, "denomen": 86, "esim": 86, "99999999999997": 86, "t_": [86, 87, 88], "eq": 86, "perfectli": 86, "stefan": [86, 87, 88], "boltzmann": [86, 87, 88], "6127": [86, 87, 88], "t_eq": 86, "300287595812": 86, "300287595811994": 86, "assupmt": 86, "tau_2": [86, 87], "t_eq_2": 86, "5542225759401": 86, "554222575940116": 86, "get_eqt": 86, "eqt": 86, "imbal": [87, 88, 89, 90], "algeba": [87, 88], "hockei": 87, "mathetmat": 87, "hadcrut5": 87, "blend": 87, "subsampl": [87, 105], "erupt": [87, 113], "asterisk": 87, "indirectli": 87, "inset": 87, "berkelei": 87, "noaaglobaltemp": 87, "kadow": 87, "rcp4": 87, "bock": 87, "0http": 87, "asr": [87, 88, 89, 90], "multipli": [87, 89, 101, 103, 105], "c_": 87, "oc": [87, 94], "atmo": 87, "atm": 87, "w_": 87, "graviti": 87, "rho_": 87, "d_": 87, "c_oc": 87, "3850": 87, "rho_oc": 87, "1025": 87, "m3": 87, "d_oc": 87, "mize": 87, "c_atm": 87, "w_atm": 87, "100000": 87, "capactii": 87, "276237500": 87, "10234454": 87, "638124362": 87, "286471954": [87, 88], "63812435": 87, "discret": [87, 94, 95, 96, 97, 98], "euler": [87, 88], "t_n": 87, "2941": 87, "radit": [87, 88], "tempeatur": 87, "step_forward": [87, 88, 89, 90], "insol": 87, "t_new": [87, 88], "numtstep": [87, 88], "sec_2_yr": [87, 88], "154e7": [87, 88], "intial": [87, 88, 111], "t_seri": [87, 88], "1105634820389": 87, "18070153127155": 87, "22517079984357": 87, "25335571129256": 87, "2712155880614": 87, "2825312527962": 87, "28970000469195": 87, "29424133262887": 87, "2971181140696": 87, "29894041951593": 87, "300094747791": 87, "30082594344617": 87, "3012891080957": 87, "3015824915692": 87, "30176832972967": 87, "dispai": 87, "9998731769181991": 87, "9997463538363982": 87, "999619530754597": 87, "9994927076727964": 87, "999365884590995": 87, "999239061509194": 87, "999112238427394": 87, "998985415345593": 87, "998858592263792": 87, "99873176918199": 87, "99860494610019": 87, "998478123018389": 87, "998351299936589": 87, "998224476854787": 87, "998097653772987": 87, "one_yr": 87, "dt_2": 87, "doubl": [87, 113], "step_forward_forc": 87, "93": [87, 114], "wm": 87, "ftoa": [87, 88], "equilbrium": [87, 89, 90], "unforc": 87, "wrote": 87, "t_series_forc": 87, "t_new_forc": 87, "ftoa_forc": 87, "typeerror": 87, "sensitivti": 87, "unsupport": 87, "operand": 87, "interchang": 87, "planck": [88, 96, 113, 115], "brentq": 88, "amplifi": [88, 102], "cl": 88, "ot": 88, "asr_val": 88, "zeros_lik": 88, "ramp": 88, "permafrost": 88, "olr_val": 88, "tt": [88, 103], "im": [88, 118], "unstabl": [88, 90, 110], "asymptot": [88, 102], "init_temp": 88, "teq1": 88, "teq2": 88, "teq3": 88, "320": 88, "stabil": [88, 90, 102, 115], "osr": 88, "recaclul": 88, "pos_ind1": 88, "pos_ind2": 88, "neg_ind1": 88, "neg_ind2": 88, "ls": [88, 103], "eq1": 88, "xy": [88, 120], "xytext": [88, 120], "annotation_clip": 88, "eq2": 88, "eq3": 88, "arrowprop": [88, 120], "arrowstyl": 88, "305": 88, "307": 88, "q_val": 88, "420": 88, "q_2": 88, "frozen": 88, "steadili": 88, "insolation_v": 88, "385": 88, "rapid": [88, 89, 99, 102], "bonu": 88, "reddest": 88, "preciselt": 88, "anaconda": [89, 90], "forg": [89, 90, 99], "metpi": [89, 90], "urllib": [89, 90, 102, 105], "internet": [89, 90, 123], "skew": [89, 90, 108, 110, 112, 113], "skewt": [89, 90], "explicitli": [89, 103, 105], "constitu": 89, "filename_sq": [89, 90], "cpl_1850_f19": [89, 90], "gw": [89, 90], "h0": [89, 90], "url_sq": [89, 90], "c6q4j": [89, 90], "weight_factor": [89, 90], "qglobal": [89, 90], "lev": [89, 90], "mystat": [89, 90], "column_st": [89, 90], "water_depth": [89, 90], "rrtmg": [89, 90], "radmodel": [89, 90], "specific_humid": [89, 90], "seconds_per_dai": [89, 90], "tatm": [89, 90], "perk": 89, "bulk": [89, 102], "absorber_vmr": 89, "volumn": 89, "diagnost": [89, 90], "diag_d": 89, "to_xarrai": 89, "ran": 89, "gram": 89, "ppmv": 89, "logarithm": [89, 109], "lowest": [89, 90, 109], "log": [89, 101, 103, 105, 109, 111, 114, 115], "filename_ncep_air": [89, 90], "ltm": [89, 90], "url_ncep_air": [89, 90], "w6cd5": [89, 90], "ncep_air": [89, 90], "compens": [89, 90], "coslat": [89, 90], "tglobal": [89, 90], "funciton": 89, "make_skewt": [89, 90], "1050": [89, 90], "plot_dry_adiabat": [89, 90], "adiabat": [89, 90], "plot_moist_adiabat": [89, 90], "moist": [89, 90], "plot_mixing_lin": [89, 90], "add_profil": [89, 90], "tempctok": [89, 90], "markers": [89, 90, 113, 119], "get_color": [89, 90], "logp": 89, "ab": [89, 90], "h20": 89, "clone": 89, "radmodel_noh2o": 89, "process_lik": 89, "rcparam": [90, 102, 103], "jshtml": 90, "initial_figur": 90, "ioff": 90, "hide": [90, 97, 98, 99], "c0": [90, 97, 98, 99, 103, 105, 109, 112, 113, 115], "rc": 90, "set_xdata": 90, "1e3": [90, 102, 105], "set_text": 90, "days_elaps": 90, "hack": 90, "make_basic_skewt": 90, "static": 90, "turbul": 90, "boil": 90, "tropospher": 90, "10km": 90, "unsatur": 90, "lesser": 90, "mini": [90, 94, 99], "steeper": 90, "inhibit": 90, "restat": 90, "eas": [90, 118], "rad": 90, "conv": 90, "convectiveadjust": 90, "adj_lapse_r": 90, "laps": 90, "rcm": 90, "subprocess": 90, "compute_diagnost": 90, "funcanim": 90, "farg": 90, "instant": 90, "instabl": 90, "isotherm": 90, "uniform": [90, 97, 98, 99], "necess": 90, "buseck": [91, 94, 95, 96, 97, 98, 99], "tom": [91, 94, 95, 96, 97, 98, 99], "nichola": [91, 94, 95, 96, 97, 98, 99], "fail": [91, 94, 95, 96, 97, 98, 99], "increasingli": [91, 105], "biom": 91, "prepart": 91, "historicallli": 91, "massiv": 91, "grid_id": [91, 94], "gr": 91, "repeatedli": [91, 120], "vocabulari": [91, 101, 105], "somehow": 91, "zarr": [91, 99], "dask": 91, "lazi": [91, 94], "tb": 91, "subtl": 91, "crowdsourc": 91, "convieni": 91, "hfl": 91, "hfss": 91, "rld": 91, "rlu": 91, "rsdt": 91, "rsut": 91, "rlut": 91, "hist": [91, 113, 115, 119, 120], "analog": 91, "day1": 91, "experiment1": 91, "experiment2": 91, "my_funct": 91, "hist_dt": 91, "hist_nat": 91, "r_": 91, "uparrow": 91, "downarrow": 91, "evapor": [91, 115], "hidden": [91, 120], "thermomet": 91, "compris": [91, 96], "geotherm": 91, "fusion": 91, "predefin": [91, 108], "hist_am_latent_heat_flux": 91, "hist_am_sensible_heat_flux": 91, "hist_am_downwelling_longwave_flux": 91, "hist_am_upwelling_longwave_flux": 91, "hist_am_downwelling_shortwave_flux": 91, "hist_am_upwelling_shortwave_flux": 91, "ariabl": 91, "hist_am_net_shortwave_heat_flux": 91, "hist_am_net_longwave_heat_flux": 91, "hist_am_net_heat_flux": 91, "ax_lat": 91, "ax_shortwav": 91, "ax_sens": 91, "ax_longwav": 91, "weak": 91, "rce": 91, "hist_azm_latent_heat_flux": 91, "hist_azm_sensible_heat_flux": 91, "hist_azm_net_shortwave_flux": 91, "hist_azm_net_longwave_flux": 91, "hist_azm_net_heat_flux": 91, "30n": 91, "60n": 91, "dip": 91, "symmetri": 91, "hypothet": 91, "oN": 91, "elucid": 91, "experiment": 93, "eyr": 93, "gmd": 93, "1937": 93, "taiesm1": [94, 95, 96, 97, 99], "taiwan": [94, 96], "prove": 94, "thie": 94, "cut": [94, 122], "sst_ssp585": 94, "sst_present": 94, "2100": [94, 95, 97, 99, 102, 103, 113, 115], "snapshot": [94, 98], "ax_futur": 94, "ax_diff_juli": 94, "ax_diff_jan": 94, "sst_futur": 94, "sst_difference_juli": 94, "sst_difference_jan": 94, "dissimilar": 94, "di": [94, 107], "apart": 94, "oceanograph": 94, "bia": [94, 99, 105], "lazili": 94, "quicker": 94, "ds_target": 94, "regridd": 94, "bilinear": [94, 105], "sst_ssp585_regrid": 94, "slow": [94, 102, 105], "ax_regrid": 94, "ax_n": 94, "sst_future_regrid": 94, "scenariomip": [95, 97], "cat_area": [95, 96, 97, 98, 99], "hopefulli": [95, 98, 110], "dt_area": [95, 96, 97, 98, 99], "dt_with_area": [95, 96, 97, 99], "s_": 95, "iint_": 95, "dxdy": 95, "summat": 95, "sum_": [95, 101, 119], "2d": 95, "neccessari": 95, "fillna": [95, 96, 97, 98, 99, 115], "keep_attr": [95, 96, 97, 98, 99], "perhap": [95, 102], "global_mean": [95, 96, 97, 98, 99], "dt_gm": [95, 96, 97, 99], "intent": 95, "ultim": [95, 102], "rcp": 95, "gtco2yr": 95, "sulphur": 95, "so2": 95, "nitrogen": 95, "nox": 95, "mt": [95, 102], "ppb": 95, "fourth": 95, "gwl": 95, "synthes": [95, 99], "datafrom": 96, "ipsl": [96, 97, 99], "cm6a": [96, 97, 99], "pierr": 96, "simon": 96, "laplac": 96, "franc": 96, "cm2": [96, 97, 99, 113], "csiro": [96, 113], "arccss": [96, 113], "abbrevi": 96, "hr": [96, 113, 115], "ellips": [96, 97, 98, 99], "concat": [96, 97, 98, 99, 105, 119], "finish": 96, "plot_historical_ssp126_combin": [96, 97, 98, 99], "da_combin": [96, 97, 98, 99], "slight": [96, 110], "care": 96, "gmsst": [96, 99], "1950": [96, 97, 98, 99, 115], "datatree_anomali": [96, 97, 98, 99], "dt_out": [96, 97, 98, 99], "dt_gm_anomali": [96, 97, 99], "2080": 96, "elsewher": [97, 98, 99], "libari": [97, 98, 99], "da_upp": [97, 98, 99], "da_low": [97, 98, 99], "c2": [97, 98, 99, 112, 113, 115], "annual_sst": [97, 99], "assign_coord": [97, 99], "french": [97, 99], "overrid": [97, 99], "realiz": [98, 103, 121], "r5i1p1f1": 98, "spin": 98, "cat_ensembl": 98, "r2i1p1f1": 98, "r3i1p1f1": 98, "dt_ensembl": 98, "dt_ensemble_with_area": 98, "dt_ensemble_gm": 98, "dt_ensemble_gm_anomali": 98, "plot_historical_ssp126_ensemble_combin": 98, "hue": [98, 102, 113], "spread": [98, 119], "contextu": 99, "1870": 99, "126": [99, 113, 115], "quantil": [99, 108, 110, 111, 113, 114, 115], "dashboard": 99, "feedstock": 99, "ncsa": 99, "osn": 99, "xsede": 99, "ds_ob": 99, "convert_calendar": 99, "sst_obs_gm": 99, "sst_obs_gm_anomali": 99, "glean": 99, "pleiocen": 99, "mpwp": 99, "lig": 99, "caption": 99, "pmip": 99, "highresmip": 99, "1995": 99, "2050": [99, 113, 115], "diagon": [99, 118, 119], "palroclim": 99, "synthesi": 99, "recor": 99, "contempl": 99, "realism": [99, 103], "intric": [99, 102, 105, 119], "capit": [101, 102, 103], "labor": [101, 103], "hinder": [101, 102, 103], "welfar": [101, 103], "dice": 101, "e_": [101, 103], "ind": [101, 103], "inflict": [101, 103], "omega": [101, 103], "mu_t": [101, 103], "s_t": [101, 103], "lambda_t": 101, "theta_1": 101, "theta_2": 101, "invest": [101, 102, 103], "essenc": [101, 103], "depreci": [101, 102], "k_": 101, "k_t": 101, "i_t": 101, "sq": 101, "elast": [101, 103], "2nd": 101, "weakli": [101, 102], "sigmoid": [101, 118], "lu": 101, "isoelast": 101, "infti": 101, "c_t": 101, "l_t": 101, "discount": 101, "unconstrain": 101, "sweet": [101, 103], "spot": [101, 103], "counterbal": [101, 103], "horizon": [101, 103], "scc": 101, "newbold": 101, "griffith": 101, "moor": 101, "wolverton": 101, "kopit": 101, "scc_t": 101, "propto": 101, "partial": [101, 118], "e_t": 101, "proportion": 101, "tonn": 101, "tweet": [101, 105], "tf": [101, 105], "denomin": 101, "tfidf": [101, 105], "idf": [101, 105], "sklearn": [101, 105, 118, 119, 120], "vec": 101, "nx": 101, "2_i": 101, "euclidean": 101, "downweight": [101, 105], "maximilian": [102, 103, 105], "puelma": [102, 103, 105], "touzel": [102, 103, 105], "duplexlaura": [102, 103], "manisha": [102, 103, 105], "renew": [102, 105], "thier": 102, "scarciti": 102, "uncheck": 102, "iam": [102, 113], "plot_world_vari": 102, "get_ipcc_data": 102, "var_nam": 102, "iamdf": 102, "read_excel": 102, "tail": [102, 108, 110, 112], "trail": 102, "wideform": 102, "longform": 102, "datum": 102, "wide_to_long": 102, "reformat": 102, "set_nam": 102, "run_and_plot": 102, "nri_factor": 102, "new_lifetime_industrial_capit": 102, "nonrenew": 102, "init_world3_const": 102, "nri": 102, "1e12": 102, "alic1": 102, "alic2": 102, "init_world3_vari": 102, "set_world3_table_funct": 102, "set_world3_delay_funct": 102, "run_world3": 102, "nrfr": 102, "iopc": 102, "fpc": 102, "ppolx": 102, "variable_label": 102, "capita": 102, "kilogram": 102, "perist": 102, "36e8": 102, "death": 102, "deathrat": 102, "variable_limit": 102, "16e9": 102, "5e8": 102, "img_background": 102, "img": 102, "fig7": 102, "png": 102, "scenario_nam": 102, "baselin": 102, "pop_path": 102, "ed9aq": 102, "iampopdf": 102, "year_data": 102, "var_data": 102, "gcf": 102, "frameon": [102, 103], "w2d3_futureclim": [102, 105], "ipccii": [102, 105], "iiisocio": [102, 105], "economicbasi": [102, 105], "ssp4": 102, "rivalri": 102, "rocki": 102, "fossil": [102, 105, 113], "highwai": 102, "iamc_db": 102, "xlsx": 102, "_forc": 102, "_pop": 102, "_co2": 102, "repositori": 102, "iamc_db_forc": 102, "iamc_db_pop": 102, "iamc_db_co2": 102, "tkrf7": 102, "gcb79": 102, "axis_s": 102, "ax_idx": 102, "data_df": 102, "lineplot": 102, "fed": [102, 120], "endogen": 102, "exogen": [102, 103], "explicit": 102, "unawar": 102, "mortal": 102, "wast": 102, "neoclass": [102, 103], "wrong": 102, "poor": [102, 120], "qualit": 102, "certainli": 102, "similr": 102, "critiqu": 102, "stock": 102, "hzrsn": 102, "unconfin": 102, "meadow": 102, "naill": 102, "rander": 102, "zahn": 102, "wright": 102, "ma": 102, "1974": 102, "mdpi": 102, "09864": 102, "article_deploi": 102, "g001": 102, "precursor": 102, "jai": 102, "forrest": 102, "petterholdotm": 102, "wordpress": 102, "3000": 102, "quadrant": 102, "todo": 102, "h3mj2": 102, "1972": 102, "attenu": 102, "feedbak": 102, "pg": 102, "birth": 102, "wellb": 102, "undergo": 102, "exhaust": 102, "demand": [102, 103], "legitim": 102, "oil": 102, "quell": 102, "shale": 102, "revolut": 102, "presum": 102, "metal": 102, "jevon": 102, "paradox": 102, "coal": 102, "lifetim": 102, "maxyear": 102, "tripl": 102, "2025": 102, "year_max": 102, "savefig": 102, "world3_timeseries_case_1": 102, "bbox_inch": 102, "tight": 102, "declin": 102, "pink": [102, 103], "latter": 102, "effec": 102, "priori": 102, "unclear": 102, "obviou": [102, 119], "decoupl": 102, "inher": [102, 103], "world3_timeseries_case_2": 102, "diminish": 102, "increaesd": 102, "infrastructur": [102, 109], "rozenberg": 102, "lett": [102, 103], "abruptli": 102, "pyear": 102, "world3_timeseries_case_3": 102, "gradual": 102, "slowli": 102, "decarbon": 102, "downturn": 102, "stagnat": 102, "coplei": 102, "rivari": 102, "replic": 102, "cooper": 102, "hoc": [102, 103], "monolith": 102, "unregul": 102, "cornerston": 103, "intertwin": 103, "inner": 103, "uncertain": 103, "dicelib": 103, "mptouzel": 103, "pydic": 103, "plot_future_return": 103, "random_se": 103, "seed": [103, 105, 119, 120], "undiscounted_utility_time_seri": 103, "rand": [103, 119], "time_step": 103, "discounted_utility_time_seri": 103, "cumulsum_discounted_utility_time_seri": 103, "cumulsum_undiscounted_utility_time_seri": 103, "undiscount": 103, "promin": 103, "economist": 103, "world3": 103, "sandbox": 103, "critis": 103, "hansel": 103, "barrag": 103, "nordhau": 103, "dice2016": 103, "neo": 103, "classic": 103, "valuat": 103, "formal": 103, "monei": 103, "placehold": [103, 108], "h\u00fcttel": 103, "balderjahn": 103, "hoffmann": 103, "crude": 103, "meal": 103, "haven": 103, "eaten": 103, "comsumpt": 103, "constrast": 103, "socal": 103, "intertempor": 103, "theorist": 103, "recognit": 103, "devalu": 103, "cost": 103, "utili": 103, "unsidcount": 103, "cumul": [103, 105, 111, 118], "approx0": 103, "determinist": 103, "destroi": 103, "gdp": 103, "a1dic": 103, "00236": 103, "a2": 103, "a1": 103, "a_1": 103, "dice2023": 103, "exponenti": [103, 114], "a_2": 103, "appallingli": 103, "keen": 103, "predictor": [103, 118, 120], "poorli": [103, 119], "procedur": [103, 105, 114], "unrealist": 103, "causal": 103, "paradigm": 103, "serious": 103, "downplai": 103, "strive": 103, "contemporari": 103, "der": 103, "wijst": 103, "mcnamara": 103, "fallaci": 103, "market": 103, "cge": 103, "catastroph": 103, "riverin": 103, "gone": 103, "fore": 103, "fork": 103, "refactor": 103, "exis": 103, "dice_std": 103, "init_paramet": 103, "init_vari": 103, "controls_start_std": 103, "controls_bounds_std": 103, "get_control_bounds_and_startvalu": 103, "optimize_control": 103, "max_year": 103, "nt": 103, "upp": 103, "optimal_control": 103, "2500": 103, "2140": 103, "unattain": 103, "favor": 103, "sociolog": 103, "roll_out": 103, "plot_run": 103, "em": 103, "patter": 103, "price": 103, "2090": 103, "a3": 103, "controls_start": 103, "controls_bound": 103, "incur": 103, "schult": 103, "absent": 103, "quickli": [103, 123], "prstp": 103, "015": 103, "elasmu": 103, "dialogu": 103, "twitter": 105, "parti": 105, "cop": 105, "falkenberg": 105, "ngo": 105, "negoti": 105, "hypocrisi": 105, "nuanc": 105, "advocaci": 105, "wordcloud": 105, "feature_extract": 105, "tfidfvector": 105, "countvector": 105, "nltk": 105, "corpu": 105, "stopword": 105, "mpl_toolkit": 105, "axes_grid1": 105, "inset_loc": 105, "inset_ax": 105, "stuff": 105, "afinn": 105, "hereon": 105, "copx": 105, "twarc2": 105, "twarc": 105, "rehydr": 105, "hydrat": 105, "source_fil": 105, "store_fil": 105, "jsonl": 105, "batch": 105, "dir_nam": 105, "falkenberg2022_data": 105, "mkdir": 105, "batch_siz": 105, "1e5": 105, "download_pathnam": 105, "socioecondai": 105, "cop_twitter_id": 105, "copid": 105, "df_tweetid": 105, "tweet_ids_cop": 105, "batch_id": 105, "break_id": 105, "file_nam": 105, "tweetids_cop": 105, "_b": 105, "to_csv": 105, "cop26": 105, "50gb": 105, "filename_list": 105, "tweet_data": 105, "itt": 105, "tweet_id_batch_filenam": 105, "strvar": 105, "tweet_store_filenam": 105, "tweets_": 105, "st": 105, "tweets_cop": 105, "num_lin": 105, "selected_column": 105, "created_at": 105, "lang": 105, "tweet_batch_filenam": 105, "reader": 105, "read_json": 105, "chunksiz": 105, "sublist": 105, "tolist": [105, 113], "ignore_index": 105, "to_datetim": 105, "feather": 105, "to_feath": 105, "stored_tweet": 105, "filename_tweet": 105, "url_tweet": 105, "8p52x": 105, "read_feath": 105, "total_tweetcount": 105, "set_xticklabel": [105, 119, 120], "get_xticklabel": [105, 119], "set_yscal": 105, "copdat": 105, "value_count": 105, "target_url": 105, "gist": 105, "carlopir": 105, "1262033": 105, "c52ef0f7ce4f58108619508308372edd8d0bd518": 105, "gistfile1": 105, "exec": 105, "urlopen": 105, "lang_code_dict": 105, "iso_639_choic": 105, "language_cod": 105, "max_row": 105, "hypocrit": 105, "ideolog": 105, "appeal": [105, 114], "operation": 105, "selected_word": 105, "greenwash": 105, "wash": 105, "blah": 105, "greta": 105, "thurnberg": 105, "speech": 105, "sept": 105, "selectwords_detector": 105, "detector": 105, "wordlist": 105, "select_talk": 105, "ignorecas": 105, "flag": 105, "selected_tweet": 105, "isnul": [105, 119], "selected_tweet_count": 105, "selected_tweet_fract": 105, "randomli": [105, 110, 111, 119], "selected_words_2": 105, "selectwords_detector_2": 105, "select_talk_2": 105, "selected_tweets_2": 105, "selected_tweet_counts_2": 105, "selected_tweet_fraction_2": 105, "connot": 105, "g7": 105, "caren": 105, "neal": 105, "score": [105, 118, 119, 120], "english": 105, "477": 105, "filename_afinn_wl": 105, "111": 105, "url_afinn_wl": 105, "fnielsen": 105, "master": [105, 114], "afinn_wl_df": 105, "sepeat": 105, "808": 105, "random_st": [105, 119], "sort_index": 105, "finn": 105, "focuss": 105, "smalldf": 105, "afinn_scor": 105, "1hr": 105, "afinn_adjust": 105, "word_count": 105, "text_str": 105, "bori": 105, "davo": 105, "sel_word": 105, "sel_nam": 105, "probabilti": 105, "histogram": [105, 108, 112, 113, 115, 119, 120], "icecream": 105, "34823": 105, "5937": 105, "79345": 105, "jargon": 105, "vectyp": 105, "doc_data": 105, "ngram_rang": 105, "remove_word": 105, "min_doc_freq": 105, "vectorized_data_dict": 105, "vectorizer_typ": 105, "stop_word": 105, "min_df": 105, "vectorized_doc_list": 105, "fit_transform": 105, "todens": 105, "feature_nam": [105, 120], "get_feature_names_out": 105, "get_feature_nam": 105, "scikit": [105, 118, 119], "wdf": 105, "plot_wordcloud_and_freqdist": 105, "title_str": 105, "pixel_s": 105, "ogrid": 105, "wc": 105, "background_color": 105, "rgba": 105, "max_word": 105, "relative_sc": 105, "wordfreq": 105, "num_show": 105, "sorted_id": 105, "argsort": 105, "ax_wc": 105, "generate_from_frequ": 105, "semant": 105, "je": 105, "rt": 105, "limacop20": 105, "un_climatetalk": 105, "climatechang": [105, 117], "ht": 105, "unfccc": 105, "peru": 105, "peruvian": 105, "lima": 105, "altogeth": 105, "futher": 105, "justin": 105, "grimmer": 105, "margaret": 105, "brandon": 105, "stewart": 105, "stone": 105, "knmi": [107, 108, 109, 110, 111], "climexp": 107, "nl": 107, "worldweatherattribut": 107, "friederik": 107, "627": 107, "1146": 107, "annurev": 107, "102016": 107, "060847": 107, "stott": 107, "nikolao": 107, "christidi": 107, "ying": 107, "jean": 107, "vanderlinden": 107, "geert": 107, "oldenborgh": 107, "vautard": 107, "wcc": 107, "380": 107, "oxford": 107, "bibliographi": 107, "1093": 107, "obo": 107, "9780199363445": 107, "0067": 107, "robin": 107, "yoann": 107, "aur\u00e9lien": 107, "ribe": 107, "nonstationari": 107, "oceanographi": 107, "ascmo": 107, "adnan": 107, "badi": 107, "dereczynski": 107, "luca": 107, "pirani": 107, "connor": 107, "p\u00e9an": 107, "berger": 107, "caud": 107, "exacerb": 107, "mora": 107, "camilo": 107, "b\u00e9n\u00e9dict": 107, "dousset": 107, "iain": 107, "caldwel": 107, "farrah": 107, "powel": 107, "rollan": 107, "geronimo": 107, "bielecki": 107, "chelsi": 107, "counsel": 107, "risk": [107, 108, 115, 122], "deadli": 107, "501": 107, "nclimate3322": 107, "treatment": 107, "cole": 107, "stuart": 107, "springer": 107, "4471": 107, "3675": 107, "matthia": [108, 109, 110, 111, 112, 113, 114, 115], "aengenheyst": [108, 109, 110, 111, 112, 113, 114, 115], "joeri": [108, 109, 110, 111, 112, 113, 114, 115], "reinder": [108, 109, 110, 111, 112, 113, 114, 115], "w2d4_climaterespons": [108, 109, 110, 111, 112, 113, 114, 115], "pose": [108, 110, 112], "disaster": 108, "precipitationgermany_1920": [108, 109, 110, 111], "filename_precipitationgermani": [108, 109, 110, 111], "url_precipitationgermani": [108, 109, 110, 111], "xs7h6": [108, 109, 110, 111], "index_col": [108, 109, 110, 111, 112, 114], "1920": 108, "histplot": [108, 110, 112, 113], "kurtosi": [108, 110], "stretch": 108, "geometri": 108, "mean_pr": 108, "var_pr": 108, "std_pr": 108, "get_ylim": [108, 110, 114, 115], "vline": 108, "c3": [108, 110], "normal_data": 108, "unskew": 108, "entail": 108, "accompani": [108, 123], "plote": 108, "x_r100": [108, 110], "drawn": [108, 111], "th": 108, "random_sampl": 108, "pdfi": 108, "lim": 108, "maximu": 108, "hole": [108, 109, 110, 111], "bridg": 109, "withstand": 109, "evacu": 109, "earthquak": 109, "nuclear": 109, "rank": [109, 111, 113], "descend": 109, "103": 109, "precip_df": 109, "rankdata": [109, 111, 113], "ranks_sp": [109, 111, 113], "plu": [109, 118, 120], "set_xscal": [109, 111], "xscale": 109, "trick": 109, "bootstrap": [109, 111, 113], "oneself": 109, "fake": 109, "artifici": [109, 111, 118], "artif": 109, "hot": [109, 115], "noon": 109, "empirical_period": 109, "tru": 109, "ko": 109, "empir": [110, 111, 113, 114, 115], "adequ": 110, "genextrem": [110, 111, 112, 113, 114, 115], "quanitil": 110, "ppf": [110, 111, 113, 114, 115], "x_r1": 110, "set_aspect": 110, "wors": [110, 114, 120], "concur": 110, "underestim": 110, "symmetr": 110, "thinner": 110, "thicker": [110, 112], "guess": 110, "algorithm": [110, 111, 113, 119], "incorrect": [110, 118], "x_r80": 110, "exepect": 110, "held": [110, 119], "range_loc": 110, "colors_loc": 110, "loci": [110, 113], "range_scal": 110, "colors_scal": 110, "scalei": [110, 113], "range_shap": 110, "colors_shap": 110, "shapei": [110, 113], "overlaid": [110, 120], "cdf": 111, "rarer": 111, "80mm": 111, "estimate_return_level": [111, 114], "empirical_return_level": [111, 113], "negtiv": 111, "quantitiv": 111, "dc": [112, 114], "exception": 112, "safeti": 112, "gev": [112, 113, 114, 115], "washingtondcssh1930": [112, 114], "filename_washingtondcssh1": [112, 114], "url_washingtondcssh1": [112, 114], "4zynp": [112, 114], "ssh": [112, 114], "regardless": 112, "heavili": 112, "1931": 112, "1961": 112, "data_period1": [112, 113], "data_period2": [112, 113], "data_period3": [112, 113], "kde": [112, 113], "periods_stat": [112, 113], "info": 112, "stationari": [112, 114, 115], "params_period1": [112, 113], "shape_period1": [112, 113], "loc_period1": [112, 113], "scale_period1": [112, 113], "params_period2": [112, 113], "shape_period2": [112, 113], "loc_period2": [112, 113], "scale_period2": [112, 113], "params_period3": [112, 113], "shape_period3": [112, 113], "loc_period3": [112, 113], "scale_period3": [112, 113], "dsitribut": 112, "worldwid": 113, "1851": 113, "certainti": 113, "plausibl": 113, "descipt": 113, "ambiti": 113, "ndc": 113, "mildli": 113, "pessimist": 113, "fuell": 113, "estimate_return_level_period": [113, 114, 115], "fit_return_level": [113, 114, 115], "n_boot": [113, 114, 115], "period_emp": 113, "datai": 113, "leve": 113, "quant": 113, "3f": 113, "tupl": [113, 120], "plot_return_level": [113, 114, 115], "obj": 113, "gca": 113, "_label": 113, "mec": 113, "semilogx": 113, "cmip6_data_city_daily_scenarios_tasmax_pr_model": 113, "filename_cmip6_data": 113, "url_cmip6_data": 113, "ngafk": 113, "tasmax": 113, "madrid": 113, "data_c": 113, "diverg": 113, "constrained_layout": [113, 114, 115], "add_legend": 113, "maxima": 113, "pr_citi": 113, "pr_city_max": 113, "1925": 113, "1954": 113, "to_datafram": 113, "1955": 113, "1984": 113, "gev_funct": [113, 114, 115], "fit_period1": 113, "fit_period2": 113, "fit_period3": 113, "2071": [113, 115], "miroc6": 113, "data_city_fut": 113, "data_hist": 113, "data_ssp126": 113, "data_ssp245": 113, "data_ssp585": 113, "ef": [113, 114, 115], "plot_levels_from_obj": 113, "line_kw": 113, "245": [113, 115], "585": [113, 115], "shape_hist": [113, 115], "loc_hist": [113, 115], "scale_hist": [113, 115], "shape_ssp126": 113, "loc_ssp126": 113, "scale_ssp126": 113, "shape_ssp245": 113, "loc_ssp245": 113, "scale_ssp245": 113, "shape_ssp585": 113, "loc_ssp585": 113, "scale_ssp585": 113, "fit_hist": 113, "fit_ssp126": 113, "fit_ssp245": 113, "fit_ssp585": 113, "hamburg": [113, 115], "commonwealth": 113, "australian": 113, "climateextrem": 113, "eigen": 114, "sdfc": [114, 115], "texttabl": 114, "yrobink": [114, 115], "subdirectori": 114, "njleach": 114, "mystatsfunct": [114, 115], "extremes_funct": [114, 115], "sd": [114, 115], "nheight": 114, "get_xlim": [114, 115, 119], "kdeplot": [114, 115], "simplest": 114, "c_loc": [114, 115], "law_n": 114, "print_law": 114, "sequenti": 114, "c_scale": 114, "c_shape": 114, "unabl": 114, "aic": [114, 115], "akaik": 114, "compute_a": [114, 115], "coef_": [114, 115, 118], "info_": [114, 115], "mle_optim_result": [114, 115], "law_stat": 114, "law_ns_scal": 114, "law_ns_shap": 114, "law_ns_loc_scal": 114, "accommod": 114, "bodi": 115, "physiolog": 115, "sweat": 115, "skin": 115, "hotter": 115, "hamper": 115, "bulb": 115, "ambient": 115, "cmo": 115, "ols": 115, "lmoment": 115, "nc_time_axi": 115, "wbgt_day_mpi": 115, "hr_historical_r1i1p1f1_raw_runmean7_yearmax": 115, "filename_wbgt_dai": 115, "url_wbgt_dai": 115, "69ms8": 115, "wetbulb_hist": 115, "wbgt": 115, "leap": 115, "undesir": 115, "belong": [115, 118], "thoroughli": 115, "failur": [115, 118], "hr_ssp126_r1i1p1f1_raw_runmean7_yearmax": 115, "filename_ssp126": 115, "url_ssp126": 115, "67b8m": 115, "wetbulb_126": 115, "hr_ssp245_r1i1p1f1_raw_runmean7_yearmax": 115, "filename_ssp245": 115, "url_ssp245": 115, "fsx5y": 115, "wetbulb_245": 115, "hr_ssp585_r1i1p1f1_raw_runmean7_yearmax": 115, "filename_ssp585": 115, "url_ssp585": 115, "pr456": 115, "wetbulb_585": 115, "diff": 115, "wetbulb_hist_delhi": 115, "wetbulb_126_delhi": 115, "wetbulb_245_delhi": 115, "wetbulb_585_delhi": 115, "return_levels_hist": 115, "histtyp": 115, "shape_245": 115, "loc_245": 115, "scale_245": 115, "2070": 115, "return_levels_245": 115, "2051": 115, "return_levels_126": 115, "return_levels_585": 115, "return_levels_126_2015_2050": 115, "return_levels_245_2015_2050": 115, "return_levels_585_2015_2050": 115, "hline": 115, "choosen": 115, "estimate_return_level_model": 115, "law_ns_hist": 115, "law_ns_126": 115, "law_ns_245": 115, "law_ns_585": 115, "law_ss_hist": 115, "law_ss_126": 115, "law_ss_245": 115, "law_ss_585": 115, "precomput": 115, "rerun": 115, "fit_sp_hist": 115, "fit_return_levels_sdfc_2d": 115, "periods_per_year": 115, "fit_sp_126": 115, "fit_sp_245": 115, "fit_sp_585": 115, "wbgt_hist_raw_runmean7_gev": 115, "fname_wbgt_hist": 115, "url_wbgt_hist": 115, "dakv3": 115, "wbgt_126_raw_runmean7_gev_2071": 115, "fname_wbgt_126": 115, "url_wbgt_126": 115, "ef9pv": 115, "wbgt_245_raw_runmean7_gev_2071": 115, "fname_wbgt_245": 115, "url_wbgt_245": 115, "j4hfc": 115, "wbgt_585_raw_runmean7_gev_2071": 115, "fname_bgt_58": 115, "url_bgt_585": 115, "y6edw": 115, "area_mpi": 115, "filename_area_mpi": 115, "url_area_mpi": 115, "zqd86": 115, "area_land_mpi": 115, "url_area_land_mpi": 115, "dxq98": 115, "area_land": 115, "russia": 115, "amp": 115, "add_colorbar": 115, "cbar": 115, "2091": 115, "die": 115, "surpass": 115, "aor": 115, "ai": [117, 121], "deeplearn": 117, "deepak": [118, 119, 120, 121], "mewada": [118, 119, 120, 121], "xiaomei": 118, "cautiou": 118, "dengu": 118, "fever": 118, "neural": 118, "ann": 118, "linear_model": [118, 119, 120], "linearregress": [118, 119], "mport": 118, "logisticregress": [118, 120], "confusion_matrix": 118, "regressor": 118, "flight": 118, "straight": 118, "x_1": 118, "x_2": 118, "epsilon": 118, "data_point": 118, "twice": 118, "alia": 118, "x1": 118, "x2": 118, "popular": 118, "y_func": 118, "datapoint": 118, "scalar": 118, "reg_model": [118, 119], "conform": 118, "hasn": 118, "x_1_test1": 118, "x_2_test1": 118, "regressors_test1": 118, "preds_test1": 118, "y_test1": 118, "x_1_test2": 118, "x_2_test2": 118, "regressors_test2": 118, "preds_test2": 118, "y_test2": 118, "claim": 118, "congratul": 118, "classifi": [118, 120], "relationsip": 118, "unexplain": 118, "labeld": 118, "integ": [118, 120], "visualis": [118, 119], "logreg_model": 118, "xx": 118, "yy": 118, "intercept_": 118, "pred": 118, "perfrom": 118, "dummi": 119, "poisson": 119, "glm": 119, "mean_absolute_error": 119, "mean_squared_error": 119, "randomforestregressor": 119, "permutation_import": [119, 120], "poissonregressor": 119, "w2d5_climaterespons": [119, 120], "adaptationimpact": [119, 120], "drivendata": 119, "dengue_features_train": 119, "filename_dengu": 119, "url_dengu": 119, "wm9un": 119, "df_featur": 119, "outlier": 119, "inconsist": 119, "subsect": 119, "dengue_labels_train": 119, "df_dengu": 119, "filename_dengue_label": 119, "url_dengue_label": 119, "6nw9x": 119, "df_label": 119, "total_cas": 119, "weekofyear": 119, "week_start_d": 119, "df_clean": 119, "safest": 119, "1456": 119, "1199": 119, "mislead": [119, 120], "145": 119, "df_cleaned_train": 119, "df_cleaned_test": 119, "cases_train": 119, "cases_test": 119, "cluster": 119, "mae": 119, "mse": 119, "y_pred": 119, "rmse": 119, "y_i": 119, "hat": 119, "_i": 119, "chose": 119, "arbitrarili": 119, "df_cleaned_c": 119, "get_dummi": 119, "drop_first": 119, "df_cleaned_combin": 119, "df_cleaned_city_train": 119, "df_cleaned_city_test": 119, "cases_city_train": 119, "cases_city_test": 119, "reg_model_c": 119, "y_pred_citi": 119, "poisson_reg": 119, "recurs": 119, "outbreak": 119, "hyperparamet": 119, "rf": 119, "attributeerror": 119, "overfit": 119, "permut": 119, "shuffl": [119, 120], "kit": 119, "plot_feature_import": 119, "perm_feat_imp": [119, 120], "readabl": 119, "navi": [119, 120], "errorbar": 119, "importances_mean": [119, 120], "importances_std": [119, 120], "fmt": [119, 120], "capsiz": 119, "n_repeat": 119, "empow": 119, "unlock": 119, "unravel": 119, "suspect": 119, "chart": 119, "feature_importances_": 119, "permuat": 119, "learner": 119, "n_estim": 119, "max_depth": 119, "min_samples_leaf": 119, "plot_tre": 119, "michael": 120, "rizzo": 120, "skm": 120, "neural_network": 120, "mlpclassifi": 120, "convergencewarn": 120, "plot_feature_perform": 120, "missing_feature_perform": 120, "only_feature_perform": 120, "wspace": 120, "plot_permutation_feature_import": 120, "x_test": 120, "yerr": 120, "togoles": 120, "republ": 120, "repo": 120, "1290": 120, "306": 120, "sentintel": 120, "filename_togo_crops_train": 120, "url_togo_crops_train": 120, "7m8cz": 120, "training_d": 120, "filename_togo_crops_test": 120, "url_togo_crops_test": 120, "7r6cp": 120, "test_d": 120, "x_train": 120, "y_train": 120, "y_test": 120, "pos_ind": 120, "neg_ind": 120, "heatmap": 120, "corrcoef": 120, "rowvar": 120, "xticklabel": 120, "yticklabel": 120, "12x12": 120, "bwr": 120, "togo": 120, "evaluate_model": 120, "trained_model": 120, "train_accuraci": 120, "test_accuraci": 120, "train_acc": 120, "test_acc": 120, "precision_scor": 120, "recall_scor": 120, "evaluate_model_perform": 120, "su": 120, "test_recal": 120, "test_precis": 120, "pred_test": 120, "catch": [120, 122], "calculate_perform": 120, "x_train_reduc": 120, "x_test_reduc": 120, "reduced_trained_model": 120, "reshap": 120, "alon": 120, "brain": 120, "neuron": 120, "scitkit": 120, "mlp": 120, "perceptron": 120, "memor": 120, "hidden_layer_s": 120, "mlp_perform": 120, "plot_mlp_perform": 120, "hidden_unit": 120, "crimson": 120, "labels": 120, "set_vis": 120, "layout": 120, "n_train": 120, "n_test": 120, "epoch": 120, "max_it": 120, "plot_training_perform": 120, "train_perf": 120, "test_perf": 120, "max_test_acc": 120, "max_test_epoch": 120, "train_epoch": 120, "start_epoch": 120, "end_epoch": 120, "n_sampl": 120, "n_featur": 120, "buid": 120, "out2": 122, "curat": [122, 123], "asynchron": [122, 123], "pythia": [122, 123], "calculu": 122, "equit": 122, "taught": 122, "fantast": 123, "5min": 123, "fabul": 123, "sumar": 123, "lesson": 123, "preambl": 123, "quickstart": 123, "jupyterlab": 123, "breakdown": 123, "mandatori": 123, "virtual": 123, "ampl": 123, "liter": 123, "hit": 123, "rocket": 123, "panic": 123, "python_precours": 123, "onu": 123, "clarif": 123, "classroom": 123, "carpentri": 123, "edx": 123, "handbook": 123, "cheatsheet": 123, "od": 123, "khan": 123, "matric": 123, "w0d3": 123, "beauti": 123, "phet": 123, "gilbert": 123, "strang": 123, "jiri": 123, "lebl": 123, "newton": 123, "circular": 123, "kinemat": 123, "dave": 123, "domelen": 123, "encyclopedia": 123, "britannica": 123, "uron": 123, "hinrich": 123, "dirk": 123, "atom": 123, "bond": 123, "theopold": 123, "langlei": 123, "andrea": 123, "schmitner": 123, "0x144625ab0": [], "0x1471e42e0": [], "0x147227070": [], "0x1473774c0": [], "0x15aced6f0": [], "0x15b0b7e20": [], "0x15b122d40": [], "0x15b273100": [], "0x137dc1cc0": [], "0x143fe0490": [], "0x144023280": [], "0x1441736a0": [], "0x12fb85a20": [], "0x1397a0250": [], "0x1397e2fe0": [], "0x139ad3fd0": [], "0x1615118d0": [], "0x161c604c0": [], "0x161ca3100": [], "0x161def5b0": [], "ipywidgetsimport": [], "syntaxerror": [], "0x144e75c30": [], "0x145ca0670": [], "0x145ce3160": [], "0x145e33610": [], "ipykernel": [], "traitlet": [], "widgetsnbextens": [], "appnop": [], "comm": [], "debugpi": [], "asyncio": [], "psutil": [], "pyzmq": [], "tornado": [], "backcal": [], "decor": [], "jedi": [], "pickleshar": [], "pygment": [], "pexpect": [], "parso": [], "dateutil": [], "platformdir": [], "ptyprocess": [], "wcwidth": [], "asttoken": [], "eval": [], "0x15cd659f0": [], "0x15db601f0": [], "0x15dba3010": [], "0x169c133d0": [], "0x168a75450": [], "0x16c5aba90": [], "0x16c6169e0": [], "0x16c8d6e60": [], "0x168cc1ba0": [], "0x169a60490": [], "0x169aa34c0": [], "0x16bb97580": [], "0x1666cd6c0": [], "0x167c77e50": [], "0x167ce6da0": [], "0x167fa70d0": [], "0x15a9ddde0": [], "0x15af60640": [], "0x15afcffd0": [], "0x15c40f7c0": [], "91466636": [], "18007387": [], "0590537": [], "53160504": [], "78027523": [], "03235929": [], "38085328": [], "64905075": [], "18710333": [], "2169815": [], "60529559": [], "18074677": [], "36784645": [], "69148091": [], "70944316": [], "68337247": [], "55151557": [], "86844881": [], "61908239": [], "82345506": [], "31503901": [], "09609158": [], "61285436": [], "54992946": [], "92005945": [], "17299915": [], "73471484": [], "96643112": [], "62959993": [], "14795937": [], "64041": [], "01246755": [], "61075074": [], "2372876": [], "60971772": [], "49144112": [], "39628697": [], "16613113": [], "14608454": [], "90882278": [], "02899621": [], "11776595": [], "6304067": [], "29459723": [], "45345677": [], "3983804": [], "36615432": [], "42585538": [], "42404159": [], "71110779": [], "55993543": [], "50206512": [], "6278577": [], "81049848": [], "59557918": [], "93098175": [], "81652518": [], "95438841": [], "73844728": [], "1621533": [], "4281": [], "76466636": [], "03007387": [], "9090537": [], "38160504": [], "63027523": [], "88235929": [], "23085328": [], "49905075": [], "03710333": [], "0669815": [], "45529559": [], "03074677": [], "21784645": [], "54148091": [], "55944316": [], "53337247": [], "40151557": [], "71844881": [], "46908239": [], "67345506": [], "16503901": [], "94609158": [], "46285436": [], "39992946": [], "77005945": [], "02299915": [], "58471484": [], "81643112": [], "47959993": [], "99795937": [], "49041": [], "86246755": [], "46075074": [], "0872876": [], "45971772": [], "34144112": [], "24628697": [], "01613113": [], "99608454": [], "75882278": [], "87899621": [], "96776595": [], "4804067": [], "14459723": [], "30345677": [], "2483804": [], "21615432": [], "27585538": [], "27404159": [], "56110779": [], "40993543": [], "35206512": [], "4778577": [], "66049848": [], "44557918": [], "78098175": [], "66652518": [], "80438841": [], "58844728": [], "0121533": [], "765": [], "909": [], "882": [], "781": [], "667": [], "588": [], "01arrai": [], "54536268": [], "39701751": [], "36936852": [], "50173717": [], "26391872": [], "20376085": [], "43888527": [], "18345267": [], "02605164": [], "41187609": [], "2037249": [], "18890202": [], "82261136": [], "88057448": [], "58110636": [], "14798266": [], "15225754": [], "80019926": [], "62955837": [], "95436029": [], "39714248": [], "49886283": [], "52502615": [], "35144574": [], "04638844": [], "48653325": [], "22126752": [], "13248905": [], "44184862": [], "80709523": [], "16896438": [], "92290882": [], "22746037": [], "36730486": [], "51035482": [], "22971723": [], "21830451": [], "78334324": [], "59806461": [], "11404537": [], "57305189": [], "65102702": [], "19586295": [], "61501175": [], "84795728": [], "76390543": [], "36310361": [], "88652467": [], "27482032": [], "56253823": [], "32892436": [], "02330223": [], "46636817": [], "1014": [], "97667473": [], "17017038": [], "49026108": [], "44671705": [], "85106431": [], "26981051": [], "24206106": [], "4999": [], "001e": [], "003e": [], "004e": [], "2xarrai": [], "float64281": [], "float64999": [], "float64278": [], "09392357": [], "71861287": [], "80765942": [], "93758977": [], "97058462": [], "77463804": [], "50037639": [], "98951251": [], "49777526": [], "69576082": [], "24390186": [], "87446248": [], "70464481": [], "19958196": [], "98561918": [], "26182092": [], "07526107": [], "79592759": [], "70732976": [], "51686617": [], "57233674": [], "56862497": [], "58422462": [], "51305543": [], "45517737": [], "58054743": [], "54890848": [], "33003456": [], "08050615": [], "03353451": [], "88554798": [], "08174168": [], "27919761": [], "8272645": [], "02691919": [], "4828863": [], "77589952": [], "70750934": [], "44721123": [], "79130546": [], "3797411": [], "65541536": [], "17416683": [], "73035929": [], "89855963": [], "25493312": [], "32287629": [], "45528841": [], "47855033": [], "17373917": [], "71170468": [], "80781312": [], "68923316": [], "38280424": [], "62754531": [], "77883223": [], "30222731": [], "34831913": [], "23261553": [], "1660333": [], "float64996": [], "71168706": [], "70518464": [], "82286126": [], "95467031": [], "29166493": [], "27025363": [], "54340146": [], "92196518": [], "32317965": [], "01588204": [], "62535804": [], "19816547": [], "40781836": [], "87538854": [], "76045874": [], "64113989": [], "93917351": [], "82770779": [], "91251531": [], "6750524": [], "48932396": [], "54845716": [], "68972092": [], "46527313": [], "58561881": [], "98813969": [], "46118028": [], "95699868": [], "93034192": [], "77486771": [], "29022858": [], "46522842": [], "6798075": [], "30735555": [], "11956561": [], "18377475": [], "11972201": [], "91609023": [], "02464287": [], "13910218": [], "71786214": [], "05632154": [], "57888041": [], "83299831": [], "49540441": [], "71221245": [], "46012855": [], "79440315": [], "66137463": [], "90897445": [], "63611034": [], "47015049": [], "90973518": [], "33845529": [], "46717935": [], "37394002": [], "34970345": [], "72912236": [], "95804547": [], "46342772": [], "4275": [], "4284": [], "32362469": [], "11576096": [], "04527742": [], "58649679": [], "20941147": [], "5289": [], "2278": [], "9arrai": [], "0x13bcfb0a0": [], "0x13bf6b670": [], "0x13bac8280": [], "0x1431e92d0": [], "0x12f45e170": [], "0x12f9e08e0": [], "0x12fa27820": [], "0x12fb73b50": [], "0x15226dc60": [], "0x1523b4640": [], "0x152435a20": [], "0x152487ee0": [], "0x137705de0": [], "0x13789e110": [], "0x1613581c0": [], "0x1616345e0": [], "0x161783a60": [], "0x16187ba90": [], "0x159d82980": [], "0x15f151210": [], "0x15f8239d0": [], "0x15ca4de70": [], "0x13e50e050": [], "0x14fdb87c0": [], "0x14fdfb5e0": [], "0x14ff4ba30": [], "0x150d215d0": [], "0x15476ffa0": [], "0x1547dab90": [], "0x1549e2fe0": [], "0x13ee354b0": [], "0x13fe9bf10": [], "0x13ff069e0": [], "0x14cc66ec0": [], "0x134cc1c60": [], "0x1364ac520": [], "0x1364ef2b0": [], "0x1367b3640": [], "04559761": [], "74429697": [], "98421753": [], "11051157": [], "59429598": [], "5282": [], "6arrai": [], "0x1492d1630": [], "0x14ac53f10": [], "0x14acc2c80": [], "0x14af83040": [], "79157613": 43, "28025839": 43, "06486385": 43, "16980748": 43, "24394557": 43, "5277": 43, "0x1469bdfc0": [], "0x15189c6a0": [], "0x1518e35e0": [], "0x151ba39a0": []}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"project": [0, 2, 3, 9, 10, 11, 12, 13, 14, 15, 28, 33, 35, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 94, 97, 99, 119], "climatematch": 1, "impact": [1, 4, 7, 9, 64, 70, 116, 121], "scholar": 1, "program": [1, 123], "elig": 1, "applic": [1, 121], "process": [1, 21, 56, 113], "1": [1, 3, 9, 12, 20, 23, 24, 28, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 54, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "express": 1, "interest": [1, 57], "2": [1, 3, 9, 11, 12, 15, 21, 28, 42, 43, 44, 45, 46, 48, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 101, 102, 103, 105, 109, 113, 115, 118, 119, 120, 121], "deadlin": 1, "3": [1, 3, 9, 22, 28, 42, 43, 44, 48, 50, 56, 57, 58, 59, 61, 64, 65, 66, 70, 71, 74, 75, 76, 78, 79, 81, 86, 87, 88, 89, 91, 94, 96, 102, 103, 104, 105, 110, 113, 118, 119, 120, 121], "decis": [1, 119], "what": [1, 7, 57, 64, 109], "involv": 1, "materi": [2, 3, 123], "daili": [3, 12, 28], "guid": 3, "summari": [3, 7, 17, 23, 27, 39, 42, 43, 44, 45, 46, 47, 48, 49, 50, 53, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "submiss": 3, "link": [3, 33], "teach": 3, "assist": 3, "time": [3, 42, 56, 67, 71, 78, 82, 87, 89, 95, 103, 108, 115], "pod": 3, "introduct": [3, 8, 56, 64, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 91, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122], "w1d1": 3, "session": 3, "4": [3, 23, 28, 43, 45, 48, 56, 59, 64, 66, 67, 71, 77, 88, 97, 101, 102, 103, 105, 111, 113, 118, 119, 120, 121], "5": [3, 24, 27, 28, 43, 46, 60, 64, 68, 71, 78, 89, 96, 98, 105, 112, 119], "6": [3, 12, 25, 47, 61, 64, 69, 79, 90, 99, 113], "dai": [3, 17, 28, 39, 53, 64], "w2d2": 3, "7": [3, 26, 48, 70, 80, 91, 114], "8": [3, 27, 49, 71, 81, 115], "9": [3, 50, 82], "content": [3, 61, 123], "w2d5": [3, 28], "final": [3, 28], "present": [3, 14], "schedul": [3, 28, 29], "logist": [3, 118, 120], "question": [3, 8, 20, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 67, 68, 69, 70, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 115, 118, 119, 120], "profession": [4, 28], "develop": [4, 28], "why": [4, 96, 105], "talk": [4, 7], "mentor": [4, 8], "meet": [4, 8], "career": [4, 5, 6], "featur": [4, 5, 7, 119, 120], "panel": [4, 6], "confirm": 6, "panelist": 6, "08": 6, "00": 6, "09": 6, "utc": 6, "20": 6, "30": [6, 8], "21": 6, "guidanc": 7, "discuss": 7, "climat": [7, 12, 15, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 54, 56, 57, 65, 67, 69, 70, 71, 75, 76, 77, 78, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 90, 91, 92, 94, 95, 96, 97, 98, 99, 100, 105, 106, 113, 116, 119, 122, 123], "justic": 7, "about": [7, 20, 57], "speaker": [7, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "video": [7, 40, 54, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121, 122], "jos\u00e9": 7, "daniel": 7, "rodr\u00edguez": 7, "or\u00fa": 7, "prompt": 7, "equiti": [7, 21, 25, 26, 27], "scienc": [7, 27, 121, 122, 123], "interview": 7, "highlight": 7, "juliana": 7, "arbel\u00e1ez": 7, "open": [7, 44, 56, 91], "lubia": 7, "vinha": 7, "psycholog": 7, "crisi": 7, "commun": [7, 27, 91], "clare": 7, "kelli": 7, "suggest": [8, 52, 63, 73, 84, 93, 107, 117], "structur": 8, "60": 8, "minut": 8, "10": 8, "s": [8, 64, 85, 90, 102], "journei": 8, "lesson": 8, "answer": 8, "network": [8, 120], "collabor": [8, 35, 36], "get": [8, 70, 74, 89], "most": 8, "out": 8, "your": [8, 9, 20, 22, 27], "The": [9, 42, 85, 87, 91, 122], "enso": [9, 56, 69, 70], "precipit": [9, 10, 12, 67, 68, 70, 71, 108, 110], "temperatur": [9, 10, 47, 57, 60, 64, 76, 81, 82, 86, 88, 95], "templat": [9, 10, 11, 12, 13, 14, 15], "data": [9, 10, 11, 12, 13, 14, 15, 22, 42, 44, 46, 48, 49, 56, 57, 59, 64, 65, 66, 67, 68, 70, 71, 75, 78, 79, 81, 89, 90, 91, 94, 95, 96, 97, 99, 105, 110, 113, 114, 115, 118, 119, 120, 121], "explor": [9, 10, 11, 12, 13, 14, 15, 57, 59, 65, 77, 102, 114, 119, 120, 121], "notebook": [9, 10, 11, 12, 13, 14, 15, 36], "setup": [9, 10, 11, 12, 13, 14, 15, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "dataset": [9, 13, 14, 15, 42, 44, 57, 78, 91, 118, 119, 120, 121], "load": [9, 59, 75, 76, 78, 81, 82, 94, 95, 96, 97, 99, 105, 113, 115, 119, 120], "cmip6": [9, 10, 14, 91, 94, 95, 96, 97, 99, 113], "model": [9, 81, 83, 85, 87, 89, 90, 91, 94, 96, 97, 98, 99, 101, 102, 103, 105, 118, 119, 120], "choic": 9, "observ": [9, 13, 71], "ocean": [9, 11, 51, 54, 56, 59, 61, 62, 64, 69, 70, 75], "nino": 9, "index": [9, 12, 56, 69, 70], "further": [9, 10, 11, 12, 13, 14, 15, 26, 52, 63, 73, 84, 93, 101, 107, 117, 120], "read": [9, 10, 11, 12, 13, 14, 15, 26, 52, 58, 63, 66, 71, 73, 84, 93, 101, 107, 117], "resourc": [9, 10, 11, 13, 14, 25, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 119, 120, 121], "heatwav": 10, "assess": [10, 42, 75, 80, 103], "dynam": 10, "interact": [10, 56, 68, 69, 85], "atmospher": [10, 11, 14, 51, 56, 58, 59, 62, 64, 77], "land": [10, 12, 14, 62, 64], "Near": 10, "surfac": [10, 11, 12, 13, 14, 57, 58, 59, 60, 64, 91, 95], "soil": 10, "moistur": 10, "option": 10, "world": [10, 40, 102], "bank": 10, "cereal": [10, 12], "product": [10, 12, 71, 82, 102], "under": 10, "hint": 10, "q7": 10, "detect": 10, "q9": 10, "correl": [10, 70, 120], "q12": 10, "linear": [10, 60, 118, 123], "regress": [10, 118, 119, 120], "q13": 10, "driven": [10, 59], "approach": [10, 14], "acidif": 11, "noaa": [11, 12, 64, 65, 66], "ph": 11, "acid": 11, "global": [11, 12, 14, 15, 42, 59, 66, 68, 95, 99], "indic": [11, 12], "from": [11, 14, 60, 66, 68, 87, 88, 90, 95, 96, 97, 99], "1750": 11, "2100": 11, "ncei": 11, "access": [11, 36, 42, 57, 66, 67], "0259391": 11, "copernicu": 11, "ecmwf": 11, "composit": 11, "reanalysi": [11, 51, 57, 59, 82], "carbon": [11, 14, 101], "dioxid": 11, "co": [11, 77], "sub": [11, 77, 102], "region": [12, 56, 57, 102], "variabl": [12, 14, 42, 57, 69, 70, 75, 98, 101, 106, 119], "extrem": [12, 106, 109, 110, 113], "event": [12, 56, 109], "chirp": 12, "version": 12, "0": 12, "25": 12, "fundament": 12, "record": [12, 65, 76, 108, 112], "fcdr": 12, "avhrr": 12, "bundl": 12, "reflect": [12, 119, 120], "normal": [12, 110, 111], "differ": [12, 57, 64, 71, 94, 103, 113, 115, 118, 119], "veget": [12, 15, 64, 66], "altern": [12, 14], "ndvi": [12, 15, 66], "sourc": [12, 99], "modi": 12, "terra": 12, "mod13c2": 12, "l3": 12, "05": 12, "cmg": 12, "worldbank": 12, "sea": [13, 64, 95], "level": [13, 48, 103, 109, 111, 115], "rise": 13, "ecco": 13, "height": 13, "ssh": 13, "tidal": 13, "gaug": 13, "chang": [14, 61, 65, 75, 76, 77, 86, 87, 88, 113], "cover": 14, "albedo": [14, 86, 88], "sequestr": 14, "obtain": [14, 67], "satellit": [14, 15, 64, 65, 66, 71], "glass": 14, "era5": [14, 57], "monthli": [14, 58, 67, 68, 71], "averag": [14, 48, 95], "1950": 14, "To": 14, "calcul": [14, 56, 60, 67, 68, 69, 109], "us": [14, 15, 31, 32, 34, 35, 36, 42, 49, 50, 57, 64, 66, 67, 68, 75, 89, 90, 95, 99, 111, 120], "monitor": [15, 65, 66, 69], "map": [15, 57, 59, 66, 74, 82, 94, 102, 122], "wildfir": 15, "inform": 15, "system": [15, 38, 57, 65, 91, 94, 96, 102], "action": 15, "larg": [15, 69], "sentinel": 15, "health": [15, 64], "burnt": 15, "area": 15, "specif": [15, 50, 67], "function": [15, 48, 74, 90, 96, 97, 98, 99, 102, 103, 113, 114, 120], "vci": 15, "drought": 15, "threshold": [15, 115], "nbr": 15, "dnbr": 15, "code": [15, 24, 43, 58, 66, 67, 68, 69, 70, 71, 76, 78, 80, 85, 86, 87, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 118, 119, 120], "good": 16, "research": 16, "practic": 16, "intro": [18, 40, 54], "overview": [18, 28, 38, 40, 54, 75], "outro": [19, 41, 55], "tutori": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "find": [20, 65, 88, 91, 111, 121], "phenomenon": 20, "ask": 20, "It": 20, "object": [20, 21, 22, 23, 24, 25, 26, 27, 42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "demo": [20, 56, 68, 69, 85], "activ": [20, 21, 22, 23, 25, 26, 27, 102], "own": 20, "make": [20, 23, 25, 42, 57, 75], "sure": [20, 23], "avoid": [20, 23], "pitfal": [20, 23], "do": 21, "literatur": 21, "review": 21, "understand": [21, 23, 67, 80], "tip": 21, "effici": 21, "identifi": [22, 56, 121], "basic": 22, "ingredi": 22, "choos": 22, "formul": 23, "hypothesi": 23, "next": 23, "step": [23, 35], "draft": 24, "analysi": [24, 25, 46, 68, 70, 78, 79, 105, 110, 115], "exercis": [24, 43, 58, 66, 67, 68, 69, 70, 71, 76, 78, 80, 85, 86, 87, 89, 90, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 118, 119, 120], "implement": [25, 119], "figur": [25, 66, 67, 68, 69, 70, 71, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "through": [25, 26, 67], "lens": 25, "interpret": [26, 99], "result": [26, 102, 118, 119], "quantifi": [26, 71, 97], "uncertainti": [26, 97], "len": 26, "conclus": 27, "publish": 27, "gener": [28, 42, 118], "2023": 28, "cours": [28, 36], "run": [28, 89, 103], "juli": 28, "17": 28, "28": 28, "timezon": 28, "curriculum": 28, "share": [30, 42], "calendar": 30, "discord": 31, "jupyterbook": 32, "quick": 33, "polici": 33, "coursework": 33, "attend": 33, "googl": 34, "colab": 34, "advic": 34, "jupyterhub": 35, "TO": 35, "ON": 35, "kaggl": 36, "first": [36, 42], "enabl": 36, "internet": 36, "kernel": 36, "gpu": 36, "technic": 37, "help": 37, "solut": [40, 88], "warm": [40, 75], "slide": 54, "creat": [42, 94, 101], "dataarrai": 42, "pythia": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "cmip": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "png": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56], "introduc": 42, "section": [42, 43, 44, 45, 46, 47, 48, 49, 50, 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120, 121], "creation": 42, "random": 42, "numpi": [42, 43], "arrai": 42, "wrap": 42, "attempt": 42, "assign": 42, "dimens": 42, "name": [42, 65, 66, 67, 68, 69, 70, 71], "coordin": [42, 43, 50, 57], "space": 42, "initi": [42, 65], "complet": [42, 102], "info": 42, "set": [42, 66, 67, 68, 69, 70, 71, 85, 86, 87, 89, 90, 91, 94, 95, 96, 97, 98, 99, 102, 103, 105, 108, 109, 110, 111, 112, 113, 114, 115, 118, 119, 120], "attribut": 42, "ar": 42, "Not": 42, "preserv": 42, "default": 42, "contain": 42, "pressur": 42, "same": 42, "select": [43, 56, 57], "interpol": [43, 78], "slice": 43, "subset": [43, 44], "valu": [43, 50, 110, 118, 119], "like": 43, "sel": 43, "approxim": 43, "nearest": 43, "neighbor": 43, "sampl": [43, 64, 78], "along": 43, "One": [43, 49, 90], "more": 43, "method": [43, 45, 48, 101, 119, 120], "loc": 43, "plot": [44, 47, 57, 59, 60, 67, 74, 75, 79, 82, 90, 96, 108, 118, 120], "netcdf": 44, "aggreg": [44, 45], "oper": [44, 45], "xarrai": [44, 46, 48, 56, 91, 94, 95, 99], "simpl": [44, 85, 105], "visual": [44, 66, 67, 94, 119, 120], "custom": [44, 50], "2d": 44, "connect": [44, 45, 46, 47, 48, 49, 50, 65, 67, 69, 70, 75, 77, 78, 79, 80, 81, 82, 85, 86, 87, 88, 89, 90, 91, 94, 95, 96, 97, 98, 99, 119], "arithmet": 45, "climatolog": [46, 56, 58, 67, 68], "groupbi": 46, "split": 46, "appli": 46, "combin": [46, 96], "comput": [46, 47, 48, 56, 115, 122, 123], "spatial": [46, 57, 61, 64, 70, 71, 115], "variat": [46, 77], "anomali": [47, 56, 68, 69, 70, 82], "other": [48, 121], "tool": [48, 78, 122, 123], "high": 48, "resampl": 48, "move": [48, 87], "coarsen": 48, "compar": [48, 57, 59, 71, 89, 94, 119, 120], "mask": [49, 50, 66], "condit": [49, 50], "where": [49, 50], "multipl": [50, 57, 88], "fill": 50, "state": [51, 60], "el": [56, 69, 75], "ni\u00f1o": [56, 69, 70, 75], "southern": [56, 69], "oscil": [56, 69, 96], "tropic": [56, 58], "pacif": 56, "dure": 56, "la": 56, "ni\u00f1a": 56, "sst": [56, 69, 94, 95, 96, 99], "smooth": 56, "seri": [56, 67, 71, 75, 82, 95], "A": [57, 85, 86, 87, 102, 105], "lot": 57, "weather": 57, "timeseri": 57, "air": 57, "bonu": [57, 58, 85, 87, 91, 111, 119, 120], "note": [57, 102], "geograph": 57, "thi": 57, "circul": [58, 59, 60], "wind": [58, 59], "annual": [58, 59], "mean": [58, 59, 68, 95], "speed": 58, "zonal": 58, "addit": 58, "extra": [58, 119], "storm": 58, "stress": 59, "current": 59, "thermohalin": 60, "salin": 60, "densiti": [60, 79], "equat": 60, "full": [60, 64], "nonlinear": 60, "heat": 61, "vertic": 61, "distribut": [61, 108, 110, 111], "within": 61, "remot": [62, 64, 120], "sens": [62, 64, 120], "electromagnet": 64, "spectrum": 64, "orbit": 64, "imag": 64, "goe": 64, "west": 64, "left": 64, "east": 64, "right": 64, "disk": 64, "summer": 64, "solitic": 64, "2022": 64, "resolut": 64, "aviri": 64, "over": [64, 103, 108, 115], "lake": 64, "evapor": 64, "pond": 64, "illustr": 64, "radiometr": 64, "resoult": 64, "exampl": 64, "case": [64, 103, 119], "cryospher": 64, "snow": 64, "coverag": 64, "modis_snow": 64, "terrestri": [64, 76], "ecolog": 64, "modis_ndvi": 64, "cloud": [64, 101, 105], "modis_cloud": 64, "rainfal": 64, "modis_sst": 64, "marin": 64, "ecosystem": 64, "chlorophyl": 64, "modis_chl": 64, "mission": 65, "environment": [65, 119], "inter": 65, "calibr": 65, "esa": 65, "nasa": 65, "earth": [65, 85, 91, 94, 96], "cdr": [66, 67], "statu": 66, "aw": [66, 67], "qualiti": 66, "flag": 66, "gpcp": [67, 71], "cartopi": 67, "locat": [67, 74], "examin": 68, "roll": 68, "scale": 69, "oni": 70, "pattern": [70, 71], "With": [71, 118], "In": 71, "situ": 71, "evalu": [71, 119, 120], "acces": 71, "nclimgrid": 71, "station": 71, "base": [71, 81], "grid": 71, "comparison": [71, 81, 95], "paleoclim": [72, 74, 75, 76, 78, 79, 81, 82], "proxi": [74, 75, 81], "helper": [74, 96, 97, 98, 99, 102, 103, 113, 114], "pages2k": 74, "lipd": 74, "file": 74, "reconstruct": [74, 75, 76, 77, 81, 82], "past": [75, 76, 77, 96], "an": [75, 102, 109, 120], "isotop": 75, "relat": 75, "pyleoclim": 75, "coral": 75, "oxygen": 75, "palmyra": 75, "line": 75, "island": 75, "multiseri": 75, "stripe": 75, "relationship": [77, 118], "between": [77, 113, 120], "\u03b4d": 77, "uniform": 78, "bin": 78, "princip": 78, "compon": 78, "pca": 78, "spectral": 79, "lr04": 79, "\u03b4": 79, "sup": 79, "18": 79, "o": 79, "benthic": 79, "stack": 79, "lro4": 79, "signific": 79, "test": [79, 118], "wavelet": 79, "forc": 80, "construct": 80, "insol": [80, 86, 88], "curv": 80, "last": [81, 90], "millenium": 81, "pmip3": 81, "gmst": 81, "lgmr": 82, "greenhous": [85, 86, 87, 105], "radiat": [85, 86], "planck": 85, "law": 85, "stefan": 85, "boltzmann": 85, "effect": [85, 87, 88], "blackbodi": 85, "energi": [86, 87, 91], "balanc": [86, 87, 91], "sun": 86, "incom": 86, "solar": 86, "alpha": 86, "absorb": 86, "shortwav": 86, "asr": 86, "equilibrium": [86, 87, 88, 89, 90], "scenario": [86, 87, 95, 99, 102, 113, 119], "increas": 86, "ga": 86, "concentr": 86, "zero": 87, "dimension": [87, 90], "build": 87, "forward": [87, 89], "numer": [87, 88], "revisit": 87, "enhanc": 87, "sensit": 87, "feedback": 88, "et": 88, "ic": 88, "depend": [88, 113, 115, 119], "equilibria": 88, "graph": 88, "determin": 88, "converg": 88, "diverg": 88, "number": 88, "radi": [89, 90], "up": 89, "climlab": [89, 90], "convect": 90, "reproduc": [90, 99], "cesm": 91, "check": [91, 118], "budget": 91, "latitud": 91, "futur": [92, 95, 96, 99, 100, 113], "ipcc": [92, 100, 102], "i": 92, "physic": [92, 123], "basi": [92, 100], "esm": 94, "recap": 94, "horizont": 94, "regrid": 94, "sever": [95, 99], "experi": [95, 96, 97, 99], "gmsst": 95, "multi": [96, 97], "ensembl": [96, 97, 98], "so": 96, "mani": 96, "five": 96, "three": 96, "remov": 96, "season": 96, "all": 96, "we": 96, "just": 96, "variou": 97, "intern": 98, "singl": 98, "synthesis": 99, "divers": 99, "histor": [99, 112, 113], "context": 99, "ii": 100, "iii": 100, "socio": 100, "econom": [100, 103], "iam": [101, 103, 104], "exogen": 101, "control": 101, "economi": 101, "optim": [101, 103], "plan": [101, 103], "social": 101, "cost": 101, "vector": 101, "word": [101, 105], "titl": [102, 103], "socioeconom": 102, "world3": 102, "exponenti": 102, "growth": 102, "bound": 102, "work": 102, "pyworld3": 102, "origin": 102, "busi": 102, "As": 102, "usual": 102, "bau": 102, "bau3": 102, "abund": 102, "cap": 102, "valid": 102, "limit": 102, "transit": 103, "goal": 103, "integr": 103, "background": 103, "dice": 103, "util": 103, "consumpt": 103, "popul": 103, "damag": 103, "simul": 103, "standard": 103, "discount": 103, "rate": 103, "ssp": 104, "public": 105, "opinion": 105, "emerg": 105, "matter": 105, "preprocess": [105, 119], "inspect": [105, 108, 113], "preval": 105, "sentiment": 105, "respons": [106, 116], "empir": 109, "return": [109, 111, 115], "gev": [110, 111], "histogram": 110, "period": [111, 113], "confid": 111, "interv": [111, 115], "non": [112, 114], "stationar": [112, 114], "evt": 114, "framework": 114, "download": [114, 115], "focu": 115, "new": [115, 118], "delhi": 115, "india": 115, "pre": 115, "adapt": 116, "synthet": 118, "fit": [118, 119, 120], "analyz": [118, 119], "unseen": 118, "x": 118, "slightli": 118, "tree": 119, "dengu": 119, "fever": 119, "correspond": 119, "weekli": 119, "perform": [119, 120], "handl": 119, "categor": 119, "regressor": 119, "integ": 119, "look": 119, "import": [119, 120], "idea": 119, "ann": 120, "crop": 120, "visualis": 120, "scikit": 120, "learn": 120, "anoth": 120, "permut": 120, "artifici": 120, "neural": 120, "train": 120, "overfit": 120, "too": 120, "much": 120, "consid": 121, "frame": 121, "problem": 121, "term": 121, "welcom": 122, "concept": 122, "prerequisit": [122, 123], "refresh": 122, "academi": 122, "begin": 122, "preparatori": 123, "math": 123, "algebra": 123, "statist": 123, "calculu": 123, "chemistri": 123}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1, "sphinx": 56}}) \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/chapter_title.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/chapter_title.html deleted file mode 100644 index 7a275bb2f..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - Good Research Practices — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Good Research Practices

- -
-
- -
-
-
- - - - -
- -
-

Good Research Practices#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/further_reading.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/further_reading.html deleted file mode 100644 index 64a625e54..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/further_reading.html +++ /dev/null @@ -1,1077 +0,0 @@ - - - - - - - - - - - - <no title> — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- - - - - -
- - - - - - -
- - - -
- - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary.html deleted file mode 100644 index eb5a85d3f..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_DaySummary.html +++ /dev/null @@ -1,1097 +0,0 @@ - - - - - - - - - - - - Day Summary — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Day Summary

- -
-
- -
-
-
- - - - -
- -
-

Day Summary#

-

In this tutorial, you’ve learned about how to construct a research project. You now know how to:

-
    -
  • Identify a phenomenon and ask a good research question

  • -
  • Do a literature review to determine what is already known about the phenomenon

  • -
  • Choose a dataset to address your research question

  • -
  • Form a good, testable hypothesis

  • -
  • Draft and implement data analysis

  • -
  • Interpret your results

  • -
  • Communicate your findings to a broader audience

  • -
-

Feel free to refer back to this section as you work on your own research projects for reminders about the scientific process and how to avoid pitfalls.

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Intro.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Intro.html deleted file mode 100644 index 0a03f49fb..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Intro.html +++ /dev/null @@ -1,1115 +0,0 @@ - - - - - - - - - - - - Intro — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Intro

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Intro#

-
-

Overview#

-

This tutorial is all about the research process from concept to conclusion. We will walk you through the thinking process behind scientific research and some tools that will help you as you think through your own projects. The first half will focus on the process of planning a research project. In Step 1, we will walk you through how to ask a good research question. Step 2 will explain the goals of the literature review process. Step 3 will introduce you to the wide range of datasets used in climate science and give an introduction to when you might use some of them. Step 4 will explain how to develop a robust hypothesis based on the resources available.

-

The second half will focus on data analysis and communicating your results. Step 5 will guide you through drafting the analysis, and at Step 6 we will implement a sample analysis. Step 7 will explain what to take into consideration when interpreting your results. Finally, Step 8 will talk you through how to communicate your conclusions to different audiences. We hope that after this tutorial, you will have a better understanding of how to complete research that is clearly motivated and rigorously supported.

-
-
- - - - -
- - - - - - -
- - - -
- - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Outro.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Outro.html deleted file mode 100644 index 7feffc301..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Outro.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - - - - - - - Outro — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Outro

- -
-
- -
-
-
- - - - -
- -
-

Outro#

-

Now you have learned about doing climate research and presenting your results. These include many equity concerns, including possible impacts on populations in many parts of the world.

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1.html deleted file mode 100644 index 04e3059ba..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial1.html +++ /dev/null @@ -1,1185 +0,0 @@ - - - - - - - - - - - - Tutorial 1: Finding a Phenomenon and Asking a Question About It — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Tutorial 1: Finding a Phenomenon and Asking a Question About It

- -
- -
-
- - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1: Finding a Phenomenon and Asking a Question About It#

-

Good Research Practices

-

Content creators: Marguerite Brown, Dionessa Baton, Yuxin Zhou, Natalie Steinemann, Zane Mitrevica

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-

Demos#

-

In order to illustrate the process, we will use a sample research question about how the surface temperature of the earth depends on the CO\(_2\) content of the atmosphere.

-
-
-
-
-
-
-

Activity: Asking Your Own Question#

-

Write down a phenomenon you would like to gain understanding about. Take 5 minutes to construct a question about the phenomenon. Discuss amongst your group to improve the question. For some inspiration:

-
    -
  • Are there other aspects of the planet that may influence the average surface temperature?

  • -
  • Are there other features of the planet that may be impacted by changes in the average surface temperature?

  • -
-
-

Make Sure to Avoid the Pitfalls!#

-
-Click here for a recap on pitfalls -

Question is too broad

-
    -
  • Science advances one small step at a time. Narrowing the scope will help clarify your next steps
  • -
-

Question does not identify a precise aspect of the phenomenon

-
    -
  • Clarity will help identify next steps in your research
  • -
  • If you are struggling to identify a precise aspect, you might need to learn more about the phenomenon. Look to the literature (Step 2)!
  • -
-

Question is about an analysis method

-
    -
  • An analysis method is a tool, not the big picture
  • -
-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2.html deleted file mode 100644 index 27f564e4c..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial2.html +++ /dev/null @@ -1,1207 +0,0 @@ - - - - - - - - - - - - Tutorial 2: Doing a Literature Review — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2: Doing a Literature Review#

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou, Zane Mitrevica, Natalie Steinemann

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-
-
-
-
-

Activity: Understanding the Literature Review Process#

-

While a comprehensive literature review typically requires an extensive timeframe spanning months or even years, in the context of your Project Template, we will conduct a condensed literature review within two days. Instead of tasking you with reviewing the literature on our sample research topic, we will provide additional guidance on the process of conducting a literature review.

-

During this timeframe, you will be introduced to the fundamental aspects and techniques of performing a literature review, enabling you to gain insights into the necessary steps and best practices. Although the review will be concise, it will equip you with the essential skills to navigate the literature effectively and lay the foundation for future in-depth literature reviews.

-
-

Equity in Literature Review#

-
-Click here for some points to consider when doing your literature review -

The choices we make as a collective have an impact on who is included and who is excluded in the scientific process. While there is no perfect solution to addressing inequity in the sciences, we can contribute by engaging in an ongoing conversation and being receptive to feedback regarding our impact. Here are some points to consider:

-
    -
  • Which papers are you selecting for your review? Which papers are you citing? Are there overlooked studies with valuable results?

  • -
  • Does your work relate to a phenomenon that affects a specific community? Have members of that community made observations or documented the phenomenon?

  • -
  • Has your own experience informed you of equity concerns in the knowledge base that you are in a good position to address?

  • -
-

Remember, perfection is not the goal. Every choice we make carries unintended consequences. By keeping equity in mind, we can remain open to constructive feedback and identify areas where we can make a positive impact.

-

Here are some resources that may help you incorporate knowledge and understanding from underrepresented groups:

- -

Here is some reading relating to Arrhenius and his racism:

-

College Chemistry Textbooks Aid and Abet Racial Disparity. Mona L. Becker and Melanie R. Nilsson. Journal of Chemical Education 2022 99 (5), 1847-1854. DOI: https://doi.org/10.1021/acs.jchemed.1c00968

-
-
-

Tips for Efficiency#

-
-Click here for some pointers on reviewing literature efficiently -

There are many different strategies for reviewing literature efficiently. Here are some descriptions of the processes that different researchers use. If you are new to a topic, we recommend you start by looking for a review paper, which will summarize the results of multiple studies and direct you to other papers worth reading.

-

Here is one option for reading papers efficiently:

-
    -
  • Start by reviewing the abstract and conclusions sections. This will help you determine the relevance of the paper’s results to your research.

  • -
  • Conduct a “quick pass” of the paper

  • -
-
    -
  • Scan through the figures and diagrams.
  • -
  • Identify the references to these figures in the text and read the surrounding discussion.
  • -
  • Take note of any parts of the figures or discussion that you find difficult to understand.
  • -
-* Seek additional information to address the areas that you found challenging: -
    -
  • Refer to previous sections of the paper that describe the methods and analysis.
  • -
  • Explore other papers that cite or are cited by the paper you are reading.
  • -
  • Consult relevant textbooks or resources on the subject.
  • -
  • Seek guidance from professors or peers in your field.
  • -
-* If the paper seems extremely important, or if you are tasked with presenting it to a group, consider reading it in its entirety. To maximize your comprehension, you can -
    -
  • Summarize the main message of each paragraph in one sentence or less.
  • -
  • Create written descriptions or sketches of the phenomena discussed.
  • -
  • Identify the physical meaning and implications of terms and equations.
  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3.html deleted file mode 100644 index 44130488c..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial3.html +++ /dev/null @@ -1,1217 +0,0 @@ - - - - - - - - - - - - Tutorial 3: Identifying the Basic Ingredients — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Tutorial 3: Identifying the Basic Ingredients

- -
- -
-
- - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3: Identifying the Basic Ingredients#

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou, Natalie Steinemann, Zane Mitrevica

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-
-
-
-
-

Activity: Identifying Basic Ingredients#

-

Take 10 minutes to discuss the advantages and disadvantages of utilizing the following basic ingredients to explore the research question discussed in Video 1:

-
    -
  • Ice core data for CO2

  • -
  • Deep sea sediment data for sea surface temperature

  • -
-

Can you think of alternative approaches that might work well?

-
-

Choosing Your Data#

-
-Click here for some pointers on how to choose your data -

Here are some questions to ask yourself when choosing the data to use:

-

What physical processes must be included?

-
    -
  • You don't want an approach that contains less than the bare minimum. For some phenomena, we know what the bare minimum is. For others, more research is needed...
  • -
  • If you are unsure about what physical processes are needed, check the literature!
-

What spatial and temporal resolution is necessary to capture the phenomenon?

-
    -
  • GCMs can typically have a spatial resolution around 100km and time resolution of several hours.
  • -
  • For phenomena that require higher resolution, you can either
  • -
    • Use a more idealized model that resolves smaller scales
    • Implement a parameterization of the sub-gridscale features within the GCM.
    • -
-

What restrictions do I have for computational resources?

-
    -
  • If you do not have access to large computational resources, you can still do research using smaller datasets or idealized models
  • -
-

Am I interested in looking at a particular time period or a specific physical location?

-
    -
  • Reanalysis can be used for time periods after roughly the 1940s
  • -
  • Proxy data can be used for a wider historical and prehistorical data
  • -
  • Both reanalysis and proxy data can provide specific location information
  • -
  • Models can be designed to mimic the conditions of the location or time, for example:
    • -
    • GCMs (General Circulation Models or Global Climate Models) can be set according to parameters that resemble the time period
    • -
    • Energy balance models can capture some aspects of average temperature in other time periods
    • -
    • Radiative-convective equilibrium models can capture some phenomena in the tropics
    • -
    • Quasi-geostrophic models can capture some phenomena in the mid-latitudes (between ~30-60 degrees)
    • -
    • And many more!
    • -
    -
-

Am I interested in studying a feature of the phenomenon in isolation or interactions between multiple features?

-
    -
  • If you want to isolate a single aspect of the phenomenon, an idealized model may be more appropriate
  • -
  • If you want to study interactions between multiple features, either observational data or a more complex model may be appropriate
  • -
-

Am I trying to…

-
    -
  • explain the theory behind the phenomenon? An idealized model may be appropriate
  • -
  • provide evidence to support or challenge a pre-existing hypothesis? Observational data or a more complex model may be appropriate
  • -
  • document the features of the phenomenon? Observational data may be appropriate
  • -
-

For more information on observational data:

- -

For more information on numerical modeling:

-
    -
  • Atmospheric Model Hierarchies: Maher, P., Gerber, E. P., Medeiros, B., Merlis, T. M., Sherwood, S., Sheshadri, A., et al. (2019). Model hierarchies for understanding atmospheric circulation, Reviews of Geophysics, 57, 250– 280. https://doi.org/10.1029/2018RG000607

  • -
  • Ocean Model Hierarchies: Hsu, T.-Y., Primeau, F., & Magnusdottir, G. (2022). A hierarchy of global ocean models coupled to CESM1. Journal of Advances in Modeling Earth Systems, 14, e2021MS002979. https://doi.org/10.1029/2021MS002979

  • -
-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4.html deleted file mode 100644 index 8a85c749e..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial4.html +++ /dev/null @@ -1,1193 +0,0 @@ - - - - - - - - - - - - Tutorial 4: Formulating a Hypothesis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 4: Formulating a Hypothesis#

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou, Zane Mitrevica, Natalie Steinemann

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-
-
-
-
-

Activity: Understanding Hypothesis#

-

Take 5 minutes to discuss how a hypothesis differs from a research question.

-
-

Make Sure to Avoid the pitfalls!#

-
-Click here for a recap on pitfalls -

I don’t need a hypothesis, I will just play around with the model/data

-
    -
  • A hypothesis will help to clarify your goals when presenting research. After all, "I just played around with this model a lot" isn't a very satisfying scientific result
  • -
  • However, we encourage you to explore and experiment with the model and the data, as this can help develop your intuition and understanding of the subject matter
  • -
  • Hypothesis formation is often an iterative process involving both the literature review and playing around with your model and data
  • -
-

My hypothesis doesn’t match my question (or vice versa)

-
    -
  • This is a normal part of the process!
  • -
  • You can return to Step 1 and update your question / phenomenon / goals
  • -
-

I can’t write down a hypothesis

-
    -
  • If you find it challenging to articulate a hypothesis, it may indicate that you lack ingredients and/or clarity on the hypothesis. Try returning to Step 2 to further your literature review, or continue playing around with your model or data.
  • -
-
-
-
-

Tutorials 1-4 Summary#

-

Through tutorials 1-4, we worked through the preliminary steps of starting a research project.

-
    -
  • We identified a phenomenon and formulated a question (Step 1)

  • -
  • We did a review of the literature and determine what has already been studied about the phenomenon (Step 2)

  • -
  • We determined what basic ingredients we need to investigate the phenomenon (Step 3)

  • -
  • We used all of the above to formulate a testable hypothesis (Step 4)

  • -
-
-
-

Next Steps#

-

Tutorials 5-8 will illustrate the steps involved in data analysis, interpreting your results, and communicating your results to an audience. As you do your own research, feel free to return to this tutorial as a guide.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5.html deleted file mode 100644 index a0180f5af..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial5.html +++ /dev/null @@ -1,1156 +0,0 @@ - - - - - - - - - - - - Tutorial 5: Drafting the Analysis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Tutorial 5: Drafting the Analysis

- -
- -
-
- - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 5: Drafting the Analysis#

-

Good Research Practices

-

Content creators: Yuxin Zhou, Marguerite Brown, Natalie Steinemann, Zane Mitrevica

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorials Objectives#

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-
-
-
-
-

Coding Exercise 1#

-

To explore the relationship between CO2 and temperature, you may want to make a scatter plot of the two variables, where the x-axis represents CO2 and the y-axis represents temperature. Then you can see if a linear regression model fits the data well.

-

Before you do that, let’s learn how to apply a linear regression model using generated data.

-

If you aren’t familiar with a linear regression model, it is simply a way of isolating a relationship between two variables (e.g. x and y). For example, each giraffe might have different running speeds. You might wonder if taller giraffes run faster than shorter ones. How do we describe the relationship between a giraffe’s height and its running speed? A linear regression model will be able to provide us a mathematical equation:

-

speed = a * height +  b

-

where a and b are the slope and intercept of the equation, respectively. Such an equation allows us to predict an unknown giraffe’s running speed by simply plugging its height into the equation. Not all giraffes will fit the relationship and other factors might influence their speeds, such as health, diet, age, etc. However, because of its simplicity, linear regression models are usually first attempted by scientists to quantify the relationship between variables.

-

For more information on linear regression models, see the Wikipedia page, especially the first figure on that page:

-

To get a sense of how our model fits the data, you can look at the regression results.

-

Now that we know how to write codes to analyze the linear relationship between two variables, we’re ready to move on to real world data!

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6.html deleted file mode 100644 index 0e5a15fe6..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial6.html +++ /dev/null @@ -1,1314 +0,0 @@ - - - - - - - - - - - - Tutorial 6: Implementing the Analysis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Tutorial 6: Implementing the Analysis

- -
- -
-
- - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 6: Implementing the Analysis#

-

Good Research Practices

-

Content creators: Yuxin Zhou, Marguerite Brown, Zane Mitrevica, Natalie Steinemann

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorials Objectives#

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-

Activity: Implement the Analysis#

-

In this tutorial, you will be implementing a linear regression model as outlined in Step 5 on real-world CO2 and temperature records.

-

The CO2 and temperature records we will be analyzing are both examples of paleoclimate data (for more information, refer back to Step 3). The CO2 record (Bereiter et al., 2015) was generated by measuring the CO2 concentration in ancient air bubbles trapped inside ice from multiple ice cores retrieved from Antarctica. The temperature record (Shakun et al., 2015) is based on chemical analysis done on the shells of planktic foraminifera. The foraminifera shells were identified and picked from deep-sea sediments, and the temperature record combined multiple sea-surface temperature records from a range of sites globally.

-

Why are we focusing on these two records specifically? The CO2 record from Antarctic ice core is the gold standard of air CO2 variability on glacial-interglacial time scales, and it has a temporal resolution unmatched by any other reconstruction methods. The temperature record comes from sediment cores all over the global ocean, and therefore is likely representative of the global surface ocean temperature variability. Polar air temperature records are also available from ice core studies, but such records may represent an exaggerated view of the global temperature because of polar amplification.

-

If you would like to learn more, the data sources are listed at the bottom of the page.

-
-
-
# @title Helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
# time series
-# read SST data "Shakun2015_SST.txt"
-filename_Shakun2015_SST = "Shakun2015_SST.txt"
-url_Shakun2015_SST = "https://osf.io/kmy5w/download"
-SST = pd.read_table(pooch_load(url_Shakun2015_SST, filename_Shakun2015_SST))
-SST.set_index("Age", inplace=True)
-SST
-
-
-
-
-
-
-
# read CO2 dataantarctica2015co2composite_cleaned.txt
-filename_antarctica2015co2composite_cleaned = "antarctica2015co2composite_cleaned.txt"
-url_antarctica2015co2composite_cleaned = "https://osf.io/45fev/download"
-CO2 = pd.read_table(
-    pooch_load(
-        url_antarctica2015co2composite_cleaned,
-        filename_antarctica2015co2composite_cleaned,
-    )
-)
-CO2.set_index("age_gas_calBP", inplace=True)
-CO2
-
-
-
-
-
-
-
# plot
-# set up two subplots in a grid of 2 rows and 1 column
-# also make sure the two plots share the same x(time) axis
-fig, axes = plt.subplots(2, 1, sharex=True)
-# move the two subplots closer to each other
-fig.subplots_adjust(hspace=-0.5)
-axes[0].plot(SST.index, SST["SST stack"], color="C4")
-axes[1].plot(CO2.index / 1000, CO2["co2_ppm"], color="C1")
-
-# beautification
-# since sharex=True in plt.subplots(), this sets the x axis limit for both panels
-axes[1].set_xlim((0, 805))
-# axis labels
-axes[1].set_xlabel("Age (ka BP)")
-axes[0].set_ylabel(r"Sea Surface Temperature" "\n" "detrended (°C)", color="C4")
-axes[1].set_ylabel(r"CO${}_\mathrm{2}$ (ppm)", color="C1")
-
-# despine makes the plots look cleaner
-sns.despine(ax=axes[0], top=True, right=False, bottom=True, left=True)
-sns.despine(ax=axes[1], top=True, right=True, bottom=False, left=False)
-# clean up top panel x axis ticks
-axes[0].xaxis.set_ticks_position("none")
-# move top panel xlabel to the right side
-axes[0].yaxis.set_label_position("right")
-# the following code ensures the subplots don't overlap
-for ax in axes:
-    ax.set_zorder(10)
-    ax.set_facecolor("none")
-# color the axis
-axes[0].spines["right"].set_color("C4")
-axes[1].spines["left"].set_color("C1")
-axes[0].tick_params(axis="y", colors="C4")
-axes[1].tick_params(axis="y", colors="C1")
-
-
-
-
-

Now that we’ve taken a look at the two time series, let’s make a scatter plot between them and fit a linear regression model through the data.

-
-
-
# in this code block, we will make a scatter plot of CO2 and temperature
-# and fit a linear regression model through the data
-
-
-def age_model_interp(CO2_age, CO2, SST_age):
-    """
-    This helper function linearly interpolates CO2 data, which
-    have a very high temporal resolution, to temperature data,
-    which have a relatively low resolution
-    """
-    f = interpolate.interp1d(CO2_age, CO2)
-    all_ages = f(SST_age)
-    return all_ages
-
-
-# interpolate CO2 data to SST age
-CO2_interpolated = age_model_interp(CO2.index / 1000, CO2["co2_ppm"], SST.index)
-
-# plot
-# set up two subplots in a grid of 2 rows and 1 column
-# also make sure the two plots share the same x(time) axis
-fig, ax = plt.subplots(1, 1, sharex=True)
-
-ax.scatter(CO2_interpolated, SST["SST stack"], color="gray")
-
-# regression
-X = CO2_interpolated
-y = SST["SST stack"]
-res = stats.linregress(X, y)  # ordinary least sqaure
-
-x_fit = np.arange(180, 280)
-# intercept
-y_fit = x_fit * res.slope + res.intercept
-ax.plot(x_fit, y_fit, color="k")
-
-# beautification
-# axis labels
-ax.set_xlabel(r"CO${}_\mathrm{2}$ (ppm)")
-ax.set_ylabel(r"Sea Surface Temperature" "\n" "detrended (°C)")
-print(
-    "pearson (r^2) value: "
-    + "{:.2f}".format(res.rvalue**2)
-    + " \nwith a p-value of: "
-    + "{:.2e}".format(res.pvalue)
-)
-
-
-
-
-
-

Figure Making Through the Equity Lense#

-
-Click here for some information -Are the colors in your figure distinguishable for people with color-vision deficiencies? -

More readings on this topic:

-

Contrast checker: https://www.color-blindness.com/coblis-color-blindness-simulator/

-

Coloring for color blindness: https://davidmathlogic.com/colorblind

-

Python-specific color palettes that are friendly to those with color-vision deficiency: https://seaborn.pydata.org/tutorial/color_palettes.html

-
-
-
-

Resources#

-

Data from the following sources are used in this tutorial:

-

CO2: Bereiter, B., Eggleston, S., Schmitt, J., Nehrbass-Ahles, C., Stocker, T.F., Fischer, H., Kipfstuhl, S., Chappellaz, J., 2015. Revision of the EPICA Dome C CO2 record from 800 to 600 kyr before present. Geophysical Research Letters 42, 542–549. https://doi.org/10.1002/2014GL061957

-

Temperature: Shakun, J.D., Lea, D.W., Lisiecki, L.E., Raymo, M.E., 2015. An 800-kyr record of global surface ocean δ18O and implications for ice volume-temperature coupling. Earth and Planetary Science Letters 426, 58–68. https://doi.org/10.1016/j.epsl.2015.05.042

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7.html deleted file mode 100644 index 7f7af6f82..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial7.html +++ /dev/null @@ -1,1166 +0,0 @@ - - - - - - - - - - - - Tutorial 7: Interpreting the Results — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 7: Interpreting the Results#

-

Good Research Practices

-

Content creators: Yuxin Zhou, Samuel Akpan, Marguerite Brown, Natalie Steinemann, Zane Mitrevica

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorials Objectives#

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-
-
-

In Step 6, we created plots displaying the global CO2 levels and sea surface temperature data spanning the past 800 thousand years. Additionally, we attempted to fit both variables using a linear regression model. Nevertheless, it is crucial to bear in mind that correlation does not imply causation. The fact that global CO2 and sea surface temperature appear to co-vary does not automatically imply that one variable directly causes changes in the other. To establish causation, it is imperative to gather multiple lines of evidence. This underscores the importance of literature review in Step 2, as it aids in identifying corroborating evidence in climate research.

-
-
-

Quantifying the Uncertainty#

-
-Click here for some information -Look up "linear regression model R squared" and how it measures the uncertainty of a linear regression model. What does it say about how confident you can be about a linear relationship between CO2 and temperature?
-
-

Activity: Interpreting the Results Through the Lens of Equity#

-

For the next 10 minutes, discuss what the results capture well in terms of the relationship between CO2 and temperature. Who is represented by this data, specifically the compiled temperature record, and who is not? Who generated these data? Who has access to this information? Who is in a position to use it?

-
-
-

Further readings#

-
-Click here for more readings on Interpreting the Results through the lens of equity -

Donovan, R. (2023), Climate journalism needs voices from the Global South, Eos, 104, https://doi.org/10.1029/2023EO230085

-

Tandon, A. (2021), Analysis: The lack of diversity in climate-science research, Carbon Brief, https://www.carbonbrief.org/analysis-the-lack-of-diversity-in-climate-science-research/

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8.html b/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8.html deleted file mode 100644 index 4df1cc92b..000000000 --- a/book/_build/html/tutorials/Projects_GoodResearchPractices/student/Projects_Tutorial8.html +++ /dev/null @@ -1,1196 +0,0 @@ - - - - - - - - - - - - Tutorial 8: Communicating Your Conclusions — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 8: Communicating Your Conclusions#

-

Good Research Practices

-

Content creators: Yuxin Zhou, Natalie Steinemann, Marguerite Brown, Zane Mitrevica

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorials Objectives#

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-
-
-
-
-

Activity: Communicating Your Conclusions#

-

For the next 20 minutes, break out into groups of 2 or 3 and pick one presentation format and discuss:

-
    -
  • Who is the target audience of this format?

  • -
  • What information is important to include?

  • -
-

After this, come back together as a whole pod and discuss everyone’s suggestions.

-
-

Equity in the Science Publishing#

-
-Click here for some information about equity and publishing -

There are aspects of our current research culture that perpetuate inequity in the publishing process. Academic institutions and funding agencies often place importance on publishing in peer-reviewed journals. However, they have some drawbacks, including

-
    -
  • Accessibility

  • -
-
  • Papers in these journals are often kept behind a paywall, making them less accessible to people without the backing of either a university or a company.
  • -
  • More and more journals offer the option of publishing open access, but at expense to the submitting authors: fees can often exceed 1000 USD.
  • -
  • -If you want to ensure accessibility, consider also releasing your results in other formats as well. For instance, -
    • Blog posts
    • -
    • Podcasts
    • -
    • Social media posts
    • -
    • Conferences
    -
  • If you know that your research contains results that are relevant to specific populations, it is valuable to find ways to communicate your results to them.
-* Peer Review as Gatekeeping -
  • At its best, the peer review process enforces scientific rigor.
  • -
  • At its worst, it can become a tool for enforcing pre-existing norms, including the biases of its reviewers.
  • -
  • REMEMBER: Bad experiences with reviewers and rejections does not mean that your research is bad. There are papers which went on to win Nobel prizes that experienced resistance and rejection during the peer review process BECAUSE they were introducing important new ideas.
  • -
  • Further Reading:
  • -
    • Campanario, J. M. (2009). Rejecting and resisting Nobel class discoveries: Accounts by Nobel Laureates. Scientometrics, 81(2), 549–565.
    • -
    • Bancroft, S. F., Ryoo, K., & Miles, M. (2022). Promoting equity in the peer review process of journal publication. Science Education, 106, 1232– 1248. https://doi.org/10.1002/sce.21733
-
-
-

Tutorials 5-8 Summary#

-

In this tutorial, we worked through how to analyze and present research.

-
    -
  • We learned how to draft an analysis (Step 5)

  • -
  • We implemented the analysis that we drafted (Step 6)

  • -
  • We learned how to interpret the results of the analysis (Step 7)

  • -
  • We learned about how to communicate the conclusions of our research (Step 8)

  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Schedule/daily_schedules.html b/book/_build/html/tutorials/Schedule/daily_schedules.html deleted file mode 100644 index 161f7d967..000000000 --- a/book/_build/html/tutorials/Schedule/daily_schedules.html +++ /dev/null @@ -1,1656 +0,0 @@ - - - - - - - - - - - - General Schedule — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

General Schedule#

-
-

2023 course will run July 17-28, 2023#

-
-
-

Course Overview#

-

The course will begin with Opening Ceremonies on Sunday, July 9th

-
    -
  • 7:00 am UTC

  • -
  • 3:00 pm UTC

  • -
-

Tutorials, Projects and Professional Development activities will take place between July 17th and July 28th, 2023.

-
-
-

Course Schedule for Timezones 2 & 5#

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Course Schedule - Timezones 2 & 5 -
Week 1 - W1D1 - W1D2 - W1D3 - W1D4 - W1D5 -
Curriculum -

-(5 hours) -

Climate System Overview - Ocean-Atmosphere Reanalysis - Remote Sensing - Paleoclimate - Climate Modeling -
- - - - -
Projects & Professional Development -

-(3 hours) -

Session 1 -

- Tutorial on good research Practices -

Session 2 -

- Guided data exploration -

Session 3 -

-Literature review & question formulation -

Session 4 -

- Proposal writing, swaps & submission -

Session 5 -

- Drafting the analyses & task allocation -

- Impact Talk: -

- Climate Justice -

Impact Talk: -

Equity in Climate Science -

- -
-
Week 2 - W2D1 - W2D2 - W2D3 - W2D4 - W2D5 -
Curriculum -

-(5 hours) -

IPCC I: -

- Physical Basis -

Project Day - IPCC II & III: -

- Socioeconomic Basis -

Extremes & Vulnerability - Adaptation & Impact -
- - - - -
Projects & Professional Development -

-(3 hours) -

Session 6 -

- Implementation -

Session 7 -

- Implementation -

Session 8 -

- Implementation & result interpretation -

Session 9 -

- Presentation preparation & project submission -

Presentations -

- Closing ceremony -

Impact Talk: -

- Open Climate Science -

Career Panel - Impact Talk: -

- Climate Science Communication -

- -
-
-
-

Course Schedule for Timezones 1, 3 & 4#

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Course Schedule - Timezones 1, 3 & 4 -
Week 1 - W1D1 - W1D2 - W1D3 - W1D4 - W1D5 -
Projects & Professional Development -

-(3 hours) -

No project time - Session 1 -

- Tutorial on good research Practices -

Session 2 -

- Guided data exploration -

Session 3 -

- Literature review & question formulation -

Session 4 -

- Proposal writing, swaps & submission -

- Impact Talk: -

- Climate Justice -

Impact Talk: -

- Equity in Climate Science -

-
Curriculum -

-(5 hours) -

Climate System Overview - Ocean-Atmosphere Reanalysis - Remote Sensing - Paleoclimate - Climate Modeling -
- - - - -
-
Week 2 - W2D1 - W2D2 - W2D3 - W2D4 - W2D5 -
Projects & Professional Development -

-(3 hours) -

Session 5 -

- Drafting the analyses & task allocation -

Session 6 -

- Implementation -

Session 7 -

- Implementation -

Session 8 -

- Implementation & result interpretation -

Session 9 -

- Presentation preparation & project submission -

- Impact Talk: -

- Open Climate Science -

- Career Panel -

- Impact Talk: -

- Climate Science Communication -

-
Curriculum -

-(5 hours) -

IPCC I: -

- Physical Basis -

Project Day - IPCC II & III: -

- Socioeconomic Basis -

Extremes & Vulnerability - Adaptation & Impact -
- - - - -
- - - - - Presentations -

- Closing ceremony -

-
-
-

Daily Schedule#

-

These schedules refer to the time spent working on the course curriculum (5 hours each day).

-
-

Curriculum Schedule#

-

All days (except W1D1 and W2D2) will follow this schedule for course time:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Time (Hour) - Component -
-0:30-0:00 - Keynote speaker -
0:00-0:15* - Pod discussion I -
0:15-1:35 - Tutorials I -
1:35-2:35 - Big break -
2:35-4:15 - Tutorials II -
4:15-4:25 - Pod discussion II -
4:25-4:30 - Reflections -
-

*Note that the synchronous coursework session starts at 0:00 with the first pod discussion.

-

W1D1: The synchronous coursework session starts at -0:30 with 30 minutes for pod introductions. Students should watch the keynote lecture beforehand.

-

W2D2: Following a keynote lecture in its usual slot, 0:00-3:30 will be spent working on the group project. At 3:30-4:30, there will be a live career panel as part of the Professional Development program. You can find more information about this day in the Daily Guide for Projects.

-
-
-

Project Schedule#

-

In addition to curriculum time, each day will have 3 hours of project time. Check the time slot widget to see when project time is scheduled for your slot.

-

On W2D2 you will additionally be working on your group projects during the time usually allocated for tutorials.

-
-
-

Professional Development Schedule#

-

A series of professional development events (viewing and discussing four Impact Talks, a career panel, and two meetings with mentors) will take place during the 3-hour project time. Check the time slot widget to see when project time is scheduled for your slot.

-
    -
  • Impact talks and discussions will take place during the first or last 30 minutes of Project Sessions 2, 3, 6 and 8.

  • -
  • The career panel will take place during the last hour of the time usually allocated for tutorials on W2D2.

  • -
  • Mentor meetings could take place on any day between July 19 and July 28. Your pod’s Teaching Assistant will tell you the exact times!

  • -
-
-
-

W2D5: Final Day of the Course#

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Time (Hour) - Component -
-4:00-(-1:00) - Projects (slots 1/3/4) -
-0:30-0:00 - Keynote speaker -
0:00-0:15* - Pod discussion I -
0:15-1:35 - Tutorials I -
1:35-2:35 - Big break -
2:35-4:15 - Tutorials II -
4:15-4:25 - Pod discussion II -
4:25-4:30 - Reflections -
4:30-4:45* - Short break -
4:45-5:15* - Course feedback survey -
5:15-6:15* - Project presentations (all slots) -
6:15-6:30* - Pod farewell -
-

*Note that these events take place after the normal coursework time for slots 1/3/4.

-

Course feedback survey: We will have a course completion survey for both students and teaching assistants. The link will be shared on discord. Please fill it out during this time!

-

Pod farewell: This is just a chance for your pod to say goodbye to each other. No structure imposed here!

-

Closing Ceremony / Graduation: We will do this all together on crowdcast on the Saturday after the course.

-
-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Schedule/schedule_intro.html b/book/_build/html/tutorials/Schedule/schedule_intro.html deleted file mode 100644 index 0e708c45f..000000000 --- a/book/_build/html/tutorials/Schedule/schedule_intro.html +++ /dev/null @@ -1,1057 +0,0 @@ - - - - - - - - - - - - Schedule — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Schedule

- -
-
- -
-
-
- - - - -
- -
-

Schedule#

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/Schedule/shared_calendars.html b/book/_build/html/tutorials/Schedule/shared_calendars.html deleted file mode 100644 index f2efd8162..000000000 --- a/book/_build/html/tutorials/Schedule/shared_calendars.html +++ /dev/null @@ -1,1063 +0,0 @@ - - - - - - - - - - - - Shared calendars — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Shared calendars

- -
-
- -
-
-
- - - - -
- -
-

Shared calendars#

-

We have five google calendars to help you see events in your local time! If you open the links below, they will be in -universal coordinated time (UTC). If you click at the bottom to add to your Google Calendar, you should see them in the time zone of your google -calendar (probably yours)!

-

Time slot 1

-

Time slot 2

-

Time slot 3

-

Time slot 4

-

Time slot 5

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/TechnicalHelp/Discord.html b/book/_build/html/tutorials/TechnicalHelp/Discord.html deleted file mode 100644 index ae9d9e592..000000000 --- a/book/_build/html/tutorials/TechnicalHelp/Discord.html +++ /dev/null @@ -1,1056 +0,0 @@ - - - - - - - - - - - - Using discord — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Using discord

- -
-
- -
-
-
- - - - -
- -
-

Using discord#

-

Please click here for Discord Guide

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/TechnicalHelp/Jupyterbook.html b/book/_build/html/tutorials/TechnicalHelp/Jupyterbook.html deleted file mode 100644 index 3c211c5fb..000000000 --- a/book/_build/html/tutorials/TechnicalHelp/Jupyterbook.html +++ /dev/null @@ -1,1058 +0,0 @@ - - - - - - - - - - - - Using jupyterbook — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Using jupyterbook

- -
-
- -
-
-
- - - - -
- -
-

Using jupyterbook#

-

While you can see videos and the notebooks in this jupyterbook, you have to launch each page in an interactive environment in order to write or run code.

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/TechnicalHelp/Links_Policy.html b/book/_build/html/tutorials/TechnicalHelp/Links_Policy.html deleted file mode 100644 index c58ede137..000000000 --- a/book/_build/html/tutorials/TechnicalHelp/Links_Policy.html +++ /dev/null @@ -1,1113 +0,0 @@ - - - - - - - - - - - - Quick links and policies — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Quick links and policies

- -
- -
-
- - - - -
- - - - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/TechnicalHelp/Tutorial_colab.html b/book/_build/html/tutorials/TechnicalHelp/Tutorial_colab.html deleted file mode 100644 index efac92915..000000000 --- a/book/_build/html/tutorials/TechnicalHelp/Tutorial_colab.html +++ /dev/null @@ -1,1095 +0,0 @@ - - - - - - - - - - - - Using Google Colab — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Using Google Colab

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Using Google Colab#

-

If you have access to Google Colab, you can click the “Open in Colab” button at the top of each page to launch it in an interactive environment where you can write and run code. Please note that we recommend JupyterHub if you can access it.

-
-

Advice for using Colab#

-
    -
  • Make a local copy to your Drive: otherwise changes you make (e.g. notes you take, code you write, etc) will not be saved

  • -
  • Do not edit the same colab directly as a group. Unlike Google Docs, one person’s version will overwrite another’s. If your browser happens to be open, it can overwrite anything that has been done by others since the last version in your browser!

  • -
  • Colab does not have version control! Use git for this if you want to collaborate (on a group project colab for example)

  • -
  • If you wish to work collaboratively in a single colab notebook, make sure to take advantage of its revision history: File -> Revision history. While the gold standard for version control is git, colab offers an easy alternative to those not familiar with git.

    -
      -
    • You can rename and revert to specific previous versions of the notebook by clicking on the three dots next your preferred revision in Revision history.

    • -
    • Note that old revisions get removed! To maintain a saved version over an extended period of time, use File -> Save and pin revision.

    • -
    -
  • -
-

To learn the basics of Colab, please check out this Colab notebook: https://colab.research.google.com/notebooks/intro.ipynb

-
-
- - - - -
- - - - - - -
- - - -
- - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/TechnicalHelp/Tutorial_jupyterhub.html b/book/_build/html/tutorials/TechnicalHelp/Tutorial_jupyterhub.html deleted file mode 100644 index 6aae265a7..000000000 --- a/book/_build/html/tutorials/TechnicalHelp/Tutorial_jupyterhub.html +++ /dev/null @@ -1,1137 +0,0 @@ - - - - - - - - - - - - Using JupyterHub — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Using JupyterHub

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Using JupyterHub#

-

The JupyterHub is a cloud-based platform that provides a seamless coding environment able to interact with climate datasets and pre-installed python packages to be used in the course.

-

Unlike Google Colab and Kaggle, in the JupyterHub there is no need to !pip install any packages or download data from osf. These should all be available already in the JupyterHub environment. We hope this experience will provide flexibility as you explore projects and practice the new skills you acquire over the next two weeks.

-

Note that if you live in a region with difficult access to the JupyterHub, the Climatematch Academy team has also subsetted datasets that can be loaded in Google Colab and Kaggle environments.

-

To read more about what a JupyterHub is: https://jupyterhub.readthedocs.io/en/stable/

-

To read more about our collaborators at 2i2c that are providing this experience https://2i2c.org/

-
-

#

-
-

STEPS:#

-
    -
  1. You should have already opened a Github account and provided the Climatematch Academy team your username. This step is necessary for you to be added to the course Github Team which enables access to the JupyterHub.

  2. -
  3. Click the Rocketship button found on top of every page containing a tutorial.

    -JupyterHub icon -
  4. -
  5. You may need to wait a couple minutes until a node becomes available, especially in the first login of the day.

    -JupyterHub waiting screen -

    Just in case, we recommend that you launch your first tutorial before you begin watching the invited speaker’s video (or 30 minutes before you plan to start coding).

    -
  6. -
  7. Once your server has started, you will find an interactive coding environment.

    -JupyterHub interactive coding environment -
  8. -
  9. We have preloaded datasets to the JupyterHub which are shared across all users. However, you will also have your own home directory where you can save notebooks and subsetted data you have analyzed.

  10. -
  11. Note that other users will not be able to access your home directory. To collaborate over projects it is best practice to share code using git.

  12. -
-
-
-
-

#

-
-

USING JUPYTERHUB TO COLLABORATE ON PROJECTS#

-

To help you share code, data, and plots, we have created a shared-public folder on JupyterHub. Each project group has a dedicated subfolder named after the group. Work ONLY in your project group’s folder!!!!

-JupyterHub interactive coding environment -

Inside your group’s folder, you will find a dev.ipynb notebook that you can use to develop code collaboratively.

-JupyterHub interactive coding environment -

For best practices:

-
    -
  • Only work in your group’s folder!!!!

  • -
  • Do not delete any code or data from this folder without the entire group’s permission– this cannot be restored!!

  • -
  • One member can share their screen while the group works together on shared code. Note that it may take a few minutes for code to update so best to avoid multiple people updating code simultaneously.

  • -
  • Alternatively, you can also each develop code in a notebook on your local folder. If there are code snippets you would like to share you can place in dev.ipynb, where other team members can copy over to their local notebook/folder.

  • -
  • We recommend everyone to still maintain a local copy of each notebook– just in case.

  • -
-
-
-
- - - - -
- - - - - - -
- - - -
- - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/TechnicalHelp/Tutorial_kaggle.html b/book/_build/html/tutorials/TechnicalHelp/Tutorial_kaggle.html deleted file mode 100644 index 3ca6150ad..000000000 --- a/book/_build/html/tutorials/TechnicalHelp/Tutorial_kaggle.html +++ /dev/null @@ -1,1136 +0,0 @@ - - - - - - - - - - - - Using Kaggle — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Using Kaggle#

-

If you are in China or another region with difficult access to JupyterHub and Google Colab, you can use Kaggle as a substitute for launching an interactive coding environment where you can write and run code. Please note that we recommend JupyterHub if you can access it.

-
-

First use#

-

1. First, sign in to your Kaggle account. If you don’t have a Kaggle account, create one by registering here.

-

Step 1

-

2. Get your account phone-verified. This is necessary for accessing GPU/internet on kernels, as well as for collaborative work. To do this:

-
    -
  • click on your profile icon in the top right corner

  • -
-

Step 2

-
    -
  • select Settings and scroll down to the Phone verification section

  • -
-

Step 3

-
    -
  • enter your phone number and subsequently the code verification code received in a text message

  • -
-

Step 4

-
-
-

Accessing course notebooks#

-

Click the kaggle button found on top of every page containing a jupyter notebook, such as tutorial pages.

-

Step 5

-
-

NOTE: If you receive an error asocociated with !pip install, follow this workaround.

-
-
-
-

Enabling internet access on kernels#

-

To enable this, click on Notebook options in the right side bar of the kaggle notebook editor. Scroll down and toggle Internet on. -This will let you fetch data from an external online source or install a custom python package. If after the installation you experience any error when trying to import an installed module, make sure to restart the kernel after installing the module and then it should work.

-

Step 3.2

-
-
-

Enabling GPU access on kernels#

-

Click on Notebook options in the right side bar of the kaggle notebook editor as above. Change Accelerator from None to GPU.

-
-

NOTE: A GPU is NOT required in the Computational Tools for Climate Science course! However, some advanced groups might design projects that benefit from GPU use.

-
-
-
-

Collaborating in kaggle#

-

To share a notebook with your project teammates, add them as collaborators by clicking Share in the top right corner of the notebook editor when you have the notebook of interest open. Keep the notebook as Private and search your teammates by their kaggle username. You can give them access to view or edit your work. This is also where you can enable comments for your notebook.

-

Step 7

-
-

NOTE: Unlike in Colab, collaborators CANNOT edit the same version of a notebook simultaneously! Your edits will be accessible to collaborators only after you Save version -> Save & Run All (Commit), but they will not get merged into their working version of the notebook automatically. Commits from separate notebook versions must be merged manually!

-
-

To view your collaborators’ work, open the version history by clicking on the number next to Save Version in the top right corner. Clicking on the three dots next to a specific version lets you view, rename, and pin it, as well as revert to it or compare it to another version.

-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/TechnicalHelp/tech_intro.html b/book/_build/html/tutorials/TechnicalHelp/tech_intro.html deleted file mode 100644 index 6dc45563e..000000000 --- a/book/_build/html/tutorials/TechnicalHelp/tech_intro.html +++ /dev/null @@ -1,1059 +0,0 @@ - - - - - - - - - - - - Technical Help — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Technical Help

- -
-
- -
-
-
- - - - -
- -
-

Technical Help#

-Wrench labeled neuromatch on top of a phone -

Artwork by Daniela Buchwald

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/chapter_title.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/chapter_title.html deleted file mode 100644 index 23934488c..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - Climate System Overview — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Climate System Overview

- -
-
- -
-
-
- - - - -
- -
-

Climate System Overview#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/further_reading.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/further_reading.html deleted file mode 100644 index 76a123d05..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/further_reading.html +++ /dev/null @@ -1,1068 +0,0 @@ - - - - - - - - - - - - Suggested Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Suggested Further Reading

- -
-
- -
-
-
- - - - -
- -
-

Suggested Further Reading#

-

Introduction to the Climate System:

- -

Introduction to Xarray

- -
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/.DS_Store b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/.DS_Store deleted file mode 100644 index 5008ddfcf..000000000 Binary files a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/.DS_Store and /dev/null differ diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary.html deleted file mode 100644 index 0856f8ca8..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_DaySummary.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - - - - - - - Day Summary — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Day Summary

- -
-
- -
-
-
- - - - -
- -
-

Day Summary#

-

The tutorials today provided an overview of Earth’s climate system as well as an introduction to Xarray. You learned about long-term, natural forcings and feedbacks that influence Earth’s climate including Earth’s energy budget, orbital forcings and the carbon cycle and explored various processes within the atmospheric, oceanic and terrestrial components of Earth’s climate system. Additionally, you learned useful tools in Xarray for formatting, analyzing and interpreting climate data

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro.html deleted file mode 100644 index 3482a0c28..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Intro.html +++ /dev/null @@ -1,1127 +0,0 @@ - - - - - - - - - - - - Intro — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Intro

- -
- -
-
- - - - -
- -
-

Intro#

-
-

Overview#

-

Welcome to the first day of the Computational Tools for Climate Science course! During this first day, the videos will provide an overview of Earth’s climate system. You’ll learn about various aspects of Earth’s climate including different parts of the climate system, forcings and mechanisms that drive changes in the climate system and the importance of understanding past, present and future climate variability. You’ll begin by learning about the effect of incoming solar radiation and Earth’s energy budget on the climate. You’ll then explore various processes within the atmospheric, oceanic and terrestrial components of Earth’s climate system. Finally, you’ll investigate long-term, natural forcings and feedbacks that influence Earth’s climate, and will begin to think about these processes in the contest of past, present and future climate variability.

-

Additionally, the notebooks in today’s tutorials will elaborate on the climate concepts introduced in the videos, but will primarily focus on introducing the Xarray Python package, which is commonly used to analyze large climate datasets and makes working with multi-dimensional arrays simple and efficient. Xarray introduces labels in the form of dimensions, coordinates and attributes on top of raw data array, and includes a large number of functions for advanced analytics and visualization with these data structures. Throughout the tutorials today, you’ll learn the basics of Xarray and apply some of these tools to climate datasets to further explore the climate system concepts introduced in the videos.

-
-
-

Video 1: Climate Solutions for a Warming World#

-
-
-
-
-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro.html deleted file mode 100644 index e4a93aa51..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Outro.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - - - - - - - Outro — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Outro

- -
-
- -
-
-
- - - - -
- -
-

Outro#

-

Now that you’ve explored various components, forcings and processes of Earth’s climate system, we can start to use additional climate data from various sources to investigate variability in Earth’s climate on multiple spatial and temporal scales.

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.html deleted file mode 100644 index ea0ac387b..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial1.html +++ /dev/null @@ -1,1409 +0,0 @@ - - - - - - - - - - - - Tutorial 1: Creating DataArrays and Datasets to Assess Global Climate Data — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1: Creating DataArrays and Datasets to Assess Global Climate Data#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Yosmely Bermúdez, Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS, Google DeepMind, NFDI4Earth!

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

As you just learned in the Introduction to Climate video, variations in global climate involve various forcings, feedbacks, and interactions between multiple processes and systems. Because of this complexity, global climate datasets are often very large with multiple dimensions and variables.

-

One useful computational tool for organizing, analyzing and interpreting large global datasets is Xarray, an open source project and Python package that makes working with labelled multi-dimensional arrays simple and efficient.

-

In this first tutorial, we will use the DataArray and Dataset objects, which are used to represent and manipulate spatial data, to practice organizing large global climate datasets and to understand variations in Earth’s climate system.

-
-
-

Setup#

-

Similar to numpy, np; pandas, pd; you may often encounter xarray imported within a shortened namespace as xr.

-
-
- - -Hide code cell content - -
-
# imports
-import numpy as np
-import pandas as pd
-import xarray as xr
-import matplotlib.pyplot as plt
-
-
-
-
-
-
-
-
-
-
-
-

Introducing the DataArray and Dataset#

-

Xarray expands on the capabilities on NumPy arrays, providing a lot of streamlined data manipulation. It is similar in that respect to Pandas, but whereas Pandas excels at working with tabular data, Xarray is focused on N-dimensional arrays of data (i.e. grids). Its interface is based largely on the netCDF data model (variables, attributes, and dimensions), but it goes beyond the traditional netCDF interfaces to provide functionality similar to netCDF-java’s Common Data Model (CDM).

-
-
-

Section 1: Creation of a DataArray Object#

-

The DataArray is one of the basic building blocks of Xarray (see docs here). It provides a numpy.ndarray-like object that expands to provide two critical pieces of functionality:

-
    -
  1. Coordinate names and values are stored with the data, making slicing and indexing much more powerful

  2. -
  3. It has a built-in container for attributes

  4. -
-

Here we’ll initialize a DataArray object by wrapping a plain NumPy array, and explore a few of its properties.

-
-

Section 1.1: Generate a Random Numpy Array#

-

For our first example, we’ll just create a random array of “temperature” data in units of Kelvin:

-
-
-
rand_data = 283 + 5 * np.random.randn(5, 3, 4)
-rand_data
-
-
-
-
-
-
-

Section 1.2: Wrap the Array: First Attempt#

-

Now we create a basic DataArray just by passing our plain data as an input:

-
-
-
temperature = xr.DataArray(rand_data)
-temperature
-
-
-
-
-

Note two things:

-
    -
  1. Xarray generates some basic dimension names for us (dim_0, dim_1, dim_2). We’ll improve this with better names in the next example.

  2. -
  3. Wrapping the numpy array in a DataArray gives us a rich display in the notebook! (Try clicking the array symbol to expand or collapse the view)

  4. -
-
-
-

Section 1.3: Assign Dimension Names#

-

Much of the power of Xarray comes from making use of named dimensions. So let’s add some more useful names! We can do that by passing an ordered list of names using the keyword argument dims:

-
-
-
temperature = xr.DataArray(rand_data, dims=["time", "lat", "lon"])
-temperature
-
-
-
-
-

This is already an improvement over a NumPy array because we have names for each of the dimensions (or axes). Even better, we can associate arrays representing the values for the coordinates for each of these dimensions with the data when we create the DataArray. We’ll see this in the next example.

-
-
-
-

Section 2: Create a DataArray with Named Coordinates#

-
-

Section 2.1: Make Time and Space Coordinates#

-

Here we will use Pandas to create an array of datetime data, which we will then use to create a DataArray with a named coordinate time.

-
-
-
times_index = pd.date_range("2018-01-01", periods=5)
-times_index
-
-
-
-
-

We’ll also create arrays to represent sample longitude and latitude:

-
-
-
lons = np.linspace(-120, -60, 4)
-lats = np.linspace(25, 55, 3)
-
-
-
-
-
-

Section 2.1.1: Initialize the DataArray with Complete Coordinate Info#

-

When we create the DataArray instance, we pass in the arrays we just created:

-
-
-
temperature = xr.DataArray(
-    rand_data, coords=[times_index, lats, lons], dims=["time", "lat", "lon"]
-)
-temperature
-
-
-
-
-
-
-

Section 2.1.2: Set Useful Attributes#

-

We can also set some attribute metadata, which will help provide clear descriptions of the data. In this case, we can specify that we’re looking at ‘air_temperature’ data and the units are ‘kelvin’.

-
-
-
temperature.attrs["units"] = "kelvin"
-temperature.attrs["standard_name"] = "air_temperature"
-
-temperature
-
-
-
-
-
-
-

Section 2.1.3: Attributes Are Not Preserved by Default!#

-

Notice what happens if we perform a mathematical operaton with the DataArray: the coordinate values persist, but the attributes are lost. This is done because it is very challenging to know if the attribute metadata is still correct or appropriate after arbitrary arithmetic operations.

-

To illustrate this, we’ll do a simple unit conversion from Kelvin to Celsius:

-
-
-
temperature_in_celsius = temperature - 273.15
-temperature_in_celsius
-
-
-
-
-

We usually wish to keep metadata with our dataset, even after manipulating the data. For example it can tell us what the units are of a variable of interest. So when you perform operations on your data, make sure to check that all the information you want is carried over. If it isn’t, you can add it back in following the instructions in the section before this. For an in-depth discussion of how Xarray handles metadata, you can find more information in the Xarray documents here.

-
-
-
-
-

Section 3: The Dataset: a Container for DataArrays with Shared Coordinates#

-

Along with DataArray, the other key object type in Xarray is the Dataset, which is a dictionary-like container that holds one or more DataArrays, which can also optionally share coordinates (see docs here).

-

The most common way to create a Dataset object is to load data from a file (which we will practice in a later tutorial). Here, instead, we will create another DataArray and combine it with our temperature data.

-

This will illustrate how the information about common coordinate axes is used.

-
-

Section 3.1: Create a Pressure DataArray Using the Same Coordinates#

-

For our next DataArry example, we’ll create a random array of pressure data in units of hectopascal (hPa). This code mirrors how we created the temperature object above.

-
-
-
pressure_data = 1000.0 + 5 * np.random.randn(5, 3, 4)
-pressure = xr.DataArray(
-    pressure_data, coords=[times_index, lats,
-                           lons], dims=["time", "lat", "lon"]
-)
-pressure.attrs["units"] = "hPa"
-pressure.attrs["standard_name"] = "air_pressure"
-
-pressure
-
-
-
-
-
-
-

Section 3.2: Create a Dataset Object#

-

Each DataArray in our Dataset needs a name!

-

The most straightforward way to create a Dataset with our temperature and pressure arrays is to pass a dictionary using the keyword argument data_vars:

-
-
-
ds = xr.Dataset(data_vars={"Temperature": temperature, "Pressure": pressure})
-ds
-
-
-
-
-

Notice that the Dataset object ds is aware that both data arrays sit on the same coordinate axes.

-
-
-

Section 3.3: Access Data Variables and Coordinates in a Dataset#

-

We can pull out any of the individual DataArray objects in a few different ways.

-

Using the “dot” notation:

-
-
-
ds.Pressure
-
-
-
-
-

… or using dictionary access like this:

-
-
-
ds["Pressure"]
-
-
-
-
-

We’ll return to the Dataset object when we start loading data from files in later tutorials today.

-
-
-
-

Summary#

-

In this initial tutorial, the DataArray and Dataset objects were utilized to create and explore synthetic examples of climate data.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2.html deleted file mode 100644 index 1fe29f7f6..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial2.html +++ /dev/null @@ -1,1751 +0,0 @@ - - - - - - - - - - - - Tutorial 2: Selection, Interpolation and Slicing — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2: Selection, Interpolation and Slicing#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind!

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

In the previous tutorial, we learned how to use Xarray to create DataArray and Dataset objects. Global climate datasets can be very large with multiple variables, and DataArrays and Datasets are very useful tools for organizing, comparing and interpreting such data. However, sometimes we are not interested in examining a global dataset but wish to examine a specific time or location. For example, we might want to look at climate variables in a particular region of Earth, and potentially compare that to another region. In order to carry-out such analyses, it’s useful to be able to extract and compare subsets of data from a global dataset.

-

In this tutorial, you will explore multiple computational tools in Xarray that allow you to select data from a specific spatial and temporal range. In particular, you will practice using:

-
    -
  • .sel(): select data based on coordinate values or date

  • -
  • .interp(): interpolate to any latitude/longitude location to extract data

  • -
  • slice(): to select a range (or slice) along one or more coordinates, we can pass a Python slice object to .sel()

  • -
-
-
-

Setup#

-
-
-
-
-

To explore these Xarray tools, first recreate the synthetic temperature and pressure DataArrays you generated in the previous tutorial, and combine these two DataArrays into a Dataset.

-
-
-

Section 1: Subsetting and Selection by Coordinate Values#

-

Since Xarray allows us to label coordinates, you can select data based on coordinate names and values, rather than array indices. We’ll explore this briefly here. First, we will recreate the temperature and pressure data from Tutorial 1.

-
-
-
# temperature data
-rand_data = 283 + 5 * np.random.randn(5, 3, 4)
-times_index = pd.date_range("2018-01-01", periods=5)
-lons = np.linspace(-120, -60, 4)
-lats = np.linspace(25, 55, 3)
-temperature = xr.DataArray(
-    rand_data, coords=[times_index, lats, lons], dims=["time", "lat", "lon"]
-)
-temperature.attrs["units"] = "kelvin"
-temperature.attrs["standard_name"] = "air_temperature"
-
-# pressure data
-pressure_data = 1000.0 + 5 * np.random.randn(5, 3, 4)
-pressure = xr.DataArray(
-    pressure_data, coords=[times_index, lats, lons], dims=["time", "lat", "lon"]
-)
-pressure.attrs["units"] = "hPa"
-pressure.attrs["standard_name"] = "air_pressure"
-
-# combinate temperature and pressure DataArrays into a Dataset called 'ds'
-ds = xr.Dataset(data_vars={"Temperature": temperature, "Pressure": pressure})
-ds
-
-
-
-
-

To refresh your memory from the previous tutorial, take a look at the DataArrays you created for temperature and pressure by clicking on those variables in the dataset above.

-
-

Section 1.1: NumPy-like Selection#

-

Suppose you want to extract all the spatial data for one single date: January 2, 2018. It’s possible to achieve that with NumPy-like index selection:

-
-
-
indexed_selection = temperature[
-    1, :, :
-]  # index 1 along axis 0 is the time slice we want...
-indexed_selection
-
-
-
-
-

However, notice that this requires us (the user) to have detailed knowledge of the order of the axes and the meaning of the indices along those axes. By having named coordinates in Xarray, we can avoid this issue.

-
-
-

Section 1.2: .sel()#

-

Rather than using a NumPy-like index selection, in Xarray, we can instead select data based on coordinate values using the .sel() method, which takes one or more named coordinate(s) as a keyword argument:

-
-
-
named_selection = temperature.sel(time="2018-01-02")
-named_selection
-
-
-
-
-

We got the same result as when we used the NumPy-like index selection, but

-
    -
  • we didn’t have to know anything about how the array was created or stored

  • -
  • our code is agnostic about how many dimensions we are dealing with

  • -
  • the intended meaning of our code is much clearer!

  • -
-

By using the .sel() method in Xarray, we can easily isolate data from a specific time. You can also isolate data from a specific coordinate.

-
-

Coding Exercises 1.2#

-
    -
  1. Write a line of code to select the temperature data from the coordinates 25,-120.

  2. -
-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Write a line of code to select the temperature data from the coordinates 25,-120."
-)
-#################################################
-
-coordinate_selection = ...
-coordinate_selection
-
-
-
-
-
-
-
-

Section 1.3: Approximate Selection and Interpolation#

-

The spatial and temporal resolution of climate data often differs between datasets or a dataset may be incomplete. Therefore, with time and space data, we frequently want to sample “near” the coordinate points in our dataset. For example, we may want to analyze data from a specific coordinate or a specific time, but may not have a value from that specific location or date. In that case, we would want to use the data from the closest coordinate or time-step. Here are a few simple ways to achieve that.

-
-

Section 1.3.1: Nearest-neighbor Sampling#

-

Suppose we want to know the temperature from 2018-01-07. However, the last day on our time axis is 2018-01-05. We can therefore sample within two days of our desired date of 2018-01-07. We can do this using the .sel method we used earlier, but with the added flexibility of performing nearest neighbor sampling and specifying an optional tolerance. This is called an inexact lookup because we are not searching for a perfect match, although there may be one. Here the tolerance is the maximum distance away from our desired point Xarray will search for a nearest neighbor.

-
-
-
temperature.sel(time="2018-01-07", method="nearest", tolerance=timedelta(days=2))
-
-
-
-
-

Notice that the resulting data is from the date 2018-01-05.

-
-
-

Section 1.3.2: Interpolation#

-

The latitude values of our dataset are 25ºN, 40ºN, 55ºN, and the longitude values are 120ºW, 100ºW, 80ºW, 60ºW. But suppose we want to extract a timeseries for Boulder, Colorado, USA (40°N, 105°W). Since lon=-105 is not a point on our longitude axis, this requires interpolation between data points.

-

We can do this using the .interp() method (see the docs here), which works similarly to .sel(). Using .interp(), we can interpolate to any latitude/longitude location using an interpolation method of our choice. In the example below, you will linearly interpolate between known points.

-
-
-
temperature.interp(lon=-105, lat=40, method="linear")
-
-
-
-
-
- - - - - - - - - - - - - - -
<xarray.DataArray (time: 5)>
-array([277.79157613, 279.28025839, 283.06486385, 292.16980748,
-       281.24394557])
-Coordinates:
-  * time     (time) datetime64[ns] 2018-01-01 2018-01-02 ... 2018-01-05
-    lon      int64 -105
-    lat      int64 40
-Attributes:
-    units:          kelvin
-    standard_name:  air_temperature
-
-

In this case, we specified a linear interpolation method, yet one can choose other methods as well (e.g., nearest, cubic, quadratic). Note that the temperature values we extracted in the code cell above are not actual values in the dataset, but are instead calculated based on linear interpolations between values that are in the dataset.

-
-
-
-

Section 1.4: Slicing Along Coordinates#

-

Frequently we want to select a range (or slice) along one or more coordinate(s). For example, you may wish to only assess average annual temperatures in equatorial regions. We can achieve this by passing a Python slice object to .sel(). The calling sequence for slice always looks like slice(start, stop[, step]), where step is optional. In this case, let’s only look at values between 110ºW-70ºW and 25ºN-40ºN:

-
-
-
temperature.sel(
-    time=slice("2018-01-01", "2018-01-03"), lon=slice(-110, -70), lat=slice(25, 45)
-)
-
-
-
-
-
-
-

Section 1.5: One More Selection Method: .loc#

-

All of these operations can also be done within square brackets on the .loc attribute of the DataArray:

-
-
-
temperature.loc['2018-01-02']
-
-
-
-
-

This is sort of in between the NumPy-style selection

-
temp[1,:,:]
-
-
-

and the fully label-based selection using .sel()

-

With .loc, we make use of the coordinate values, but lose the ability to specify the names of the various dimensions. Instead, the slicing must be done in the correct order:

-
-
-
temperature.loc['2018-01-01':'2018-01-03', 25:45, -110:-70]
-
-
-
-
-

One advantage of using .loc is that we can use NumPy-style slice notation like 25:45, rather than the more verbose slice(25,45). But of course that also works:

-
-
-
temperature.loc["2018-01-01":"2018-01-03", slice(25, 45), -110:-70]
-
-
-
-
-

What doesn’t work is passing the slices in a different order to the dimensions of the dataset:

-
-
-
# This will generate an error
-# temperature.loc[-110:-70, 25:45,'2018-01-01':'2018-01-03']
-
-
-
-
-
-
-
-

Summary#

-

In this tutorial, we have explored the practical use of .sel() .interp() .loc(): and slicing techniques to extract data from specific spatial and temporal ranges. These methods are valuable when we are intereseted in only certain pieces of large datasets.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3.html deleted file mode 100644 index 8bc551656..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial3.html +++ /dev/null @@ -1,1370 +0,0 @@ - - - - - - - - - - - - Tutorial 3: Opening and Plotting netCDF Data — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3: Opening and Plotting netCDF Data#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

Many global climate datasets are stored as NetCDF (network Common Data Form) files. NetCDF is a file format for storing multidimensional variables such as temperature, humidity, pressure, wind speed, and direction. These types of files also include metadata that gives you information about the variables and dataset itself.

-

In this tutorial, we will import atmospheric pressure and temperature data stored in a NetCDF file. We will learn how to use various attributes of Xarray to import, analyze, interpret, and plot the data.

-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: Opening netCDF Data#

-

Xarray is closely linked with the netCDF data model, and it even treats netCDF as a ‘first-class’ file format. This means that Xarray can easily open netCDF datasets. However, these datasets need to follow some of Xarray’s rules. One such rule is that coordinates must be 1-dimensional.

-

Here we’re getting the data from Project Pythia’s custom library of example data, which we already imported above with from pythia_datasets import DATASETS. The DATASETS.fetch() method will automatically download and cache (store) our example data file NARR_19930313_0000.nc locally.

-
-
-
filepath = DATASETS.fetch("NARR_19930313_0000.nc")
-
-
-
-
-

Once we have a valid path to a data file that Xarray knows how to read, we can open it like this:

-
-
-
ds = xr.open_dataset(filepath)
-ds
-
-
-
-
-
-

Questions 1#

-
    -
  1. What are the dimensions of this dataset?

  2. -
  3. How many climate variables are in this dataset?

  4. -
-
-
-

Section 1.1: Subsetting the Dataset#

-

Our call to xr.open_dataset() above returned a Dataset object that we’ve decided to call ds. We can then pull out individual fields. First, let’s assess the isobaric1 values. Isobaric means characterized by constant or equal pressure. Let’s look at the isobaric1 values:

-
-
-
ds.isobaric1
-# Recall that we can also use dictionary syntax like `ds['isobaric1']` to do the same thing
-
-
-
-
-

The isobaric1 coordinate contains 29 pressure values (in hPa) corresponding to different pressures of the atmosphere. Recall from the video that pressure decreases with height in the atmosphere. Therefore, in our dataset lower atmospheric pressure values will correspond to higher altitudes. For each isobaric pressure value, there is data for all other variables in the dataset at that same pressure level of the atmosphere:

-
    -
  • Wind: the u and v components of the wind describe the direction of wind movement along a pressure level of the atmosphere. The U wind component is parallel to the x-axis (i.e. longitude) and the V wind component is parallel to the y- axis (i.e. latitude).

  • -
  • Temperature: temperatures on a specific atmospheric pressure level

  • -
  • Geopotential Height: the height of a given point in the atmosphere in units proportional to the potential energy of unit mass (geopotential) at this height relative to sea level

  • -
-

Let’s explore this Dataset a bit further.

-

Datasets also support much of the same subsetting operations as DataArray, but will perform the operation on all data. Let’s subset all data from an atmospheric pressure of 1000 hPa (the typical pressure at sea level):

-
-
-
ds_1000 = ds.sel(isobaric1=1000.0)
-ds_1000
-
-
-
-
-

We can further subset to a single DataArray to isolate a specific climate measurement. Let’s subset temperature from the atmospheric level at which the isobaric pressure is 1000 hPa:

-
-
-
ds_1000.Temperature_isobaric
-
-
-
-
-
-
-

Section 1.2: Aggregation Operations#

-

Not only can you use the named dimensions for manual slicing and indexing of data (as we saw in the last tutorial), but you can also use it to control aggregation operations (e.g., average, sum, standard deviation). Aggregation methods for Xarray objects operate over the named coordinate dimensions specified by keyword argument dim.

-

First, let’s try calculating the std (standard deviation) of the u component of the isobaric wind from our Dataset. The following code will calculate the standard deviation of all the u-component_of_wind_isobaric values at each isobaric level. In other words, we’ll end up with one standard deviation value for each of the 29 isobaric levels. Note: because of the ‘-’ present in the name, we cannot use dot notation to select this variable and must use a dictionary key style selection instead.

-
-
-
# get wind data
-u_winds = ds["u-component_of_wind_isobaric"]
-
-# take the standard deviation
-u_winds.std(dim=["x", "y"])
-
-
-
-
-

Side note: Recall that the U wind component is parallel to the x-axis (i.e. longitude) and the V wind component is parallel to the y- axis (i.e. latitude). A positive U wind comes from the west, and a negative U wind comes from the east. A positive V wind comes from the south, and a negative V wind comes from the north.

-

Next, let’s try calculating the mean of the temperature profile (temperature as a function of pressure) over a specific region. For this exercise, we will calculate the temperature profile over Colorado, USA. The bounds of Colorado are:

-
    -
  • x: -182km to 424km

  • -
  • y: -1450km to -990km

  • -
-

If you look back at the values for x and y in our dataset, the units for these values are kilometers (km). Remember that they are also the coordinates for the lat and lon variables in our dataset. The bounds for Colorado correspond to the coordinates 37°N to 41°N and 102°W to 109°W.

-
-
-
# get the temperature data
-temps = ds.Temperature_isobaric
-
-# take just the spatial data we are interested in for Colorado
-co_temps = temps.sel(x=slice(-182, 424), y=slice(-1450, -990))
-
-# take the average
-prof = co_temps.mean(dim=["x", "y"])
-prof
-
-
-
-
-
-
-
-

Section 2: Plotting with Xarray#

-

Another major benefit of using labeled data structures is that they enable automated plotting with axis labels.

-
-

Section 2.1: Simple Visualization with .plot()#

-

Much like Pandas, Xarray includes an interface to Matplotlib that we can access through the .plot() method of every DataArray.

-

For quick and easy data exploration, we can just call .plot() without any modifiers:

-
-
-
prof.plot()
-
-
-
-
-

Here Xarray has generated a line plot of the temperature data against the coordinate variable isobaric. Also, the metadata are used to auto-generate axis labels and units.

-

Consider the following questions:

-
    -
  • What isobaric pressure corresponds to Earth’s surface?

  • -
  • How does temperature change with increasing altitude in the atmosphere?

  • -
-

It might be a bit difficult to answer these questions with our current plot, so let’s try customizing our figure to present the data clearer.

-
-
-

Section 2.2: Customizing the Plot#

-

As in Pandas, the .plot() method is mostly just a wrapper to Matplotlib, so we can customize our plot in familiar ways.

-

In this air temperature profile example, we would like to make two changes:

-
    -
  • swap the axes so that we have isobaric levels on the y (vertical) axis of the figure (since isobaric levels correspond to altitude)

  • -
  • make pressure decrease upward in the figure, so that up is up (since pressure decreases with altitude)

  • -
-

We can do this by adding a few keyword arguments to our .plot():

-
-
-
prof.plot(y="isobaric1", yincrease=False)
-
-
-
-
-
-

Questions 2.2#

-
    -
  1. What isobaric pressure corresponds to Earth’s surface?

  2. -
  3. Why do you think temperature generally decreases with height?

  4. -
-
-
-
-

Section 2.3: Plotting 2D Data#

-

In the example above, the .plot() method produced a line plot.

-

What if we call .plot() on a 2D array? Let’s try plotting the temperature data from the 1000 hPa isobaric level (surface temperature) for all x and y values:

-
-
-
temps.sel(isobaric1=1000).plot()
-
-
-
-
-

Xarray has recognized that the DataArray object calling the plot method has two coordinate variables, and generates a 2D plot using the pcolormesh method from Matplotlib.

-

In this case, we are looking at air temperatures on the 1000 hPa isobaric surface over North America. Note you could improve this figure further by using Cartopy to handle the map projection and geographic features.

-
-

Questions 2.2: Climate Connection#

-
    -
  1. The map you made is showing temperature across the United States at the 1000 hPa level of the atmosphere. How do you think temperatures at the 500 hPa level would compare? What might be causing the spatial differences in temperature seen in the map?

  2. -
-
-
-
-
-

Summary#

-

Xarray brings the joy of Pandas-style labeled data operations to N-dimensional data. As such, it has become a central workhorse in the geoscience community for analyzing gridded datasets. Xarray allows us to open self-describing NetCDF files and make full use of the coordinate axes, labels, units, and other metadata. By utilizing labeled coordinates, our code becomes simpler to write, easier to read, and more robust.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4.html deleted file mode 100644 index 5d3d5f201..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial4.html +++ /dev/null @@ -1,1302 +0,0 @@ - - - - - - - - - - - - Tutorial 4: Arithmetic and Aggregation Methods — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 4: Arithmetic and Aggregation Methods#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

As we just learned in the video, alongside the latitudinal temperature gradients set by solar radiation, the large-scale ocean circulation patterns are one of the main controls on global sea surface temperature (SST, or tos). The surface currents distort this meridional gradient and can transport heat globally. In this tutorial, we’ll use a series of tools in Xarray to interpret sea surface temperature data.

-

Specifically, we’ll import monthly SST data from the Community Earth System Model v2 (CESM2), which is a Global Climate Model. A climate model is a mathematical representation of Earth’s climate system components and their interactions. Climate models are based on well-documented physical processes to simulate the transfer of energy and materials through the climate system. You’ll learn more about climate models later this week and next week, but for now, we’re going to be working with SST data produced from a climate model.

-

To assess global variations in this SST dataset, we will practice using multiple attributes of Xarray:

-
    -
  • Arithmetic methods to convert temperatures from Celsius to Kelvin

  • -
  • Aggregation methods to calculate mean, median, minimum and maximum values of the data.

  • -
-

Finally, we’ll create a map of global mean annual SST to visualize spatial variations in SST.

-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: Arithmetic Operations#

-

Arithmetic operations with a single DataArray automatically apply over all array values (like NumPy). This process is called vectorization. First, let’s open the monthly sea surface temperature (SST) data from the Community Earth System Model v2 (CESM2), which is a Global Climate Model.

-
-
-
filepath = DATASETS.fetch("CESM2_sst_data.nc")
-ds = xr.open_dataset(filepath)
-ds
-
-
-
-
-

And look at the temeprature variable tos.

-
-
-
ds.tos
-
-
-
-
-

Note in the attributes that the units are ‘degC’. One arithmetic operation we can do is to the convert the temperature from degrees Celsius to Kelvin:

-
-
-
ds.tos + 273.15
-
-
-
-
-

You may notice that there are a lot of NaN values in the DataArray for tos. NaN isn’t a bad thing and it just means there isn’t data for those coordinates. In this case, there’s no tos data for areas with land since this dataset only contains SST values.

-

Just to practice another arithmetic operation, lets’s square all values in tos:

-
-
-
ds.tos**2
-
-
-
-
-
-
-

Section 2: Aggregation Methods#

-

A very common step during data analysis is to summarize the data in question by computing aggregations like sum(), mean(), median(), min(), max() in which reduced data provide insight into the nature of the large dataset. For example, in the introductory video for this tutorial, we saw maps of the mean annual sea surface temperature and sea surface density.

-

The following table summarizes some other built-in xarray aggregations:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Aggregation

Description

count()

Total number of items

mean(), median()

Mean and median

min(), max()

Minimum and maximum

std(), var()

Standard deviation and variance

prod()

Compute product of elements

sum()

Compute sum of elements

argmin(), argmax()

Find index of minimum and maximum value

-

Let’s explore some of these aggregation methods.

-

Compute the temporal minimum:

-
-
-
ds.tos.min(dim="time")
-
-
-
-
-

Compute the spatial sum:

-
-
-
ds.tos.sum(dim=["lat", "lon"])
-
-
-
-
-

Compute the temporal median:

-
-
-
ds.tos.median(dim="time")
-
-
-
-
-

Compute the mean SST:

-
-
-
ds.tos.mean()
-
-
-
-
-

Because we specified no dim argument, the function was applied over all dimensions, computing the mean of every element of tos across time and space. It is possible to specify a dimension along which to compute an aggregation. For example, to calculate the mean in time for all locations (i.e. the global mean annual SST), specify the time dimension as the dimension along which the mean should be calculated:

-
-
-
ds.tos.mean(dim="time").plot(size=7, vmin=-2, vmax=32, cmap="coolwarm")
-
-
-
-
-
-

Questions 2: Climate Connection#

-

Observe the spatial patterns in SST and consider the following in the context of the components of the ocean climate system we learned about in the video:

-
    -
  1. Recall that upwelling commonly occurs off the west coast of continents, for example, in the eastern tropical Pacific off the west coast of South America. Do you see evidence for upwelling in this region? How do you think the mean SST in this region would change if you looked at a specific season rather than the annual mean? Would upwelling be more or less evident?

  2. -
-
-
-
-

Summary#

-

In this tutorial, we have explored the use of the CESM2 and have imported and analyzed monthly sea surface temperature (SST, or tos) data. We used arithmetic methods to convert SST from Celsius to Kelvin, and aggregation methods such as the mean, median, minimum, and maximum values of the data. To conclude, we visualized the spatial variations in SST by generating a map of the global mean annual SST. This tutorial has provided us with valuable insights into global variations in SST and how to manipulate and analyze such data using Xarray.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.html deleted file mode 100644 index 49563693d..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial5.html +++ /dev/null @@ -1,1318 +0,0 @@ - - - - - - - - - - - - Tutorial 5: Xarray Data Analysis and Climatology — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 5: Xarray Data Analysis and Climatology#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

Global climate can vary on long timescales, but it’s also important to understand seasonal variations. For example, seasonal variations in precipitation associated with the migration of the Intertropical Convergence Zone (ITCZ) and monsoon systems occur in response to seasonal changes in temperature. In this tutorial, we will use data analysis tools in Xarray to explore the seasonal climatology of global temperature. Specifically, in this tutorial, we’ll use the groupby operation in Xarray, which involves the following steps:

-
    -
  • Split: group data by value (e.g., month).

  • -
  • Apply: compute some function (e.g., aggregate) within the individual groups.

  • -
  • Combine: merge the results of these operations into an output dataset.

  • -
-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: GroupBy: Split, Apply, Combine#

-

Simple aggregations (as we learned in the previous tutorial) can give useful summary of our dataset, but often we would prefer to aggregate conditionally on some coordinate labels or groups. Xarray provides the so-called groupby operation which enables the split-apply-combine workflow on Xarray DataArrays and Datasets. The split-apply-combine operation is illustrated in this figure from Project Pythia:

-split-apply-combine -
    -
  • The split step involves breaking up and grouping an xarray Dataset or DataArray depending on the value of the specified group key.

  • -
  • The apply step involves computing some function, usually an aggregate, transformation, or filtering, within the individual groups.

  • -
  • The combine step merges the results of these operations into an output xarray Dataset or DataArray.

  • -
-

We are going to use groupby to remove the seasonal cycle (“climatology”) from our dataset, which will allow us to better observe long-term trends in the data. See the xarray groupby user guide for more examples of what groupby can take as an input.

-

Let’s start by loading the same data that we used in the previous tutorial (monthly SST data from CESM2):

-
-
-
filepath = DATASETS.fetch("CESM2_sst_data.nc")
-ds = xr.open_dataset(filepath)
-ds
-
-
-
-
-

Then, let’s select a gridpoint closest to a specified lat-lon (in this case let’s select 50ºN, 310ºE), and plot a time series of SST at that point (recall that we learned this is Tutorial 2). The annual cycle will be quite pronounced. Note that we are using the nearest method (see Tutorial 2 for a refresher) to find the points in our datasets closest to the lat-lon values we specify. What this returns may not match these inputs exactly.

-
-
-
ds.tos.sel(
-    lon=310, lat=50, method="nearest"
-).plot()  # time range is 2000-01-15 to 2014-12-15
-
-
-
-
-

This plot is showing changes in monthly SST between 2000-01-15 to 2014-12-15. The annual cycle of SST change is apparent in this figure, but to understand the climatatology of this region, we need to calculate the average SST for each month over this time period. The first step is to split the data into groups based on month.

-
-

Section 1.1: Split#

-

Let’s group data by month, i.e. all Januaries in one group, all Februaries in one group, etc.

-
-
-
ds.tos.groupby(ds.time.dt.month)
-
-
-
-
-
-

In the above code, we are using the .dt DatetimeAccessor to extract specific components of dates/times in our time coordinate dimension. For example, we can extract the year with ds.time.dt.year. See also the equivalent Pandas documentation.

-

Xarray also offers a more concise syntax when the variable you’re grouping on is already present in the dataset. This is identical to ds.tos.groupby(ds.time.dt.month):

-
-
-
ds.tos.groupby("time.month")
-
-
-
-
-
-
-

Section 1.2: Apply & Combine#

-

Now that we have groups defined, it’s time to “apply” a calculation to the group. These calculations can either be:

-
    -
  • aggregation: reduces the size of the group

  • -
  • transformation: preserves the group’s full size

  • -
-

At then end of the apply step, xarray will automatically combine the aggregated/transformed groups back into a single object.

-
-

Section 1.2.1: Compute the Climatology#

-

Let’s calculate the climatology at every point in the dataset. To do so, we will use aggregation and will calculate the mean SST for each month:

-
-
-
tos_clim = ds.tos.groupby("time.month").mean()
-tos_clim
-
-
-
-
-

For every spatial coordinate, we now have a monthly mean SST for the time period 2000-01-15 to 2014-12-15.

-

We can now plot the climatology at a specific point:

-
-
-
tos_clim.sel(lon=310, lat=50, method="nearest").plot()
-
-
-
-
-

Based on this plot, the climatology of this location is defined by cooler SST from December to April and warmer SST from June to October, with an annual SST range of ~8ºC.

-
-

Questions 1.2.1: Climate Connection#

-
    -
  1. Considering the latitude and longitude of this data, can you explain why we observe this climatology?

  2. -
  3. How do you think seasonal variations in SST would differ at the equator? What about at the poles? What about at 50ºS?

  4. -
-
-
-
-

Section 1.2.2: Spatial Variations#

-

We can now add a spatial dimension to this plot and look at the zonal mean climatology (the monthly mean SST at different latitudes):

-
-
-
tos_clim.mean(dim="lon").transpose().plot.contourf(levels=12, cmap="turbo")
-
-
-
-
-

This gives us helpful information about the mean SST for each month, but it’s difficult to asses the range of monthly temperatures throughout the year using this plot.

-

To better represent the range of SST, we can calculate and plot the difference between January and July climatologies:

-
-
-
(tos_clim.sel(month=1) - tos_clim.sel(month=7)).plot(size=6, robust=True)
-
-
-
-
-
-

Questions 1.2.1: Climate Connection#

-
    -
  1. What patterns do you observe in this map?

  2. -
  3. Why is there such an apparent difference between the Northern and Southern Hemisphere SST changes?

  4. -
  5. How does the migration of the ITCZ relate to seasonal changes in Northern vs. Southern Hemisphere temperatures?

  6. -
-
-
-
-
-
-

Summary#

-

In this tutorial, we focused on exploring seasonal climatology in global temperature data using the split-apply-combine approach in Xarray. By utilizing the split-apply-combine approach, we gained insights into the seasonal climatology of temperature and precipitation data, enabling us to analyze and understand the seasonal variations associated with global climate patterns.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6.html deleted file mode 100644 index 456ae4212..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial6.html +++ /dev/null @@ -1,1310 +0,0 @@ - - - - - - - - - - - - Tutorial 6: Compute and Plot Temperature Anomalies — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Tutorial 6: Compute and Plot Temperature Anomalies

- -
- -
-
- - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 6: Compute and Plot Temperature Anomalies#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

In the previous tutorials, we have explored global climate patterns and processes, focusing on the terrestrial, atmospheric and oceanic climate systems. We have understood that Earth’s energy budget, primarily controlled by incoming solar radiation, plays a crucial role in shaping Earth’s climate. In addition to these factors, there are other significant long-term climate forcings that can influence global temperatures. To gain insight into these forcings, we need to look into historical temperature data, as it offers a valuable point of comparison for assessing changes in temperature and understanding climatic influences.

-

Recent and future temperature change is often presented as an anomaly relative to a past climate state or historical period. For example, past and future temperature changes relative to pre-industrial average temperature is a common comparison.

-

In this tutorial, our objective is to deepen our understanding of these temperature anomalies. We will compute and plot the global temperature anomaly from 2000-01-15 to 2014-12-1, providing us with a clearer perspective on recent climatic changes.

-
-
-

Setup#

-
-
-
# @title Video 1: Orbital Cycles
-
-from ipywidgets import widgets
-from IPython.display import YouTubeVideo
-from IPython.display import IFrame
-from IPython.display import display
-
-
-class PlayVideo(IFrame):
-  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
-    self.id = id
-    if source == 'Bilibili':
-      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
-    elif source == 'Osf':
-      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
-    super(PlayVideo, self).__init__(src, width, height, **kwargs)
-
-
-def display_videos(video_ids, W=400, H=300, fs=1):
-  tab_contents = []
-  for i, video_id in enumerate(video_ids):
-    out = widgets.Output()
-    with out:
-      if video_ids[i][0] == 'Youtube':
-        video = YouTubeVideo(id=video_ids[i][1], width=W,
-                             height=H, fs=fs, rel=0)
-        print(f'Video available at https://youtube.com/watch?v={video.id}')
-      else:
-        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
-                          height=H, fs=fs, autoplay=False)
-        if video_ids[i][0] == 'Bilibili':
-          print(f'Video available at https://www.bilibili.com/video/{video.id}')
-        elif video_ids[i][0] == 'Osf':
-          print(f'Video available at https://osf.io/{video.id}')
-      display(video)
-    tab_contents.append(out)
-  return tab_contents
-
-
-video_ids = [('Youtube', 'CdZkSWnfvYs'), ('Bilibili', 'BV1p8411D7ic')]
-tab_contents = display_videos(video_ids, W=730, H=410)
-tabs = widgets.Tab()
-tabs.children = tab_contents
-for i in range(len(tab_contents)):
-  tabs.set_title(i, video_ids[i][0])
-display(tabs)
-
-
-
-
-
-
-

Section 1: Compute Anomaly#

-

First, let’s load the same data that we used in the previous tutorial (monthly SST data from CESM2):

-
-
-
filepath = DATASETS.fetch("CESM2_sst_data.nc")
-ds = xr.open_dataset(filepath)
-ds
-
-
-
-
-

We’ll compute the climatology using xarray’s groupby operation to split the SST data by month. Then, we’ll remove this climatology from our original data to find the anomaly:

-
-
-
# group all data by month
-gb = ds.tos.groupby("time.month")
-
-# take the mean over time to get monthly averages
-tos_clim = gb.mean(dim="time")
-
-# subtract this mean from all data of the same month
-tos_anom = gb - tos_clim
-tos_anom
-
-
-
-
-

Let’s try plotting the anomaly from a specific location:

-
-
-
tos_anom.sel(lon=310, lat=50, method="nearest").plot()
-plt.ylabel("tos anomaly")
-
-
-
-
-

Next, let’s compute and visualize the mean global anomaly over time. We need to specify both lat and lon dimensions in the dim argument to mean():

-
-
-
unweighted_mean_global_anom = tos_anom.mean(dim=["lat", "lon"])
-unweighted_mean_global_anom.plot()
-plt.ylabel("global mean tos anomaly")
-
-
-
-
-

Notice that we called our variable unweighted_mean_global_anom. Next, we are going to compute the weighted_mean_global_anom. Why do we need to weight our data? Grid cells with the same range of degrees latitude and longitude are not necessarily same size. Specifically, grid cells closer to the equator are much larger than those near the poles, as seen in the figure below (Djexplo, 2011, CC-BY).

-area by latitude -

Therefore, an operation which combines grid cells of different size is not scientifically valid unless each cell is weighted by the size of the grid cell. Xarray has a convenient .weighted() method to accomplish this.

-

Let’s first load the grid cell area data from another CESM2 dataset that contains the weights for the grid cells:

-
-
-
filepath2 = DATASETS.fetch("CESM2_grid_variables.nc")
-areacello = xr.open_dataset(filepath2).areacello
-areacello
-
-
-
-
-

Let’s calculate area-weighted mean global anomaly:

-
-
-
weighted_mean_global_anom = tos_anom.weighted(
-    areacello).mean(dim=["lat", "lon"])
-
-
-
-
-

Let’s plot both unweighted and weighted means:

-
-
-
unweighted_mean_global_anom.plot(size=7)
-weighted_mean_global_anom.plot()
-plt.legend(["unweighted", "weighted"])
-plt.ylabel("global mean tos anomaly")
-
-
-
-
-
-

Questions 1: Climate Connection#

-
    -
  1. What is the significance of calculating area-weighted mean global temperature anomalies when assessing climate change? How are the weighted and unweighted SST means similar and different?

  2. -
  3. What overall trends do you observe in the global SST mean over this time? How does this magnitude and rate of temperature change compare to past temperature variations on longer timescales (refer back to the figures in the video)?

  4. -
-
-
-
-

Summary#

-

In this tutorial, we focused on historical temperature changes. We computed and plotted the global temperature anomaly from 2000 to 2014. This helped us enhance our understanding of recent climatic changes and their potential implications for the future.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7.html deleted file mode 100644 index 336624bc4..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial7.html +++ /dev/null @@ -1,1315 +0,0 @@ - - - - - - - - - - - - Tutorial 7: Other Computational Tools in Xarray — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 7: Other Computational Tools in Xarray#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

Thus far, we’ve learned about various climate processes in the videos, and we’ve explored tools in Xarray that are useful for analyzing and interpreting climate data.

-

In this tutorial you’ll continue using the SST data from CESM2 and practice using some additional computational tools in Xarray to resample your data, which can help with data comparison and analysis. The functions you will use are:

-
    -
  • resample: Groupby-like functionality specifically for time dimensions. Can be used for temporal upsampling and downsampling. Additional information about resampling in Xarray can be found here.

  • -
  • rolling: Useful for computing aggregations on moving windows of your dataset e.g. computing moving averages. Additional information about resampling in Xarray can be found here.

  • -
  • coarsen: Generic functionality for downsampling data. Additional information about resampling in Xarray can be found here.

  • -
-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: High-level Computation Functionality#

-

In this tutorial you will learn about several methods for dealing with the resolution of data. Here are some links for quick reference, and we will go into detail in each of them in the sections below.

- -

First, let’s load the same data that we used in the previous tutorial (monthly SST data from CESM2):

-
-
-
filepath = DATASETS.fetch("CESM2_sst_data.nc")
-ds = xr.open_dataset(filepath)
-ds
-
-
-
-
-
-

Section 1.1: Resampling Data#

-

For upsampling or downsampling temporal resolutions, we can use the resample() method in Xarray. For example, you can use this function to downsample a dataset from hourly to 6-hourly resolution.

-

Our original SST data is monthly resolution. Let’s use resample() to downsample to annual frequency:

-
-
-
# resample from a monthly to an annual frequency
-tos_yearly = ds.tos.resample(time="AS")
-tos_yearly
-
-
-
-
-
-
-
# calculate the global mean of the resampled data
-annual_mean = tos_yearly.mean()
-annual_mean_global = annual_mean.mean(dim=["lat", "lon"])
-annual_mean_global.plot()
-
-
-
-
-
-
-

Section 1.2: Moving Average#

-

The rolling() method allows for a rolling window aggregation and is applied along one dimension using the name of the dimension as a key (e.g. time) and the window size as the value (e.g. 6). We will use these values in the demonstration below.

-

Let’s use the rolling() function to compute a 6-month moving average of our SST data:

-
-
-
# calculate the running mean
-tos_m_avg = ds.tos.rolling(time=6, center=True).mean()
-tos_m_avg
-
-
-
-
-
-
-
# calculate the global average of the running mean
-tos_m_avg_global = tos_m_avg.mean(dim=["lat", "lon"])
-tos_m_avg_global.plot()
-
-
-
-
-
-
-

Section 1.3: Coarsening the Data#

-

The coarsen() function allows for block aggregation along multiple dimensions.

-

Let’s use the coarsen() function to take a block mean for every 4 months and globally (i.e., 180 points along the latitude dimension and 360 points along the longitude dimension). Although we know the dimensions of our data quite well, we will include code that finds the length of the latitude and longitude variables so that it could work for other datasets that had a different format.

-
-
-
# coarsen the data
-coarse_data = ds.coarsen(time=4, lat=len(ds.lat), lon=len(ds.lon)).mean()
-coarse_data
-
-
-
-
-
-
-
coarse_data.tos.plot()
-
-
-
-
-
-
-

Section 1.4: Compare the Resampling Methods#

-

Now that we’ve tried multiple resampling methods on different temporal resolutions, we can compare the resampled datasets to the original.

-
-
-
original_global = ds.mean(dim=["lat", "lon"])
-
-
-
-
-
-
-
original_global.tos.plot(size=6)
-coarse_data.tos.plot()
-tos_m_avg_global.plot()
-annual_mean_global.plot()
-
-
-plt.legend(
-    [
-        "original data (monthly)",
-        "coarsened (4 months)",
-        "moving average (6 months)",
-        "annually resampled (12 months)",
-    ]
-)
-
-
-
-
-
-

Questions 1.4: Climate Connection#

-
    -
  1. What type of information can you obtain from each time series?

  2. -
  3. In what scenarios would you use different temporal resolutions?

  4. -
-
-
-
-
-

Summary#

-

In this tutorial, we’ve explored Xarray tools to simplify and understand climate data better. Given the complexity and variability of climate data, tools like resample, rolling, and coarsen come in handy to make the data easier to compare and find long-term trends. You’ve also looked at valuable techniques like calculating moving averages.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8.html deleted file mode 100644 index 9de0873ba..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial8.html +++ /dev/null @@ -1,1246 +0,0 @@ - - - - - - - - - - - - Tutorial 8: Masking with One Condition — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 8: Masking with One Condition#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

One useful tool for assessing climate data is masking, which allows you to filter elements of a dataset according to a specific condition and create a “masked array” in which the elements not fulfilling the condition will not be shown. This tool is helpful if you wish to, for example, only look at data greater or less than a certain value, or from a specific temporal or spatial range. For instance, when analyzing a map of global precipitation, we could mask regions that contain a value of mean annual precipitation above or below a specific value or range of values in order to assess wet and dry seasons.

-

In this tutorial you will learn how to mask data with one condition, and will apply this to your map of global SST.

-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: Masking Data#

-

Using the xr.where() or .where() method, elements of an xarray Dataset or xarray DataArray that satisfy a given condition or multiple conditions can be replaced/masked. To demonstrate this, we are going to use the .where() method on the tos DataArray that we’ve been using in the past few tutorials.

-

Let’s load the same data that we used in the previous tutorial (monthly SST data from CESM2):

-
-
-
filepath = DATASETS.fetch("CESM2_sst_data.nc")
-ds = xr.open_dataset(filepath)
-ds
-
-
-
-
-
-

Section 1.1: Using where with One Condition#

-

Let’s say we want to analyze SST just from the last time in the dataset (2014-09-15). We can isolate this time using .isel():

-
-
-
sample = ds.tos.sel(time='2014-09')
-sample
-
-
-
-
-

Now that we have our DataArray from the desired time period, we can use another function, .where() to filter elements according to a condition. The conditional expression in .where() can be a DataArray, a Dataset or a function. Indexing methods on xarray objects generally return a subset of the original data. However, it is sometimes useful to select an object with the same shape as the original data, but with some elements masked. Unlike .isel() and .sel() that change the shape of the returned results, .where() preserves the shape of the original data. It accomplishes this by returning values from the original DataArray or Dataset if the condition is True, and fills in values (by default nan) wherever the condition is False. Additional information can be found in the .where() documentation.

-

Let’s use .where() to mask locations with temperature values greater than 0ºC. Note that the condition we supply to .where() are the regions we wish to preserve, not those we wish to mask. So if we are interested in masking temperature values that are above 0ºC, we will pass the condition to preserve those that are greater than or equal to 0ºC.

-
-
-
# preserve temperatures greater than or equal to 0, mask those that are less than 0
-masked_sample = sample.where(sample <= 0.0)
-masked_sample
-
-
-
-
-

Let’s plot both our original sample, and the masked sample for September 15th, 2014. Note we are using a different colorbar for the right hand figure, where the range of values is much smaller, and the same colors on the left would not correspond to the same colors on the right.

-
-
-
fig, axes = plt.subplots(ncols=2, figsize=(19, 6))
-sample.plot(ax=axes[0])
-masked_sample.plot(ax=axes[1])
-
-
-
-
-

Notice how in the figure on the right, only the SST from the areas where SST is below 0ºC is shown and the other areas are white since these are now NaN values. Now let’s assess how polar SST has changed over the time period recorded by the original dataset. To do so, we can run the same code but focus on the time 2000-09-15.

-
-
-
sample_2 = ds.tos.sel(time="2000-09")
-masked_sample_2 = sample_2.where(sample_2 < 0.0)
-fig, axes = plt.subplots(ncols=2, figsize=(19, 6))
-masked_sample_2.plot(ax=axes[0])
-masked_sample.plot(ax=axes[1])
-
-
-
-
-
-

Questions 1.1: Climate Connection#

-
    -
  1. What is the purpose of masking in the analysis of climate data?

  2. -
  3. Within the areas that are not masked, how does the distribution of SST compare between these maps?

  4. -
  5. The minimum sea ice extent in the Arctic typically occurs annually in September after spring has brought in more sunlight and warmer temperatures. Considering both plots of September SST above (from 2000 on the left and 2014 on the right), how might changes in the ice-albedo feedback be playing a role in what you observe? Please state any assumptions you would make in your answer.

  6. -
-
-
-
-
-

Summary#

-

In this tutorial, we’ve explored the application of masking tools in the analysis of Sea Surface Temperature (SST) maps. Through masking, we’ve been able to focus our attention on areas where the SST is below 0°C. These are the regions where changes in the ice-albedo feedback mechanism are most evident in our present day. This has facilitated a more targeted analysis and clearer understanding of the data.

-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9.html b/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9.html deleted file mode 100644 index 4b6df91fd..000000000 --- a/book/_build/html/tutorials/W1D1_ClimateSystemOverview/student/W1D1_Tutorial9.html +++ /dev/null @@ -1,1261 +0,0 @@ - - - - - - - - - - - - Tutorial 9: Masking with Multiple Conditions — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 9: Masking with Multiple Conditions#

-

Week 1, Day 1, Climate System Overview

-

Content creators: Sloane Garelick, Julia Kent

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

In the previous tutorial, you masked data using one condition (areas where SST was above 0ºC). You can also mask data using multiple conditions. For example, you can mask data from regions outside a certain spatial area by providing constraints on the latitude and longitude.

-

In this tutorial, you will practice masking data using multiple conditions in order to interpret SST in the tropical Pacific Ocean in the context of the El Niño Southern Oscillation (ENSO).

-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: Using .where() with multiple conditions#

-

First, let’s load the same data that we used in the previous tutorial (monthly SST data from CESM2):

-
-
-
filepath = DATASETS.fetch("CESM2_sst_data.nc")
-ds = xr.open_dataset(filepath)
-ds
-
-
-
-
-

.where() allows us to mask using multiple conditions. To do this, we need to make sure each conditional expression is enclosed in (). To combine conditions, we use the bit-wise and (&) operator and/or the bit-wise or (|). Let’s use .where() to isolate locations with temperature values greater than 25 and less than 30:

-
-
-
# take the last time step as our data
-sample = ds.tos.isel(time=-1)
-
-# just keep data between 25-30 C
-sample.where((sample > 25) & (sample < 30)).plot(size=6)
-
-
-
-
-
-
-

Section 2: Using .where() with a Custom Fill Value#

-

.where() can take a second argument, which, if supplied, defines a fill value for the masked region. Below we fill masked regions with a constant 0:

-
-
-
sample.where((sample > 25) & (sample < 30), 0).plot(size=6)
-
-
-
-
-
-
-

Section 3: Using .where() with Specific Coordinates#

-

We can use coordinates to apply a mask as well. For example, we can use a mask to assess tropical Pacific SST associated with the El Niño Southern Oscillation (ENSO). As we learned in the video, ENSO is a climate phenomena that originates in the tropical Pacific ocean but has global impacts on atmospheric circulation, temperature and precipitation. The two phases of ENSO are El Niño (warmer than average SSTs in the central and eastern tropical Pacific Ocean) and La Niña (cooler than average SSTs in the central and eastern tropical Pacific Ocean). The Niño 3.4 region is an area in the centeral and eastern Pacific Ocean that is often used for determining the phase of ENSO. Below, we will use the latitude and longitude coordinates to mask everywhere outside of the Niño 3.4 region. Note in our data that we are in degrees East, so the values we input for longitude will be shifted compared to the figure below.

-

-
-
-
# input the conditions for the latitude and longitude values we wish to preserve
-sample.where(
-    (sample.lat < 5) & (sample.lat > -5) & (sample.lon > 190) & (sample.lon < 240)
-).plot(size=6)
-
-
-
-
-

Now let’s look at a time series of the data from this masked region. Rather than specifying a certain time period, we can mask all areas outside of the Niño 3.4 region and then take the spatial mean to assess changes in Niño 3.4 SST over this time period.

-
-
-
nino = ds.tos.where(
-    (sample.lat < 5) & (sample.lat > -5) & (sample.lon > 190) & (sample.lon < 240)
-)
-
-nino_mean = ds.tos.mean(dim=["lat", "lon"])
-nino_mean
-
-
-
-
-
-
-
nino_mean.plot()
-
-
-
-
-
-

Questions 3: Climate Connection#

-
    -
  1. What patterns (e.g. cycles, trends) do you observe in this SST time series for the Niño 3.4 region?

  2. -
  3. What do you think might be responsible for the patterns you observe? What about any trends?

  4. -
  5. Notice that we did not use a weighted mean. Do you think the results would be very different if we did weight the mean?

  6. -
-
-
-
-

Summary#

-
    -
  • Similar to NumPy, arithmetic operations are vectorized over a DataArray

  • -
  • Xarray provides aggregation methods like sum() and mean(), with the option to specify which dimension over which the operation will be done

  • -
  • groupby enables the convenient split-apply-combine workflow

  • -
  • The .where() method allows for filtering or replacing of data based on one or more provided conditions

  • -
-
-
-

Resources#

-

Code and data for this tutorial is based on existing content from Project Pythia.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title.html deleted file mode 100644 index fabda0114..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - State of the Climate Ocean and Atmosphere Reanalysis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

State of the Climate Ocean and Atmosphere Reanalysis

- -
-
- -
-
-
- - - - -
- -
-

State of the Climate Ocean and Atmosphere Reanalysis#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading.html deleted file mode 100644 index 89c6f22f1..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/further_reading.html +++ /dev/null @@ -1,1062 +0,0 @@ - - - - - - - - - - - - Suggested Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Suggested Further Reading

- -
-
- -
-
-
- - - - -
- -
-

Suggested Further Reading#

- -
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary.html deleted file mode 100644 index 31db20ca8..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_DaySummary.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - - - - - - - Day Summary — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Day Summary

- -
-
- -
-
-
- - - - -
- -
-

Day Summary#

-

Day 2 explored the complex interplay between the ocean and atmosphere within the climate system. You began the day with an exploration of SST variations during El Niño and La Niña events, utilizing Xarray tools and the CESM2 model data. You then worked with reanalysis data to explore the large-scale circulation of the ocean and atmosphere, and the changes in ocean heat storage over recent decades.

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro.html deleted file mode 100644 index 17984c5a2..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Intro.html +++ /dev/null @@ -1,1133 +0,0 @@ - - - - - - - - - - - - Intro — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Intro

- -
-
- -
-

Contents

-
- -
-
-
- - - - -
- -
-

Intro#

-
-

Overview#

-

Welcome to the second day of the Computational Tools for Climate Science course! Today we dive into scientific exploration of the modern ocean and atmosphere systems using reanalysis datasets, building on yesterday’s climate system overview.

-

In the course of today’s study, you will leverage computational tools and datasets such as Xarray, climate models (CESM2), and reanalysis dataset (ERA5), to explore the large-scale properties of the ocean and atmosphere, and their interactions. You will start by diagnosing anomalies of sea surface temperature (SST), their relation to El Niño and La Niña events, and their influence on global atmospheric circulation patterns and ocean dynamics. You will then examine how large-scale ocean currents are driven by both atmospheric flow (wind-driven circulation) and ocean density variations (thermohaline circulation). Finally, you will investigate how the heat stored within different layers of the ocean has changed over recent decades, and the consequent impacts on Earth’s climate system.

-

Throughout Day 2, you will learn about large-scale ocean and atmospheric circulation, and develop familiarity with computational tools for the analysis and interpretation of complex climate data.

-
-
-

Video 1: Oceans in Climate#

-
-
-
-
-
-
-

Slides#

-
-
- - - - -
- - - - - - -
- - - -
- - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro.html deleted file mode 100644 index 62100c8ff..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Outro.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - - - - - - - Outro — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Outro

- -
-
- -
-
-
- - - - -
- -
-

Outro#

-

Today you have navigated through the large-scale structure of oceanic and atmospheric systems, utilizing reanalysis data and various computational tools to analyze and interpret ocean-atmospheric interactions. Tomorrow, you will transition your focus to remote sensing for climate applications, where you will also begin to explore the land system in addition to the ocean and atmosphere.

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1.html deleted file mode 100644 index 0230b17fb..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial1.html +++ /dev/null @@ -1,1518 +0,0 @@ - - - - - - - - - - - - Tutorial 1: Calculating ENSO with Xarray — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1: Calculating ENSO with Xarray#

-

Week 1, Day 2, Ocean-Atmosphere Reanalysis

-

Content creators: Abigail Bodner, Momme Hell, Aurora Basinski

-

Content reviewers: Yosemley Bermúdez, Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-

project pythia#

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

CMIP.png#

-
-
-
-

Tutorial Objectives#

-

In this notebook (adapted from Project Pythia), you will practice using multiple tools to examine sea surface temperature (SST) and explore variations in the climate system that occur during El Nino and La Nina events. You will learn to:

-
    -
  1. Load Sea Surface Temprature data from the CESM2 model

  2. -
  3. Mask data using .where()

  4. -
  5. Compute climatologies and anomalies using .groupby()

  6. -
  7. Use .rolling() to compute moving average

  8. -
  9. Compute, normalize, and plot the Oceanic Niño Index

  10. -
-

After completing the tasks above, you should be able to plot Oceanic Niño Index that looks similar to the figure below. The red and blue regions correspond to the phases of El Niño and La Niña respectively.

-

ONI index plot from NCAR Climate Data Guide

-

Credit: NCAR

-

Pythia credit: Rose, B. E. J., Kent, J., Tyle, K., Clyne, J., Banihirwe, A., Camron, D., May, R., Grover, M., Ford, R. R., Paul, K., Morley, J., Eroglu, O., Kailyn, L., & Zacharias, A. (2023). Pythia Foundations (Version v2023.05.01) https://zenodo.org/record/8065851

-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: Introduction to El Niño Southern Oscillation (ENSO)#

-

In W1D1 you practiced using Xarray to calculate a monthly climatology, climate anomalies, and a running average on monthly global Sea Surface Temperature (SST) data from the Community Earth System Model v2 (CESM2). You also used the .where() method to isolate SST data between 5ºN-5ºS and 190ºE-240ºE (or 170ºW-120ºW). This geographic region, known as the Niño 3.4 region, is in the tropical Pacific Ocean and is commonly used as a metric for determining the phase of the El Niño-Southern Oscillation (ENSO). ENSO is a recurring climate pattern involving changes in SST in the central and eastern tropical Pacific Ocean, which has two alternating phases:

-
    -
  • El Niño: the phase of ENSO characterized by warmer than average SSTs in the central and eastern tropical Pacific Ocean, weakened east to west equatorial winds and increased rainfall in the eastern tropical Pacific.

  • -
  • La Niña: the phase of ENSO which is characterized by cooler than average SSTs in the central and eastern tropical Pacific Ocean, stronger east to west equatorial winds and decreased rainfall in the eastern tropical Pacific.

  • -
-
-

Section 1.1: Tropical Pacific Climate Processes#

-

To better understand the climate system processes that result in El Niño and La Niña events, let’s first consider typical climate conditions in the tropical Pacific Ocean. Recall from W1D1, trade winds are winds that blow east to west just north and south of the equator (these are sometimes referred to as “easterly” winds since the winds are originating from the east and blowing toward the west). And as we discussed yesterday, the reason that the trade winds blow from east to west is related to Earth’s rotation, which causes the winds in the Northern Hemisphere to curve to the right and winds in the Southern Hemisphere to curve to the left. This is known as the Coriolis effect.

-

If Earth’s rotation affects air movement, do you think it also influences surface ocean water movement? It does! As trade winds blow across the tropical Pacific Ocean, they move water because of friction at the ocean surface. But because of the Coriolis effect, surface water moves to the right of the wind direction in the Northern Hemisphere and to the left of the wind direction in the Southern Hemisphere. However, the speed and direction of water movement changes with depth. Ocean surface water moves at an angle to the wind, and the water under the surface water moves at a slightly larger angle, and the water below that turns at an even larger angle. The average direction of all this turning water is about a right angle from the wind direction. This average is known as Ekman transport. Since this process is driven by the trade winds, the strength of this ocean water transport varies in response to changes in the strength of the trade winds.

-
-
-

Section 1.2: Ocean-Atmosphere Interactions During El Niño and La Niña#

-

So, how does all of this relate to El Niño and La Niña? Changes in the strength of Pacific Ocean trade winds and the resulting impact on Ekman transport create variations in the tropical Pacific Ocean SST, which further results in changes to atmospheric circulation patterns and rainfall.

-

During an El Niño event, easterly trade winds are weaker. As a result, less warm surface water is transported to the west via Ekman transport, which causes a build-up of warm surface water in the eastern equatorial Pacific. This creates warmer than average SSTs in the eastern equatorial Pacific Ocean. The atmosphere responds to this warming with increased rising air motion and above-average rainfall in the eastern Pacific. In contrast, during a La Niña event, easterly trade winds are stronger. As a result, more warm surface water is transported to the west via Ekman transport, and cool water from deeper in the ocean rises up in the eastern Pacific during a process known as upwelling. This creates cooler than average SSTs in the eastern equatorial Pacific Ocean. This cooling decreases rising air movement in the eastern Pacific, resulting in drier than average conditions.

-

In this tutorial, we’ll examine SST temperatures to explore variations in the climate system that occur during El Niño and La Niña events. Specifically, we will plot and interpret CESM2 SST data from the Niño 3.4 region.

-
-
-
-

Section 2: Calculate the Oceanic Niño Index#

-

In this notebook, we are going to combine several topics and methods you’ve covered so far to compute the Oceanic Niño Index using SST from the CESM2 submission to the CMIP6 project.

-

You will be working with CMIP6 data later in the week, particularly during W2D1. You can also learn more about CMIP, including additional methods to access CMIP data, please see our CMIP Resource Bank and the CMIP website.

-

To calculate the Oceanic Niño Index you will:

-
    -
  1. Select SST data from Niño 3.4 region of 5ºN-5ºS and 190ºE-240ºE (or 170ºW-120ºW) shown in the figure below.

  2. -
-

-
    -
  1. Compute the climatology (here from 2000-2014) for the Niño 3.4 region.

  2. -
  3. Compute the monthly anomaly for the Niño 3.4 region.

  4. -
  5. Compute the area-weighted mean of the anomalies for the Niño 3.4 region to obtain a time series.

  6. -
  7. Smooth the time series of anomalies with a 3-month running mean.

  8. -
-

Here we will briefly move through each of these steps, and tomorrow you will learn about them in more detail.

-
-

Section 2.1: Open the SST Data#

-

First, open the SST and areacello datasets, and use Xarray’s merge method to combine them into a single dataset:

-
-
-
# retrive (fetch) the SST data we are going to be working on
-SST_path = DATASETS.fetch("CESM2_sst_data.nc")
-
-# open the file we acquired with xarray
-SST_data = xr.open_dataset(SST_path)
-
-# remember that one degree spatial cell is not constant around the globe, each is a different size in square km.
-# we need to account for this when taking averages for example
-
-# fetch the weight for each grid cell
-gridvars_path = DATASETS.fetch("CESM2_grid_variables.nc")
-
-# open and save only the gridcell weights whose variable name is 'areacello'
-# here the 'o' at the end refers to the area cells of the 'ocean' grid
-areacello_data = xr.open_dataset(gridvars_path).areacello
-
-# merge the SST and weights into one easy to use dataset - ds stands for dataset
-ds_SST = xr.merge([SST_data, areacello_data])
-ds_SST
-
-
-
-
-

Visualize the first time point in the early 2000s. You can check this on the indexes of the variable ‘time’ from the ds_SST above. Note that using the plot function of our dataarray will automatically include this as a title when we select just the first time index.

-
-
-
# define the plot size
-fig = plt.figure(figsize=(12, 6))
-
-# asssign axis and define the projection -  for a round plot
-ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))
-
-# add coastlines - this will issue a download warning but that is ok
-ax.coastlines()
-
-# add gridlines (lon and lat)
-ax.gridlines()
-
-# plots the first time index (0) of SST (variable name 'tos') at the first time
-ds_SST.tos.isel(time=0).plot(
-    ax=ax,
-    transform=ccrs.PlateCarree(),  # give our axis a map projection
-    vmin=-2,
-    vmax=30,  # define the temp range of the colorbarfrom -2 to 30C
-    cmap="coolwarm",  # choose a colormap
-)
-
-
-
-
-
-

Interactive Demo 2.1#

-

You can visualize what the next few times look like in the model by using the interactive sliderbar below.

-
-
-
# a bit more complicated code that allows interactive plots
-gv.extension("bokeh")  # load Bokeh
-dataset_plot = gv.Dataset(
-    ds_SST.isel(time=slice(0, 10))
-)  # slice only the first 10 timepoint, as it is a time consuming task
-images = dataset_plot.to(gv.Image, ["longitude", "latitude"], "tos", "time")
-images.opts(
-    cmap="coolwarm",
-    colorbar=True,
-    width=600,
-    height=400,
-    projection=ccrs.Robinson(),
-    clabel="Sea Surface Temperature [˚C]",
-) * gf.coastline
-
-
-
-
-
-
-
-

Section 2.2: Select the Niño 3.4 Region#

-

You may have noticed that the lon for the SST data is organized between 0°–360°E.

-
-
-
ds_SST.lon
-
-
-
-
-

This is different from how we typically use longitude (-180°–180°). How do we covert the value of longitude between two systems (0-360° v.s. -180°–180°)?

-

Let’s use lon2 refer to the longitude system of 0°-360° while lon refers to the system of -180°–180°. 0°-360° is equivalent to 0–180°, -180°–0°.

-

In other words, lon2=181° is same as lon=-179°. Hence, in the western hemisphere, lon2=lon+360.

-

Therefore, the Niño 3.4 region should be (-5°–5°, 190–240°) using the lon2 system.

-

Now that we have identified the longitude values we need to select, there are a couple ways to select the Niño 3.4 region. We will demonstrate how to use both below.

-
    -
  1. sel()

  2. -
-
-
-
# select just the Nino 3.4 region (note our longitude values are in degrees east) by slicing
-tos_nino34_op1 = ds_SST.sel(lat=slice(-5, 5), lon=slice(190, 240))
-tos_nino34_op1
-
-
-
-
-
    -
  1. Use where() and select all values within the bounds of interest

  2. -
-
-
-
# select just the Nino 3.4 region (note our longitude values are in degrees east) by boolean conditioning
-tos_nino34_op2 = ds_SST.where(
-    (ds_SST.lat < 5) & (ds_SST.lat > -5) & (ds_SST.lon > 190) & (ds_SST.lon < 240),
-    drop=True,
-)  # use dataset where function. use boolean commands
-tos_nino34_op2
-
-
-
-
-

You can verify that tos_nino34_op1 and tos_nino34_op2 are the same by comparing the lat and lon indexes.

-

We only need one of these, so let us choose the second option and set that to the variable we will use moving forward.

-
-
-
# SST in just the Nino 3.4 region
-tos_nino34 = tos_nino34_op2
-
-
-
-
-

Let’s utilize the same code we used to plot the entire Earth, but this time focusing on the Niño 3.4 region slice only.

-
-
-
# define the figure size
-fig = plt.figure(figsize=(12, 6))
-
-# assign axis and projection
-ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))
-
-# add coastlines
-ax.coastlines()
-
-# add gridlines (lon and lat)
-ax.gridlines()
-
-# plot as above
-tos_nino34.tos.isel(time=0).plot(
-    ax=ax, transform=ccrs.PlateCarree(), vmin=-2, vmax=30, cmap="coolwarm"
-)
-
-# make sure we see more areas of the earth and not only the square around Niño 3.4
-ax.set_extent((120, 300, 10, -10))
-
-
-
-
-
-
-

Section 2.3: Compute the Climatology and Anomalies#

-

Now that we have selected our area, we can compute the monthly anomaly by first grouping all the data by month, then substracting the monthly climatology from each month.

-
-
-
# group the dataset by month
-tos_nino34_mon = tos_nino34.tos.groupby("time.month")
-
-# find the monthly climatology in the Nino 3.4 region
-tos_nino34_clim = tos_nino34_mon.mean(dim="time")
-
-# find the monthly anomaly in the Nino 3.4 region
-tos_nino34_anom = tos_nino34_mon - tos_nino34_clim
-
-# take the area weighted average of anomalies in the Nino 3.4 region
-tos_nino34_anom_mean = tos_nino34_anom.weighted(tos_nino34.areacello).mean(
-    dim=["lat", "lon"]
-)
-tos_nino34_anom_mean
-
-
-
-
-
-
-

Section 2.4: Smooth the Anomaly Time Series#

-

ENSO occurs on interannual timescales (a few years or more). To isolate the variability of this longer-term phenomenon on the Niño 3.4 region, we can smooth out the fluctuations due to variability on shorter timescales. To achieve this, we will apply a 3-month running mean to our time series of SST anomalies.

-
-
-
# smooth using a centered 3 month running mean
-oni_index = tos_nino34_anom_mean.rolling(time=3, center=True).mean()
-
-
-
-
-
-
-
# define the plot size
-fig = plt.figure(figsize=(12, 6))
-
-# assign axis
-ax = plt.axes()
-
-# plot the monhtly data on the assigned axis
-tos_nino34_anom_mean.plot(ax=ax)
-
-# plot the smoothed data on the assigned axis
-oni_index.plot(ax=ax)
-
-# add legend
-ax.legend(["monthly", "3-month running mean"])
-
-# add ylabel
-ax.set_ylabel("temprature anomalies")
-
-# add xlabel
-ax.set_xlabel("Year")
-
-
-
-
-
-
-
-

Section 3: Identify El Niño and La Niña Events#

-

We will highlight values in excess of \(\pm\)0.5, roughly corresponding to El Niño (warm) and La Niña (cold) events.

-
-
-
fig = plt.figure(figsize=(12, 6))  # assing figure size
-
-plt.fill_between(  # plot with color in between
-    oni_index.time.data,  # x values
-    oni_index.where(oni_index >= 0.5).data,  # top boundary - y values above 0.5
-    0.5,  # bottom boundary - 0.5
-    color="red",  # color
-    alpha=0.9,  # transparency value
-)
-plt.fill_between(
-    oni_index.time.data,
-    oni_index.where(oni_index <= -0.5).data,
-    -0.5,
-    color="blue",
-    alpha=0.9,
-)
-
-oni_index.plot(color="black")  # plot the smoothed data
-plt.axhline(0, color="black", lw=0.5)  # add a black line at x=0
-plt.axhline(
-    0.5, color="black", linewidth=0.5, linestyle="dotted"
-)  # add a black line at x=0.5
-plt.axhline(
-    -0.5, color="black", linewidth=0.5, linestyle="dotted"
-)  # add a black line at x=-0.5
-plt.title("Oceanic Niño Index (ONI)")
-
-
-
-
-
-

Questions 3:#

- -

Now that we’ve normalized the data and highlighted SST anomalies that correspond to El Niño (warm) and La Niña (cold) events, consider the following questions:

-
    -
  1. How frequently do El Niño and La Niña events occur over the period of time studied here?

  2. -
  3. When were the strongest El Niño and La Niña events over this time period?

  4. -
  5. Considering the ocean-atmosphere interactions that cause El Niño and La Niña events, can you hypothesize potential reasons one El Niño or La Niña event may be stronger than others?

  6. -
-
-
-
-

Summary#

-

In this tutorial, we have learned to utilize a variety of Xarray tools to examine variations in SST during El Niño and La Niña events. We’ve practiced loading SST data from the CESM2 model, and masking data using the .where() function for focused analysis. We have also computed climatologies and anomalies using the .groupby() function, and learned to compute moving averages using the .rolling() function. Finally, we have calculated, normalized, and plotted the Oceanic Niño Index (ONI), enhancing our understanding of the El Niño Southern Oscillation (ENSO) and its impacts on global climate patterns.

-
-
-

Resources#

-

Data from this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2.html deleted file mode 100644 index 9e7905e2a..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial2.html +++ /dev/null @@ -1,1515 +0,0 @@ - - - - - - - - - - - - Tutorial 2: A Lot of Weather Makes Climate - Exploring the ERA5 Reanalysis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2: A Lot of Weather Makes Climate - Exploring the ERA5 Reanalysis#

-

Week 1, Day 2, Ocean-Atmosphere Reanalysis

-

Content creators: Momme Hell

-

Content reviewers: Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In the previous tutorial, we learned about ENSO, which is a specific atmosphere-ocean dynamical phenomena. You will now examine the atmosphere and the ocean systems more generally.

-

In this tutorial, you will learn to work with reanalysis data. These data combine observations and models of the Earth system, and are a critical tool for weather and climate science. You will first utilize two methods to access a specific reanalysis dataset (ECMWF’s ERA5; through PO.DAAC and through the web Copernicus API). You will then select and mask a region of interest, investigating how important climate variables change on medium length timescales (hours to months) within this region.

-

By the end of this tutorial, you will be able to:

-
    -
  • Access and select reanalysis data of cliamtically-important variables

  • -
  • Plot maps to explore changes on various time scales.

  • -
  • Compute and compare timeseries of different variables from reanalysis data.

  • -
-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: What is Reanalysis Data?#

-

Reanalysis refers to the process of combining historical observations from a variety of sources, such as weather stations, satellite measurments, and ocean buoys, with numerical models to create a comprehensive and consistent record of past weather and climate conditions. Reanalysis data is a useful tool to examine the Earth’s climate system over a wide range of time scales, from seasonal through decadal to century-scale changes.

-

There are multiple Earth system reanalysis products (e.g. MERRA-2, NCEP-NCAR, JRA-55C, see extensive list here), and no single product fits all needs. For the purposes of this tutorial you will be using a product from the European Centre for Medium-Range Weather Forecasts (ECMWF) called ECMWF Reanalysis v5 (ERA5). This video from the ECMWF provides you with a brief introduction to the ERA5 product.

-
-

Section 1.1: Accessing ERA5 Data#

-

You will access the data through the an AWS S3 bucket of the data: ECMWF ERA5 Reanalysis. To do this you need the name of the bucket “era5-pds”, and the file location in the bucket. Note: you can open the AWS link and find a guided tutorial on how to explore the S3 bucket.

-

Let’s select a specific year and month to work with, March of 2018:

-
-
-
era5_bucket = "era5-pds"
-client = boto3.client(
-    "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-)  # initialize aws s3 bucket client
-date_sel = datetime.datetime(
-    2018, 3, 1, 0
-)  # select a desired date and hours (midnight is zero)
-prefix = date_sel.strftime("%Y/%m/")  # format the date to match the s3 bucket
-metadata_file = "main.nc"  # filename on the s3 bucket
-metadata_key = prefix + metadata_file  # file location and name on the s3 bucket
-filepath = pooch_load(
-    filelocation="http://s3.amazonaws.com/" + era5_bucket + "/" + metadata_key,
-    filename=metadata_file,
-)  # open the file
-
-ds_meta = xr.open_dataset(filepath)  # open the file
-ds_meta
-
-
-
-
-

You just loaded an xarray dataset, as introduced at the first day. This dataset contains 19 variables covering the whole globe (-90 to +90 degrees in latitude, 0 to 360 degrees on longitude) along with their respective coordinates. With this dataset you have access to our best estimates of climate parameters with a temporal resolution of 1 hour and a spatial resolution of 1/4 degree (i.e. grid points near the Equator represent a ~25 km x 25 km region). This is a lot of data, but still just a fraction the data available through the full ERA5 dataset.

-
-
-

Section 1.2: Selecting Regions of Interest#

-

The global ERA5 data over the entire time range is so large that even just one variable would be too large to store on your computer. Here you will apply a method to load a region (i.e., a spatial subset) of the data. In this first example, you will load air surface temperature at 2 meters data for a small region in the Northeastern United States. In later tutorials you will have the opportunity to select a region of your choice and to explore other climate variables.

-
-
-
# the order of the lat lon range has to follow the convention of the data set.
-# for this dataset, longitude ranges from 0 to 360 degrees and
-# latitude ranges from 90 degrees Northto 90 degrees South .
-
-# northeastern United States
-lat_range = [55.2, 30.2]  # from north to south
-lon_range = [270, 295]  # from west to east
-
-
-
-
-
-
-
# note this can take several minutes to download
-selected_vars = [
-    "air_temperature_at_2_metres",
-    "northward_wind_at_10_metres",
-    "eastward_wind_at_10_metres",
-    "surface_air_pressure",
-    "sea_surface_temperature",
-]  # the variables we want
-s3_data_ptrn = (
-    "{year}/{month}/data/{var}.nc"  # path and filename format for this S3 bucket
-)
-year_s3 = date_sel.strftime("%Y")  # extract the year
-month_s3 = date_sel.strftime("%m")  # extract the month
-ERA5_select = []  # initialize the dataset, will save a complicated check later
-for var in selected_vars:  # this will download 5 files of 500Mb each.
-    s3_data_key = s3_data_ptrn.format(
-        year=year_s3, month=month_s3, var=var
-    )  # variable specific  key
-    print("Downloading %s from S3..." % s3_data_key)
-    filepath = pooch_load(
-        filelocation="http://s3.amazonaws.com/" + era5_bucket + "/" + s3_data_key,
-        filename=s3_data_key,
-    )  # open the file
-    ds_temp = xr.open_dataset(filepath)  # retrieve the variable from the bucket
-    if (
-        ERA5_select
-    ):  # check if the dataset is empty or not (first iteration of the loop)
-        ERA5_select = xr.merge(
-            [ERA5_select, ds_temp]
-        )  # if not empty, merge the new file
-    else:
-        ERA5_select = ds_temp  # if empty, just assign the new file
-
-ERA5_allvars = ERA5_select.sel(lon=slice(lon_range[0], lon_range[1])).sel(
-    lat=slice(lat_range[0], lat_range[1])
-)
-ERA5_allvars
-
-
-
-
-

The magnitude of the wind vector represents the wind speed

-
-(1)#\[\begin{align} -||u|| = \sqrt{u^2 + v^2} -\end{align}\]
-

which you will use later in the tutorial and discuss in more detail in tutorial 4. We will calculate that here and add it to our dataset.

-
-
-
# compute ten meter wind speed
-ERA5_allvars["wind_speed"] = np.sqrt(
-    ERA5_allvars["northward_wind_at_10_metres"] ** 2
-    + ERA5_allvars["eastward_wind_at_10_metres"] ** 2
-)  # calculate the wind speed from the vectors
-# name and units in the DataArray:
-ERA5_allvars["wind_speed"].attrs[
-    "long_name"
-] = "10-meter wind speed"  # assigning long name to the windspeed
-ERA5_allvars["wind_speed"].attrs["units"] = "m/s"  # assigning units
-ERA5_allvars
-
-
-
-
-
-
-
-

Section 2: Plotting Spatial Maps of Reanalysis Data#

-

First, let’s plot the region’s surface temperature for the first time step of the reanalysis dataset. To do this let’s extract the air temperatre data from the dataset containing all the variables.

-
-
-
ds_surface_temp_2m = ERA5_allvars.air_temperature_at_2_metres
-
-
-
-
-

We will be plotting this a little bit differently that you have previously plotted a map (and differently to how you will plot in most tutorials) so we can look at a few times steps interactively later. To do this we are using the package geoviews.

-
-
-
holoviews.extension("bokeh")
-
-dataset_plot = gvDataset(ds_surface_temp_2m.isel(time0=0))  # select the first time step
-
-# create the image
-images = dataset_plot.to(
-    gvImage, ["longitude", "latitude"], ["air_temperature_at_2_metres"], "hour"
-)
-
-# aesthetics, add coastlines etc.
-images.opts(
-    cmap="coolwarm",
-    colorbar=True,
-    width=600,
-    height=400,
-    projection=ccrs.PlateCarree(),
-    clabel="2m Air Temperature [K]",
-) * gf.coastline
-
-
-
-
-

In the above figure, coastlines are shown as black lines. Most of the selected region is land, with some ocean (lower left) and a lake (top middle).

-

Next, we will examine variability at two different frequencies using interactive plots:

-
    -
  1. Hourly variability

  2. -
  3. Daily variability

  4. -
-

Note that in the previous tutorial you computed the monthly variability, or climatology, but here you only have one month of data loaded (March 2018). If you are curious about longer timescales you will visit this in the next tutorial!

-
-
-
# interactive plot of hourly frequency of surface temperature
-# this cell may take a little longer as it contains several maps in a single plotting function
-ds_surface_temp_2m_hour = ds_surface_temp_2m.groupby("time0.hour").mean()
-dataset_plot = gvDataset(
-    ds_surface_temp_2m_hour.isel(hour=slice(0, 12))
-)  # only the first 12 time steps, as it is a time consuming task
-images = dataset_plot.to(
-    gvImage, ["longitude", "latitude"], ["air_temperature_at_2_metres"], "hour"
-)
-images.opts(
-    cmap="coolwarm",
-    colorbar=True,
-    width=600,
-    height=400,
-    projection=ccrs.PlateCarree(),
-    clabel="2m Air Temperature [K]",
-) * gf.coastline
-
-
-
-
-
-
-
# interactive plot of hourly frequency of surface temperature
-# this cell may take a little longer as it contains several maps in a single plotting function holoviews.extension('bokeh')
-ds_surface_temp_2m_day = ds_surface_temp_2m.groupby("time0.day").mean()
-dataset_plot = gvDataset(
-    ds_surface_temp_2m_day.isel(day=slice(0, 10))
-)  # only the first 10 time steps, as it is a time consuming task
-images = dataset_plot.to(
-    gvImage, ["longitude", "latitude"], ["air_temperature_at_2_metres"], "day"
-)
-images.opts(
-    cmap="coolwarm",
-    colorbar=True,
-    width=600,
-    height=400,
-    projection=ccrs.PlateCarree(),
-    clabel="Air Temperature [K]",
-) * gf.coastline
-
-
-
-
-
-

Question 2#

-
    -
  1. What differences do you notice between the hourly and daily interactive plots, and are there any interesting spatial patterns of these temperature changes?

  2. -
-
-
-
-

Section 3: Plotting Timeseries of Reanalysis Data#

-
-

Section 3.1: Surface Air Temperature Timeseries#

-

You have demonstrated that there are a lot of changes in surface temperature within a day and between days. It is crucial to understand this temporal variability in the data when performing climate analysis.

-

Rather than plotting interactive spatial maps for different timescales, in this last section you will create a timeseries of surface air temperature from the data you have already examined to look at variability on longer than daily timescales. Instead of taking the mean in time to create maps, you will now take the mean in space to create timeseries.

-

Note that the spatially-averaged data will now only have a time coordinate coordinate, making it a timeseries (ts).

-
-
-
# find weights (this is a regular grid so we can use cos(lat))
-weights = np.cos(np.deg2rad(ds_surface_temp_2m.lat))
-weights.name = "weights"
-
-# take the weighted spatial mean since the latitude range of the region of interest is large
-ds_surface_temp_2m_ts = ds_surface_temp_2m.weighted(weights).mean(["lon", "lat"])
-ds_surface_temp_2m_ts
-
-
-
-
-
-
-
# plot the timeseries of surface temperature
-
-fig, ax = plt.subplots(1, 1, figsize=(10, 3))
-
-ax.plot(ds_surface_temp_2m_ts.time0, ds_surface_temp_2m_ts)
-ax.set_ylabel("2m Air \nTemperature (K)")
-ax.xaxis.set_tick_params(rotation=45)
-
-
-
-
-
-

Questions 3.1#

-
    -
  1. What is the dominant source of the high frequency (short timescale) variability?

  2. -
  3. What drives the lower frequency variability?

  4. -
  5. Would the ENSO variablity that you computed in the previous tutorial show up here? Why or why not?

  6. -
-
-
-
-

Section 3.2: Comparing Timeseries of Multiple Variables#

-

Below you will calculate the timeseries of the surface air temperature which we just plotted, alongside timeseries of several other ERA5 variables for the same period and region: 10-meter wind speed, atmospheric surface pressure, and sea surface temperature.

-
-
-
ERA5_allvars_ts = ERA5_allvars.weighted(weights).mean(["lon", "lat"])
-
-
-
-
-
-
-
plot_vars = [
-    "air_temperature_at_2_metres",
-    "wind_speed",
-    "surface_air_pressure",
-    "sea_surface_temperature",
-]
-
-fig, ax_list = plt.subplots(len(plot_vars), 1, figsize=(10, 13), sharex=True)
-
-for var, ax in zip(plot_vars, ax_list):
-
-    ax.plot(ERA5_allvars_ts.time0, ERA5_allvars_ts[var])
-    ax.set_ylabel(
-        ERA5_allvars[var].attrs["long_name"] + ": " + ERA5_allvars[var].attrs["units"],
-        fontsize=12,
-    )
-    ax.xaxis.set_tick_params(rotation=45)
-
-
-
-
-
-

Questions 3.2#

-

Which variable shows variability that is dominated by:

-
    -
  1. The diurnal cycle?

  2. -
  3. The synoptic [~5 day] scale?

  4. -
  5. A mix of these two timescales?

  6. -
  7. Longer timescales?

  8. -
-
-
-
-

Bonus Section 1: Selecting a Different Spatial Region#

-

Define another spatial region, such as where you live, by selecting a longitude and latitude range of of your choosing. To find the longitude and latitude coordinates of your region, you can use Google Earth view, and read the position of your cursor in the lower right corner.

-
-

Bonus Section 1.1: Note About the Geographic Coordinate System and the Coordinates Used in This Dataset#

-

A point on Earth is described by latitude-longitude coordinates relative to the zero-meridian line going through Greenwich in London, UK (longitude = 0 degree) and the xero-latitude line along the equator (latitude = 0 degrees). Points east of Greenwich up to the dateline on the opposite side of the globe are referenced as 0 to +180 and points to the west of Greenwich are 0 to -180. -180 and +180 refer to the same longitude, the so-called dateline in the central pacific.

-

However, our data is referenced in a slightly different way where longitude runs from 0 to 360 rather than -180 to +180. Longitude increases as you move east of Greenwich, until you reach Greenwich again (0 or 360 degrees), rather than stopping at the dateline.

-
-
-
-
-

Summary#

-

In this tutorial, you learned how to access and process ERA5 reanalysis data. You are able to select specific regions within the reanalysis dataset and perform operations such as taking spatial and temporal averages.

-

You also looked at different climate variables to distinguish idenitfy the variability present at different timescales.

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.html deleted file mode 100644 index 3f09ea895..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial3.html +++ /dev/null @@ -1,1490 +0,0 @@ - - - - - - - - - - - - Tutorial 3: Atmospheric Circulation — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3: Atmospheric Circulation#

-

Week 1, Day 2, Ocean-Atmosphere Reanalysis

-

Content creators: Momme Hell

-

Content reviewers: Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In the previous tutorial you examined atmospheric surface temperatures. Spatial variations in surface temperature created by uneven solar radiation (e.g., between the Equator and poles), are one of the main drivers of global-scale air movement. Other processes such as the Earth’s rotation, storm tracks, and surface topography can also influence global wind patterns.

-

By the end of this tutorial, you will be able to:

-
    -
  • Describe the seasonal variations in surface winds.

  • -
  • Calculate seasonal climatologies and create global maps.

  • -
  • Compare statistics derived from these climatologies.

  • -
-

In this tutorial, you will again utilize the monthly-mean surface wind fields from ERA5 over a 30-year period.

-
-
-

Setup#

-
-
-
# @title Plotting Functions
-
-
-def set_projection_figure(projection=ccrs.PlateCarree(), figsize=(5, 4.5)):
-    # source:https://foundations.projectpythia.org/core/cartopy/cartopy.html
-
-    projLccNY = projection  # ccrs.LambertConformal(central_longitude=cLon, central_latitude=cLat)
-
-    fig = plt.figure(figsize=figsize)
-    ax = plt.subplot(1, 1, 1, projection=projLccNY)
-
-    format_axes(ax)
-    # ax.add_feature(cfeature.STATES)
-    # ax.add_feature(cfeature.RIVERS)
-    return fig, ax
-
-
-def format_axes(ax):
-    ax.add_feature(cfeature.COASTLINE)
-    ax.add_feature(cfeature.LAKES, edgecolor="black", facecolor="None", alpha=0.3)
-    gl = ax.gridlines(
-        draw_labels=True, linewidth=1, color="black", alpha=0.5, linestyle="--"
-    )
-    gl.xlocator = matplotlib.ticker.MaxNLocator(7)
-    gl.ylocator = matplotlib.ticker.MaxNLocator(5)
-    gl.xlabels_top = False
-    gl.ylabels_left = False
-    # gl.xlines = False
-
-
-# helping functions:
-def geographic_lon_to_360(lon):
-    return 360 + lon
-
-
-def inverted_geographic_lon_to_360(lon):
-    return lon - 180
-
-
-def cbar_label(DD):
-    return DD.attrs["long_name"] + " [" + DD.attrs["units"] + "]"
-
-
-
-
-
-
-
# @title Helper functions
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-
-
-

Section 1: Surface Winds#

-

The large-scale atmospheric circulation significantly influences the climate we experience at different latitudes. The global atmospheric circulation is often depicted as a three-cell structure, as visualized in this figure showing the surface winds:

-

Earth Global Circulation - en.svg.

-

This schematic of atmospheric circulation cells reveal meridional (north-south) and zonal (east-west) components of the large-scale surface winds.

-

Let’s see if you are able to detect these large-scale patterns in reanalysis data! -For this you will load ERA5 wind data from Pangeo catalog

-
-

Section 1.1: Annual Mean Wind Speed#

-

You should start investigating this data by examining the global surface winds. These winds are represented as vectors, consisting of a zonal component denoted as u10 and a meridional component denoted as v10.

-

Recall from the previous tutorial that the magnitude of the wind vector represents the wind speed you will use later in the tutorial, given by:

-
-(2)#\[\begin{align} -||u|| = \sqrt{u^2 + v^2} -\end{align}\]
-

To examine long-term changes in the wind field you should visualize the zonal wind component \(u\) and the meridional wind component \(v\) with monthly-mean data. With the help of xarray, you can derive monthly means from higher-resolution data (such as those used in tutorial 2) using the xr.resample('1M').mean('time') function.

-

For your convenience, we have already performed this step, and you can load the data using the following instructions:

-
    -
  • The variable si10 represents the wind speed in this dataset.

  • -
  • To calculate the long-term mean, we selected 30 years of data ranging from 1980 to 2010.

  • -
-

Let’s grab the reanalysis data from before that we have prepocessed (noting naming convention changes):

-
-
-
# note this can take a few minutes to download
-filename_era5_mm = "ERA5_surface_winds_mm.nc"
-url_era5_mm = "https://osf.io/3q4vs/download"
-
-ERA5_mm = xr.open_dataset(pooch_load(url_era5_mm, filename_era5_mm)).sel(
-    time=slice("1980", "2010")
-)  # select the timeslice during loading
-ERA5_mm
-
-
-
-
-

Now take the annual mean zonal surface wind speed.

-
-
-
# take the time mean
-ERA5_ANN = ERA5_mm.mean("time")
-
-
-
-
-

To visualize this data, we will be using some helper functions defined in the beginning of the tutorial just to set the map features and aesthetics. Please take a look at them if you are interested in seeing how they work.

-
-
-
# adjust colorlevels to weaker amplitudes
-colorlevels_clim = np.arange(-10, 11, 1)
-
-var = "u10"  # select our variable
-fig, ax = set_projection_figure(
-    projection=ccrs.PlateCarree(), figsize=(9, 5.5)
-)  # same plot function as Part I
-ax.set_title("Mean " + var, loc="left")
-dataplot = ax.contourf(
-    ERA5_ANN.longitude,
-    ERA5_ANN.latitude,
-    ERA5_ANN[var],
-    levels=colorlevels_clim,
-    transform=ccrs.PlateCarree(),
-    cmap=plt.cm.coolwarm,
-)
-fig.colorbar(dataplot, orientation="vertical", label="m/s", shrink=0.55, pad=0.08)
-
-
-
-
-

In the zonal wind speed figure you created, there are two distinct wind bands between 35 to 65 degrees both north and south of the equator that blow from west to east (red, positive wind speeds). These mid-latitude wind bands are known as the westerlies. Additionally, you can see that winds predominantly blow from the east to the west (blue, negative wind speeds) in the tropics (less than 30° N/S), and are referred to as the easterlies.

-
-

Coding Exercise 1.1#

-

Reproduce the previous figure, but modify it to plot meridional wind rather than zonal wind

-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Reproduce the previous figure, but modify it to plot meridional wind rather than zonal wind"
-)
-#################################################
-var = ...
-fig, ax = set_projection_figure(projection=ccrs.PlateCarree(), figsize=(9, 5.5))
-ax.set_title("Mean " + var, loc="left")
-dataplot = ax.contourf(
-    ERA5_ANN.longitude,
-    ERA5_ANN.latitude,
-    ERA5_ANN[var],
-    levels=colorlevels_clim,
-    transform=ccrs.PlateCarree(),
-    cmap=plt.cm.coolwarm,
-)
-fig.colorbar(dataplot, orientation="vertical", label="m/s", shrink=0.55, pad=0.08)
-
-
-
-
-

There are strong southward winds in the subtropics of the Northern Hemisphere (blue, negative wind speed), and northward winds in the subtropics of the Southern Hemisphere (red, positive wind speed). The meridional winds are strongest on the western side of the continents.

-
-
-

Questions 1.1#

-
    -
  1. Among the three atmospheric “cells” (the Hadley Cell, Ferrel Cell, and Polar Cell) depicted in the figure from Section 1 above, which ones correspond to the zonal wind bands that we visualized in the first plot above?

  2. -
  3. How do the zonal and meridional winds compare in magnitude, longitude, and latitude?

  4. -
-
-
-
-

Section 1.2 : Zonal-mean Wind Speed#

-

To examine the latitudinal variation in the surface winds, you can plot the zonal mean of the annual mean zonal and meridional winds:

-
-
-
fig, ax = plt.subplots(figsize=(9, 5.5))
-ERA5_ANN.mean("longitude")["u10"].plot(
-    label="zonal wind", ax=ax
-)  # find the u10 mean value over the latitude
-ERA5_ANN.mean("longitude")["v10"].plot(
-    label="meridional wind", ax=ax
-)  # find the v10 mean value over the latitude
-ax.legend()  # add legend
-ax.set_title("Annual mean, zonal mean winds", loc="left")  # add title
-ax.set_ylabel("wind speed (m/s)")
-ax.axhline(0, color="black")  # add a black line at x=0
-
-
-
-
-
-

Questions 1.2#

-
    -
  1. Considering the zonal-mean wind speed figure provided, what factors contribute to the noticeable disparities between the Northern and Southern Hemispheres in terms of wind patterns?

  2. -
-
-
-
-
-

Section 2: Monthly Climatology#

-

Now, you should examine how the zonal mean winds vary throughout the seasons. You will focus on the zonal wind component and create a special type of diagram called a Hoffmöller diagram. In this diagram, the horizontal axis represents latitude, while the vertical axis represents time.

-

By using the Hoffmöller diagram, you can visualize how the average east-west winds change with each season.

-
-
-
# the groupby command regroups the data by month, such that all Januarys, all Februaries, .. and so on are taken the mean over
-# note how we use several commands in one line. python perfom them by order. slice (long, u10), groupby, mean and lastely plot.
-ERA5_mm.mean("longitude")["u10"].groupby("time.month").mean().plot()
-
-
-
-
-
-

Coding Exercises 2#

-

Extend the above analysis to create a Hoffmöller diagram of the meridional winds.

-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Extend the above analysis to create a Hoffmöller diagram of the meridional winds."
-)
-#################################################
-
-ERA5_mm.mean("longitude")["..."].groupby("time.month").mean().plot()
-
-
-
-
-

Note:

-
    -
  • The winds in the Southern Hemisphere appear to be generally stronger compared to the Northern Hemisphere.

  • -
  • The period between June and September shows strong meridional winds. These winds result from the seasonal variation of the Hadley cell. During the winter hemisphere in each respective hemisphere, the Hadley cell becomes much stronger, leading to the intensification of meridional winds.

  • -
-
-
-

Bonus exercise#

-
    -
  • Plot the global map for DJF and JJA of the zonal wind. What do you see when you compare the mid-latitudes? (you can also plot their difference!)

  • -
  • Plot trend of the zonal mean zonal wind in DJF

  • -
-

That is because the solar insulation leads to varying circulation patterns with seasons. -More about this you can find in Global Physical Climatology, -The Atmospheric General Circulation -or the first few chapters of this evolving draft Physics of Earth’s Climate

-
-
-
# note, this codes takes a while to run
-ERA5_season = ...
-
-var='u10'
-season='DJF'
-F, ax = set_projection_figure(projection = ccrs.PlateCarree(), figsize = (9, 5.5) )
-ax.set_title('Zonal Wind DJF mean | '+ var , loc ='left')
-dataplot = ...
-_ = ... # colorbar
-plt.show()
-
-
-var='u10'
-season='JJA'
-F, ax = set_projection_figure(projection = ccrs.PlateCarree(), figsize = (9, 5.5) )
-ax.set_title('Zonal Wind DJF mean | '+ var , loc ='left')
-dataplot = ...
-_ = ... # colorbar
-plt.show()
-
-# difference:
-var='u10'
-pdata = ...
-
-F, ax = set_projection_figure(projection = ccrs.PlateCarree(), figsize = (9, 5.5) )
-ax.set_title(... , loc ='left')
-dataplot = ...
-_ = ... # colorbar
-plt.show()
-
-
-
-
-
-
-

Additional Reading: Extra-tropical Storms#

-

In the wind speed figure, you can notice areas of strong winds over the Southern Ocean, North Pacific, and North Atlantic. These powerful winds are caused by weather systems known as extratropical storms or mid-latitude cyclones. These storms occur in the middle latitudes, between 30 and 60 degrees north or south of the equator. During winter, they are particularly strong over the Southern Ocean and the oceans in the Northern Hemisphere.

-

Extratropical storms form when warm and cold air masses interact. They have a low-pressure center and produce winds that circulate counterclockwise in the Northern Hemisphere and clockwise in the Southern Hemisphere. These storms can be intense, bringing strong winds, heavy rain, snow, and sleet. They often lead to problems like flooding, power outages, and disruptions in transportation.

-

The strength of these storms depends on factors such as the temperature difference between air masses, the speed of the jet stream, and the amount of moisture in the air. If you want to learn more about extratropical storms, you can refer to basic meteorology and atmospheric dynamics resources, or you can explore online sources such as the following:

- -

Although an individual storm may last only a few days and doesn’t create significant ocean currents, the continuous winds and the occurrence of multiple storms over a year can influence the development of ocean currents. These currents are a response to the persistent wind patterns.

-
-
-
-

Summary#

-

Within this tutorial, you analysed the global atmospheric circulation by using ERA5 reanalysis data. You explored the distribution of westerlies and easterlies across the globe, observed their seasonal variations. You observed that the strongest winds were found to occur over the Southern Ocean.

-
-
-

Resources#

-

Data from this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4.html deleted file mode 100644 index 963b918cd..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial4.html +++ /dev/null @@ -1,1431 +0,0 @@ - - - - - - - - - - - - Tutorial 4: Oceanic Wind-driven Circulation — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 4: Oceanic Wind-driven Circulation#

-

Week 1, Day 2: Ocean and Atmospheric Reanalysis

-

Content creators: Abigail Bodner

-

Content reviewers: Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

The ocean’s motion is driven by radiation from the sun, winds, and various sources & sinks of fresh water (precipitation, rivers, melting and freezing ice). In the previous tutorial, you quantified the surface winds around the world. The surface winds drags on the surface of the ocean which results in ocean transport, known as Ekman transport.

-

In this tutorial you will use the ECCO (Estimating the Circulation and Climate of the Ocean) reanalysis data, to visualize the ocean’s surface currents and to compare these currents against local atmospheric conditions.

-

At the end of this tutorial you will be able to

-
    -
  • Access and manipulate ocean reanalysis data

  • -
  • Plot annual mean ocean surface currents and atmospheric surface winds

  • -
  • Compare oceanic and atmospheric circulation patterns

  • -
-
-
-

Setup#

-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[4], line 3
-      1 # @title Video 1: Ocean Wind-driven Circulation
-----> 3 from ipywidgets import widgets
-      4 from IPython.display import YouTubeVideo
-      5 from IPython.display import IFrame
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-

Section 1: Load Ocean & Atmosphere Reanalysis Data#

-

Here you will load atmospheric near-surface winds (at 10-meter height), and then load the oceanic surface currents from ECCO reanalysis data

-

Note, each of these variables is a velocity with two components (zonal and meridional). These two velocity components must be loaded separately for each variable, so you will load four datasets.

-
-
-
# load data: atmospheric 10m wind from ECCO
-# wind in east/west direction labeled here as 'u'
-fname_atm_wind_u = "wind_evel_monthly_2016.nc"
-url_atm_wind_u = "https://osf.io/ke9yp/download"
-atm_wind_u = xr.open_dataarray(pooch_load(url_atm_wind_u, fname_atm_wind_u))
-atm_wind_u
-
-
-
-
-
-
-
# wind in north/south direction labeled here as 'v'
-fname_atm_wind_v = "wind_nvel_monthly_2016.nc"
-url_atm_wind_v = "https://osf.io/9zkgd/download"
-atm_wind_v = xr.open_dataarray(pooch_load(url_atm_wind_v, fname_atm_wind_v))
-atm_wind_v
-
-
-
-
-
-
-
# load data: oceanic surface current from ECCO
-# current in east/west direction labeled here as 'u'
-fname_ocn_surface_current_u = "evel_monthly_2016.nc"
-url_ocn_surface_current_u = "https://osf.io/ndx5a/download"
-ocn_surface_current_u = xr.open_dataarray(
-    pooch_load(url_ocn_surface_current_u, fname_ocn_surface_current_u)
-)
-ocn_surface_current_u
-
-
-
-
-
-
-
# current in east/west direction labeled here as 'v'
-fname_ocn_surface_current_v = "nvel_monthly_2016.nc"
-url_ocn_surface_current_v = "https://osf.io/qa9ex/download"
-ocn_surface_current_v = xr.open_dataarray(
-    pooch_load(url_ocn_surface_current_v, fname_ocn_surface_current_v)
-)
-ocn_surface_current_v
-
-
-
-
-
-

Section 1.1: Exploring the Reanalysis Data#

-

Let’s examine the time (or temporal/output) frequency, which descibes the rate at which the reanalysis data is provided, for one of the ECCO variables (atm_wind_u).

-

Note that all the variables should have the same output frequency.

-
-
-
atm_wind_u.time
-
-
-
-
-
-

Questions 1.1#

-
    -
  1. Why do you think the atmospheric reanalysis dataset from the previous tutorial (ERA5) has higher output frequency (hourly) than the ECCO ocean reanalysis dataset (daily)?

  2. -
  3. What can you infer about the role of these two systems at different timescales in the climate system?

  4. -
-
-
-
-
-

Section 2: Plotting the Annual Mean of Global Surface Wind Stress#

-

In this section you will create global maps displaying the annual mean of atmospheric 10m winds.

-

First, you should compute the annual mean of the surface wind variables. You can do so by averaging over the time dimension using .mean(dim='time'). Since you have monthly data spanning only one year, .mean(dim='time') will give the annual mean for the year 2016.

-
-
-
# compute the annual mean of atm_wind_u
-atm_wind_u_an_mean = atm_wind_u.mean(dim="time")
-atm_wind_u_an_mean
-
-
-
-
-
-
-
# take the annual mean of atm_wind_stress_v
-atm_wind_v_an_mean = atm_wind_v.mean(dim="time")
-atm_wind_v_an_mean
-
-
-
-
-

You are now almost ready to plot!

-

However, you currently have seperate zonal and meridional wind velocity components \((u,v)\). An effective way of visualizing the total surface wind stress is to create a global map of the magnitude and direction of the wind velocity vector. This type of plot is known as a vector field. A vector is a special mathematical quantity that has both magnitude and direction, just like the wind! The velocity components describe the intensity of wind blowing in the zonal (\(u\)) or meridional (\(v\)) directions. Specifically, wind can blow eastward (positive \(u\)) or westward (negative \(u\)), as well as northward (positive \(v\)) or southward (negative \(v\)).

-

The total velocity vector is the vector sum of these two components and exhibits varying magnitude and direction. The magnitude (\(||u||\)) and direction (\(θ\)) of the total velocity vector can be determined using the following equations:

-
-(3)#\[\begin{align} -||u|| = \sqrt{u^2 + v^2}, \ \ \ \ \theta = tan^{-1}(\frac{v}{u}) -\end{align}\]
-

When plotting a vector field using a computer, it is commonly referred to as a quiver plot. In our case, we will utilize a quiver function created by Ryan Abernathey that calculates the magnitude and direction of the total velocity vector based on the given zonal and meridional components.

-

We will overlay the quiver plot on top of the annual mean ocean surface temperature (labeled here as theta).

-
-
-
fname_surface_temp = "surface_theta.nc"
-url_fname_surface_temp = "https://osf.io/98ksr/download"
-ocn_surface_temp = xr.open_dataarray(
-    pooch.retrieve(url_fname_surface_temp, known_hash=None, fname=fname_surface_temp)
-)
-ocn_surface_temp
-
-
-
-
-
-
-
# longitude ad latitude coordinates for plotting
-lon = atm_wind_u_an_mean.longitude
-lat = atm_wind_u_an_mean.latitude
-
-# calculate magnitude of total velocity
-mag = (atm_wind_u_an_mean**2 + atm_wind_v_an_mean**2) ** 0.5
-
-# coarsen the grid so the arrows are distinguishable by only selecting
-# some longitudes and latitudes defined by sampling_x and sampling_y.
-slx = slice(None, None, 20)
-sly = slice(None, None, 20)
-sl2d = (sly, slx)
-
-fig, ax = plt.subplots(
-    figsize=(12, 6), subplot_kw={"projection": ccrs.Robinson(central_longitude=180)}
-)
-
-c = ax.contourf(lon, lat, ocn_surface_temp, alpha=0.5)
-
-# plot quiver arrows indicating vector direction (winds are in blue, alpha is for opacity)
-q = ax.quiver(
-    lon[slx],
-    lat[sly],
-    atm_wind_u_an_mean[sl2d],
-    atm_wind_v_an_mean[sl2d],
-    color="b",
-    alpha=0.5,
-)
-
-ax.quiverkey(q, 175, 95, 5, "5 m/s", coordinates="data")
-
-fig.colorbar(c, label="Sea Surface Temperature (degC)")
-
-
-
-
-
-
-

Section 3: Comparing Global Maps of Surface Currents and Winds#

-

In this section you will compute the annual mean of the ocean surface currents, similar to your above analyses of atmospheric winds, and you will create a global map that shows both of these variables simultaneously.

-
-
-
# take the annual mean of ocn_surface_current_u
-ocn_surface_current_u_an_mean = ocn_surface_current_u.mean(dim="time")
-ocn_surface_current_u_an_mean
-
-
-
-
-
-
-
# take the annual mean of ocn_surface_current_v
-ocn_surface_current_v_an_mean = ocn_surface_current_v.mean(dim="time")
-ocn_surface_current_v_an_mean
-
-
-
-
-

Let’s add ocean surface currents to the previous plot above, using red quivers. Note the scale of the arrows for the ocean and atmosphere are very different.

-
-
-
# longitude ad latitude coordinates for plotting
-lon = atm_wind_u_an_mean.longitude
-lat = atm_wind_u_an_mean.latitude
-
-# calculate magnitude of total velocity
-mag = (atm_wind_u_an_mean**2 + atm_wind_v_an_mean**2) ** 0.5
-
-# coarsen the grid so the arrows are distinguishable by only selecting
-# some longitudes and latitudes defined by sampling_x and sampling_y.
-slx = slice(None, None, 20)
-sly = slice(None, None, 20)
-sl2d = (sly, slx)
-
-# fig, ax = plt.subplots(**kwargs)
-fig, ax = plt.subplots(
-    figsize=(12, 6), subplot_kw={"projection": ccrs.Robinson(central_longitude=180)}
-)
-
-c = ax.contourf(lon, lat, ocn_surface_temp, alpha=0.5)
-
-# plot quiver arrows indicating vector direction (winds are in blue, alpha is for opacity)
-q1 = ax.quiver(
-    lon[slx],
-    lat[sly],
-    atm_wind_u_an_mean[sl2d],
-    atm_wind_v_an_mean[sl2d],
-    color="b",
-    alpha=0.5,
-)
-
-# plot quiver arrows indicating vector direction (ocean currents are in red, alpha is for opacity)
-q2 = ax.quiver(
-    lon[slx],
-    lat[sly],
-    ocn_surface_current_u_an_mean[sl2d],
-    ocn_surface_current_v_an_mean[sl2d],
-    color="r",
-    alpha=0.5,
-)
-
-ax.quiverkey(q1, 175, 95, 5, "5 m/s", coordinates="data")
-
-ax.quiverkey(q2, 150, 95, 0.05, "5 cm/s", coordinates="data")
-
-fig.colorbar(c, label="Sea Surface Temperature (degC)")
-
-
-
-
-
-

Questions 3#

-

You may notice that the surface currents (red) are typically not aligned with the wind direction (blue). In fact, the surface ocean currents flow at an angle of approximately 45 degrees to the wind direction!

-

The combination of Coriolis force and the friction between ocean layers causes the wind-driven currents to turn and weaken with depth, eventually dissapearing entirely at depth. The resulting current profile is called the Ekman Spiral, and the depth over which the spiral is present is called the Ekman layer. While the shape of this spiral can vary in time and space, the depth-integrated transport of water within the Ekman layer is called Ekman transport. Ekman transport is always 90 degrees to the right of the wind in the Northern Hemisphere, and 90 degrees to the left of the wind in the Southern Hemisphere. Under certain wind patterns or near coastlines, Ekman transport can lead to Ekman Pumping, where water is upwelled or downwelled depending on the wind direction. This process is particularily important for coastal ecosystems that rely on this upwelling (which is often seasonal) to bring nutrient-rich waters near the surface. These nutrients fuel the growth of tiny marine plants that support the entire food chain, upon which coastal economies often rely. These tiny plants are also responsible for most of the oxygen we breathe!

-
    -
  1. Do you observe a deflection of the surface currents relative to the wind?

  2. -
  3. Is this deflection the same in both the Northern and Southern Hemispheres?

  4. -
-
-
-
-

Summary#

-

In this tutorial, you explored how atmospheric winds can shape ocean surface currents.

-

You calculated the surface wind vector an assessed its influence on surface ocean currents called the wind-driven circulation.

-

This circulation influences global climate (e.g., moving heat between latitudes) and biogeochemical cycles (e.g., by driving upwelling of nutrient rich water). In the next tutorial you will explore another mechanism for ocean movement, density-driven circulation.

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5.html deleted file mode 100644 index 9463dcfa8..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial5.html +++ /dev/null @@ -1,1431 +0,0 @@ - - - - - - - - - - - - Tutorial 5: Thermohaline Circulation — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 5: Thermohaline Circulation#

-

Week 1, Day 2: Ocean and Atmospheric Reanalysis

-

Content creators: Aurora Basinski

-

Content reviewers: Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In the previous tutorial, we discussed how the surface ocean’s movement is driven by wind forcing. However, the ocean can also experience movement due to density differences. The large scale ocean movement driven by these density differences is known as the thermohaline circulation. The density of ocean water is influenced by temperature (thermo) and salinity (haline), and fluid motion occur in response to pressure gradients caused by these density variations.

-

In this tutorial, we will use ocean surface data for 2014 to 2016 from the Estimating the Circulation and Climate of the Ocean (ECCO) dataset to

-
    -
  • Plot sea surface salinity and temperature

  • -
  • Understand the relationship between salinity, temperature, and ocean density

  • -
  • Explore the difference between linear and non-linear equations of state

  • -
-
-
-

Setup#

-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[4], line 3
-      1 # @title Video 1: Thermohaline Circulation
-----> 3 from ipywidgets import widgets
-      4 from IPython.display import YouTubeVideo
-      5 from IPython.display import IFrame
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-

Section 1: Plot Surface Temperature and Salinity#

-

In the slides, we discovered that ocean flows can be driven by density variations in addition to wind-driven circulation. One example of a density-driven flow is the thermohaline circulation. Density in the ocean is influenced by two main factors:

-
    -
  1. Salinity (higher salinity leads to greater density) and

  2. -
  3. Temperature (lower temperature generally results in higher density),

  4. -
  5. Also, pressure affects density (higher pressure results in higher density), but it generally has a much smaller impact on ocean density than temperature and salinity.

  6. -
-

To develop a better understanding of how density varies across different regions, let’s examine the average salinity and temperature at the ocean surface.

-

First let’s load the data.

-
-
-
# import preprocessed ecco data. This data is surface data that is monthly over the period 2014 to 2016.
-filename_theta = "surface_theta.nc"
-url_theta = "https://osf.io/98ksr/download"
-
-subset_theta = xr.open_dataset(pooch_load(url_theta, filename_theta))
-subset_theta
-
-
-
-
-
-
-
filename_salt = "surface_salt.nc"
-url_salt = "https://osf.io/aufs2/download"
-
-subset_salt = xr.open_dataset(pooch_load(url_salt, filename_salt))
-subset_salt
-
-
-
-
-
-
-
# make land points NaN (not a number)
-subset_theta = subset_theta.where(
-    subset_theta != 0
-)  # change anywhere that the value is zero to NaN
-subset_salt = subset_salt.where(subset_salt != 0)  # same
-subset_theta = subset_theta.THETA  # choose the variable to remove the dimension
-subset_salt = subset_salt.SALT
-
-
-
-
-
-
-
# plot Sea Surface Temprature - similar to plots we used in tutorials 2+3
-fig, ax = plt.subplots(
-    subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100
-)  # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html
-p = subset_theta.plot(
-    vmin=0,
-    cmap=cmocean.cm.thermal,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "degree C",
-    },
-    ax=ax,
-)
-ax.coastlines(color="grey", lw=0.5)
-ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax.add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax.set_title("Sea Surface Temperature (2014-2016 mean)")
-fig.tight_layout()
-
-
-
-
-
-
-
# plot Sea Surface Salinity
-fig, ax = plt.subplots(
-    subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100
-)  # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html
-p = subset_salt.plot(
-    cmap=cmocean.cm.haline,
-    vmin=30,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "psu",
-    },
-    ax=ax,
-)
-ax.coastlines(color="grey", lw=0.5)
-ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax.add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax.set_title("Sea Surface Salinity (2014-2016 mean)")
-fig.tight_layout()
-
-
-
-
-
-
-

Section 2: Calculating Density from Salinity & Temperature#

-

The equation relating ocean water density to other water properties is called the equation of state. It is a non-linear function of temperature, salinity, and pressure. This can be expressed as \(\rho=\rho(T,S,p)\). Here we will show two ways to calculate the density.

-

The first is a linear approximation to the equation of state. We will then show how to calculate the full, non-linear equation of state using the gsw package

-
-

Section 2.1: Linearized Equation of State#

-

Here we take the linearized equation of state from equation 1.57 in Vallis’ textbook Atmospheric and Oceanic Fluid Dynamics

-
-\[ \rho=\rho_0[1-\beta_T(T-T_0)+\beta_S(S-S_0)+\beta_p(p-p_0)] \]
-

In this equation, \(\rho_0\simeq 1027\) is a reference density, \(\beta_T \simeq 2*10^{-4}\)/K is the thermal expansion coefficient, \(\beta_S \simeq 7.6*10^{-4}\)/ppt is the haline contraction coefficient, and \(\beta_p \simeq 4.4*10^{-10}\)/Pa is the compressibility coefficient. The values with \(_0\) are reference values, and here we use \(T_0=283\)K and \(S_0=35\). Since surface pressure rarely changes by more than a few percent, let’s assume that the pressure at the surface is equal to the reference pressure at every point (\(\beta_p(p-p_0)=0\)). The non-linearities in the full equation of state (which we will use later) arise because, in reality, the \(\beta\) terms themselves vary with pressure, salinity, and temperature.

-

Let’s now calculate a global map of surface density using this linear equation of state. Note that since we are using theta and salt datasets, our result will also be a dataset.

-
-
-
rho_linear = 1027 * (
-    1 - 2e-4 * (subset_theta + 273.15 - 283) + 7.6e-4 * (subset_salt - 35)
-)
-rho_linear
-
-
-
-
-
-
-
# plot linearized density
-fig, ax = plt.subplots(
-    subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100
-)  # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html
-p = rho_linear.plot(
-    cmap=cmocean.cm.dense,
-    vmin=1021,
-    vmax=1029,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "kg/m$^3$",
-    },
-    ax=ax,
-)
-ax.coastlines(color="grey", lw=0.5)
-ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax.add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax.set_title("Surface density from linear equation (2014-2016 mean)")
-fig.tight_layout()
-
-
-
-
-
-
-

Section 2.2: Full Nonlinear Equation of State#

-

The full, non-linear equation of state is more complicated than the linear equation we just used. It contains dozens of equations which are impractical to code in this tutorial. Fortunately packages exist to do this calculation!

-

Here we will compute surface density from the full nonlinear equation in python using the gsw package which is a Python implementation of the Thermodynamic Equation of Seawater 2010 (TEOS-10)

-
-
-
CT = gsw.CT_from_pt(
-    subset_salt, subset_theta
-)  # get conservative temperature from potential temperature
-rho_nonlinear = gsw.rho(subset_salt, CT, 0)
-
-
-
-
-
-
-
# plot density from full nonlinear equation
-fig, ax = plt.subplots(
-    subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100
-)  # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html
-p = rho_nonlinear.plot(
-    cmap=cmocean.cm.dense,
-    vmin=1021,
-    vmax=1029,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "kg/m$^3$",
-    },
-    ax=ax,
-)
-ax.coastlines(color="grey", lw=0.5)
-ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax.add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax.set_title("Surface density from nonlinear equation (2014-2016 mean)")
-fig.tight_layout()
-
-
-
-
-
-
-
# plot difference between linear and non-linear equations of state
-fig, ax = plt.subplots(
-    subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100
-)  # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html
-p = (rho_linear - rho_nonlinear).plot(
-    cmap="coolwarm",
-    vmin=-3,
-    vmax=3,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "kg/m$^3$",
-    },
-    ax=ax,
-)
-ax.coastlines(color="grey", lw=0.5)
-ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax.add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax.set_title("Linear minus non-linear equation of state (2014-2016 mean)")
-fig.tight_layout()
-
-
-
-
-

Upon comparing the two equations of state, we observe that they are generally similar, but certain differences arise. These differences stem from the nonlinearity of the equation of state, where the haline contraction coefficient and thermal expansion coefficient are not constant as assumed in our linear equation of state.

-

Irrespective of the method used to calculate density, we notice the presence of horizontal density variations (gradients) at the ocean surface. For instance, seawater tends to be less dense in the subtropics and denser near the poles. These density differences play a crucial role in driving ocean currents, as we discussed in the slides.

-

These findings emphasize the significant density gradients in the ocean, which shape oceanic circulation patterns. The nonlinearity in the equation of state contributes to these density variations, which in turn also influences the movement of water masses and the formation of currents.

-
-

Questions 2.2#

-
    -
  1. Considering the nonlinear equation of state and TEOS-10, how do changes in ocean salinity and temperature uniquely impact the haline contraction and thermal expansion coefficients, thereby affecting density and ocean currents?

  2. -
  3. One place that deep convection, a critical component of thermohaline circulation occurs, is in the North Atlantic Ocean to the south of Greenland. Based on the density maps you made, does it make sense that this would be an ideal location for a deepwater mass to form?

  4. -
-
-
-
-
-

Summary#

-

In this tutorial, you explored sea surface salinity and temperature data from 2014 to 2016, and how those contribute to surface density patterns through the equation of state. You also compared the linear and non-linear equation of state and analyzed their differences.

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6.html b/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6.html deleted file mode 100644 index f03558caf..000000000 --- a/book/_build/html/tutorials/W1D2_StateoftheClimateOceanandAtmosphereReanalysis/student/W1D2_Tutorial6.html +++ /dev/null @@ -1,1509 +0,0 @@ - - - - - - - - - - - - Tutorial 6: Ocean Heat Content — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 6: Ocean Heat Content#

-

Week 1, Day 2: Ocean and Atmospheric Reanalysis

-

Content creators: Aurora Basinski

-

Content reviewers: Katrina Dobson, Danika Gupta, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Brodie, Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will explore the ocean’s vast heat capacity, which has a significant impact on the climate system.

-

The ocean has a heat capacity that is approximately 1000 times greater than the entire atmosphere, due to the relatively large mass and specific heat capacity of water. This means that the ocean has a significant impact on Earth’s thermal equilibrium state. Ocean heat uptake and ocean carbon uptake mitigates the effect of anthropogenic climate change by absorbing roughly 90% of the excess heat and 25% of human-emitted CO2. As you will see in this tutorial, ocean heat uptake largely occurs in the upper ocean as it is the region in contact with the atmosphere.

-

The ocean’s high heat capacity also facilitates meridional ocean heat transport from the equator to the poles, which acts in addition to the meridional atmospheric heat transport.

-

Through this tutorial, you will explore the spatial distribution of heat in the ocean and how the ocean’s heat content is changing over time. To do this, you will utilize the Estimating the Circulation and Climate of the Ocean (ECCO) dataset.

-
-
-

Setup#

-
-
-
-
-
-
-

Section 1: Vertical Distribution of Heat Within the Ocean#

-

First, let’s load ECCO ocean temperature (THETA). This datasets contains the annual mean temperature over the period of 1992 to 2016.

-
-
-
# import preprocessed ECCO data. This data is full depth temperature data over 1992 to 2016 (annual mean)
-# this file takes about 5 minutes to load
-filename_theta_annual = "theta_annual_mean.nc"
-url_theta_annual = "https://osf.io/c8wqt/download"
-
-theta_annual = xr.open_dataset(pooch_load(url_theta_annual, filename_theta_annual))
-theta_annual = theta_annual.THETA
-theta_annual = theta_annual.where(theta_annual != 0)  # make land points equal to NaN
-theta_annual
-
-
-
-
-
-
-
# take the mean over the period 1992 to 1994
-subset_theta = theta_annual.sel(year=slice("1992", "1994")).mean("year")
-subset_theta
-
-
-
-
-
-
-
# plot a zonal mean slice of this data. we take a mean just in longitudes by dividing the dA coordinate by the
-fig, ax = plt.subplots(figsize=(8, 6))
-(
-    ((subset_theta - 273.15) * subset_theta.dX).sum("longitude")
-    / (subset_theta.dX.sum("longitude"))
-).plot(ax=ax)
-ax.set_title("Global zonal mean of temperature (C)")
-
-
-
-
-

Temperatures are warmest near the ocean’s surface and close to the Equator, which suggests that heat is not distributed evenly within the ocean. In this tutorial you will explore the spatial distribution of heat storage in the ocean (i.e., ocean heat content), and how this distribution is changing over time.

-

Heat content is typically measured in Joules, which is equivalent to the units kg\(*\)m\(^2\)/s\(^2\). To determine the heat content within a specific depth range of the global ocean, i.e., between depth \(z_1\) and the surface (height of 0), you can calculate a volume integral over the dimensions \(x,y,\) and \(z\). This integral can be written as: -$\(\iiint_{-z_1}^0 c_p \cdot \rho_0 \cdot \theta(x,y,z) dz dA\)$

-

Here, \(dA\) represents the area integral over the \(x\) and \(y\) (lat, lon) coordinates. \(\rho_0\) is the reference density in units of kg/m\(^3\) and \(c_p\) is specific heat capacity in units of J/(kg\(*\)K)

-
-
-
theta_area_int = (
-    (subset_theta * subset_theta.dA).sum("latitude").sum("longitude")
-)  # we take an area integral first at each depth level
-
-
-
-
-
-
-
rho = 1026  # kg/m^3
-c_p = 3990  # J/(kg K)
-
-sns.set_style(style="whitegrid")
-fig, ax = plt.subplots(figsize=(8, 6))
-ax.plot(
-    -subset_theta.Zu, (rho * c_p * theta_area_int * subset_theta.dZ).cumsum() / 10**27
-)
-ax.set_xlabel("Depth (m)")
-ax.set_ylabel("Heat content above this depth ($10^6$ ZJ)")
-ax.set_title("Global Ocean Heat Content above each depth")
-
-
-
-
-

You can see that much of the ocean’s heat is concentrated in the upper ocean (where the line is steep), with less heat stored in the deepest ocean regions (where the line plateaus). At first glance, this seems consistent with the zonal mean plot you plotted earlier in the tutorial, where the upper ocean tends to be warmer than deeper waters. However, in the integral equation above, \(\theta\) is not the only depth-dependent term. The global ocean area (\(A\)) also varies with depth, with the area of the global ocean decreasing with depth until only a few deep trenches contain water at the greatest ocean depths.

-

Let’s explore whether the ocean heat content plot we just created is driven by temperature variations or global ocean area variations with depth. One way to do this is to calculate and plot an integral of the global ocean area between each depth and the surface (i.e., the volume of the ocean above a each depth): \(Volume(z) = \iiint_{-z_1}^0 dz dA\).

-

If the volume as a function of depth looks similar to the heat content plot above, it would suggest that the smaller heat content of the deeper ocean (i.e., the plateau at large depths) is caused by the relatively small volume of water contained at these depths, rather than the vertical variations in temperature.

-
-
-
area_of_ocean = (
-    (subset_theta * subset_theta.dA / subset_theta).sum("latitude").sum("longitude")
-)  # we take an area integral first at each depth level
-
-sns.set_style(style="whitegrid")
-fig, ax = plt.subplots(figsize=(8, 6))
-ax.plot(-subset_theta.Zu, (area_of_ocean * subset_theta.dZ).cumsum())
-ax.set_xlabel("Depth (m)")
-ax.set_ylabel("Volume of the global ocean above this depth (m$^3$)")
-ax.set_title("Global ocean volume above each depth")
-
-
-
-
-
-

Question 1#

-
    -
  1. Based on the last two plots, are depth-variations in ocean heat content primarily due to vertical changes in the temperature or area of the ocean?

  2. -
-
-
-
-

Section 2: Changes in Ocean Heat Content#

-

In this section you will examine how the total (i.e., full-depth) heat content of the ocean has changed over time. You will also explore heat content changes within two specific upper-ocean layers: one above 700 m depth and another above 2000 m depth\(^*\). By analyzing these near surface layers, you will identify whether changes in the ocean’s heat content are evenly distributed through the water column.

-

\(^*\)Note: technically the grid of the data means you will be looking above 677 m and 1997 m respectively

-
-
-
# this cell may take a while to run!
-rho = 1026  # kg/m^3
-c_p = 3990  # J/(kg K)
-global_heat, years_to_plot, global_heat_upper2000, global_heat_upper700 = [], [], [], []
-for year in theta_annual.year:
-    years_to_plot.append(int(year))
-    subset_theta_year = theta_annual.sel(year=int(year))
-    global_heat.append(
-        float(
-            rho
-            * c_p
-            * (subset_theta_year * subset_theta_year.dZ * subset_theta_year.dA)
-            .sum("Z")
-            .sum("latitude")
-            .sum("longitude")
-        )
-    )
-    global_heat_upper2000.append(
-        float(
-            rho
-            * c_p
-            * (
-                (
-                    subset_theta_year.where(subset_theta_year.Zu > -2000)
-                    * subset_theta_year.dZ
-                    * subset_theta_year.dA
-                )
-                .sum("Z")
-                .sum("latitude")
-                .sum("longitude")
-            )
-        )
-    )
-    global_heat_upper700.append(
-        float(
-            rho
-            * c_p
-            * (
-                (
-                    subset_theta_year.where(subset_theta_year.Zu > -700)
-                    * subset_theta_year.dZ
-                    * subset_theta_year.dA
-                )
-                .sum("Z")
-                .sum("latitude")
-                .sum("longitude")
-            )
-        )
-    )
-
-# we now have lists, and list don't support math operations (-)
-# we also divide the values by 10**21 to make them easier to read.
-
-heat_anom_fulldepth = [
-    (heat - global_heat[0]) / 10**21 for heat in global_heat
-]  # remove year 1992
-heat_anom_upper2000 = [
-    (heat - global_heat_upper2000[0]) / 10**21 for heat in global_heat_upper2000
-]  # remove year 1992
-heat_anom_upper700 = [
-    (heat - global_heat_upper700[0]) / 10**21 for heat in global_heat_upper700
-]  # remove year 1992
-heat_anom_upper2000_700 = [
-    a - b for a, b in zip(heat_anom_upper2000, heat_anom_upper700)
-]  # difference series between 2000 to 700
-heat_anom_upperfulldepth_2000 = [
-    a - b for a, b in zip(heat_anom_fulldepth, heat_anom_upper2000)
-]  # difference series between fulldepth to 2000
-
-
-
-
-
-
-
fig, ax = plt.subplots(figsize=(8, 6))
-sns.set_style(style="whitegrid")
-ax.plot(years_to_plot, heat_anom_fulldepth, "k--")
-ax.plot(years_to_plot, heat_anom_upper700)
-ax.plot(years_to_plot, heat_anom_upper2000_700)
-ax.plot(years_to_plot, heat_anom_upperfulldepth_2000)
-ax.set_xlabel("Time")
-ax.set_ylabel("Heat content change (ZJ)")
-ax.legend(
-    [
-        "Full depth",
-        "Surface to 700 meters depth",
-        "700 to 2000 meters depth",
-        "Below 2000 meters depth",
-    ]
-)
-ax.set_title("Change in heat over time")
-
-
-
-
-
-

Questions 2#

-

The volume of the ocean model in the reanalysis product does not change over time. Thus the changes in ocean heat content that you just calculated are caused by changes in the ocean’s temperature. Most of the ocean’s warming (heat gain) has been within the upper ocean (shallower than 700 m). The deeper ocean has also warmed, but not as substantially as near-surface waters.

-
    -
  1. Based on this graph, what percentage of the ocean’s heat gain since 1992 is contained within the top 2000 meters?

  2. -
-
-
-
-

Section 3: Spatial Distribution of Ocean Heat Content#

-

You just saw that the ocean heat increase is concentrated near the ocean surface. Now you will explore where that heat is stored as a function of latitude and longitude. You can do this by creating a global map of ocean heat content in the upper 700 m of the ocean - which is essentially the same integral as above without the horizontal area integral: \(\int_{-700m}^0 c_p\rho_0\theta(x,y,z) dz\)

-
-
-
# first let's plot where heat is stored in the mean
-fig, ax = plt.subplots(
-    subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100
-)  # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html
-
-p = (
-    (
-        (rho * c_p * subset_theta.where(-subset_theta.Zu < 700) * subset_theta.dZ).sum(
-            "Z"
-        )
-    )
-).plot(
-    vmin=7e11,
-    vmax=8.15e11,
-    cmap=cmocean.cm.thermal,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "",
-    },
-    ax=ax,
-)
-ax.coastlines(color="grey", lw=0.5)
-ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax.add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax.set_title(
-    "Ocean Heat Content of top 700 m per unit area, mean of 1992 to 1994, J m$^{-2}$"
-)
-fig.tight_layout()
-
-
-
-
-

The lower latitude ocean contains more heat than the higher latitudes. This finding is consistent with your previous plot of warmer waters near the Equator during this tutorial.

-

Note: the color scale of this figure was chosen to emphasize latitudinal differences in ocean heat conent. As a result, some regions with shallow water depth display as black on the plot due to their relatively low column-integrated ocean heat content (\(<7 \times 10^{11} J m^{-2}\)). These black regions do not have zero ocean heat content.

-

Now let’s explore the spatial pattern of (full-depth) ocean heat content rate of change between 1992 and 2016.

-
-
-
# we already defined an object that's the mean over years 1992 to 1994 (subset_theta)
-# now define an object that's the mean over 2014 to 2016
-subset_theta_future = theta_annual.sel(year=slice("2014", "2016")).mean("year")
-
-length_of_time_period = 24 * 60 * 60 * 365 * (2015 - 1993)
-
-full_depth_heat_content_change = (
-    rho * c_p * subset_theta_future * subset_theta_future.dZ
-).sum("Z") - (rho * c_p * subset_theta * subset_theta.dZ).sum("Z")
-upper_700m_heat_content_change = (
-    rho
-    * c_p
-    * subset_theta_future.where(-subset_theta.Zu < 700)
-    * subset_theta_future.dZ
-).sum("Z") - (
-    rho * c_p * subset_theta.where(-subset_theta.Zu < 700) * subset_theta.dZ
-).sum(
-    "Z"
-)
-
-
-
-
-
-
-
fig, ax = plt.subplots(
-    1, 2, subplot_kw={"projection": ccrs.PlateCarree()}, figsize=(11, 12), dpi=100
-)  # this is from cartopy https://rabernat.github.io/research_computing_2018/maps-with-cartopy.html
-(full_depth_heat_content_change / length_of_time_period).plot(
-    ax=ax[0],
-    vmin=-10,
-    vmax=10,
-    cmap=cmocean.cm.balance,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "",
-    },
-)
-(upper_700m_heat_content_change / length_of_time_period).plot(
-    ax=ax[1],
-    vmin=-10,
-    vmax=10,
-    cmap=cmocean.cm.balance,
-    cbar_kwargs={
-        "shrink": 0.75,
-        "orientation": "horizontal",
-        "extend": "both",
-        "pad": 0.05,
-        "label": "",
-    },
-)
-ax[0].coastlines(color="grey", lw=0.5)
-ax[0].set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax[0].set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax[0].add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax[0].set_title(
-    "Rate of change in full-depth ocean heat content \n (2014-2016 minus 1992-1994); (J m$^{-2}$)/year"
-)
-fig.tight_layout
-ax[1].coastlines(color="grey", lw=0.5)
-ax[1].set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree())
-ax[1].set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
-ax[0].set_ylabel("Latitude")
-ax[1].set_ylabel("")
-ax[0].set_xlabel("Longitude")
-ax[1].set_xlabel("Longitude")
-lon_formatter = LongitudeFormatter(zero_direction_label=True)
-lat_formatter = LatitudeFormatter()
-ax[1].add_feature(cart.feature.LAND, zorder=100, edgecolor="k")
-ax[1].set_title(
-    "Rate of change in upper 700 m ocean heat content \n (2014-2016 minus 1992-1994); (J m$^{-2}$)/year"
-)
-fig.tight_layout
-
-
-
-
-

With these plots, you demonstrated that ocean heat gain is not evenly distributed across space. When comparing the two plots, you once again see that the upper ocean contains a large fraction of the warming (recall that Equatorial regions contribute more to the global mean than high-latitude regions becasue of their relatively large area).

-
-
-

Summary#

-

In this tutorial, you have quantified the spatial patterns and temporal changes of the ocean’s heat content. You showed that the upper layers of the ocean contain most of the ocean’s heat content, due to their relatively large area (and hence volume) compared to the deepest ocean layers. These upper layers also experience a disproportionately large fraction of the ocean warming that has been observed in recent decades. You also found that heat content distribution varies by latitude and longitude, and is typically greater in the lower latitudes, and the ocean’s heat gain over time is not uniformly distributed across different oceanic regions.

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title.html deleted file mode 100644 index 05e118431..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - Remote Sensing Land Ocean and Atmosphere — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Remote Sensing Land Ocean and Atmosphere

- -
-
- -
-
-
- - - - -
- -
-

Remote Sensing Land Ocean and Atmosphere#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading.html deleted file mode 100644 index 8aae8fb07..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/further_reading.html +++ /dev/null @@ -1,1062 +0,0 @@ - - - - - - - - - - - - Suggested Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Suggested Further Reading

- -
-
- -
-
-
- - - - -
- -
-

Suggested Further Reading#

- -
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1.html deleted file mode 100644 index c7cde44c1..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial1.html +++ /dev/null @@ -1,1401 +0,0 @@ - - - - - - - - - - - - Tutorial 1: Introduction to Remote Sensing — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 1: Introduction to Remote Sensing#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Dionessa Biton, Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

Today you will learn the basics of remote sensing, how to find remote sensing data, and how to use it for studying the climate across 8 tutorials.

-

The first tutorial introduces the fundamental concepts of remote sensing technologies and data. Although you won’t be doing any coding in this initial module, some compelling examples of how remote sensing data can be utilized to monitor our environment and society’s diverse facets will be illustrated.

-

By the end of this tutorial, you’ll be able to:

-
    -
  • Grasp key concepts of satellite remote sensing, including the electromagnetic spectrum, satellite orbits, and resolutions.

  • -
  • Appreciate the value and benefits of satellite remote sensing for climate studies through selected examples.

  • -
-
-

Video 1: What is Remote Sensing#

-
-

Video 1: What is Remote Sensing#

-
-
- - -Hide code cell source - -
-
# @title Video 1: What is Remote Sensing
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: What is Remote Sensing?#

-

Remote sensing is the technique of getting information from a distance (remotely). In daily life, photography is a very common format of remote sensing. In Earth and environmental science, sensors are often used on satellites in space or aircrafts in the sky to acquire information on topics such as agriculture, disaster response, and air pollution.

-

There are many organizations involved in this work, including government agencies like NASA and NOAA, private companies like Planet and Maxar, and various universities. They design and launch remote sensors on satellites and aircraft to monitor natural and human environments.

-

These remote sensors offer a unique perspective of Earth and enable data-informed decision making about our planet’s present and future state. For an example of the data these sensors can provide, this is the Visible Infrared Imager Radiometer Suite (VIIRS) onboard the Suomi-NPP satellite launched in 2011. The image below is the first global image it captured on November 28, 2011.

-

The first global composite of data captured by VIIRS on November 28, 2011 -The first global composite of data captured by VIIRS on November 28, 2011. (Credit: NASA Earth Observatory)

-
-

Section 1.1: Electromagnetic Spectrum#

-

The concept of the electromagnetic spectrum is at the core of remote sensing.

-
    -
  • Electromagnetic energy, radiated or reflected by objects, travels as waves through the atmosphere and the void of space. These waves exhibit different wavelengths (the distance between successive wave crests) and frequencies; a shorter wavelength corresponds to a higher frequency. Certain waves, like radio, microwave, and infrared, possess longer wavelengths, whereas others, such as ultraviolet, x-rays, and gamma rays, possess much shorter wavelengths.

  • -
  • Humans can only perceive visible light, situated in the middle of the spectrum that spans from longwave to shortwave radiation.

  • -
  • Nonetheless, we can engineer sensors to capture all other forms of electromagnetic energy emitted or reflected by elements of the Earth system, enabling us to monitor and research the Earth system.

  • -
-

Diagram of the Electromagnetic Spectrum -Diagram of the Electromagnetic Spectrum. (Credit: NASA Science)

-

What is the connection between the electromagnetic spectrum and the study and monitoring of Earth?

-

Every element of Earth’s system—land, water, air, and life—interacts with energy differently, reflecting, absorbing, or transmitting varying amounts depending on the wavelength. These energy interactions can be captured by strategically designed remote sensors, allowing us to analyze and understand these components.

-

For instance,

-
    -
  • Snow possesses a high albedo, reflecting up to 90% of incoming solar radiation in the visible light wavelength. This high reflectivity accounts for snow’s bright, white appearance to the human eye.

  • -
  • Conversely, the ocean reflects only about 6% of incoming solar radiation, absorbing the remainder. This absorption makes the ocean appear darker, though its appearance can be influenced by other factors like surface waves, phytoplankton presence, and water quality.

  • -
  • When solar energy is absorbed, it is typically re-emitted at longer wavelengths, such as infrared and thermal infrared. Thus, the ocean commonly re-emits absorbed solar energy as infrared radiation, which is utilized to monitor ocean temperatures. -These are processes we experience in our everyday life, even if we don’t consciously recognize them. Have you ever wondered why most leaves are green, why the sky is blue, or why flowers come in such a variety of colors?

  • -
-

The answers to these questions assist scientists in developing sensors to monitor vegetation health, air and water quality, detect wildfires, and many other crucial applications.

-

Want to learn more about electromagnetic spectrum? Take a tour of the electromagnetic spectrum with NASA Science!

-
-
-

Section 1.2: Satellite Orbits#

-

Satellites can occupy several types of orbits around Earth. The three common categories of orbits are:

-
    -
  • Low-Earth orbit (approximately 160 to 2,000 km above Earth): This orbit is common for many Earth-observing satellites, including polar-orbiting satellites (e.g., Terra, Aqua, CloudSat, CALIPSO). As the name suggests, polar-orbiting satellites travel from pole to pole, allowing Earth to rotate beneath them. This movement enables the onboard sensors to rapidly collect data across the entire globe, inclusive of the polar regions.

    -

    Illustration of the A-train polar-orbiting satellites operated by NASA and partner organizations.
    -Illustration of the A-train polar-orbiting satellites operated by NASA. (Credit: NASA)

    -
  • -
  • Medium-Earth orbit (approximately 2,000 to 35,500 km above Earth): this type of orbit is often used by the Global Positioning System (GPS) satellites.

  • -
  • High-Earth orbit (above 35,500 km above Earth): Satellites in this orbit are typically geostationary. They maintain a fixed position above a specific location on Earth’s surface. NOAA, for instance, operates two geostationary satellites that provide observations of the western hemisphere every five minutes and targeted observations of severe weather events every 30 seconds.

  • -
-
-
-

Satellite images of NOAA's GOES-West (on the left) and GOES-East (on the right) full disk data on the day of summer solitice of 2022. |#

-

Satellite images of NOAA’s GOES-West (on the left) and GOES-East (on the right) full disk data on the day of summer solstice of 2022. (Credit: NOAA )

-
-
-

Section 1.3: Resolution#

-

Resolution plays a crucial role in determining how data from a sensor can be interpreted and utilized. This can vary depending on the design of the satellite’s sensor and its orbit. Four types of resolution are important to consider for any dataset—radiometric, spatial, spectral, and temporal.

-

Spatial resolution is defined as the area on Earth’s surface represented by each pixel within a remotely sensed image. Typically, a pixel representing a smaller area indicates a higher spatial resolution. The fine the resolution (the smaller the numerical value), the more detail can be discerned. In the image below, you can observe the difference in pixelation between a higher resolution 30 m/pixel image (left image), a medium resolution 100 m/pixel image (center image), and a coarser resolution 300 m/pixel image (right image).

-
-
-

Different Spatial Resolution |#

-

(Credit: NASA Earth Observatory)

-

Consequently, the spatial resolution of remotely sensed data imposes constraints on the types of applications for which the data can be utilized. For instance, it would likely be inappropriate to use the right image above to map local roads, whereas the left image might be suitable for such an application.

-

Temporal resolution, also frequently referred to as revisiting frequency, is the time it takes for a satellite to complete an orbit and revisit the same observation area. This parameter often depends on the satellite’s orbit, the characteristics of the sensor, and the sensor’s field of view from space.

-
    -
  • For polar-orbiting satellites, temporal resolution can vary from 1 day to 16 days. The Moderate Resolution Imaging Spectroradiometer (MODIS, spatial resolution ranging from 250 m/pixel to 1 km/pixel depending on wavelength) flying onboard NASA’s Terra and Aqua satellite since 2000 has a temporal resolution of 1-2 days. Conversely, the Operational Land Imager (OLI, with a spatial resolution of 30 meter/pixel is featured on Landsat-8, a satellite jointly operated by NASA/USGS that has a narrower swath width and temporal resolution of 16 days.

  • -
  • Geostationary satellites maintain pace with Earth’s rotation, allowing them to provide sub-hourly temporal resolution for remotely sensed data. For instance, the latest generation of geostationary satellites offers a temporal resolution of 5-15 minutes, while their predecessors provided a resolution of 0.5-3 hours.

  • -
-

Spectral resolution represents a sensor’s capability to distinguish finer, or more and narrower, wavelengths. The more wavelengths a sensor can distinguish, the more information we can obtain and the more applications we can apply the data to. Typically, multispectral remote sensors feature 3-10 spectral bands, while hyperspectral sensors have hundreds of spectral bands, enabling us to scrutinize Earth’s objects in more detail.

-

For instance, the Airborne Visible/Infrared Imaging Spectrometer (AVIRIS) shown below records data in 224 spectral channels. These sensors enable us to differentiate between various rock and mineral types, vegetation types, water quality, and other features.

-
-
-

Sample image of AVIRIS over a lake and evaporation pond. |#

-

(Credit: NASA JPL)

-

Radiometric resolution quantifies the amount of information contained in each pixel and is often expressed as the number of bits representing the recorded energy. Each bit records an exponent of power 2. For instance, an 8-bit resolution equals \(2^8\), implying that the sensor can utilize 256 potential digital values (0-255) to store information. The image below from NASA Earth Observatory illustrates how radiometric resolution affects the level of detail visible in remotely sensed data.

-
-
-

Illustration of the impact of radiometric resoultion on remotely sensed data. |#

-

Credit: NASA

-

As illustrated in the image above, the higher the radiometric resolution (right image), the more values are available to store information, providing better discrimination between even the slightest differences in energy.

-

“Why can’t we have the sensor with the best resolution of all four categories?”

-

This is a great question! Due to technology limitations, it is very difficult to have the “perfect sensor”. If you’re aiming for high spatial resolution, there’s only a limited amount of energy in the area for that pixel. This implies that you’ll need a longer exposure to capture enough energy to extract meaningful information from that area. The longer the exposure, the less frequently you can revisit the same place. However, we can overcome this issue by using a constellation of satellites equipped with identical sensors to minimize the gaps between revisits. An example of this approach is the Sentinel-2 satellite pairs used by the European Space Agency.

-
-

Questions 1.3#

-
    -
  1. Now you have learned about four different types of resolution. Imagine a specific subject that you would like to study or monitor. It could be monitoring crop health, studying the impact of a landslide on a city, or any other topic of interest. Can you describe what type of remotely sensed data would be necessary for your project? Try to be specific - how often would you need the data (e.g., every few minutes, daily, weekly, etc.)? What would be the ideal spatial resolution for your purposes?

  2. -
-

Hint: You can look at NASA’s Earthdata Data Pathfinders to see if you can find some inspirations.

-

Click for solution

-
-
-
-
-

Section 2: Example Use Cases#

-

You’ve just completed a quick dive into the realm of satellite remote sensing and grasped some fundamental concepts. You might be wondering, “How can satellite data help answer some of my climate-related questions?”

-

To illuminate this, we’ll present six diverse examples of long-term satellite remote sensing data that track the dynamics of our land, ocean, and atmosphere. These animations are created using aggregated monthly satellite data, showcasing the fluidity of different Earth’s components. As we proceed, you’ll acquire computational skills to independently generate such animations.

-

These animations are all generated by NASA Earth Observatory using NASA satellite products. You can explore the dynamics of different components of the Earth system.

-
-

Section 2.1: Land/Cryosphere – Snow Coverage#

-

One of the most immediate effects of a warming planet is a reduction of snow coverage. Through long-term satellite data, we can accurately measure how the cryosphere has responded to changing temperature.

-

For instance, we can answer questions such as:

-
    -
  • Are there fewer days in which a region is covered by snow during the winter?

  • -
  • Has the first day of snow coverage shifted for a specific region?

  • -
  • Has the maximum snow coverage for a given region experienced any changes?

  • -
-

The answers to these questions bear significant implications for local water availability, thereby influencing crucial areas such as agriculture, wildlife conservation, and energy consumption.

-
-
-

modis_snow |#

-

Credit: NASA

-
-
-

Section 2.2: Land/Terrestrial Ecology – Vegetation Health#

-

The global terrestrial ecosystem is highly regulated by the climatic conditions of different geographical regions. Long-term satellite data records allow us to map vegetation dynamics at relatively high spatial resolution (i.e., 1-5 km) frequently (i.e., daily to monthly). This data can help us answer questions about the impact of climate on ecosystems, both natural (e.g., forest and grassland) and human-modified (e.g., cropland) including:

-
    -
  • Has the growing season of different ecosystems changed (e.g., lengthened or shortened) due to climate change?

  • -
  • What’s the impact of extreme events like drought, heatwave, wildfire, and flooding on different ecosystems?

  • -
  • How much carbon does the ecosystem store?

  • -
-

These applications have strong implications on communities through food security, culture activities, and other economic activities.

-
-
-

modis_ndvi |#

-

Credit: NASA

-
-
-

Section 2.3: Atmosphere – Cloud#

-

Clouds are one of the most complex proceses of the climate system. With long-term satellite data, different aspects of this critical component can be studied.

-

To study cloud processes, remotely sensed data can provide information about:

-
    -
  • When and where do clouds exist in the atmosphere?

  • -
  • Physical properties of clouds (e.g., cloud height, cloud depth, cloud top temperature).

  • -
  • Microphysical properties of clouds (e.g., cloud partical sizes).

  • -
-

Clouds are one of the major sources of uncertainty in future climate projections. Satellite data is valuable to help us deepen our understanding of cloud processes to better incorporate the effects of clouds in climate models.

-
-
-

modis_cloud |#

-

Cloud fraction, or the portion of a pixel covered by clouds. Credit: NASA

-
-
-

Section 2.4: Atmosphere – Rainfall#

-

In addition to temperature change, rainfall is another important aspect of climate change which has notable impacts on society and natural systems, for example through droughts and floods.

-

We can use remote sensing data to:

-
    -
  • Quantify the variations in rainfall rates across different regions over time. This information can support water resource planning and management to meet the needs of local communities.

  • -
  • Investigate the frequency and potential causes of extreme rainfall events and examine their impacts on societal and natural systems. Examples include studying hurricanes and extreme rainfall events.

  • -
-
-
-

rainfall |#

-

Credit: NASA

-
-
-

Section 2.5: Ocean – Sea Surface Temperature#

-

Given that over 70% of the Earth’s surface is covered by the ocean, the ocean plays a vital role in the functioning of the entire Earth system. Utilizing remotely sensed data, we can investigate changes in the physical ocean system and comprehend its impact on other interconnected systems.

-

Here are some key points regarding the significance of sea surface temperature (SST) in this context:

-
    -
  • SST serves as a crucial indicator for monitoring global surface temperature changes. By analyzing SST data, we can gain insights into the overall warming or cooling trends of the Earth’s surface.

  • -
  • Monitoring SST is essential for studying large-scale ocean circulation and climate variability, such as the El Niño-Southern Oscillation (ENSO). Changes in SST patterns can provide valuable information about the occurrence and strength of ENSO events, which have significant impacts on global weather patterns.

  • -
  • SST plays a pivotal role in the study and prediction of tropical cyclones. Warm SST provides the necessary energy for the formation and intensification of tropical cyclones, making SST data critical for understanding and forecasting these powerful storm systems.

  • -
-
-
-

modis_sst |#

-

Credit: NASA

-
-
-

Section 2.6: Ocean/Marine Ecosystem – Chlorophyll#

-

Similar to terrestrial ecosystems, remotely sensed data can be harnessed to monitor and study marine ecosystems. Within these ecosystems, phytoplankton, a diverse group of microorganisms, play a critical role in marine food webs, thus significantly impacting marine ecosystems and various human activities, including fisheries.

-

Satellite data allows us to monitor changes in chlorophyll concentration, which serves as a proxy for the abundance of phytoplankton. This data enables exploration of important questions such as:

-
    -
  • How have phytoplankton populations changed in response to shifting sea surface temperatures in different ocean basins?

  • -
  • By combining phytoplankton data with socioeconomic information, can we gain a comprehensive understanding of how the changing climate affects the fishing industry and the communities reliant on it.

  • -
-
-
-

modis_chl |#

-

Credit: NASA

-
-
-
-

Summary#

-

In this tutorial, you’ve explored the fundamental concepts of satellite remote sensing, equipping you with the knowledge to select appropriate remote sensing data for climate applications. Considerations such as spatial resolution and revisiting frequency were highlighted to ensure the optimal choice of data.

-

You also delved into the potential applications of satellite remote sensing for climate studies across land, ocean, and atmosphere. Specifically, you examined how satellite data can be utilized to monitor and analyze snow coverage, vegetation health, cloud, temperature changes, rainfall patterns, sea surface temperature, and phytoplankton abundance.

-

By understanding the capabilities and applications of satellite remote sensing, you are better equipped to leverage this technology for climate-related research, monitoring, and decision-making processes. This tutorial has laid the foundation for utilizing remote sensing data effectively in climate studies and emphasizes the vast potential it holds in advancing our understanding of Earth’s climate system.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2.html deleted file mode 100644 index cde317031..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial2.html +++ /dev/null @@ -1,1482 +0,0 @@ - - - - - - - - - - - - Tutorial 2: Exploring Satellite Climate Data Records — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 2: Exploring Satellite Climate Data Records#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will enhance your understanding of several key concepts and tools crucial in the field of satellite remote sensing for climate applications. Specifically, by the end of this session, you should be able to:

-
    -
  • Grasp the principle of inter-satellite calibration, a critical step in creating reliable climate data records.

  • -
  • Familiarize yourself with an array of long-term satellite remote sensing datasets that are tailored for climate applications, brought to you by three leading data providers: NOAA, NASA, and ESA.

  • -
  • Navigate and utilize these datasets in your own climate-related studies or projects.

  • -
-
-

Video 1: Video 1 Name#

-
-

Video 1: Video 1 Name#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Video 1 Name
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Satellite Climate Data Records#

-

You have already seen some examples of how satellite remote sensing data can be used for climate research and applications. But are all satellite data “created equal” for these purposes? There are a lot of considerations that need to be taken into account when using satellite data to monitor the long-term change of different components of the Earth system. In this section you will explore some of these considerations. Many of these are outlines in the definition of a climate data record given below.

-

Satellite Climate Data Records

-

In 2004, a committee convened by the US National Research Council defined a Climate Data Record (CDR) is “a time series of measurements of sufficient length, consistency and continuity to determine climate variability and change.” Although there are no specific number to determine the “sufficient length”, the typical climate length is considered to be at least 30 years. To achieve a stable, consistent, and reliable satellite CDR, we need to carefully calibrate the raw satellite data.

-
-

Section 1.1: Satellite Missions for Environmental Monitoring#

-

When it comes to monitoring environmental and climate changes in a region using weather stations, we have confidence in the data quality due to regular inspections and maintenance of these stations and instruments. In North America and Europe, for instance, there are numerous weather stations that have been operating for over a century, providing reliable long-term data.

-

In contrast, a single satellite mission has a designed operational lifespan of 5-8 years, and over time, the sensors on these satellites can deteriorate. While some satellites like Terra and Aqua have exceeded their designed lifespan and continue to operate successfully for more than 20 years, relying on a single satellite for climate monitoring and applications is exceedingly challenging, if not impossible.

-

Thankfully, we have a range of satellite platforms at our disposal that operate continuously and carry similar remote sensors, making it feasible to utilize multiple satellites together for climate-related purposes. Since the 1970s, dozens of satellites, including both polar-orbiting and geostationary satellites, have been designed for weather and environmental monitoring. While not originally intended for climate studies, researchers have developed methods to merge data from various satellite platforms, enabling the creation of robust long-term time series of satellite data. Moreover, future satellite missions are being carefully designed to extend these data records further.

-

The image below illustrates a timeline showcasing a selection of polar-orbiting satellite missions whose data are commonly employed to generate satellite Climate Data Records (CDRs).

-

satellite_timeline

-

Credit: Douglas Rao

-

The above figure shows the variety of satellite lifespans - some satellites only operated 3-5 years while there are a handful of satellite missions that operated for more than 15 years. Most importantly, we usually have at least two satellite missions operating during the same time period.

-

The overlap among satellite missions is critical for generating satellite CDRs, as we can compare the data during the overlapping time period and account for the systematic differences between satellite missions.

-

Meanwhile, there is significant technological advancement in remote sensors aboard different satellite missions. These different generations of remote sensors are identified by the solid grey lines in the figure. As indicated in the figure above, we have seen three major upgrades in sensor technologies. NOTE: these sensor changes also need to be accounted for when creating satellite CDRs.

-
-
-

Section 1.2: Inter-satellite Calibration#

-

As noted in the previous section, the change in satellite missions and remote sensors make it hard to use remotely sensed data “as it is” for climate applications. These changes often cause systematic differences in raw satellite data (see image below).

-

This figure is exagerating the possible systematic differences between raw data collected by different satellite missions. Nonetheless, these systematic differences can often cause large uncertainty for climate science when not addressed properly.

-

t2_calibration

-

To address the differences that are caused by sensor and satellite changes, we often perform an inter-satellite calibration - which adjusts the raw data collected by different satellites to a pre-defined reference to remove or minimize the systematic difference between data. This pre-defined reference is usually determined using data during there perioud of time when the satellites overlap (see image below). But we can also use other high quality reference data like surface observations, theoretical bases, or other ancillary data. Click here for more information on inter-satellite calibration.

-

t2_calibration_pt2

-

A well-calibrated multi-satellite date record is often assessed by examining the differences between satellite data during the overlapping time period. Once we are confident that the differences are minimal or within an accepted range, the long term time series based on multiple satellites can be used for climate applications.

-

The inter-satellite calibration step is the key to ensure that climate signals can be accurately reflected in the satellite data and not affected by the noise caused by change in satellite platforms and sensors. Therefore, when you are choosing satellite data for climate applications, you should be asking yourself a few questions:

-
    -
  • Are the data that you are planning to use collected by the same sensor and satellite?

  • -
  • If the data are from multiple satellites/sensors, are there steps to ensure the data are consistent across difference satellites/sensors?

  • -
  • Can you find out how the inter-satellite calibration is done and what is the level of difference between satellites/sensors?

  • -
-

These questions will help you determine if the remotely sensed data is appropriate for climate applications that you are interested in.

-

t2_calibration_pt3

-
-

Questions 1.2: Climate Connection#

-

Assuming that you are interested in using remote sensing data to understand how the rainfall amount and frequency have changed for the region that you are in since 1990. There are three different satellite data that you can choose from:

-
    -
  • Option A: Data from the most recent satellite missions designed to monitor global precipitation. The satellite has the most accurate sensor and the satellite was launched in 2014.

  • -
  • Option B: Data from three different satellite missions that carry similar sensors (first satellite: 1985-1994; second satellite: 1992-2006; third satellite: 2003-present).

  • -
  • Option C: Data from the three different satellite missions described in Option B that has been calibrated using long term surface measurements of rainfall in your region.

  • -
-

Can you choose the best data for your application? Why would you make this choice? Do you need more information to make the decision?

-

Click for solution

-
-
-
-
-

Section 2: Finding Satellite Climate Data Records#

-

Finding the right satellite Climate Data Records (CDRs) for your desired application can be a challenge. In this section, we will explore satellite data from three major remote sensing data providers: the National Atmospheric and Oceanic Administration (NOAA), the National Aeronautics and Space Administration (NASA), and the European Space Agency (ESA). While we won’t cover the code to analyze the data in this tutorial, you will learn how to do that in the upcoming tutorials.

-
-

Section 2.1: NOAA Climate Data Records#

-

The National Atmospheric and Oceanic Administration (NOAA) implemented the recommendation from the US National Research Council to develop satellite-based climate data records in the 2000s, and they have maintained a suite of operational CDRs that can be used to study different aspects of the changing climate system since then.

-

All NOAA CDR data are available freely to the public via NOAA National Centers for Environmental Information. Recently, the NOAA Open Data Dissemination Program also made all NOAA CDRs available on three major commercial cloud service providers (i.e., Amazon Web Service, Google Cloud, and Microsoft Azure). The NOAA Climate Data Records (CDRs) are available to anyone interested in accessing the data and are typically free of charge.

-

NOAA CDRs have two different categories with different purposes:

-
    -
  • Fundamental CDR (FCDR): This category consists of high-quality, low-level processed satellite sensor data, such as reflectance and brightness temperature. The FCDR datasets are carefully calibrated between satellites and sensors to ensure accuracy and consistency. These datasets are primarily used to assess and improve Earth system models (which you will learn about next week).

  • -
  • Thematic CDR: Thematic CDRs provide valuable information for understanding climate processes and changes in various domains. The thematic CDRs are divided into terrestrial, atmospheric, and ocean categories to reflect the different components of the climate system.

  • -
-

The table below lists a selection of thematic CDRs operates by NOAA. You can find out more about all NOAA CDRs by visiting the specific webpage of each CDR categories:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Dataset

Category

Start Year

Frequency

Spatial Resolution

Example Application Areas

Leaf Area Index and FAPAR

Terrestrial

1981

Daily

0.05°

Vegetation status monitoring; Agriculture monitoring; Crop yield/food security

Normalized Difference Vegetation Index (NDVI)

Terrestrial

1981

Daily

0.05°

Vegetation status monitoring; Vegetation phenology study

Snow Cover Extent (Northern Hemisphere)

Terrestrial

1966

Weekly (prior 1999-06)

Daily (post 1999-06)

~190 km

Hydrology; Water resources; Snow-climate feedback

Aerosol Optical Thickness

Atmospheric

1981

Daily & Monthly

0.1°

Air quality; Aerosol-climate feedback

PATMOS-x Cloud Properties

Atmospheric

1979

Daily

0.1°

Cloud process; Cloud-climate feedback

Precipitation - PERSIANN

Atmospheric

1982

Daily

0.25°

(60°S–60°N)

Hydrology; Water resources; Extreme events

Sea Surface Temperature - Optimum Interpolation

Oceanic

1981

Daily

0.25°

Climate variability; Marine heatwave; Marine ecosystem

Sea Ice Concentration

Oceanic

1978

Daily & Monthly

25 km

Crosphere study; Wildlife conservation; Ocean/climate modeling

-
-
-

Section 2.2: ESA Climate Change Initiative#

-

The European Space Agency (ESA) initiated a similar effort to develop consistent satellite-based long-term records to support the mission of climate monitoring for societal benefits in late 2010s. ESA Climate Change Initiative (CCI) has established more than 26 projects to develop satellite-based CDRs and directly engage with downstream users.

-

Through CCI, there is very strong emphasis on applications to support the monitoring of essential climate variables (ECVs) defined by Global Climate Observing System (GCOS). An ECV is defined as “a physical, chemical or biological variable or a group of linked variables that critically contributes to the characterization of Earth’ s climate.”

-

The table below lists a selection of ESA CCI datasets and their example application areas.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Dataset

Category

Duration

Frequency

Spatial Resolution

Example Application Areas

Sea Level

Oceanic

1992-2015

Monthly

0.25°

Sea level rise; Ocean modeling

Water Vapor

Atmospheric

1985-2019

Monthly

Water vapor-climate feedback; Hydrology

Fire

Terrestrial

1981-2020

Monthly

0.05° (pixel dataset)

0.25° (grid dataset)

Ecosystem disturbance; Extreme events; Social impact

Land Cover

Terrestrial

1992-2020

Yearly

300 m

Terrestrial modeling

Soil Moisture

Terrestrial

1978-2021

Daily

0.25°

Hydrology; Ecosystem impacts; Extreme events

-

You may observe that some datasets do not span the typical duration necessary for climate studies (for instance, 30 years). This occurrence is influenced by a variety of factors such as:

-
    -
  • Legacy sensors were not designed or capable of accurately capturing the ECVs of interest.

  • -
  • The CCI project is executed in stages, initiating with the most recent satellite missions/sensors. However, plans are underway to incorporate older data from heritage satellite missions/sensors.

  • -
-

Moreover, each ESA CCI project frequently offers different versions of ECV variables, each designed for specific applications. The specifications of these ECV variables might deviate from the table above if they represent a subset of the time period, utilizing data from the latest sensors. The table primarily provides information on the longest time record for each CCI.

-

All ESA CCI data are openly accessible and free of charge to users without any restrictions. All these resources can be accessed via the ESA CCI Open Data Portal.

-

To further assist users in accessing and analyzing the CCI data, ESA has also developed the CCI Analysis Toolbox (Cate). It is described as a “cloud-enabled computing environment geared for scientists who need to analyze, process, and visualize ESA’s climate data and other spatiotemporal data.”

-
-
-

Section 2.3: NASA Earth System Data Records#

-

Similar to other two satellite data providers, the National Aeronautics and Space Administration (NASA) also produces and distributes long-term satellite-based data records that may be suitable for different climate applications. NASA Earth System Data Records (ESDRs) are defined as “as a unified and coherent set of observations of a given parameter of the Earth system, which is optimized to meet specific requirements in addressing science questions.”

-

While NASA’s ESDR does not specifically target climate, these records are often created to monitor and study various components of the climate system. For instance, surface temperature, global forest coverage change, atmospheric compositions, and ice sheet velocity are all areas of focus.

-

The table below showcases a selection of NASA ESDRs datasets that nicely complement the satellite Climate Data Records (CDRs) offered by NOAA and ESA.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Dataset

Category

Duration

Frequency

Spatial Resolution

Example Application Areas

Sulfur Dioxide

Atmospheric

1978-2022

Daily

50 km

Atmospheric modeling; Air quality

Ozone

Atmospheric

1970-2013

Monthly

Ozone monitoring; Air quality

Sea Surface Height

Oceanic

1992-ongoing

5-Day

1/6°

Sea level rise; Ocean modeling

GPCP Satellite-Gauge Combined Precipitation Data

Atmospheric

1983-2020

Daily & Monthly

0.5°

Hydrology; Extreme events

-

If you’ve visited the linked NASA ESDR page above, you may have noticed that it appears less structured compared to the NOAA CDR program and the ESA CCI open data portal. This is partly because NASA operates different data centers for distinct application areas (e.g., atmosphere, snow/ice, land, etc.). However, you can always visit NASA’s Earth Data Search – a comprehensive portal for accessing datasets provided by NASA’s Earth science data system. To access the data, you’ll be required to create a user account. Rest assured, registration for the NASA Earthdata system is free and open to anyone.

-
-

Questions 2.3: Climate Connection#

-

Now that you have been introduced to three major sources of remote sensing data for climate applications, it’s time to identify the dataset that best suits your requirements. In this exercise, you can choose one or more data providers (NASA, NOAA, ESA) and explore their satellite data to determine which one aligns best with your application needs.

-
-
-
### Step 1: Describe your application interest. Be as specific as you can, this
-### will help you narrow down your search for the data
-"""
-
-"""
-### Step 2: Identify an ideal spatial and temporal resolution for your application
-### (e.g., daiyl/weekly/monthly, 500 m/5 km/25 km/...?)
-"""
-
-"""
-### Step 3: Explore the data from one of the data providers to see if there is
-### any data that can fit your application need and explain why
-"""
-
-"""
-
-
-
-
-
'\n\n'
-
-
-
-
-
-
-
-
-

Summary#

-

In this tutorial, we learned about

-
    -
  • how Inter-satellite calibration is a critical step to produce a consistent remote sensing dataset for climate applications and allows us to use data from different satellites and sensors over different but overlappign time-periods.

  • -
  • major collections of satellite-based datasets for climate applications, including NOAA Climate Data Records, ESA Climate Change Initiative, and NASA Earth System Data Records.

  • -
-

In the upcoming tutorial, we will be transitioning towards exploring how to utilize computational tools to access publicly available remote sensing data for climate applications.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3.html deleted file mode 100644 index eb4cbfc3a..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial3.html +++ /dev/null @@ -1,1877 +0,0 @@ - - - - - - - - - - - - Tutorial 3: Visualizing Satellite CDR - Global Vegetation Mapping — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 3: Visualizing Satellite CDR - Global Vegetation Mapping#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will acquire skills necessary for accessing and analyzing satellite remote sensing products, particularly in the context of climate applications. We will be using vegetation mapping as an example, and use long-term vegetation greeness data to demonstrate these skills.

-

By the end of this tutorial you will be able to:

-
    -
  • Locate, access, and visualize vegetation greeness data (NDVI) from the cloud using xarray and matplotlib.

  • -
  • Understand how to use quality flag information included in the datasets to filter out data that is not acceptable to use for climate analysis.

  • -
-
-
-

Setup#

-
-
-
# !pip install s3fs --quiet
-# !pip install cartopy --quiet
-
-
-
-
-
-
-
# imports
-import s3fs
-import numpy as np
-import xarray as xr
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import datetime
-import boto3
-import botocore
-import pooch
-import os
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import s3fs
-      3 import numpy as np
-      4 import xarray as xr
-
-ModuleNotFoundError: No module named 's3fs'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Video 1 Name#

-
-

Video 1: Video 1 Name#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Video 1 Name
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation="", filename=""):
-    shared_location = "/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Satellite Monitoring of Vegetation Status#

-

As we learned in the previous tutorial, all the National Atmospheric and Oceanic Administration Climate Data Record (NOAA-CDR) datasets are available both at NOAA National Centers for Environmental Information (NCEI) and commercial cloud platforms. Here, we are accessing the data directly via the Amazon Web Service (AWS). You can find out information about the NOAA CDRs on AWS’s Open Data Registry.

- -

The index we will use in this tutorial is the Normalized Difference Vegetation Index (NDVI). It is one of the most commonly used remotely sensed indices. It measures the “greeness” of vegetation, and is useful in understanding vegetation density and assessing changes in plant health. For example, NDVI can be used to study the impact of drought, heatwave, and insect infestation on plants covering Earth’s surface.

-
-

Section 1.1: Access NOAA NDVI CDR Data from AWS#

-

If we go to the cloud storage space (or a S3 bucket) that hosts NOAA NDVI CDR data, you will see the pattern of how the NOAA NDVI CDR is organized:

-

s3://noaa-cdr-ndvi-pds/data/1981/AVHRR-Land_v005_AVH13C1_NOAA-07_19810624_c20170610041337.nc

-

We can take advantage of the pattern to search for the data file systematically.

-
-

Parent directory: s3://noaa-cdr-ndvi-pds/data/
-Sub-directory for each year: 1981/
-File name of each day: AVHRR-Land_v005_AVH13C1_NOAA-07_19810624_c20170610041337.nc

-
-

The file name also has a clear pattern:

-
-

Sensor name: AVHRR
-Product category: Land
-Product version: v005
-Product code: AVH13C1
-Satellite platform: NOAA-07
-Date of the data: 19810624
-Processing time: c20170610041337 (This will change for each file based on when the file was processed)
-File format: .nc (netCDR-4 format)

-
-

In other words, if we are looking for the data of a specific day, we can easily locate where the file might be.

-

For example, if we want to find the AVHRR data for the day of 2002-03-12 (or March 12, 2002), you can use:

-

s3://noaa-cdr-ndvi-pds/data/2002/AVHRR-Land_v005_AVH13C1_*_20020312_c*.nc

-

The reasaon that we put * in the above directory is because we are not sure about what satellite platform this data is from and when the data was processed. The * is called a wildcard, and is used because we want all the files that contain our specific criteria, but do not want to have to specify all the other pieces of the filename we are not sure about yet. It should return all the data satisfying that initial criteria and you can refine further once you see what is available. Essentially, this first step helps to narrow down the data search.

-
-
-
# to access the NDVI data from AWS S3 bucket, we first need to connect to s3 bucket
-fs = s3fs.S3FileSystem(anon=True)
-
-# we can now check to see if the file exist in this cloud storage bucket using the file name pattern we just described
-date_sel = datetime.datetime(
-    2002, 3, 12, 0
-)  # select a desired date and hours (midnight is zero)
-
-# automatic filename from data_sel. we use strftime (string format time) to get the text format of the file in question.
-file_location = fs.glob(
-    "s3://noaa-cdr-ndvi-pds/data/"
-    + date_sel.strftime("%Y")
-    + "/AVHRR-Land_v005_AVH13C1_*"
-    + date_sel.strftime("%Y%m%d")
-    + "_c*.nc"
-)
-# now let's check if there is a file match the pattern of the date that we are interested in.
-file_location
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 2
-      1 # to access the NDVI data from AWS S3 bucket, we first need to connect to s3 bucket
-----> 2 fs = s3fs.S3FileSystem(anon=True)
-      4 # we can now check to see if the file exist in this cloud storage bucket using the file name pattern we just described
-      5 date_sel = datetime.datetime(
-      6     2002, 3, 12, 0
-      7 )  # select a desired date and hours (midnight is zero)
-
-NameError: name 's3fs' is not defined
-
-
-
-
-
-

Coding Exercises 1.1#

-
    -
  1. NDVI CDR data switched sensors on 2014 from AVHRR (the older generation sensor) to VIIRS (the newest generation sensor). Using the code above and the list of data names for VIIRS, find data from a day after 2014. You will need to modify string input into glob() to do so.

  2. -
-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Choose identify the location of the NDVI CDR data on Amazon Web Service for a day after 2014."
-)
-#################################################
-
-# select a desired date and hours (midnight is zero)
-exercise_date_sel = ...
-
-# automatic filename from data_sel. we use strftime (string format time) to get the text format of the file in question.
-exercise_file_location = ...
-
-# now let's check if there is a file match the pattern of the date that we are interested in.
-exercise_file_location
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[7], line 3
-      1 #################################################
-      2 # Students: Fill in missing code (...) and comment or remove the next line
-----> 3 raise NotImplementedError(
-      4     "Student exercise: Choose identify the location of the NDVI CDR data on Amazon Web Service for a day after 2014."
-      5 )
-      6 #################################################
-      7 
-      8 # select a desired date and hours (midnight is zero)
-      9 exercise_date_sel = ...
-
-NotImplementedError: Student exercise: Choose identify the location of the NDVI CDR data on Amazon Web Service for a day after 2014.
-
-
-
-
-

Click for solution

-
-
-
-

Section 1.2: Read NDVI CDR Data#

-

Now that you have the location of the NDVI data for a specific date, you can read in the data using the python library xarray to open the netCDF-4 file, a common data format used to store satellite and climate datasets.

-
-
-
# first, we need to open the connection to the file object of the selected date.
-# we are still using the date of 2002-03-12 as the example here.
-
-# to keep up with previous tutorials (consistency), we are going to use boto3 and pooch to open the file.
-# but note s3fs also has the ability to open files from s3 remotely.
-
-client = boto3.client(
-    "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-)  # initialize aws s3 bucket client
-
-ds = xr.open_dataset(
-    pooch_load(
-        filelocation="http://s3.amazonaws.com/" + file_location[0],
-        filename=file_location[0],
-    )
-)  # open the file
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 7
-      1 # first, we need to open the connection to the file object of the selected date.
-      2 # we are still using the date of 2002-03-12 as the example here.
-      3 
-      4 # to keep up with previous tutorials (consistency), we are going to use boto3 and pooch to open the file.
-      5 # but note s3fs also has the ability to open files from s3 remotely.
-----> 7 client = boto3.client(
-      8     "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-      9 )  # initialize aws s3 bucket client
-     11 ds = xr.open_dataset(
-     12     pooch_load(
-     13         filelocation="http://s3.amazonaws.com/" + file_location[0],
-     14         filename=file_location[0],
-     15     )
-     16 )  # open the file
-     17 ds
-
-NameError: name 'boto3' is not defined
-
-
-
-
-

The output from the code block tells us that the NDVI data file of 2002-03-12 has dimensions of 3600x7200. This makes sense for a dataset with the spatial resolution of 0.05°×0.05° that spans 180° of latitude and 360° of longitude. There is another dimension of the dataset named time. Since it is a daily data file, it only contains one value.

-

Two main data variables are in this dataset are NDVI and QA.

-
    -
  • NDVI is the variable that contains the value of Normalized Difference Vegetation Index (NDVI - ranges between -1 and 1) that can be used to measure the vegetation greeness.

  • -
  • QA is the variable that indicates the quality of the NDVI values for each corresponding grid. It reflects whether the data is of high quality or should be discarded because of various reasons (e.g., bad sensor data, potentially contanminated by clouds).

  • -
-
-
-

Section 1.3: Visualize NDVI CDR Data#

-
-
-
# examine NDVI values from the dataset
-ndvi = ds.NDVI
-ndvi
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # examine NDVI values from the dataset
-----> 2 ndvi = ds.NDVI
-      3 ndvi
-
-NameError: name 'ds' is not defined
-
-
-
-
-

To visualize the raw data, we will will plot it using matplotlib by calling .plot() on our xarray DataArray.

-
-
-
# figure settings:
-# vmin & vmax: minimum and maximum values for the legend
-# aspect: setting the aspect ratio of the figure, must be combined with `size`
-# size: setting the overall size of the figure
-
-# to make plotting faster and less memory intesive we use coarsen to reduce the number of pixels
-ndvi.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(
-    vmin=-0.1, vmax=1.0, aspect=1.8, size=5
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 7
-      1 # figure settings:
-      2 # vmin & vmax: minimum and maximum values for the legend
-      3 # aspect: setting the aspect ratio of the figure, must be combined with `size`
-      4 # size: setting the overall size of the figure
-      5 
-      6 # to make plotting faster and less memory intesive we use coarsen to reduce the number of pixels
-----> 7 ndvi.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(
-      8     vmin=-0.1, vmax=1.0, aspect=1.8, size=5
-      9 )
-
-NameError: name 'ndvi' is not defined
-
-
-
-
-
-
-

Section 1.4: Mask NDVI Data Using a Quality Flag#

-

As stated earlier, there is also a variable QA that indicates the quality of the NDVI value for each grid cell. This quality information is very important when using satellite data to ensure the climate analysis is done using only the highest quality data.

-

For NDVI CDR data, it has a complex quality flag system that is represented using a 16-bit system. Although when you explore the values of QA,= it appears to be normal numeric values, the QA value needs to be converted to binary values of 16 bits and recognize the quality flag based on the information listed in the table below.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Bit No.

Description

Value=1

Value=0

15

Flag to indicate if the pixel is in polar region

Yes

No

14

Flag to indicate BRDF-correction issues

Yes

No

13

Flag to indicate RH03 value is invalid

Yes

No

12

Flag to indicate AVHRR Channel 5 value is invalid

Yes

No

11

Flag to indicate AVHRR Channel 4 value is invalid

Yes

No

10

Flag to indicate AVHRR Channel 3 value is invalid

Yes

No

9

Flag to indicate AVHRR Channel 2 value is invalid

Yes

No

8

Flag to indicate AVHRR Channel 1 value is invalid

Yes

No

7

Flag to indicate all 5 AVHRR Channels are valid

Yes

No

6

Flag to indicate the pixel is at night (no visible channel data)

Yes

No

5

Flag to indicate the pixel is over dense dark vegetation

Yes

No

4

Flag to indicate the pixel is over sunglint (over ocean)

Yes

No

3

Flag to indicate the pixel is over water

Yes

No

2

Flag to indicate the pixel contains cloud shadow

Yes

No

1

Flag to indicate the pixel is cloudy

Yes

No

0

(Unused)

Yes

No

-

This shows the complex system to ensure that satellite CDR data is of high quality for climate applications. But how can we decifer the quality of a given pixel?

-

Assuming that we have a grid with QA=18, when converted into a binary value with the length of 16 bits it becomes 0000000000010010. That is, every QA value will be convereted into a list of 1’s and 0’s that is 16 numbers long. Converting our example above of 18 we have:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Bit15

Bit14

Bit13

Bit12

Bit11

Bit10

Bit9

Bit8

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

0

0

0

0

0

0

0

0

1

0

0

1

0

0

1

0

No

No

No

No

No

No

No

No

Yes

No

No

Yes

No

No

Yes

No

-

Note here that 1 is True and 0 is False. Interpreting the table above, for a quality flag of 18, the NDVI is retrieved from valid values of AVHRR channels (Bit7=1) and the grid is over dense dark vegetation (Bit5=1), but the grid is cloudy (Bit1=1). Therefore, the QA tells us that we should not use this grid since it is covered by clouds and does not reflect vegetation information on the land surface.

-

If you are a little confused by how to convert to binary, that is ok! This is a skill that you can practice more in your projects. For this tutorial, we will define a function that will automate our selection process of avoiding cloudy data.

-
-
-
# define a function to extract high quality NDVI data
-def get_quality_info(QA):
-    """
-    QA: the QA value read in from the NDVI data
-
-    High quality NDVI should meet the following criteria:
-    Bit 7: 1 (All AVHRR channels have valid values)
-    Bit 2: 0 (The pixel is not covered by cloud shadow)
-    Bit 1: 0 (The pixel is not covered by cloud)
-
-    Output:
-    True: high quality
-    False: low quality
-    """
-    # unpack quality assurance flag for cloud (byte: 1)
-    cld_flag = (QA % (2**2)) // 2
-    # unpack quality assurance flag for cloud shadow (byte: 2)
-    cld_shadow = (QA % (2**3)) // 2**2
-    # unpack quality assurance flag for AVHRR values (byte: 7)
-    value_valid = (QA % (2**8)) // 2**7
-
-    mask = (cld_flag == 0) & (cld_shadow == 0) & (value_valid == 1)
-
-    return mask
-
-
-
-
-
-
-
# get the quality assurance value from NDVI data
-QA = ds.QA
-
-# create the high quality information mask
-mask = get_quality_info(QA)
-
-# check the quality flag mask information
-mask
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # get the quality assurance value from NDVI data
-----> 2 QA = ds.QA
-      4 # create the high quality information mask
-      5 mask = get_quality_info(QA)
-
-NameError: name 'ds' is not defined
-
-
-
-
-

The output of the previous operation gives us a data array with logical values to indicate if a grid has high quality NDVI values or not. Now let’s mask out the NDVI data array with this quality information to see if this will make a difference in the final map.

-
-
-
# use `.where` to only keep the NDVI values with high quality flag
-ndvi_masked = ndvi.where(mask)
-ndvi_masked
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # use `.where` to only keep the NDVI values with high quality flag
-----> 2 ndvi_masked = ndvi.where(mask)
-      3 ndvi_masked
-
-NameError: name 'ndvi' is not defined
-
-
-
-
-

As you may have noticed, a lot of the NDVI values in the masked data array becomes nan which means not a number. This means that the grid does not have a high quality NDVI value based on the QA value. Now, let’s plot the map one more time to see the difference after the quality masking.

-
-
-
# re-plot the NDVI map using masked data
-ndvi_masked.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(
-    vmin=-0.1, vmax=1.0, aspect=1.8, size=5
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 # re-plot the NDVI map using masked data
-----> 2 ndvi_masked.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(
-      3     vmin=-0.1, vmax=1.0, aspect=1.8, size=5
-      4 )
-
-NameError: name 'ndvi_masked' is not defined
-
-
-
-
-

Note the large difference after the quality mask was applied and you removed data that was compromised due to clouds. Since the NDVI value is calculated using the reflectance values of the red and near-infrared spectral band, this value is only useful for vegetation and surface monitoring when there are no clouds present. Thus, we always need to remove the grid with clouds in the data.

-
-

Coding Exercises 1.4#

-

You just learned how to use xarray and matplotlib to access NDVI CDR data from AWS and visualize it. Can you find a different date that you are interested in and visualize the high quality NDVI data of that day? Note the solution is just an example of a date that you could choose.

-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Access and plot NDVI for a date of your choosing."
-)
-#################################################
-
-# define the date of your interest YYYYMMDD (e.g., 20030701)
-# select a desired date and hours (midnight is zero)
-date_sel_exercise = ...
-
-# locate the data in the AWS S3 bucket
-# hint: use the file pattern that we described
-file_location_exercise = ...
-
-# open file connection to the file in AWS S3 bucket and Use xarray to open the NDVI CDR file
-# open the file
-ds_exercise = ...
-
-# get the QA value and extract the high quality data mask and Mask NDVI data to keep only high quality value
-# hint: reuse the get_quality_info helper function we defined
-ndvi_masked_exercise = ...
-
-# plot high quality NDVI data
-# hint: use plot() function
-ndvi_masked_exercise.coarsen(latitude=5).mean().coarsen(longitude=5).mean().plot(
-    vmin=-0.1, vmax=1.0, aspect=1.8, size=5
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[15], line 3
-      1 #################################################
-      2 # Students: Fill in missing code (...) and comment or remove the next line
-----> 3 raise NotImplementedError(
-      4     "Student exercise: Access and plot NDVI for a date of your choosing."
-      5 )
-      6 #################################################
-      7 
-      8 # define the date of your interest YYYYMMDD (e.g., 20030701)
-      9 # select a desired date and hours (midnight is zero)
-     10 date_sel_exercise = ...
-
-NotImplementedError: Student exercise: Access and plot NDVI for a date of your choosing.
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-
-

Summary#

-

In this tutorial, you successfully accessed and visualized one of the most commonly used remotely sensed climate datasets for land applications! In addition, you should now:

-
    -
  • Understand the file organization pattern to help you identify the data that you are interested in.

  • -
  • Understand thow to extract only the high quality data using quality flags provided with the datasets.

  • -
  • Know how to apply a quality flag mask and plot the resulting data.

  • -
-

In the next tutorial, you will explore how to perform time series analysis, including calculating a climatology and anomaly with precipitation data.

-
-
-

Resources#

-

Data from this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4.html deleted file mode 100644 index bd355b0ea..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial4.html +++ /dev/null @@ -1,1886 +0,0 @@ - - - - - - - - - - - - Tutorial 4: Understanding Climatology Through Precipitation Data — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 4: Understanding Climatology Through Precipitation Data#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will explore the concept of a climatology, and learn how to leverage it using satellite precipitation data. You have already practiced how to calcuate a climatology using temperature data in the overview of the climate system day. That data spanned only 14 years, and typically you would want your data to span at least 30 years to calculate a climatology. Here you will use data spanning several decades to explore the seasonal cycle of precpitation at a specific location.

-

Upon completing this tutorial, you’ll be able to:

-
    -
  • Comprehend the fundamentals of climatologies.

  • -
  • Compute a climatology utilizing long-term satellite precipitation data.

  • -
  • Create informative maps including features such as projections, coastlines, and other advanced plotting components.

  • -
-

Throughout this tutorial, you’ll employ NOAA’s monthly precipitation climate data records as the primary resource to demonstrate the process of calculating a long-term climatology for climate analysis. Specifically, you’ll use the Global Precipitation Climatology Project (GPCP) Monthly Precipitation Climate Data Record (CDR). As part of your investigation, you’ll focus on a specific location, observing its data across the entire time duration covered by the GPCP monthly dataset.

-
-
-

Setup#

-
-
-
# !pip install s3fs --quiet
-
-# properly install cartopy in colab to avoid session crash
-# !apt-get install libproj-dev proj-data proj-bin --quiet
-# !apt-get install libgeos-dev --quiet
-# !pip install cython --quiet
-# !pip install cartopy --quiet
-
-# !apt-get -qq install python-cartopy python3-cartopy  --quiet
-# !pip uninstall -y shapely  --quiet
-# !pip install shapely --no-binary shapely  --quiet
-
-
-
-
-
-
-
# imports
-import s3fs
-import xarray as xr
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import boto3
-import botocore
-import pooch
-import os
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import s3fs
-      3 import xarray as xr
-      4 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 's3fs'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Video 1 Name#

-
-

Video 1: Video 1 Name#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Video 1 Name
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation="", filename=""):
-    shared_location = "/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Obtain Monthly Precipitation Data#

-

In this tutorial, the objective is to demonstrate how to calculate the long-term precipitation climatology using monthly precipitation climate data records from NOAA.

-

You’ll be utilizing the Global Precipitation Climatology Project (GPCP) Monthly Precipitation Climate Data Record (CDR). This dataset contains monthly satellite-gauge data and corresponding precipitation error estimates from January 1979 to the present, gridded at a 2.5°×2.5° resolution. Satellite-gauge means that the climate data record (CDR) is a compilation of precipitation data from multiple satellites and in-situ sources, combined into a final product that optimizes the advantages of each type of data.

-

While a higher spatial resolution (1°×1°) at daily resolution exists for varied applications, we will restrict ourselves to the coarser resolution monthly data due to computational limitations. However, you are encouraged to delve into the daily higher resolution data for your specific project needs.

-
-

Section 1.1: Access GPCP Monthly CDR Data on AWS#

-

To perform analysis, we will need to access the monthly data files from AWS first. We will use the skills that we learned from last tutorial on accessing data from an AWS S3 bucket.

-
-
-
# connect to the AWS S3 bucket for the GPCP Monthly Precipitation CDR data
-fs = s3fs.S3FileSystem(anon=True)
-
-# get the list of all data files in the AWS S3 bucket fit the data file pattern.
-file_pattern = "noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc"
-file_location = fs.glob(file_pattern)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 2
-      1 # connect to the AWS S3 bucket for the GPCP Monthly Precipitation CDR data
-----> 2 fs = s3fs.S3FileSystem(anon=True)
-      4 # get the list of all data files in the AWS S3 bucket fit the data file pattern.
-      5 file_pattern = "noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc"
-
-NameError: name 's3fs' is not defined
-
-
-
-
-
-
-
print("Total number of GPCP Monthly precipitation data files:")
-print(len(file_location))
-
-
-
-
-
Total number of GPCP Monthly precipitation data files:
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 print("Total number of GPCP Monthly precipitation data files:")
-----> 2 print(len(file_location))
-
-NameError: name 'file_location' is not defined
-
-
-
-
-

We have more than 500 GPCP monthly precipitation CDR data files in the AWS S3 bucket. Each data file contains the data of each month globally starting from January 1979. Now, let’s open a single data file to look at the data structure before we open all data files.

-
-
-
# first, open a client connection
-client = boto3.client(
-    "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-)  # initialize aws s3 bucket client
-
-# read single data file to understand the file structure
-# ds_single = xr.open_dataset(pooch.retrieve('http://s3.amazonaws.com/'+file_location[0],known_hash=None )) # open the file
-ds_single = xr.open_dataset(
-    pooch_load(
-        filelocation="http://s3.amazonaws.com/" + file_location[0],
-        filename=file_location[0],
-    )
-)
-# check how many variables are inluded in one data file
-ds_single.data_vars
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # first, open a client connection
-----> 2 client = boto3.client(
-      3     "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-      4 )  # initialize aws s3 bucket client
-      6 # read single data file to understand the file structure
-      7 # ds_single = xr.open_dataset(pooch.retrieve('http://s3.amazonaws.com/'+file_location[0],known_hash=None )) # open the file
-      8 ds_single = xr.open_dataset(
-      9     pooch_load(
-     10         filelocation="http://s3.amazonaws.com/" + file_location[0],
-     11         filename=file_location[0],
-     12     )
-     13 )
-
-NameError: name 'boto3' is not defined
-
-
-
-
-

From the information provided by xarray, there are a total of five data variables in this monthly data file, including precip for the monthly precipitation and precip_error for the monthly precipitation error.

-
-
-
# check the coordinates for the data file
-ds_single.coords
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # check the coordinates for the data file
-----> 2 ds_single.coords
-
-NameError: name 'ds_single' is not defined
-
-
-
-
-

All data is organized in three dimensions: latitude, longitude, and time. We want to create a three-dimensional data array for the monthly precipitation data across the entire data period (from January 1979 until present) so we must open all the available files

-
-
-
# open all the monthly data files
-# this process will take ~ 5 minute to complete due to the number of data files.
-
-# file_ob = [pooch.retrieve('http://s3.amazonaws.com/'+file,known_hash=None ) for file in file_location]
-file_ob = [
-    pooch_load(filelocation="http://s3.amazonaws.com/" + file, filename=file)
-    for file in file_location
-]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 7
-      1 # open all the monthly data files
-      2 # this process will take ~ 5 minute to complete due to the number of data files.
-      3 
-      4 # file_ob = [pooch.retrieve('http://s3.amazonaws.com/'+file,known_hash=None ) for file in file_location]
-      5 file_ob = [
-      6     pooch_load(filelocation="http://s3.amazonaws.com/" + file, filename=file)
-----> 7     for file in file_location
-      8 ]
-
-NameError: name 'file_location' is not defined
-
-
-
-
-
-
-
# using this function instead of 'open_dataset' will concatenate the data along the dimension we specify
-ds = xr.open_mfdataset(file_ob, combine="nested", concat_dim="time")
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # using this function instead of 'open_dataset' will concatenate the data along the dimension we specify
-----> 2 ds = xr.open_mfdataset(file_ob, combine="nested", concat_dim="time")
-      3 ds
-
-NameError: name 'xr' is not defined
-
-
-
-
-

In the above code, we used combine='nested', concat_dim='time' to combine all monthly precipitation data into one data array along the dimension of time. This command is very useful when reading in multiple data files of the same structure but covering different parts of the full data record.

-

Since we are interested in the precipitation data globally at this moment, let’s extract the entire data array of precipitation from the entire dataset.

-
-
-
# examine the precipitation data variable
-precip = ds.precip
-precip
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # examine the precipitation data variable
-----> 2 precip = ds.precip
-      3 precip
-
-NameError: name 'ds' is not defined
-
-
-
-
-

As you can see, the data array has the dimensions of time longitude latitude. Before delving into further analysis, let’s visualize the precipitation data to gain a better understanding of its patterns and characteristics.

-
-
-

Section 1.2: Visualize GPCP Data Using Cartopy#

-

In previous tutorials, we’ve learned how to make simple visualization using matplotlib using latitude and longitude as the y-axis and x-axis.

-
-
-
# create simple map of the GPCP precipitation data using matplotlib
-fig, ax = plt.subplots(figsize=(9, 6))
-
-# use the first month of data as an example
-precip.sel(time="1979-01-01").plot(ax=ax)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # create simple map of the GPCP precipitation data using matplotlib
-----> 2 fig, ax = plt.subplots(figsize=(9, 6))
-      4 # use the first month of data as an example
-      5 precip.sel(time="1979-01-01").plot(ax=ax)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

From the figure, the boundary between land and ocean, especially for North and South America, can be observed vaguely. However, this visualization is not ideal as it requires some guesswork in identifying the specific regions. To overcome this limitation and enhance the visualization, we will employ cartopy, a library that offers advanced mapping features. With cartopy, we can incorporate additional elements such as coastlines, major grid markings, and specific map projections.

-
-
-
# visualize the precipitation data of a selected month using cartopy
-
-# select data for the month of interest
-data = precip.sel(time="1979-01-01", method="nearest")
-
-# initate plot with the specific figure size
-fig, ax = plt.subplots(subplot_kw={"projection": ccrs.Robinson()}, figsize=(9, 6))
-
-# add coastal lines to indicate land/ocean
-ax.coastlines()
-
-# add major grid lines for latitude and longitute
-ax.gridlines()
-
-# add the precipitation data with map projection transformation
-# also specify the maximum and minumum value show on the map to increase the
-# contrast in the map.
-data.plot(
-    ax=ax,
-    transform=ccrs.PlateCarree(),
-    vmin=0,
-    vmax=20,
-    cbar_kwargs=dict(shrink=0.5, label="GPCP Monthly Precipitation \n(mm/day)"),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 4
-      1 # visualize the precipitation data of a selected month using cartopy
-      2 
-      3 # select data for the month of interest
-----> 4 data = precip.sel(time="1979-01-01", method="nearest")
-      6 # initate plot with the specific figure size
-      7 fig, ax = plt.subplots(subplot_kw={"projection": ccrs.Robinson()}, figsize=(9, 6))
-
-NameError: name 'precip' is not defined
-
-
-
-
-

The updated map provides significant improvements, offering us a wealth of information to enhance our understanding of the GPCP monthly precipitation data. From the visualization, we can observe that regions such as the Amazon rainforest, the northern part of Australia, and other tropical areas exhibit higher levels of monthly precipitation in January 1979. These patterns align with our basic geographical knowledge, reinforcing the validity of the data and representation.

-
-

Coding Exercises 1.2#

-

Remember the GPCP also offers a data variable that documents the error of the monthly precipitation data used above. This error information is valuable for understanding the level of confidence we can place on the data.

-
    -
  1. Generate the precipitation error for the same month (1979-01-01) using the examples provided above.

  2. -
-
-
-
# select data for the month of interest
-data = ...
-
-# initate plot with the specific figure size
-fig, ax = plt.subplots(subplot_kw={"projection": ccrs.Robinson()}, figsize=(9, 6))
-
-# add coastal lines to indicate land/ocean
-_ = ...
-
-# add grid lines for latitude and longitute
-_ = ...
-
-# add the precipitation data for
-_ = ...
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[15], line 5
-      2 data = ...
-      4 # initate plot with the specific figure size
-----> 5 fig, ax = plt.subplots(subplot_kw={"projection": ccrs.Robinson()}, figsize=(9, 6))
-      7 # add coastal lines to indicate land/ocean
-      8 _ = ...
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Questions 1.2: Climate Connection#

-
    -
  1. Comment on the spatial pattern of the precipitation error provided by GPCP CDR data for this specific month.

  2. -
  3. Which areas have the highest errors? Why do you think this might be?

  4. -
-

Click for solution

-
-
-
-
-

Section 2: Climatology#

-
-

Section 2.1: Plot Time Series of Data at a Specific Location#

-

We have over 40 years of monthly precipitation data. Let’s examine a specific location throughout the entire time span covered by the GPCP monthly data. For this purpose, we will focus on the data point located at (0°N, 0°E).

-
-
-
# select the entire time series for the grid that contains the location of (0N, 0E)
-grid = ds.precip.sel(latitude=0, longitude=0, method="nearest")
-
-# initate plot
-fig, ax = plt.subplots(figsize=(9, 6))
-
-# plot the data
-grid.plot(ax=ax)
-
-# remove the automatically generated title
-ax.set_title("")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 2
-      1 # select the entire time series for the grid that contains the location of (0N, 0E)
-----> 2 grid = ds.precip.sel(latitude=0, longitude=0, method="nearest")
-      4 # initate plot
-      5 fig, ax = plt.subplots(figsize=(9, 6))
-
-NameError: name 'ds' is not defined
-
-
-
-
-

From the time series plot, note a repeating pattern with a seasonal cycle (roughly the same ups and downs over the course of a year, for each year). In previous tutorials during the climate system overview you learned how to calculate climatology. We can apply this same calculation to the precipitation CDR data to investigate the annual cycle of precipitation at this location.

-
-
-

Section 2.2: Calculate the Climatology#

-

As a refresher, a climatology typically employs a 30-year time period to use for the calculation. In this case, let’s use the reference period of 1981-2010.

-
-
-
# first, let's extract the data for the time period that we want (1981-2010)
-precip_30yr = ds.precip.sel(time=slice("1981-01-01", "2010-12-30"))
-precip_30yr
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 2
-      1 # first, let's extract the data for the time period that we want (1981-2010)
-----> 2 precip_30yr = ds.precip.sel(time=slice("1981-01-01", "2010-12-30"))
-      3 precip_30yr
-
-NameError: name 'ds' is not defined
-
-
-
-
-

Now we can use Xarray’s .groupby() functionality to calculate the monthly climatology.

-

Recall that .groupby() splits the data based on a specific criterion (in this case, the month of the year) and then applies a process (in our case, calculating the mean value across 30 years for that specific month) to each group before recombining the data together.

-
-
-
# use groupby to calculate monthly climatology (1981-2010)
-precip_clim = precip_30yr.groupby("time.month").mean(dim="time")
-precip_clim
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[18], line 2
-      1 # use groupby to calculate monthly climatology (1981-2010)
-----> 2 precip_clim = precip_30yr.groupby("time.month").mean(dim="time")
-      3 precip_clim
-
-NameError: name 'precip_30yr' is not defined
-
-
-
-
-

With the resulting climatology data array, we can make a set of maps to visualize the monthly climatology from four different seasons.

-
-
-
# define the figure and each axis for the 2 rows and 2 columns
-fig, axs = plt.subplots(
-    nrows=2, ncols=2, subplot_kw={"projection": ccrs.Robinson()}, figsize=(12, 8)
-)
-
-# axs is a 2 dimensional array of `GeoAxes`.  We will flatten it into a 1-D array
-axs = axs.flatten()
-
-# loop over selected months (Jan, Apr, Jul, Oct)
-for i, month in enumerate([1, 4, 7, 10]):
-
-    # Draw the coastines and major gridline for each subplot
-    axs[i].coastlines()
-    axs[i].gridlines()
-
-    # Draw the precipitation data
-    precip_clim.sel(month=month).plot(
-        ax=axs[i],
-        transform=ccrs.PlateCarree(),
-        vmin=0,
-        vmax=15,  # use the same range of max and min value
-        cbar_kwargs=dict(shrink=0.5, label="GPCP Climatology\n(mm/day)"),
-    )
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[19], line 2
-      1 # define the figure and each axis for the 2 rows and 2 columns
-----> 2 fig, axs = plt.subplots(
-      3     nrows=2, ncols=2, subplot_kw={"projection": ccrs.Robinson()}, figsize=(12, 8)
-      4 )
-      6 # axs is a 2 dimensional array of `GeoAxes`.  We will flatten it into a 1-D array
-      7 axs = axs.flatten()
-
-NameError: name 'plt' is not defined
-
-
-
-
-

In the seasonal collection of the climatology map, we can observe a clear pattern of precipitation across the globe. The tropics exhibit a higher amount of precipitation compared to other regions. Additionally, the map illustrates the seasonal patterns of precipitation changes across different regions of the globe, including areas influenced by monsoons.

-
-

Questions 2.2: Climate Connection#

-
    -
  1. Do the tropics or high-latitudes recieve more precipitation all year round? Why do you think this is? Think back to the climate system overview tutorials on atmospheric circulation to help form your answer.

  2. -
  3. In the climate system overview tutorials you learned about Monsoon systems in places such as India, South-east Asia and East Africa where there are notable wet and dry seasons. Do you see evidence of say, the Indian monsoon, in these maps?

  4. -
-

Click for solution

-

Now let’s examine the climatology of the location we previously analyzed throughout the entire time series, specifically at (0°N, 0°E).

-
-
-
# initate plot with the specific figure size
-fig, ax = plt.subplots(figsize=(9, 6))
-
-precip_clim.sel(latitude=0, longitude=0, method="nearest").plot(ax=ax)
-# Remove the automatically generated title
-ax.set_title("")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[20], line 2
-      1 # initate plot with the specific figure size
-----> 2 fig, ax = plt.subplots(figsize=(9, 6))
-      4 precip_clim.sel(latitude=0, longitude=0, method="nearest").plot(ax=ax)
-      5 # Remove the automatically generated title
-
-NameError: name 'plt' is not defined
-
-
-
-
-

The monthly climatology time series for the point of interest demonstrates a noticeable seasonal pattern, with dry and rainy months observed in the region. Precipitation is typically more abundant between December and May, while August experiences the driest conditions throughout the year.

-
-
-

Coding Exercises 2.1#

-

As climate changes, the climatology of precipitation may also change. In fact, climate researchers recalculate climatology every 10 years. This allows climate scientists to monitor how the norms of our climate system change. In this exercise, you will visualize how the climatology of our dataset changes depending on the reference period used.

-
    -
  1. Calculate the climatology for a different reference period (1991-2020) and compare it to the climatology that we just generated with reference period (1981-2010). Be sure to compare the two and note differences. Can you see why it is important to re-calculate this climatology?

  2. -
-
-
-
# extract 30 year data for 1991-2020
-precip_30yr_exercise = ...
-
-# calculate climatology for 1991-2020
-precip_clim_exercise = ...
-
-# find difference in climatologies: (1981-2010) minues (1991-2020)
-precip_diff_exercise = ...
-
-# Compare the climatology for four different seasons by generating the
-#         difference maps for January, April, July, and October with colorbar max and min = 1,-1
-
-# Define the figure and each axis for the 2 rows and 2 columns
-fig, axs = plt.subplots(
-    nrows=2, ncols=2, subplot_kw={"projection": ccrs.Robinson()}, figsize=(12, 8)
-)
-
-# axs is a 2 dimensional array of `GeoAxes`.  We will flatten it into a 1-D array
-axs = ...
-
-#Loop over selected months (Jan, Apr, Jul, Oct)
-for i, month in enumerate([1, 4, 7, 10]):
-    ...
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[21], line 14
-      8 precip_diff_exercise = ...
-     10 # Compare the climatology for four different seasons by generating the
-     11 #         difference maps for January, April, July, and October with colorbar max and min = 1,-1
-     12 
-     13 # Define the figure and each axis for the 2 rows and 2 columns
----> 14 fig, axs = plt.subplots(
-     15     nrows=2, ncols=2, subplot_kw={"projection": ccrs.Robinson()}, figsize=(12, 8)
-     16 )
-     18 # axs is a 2 dimensional array of `GeoAxes`.  We will flatten it into a 1-D array
-     19 axs = ...
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-
-

Summary#

-

Climatologies provide valuable insight into typical weather patterns of a region. Key takeaways from the tutorial include:

-
    -
  • A climatology pertains to the long-term average of various system attributes, such as temperature and precipitation, often spanning a duration of 30 years.

  • -
  • Satellite climate data records offer valuable insights for calculating climatology on a global scale.

  • -
-

By comparing the weather conditions of a specific day or month to the climatology, we can determine the extent to which they deviate from the norm. This concept of comparing against the climatology, or the norm, will be the focus of our next tutorial - the anomaly!

-
-
-

Resources#

-

Data from this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5.html deleted file mode 100644 index 0290058cd..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial5.html +++ /dev/null @@ -1,1827 +0,0 @@ - - - - - - - - - - - - Tutorial 5: Calculating Anomalies Using Precipitation Data — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 5: Calculating Anomalies Using Precipitation Data#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will learn how to calculate climate anomalies using satellite climate data records.

-

By the end of this tutorial you will be able to:

-
    -
  • Calculate an anomaly to a climatology.

  • -
  • Calculate the rolling mean of the anomaly data to smooth the time series and extract long-term signals/patterns.

  • -
-
-
-

Setup#

-
-
-
# !pip install s3fs --quiet
-
-# properly install cartopy in colab to avoid session crash
-# !apt-get install libproj-dev proj-data proj-bin --quiet
-# !apt-get install libgeos-dev --quiet
-# !pip install cython --quiet
-# !pip install cartopy --quiet
-
-# !apt-get -qq install python-cartopy python3-cartopy  --quiet
-# !pip uninstall -y shapely  --quiet
-# !pip install shapely --no-binary shapely  --quiet
-
-
-
-
-
-
-
# imports
-import s3fs
-import xarray as xr
-import numpy as np
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import boto3
-import botocore
-import os
-import pooch
-import tempfile
-import holoviews
-from geoviews import Dataset as gvDataset
-import geoviews.feature as gf
-from geoviews import Image as gvImage
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import s3fs
-      3 import xarray as xr
-      4 import numpy as np
-
-ModuleNotFoundError: No module named 's3fs'
-
-
-
-
-
-

Video 1: Video 1 Name#

-
-

Video 1: Video 1 Name#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Video 1 Name
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[4], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation="", filename=""):
-    shared_location = "/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: From Climatology to Anomaly#

-

Building upon your knowledge of climatology from the last tutorial, you will now calculate the anomalies from this climatology. An anomaly, in the context of climate studies, represents a departure from standard climatological conditions. For example, if the normal January temperature of the city that you live in is 10 °C and the January temperature of this year is 15 °C. We usually say the temperature anomaly of January this year is 5 °C above normal/ the climatology. The anomaly is an essential tool in detecting changes in climate patterns and is frequently utilized in critical climate reports such as those generated by the Intergovernmental Panel on Climate Change (IPCC).

-

To calculate an anomaly, we first establish a reference period, usually a 30-year window, to define our climatology. In this process, it is crucial to use high-quality data and aggregate it to the desired spatial resolution and temporal frequency, such as weekly or monthly. The anomaly is then determined by subtracting this long-term average from a given observation, thus creating a useful metric for further climate analysis such as trend analysis.

-

In this tutorial, we will employ the CPCP monthly precipitation Climate Data Record (CDR) to compute a monthly anomaly time series. Furthermore, we will learn to calculate the rolling mean of the generated precipitation anomaly time series. This knowledge will be invaluable for our upcoming tutorial on climate variability.

-
-

Section 1.1: Calculating the Monthly Anomaly#

-

To calculate anomaly, you first need to calculate the monthly climatology. Since you already learned how to do this during last tutorial, we will fast forward this step.

-
-
-
# connect to the AWS S3 bucket for the GPCP Monthly Precipitation CDR data
-fs = s3fs.S3FileSystem(anon=True)
-
-# get the list of all data files in the AWS S3 bucket
-file_pattern = "noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc"
-file_location = fs.glob(file_pattern)
-
-# open connection to all data files
-client = boto3.client(
-    "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-)  # initialize aws s3 bucket client
-file_ob = [
-    pooch_load(filelocation="http://s3.amazonaws.com/" + file, filename=file)
-    for file in file_location
-]
-
-# open all the monthly data files and concatenate them along the time dimension
-# this process will take ~ 1 minute to complete due to the number of data files
-ds = xr.open_mfdataset(file_ob, combine="nested", concat_dim="time")
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 2
-      1 # connect to the AWS S3 bucket for the GPCP Monthly Precipitation CDR data
-----> 2 fs = s3fs.S3FileSystem(anon=True)
-      4 # get the list of all data files in the AWS S3 bucket
-      5 file_pattern = "noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc"
-
-NameError: name 's3fs' is not defined
-
-
-
-
-
-
-
# calculate climatology using `.sel()` and `.groupby()` directly.
-precip_clim = (
-    ds.precip.sel(time=slice("1981-01-01", "2010-12-01"))
-    .groupby("time.month")
-    .mean(dim="time")
-)
-precip_clim
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 3
-      1 # calculate climatology using `.sel()` and `.groupby()` directly.
-      2 precip_clim = (
-----> 3     ds.precip.sel(time=slice("1981-01-01", "2010-12-01"))
-      4     .groupby("time.month")
-      5     .mean(dim="time")
-      6 )
-      7 precip_clim
-
-NameError: name 'ds' is not defined
-
-
-
-
-

Now we have the monthly precipitation climatology. How can we calculate the monthly anomaly?

-

As we learned before - let’s use .groupby() from xarray. We can split the entire time period based on the month of the year and then subtract the climatology of that specific month from the monthly value and recombine the value together.

-
-
-
# use `.groupby()` to calculate the monthly anomaly
-precip_anom = ds.precip.groupby("time.month") - precip_clim
-precip_anom
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # use `.groupby()` to calculate the monthly anomaly
-----> 2 precip_anom = ds.precip.groupby("time.month") - precip_clim
-      3 precip_anom
-
-NameError: name 'ds' is not defined
-
-
-
-
-

You may have noticed that there is an additional coordinate in the anomaly dataset. The additional coordinate is month which is a direct outcome because of the .groupby() action we just performed.

-

If you want to save the data for future use, you can write the data out to a netCDF file using .to_netcdf(). It will automatically carry all the coordinates, dimensions, and relevant information into the netCDF file.

-
-
-
# an example of how to export the GPCP monthly anomaly data comparing to the climatology period of 1981-2010.
-# precip_anom.to_netcdf('t5_gpcp-monthly-anomaly_1981-2010.nc')
-
-
-
-
-
-
-

Section 1.2: Examining the Anomaly#

-

First, let’s take a look at the geospatial pattern of the monthly anomaly of a selected month – January of 1979.

-
-
-
# initate plot
-fig = plt.figure(figsize=(9, 6))
-
-# set map projection
-ax = plt.axes(projection=ccrs.Robinson())
-
-# add coastal lines to indicate land/ocean
-ax.coastlines()
-
-# add grid lines for latitude and longitude
-ax.gridlines()
-
-# add the precipitation data for
-precip_anom.sel(time="1979-01-01").plot(
-    ax=ax,
-    transform=ccrs.PlateCarree(),
-    vmin=-8,
-    vmax=8,
-    cmap="BrBG",
-    cbar_kwargs=dict(shrink=0.5, label="Monthly Anomaly \n(mm/day)"),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # initate plot
-----> 2 fig = plt.figure(figsize=(9, 6))
-      4 # set map projection
-      5 ax = plt.axes(projection=ccrs.Robinson())
-
-NameError: name 'plt' is not defined
-
-
-
-
-

From the map of this monthly anomaly, we can see the spatial pattern of how precipitation for the January of 1979 has departed from the 30-year normal. Part of the Amazon saw notable increase of precipitation during this month as well as the northeast coast of the United States.

-
-

Interactive Demo 1.2#

-

In the interactive demo below (make sure to run the code) you will be able to scroll through the anomaly for a few months in 1979 to see how it changes from month to month during this year.

-
-
-
holoviews.extension("bokeh")
-dataset_plot = gvDataset(
-    precip_anom.isel(time=slice(0, 10))
-)  # only the first 10, as it is a time consuming task
-images = dataset_plot.to(gvImage, ["longitude", "latitude"], ["precip"], "time")
-images.opts(
-    cmap="BrBG",
-    colorbar=True,
-    width=600,
-    height=400,
-    projection=ccrs.Robinson(),
-    clim=(-8, 8),
-    clabel="Monthly Anomaly \n(mm/day)",
-) * gf.coastline
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 holoviews.extension("bokeh")
-      2 dataset_plot = gvDataset(
-      3     precip_anom.isel(time=slice(0, 10))
-      4 )  # only the first 10, as it is a time consuming task
-      5 images = dataset_plot.to(gvImage, ["longitude", "latitude"], ["precip"], "time")
-
-NameError: name 'holoviews' is not defined
-
-
-
-
-

To visualize the changes in the precipitation anomaly over many months, we can also take a look at the time series of a selected grid. We will use the same point (0°N, 0°E) that we used as an example in the last tutorial.

-
-
-
# set up two subplots that share the x-axis to compare monthly precipitation and monthly anomaly
-fig, axs = plt.subplots(2, sharex=True)
-fig.suptitle("GPCP Monthly Precipitaion v.s. Monthly Anomaly")
-axs[0].plot(ds.time, ds.precip.sel(latitude=0, longitude=0, method="nearest"))
-axs[0].set_ylabel("Precip (mm/day)")
-axs[1].plot(
-    precip_anom.time, precip_anom.sel(latitude=0, longitude=0, method="nearest")
-)
-axs[1].set_ylabel("Anomaly (mm/day)")
-axs[1].set_xlabel("Time")
-
-# add horizontal line of y=0 for the anomaly subplot
-axs[1].axhline(y=0, color="k", linestyle="-")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # set up two subplots that share the x-axis to compare monthly precipitation and monthly anomaly
-----> 2 fig, axs = plt.subplots(2, sharex=True)
-      3 fig.suptitle("GPCP Monthly Precipitaion v.s. Monthly Anomaly")
-      4 axs[0].plot(ds.time, ds.precip.sel(latitude=0, longitude=0, method="nearest"))
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Note that, unlike the upper panel showing precipitation values, the lower panel displaying the monthly anomaly not exhibit distinct seasonal cycles. This discrepancy highlights one of the advantages of utilizing anomaly data for climate analysis. By removing the repetitive patterns induced by seasonality or other stable factors, we can effectively isolate the specific signals in the data that are of interest, such as climate variability or climate trends. This approach allows for a clearer focus on the desired climate-related patterns without the interference of predictable seasonal variations.

-
-
-
-
-

Section 2: Anomaly Analysis#

-

In this section, we are going to explore a few different analyses on the anomaly data:

-
    -
  • Calculating rolling mean

  • -
  • Calculating global mean

  • -
-

You have already practiced using these tools during the last two days or material, here we will focus on applying them to a much longer satellite data record than you have encountered previously.

-
-

Section 2.1: Rolling Mean#

-

The monthly anomaly time series often contains noisy data that may obscure the patterns associated with large-scale climate variability. To mitigate this noise and enhance the visibility of underlying patterns, we can apply a rolling mean technique using the .rolling() function. This approach involves smoothing the monthly time series to facilitate the identification of climate variability.

-
-
-
# calculate 12-month rolling mean for the selected location
-grid_month = precip_anom.sel(latitude=0, longitude=0, method="nearest")
-grid_rolling = grid_month.rolling(time=12, center=True).mean()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # calculate 12-month rolling mean for the selected location
-----> 2 grid_month = precip_anom.sel(latitude=0, longitude=0, method="nearest")
-      3 grid_rolling = grid_month.rolling(time=12, center=True).mean()
-
-NameError: name 'precip_anom' is not defined
-
-
-
-
-
-
-
# create the time series plot of monthly anomaly
-fig, ax = plt.subplots(figsize=(12, 6))
-grid_month.plot(label="Monthly Anomaly", ax=ax)
-grid_rolling.plot(color="k", label="12-mon rolling mean", ax=ax)
-ax.axhline(y=0, color="y", linestyle="-")
-ax.set_ylabel("Precipitation Anomaly (mm/day)")
-ax.legend()
-ax.set_xlabel("Time")
-# remove the automatically generated title
-ax.set_title("")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 # create the time series plot of monthly anomaly
-----> 2 fig, ax = plt.subplots(figsize=(12, 6))
-      3 grid_month.plot(label="Monthly Anomaly", ax=ax)
-      4 grid_rolling.plot(color="k", label="12-mon rolling mean", ax=ax)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

As you can see, the 12-month rolling mean removes the high-frequency variations of monthly precipitation anomaly data, allowing the slower-changing patterns of precipitation to become more apparent.

-
-

Coding Exercises 2.1#

-
    -
  1. Calculate the 24-month rolling mean for the same grid and compare the three different time series (monthly anomaly, 12-month rolling mean, 24-month rolling mean).

  2. -
-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Compare monthly anomaly with 12-month and 24-month rolling mean."
-)
-#################################################
-
-# calculate 24-month rolling mean
-grid_rolling_24m = ...
-
-# plot all three time series together with different colors
-fig, ax = ...
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[15], line 3
-      1 #################################################
-      2 # Students: Fill in missing code (...) and comment or remove the next line
-----> 3 raise NotImplementedError(
-      4     "Student exercise: Compare monthly anomaly with 12-month and 24-month rolling mean."
-      5 )
-      6 #################################################
-      7 
-      8 # calculate 24-month rolling mean
-      9 grid_rolling_24m = ...
-
-NotImplementedError: Student exercise: Compare monthly anomaly with 12-month and 24-month rolling mean.
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Questions 2.1#

-
    -
  1. What are the major differences you notice between the 12 and 24 month rolling averages?

  2. -
  3. What would generally dictate the window size to use in a rolling average of a satellite derived climate variable such as precipitation anomalies?

  4. -
-

Click for solution

-
-
-
-

Section 2.2: Global Mean#

-

When examining global-scale changes, it is common to aggregate global mean values from all grid cells. However, it is important to note that despite each grid having the same resolution of 2.5°×2.5°, they represent different areas on the Earth’s surface. Specifically, the same grid covers larger spatial areas in the tropics compared to the polar regions as discussed in the climate system overview day.

-

To address this issue, it is necessary to weight the values based on their respective surface areas. Unlink the model data you used previously, where you had the grid cell area available as a variable, for our gridded observations we will use weights based on the cosine of the latitude as this function takes into account the decreasing area towards the poles.

-
-
-
# calculate the weights using the latitude coordinates
-weights = np.cos(np.deg2rad(precip_anom.latitude))
-weights.name = "weights"
-weights
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 2
-      1 # calculate the weights using the latitude coordinates
-----> 2 weights = np.cos(np.deg2rad(precip_anom.latitude))
-      3 weights.name = "weights"
-      4 weights
-
-NameError: name 'np' is not defined
-
-
-
-
-
-
-
# calculate weighted global monthly mean
-anom_weighted = precip_anom.weighted(weights)
-global_weighted_mean = anom_weighted.mean(("latitude", "longitude"))
-global_weighted_mean
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 2
-      1 # calculate weighted global monthly mean
-----> 2 anom_weighted = precip_anom.weighted(weights)
-      3 global_weighted_mean = anom_weighted.mean(("latitude", "longitude"))
-      4 global_weighted_mean
-
-NameError: name 'precip_anom' is not defined
-
-
-
-
-
-
-
# create the time series plot of global weighted monthly anomaly
-fig, ax = plt.subplots(figsize=(12, 6))
-global_weighted_mean.plot(label="Monthly anomaly", ax=ax)
-global_weighted_mean.rolling(time=12, center=True).mean(("latitude", "longitude")).plot(
-    color="k", label="12-mon rolling mean", ax=ax
-)
-ax.axhline(y=0, color="y", linestyle="-")
-ax.set_ylabel("Precipitation Anomaly (mm/day)")
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[18], line 2
-      1 # create the time series plot of global weighted monthly anomaly
-----> 2 fig, ax = plt.subplots(figsize=(12, 6))
-      3 global_weighted_mean.plot(label="Monthly anomaly", ax=ax)
-      4 global_weighted_mean.rolling(time=12, center=True).mean(("latitude", "longitude")).plot(
-      5     color="k", label="12-mon rolling mean", ax=ax
-      6 )
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Coding Exercises 2.2#

-
    -
  1. Plot the 12-month rolling average of the difference between the global weighted and unweighted mean time series.

  2. -
-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Compare global weighted and unweighted mean time series."
-)
-#################################################
-
-# calculate unweighted global mean
-global_unweighted_mean = ...
-
-# calculate different between weighted and unweighted global mean
-global_diff = global_weighted_mean - global_unweighted_mean
-
-# plot the time series of the difference
-fig, ax = ...
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[19], line 3
-      1 #################################################
-      2 # Students: Fill in missing code (...) and comment or remove the next line
-----> 3 raise NotImplementedError(
-      4     "Student exercise: Compare global weighted and unweighted mean time series."
-      5 )
-      6 #################################################
-      7 
-      8 # calculate unweighted global mean
-      9 global_unweighted_mean = ...
-
-NotImplementedError: Student exercise: Compare global weighted and unweighted mean time series.
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Questions 2.2#

-
    -
  1. Give one example of why the weighted mean might be higher than the unweighted mean, as in the 2000-2004 period.

  2. -
-

Click for solution

-
-
-
-
-

Summary#

-

In this tutorial, you learned how to calculate a climate anomaly using satellite derived precipitation data.

-
    -
  • The anomaly allows us to look at the signals that may be covered by the seasonal cycle pattern (e.g., temperature/precipitation seasonal cycle).

  • -
  • The anomaly data can be further smoothed using rolling mean to reveal longer-term signals at annual or decade time scale.

  • -
-

We will use the anomaly concept to study climate variability in the next tutorial.

-
-
-

Resources#

-

Data from this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6.html deleted file mode 100644 index 405530588..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial6.html +++ /dev/null @@ -1,1706 +0,0 @@ - - - - - - - - - - - - Tutorial 6: Large Scale Climate Variability - ENSO — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 6: Large Scale Climate Variability - ENSO#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will build upon the introduction to El Niño-Southern Oscillation (ENSO) from Day 1 and 2. ENSO is recognized as one of the most influential large-scale climate variabilities that impact weather and climate patterns.

-

By the end of this tutorial, you will:

-
    -
  • Enhance your comprehension of the concept of ENSO and the three distinct phases associated with it.

  • -
  • Utilize satellite-derived sea surface temperature (SST) data to compute an index for monitoring ENSO.

  • -
-
-
-

Setup#

-
-
-
# !apt-get install libproj-dev proj-data proj-bin --quiet
-# !apt-get install libgeos-dev --quiet
-# !pip install cython --quiet
-# !pip install cartopy --quiet
-
-# !apt-get -qq install python-cartopy python3-cartopy  --quiet
-# !pip uninstall -y shapely  --quiet
-# !pip install shapely --no-binary shapely  --quiet
-
-
-
-
-
-
-
# imports
-import xarray as xr
-import numpy as np
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import os
-import requests
-import tarfile
-import pooch
-import os
-import tempfile
-import holoviews
-from geoviews import Dataset as gvDataset
-import geoviews.feature as gf
-from geoviews import Image as gvImage
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import xarray as xr
-      3 import numpy as np
-      4 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'xarray'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Video 1 Name#

-
-

Video 1: Video 1 Name#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Video 1 Name
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation="", filename=""):
-    shared_location = "/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: El Niño-Southern Oscillation (ENSO)#

-

As you learned in Day 1 and 2, one of the most significant large-scale climate variabilities is El Niño-Southern Oscillation (ENSO). ENSO can change the global atmospheric circulation, which in turn, influences temperature and precipitation across the globe.

-

Despite being a single climate phenomenon, ENSO exhibits three distinct phases:

-
    -
  • El Niño: A warming of the ocean surface, or above-average sea surface temperatures, in the central and eastern tropical Pacific Ocean.

  • -
  • La Niña: A cooling of the ocean surface, or below-average sea surface temperatures, in the central and eastern tropical Pacific Ocean.

  • -
  • Neutral: Neither El Niño or La Niña. Often tropical Pacific SSTs are generally close to average.

  • -
-

In Day 2, you practiced utilizing a variety of Xarray tools to examine variations in sea surface temperature (SST) during El Niño and La Niña events by calculating the Oceanic Niño Index (ONI) from reanalysis data over the time period 2000-2014.

-

In contrast to previous days, in this tutorial you will use satellite-based SST data to monitor ENSO over a longer time period starting in 1981.

-
-

Section 1.1: Calculate SST Anomaly#

-

Optimum Interpolation Sea Surface Temperature (OISST) is a long-term Climate Data Record that incorporates observations from different platforms (satellites, ships, buoys and Argo floats) into a regular global grid. OISST data is originally produced at daily and 1/4° spatial resolution. To avoid the large amount of data processing of daily data, we use the monthly aggregated OISST SST data provided by NOAA Physical Systems Laboratory.

-
-
-
# download the monthly sea surface temperature data from NOAA Physical System
-# Laboratory. The data is processed using the OISST SST Climate Data Records
-# from the NOAA CDR program.
-# the data downloading may take 2-3 minutes to complete.
-# filename=sst.mon.mean.nc
-url_sst = "https://osf.io/6pgc2/download/"
-filename = "sst.mon.mean.nc"
-
-# we divide the data into small chunks to allow for easier memory manangement. this is all done automatically, no need for you to do anything
-ds = xr.open_dataset(
-    pooch_load(filelocation=url_sst, filename=filename),
-    chunks={"time": 25, "latitude": 200, "longitude": 200},
-)
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 10
-      7 filename = "sst.mon.mean.nc"
-      9 # we divide the data into small chunks to allow for easier memory manangement. this is all done automatically, no need for you to do anything
----> 10 ds = xr.open_dataset(
-     11     pooch_load(filelocation=url_sst, filename=filename),
-     12     chunks={"time": 25, "latitude": 200, "longitude": 200},
-     13 )
-     14 ds
-
-NameError: name 'xr' is not defined
-
-
-
-
-

The monthly OISST data is available starting from September of 1981. We will use the Niño 3.4 (5N-5S, 170W-120W) region to monitor the ENSO as identified in the map below provided by NOAA Climate portal.

-

Location of four different nino regions

-

Credit: NOAA

-

The data is only available in full years starting 1982, so we will use 1982-2011 as the climatology period.

-
-
-
# get 30-year climatology from 1982-2011
-sst_30yr = ds.sst.sel(time=slice("1982-01-01", "2011-12-01"))
-
-# calculate monthly climatology
-sst_clim = sst_30yr.groupby("time.month").mean()
-sst_clim
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # get 30-year climatology from 1982-2011
-----> 2 sst_30yr = ds.sst.sel(time=slice("1982-01-01", "2011-12-01"))
-      4 # calculate monthly climatology
-      5 sst_clim = sst_30yr.groupby("time.month").mean()
-
-NameError: name 'ds' is not defined
-
-
-
-
-
-
-
# calculate monthly anomaly
-sst_anom = ds.sst.groupby("time.month") - sst_clim
-sst_anom
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # calculate monthly anomaly
-----> 2 sst_anom = ds.sst.groupby("time.month") - sst_clim
-      3 sst_anom
-
-NameError: name 'ds' is not defined
-
-
-
-
-

Now, we can take a look at the SST anomaly of a given month. We use January of 1998 to show the specific change of SST during that time period.

-
-
-
sst = sst_anom.sel(time="1998-01-01")
-
-# initate plot
-fig, ax = plt.subplots(
-    subplot_kw={"projection": ccrs.Robinson(central_longitude=180)}, figsize=(9, 6)
-)
-
-# focus on the ocean with the central_longitude=180
-ax.coastlines()
-ax.gridlines()
-sst.plot(
-    ax=ax,
-    transform=ccrs.PlateCarree(),
-    vmin=-3,
-    vmax=3,
-    cmap="RdBu_r",
-    cbar_kwargs=dict(shrink=0.5, label="OISST Anomaly (degC)"),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 1
-----> 1 sst = sst_anom.sel(time="1998-01-01")
-      3 # initate plot
-      4 fig, ax = plt.subplots(
-      5     subplot_kw={"projection": ccrs.Robinson(central_longitude=180)}, figsize=(9, 6)
-      6 )
-
-NameError: name 'sst_anom' is not defined
-
-
-
-
-
-

Interactive Demo 1.1#

-

Use the slider bar below to explore maps of the anomalies through the year in 1998.

-
-
-
# note this code takes a while to load. probably an hour
-# holoviews.extension('bokeh')
-
-# dataset_plot = gvDataset(sst_anom.sel(time=slice('1998-01-01','1998-12-01'))) # taking only 12 months
-# images = dataset_plot.to(gvImage, ['lon', 'lat'], ['sst'], 'time')
-# images.opts(cmap='RdBu_r', colorbar=True, width=600, height=400,projection=ccrs.Robinson(),
-#             clim=(-3,3),clabel ='OISST Anomaly (degC)') * gf.coastline
-
-
-
-
-
-
-
-

Section 1.2: Monitoring ENSO with Oceanic Niño Index#

-

As you learned in Day 2, the Oceanic Niño Index (ONI) is a common index used to monitor ENSO. It is calculated using the Niño 3.4 region (5N-5S, 170W-120W) and by applying a 3-month rolling mean to the mean SST anomalies in that region.

-

You may have noticed that the lon for the SST data from NOAA Physical Systems Laboratory is organized between 0°–360°E. Just as in Tutorial 1 of Day 2, we find that the region to subset with our dataset is (-5°–5°, 190–240°).

-
-
-
# extract SST data from the Nino 3.4 region
-sst_nino34 = sst_anom.sel(lat=slice(-5, 5), lon=slice(190, 240))
-sst_nino34
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # extract SST data from the Nino 3.4 region
-----> 2 sst_nino34 = sst_anom.sel(lat=slice(-5, 5), lon=slice(190, 240))
-      3 sst_nino34
-
-NameError: name 'sst_anom' is not defined
-
-
-
-
-
-
-
# calculate the mean values for the Nino 3.4 region
-nino34 = sst_nino34.mean(dim=["lat", "lon"])
-
-# Pplot time series for Nino 3.4 mean anomaly
-fig, ax = plt.subplots(figsize=(12, 6))
-nino34.plot(ax=ax)
-ax.set_ylabel("Nino3.4 Anomaly (degC)")
-ax.axhline(y=0, color="k", linestyle="dashed")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # calculate the mean values for the Nino 3.4 region
-----> 2 nino34 = sst_nino34.mean(dim=["lat", "lon"])
-      4 # Pplot time series for Nino 3.4 mean anomaly
-      5 fig, ax = plt.subplots(figsize=(12, 6))
-
-NameError: name 'sst_nino34' is not defined
-
-
-
-
-

The ONI is defined as the 3-month rolling mean of the monthly regional average of the SST anomaly for the Nino 3.4 region. We can use .rolling() to calculate the ONI value for each month from the OISST monthly anomaly.

-
-
-
# calculate 3-month rolling mean of Nino 3.4 anomaly for the ONI
-oni = nino34.rolling(time=3, center=True).mean()
-
-# generate time series plot
-fig, ax = plt.subplots(figsize=(12, 6))
-nino34.plot(label="Nino 3.4", ax=ax)
-oni.plot(color="k", label="ONI", ax=ax)
-ax.set_ylabel("Anomaly (degC)")
-ax.axhline(y=0, color="k", linestyle="dashed")
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # calculate 3-month rolling mean of Nino 3.4 anomaly for the ONI
-----> 2 oni = nino34.rolling(time=3, center=True).mean()
-      4 # generate time series plot
-      5 fig, ax = plt.subplots(figsize=(12, 6))
-
-NameError: name 'nino34' is not defined
-
-
-
-
-

The different phases of ENSO are nominally defined based on a threshold of \(\pm\) 0.5 with the ONI index.

-
    -
  • El Niño [ONI values higher than 0.5]: surface waters in the east-central tropical Pacific are at least 0.5 degrees Celsius warmer than normal.

  • -
  • La Niña [ONI values lower than -0.5]: surface waters ub the west tropical Pacific are at least 0.5 degrees Celsius cooler than normal.

  • -
-

The neutral phase is when ONI values are in between these two thresholds. We can make the ONI plot that is used by NOAA and other organizations to monitor ENSO phases.

-
-
-
# set up the plot size
-fig, ax = plt.subplots(figsize=(12, 6))
-
-# create the filled area when ONI values are above 0.5 for El Nino
-ax.fill_between(
-    oni.time.data,
-    oni.where(oni >= 0.5).data,
-    0.5,
-    color="red",
-    alpha=0.9,
-)
-
-# create the filled area when ONI values are below -0.5 for La Nina
-ax.fill_between(
-    oni.time.data,
-    oni.where(oni <= -0.5).data,
-    -0.5,
-    color="blue",
-    alpha=0.9,
-)
-
-# create the time series of ONI
-oni.plot(color="black", ax=ax)
-
-# add the threshold lines on the plot
-ax.axhline(0, color="black", lw=0.5)
-ax.axhline(0.5, color="red", linewidth=0.5, linestyle="dotted")
-ax.axhline(-0.5, color="blue", linewidth=0.5, linestyle="dotted")
-ax.set_title("Oceanic Niño Index")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 # set up the plot size
-----> 2 fig, ax = plt.subplots(figsize=(12, 6))
-      4 # create the filled area when ONI values are above 0.5 for El Nino
-      5 ax.fill_between(
-      6     oni.time.data,
-      7     oni.where(oni >= 0.5).data,
-   (...)
-     10     alpha=0.9,
-     11 )
-
-NameError: name 'plt' is not defined
-
-
-
-
-

From the plot, we can see the historical ENSO phases swing from El Nino to La Nina events. The major ENSO events like 1997-1998 shows up very clearly on the ONI plot.

-

We will use the ONI data to perform analysis to understand the impact of ENSO on precipitation. So you can export the ONI time series into a netCDF file for future use via .to_netcdf(). For our purposes, we will download a dataset that has been previously saved in the next tutorial. If you wanted to save the data when working on your own computer, this is the code you could use.

-
-
-
# oni.to_netcdf('t6_oceanic-nino-index.nc')
-
-
-
-
-
-

Coding Exercises 1.2#

-

As we learned here, ENSO is monitored using the anomaly of SST data for a specific region (e.g., Nino 3.4). We also learned previously that the reference periods used to calculate climatolgies are updated regularly to reflect the most up to date ‘normal’.

-
    -
  1. Compare the ONI time series calculated using two different climatology reference periods (1982-2011 v.s. 1991-2020).

  2. -
-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Compare the ONI time series calculated using two different climatology reference periods (1982-2011 v.s. 1991-2020)."
-)
-#################################################
-# select data from 1991-2020.
-sst_30yr_later = ...
-
-# calculate climatology
-sst_clim_later = ...
-
-# calculate anomaly
-sst_anom_later = ...
-
-# calculate mean over Nino 3.4 region
-nino34_later = ...
-
-# compute 3 month rolling mean
-oni_later = ...
-
-# compare the two ONI time series and visualize the difference as a time series plot
-fig, ax = plt.subplots(figsize=(12, 6))
-oni.plot(color="k", label="ONI (1982-2011)", ax=ax)
-oni_later.plot(color="r", label="ONI (1991-2020)", ax=ax)
-ax.set_ylabel("Anomaly (degC)")
-ax.axhline(y=0, color="k", linestyle="dashed")
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[16], line 3
-      1 #################################################
-      2 # Students: Fill in missing code (...) and comment or remove the next line
-----> 3 raise NotImplementedError(
-      4     "Student exercise: Compare the ONI time series calculated using two different climatology reference periods (1982-2011 v.s. 1991-2020)."
-      5 )
-      6 #################################################
-      7 # select data from 1991-2020.
-      8 sst_30yr_later = ...
-
-NotImplementedError: Student exercise: Compare the ONI time series calculated using two different climatology reference periods (1982-2011 v.s. 1991-2020).
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Questions 1.2: Climate Connection#

-
    -
  1. What is the main difference you note about this plot?

  2. -
  3. What does this tell you about the climatology calculated from 1982-2011 versus 1991-2020?

  4. -
  5. Why is it important to use appropriate climatologies when finding anomalies?

  6. -
-

Click for solution

-
-
-
-
-

Summary#

-

In this tutorial, you revisted the foundational principles of ENSO and explored how satellite data can be employed to track this phenomenon.

-
    -
  • As one of the most potent climate influences on Earth, ENSO has the capacity to alter global atmospheric circulation with impacts around the world.

  • -
  • You observed the three phases of ENSO by utilizing SST data gathered from satellites and calculating the Oceanic Niño Index.

  • -
-

In the forthcoming tutorial, we will utilize the ONI, calculated in this session, to evaluate the influence of ENSO on precipitation in select regions.

-
-
-

Resources#

-

Data from this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7.html deleted file mode 100644 index de04a7970..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial7.html +++ /dev/null @@ -1,1824 +0,0 @@ - - - - - - - - - - - - Tutorial 7: Impact of Climate Variability - Precipitation — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 7: Impact of Climate Variability - Precipitation#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, the primary goal is to understand how to utilize satellite data to investigate the effects of large-scale climate variability on precipitation.

-

Upon the completion of this tutorial, you will be able to:

-
    -
  • Comprehend the influence of the El Niño-Southern Oscillation (ENSO) on precipitation and its geographical distribution.

  • -
  • Compute Pearson’s correlation coefficient, a statistical measure used to determine the relationship between two time series.

  • -
-
-
-

Setup#

-
-
-
# properly install cartopy in colab to avoid session crash
-# !apt-get install libproj-dev proj-data proj-bin --quiet
-# !apt-get install libgeos-dev --quiet
-# !pip install cython --quiet
-# !pip install cartopy --quiet
-
-# !apt-get -qq install python-cartopy python3-cartopy  --quiet
-# !pip uninstall -y shapely  --quiet
-# !pip install shapely --no-binary shapely  --quiet
-
-
-
-
-
-
-
# imports
-import xarray as xr
-import numpy as np
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import os
-import requests
-import pooch
-import tempfile
-from scipy import stats
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import xarray as xr
-      3 import numpy as np
-      4 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'xarray'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Video 1 Name#

-
-

Video 1: Video 1 Name#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Video 1 Name
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation="", filename=""):
-    shared_location = "/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: ENSO and precipitation#

-

As discussed in previous tutorials, ENSO oscillates irregularly between El Niño and La Niña phases every two to seven years. These shifts often prompt predictable changes in ocean surface temperature and disrupt wind and rainfall patterns across the tropics, leading to a cascade of global side effects.

-

In this context, we will be utilizing satellite data to scrutinize the influence of ENSO on precipitation patterns.

-
-

Section 1.1: Get ENSO Index Oceanic Niño Index (ONI)#

-

In last tutorial, we generated the Oceanic Niño Index (ONI) using the OISST Climate Data Records. Now we just read the ONI value using the climatology of 1982-2011.

-
-
-
# download't6_oceanic-nino-index.nc'
-
-url_nino = "https://osf.io/8rwxb/download/"
-filename_nino = "t6_oceanic-nino-index"
-oni = xr.open_dataset(pooch_load(filelocation=url_nino, filename=filename_nino))
-oni
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 5
-      3 url_nino = "https://osf.io/8rwxb/download/"
-      4 filename_nino = "t6_oceanic-nino-index"
-----> 5 oni = xr.open_dataset(pooch_load(filelocation=url_nino, filename=filename_nino))
-      6 oni
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
# plot the oni timeseries we just downloaded
-fig, ax = plt.subplots(figsize=(12, 6))
-oni.sst.plot(ax=ax)
-ax.set_ylabel("Oceanic Nino Index")
-ax.axhline(y=0, linestyle="dashed", color="k")
-ax.axhline(y=0.5, linestyle="dotted", color="r")
-ax.axhline(y=-0.5, linestyle="dotted", color="b")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # plot the oni timeseries we just downloaded
-----> 2 fig, ax = plt.subplots(figsize=(12, 6))
-      3 oni.sst.plot(ax=ax)
-      4 ax.set_ylabel("Oceanic Nino Index")
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-
-

Section 1.2: Get Precipitation Anomaly Data#

-

In tutorial 5, we created the monthly anomaly data of precipitation globally using the GPCP Monthly Precipitation Climate Data Records. Here, we read in the anomaly data and look at one specific month (e.g., 1998-01-01).

-
-
-
# download file 't5_gpcp-monthly-anomaly_1981-2010.nc'
-url_precip = "https://osf.io/vhdcg/download/"
-filename_precip = "t5_gpcp-monthly-anomaly_1981-2010.nc"
-precip = xr.open_dataset(pooch_load(filelocation=url_precip, filename=filename_precip))
-precip
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 4
-      2 url_precip = "https://osf.io/vhdcg/download/"
-      3 filename_precip = "t5_gpcp-monthly-anomaly_1981-2010.nc"
-----> 4 precip = xr.open_dataset(pooch_load(filelocation=url_precip, filename=filename_precip))
-      5 precip
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
# select just data from 1998
-data = precip.sel(time="1998-01-01")
-
-# initate plot
-fig = plt.figure(figsize=(9, 6))
-ax = plt.axes(projection=ccrs.Robinson(central_longitude=180))
-ax.coastlines()
-ax.gridlines()
-data.precip.plot(
-    ax=ax,
-    transform=ccrs.PlateCarree(),
-    vmin=-10,
-    vmax=10,
-    cmap="BrBG",
-    cbar_kwargs=dict(shrink=0.5, label="Precip Anomaly (mm/day)"),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # select just data from 1998
-----> 2 data = precip.sel(time="1998-01-01")
-      4 # initate plot
-      5 fig = plt.figure(figsize=(9, 6))
-
-NameError: name 'precip' is not defined
-
-
-
-
-
-
-

Section 1.3: Spatial Pattern#

-

Let’s look at one specific ENSO event - the 1997/1998 El Niño and see how the spatial pattern of the precipitation evolves. The 1997/1998 El Niño is one of the most significant ENSO events that started in May of 1997 and ended April of 1998.

-

Let’s examine the seasonal precipitation anomaly pattern during this time period.

-
-
-
# define the figure and each axis for the 2 rows and 2 columns
-fig, axs = plt.subplots(
-    nrows=2,
-    ncols=2,
-    subplot_kw={"projection": ccrs.Robinson(central_longitude=180)},
-    figsize=(12, 7.5),
-    sharex=True,
-    sharey=True,
-)
-
-# axs is a 2 dimensional array of `GeoAxes`.  We will flatten it into a 1-D array
-axs = axs.flatten()
-
-# loop over selected months (Jan, Apr, Jul, Oct)
-for i, month in enumerate(["1997-07-01", "1997-10-01", "1998-01-01", "1998-04-01"]):
-
-    # draw the coastines and major gridline for each subplot
-    axs[i].coastlines()
-    axs[i].gridlines()
-
-    # draw the precipitation anomaly data
-    precip.precip.sel(time=month).plot(
-        ax=axs[i],
-        transform=ccrs.PlateCarree(),
-        vmin=-10,
-        vmax=10,  # use the same range of max and min value
-        cmap="BrBG",
-        cbar_kwargs=dict(shrink=0.4, label="Precip anomaly\n(mm/day)"),
-    )
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # define the figure and each axis for the 2 rows and 2 columns
-----> 2 fig, axs = plt.subplots(
-      3     nrows=2,
-      4     ncols=2,
-      5     subplot_kw={"projection": ccrs.Robinson(central_longitude=180)},
-      6     figsize=(12, 7.5),
-      7     sharex=True,
-      8     sharey=True,
-      9 )
-     11 # axs is a 2 dimensional array of `GeoAxes`.  We will flatten it into a 1-D array
-     12 axs = axs.flatten()
-
-NameError: name 'plt' is not defined
-
-
-
-
-

In this series of four monthly maps, notice the shifts in precipitation patterns across the tropics and various land regions.

-

In particular there are large increases and decreases in precipitation over the tropical ocean, where ENSO is actively monitored. In the Nino 3.4 region, the intensification of the El Niño phase from (which is characterized by warmer SSTs over the central and eastern Pacific) occurs alongside an increase in rainfall shown here (more blue ares near the equator).

-

In addition to these changes, there are also rainfall patterns in regions such as in North and South America, with the Amazon as a notable example.

-
-
-
-

Section 2: Correlation Analysis#

-

Beyond visual inspection, we can also quantify the correlation between the ENSO (ONI) and the precipitation anomaly for a region of our interest.

-

Let’s use Niño 3.4 region as an example to calculate the correlation berween precipitation and ONI.

-
-
-
# extract precipitation data for the Nino 3.4 region & the same time period with ONI data
-precip_nino34 = precip.sel(
-    latitude=slice(-5, 5),
-    longitude=slice(190, 240),
-    time=slice("1981-09-01", "2022-12-01"),
-)
-precip_nino34
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # extract precipitation data for the Nino 3.4 region & the same time period with ONI data
-----> 2 precip_nino34 = precip.sel(
-      3     latitude=slice(-5, 5),
-      4     longitude=slice(190, 240),
-      5     time=slice("1981-09-01", "2022-12-01"),
-      6 )
-      7 precip_nino34
-
-NameError: name 'precip' is not defined
-
-
-
-
-
-
-
# calculate regional mean of the precipitation anomaly
-precip_nino34_mean = precip_nino34.mean(("latitude", "longitude"))
-
-# extract ONI value for the common period (ending at 2022-12-01)
-nino34 = oni.sel(time=slice("1981-09-01", "2022-12-01"))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # calculate regional mean of the precipitation anomaly
-----> 2 precip_nino34_mean = precip_nino34.mean(("latitude", "longitude"))
-      4 # extract ONI value for the common period (ending at 2022-12-01)
-      5 nino34 = oni.sel(time=slice("1981-09-01", "2022-12-01"))
-
-NameError: name 'precip_nino34' is not defined
-
-
-
-
-
-
-
# set up two subplots that share the x-axis to compare precipitation anomaly and ONI index
-fig, axs = plt.subplots(2, sharex=True)
-fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-axs[0].plot(precip_nino34_mean.time, precip_nino34_mean.precip)
-axs[0].set_ylabel("Precip (mm/day)")
-axs[0].axhline(y=0, color="k", linestyle="dashed")
-axs[1].plot(nino34.time, nino34.sst)
-axs[1].set_ylabel("ONI (degC)")
-axs[1].set_xlabel("Time")
-axs[1].axhline(y=0, color="k", linestyle="dashed")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # set up two subplots that share the x-axis to compare precipitation anomaly and ONI index
-----> 2 fig, axs = plt.subplots(2, sharex=True)
-      3 fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-      4 axs[0].plot(precip_nino34_mean.time, precip_nino34_mean.precip)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

From theses two time series, a pattern exists of a synchronized change in the precipitation anomaly and ONI. Now, we can generate a scatter plot to further examine this relationship.

-
-
-
# set up scatter plot
-fig, ax = plt.subplots(figsize=(7, 7))
-fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-ax.scatter(nino34.sst, precip_nino34_mean.precip, alpha=0.6)
-
-# add horizontal and vertical lines of 0 values
-ax.axhline(y=0, linestyle="dashed", color="k", alpha=0.6)
-ax.axvline(x=0, linestyle="dashed", color="k", alpha=0.6)
-ax.axvline(x=0.5, linestyle="dashed", color="r", alpha=0.6)  # El Nino threshold
-ax.axvline(x=-0.5, linestyle="dashed", color="b", alpha=0.6)  # La Nina threshold
-ax.set_xlabel("ONI (degC)")
-ax.set_ylabel("Precipitation Anomaly (mm/day)")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 # set up scatter plot
-----> 2 fig, ax = plt.subplots(figsize=(7, 7))
-      3 fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-      4 ax.scatter(nino34.sst, precip_nino34_mean.precip, alpha=0.6)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

The scatter plot unveils a nonlinear relationship between precipitation anomalies and the ONI across different ENSO phases:

-
    -
  • During the La Niña phase (i.e., when ONI values fall below -0.5/ the blue line), the Niño 3.4 region typically experiences below-average precipitation.

  • -
  • In contrast, during the El Niño phase (i.e., when ONI values rise above 0.5/ the red line), the Nino 3.4 region is inclined towards above-average precipitation.

  • -
-

Although the overall relationship is nonlinear, we are only interested in the data during different ENSO phases (ONI above and below 0.5). Looking at this data separately, visually a linear fit seems appropriate. For your projects, you should check this is so by looking at the distribution of the residuals of the linear fit. The residuals are the difference between a dataset predicted by the linear model you will find during the regression process and the true data. If the fit is good, there should be no relationship between these two (i.e. the distribution of residuals should have little to no correlation with your data. For simplicity, we skip this step here.

-

After you separate our data, you can look at the correlation coefficient and the associated p-value. This tells us how strongly related changes in the ONI are related to changes in precipitatoin anomalies. It is a value between -1 and 1, where the sign indicates whether the relationship is positive or negative, and the the absolute value tells us how strong the correlation. An absolute value of the correlatin coefficient closer to 1 indicates a stronger correlation. A low p-value will then assure us that likelihood of the correlation we find being purely due to chance is very low.

-

First let us separate our data into El Niño and La Niña phases by using the ONI as a threshold.

-
-
-
# El Nino Data, logically index to keep ONI values above 0.5
-el_nino_sst = nino34.sst[nino34.sst > 0.5]
-el_nino_precip = precip_nino34_mean.precip[nino34.sst > 0.5]
-
-# La Nina Data, logically index to keep ONI values below -0.5
-la_nina_sst = nino34.sst[nino34.sst < -0.5]
-la_nina_precip = precip_nino34_mean.precip[nino34.sst < -0.5]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[15], line 2
-      1 # El Nino Data, logically index to keep ONI values above 0.5
-----> 2 el_nino_sst = nino34.sst[nino34.sst > 0.5]
-      3 el_nino_precip = precip_nino34_mean.precip[nino34.sst > 0.5]
-      5 # La Nina Data, logically index to keep ONI values below -0.5
-
-NameError: name 'nino34' is not defined
-
-
-
-
-
-
-
# set up scatter plot for just El Nino and La Nina phases
-fig, ax = plt.subplots(figsize=(7, 7))
-fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-ax.scatter(el_nino_sst, el_nino_precip, c="r", alpha=0.6)
-ax.scatter(la_nina_sst, la_nina_precip, c="b", alpha=0.6)
-
-# add horizontal and vertical lines of 0 values
-ax.axhline(y=0, linestyle="dashed", color="k", alpha=0.6)
-ax.axvline(x=0, linestyle="dashed", color="k", alpha=0.6)
-ax.axvline(x=0.5, linestyle="dashed", color="r", alpha=0.6)  # El Nino threshold
-ax.axvline(x=-0.5, linestyle="dashed", color="b", alpha=0.6)  # La Nina threshold
-ax.set_xlabel("ONI (degC)")
-ax.set_ylabel("Precipitation Anomaly (mm/day)")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 2
-      1 # set up scatter plot for just El Nino and La Nina phases
-----> 2 fig, ax = plt.subplots(figsize=(7, 7))
-      3 fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-      4 ax.scatter(el_nino_sst, el_nino_precip, c="r", alpha=0.6)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Now find the linear correlation coefficient using SciPy stats package.

-
-
-
# correlation for El Nino data
-el_nino_r, el_nino_p = stats.pearsonr(el_nino_sst, el_nino_precip)
-
-print("El Nino - Corr Coef: " + str(el_nino_r) + ", p-val: " + str(el_nino_p))
-
-# correlation for La Nina data
-la_nina_r, la_nina_p = stats.pearsonr(la_nina_sst, la_nina_precip)
-
-print("La Nina - Corr Coef: " + str(la_nina_r) + ", p-val: " + str(la_nina_p))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 2
-      1 # correlation for El Nino data
-----> 2 el_nino_r, el_nino_p = stats.pearsonr(el_nino_sst, el_nino_precip)
-      4 print("El Nino - Corr Coef: " + str(el_nino_r) + ", p-val: " + str(el_nino_p))
-      6 # correlation for La Nina data
-
-NameError: name 'stats' is not defined
-
-
-
-
-
-

Questions 2: Climate Connection#

-
    -
  1. Note that the correlation during La Niña phases is low with a higher p-value (less significant) than the correlation coefficient during El Niño phases. Explain what this means.

  2. -
  3. Do the differences in correlation coefficients between phases line up with the time series above? Explain why.

  4. -
-

Click for solution

-
-
-

Coding Exercises 2#

-
    -
  1. Choose a region of your interest to examine the relationship between ENSO (using ONI data) and precipitation anomaly globally. It will be interesting to see if the figures you make line up with your expectations from the maps we have made in the beginning of the tutorial. Will they be more or less correlated that the Niño 3.4 region? In the example code we will use Italy, but you can change this to be whatever region you are interested in.

  2. -
-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Examine the relationship between ENSO and precipitation anomaly in a region of your choice."
-)
-#################################################
-
-# define region of interest for the precipitation anomaly
-italy_lon = [...]
-italy_lat = [...]
-
-# calculate regional mean time series
-precip_nino34_italy = precip.sel(
-    latitude=slice(...),
-    longitude=slice(...),
-    time=slice("1981-09-01", "2022-12-01"),
-).mean(dim=(...))
-
-# plot the time series of precipitation anomaly and ONI for the same time period on different subplots
-fig, axs = plt.subplots(2, sharex=True)
-fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-axs[0].plot(precip_nino34_italy.time, precip_nino34_italy.precip)
-axs[0].set_ylabel("Precip (mm/day)")
-axs[0].axhline(y=0, color="k", linestyle="dashed")
-axs[1].plot(nino34.time, nino34.sst)
-axs[1].set_ylabel("ONI (degC)")
-axs[1].set_xlabel("Time")
-axs[1].axhline(y=0, color="k", linestyle="dashed")
-
-# El Nino Data, logically index to keep ONI values above 0.5
-italy_el_nino_sst = ...
-italy_el_nino_precip = ...
-
-# La Nina Data, logically index to keep ONI values below -0.5
-italy_la_nina_sst = ...
-italy_la_nina_precip = ...
-
-# correlation for El Nino data
-italy_el_nino_r, italy_el_nino_p = ...
-
-print(
-    "El Nino - Corr Coef: " + str(italy_el_nino_r) + ", p-val: " + str(italy_el_nino_p)
-)
-
-# correlation for La Nina data
-italy_la_nina_r, italy_la_nina_p = ...
-
-print(
-    "La Nina - Corr Coef: " + str(italy_la_nina_r) + ", p-val: " + str(italy_la_nina_p)
-)
-
-# plot scatter plot between precipitation and ONI
-fig, ax = plt.subplots(figsize=(7, 7))
-fig.suptitle("GPCP Precipitaion Anomaly v.s. Oceanic Nino Index")
-ax.scatter(italy_el_nino_sst, italy_el_nino_precip, c="r", alpha=0.6)
-ax.scatter(italy_la_nina_sst, italy_la_nina_precip, c="b", alpha=0.6)
-
-# add horizontal and vertical lines of 0 values
-ax.axhline(y=0, linestyle="dashed", color="k", alpha=0.6)
-ax.axvline(x=0, linestyle="dashed", color="k", alpha=0.6)
-ax.axvline(x=0.5, linestyle="dashed", color="r", alpha=0.6)  # El Nino threshold
-ax.axvline(x=-0.5, linestyle="dashed", color="b", alpha=0.6)  # La Nina threshold
-ax.set_xlabel("ONI (degC)")
-ax.set_ylabel("Precipitation Anomaly (mm/day)")
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[18], line 3
-      1 #################################################
-      2 # Students: Fill in missing code (...) and comment or remove the next line
-----> 3 raise NotImplementedError(
-      4     "Student exercise: Examine the relationship between ENSO and precipitation anomaly in a region of your choice."
-      5 )
-      6 #################################################
-      7 
-      8 # define region of interest for the precipitation anomaly
-      9 italy_lon = [...]
-
-NotImplementedError: Student exercise: Examine the relationship between ENSO and precipitation anomaly in a region of your choice.
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -Solution hint -
-
-
-

Summary#

-

In this tutorial, you’ve acquired skills to evaluate the connection between precipitation and large-scale climate variability by analyzing the Oceanic Nino Index (ONI) and precipitation data.

-
    -
  • You’ve discovered that the during ENSO, precipitation patterns in the tropics are altered.

  • -
  • You have used Pearson’s correlation coefficient to investigate potential correlations. However, it’s critical to further scrutinize these correlations with physical explanations to ensure that any detected signals are valid.

  • -
-
-
-

Resources#

-

Data from this tutorial can be accessed for OISST here and precipitation here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8.html b/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8.html deleted file mode 100644 index 9a7c06dc7..000000000 --- a/book/_build/html/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere/student/W1D3_Tutorial8.html +++ /dev/null @@ -1,1814 +0,0 @@ - - - - - - - - - - - - Tutorial 8: Comparing Satellite Products With In Situ Data — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 8: Comparing Satellite Products With In Situ Data#

-

Week 1, Day 3, Remote Sensing

-

Content creators: Douglas Rao

-

Content reviewers: Katrina Dobson, Younkap Nina Duplex, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, our primary focus will be on the ‘Verification of Satellite Data’. Building on our previous modules where we explored various climate applications of satellite data, we will now delve into the critical task of assessing the quality and reliability of such data.

-

By the end of this tutorial, you will learn how to use land-based observations to validate satellite climate data. In this process you will:

-
    -
  • Learn how to access the gridded climate data derived from station observations from AWS.

  • -
  • Learn how to convert monthly total values to a daily rate.

  • -
  • Learn how to correctly evaluate satellite data against land-based observations.

  • -
-
-
-

Setup#

-
-
-
# !pip install s3fs --quiet
-
-# properly install cartopy in colab to avoid session crash
-# !apt-get install libproj-dev proj-data proj-bin --quiet
-# !apt-get install libgeos-dev --quiet
-# !pip install cython --quiet
-# !pip install cartopy --quiet
-
-# !apt-get -qq install python-cartopy python3-cartopy  --quiet
-# !pip uninstall -y shapely  --quiet
-# !pip install shapely --no-binary shapely  --quiet
-
-
-
-
-
-
-
# imports
-import s3fs
-import xarray as xr
-import numpy as np
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import pooch
-import os
-import tempfile
-import boto3
-import botocore
-from scipy import stats
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import s3fs
-      3 import xarray as xr
-      4 import numpy as np
-
-ModuleNotFoundError: No module named 's3fs'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Video 1 Name#

-
-

Video 1: Video 1 Name#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Video 1 Name
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation="", filename=""):
-    shared_location = "/home/jovyan/shared/data/tutorials/W1D3_RemoteSensingLandOceanandAtmosphere"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation, known_hash=None, fname=os.path.join(user_temp_cache, filename)
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Evaluating Satellite Data with Observations#

-

Satellite data is frequently cross-verified against observations deemed reliable to evaluate its quality. Station-based observations and derived data are typically regarded as a reliable reference. When it comes to oceanic data, measurements taken by ships, buoys, drifters, or gliders are often used as a benchmark to assess the quality of satellite data.

-

In this tutorial, we will be using the nClimGrid dataset, a gridded climate dataset produced by NOAA. This dataset provides daily and monthly temperature and precipitation data, leveraging all available station observations. However, it’s important to note that this dataset is exclusive to the United States. We have selected this dataset due to its public availability on AWS. You are encouraged to explore other station data for the evaluation of satellite data in your projects.

-
-

Section 1.1: Accesing nClimGrid - a station based gridded climate data#

-

The nClimGrid-monthly dataset is a gridded dataset derived from spatially interpolating data from the Global Historical Climatology Network (GHCN). The dataset includes monthly precipitation, monthly temperature average, monthly temperature maximum and monthly temperature minimum. The dataset provides monthly values in a approximate 5x5 km lat/lon grid for the Continental United States. Data is available from 1895 to the present via NOAA NCEI or AWS. We will be accessing the data via AWS directly.

-
-
-
# connect to the AWS S3 bucket for the nClimGrid Monthly Precipitation data
-
-# read in the monthly precipitation data from nClimGrid on AWS
-client = boto3.client(
-    "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-)  # initialize aws s3 bucket client
-
-file_nclimgrid = "noaa-nclimgrid-monthly-pds/nclimgrid_prcp.nc"
-ds = xr.open_dataset(
-    pooch_load(
-        filelocation="http://s3.amazonaws.com/" + file_nclimgrid,
-        filename=file_nclimgrid,
-    )
-)
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 4
-      1 # connect to the AWS S3 bucket for the nClimGrid Monthly Precipitation data
-      2 
-      3 # read in the monthly precipitation data from nClimGrid on AWS
-----> 4 client = boto3.client(
-      5     "s3", config=botocore.client.Config(signature_version=botocore.UNSIGNED)
-      6 )  # initialize aws s3 bucket client
-      8 file_nclimgrid = "noaa-nclimgrid-monthly-pds/nclimgrid_prcp.nc"
-      9 ds = xr.open_dataset(
-     10     pooch_load(
-     11         filelocation="http://s3.amazonaws.com/" + file_nclimgrid,
-     12         filename=file_nclimgrid,
-     13     )
-     14 )
-
-NameError: name 'boto3' is not defined
-
-
-
-
-

The nClimGrid dataset is available from 1895-01-01 until present. Since our GPCP data is only available between 1979-01-01 and 2022-12-01, extract only the data from that time period from the nClimGrid monthly data.

-
-
-
prcp_obs = ds.sel(time=slice("1979-01-01", "2022-12-31"))
-prcp_obs
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 prcp_obs = ds.sel(time=slice("1979-01-01", "2022-12-31"))
-      2 prcp_obs
-
-NameError: name 'ds' is not defined
-
-
-
-
-

From the information about the precipitation data from nClimGird monthly dataset, we know it is the monthly total precipitation, which is the total amount of rainfall that a location receives for the entire month with the unit of millimeter.

-
-
-
prcp_obs.prcp
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 prcp_obs.prcp
-
-NameError: name 'prcp_obs' is not defined
-
-
-
-
-

However, the GPCP satellite precipitation variable is the daily precipitation rate with the unit of mm/day. This variable quantifies the average amount of precipitation in a day for a given location in a month.

-

To convert from the total amount to the precipitation rate, we just need to divide the amount by the number of days within a month (e.g., 31 days for January). We can use .days_in_month to achieve that.

-
-
-
# calculate precipitation rate from nClimGrid
-obs_rate = prcp_obs.prcp / prcp_obs.time.dt.days_in_month
-obs_rate
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # calculate precipitation rate from nClimGrid
-----> 2 obs_rate = prcp_obs.prcp / prcp_obs.time.dt.days_in_month
-      3 obs_rate
-
-NameError: name 'prcp_obs' is not defined
-
-
-
-
-
-
-
# generate the map of precipitation rate from nClimGrid monthly data
-obs_rate[0].plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # generate the map of precipitation rate from nClimGrid monthly data
-----> 2 obs_rate[0].plot()
-
-NameError: name 'obs_rate' is not defined
-
-
-
-
-

In this quick map, we can see the value range of the precipitation rate appears to be reasonable compared to the GPCP monthly precipitation CDR data (0-20 mm/day).

-
-
-

Section 1.2: Read GPCP Monthly Precipitation Data#

-

Now we are ready to compare our land-based observations to the monthly GPCP satellite from AWS public data catalog.

-
-
-
# get the list of all data files in the AWS S3 bucket
-fs = s3fs.S3FileSystem(anon=True)
-file_pattern = "noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc"
-file_location = fs.glob(file_pattern)
-
-# open connection to all data files
-file_ob = [
-    pooch_load(filelocation="http://s3.amazonaws.com/" + file, filename=file)
-    for file in file_location
-]
-
-# open all the monthly data files and concatenate them along the time dimension.
-# this process will take ~ 1 minute to complete due to the number of data files.
-ds_gpcp = xr.open_mfdataset(file_ob, combine="nested", concat_dim="time")
-ds_gpcp
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # get the list of all data files in the AWS S3 bucket
-----> 2 fs = s3fs.S3FileSystem(anon=True)
-      3 file_pattern = "noaa-cdr-precip-gpcp-monthly-pds/data/*/gpcp_v02r03_monthly_*.nc"
-      4 file_location = fs.glob(file_pattern)
-
-NameError: name 's3fs' is not defined
-
-
-
-
-
-
-
# get the GPCP precipitation rate
-prcp_sat = ds_gpcp.precip
-prcp_sat
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # get the GPCP precipitation rate
-----> 2 prcp_sat = ds_gpcp.precip
-      3 prcp_sat
-
-NameError: name 'ds_gpcp' is not defined
-
-
-
-
-
-
-

Section 1.3: Spatial Pattern#

-

Now, let’s take a quick look at the spatial pattern between these two datasets for a selected month (e.g., 1979-01-01).

-
-
-
# set up the geographical region for continental US
-central_lat = 37.5
-central_lon = -96
-extent = [-120, -70, 21, 50]
-central_lon = np.mean(extent[:2])
-central_lat = np.mean(extent[2:])
-
-# extract sat and obs data for the month of 1979-01-01
-sat = prcp_sat.sel(time="1979-01-01")
-obs = obs_rate.sel(time="1979-01-01")
-
-# initate plot for North America using two suplots
-fig, axs = plt.subplots(
-    2,
-    subplot_kw={"projection": ccrs.AlbersEqualArea(central_lon, central_lat)},
-    figsize=(9, 12),
-    sharex=True,
-    sharey=True,
-)
-axs[0].set_extent(extent)
-axs[0].coastlines()
-axs[0].set_title("GPCP Monthly")
-sat.plot(
-    ax=axs[0],
-    transform=ccrs.PlateCarree(),
-    vmin=0,
-    vmax=15,
-    cbar_kwargs=dict(shrink=0.5, label="GPCP Precipitation (mm/day)"),
-)
-axs[1].set_extent(extent)
-axs[1].coastlines()
-axs[1].set_title("nClimGrid Monthly")
-obs.plot(
-    ax=axs[1],
-    transform=ccrs.PlateCarree(),
-    vmin=0,
-    vmax=15,
-    cbar_kwargs=dict(shrink=0.5, label="nClimGrid Precipitation (mm/day)"),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 5
-      3 central_lon = -96
-      4 extent = [-120, -70, 21, 50]
-----> 5 central_lon = np.mean(extent[:2])
-      6 central_lat = np.mean(extent[2:])
-      8 # extract sat and obs data for the month of 1979-01-01
-
-NameError: name 'np' is not defined
-
-
-
-
-

Overall, we have a similar spatial pattern but with widely different spatial resolution (i.e., 5km v.s. 2.5°).

-
-
-

Section 1.4: Time series comparison#

-

Let’s use New York City as an example, we can examine the time series of the satellite and observation-based dataset to evaluate the performance.

-

The latitute and longitute of NYC is (40.71°N, 74.01°W). We will use it to extract the time series from GPCP and nClimGrid using the nearest method you discussed in Day 1 due to the differing resolutions of each dataset.

-
-
-
# note that GPCP data is stored as 0-360 degree for the longitude, so the longitude should be using (360 - lon)
-sat = prcp_sat.sel(longitude=285.99, latitude=40.71, method="nearest")
-obs = obs_rate.sel(lon=-74.01, lat=40.71, method="nearest")  # precipitation rate
-obs_total = prcp_obs.sel(lon=-74.01, lat=40.71, method="nearest")  # total amount
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 # note that GPCP data is stored as 0-360 degree for the longitude, so the longitude should be using (360 - lon)
-----> 2 sat = prcp_sat.sel(longitude=285.99, latitude=40.71, method="nearest")
-      3 obs = obs_rate.sel(lon=-74.01, lat=40.71, method="nearest")  # precipitation rate
-      4 obs_total = prcp_obs.sel(lon=-74.01, lat=40.71, method="nearest")  # total amount
-
-NameError: name 'prcp_sat' is not defined
-
-
-
-
-
-
-
# let's look at the comparison between the precipitation rate from nClimGrid and satellite CDR
-fig, ax = plt.subplots(figsize=(12, 6))
-obs.plot(label="nClimGrid Monthly Precipitation Rate", ax=ax)
-sat.plot(color="k", alpha=0.6, label="GPCP Monthly Precipitation Rate", ax=ax)
-ax.set_ylabel("nClimGrid v.s. GPCP (New York City) (mm/day)")
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[15], line 2
-      1 # let's look at the comparison between the precipitation rate from nClimGrid and satellite CDR
-----> 2 fig, ax = plt.subplots(figsize=(12, 6))
-      3 obs.plot(label="nClimGrid Monthly Precipitation Rate", ax=ax)
-      4 sat.plot(color="k", alpha=0.6, label="GPCP Monthly Precipitation Rate", ax=ax)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Now we are going to zoom in to a few years to see how the data compares.

-
-
-
fig, ax = plt.subplots(figsize=(12, 6))
-obs.sel(time=slice("2011-01-01", "2015-12-01")).plot(label="nClimGrid", ax=ax)
-sat.sel(time=slice("2011-01-01", "2015-12-01")).plot(
-    marker="o", label="GPCP Monthly", ax=ax
-)
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 1
-----> 1 fig, ax = plt.subplots(figsize=(12, 6))
-      2 obs.sel(time=slice("2011-01-01", "2015-12-01")).plot(label="nClimGrid", ax=ax)
-      3 sat.sel(time=slice("2011-01-01", "2015-12-01")).plot(
-      4     marker="o", label="GPCP Monthly", ax=ax
-      5 )
-
-NameError: name 'plt' is not defined
-
-
-
-
-

We see a great alignment in the precipitation rate between the nClimGrid and GPCP data when we look at the details over this small chosen window. However, we cannot zoom in to every location for all times to confirm they are a good match. We can use statistics to quantify the relationship between these two datasets for as in a automated fashion, and will do so in the next section.

-
-
-

Section 1.5: Quantify the Difference#

-

One way to more robustly compare the datasets is through a scatterplot. The data would ideally follow the 1:1 line, which would suggest that they are very closely matched. Let’s make this plot and observe how our data compares to one another:

-
-
-
# make sure that both observation and satellite data are for the samte time period
-sat = sat.sel(time=slice("1979-01-01", "2022-12-01"))
-obs = obs.sel(time=slice("1979-01-01", "2022-12-01"))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 2
-      1 # make sure that both observation and satellite data are for the samte time period
-----> 2 sat = sat.sel(time=slice("1979-01-01", "2022-12-01"))
-      3 obs = obs.sel(time=slice("1979-01-01", "2022-12-01"))
-
-NameError: name 'sat' is not defined
-
-
-
-
-
-
-
# plot the scatter plot between nClimGrid and GPCP monthly precipitation CDR
-fig, ax = plt.subplots(figsize=(12, 6))
-fig.suptitle("GPCP Precipitaion v.s. nClimGrid")
-ax.scatter(sat, obs, alpha=0.6)
-# Add 1:1 line
-y_lim = (0, 15)
-x_lim = (0, 15)
-ax.plot((0, 15), (0, 15), "r-")
-ax.set_ylim(y_lim)
-ax.set_xlim(x_lim)
-ax.set_xlabel("GPCP Precipitation (mm/day)")
-ax.set_ylabel("nClimGrid (mm/day)")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[18], line 2
-      1 # plot the scatter plot between nClimGrid and GPCP monthly precipitation CDR
-----> 2 fig, ax = plt.subplots(figsize=(12, 6))
-      3 fig.suptitle("GPCP Precipitaion v.s. nClimGrid")
-      4 ax.scatter(sat, obs, alpha=0.6)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

By eye, there appears to be a stong correlation between the satellite data and the observations for NYC, with much of the data following the 1:1 line plotted in red. As in the last tutorial, we can calculate the correlation coefficient and corresponding p-value.

-
-
-
r, p = stats.pearsonr(sat, obs)
-print("Corr Coef: " + str(r) + ", p-val: " + str(p))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[19], line 1
-----> 1 r, p = stats.pearsonr(sat, obs)
-      2 print("Corr Coef: " + str(r) + ", p-val: " + str(p))
-
-NameError: name 'stats' is not defined
-
-
-
-
-

As we expected, the data are significantly correlated.

-
-

Coding Exercises 1.5#

-
    -
  1. Sometimes, we are more interested in the difference among the anomaly data rather than the total data. Using the same location, compare the anomaly data.

  2. -
-
-
-
#################################################
-# Students: Fill in missing code (...) and comment or remove the next line
-raise NotImplementedError(
-    "Student exercise: Compare the anomaly of precipitation rate for NYC."
-)
-#################################################
-
-# calculate climatology for the 1981-2010 period for both GPCP and nClimGrid
-sat_clim = ...
-obs_clim = ...
-
-# calculate anomaly of the NYC time series for both GPCP and nClimGrid
-sat_clim_anom = ...
-obs_clim_anom = ...
-
-# plot time series and scatter plot between two time series
-fig, ax = plt.subplots(figsize=(12, 6))
-obs_clim_anom.sel(time=slice("2011-01-01", "2015-12-01")).plot(
-    label="nClimGrid anomaly", ax=ax
-)
-sat_clim_anom.sel(time=slice("2011-01-01", "2015-12-01")).plot(
-    marker="o", label="GPCP Monthly anomaly", ax=ax
-)
-ax.legend()
-
-# plot the scatter plot between nClimGrid and GPCP monthly precipitation CDR
-fig, ax = plt.subplots(figsize=(12, 6))
-fig.suptitle("GPCP Precipitaion v.s. nClimGrid")
-ax.scatter(sat_clim_anom, obs_clim_anom, alpha=0.6)
-# Add 1:1 line
-y_lim = (0, 15)
-x_lim = (0, 15)
-ax.plot((0, 15), (0, 15), "r-")
-ax.set_ylim(y_lim)
-ax.set_xlim(x_lim)
-ax.set_xlabel("GPCP Precipitation anomaly (mm/day)")
-ax.set_ylabel("nClimGrid anomaly (mm/day)")
-
-# calculate and print correlation coefficient and p-value
-r, p = ...
-print("Corr Coef: " + str(r) + ", p-val: " + str(p))
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[20], line 3
-      1 #################################################
-      2 # Students: Fill in missing code (...) and comment or remove the next line
-----> 3 raise NotImplementedError(
-      4     "Student exercise: Compare the anomaly of precipitation rate for NYC."
-      5 )
-      6 #################################################
-      7 
-      8 # calculate climatology for the 1981-2010 period for both GPCP and nClimGrid
-      9 sat_clim = ...
-
-NotImplementedError: Student exercise: Compare the anomaly of precipitation rate for NYC.
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -Solution hint -
-
-
-
-

Summary#

-

In this tutorial, you explored how to use station-based observations within the U.S. to evaluate satellite precipitation data. While this isn’t a global comparison, the methodology can be applied to other station or observation data you may wish to utilize.

-

When carrying out these comparisons, remember the following key points:

-
    -
  • Ensure that both the satellite data and the observations represent the same quantity (for example, total precipitation amount versus precipitation rate).

  • -
  • Comparisons should be made for the same geolocation (or very near to it) and the same time period.

  • -
  • Be aware of potential spatial scale effects. Satellite data measures over a large area, whereas observations may be narrowly focused, particularly for elements that exhibit substantial spatial variability. This can lead to considerable uncertainty in the satellite data.

  • -
-
-
-

Resources#

-

Data from this tutorial can be accessed here and here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/chapter_title.html b/book/_build/html/tutorials/W1D4_Paleoclimate/chapter_title.html deleted file mode 100644 index ebcd9251b..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - Paleoclimate — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Paleoclimate

- -
-
- -
-
-
- - - - -
- -
-

Paleoclimate#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/further_reading.html b/book/_build/html/tutorials/W1D4_Paleoclimate/further_reading.html deleted file mode 100644 index 2ab318e46..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/further_reading.html +++ /dev/null @@ -1,1077 +0,0 @@ - - - - - - - - - - - - Suggested Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Suggested Further Reading

- -
-
- -
-
-
- - - - -
- -
-

Suggested Further Reading#

-

General overview of paleoclimate:

- -

IPCC Information from Paleoclimate Archives:

- -

Major climate variations in earth’s history:

- -

Modern climate changes in the context of paleoclimate:

- -

Delta-18O information:

- -
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.html deleted file mode 100644 index c38001418..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial1.html +++ /dev/null @@ -1,1573 +0,0 @@ - - - - - - - - - - - - Tutorial 1: Paleoclimate Proxies — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1: Paleoclimate Proxies#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you’ll learn about different types of paleoclimate proxies (physical characteristics of the environment that can stand in for direct measurements), the file type they come in, and how to convert these files to more usable formats.

-

By the end of this tutorial you will be able to:

-
    -
  • Understand some types of paleoclimate proxies and archives that exist

  • -
  • Create a global map of locations of proxy paleoclimate records in a specific data network

  • -
-
-
-

Setup#

-
-
-
# imports
-import os
-import pandas as pd
-import numpy as np
-import pooch  # to donwload the  PAGES2K data
-import matplotlib.pyplot as plt
-import tempfile
-import lipd
-import cartopy.crs as ccrs
-import cartopy.feature as cfeature
-import cartopy.io.shapereader as shapereader
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # imports
-      2 import os
-----> 3 import pandas as pd
-      4 import numpy as np
-      5 import pooch  # to donwload the  PAGES2K data
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-
-

Helper functions#

-
-

Helper functions#

-
-
- - -Hide code cell source - -
-
# @title Helper functions
-
-# Convert the PAGES2K LiDP files into a pandas.DataFrame
-
-# Function to convert the PAGES2K LiDP files in a pandas.DataFrame
-def lipd2df(
-    lipd_dirpath,
-    pkl_filepath=None,
-    col_str=[
-        "paleoData_pages2kID",
-        "dataSetName",
-        "archiveType",
-        "geo_meanElev",
-        "geo_meanLat",
-        "geo_meanLon",
-        "year",
-        "yearUnits",
-        "paleoData_variableName",
-        "paleoData_units",
-        "paleoData_values",
-        "paleoData_proxy",
-    ],
-):
-    """
-    Convert a bunch of PAGES2k LiPD files to a `pandas.DataFrame` to boost data loading.
-
-    If `pkl_filepath` isn't `None`, save the DataFrame as a pikle file.
-
-    Parameters:
-    ----------
-        lipd_dirpath: str
-          Path of the PAGES2k LiPD files
-        pkl_filepath: str or None
-          Path of the converted pickle file. Default: `None`
-        col_str: list of str
-          Name of the variables to extract from the LiPD files
-
-    Returns:
-    -------
-        df: `pandas.DataFrame`
-          Converted Pandas DataFrame
-    """
-
-    # Save the current working directory for later use, as the LiPD utility will change it in the background
-    work_dir = os.getcwd()
-    # LiPD utility requries the absolute path
-    lipd_dirpath = os.path.abspath(lipd_dirpath)
-    # Load LiPD files
-    lipds = lipd.readLipd(lipd_dirpath)
-    # Extract timeseries from the list of LiDP objects
-    ts_list = lipd.extractTs(lipds)
-    # Recover the working directory
-    os.chdir(work_dir)
-    # Create an empty pandas.DataFrame with the number of rows to be the number of the timeseries (PAGES2k records),
-    # and the columns to be the variables we'd like to extract
-    df_tmp = pd.DataFrame(index=range(len(ts_list)), columns=col_str)
-    # Loop over the timeseries and pick those for global temperature analysis
-    i = 0
-    for ts in ts_list:
-        if (
-            "paleoData_useInGlobalTemperatureAnalysis" in ts.keys()
-            and ts["paleoData_useInGlobalTemperatureAnalysis"] == "TRUE"
-        ):
-            for name in col_str:
-                try:
-                    df_tmp.loc[i, name] = ts[name]
-                except:
-                    df_tmp.loc[i, name] = np.nan
-            i += 1
-    # Drop the rows with all NaNs (those not for global temperature analysis)
-    df = df_tmp.dropna(how="all")
-    # Save the dataframe to a pickle file for later use
-    if pkl_filepath:
-        save_path = os.path.abspath(pkl_filepath)
-        print(f"Saving pickle file at: {save_path}")
-        df.to_pickle(save_path)
-    return df
-
-
-
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Introduction to PAGES2k#

-

As we’ve now seen from introductory video, there are various types of paleoclimate archives and proxies that can be used to reconstruct past changes in Earth’s climate. For example:

-
    -
  • Sediment Cores: Sediments deposited in layers within lakes and oceans serve as a record of climate variations over time. Various proxies for past climate are preserved in sediment cores including, pollen, microfossils, charcoal, microscopic organisms, organic molecules, etc.

  • -
  • Ice Cores: Similarly to sediment cores, ice cores capture past climate changes in layers of ice accumulated over time. Common proxies for reconstructing past climate in ice cores include water isotopes, greenhouse gas concentrations of air bubbles in the ice, and dust.

  • -
  • Corals: Corals form annual growth bands within their carbonate skeletons, recording temperature changes over time. Scientists analyze the chemical composition of each layer to reconstruct temperature and salinity. Corals typically preserve relatively short paleoclimate records, but they provide very high-resolution reconstructions (monthly and seasonal) and are therefore valuable for understanding past changes in short-term phenomena.

  • -
  • Speleothems: These are cave formations that result from the deposition of minerals from groundwater. As the water flows into the cave, thin layers of minerals (e.g., calcium carbonate), are deposited. The thickness and chemical composition of speleothem layers can be used to reconstruct climate changes in the past.

  • -
  • Tree Rings: Each year, trees add a new layer of growth, known as a tree ring. These rings record changes in temperature and precipitation. Proxy measurements of tree rings include thickness and isotopes, which reflect annual variability in moisture and temperature.

  • -
-

There are many existing paleoclimate reconstructions spanning a variety of timescales and from global locations. Given the temporal and spatial vastness of existing paleoclimate records, it can be challenging to know what paleoclimate data already exists and where to find it. One useful solution is compiling all existing paleoclimate records for a single climate variable (temperature, greenhouse gas concentration, precipitation, etc.) and over a specific time period (Holocene to present, the past 800,000 years, etc.).

-

One example of this is the PAGES2k network, which is a community-sourced database of temperature-sensitive proxy records. The database consists of 692 records from 648 locations, that are from a variety of archives (e.g., trees, ice, sediment, corals, speleothems, etc.) and span the Common Era (1 CE to present, i.e., the past ~2,000 years). You can read more about the PAGES2k network, in PAGES 2k Consortium (2017).

-

In this tutorial, we will explore the types of proxy records in the PAGES2k network and create a map of proxy record locations.

-
-
-

Section 2: Get PAGES2k LiPD Files#

-

The PAGES2k network is stored in a specific file format known as Linked Paleo Data format (LiPD). LiPD files contain time series information in addition to supporting metadata (e.g., root metadata, location). Pyleoclim (and its dependency package LiPD) leverages this additional information using LiPD-specific functionality.

-

Data stored in the .lpd format can be loaded directly as an Lipd object. If the data_path points to one LiPD file, lipd.readLipd.() will load the specific record, while if data_path points to a folder of lipd files, lipd.readLipd.() will load the full set of records. This function to read in the data is imbedded in the helper function above used to read the data in and convert it to a more usable format.

-

The first thing we need to do it to download the data.

-
-
-
# Set the name to save the PAGES2K data
-fname = "pages2k_data"
-
-# Download the datae
-lipd_file_path = pooch.retrieve(
-    url="https://ndownloader.figshare.com/files/8119937",
-    known_hash=None,
-    path="./",
-    fname=fname,
-    processor=pooch.Unzip(),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 5
-      2 fname = "pages2k_data"
-      4 # Download the datae
-----> 5 lipd_file_path = pooch.retrieve(
-      6     url="https://ndownloader.figshare.com/files/8119937",
-      7     known_hash=None,
-      8     path="./",
-      9     fname=fname,
-     10     processor=pooch.Unzip(),
-     11 )
-
-NameError: name 'pooch' is not defined
-
-
-
-
-

Now we can use our helpfer function lipd_2df() to convert the LiPD files to a Pandas dataframe.

-

NOTE: when you run some of the next code cell to convert the Lipd files to a DataFrame, you will get some error messages. This is fine and the code will still accomplish what it needs to do. The code will also take a few minutes to run, so if it’s taking longer than you’d expect, that’s alright!

-
-
-
# convert all the lipd files into a DataFrame
-fname = "pages2k_data"
-
-pages2k_data = lipd2df(lipd_dirpath=os.path.join(".", f"{fname}.unzip", "LiPD_Files"))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 4
-      1 # convert all the lipd files into a DataFrame
-      2 fname = "pages2k_data"
-----> 4 pages2k_data = lipd2df(lipd_dirpath=os.path.join(".", f"{fname}.unzip", "LiPD_Files"))
-
-Cell In[2], line 49, in lipd2df(lipd_dirpath, pkl_filepath, col_str)
-     47 lipd_dirpath = os.path.abspath(lipd_dirpath)
-     48 # Load LiPD files
----> 49 lipds = lipd.readLipd(lipd_dirpath)
-     50 # Extract timeseries from the list of LiDP objects
-     51 ts_list = lipd.extractTs(lipds)
-
-NameError: name 'lipd' is not defined
-
-
-
-
-

The PAGES2k data is now stored as a dataframe and we can view the data to understand different attributes it contains.

-
-
-
# print the top few rows of the PAGES2K data
-pages2k_data.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # print the top few rows of the PAGES2K data
-----> 2 pages2k_data.head()
-
-NameError: name 'pages2k_data' is not defined
-
-
-
-
-
-
-

Section 3: Plotting a Map of Proxy Reconstruction Locations#

-

Now that we have converted the data into a Pandas dataframe, we can plot the PAGES2k network on a map to understand the spatial distribution of the temperature records and the types of proxies that were measured.

-

Before generating the plot, we have to define the colours and the marker types that we want to use in the plot. We also need to set a list with the different archive_type names that appear in the data frame.

-
-
-
# list of markers and colors for the different archive_type
-markers = ["p", "p", "o", "v", "d", "*", "s", "s", "8", "D", "^"]
-colors = [
-    np.array([1.0, 0.83984375, 0.0]),
-    np.array([0.73828125, 0.71484375, 0.41796875]),
-    np.array([1.0, 0.546875, 0.0]),
-    np.array([0.41015625, 0.41015625, 0.41015625]),
-    np.array([0.52734375, 0.8046875, 0.97916667]),
-    np.array([0.0, 0.74609375, 1.0]),
-    np.array([0.25390625, 0.41015625, 0.87890625]),
-    np.array([0.54296875, 0.26953125, 0.07421875]),
-    np.array([1, 0, 0]),
-    np.array([1.0, 0.078125, 0.57421875]),
-    np.array([0.1953125, 0.80078125, 0.1953125]),
-]
-
-# create the plot
-
-fig = plt.figure(figsize=(10, 5))
-ax = fig.add_subplot(1, 1, 1, projection=ccrs.Robinson())
-
-# add plot title
-ax.set_title(f"PAGES2k Network (n={len(pages2k_data)})", fontsize=20, fontweight="bold")
-
-# set the base map
-# ----------------
-ax.set_global()
-
-# add coast lines
-ax.coastlines()
-
-# add land fratures using gray color
-ax.add_feature(cfeature.LAND, facecolor="gray", alpha=0.3)
-
-# add gridlines for latitude and longitude
-ax.gridlines(edgecolor="gray", linestyle=":")
-
-
-# plot the different archive types
-# -------------------------------
-
-# extract the name of the different archive types
-archive_types = pages2k_data.archiveType.unique()
-
-# plot the archive_type using a forloop
-for i, type_i in enumerate(archive_types):
-    df = pages2k_data[pages2k_data["archiveType"] == type_i]
-    # count the number of appearances of the same archive_type
-    count = df["archiveType"].count()
-    # generate the plot
-    ax.scatter(
-        df["geo_meanLon"],
-        df["geo_meanLat"],
-        marker=markers[i],
-        c=colors[i],
-        edgecolor="k",
-        s=50,
-        transform=ccrs.Geodetic(),
-        label=f"{type_i} (n = {count})",
-    )
-# add legend to the plot
-ax.legend(
-    scatterpoints=1,
-    bbox_to_anchor=(0, -0.4),
-    loc="lower left",
-    ncol=3,
-    fontsize=15,
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 4
-      1 # list of markers and colors for the different archive_type
-      2 markers = ["p", "p", "o", "v", "d", "*", "s", "s", "8", "D", "^"]
-      3 colors = [
-----> 4     np.array([1.0, 0.83984375, 0.0]),
-      5     np.array([0.73828125, 0.71484375, 0.41796875]),
-      6     np.array([1.0, 0.546875, 0.0]),
-      7     np.array([0.41015625, 0.41015625, 0.41015625]),
-      8     np.array([0.52734375, 0.8046875, 0.97916667]),
-      9     np.array([0.0, 0.74609375, 1.0]),
-     10     np.array([0.25390625, 0.41015625, 0.87890625]),
-     11     np.array([0.54296875, 0.26953125, 0.07421875]),
-     12     np.array([1, 0, 0]),
-     13     np.array([1.0, 0.078125, 0.57421875]),
-     14     np.array([0.1953125, 0.80078125, 0.1953125]),
-     15 ]
-     17 # create the plot
-     19 fig = plt.figure(figsize=(10, 5))
-
-NameError: name 'np' is not defined
-
-
-
-
-
-

Questions 3#

-

You have just plotted the global distribution and temperature proxy type of the 692 records in the PAGES2k network!

-
    -
  1. Which temperature proxy is the most and least abundant in this database?

  2. -
  3. In what region do you observe the most and least temperature records? Why might this be the case?

  4. -
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, you explored the PAGES2K network, which offers an extensive collection of proxy temperature reconstructions spanning the last 2,000 years. You surveyed various types of paleoclimate proxies and archives available, in addition to crafting a global map pinpointing the locations of the PAGES2k proxy records. As you advance throughout this module, you will extract and meticulously analyze the temperature timelines embedded within reconstructions such as those shown here.

-
-
-

Resources#

-

Code for this tutorial is based on existing notebooks from LinkedEarth that convert LiPD files to a Pandas dataframe and create a map of the PAGES2k network.

-

The following data is used in this tutorial:

- -
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.html deleted file mode 100644 index 7d4b2de24..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial2.html +++ /dev/null @@ -1,1727 +0,0 @@ - - - - - - - - - - - - Tutorial 2: Reconstructing Past Changes in Ocean Climate — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2: Reconstructing Past Changes in Ocean Climate#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In the previous days, you learned about the El Niño–Southern Oscillation (ENSO), and have explored how satellite data can be employed to track this phenomenon during the instrumental period. In this tutorial, you will explore how oxygen isotopes of corals can record changes in temperature associated with the phase of ENSO even further back in time.

-

By the end of this tutorial you will be able to:

-
    -
  • Understand the types of marine proxies that are used to reconstruct past climate

  • -
  • Create a stacked plot and warming stripe to visualize ENSO temperature reconstructions

  • -
-
-

An Overview of Isotopes in Paleoclimate#

-

In this tutorial, and many of the remaining tutorials in 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.

-

image-3.png

-

Credit: NASA Climate Science Investigations

-

image-2.png

-

Credit: NASA Climate Science Investigations

-

Changes in the ratio of the heavy to light isotope can reflect changes in different climate variables, depending on geographic location and the material being measured. The ratio represented in delta notation (δ) and in units of per mille (‰), and is calculated using the equation below (the same applies to the ratio of the heavy and light hydrogen isotopes):

-

image.png

-

The terminology for discussing δ18O and δD can be a bit confusing and there are multiple ways to reference the same trends in the data. The most common terms used to describe isotopic compositions are “depleted” and “enriched”. These terms refer to the relative amout of the heavy isotopes. Therefore, a “more depleted” isotopic value is more depleted in the heavy isotope (i.e., there is less of the heavy isotope), whereas a “more enriched” isotopic value is more enriched in the heavy isotope (i.e., there is more of the heavy isotope). Other terms that are sometimes used to describe whether isotopes are depleted or enriched are “more negative” or “more positive”. Isotopic values can be both positive and negative, so using “more negative” and “more positive” can be a bit confusing. For example, if we have isotopic values are of -15‰ and -9‰, the value of -9‰ is “more enriched” (i.e., has more of the heavy isotope) or “more positive” (i.e., is closer to zero and positive values) than -15‰. Finally, the terms “smaller” or “larger” isotopic values can also be used to reference isotopes.

-

Additional information about the use of isotopes in paleoclimate can be found here.

-
-
-
-

Setup#

-
-
-
# imports
-import pandas as pd
-import numpy as np
-import pooch
-import os
-import tempfile
-import cartopy
-import pyleoclim as pyleo
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import cartopy.feature as cfeature
-from matplotlib import patches
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import pandas as pd
-      3 import numpy as np
-      4 import pooch
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
- -
-

Section 2: Plot the Data Using Multiseries#

-

We will utilize the built in features of a multiseries object to plot our coral proxy data side by side. To create a pyleo.MultipleSeries, we first create a list with our pyleo.Series objects and then pass this into a pyleo.MultipleSeries.

-
-
-
# combine into a list
-nino_comparison = [palmyra_stnd, line_stnd]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # combine into a list
-----> 2 nino_comparison = [palmyra_stnd, line_stnd]
-
-NameError: name 'palmyra_stnd' is not defined
-
-
-
-
-
-
-
# create multiseries
-nino = pyleo.MultipleSeries(nino_comparison, name="El Nino Comparison")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # create multiseries
-----> 2 nino = pyleo.MultipleSeries(nino_comparison, name="El Nino Comparison")
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-
-
-
# plot the time series of both datasets
-fig, ax = nino.stackplot(time_unit="year", xlim=[1960, 2000], colors=["b", "g"])
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # plot the time series of both datasets
-----> 2 fig, ax = nino.stackplot(time_unit="year", xlim=[1960, 2000], colors=["b", "g"])
-
-NameError: name 'nino' is not defined
-
-
-
-
-
-

Questions 2: Climate Connection#

-

Recall that as SST becomes colder, δ18O becomes more positive, and vice versa. Compare the figure below of the ONI to the time series of coral δ18O you plotted above and answer the questions below.

-

-

Credit: UCAR

-
    -
  1. Do the ENSO events recorded by the ONI agree with the coral data?

  2. -
  3. What are some considerations you can think of when comparing proxies such as this to the ONI?

  4. -
-

Click for solution

-
-
-
-

Section 1.3: Make Warming Stripes Plot#

-

We can also make a warming stripe for this data Series using the .stripes() method, where darker red stripes indicate a warmer eastern Pacific and possibly an El Niño phase, and darker blue stripes indicate a cooler eastern Pacific and possibly La Niña phase. Can you see the trend present in the data?

-
-
-
fig, ax = nino.stripes(
-    ref_period=(1960, 1990), time_unit="year", show_xaxis=True, cmap="RdBu"
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 1
-----> 1 fig, ax = nino.stripes(
-      2     ref_period=(1960, 1990), time_unit="year", show_xaxis=True, cmap="RdBu"
-      3 )
-
-NameError: name 'nino' is not defined
-
-
-
-
-
-
-

Summary#

-

In this tutorial, we discovered how oxygen isotopes within corals serve as a valuable archive, recording changes in temperature associated with ENSO phases.

-

During our explorations,

-
    -
  • We ventured into the study of proxy-based coral δ18O records, gaining insights into the rich historical climate data encapsulated within these marine structures.

  • -
  • We compared these records to noted ENSO events over a few decades, offering us a glimpse into the dynamic nature of this influential climate phenomenon.

  • -
-
-
-

Resources#

-

Code for this tutorial is based on existing notebooks from LinkedEarth that uses the Pyleoclim package to assess variability in the El Nino.

-

Data from the following sources are used in this tutorial:

- -
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.html deleted file mode 100644 index ca0888822..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial3.html +++ /dev/null @@ -1,1645 +0,0 @@ - - - - - - - - - - - - Tutorial 3: Reconstructing Past Changes in Terrestrial Climate — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3: Reconstructing Past Changes in Terrestrial Climate#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, we’ll explore the Euro2K proxy network, which is a subset of PAGES2K, the database we explored in the first tutorial. We will specifically focus on interpreting temperature change over the past 2,000 years as recorded by proxy records from tree rings, speleothems, and lake sediments. To analyze these datasets, we will group them by archive and create time series plots to assess temperature variations.

-

During this tutorial you will:

-
    -
  • Plot temperature records based on three different terrestrial proxies

  • -
  • Assess similarities and differences between the temperature records

  • -
-
-
-

Setup#

-
-
-
# imports
-import pyleoclim as pyleo
-import pandas as pd
-import numpy as np
-import os
-import pooch
-import tempfile
-import matplotlib.pyplot as plt
-import cartopy
-import cartopy.crs as ccrs
-import cartopy.feature as cfeature
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import pyleoclim as pyleo
-      3 import pandas as pd
-      4 import numpy as np
-
-ModuleNotFoundError: No module named 'pyleoclim'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Loading Terrestrial Paleoclimate Records#

-

First, we need to download the data. Similar to Tutorial 1, the data is stored as a LiPD file, and we will be using Pyleoclim to format and interpret the data.

-
-
-
# set the name to save the Euro2k data
-fname = "euro2k_data"
-
-# download the data
-lipd_file_path = pooch.retrieve(
-    url="https://osf.io/7ezp3/download/",
-    known_hash=None,
-    path="./",
-    fname=fname,
-    processor=pooch.Unzip(),
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 5
-      2 fname = "euro2k_data"
-      4 # download the data
-----> 5 lipd_file_path = pooch.retrieve(
-      6     url="https://osf.io/7ezp3/download/",
-      7     known_hash=None,
-      8     path="./",
-      9     fname=fname,
-     10     processor=pooch.Unzip(),
-     11 )
-
-NameError: name 'pooch' is not defined
-
-
-
-
-
-
-
# the LiPD object can be used to load datasets stored in the LiPD format.
-# in this first case study, we will load an entire library of LiPD files:
-d_euro = pyleo.Lipd(os.path.join(".", f"{fname}.unzip", "Euro2k"))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 3
-      1 # the LiPD object can be used to load datasets stored in the LiPD format.
-      2 # in this first case study, we will load an entire library of LiPD files:
-----> 3 d_euro = pyleo.Lipd(os.path.join(".", f"{fname}.unzip", "Euro2k"))
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-
-
-

Section 2: Temperature Reconstructions#

-

Before plotting, let’s narrow the data down a bit. We can filter all of the data so that we only keep reconstructions of temperature from terrestrial archives (e.g. tree rings, speleothems and lake sediments). This is accomplished with the function below.

-
-
-
def filter_data(dataset, archive_type, variable_name):
-    """
-    Return a MultipleSeries object with the variable record (variable_name) for a given archive_type and coordinates.
-    """
-    # Create a list of dictionary that can be iterated upon using Lipd.to_tso method
-    ts_list = dataset.to_tso()
-    # Append the correct indices for a given value of archive_type and variable_name
-    indices = []
-    lat = []
-    lon = []
-    for idx, item in enumerate(ts_list):
-        # Check that it is available to avoid errors on the loop
-        if "archiveType" in item.keys():
-            # If it's a archive_type, then proceed to the next step
-            if item["archiveType"] == archive_type:
-                if item["paleoData_variableName"] == variable_name:
-                    indices.append(idx)
-    print(indices)
-    # Create a list of LipdSeries for the given indices
-    ts_list_archive_type = []
-    for indice in indices:
-        ts_list_archive_type.append(pyleo.LipdSeries(ts_list[indice]))
-
-        # save lat and lons of proxies
-        lat.append(ts_list[indice]["geo_meanLat"])
-        lon.append(ts_list[indice]["geo_meanLon"])
-
-    return pyleo.MultipleSeries(ts_list_archive_type), lat, lon
-
-
-
-
-

In the function above, the Lipd.to_tso method is used to obtain a list of dictionaries that can be iterated upon.

-
-
-
ts_list = d_euro.to_tso()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 ts_list = d_euro.to_tso()
-
-NameError: name 'd_euro' is not defined
-
-
-
-
-

Dictionaries are native to Python and can be explored as shown below.

-
-
-
# look at available entries for just one time-series
-ts_list[0].keys()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # look at available entries for just one time-series
-----> 2 ts_list[0].keys()
-
-NameError: name 'ts_list' is not defined
-
-
-
-
-
-
-
# print relevant information for all entries
-for idx, item in enumerate(ts_list):
-    print(str(idx) + ": " + item["dataSetName"] + ": " + item["paleoData_variableName"])
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # print relevant information for all entries
-----> 2 for idx, item in enumerate(ts_list):
-      3     print(str(idx) + ": " + item["dataSetName"] + ": " + item["paleoData_variableName"])
-
-NameError: name 'ts_list' is not defined
-
-
-
-
-

Now let’s use our pre-defined function to create a new list that only has temperature reconstructions based on proxies from lake sediments:

-
-
-
ms_euro_lake, euro_lake_lat, euro_lake_lon = filter_data(
-    d_euro, "lake sediment", "temperature"
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 ms_euro_lake, euro_lake_lat, euro_lake_lon = filter_data(
-----> 2     d_euro, "lake sediment", "temperature"
-      3 )
-
-NameError: name 'd_euro' is not defined
-
-
-
-
-

And a new list that only has temperature reconstructions based on proxies from tree rings:

-
-
-
ms_euro_tree, euro_tree_lat, euro_tree_lon = filter_data(d_euro, "tree", "temperature")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 ms_euro_tree, euro_tree_lat, euro_tree_lon = filter_data(d_euro, "tree", "temperature")
-
-NameError: name 'd_euro' is not defined
-
-
-
-
-

And finally, a new list that only has temperature information based on proxies from speleothems:

-
-
-
ms_euro_spel, euro_spel_lat, euro_spel_lon = filter_data(d_euro, "speleothem", "d18O")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 1
-----> 1 ms_euro_spel, euro_spel_lat, euro_spel_lon = filter_data(d_euro, "speleothem", "d18O")
-
-NameError: name 'd_euro' is not defined
-
-
-
-
-
-

Coding Exercises 2#

-

Using the coordinate information output from the filter_data() function, make a plot of the locations of the proxies using the markers and colors from Tutorial 1. Note that data close together may not be very visible.

-
-
-
# initate plot with the specific figure size
-fig = plt.figure(figsize=(9, 6))
-
-# set base map projection
-ax = plt.axes(projection=ccrs.Robinson())
-
-ax.set_global()
-
-# add land fratures using gray color
-ax.add_feature(cfeature.LAND, facecolor="k")
-
-# add coastlines
-ax.add_feature(cfeature.COASTLINE)
-
-# add the proxy locations
-# Uncomment and complete following line
-# ax.scatter(
-#     ...,
-#     ...,
-#     transform=ccrs.Geodetic(),
-#     label=...,
-#     s=50,
-#     marker="d",
-#     color=[0.52734375, 0.8046875, 0.97916667],
-#     edgecolor="k",
-#     zorder=2,
-# )
-# ax.scatter(
-#     ...,
-#     ...,
-#     transform=ccrs.Geodetic(),
-#     label=...,
-#     s=50,
-#     marker="p",
-#     color=[0.73828125, 0.71484375, 0.41796875],
-#     edgecolor="k",
-#     zorder=2,
-# )
-# ax.scatter(
-#     ...,
-#     ...,
-#     transform=ccrs.Geodetic(),
-#     label=...,
-#     s=50,
-#     marker="8",
-#     color=[1, 0, 0],
-#     edgecolor="k",
-#     zorder=2,
-# )
-
-# change the map view to zoom in on central Pacific
-ax.set_extent((0, 360, 0, 90), crs=ccrs.PlateCarree())
-
-ax.legend(
-    scatterpoints=1,
-    bbox_to_anchor=(0, -0.4),
-    loc="lower left",
-    ncol=3,
-    fontsize=15,
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # initate plot with the specific figure size
-----> 2 fig = plt.figure(figsize=(9, 6))
-      4 # set base map projection
-      5 ax = plt.axes(projection=ccrs.Robinson())
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -

Since we are going to compare temperature datasets based on different terrestrial climate archives (lake sediments, tree rings and speleothems), the quantitative values of the measurements in each record will differ (i.e., the lake sediment and tree ring data are temperature in degrees C, but the speleothem data is oxygen isotopes in per mille). Therefore, to more easily and accurately compare temperature between the records, it’s helpful to standardize the data as we did in tutorial 2. The .standardize() function removes the estimated mean of the time series and divides by its estimated standard deviation.

-
-
-
# standardize the data
-spel_stnd = ms_euro_spel.standardize()
-lake_stnd = ms_euro_lake.standardize()
-tree_stnd = ms_euro_tree.standardize()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 # standardize the data
-----> 2 spel_stnd = ms_euro_spel.standardize()
-      3 lake_stnd = ms_euro_lake.standardize()
-      4 tree_stnd = ms_euro_tree.standardize()
-
-NameError: name 'ms_euro_spel' is not defined
-
-
-
-
-

Now we can use Pyleoclim functions to create three stacked plots of this data with lake sediment records on top, tree ring reconstructions in the middle and speleothem records on the bottom.

-

Note that the colors used for the time series in each plot are the default colors generated by the function, so the corresponding colors in each of the three plots are not relevant.

-
-
-
# note the x axis is years before present, so read from left to right moving back in time
-
-ax = lake_stnd.stackplot(
-    label_x_loc=1.7,
-    xlim=[0, 2000],
-    v_shift_factor=1,
-    figsize=[9, 5],
-    time_unit="yrs BP",
-)
-ax[0].suptitle("Lake Cores", y=1.2)
-
-ax = tree_stnd.stackplot(
-    label_x_loc=1.7,
-    xlim=[0, 2000],
-    v_shift_factor=1,
-    figsize=[9, 5],
-    time_unit="yrs BP",
-)
-ax[0].suptitle("Tree Rings", y=1.2)
-
-# recall d18O is a proxy for SST, and that more positive d18O means colder SST
-ax = spel_stnd.stackplot(
-    label_x_loc=1.7,
-    xlim=[0, 2000],
-    v_shift_factor=1,
-    figsize=[9, 5],
-    time_unit="yrs BP",
-)
-ax[0].suptitle("Speleothems", y=1.2)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[15], line 3
-      1 # note the x axis is years before present, so read from left to right moving back in time
-----> 3 ax = lake_stnd.stackplot(
-      4     label_x_loc=1.7,
-      5     xlim=[0, 2000],
-      6     v_shift_factor=1,
-      7     figsize=[9, 5],
-      8     time_unit="yrs BP",
-      9 )
-     10 ax[0].suptitle("Lake Cores", y=1.2)
-     12 ax = tree_stnd.stackplot(
-     13     label_x_loc=1.7,
-     14     xlim=[0, 2000],
-   (...)
-     17     time_unit="yrs BP",
-     18 )
-
-NameError: name 'lake_stnd' is not defined
-
-
-
-
-
-
-

Questions 2#

-

Using the plots we just made (and recalling that all of these records are from Europe), let’s make some inferences about the temperature data over the past 2,000 years:

-
    -
  1. Recall that δ18O is a proxy for SST, and that more positive δ18O means colder SST. Do the temperature records based on a single proxy type record similar patterns?

  2. -
  3. Do the three proxy types collectively record similar patterns?

  4. -
  5. What might be causing the more frequent variations in temperature?

  6. -
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, we explored how to use the Euro2k proxy network to investigate changes in temperature over the past 2,000 years from tree rings, speleothems, and lake sediments. To analyze these diverse datasets, we categorized them based on their archive type and constructed time series plots.

-
-
-

Resources#

-

Code for this tutorial is based on an existing notebook from LinkedEarth that provides instruction on working with LiPD files.

-

Data from the following sources are used in this tutorial:

-
    -
  • Euro2k database: PAGES2k Consortium., Emile-Geay, J., McKay, N. et al. A global multiproxy database for temperature reconstructions of the Common Era. Sci Data 4, 170088 (2017). https://doi.org/10.1038/sdata.2017.88

  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.html deleted file mode 100644 index a02012bfc..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.html +++ /dev/null @@ -1,1474 +0,0 @@ - - - - - - - - - - - - Tutorial 4: Reconstructing Past Changes in Atmospheric Climate — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 4: Reconstructing Past Changes in Atmospheric Climate#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, we’ll analyze δD and atmospheric CO2 data from the EPICA Dome C ice core. Recall from the video that δD and δ18O measurements on ice cores record past changes in temperature, and that measurements of CO2 trapped in ice cores can be used to reconstruction past changes in Earth’s atmospheric composition.

-

By the end of this tutorial you will be able to:

-
    -
  • Plot δD and CO2 records from the EPICA Dome C ice core

  • -
  • Assess changes in temperature and atmospheric greenhouse gas concentration over the past 800,000 years

  • -
-
-
-

Setup#

-
-
-
# Import libraries
-import pandas as pd
-import pooch
-import os
-import tempfile
-import pyleoclim as pyleo
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # Import libraries
-----> 2 import pandas as pd
-      3 import pooch
-      4 import os
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Exploring past variations in atmospheric CO2#

-

As we learned in the video, paleoclimatologists can reconstruct past changes in atmospheric composition by measuring gases trapped in layers of ice from ice cores retrieved from polar regions and high elevation mountain glaciers. We’ll specifically be focusing on paleoclimate records produced from the EPICA Dome C ice core from Antarctica.

-

-

Credit: Conway et al 2015, Nature Communications

-

Let’s start by downloading the data for the composite CO2 record for EPICA Dome C in Antarctica:

-
-
-
# donwload the data using the url
-filename_antarctica2015 = "antarctica2015co2composite.txt"
-url_antarctica2015 = "https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/antarctica2015co2composite.txt"
-
-data_path = pooch_load(
-    filelocation=url_antarctica2015, filename=filename_antarctica2015
-)  # open the file
-
-co2df = pd.read_csv(data_path, skiprows=137, sep="\t")
-
-co2df.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 5
-      2 filename_antarctica2015 = "antarctica2015co2composite.txt"
-      3 url_antarctica2015 = "https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/antarctica2015co2composite.txt"
-----> 5 data_path = pooch_load(
-      6     filelocation=url_antarctica2015, filename=filename_antarctica2015
-      7 )  # open the file
-      9 co2df = pd.read_csv(data_path, skiprows=137, sep="\t")
-     11 co2df.head()
-
-Cell In[3], line 6, in pooch_load(filelocation, filename, processor)
-      4 def pooch_load(filelocation=None, filename=None, processor=None):
-      5     shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-----> 6     user_temp_cache = tempfile.gettempdir()
-      8     if os.path.exists(os.path.join(shared_location, filename)):
-      9         file = os.path.join(shared_location, filename)
-
-NameError: name 'tempfile' is not defined
-
-
-
-
-

Next, we can store this data as a Series in Pyleoclim:

-
-
-
ts_co2 = pyleo.Series(
-    time=co2df["age_gas_calBP"] / 1000,
-    value=co2df["co2_ppm"],
-    time_name="Age",
-    time_unit="kyr BP",
-    value_name=r"$CO_2$",
-    value_unit="ppm",
-    label="EPICA Dome C CO2",
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 1
-----> 1 ts_co2 = pyleo.Series(
-      2     time=co2df["age_gas_calBP"] / 1000,
-      3     value=co2df["co2_ppm"],
-      4     time_name="Age",
-      5     time_unit="kyr BP",
-      6     value_name=r"$CO_2$",
-      7     value_unit="ppm",
-      8     label="EPICA Dome C CO2",
-      9 )
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-

We can now plot age vs. CO2 from EPICA Dome C:

-
-
-
ts_co2.plot(color="C1")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 ts_co2.plot(color="C1")
-
-NameError: name 'ts_co2' is not defined
-
-
-
-
-

Notice that the x-axis is plotted with present-day (0 kyr) on the left and the past (800 kyr) on the right. This is a common practice when plotting paleoclimate time series data.

-

These changes in CO2 are tracking glacial-interglacial cycles (Ice Ages) over the past 800,000 years. Recall that these Ice Ages occur as a result of changes in the orbital cycles of Earth: eccentricity (100,000 year cycle), obliquity (40,000 year cycle) and precession (21,000 year cycle). Can you observe them in the graph above?

-
-
-

Section 2: Exploring the relationship between δD and atmospheric CO2#

-

To investigate the relationship between glacial cycles, atmospheric CO2 and temperature, we can compare CO2 to a record of hydrogen isotopic values (δD) of ice cores, which is a proxy for temperature in this case. Remember, when interpreting isotopic measurements of ice cores, a more depleted δD value indicates cooler temperatures, and a more enriched δD value indicates warmer temperatures. This is the opposite relationship we have looked at previously with δ18O, not because we are looking at a different isotope, but because we are not looking at the isotopic composition of ice rather than the isotopic composition of the ocean.

-

Let’s download the EPICA Dome C δD data, store it as a Series, and plot the data:

-
-
-
# donwload the data using the url
-filename_edc3deuttemp2007 = "edc3deuttemp2007.txt"
-url_edc3deuttemp2007 = "https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/epica_domec/edc3deuttemp2007.txt"
-data_path = pooch_load(
-    filelocation=url_edc3deuttemp2007, filename=filename_edc3deuttemp2007
-)  # open the file
-
-dDdf = pd.read_csv(data_path, skiprows=91, encoding="unicode_escape", sep="\s+")
-# remove nan values
-dDdf.dropna(inplace=True)
-
-dDdf.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 4
-      2 filename_edc3deuttemp2007 = "edc3deuttemp2007.txt"
-      3 url_edc3deuttemp2007 = "https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/epica_domec/edc3deuttemp2007.txt"
-----> 4 data_path = pooch_load(
-      5     filelocation=url_edc3deuttemp2007, filename=filename_edc3deuttemp2007
-      6 )  # open the file
-      8 dDdf = pd.read_csv(data_path, skiprows=91, encoding="unicode_escape", sep="\s+")
-      9 # remove nan values
-
-Cell In[3], line 6, in pooch_load(filelocation, filename, processor)
-      4 def pooch_load(filelocation=None, filename=None, processor=None):
-      5     shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-----> 6     user_temp_cache = tempfile.gettempdir()
-      8     if os.path.exists(os.path.join(shared_location, filename)):
-      9         file = os.path.join(shared_location, filename)
-
-NameError: name 'tempfile' is not defined
-
-
-
-
-
-
-
dDts = pyleo.Series(
-    time=dDdf["Age"] / 1000,
-    value=dDdf["Deuterium"],
-    time_name="Age",
-    time_unit="kyr BP",
-    value_name=r"$\delta D$",
-    value_unit="\u2030",
-    label=r"EPICA Dome C $\delta D$",
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 dDts = pyleo.Series(
-      2     time=dDdf["Age"] / 1000,
-      3     value=dDdf["Deuterium"],
-      4     time_name="Age",
-      5     time_unit="kyr BP",
-      6     value_name=r"$\delta D$",
-      7     value_unit="\u2030",
-      8     label=r"EPICA Dome C $\delta D$",
-      9 )
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-
-
-
dDts.plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 1
-----> 1 dDts.plot()
-
-NameError: name 'dDts' is not defined
-
-
-
-
-

When we observe the δD data, we see very similar patterns as in the atmospheric CO2 data. To more easily compare the two records, we can plot the two series side by side by putting them into a MultipleSeries object. Since the δD and CO2 values have different units, we can first standardize the series and then plot the data.

-
-
-
# combine series
-ms = pyleo.MultipleSeries([dDts, ts_co2])
-
-# standarize series and plot
-ms.standardize().plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # combine series
-----> 2 ms = pyleo.MultipleSeries([dDts, ts_co2])
-      4 # standarize series and plot
-      5 ms.standardize().plot()
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-

Now we can more easily compare the timing and magnitude of changes in CO2 and δD at EPICA Dome C over the past 800,000 years. During glacial periods, δD was more depleted (cooler temperatures) and atmospheric CO2 was lower. During interglacial periods, δD was more enriched (warmer temperatures) and atmospheric CO2 was higher.

-
-
-

Questions 2: Climate Connection#

-
    -
  1. Why do δD, CO2 and glacial cycles covary so closely?

  2. -
  3. Can you identify glacial and interglacial periods? Today, are we in an interglacial or glacial period?

  4. -
  5. Do the cooling and warming periods of the cycles happen at the same rate?

  6. -
  7. What climate forcings do you think are driving these cycles?

  8. -
-

Click for solution

-
-
-

Summary#

-

In this tutorial, we dove into the captivating world of paleoclimatology, focusing on the analysis of hydrogen isotopes (δD) and atmospheric CO2 data from the EPICA Dome C ice core. This involved understanding how δD and δ18O measurements from ice cores can enlighten us about past temperature changes, and how trapped CO2 in these ice cores can help us reconstruct shifts in Earth’s atmospheric composition.

-

By the end of the tutorial, you should be comfortable with plotting δD and CO2 records from the EPICA Dome C ice core and assessing changes in temperature and atmospheric greenhouse gas concentrations over the past 800,000 years. In the next tutorial, we’ll introduce various paleoclimate data analysis tools.

-
-
-

Resources#

-

Code for this tutorial is based on an existing notebook from LinkedEarth that explores EPICA Dome C paleoclimate records.

-

Data from the following sources are used in this tutorial:

- -
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.html deleted file mode 100644 index 10d4f3460..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial5.html +++ /dev/null @@ -1,1900 +0,0 @@ - - - - - - - - - - - - Tutorial 5: Paleoclimate Data Analysis Tools — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 5: Paleoclimate Data Analysis Tools#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will explore various computational analyses for interpreting paleoclimate data and understand why these methods are useful. A common issue in paleoclimate is the presence of uneven time spacing between consecutive observations. Pyleoclim includes several methods that can deal with uneven sampling effectively, but there are certain applications and analyses for which it’s ncessary to place the records on a uniform time axis. In this tutorial you’ll learn a few ways to do this with Pyleoclim. Additionally, we will explore another useful paleoclimate data analysis tool, Principal Component Analysis (PCA), which allows us to identify a common signal between various paleoclimate reconstructions.

-

By the end of this tutorial you’ll be able to perform the following data analysis techniques on proxy-based climate reconstructions:

-
    -
  • Interpolation

  • -
  • Binning

  • -
  • Principal component analysis

  • -
-
-
-

Setup#

-
-
-
# imports
-import pandas as pd
-import cartopy
-import pyleoclim as pyleo
-import matplotlib.pyplot as plt
-import pooch
-import os
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import pandas as pd
-      3 import cartopy
-      4 import pyleoclim as pyleo
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Load the sample dataset for analysis#

-

For this tutorial, we are going to use an example dataset to practice the various data analysis techniques. The dataset we’ll be using is a record of hydrogen isotopes of leaf waxes (δDwax) from Lake Tanganyika in East Africa (Tierney et al., 2008). Recall from the video that δDwax is a proxy that is typically thought to record changes in the amount of precipitation in the tropics via the amount effect. In the previous tutorial, we looked at δD data from high-latitude ice cores. In that case, δD was a proxy for temperature, but in the tropics, δD more commonly reflects rainfall amount, as explained in the introductory video.

-

Let’s first read the data from a .csv file.

-
-
-
filename_tang = "tanganyika_dD.csv"
-url_tang = "https://osf.io/sujvp/download/"
-tang_dD = pd.read_csv(pooch_load(filelocation=url_tang, filename=filename_tang))
-tang_dD.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 3
-      1 filename_tang = "tanganyika_dD.csv"
-      2 url_tang = "https://osf.io/sujvp/download/"
-----> 3 tang_dD = pd.read_csv(pooch_load(filelocation=url_tang, filename=filename_tang))
-      4 tang_dD.head()
-
-NameError: name 'pd' is not defined
-
-
-
-
-

We can now create a Series in Pyleoclim and assign names to different variables so that we can easily plot the data.

-
-
-
ts_tang = pyleo.Series(
-    time=tang_dD["Age"],
-    value=tang_dD["dD_IVonly"],
-    time_name="Age",
-    time_unit="yr BP",
-    value_name="dDwax",
-    value_unit="per mille",
-    label="Lake Tanganyika dDprecip",
-)
-
-ts_tang.plot(color="C1", invert_yaxis=True)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 1
-----> 1 ts_tang = pyleo.Series(
-      2     time=tang_dD["Age"],
-      3     value=tang_dD["dD_IVonly"],
-      4     time_name="Age",
-      5     time_unit="yr BP",
-      6     value_name="dDwax",
-      7     value_unit="per mille",
-      8     label="Lake Tanganyika dDprecip",
-      9 )
-     11 ts_tang.plot(color="C1", invert_yaxis=True)
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-

You may notice that the y-axis is inverted. When we’re plotting δD data, we typically invert the y-axis because more negative (“depleted”) values suggest increased rainfall, whereas more positive (“enriched”) values suggest decreased rainfall.

-
-
-

Section 2: Uniform Time-Sampling of the Data#

-

There are a number of different reasons we might want to assign new values to our data. For example, if the data is not evenly spaced, we might need to resample in order to use a sepcific data analysis technique or to more easily compare to other data of a different sampling resolution.

-

First, let’s check whether our data is already evenly spaced using the .is_evenly_spaced() method:

-
-
-
ts_tang.is_evenly_spaced()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 ts_tang.is_evenly_spaced()
-
-NameError: name 'ts_tang' is not defined
-
-
-
-
-

Our data is not evenly spaced. There are a few different methods available in pyleoclim to place the data on a uniform axis, and in this tutorial, we’ll explore two methods: interpolating and binning. In general, these methods use the available data near a chosen time to estimate what the value was at that time, but each method differs in which nearby data points it uses and how it uses them.

-
-

Section 2.1: Interpolation#

-

To start out, let’s try using interpolation to evenly space our data. Interpolation projects the data onto an evenly spaced time axis with a distance between points (step size) of our choosing. There are a variety of different methods by which the data can be interpolated, these being: linear, nearest, zero, slinear, quadratic, cubic, previous, and next. More on these and their associated key word arguments can be found in the documentation. By default, the function .interp() implements linear interpolation:

-
-
-
tang_linear = ts_tang.interp()  # default method = 'linear'
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 tang_linear = ts_tang.interp()  # default method = 'linear'
-
-NameError: name 'ts_tang' is not defined
-
-
-
-
-
-
-
# check whether or not the series is now evenly spaced
-tang_linear.is_evenly_spaced()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # check whether or not the series is now evenly spaced
-----> 2 tang_linear.is_evenly_spaced()
-
-NameError: name 'tang_linear' is not defined
-
-
-
-
-

Now that we’ve interpolated our data, let’s compare the original dataset to the linearly interpolated dataset we just created.

-
-
-
fig, ax = plt.subplots()  # assign a new plot axis
-ts_tang.plot(ax=ax, label="Original", invert_yaxis=True)
-tang_linear.plot(ax=ax, label="Linear")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 1
-----> 1 fig, ax = plt.subplots()  # assign a new plot axis
-      2 ts_tang.plot(ax=ax, label="Original", invert_yaxis=True)
-      3 tang_linear.plot(ax=ax, label="Linear")
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Notice there are only some minor differences between the original and linearly interpolated data.

-

You can print the data in the original and interpolated time series to see the difference in the ages between the two datasets. The interpolated dataset is now evenly spaced with a δD value every ~290 years.

-
-
-
ts_tang
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 1
-----> 1 ts_tang
-
-NameError: name 'ts_tang' is not defined
-
-
-
-
-
-
-
tang_linear
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 tang_linear
-
-NameError: name 'tang_linear' is not defined
-
-
-
-
-

Let’s compare a few of the different interpolation methods (e.g., quadratic, next, zero) with one another just to see how they are similar and different:

-
-
-
fig, ax = plt.subplots()  # assign a new plot axis
-ts_tang.plot(ax=ax, label="original", invert_yaxis=True)
-for method in ["linear", "quadratic", "next", "zero"]:
-    ts_tang.interp(method=method).plot(
-        ax=ax, label=method, alpha=0.9
-    )  # plot all the method we want
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 1
-----> 1 fig, ax = plt.subplots()  # assign a new plot axis
-      2 ts_tang.plot(ax=ax, label="original", invert_yaxis=True)
-      3 for method in ["linear", "quadratic", "next", "zero"]:
-
-NameError: name 'plt' is not defined
-
-
-
-
-

The methods can produce slightly different results, but mostly reproduce the same overall trend. In this case, the quadractic method may be less appropriate than the other methods.

-
-
-

Section 2.2: Binning#

-

Another option for resampling our data onto a uniform time axis is binning. Binning is when a set of time intervals is defined and data is grouped or binned with other data in the same interval, then all those points in a “bin” are averaged to get a data value for that bin. The defaults for binning pick a bin size at the coarsest time spacing present in the dataset and average data over a uniform sequence of such intervals.

-
-
-
tang_bin = (
-    ts_tang.bin()
-)  # default settings pick the coarsest time spacing in the data as the binning period
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 tang_bin = (
-----> 2     ts_tang.bin()
-      3 )  # default settings pick the coarsest time spacing in the data as the binning period
-
-NameError: name 'ts_tang' is not defined
-
-
-
-
-
-
-
fig, ax = plt.subplots()  # assign a new plot axis
-ts_tang.plot(ax=ax, label="Original", invert_yaxis=True)
-tang_bin.plot(ax=ax, label="Binned")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 1
-----> 1 fig, ax = plt.subplots()  # assign a new plot axis
-      2 ts_tang.plot(ax=ax, label="Original", invert_yaxis=True)
-      3 tang_bin.plot(ax=ax, label="Binned")
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Again, notice that although there are some minor differences between the original and binned data, the records still capture the same overall trend.

-
-
-

Coding Exercises 2.2#

-
    -
  1. Experiment with different bin sizes to see how this affects the resampling. You can do so by adding bin_size = to ts_tang.bin(). Try a bin size of 500 years and 1,000 years and plot both of them on the same graph as the original data and the binned data using the default bin size.

  2. -
-
-
-
# bin size of 500
-tang_bin_500 = ...
-
-# bin size of 1000
-tang_bin_1000 = ...
-
-# plot
-fig, ax = plt.subplots()  # assign a new plot axis
-_ = ...
-_ = ...
-_ = ...
-_ = ...
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[15], line 8
-      5 tang_bin_1000 = ...
-      7 # plot
-----> 8 fig, ax = plt.subplots()  # assign a new plot axis
-      9 _ = ...
-     10 _ = ...
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-

Section 3: Principal Component Analysis (PCA)#

-

Large datasets, such as global climate datasets, are often difficult to interpret due to their multiple dimensions. Although tools such as Xarray help us to organize large, multidimensional climate datasets, it can still sometimes be difficult to interpret certain aspects of such data. Principal Component Analysis (PCA) is a tool for reducing the dimensionality of such datasets and increasing interpretability with minimal modification or loss of data. In other words, PCA allows us to reduce the number of variables of a dataset, while preserving as much information as possible.

-

The first step in PCA is to calculate a matrix that summarizes how the variables in a dataset all relate to one another. This matrix is then broken down into new uncorrelated variables that are linear combinations or mixtures of the initial variables. These new variables are the principal components. The initial dimensions of the dataset determines the number of principal components calculated. Most of the information within the initial variables is compressed into the first components. Additional details about PCA and the calculations involved can be found here.

-

Applied to paleoclimate, PCA can reduce the dimensionality of large paleoclimate datasets with multiple variables and can help us identify a common signal between various paleoclimate reconstructions. An example of a study that applies PCA to paleoclimate is Otto-Bliesner et al., 2014. This study applies PCA to rainfall reconstructions from models and proxies from throughout Africa to determine common climate signals in these reconstructions.

-

In this section, we will calculate the PCA of four δD paleoclimate records from Africa to assess common climate signals in the four records. In order to calculate the PCA of multiple paleoclimate time series, all of the records need to be on a common time-step. To do so, we can apply the resampling tools we’ve learned in this tutorial.

-

So far, we’ve been looking at δD data from Lake Tanganyika in tropical East Africa. Let’s compare this δD record to other existing δD records from lake and marine sediment cores in tropical Africa from the Gulf of Aden (Tierney and deMenocal, 2017), Lake Bosumtwi (Shanahan et al., 2015), and the West African Margin (Tierney et al., 2017).

-

First, let’s load these datasets:

-
-
-
# Gulf of Aden
-filename_aden = "aden_dD.csv"
-url_aden = "https://osf.io/gm2v9/download/"
-aden_dD = pd.read_csv(pooch_load(filelocation=url_aden, filename=filename_aden))
-aden_dD.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 4
-      2 filename_aden = "aden_dD.csv"
-      3 url_aden = "https://osf.io/gm2v9/download/"
-----> 4 aden_dD = pd.read_csv(pooch_load(filelocation=url_aden, filename=filename_aden))
-      5 aden_dD.head()
-
-NameError: name 'pd' is not defined
-
-
-
-
-
-
-
# Lake Bosumtwi
-filename_Bosumtwi = "bosumtwi_dD.csv"
-url_Bosumtwi = "https://osf.io/mr7d9/download/"
-bosumtwi_dD = pd.read_csv(
-    pooch_load(filelocation=url_Bosumtwi, filename=filename_Bosumtwi)
-)
-bosumtwi_dD.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 4
-      2 filename_Bosumtwi = "bosumtwi_dD.csv"
-      3 url_Bosumtwi = "https://osf.io/mr7d9/download/"
-----> 4 bosumtwi_dD = pd.read_csv(
-      5     pooch_load(filelocation=url_Bosumtwi, filename=filename_Bosumtwi)
-      6 )
-      7 bosumtwi_dD.head()
-
-NameError: name 'pd' is not defined
-
-
-
-
-
-
-
# GC27 (West African Margin)
-filename_GC27 = "gc27_dD.csv"
-url_GC27 = "https://osf.io/k6e3a/download/"
-gc27_dD = pd.read_csv(pooch_load(filelocation=url_GC27, filename=filename_GC27))
-gc27_dD.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[18], line 4
-      2 filename_GC27 = "gc27_dD.csv"
-      3 url_GC27 = "https://osf.io/k6e3a/download/"
-----> 4 gc27_dD = pd.read_csv(pooch_load(filelocation=url_GC27, filename=filename_GC27))
-      5 gc27_dD.head()
-
-NameError: name 'pd' is not defined
-
-
-
-
-

Next, let’s convert each dataset into a Series in Pyleoclim.

-
-
-
ts_tanganyika = pyleo.Series(
-    time=tang_dD["Age"],
-    value=tang_dD["dD_IVonly"],
-    time_name="Age",
-    time_unit="yr BP",
-    value_name="dDwax",
-    label="Lake Tanganyika",
-)
-ts_aden = pyleo.Series(
-    time=aden_dD["age_calBP"],
-    value=aden_dD["dDwaxIVcorr"],
-    time_name="Age",
-    time_unit="yr BP",
-    value_name="dDwax",
-    label="Gulf of Aden",
-)
-ts_bosumtwi = pyleo.Series(
-    time=bosumtwi_dD["age_calBP"],
-    value=bosumtwi_dD["d2HleafwaxC31ivc"],
-    time_name="Age",
-    time_unit="yr BP",
-    value_name="dDwax",
-    label="Lake Bosumtwi",
-)
-ts_gc27 = pyleo.Series(
-    time=gc27_dD["age_BP"],
-    value=gc27_dD["dDwax_iv"],
-    time_name="Age",
-    time_unit="yr BP",
-    value_name="dDwax",
-    label="GC27",
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[19], line 1
-----> 1 ts_tanganyika = pyleo.Series(
-      2     time=tang_dD["Age"],
-      3     value=tang_dD["dD_IVonly"],
-      4     time_name="Age",
-      5     time_unit="yr BP",
-      6     value_name="dDwax",
-      7     label="Lake Tanganyika",
-      8 )
-      9 ts_aden = pyleo.Series(
-     10     time=aden_dD["age_calBP"],
-     11     value=aden_dD["dDwaxIVcorr"],
-   (...)
-     15     label="Gulf of Aden",
-     16 )
-     17 ts_bosumtwi = pyleo.Series(
-     18     time=bosumtwi_dD["age_calBP"],
-     19     value=bosumtwi_dD["d2HleafwaxC31ivc"],
-   (...)
-     23     label="Lake Bosumtwi",
-     24 )
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-

Now let’s set up a MultipleSeries using Pyleoclim with all four δD datasets.

-
-
-
ts_list = [ts_tanganyika, ts_aden, ts_bosumtwi, ts_gc27]
-ms_africa = pyleo.MultipleSeries(ts_list, label="African dDwax")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[20], line 1
-----> 1 ts_list = [ts_tanganyika, ts_aden, ts_bosumtwi, ts_gc27]
-      2 ms_africa = pyleo.MultipleSeries(ts_list, label="African dDwax")
-
-NameError: name 'ts_tanganyika' is not defined
-
-
-
-
-

We can now create a stackplot with all four δD records:

-
-
-
fig, ax = ms_africa.stackplot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[21], line 1
-----> 1 fig, ax = ms_africa.stackplot()
-
-NameError: name 'ms_africa' is not defined
-
-
-
-
-

By creating a stackplot, we can visually compare between the datasets. However, the four δD records aren’t the same resolution and don’t span the same time interval.

-

To better compare the records and assess a common trend, we can use PCA. First, we can use [.common_time()] to place the records on a shared time axis with a common sampling frequency. This function takes the argument method, which can be either bin, interp, and gdkernel. The binning and interpolation methods are what we just covered in the previous section. Let’s set the time step to 500 years, the method to interp, and standarize the data:

-
-
-
africa_ct = ms_africa.common_time(method="interp", step=0.5).standardize()
-fig, ax = africa_ct.stackplot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[22], line 1
-----> 1 africa_ct = ms_africa.common_time(method="interp", step=0.5).standardize()
-      2 fig, ax = africa_ct.stackplot()
-
-NameError: name 'ms_africa' is not defined
-
-
-
-
-

We now have standardized δD records that are the same sampling resolution and span the same time interval. Note this meant trimming the longer time series down to around 20,000 years in length.

-

We can now apply PCA which will allow us to quantitatively identify a common signal between the four δD paleoclimate reconstructions through the .pca method. Note that this line of code may take a few minutes to run.

-
-
-
africa_PCA = africa_ct.pca()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[23], line 1
-----> 1 africa_PCA = africa_ct.pca()
-
-NameError: name 'africa_ct' is not defined
-
-
-
-
-

The result is an object containing multiple outputs, and with two plotting methods attached to it. The two outputs we’ll look at are pctvar (the variance) and pcs (the principal components).

-

First, let’s print the percentage of variance accounted for by each mode, which is saved as pctvar:

-
-
-
print(africa_PCA.pctvar.round())
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[24], line 1
-----> 1 print(africa_PCA.pctvar.round())
-
-NameError: name 'africa_PCA' is not defined
-
-
-
-
-

This means that 97% of the variance in the four paleoclimate records is explained by the first principal component. The number of datasets in the PCA constrains the number of principal components that can be defined, which is why we only have four components in this example.

-

We can now look at the principal component of the first mode of variance. Let’s create a new series for the first mode of variance and plot it against the original datasets:

-
-
-
africa_pc1 = africa_PCA.pcs
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[25], line 1
-----> 1 africa_pc1 = africa_PCA.pcs
-
-NameError: name 'africa_PCA' is not defined
-
-
-
-
-
-
-
africa_mode1 = pyleo.Series(
-    time=africa_ct.series_list[0].time,
-    value=africa_PCA.pcs[:, 0],
-    label=r"$PC_1$",
-    value_name="PC1",
-    time_name="age",
-    time_unit="yr BP",
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[26], line 1
-----> 1 africa_mode1 = pyleo.Series(
-      2     time=africa_ct.series_list[0].time,
-      3     value=africa_PCA.pcs[:, 0],
-      4     label=r"$PC_1$",
-      5     value_name="PC1",
-      6     time_name="age",
-      7     time_unit="yr BP",
-      8 )
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-
-
-
fig, ax1 = plt.subplots()
-
-ax1.set_ylabel("dDwax")
-ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
-ax2.set_ylabel("PC1")  # we already handled the x-label with ax1
-
-# plt.plot(mode1.time,pc1_scaled)
-africa_mode1.plot(color="black", ax=ax2, invert_yaxis=True)
-africa_ct.plot(ax=ax1, linewidth=0.5)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[27], line 1
-----> 1 fig, ax1 = plt.subplots()
-      3 ax1.set_ylabel("dDwax")
-      4 ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
-
-NameError: name 'plt' is not defined
-
-
-
-
-

The original δD records are shown in the colored lines, and the first principal component (PC1) time series is shown in black.

-
-

Questions 3: Climate Connection#

-
    -
  1. How do the original time series compare to the PC1 time series? Do they record similar trends?

  2. -
  3. Which original δD record most closely resembles the PC1 time series? Which is the most different?

  4. -
  5. What changes in climate does the PC1 time series record over the past 20,000 years? Hint: remember that more depleted (more negative) δD suggests increased rainfall.

  6. -
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, you explored a variety of computational techniques for analyzing paleoclimate data. You learned how to handle irregular data and place these records on a uniform time axis using interpolation and binning.

-

You then explored Principal Component Analysis (PCA), a method that reveals common signals across various paleoclimate reconstructions. To effectively utilize PCA, it’s essential to have all records on the same sampling resolution and same time-step, which can be achieved using the resampling tools you learned in this tutorial.

-

For your practical example, we used a dataset of hydrogen isotopes of leaf waxes (δDwax) from Lake Tanganyika in East Africa to further enhance your understanding of the discussed techniques, equipping you to better analyze and understand the complexities of paleoclimate data.

-
-
-

Resources#

-

Code for this tutorial is based on existing notebooks from LinkedEarth for anlayzing LiPD datasets and resampling data with Pyleoclim.

-

Data from the following sources are used in this tutorial:

- -
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.html deleted file mode 100644 index 77505204c..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial6.html +++ /dev/null @@ -1,1569 +0,0 @@ - - - - - - - - - - - - Tutorial 6: Spectral Analysis of Paleoclimate Data — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 6: Spectral Analysis of Paleoclimate Data#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will manipulate paleoclimate proxy datasets using previously learned computational tools, and apply spectral analysis to further interpret the data.

-

By the end of this tutorial you will be able to:

-
    -
  • Interpret the LR04 benthic δ18O curve and how it records temperature

  • -
  • Perform various spectral analysis methods to assess dominant spectral powers in the LR04 data

  • -
  • Interpret variations in glacial-interglacial cycles recorded by the LR04 δ18O record

  • -
-
-
-

Setup#

-
-
-
# imports
-import pooch
-import os
-import tempfile
-import pandas as pd
-import numpy as np
-import matplotlib.pyplot as plt
-
-import cartopy
-import pyleoclim as pyleo
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import pooch
-      3 import os
-      4 import tempfile
-
-ModuleNotFoundError: No module named 'pooch'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Plotting the LR04 δ18O benthic stack#

-

We will be analyzing a δ18O data from Lisiecki, L. E., and Raymo, M. E. (2005), a stack of 57 globally distributed records of δ18O from benthic foraminifera that spans the past ~5 million years. As we learned from the introductory video, δ18O of foraminifera records temperature due to differences in the isotopic composition of the ocean during glacial and interglacial periods. The δ18O of the ocean (and forams) is more depleted (takes on a smaller values) during interglacials and more enriched (takes on a larger value) during glacials.

-

Let’s start by importing the data:

-
-
-
# Donwload the data
-filename_LR04 = "LR04.csv"
-url_LR04 = (
-    "https://raw.githubusercontent.com/LinkedEarth/PyleoTutorials/main/data/LR04.csv"
-)
-lr04_data = pd.read_csv(
-    pooch_load(filelocation=url_LR04, filename=filename_LR04), skiprows=4
-)
-lr04_data.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 6
-      2 filename_LR04 = "LR04.csv"
-      3 url_LR04 = (
-      4     "https://raw.githubusercontent.com/LinkedEarth/PyleoTutorials/main/data/LR04.csv"
-      5 )
-----> 6 lr04_data = pd.read_csv(
-      7     pooch_load(filelocation=url_LR04, filename=filename_LR04), skiprows=4
-      8 )
-      9 lr04_data.head()
-
-NameError: name 'pd' is not defined
-
-
-
-
-

We can now create a Series object containing the data:

-
-
-
ts_lr04 = pyleo.Series(
-    time=lr04_data["Time (ka)"],
-    value=lr04_data["Benthic d18O (per mil)  "],
-    time_name="Age",
-    time_unit="kyr BP",
-    value_name="Benthic d18O (per mil)",
-    value_unit="\u2030",
-    label="LR04",
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 1
-----> 1 ts_lr04 = pyleo.Series(
-      2     time=lr04_data["Time (ka)"],
-      3     value=lr04_data["Benthic d18O (per mil)  "],
-      4     time_name="Age",
-      5     time_unit="kyr BP",
-      6     value_name="Benthic d18O (per mil)",
-      7     value_unit="\u2030",
-      8     label="LR04",
-      9 )
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-

This record spans the past ~5 million years (5,000 kyr), but we’re going to focus in on the past 1 million years (1,000 kyr), so let’s create a time slice of just this time period, and plot the time series.

-
-
-
lr04_slice = ts_lr04.slice([0, 1000])
-fig, ax = plt.subplots()  # assign a new plot axis
-lr04_slice.plot(ax=ax, legend=False, invert_yaxis=True)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 lr04_slice = ts_lr04.slice([0, 1000])
-      2 fig, ax = plt.subplots()  # assign a new plot axis
-      3 lr04_slice.plot(ax=ax, legend=False, invert_yaxis=True)
-
-NameError: name 'ts_lr04' is not defined
-
-
-
-
-
-
-

Questions 2#

-
    -
  1. What patterns do you observe in the record?

  2. -
  3. Does the amplitude of the glacial-interglacial cycles vary over time?

  4. -
  5. At what frequency do these glacial-interglacial cycles occur?

  6. -
-

Click for solution

-
-
-

Section 2: Spectral analysis of the LRO4 δ18O benthic stack#

-

To better assess the dominant temporal patterns in this record, you can use spectral analysis. As you learned in the introductory video, spectral analysis is a useful data analysis tool in paleoclimate because it allows us to discover underlying periodicities in time series data and can help establish quantitative relationships between forcings and climate variations.

-

Let’s explore various spectral analysis methods and apply them to the LR04 record to interpret changes in the frequency of glacial-interglacial cycles.

-
-

Section 2.1: Spectral Density#

-

Pyleoclim enables five methods to estimate the spectral density, which will be our main interest in this tutorial:

-
    -
  • Basic Periodogram, which uses a Fourier transform. The method has various windowing available to reduce variance.

  • -
  • Welch’s periodogram, a variant of the basic periodogram, which uses Welch’s method of overlapping segments. The periodogram is computed on each segment and averaged together.

  • -
  • Multi-taper method (MTM), which attempts to reduce the variance of spectral estimates by using a small set of tapers rather than the unique data taper or spectral window.

  • -
  • Lomb-Scargle periodogram, an inverse approach designed for unevenly-spaced datasets. Several windows are available and Welch’s segmentation can also be used with this method.

  • -
  • Weighted wavelet Z-transform (WWZ), a wavelet-based method also made for unevenly-spaced datasets.

  • -
-

All of these methods are available through Series.spectral() by changing the method argument. In this tutorial, we’ll focus on Lomb-Scargle and Weighted wavelet Z-transform in more detail. For additional information on the other methods, refer to this notebook from Pyleoclim.

-

To get a sense of how the estimates of the spectral density using each of these methods compare, we can plot them on the same graph below. Note we must first interpolate to an even grid and then standardize before estimating the spectral density.

-
-
-
fig, ax = plt.subplots()
-
-# basic periodogram
-lr04_slice.interp(step=0.5).standardize().spectral(method="periodogram").plot(
-    ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label="periodogram"
-)
-# Welch's periodogram
-lr04_slice.interp(step=0.5).standardize().spectral(method="welch").plot(
-    ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label="welch"
-)
-# Multi-taper Method
-lr04_slice.interp(step=0.5).standardize().spectral(method="mtm").plot(
-    ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label="mtm"
-)
-# Lomb-Scargle periodogram
-lr04_slice.interp(step=0.5).standardize().spectral(method="lomb_scargle").plot(
-    ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label="lomb_scargle"
-)
-# weighted wavelet Z-transform (WWZ)
-lr04_slice.interp(step=0.5).standardize().spectral(method="wwz").plot(
-    ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label="wwz"
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 fig, ax = plt.subplots()
-      3 # basic periodogram
-      4 lr04_slice.interp(step=0.5).standardize().spectral(method="periodogram").plot(
-      5     ax=ax, xlim=[1000, 5], ylim=[0.001, 1000], label="periodogram"
-      6 )
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Which method should you choose? The Lomb-Scargle periodogram is the default method in Pyleoclim, and is a good choice for many applications because: (1) it works with unevenly-spaced timeseries which are often encountered in paleoclimate data, (2) it seems to give consistent results over parameter ranges, (3) doesn’t require interpolation, limiting timeseries manipulation, and (4) it is fairly fast to compute. We will choose this estimate to analyze.

-
-
-
# Lomb-Scargle periodogram
-lr04_ls_sd = lr04_slice.interp(step=0.5).standardize().spectral(method="lomb_scargle")
-
-lr04_ls_sd.plot(xlim=[1000, 5], ylim=[0.001, 1000], label="lomb_scargle")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # Lomb-Scargle periodogram
-----> 2 lr04_ls_sd = lr04_slice.interp(step=0.5).standardize().spectral(method="lomb_scargle")
-      4 lr04_ls_sd.plot(xlim=[1000, 5], ylim=[0.001, 1000], label="lomb_scargle")
-
-NameError: name 'lr04_slice' is not defined
-
-
-
-
-
-
-
-

Section 2.2: Significance Testing#

-

Note that there are few peaks that seem more dominant than others, but which of these peaks are significant? That is, do they stand out more than peaks would from a random time series? To figure that out, we can use the method signif_test. Pyleoclim generates many surrogates of the time series using an AR(1) (Autoregressive Process of order 1 - i.e. a random process). These surrogates serve to identify the probability of a peak not just being from random noise and the likelihood that the peak of the same magnitude would be unlikely to be present in a random dataset. The default number of surrogates generated is 200, and the larger this value, the more smooth and precise our results are.

-
-
-
lr04_ls_sd_sig = lr04_ls_sd.signif_test()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 1
-----> 1 lr04_ls_sd_sig = lr04_ls_sd.signif_test()
-
-NameError: name 'lr04_ls_sd' is not defined
-
-
-
-
-
-
-
lr04_ls_sd_sig.plot(xlabel="Period [kyrs]")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 1
-----> 1 lr04_ls_sd_sig.plot(xlabel="Period [kyrs]")
-
-NameError: name 'lr04_ls_sd_sig' is not defined
-
-
-
-
-

The variable lr04_ls_sd_sig PSD object contains the significant frequencies of the significant peaks from the spectral density of the LR04 data. We can now create the same plot of spectral power, but with only the significant peaks.

-

NOTE: For this figure, we will plot the x-axis a bit differently. In the previous plot, the x-axis was the “period” but this time the x-axis will be “frequency”, which is the inverse of the period.

-
-
-
fig, ax = plt.subplots()
-ax.plot(lr04_ls_sd_sig.frequency, lr04_ls_sd_sig.amplitude)
-ax.set_xlim([0.005, 0.07])
-ax.set_ylim([0, 200])
-ax.set_xlabel("Frequency [1/kyr]")
-ax.set_ylabel("Spectra Amplitude")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 fig, ax = plt.subplots()
-      2 ax.plot(lr04_ls_sd_sig.frequency, lr04_ls_sd_sig.amplitude)
-      3 ax.set_xlim([0.005, 0.07])
-
-NameError: name 'plt' is not defined
-
-
-
-
-

The largest spectral powers in the data occur at a frequencies of ~0.01 and ~0.025, as well as a smaller peak at ~0.042, which correspond to 100 kyr, 40 kyr, and 23 kyr, respectively. Do those periodicities sound familiar?

-

These are the cycles of eccentricity, obliquity and precession. The presence of spectral powers in the LR04 data at the eccentricity, obliquity and precession frequencies highlights the influence of orbital forcings on glacial-interglacial cycles.

-
-

Section 2.3: Wavelet Analysis#

-

Another related tool we can use to learn more about the climate variability recorded in the data is wavelet analysis. This method allows us to “unfold” a spectrum and look at its evolution over time. In other words, wavelet analysis can help us determine changes in the spectral power over time. For additional details about wavelet analysis, refer to this guide.

-

There are several ways to access this functionality in Pyleoclim, but here we use summary_plot, which stacks together the timeseries itself in the upper panel, its scalogram (a plot of the magnitude of the wavelet power) in the middle, and the power spectral density (PSD, which we plotted earlier in this tutorial) obtained from summing the wavelet coefficients over time to the right.

-
-
-
# create a scalogram
-scal = lr04_slice.interp(step=0.5).standardize().wavelet()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # create a scalogram
-----> 2 scal = lr04_slice.interp(step=0.5).standardize().wavelet()
-
-NameError: name 'lr04_slice' is not defined
-
-
-
-
-
-
-
# make plot
-lr04_slice.summary_plot(
-    psd=lr04_ls_sd_sig, scalogram=scal, time_lim=[0, 1000], psd_label="Amplitude"
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # make plot
-----> 2 lr04_slice.summary_plot(
-      3     psd=lr04_ls_sd_sig, scalogram=scal, time_lim=[0, 1000], psd_label="Amplitude"
-      4 )
-
-NameError: name 'lr04_slice' is not defined
-
-
-
-
-

In this wavelet spectrum, the age of the record is on the x-axis, the period is on the y-axis, and the color represents the amplitude of that power spectrum, with yellow indicating a higher power and purple indicating a lower power. The time series on top is the original LR04 δ18O data, and the plot on the right is the spectral analysis and significance test figure we created earlier in this tutorial.

-
-

Questions 2.3: Climate Connection#

-
    -
  1. In the spectral analysis above, the 100 kyr and 40 kyr period are the most dominant. Here, we further see that over the past 1 million years, the 100 kyr cycle is the strongest (as seen by the yellow color at the 100 kyr scale), followed by the 40 kyr cycle (as seen by the light purple color at the 40 kyr scale). You may notice an absence of much color at the 23 kyr scale. What does this suggest about the influence of precession on glacial-interglacial cycles on this timescale?

  2. -
-

Click for solution

-
-
-
-
-

Summary#

-

In this tutorial you learned how to analyze paleoclimate proxy datasets using spectral and wavelet analysis. You were introduced to several spectral analysis methods, identified significant spectral peaks in the spectral density, and looked at the wavelet transform, it’s evolution over time. By the end, you were able to determine the influence of various periods, like the 100 kyr and 40 kyr orbital cycles, on glacial-interglacial cycles.

-
-
-

Resources#

-

Code for this tutorial is based on existing notebooks from LinkedEarth for spectral analysis and wavelet analysis.

-

Data from the following sources are used in this tutorial:

-
    -
  • Lisiecki, L. E., and Raymo, M. E. (2005), A Pliocene-Pleistocene stack of 57 globally distributed benthic δ18O records, Paleoceanography, 20, PA1003, https://doi.org/10.1029/2004PA001071.

  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.html deleted file mode 100644 index 2a76d4dde..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial7.html +++ /dev/null @@ -1,1544 +0,0 @@ - - - - - - - - - - - - Tutorial 7: Assessing Climate Forcings — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 7: Assessing Climate Forcings#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Mauro Tripaldi, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will use data analysis tools and climate concepts you’ve learned today, and on previous days, to assess the forcings of climate variations observed in paleoclimate records.

-

By the end of this tutorial you will be able to:

-
    -
  • Plot and interpret temperature reconstructions from speleothem oxygen isotopes

  • -
  • Generate and plot time series of solar insolation

  • -
  • Assess the orbital forcings on monsoon intensity over the past 400,000 years using spectral analysis

  • -
-
-
-

Setup#

-
-
-
# imports
-import pooch
-import os
-import tempfile
-import pandas as pd
-import numpy as np
-import matplotlib.pyplot as plt
-
-import cartopy.crs
-import pyleoclim as pyleo
-
-from climlab import constants as const
-from climlab.solar.orbital import OrbitalTable
-from climlab.solar.insolation import daily_insolation
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import pooch
-      3 import os
-      4 import tempfile
-
-ModuleNotFoundError: No module named 'pooch'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Understanding Climate Forcings#

-

A common task in paleoclimatology is to relate a proxy record (or several of them) to the particular forcing(s) that is thought to dominate that particular record (e.g., based on the proxy, location, etc.). We’ve already spent some time in earlier tutorials learning about the influence of Earth’s orbital configuration on glacial-interglacial cycles. In this tutorial, we’ll assess the the climate forcings of monsoon intensity over the past 400,000 years.

-

Recall from the video that monsoons are seasonal changes in the direction of strongest wind and precipitation that are primarily driven by variations in seasonal insolation. Land and the ocean have different abilities to hold onto heat. Land cools and warms much faster than the ocean does due to high heat capacity. This temperature difference leads to a pressure difference that drives atmospheric circulations called monsoons.

-
    -
  • Summer (Northern Hemisphere): land is warmer than the ocean, so the winds blow towards the land, resulting in heavy rainfall over land.

  • -
  • Winter (Northern Hemisphere): land is cooler than the ocean, so the winds blow away from the land, resulting in heavy rainfall over the ocean and decreased rainfall over land.

  • -
-

On longer timescales, changes in insolation and the mean climate state can drive changes in monsoon intensity. To assess these long-term changes, we can analyze paleoclimate reconstructions from monsoon regions such as India, Southeast Asia or Africa. δ18O records from speleothems in Chinese caves are broadly interpreted to reflect continental-scale monsoon circulations.

-

In this tutorial we’ll plot and analyze a composite of three δ18O speleothem records from multiple caves in China (Sanbao, Hulu, and Dongge caves) from Cheng et al. (2016). We will then assess the relationship between the climate signals recorded by the speleothem δ18O and solar insolation.

-

First, we can download and plot the speleothem oxygen isotope data:

-
-
-
# download the data from the url
-filename_Sanbao_composite = "Sanbao_composite.csv"
-url_Sanbao_composite = "https://raw.githubusercontent.com/LinkedEarth/paleoHackathon/main/data/Orbital_records/Sanbao_composite.csv"
-data = pd.read_csv(
-    pooch_load(filelocation=url_Sanbao_composite, filename=filename_Sanbao_composite)
-)
-
-# create a pyleo.Series
-d18O_data = pyleo.Series(
-    time=data["age"] / 1000,
-    time_name="Age",
-    time_unit="kyr BP",
-    value=-data["d18O"],
-    value_name=r"$\delta^{18}$O",
-    value_unit="\u2030",
-)
-d18O_data.plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 4
-      2 filename_Sanbao_composite = "Sanbao_composite.csv"
-      3 url_Sanbao_composite = "https://raw.githubusercontent.com/LinkedEarth/paleoHackathon/main/data/Orbital_records/Sanbao_composite.csv"
-----> 4 data = pd.read_csv(
-      5     pooch_load(filelocation=url_Sanbao_composite, filename=filename_Sanbao_composite)
-      6 )
-      8 # create a pyleo.Series
-      9 d18O_data = pyleo.Series(
-     10     time=data["age"] / 1000,
-     11     time_name="Age",
-   (...)
-     15     value_unit="\u2030",
-     16 )
-
-NameError: name 'pd' is not defined
-
-
-
-
-

You may notice that in the figure we just made, the δ18O values on the y-axis is plotted with more positive values up, whereas in previous tutorials, we’ve plotted isotopic data with more negative values up (since more negative/“depleted” suggests warmer temperatures or increased rainfall). However, the pre-processed δ18O data that we’re using in this tutorial was multipled by -1, so now a more positive/“enriched” value suggests warmer temperatures or increased rainfall. In other words, in this figure, upward on the y-axis is increased monsoon intensity and downward on the y-axis is decreased monsoon intensity.

-

Let’s apply what we learned in the previous tutorial to perform spectral analysis on the speleothem oxygen isotope data. Recall from the previous tutorial that spectral analysis can help us identify dominant cyclicities in the data, which can be useful for assessing potential climate forcings.

-

Here we’ll use the Weighted Wavelet Z-Transform (WWZ) method you learned about in the previous tutorial:

-
-
-
# standardize the data
-d18O_stnd = d18O_data.interp(step=0.5).standardize()  # save it for future use
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 2
-      1 # standardize the data
-----> 2 d18O_stnd = d18O_data.interp(step=0.5).standardize()  # save it for future use
-
-NameError: name 'd18O_data' is not defined
-
-
-
-
-
-
-
# calculate the WWZ spectral analysis
-d18O_wwz = d18O_stnd.spectral(method="wwz")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 2
-      1 # calculate the WWZ spectral analysis
-----> 2 d18O_wwz = d18O_stnd.spectral(method="wwz")
-
-NameError: name 'd18O_stnd' is not defined
-
-
-
-
-
-
-
# plot WWZ results
-d18O_wwz.plot(xlim=[100, 5], ylim=[0.001, 1000])
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # plot WWZ results
-----> 2 d18O_wwz.plot(xlim=[100, 5], ylim=[0.001, 1000])
-
-NameError: name 'd18O_wwz' is not defined
-
-
-
-
-
-

Coding Exercises 1#

-
    -
  1. The dominant spectral power is at ~23,000 years. This suggests a link between monsoon intensity and orbital precession! Is this peak significant? Use the skills you learned in the last tutorial to test the significance of this peak at the 95% confidence level. For this exercise, input number = 5 as the default value which will take a long time to run.

  2. -
-

note: if you have time, change the number to 30. it will take about 5-10 minutes to run

-
-
-
# perform significance test with 5 surrogates
-d18O_wwz_sig = ...
-
-# plot the results
-_ = ...
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-

Section 2: Constructing Insolation Curves#

-

To further explore and confirm the relationship between monsoon intensity and orbital precession, let’s take a look at insolation data and compare this to the speleothem δ18O records from Asia. Recall that insolation is controlled by variations in Earth’s orbital cycles (eccentricity, obliquity, precession), so by comparing the δ18O record to insolation, we can assess the influence of orbital variations on δ18O and monsoon intensity.

-

To compute solar insolation, we can use the package climlab by Brian Rose. Let’s create a time series over the past 400,000 years of changes in summer insolation at 31.67ºN, which is the latitude of Sanbao, one of the caves from which the speleothem records were produced.

-
-
-
# specify time interval and units
-kyears = np.linspace(-400, 0, 1001)
-
-# subset of orbital parameters for specified time
-orb = OrbitalTable.interp(kyear=kyears)
-days = np.linspace(0, const.days_per_year, 365)
-
-# generate insolation at Sanbao latitude (31.67)
-Qsb = daily_insolation(31.67, days, orb)
-
-# julian days 152-243 are JJA
-Qsb_jja = np.mean(Qsb[:, 151:243], axis=1)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # specify time interval and units
-----> 2 kyears = np.linspace(-400, 0, 1001)
-      4 # subset of orbital parameters for specified time
-      5 orb = OrbitalTable.interp(kyear=kyears)
-
-NameError: name 'np' is not defined
-
-
-
-
-

Now we can store this data as a Series in Pyleoclim and plot the data versus time:

-
-
-
ts_qsb = pyleo.Series(
-    time=-kyears,
-    time_name="Age",
-    time_unit="ky BP",
-    value=Qsb_jja,
-    value_name="JJA Insolation",
-    value_unit=r"$W.m^{-2}$",
-)
-
-ts_qsb.plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 1
-----> 1 ts_qsb = pyleo.Series(
-      2     time=-kyears,
-      3     time_name="Age",
-      4     time_unit="ky BP",
-      5     value=Qsb_jja,
-      6     value_name="JJA Insolation",
-      7     value_unit=r"$W.m^{-2}$",
-      8 )
-     10 ts_qsb.plot()
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-

Next, let’s plot and compare the speleothem δ18O data and the solar insolation data:

-
-
-
# standardize the insolation data
-ts_qsb_stnd = ts_qsb.standardize()
-
-# create a MultipleSeries of the speleothem d18O record and insolation data
-compare = [d18O_stnd, ts_qsb_stnd]
-ms_compare = pyleo.MultipleSeries(compare, time_unit="kyr BP", name=None)
-
-# create a stackplot to compare the data
-ms_compare.stackplot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # standardize the insolation data
-----> 2 ts_qsb_stnd = ts_qsb.standardize()
-      4 # create a MultipleSeries of the speleothem d18O record and insolation data
-      5 compare = [d18O_stnd, ts_qsb_stnd]
-
-NameError: name 'ts_qsb' is not defined
-
-
-
-
-

By visually comparing the time series of the two records, we can see similarites at orbital scales. To confirm this, we can use spectral analysis to determine the dominant spectral power of the insolation data:

-
-
-
# calculate the WWZ spectral analysis
-psd_wwz = ts_qsb_stnd.spectral(method="wwz")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # calculate the WWZ spectral analysis
-----> 2 psd_wwz = ts_qsb_stnd.spectral(method="wwz")
-
-NameError: name 'ts_qsb_stnd' is not defined
-
-
-
-
-
-
-
psd_wwz.plot()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 1
-----> 1 psd_wwz.plot()
-
-NameError: name 'psd_wwz' is not defined
-
-
-
-
-
-

Questions 2: Climate Connection#

-
    -
  1. What is the dominant spectral power in summer insolation at 31ºN latitude? How does this compare to the speleothem data?

  2. -
  3. Why might there be a relationship between solar insolation and monsoon intensity? What does the common spectral power in both the insolation and δ18O records suggest about the climate forcings driving monsoon intensity in this region?

  4. -
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, you’ve gained valuable insights into the complex world of paleoclimatology and climate forcings. Here’s a recap of what you’ve learned:

-
    -
  • You’ve discovered how to plot and interpret temperature reconstructions derived from speleothem oxygen isotopes.

  • -
  • You’ve assessed the likely impact of orbital forcings on monsoon intensity over the past 400,000 years using spectral analysis.

  • -
  • By comparing the δ18O record to insolation, you’ve developed a deeper understanding of the relationship between solar insolation and monsoon intensity.

  • -
-
-
-

Resources#

-

Code for this tutorial is based on an existing notebook from LinkedEarth that explore forcing and responses in paleoclimate data.

-

Data from the following sources are used in this tutorial:

-
    -
  • Cheng, H., Edwards, R., Sinha, A. et al. The Asian monsoon over the past 640,000 years and ice age terminations. Nature 534, 640–646 (2016). https://doi.org/10.1038/nature18591

  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.html deleted file mode 100644 index 1475d4550..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial8.html +++ /dev/null @@ -1,1629 +0,0 @@ - - - - - - - - - - - - Tutorial 8: Paleoclimate Models — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 8: Paleoclimate Models#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Rieke Schäfer, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

So far today, we’ve been focusing on how proxy-based reconstructions can be used to understand past variations in Earth’s climate sytem. However, another useful tool in paleoclimate is the use of climate models.

-

In this tutorial, you’ll explore data from the Paleoclimate Modelling Intercomparison Project 3 (PMIP3). More specifically, you’ll be analyzing global mean surface temperature (GMST) data from simulations for the past 1,000 years.

-

You’ll also compare the PMIP3 GMST data to a proxy-based reconstruction of temperature from Lake Tanganyika in East Africa (Tierney et al., 2010). Through this proxy-model comparison, you’ll be able to assess the differences and similarities between the two datasets.

-

By the end of this tutorial you will be able to:

-
    -
  • Plot time series of paleoclimate model simulations

  • -
  • Compare and interpret proxy-based reconstructions of climate to paleoclimate model simulations of climate

  • -
-
-
-

Setup#

-
-
-
# imports
-import pandas as pd
-import numpy as np
-import xarray as xr
-import pooch
-import os
-import tempfile
-import cartopy
-import pyleoclim as pyleo
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import pandas as pd
-      3 import numpy as np
-      4 import xarray as xr
-
-ModuleNotFoundError: No module named 'pandas'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Load Proxy-Based Temperature Reconstructions#

-

The proxy record we’ll be analyzing in this tutorial is a 1,000 year-long lake surface temperature reconstruction from Tierney et al., 2010. This record is from Lake Taganyika in equatorial East Africa and is based on the TEX86 ratio, which is a temperature proxy derived from the distribution of the isoprenoid glycerol dialkyl glycerol tetraether (iGDGT) of archaeal membrane lipids. The organisms producing these iGDGT compounds alter the structure of the compound in response to changes in temperature, so by measuring changes in the ratio of the different compounds, we can infer past changes in temperature.

-

Let’s start by loading the proxy data, saving it as a Series in Pyleoclim, and plotting a time series.

-
-
-
filename_tang = "tang_sst.csv"
-url_tang = "https://osf.io/p8tx3/download"
-proxy_temp = pd.read_csv(pooch_load(filelocation=url_tang, filename=filename_tang))
-proxy_temp.head()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 3
-      1 filename_tang = "tang_sst.csv"
-      2 url_tang = "https://osf.io/p8tx3/download"
-----> 3 proxy_temp = pd.read_csv(pooch_load(filelocation=url_tang, filename=filename_tang))
-      4 proxy_temp.head()
-
-NameError: name 'pd' is not defined
-
-
-
-
-
-
-
proxy_t = pyleo.Series(
-    time=proxy_temp["Year"],
-    value=proxy_temp["LST"],
-    time_name="Time",
-    time_unit="yrs",
-    value_name="Surface Temperature",
-    value_unit="ºC",
-    label="Lake Tanganyika Surface Temperature",
-)
-
-proxy_t.plot(color="C1")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 1
-----> 1 proxy_t = pyleo.Series(
-      2     time=proxy_temp["Year"],
-      3     value=proxy_temp["LST"],
-      4     time_name="Time",
-      5     time_unit="yrs",
-      6     value_name="Surface Temperature",
-      7     value_unit="ºC",
-      8     label="Lake Tanganyika Surface Temperature",
-      9 )
-     11 proxy_t.plot(color="C1")
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-
-

Questions 1#

-

Let’s make some initial observations about the data:

-
    -
  1. What is the overall temperature trend over the past 2,000 years? Where are the major increases or decrease in temperature?

  2. -
  3. What could be the cause of these shifts in lake surface temperature?

  4. -
-

Click for solution

-
-
-
-

Section 2: Last Millenium PMIP3 GMST Data#

-

We can now load GMST anomaly data from the PMIP3 simulations for the past 1,000 years (Braconnot et al., 2012 and PAGES 2k-PMIP3 group, 2015). The anomalies are computed compared to the mean of the time series over the full length of temporal overlap between simulations.

-
-
-
# load the raw data 'PMIP3_GMST.txt'
-filename_PMIP3 = "PMIP3_GMST.txt"
-url_PMIP3 = "https://osf.io/gw2m5/download"
-df = pd.read_table(pooch_load(filelocation=url_PMIP3, filename=filename_PMIP3))
-
-# display the raw data
-df
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 4
-      2 filename_PMIP3 = "PMIP3_GMST.txt"
-      3 url_PMIP3 = "https://osf.io/gw2m5/download"
-----> 4 df = pd.read_table(pooch_load(filelocation=url_PMIP3, filename=filename_PMIP3))
-      6 # display the raw data
-      7 df
-
-NameError: name 'pd' is not defined
-
-
-
-
-

Note that the data file includes several ensemble members for Community Earth System Model (CESM) and Goddard Institute for Space Studies (GISS) simulations. Ensembles are essentially groups of climate model simulations used for climate projections, or in this case, reconstructions. You will learn about this in much more detail on W1D5: Climate Modeling.

-

For now, we can replace these with their ensemble mean series.

-
-
-
# create a new pandas.DataFrame to store the processed data
-df_new = df.copy()
-
-# remove the data columns for CESM and GISS ensemble members
-for i in range(10):
-    df_new = df_new.drop([f"CESM_member_{i+1}"], axis=1)
-
-df_new = df_new.drop(["GISS-E2-R_r1i1p127.1"], axis=1)
-df_new = df_new.drop(["GISS-E2-R_r1i1p127"], axis=1)
-df_new = df_new.drop(["GISS-E2-R_r1i1p121"], axis=1)
-
-# calculate the ensemble mean for CESM and GISS, and add the results into the table
-df_new["CESM"] = df[
-    [
-        "CESM_member_1",
-        "CESM_member_2",
-        "CESM_member_3",
-        "CESM_member_4",
-        "CESM_member_5",
-        "CESM_member_6",
-        "CESM_member_7",
-        "CESM_member_8",
-        "CESM_member_9",
-        "CESM_member_10",
-    ]
-].mean(axis=1)
-
-df_new["GISS"] = df[
-    [
-        "GISS-E2-R_r1i1p127.1",
-        "GISS-E2-R_r1i1p127",
-        "GISS-E2-R_r1i1p121",
-    ]
-].mean(axis=1)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # create a new pandas.DataFrame to store the processed data
-----> 2 df_new = df.copy()
-      4 # remove the data columns for CESM and GISS ensemble members
-      5 for i in range(10):
-
-NameError: name 'df' is not defined
-
-
-
-
-
-
-
# display the processed data
-df_new
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # display the processed data
-----> 2 df_new
-
-NameError: name 'df_new' is not defined
-
-
-
-
-

In our new dataframe, you can now see that the ensemble members for CESM and GISS are now replaced with one ensemble mean for each model simulation.

-

Now we can create a Pyleoclim Series object for each simulated GMST time series, which will allow us to easily plot the time series for each simulation and perform data analysis using various built-in tools.

-
-
-
# store each pyleoclim.Series() object into a dictionary
-ts_dict = {}
-for name in df_new.columns[1:]:
-    ts_dict[name] = pyleo.Series(
-        time=df_new["Year"].values,  # the time axis
-        value=df_new[name].values,  # the value axis
-        label=name,  # optional metadata: the nickname of the series
-        time_name="Time",  # optional metadata: the name of the time axis
-        time_unit="yrs",  # optional metadata: the unit of the time axis
-        value_name="GMST anomaly",  # optional metadata: the name of the value axis
-        value_unit="ºC",  # optional metadata: the unit of the value axis
-    )
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 3
-      1 # store each pyleoclim.Series() object into a dictionary
-      2 ts_dict = {}
-----> 3 for name in df_new.columns[1:]:
-      4     ts_dict[name] = pyleo.Series(
-      5         time=df_new["Year"].values,  # the time axis
-      6         value=df_new[name].values,  # the value axis
-   (...)
-     11         value_unit="ºC",  # optional metadata: the unit of the value axis
-     12     )
-
-NameError: name 'df_new' is not defined
-
-
-
-
-

We can now plot each simulation. For example, let’s plot the CCSM4 GMST anomaly:

-
-
-
ts_dict["CCSM4"].plot()
-
-
-
-
-
---------------------------------------------------------------------------
-KeyError                                  Traceback (most recent call last)
-Cell In[10], line 1
-----> 1 ts_dict["CCSM4"].plot()
-
-KeyError: 'CCSM4'
-
-
-
-
-

But what if we wanted to plot all of the PMIP3 time series at once? We can do that using the MultipleSeries object in Pyleoclim, which takes a list of Series objects as input. To do so, we have to convert the dictionary of Series into a list and then create a MultipleSeries object.

-
-
-
ts_list = [
-    v for k, v in ts_dict.items()
-]  # a pythonic way to convert the pyleo.Series items in the dictionary to a list
-ms_pmip = pyleo.MultipleSeries(ts_list)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 4
-      1 ts_list = [
-      2     v for k, v in ts_dict.items()
-      3 ]  # a pythonic way to convert the pyleo.Series items in the dictionary to a list
-----> 4 ms_pmip = pyleo.MultipleSeries(ts_list)
-
-NameError: name 'pyleo' is not defined
-
-
-
-
-

We can now plot all PMIP3 simulation time series at once:

-
-
-
ms_pmip.plot(
-    lgd_kwargs={
-        "bbox_to_anchor": (1.25, 1),  # move the legend to the right side
-    }
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 1
-----> 1 ms_pmip.plot(
-      2     lgd_kwargs={
-      3         "bbox_to_anchor": (1.25, 1),  # move the legend to the right side
-      4     }
-      5 )
-
-NameError: name 'ms_pmip' is not defined
-
-
-
-
-

Note that like the paleo proxy data we have looked at, these model simulations are also referred to as reconstructions as they are attempts to recreate past climates.

-

The reconstructed GMST anomalies from all of the PMIP3 simulations follow the same overall trend of relatively stable, long-term temperature from 800-1800 AD, followed by an increase in temperature over the past 200 years. What do you think is driving this recent warming trend?

-

Despite the long-term similarities, there are also noticeable differences between the GMST time series from each simulation.

-
-

Questions 2: Climate Connection#

-
    -
  1. How are the GMST anomalies from each simulation different? What could be causing these differences?

  2. -
  3. How do we know which simulation is the most accurate and reliable?

  4. -
-

Click for solution

-
-
-
-

Section 3: Proxy-Model Comparisons#

-

Proxy-based reconstructions of climate variables in the past can provide direct measurements of temperature, precipitation, greenhouse gas concentration, etc. Comparing proxy paleoclimate records with paleoclimate model simulations can help to clarify the interpretation of the proxy record and also help to improve the ability of climate models to simulate past variations in climate.

-

Here, we’ll compare the proxy-based Lake Tanganyika surface temperature reconstruction we downloaded and plotted at the beginning of the tutorial, with the GMST anomaly PMIP3 simulations. But first, we need to standardize the Lake Tanganyika data since we’re comparing the data to the GMST anomaly.

-
-
-
# standardize the proxy data
-proxy_stnd = proxy_t.standardize()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # standardize the proxy data
-----> 2 proxy_stnd = proxy_t.standardize()
-
-NameError: name 'proxy_t' is not defined
-
-
-
-
-
-
-
fig, ax = ms_pmip.plot(
-    lgd_kwargs={
-        "bbox_to_anchor": (1.25, 1),  # move the legend to the right side
-    }
-)
-
-ax.set_ylabel("GMST anomaly (ºC)")
-ax1 = ax.twinx()  # create a second axes that shares the same x-axis
-ax1.set_ylabel("Tanganyika Surface Temperature Anomaly (ºC)")
-
-proxy_stnd.plot(ax=ax1, color="black")
-ax.set_xlim(xmin=850, xmax=2000)
-ax.set_ylim(ymin=-4, ymax=2)
-ax1.set_ylim(ymin=-4, ymax=2)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 1
-----> 1 fig, ax = ms_pmip.plot(
-      2     lgd_kwargs={
-      3         "bbox_to_anchor": (1.25, 1),  # move the legend to the right side
-      4     }
-      5 )
-      7 ax.set_ylabel("GMST anomaly (ºC)")
-      8 ax1 = ax.twinx()  # create a second axes that shares the same x-axis
-
-NameError: name 'ms_pmip' is not defined
-
-
-
-
-
-

Questions 3: Climate Connection#

-

How do the model simulated GMST and proxy-based surface temperature compare?

-
    -
  1. Is there more variability in the proxy or model temperatures? What might be causing this?

  2. -
  3. Are the long-term trends over the last millenium in the simulated GMST anomaly and proxy-based surface temperature record similar or different?

  4. -
-

Click for solution

-

This is just one simplified example of a proxy-model comparison. Larger-scale proxy-model comparisons can help to identify spatial patterns of temperature change and assess forcing mechanisms of paleoclimate variations. In W2D1, you’ll spend more time exploring climate models.

-
-
-
-

Summary#

-

In this tutorial, you explored the role of climate models in paleoclimate research, particularly focusing on data from PMIP3. You learned to analyze and plot time series of paleoclimate model simulations, specifically GMST anomaly data from the past 1,000 years. This data reveals a trend of relatively stable global mean surface temperature anomalies from 800-1800 AD, followed by a noticeable rise in temperature over the last two centuries.

-

Furthermore, you have learned to compare this model data with proxy-based reconstructions. Using the example of temperature data from Lake Tanganyika in East Africa, we’ve assessed the differences and similarities between the model and proxy data. This process not only enhances our interpretation of the proxy record but also improves our understanding of how well climate models simulate past climate variations.

-

In the next and final tutorial for today, you’ll explore another tool for assessing past climate variability using both proxies and models.

-
-
-

Resources#

-

Code for this tutorial is based on existing notebooks from LinkedEarth that explore paleoclimate model-data comparisons using PMIP3 model simulations.

-

Data from the following sources are used in this tutorial:

-
    -
  • Braconnot, P., Harrison, S., Kageyama, M. et al. Evaluation of climate models using palaeoclimatic data. Nature Clim Change 2, 417–424 (2012). https://doi.org/10.1038/nclimate1456

  • -
  • Tierney, J., Mayes, M., Meyer, N. et al. Late-twentieth-century warming in Lake Tanganyika unprecedented since AD 500. Nature Geosci 3, 422–425 (2010). https://doi.org/10.1038/ngeo865

  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.html b/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.html deleted file mode 100644 index 6d794a4fc..000000000 --- a/book/_build/html/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial9.html +++ /dev/null @@ -1,1512 +0,0 @@ - - - - - - - - - - - - Tutorial 9: Paleoclimate Reanalysis Products — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 9: Paleoclimate Reanalysis Products#

-

Week 1, Day 4, Paleoclimate

-

Content creators: Sloane Garelick

-

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

As we discussed in the video, proxies and models both have advantages and limitations for reconstructing past changes in Earth’s climate system. One approach for combining the strengths of both paleoclimate proxies and models is data assimilation. This is the same approach used in Day 2, except instead of simulations of Earth’s recent past, we are using a simulation that spans many thousands of years back in time and is constrained by proxies, rather than modern instrumental measurements. The results of this process are called reanalysis products.

-

In this tutorial, we’ll look at paleoclimate reconstructions from the Last Glacial Maximum Reanalysis (LGMR) product from Osman et al. (2021), which contains temperature for the past 24,000 years.

-

During this tutorial you will:

-
    -
  • Plot a time series of the paleoclimate reconstruction

  • -
  • Create global maps and zonal mean plots of temperature anomalies

  • -
  • Assess how and why LGM to present temperature anomalies vary with latitude

  • -
-
-
-

Setup#

-
-
-
# imports
-import pooch
-import os
-import tempfile
-import numpy as np
-import xarray as xr
-import matplotlib.pyplot as plt
-
-import cartopy.crs as ccrs
-import cartopy.util as cutil
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import pooch
-      3 import os
-      4 import tempfile
-
-ModuleNotFoundError: No module named 'pooch'
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Load the LGMR Paleoclimate Reconstruction#

-

This dataset contains a reconstruction of surface air temperature (SAT) from the product Last Glacial Maximum Reanalysis (LGMR). Note that this data starts from 100 years before present and goes back in time to ~24,000 BP. The period of time from ~21,000 to 18,000 years ago is referred to as the Last Glacial Maximum (LGM). The LGM was the most recent glacial period in Earth’s history. During this time, northern hemisphere ice sheets were larger, global sea level was lower, atmospheric CO2 was lower, and global mean temperature was cooler. (Note: if you are interested in looking at data for the present to last millenium, that reanalyses product is available here.)

-

We will calculate the global mean temperature from the LGM to 100 years before present from a paleoclimate data assimilation to asses how Earth’s climate varied over the past 24,000 years.

-

First let’s download the paleoclimate data assimilation reconstruction for surface air temperature (SAT).

-
-
-
filename_LGMR_SAT_climo = "LGMR_SAT_climo.nc"
-url_LGMR_SAT_climo = "https://www.ncei.noaa.gov/pub/data/paleo/reconstructions/osman2021/LGMR_SAT_climo.nc"
-
-ds = xr.open_dataset(
-    pooch_load(filelocation=url_LGMR_SAT_climo, filename=filename_LGMR_SAT_climo)
-)
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 4
-      1 filename_LGMR_SAT_climo = "LGMR_SAT_climo.nc"
-      2 url_LGMR_SAT_climo = "https://www.ncei.noaa.gov/pub/data/paleo/reconstructions/osman2021/LGMR_SAT_climo.nc"
-----> 4 ds = xr.open_dataset(
-      5     pooch_load(filelocation=url_LGMR_SAT_climo, filename=filename_LGMR_SAT_climo)
-      6 )
-      7 ds
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-

Section 1.1: Plotting the Temperature Time Series#

-

Now that the data is loaded, we can plot a time series of the temperature data to assess global changes. However, the dimensions of the sat_mean variable are age-lat-lon, so we first need to weight the data and calculate a global mean.

-
-
-
# assign weights
-weights = np.cos(np.deg2rad(ds.lat))
-
-# calculate the global mean surface temperature
-sat_global_mean = ds.sat.weighted(weights).mean(dim=["lat", "lon"])
-sat_global_mean
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 2
-      1 # assign weights
-----> 2 weights = np.cos(np.deg2rad(ds.lat))
-      4 # calculate the global mean surface temperature
-      5 sat_global_mean = ds.sat.weighted(weights).mean(dim=["lat", "lon"])
-
-NameError: name 'np' is not defined
-
-
-
-
-

Now that we calculated our global mean, we can plot the results as a time series to assess global changes in temperature over the past 24,000 years:

-
-
-
# plot the global mean surface temperature since the LGM
-f, ax1 = plt.subplots(1, 1, figsize=(12, 6))
-ax1.plot(ds["age"], sat_global_mean, linewidth=3)
-
-ax1.set_xlim(ds["age"].max().values, ds["age"].min().values)
-ax1.set_ylabel("Global Mean SAT for LGM ($^\circ$C)", fontsize=16)
-ax1.set_xlabel("Age (yr BP)", fontsize=16)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 2
-      1 # plot the global mean surface temperature since the LGM
-----> 2 f, ax1 = plt.subplots(1, 1, figsize=(12, 6))
-      3 ax1.plot(ds["age"], sat_global_mean, linewidth=3)
-      5 ax1.set_xlim(ds["age"].max().values, ds["age"].min().values)
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Questions 1.1: Climate Connection#

-
    -
  1. How has global temperature varied over the past 24,000 years?

  2. -
  3. What climate forcings may have contributed to the increase in temperature ~17,000 years ago?

  4. -
-

Click for solution

-
-
-
-

Section 1.2: Plotting a Temperature Anomaly Map#

-

The reanalysis contains spatial reconstructions, so we can also make figures showing spatial temperature anomalies for different time periods (i.e., the change in temperature between two specified times). The anomaly that we’ll interpret is the difference between global temperature from 18,000 to 21,000 years ago (i.e. “LGM”) and 100 to 1,000 years ago (i.e. “modern”) . First, we’ll calculate the average temperatures for each time period.

-
-
-
# calculate the LGM (18,000-21,000 year) mean temperature
-lgm = ds.sat.sel(age=slice("18000", "21000"), lon=slice(0, 357.5), lat=slice(-90, 90))
-lgm_mean = lgm.mean(dim="age")
-
-# calculate the "modern" (100-1000 year) mean temperature
-modern = ds.sat.sel(age=slice("100", "1000"), lon=slice(0, 357.5), lat=slice(-90, 90))
-modern_mean = modern.mean(dim="age")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # calculate the LGM (18,000-21,000 year) mean temperature
-----> 2 lgm = ds.sat.sel(age=slice("18000", "21000"), lon=slice(0, 357.5), lat=slice(-90, 90))
-      3 lgm_mean = lgm.mean(dim="age")
-      5 # calculate the "modern" (100-1000 year) mean temperature
-
-NameError: name 'ds' is not defined
-
-
-
-
-

Now we can calculate the anomaly and create a map to visualize the change in temperature from the LGM to present in different parts on Earth.

-
-
-
sat_change = modern_mean - lgm_mean
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 sat_change = modern_mean - lgm_mean
-
-NameError: name 'modern_mean' is not defined
-
-
-
-
-
-
-
# make a map of changes
-fig, ax = plt.subplots(figsize=(12, 8), subplot_kw={"projection": ccrs.Robinson()})
-ax.set_global()
-sat_change.plot(
-    ax=ax,
-    transform=ccrs.PlateCarree(),
-    x="lon",
-    y="lat",
-    cmap="Reds",
-    vmax=30,
-    cbar_kwargs={"orientation": "horizontal", "label": "$\Delta$SAT ($^\circ$C)"},
-)
-ax.coastlines()
-ax.set_title(f"Modern - LGM SAT ($^\circ$C)", loc="center", fontsize=16)
-ax.gridlines(color="k", linewidth=1, linestyle=(0, (1, 5)))
-ax.spines["geo"].set_edgecolor("black")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # make a map of changes
-----> 2 fig, ax = plt.subplots(figsize=(12, 8), subplot_kw={"projection": ccrs.Robinson()})
-      3 ax.set_global()
-      4 sat_change.plot(
-      5     ax=ax,
-      6     transform=ccrs.PlateCarree(),
-   (...)
-     11     cbar_kwargs={"orientation": "horizontal", "label": "$\Delta$SAT ($^\circ$C)"},
-     12 )
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Before we interpret this data, another useful way to visualize this data is through a plot of zonal mean temperature (the average temperature for all locations at a single latitude). Once we calculate this zonal mean, we can create a plot of LGM to present temperature anomalies versus latitude.

-
-
-
zonal_mean = sat_change.mean(dim="lon")
-latitude = ds.lat
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 1
-----> 1 zonal_mean = sat_change.mean(dim="lon")
-      2 latitude = ds.lat
-
-NameError: name 'sat_change' is not defined
-
-
-
-
-
-
-
# Make a zonal mean figure of the changes
-fig, ax1 = plt.subplots(1, 1)
-ax1.plot(zonal_mean, latitude)
-ax1.axvline(x=0, color="gray", alpha=1, linestyle=":", linewidth=2)
-ax1.set_ylim(-90, 90)
-ax1.set_xlabel("$\Delta$T ($^\circ$C)")
-ax1.set_ylabel("Latitude ($^\circ$)")
-ax1.set_title(
-    f"Zonal-mean $\Delta$T ($^\circ$C) changes",  # ohad comment: same changes
-    loc="center",
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # Make a zonal mean figure of the changes
-----> 2 fig, ax1 = plt.subplots(1, 1)
-      3 ax1.plot(zonal_mean, latitude)
-      4 ax1.axvline(x=0, color="gray", alpha=1, linestyle=":", linewidth=2)
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Questions 1.1: Climate Connection#

-

Looking at both the map and zonal mean plot, consider the following questions:

-
    -
  1. How does the temperature anomaly vary with latitude?

  2. -
  3. What might be causing spatial differences in the temperature anomaly?

  4. -
-

Click for solution

-
-
-
-
-

Summary#

-

In this last tutorial of this day, you explored the intersection of paleoclimate proxies and models through reanalysis products, specifically analyzing the Last Glacial Maximum Reanalysis (LGMR) from Osman et al. (2021).

-

Through this tutorial, you’ve learned a range of new skills and knowledge:

-
    -
  • Interpreting Paleoclimate Reconstructions: You have learned how to decode and visualize the time series of a paleoclimate reconstruction of surface air temprature from a reanalysis product in order to enhance your understanding of the temperature variations from the Last Glacial Maximum to the present day.

  • -
  • Constructing Global Temperature Anomaly Maps: You’ve acquired the ability to construct and understand global maps that represent temperature anomalies, providing a more holistic view of the Earth’s climate during the Last Glacial Maximum.

  • -
  • Examining Latitude’s Role in Temperature Variations: You’ve explored how temperature anomalies from the Last Glacial Maximum to the present day vary by latitude and pondered the reasons behind these variations, enriching your understanding of latitudinal effects on global climate patterns.

  • -
-
-
-

Resources#

-

The code for this notebook is based on code available from Erb et al. (2022) and workflow presented during the Paleoclimate Data Assimilation Workshop 2022.

-

Data from the following sources are used in this tutorial:

-
    -
  • Matthew B. Osman, Jessica E. Tierney, Jiang Zhu, Robert Tardif, Gregory J. Hakim, Jonathan King, Christopher J. Poulsen. 2021. Globally resolved surface temperatures since the Last Glacial Maximum. Nature, 599, 239-244. http://doi.org/10.1038/s41586-021-03984-4.

  • -
  • King, J. M., Tierney, J., Osman, M., Judd, E. J., & Anchukaitis, K. J. (2023). DASH: A MATLAB Toolbox for Paleoclimate Data Assimilation. Geoscientific Model Development, preprint. https://doi.org/10.5194/egusphere-2023-68.

  • -
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/chapter_title.html b/book/_build/html/tutorials/W1D5_ClimateModeling/chapter_title.html deleted file mode 100644 index 924fe9af3..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - Climate Modeling — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Climate Modeling

- -
-
- -
-
-
- - - - -
- -
-

Climate Modeling#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/further_reading.html b/book/_build/html/tutorials/W1D5_ClimateModeling/further_reading.html deleted file mode 100644 index 7b8591f5b..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/further_reading.html +++ /dev/null @@ -1,1056 +0,0 @@ - - - - - - - - - - - - Suggested Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Suggested Further Reading

- -
-
- -
-
-
- - - - -
- -
-

Suggested Further Reading#

-

Today’s lectures and tutorials were inspired by The Climate Laboratory, Brian Rose, 2022. If you want further information or context on any of today’s topics, this The Climate Laboratory likely contains that information or links to other appropriate readings.

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.html b/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.html deleted file mode 100644 index e61adc53e..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial1.html +++ /dev/null @@ -1,1687 +0,0 @@ - - - - - - - - - - - - Tutorial 1 : A Simple Greenhouse Model — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1 : A Simple Greenhouse Model#

-

Week 1, Day 5, Climate Modeling

-

Content creators: Jenna Pearson

-

Content reviewers: Dionessa Biton, Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan

-

Content editors: Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial students will learn about blackbody radiation and greenhouse models for energy emitted from Earth.

-

By the end of this tutorial students will be able to:

-
    -
  • Understand what an emission temperature is, and how to find it given observed outgoing longwave radiation.

  • -
  • Modify the blackbody radiation model to include the greenhouse effect.

  • -
-
-
-

Setup#

-
-
-
# imports
-import holoviews as hv
-import panel as pn
-import matplotlib.pyplot as plt
-import numpy as np
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import holoviews as hv
-      3 import panel as pn
-      4 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'holoviews'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Speaker Introduction#

-
-

Video 1: Speaker Introduction#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Speaker Introduction
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-

Video 2: A Simple Greenhouse Model#

-
-

Video 2: A Simple Greenhouse Model#

-
-
- - -Hide code cell source - -
-
# @title Video 2: A Simple Greenhouse Model
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1 : A Radiating Earth#

-
-

Section 1.1 Planck’s Law#

-

All objects with a temperature emit electromagnetic radiation. This energy travels through space in the form of waves. In the lecture we discussed that blackbody radiation is a model of how Earth loses radiative energy to space. Although this is not a perfect model for Earth, we will use it as a basis to understand Earth’s energy balance throughout tutorials 1-4. If we suppose Earth behaves as a perfect blackbody, then it emits energy at all wavelengths according to Planck’s Law:

-
-(4)#\[\begin{align} -B(\lambda,T) = \frac{2 h c^2}{\lambda^5}\frac{1}{e^{hc/(\kappa T)}-1} -\end{align}\]
-

where \(h = 6.626075 \times 10^{-34} J s\) is Planck’s constant, \(c= 2.99792 \times 108 m s^{-1}\) is the speed of light, and \(\kappa = 1.3804 \times 10^{23} W K^{-1}\) is Boltzmann’s constant.

-
-

Interactive Demo 1.1#

-

This interactive demo will allow you to visualize how to blackbody curve changes as Earth warms and cools relative to it’s current surface temperature of about 288K. Use the slide bar to adjust the emission temperature. Give the code few seconds to replot before choosing a new temperature.

-

No need to worry about understanding the code here - this is conceptual.

-

Make sure you execute this cell to enable the widget!

-

Make sure you execute this cell to enable the widget!

-
-
- - -Hide code cell source - -
-
# @markdown Make sure you execute this cell to enable the widget!
-
-hv.extension("bokeh")
-
-# define constants used in Planck's Law
-h = 6.626075e-34  # J s
-c = 2.99792e8  # m s^-1
-k = 1.3804e-23  # W K^-1
-
-
-# define the function for Planck's Law depedent on wavelength (lambda) and temeprature (T)
-def planck(wavelength, temperature):
-    a = 2.0 * h * c**2
-    b = h * c / (wavelength * k * temperature)
-    intensity = a / ((wavelength**5) * (np.exp(b) - 1.0))
-
-    lpeak = (2.898 * 1e-3) / temperature
-
-    return intensity
-
-
-def update_plot(emiss_temp):
-    # generate x-axis in increments from 1um to 100 micrometer in 1 nm increments
-    # starting at 1 nm to avoid wav = 0, which would result in division by zero.
-    wavelengths = np.arange(1e-6, 50e-6, 1e-9)
-
-    # get the blackbody curve and peak emission wavelength for 288 K
-    intensity288 = planck(wavelengths, 288)
-
-    # get the blackbody curve and peak emission wavelength for selected temperature
-    intensity = planck(wavelengths, emiss_temp)
-
-    #     # get the intensity at peak wavelength to limit the lines
-    #     Ipeak,_ = planck(lpeak,emission_temperature)
-    #     Ipeak288,_ = planck(lpeak288,288)
-
-    # curves output
-    vary = zip(wavelengths * 1e6, intensity)
-    init_val = zip(wavelengths * 1e6, intensity288)
-
-    # Specified individually
-    list_of_curves = [
-        hv.Curve(init_val, label="T=" + str(emiss_temp) + "K").opts(ylim=(0, 1.0e7)),
-        hv.Curve(vary, label="T=288K").opts(ylim=(0, 1.0e7)),
-    ]
-
-    bb_plot = hv.Overlay(list_of_curves).opts(
-        height=300,
-        width=600,
-        xlabel="Wavelength (μm)",
-        ylabel="B(λ,T) (W/(m³ steradian)",
-        title="Spectral Radiance",
-    )
-
-    return bb_plot
-
-
-emiss_temp_widget = pn.widgets.IntSlider(
-    name="Emission Temperature", value=288, start=250, end=300
-)
-bound_plot = pn.bind(update_plot, emiss_temp=emiss_temp_widget)
-
-pn.Row(emiss_temp_widget, bound_plot)
-
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 3
-      1 # @markdown Make sure you execute this cell to enable the widget!
-----> 3 hv.extension("bokeh")
-      5 # define constants used in Planck's Law
-      6 h = 6.626075e-34  # J s
-
-NameError: name 'hv' is not defined
-
-
-
-
-
-
-

Questions 1.1: Climate Connection#

-
    -
  1. Recall from Tutorial 1 on Week 1 Day 3 the electromagnetic spectrum (shown below), which displays the different wavelengths of electromagnetic energy. According to our model and noting that 1 micrometer = \(10^{-6}\) meters, with a surface temperature of 288K what type of radiation does Earth primarily emit at?

  2. -
-

Diagram of the Electromagnetic Spectrum -Diagram of the Electromagnetic Spectrum. (Credit: Wikipedia)

-

Click for solution

-
-
-
-

Section 1.2: The Stefan-Boltzmann Law#

-

If we integrate Planck’s Law over all wavelengths and outward angles of emission, the total outgoing longwave radiation (OLR) for a given emission temperature (\(\mathbf{T}\)) follows the Stefan-Boltzmann Law.

-
-(5)#\[\begin{align} -OLR = \sigma T^4 -\end{align}\]
-

Where the Stefan-Boltzmann constant \(\sigma = 5.67 \times 10^{-8} W m^{-2} K^{-4}\).

-

Rearranging the equation above, we can solve for the emission temperature of Earth, \(T\).

-
-(6)#\[\begin{align} -T = \sqrt[4]{\frac{OLR}{\sigma}} -\end{align}\]
-

Using \(OLR = 239 W m^{-2}\), we can calcuate this using python.

-
-
-
# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-sigma = 5.67e-8  # W m^-2 K^-4
-
-# define the outgoing longwave radiation based on observations from the IPCC AR6 Figure 7.2
-OLR = 239  # W m^-2
-
-# plug into equation
-T = (OLR / sigma) ** (1 / 4)
-
-# display answer
-print("Emission Temperature: ", T, "K or", T - 273, "C")
-
-
-
-
-
Emission Temperature:  254.80251510194708 K or -18.19748489805292 C
-
-
-
-
-
-

Questions 1.2: Climate Connection#

-
    -
  1. How does this compare to the actual global mean surface temperature of ~288 \(K\) / 15 \(C\)?

  2. -
  3. Using \(T = 288 K\) would you expect the corresponding outgoing longwave radiation to be higher or lower than the observed 239 \(W m^{-2}\)?

  4. -
  5. What could be accounted for in this model to make it more realistic?

  6. -
-

Click for solution

-
-
-

Coding Exercises 1.2#

-
    -
  1. By modifying the code above and solving for OLR, find the outgoing longwave radiation expected for the observed surface temperature of \(288 K\). This should help you answer Question 2 above.

  2. -
-
-
-
# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-sigma = ...
-
-# define the global mean surface temperature based on observations
-T = ...
-
-# plug into equation
-OLR = ...
-
-# display answer
-print("OLR: ", OLR, "W m^2")
-
-
-
-
-
OLR:  Ellipsis W m^2
-
-
-
-
-

Click for solution

-
-
-
-
-

Section 2 : The Greenhouse Effect#

-

The expected surface temperature using the blackbody radiation model is much colder than we observe it to be. In this model we assumed there is nothing that lies between Earth’s surface and space that interacts with Earth’s emitted radiation. From the initial lecture on the global energy budget we know this is not true. Earth has an atmosphere, and within it are many gases that interact with radiation in the infrared range at which Earth primarily emits. The effect of these gases on radiation, called the greenhouse effect, is what warms earth to a habitable temperature.

-

The gases that are responsible for this (carbon dioxide, water vapor, methane, ozone, nitrous oxide, and chloroflourocarbons) are termed greenhouse gases. The figure below shows the contributions to the global surface air temperature change relative to 1750. We can see that all of these gases have contributed positively, that is towards warming Earth. Also note that the total curve tracks the volcano curve quite well until around the 1850s when industrialization took hold. The total and volcanic curves begin to deviate here, and after the mid 1900s the total curve begins tracking the total anthropogenic curve instead.

-

Attributed global surface air temperature change (GSAT)
-Figure 7.8 | Attributed global surface air temperature change (GSAT) from 1750 to 2019 produced using the two-layer emulator (Supplementary Material 7.SM.2), forced with ERF derived in this chapter (displayed in Figure 2.10) and climate response constrained to assessed ranges for key climate metrics described in Cross-Chapter Box 7.1. The results shown are the medians from a 2237-member ensemble that encompasses uncertainty in forcing and climate response (year-2019 best estimates and uncertainties are shown in Figure 7.7 for several components). Temperature contributions are expressed for carbon dioxide (CO2), methane (CH4), nitrous oxide (N2O), other well-mixed greenhouse gases (WMGHGs), ozone (O3), aerosols, and other anthropogenic forcings, as well as total anthropogenic, solar, volcanic, and total forcing. Shaded uncertainty bands showvery likely (5–95%)ranges. Further details on data sources and processing are available in the chapter data table (Table 7.SM.14). (Credit IPCC)

-

As shown above, greenhouse gases are incredibly important for regulating Earth’s energy balance and temperature. A first approach is to model the greenhouse effect on outgoing longwave radiation (OLR) to space by adding a transmissivity coefficient. The transmissivity coeficient (\(\mathbf{\tau}\)) is the fraction of -the radiation emitted from Earth that actually makes it to space. This coefficient \(\mathbf{\tau}\) is a number that lies between 0 and 1, and represents the effects of all the greenhouse gases on radiation, rather than including them explicity in the model. This approach is called a parametrization.

-

Applying this to the original model for blackbody radiation, the modified model is

-
-(7)#\[\begin{align} -OLR = \tau \sigma T^4 -\end{align}\]
-

Using \(OLR = 239 W m^{-2}\) and \(T = 288 K\), we can estimate \(\tau\).

-
-
-
# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-sigma = 5.67e-8  # W m^-2 K^-4
-
-# define the outgoing longwave radiation based on observations from the IPCC AR6 Figure 7.2
-OLR = 239  # W m^-2
-
-# define the emission temperature based on observtions of global mean surface temperature
-T = 288  # K
-
-# plug into equation
-tau = OLR / (sigma * T**4)  # unitless number between 0 and 1
-
-# display answer
-print("Transmissivity Coefficient: ", tau)
-
-
-
-
-
Transmissivity Coefficient:  0.6126957827090973
-
-
-
-
-
-

Questions 2.1: Climate Connection#

-
    -
  1. For a generic planet, what could be said about the planet’s atmosphere when \(\tau\) is close to 1? Close to 0? Use the OLR seen at the top of the atmosphere in your answer.

  2. -
  3. In terms of energy received from the sun, what does only modifying the OLR to account for the greenhouse effect imply? Are there any greenhouse gases you think would make this implication problematic?

  4. -
  5. Is there any other part of the atmosphere aside from greenhouse gases that we have not discussed that would also affect \(\tau\)?

  6. -
-

Click for solution

-
-
-

Coding Exercises 2.1#

-
    -
  1. Using list comprehension, calculate the OLR for three values of \(\tau = 0.2,0.6114,0.8\). Then plot this on a bar chat to compare. This should help you answer question 1 above. Hint: what is list comprehension?

  2. -
-
-
-
# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-sigma = ...
-
-# define the emission temperature based on observtions of global mean surface temperature
-T = ...
-
-# define values of tau
-tau = ...
-
-# get values of OLR from tau using list comprehension
-OLR = ...
-
-# convert tau to list of strings using list comprehension so we can create a categorical plot
-tau = ...
-
-fig, ax = plt.subplots()
-_ = ...
-ax.set_xlabel("Transmissivity")
-ax.set_ylabel("Outgoing Longwave Radiation ($W m^{-2}$)")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 16
-     13 # convert tau to list of strings using list comprehension so we can create a categorical plot
-     14 tau = ...
----> 16 fig, ax = plt.subplots()
-     17 _ = ...
-     18 ax.set_xlabel("Transmissivity")
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-

Bonus: Blackbody Radiation Coding Exercise#

-

By defining a function for Planck’s Law, plot the blackbody radiation curve for the sun, assuming an emission temperature of 5800K. Underlay an approximation of the visible range from the electromagnetic spectrum. This exercise should help you understand why we see in color as well as why the sun’s radiation headed towards Earth is called incoming shortwave radiation.

-
-
-
# define the emission temperature of the sun
-T_sun = ...
-
-
-# define constants used in Planck's Law
-h = 6.626075e-34  # J s
-c = 2.99792e8  # m s^-1
-k = 1.3804e-23  # W K^-1
-
-
-# define the function for Planck's Law that returns the intensity as well
-# as the peak wavelength defined by Wien's Law
-def planck(wavelength, temperature):
-    ...
-    intensity = ...
-    lpeak = ...
-    return intensity, lpeak
-
-
-# generate x-axis in increments from 1um to 100 micrometer in 1 nm increments
-# starting at 1 nm to avoid wav = 0, which would result in division by zero.
-wavelengths = np.arange(1e-7, 4e-6, 1e-9)
-
-# intensity and peak radiating wavelength at different temperatures
-intensity, lpeak = planck(wavelengths, T_sun)
-
-# get the intensity at peak wavelength to limit the lines
-Ipeak, _ = planck(lpeak, T_sun)
-
-# plot an approximation of the visible range by defining a dictionary with
-# wavelength ranges and colors
-rainbow_dict = {
-    (0.4, 0.44): "#8b00ff",
-    (0.44, 0.46): "#4b0082",
-    (0.46, 0.5): "#0000ff",
-    (0.5, 0.57): "#00ff00",
-    (0.57, 0.59): "#ffff00",
-    (0.59, 0.62): "#ff7f00",
-    (0.62, 0.75): "#ff0000",
-}
-for wv_range, rgb in rainbow_dict.items():
-    plt.axvspan(*wv_range, color=rgb, ec="none")
-
-fig, ax = plt.subplots()
-# add in wiens law
-_ = ...
-
-# plot intensity curve
-_ = ...
-
-ax.set_xlabel("Wavelength ($\mu m$)", fontsize=20, labelpad=30)
-ax.set_ylabel("$B_\lambda(\lambda,T)$ $(W/(m^3 steradian)$", fontsize=20)
-
-ax.set_title("Spectral Radiance")
-
-# add legend
-ax.legend(bbox_to_anchor=(0.5, 0.5))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 22
-     17     return intensity, lpeak
-     20 # generate x-axis in increments from 1um to 100 micrometer in 1 nm increments
-     21 # starting at 1 nm to avoid wav = 0, which would result in division by zero.
----> 22 wavelengths = np.arange(1e-7, 4e-6, 1e-9)
-     24 # intensity and peak radiating wavelength at different temperatures
-     25 intensity, lpeak = planck(wavelengths, T_sun)
-
-NameError: name 'np' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -Solution hint -
-
-

Summary#

-

In this tutorial, we’ve learned about the principles of blackbody and greenhouse radiation models, which are crucial to understanding Earth’s energy emission. We explored the concept of emission temperature and how it’s calculated using observed outgoing longwave radiation. We discovered that the simple blackbody model needs to be augmented by considering the greenhouse effect to accurately represent Earth’s observed surface temperature. This led us to incorporate the transmissivity coefficient, a representation of greenhouse gases’ impact, into our model.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.html b/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.html deleted file mode 100644 index cb850d969..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial2.html +++ /dev/null @@ -1,1511 +0,0 @@ - - - - - - - - - - - - Tutorial 2 : Energy Balance — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2 : Energy Balance#

-

Week 1, Day 5, Climate Modeling

-

Content creators: Jenna Pearson

-

Content reviewers: Dionessa Biton, Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan

-

Content editors: Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial students will learn about the components that define energy balance, including insolation and albedo.

-

By the end of this tutorial students will be able to:

-
    -
  • Calculate the albedo of Earth based on observations.

  • -
  • Define and find the equilibrium temperature under the assumption of energy balance.

  • -
  • Understand the relationship between transmissivity and equilibrium temperature.

  • -
-
-
-

Setup#

-
-
-
# imports
-import xarray as xr  # used to manipulate data and open datasets
-import numpy as np  # used for algebra and array operations
-import matplotlib.pyplot as plt  # used for plotting
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import xarray as xr  # used to manipulate data and open datasets
-      3 import numpy as np  # used for algebra and array operations
-      4 import matplotlib.pyplot as plt  # used for plotting
-
-ModuleNotFoundError: No module named 'xarray'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Energy Balance#

-
-

Video 1: Energy Balance#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Energy Balance
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1 : A Radiating Sun#

-
-

Section 1.1: Incoming Solar Radiation (Insolation) and Albedo (\(\alpha\))#

-

Just as Earth emits radiation, so does the sun. The incoming solar radiation, called insolation. From the ‘All Sky’ Energy budget shown below, this is observed to be \(Q = 340 W m^{-2}\).

-

Some of this radiation is reflected back to space (for example off of ice and snow or clouds).

-

From the ‘All Sky’ energy budget below, the amount reflected back is \(F_{ref} = 100 W m^{-2}\).

-

Global Mean Energy Budget -Figure 7.2 | Schematic representation of the global mean energy budget of the Earth (upper panel), and its equivalent without considerations of cloud effects (lower panel). Numbers indicate best estimates for the magnitudes of the globally averaged energy balance components in W m–2 together with their uncertainty ranges in parentheses (5–95% confidence range), representing climate conditions at the beginning of the 21st century. Note that the cloud-free energy budget shown in the lower panel is not the one that Earth would achieve in equilibrium when no clouds could form. It rather represents the global mean fluxes as determined solely by removing the clouds but otherwise retaining the entire atmospheric structure. This enables the quantification of the effects of clouds on the Earth energy budget and corresponds to the way clear-sky fluxes are calculated in climate models. Thus, the cloud-free energy budget is not closed and therefore the sensible and latent heat fluxes are not quantified in the lower panel. Figure adapted from Wild et al. (2015, 2019). (Credit: IPCC AR6 Report)

-

The fraction of reflected radiation is captured by the albedo (\(\mathbf{\alpha}\))

-
-(8)#\[\begin{align} -\alpha = \frac{F\_{ref}}{Q} -\end{align}\]
-

Albedo is a unitless number between 0 and 1. We can use this formula to find the albedo of Earth.

-
-
-
# define the observed insolation based on observations from the IPCC AR6 Figure 7.2
-Q = 340  # W m^-2
-
-# define the observed reflected radiation based on observations from the IPCC AR6 Figure 7.2
-F_ref = 100  # W m^-2
-
-# plug into equation
-alpha = F_ref / Q  # unitless number between 0 and 1
-
-# display answer
-print("Albedo: ", alpha)
-
-
-
-
-
Albedo:  0.29411764705882354
-
-
-
-
-
-

Questions 1.1: Climate Connection#

-
    -
  1. Keeping insolation (\(Q\)) constant, what does a low albedo imply? What about a high albedo?

  2. -
  3. There are two components to albedo, the reflected radiation in the numerator and the insolation in the denomenator. Do you think one or both of these have changed over Earth’s history?

  4. -
-

Click for solution

-
-
-
-

Section 1.2 : Absorbed Shortwave Radiation (ASR)#

-

The absorbed shortwave radiation (ASR) is the amount of this isolation that is not reflected, and actually makes it to Earth’s surface. Thus,

-
-(9)#\[\begin{align} -ASR = Q-F\_{ref} = (1-\alpha)Q -\end{align}\]
-

From observations, we can esimate the absorbed shortwave radiation.

-
-
-
# plug into equation
-ASR = (1 - alpha) * Q
-
-# display answer
-print("Absorbed Shortwave Radiation: ", ASR, " W m^-2")
-
-
-
-
-
Absorbed Shortwave Radiation:  239.99999999999997  W m^-2
-
-
-
-
-
-

Questions 1.2: Climate Connection#

-
    -
  1. Compare the value of ASR to the observed OLR of \(239 W m^{-2}\). Is it more or less? What do you think this means?

  2. -
  3. Does this model take into account any effects of gases in that atmosphere on the incoming shortwave radiation that makes it to Earth’s surface? Are there any greenhouse gases you think are important and should be included in more complex models?

  4. -
-

Click for solution

-
-
-
-
-

Section 2 : Energy Balance#

-
-

Section 2.1: Equilibrium Temperature#

-

Energy Balance is achieved when radiation absorbed by Earth’s surface (ASR) is equal to longwave radiation going out to space (OLR). That is

-
-(10)#\[\begin{align} -ASR = OLR -\end{align}\]
-

By substituting into the equations from previous sections, we can find the surface temperature of Earth needed to maintain this balance. This is called the equilibrium temperature ( \(\mathbf{T_{eq}}\) ).

-

Recall \(OLR = \tau\sigma T^4\) and \(ASR = (1-\alpha)Q\). The equilibrium temperature is the temperature the system would have if energy balance was perfectly reached. Assuming energy balance, we will call the emission temperature denoted previously the equilibrium temperature (\(T_{eq}\)) instead. Thus,

-
-(11)#\[\begin{align} -(1-\alpha)Q = ASR = OLR = \tau\sigma T\_{eq}^4 -\end{align}\]
-

Solving for \(T_{eq}\) we find

-
-(12)#\[\begin{align} -T\_{eq} = \sqrt[4]{\frac{(1-\alpha)Q}{\tau\sigma}} -\end{align}\]
-

Let’s calculate what this should be for Earth using observations:

-
-
-
# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-sigma = 5.67e-8  # W m^-2 K^-4
-
-# define transmissivity (calculated previously from observations in tutorial 1)
-tau = 0.6127  # unitless number between 0 and 1
-
-# plug into equation
-T_eq = (((1 - alpha) * Q) / (tau * sigma)) ** (1 / 4)
-
-# display answer
-print("Equilibrium Temperature: ", T_eq, "K or", T_eq - 273, "C")
-
-
-
-
-
Equilibrium Temperature:  288.300287595812 K or 15.300287595811994 C
-
-
-
-
-
-
-
-

Section 3 : Climate Change Scenario#

-
-

Section 3.1: Increasing Greenhouse Gas Concentrations#

-

Assume due to the increasing presence of greenhouse gases in the the atmosphere, that \(\tau\) decreases to \(0.57\).

-

We can then use our climate model and python to find the new equilibrium temperature.

-
-
-
# define transmissivity (assupmtion in this case)
-tau_2 = 0.57  # unitless number between 0 and 1
-
-# plug into equation
-T_eq_2 = (((1 - alpha) * Q) / (tau_2 * sigma)) ** (1 / 4)
-
-# display answer
-print("New Equilibrium Temperature: ", T_eq_2, "K or", T_eq_2 - 273, "C")
-
-
-
-
-
New Equilibrium Temperature:  293.5542225759401 K or 20.554222575940116 C
-
-
-
-
-
-

Questions 3.1: Climate Connection#

-
    -
  1. Does a reduction in the transmissivity, \(\tau\), imply a decrease or increase in OLR?

  2. -
  3. How does the new equilibrium temperature compare to that calculated previously? Why do you think this is?

  4. -
-

Click for solution

-
-
-

Coding Exercises 3.1#

-
    -
  1. Plot the equilibrium temperature as a function of \(\tau\), for \(\tau\) ranging from zero to one.

  2. -
-
-
-
# define the observed insolation based on observations from the IPCC AR6 Figure 7.2
-Q = ...
-
-# define the observed reflected radiation based on observations from the IPCC AR6 Figure 7.2
-F_ref = ...
-
-# define albedo
-alpha = ...
-
-# define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-sigma = ...
-
-
-# define a function that returns the equilibrium temperature and takes argument tau
-def get_eqT(tau):
-    return ...
-
-
-# define tau as an array extending from 0 to 1 with spacing interval 0.01
-tau = ...
-
-# use list comprehension to obtain the equilibrium temperature as a function of tau
-eqT = ...
-
-fig, ax = plt.subplots()
-# Plot tau vs. eqT
-_ = ...
-ax.set_xlabel(...)
-ax.set_ylabel(...)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 25
-     22 # use list comprehension to obtain the equilibrium temperature as a function of tau
-     23 eqT = ...
----> 25 fig, ax = plt.subplots()
-     26 # Plot tau vs. eqT
-     27 _ = ...
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-
-

Summary#

-

In this tutorial, you explored the fundamentals of Earth’s energy balance. You learned how to calculate Earth’s albedo \(\mathbf{\alpha}\) and how absorbed shortwave radiation contributes to energy balance. You also discovered the concept of equilibrium temperature and it’s relationship to energy balance. The tutorial also highlighted the impact of increasing greenhouse gases on the equilibrium temperature.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.html b/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.html deleted file mode 100644 index 9b1dda1f0..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial3.html +++ /dev/null @@ -1,1919 +0,0 @@ - - - - - - - - - - - - Tutorial 3 : A Zero-Dimensional Energy Balance Model — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3 : A Zero-Dimensional Energy Balance Model#

-

Week 1, Day 5, Climate Modeling

-

Content creators: Jenna Pearson

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Agustina Pesce, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan

-

Content editors: Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial students will learn about the heat capacity of the atmosphere and oceans, how this related to temperature changes over time, and set up their first climate model.

-

By the end of this tutorial students will be able to:

-
    -
  • Calculate the heat capacity of the ocean and atmosphere.

  • -
  • Create and run a time-dependent model of the change in global mean surface temperature in response to energy imbalances.

  • -
  • Describe the influence of transmissivity and albedo on the equilibrium temperature from this model.

  • -
  • Bonus: What equilibrium climate sensitivity is and how to find it using the model.

  • -
-
-
-

Setup#

-
-
-
# imports
-import xarray as xr  # used to manipulate data and open datasets
-import numpy as np  # used for algeba and array operations
-import matplotlib.pyplot as plt  # used for plotting
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 2
-      1 # imports
-----> 2 import xarray as xr  # used to manipulate data and open datasets
-      3 import numpy as np  # used for algeba and array operations
-      4 import matplotlib.pyplot as plt  # used for plotting
-
-ModuleNotFoundError: No module named 'xarray'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: A Zero-Dimensional Energy Balance Model#

-
-

Video 1: A Zero-Dimensional Energy Balance Model#

-
-
- - -Hide code cell source - -
-
# @title Video 1: A Zero-Dimensional Energy Balance Model
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1 : Building the Model#

-
-

Section 1.1 : Moving Forward in Time#

-

One of the crucial things missing from the simple model we have looked at so far is it’s ability to change with time. As the composition of the atmosphere (among other things) changes with time, in response, so does the energy balance and global mean surface temperature. This is shown by the thick black lines in the figure below, where the time series of observed global mean surface air temperature change from the 1850-1900 reference period is plotted. Figures like this are called ‘hockey stick’ figures due to their shape: a relatively stable period followed by a steep increase. In order to incorporate this into our model, we need to include a mathetmatical representation of how the change in energy relates to a change in temperature over time.

-

Observerd and simulated change in temparture -Figure 3.4 | Observed and simulated time series of the anomalies in annual and global mean surface air temperature (GSAT). All anomalies are differences from the 1850–1900 time-mean of each individual time series. The reference period 1850–1900 is indicated by grey shading. (a) Single simulations from CMIP6 models (thin lines) and the multi-model mean (thick red line). Observational data (thick black lines) are from the Met Office Hadley Centre/Climatic Research Unit dataset (HadCRUT5), and are blended surface temperature (2 m air temperature over land and sea surface temperature over the ocean). All models have been subsampled using the HadCRUT5 observational data mask. Vertical lines indicate large historical volcanic eruptions. CMIP6 models which are marked with an asterisk are either tuned to reproduce observed warming directly, or indirectly by tuning equilibrium climate sensitivity. Inset: GSAT for each model over the reference period, not masked to any observations. (b) Multi-model means of CMIP5 (blue line) and CMIP6 (red line) ensembles and associated 5th to 95th percentile ranges (shaded regions). Observational data are HadCRUT5, Berkeley Earth, National Oceanic and Atmospheric Administration NOAAGlobalTemp-Interim and Kadow et al. (2020). Masking was done as in (a). CMIP6 historical simulations were extended with SSP2-4.5 simulations for the period 2015–2020 and CMIP5 simulations were extended with RCP4.5 simulations for the period 2006–2020. All available ensemble members were used (see Section 3.2). The multi-model means and percentiles were calculated solely from simulations available for the whole time span (1850–2020). Figure is updated from Bock et al. (2020), their Figures 1 and 2. CC BY 4.0https://creativecommons.org/licenses/by/4.0/. Further details on data sources and processing are available in the chapter data table (Table 3.SM.1). (Credit IPCC Report AR6)

-

We can represent the change in temperature over time as the net heat input or loss from radiation (\(ASR-OLR\)) multiplied by the heat capacity of the Earth system.

-

As we learned in Day 2 of this week, the heat capacity of a medium is its ability to increase in temperature given an input of heat. Not all components of the Earth system (for example land, ocean, atmosphere) have the same heat capacity.

-

Mathematically, the rate of change of global mean surface temperature (\(T\)) over time is given as

-
-(13)#\[\begin{align} -\text{rate of change of }T = \frac{1}{\text{heat capacity}}\cdot (\text{energy flux in - energy flux out}) = \frac{1}{C} \cdot ASR - OLR -\end{align}\]
-

where \(C\) is the heat capacity of the Earth system. Note here that when \(ASR > OLR\), then the system is gaining heat. Conversely when \(ASR < OLR\), then the system is losing heat over time.

-

To calculate the heat capacity for the Earth system, we will assume the it is a combination of atmosphere and ocean only, that is \(C = C_{oc} + C_{atmo}\).

-

Generally, the heat capacity of a medium is the specific heat of that medium times the total mass.

-

For the atmosphere we have \(C_{atm} = c_{atm} \cdot \frac{W_{atm}}{g} \) where \(c_{atm}\) is the specific heat of the atmosphere, \(W_{atm}\) is the weight of a column of air, and \(g\) is the acceleration due to gravity.

-

For the ocean we have \(C_{oc} = c_{oc} \cdot \rho_{oc} \cdot d_{oc}\) where \(c_{oc}\) is the specific heat of the ocean, \(\rho_{oc}\) is the density of seawater, and \(d_{oc}\) is a representative depth of the ocean.

-

We will use these definitions to find the heat capacities of the atmosphere and ocean and to refresh what we learned in Day 2.

-
-
-
# heat capacity of the ocean
-c_oc = 3850  #  specific heat of seawater in J/kg/K
-rho_oc = 1025  #  average density of seawater in kg/m3
-d_oc = 70  #  depth of water in m (here representative of the mized layer)
-C_oc = c_oc * rho_oc * d_oc  #  heat capacity of the ocean
-
-# heat capacity of the atmosphere
-c_atm = 1004  #  specific heat of the atmosphere at constant pressure in J/kg/K
-W_atm = 100000  #  weight (pressure) of atmospheric column in Pa
-g = 9.81  #  acceleration due to gravity in m/s^2
-C_atm = c_atm * (W_atm / g)  #  heat capacity of the atmosphere
-
-# total heat capacity
-C = C_oc + C_atm
-
-# print results.
-
-print("Ocean Heat Capactiy:      ", C_oc, " J m^-2K^-2")
-print("Atmosphere Heat Capacity: ", C_atm, "   J m^-2K^-2")
-print("Total Heat Capactiy:      ", C, " J m^-2K^-2")
-
-
-
-
-
Ocean Heat Capactiy:       276237500  J m^-2K^-2
-Atmosphere Heat Capacity:  10234454.638124362    J m^-2K^-2
-Total Heat Capactiy:       286471954.63812435  J m^-2K^-2
-
-
-
-
-
-

Coding Exercises 1.1#

-
    -
  1. Calculate the depth of the ocean needed for the ocean to have the same heat capacity at the atmosphere.

  2. -
-
-
-
# heat capacity of the atmosphere
-c_atm = 1004  #  specific heat of the atmosphere at constant pressure in J/kg/K
-W_atm = 100000  #  weight (pressure) of atmospheric column in Pa
-g = 9.81  #  height of atmosphere in m (representative of )
-C_atm = c_atm * (W_atm / g)  #  heat capacity of the atmosphere
-
-# find the depth of the ocean for equivalent atmospheric heat capacity
-c_oc = 3850  #  specific heat of seawater in J/kg/K
-rho_oc = 1025  #  average density of seawater in kg/m3
-
-d_oc = ...
-d_oc
-
-
-
-
-
Ellipsis
-
-
-
-
-

Click for solution

-
-
-

Questions 1.1: Climate Connection#

-
    -
  1. In your own words, describe what the answer to your coding exercise means.

  2. -
-

Click for solution

-
-
-
-

Section 1.2 : The Numerical Model#

-

Knowing the heat capacity, and the descriptions of \(OLR\) and \(ASR\) from previous tutorials, we can write the equation

-
-(14)#\[\begin{align} -\text{rate of change }T = \frac{\text{change in }T}{\text{change in time}}=\frac{dT}{dt}= \frac{1}{C}(ASR - OLR) -\end{align}\]
-

Numerically, we can use this equation to compute the global mean surface temperature after a small interval of time by adding on the amount of energy gained or lost multiplied by the time interval itself.

-

The particular method of numerically defining the time and temperature intervals (changes) is called discretization, and the way we have chosen to do this is called the Euler method. The exact details of this method are beyond the scope of this tutorial, and we will use the method without further elaboration.

-

The Euler method assumes we can use \(\text{change in }T = T_{n+1} - T_{n}\) and \(\text{change in t} = t_{n+1} - t_{n}\) where \(t\) is time. Thus, if we know the time interval and the current temperature (\(T_n\)), we can predict the temperature at the end of our time interval, (\(T_{n+1}\)).

-
-
-
# define the time interval, currently one year expressed in seconds
-dt = 60.0 * 60.0 * 24.0 * 365.0
-
-# define albedo
-alpha = 0.2941  # unitless number between 0 and 1 (calculated previously from observations in tutorial 2)
-
-# define transmissivity (calculated previously from observations in tutorial 1)
-tau = 0.6127  # unitless number between 0 and 1
-
-
-# define a function for absorbed shortwave radiation (ASR)
-def ASR(alpha, Q):
-    return (1 - alpha) * Q
-
-
-# define a function for outgoing longwave raditation (OLR)
-def OLR(tau, T):
-    # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-    sigma = 5.67e-8  # W m^-2 K^-4
-
-    return tau * sigma * T**4
-
-
-# create a function to find the new tempeature based on the previous using Euler's method.
-def step_forward(T, alpha, tau, dt):
-
-    # define the observed insolation based on observations from the IPCC AR6 Figure 7.2
-    Q = 340  # W m^-2
-
-    # find the new temperature using forward Euler method
-    T_new = T + dt / C * (ASR(alpha, Q) - OLR(tau, T))
-
-    return T_new
-
-
-
-
-

We can now use a loop to apply this function many times over by specifying an initial temperature and a time interval. Note we will be using lists to do so.

-
-
-
# define the number of timesteps (currently years) to run the model
-numtsteps = 15
-
-# for converting number of seconds in a year
-sec_2_yr = 3.154e7
-
-# set the intial temperature (initial condition)
-T_series = [288]
-
-# set the initial time to 0
-t_series = [0]
-
-# run the model
-for n in range(numtsteps):
-
-    # calculate and append the time since running the model, dependent on dt and the numtsteps
-    t_series.append((n + 1) * dt / sec_2_yr)
-
-    # calculate and append the new temperature using our pre-defined function
-    T_series.append(step_forward(T_series[n], alpha=alpha, tau=tau, dt=dt))
-
-# display the temeprature time series
-print(T_series)
-
-
-
-
-
[288, 288.1105634820389, 288.18070153127155, 288.22517079984357, 288.25335571129256, 288.2712155880614, 288.2825312527962, 288.28970000469195, 288.29424133262887, 288.2971181140696, 288.29894041951593, 288.300094747791, 288.30082594344617, 288.3012891080957, 288.3015824915692, 288.30176832972967]
-
-
-
-
-
-
-
# dispay the time series
-print(t_series)
-
-
-
-
-
[0, 0.9998731769181991, 1.9997463538363982, 2.999619530754597, 3.9994927076727964, 4.999365884590995, 5.999239061509194, 6.999112238427394, 7.998985415345593, 8.998858592263792, 9.99873176918199, 10.99860494610019, 11.998478123018389, 12.998351299936589, 13.998224476854787, 14.998097653772987]
-
-
-
-
-
-
-
# plot the results
-fig, ax = plt.subplots()
-ax.plot(t_series, T_series)
-ax.set_xlabel("Years")
-ax.set_ylabel("Global mean temperature (K)");
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # plot the results
-----> 2 fig, ax = plt.subplots()
-      3 ax.plot(t_series, T_series)
-      4 ax.set_xlabel("Years")
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Questions 1.2#

-
    -
  1. Do you think the time step (interval) we have used will affect the solution? If so, how?

  2. -
-

Click for solution

-
-
-

Coding Exercise 1.2#

-
    -
  1. Using a for loop, run the model for 15 years with two different three intervals (\(dt\)) of a half year, 1 year and 5 years and plot the results. Note you will have to change the number of timesteps used when changing dt so that the model runs for the same amount of time. Plot your results on the same figure.

  2. -
-
-
-
# one year expressed in seconds
-one_yr = 60.0 * 60.0 * 24.0 * 365.0
-
-# legend labels
-labels = ["dt = half-year", "dt = one year", "dt = five years"]
-
-# define the number of timesteps (years) to run the model
-numtsteps = np.array([10, 5, 1]) * 3
-
-# for converting number of seconds in a year
-sec_2_yr = ...
-
-fig, ax = plt.subplots()
-# loop through each choice of time step
-for dd, dt_2 in enumerate([one_yr * 0.5, one_yr, one_yr * 5]):
-
-    # set the intial temperature (initial condition)
-    ...
-
-    # set the initial time to 0
-    ...
-
-    # run the model
-    for n in range(numtsteps[dd]):
-
-        # calculate and append the time since running the model, dependent on dt and the numtsteps
-        ...
-
-        # calculate and append the new temperature using our pre-defined function
-        ...
-
-    ax.plot(t_series, T_series, label=labels[dd])
-
-ax.set_xlabel("Years")
-ax.set_ylabel("Global mean temperature (K)")
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 8
-      5 labels = ["dt = half-year", "dt = one year", "dt = five years"]
-      7 # define the number of timesteps (years) to run the model
-----> 8 numtsteps = np.array([10, 5, 1]) * 3
-     10 # for converting number of seconds in a year
-     11 sec_2_yr = ...
-
-NameError: name 'np' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-
-

Section 2: Revisiting the Climate Change Scenario from Tutorial 2#

-
-

Section 2.1: Enhanced Greenhouse Effect#

-

In tutorial 2 we looked at how changing the transmissivity (\(\tau\)) affected the equilibrium temperature. Now we can use our time-dependent model to investigate this more fully. Reuse the model, this time setting \(\tau=0.57\)

-
-
-
# define transmissivity (calculated previously from observations)
-tau_2 = 0.57  # unitless number between 0 and 1
-
-# define the number of timesteps (currently years) to run the model
-numtsteps = 15
-
-# set the intial temperature (initial condition)
-T_series = [288]
-
-# set the initial time to 0
-t_series = [0]
-
-# run the model
-for n in range(numtsteps):
-
-    # calculate and append the time since running the model, dependent on dt and the numtsteps
-    t_series.append((n + 1) * dt / sec_2_yr)
-
-    # calculate and append the new temperature using our pre-defined function
-    T_series.append(step_forward(T_series[n], alpha=alpha, tau=tau_2, dt=dt))
-
-fig, ax = plt.subplots()
-ax.plot(t_series, T_series)
-
-ax.set_xlabel("Years")
-ax.set_ylabel("Global mean temperature (K)");
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 22
-     19     # calculate and append the new temperature using our pre-defined function
-     20     T_series.append(step_forward(T_series[n], alpha=alpha, tau=tau_2, dt=dt))
----> 22 fig, ax = plt.subplots()
-     23 ax.plot(t_series, T_series)
-     25 ax.set_xlabel("Years")
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Questions 2.1#

-
    -
  1. How does the long-term temperature here compare to the value you found from tutorial 2?

  2. -
-

Click for solution

-
-
-
-
-

Bonus Coding Exercise: Equilibrium Climate Sensitivity#

-

Here we define the equilibrium climate sensitivity as the long-term global warming (equilibrium temperature increase) caused by a doubling of carbon dioxide above its pre-industrial concentration. The impact of a doubling of carbon dioxide on these energy flows is measured by a radiative forcing. Here a positive radiation forcing leads to warming, and a negative radiative forcing leads to cooling.

-

The equilibrium climate sensitivity depends on a number of things, including physics and feedbacks of the model used. In the following exercise, you will calculate the equilibrium climate sensitivity of our model.

-
    -
  1. Write a function called step_forward() as from above, and then create another function that adds in a radiative forcing to the difference between ASR and OLR and call it step_forward_forced(). Make sure both functions output the energy balance of the model. Consistent with the IPCC AR6, use an effective radiative forcing of 3.93 \(Wm^2\), where effective means the climate system, but not the surface temperature, has been allowed to adjust.

  2. -
-
-
-
# define your functions and constants
-
-# define albedo
-alpha = 0.2941  # unitless number between 0 and 1 (calculated previously from observations in tutorial 2)
-
-# define transmissivity (calculated previously from observations in tutorial 1)
-tau = 0.6127  # unitless number between 0 and 1
-
-# effective radiative forcing for a doubling of CO2
-F = 3.93  # W/m^2
-
-# define the time interval, one year expressed in seconds
-dt = 60.0 * 60.0 * 24.0 * 365.0
-
-# for converting number of seconds in a year
-sec_2_yr = 3.154e7
-
-
-# create a function to find the new tempeature based on the previous using Euler's method.
-def step_forward(T, alpha, tau, dt):
-
-    # define the observed insolation based on observations from the IPCC AR6 Figure 7.2
-    ...
-
-    # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-    ...
-
-    Ftoa = ...
-
-    T_new = ...
-
-    return ...
-
-
-# create a function to find the new tempeature based on the previous using Euler's method.
-def step_forward_forced(T, alpha, tau, dt):
-
-    # define the observed insolation based on observations from the IPCC AR6 Figure 7.2
-    ...
-
-    # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-    ...
-
-    Ftoa = ...
-
-    T_new = ...
-
-    return ...
-
-
-
-
-

Click for solution

-
    -
  1. Using an initial temperature of 288K, run the model to equilibrium. Make sure your model is in equilbrium by checking that the energy balance is near zero.

  2. -
-
-
-
# run the model to equilibrium without forcing and begining with T(0) = 288K
-
-# define the number of timesteps (years) to run the model
-numtsteps = 40
-
-# set the intial temperature (initial condition)
-T_series = [288]
-
-# set the initial time to 0
-t_series = [0]
-
-# run the model
-for n in range(numtsteps):
-
-    # calculate and append the time since running the model, dependent on dt and the numtsteps
-    t_series.append(...)
-
-    # calculate and append the new temperature using our pre-defined function and get energy balance
-    ...
-    T_series.append(...)
-
-print(...)
-
-
-
-
-
Ellipsis
-
-
-
-
-

Click for solution

-
    -
  1. Run the forced model equilibrium using the unforced equilibrium temperature as your inital condition and the step_forward_forced() function you wrote above.

  2. -
-
-
-
# define the number of timesteps (years) to run the model
-numtsteps = 40
-
-# set initial condition (temperature) to the equilibrium value from the last run without forcing
-T_series_forced = [T_series[-1]]
-
-# set the initial time to 0
-t_series_forced = [0]
-
-# run the model
-for n in range(numtsteps):
-
-    # calculate and append the time since running the model, dependent on dt and the numtsteps
-    t_series_forced.append(...)
-
-    # calculate and append the new temperature using our pre-defined function and get energy balance
-    ...
-    T_series_forced.append(...)
-
-print(...)
-
-
-
-
-
Ellipsis
-
-
-
-
-
-
-
# run the model to equilibrium without forcing and begining with T(0) = 288K
-
-# define the number of timesteps (years) to run the model
-numtsteps = 40
-
-# set initial condition (temperature) to the equilibrium value from the last run without forcing
-T_series_forced = [T_series[-1]]
-
-# set the initial time to 0
-t_series_forced = [0]
-
-# run the model
-for n in range(numtsteps):
-
-    # calculate and append the time since running the model, dependent on dt and the numtsteps
-    t_series_forced.append((n + 1) * dt / sec_2_yr)
-
-    # calculate and append the new temperature using our pre-defined function and get energy balance
-    T_new_forced, Ftoa_forced = step_forward_forced(
-        T_series_forced[n], alpha=alpha, tau=tau, dt=dt
-    )
-    T_series_forced.append(T_new_forced)
-
-print(Ftoa_forced)
-
-
-
-
-
---------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-Cell In[15], line 19
-     16     t_series_forced.append((n + 1) * dt / sec_2_yr)
-     18     # calculate and append the new temperature using our pre-defined function and get energy balance
----> 19     T_new_forced, Ftoa_forced = step_forward_forced(
-     20         T_series_forced[n], alpha=alpha, tau=tau, dt=dt
-     21     )
-     22     T_series_forced.append(T_new_forced)
-     24 print(Ftoa_forced)
-
-TypeError: cannot unpack non-iterable ellipsis object
-
-
-
-
-
    -
  1. Plot the temperature curve from the forced simulation as a function of time.

  2. -
-
-
-
# plot the time series
-fig, ax = plt.subplots()
-...
-
-ax.set_xlabel("Years")
-ax.set_ylabel("Global mean temperature (K)");
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 2
-      1 # plot the time series
-----> 2 fig, ax = plt.subplots()
-      3 ...
-      5 ax.set_xlabel("Years")
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-
-
# plot the time series
-fig, ax = plt.subplots()
-ax.plot(t_series_forced, T_series_forced)
-
-ax.set_xlabel("Years")
-ax.set_ylabel("Global mean temperature (K)");
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 2
-      1 # plot the time series
-----> 2 fig, ax = plt.subplots()
-      3 ax.plot(t_series_forced, T_series_forced)
-      5 ax.set_xlabel("Years")
-
-NameError: name 'plt' is not defined
-
-
-
-
-
    -
  1. Subtract the intial temperature used for your forced simulation from the final temperature after running to equilibrium to get the equilibrium climate sensitivty.

  2. -
-
-
-
# calculate equilibrium climate sensitivity
-print("Equilibrium Climate Sensitivity: ", ...)
-
-
-
-
-
Equilibrium Climate Sensitivity:  Ellipsis
-
-
-
-
-
-
-
# calculate equilibrium climate sensitivity
-print("Equilibrium Climate Sensitivity: ", T_series_forced[-1] - T_series_forced[0])
-
-
-
-
-
---------------------------------------------------------------------------
-TypeError                                 Traceback (most recent call last)
-Cell In[19], line 2
-      1 # calculate equilibrium climate sensitivity
-----> 2 print("Equilibrium Climate Sensitivity: ", T_series_forced[-1] - T_series_forced[0])
-
-TypeError: unsupported operand type(s) for -: 'ellipsis' and 'ellipsis'
-
-
-
-
-
-

Bonus Questions: Climate Connection#

-
    -
  1. How does this compare to the IPCC AR6 estimate of equilibrium climate sensitivity of 2-5 K? Is it higher or lower? Note here it is a temperature difference, so the units of C in the report and K found here are interchangeable.

  2. -
  3. In your own words, describes what this implies with respect to global mean temperatures in our models versus those in used in the IPCC report.

  4. -
  5. What do you think could be missing in our model?

  6. -
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, you explored the relationship between the heat capacity of the atmosphere and oceans and temperature changes over time. You learned how to calculate the heat capacity of these components and used this knowledge to develop a climate model. This model simulates the change in global mean surface temperature in response to energy imbalances. You explored the effects of transmissivity on the equilibrium temperature and discussed equilibrium climate sensitivity.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.html b/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.html deleted file mode 100644 index d621f32ab..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial4.html +++ /dev/null @@ -1,1775 +0,0 @@ - - - - - - - - - - - - Tutorial 4: Climate Feedbacks — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 4: Climate Feedbacks#

-

Week 1, Day 5, Climate Modeling

-

Content creators: Jenna Pearson, Brodie Pearson, and Abigail Bodner

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Will Gregory, Peter Ohue, Agustina Pesce, Derick Temfack, Yunlong Xu, Peizhen Yang, Chi Zhang, Ohad Zivan

-

Content editors: Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial students will learn about climate feedbacks, in particular the Planck and ice-albedo feedbacks. Students will also learn about how variations in the insolation over time can affect the equilibrium temperature of Earth.

-

By the end of this tutorial students will be able to:

-
    -
  • Apply a temperature-dependent albedo within their existing climate model.

  • -
  • Understand the impact of insolation changes on the equilibrium temperature of Earth.

  • -
-
-
-

Setup#

-
-
-
# imports
-
-import xarray as xr  # used to manipulate data and open datasets
-import numpy as np  # used for algeba and array operations
-import matplotlib.pyplot as plt  # used for plotting
-from scipy.optimize import (
-    brentq,
-)  # used for numerical root-finding to get the equilibria
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # imports
-----> 3 import xarray as xr  # used to manipulate data and open datasets
-      4 import numpy as np  # used for algeba and array operations
-      5 import matplotlib.pyplot as plt  # used for plotting
-
-ModuleNotFoundError: No module named 'xarray'
-
-
-
-
-
-

Figure ettings#

-
-

Figure ettings#

-
-
- - -Hide code cell source - -
-
# @title Figure ettings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # @title Figure ettings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Climate Feedbacks#

-
-

Video 1: Climate Feedbacks#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Climate Feedbacks
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Ice-Albedo Feedback#

-
-

Section 1.1: Temperature Dependent Albedo#

-

Our current model only contains one feedback, the ‘Planck feedback’ also called the ‘Planck temperature response’. This feedback encapsulates that a warming of Earth leads to the planet emitting more energy (see Planck’s law from Tutorial 1). In reality, there are many climate feedbacks that contribute to the Earth’s net temperature change due to an energy imbalance. In this tutorial we will focus on incorporating an ice-albedo feedback into our model.

-

When earth’s surface warms, snow and ice melt. This lowers the albedo (\(\mathbf{\alpha}\)), because less solar radiation is reflected off Earth’s surface. This lower albedo causes the climate to warm even more than if the albedo had stayed the same, increasing the snow and ice melt. This is referred to as a positive feedback. Positive feedbacks amplify the changes that are already occurring. This particular feedback is referred to as the ice-albedo feedback.

-

A simple way to parameterize ice-albedo feedback in our model is through a temperature dependent albedo, such as the one defined below (see the tutorial lecture slides for an explanation of why we use this function).

-
-(15)#\[\begin{align} -\alpha = \left\{ - \begin{array}{cl} - 0.1 & T \gt 300 K \\ - 0.1 + (0.7-0.1) \cdot \frac{(T-300)^2}{(240-300)^2} & 240 \le T \le 300 \\ - 0.7 & T \lt 240 - \end{array} - \right. -\end{align}\]
-

Using this new temperature-dependent albedo, we can plot the graphs of absorbed shortwave radiation (ASR) and outgoing longwave radiation (OLR):

-
-
-
# create a array ot temperatures to evaluates the ASR and OLR at
-T = np.arange(200, 360, 2, dtype=np.float64)
-
-# create empty arrays to fill with values later
-ASR_vals = np.zeros_like(T)
-
-# define the slope of the ramp function
-m = (0.7 - 0.3) / (280 - 250)
-
-# define the observed insolation based on observations from the IPCC AR6 Figure 7.2
-Q = 340  # W m^-2
-
-# define transmissivity (calculated previously from observations in tutorial 1)
-tau = 0.6127  # unitless number between 0 and 1
-
-# define a function for absorbed shortwave radiation (ASR)
-def ASR(Q, T):
-    # define function for albedo
-    if T >= 300:  # temperature of very warm and ice free earth.
-        alpha = 0.1  # average albedo of land and sea without ice
-    elif T > 240:  # temperature of Earth to sustain permafrost and sea ice everywhere.
-        alpha = 0.1 + (0.7 - 0.1) * (T - 300) ** 2 / (240 - 300) ** 2
-    else:
-        alpha = 0.7  # average albedo of land and sea ice
-    return (1 - alpha) * Q
-
-
-# define a function for outgoing longwave raditation (OLR)
-def OLR(tau, T):
-    # define the Stefan-Boltzmann Constant, noting we are using 'e' for scientific notation
-    sigma = 5.67e-8  # W m^-2 K^-4
-
-    return tau * sigma * T**4
-
-
-# calculate OLR for different values of T
-OLR_vals = OLR(tau, T)
-
-# calculate ASR for different values of T
-for tt, temp in enumerate(T):
-    ASR_vals[tt] = ASR(Q, temp)
-
-# make plots
-fig, ax = plt.subplots()
-ax.plot(T, ASR_vals, label="Absorbed Shortwave Radiation (ASR)", lw=3)
-ax.plot(T, OLR_vals, label="Outgoing Longwave Radiation (OLR)", lw=3)
-
-ax.set_title("", fontsize=16)
-ax.set_xlabel("Temperature (K)", fontsize=14)
-ax.set_ylabel("Radiative Flux", fontsize=14)
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 2
-      1 # create a array ot temperatures to evaluates the ASR and OLR at
-----> 2 T = np.arange(200, 360, 2, dtype=np.float64)
-      4 # create empty arrays to fill with values later
-      5 ASR_vals = np.zeros_like(T)
-
-NameError: name 'np' is not defined
-
-
-
-
-
-

Questions 1.1: Climate Connection#

-
    -
  1. How many times do the graphs of ASR and OLR intersect?

  2. -
  3. What does this intersection mean in terms of Earth’s energy (im)balance?

  4. -
-

Click for solution

-
-
-
-

Section 1.2: Multiple Equilibria From Graphs#

-

Equilibrium temperatures are solutions to the model equation when the rate of change of temperature is zero. There are two types of equilibrium solutions: stable and unstable.

-
    -
  • A stable equilibrium temperature is a solution that the model asymptotes to (moves towards) over time.

  • -
  • An unstable equilibrium temperature is a solution that the model diverges (moves away) from over time. The only time the model will stay at this equilibrium is if it starts exactly at the unstable equilibrium temperature.

  • -
-

We can now incorporate the temperature-dependent albedo we defined above into our time-dependent model from Tutorial 3, to investigate the impact of the ice-albedo feedback on the long-term behavior temperature.

-
-
-
# create a function to find the new temperature based on the previous using Euler's method.
-def step_forward(T, tau, Q, dt):
-
-    # define the heat capacity (calculated in Tutorial 3)
-    C = 286471954.64  # J m^-2K^-2
-
-    T_new = T + dt / C * (ASR(Q, T) - OLR(tau, T))
-
-    return T_new
-
-
-
-
-

Let us explore how our model behaves under a variety of initial temperatures. We can use a for loop compare different initial temperatures.

-
-
-
dt = 60.0 * 60.0 * 24.0 * 365.0  # time interval, one year expressed in seconds
-
-fig, ax = plt.subplots()
-for init_temp in T:  # suite of intial temperatures in K
-    numtsteps = 40  #  number of years to run the model
-
-    # for converting number of seconds in a year
-    sec_2_yr = 3.154e7
-
-    # set the intial temperature (initial condition)
-    T_series = [init_temp]
-
-    # set the initial time to 0
-    t_series = [0]
-
-    # run the model
-    for n in range(numtsteps):
-
-        # calculate and append the time since running the model, dependent on dt and the numtsteps
-        t_series.append((n + 1) * dt / sec_2_yr)
-
-        # calculate and append the new temperature using our pre-defined function
-        T_series.append(step_forward(T_series[n], tau=tau, Q=Q, dt=dt))
-
-    # make plot
-    ax.plot(t_series, T_series)
-
-ax.set_title("Time Evolution of Temperature", fontsize=16)
-ax.set_xlabel("Time (years)", fontsize=14)
-ax.set_ylabel("Temperature (C)", fontsize=14)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 3
-      1 dt = 60.0 * 60.0 * 24.0 * 365.0  # time interval, one year expressed in seconds
-----> 3 fig, ax = plt.subplots()
-      4 for init_temp in T:  # suite of intial temperatures in K
-      5     numtsteps = 40  #  number of years to run the model
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Questions 1.2#

-
    -
  1. How many stable equilibria can you find on the figure above? Estimate their values.

  2. -
  3. What do these values represent on the figure you made in Part 1?

  4. -
  5. There is an unstable equilibrium state within this model. What is it’s value?

  6. -
-

Click for solution

-
-
-
-

Section 1.3: Finding Equilibria Numerically & Determining Convergence or Divergence#

-

To verify the equilibrium solutions we identified graphically in the previous section, we can use python to find the exact values (i.e., where the rate of change in temperature is zero). That is find the temperatures that satisfy

-
-(16)#\[\begin{align} -0 = ASR-OLR. -\end{align}\]
-

To aid us, we will use brentq, a root-finding function from the scipy package.

-
-
-
# create function to find the forcing at the top of the atmosphere
-def Ftoa(T):
-    return ASR(Q, T) - OLR(tau, T)
-
-
-#  it requires a function and two end-points be input as arguments
-#  it will look for a zero of the function between those end-points
-Teq1 = brentq(
-    Ftoa, 200.0, 240.0
-)  # these ranges are from the intersections of the graphs of ASR and OLR
-Teq2 = brentq(Ftoa, 240.0, 280.0)
-Teq3 = brentq(Ftoa, 280.0, 320.0)
-
-print(Teq1, Teq2, Teq3)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 8
-      3     return ASR(Q, T) - OLR(tau, T)
-      6 #  it requires a function and two end-points be input as arguments
-      7 #  it will look for a zero of the function between those end-points
-----> 8 Teq1 = brentq(
-      9     Ftoa, 200.0, 240.0
-     10 )  # these ranges are from the intersections of the graphs of ASR and OLR
-     11 Teq2 = brentq(Ftoa, 240.0, 280.0)
-     12 Teq3 = brentq(Ftoa, 280.0, 320.0)
-
-NameError: name 'brentq' is not defined
-
-
-
-
-

To assess the stability of these equilibria, we can plot the difference in ASR and OSR. This is the same function (Ftoa) that we calculated in the previous cell, but we will recaclulate it below for plotting purposes.

-
-
-
# we've already calculated ASR and OLR above
-fig, ax = plt.subplots()
-F = ASR_vals - OLR_vals
-ax.plot(T, F, color="k", linewidth=3)
-
-# find positive values and fill with red
-pos_ind1 = T <= Teq1
-ax.fill_between(T[pos_ind1], 0, F[pos_ind1], color="red")
-
-pos_ind2 = (T >= Teq2) & (T <= Teq3)
-ax.fill_between(T[pos_ind2], 0, F[pos_ind2], color="red")
-
-# find negative values and fill with blue
-neg_ind1 = (T >= Teq1) & (T <= Teq2)
-ax.fill_between(T[neg_ind1], 0, F[neg_ind1], color="blue")
-
-neg_ind2 = T >= Teq3
-ax.fill_between(T[neg_ind2], 0, F[neg_ind2], color="blue")
-
-# plot vertical lines/names at equilibrium temperatures
-ax.axvline(x=Teq1, color="k", ls=":")
-ax.axvline(x=Teq2, color="k", ls=":")
-ax.axvline(x=Teq3, color="k", ls=":")
-
-ax.annotate(
-    "$T_{eq1}$",
-    xy=(Teq1 - 5, -340),
-    xytext=(Teq1 - 5, -340),
-    rotation=90,
-    annotation_clip=False,
-)
-ax.annotate(
-    "$T_{eq2}$",
-    xy=(Teq2 - 5, -340),
-    xytext=(Teq2 - 5, -340),
-    rotation=90,
-    annotation_clip=False,
-)
-ax.annotate(
-    "$T_{eq3}$",
-    xy=(Teq3 - 5, -340),
-    xytext=(Teq3 - 5, -340),
-    rotation=90,
-    annotation_clip=False,
-)
-
-# plot arrows/text to show stability of equilibrium points
-ax.annotate(
-    "",
-    xy=(232, -50),
-    xytext=(200, -50),
-    arrowprops=dict(facecolor="black", arrowstyle="-|>"),
-)
-
-ax.annotate(
-    "",
-    xy=(242.5, -50),
-    xytext=(233, -50),
-    arrowprops=dict(facecolor="black", arrowstyle="<|-"),
-)
-
-ax.annotate(
-    "",
-    xy=(305.5, -50),
-    xytext=(243.5, -50),
-    arrowprops=dict(facecolor="black", arrowstyle="-|>"),
-)
-
-ax.annotate(
-    "",
-    xy=(358, -50),
-    xytext=(307, -50),
-    arrowprops=dict(facecolor="black", arrowstyle="<|-"),
-)
-
-
-ax.annotate("convergence", xy=(358, -160), xytext=(307, -160), rotation=90)
-
-ax.annotate("divergence", xy=(305.5, -160), xytext=(243.5, -160), rotation=90)
-
-ax.annotate("convergence", xy=(242.5, -160), xytext=(233, -160), rotation=90)
-
-
-ax.set_xlabel("Temperature (K)", fontsize=14)
-ax.set_ylabel("ASR-OLR", fontsize=14);
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # we've already calculated ASR and OLR above
-----> 2 fig, ax = plt.subplots()
-      3 F = ASR_vals - OLR_vals
-      4 ax.plot(T, F, color="k", linewidth=3)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

The red regions represent conditions where the Earth would warm, because the energy absorbed by the Earth system is greater than the energy emitted or reflected back into space.

-

The blue regions represent conditions where the Earth would cool, because the outgoing radiation is larger than the absorbed radiation.

-

For example, if Earth started at an initial temperature below \(T_{eq1}\) (in the left red region), it will move to the right on the \(x\)-axis, towards the \(T_{eq1}\) equilibrium state. Conversely, if Earth started between \(T_{eq1}\) and \(T_{eq1}\) (the left blue region), the temperature would decrease, moving left on the \(x\)-axis until it reaches \(T_{eq1}\). Thus \(T_{eq1}\) is a stable equilibrium as the temperature curves will tend to this point after a long time.

-
-

Questions 1.3#

-
    -
  1. Identify the stable and unstable equilibria from this graph. Do these agree with the figure you made in Section 1.2?

  2. -
-

Click for solution

-
-
-
-
-

Section 2: Changing Insolation#

-
-

Section 2.1: Effect on the Number Equilibrium Solutions#

-

During Day 1 of this week, you learned that insolation (the amount of radiation Earth receives from the sun at the top of the atmosphere) fluctuates with time. Over Earth’s history, the insolation has sometimes been lower, and sometimes been higher, than the currently observed \(340 W m^{-2}\).

-

These insolation changes directly affect the ASR, causing Earth to warm or cool depending on whether it receives more or less insolation respectively. To look at the effect that changing insolation has on Earth’s equilibrium state(s), we can re-plot ASR as a function of temperature for several different insolation values (including the temperature-dependent albedo), alongside the OLR.

-
-
-
# define the observed insolation
-Q_vals = [220, 340, 420]  # W m^-2
-
-fig, ax = plt.subplots()
-for Q_2 in Q_vals:
-    # calculate ASR and OLR for different values of T
-    for tt, temp in enumerate(T):
-
-        ASR_vals[tt] = ASR(Q_2, temp)
-
-    # make plots
-    ax.plot(T, ASR_vals, lw=3, label="ASR for Q = " + str(Q_2) + " $W$ $m^{-2}$")
-
-# note we calculated OLR previously, and it does not depend on Q
-ax.plot(T, OLR_vals, lw=3, label="OLR")
-
-ax.set_title("", fontsize=16)
-ax.set_xlabel("Temperature (K)", fontsize=14)
-ax.set_ylabel("Radiative Flux", fontsize=14)
-ax.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 4
-      1 # define the observed insolation
-      2 Q_vals = [220, 340, 420]  # W m^-2
-----> 4 fig, ax = plt.subplots()
-      5 for Q_2 in Q_vals:
-      6     # calculate ASR and OLR for different values of T
-      7     for tt, temp in enumerate(T):
-
-NameError: name 'plt' is not defined
-
-
-
-
-

As we increase or decrease the insolation, the number of intersections between ASR and OLR can change! This means the number of equilibrium solutions for our model will also change.

-
-

Questions 2.1#

-
    -
  1. How many stable equilibrium solutions are there when \(Q=220\) \(W\) \(m^{-2}\)? Warm (ice-free) or cold (completely-frozen) state(s)?

  2. -
  3. For \(Q=420\) \(W\) \(m^{-2}\)? Warm or cold equilibrium state(s)?

  4. -
-

Click for solution

-
-
-
-

Section 2.2: Effect on Equilibrium Temperatures#

-

To understand how this effect translates to different equilibrium temperatures of our model over time, we will apply a range of insolation values to our model. Let us first start off with a very cold Earth, at 220 K, and warm the Earth by steadily increasing the insolation above our present day 340 \(W\) \(m^{-2}\) value.

-
-
-
# these are the values of insolation we will use
-insolation_vals = np.arange(340, 500, 3)
-
-# initial temperature we will use
-init_temp = 220  # K
-
-fig, ax = plt.subplots()
-
-for i, insolation in enumerate(insolation_vals):  # suite of initial temperatures in K
-
-    numtsteps = 100  #  number of years to run the model
-
-    # for converting number of seconds in a year
-    sec_2_yr = 3.154e7
-
-    # set the intial temperature (initial condition)
-    T_series = [init_temp]
-
-    # set the initial time to 0
-    t_series = [0]
-
-    # run the model
-    for n in range(numtsteps):
-
-        # calculate and append the time since running the model, dependent on dt and the numtsteps
-        t_series.append((n + 1) * dt / sec_2_yr)
-
-        # calculate and append the new temperature using our pre-defined function
-        T_series.append(step_forward(T_series[n], tau=tau, Q=insolation, dt=dt))
-
-    # make plot
-    colors = plt.cm.coolwarm(np.linspace(0, 1, insolation_vals.shape[0]))
-    if (
-        insolation == 385
-    ):  # This is just to highlight a particularly interesting insolation value
-        ax.plot(t_series, T_series, color=colors[i], linestyle="dashed")
-    else:
-        ax.plot(t_series, T_series, color=colors[i])
-
-ax.set_ylabel("Temperature (K)", fontsize=14)
-ax.set_xlabel("Years", fontsize=14)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # these are the values of insolation we will use
-----> 2 insolation_vals = np.arange(340, 500, 3)
-      4 # initial temperature we will use
-      5 init_temp = 220  # K
-
-NameError: name 'np' is not defined
-
-
-
-
-
-

Questions 2.2: Climate Connection#

-
    -
  1. Noting the dashed blue lines, at approximately what temperature do you note a rapid transition from cold to warm equilibrium states? How do these compare to your equation for albedo?

  2. -
  3. How would you interpret the rapid transition in equilibrium temperatures with changing insolation (the big gap in the figure) using the ASR & OLR vs. temperature plot that you made in Section 2.1?

  4. -
  5. BONUS: How does the time-varying behavior of the reddest (warm-state) lines relate to the ice-albedo feedback?

  6. -
-

Click for solution

-
-
-
-
-

Summary#

-

In this tutorial, you learned about stable and unstable equilibria, identifying them from graphs and preciselt calculating them. You also incorporated an ice-albedo feedback into your model to observe its effects on equilibrium solutions under varying insolation.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.html b/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.html deleted file mode 100644 index 2b87fc327..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial5.html +++ /dev/null @@ -1,1894 +0,0 @@ - - - - - - - - - - - - Tutorial 5: Radiative Equilibrium — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 5: Radiative Equilibrium#

-

Week 1, Day 5, Climate Modeling

-

Content creators: Jenna Pearson

-

Content reviewers: Yunlong Xu, Will Gregory, Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina Duplex, Ohad Zivan, Chi Zhang

-

Content editors: Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial students will run a one-dimensional radiative equilibrium model that predicts the global mean atmospheric temperature as a function of height. Much of the code shown here was taken from The Climate Laboratory by Brian Rose. Students are encouraged to visit this website for more tutorials and background on these models.

-

By the end of this tutorial students will be able to:

-
    -
  • Implement a 1-D model that predicts atmospheric temperature as a function of height using the python package climlab.

  • -
  • Understand how this model builds off of the energy balance models developed in the previous tutorials.

  • -
-
-
-

Setup#

-
-
-
# note the conda install takes quite a while, but conda is REQUIRED to properly download the dependencies (that are not just python packages)
-# !pip install condacolab &> /dev/null           # need to use conda installation of climlab, pip won't work. condacolab is a workaround
-# import condacolab
-# condacolab.install()
-# !mamba install -c anaconda cftime xarray numpy &> /dev/null    # for decoding time variables when opening datasets
-# !mamba install -c conda-forge metpy climlab &> /dev/null
-
-
-
-
-
-
-
# imports
-import xarray as xr  # used to manipulate data and open datasets
-import numpy as np  # used for algebra/arrays
-import urllib.request  # used to download data from the internet
-import climlab  # one of the models we are using
-import matplotlib.pyplot as plt  # used for plotting
-import metpy  # used to make Skew T Plots of temperature and pressure
-from metpy.plots import SkewT  # plotting function used widely in climate science
-import pooch
-import os
-import tempfile
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import xarray as xr  # used to manipulate data and open datasets
-      3 import numpy as np  # used for algebra/arrays
-      4 import urllib.request  # used to download data from the internet
-
-ModuleNotFoundError: No module named 'xarray'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Radiative Equilibrium#

-
-

Video 1: Radiative Equilibrium#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Radiative Equilibrium
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-
-

Section 1: Setting up the Radiative Equilibrium Model Using Climlab#

-

The energy balance model we used earlier today was zero-dimensional, yielding only the global mean surface temperature. We might ask, is it possible to construct a similar, one-dimensional, model for an atmospheric column to estimate the global mean temperature profile (i.e., including the height/\(z\) dimension). Additionally, can we explicitly include the effects of different gases in this model, rather than just parametrizing their collective effects through a single parameter \(\tau\)? The answer is yes, we can!

-

This model is too complex to construct from scratch, as we did in the previous tutorials. Instead, we will use a model already available within the python package climlab.

-

The model we will first use is a radiative equilbrium model. Radiative equilibrium models consider different layers of the atmosphere. Each of these layers absorbs and emits radiation depending on its constituent gases, allowing the model to calculate the radiation budget for each layer as radiative energy is transferred between atmospheric layers, the Earth’s surface, and space. Radiative equilibrium is reached when each layer gains energy at the same rate as it loses energy. In this tutorial you will analyze the temperature profile of this new model once it has reached equilibrium.

-

To set up this model, we will need information about some of the mean properties of the atmosphere. We are going to download water vapor data from the Community Earth System Model, a global climate model that we will go into detail on in the next tutorial, to use a variable called specific humidity. Specific humidity is the mass of water vapor per mass of a unit block of air. This is useful because water vapor is an important greenhouse gas.

-
-
-
filename_sq = "cpl_1850_f19-Q-gw-only.cam.h0.nc"
-url_sq = "https://osf.io/c6q4j/download/"
-
-ds = xr.open_dataset(
-    pooch_load(filelocation=url_sq, filename=filename_sq)
-)  # ds = dataset
-ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 4
-      1 filename_sq = "cpl_1850_f19-Q-gw-only.cam.h0.nc"
-      2 url_sq = "https://osf.io/c6q4j/download/"
-----> 4 ds = xr.open_dataset(
-      5     pooch_load(filelocation=url_sq, filename=filename_sq)
-      6 )  # ds = dataset
-      7 ds
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
# the specific humidity is stored in a variable called Q
-ds.Q
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # the specific humidity is stored in a variable called Q
-----> 2 ds.Q
-
-NameError: name 'ds' is not defined
-
-
-
-
-
-
-
ds.time
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 ds.time
-
-NameError: name 'ds' is not defined
-
-
-
-
-

however, we want an annual average profile:

-
-
-
# take global, annual average using a weighting (ds.gw) that is calculated based on the model grid - and is similar, but not identical, to a cosine(latitude) weighting
-
-weight_factor = ds.gw / ds.gw.mean(dim="lat")
-Qglobal = (ds.Q * weight_factor).mean(dim=("lat", "lon", "time"))
-# print specific humidity profile
-Qglobal
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 3
-      1 # take global, annual average using a weighting (ds.gw) that is calculated based on the model grid - and is similar, but not identical, to a cosine(latitude) weighting
-----> 3 weight_factor = ds.gw / ds.gw.mean(dim="lat")
-      4 Qglobal = (ds.Q * weight_factor).mean(dim=("lat", "lon", "time"))
-      5 # print specific humidity profile
-
-NameError: name 'ds' is not defined
-
-
-
-
-

Now that we have a global mean water vapor profile, we can define a model that has the same vertical levels as this water vapor data.

-
-
-
# use 'lev=Qglobal.lev' to create an identical vertical grid to water vapor data
-mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)
-mystate
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # use 'lev=Qglobal.lev' to create an identical vertical grid to water vapor data
-----> 2 mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)
-      3 mystate
-
-NameError: name 'climlab' is not defined
-
-
-
-
-

To model the absorption and emission of different gases within each atmospheric layer, we use the Rapid Radiative Transfer Model, which is contained within the RRTMG module. We must first initialize our model using the water vapor .

-
-
-
radmodel = climlab.radiation.RRTMG(
-    name="Radiation (all gases)",  # give our model a name!
-    state=mystate,  # give our model an initial condition!
-    specific_humidity=Qglobal.values,  # tell the model how much water vapor there is
-    albedo=0.25,  # this the SURFACE shortwave albedo
-    timestep=climlab.constants.seconds_per_day,  # set the timestep to one day (measured in seconds)
-)
-radmodel
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 radmodel = climlab.radiation.RRTMG(
-      2     name="Radiation (all gases)",  # give our model a name!
-      3     state=mystate,  # give our model an initial condition!
-      4     specific_humidity=Qglobal.values,  # tell the model how much water vapor there is
-      5     albedo=0.25,  # this the SURFACE shortwave albedo
-      6     timestep=climlab.constants.seconds_per_day,  # set the timestep to one day (measured in seconds)
-      7 )
-      8 radmodel
-
-NameError: name 'climlab' is not defined
-
-
-
-
-

Let’s explore this initial state. Here Ts is the initial global mean surface temperature, and Tatm is the initial global mean air temperature profile.

-
-
-
radmodel.state
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 1
-----> 1 radmodel.state
-
-NameError: name 'radmodel' is not defined
-
-
-
-
-

One of the perks of using this model is it’s ability to incorporate the radiative effects of individual greenhouse gases in different parts of the radiation spectrum, rather than using a bulk reduction in transmission of outgoing longwave radiation (as in our previous models).

-

Let’s display ‘absorber_vmr’, which contains the volume mixing ratio’s of each gas used in the radiative transfer model (these are pre-defined; and do not include the water vapor we used as a model input above). The volume mixing ratio describes the fraction of molecules in the air that are a given gas. For example, \(21\%\) of air is oxygen and so it’s volumn mixing ratio is 0.21.

-
-
-
radmodel.absorber_vmr
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 1
-----> 1 radmodel.absorber_vmr
-
-NameError: name 'radmodel' is not defined
-
-
-
-
-

To look at carbon dioxide (CO2) in a more familiar unit, parts per million (by volume), we can convert and print the new value.

-
-
-
radmodel.absorber_vmr["CO2"] * 1e6
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 1
-----> 1 radmodel.absorber_vmr["CO2"] * 1e6
-
-NameError: name 'radmodel' is not defined
-
-
-
-
-

We can also look at all the available diagnostics of our model:

-
-
-
diag_ds = climlab.to_xarray(radmodel.diagnostics)
-diag_ds
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[15], line 1
-----> 1 diag_ds = climlab.to_xarray(radmodel.diagnostics)
-      2 diag_ds
-
-NameError: name 'climlab' is not defined
-
-
-
-
-

For example to look at OLR,

-
-
-
radmodel.OLR
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[16], line 1
-----> 1 radmodel.OLR
-
-NameError: name 'radmodel' is not defined
-
-
-
-
-

Note. the OLR is currently 0 as we have not ran the model forward in time, so it has not calculated any radiation components.

-
-

Questions 1: Climate Connection#

-
    -
  1. Why do you think all gases, except ozone and water vapor, are represented by single values in the model?

  2. -
-

Click for solution

-
-
-

Coding Exercises 1#

-
    -
  1. On the same graph, plot the annual mean specific humidity profile and ozone profiles.

  2. -
-
-
-
fig, ax = plt.subplots()
-# multiply Qglobal by 1000 to put in units of grams water vapor per kg of air
-_ = ...
-# multiply by 1E6 to get units of ppmv = parts per million by volume
-_ = ...
-
-# pressure decreases logarithmically with height in the atmosphere
-# invert the axis so the largest value of pressure is lowest
-ax.invert_yaxis()
-# set y axis to a log scale
-_ = ...
-
-ax.set_ylabel("Pressure (hPa)")
-ax.set_xlabel("Specific humidity (g/kg)")
-
-# turn on the grid lines
-_ = ...
-
-# turn on legend
-_ = ...
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[17], line 1
-----> 1 fig, ax = plt.subplots()
-      2 # multiply Qglobal by 1000 to put in units of grams water vapor per kg of air
-      3 _ = ...
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-

Section 2: Getting Data to Compare to the Model#

-

Before we run our model forward, we will download a reanalysis product from NCEP to get a sense of what the real global mean atmospheric temperature profile looks like. We will compare this profile to our model runs later.

-
-
-
filename_ncep_air = "air.mon.1981-2010.ltm.nc"
-url_ncep_air = "https://osf.io/w6cd5/download/"
-ncep_air = xr.open_dataset(
-    pooch_load(filelocation=url_ncep_air, filename=filename_ncep_air)
-)  # ds = dataset
-
-# this is the long term monthly means (note only 12 time steps)
-ncep_air.air
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[18], line 3
-      1 filename_ncep_air = "air.mon.1981-2010.ltm.nc"
-      2 url_ncep_air = "https://osf.io/w6cd5/download/"
-----> 3 ncep_air = xr.open_dataset(
-      4     pooch_load(filelocation=url_ncep_air, filename=filename_ncep_air)
-      5 )  # ds = dataset
-      7 # this is the long term monthly means (note only 12 time steps)
-      8 ncep_air.air
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
# need to take the average over space and time
-# the grid cells are not the same size moving towards the poles, so we weight by the cosine of latitude to compensate for this
-coslat = np.cos(np.deg2rad(ncep_air.lat))
-weight = coslat / coslat.mean(dim="lat")
-
-Tglobal = (ncep_air.air * weight).mean(dim=("lat", "lon", "time"))
-Tglobal
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[19], line 3
-      1 # need to take the average over space and time
-      2 # the grid cells are not the same size moving towards the poles, so we weight by the cosine of latitude to compensate for this
-----> 3 coslat = np.cos(np.deg2rad(ncep_air.lat))
-      4 weight = coslat / coslat.mean(dim="lat")
-      6 Tglobal = (ncep_air.air * weight).mean(dim=("lat", "lon", "time"))
-
-NameError: name 'np' is not defined
-
-
-
-
-

Below we will define two helper funcitons to visualize the profiles output from our model with a SkewT plot. This is common way to plot atmospheric temperature in climate science, and the metpy package has a built in function to make this easier.

-
-
-
# to setup the skewT and plot observations
-def make_skewT():
-    fig = plt.figure(figsize=(9, 9))
-    skew = SkewT(fig, rotation=30)
-    skew.plot(
-        Tglobal.level,
-        Tglobal,
-        color="black",
-        linestyle="-",
-        linewidth=2,
-        label="Observations",
-    )
-    skew.ax.set_ylim(1050, 10)
-    skew.ax.set_xlim(-90, 45)
-    # Add the relevant special lines
-    # skew.plot_dry_adiabats(linewidth=1.5, label = 'dry adiabats')
-    # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')
-    # skew.plot_mixing_lines()
-    skew.ax.legend()
-    skew.ax.set_xlabel("Temperature (degC)", fontsize=14)
-    skew.ax.set_ylabel("Pressure (hPa)", fontsize=14)
-    return skew
-
-
-
-
-
-
-
# to add a model derived profile to the skewT figure
-def add_profile(skew, model, linestyle="-", color=None):
-    line = skew.plot(
-        model.lev,
-        model.Tatm - climlab.constants.tempCtoK,
-        label=model.name,
-        linewidth=2,
-    )[0]
-    skew.plot(
-        1000,
-        model.Ts - climlab.constants.tempCtoK,
-        "o",
-        markersize=8,
-        color=line.get_color(),
-    )
-    skew.ax.legend()
-
-
-
-
-
-
-
skew = make_skewT()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[22], line 1
-----> 1 skew = make_skewT()
-
-Cell In[20], line 3, in make_skewT()
-      2 def make_skewT():
-----> 3     fig = plt.figure(figsize=(9, 9))
-      4     skew = SkewT(fig, rotation=30)
-      5     skew.plot(
-      6         Tglobal.level,
-      7         Tglobal,
-   (...)
-     11         label="Observations",
-     12     )
-
-NameError: name 'plt' is not defined
-
-
-
-
-

SkewT (also known as SkewT-logP) plots are generally used for much more complex reasons than we will use here. However, one of the benefits of this plot that we will utilize is the fact that pressure decreases approximately logarithmically with height. Thus, with a logP axis, we are showing information that is roughly linear in height, making the plots more intuitive.

-
-
-

Section 3: Running the Radiative Equilibrium Model Forward in Time#

-

We can run this model over many time steps, just like the simple greenhouse model, but now we can examine the behavior of the temperature profile rather than just the surface temperature.

-

There is no need to write out a function to step our model forward - climlab already has this feature. We will use this function to run our model to equilibrium (i.e., until OLR is balanced by ASR).

-
-
-
# take a single step forward to the diagnostics are updated and there is some energy imbalance
-radmodel.step_forward()
-
-# run the model to equilibrium (the difference between ASR and OLR is a very small number)
-while np.abs(radmodel.ASR - radmodel.OLR) > 0.001:
-    radmodel.step_forward()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[23], line 2
-      1 # take a single step forward to the diagnostics are updated and there is some energy imbalance
-----> 2 radmodel.step_forward()
-      4 # run the model to equilibrium (the difference between ASR and OLR is a very small number)
-      5 while np.abs(radmodel.ASR - radmodel.OLR) > 0.001:
-
-NameError: name 'radmodel' is not defined
-
-
-
-
-
-
-
#  check the energy budget to make sure we are really at equilibrium
-radmodel.ASR - radmodel.OLR
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[24], line 2
-      1 #  check the energy budget to make sure we are really at equilibrium
-----> 2 radmodel.ASR - radmodel.OLR
-
-NameError: name 'radmodel' is not defined
-
-
-
-
-

Now let’s can compare this to observations.

-
-
-
skew = make_skewT()
-add_profile(skew, radmodel)
-skew.ax.set_title("Pure Radiative Equilibrium", fontsize=18);
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[25], line 1
-----> 1 skew = make_skewT()
-      2 add_profile(skew, radmodel)
-      3 skew.ax.set_title("Pure Radiative Equilibrium", fontsize=18);
-
-Cell In[20], line 3, in make_skewT()
-      2 def make_skewT():
-----> 3     fig = plt.figure(figsize=(9, 9))
-      4     skew = SkewT(fig, rotation=30)
-      5     skew.plot(
-      6         Tglobal.level,
-      7         Tglobal,
-   (...)
-     11         label="Observations",
-     12     )
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Questions 3: Climate Connection#

-
    -
  1. The profile from our model does not match observations well. Can you think of one component we might be missing?

  2. -
  3. What effect do you think the individual gases play in determining this profile and why?

  4. -
-

Click for solution

-
-
-

Coding Exercises 3#

-
    -
  1. Create a second model called ‘Radiation (no H20)’ that lacks water vapor. Then re-create the plot above, but add on this extra profile without water vapor.

  2. -
-
-
-
# make an exact clone of our existing model
-radmodel_noH2O = climlab.process_like(radmodel)
-# change the name of our new model
-radmodel_noH2O.name = ...
-
-# set the water vapor profile to all zeros
-radmodel_noH2O.specific_humidity *= 0.0
-
-# run the model to equilibrium
-radmodel_noH2O.step_forward()
-while np.abs(radmodel_noH2O.ASR - radmodel_noH2O.OLR) > 0.01:
-    radmodel_noH2O.step_forward()
-
-# create skewT plot
-skew = make_skewT()
-
-# add profiles for both models to plot
-for model in [...]:
-    ...
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[26], line 2
-      1 # make an exact clone of our existing model
-----> 2 radmodel_noH2O = climlab.process_like(radmodel)
-      3 # change the name of our new model
-      4 radmodel_noH2O.name = ...
-
-NameError: name 'climlab' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-

Summary#

-

In this tutorial, you’ve learned how to use the python package climlab to construct a one-dimensional radiative equilibrium model, and run it forward in time to predict the global mean atmospheric temperature profile. You’ve also visualized these results through SkewT plots.

-
-
-

Resources#

-

Data from this tutorial can be accessed for specific humidity here and reanalysis temperature here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.html b/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.html deleted file mode 100644 index c3c176903..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial6.html +++ /dev/null @@ -1,1707 +0,0 @@ - - - - - - - - - - - - Tutorial 6: Radiative Convective Equilibrium — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 6: Radiative Convective Equilibrium#

-

Week 1, Day 5, Climate Modeling

-

Content creators: Jenna Pearson

-

Content reviewers: Yunlong Xu, Will Gregory, Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina Duplex, Ohad Zivan, Chi Zhang

-

Content editors: Brodie Pearson, Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

Building on the understanding of a one-dimensional radiative balance model from previous tutorial, in this tutorial students will learn about radiative-convective-equilibrium. Much of the code shown here was taken from The Climate Laboratory by Brian Rose. Students are encouraged to visit this website for more tutorials and background on these models.

-

By the end of this tutorial students will be able to:

-
    -
  • Implement a radiative-convective equilibrium model using the python package climlab.

  • -
  • Understand how this model builds off the one-dimensional radiative balance model used in the previous tutorials.

  • -
-
-
-

Setup#

-
-
-
# note the conda install takes quite a while, but conda is REQUIRED to properly download the dependencies (that are not just python packages)
-# !pip install condacolab &> /dev/null           # need to use conda installation of climlab, pip won't work. condacolab is a workaround
-# import condacolab
-# condacolab.install()
-# !mamba install -c anaconda cftime xarray numpy &> /dev/null    # for decoding time variables when opening datasets
-# !mamba install -c conda-forge metpy climlab &> /dev/null
-
-
-
-
-
-
-
# imports
-
-import xarray as xr  # used to manipulate data and open datasets
-import numpy as np  # used for algebra/arrays
-import urllib.request  # used to download data from the internet
-import climlab  # one of the models we are using
-import matplotlib.pyplot as plt  # used for plotting
-import metpy  # used to make Skew T Plots of temperature and pressure
-from metpy.plots import SkewT  # plotting function used widely in climate science
-import pooch
-import os
-import tempfile
-from IPython.display import HTML
-from matplotlib import animation
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 3
-      1 # imports
-----> 3 import xarray as xr  # used to manipulate data and open datasets
-      4 import numpy as np  # used for algebra/arrays
-      5 import urllib.request  # used to download data from the internet
-
-ModuleNotFoundError: No module named 'xarray'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-

Plotting functions#

-
-

Plotting functions#

-
-
- - -Hide code cell source - -
-
# @title Plotting functions
-
-#  make the videos at the end of the tutorial
-plt.rcParams["animation.html"] = "jshtml"
-
-# these three functions are used to make videos at the end of the tutorial
-
-
-def initial_figure(model):
-    with plt.ioff():  # will hide the inital figure which will plot separate from the video otherwise
-        fig = plt.figure(figsize=(6, 6))
-        lines = []
-
-        skew = SkewT(fig, rotation=30)
-        #  plot the observations
-        skew.plot(
-            Tglobal.level,
-            Tglobal,
-            color="black",
-            linestyle="-",
-            linewidth=2,
-            label="Observations",
-        )
-        lines.append(
-            skew.plot(
-                model.lev,
-                model.Tatm - climlab.constants.tempCtoK,
-                linestyle="-",
-                linewidth=2,
-                color="C0",
-                label="RC model (all gases)",
-            )[0]
-        )
-        skew.ax.legend()
-        skew.ax.set_ylim(1050, 10)
-        skew.ax.set_xlim(-60, 75)
-        # Add the relevant special lines
-        skew.plot_dry_adiabats(linewidth=1.5, label="dry adiabats")
-        # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')
-        skew.ax.set_xlabel("Temperature ($^\circ$C)", fontsize=14)
-        skew.ax.set_ylabel("Pressure (hPa)", fontsize=14)
-        lines.append(
-            skew.plot(
-                1000,
-                model.Ts - climlab.constants.tempCtoK,
-                "o",
-                markersize=8,
-                color="C0",
-            )[0]
-        )
-
-    return fig, lines
-
-
-def animate(day, model, lines):
-    lines[0].set_xdata(np.array(model.Tatm) - climlab.constants.tempCtoK)
-    lines[1].set_xdata(np.array(model.Ts) - climlab.constants.tempCtoK)
-    # lines[2].set_xdata(np.array(model.q)*1E3)
-    # lines[-1].set_text('Day {}'.format(int(model.time['days_elapsed'])))
-    # This is kind of a hack, but without it the initial frame doesn't appear
-    if day != 0:
-        model.step_forward()
-    return lines
-
-
-# to setup the skewT and plot observations
-def make_basic_skewT():
-    fig = plt.figure(figsize=(9, 9))
-    skew = SkewT(fig, rotation=30)
-    skew.plot(
-        Tglobal.level,
-        Tglobal,
-        color="black",
-        linestyle="-",
-        linewidth=2,
-        label="Observations",
-    )
-    skew.ax.set_ylim(1050, 10)
-    skew.ax.set_xlim(-90, 45)
-    # Add the relevant special lines
-    # skew.plot_dry_adiabats(linewidth=1.5, label = 'dry adiabats')
-    # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')
-    # skew.plot_mixing_lines()
-    skew.ax.legend()
-    skew.ax.set_xlabel("Temperature (degC)", fontsize=14)
-    skew.ax.set_ylabel("Pressure (hPa)", fontsize=14)
-    return skew
-
-
-# to setup the skewT and plot observations
-def make_skewT():
-    fig = plt.figure(figsize=(9, 9))
-    skew = SkewT(fig, rotation=30)
-    skew.plot(
-        Tglobal.level,
-        Tglobal,
-        color="black",
-        linestyle="-",
-        linewidth=2,
-        label="Observations",
-    )
-    skew.ax.set_ylim(1050, 10)
-    skew.ax.set_xlim(-90, 45)
-    # Add the relevant special lines
-    skew.plot_dry_adiabats(linewidth=1.5, label="dry adiabats")
-    # skew.plot_moist_adiabats(linewidth=1.5, label = 'moist adiabats')
-    # skew.plot_mixing_lines()
-    skew.ax.legend()
-    skew.ax.set_xlabel("Temperature (degC)", fontsize=14)
-    skew.ax.set_ylabel("Pressure (hPa)", fontsize=14)
-    return skew
-
-
-# to add a model derived profile to the skewT figure
-def add_profile(skew, model, linestyle="-", color=None):
-    line = skew.plot(
-        model.lev,
-        model.Tatm - climlab.constants.tempCtoK,
-        label=model.name,
-        linewidth=2,
-    )[0]
-    skew.plot(
-        1000,
-        model.Ts - climlab.constants.tempCtoK,
-        "o",
-        markersize=8,
-        color=line.get_color(),
-    )
-    skew.ax.legend()
-
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 4
-      1 # @title Plotting functions
-      2 
-      3 #  make the videos at the end of the tutorial
-----> 4 plt.rcParams["animation.html"] = "jshtml"
-      6 # these three functions are used to make videos at the end of the tutorial
-      9 def initial_figure(model):
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-
-
-

Video 1: Radiative-Convective Equilibrium#

-
-

Video 1: Radiative-Convective Equilibrium#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Radiative-Convective Equilibrium
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Reproducing Data from the Last Tutorial’s One-dimensional Radiative Equilibrium Model Using Climlab#

-
-
-
filename_sq = "cpl_1850_f19-Q-gw-only.cam.h0.nc"
-url_sq = "https://osf.io/c6q4j/download/"
-ds = xr.open_dataset(
-    pooch_load(filelocation=url_sq, filename=filename_sq)
-)  # ds = dataset
-
-filename_ncep_air = "air.mon.1981-2010.ltm.nc"
-url_ncep_air = "https://osf.io/w6cd5/download/"
-ncep_air = xr.open_dataset(
-    pooch_load(filelocation=url_ncep_air, filename=filename_ncep_air)
-)  # ds = dataset
-
-# take global, annual average
-weight_factor = ds.gw / ds.gw.mean(dim="lat")
-Qglobal = (ds.Q * weight_factor).mean(dim=("lat", "lon", "time"))
-
-# use 'lev=Qglobal.lev' to create an identical vertical grid to water vapor data
-mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)
-
-radmodel = climlab.radiation.RRTMG(
-    name="Radiation (all gases)",  # give our model a name!
-    state=mystate,  # give our model an initial condition!
-    specific_humidity=Qglobal.values,  # tell the model how much water vapor there is
-    albedo=0.25,  # this the SURFACE shortwave albedo
-    timestep=climlab.constants.seconds_per_day,  # set the timestep to one day (measured in seconds)
-)
-
-# need to take the average over space and time
-# the grid cells are not the same size moving towards the poles, so we weight by the cosine of latitude to compensate for this
-coslat = np.cos(np.deg2rad(ncep_air.lat))
-weight = coslat / coslat.mean(dim="lat")
-
-Tglobal = (ncep_air.air * weight).mean(dim=("lat", "lon", "time"))
-
-# take a single step forward to the diagnostics are updated and there is some energy imbalance
-radmodel.step_forward()
-
-# run the model to equilibrium (the difference between ASR and OLR is a very small number)
-while np.abs(radmodel.ASR - radmodel.OLR) > 0.001:
-    radmodel.step_forward()
-
-skew = make_basic_skewT()
-add_profile(skew, radmodel)
-skew.ax.set_title("Pure Radiative Equilibrium", fontsize=18);
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 3
-      1 filename_sq = "cpl_1850_f19-Q-gw-only.cam.h0.nc"
-      2 url_sq = "https://osf.io/c6q4j/download/"
-----> 3 ds = xr.open_dataset(
-      4     pooch_load(filelocation=url_sq, filename=filename_sq)
-      5 )  # ds = dataset
-      7 filename_ncep_air = "air.mon.1981-2010.ltm.nc"
-      8 url_ncep_air = "https://osf.io/w6cd5/download/"
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-

Section 2: Radiative-Convective Equilibrium#

-

From the plot you just made, one of the largest differences between observations and the pure radiation model with all gases lies in the lower atmosphere, where the surface air temperature is 20 degrees too warm and the 200 hPa pressure surface is 40 degrees too cold. What could be the issue?

-

One thing we have not included in our model yet is dynamics (motion of the air). The model’s temperature profile is what’s known as statically unstable (note this definition of stability is different than that used in the previous tutorials).

-

Here static means not due to wind, and unstable means the atmosphere wants to adjust to a different state because the surface air is relatively light and wants to rise into upper layers of the atmosphere. As the air rises, it creates convective turbulence (similar to boiling water, where convective circulation is introduced from heating water from below). The rising air, and the resultant turbulence, mixes the atmospheric column. This mixing often occurs across the troposphere, which is roughly the lowest 10km of the atmosphere. Most of the weather we experience lies in the troposphere.

-

When air rises adiabatically, it expands and cools due to the lower pressure. The rate of cooling depends on whether the air is saturated with water vapor. When rising air is unsaturated, it cools following the dry adiabats. If the air saturates, it cools at a lesser rate denoted by the moist adiabats (we did not have time to discuss these moisture effects in the mini-lecture).

-

To identify unstable atmospheric layers, let’s take another look at the SkewT plot, but this time we will plot the dry adiabats. We can then compare the rates of cooling of our model to these adiabats.

-
-
-
skew = make_skewT()
-add_profile(skew, radmodel)
-skew.ax.set_title("Pure Radiative Equilibrium", fontsize=18)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 skew = make_skewT()
-      2 add_profile(skew, radmodel)
-      3 skew.ax.set_title("Pure Radiative Equilibrium", fontsize=18)
-
-NameError: name 'make_skewT' is not defined
-
-
-
-
-

Near the surface, the reanalysis temperature profile is steeper than the dry adiabats. In these layers vertical motion is inhibited, and the surface conditions are considered stable. However, the model profile is shallower than the dry adiabats. In the model, the surface air is statically unstable, which would lead to convective mixing if this physical process was included in the model (the model currently only includes radiative processes). In this tutorial we will see whether including convective mixing in our model can bring the model closer to the reanalysis temperature profile.

-

To build a radiative-convective model we can take the radiative model we have already made and couple it to a convective model. Here the term couple implies there is communication between the models such that their effects are both incorporated into the final product, which in our case is the temperature profile.

-
-
-
# restate the model here for ease of coding
-
-# make a model on same vertical domain as the water vapor data
-mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)
-
-# create the radiation model
-rad = climlab.radiation.RRTMG(
-    name="Radiation (net)",
-    state=mystate,
-    specific_humidity=Qglobal.values,
-    timestep=climlab.constants.seconds_per_day,
-    albedo=0.25,  # surface albedo, tuned to give reasonable ASR for reference cloud-free model
-)
-
-# create the convection model
-conv = climlab.convection.ConvectiveAdjustment(
-    name="Convection",
-    state=mystate,
-    adj_lapse_rate=6.5,  # the adiabatic lapse rate of the atmopshere
-    timestep=rad.timestep,  # same timestep as radiation model
-)
-# couple the two components
-rcm = climlab.couple([rad, conv], name="Radiative-Convective Model")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 4
-      1 # restate the model here for ease of coding
-      2 
-      3 # make a model on same vertical domain as the water vapor data
-----> 4 mystate = climlab.column_state(lev=Qglobal.lev, water_depth=2.5)
-      6 # create the radiation model
-      7 rad = climlab.radiation.RRTMG(
-      8     name="Radiation (net)",
-      9     state=mystate,
-   (...)
-     12     albedo=0.25,  # surface albedo, tuned to give reasonable ASR for reference cloud-free model
-     13 )
-
-NameError: name 'climlab' is not defined
-
-
-
-
-

Now let’s run the radiation part to equilibrium, which should give us the same profile as in the previous section. Once we get this radiative equilibrium profile we will add convective mixing physics to the model and continue running it until it reaches radiative-convective equilibrium.

-

The new model does not actually resolve the actual vertical motion and mixing that occurs in convection. Instead, the model includes a parameterization for convection which automatically mixes regions of the atmospheric column that are statically unstable.

-
-
-
# run JUST the radiative component to equilibrium
-for n in range(1000):
-    rcm.subprocess["Radiation (net)"].step_forward()
-
-# compute diagnostics
-rcm.compute_diagnostics()
-
-#  plot the resulting profile (our initial condition once we turn on the physics)
-fig, lines = initial_figure(rcm)
-
-# this animation can take a while
-animation.FuncAnimation(fig, animate, 50, fargs=(rcm, lines))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 3
-      1 # run JUST the radiative component to equilibrium
-      2 for n in range(1000):
-----> 3     rcm.subprocess["Radiation (net)"].step_forward()
-      5 # compute diagnostics
-      6 rcm.compute_diagnostics()
-
-NameError: name 'rcm' is not defined
-
-
-
-
-

Adding convective mixing to the initially unstable temperature profile leads to an instant mixing of air throughout the lower atmosphere, moving the profile towards the observations. The balance at play is between radiative process that warm the surface and cool the troposphere (lower atmosphere) as well as convection which moves heat away from the surface, leading to a colder surface and warmer troposphere. Note the differences in surface versus tropospheric temperatures in the new versus old equilibrium profiles.

-
-

Questions 2: Climate Connection#

-
    -
  1. The static instability was removed in the first time step! In reality, which process do you think changes temperature faster, convection or radiation?

  2. -
  3. What do you think the next step would be to move towards a more realistic climate model?

  4. -
-

Click for solution

-
-
-

Coding Exercises 2#

-
    -
  1. Recreate the video above except using an isothermal atmosphere (uniform temperature profile) set to the surface temprature (rcm.state.Ts). Does the equilbrium profile look any different than the one you made before?

  2. -
-
-
-
# set initial temperature profile to be the surface temperature (isothermal)
-rcm.state.Tatm[:] = rcm.state.Ts
-
-# compute diagnostics
-_ = ...
-
-#  plot initial data
-fig, lines = initial_figure(rcm)
-
-# make animation - this animation can take a while
-# animation.FuncAnimation(fig, animate, 50, fargs=(rcm, lines))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # set initial temperature profile to be the surface temperature (isothermal)
-----> 2 rcm.state.Tatm[:] = rcm.state.Ts
-      4 # compute diagnostics
-      5 _ = ...
-
-NameError: name 'rcm' is not defined
-
-
-
-
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, you explored the concept of radiative-convective equilibrium, learning to implement a Python model using the climlab package. You learned the limitations of a pure radiation model and the necessity to include atmospheric dynamics such as convection. Through coupling a radiation model with a convective model, you have simulated a more realistic atmospheric temperature profile. Even though the model does not directly resolve the vertical motion during convection, it incorporates a parameterization to automatically account for mixing in statically unstable regions. By the end of the tutorial, you could comprehend how this model expands on the previous energy balance models from tutorials 1-4.

-
-
-

Resources#

-

Data from this tutorial can be accessed for specific humidity here and reanalysis temperature here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.html b/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.html deleted file mode 100644 index bd99be236..000000000 --- a/book/_build/html/tutorials/W1D5_ClimateModeling/student/W1D5_Tutorial7.html +++ /dev/null @@ -1,1764 +0,0 @@ - - - - - - - - - - - - Tutorial 7: Introduction to Earth System Models — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 7: Introduction to Earth System Models#

-

Week 1, Day 5, Climate Modeling

-

Content creators: Brodie Pearson, Jenna Pearson, Julius Busecke, and Tom Nicholas

-

Content reviewers: Yunlong Xu, Will Gregory, Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina Duplex, Ohad Zivan, Chi Zhang

-

Content editors: Abigail Bodner, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives#

-

In this tutorial students will learn how to load, visualize, and manipulate data from an Earth System Model (ESM) to explore the spatial variations in each component of the surface heat flux.

-

By the end of this tutorial students will be able to:

-
    -
  • Load data from the Community Earth System Model (CESM)

  • -
  • Analyze the zonal-mean surface energy budget of a realistic climate model (i.e., the budget at each latitude)

  • -
  • Link variations in different surface heat flux to physical differences in the air-surface conditions across regions.

  • -
-
-
-

Setup#

-
-
-
# note the conda install takes quite a while, but conda or mamba is REQUIRED to properly download the dependencies
-# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# crucial to install all packages in one line, otherwise code will fail.
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils &> /dev/null
-
-
-
-
-
-
-
# imports
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-from xmip.utils import google_cmip_col
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-import cartopy.crs as ccrs
-import pooch
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # imports
-----> 2 import intake
-      3 import numpy as np
-      4 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-
-

Section 1: The Community Earth System Model (CESM)#

-

Throughout today’s tutorials, we have been working with increasingly complex climate models. In this final tutorial we will look at data from the most complex type of climate model, an Earth System Model (ESM). These ESMs include the physical processes typical of General Circulation Models (GCMs), but also include chemical and biological changes within the climate system (e.g. changes in vegetation, biomes, atmospheric \(CO_2\)).

-

The Community Earth System Model (CESM) is the specific ESM that we will analyze here in prepartion for next week where you will look at many ESM data sets simultaneously. We will be analyzing a historical simulation of CESM, which covers the period 1850 to 2015 using the historicallly observed forcing of the climate system.

-
-

Section 1.1: Finding & opening CMIP6 data with xarray#

-

Massive projects like CMIP6 can contain millions of datasets. For most practical applications we only need a subset of the data. To do this, we need to specify exactly which data sets we need. The naming conventions of CMIP6 data sets are standardized across all models and experiments, which allows us to load multiple related data sets with efficient code.

-

In order to load a CMIP6 dataset the following information must be specified:

-
    -
  1. variable_id: The variable(s) of interest

    -
      -
    • in CMIP6 SST is called tos

    • -
    -
  2. -
  3. source_id: The CMIP6 model(s) that we want data from

  4. -
  5. table_id: The origin system and output frequency desired of the variable(s)

    -
      -
    • We use Omon - data from the ocean model at monthly resolution

    • -
    -
  6. -
  7. grid_id: The grid that we want the data to be on

    -
      -
    • We use gn which is data on the model’s native grid, some models also provide gr (regridded data) and other grid options

    • -
    -
  8. -
  9. experiment_id: The CMIP6 experiments that we want to analyze

    -
      -
    • We will load three experiments: historical, ssp126 and ssp585. We’ll discuss these more in the next few tutorials

    • -
    -
  10. -
  11. member_id: this distinguishes simulations if the same model is run repeatedly for an experiment

    -
      -
    • We use r1i1p1f1 for now, but will explore this in a later tutorial

    • -
    -
  12. -
-

Each of these terms is called a facet in CMIP vocabulary.

-

Once you have defined the facets of interest you need to somehow search and retrieve the datasets that contain these facets.

-

There are many ways to do this, but here we will show a workflow using an intake-esm catalog object based on a CSV file that is maintained by the pangeo community.

-
-
-
col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)  # open an intake catalog containing the Pangeo CMIP cloud data
-col
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 1
-----> 1 col = intake.open_esm_datastore(
-      2     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      3 )  # open an intake catalog containing the Pangeo CMIP cloud data
-      4 col
-
-NameError: name 'intake' is not defined
-
-
-
-
-

We just loaded the full collection of Pangeo cloud datasets into an intake catalog, and defined a list of 5 example models (‘source_ids’) for this demonstration. There are many more to test out! You could run col.df['source_id'].unique() in a new cell to get a list of all available models

-

Now we will create a subset according to the provided facets using the .search() method, and finally open the zarr stores in the cloud into xarray datasets.

-

The data returned are xarray datasets which contain dask arrays. These are ‘lazy’, meaning the actual data will only be loaded when a computation is performed. What is loaded here is only the metadata, which enables us to inspect the data (e.g. the dimensionality/variable units) without loading in GBs or TBs of data!

-

A subtle but important step in the opening stage is the use of a preprocessing function! By passing preprocess=combined_preprocessing we apply crowdsourced fixes from the xMIP package to each dataset. This ensures consistent naming of dimensions (and other convienient things - see here for more).

-
-
-
# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id="CESM2",
-    variable_id=[
-        "hfls",
-        "hfss",
-        "rlds",
-        "rlus",
-        "rsds",
-        "rsus",
-        "tas",
-        "rsdt",
-        "rsut",
-        "rlut",
-    ],
-    member_id="r1i1p1f1",
-    table_id="Amon",
-    grid_label="gn",
-    experiment_id=["historical", "hist-nat"],
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt = cat.to_datatree(**kwargs)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 2
-      1 # from the full `col` object, create a subset using facet search
-----> 2 cat = col.search(
-      3     source_id="CESM2",
-      4     variable_id=[
-      5         "hfls",
-      6         "hfss",
-      7         "rlds",
-      8         "rlus",
-      9         "rsds",
-     10         "rsus",
-     11         "tas",
-     12         "rsdt",
-     13         "rsut",
-     14         "rlut",
-     15     ],
-     16     member_id="r1i1p1f1",
-     17     table_id="Amon",
-     18     grid_label="gn",
-     19     experiment_id=["historical", "hist-nat"],
-     20     require_all_on=[
-     21         "source_id"
-     22     ],  # make sure that we only get models which have all of the above experiments
-     23 )
-     25 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     26 kwargs = dict(
-     27     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     28     xarray_open_kwargs=dict(
-   (...)
-     33     },  # anonymous/public authentication to google cloud storage
-     34 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-
-

Section 1.2: Checking the CMIP6 datasets#

-

We now have a “datatree” containing the data we searched for. A datatree is a high-level container of xarray data, useful for organizing many related datasets together. You can think of a single DataTree object as being like a (nested) dictionary of xarray.Dataset objects. Each dataset in the tree is known as a “node” or “group”, and we can also have empty nodes. You can explore the nodes of the tree and its contents interactively in a similar way to how you can explore the contents of an xarray.Dataset. Click on the arrows to expand the information about the datatree below:

-
-
-
dt
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 dt
-
-NameError: name 'dt' is not defined
-
-
-
-
-

Each group in the tree is stored under a corresponding name, and we can select nodes via their name. The real usefulness of a datatree comes from having many groups at different depths, analogous to how one might store files in nested directories (e.g. day1/experiment1/data.txt, day1/experiment2/data.txt etc.).

-

In our case the particular datatree object has different CMIP models and different experiments stored at distinct levels of the tree. This is useful because we can select just one experiment for one model, or all experiments for one model, or all experiments for all models!

-

We can also apply xarray operations (e.g. taking the average using the .mean() method) over all the data in a tree at once, just by calling that same method on the DataTree object. We can even map custom functions over all nodes in the tree using dt.map_over_subtree(my_function).

-

All the operations below can be accomplished without using datatrees, but it saves us many lines of code as we don’t have to use for loops over all our the different datasets. For more information about datatree see the documentation here.

-

Now, let’s pull out relevant CESM2 datasets from the datatree; the historical simulation (human & natural forcing) and the hist-nat simulation (natural forcing only).

-
-
-
# the historical including anthropogenic forcing
-hist_dt = dt["CESM2"]["historical"]
-hist_dt
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # the historical including anthropogenic forcing
-----> 2 hist_dt = dt["CESM2"]["historical"]
-      3 hist_dt
-
-NameError: name 'dt' is not defined
-
-
-
-
-
-
-
# the historical run without anthropogenic forcing
-hist_nat = dt["CESM2"]["hist-nat"]
-hist_nat
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 2
-      1 # the historical run without anthropogenic forcing
-----> 2 hist_nat = dt["CESM2"]["hist-nat"]
-      3 hist_nat
-
-NameError: name 'dt' is not defined
-
-
-
-
-
-
-
-

Section 2: Surface Energy Balance#

-

Up until this point we have been analyzing budgets at the top of the atmosphere. Now we will move to Earth’s surface, where we will run into both familiar and unfamiliar terminology.

-

The first two terms we will analyze define the radiative component of the surface energy budget: shortwave and longwave radiation. For each of these terms, there is an upwelling and downwelling component. This is because, for example, some of the downwelling shortwave radiation is reflected back upwards due to the surface albedo. Similarly, some upwelling longwave radiation from Earth is absorbed by the atmosphere and re-emitted back towards the surface. The net radiative flux is given as

-
-(17)#\[\begin{align} -R_{net} = [R_{\uparrow S} - R_{\downarrow S}] + [R_{\uparrow L} - R_{\downarrow L}] -\end{align}\]
-

where the arrows indicate up(down)welling and the \(S\) and \(L\) are shortwave and longwave. Note that in keeping with the rest of the variables we will look at, the net radiation is defined so that a positive value refers to an upward flux of energy from the ocean or land to the atmosphere. That is, positive indicates heat transport upwards and away from the surface.

-

We will also be looking at latent and sensible heat. Sensible heat is the heat transferred due to a temperature difference between touching materials, for example between the air and the land or ocean surface. In this case, if the surface air is warmer than the land/ocean then heat is transferred from the air to the land/ocean (which is a downward or negative sensible heat flux), with an opposite-direction transfer if the air was colder than the land/ocean.

-

Latent heat is due to evaporation and condensation of water, as these phase changes absorb and release heat respectively. Here ‘latent’ means hidden, in that the energy is stored in molecules and there is no temperature change sensed through a thermometer even though a heat transfer takes place.

-

While these are not the only terms that comprise the surface energy budget (i.e. geothermal heating, latent heat of fusion for melting ice or snow, biological processes) these are typically the dominant terms that set the global patterns.

-

Let’s take a look at the long_name of some variables we just downloaded.

-
-
-
(
-    hist_dt.hfls.long_name,
-    hist_dt.hfss.long_name,
-    hist_dt.rlds.long_name,
-    hist_dt.rlus.long_name,
-    hist_dt.rsds.long_name,
-    hist_dt.rsus.long_name,
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 (
-----> 2     hist_dt.hfls.long_name,
-      3     hist_dt.hfss.long_name,
-      4     hist_dt.rlds.long_name,
-      5     hist_dt.rlus.long_name,
-      6     hist_dt.rsds.long_name,
-      7     hist_dt.rsus.long_name,
-      8 )
-
-NameError: name 'hist_dt' is not defined
-
-
-
-
-
-
-
# predefine heat fluxes for each experiement, take annual means
-
-# model output variables (.squeeze() removes singleton dimensions)
-hist_am_latent_heat_flux = hist_dt.ds.hfls.mean(dim="time").squeeze()
-hist_am_sensible_heat_flux = hist_dt.ds.hfss.mean(dim="time").squeeze()
-hist_am_downwelling_longwave_flux = hist_dt.ds.rlds.mean(dim="time").squeeze()
-hist_am_upwelling_longwave_flux = hist_dt.ds.rlus.mean(dim="time").squeeze()
-hist_am_downwelling_shortwave_flux = hist_dt.ds.rsds.mean(dim="time").squeeze()
-hist_am_upwelling_shortwave_flux = hist_dt.ds.rsus.mean(dim="time").squeeze()
-
-# derived ariables
-hist_am_net_shortwave_heat_flux = (
-    hist_am_upwelling_shortwave_flux - hist_am_downwelling_shortwave_flux
-)
-hist_am_net_longwave_heat_flux = (
-    hist_am_upwelling_longwave_flux - hist_am_downwelling_longwave_flux
-)
-hist_am_net_heat_flux = (
-    hist_am_net_shortwave_heat_flux
-    + hist_am_net_longwave_heat_flux
-    + hist_am_latent_heat_flux
-    + hist_am_sensible_heat_flux
-)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 4
-      1 # predefine heat fluxes for each experiement, take annual means
-      2 
-      3 # model output variables (.squeeze() removes singleton dimensions)
-----> 4 hist_am_latent_heat_flux = hist_dt.ds.hfls.mean(dim="time").squeeze()
-      5 hist_am_sensible_heat_flux = hist_dt.ds.hfss.mean(dim="time").squeeze()
-      6 hist_am_downwelling_longwave_flux = hist_dt.ds.rlds.mean(dim="time").squeeze()
-
-NameError: name 'hist_dt' is not defined
-
-
-
-
-

Now we will plot the annual mean over the historical time period 1850-2015.

-
-
-
fig, ([ax_latent, ax_shortwave], [ax_sensible, ax_longwave]) = plt.subplots(
-    ncols=2, nrows=2, figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-)
-
-# plot surface latent heat flux the first month of the historical period
-hist_am_latent_heat_flux.plot(
-    ax=ax_latent,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-300,
-    vmax=300,
-    cmap="coolwarm",
-    robust=True,
-    cbar_kwargs={"label": "$W/m^2$"},
-)
-ax_latent.coastlines()
-ax_latent.set_title("Latent Heat Flux")
-
-# Repeat for sensible heat flux
-hist_am_sensible_heat_flux.plot(
-    ax=ax_sensible,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-150,
-    vmax=150,
-    cmap="coolwarm",
-    robust=True,
-    cbar_kwargs={"label": "$W/m^2$"},
-)
-ax_sensible.coastlines()
-ax_sensible.set_title("Sensible Heat Flux")
-
-# Repeat for net shortwave radiative heat flux
-hist_am_net_shortwave_heat_flux.plot(
-    ax=ax_shortwave,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-300,
-    vmax=300,
-    cmap="coolwarm",
-    robust=True,
-    cbar_kwargs={"label": "$W/m^2$"},
-)
-ax_shortwave.coastlines()
-ax_shortwave.set_title("Net Upward Shortwave Flux")
-
-# Repeat for net longwave radiative heat flux
-hist_am_net_longwave_heat_flux.plot(
-    ax=ax_longwave,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-150,
-    vmax=150,
-    cmap="coolwarm",
-    robust=True,
-    cbar_kwargs={"label": "$W/m^2$"},
-)
-ax_longwave.coastlines()
-ax_longwave.set_title("Net Upward Longwave Flux")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 fig, ([ax_latent, ax_shortwave], [ax_sensible, ax_longwave]) = plt.subplots(
-      2     ncols=2, nrows=2, figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-      3 )
-      5 # plot surface latent heat flux the first month of the historical period
-      6 hist_am_latent_heat_flux.plot(
-      7     ax=ax_latent,
-      8     x="lon",
-   (...)
-     15     cbar_kwargs={"label": "$W/m^2$"},
-     16 )
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Questions 2: Climate Connection#

-
    -
  1. What do you think causes the large spatial variations of the sensible heat flux between strong positive, weak, and strong negative fluxes? Consider different surface types in your answer.

  2. -
-

Click for solution

-
-
-
-

Section 3: Surface Energy Budget by Latitude#

-

We can also calculate a zonal average which allows us to compare the contributions of each of these fluxes to the net heat flux by latitude (similar to the plot in the last lecture that considered the RCE model prediction as a function of latitude).

-

To calculate a spatial average of a gridded data set, we often have to weight the data based on the size of the area it is describing. Fortunately, CESM data is on a regular latitude-longitude grid, which means that grid cells at a specific latitude have the same area as all the other grid cells at that latitude. This makes a zonal average easy, because at each latitude we can simply calculate the mean of all data at that latitude.

-

Note: Our averaging would have required area-weighting if we were calculating a global mean (as you did in previous Tutorials) or if you had irregularly gridded data (which we will encounter on W2D1)!

-
-
-
# find the zonal means (.squeeze() removes singleton dimensions)
-hist_azm_latent_heat_flux = hist_am_latent_heat_flux.mean(dim="x").squeeze()
-hist_azm_sensible_heat_flux = hist_am_sensible_heat_flux.mean(dim="x").squeeze()
-hist_azm_net_shortwave_flux = hist_am_net_shortwave_heat_flux.mean(dim="x").squeeze()
-hist_azm_net_longwave_flux = hist_am_net_longwave_heat_flux.mean(dim="x").squeeze()
-hist_azm_net_heat_flux = hist_am_net_heat_flux.mean(dim="x").squeeze()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # find the zonal means (.squeeze() removes singleton dimensions)
-----> 2 hist_azm_latent_heat_flux = hist_am_latent_heat_flux.mean(dim="x").squeeze()
-      3 hist_azm_sensible_heat_flux = hist_am_sensible_heat_flux.mean(dim="x").squeeze()
-      4 hist_azm_net_shortwave_flux = hist_am_net_shortwave_heat_flux.mean(dim="x").squeeze()
-
-NameError: name 'hist_am_latent_heat_flux' is not defined
-
-
-
-
-
-
-
lat = hist_am_latent_heat_flux.lat[0, :]
-
-fig = plt.figure(figsize=(8, 5))
-
-plt.plot(lat, hist_azm_latent_heat_flux, label="Latent Heat")
-plt.plot(lat, hist_azm_sensible_heat_flux, label="Sensible Heat")
-plt.plot(lat, hist_azm_net_shortwave_flux, label="Shortwave")
-plt.plot(lat, hist_azm_net_longwave_flux, label="Longwave")
-plt.plot(lat, hist_azm_net_heat_flux, lw=3, color="k", label="Net")
-plt.plot(lat, 0 * lat, color="black")
-
-plt.title("Components of Annual Surface Energy Budget (+ up)")
-plt.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 1
-----> 1 lat = hist_am_latent_heat_flux.lat[0, :]
-      3 fig = plt.figure(figsize=(8, 5))
-      5 plt.plot(lat, hist_azm_latent_heat_flux, label="Latent Heat")
-
-NameError: name 'hist_am_latent_heat_flux' is not defined
-
-
-
-
-
-

Questions 3: Climate Connection#

-
    -
  1. Describe the dominant balance in the tropics (30S to 30N).

  2. -
  3. What about for the polar regions (above 60N and below 60S).

  4. -
  5. What do you think causes the dip in latent heat near the equator?

  6. -
  7. Is there symmetry in the longwave radiation in the high southern and northern latitudes? What about for sensible heat?

  8. -
-

Click for solution

-
-
-
-

Bonus Question: Climate Connection#

-
    -
  1. Hypothetically, imagine this plot showed that the net heat flux was:

  2. -
-
    -
  • Negative 100 \(W m^{-2}\) between 45\(^oN\) to 45\(^oS\) (i.e., 90 degrees of latitude centered on the Equator) and,

  • -
  • Positive 100 \(W m^{-2}\) between 45\(^oN\) to 90\(^oN\) and between 45\(^oS\) to 90\(^oS\)

  • -
-

Would you expect Earth to warm, cool, or remain the same temperature? Why?

-

Click for solution

-
-
-

Summary#

-

In this tutorial, you learned to identify and access specific CMIP6 datasets, which is vital for handling the vast datasets generated by climate models. You analyzed data from a CESM simulation, focusing on how shortwave/longwave radiation, sensible and latent heat, contribute to the surface energy budget. This tutorial also explored the zonal-mean surface energy budget, elucidating how different surface heat flux components vary with latitude due to physical differences in air-surface conditions across regions.

-
-
-

Resources#

-

Data from this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title.html deleted file mode 100644 index c129c0dbb..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - Future Climate - IPCC I Physical Basis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Future Climate - IPCC I Physical Basis

- -
-
- -
-
-
- - - - -
- -
-

Future Climate - IPCC I Physical Basis#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading.html deleted file mode 100644 index 006d9c26f..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/further_reading.html +++ /dev/null @@ -1,1056 +0,0 @@ - - - - - - - - - - - - Suggested Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Suggested Further Reading

- -
-
- -
-
-
- - - - -
- -
-

Suggested Further Reading#

-

If you would like further context about the goals, design, and scope of CMIP6, you should read Overview of the Coupled Model Intercomparison Project Phase 6 (CMIP6) experimental design and Organization, Eyring et al., 2016 (DOI:10.5194/gmd-9-1937-2016)

-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1.html deleted file mode 100644 index 5fa1fb410..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial1.html +++ /dev/null @@ -1,1785 +0,0 @@ - - - - - - - - - - - - Tutorial 1: Creating Maps of CMIP6 Earth System Model (ESM) Projections — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1: Creating Maps of CMIP6 Earth System Model (ESM) Projections#

-

Week 2, Day 1, Future Climate: The Physical Basis

-

Content creators: Brodie Pearson, Julius Busecke, Tom Nicholas

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Agustina Pesce, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives#

-

Earth System Models (ESMs) provide physically-based projections of how Earth’s climate could change in the coming years, decades, and centuries at both global and local scales. In the following tutorial you will:

-
    -
  • Revisit how to load ESM data from the CMIP6 experiments, and

  • -
  • Create maps showing projected future changes in sea surface temperature (SST).

  • -
-
-
-

Setup#

-
-
-
# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp cartopy nc-time-axis cf_xarray xarrayutils "esmf<=8.3.1" xesmf &> /dev/null
-# # For xesmf install we need to pin "esmf<=8.3.1". More context here: https://github.com/pangeo-data/xESMF/issues/246
-
-
-
-
-
-
-
# imports
-import time
-
-tic = time.time()
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-import xesmf as xe
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-import cartopy.crs as ccrs
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 6
-      2 import time
-      4 tic = time.time()
-----> 6 import intake
-      7 import numpy as np
-      8 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 1: Recap of Earth System Models#

-
-

Video 1: Recap of Earth System Models#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Recap of Earth System Models
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-

Section 1.1: Loading CMIP6 SST Data with xarray#

-

As a reminder, these ESMs simulate several systems (ocean, atmosphere, cryosphere, land) that are coupled to each other, and each system has its own variables, physics, and discretizations (grid & timestep).

-“EarthSystemModel” -

Atmospheric Model Schematic (Credit: Wikipedia)

-

Let’s repeat the CMIP6 loading method that we learned in Tutorial 6 on last week’s Climate Modelling day (Day 5).

-

Although we will only work with monthly SST (ocean) data today, the methods introduced can easily be applied/extended to load and analyze other CMIP6 variables, including from other components of the Earth system.

-

As a reminder, the facets that have to be specified for CMIP6, along with the facet choice(s) we make in this tutorial, are:

-
    -
  1. variable_id: tos = sea surface temperature

  2. -
  3. source_id: The CMIP6 model(s) that we want data from

  4. -
  5. table_id: Omon (ocean monthly output)

  6. -
  7. grid_id: gn = data on the model’s native grid

  8. -
  9. experiment_id: ssp585 (we’ll discuss experiments later today)

  10. -
  11. member_id: r1i1p1f1 for now

  12. -
-

Now, let’s repeat our CMIP6 loading method from the previous tutorial.

-

Note: today we will start by using only use one model, TaiESM1, which stands for Taiwan Earth System Model version 1, and a single experiment, ssp585 which is a high-emissions future scenario. In later tutorials you will work with 5 distinct CMIP6 models (source_id), and two additional experiments (experiment_id). TaiESM1 was developed by modifying the Community Earth System Model (CESM) version 1.2.2 to include different parameterizations (i.e., physics). As a result, the TaiESM1 model output is distinct from the CESM output you used in previous tutorials/days.

-
-
-
# open an intake catalog containing the Pangeo CMIP cloud data
-col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)
-
-# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id="TaiESM1",
-    variable_id="tos",
-    member_id="r1i1p1f1",
-    table_id="Omon",
-    grid_label="gn",
-    experiment_id="ssp585",
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt = cat.to_datatree(**kwargs)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 2
-      1 # open an intake catalog containing the Pangeo CMIP cloud data
-----> 2 col = intake.open_esm_datastore(
-      3     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      4 )
-      6 # from the full `col` object, create a subset using facet search
-      7 cat = col.search(
-      8     source_id="TaiESM1",
-      9     variable_id="tos",
-   (...)
-     16     ],  # make sure that we only get models which have all of the above experiments
-     17 )
-
-NameError: name 'intake' is not defined
-
-
-
-
-

We now have a “datatree” containing the data we searched for. A datatree is a high-level container of xarray data, useful for organizing many related datasets together. You can think of a single DataTree object as being like a (nested) dictionary of xarray.Dataset objects. Each dataset in the tree is known as a “node” or “group”, and we can also have empty nodes. This DataTree object may seem complicated when we load only one dataset, but it will prove to be very useful in later tutorials where you will work with multiple models, experiments, and ensemble members

-

You can explore the nodes of the tree and its contents interactively in a similar way to how you can explore the contents of an xarray.Dataset:

-
-
-
dt
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 dt
-
-NameError: name 'dt' is not defined
-
-
-
-
-

Now that we have the model datasets organized within thie datatree (dt) we can plot the datasets. Let’s start by plotting a map of SST from the TaiESM1 CMIP6 model in July 2023.

-

Note that CMIP6 experiments were run several years ago, so the cut-off between past (observed forcing) and future (scenario-based/projected forcing) was at the start of 2015. This means that July 2023 is about 8 years into the CMIP6 future and so it is unlikely to look exactly like Earth’s current SST state.

-
-
-
%matplotlib inline
-
-# select just a single model (TaiESM1) and experiment (ssp585) to plot
-sst_ssp585 = dt["TaiESM1"]["ssp585"].ds.tos
-
-fig, (ax_present) = plt.subplots(
-    ncols=1, nrows=1, figsize=[8, 4], subplot_kw={"projection": ccrs.Robinson()}
-)
-
-# select the model data for July 2023
-sst_present = sst_ssp585.sel(time="2023-07").squeeze()
-
-# plot the model data
-sst_present.plot(
-    ax=ax_present,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-10,
-    vmax=30,
-    cmap="magma",
-    robust=True,
-)
-ax_present.coastlines()
-ax_present.set_title("July 2023")
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 get_ipython().run_line_magic('matplotlib', 'inline')
-      3 # select just a single model (TaiESM1) and experiment (ssp585) to plot
-      4 sst_ssp585 = dt["TaiESM1"]["ssp585"].ds.tos
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/interactiveshell.py:2417, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
-   2415     kwargs['local_ns'] = self.get_local_scope(stack_depth)
-   2416 with self.builtin_trap:
--> 2417     result = fn(*args, **kwargs)
-   2419 # The code below prevents the output from being displayed
-   2420 # when using magics with decodator @output_can_be_silenced
-   2421 # when the last Python token in the expression is a ';'.
-   2422 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/magics/pylab.py:99, in PylabMagics.matplotlib(self, line)
-     97     print("Available matplotlib backends: %s" % backends_list)
-     98 else:
----> 99     gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
-    100     self._show_matplotlib_backend(args.gui, backend)
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/interactiveshell.py:3588, in InteractiveShell.enable_matplotlib(self, gui)
-   3567 def enable_matplotlib(self, gui=None):
-   3568     """Enable interactive matplotlib and inline figure support.
-   3569 
-   3570     This takes the following steps:
-   (...)
-   3586         display figures inline.
-   3587     """
--> 3588     from matplotlib_inline.backend_inline import configure_inline_support
-   3590     from IPython.core import pylabtools as pt
-   3591     gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/matplotlib_inline/__init__.py:1
-----> 1 from . import backend_inline, config  # noqa
-      2 __version__ = "0.1.6"  # noqa
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/matplotlib_inline/backend_inline.py:6
-      1 """A matplotlib backend for publishing figures via display_data"""
-      3 # Copyright (c) IPython Development Team.
-      4 # Distributed under the terms of the BSD 3-Clause License.
-----> 6 import matplotlib
-      7 from matplotlib import colors
-      8 from matplotlib.backends import backend_agg
-
-ModuleNotFoundError: No module named 'matplotlib'
-
-
-
-
-
-

Coding Exercise 1.1#

-

Now that we can plot maps of CMIP6 data, let’s look at some projected future changes using this data!

-

In this coding exercise your goals are to:

-
    -
  1. Create a map of the projected sea surface temperature in July 2100 under the SSP5-8.5 high-emissions scenario (we’ll discuss scenarios in the next mini-lecture) using data from the TaiESM1 CMIP6 model.

  2. -
  3. Create a map showing how this sea surface temperature projection is different from the current (July 2023) sea surface temperature in this model

  4. -
  5. Plot a similar map for this model that shows how January 2100 is different from January 2023

  6. -
-

To get you started, we have provided code to load the required data set into a variable called sst_ssp585, and we have plotted the current (July 2023) sea surface temperature from this data set.

-

Note: differences between two snapshots of SST are not the same as the anomalies that you encountered earlier in the course, which were the difference relative to the average during a reference period.

-
-
-
# %matplotlib inline
-
-# select just a single model and experiment
-sst_ssp585 = dt["TaiESM1"]["ssp585"].ds.tos
-
-fig, ([ax_present, ax_future], [ax_diff_july, ax_diff_jan]) = plt.subplots(
-    ncols=2, nrows=2, figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-)
-
-# plot a timestep for 2023
-sst_present = sst_ssp585.sel(time="2023-07").squeeze()
-sst_present.plot(
-    ax=ax_present,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-10,
-    vmax=30,
-    cmap="magma",
-    robust=True,
-)
-ax_present.coastlines()
-ax_present.set_title("July 2023")
-
-# repeat for 2100
-# complete the following line to extract data for July 2100
-sst_future = ...
-_ = ...
-ax_future.coastlines()
-ax_future.set_title("July 2100")
-
-# now find the difference between July 2100 and July 2023
-# complete the following line to extract the July difference
-sst_difference_july = ...
-_ = ...
-ax_diff_july.coastlines()
-ax_diff_july.set_title("2100 vs. 2023 Difference (July)")
-
-# finally, find the difference between January of the two years used above
-# complete the following line to extract the January difference
-sst_difference_jan = ...
-_ = ...
-ax_diff_jan.coastlines()
-ax_diff_jan.set_title("2100 vs. 2023 Difference (January)")
-
-plt.show()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 4
-      1 # %matplotlib inline
-      2 
-      3 # select just a single model and experiment
-----> 4 sst_ssp585 = dt["TaiESM1"]["ssp585"].ds.tos
-      6 fig, ([ax_present, ax_future], [ax_diff_july, ax_diff_jan]) = plt.subplots(
-      7     ncols=2, nrows=2, figsize=[12, 6], subplot_kw={"projection": ccrs.Robinson()}
-      8 )
-     10 # plot a timestep for 2023
-
-NameError: name 'dt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-
-

Questions 1.1: Climate Connection#

-
    -
  1. Comparing only the top two panels, how is the July SST projected to change in this particular model simulation? Do these changes agree with the map of July change that you plotted in the bottom left, and are these changes easier to see in this bottom map?

  2. -
  3. In what ways are the July and January maps similar or dissimilar, and can you think of any physical explanations for these (dis)similarities?

  4. -
  5. Why do you think the color bar axes vary? (i.e., the top panels say “Sea Surface Temperature [\(^oC\)]” while the bottom panels say “tos”)

  6. -
-

Many of the changes seen in the maps are a result of a changing climate under this high-emissions scenarios. However, keep in mind that these are differences between two months that are almost 80 years apart, so some of the changes are due to weather/synoptic differences between these particular months.

-

Click for solution

-
-
-

Section 1.2: Horizontal Regridding#

-

Many CMIP6 models use distinct spatial grids, we call this the model’s native grid.

-

You are likely familiar with the regular latitude-longitude grid where we separate the planet into boxes that have a fixed latitude and longitude span like this image we saw in the tutorial:

-Lat_Lon_Grid -

Let’s look at the grid used for the ocean component of the TaiESM1 CMIP6 model:

-
-
-
# create a scatter plot with a symbol at the center of each ocean grid cell in TaiESM1
-plt.scatter(x=sst_ssp585.lon, y=sst_ssp585.lat, s=0.1)
-plt.ylabel("Latitude")
-plt.xlabel("Longitude")
-plt.title("Grid cell locations in TaiESM1")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # create a scatter plot with a symbol at the center of each ocean grid cell in TaiESM1
-----> 2 plt.scatter(x=sst_ssp585.lon, y=sst_ssp585.lat, s=0.1)
-      3 plt.ylabel("Latitude")
-      4 plt.xlabel("Longitude")
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-
-

Questions 1.2#

-
    -
  1. How would this plot look for a regular latitude-longitude grid like the globe image shown above and in the slides? In what ways is the TaiESM1 grid different from this regular grid?

  2. -
  3. Can you think of a reason the Northern and Southern hemisphere ocean grids differ?*

  4. -
-

*Hint: from an oceanographic context, how are the North and South poles different from each other?

-

Click for solution

-

If you want to compare spatial maps from different models/observations, e.g. plot a map averaged over several models or the bias of this map relative to observations, you must first ensure the data from all the models (and observations) is on the same spatial grid. This is where regridding becomes essential!

-
-

Regridding is applied lazily, but it is still taking time to compute when it is applied. So if you want to compare for example the mean over time of several models it is often much quicker to compute the mean in time over the native grid and then regrid the result of that, instead of regridding each timestep and then calculating the mean!

-
-
-
-
# define a 'target' grid. This is simply a regular lon/lat grid that we will interpolate our data on
-ds_target = xr.Dataset(
-    {
-        "lat": (["lat"], np.arange(-90, 90, 1.0), {"units": "degrees_north"}),
-        "lon": (["lon"], np.arange(0, 360, 1.0), {"units": "degrees_east"}),
-    }
-)  # you can try to modify the parameters above to e.g. just regrid onto a region or make the resolution coarser etc
-ds_target
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 2
-      1 # define a 'target' grid. This is simply a regular lon/lat grid that we will interpolate our data on
-----> 2 ds_target = xr.Dataset(
-      3     {
-      4         "lat": (["lat"], np.arange(-90, 90, 1.0), {"units": "degrees_north"}),
-      5         "lon": (["lon"], np.arange(0, 360, 1.0), {"units": "degrees_east"}),
-      6     }
-      7 )  # you can try to modify the parameters above to e.g. just regrid onto a region or make the resolution coarser etc
-      8 ds_target
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
# define the regridder object (from our source dataarray to the target)
-regridder = xe.Regridder(
-    sst_ssp585, ds_target, "bilinear", periodic=True
-)  # this takes some time to calculate a weight matrix for the regridding
-regridder
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 2
-      1 # define the regridder object (from our source dataarray to the target)
-----> 2 regridder = xe.Regridder(
-      3     sst_ssp585, ds_target, "bilinear", periodic=True
-      4 )  # this takes some time to calculate a weight matrix for the regridding
-      5 regridder
-
-NameError: name 'xe' is not defined
-
-
-
-
-
-
-
# now we can apply the regridder to our data
-sst_ssp585_regridded = regridder(sst_ssp585)  # this is a lazy operation!
-# so it does not slow us down significantly to apply it to the full data!
-# we can work with this array just like before and the regridding will only be
-# applied to the parts that we later load into memory or plot.
-sst_ssp585_regridded
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 # now we can apply the regridder to our data
-----> 2 sst_ssp585_regridded = regridder(sst_ssp585)  # this is a lazy operation!
-      3 # so it does not slow us down significantly to apply it to the full data!
-      4 # we can work with this array just like before and the regridding will only be
-      5 # applied to the parts that we later load into memory or plot.
-      6 sst_ssp585_regridded
-
-NameError: name 'regridder' is not defined
-
-
-
-
-
-
-
# compare the shape to the original array
-sst_ssp585
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 # compare the shape to the original array
-----> 2 sst_ssp585
-
-NameError: name 'sst_ssp585' is not defined
-
-
-
-
-
-
-

Section 1.3: Visually Comparing Data with Different Map Projections#

-

Let’s use the code from above to plot a map of the model data on its original (native) grid, and a map of the model data after it is regridded.

-
-
-
fig, ([ax_regridded, ax_native]) = plt.subplots(
-    ncols=2, figsize=[12, 3], subplot_kw={"projection": ccrs.Robinson()}
-)
-
-# Native grid data
-sst_future = sst_ssp585.sel(time="2100-07").squeeze()
-sst_future.plot(
-    ax=ax_native,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-10,
-    vmax=30,
-    cmap="magma",
-    robust=True,
-)
-ax_native.coastlines()
-ax_native.set_title("July 2100 Native Grid")
-
-# Regridded data
-sst_future_regridded = sst_ssp585_regridded.sel(time="2100-07").squeeze()
-sst_future_regridded.plot(
-    ax=ax_regridded,
-    x="lon",
-    y="lat",
-    transform=ccrs.PlateCarree(),
-    vmin=-10,
-    vmax=30,
-    cmap="magma",
-    robust=True,
-)
-ax_regridded.coastlines()
-ax_regridded.set_title("July 2100 Regridded")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 1
-----> 1 fig, ([ax_regridded, ax_native]) = plt.subplots(
-      2     ncols=2, figsize=[12, 3], subplot_kw={"projection": ccrs.Robinson()}
-      3 )
-      5 # Native grid data
-      6 sst_future = sst_ssp585.sel(time="2100-07").squeeze()
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-
-

Questions 1.3#

-
    -
  1. Is this what you expected to see after regridding the data?

  2. -
-

Click for solution

-
-
-
-

Summary#

-

In Tutorial 1 you have:

-
    -
  • Loaded and manipulated data from a CMIP6 model under a high-emissions future scenario experiment

  • -
  • Created maps of future projected changes in the Earth system using CMIP6 data

  • -
  • Converted/regridded CMIP6 model data onto a desired grid. This is a critical processing step that allows us to directly compare data from different models and/or observations

  • -
-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2.html deleted file mode 100644 index 75f3709ba..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial2.html +++ /dev/null @@ -1,1503 +0,0 @@ - - - - - - - - - - - - Tutorial 2: Time Series, Global Averages, and Scenario Comparison — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2: Time Series, Global Averages, and Scenario Comparison#

-

Week 2, Day 1, Future Climate: The Physical Basis

-

Content creators: Brodie Pearson, Julius Busecke, Tom Nicholas

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives#

-

In this tutorial, we will expand to look at data from three CMIP6/ScenarioMIP experiments (historical, SSP1-2.6 and SSP5-8.5). Our aim will be to calculate the global mean SST for these 3 experiments, taking into account the spatially-varying size of the model’s grid cells (i.e., calculating a weighted mean).

-

By the end of this tutorial, you’ll be able to:

-
    -
  • Load and analyze CMIP6 SST data from different experiments.

  • -
  • Understand the difference between historical and future emission scenarios.

  • -
  • Calculate the global mean SST from gridded model data.

  • -
  • Apply the concept of weighted mean to account for varying grid cell sizes in Earth System Models.

  • -
-
-
-

Setup#

-
-
-
# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xmip xarrayutils &> /dev/null
-
-
-
-
-
-
-
# imports
-import time
-
-tic = time.time()
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 6
-      2 import time
-      4 tic = time.time()
-----> 6 import intake
-      7 import numpy as np
-      8 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-%matplotlib inline
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Video 2: Future Climate Scenarios#

-
-

Video 2: Future Climate Scenarios#

-
-
- - -Hide code cell source - -
-
# @title Video 2: Future Climate Scenarios
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Load CMIP6 SST Data from Several Experiments Using xarray#

-

In the last tutorial we loaded data from the SSP5-8.5 (high-emissions projection) experiment of one CMIP6 model called TaiESM1.

-

Let’s expand on this by using data from three experiments

-
    -
  • historical: a simulation of 1850-2015 using observed forcing,

  • -
  • SSP1-2.6: a future, low-emissions scenario, and

  • -
  • SSP5-8.5: a future, high-emissions scenario.

  • -
-
-
-
# open an intake catalog containing the Pangeo CMIP cloud data
-col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)
-
-# pick the experiments you require
-experiment_ids = ["historical", "ssp126", "ssp585"]
-
-# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id="TaiESM1",
-    variable_id="tos",
-    member_id="r1i1p1f1",
-    table_id="Omon",
-    grid_label="gn",
-    experiment_id=experiment_ids,
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt = cat.to_datatree(**kwargs)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 2
-      1 # open an intake catalog containing the Pangeo CMIP cloud data
-----> 2 col = intake.open_esm_datastore(
-      3     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      4 )
-      6 # pick the experiments you require
-      7 experiment_ids = ["historical", "ssp126", "ssp585"]
-
-NameError: name 'intake' is not defined
-
-
-
-
-
-

Coding Exercise 1.1#

-

In this tutorial and the following tutorials we will be looking at the global mean sea surface temperature. To calculate this global mean, we need to know the horizontal area of every ocean grid cell in all the models we are using.

-

Write code to load this ocean-grid area data using the previously shown method for SST data, noting that:

-
    -
  • We now need a variable called areacello (area of cells in the ocean)

  • -
  • This variable is stored in table_id Ofx (it is from the ocean model and is fixed/constant in time)

  • -
  • A model’s grid does not change between experiments so you only need to get grid data from the historical experiment for each model

  • -
-
-
-
cat_area = col.search(
-    source_id="TaiESM1",
-    # Add the appropriate variable_id
-    variable_id="areacello",
-    member_id="r1i1p1f1",
-    # Add the appropriate table_id
-    table_id="Ofx",
-    grid_label="gn",
-    # Add the appropriate experiment_id
-    experiment_id=["historical"],
-    require_all_on=["source_id"],
-)
-# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the
-# actual tutorial, so this would be a lot cleaner
-cat_area.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_area = cat_area.to_datatree(**kwargs)
-
-dt_with_area = DataTree()
-
-for model, subtree in dt.items():
-    metric = dt_area[model]["historical"].ds["areacello"]
-    dt_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 cat_area = col.search(
-      2     source_id="TaiESM1",
-      3     # Add the appropriate variable_id
-      4     variable_id="areacello",
-      5     member_id="r1i1p1f1",
-      6     # Add the appropriate table_id
-      7     table_id="Ofx",
-      8     grid_label="gn",
-      9     # Add the appropriate experiment_id
-     10     experiment_id=["historical"],
-     11     require_all_on=["source_id"],
-     12 )
-     13 # hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the
-     14 # actual tutorial, so this would be a lot cleaner
-     15 cat_area.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-
-NameError: name 'col' is not defined
-
-
-
-
-

Click for solution

-
-
-
-

Section 2: Global Mean Sea Surface Temperature (GMSST)#

-

The data files above contain spatial maps of the sea surface temperature for every month of each experiment’s time period. For the rest of today’s tutorials, we’re going to focus on the global mean sea surface temperature, rather than maps, as a way to visualize the ocean’s changing temperature at a global scale\(^*\).

-

The global mean of a property can be calculated by integrating that variable over the surface area of Earth covered by the system (ocean, atmosphere etc.) and dividing by the total surface area of that system. For Sea Surface Temperature, \(SST(x,y)\), the global mean (\(GMSST\)) can be written as an integral over the surface of the ocean (\(S_{ocean}\)):

-
-(18)#\[\begin{equation} -GMSST = \frac{\iint_{S_{ocean}}SST(x,y) dxdy}{\iint_{S_{ocean}} dxdy} -\end{equation}\]
-

where \(x\) and \(y\) are horizontal coordinates (i.e. longitude and latitude). This formulation works if \(SST(x,y)\) is a spatially-continuous function, but in a global model we only know the SST of discrete grid cells rather than a continuous SST field. Integrals are only defined for continuous variables, we must instead use a summation over the grid cells (summation is the discrete equivalent of integration):

-
-(19)#\[\begin{equation} -GMSST = \frac{ \sum_{i,j} SST(i,j) A(i,j)}{\sum_{i,j} A(i,j)} -\end{equation}\]
-

where \((i,j)\) represent the indices of the 2D spatial SST data from a CMIP6 model, and \(A\) denotes the area of each ocean grid cell, which can vary between cells/locations, as you saw in the last tutorial where TaiESM1 had irregularly-gridded output. This calculation is essentially a weighted mean of the SST across the model cells, where the weighting accounts for the varying area of cells - that is, larger cells should contribute more the global mean than smaller cells.

-

\(^*\)Note: we could alternatively look at ocean heat content, which depends on temperature at all depths, but it is a more intensive computation that would take too long to calculate in these tutorials.

-
-

Coding Exercise 2.1#

-

Complete the following code so that it calculates and plots a timeseries of global mean sea surface temperature from the TaiESM1 model for both the historical experiment and the two future projection experiments, SSP1-2.6 (low emissions) and SSP5-8.5 (high emissions).

-

As you complete this exercise this, consider the following questions:

-
    -
  • In the first function, what xarray operation is the following line doing, and why is it neccessary?

  • -
-
return ds.weighted(ds.areacello.fillna(0)).mean(['x', 'y'], keep_attrs=True)
-
-
-
    -
  • How would your time series plot might change if you instead used took a simple mean of all the sea surface temperatures across all grid cells? (Perhaps your previous maps could provide some help here)

  • -
-
-
-
def global_mean(ds: xr.Dataset) -> xr.Dataset:
-    """Global average, weighted by the cell area"""
-    return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-
-# average every dataset in the tree globally
-dt_gm = ...
-
-for experiment in ["historical", "ssp126", "ssp585"]:
-    da = ...
-    _ = ...
-plt.title("Global Mean SST from TaiESM1")
-plt.ylabel("Global Mean SST [$^\circ$C]")
-plt.xlabel("Year")
-plt.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 def global_mean(ds: xr.Dataset) -> xr.Dataset:
-      2     """Global average, weighted by the cell area"""
-      3     return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-NameError: name 'xr' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Question 1.1: Climate Connection#

-
    -
  1. Is this plot what you expected? If so, explain what you expected, and why, from the historical experiment, and the SSP1-2.6 and SSP5-8.5 scenarios (see below for a potentially useful figure).

  2. -
-

For context, here is Figure TS.4 from the Technical Summary of the IPCC Sixth Assessment Report, which shows how several elements of forcing differ between experiments (including historical and SSP experiments). In the video above we saw the \(CO_2\) panel of this figure:

-Experiment_Forcing -

Figure TS.4 | The climate change cause–effect chain: The intent of this figure is to illustrate the process chain starting from anthropogenic emissions, to changes in atmospheric concentration, to changes in Earth’s energy balance (‘forcing’), to changes in global climate and ultimately regional climate and climatic impact-drivers. Shown is the core set of five Shared Socio-economic Pathway (SSP) scenarios as well as emissions and concentration ranges for the previous Representative Concentration Pathway (RCP) scenarios in year 2100; carbon dioxide (CO2) emissions (GtCO2yr–1), panel top left; methane (CH4) emissions (middle) and sulphur dioxide (SO2), nitrogen oxide (NOx) emissions (all in Mt yr–1), top right; concentrations of atmospheric CO2(ppm) and CH4 (ppb), second row left and right; effective radiative forcing for both anthropogenic and natural forcings (W m–2), third row; changes in global surface air temperature (°C) relative to 1850–1900, fourth row; maps of projected temperature change (°C) (left) and changes in annual-mean precipitation (%) (right) at a global warming level (GWL) of 2°C relative to 1850–1900 (see also Figure TS.5), bottom row. Carbon cycle and non-CO2 biogeochemical feedbacks will also influence the ultimate response to anthropogenic emissions (arrows on the left). {1.6.1, Cross-Chapter Box 1.4, 4.2.2, 4.3.1, 4.6.1, 4.6.2}

-

Credit: IPCC

-

Click for solution

-
-
-
-

Summary#

-

In tutorial 2, you diagnosed changes at a global scale by calculating global mean timeseries with CMIP6 model mapped data. You then synthesized and compared global mean SST evolution in various CMIP6 experiments, spanning Earth’s recent past and several future scenarios.

-

We started by loading CMIP6 SST data from three different scenarios: historical, SSP1-2.6 (low-emissions future), and SSP5-8.5 (high-emissions future). This process expanded our understanding of model outputs. We then focused on calculating global mean SST, by taking into account the spatially-discrete and irregularly-gridded nature of this model’s grid cells through a weighted mean. This weighted mean approach yielded the global mean SST, providing a holistic view of the Earth’s changing sea surface temperatures under multiple future climate scenarios.

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3.html deleted file mode 100644 index 2bc5a242d..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial3.html +++ /dev/null @@ -1,1629 +0,0 @@ - - - - - - - - - - - - Tutorial 3: Multi-model Ensembles — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3: Multi-model Ensembles#

-

Week 2, Day 1, Future Climate: The Physical Basis

-

Content creators: Brodie Pearson, Julius Busecke, Tom Nicholas

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives#

-

In this tutorial, we will analyze datafrom five different CMIP6 models developed by various institutions around the world, focusing on their historical simulations and low-emission projections (SSP1-2.6). By the end of this tutorial, you will be able to

-
    -
  • Load CMIP6 Sea Surface Temperature (SST) data from multiple models;

  • -
  • Calculate the SST anomalies, and recall the concept of temperature anomaly in relation to a base period

  • -
-
-
-

Setup#

-
-
-
# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null
-
-
-
-
-
-
-
# imports
-import time
-
-tic = time.time()
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 6
-      2 import time
-      4 tic = time.time()
-----> 6 import intake
-      7 import numpy as np
-      8 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-# model_colors = {k:f"C{ki}" for ki, k in enumerate(source_ids)}
-%matplotlib inline
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Helper functions#

-
-

Helper functions#

-
-
- - -Hide code cell source - -
-
# @title Helper functions
-
-
-def global_mean(ds: xr.Dataset) -> xr.Dataset:
-    """Global average, weighted by the cell area"""
-    return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 4
-      1 # @title Helper functions
-----> 4 def global_mean(ds: xr.Dataset) -> xr.Dataset:
-      5     """Global average, weighted by the cell area"""
-      6     return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
-

Video 3: Why so many Earth System Models?#

-
-

Video 3: Why so many Earth System Models?#

-
-
- - -Hide code cell source - -
-
# @title Video 3: Why so many Earth System Models?
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Load CMIP6 SST Data from Five Models and Three Experiments#

-

In the previous section, you compared how a single CMIP6 model (TaiESM1) simulated past temperature, and how it projected temperature would change under a low-emissions scenario and a high-emissions scenario (historical, SSP1-2.6 and SSP5-8.5 experiments respectively).

-

Now we will start to analyze a multi-model ensemble that consists of data from multiple CMIP6 models. For now, we will focus on just the historical simulation and the low-emissions projection.

-

Your multi-model ensemble will consist of:

-
    -
  • Five different CMIP6 models developed by institutions from a variety of countries:

  • -
  • TaiESM1 (Research Center for Environmental Changes, Taiwan),

  • -
  • IPSL-CM6A-LR (Institut Pierre Simon Laplace, France),

  • -
  • GFDL-ESM4 (NOAA Geophysical Fluid Dynamics Laboratory, USA),

  • -
  • ACCESS-CM2 (CSIRO and ARCCSS, Australia), and

  • -
  • MPI-ESM1-2-LR (Max Planck Institute, Germany).

  • -
-

Note that these are only a subset of the dozens of models, institutes, countries, and experiments that contribute to CMIP6, as discussed in the previous W2D1 Tutorial 2 video. Some of the abbreviations in the model names refer to institutes (MPI/GFDL), while some refer to the complexity and version of the model (e.g., Earth System or Climate Model [ESM/CM] and low- or high-resolution [LR/HR]). There are often several models from a single institute with each having a distinct level of complexity.

-
-
-
col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)  # open an intake catalog containing the Pangeo CMIP cloud data
-
-# pick our five models and three experiments
-# there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-source_ids = ["IPSL-CM6A-LR", "GFDL-ESM4", "ACCESS-CM2", "MPI-ESM1-2-LR", "TaiESM1"]
-experiment_ids = ["historical", "ssp126", "ssp585"]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 col = intake.open_esm_datastore(
-      2     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      3 )  # open an intake catalog containing the Pangeo CMIP cloud data
-      5 # pick our five models and three experiments
-      6 # there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-      7 source_ids = ["IPSL-CM6A-LR", "GFDL-ESM4", "ACCESS-CM2", "MPI-ESM1-2-LR", "TaiESM1"]
-
-NameError: name 'intake' is not defined
-
-
-
-
-
-
-
# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id=source_ids,
-    variable_id="tos",
-    member_id="r1i1p1f1",
-    table_id="Omon",
-    grid_label="gn",
-    experiment_id=experiment_ids,
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt = cat.to_datatree(**kwargs)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # from the full `col` object, create a subset using facet search
-----> 2 cat = col.search(
-      3     source_id=source_ids,
-      4     variable_id="tos",
-      5     member_id="r1i1p1f1",
-      6     table_id="Omon",
-      7     grid_label="gn",
-      8     experiment_id=experiment_ids,
-      9     require_all_on=[
-     10         "source_id"
-     11     ],  # make sure that we only get models which have all of the above experiments
-     12 )
-     14 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     15 kwargs = dict(
-     16     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     17     xarray_open_kwargs=dict(
-   (...)
-     22     },  # anonymous/public authentication to google cloud storage
-     23 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-
-
cat_area = col.search(
-    source_id=source_ids,
-    variable_id="areacello",  # for the coding exercise, ellipses will go after the equals on this line
-    member_id="r1i1p1f1",
-    table_id="Ofx",  # for the coding exercise, ellipses will go after the equals on this line
-    grid_label="gn",
-    experiment_id=[
-        "historical"
-    ],  # for the coding exercise, ellipses will go after the equals on this line
-    require_all_on=["source_id"],
-)
-
-cat_area.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_area = cat_area.to_datatree(**kwargs)
-
-dt_with_area = DataTree()
-
-for model, subtree in dt.items():
-    metric = dt_area[model]["historical"].ds["areacello"]
-    dt_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 cat_area = col.search(
-      2     source_id=source_ids,
-      3     variable_id="areacello",  # for the coding exercise, ellipses will go after the equals on this line
-      4     member_id="r1i1p1f1",
-      5     table_id="Ofx",  # for the coding exercise, ellipses will go after the equals on this line
-      6     grid_label="gn",
-      7     experiment_id=[
-      8         "historical"
-      9     ],  # for the coding exercise, ellipses will go after the equals on this line
-     10     require_all_on=["source_id"],
-     11 )
-     13 cat_area.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-     14 dt_area = cat_area.to_datatree(**kwargs)
-
-NameError: name 'col' is not defined
-
-
-
-
-

Let’s first reproduce the previous tutorial’s timeseries of Global Mean SST from TaiESM1 through the historical experiment and two future emissions scenarios

-
-
-
# average every dataset in the tree globally
-dt_gm = dt_with_area.map_over_subtree(global_mean)
-
-for experiment in ["historical", "ssp126", "ssp585"]:
-    da = dt_gm["TaiESM1"][experiment].ds.tos
-    da.plot(label=experiment)
-plt.title("Global Mean SST from TaiESM1")
-plt.ylabel("Global Mean SST [$^\circ$C]")
-plt.xlabel("Year")
-plt.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 2
-      1 # average every dataset in the tree globally
-----> 2 dt_gm = dt_with_area.map_over_subtree(global_mean)
-      4 for experiment in ["historical", "ssp126", "ssp585"]:
-      5     da = dt_gm["TaiESM1"][experiment].ds.tos
-
-NameError: name 'dt_with_area' is not defined
-
-
-
-
-
-

Coding Exercise 1.1: Combine Past Data and Future Data, and Remove Seasonal Oscillations, and plot all 5 of the CMIP6 models we just loaded#

-
    -
  • The historical and projected data are separate time series. Complete the xr.concat function to combine the historical and projected data into a single continuous time series for each model.

  • -
  • The previous timeseries oscillated very rapidly due to Earth’s seasonal cycles. Finish the xarray resample function so that it smooths the monthly data with a one-year running mean. This will make it easier to distinguish the long-term changes in sea surface temperature.

  • -
  • Note: this code is already set up to use all 5 of the CMIP6 models you just loaded, as it loops through and plots each model in the DataTree [dt.keys()]

  • -
-
-
-
def plot_historical_ssp126_combined(dt):
-    for model in dt.keys():
-        datasets = []
-        for experiment in ["historical", "ssp126"]:
-            datasets.append(dt[model][experiment].tos)
-
-        # for each of the models, concatenate its historical and future data
-        da_combined = ...
-        # plot annual averages
-        ...
-
-
-_ = ...
-
-plt.title("Global Mean SST from five CMIP6 models (annually smoothed)")
-plt.ylabel("Global Mean SST [$^\circ$C]")
-plt.xlabel("Year")
-plt.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 15
-     10         ...
-     13 _ = ...
----> 15 plt.title("Global Mean SST from five CMIP6 models (annually smoothed)")
-     16 plt.ylabel("Global Mean SST [$^\circ$C]")
-     17 plt.xlabel("Year")
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Question 1.1#

-
    -
  1. Why do you think the global mean temperature varies so much between models?*

  2. -
-

*If you get stuck here, reflect on the videos from earlier today and the tutorials/videos from the Climate Modelling day for inspiration.

-

Click for solution

-
-
-

Coding Exercise 1.2#

-

As you just saw, the global mean SST varies between climate models. This is not surprising given the slight differences in physics, numerics, and discretization between each model.

-

When we are looking at future projections, we care about how the model’s change relative to their equilibrium/previous state. To do this, we typically subtract a historical reference period from the timeseries, which creates a new timeseries which we call the temperature anomaly relative to that period. Recall that you already calculated and used anomalies earlier in the course (e.g., on W1D1).

-

Modify the following code to recreate the previous multi-model figure, but now instead plot the global mean sea surface temperature (GMSST) anomaly relative the 1950-1980 base period (i.e., subtract the 1950-1980 mean GMSST of each model from that model’s timeseries)

-

Hint: you will need to use ds.sel to select data during the base period (see here under “Indexing with dimension names” for a helpful example) along with the averaging operator, mean().

-
-
-
# calculate anomaly to reference period
-def datatree_anomaly(dt):
-    dt_out = DataTree()
-    for model, subtree in dt.items():
-        # find the temporal average over the desired reference period
-        ref = ...
-        dt_out[model] = ...
-    return dt_out
-
-
-dt_gm_anomaly = datatree_anomaly(dt_gm)
-
-_ = ...
-
-plt.title("Global Mean SST Anomaly from five CMIP6 models (base period: 1950 to 1980)")
-plt.ylabel("Global Mean SST Anomaly [$^\circ$C]")
-plt.xlabel("Year")
-plt.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 11
-      7         dt_out[model] = ...
-      8     return dt_out
----> 11 dt_gm_anomaly = datatree_anomaly(dt_gm)
-     13 _ = ...
-     15 plt.title("Global Mean SST Anomaly from five CMIP6 models (base period: 1950 to 1980)")
-
-NameError: name 'dt_gm' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Questions 1.2: Climate Connection#

-
    -
  1. How does this figure compare to the previous one where the reference period was not subtracted?

  2. -
  3. This figure uses the reference period of 1950-1980 for its anomaly calculation. How does the variability across models 100 years before the base period (1850) compare to the variability 100 years after the base period (2080)? Why do you think this is?

  4. -
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, we expanded on the previous examination of a single CMIP6 model (TaiESM1), to instead work with multi-model ensemble comprising five different CMIP6 models (TaiESM1, IPSL-CM6A-LR, GFDL-ESM4, ACCESS-CM2, and MPI-ESM1-2-LR) developed by institutions around the world. We demonstrated the importance of anomalizing each of these models relative to a base period when calculating changes in the simulated Earth system. If variables are not anomalized, these absolute values can differ significantly between models due to the diversity of models (i.e., their distinct physics, numerics and discretization).

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4.html deleted file mode 100644 index e73f29979..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial4.html +++ /dev/null @@ -1,1605 +0,0 @@ - - - - - - - - - - - - Tutorial 4: Quantifying Uncertainty in Projections — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 4: Quantifying Uncertainty in Projections#

-

Week 2, Day 1, Future Climate: The Physical Basis

-

Content creators: Brodie Pearson, Julius Busecke, Tom Nicholas

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives#

-

In the previous tutorial, we constructed a multi-model ensemble using data from a diverse set of five CMIP6 models. We showed that the projections differ between models due to their distinct physics, numerics and discretizations. In this tutorial, we will calculate the uncertainty associated with future climate projections by utilizing this variability across CMIP6 models. We will establish a likely range of projections as defined by the IPCC.

-

By the end of this tutorial, you will be able to

-
    -
  • apply IPCC confidence levels to climate model data

  • -
  • quantify the uncertainty associated with CMIP6/ScenarioMIP projections.

  • -
-
-
-

Setup#

-
-
-
# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null
-
-
-
-
-
-
-
# imports
-import time
-
-tic = time.time()
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 6
-      2 import time
-      4 tic = time.time()
-----> 6 import intake
-      7 import numpy as np
-      8 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-# %matplotlib inline
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Helper functions#

-
-

Helper functions#

-
-
- - -Hide code cell source - -
-
# @title Helper functions
-
-# If any helper functions you want to hide for clarity (that has been seen before
-# or is simple/uniformative), add here
-# If helper code depends on libraries that aren't used elsewhere,
-# import those libaries here, rather than in the main import cell
-
-
-def global_mean(ds: xr.Dataset) -> xr.Dataset:
-    """Global average, weighted by the cell area"""
-    return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-
-# Calculate anomaly to reference period
-def datatree_anomaly(dt):
-    dt_out = DataTree()
-    for model, subtree in dt.items():
-        # for the coding exercise, ellipses will go after sel on the following line
-        ref = dt[model]["historical"].ds.sel(time=slice("1950", "1980")).mean()
-        dt_out[model] = subtree - ref
-    return dt_out
-
-
-def plot_historical_ssp126_combined(dt):
-    for model in dt.keys():
-        datasets = []
-        for experiment in ["historical", "ssp126"]:
-            datasets.append(dt[model][experiment].ds.tos)
-
-        da_combined = xr.concat(datasets, dim="time")
-
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 9
-      1 # @title Helper functions
-      2 
-      3 # If any helper functions you want to hide for clarity (that has been seen before
-      4 # or is simple/uniformative), add here
-      5 # If helper code depends on libraries that aren't used elsewhere,
-      6 # import those libaries here, rather than in the main import cell
-----> 9 def global_mean(ds: xr.Dataset) -> xr.Dataset:
-     10     """Global average, weighted by the cell area"""
-     11     return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
-

Video 4: Quantifying Uncertainty in Projections#

-
-

Video 4: Quantifying Uncertainty in Projections#

-
-
- - -Hide code cell source - -
-
# @title Video 4: Quantifying Uncertainty in Projections
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Loading CMIP6 Data from Various Models & Experiments#

-

First, lets load the datasets that we used in the previous tutorial, which spanned 5 models. We will use three CMIP6 experiments, adding the high-emissions (SSP5-8.5) future scenario to the historical and SSP1-2.6 experiments used in the last tutorial.

-
-
-
col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)  # open an intake catalog containing the Pangeo CMIP cloud data
-
-# pick our five models and three experiments
-# there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-source_ids = ["IPSL-CM6A-LR", "GFDL-ESM4", "ACCESS-CM2", "MPI-ESM1-2-LR", "TaiESM1"]
-experiment_ids = ["historical", "ssp126", "ssp585"]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 col = intake.open_esm_datastore(
-      2     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      3 )  # open an intake catalog containing the Pangeo CMIP cloud data
-      5 # pick our five models and three experiments
-      6 # there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-      7 source_ids = ["IPSL-CM6A-LR", "GFDL-ESM4", "ACCESS-CM2", "MPI-ESM1-2-LR", "TaiESM1"]
-
-NameError: name 'intake' is not defined
-
-
-
-
-
-
-
# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id=source_ids,
-    variable_id="tos",
-    member_id="r1i1p1f1",
-    table_id="Omon",
-    grid_label="gn",
-    experiment_id=experiment_ids,
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt = cat.to_datatree(**kwargs)
-
-cat_area = col.search(
-    source_id=source_ids,
-    variable_id="areacello",  # for the coding exercise, ellipses will go after the equals on this line
-    member_id="r1i1p1f1",
-    table_id="Ofx",  # for the coding exercise, ellipses will go after the equals on this line
-    grid_label="gn",
-    experiment_id=[
-        "historical"
-    ],  # for the coding exercise, ellipses will go after the equals on this line
-    require_all_on=["source_id"],
-)
-
-cat_area.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_area = cat_area.to_datatree(**kwargs)
-
-dt_with_area = DataTree()
-
-for model, subtree in dt.items():
-    metric = dt_area[model]["historical"].ds["areacello"]
-    dt_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)
-
-# average every dataset in the tree globally
-dt_gm = dt_with_area.map_over_subtree(global_mean)
-
-for experiment in ["historical", "ssp126", "ssp585"]:
-    da = dt_gm["TaiESM1"][experiment].ds.tos
-#     da.plot(label=experiment)
-# plt.title('Global Mean SST from TaiESM1')
-# plt.ylabel('Global Mean SST [$^\circ$C]')
-# plt.xlabel('Year')
-# plt.legend()
-
-# plot_historical_ssp126_combined(dt_gm)
-
-dt_gm_anomaly = datatree_anomaly(dt_gm)
-
-# plot_historical_ssp126_combined(dt_gm_anomaly)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # from the full `col` object, create a subset using facet search
-----> 2 cat = col.search(
-      3     source_id=source_ids,
-      4     variable_id="tos",
-      5     member_id="r1i1p1f1",
-      6     table_id="Omon",
-      7     grid_label="gn",
-      8     experiment_id=experiment_ids,
-      9     require_all_on=[
-     10         "source_id"
-     11     ],  # make sure that we only get models which have all of the above experiments
-     12 )
-     14 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     15 kwargs = dict(
-     16     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     17     xarray_open_kwargs=dict(
-   (...)
-     22     },  # anonymous/public authentication to google cloud storage
-     23 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-
-

Section 2: Quantifying Uncertainty in a CMIP6 Multi-model Ensemble#

-

Let’s create a multi-model ensemble containing data from multiple CMIP6 models, which we can use to quantify our confidence in future projected sea surface temperature change under low- and high-emissions scenarios.

-

Your goal in this tutorial is to create a likely range of future projected conditions. The IPCC uncertainty language defines the likely range as the middle 66% of model results (ignoring the upper 17% and lower 17% of results)

-
-

Coding Exercise 2.1#

-

Complete the following code to display multi-model ensemble data with IPCC uncertainty bands:

-
    -
  1. The multi-model mean temperature

  2. -
  3. Shading to display the likely range of temperatures for the CMIP6 historical and projected data (include both SSP1-2.6 and SSP5-8.5). da_upper and da_lower are the boundaries of this shaded region

  4. -
-
-
-
%matplotlib inline
-
-for experiment, color in zip(["historical", "ssp126", "ssp585"], ["C0", "C1", "C2"]):
-    datasets = []
-    for model in dt_gm_anomaly.keys():
-        annual_sst = (
-            dt_gm_anomaly[model][experiment]
-            .ds.tos.coarsen(time=12)
-            .mean()
-            .assign_coords(source_id=model)
-        )
-        datasets.append(
-            annual_sst.sel(time=slice(None, "2100")).load()
-        )  # the french model has a long running member for ssp126
-    da = xr.concat(datasets, dim="source_id", join="override").squeeze()
-    x = da.time.data
-    # Calculate the lower bound of the likely range
-    da_lower = ...
-    # Calculate the upper bound of the likely range
-    da_upper = ...
-    # plt.fill_between(range(x), da_lower, da_upper,  alpha=0.5, color=color)
-    # Calculate the multi-model mean at each time within each experiment
-    _ = ...
-plt.title(
-    "Global Mean SST Anomaly from five-member CMIP6 ensemble (base period: 1950 to 1980)"
-)
-plt.ylabel("Global Mean SST Anomaly [$^\circ$C]")
-plt.xlabel("Year")
-plt.legend()
-
-plt.show()
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 get_ipython().run_line_magic('matplotlib', 'inline')
-      3 for experiment, color in zip(["historical", "ssp126", "ssp585"], ["C0", "C1", "C2"]):
-      4     datasets = []
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/interactiveshell.py:2417, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
-   2415     kwargs['local_ns'] = self.get_local_scope(stack_depth)
-   2416 with self.builtin_trap:
--> 2417     result = fn(*args, **kwargs)
-   2419 # The code below prevents the output from being displayed
-   2420 # when using magics with decodator @output_can_be_silenced
-   2421 # when the last Python token in the expression is a ';'.
-   2422 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/magics/pylab.py:99, in PylabMagics.matplotlib(self, line)
-     97     print("Available matplotlib backends: %s" % backends_list)
-     98 else:
----> 99     gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
-    100     self._show_matplotlib_backend(args.gui, backend)
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/IPython/core/interactiveshell.py:3588, in InteractiveShell.enable_matplotlib(self, gui)
-   3567 def enable_matplotlib(self, gui=None):
-   3568     """Enable interactive matplotlib and inline figure support.
-   3569 
-   3570     This takes the following steps:
-   (...)
-   3586         display figures inline.
-   3587     """
--> 3588     from matplotlib_inline.backend_inline import configure_inline_support
-   3590     from IPython.core import pylabtools as pt
-   3591     gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/matplotlib_inline/__init__.py:1
-----> 1 from . import backend_inline, config  # noqa
-      2 __version__ = "0.1.6"  # noqa
-
-File /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/matplotlib_inline/backend_inline.py:6
-      1 """A matplotlib backend for publishing figures via display_data"""
-      3 # Copyright (c) IPython Development Team.
-      4 # Distributed under the terms of the BSD 3-Clause License.
-----> 6 import matplotlib
-      7 from matplotlib import colors
-      8 from matplotlib.backends import backend_agg
-
-ModuleNotFoundError: No module named 'matplotlib'
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Questions 2.1: Climate Connection#

-
    -
  1. What does this figure tell you about how the multi-model uncertainty compares to projected physical changes in the global mean SST?

  2. -
  3. Is this the same for both scenarios?

  4. -
  5. For a 5-model ensemble like this, how do the likely ranges specifically relate to the 5 individual model temperatures at a given time?

  6. -
-

Click for solution

-
-
-
-

Summary#

-

In this tutorial, we have quantified the uncertainty of future climate projections by analyzing variability across a multi-model CMIP6 ensemble. We learned to apply the IPCC’s confidence levels to establish a likely range of projections, which refers to the middle 66% of model results.

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5.html deleted file mode 100644 index aff2133c1..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial5.html +++ /dev/null @@ -1,1546 +0,0 @@ - - - - - - - - - - - - Tutorial 5: Internal Climate Variability — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 5: Internal Climate Variability#

-

Week 2, Day 1, Future Climate: The Physical Basis

-

Content creators: Brodie Pearson, Julius Busecke, Tom Nicholas

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives#

-

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.

-

By the end of this tutorial, you would be able to:

-
    -
  • Understand the importance of internal climate variability and its role in climate prediction and model uncertainty.

  • -
  • Create and evaluate a single-model ensemble using IPCC uncertainty bands, providing a visual representation of model uncertainty.

  • -
  • 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).

  • -
-
-
-

Setup#

-
-
-
# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null
-
-
-
-
-
-
-
# imports
-import time
-
-tic = time.time()
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 6
-      2 import time
-      4 tic = time.time()
-----> 6 import intake
-      7 import numpy as np
-      8 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-# model_colors = {k:f"C{ki}" for ki, k in enumerate(source_ids)}
-%matplotlib inline
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Helper functions#

-
-

Helper functions#

-
-
- - -Hide code cell source - -
-
# @title Helper functions
-
-# If any helper functions you want to hide for clarity (that has been seen before
-# or is simple/uniformative), add here
-# If helper code depends on libraries that aren't used elsewhere,
-# import those libaries here, rather than in the main import cell
-
-
-def global_mean(ds: xr.Dataset) -> xr.Dataset:
-    """Global average, weighted by the cell area"""
-    return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-
-# Calculate anomaly to reference period
-def datatree_anomaly(dt):
-    dt_out = DataTree()
-    for model, subtree in dt.items():
-        # for the coding exercise, ellipses will go after sel on the following line
-        ref = dt[model]["historical"].ds.sel(time=slice("1950", "1980")).mean()
-        dt_out[model] = subtree - ref
-    return dt_out
-
-
-def plot_historical_ssp126_combined(dt):
-    for model in dt.keys():
-        datasets = []
-        for experiment in ["historical", "ssp126"]:
-            datasets.append(dt[model][experiment].ds.tos)
-
-        da_combined = xr.concat(datasets, dim="time")
-
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 9
-      1 # @title Helper functions
-      2 
-      3 # If any helper functions you want to hide for clarity (that has been seen before
-      4 # or is simple/uniformative), add here
-      5 # If helper code depends on libraries that aren't used elsewhere,
-      6 # import those libaries here, rather than in the main import cell
-----> 9 def global_mean(ds: xr.Dataset) -> xr.Dataset:
-     10     """Global average, weighted by the cell area"""
-     11     return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
-

Video 5: Internal Climate Variability#

-
-

Video 5: Internal Climate Variability#

-
-
- - -Hide code cell source - -
-
# @title Video 5: Internal Climate Variability
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Internal Climate Variability & Single-model Ensembles#

-

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 center carried out multiple simulations of the model for many of the CMIP6 experiments.

-

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.

-
-

Coding Exercise 1.1#

-

Complete the following code to:

-
    -
  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.

  2. -
  3. 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.

  4. -
-
-
-
col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)  # open an intake catalog containing the Pangeo CMIP cloud data
-
-cat_ensemble = col.search(
-    source_id="MPI-ESM1-2-LR",
-    variable_id="tos",
-    table_id="Omon",
-    member_id=["r1i1p1f1", "r2i1p1f1", "r3i1p1f1", "r4i1p1f1", "r5i1p1f1"],
-    grid_label="gn",
-    experiment_id=["historical", "ssp126", "ssp585"],
-    require_all_on=["source_id", "member_id"],
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the
-# actual tutorial, so this would be a lot cleaner
-cat_ensemble.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_ensemble = cat_ensemble.to_datatree(**kwargs)
-
-cat_area = col.search(
-    source_id=["MPI-ESM1-2-LR"],
-    variable_id="areacello",  # for the coding exercise, ellipses will go after the equals on this line
-    member_id="r1i1p1f1",
-    table_id="Ofx",  # for the coding exercise, ellipses will go after the equals on this line
-    grid_label="gn",
-    experiment_id=[
-        "historical"
-    ],  # for the coding exercise, ellipses will go after the equals on this line
-    require_all_on=["source_id"],
-)
-# hopefully we can implement https://github.com/intake/intake-esm/issues/562 before the
-# actual tutorial, so this would be a lot cleaner
-cat_area.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_area = cat_area.to_datatree(**kwargs)
-
-# add the area (we can reuse the area from before, since for a given model the horizontal are does not vary between members)
-dt_ensemble_with_area = DataTree()
-for model, subtree in dt_ensemble.items():
-    metric = dt_area["MPI-ESM1-2-LR"]["historical"].ds["areacello"].squeeze()
-    dt_ensemble_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)
-
-# global average
-# average every dataset in the tree globally
-dt_ensemble_gm = dt_ensemble_with_area.map_over_subtree(global_mean)
-
-# calculate anomaly
-dt_ensemble_gm_anomaly = datatree_anomaly(dt_ensemble_gm)
-
-
-def plot_historical_ssp126_ensemble_combined(dt):
-    for model in dt.keys():
-        datasets = []
-        for experiment in ["historical", "ssp126"]:
-            datasets.append(dt[model][experiment].ds.coarsen(time=12).mean().tos)
-
-        # concatenate the historical and ssp126 timeseries for each ensemble member
-        da_combined = ...
-        # plot annual averages
-        da_combined.plot(hue="member_id")
-
-
-plt.figure()
-_ = ...
-
-plt.title("Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble")
-plt.ylabel("Global Mean SST Anomaly [$^\circ$C]")
-plt.xlabel("Year")
-plt.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 col = intake.open_esm_datastore(
-      2     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      3 )  # open an intake catalog containing the Pangeo CMIP cloud data
-      5 cat_ensemble = col.search(
-      6     source_id="MPI-ESM1-2-LR",
-      7     variable_id="tos",
-   (...)
-     12     require_all_on=["source_id", "member_id"],
-     13 )
-     15 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-
-NameError: name 'intake' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Coding Exercise 1.2#

-

Complete the following code to:

-
    -
  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.

  2. -
-
-
-
for experiment, color in zip(["historical", "ssp126", "ssp585"], ["C0", "C1", "C2"]):
-    da = (
-        dt_ensemble_gm_anomaly["MPI-ESM1-2-LR"][experiment]
-        .ds.tos.coarsen(time=12)
-        .mean()
-        .load()
-    )
-
-    # shading representing spread between members
-    x = da.time.data
-    # diagnose the lower range of the likely bounds
-    da_lower = ...
-    # diagnose the upper range of the likely bounds
-    da_upper = ...
-    _ = ...
-
-    # calculate the mean across ensemble members and plot
-    _ = ...
-plt.title("Global Mean SST Anomaly in SSP1-2.6 from a 5-member single-model ensemble")
-plt.ylabel("Global Mean SST Anomaly [$^\circ$C]")
-plt.xlabel("Year")
-plt.legend()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 3
-      1 for experiment, color in zip(["historical", "ssp126", "ssp585"], ["C0", "C1", "C2"]):
-      2     da = (
-----> 3         dt_ensemble_gm_anomaly["MPI-ESM1-2-LR"][experiment]
-      4         .ds.tos.coarsen(time=12)
-      5         .mean()
-      6         .load()
-      7     )
-      9     # shading representing spread between members
-     10     x = da.time.data
-
-NameError: name 'dt_ensemble_gm_anomaly' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Question 1.2: Climate Connection#

-
    -
  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?

  2. -
-

tutorial 4 solution

-

Click for solution

-
-
-
-

Summary#

-

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.

-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6.html b/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6.html deleted file mode 100644 index acb0ef15d..000000000 --- a/book/_build/html/tutorials/W2D1_FutureClimate-IPCCIPhysicalBasis/student/W2D1_Tutorial6.html +++ /dev/null @@ -1,1584 +0,0 @@ - - - - - - - - - - - - Tutorial 6: Synthesising & Interpreting Diverse Data Sources — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 6: Synthesising & Interpreting Diverse Data Sources#

-

Week 2, Day 1, Future Climate: The Physical Basis

-

Content creators: Brodie Pearson, Julius Busecke, Tom Nicholas

-

Content reviewers: Younkap Nina Duplex, Zahra Khodakaramimaghsoud, Sloane Garelick, Peter Ohue, Jenna Pearson, Derick Temfack, Peizhen Yang, Cheng Zhang, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Ohad Zivan, Chi Zhang

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives#

-

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

-
    -
  • Create a time series of global mean sea surface temperature from observations, models, and proxy data;

  • -
  • Use this data to validate & contextualize climate models, and to provide a holistic picture of Earth’s past and future climate evolution.

  • -
-
-
-

Setup#

-
-
-
# !pip install condacolab &> /dev/null
-# import condacolab
-# condacolab.install()
-
-# # Install all packages in one call (+ use mamba instead of conda), this must in one line or code will fail
-# !mamba install xarray-datatree intake-esm gcsfs xmip aiohttp nc-time-axis cf_xarray xarrayutils &> /dev/null
-
-
-
-
-
-
-
# imports
-import time
-
-tic = time.time()
-
-import intake
-import numpy as np
-import matplotlib.pyplot as plt
-import xarray as xr
-
-from xmip.preprocessing import combined_preprocessing
-from xarrayutils.plotting import shaded_line_plot
-
-from datatree import DataTree
-from xmip.postprocessing import _parse_metric
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 6
-      2 import time
-      4 tic = time.time()
-----> 6 import intake
-      7 import numpy as np
-      8 import matplotlib.pyplot as plt
-
-ModuleNotFoundError: No module named 'intake'
-
-
-
-
-
-

Figure settings#

-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-%config InlineBackend.figure_format = 'retina'
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-# model_colors = {k:f"C{ki}" for ki, k in enumerate(source_ids)}
-%matplotlib inline
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[3], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 get_ipython().run_line_magic('config', "InlineBackend.figure_format = 'retina'")
-      5 plt.style.use(
-      6     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      7 )
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-
-

Helper functions#

-
-

Helper functions#

-
-
- - -Hide code cell source - -
-
# @title Helper functions
-
-# If any helper functions you want to hide for clarity (that has been seen before
-# or is simple/uniformative), add here
-# If helper code depends on libraries that aren't used elsewhere,
-# import those libaries here, rather than in the main import cell
-
-
-def global_mean(ds: xr.Dataset) -> xr.Dataset:
-    """Global average, weighted by the cell area"""
-    return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-
-# calculate anomaly to reference period
-def datatree_anomaly(dt):
-    dt_out = DataTree()
-    for model, subtree in dt.items():
-        # for the coding exercise, ellipses will go after sel on the following line
-        ref = dt[model]["historical"].ds.sel(time=slice("1950", "1980")).mean()
-        dt_out[model] = subtree - ref
-    return dt_out
-
-
-def plot_historical_ssp126_combined(dt):
-    for model in dt.keys():
-        datasets = []
-        for experiment in ["historical", "ssp126"]:
-            datasets.append(dt[model][experiment].ds.tos)
-
-        da_combined = xr.concat(datasets, dim="time")
-
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[4], line 9
-      1 # @title Helper functions
-      2 
-      3 # If any helper functions you want to hide for clarity (that has been seen before
-      4 # or is simple/uniformative), add here
-      5 # If helper code depends on libraries that aren't used elsewhere,
-      6 # import those libaries here, rather than in the main import cell
-----> 9 def global_mean(ds: xr.Dataset) -> xr.Dataset:
-     10     """Global average, weighted by the cell area"""
-     11     return ds.weighted(ds.areacello.fillna(0)).mean(["x", "y"], keep_attrs=True)
-
-NameError: name 'xr' is not defined
-
-
-
-
-
-
-
-

Video 6: Historical Context for Future Projections#

-
-

Video 6: Historical Context for Future Projections#

-
-
- - -Hide code cell source - -
-
# @title Video 6: Historical Context for Future Projections
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-

Section 1: Reproduce Global SST for Historical and Future Scenario Experiments#

-

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.

-
-

Section 1.1: Load CMIP6 SST Data from Several Models using xarray#

-

Let’s load the five different CMIP6 models again for the three CMIP6 experiments.

-
-
-
col = intake.open_esm_datastore(
-    "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-)  # open an intake catalog containing the Pangeo CMIP cloud data
-
-# pick our five example models
-# there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-source_ids = ["IPSL-CM6A-LR", "GFDL-ESM4", "ACCESS-CM2", "MPI-ESM1-2-LR", "TaiESM1"]
-experiment_ids = ["historical", "ssp126", "ssp585"]
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 1
-----> 1 col = intake.open_esm_datastore(
-      2     "https://storage.googleapis.com/cmip6/pangeo-cmip6.json"
-      3 )  # open an intake catalog containing the Pangeo CMIP cloud data
-      5 # pick our five example models
-      6 # there are many more to test out! Try executing `col.df['source_id'].unique()` to get a list of all available models
-      7 source_ids = ["IPSL-CM6A-LR", "GFDL-ESM4", "ACCESS-CM2", "MPI-ESM1-2-LR", "TaiESM1"]
-
-NameError: name 'intake' is not defined
-
-
-
-
-
-
-
# from the full `col` object, create a subset using facet search
-cat = col.search(
-    source_id=source_ids,
-    variable_id="tos",
-    member_id="r1i1p1f1",
-    table_id="Omon",
-    grid_label="gn",
-    experiment_id=experiment_ids,
-    require_all_on=[
-        "source_id"
-    ],  # make sure that we only get models which have all of the above experiments
-)
-
-# convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-kwargs = dict(
-    preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-    xarray_open_kwargs=dict(
-        use_cftime=True
-    ),  # ensure all datasets use the same time index
-    storage_options={
-        "token": "anon"
-    },  # anonymous/public authentication to google cloud storage
-)
-
-cat.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt = cat.to_datatree(**kwargs)
-
-cat_area = col.search(
-    source_id=source_ids,
-    variable_id="areacello",  # for the coding exercise, ellipses will go after the equals on this line
-    member_id="r1i1p1f1",
-    table_id="Ofx",  # for the coding exercise, ellipses will go after the equals on this line
-    grid_label="gn",
-    experiment_id=[
-        "historical"
-    ],  # for the coding exercise, ellipses will go after the equals on this line
-    require_all_on=["source_id"],
-)
-
-cat_area.esmcat.aggregation_control.groupby_attrs = ["source_id", "experiment_id"]
-dt_area = cat_area.to_datatree(**kwargs)
-
-dt_with_area = DataTree()
-
-for model, subtree in dt.items():
-    metric = dt_area[model]["historical"].ds["areacello"]
-    dt_with_area[model] = subtree.map_over_subtree(_parse_metric, metric)
-
-# average every dataset in the tree globally
-dt_gm = dt_with_area.map_over_subtree(global_mean)
-
-dt_gm_anomaly = datatree_anomaly(dt_gm)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 2
-      1 # from the full `col` object, create a subset using facet search
-----> 2 cat = col.search(
-      3     source_id=source_ids,
-      4     variable_id="tos",
-      5     member_id="r1i1p1f1",
-      6     table_id="Omon",
-      7     grid_label="gn",
-      8     experiment_id=experiment_ids,
-      9     require_all_on=[
-     10         "source_id"
-     11     ],  # make sure that we only get models which have all of the above experiments
-     12 )
-     14 # convert the sub-catalog into a datatree object, by opening each dataset into an xarray.Dataset (without loading the data)
-     15 kwargs = dict(
-     16     preprocess=combined_preprocessing,  # apply xMIP fixes to each dataset
-     17     xarray_open_kwargs=dict(
-   (...)
-     22     },  # anonymous/public authentication to google cloud storage
-     23 )
-
-NameError: name 'col' is not defined
-
-
-
-
-
-

Coding Exercise 1.1#

-

Complete the following code to:

-
    -
  1. Calculate a time series of the global mean sea surface temperature (GMSST) from the HadISST dataset

  2. -
  3. Subtract a base period from the HadISST GMSST time series. Use the same base period as the CMIP6 timeseries you are comparing against.

  4. -
-
-
-
for experiment, color in zip(["historical", "ssp126", "ssp585"], ["C0", "C1", "C2"]):
-    datasets = []
-    for model in dt_gm_anomaly.keys():
-        annual_sst = (
-            dt_gm_anomaly[model][experiment]
-            .ds.tos.coarsen(time=12)
-            .mean()
-            .assign_coords(source_id=model)
-            .load()
-        )
-        datasets.append(
-            annual_sst.sel(time=slice(None, "2100")).load()
-        )  # the french model has a long running member for ssp 126 (we could change the model to keep this clean)
-    da = xr.concat(datasets, dim="source_id", join="override").squeeze()
-    x = da.time.data
-    da_lower = da.squeeze().quantile(0.17, dim="source_id")
-    da_upper = da.squeeze().quantile(0.83, dim="source_id")
-    plt.fill_between(range(len(x)), da_lower, da_upper, alpha=0.5, color=color)
-    da.mean("source_id").plot(
-        color=color,
-        label=experiment,
-    )
-
-# but now add observations (https://pangeo-forge.org/dashboard/feedstock/43)
-store = "https://ncsa.osn.xsede.org/Pangeo/pangeo-forge/HadISST-feedstock/hadisst.zarr"
-ds_obs = xr.open_dataset(store, engine="zarr", chunks={}).convert_calendar(
-    "standard", use_cftime=True
-)
-# mask missing values
-ds_obs = ds_obs.where(ds_obs > -1000)
-weights = np.cos(
-    np.deg2rad(ds_obs.latitude)
-)  # In a regular lon/lat grid, area is ~cos(latitude)
-# calculate weighted global mean for observations
-sst_obs_gm = ...
-# calculate anomaly for observations
-sst_obs_gm_anomaly = ...
-
-# coarsen, trim and calculate mean then plot observations
-_ = ...
-plt.ylabel("Global Mean SST with respect to 1950-1980")
-plt.xlabel("Year")
-plt.legend()
-
-plt.show()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 3
-      1 for experiment, color in zip(["historical", "ssp126", "ssp585"], ["C0", "C1", "C2"]):
-      2     datasets = []
-----> 3     for model in dt_gm_anomaly.keys():
-      4         annual_sst = (
-      5             dt_gm_anomaly[model][experiment]
-      6             .ds.tos.coarsen(time=12)
-   (...)
-      9             .load()
-     10         )
-     11         datasets.append(
-     12             annual_sst.sel(time=slice(None, "2100")).load()
-     13         )  # the french model has a long running member for ssp 126 (we could change the model to keep this clean)
-
-NameError: name 'dt_gm_anomaly' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -
-
-

Questions 1.1 Climate Connection#

-

Now that you have a modern and projected time series containing models and observations,

-
    -
  1. What context and/or validation of the simulations does this information provide?

  2. -
  3. 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)

  4. -
-

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)

-

-

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).

-

Click for solution

-
-
-
-

Summary#

-

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.

-

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.

-
-
-
-

Resources#

-

Data for this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/chapter_title.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/chapter_title.html deleted file mode 100644 index 363f4cbfc..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/chapter_title.html +++ /dev/null @@ -1,1262 +0,0 @@ - - - - - - - - Good Research Practices — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - -
-
- - -
-
-
-
-
- -
-

Good Research Practices

- -
-
- -
-
-
-
- -
- -
-

Good Research Practices

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/further_reading.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/further_reading.html deleted file mode 100644 index b0e0ac5c1..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/further_reading.html +++ /dev/null @@ -1,1257 +0,0 @@ - - - - - - - - Suggested Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - -
-
- - -
-
-
-
-
- -
-

Suggested Further Reading

- -
-
- -
-
-
-
- -
- -
-

Suggested Further Reading

-

We have included a number of suggested readings throughout the tutorial. Please check them out if you are interested!

-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.html deleted file mode 100644 index c697ce982..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial1.html +++ /dev/null @@ -1,1539 +0,0 @@ - - - - - - - - Tutorial 1: Finding a Phenomenon and Asking a Question About It — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1: Finding a Phenomenon and Asking a Question About It

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorial Objectives

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-

Demos

-

In order to illustrate the process, we will use a sample research question about how the surface temperature of the earth depends on the CO\(_2\) content of the atmosphere.

-
-

Video 1: Identifying a Question

-
-

Video 1: Identifying a Question

-
-

Video 1: Identifying a Question

-
-
Video 1: Identifying a Question
-
-
Video 1: Identifying a Question
-

####### Video 1: Identifying a Question

-

######## Video 1: Identifying a Question

-

######### Video 1: Identifying a Question

-

########## Video 1: Identifying a Question

-

########### Video 1: Identifying a Question

-

############ Video 1: Identifying a Question

-
-
-
# @title Video 1: Identifying a Question
-#Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-
-
-

Activity: Asking Your Own Question

-

Write down a phenomenon you would like to gain understanding about. Take 5 minutes to construct a question about the phenomenon. Discuss amongst your group to improve the question. For some inspiration:

-
    -
  • Are there other aspects of the planet that may influence the average surface temperature?

  • -
  • Are there other features of the planet that may be impacted by changes in the average surface temperature?

  • -
-
-

Make Sure to Avoid the Pitfalls!

-
-Click here for a recap on pitfalls -

Question is too broad

-
    -
  • Science advances one small step at a time. Narrowing the scope will help clarify your next steps
  • -
-

Question does not identify a precise aspect of the phenomenon

-
    -
  • Clarity will help identify next steps in your research
  • -
  • If you are struggling to identify a precise aspect, you might need to learn more about the phenomenon. Look to the literature (Step 2)!
  • -
-

Question is about an analysis method

-
    -
  • An analysis method is a tool, not the big picture
  • -
-
-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial2.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial2.html deleted file mode 100644 index 33f18eb50..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial2.html +++ /dev/null @@ -1,1561 +0,0 @@ - - - - - - - - Tutorial 2: Doing a Literature Review — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2: Doing a Literature Review

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-

Video 2: Doing a Literature Review

-
-

Video 2: Doing a Literature Review

-
-

Video 2: Doing a Literature Review

-
-
Video 2: Doing a Literature Review
-
-
Video 2: Doing a Literature Review
-

####### Video 2: Doing a Literature Review

-

######## Video 2: Doing a Literature Review

-

######### Video 2: Doing a Literature Review

-

########## Video 2: Doing a Literature Review

-

########### Video 2: Doing a Literature Review

-

############ Video 2: Doing a Literature Review

-
-
-
# @title Video 2: Doing a Literature Review
-#Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-
-
-

Tutorial Objectives

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-

Activity: Understanding the Literature Review Process

-

While a comprehensive literature review typically requires an extensive timeframe spanning months or even years, in the context of your Project Template, we will conduct a condensed literature review within two days. Instead of tasking you with reviewing the literature on our sample research topic, we will provide additional guidance on the process of conducting a literature review.

-

During this timeframe, you will be introduced to the fundamental aspects and techniques of performing a literature review, enabling you to gain insights into the necessary steps and best practices. Although the review will be concise, it will equip you with the essential skills to navigate the literature effectively and lay the foundation for future in-depth literature reviews.

-
-

Equity in Literature Review

-
-Click here for some points to consider when doing your literature review -

The choices we make as a collective have an impact on who is included and who is excluded in the scientific process. While there is no perfect solution to addressing inequity in the sciences, we can contribute by engaging in an ongoing conversation and being receptive to feedback regarding our impact. Here are some points to consider:

-
    -
  • Which papers are you selecting for your review? Which papers are you citing? Are there overlooked studies with valuable results?

  • -
  • Does your work relate to a phenomenon that affects a specific community? Have members of that community made observations or documented the phenomenon?

  • -
  • Has your own experience informed you of equity concerns in the knowledge base that you are in a good position to address?

  • -
-

Remember, perfection is not the goal. Every choice we make carries unintended consequences. By keeping equity in mind, we can remain open to constructive feedback and identify areas where we can make a positive impact.

-

Here are some resources that may help you incorporate knowledge and understanding from underrepresented groups:

- -

Here is some reading relating to Arrhenius and his racism:

-

College Chemistry Textbooks Aid and Abet Racial Disparity. Mona L. Becker and Melanie R. Nilsson. Journal of Chemical Education 2022 99 (5), 1847-1854. DOI: https://doi.org/10.1021/acs.jchemed.1c00968

-
-
-

Tips for Efficiency

-
-Click here for some pointers on reviewing literature efficiently -

There are many different strategies for reviewing literature efficiently. Here are some descriptions of the processes that different researchers use. If you are new to a topic, we recommend you start by looking for a review paper, which will summarize the results of multiple studies and direct you to other papers worth reading.

-

Here is one option for reading papers efficiently:

-
    -
  • Start by reviewing the abstract and conclusions sections. This will help you determine the relevance of the paper’s results to your research.

  • -
  • Conduct a “quick pass” of the paper

  • -
-
    -
  • Scan through the figures and diagrams.
  • -
  • Identify the references to these figures in the text and read the surrounding discussion.
  • -
  • Take note of any parts of the figures or discussion that you find difficult to understand.
  • -
-* Seek additional information to address the areas that you found challenging: -
    -
  • Refer to previous sections of the paper that describe the methods and analysis.
  • -
  • Explore other papers that cite or are cited by the paper you are reading.
  • -
  • Consult relevant textbooks or resources on the subject.
  • -
  • Seek guidance from professors or peers in your field.
  • -
-* If the paper seems extremely important, or if you are tasked with presenting it to a group, consider reading it in its entirety. To maximize your comprehension, you can -
    -
  • Summarize the main message of each paragraph in one sentence or less.
  • -
  • Create written descriptions or sketches of the phenomena discussed.
  • -
  • Identify the physical meaning and implications of terms and equations.
  • -
-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial3.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial3.html deleted file mode 100644 index ca7ef9a40..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial3.html +++ /dev/null @@ -1,1559 +0,0 @@ - - - - - - - - Tutorial 3: Identifying the Basic Ingredients — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3: Identifying the Basic Ingredients

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-

Video 3: Identifying the Basic Ingredients

-
-

Video 3: Identifying the Basic Ingredients

-
-

Video 3: Identifying the Basic Ingredients

-
-
Video 3: Identifying the Basic Ingredients
-
-
Video 3: Identifying the Basic Ingredients
-

####### Video 3: Identifying the Basic Ingredients

-

######## Video 3: Identifying the Basic Ingredients

-

######### Video 3: Identifying the Basic Ingredients

-

########## Video 3: Identifying the Basic Ingredients

-

########### Video 3: Identifying the Basic Ingredients

-

############ Video 3: Identifying the Basic Ingredients

-
-
-
# @title Video 3: Identifying the Basic Ingredients
-#Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-
-
-

Tutorial Objectives

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-

Activity: Identifying Basic Ingredients

-

Take 10 minutes to discuss the advantages and disadvantages of utilizing the following basic ingredients to explore the research question discussed in Video 1:

-
    -
  • Ice core data for CO2

  • -
  • Deep sea sediment data for sea surface temperature

  • -
-

Can you think of alternative approaches that might work well?

-
-

Choosing Your Data

-
-Click here for some pointers on how to choose your data -

Here are some questions to ask yourself when choosing the data to use:

-

What physical processes must be included?

-
    -
  • You don't want an approach that contains less than the bare minimum. For some phenomena, we know what the bare minimum is. For others, more research is needed...
  • -
  • If you are unsure about what physical processes are needed, check the literature!
-

What spatial and temporal resolution is necessary to capture the phenomenon?

-
    -
  • GCMs can typically have a spatial resolution around 100km and time resolution of several hours.
  • -
  • For phenomena that require higher resolution, you can either
  • -
    • Use a more idealized model that resolves smaller scales
    • Implement a parameterization of the sub-gridscale features within the GCM.
    • -
-

What restrictions do I have for computational resources?

-
    -
  • If you do not have access to large computational resources, you can still do research using smaller datasets or idealized models
  • -
-

Am I interested in looking at a particular time period or a specific physical location?

-
    -
  • Reanalysis can be used for time periods after roughly the 1940s
  • -
  • Proxy data can be used for a wider historical and prehistorical data
  • -
  • Both reanalysis and proxy data can provide specific location information
  • -
  • Models can be designed to mimic the conditions of the location or time, for example:
    • -
    • GCMs (General Circulation Models or Global Climate Models) can be set according to parameters that resemble the time period
    • -
    • Energy balance models can capture some aspects of average temperature in other time periods
    • -
    • Radiative-convective equilibrium models can capture some phenomena in the tropics
    • -
    • Quasi-geostrophic models can capture some phenomena in the mid-latitudes (between ~30-60 degrees)
    • -
    • And many more!
    • -
    -
-

Am I interested in studying a feature of the phenomenon in isolation or interactions between multiple features?

-
    -
  • If you want to isolate a single aspect of the phenomenon, an idealized model may be more appropriate
  • -
  • If you want to study interactions between multiple features, either observational data or a more complex model may be appropriate
  • -
-

Am I trying to…

-
    -
  • explain the theory behind the phenomenon? An idealized model may be appropriate
  • -
  • provide evidence to support or challenge a pre-existing hypothesis? Observational data or a more complex model may be appropriate
  • -
  • document the features of the phenomenon? Observational data may be appropriate
  • -
-

For more information on observational data:

- -

For more information on numerical modeling:

-
    -
  • Atmospheric Model Hierarchies: Maher, P., Gerber, E. P., Medeiros, B., Merlis, T. M., Sherwood, S., Sheshadri, A., et al. (2019). Model hierarchies for understanding atmospheric circulation, Reviews of Geophysics, 57, 250– 280. https://doi.org/10.1029/2018RG000607

  • -
  • Ocean Model Hierarchies: Hsu, T.-Y., Primeau, F., & Magnusdottir, G. (2022). A hierarchy of global ocean models coupled to CESM1. Journal of Advances in Modeling Earth Systems, 14, e2021MS002979. https://doi.org/10.1029/2021MS002979

  • -
-
-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial4.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial4.html deleted file mode 100644 index 74d8cbed2..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial4.html +++ /dev/null @@ -1,1559 +0,0 @@ - - - - - - - - Tutorial 4: Formulating a Hypothesis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 4: Formulating a Hypothesis

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-

Video 4: Formulating a Hypothesis

-
-

Video 4: Formulating a Hypothesis

-
-

Video 4: Formulating a Hypothesis

-
-
Video 4: Formulating a Hypothesis
-
-
Video 4: Formulating a Hypothesis
-

####### Video 4: Formulating a Hypothesis

-

######## Video 4: Formulating a Hypothesis

-

######### Video 4: Formulating a Hypothesis

-

########## Video 4: Formulating a Hypothesis

-

########### Video 4: Formulating a Hypothesis

-

############ Video 4: Formulating a Hypothesis

-
-
-
# @title Video 4: Formulating a Hypothesis
-#Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-
-
-

Tutorial Objectives

-

In Tutorials 1-4, you will learn about the process of research design. This includes how to

-
    -
  1. Identify a phenomenon and formulate a research question surrounding it

  2. -
  3. Efficiently review existing literature and knowledge about the phenomenon

  4. -
  5. Identify what is needed to study the phenomenon

  6. -
  7. Formulate a testable hypothesis regarding the phenomenon

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-

Activity: Understanding Hypothesis

-

Take 5 minutes to discuss how a hypothesis differs from a research question.

-
-

Make Sure to Avoid the pitfalls!

-
-Click here for a recap on pitfalls -

I don’t need a hypothesis, I will just play around with the model/data

-
    -
  • A hypothesis will help to clarify your goals when presenting research. After all, "I just played around with this model a lot" isn't a very satisfying scientific result
  • -
  • However, we encourage you to explore and experiment with the model and the data, as this can help develop your intuition and understanding of the subject matter
  • -
  • Hypothesis formation is often an iterative process involving both the literature review and playing around with your model and data
  • -
-

My hypothesis doesn’t match my question (or vice versa)

-
    -
  • This is a normal part of the process!
  • -
  • You can return to Step 1 and update your question / phenomenon / goals
  • -
-

I can’t write down a hypothesis

-
    -
  • If you find it challenging to articulate a hypothesis, it may indicate that you lack ingredients and/or clarity on the hypothesis. Try returning to Step 2 to further your literature review, or continue playing around with your model or data.
  • -
-
-
-
-

Tutorials 1-4 Summary

-

Through tutorials 1-4, we worked through the preliminary steps of starting a research project.

-
    -
  • We identified a phenomenon and formulated a question (Step 1)

  • -
  • We did a review of the literature and determine what has already been studied about the phenomenon (Step 2)

  • -
  • We determined what basic ingredients we need to investigate the phenomenon (Step 3)

  • -
  • We used all of the above to formulate a testable hypothesis (Step 4)

  • -
-
-
-

Next Steps

-

Tutorials 5-8 will illustrate the steps involved in data analysis, interpreting your results, and communicating your results to an audience. As you do your own research, feel free to return to this tutorial as a guide.

-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial5.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial5.html deleted file mode 100644 index 107ccb288..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial5.html +++ /dev/null @@ -1,1543 +0,0 @@ - - - - - - - - Tutorial 5: Drafting the Analysis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 5: Drafting the Analysis

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorials Objectives

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-
# imports
-
-import matplotlib.pyplot as plt
-import pandas as pd
-import seaborn as sns
-import numpy as np
-from scipy import interpolate
-from scipy import stats
-
-
-
-
-
-

Video 6: Drafting the Analysis

-
-

Video 6: Drafting the Analysis

-
-

Video 6: Drafting the Analysis

-
-
Video 6: Drafting the Analysis
-
-
Video 6: Drafting the Analysis
-

####### Video 6: Drafting the Analysis

-

######## Video 6: Drafting the Analysis

-

######### Video 6: Drafting the Analysis

-

########## Video 6: Drafting the Analysis

-

########### Video 6: Drafting the Analysis

-

############ Video 6: Drafting the Analysis

-
-
-
# @title Video 6: Drafting the Analysis
-#Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-
-
-

Coding Exercise 1

-

To explore the relationship between CO2 and temperature, you may want to make a scatter plot of the two variables, where the x-axis represents CO2 and the y-axis represents temperature. Then you can see if a linear regression model fits the data well.

-

Before you do that, let’s learn how to apply a linear regression model using generated data.

-

If you aren’t familiar with a linear regression model, it is simply a way of isolating a relationship between two variables (e.g. x and y). For example, each giraffe might have different running speeds. You might wonder if taller giraffes run faster than shorter ones. How do we describe the relationship between a giraffe’s height and its running speed? A linear regression model will be able to provide us a mathematical equation:

-

speed = a * height +  b

-

where a and b are the slope and intercept of the equation, respectively. Such an equation allows us to predict an unknown giraffe’s running speed by simply plugging its height into the equation. Not all giraffes will fit the relationship and other factors might influence their speeds, such as health, diet, age, etc. However, because of its simplicity, linear regression models are usually first attempted by scientists to quantify the relationship between variables.

-

For more information on linear regression models, see the Wikipedia page, especially the first figure on that page:

-
-
-
# set up a random number generator
-rng = np.random.default_rng()
-# x is one hundred random numbers between 0 and 1
-x = rng.random(100)
-# y is one hundred random numbers according to the relationship y = 1.6x + 0.5
-y = 1.6*x + rng.random(100)
-
-# plot
-plt.scatter(x, y, color='gray')
-
-# regression
-res = stats.linregress(x,y)    # ordinary least sqaure
-
-plt.plot(x, x*res.slope+res.intercept, color='k')
-plt.xlabel('x')
-plt.ylabel('y')
-
-
-
-
-
Text(0, 0.5, 'y')
-
-
-../../../_images/W2D2_Tutorial5_17_1.png -
-
-

To get a sense of how our model fits the data, you can look at the regression results.

-
-
-
 # summarize model
-
-print('pearson (r^2) value: ' +'{:.2f}'.format(res.rvalue**2)+' \nwith a p-value of: '+'{:.2e}'.format(res.pvalue))
-
-
-
-
-
pearson (r^2) value: 0.66 
-with a p-value of: 1.40e-24
-
-
-
-
-

Now that we know how to write codes to analyze the linear relationship between two variables, we’re ready to move on to real world data!

-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial6.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial6.html deleted file mode 100644 index dd44f5017..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial6.html +++ /dev/null @@ -1,1918 +0,0 @@ - - - - - - - - Tutorial 6: Implementing the Analysis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 6: Implementing the Analysis

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorials Objectives

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-
-

Activity: Implement the Analysis

-

In this tutorial, you will be implementing a linear regression model as outlined in Step 5 on real-world CO2 and temperature records.

-

The CO2 and temperature records we will be analyzing are both examples of paleoclimate data (for more information, refer back to Step 3). The CO2 record (Bereiter et al., 2015) was generated by measuring the CO2 concentration in ancient air bubbles trapped inside ice from multiple ice cores retrieved from Antarctica. The temperature record (Shakun et al., 2015) is based on chemical analysis done on the shells of planktic foraminifera. The foraminifera shells were identified and picked from deep-sea sediments, and the temperature record combined multiple sea-surface temperature records from a range of sites globally.

-

Why are we focusing on these two records specifically? The CO2 record from Antarctic ice core is the gold standard of air CO2 variability on glacial-interglacial time scales, and it has a temporal resolution unmatched by any other reconstruction methods. The temperature record comes from sediment cores all over the global ocean, and therefore is likely representative of the global surface ocean temperature variability. Polar air temperature records are also available from ice core studies, but such records may represent an exaggerated view of the global temperature because of polar amplification.

-

If you would like to learn more, the data sources are listed at the bottom of the page.

-
-
-
# imports
-
-import matplotlib.pyplot as plt
-import pandas as pd
-import seaborn as sns
-import numpy as np
-from scipy import interpolate
-from scipy import stats
-import os
-import pooch
-
-
-
-
-
-
-
# time series
-# read SST data "Shakun2015_SST.txt"
-url_Shakun2015_SST = "https://osf.io/kmy5w/download"
-SST = pd.read_table(pooch.retrieve(url_Shakun2015_SST, known_hash=None))
-SST.set_index('Age', inplace=True)
-SST
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SST stack_18Op stack_18Ob stack_18Osw stack_18Osw uncertainty (2_)Deep ocean temperatureDetrended sea-level equivalentSea level uncertainty (2_)Unnamed: 9Unnamed: 10
Age
31.2-0.81-0.88-0.580.110.0014NaNNaN
61.3-0.76-0.87-0.500.110.1-1014NaNNaN
91.4-0.57-0.62-0.280.110.5-3814NaNNaN
121.0-0.16-0.230.060.090.1-8012NaNNaN
150.10.310.270.330.09-1.4-11512NaNNaN
.................................
7860.3-0.10-0.34-0.140.220.1-5028NaNNaN
789-0.10.03-0.210.090.290.0-7936NaNNaN
792-0.30.400.260.300.23-0.8-10630NaNNaN
795-1.60.370.440.070.31-3.2-7839NaNNaN
798-0.80.230.370.170.20-2.7-9026NaNNaN
-

266 rows × 10 columns

-
-
-
-
-
# read CO2 dataantarctica2015co2composite_cleaned.txt
-url_antarctica2015co2composite_cleaned = "https://osf.io/45fev/download"
-CO2 = pd.read_table(pooch.retrieve(url_antarctica2015co2composite_cleaned, known_hash=None))
-CO2.set_index('age_gas_calBP', inplace=True)
-CO2
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
co2_ppmco2_1s_ppm
age_gas_calBP
-51.03368.020.06
-48.00361.780.37
-46.28359.650.10
-44.41357.110.16
-43.08353.950.04
.........
803925.28202.922.06
804009.87207.500.92
804522.67204.861.64
805132.44202.230.69
805668.87207.292.20
-

1901 rows × 2 columns

-
-
-
-
-
# plot
-# set up two subplots in a grid of 2 rows and 1 column
-# also make sure the two plots share the same x(time) axis
-fig, axes = plt.subplots(2, 1, sharex=True)
-# move the two subplots closer to each other
-fig.subplots_adjust(hspace=-0.5)
-axes[0].plot(SST.index, SST['SST stack'], color='C4')
-axes[1].plot(CO2.index/1000, CO2['co2_ppm'], color='C1')
-
-# beautification
-# since sharex=True in plt.subplots(), this sets the x axis limit for both panels
-axes[1].set_xlim((0, 805))
-# axis labels
-axes[1].set_xlabel('Age (ka BP)')
-axes[0].set_ylabel(r'Sea Surface Temperature'
-                   '\n'
-                   'detrended (°C)',
-                   color='C4')
-axes[1].set_ylabel(r'CO${}_\mathrm{2}$ (ppm)',
-                   color='C1')
-# despine makes the plots look cleaner
-sns.despine(ax=axes[0], top=True, right=False, bottom=True, left=True)
-sns.despine(ax=axes[1], top=True, right=True, bottom=False, left=False)
-# clean up top panel x axis ticks
-axes[0].xaxis.set_ticks_position('none')
-# move top panel xlabel to the right side
-axes[0].yaxis.set_label_position('right')
-# the following code ensures the subplots don't overlap
-for ax in axes:
-    ax.set_zorder(10)
-    ax.set_facecolor('none')
-# color the axis
-axes[0].spines['right'].set_color('C4')
-axes[1].spines['left'].set_color('C1')
-axes[0].tick_params(axis='y', colors='C4')
-axes[1].tick_params(axis='y', colors='C1')
-
-
-
-
-
---------------------------------------------------------------------------
-ValueError                                Traceback (most recent call last)
-Cell In[4], line 7
-      5 # move the two subplots closer to each other
-      6 fig.subplots_adjust(hspace=-0.5)
-----> 7 axes[0].plot(SST.index, SST['SST stack'], color='C4')
-      8 axes[1].plot(CO2.index/1000, CO2['co2_ppm'], color='C1')
-     10 # beautification
-     11 # since sharex=True in plt.subplots(), this sets the x axis limit for both panels
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/matplotlib/axes/_axes.py:1632, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
-   1390 """
-   1391 Plot y versus x as lines and/or markers.
-   1392 
-   (...)
-   1629 (``'green'``) or hex strings (``'#008000'``).
-   1630 """
-   1631 kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
--> 1632 lines = [*self._get_lines(*args, data=data, **kwargs)]
-   1633 for line in lines:
-   1634     self.add_line(line)
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/matplotlib/axes/_base.py:312, in _process_plot_var_args.__call__(self, data, *args, **kwargs)
-    310     this += args[0],
-    311     args = args[1:]
---> 312 yield from self._plot_args(this, kwargs)
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/matplotlib/axes/_base.py:487, in _process_plot_var_args._plot_args(self, tup, kwargs, return_kwargs)
-    484         kw[prop_name] = val
-    486 if len(xy) == 2:
---> 487     x = _check_1d(xy[0])
-    488     y = _check_1d(xy[1])
-    489 else:
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/matplotlib/cbook/__init__.py:1327, in _check_1d(x)
-   1321 with warnings.catch_warnings(record=True) as w:
-   1322     warnings.filterwarnings(
-   1323         "always",
-   1324         category=Warning,
-   1325         message='Support for multi-dimensional indexing')
--> 1327     ndim = x[:, None].ndim
-   1328     # we have definitely hit a pandas index or series object
-   1329     # cast to a numpy array.
-   1330     if len(w) > 0:
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/pandas/core/indexes/base.py:5199, in Index.__getitem__(self, key)
-   5197 # Because we ruled out integer above, we always get an arraylike here
-   5198 if result.ndim > 1:
--> 5199     disallow_ndim_indexing(result)
-   5201 # NB: Using _constructor._simple_new would break if MultiIndex
-   5202 #  didn't override __getitem__
-   5203 return self._constructor._simple_new(result, name=self._name)
-
-File ~/code/climatematch/course-content/venv/lib/python3.8/site-packages/pandas/core/indexers/utils.py:343, in disallow_ndim_indexing(result)
-    335 """
-    336 Helper function to disallow multi-dimensional indexing on 1D Series/Index.
-    337 
-   (...)
-    340 in GH#30588.
-    341 """
-    342 if np.ndim(result) > 1:
---> 343     raise ValueError(
-    344         "Multi-dimensional indexing (e.g. `obj[:, None]`) is no longer "
-    345         "supported. Convert to a numpy array before indexing instead."
-    346     )
-
-ValueError: Multi-dimensional indexing (e.g. `obj[:, None]`) is no longer supported. Convert to a numpy array before indexing instead.
-
-
-../../../_images/W2D2_Tutorial6_7_1.png -
-
-

Now that we’ve taken a look at the two time series, let’s make a scatter plot between them and fit a linear regression model through the data.

-
-
-
# in this code block, we will make a scatter plot of CO2 and temperature
-# and fit a linear regression model through the data
-
-def age_model_interp(CO2_age, CO2, SST_age):
-    '''
-    This helper function linearly interpolates CO2 data, which
-    have a very high temporal resolution, to temperature data,
-    which have a relatively low resolution
-    '''
-    f = interpolate.interp1d(CO2_age, CO2)
-    all_ages = f(SST_age)
-    return all_ages
-
-# interpolate CO2 data to SST age
-CO2_interpolated = age_model_interp(CO2.index/1000, CO2['co2_ppm'], SST.index)
-
-# plot
-# set up two subplots in a grid of 2 rows and 1 column
-# also make sure the two plots share the same x(time) axis
-fig, ax = plt.subplots(1, 1, sharex=True)
-
-ax.scatter(CO2_interpolated, SST['SST stack'], color='gray')
-
-# regression
-X = CO2_interpolated
-y = SST['SST stack']
-res = stats.linregress(X,y)    # ordinary least sqaure
-
-x_fit = np.arange(180, 280)
-# intercept
-y_fit = x_fit * res.slope +res.intercept
-ax.plot(x_fit, y_fit, color='k')
-
-# beautification
-# axis labels
-ax.set_xlabel(r'CO${}_\mathrm{2}$ (ppm)')
-ax.set_ylabel(r'Sea Surface Temperature'
-                    '\n'
-                    'detrended (°C)')
-print('pearson (r^2) value: ' +'{:.2f}'.format(res.rvalue**2)+' \nwith a p-value of: '+'{:.2e}'.format(res.pvalue))
-
-
-
-
-
pearson (r^2) value: 0.55 
-with a p-value of: 3.37e-47
-
-
-../../../_images/W2D2_Tutorial6_9_1.png -
-
-
-

Figure Making Through the Equity Lense

-
-Click here for some information -Are the colors in your figure distinguishable for people with color-vision deficiencies? -

More readings on this topic:

-

Contrast checker: https://www.color-blindness.com/coblis-color-blindness-simulator/

-

Coloring for color blindness: https://davidmathlogic.com/colorblind

-

Python-specific color palettes that are friendly to those with color-vision deficiency: https://seaborn.pydata.org/tutorial/color_palettes.html

-
-
-
-

Resources

-

Data from the following sources are used in this tutorial:

-

CO2: Bereiter, B., Eggleston, S., Schmitt, J., Nehrbass-Ahles, C., Stocker, T.F., Fischer, H., Kipfstuhl, S., Chappellaz, J., 2015. Revision of the EPICA Dome C CO2 record from 800 to 600 kyr before present. Geophysical Research Letters 42, 542–549. https://doi.org/10.1002/2014GL061957

-

Temperature: Shakun, J.D., Lea, D.W., Lisiecki, L.E., Raymo, M.E., 2015. An 800-kyr record of global surface ocean δ18O and implications for ice volume-temperature coupling. Earth and Planetary Science Letters 426, 58–68. https://doi.org/10.1016/j.epsl.2015.05.042

-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial7.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial7.html deleted file mode 100644 index ef69a88f5..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial7.html +++ /dev/null @@ -1,1520 +0,0 @@ - - - - - - - - Tutorial 7: Interpreting the Results — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 7: Interpreting the Results

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorials Objectives

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-

Video 1: Interpreting the Results

-
-

Video 1: Interpreting the Results

-
-

Video 1: Interpreting the Results

-
-
Video 1: Interpreting the Results
-
-
Video 1: Interpreting the Results
-

####### Video 1: Interpreting the Results

-

######## Video 1: Interpreting the Results

-

######### Video 1: Interpreting the Results

-

########## Video 1: Interpreting the Results

-

########### Video 1: Interpreting the Results

-

############ Video 1: Interpreting the Results

-
-
-
# @title Video 1: Interpreting the Results
-#Tech team will add code to format and display the video
-
-
-
-
-

In Step 6, we created plots displaying the global CO2 levels and sea surface temperature data spanning the past 800 thousand years. Additionally, we attempted to fit both variables using a linear regression model. Nevertheless, it is crucial to bear in mind that correlation does not imply causation. The fact that global CO2 and sea surface temperature appear to co-vary does not automatically imply that one variable directly causes changes in the other. To establish causation, it is imperative to gather multiple lines of evidence. This underscores the importance of literature review in Step 2, as it aids in identifying corroborating evidence in climate research.

-
-
-
-
-
-
-
-

Quantifying the Uncertainty

-
-Click here for some information -Look up "linear regression model R squared" and how it measures the uncertainty of a linear regression model. What does it say about how confident you can be about a linear relationship between CO2 and temperature?
-
-

Activity: Interpreting the Results Through the Lens of Equity

-

For the next 10 minutes, discuss what the results capture well in terms of the relationship between CO2 and temperature. Who is represented by this data, specifically the compiled temperature record, and who is not? Who generated these data? Who has access to this information? Who is in a position to use it?

-
-
-

Further readings

-
-Click here for more readings on Interpreting the Results through the lens of equity -

Donovan, R. (2023), Climate journalism needs voices from the Global South, Eos, 104, https://doi.org/10.1029/2023EO230085

-

Tandon, A. (2021), Analysis: The lack of diversity in climate-science research, Carbon Brief, https://www.carbonbrief.org/analysis-the-lack-of-diversity-in-climate-science-research/

-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial8.html b/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial8.html deleted file mode 100644 index 450e286b9..000000000 --- a/book/_build/html/tutorials/W2D2_GoodResearchPractices/student/W2D2_Tutorial8.html +++ /dev/null @@ -1,1550 +0,0 @@ - - - - - - - - Tutorial 8: Communicating Your Conclusions — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - -
- -
- -
- - - - -
-
- - - - -
-
- - - - - - - - - -
-
- - - -
-
-
- - -
- -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 8: Communicating Your Conclusions

-

Good Research Practices

-

Content creators: Marguerite Brown, Yuxin Zhou

-

Content reviewers: Sherry Mi, Maria Gonzalez, Nahid Hasan, Beatriz Cosenza Muralles, Katrina Dobson, Sloane Garelick, Cheng Zhang

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS

-
-
-

Tutorials Objectives

-

In Tutorials 5-8, you will learn about the research process. This includes how to

-
    -
  1. Draft analyses of data to test a hypothesis

  2. -
  3. Implement analysis of data

  4. -
  5. Interpret results in the context of existing knowledge

  6. -
  7. Communicate your results and conclusions

  8. -
-

By the end of these tutorials you will be able to:

-
    -
  • Understand the principles of good research practices

  • -
  • Learn to view a scientific data set or question through the lens of equity: Who is represented by this data and who is not? Who has access to this information? Who is in a position to use it?

  • -
-
-

Video 1: Communicating Your Conclusions

-
-

Video 1: Communicating Your Conclusions

-
-

Video 1: Communicating Your Conclusions

-
-
Video 1: Communicating Your Conclusions
-
-
Video 1: Communicating Your Conclusions
-

####### Video 1: Communicating Your Conclusions

-

######## Video 1: Communicating Your Conclusions

-

######### Video 1: Communicating Your Conclusions

-

########## Video 1: Communicating Your Conclusions

-

########### Video 1: Communicating Your Conclusions

-

############ Video 1: Communicating Your Conclusions

-
-
-
# @title Video 1: Communicating Your Conclusions
-#Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-
-
-
-

Activity: Communicating Your Conclusions

-

For the next 20 minutes, break out into groups of 2 or 3 and pick one presentation format and discuss:

-
    -
  • Who is the target audience of this format?

  • -
  • What information is important to include?

  • -
-

After this, come back together as a whole pod and discuss everyone’s suggestions.

-
-

Equity in the Science Publishing

-
-Click here for some information about equity and publishing -

There are aspects of our current research culture that perpetuate inequity in the publishing process. Academic institutions and funding agencies often place importance on publishing in peer-reviewed journals. However, they have some drawbacks, including

-
    -
  • Accessibility

  • -
-
  • Papers in these journals are often kept behind a paywall, making them less accessible to people without the backing of either a university or a company.
  • -
  • More and more journals offer the option of publishing open access, but at expense to the submitting authors: fees can often exceed 1000 USD.
  • -
  • -If you want to ensure accessibility, consider also releasing your results in other formats as well. For instance, -
    • Blog posts
    • -
    • Podcasts
    • -
    • Social media posts
    • -
    • Conferences
    -
  • If you know that your research contains results that are relevant to specific populations, it is valuable to find ways to communicate your results to them.
-* Peer Review as Gatekeeping -
  • At its best, the peer review process enforces scientific rigor.
  • -
  • At its worst, it can become a tool for enforcing pre-existing norms, including the biases of its reviewers.
  • -
  • REMEMBER: Bad experiences with reviewers and rejections does not mean that your research is bad. There are papers which went on to win Nobel prizes that experienced resistance and rejection during the peer review process BECAUSE they were introducing important new ideas.
  • -
  • Further Reading:
  • -
    • Campanario, J. M. (2009). Rejecting and resisting Nobel class discoveries: Accounts by Nobel Laureates. Scientometrics, 81(2), 549–565.
    • -
    • Bancroft, S. F., Ryoo, K., & Miles, M. (2022). Promoting equity in the peer review process of journal publication. Science Education, 106, 1232– 1248. https://doi.org/10.1002/sce.21733
-
-
-

Tutorials 5-8 Summary

-

In this tutorial, we worked through how to analyze and present research.

-
    -
  • We learned how to draft an analysis (Step 5)

  • -
  • We implemented the analysis that we drafted (Step 6)

  • -
  • We learned how to interpret the results of the analysis (Step 7)

  • -
  • We learned about how to communicate the conclusions of our research (Step 8)

  • -
-
- - - - -
- -
- -
-
- - -
- - -
-
- - - - - - - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title.html b/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title.html deleted file mode 100644 index f9f23ff85..000000000 --- a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/chapter_title.html +++ /dev/null @@ -1,1061 +0,0 @@ - - - - - - - - - - - - Future Climate - IPCC II & III Socio-Economic Basis — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Future Climate - IPCC II & III Socio-Economic Basis

- -
-
- -
-
-
- - - - -
- -
-

Future Climate - IPCC II & III Socio-Economic Basis#

-
-art relevant to chapter contents -
-

Artwork by Sloane Garelick

-
-
-
- - - - -
- - - - - - -
- - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading.html b/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading.html deleted file mode 100644 index 8a02ccb97..000000000 --- a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/further_reading.html +++ /dev/null @@ -1,1195 +0,0 @@ - - - - - - - - - - - - Tutorial 2 Further Reading — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -
-

Tutorial 2 Further Reading#

-
-

IAM Model Summary#

-

The economy model in most IAMs is a capital accumulation model.

-
    -
  • Capital combines with a laboring population and technology to generate productivity (\(Y\)) that is hindered by climate damage.

  • -
  • A savings fraction of production drives capital accumulation, while the rest is consumed. Welfare is determined by consumption.

  • -
  • Climate action is formulated by a mitigation rate, \(\mu\), which along with the savings rate are the two control parameters in the model.

  • -
  • These are used to maximize welfare.

  • -
-

The climate model in DICE could be improved (c.f. this study). We only summarize here how it interacts with the economy model:

-
    -
  • Productivity generates industrial emissions, $\(E_\mathrm{ind}=(1-\mu)\sigma Y,\)\( where the \)1-\mu\( factor accounts for reduced carbon intensity of production, \)\sigma$, via supply-side mitigation measures (e.g. increased efficiency).

  • -
  • The productivity \(Y\) rather than output production (\(Q\)) see model is used here because damages aren’t included.

  • -
  • Namely, the emissions produced in the process of capital production occur before climate change has a chance to inflict damage on the produced output.

  • -
  • These emissions combine with natural emissions to drive the temperature changes appearing in the damage function, closing the economy-climate loop.

  • -
-

Here are a list of variables used:

-
    -
  • \(K\) capital

  • -
  • \(Y\) productivity

  • -
  • \(Q\) production

  • -
  • \(A\) technology conversion

  • -
  • \(S\) savings rate

  • -
  • \(\mu\) mitigation rate

  • -
  • \(\Lambda\) mitigation cost

  • -
  • \(\Omega\) damage fraction of productivity

  • -
  • \(\sigma\) carbon intensity of production

  • -
  • \(E\) emissions

  • -
-
-
-

Exogeneous Control Variables#

-

There are two exogeneous variables in the model:

-
    -
  • mitigation (emissions reduction) rate \(\mu_t\), and

  • -
  • the savings rate \(S_t\).

  • -
-

There exists a mitigation cost associated with a specific mitigation rate, presented as a fraction of productivity, \(\Lambda_t=\theta_1\mu^{\theta_2}\). This implies that increased mitigation efforts correspond to elevated costs.

-

The savings rate \(S_t\) extracts a portion of the total production to invest, thereby boosting capital. The rest of the production is then allocated for consumption.

-
-
-

Economy Model Summary#

-

The essence of the economy model in DICE is a capital accumulation model. Existing capital depreciates at rate \(\delta\) and new capital arises through investment, -$\(K_{t+1}=(1-\delta)K_t+I_t\)\( -where the invested capital \)I=SQ\( is determined by a chosen fraction \)S\( of the production \)Q\( that is "saved" rather than consumed. Production is given as the productivity \)Y\( reduced by damages and mitigation cost, \)\(Q=(1-\Omega)(1-\Lambda)Y.\)\( Productivity, \)\(Y=A K^\gamma L^{1-\gamma},\)\( -is determined by the technology conversion \)A\( operating on a combination of capital \)K\( and labor \)L\( whose relative contributions are set by the capital elasticity parameter \)\gamma$. Labor is population which set to saturate over the 2nd half of the 21st century. Technology conversion is only weakly sigmoidal in time, deviating slightly from linear growth.

-

The remaining production is consumed $\(C:=(1-S)Q\)\( producing utility \)\(U(C,L)=Lu(c)=Lu(C/L),\)\( using the isoelastic utility function, \)\(u(c)=\frac{(c+1)^{1-\alpha}-1}{1-\alpha}.\)\( The overall value of a projected future is then \)\(V=\sum_{t=1}^{\infty}\gamma^t U(C_t,L_t),\)\( where \)\gamma=1/(1+\rho)\( for discount rate \)\rho\( and we use the population level utility function \)U(C,L)=Lu(C/L)$.

-

Here are a list of variables used:

-
    -
  • \(K\) capital

  • -
  • \(Y\) productivity

  • -
  • \(Q\) production

  • -
  • \(A\) technology conversion

  • -
  • \(S\) savings rate

  • -
  • \(\mu\) mitigation rate

  • -
  • \(\Lambda\) mitigation cost

  • -
  • \(\Omega\) damage fraction of productivity

  • -
  • \(\sigma\) carbon intensity of production

  • -
  • \(E\) emissions

  • -
-
-
-

Optimal Planning#

-

The unconstrained problem aims to maximize \(V\) within the bounds of \(\mu_t\) and \(S_t\) time courses (while considering constraints on \(\mu\) and \(S\)). Why is there a “sweet spot”? Increasing savings boosts investment and productivity, but higher production leads to emissions, resulting in increased temperature and damages that reduce production. Mitigation costs counterbalance this effect, creating a trade-off. As a result, there typically exists a meaningful joint time series of \(\mu_t\) and \(S_t\) that maximizes \(V\). Due to the discount factor \(\gamma\), \(V\) depends on the future consumption sequence (non-invested production) within a few multiples of the horizon, approximately \(1/(1-\gamma)\) time steps into the future.

-

Constrained formulations introduce an additional constraint to limit industrial emissions below a certain threshold.

-
-
-

Social Cost of Carbon#

-

A definition for the social cost of carbon (SCC) is

- -

The \(SCC\) quantifies how much consumption is lost with increased emissions, using changes in welfare to make the connection. In technical terms:

-
    -
  • the marginal value with respect to emissions relative to the marginal value with respect to consumption, $\(SCC_t\propto\frac{\partial V/\partial E_t}{\partial V/\partial C_t}=\frac{\partial C_t}{\partial E_t}.\)\( -This is usually expressed by multiplying by a proportionality factor of \)-1000$ that converts the units to 2010 US dollars per tonne of CO2.

  • -
-
-
-
-

Tutorial 4 Further Reading#

-
-

Vectorization Methods for Creating Word Clouds#

-

Let’s write down what they compute by denoting the index, \(d\), over the \(D\) documents and the index, \(w\), over the \(W\) words in the vocabulary (the list of all the words found in all the tweets, which we’ll call documents):

-
    -
  • term frequency, \(\mathrm{tf}(w,d)\). The frequency of a word \(w\) in a document \(d\) is $\(\mathrm{tf}(w,d):=\frac{n(w,d)}{n(d)},\)\( where \)n(w,d)\( is the number of times term \)w\( is in document \)d\( and \)n(d)=\sum_{w=1}^W n(w,d)\( is the total number of words in document \)d\(. The term frequency over all the documents is then, \)\(\mathrm{tf}(w):=\frac{\sum_{d=1}^D n(d)\mathrm{tf}(w,d)}{N},\)\( where the denominator \)N=\sum_{d=1}^D n(d)$ is just the total word count across all documents.

  • -
  • term frequency-inverse document frequency, \(\mathrm{Tfidf}(w,d):=\mathrm{tf}(w,d)\mathrm{idf}(w)\). Here, $\(\mathrm{idf}(w)=\frac{\log(D+1)}{\log(n(w)+1)+1},\)\( where \)n(w)\( is the number of documents in which term \)t\( appears, i.e. \)n(w,d)>0\(. Idf is like an inverse document frequency. The `sklearn` package then uses \)\(\mathrm{Tfidf}(w)=\frac{1}{D}\sum_{d=1}^D \frac{\mathrm{Tfidf}(w,d)}{||\mathrm{Tfidf}(\cdot,d)||},\)\( where \)||\vec{x}||=\sqrt{\sum_{i=1}^Nx^2_i}$ is the Euclidean norm.

  • -
-

\(\mathrm{Tfidf}\) aims to add more discriminability to frequency as a word relevance metric by downweighting words that appear in many documents since these common words are less discriminative.

-
-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1.html b/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1.html deleted file mode 100644 index b16ff27b6..000000000 --- a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial1.html +++ /dev/null @@ -1,1805 +0,0 @@ - - - - - - - - - - - - Tutorial 1: — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 1:#

-

Week 2, Day 3: IPCC Socio-economic Basis

-

Content creators: Maximilian Puelma Touzel

-

Content reviewers: Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina DuplexLaura Paccini, Sloane Garelick, Abigail Bodner, Manisha Sinha, Agustina Pesce, Dionessa Biton, Cheng Zhang, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

During the first week of the course, you learned about types of climate data from measurements, proxies and models, and computational tools for assessing past, present and future climate variability recorded by this data. During day one of this week, you began to explore climate model data from Earth System Models (ESMs) simulations conducted for the recent Climate Model Intercomparison Project (CMIP6) that are presented in the report from the Intergovernmental Panel on Climate Changes (IPCC). However, the dominant source of uncertainty in those projections arise from how human society responds: e.g. how our emissions reduction and renewable energy technologies develop, how coherent our global politics are, how our consumption grows etc. For these reasons, in addition to understanding the physical basis of the climate variations projected by these models, it’s also important to assess the current and future socioeconomic impact of climate change and what aspects of human activity are driving emissions. This day’s tutorials focus on the socioeconomic projections regarding the future of climate change and are centered around the Shared Socioeconomic Pathways (SSP) framework used by the IPCC.

-

In this first tutorial, you will see how society can be represented by inter-related socio-economic variables and thier projections into the future. This tutorial will provide insights into the pressing socioeconomic issues related to climate change, such as resource scarcity, population dynamics, and the potential impacts of unchecked resource extraction. In particular, you will see some socioeconomic projections of the Integrated Assessment Modelling (IAM) used by the IPCC, and the influence of shared socio-economic pathways on these projections. In the bulk of the tutorial, you will use the World3 model, a tool developed in the 1970s to analyze potential economic and population scenarios. You will use it to learn about nonlinear, coupled dynamics of various aggregated world system variables and how this model informs modern day climate challenges.

-
-
-

Setup#

-
-
-
# imports
-from IPython.display import Math
-from IPython.display import display, HTML, Image
-import seaborn as sns
-import matplotlib.pyplot as plt
-import pandas as pd
-import numpy as np
-from ipywidgets import interact
-import ipywidgets as widgets
-import pooch
-import os
-import tempfile
-import urllib
-from pyworld3 import World3
-from pyworld3.utils import plot_world_variables
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 4
-      2 from IPython.display import Math
-      3 from IPython.display import display, HTML, Image
-----> 4 import seaborn as sns
-      5 import matplotlib.pyplot as plt
-      6 import pandas as pd
-
-ModuleNotFoundError: No module named 'seaborn'
-
-
-
-
-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-sns.set_style("ticks", {"axes.grid": False})
-%matplotlib inline
-display(HTML("<style>.container { width:100% !important; }</style>"))
-params = {"lines.linewidth": "3"}
-plt.rcParams.update(params)
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 plt.style.use(
-      5     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      6 )
-      8 sns.set_style("ticks", {"axes.grid": False})
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-

Helper functions#

-
-
- - -Hide code cell source - -
-
# @title Helper functions
-
-
-def get_IPCC_data(var_name, path):
-    IAMdf = pd.read_excel(path)
-    IAMdf.drop(
-        IAMdf.tail(2).index, inplace=True
-    )  # excel file has 2 trailing rows of notes
-    IAMdf.drop(
-        ["Model", "Region", "Variable", "Unit", "Notes"], axis=1, inplace=True
-    )  # remove columns we won't need
-
-    # The data is in wideform (years are columns).
-    # Longform (year of each datum as a column) is more convenient.
-    # To collapse it to longform we'll use the `pd.wide_to_long` method that requires the following reformatting
-    IAMdf.rename(
-        columns=dict(
-            zip(IAMdf.columns[1:], [var_name + str(y) for y in IAMdf.columns[1:]])
-        ),
-        inplace=True,
-    )  # add 'pop' to the year columns to tell the method which columns to map
-    IAMdf.index = IAMdf.index.set_names(["id"])  # name index
-    IAMdf = IAMdf.reset_index()  # make index a column
-    IAMdf = pd.wide_to_long(IAMdf, [var_name], i="id", j="year")
-
-    IAMdf = IAMdf.reset_index().drop("id", axis=1)  # do some post mapping renaming
-    IAMdf.year = IAMdf.year.apply(int)  # turn year data from string to int
-    if var_name == "pop":
-        IAMdf[var_name] = 1e6 * IAMdf[var_name]  # pop is in millions
-    elif var_name == "CO2":
-        IAMdf[var_name] = 1e6 * IAMdf[var_name]  # CO2 is in Mt CO2/yr
-    elif var_name == "forcing":
-        IAMdf = IAMdf  # forcing in W/m2
-    return IAMdf
-
-
-def run_and_plot(world3, nri_factor=1, new_lifetime_industrial_capital=14):
-    # nonrenewable resources initial [resource units]
-    world3.init_world3_constants(
-        nri=nri_factor * 1e12, alic1=14, alic2=new_lifetime_industrial_capital
-    )
-    world3.init_world3_variables()
-    world3.set_world3_table_functions()
-    world3.set_world3_delay_functions()
-    world3.run_world3(fast=False)
-
-    # select model variables to plot
-    variables = [
-        world3.nrfr,
-        world3.iopc,
-        world3.fpc,
-        world3.pop,
-        world3.ppolx,
-        world3.d,
-        world3.cdr,
-    ]
-    variable_labels = [
-        "Resource",  # nonrenewable resource fraction remaining (NRFR)
-        "Industry",  # industrial output per capita [dollars/person-year] (IOPC)
-        "Food",  # food production per capita [vegetable-equivalent kilograms/person-year] (FPC)
-        "Population",  # population [persons] (POP)
-        "Pollution",  # index of persistent pollution (PPOLX)
-        # (fraction of peristent pollution in 1970 = 1.36e8 pollution units)
-        "Deaths",
-        "Deathrate\n/1000",
-    ]
-    variable_limits = [
-        [0, 1],
-        [0, 1e3],
-        [0, 1e3],
-        [0, 16e9],
-        [0, 32],
-        [0, 5e8],
-        [0, 250],
-    ]  # y axis ranges
-
-    plot_world_variables(
-        world3.time,
-        variables,
-        variable_labels,
-        variable_limits,
-        img_background=None,  # ./img/fig7-7.png",
-        figsize=[4 + len(variables), 7],
-        title="initial non-renewable resources=" + str(nri_factor) + "*1e12",
-        grid=True,
-    )
-
-    # overlay an SSP projection
-    scenario_name = "SSP2-Baseline"
-    pop_path = pooch.retrieve("https://osf.io/download/ed9aq/", known_hash=None)
-    IAMpopdf = get_IPCC_data("pop", pop_path)
-    year_data = IAMpopdf.loc[IAMpopdf.Scenario == scenario_name, "year"]
-    var_data = IAMpopdf.loc[IAMpopdf.Scenario == scenario_name, "pop"]
-    axs = plt.gcf().axes
-    axs[variable_labels.index("Population")].plot(
-        year_data, var_data, "r--", label=scenario_name
-    )
-    axs[variable_labels.index("Population")].legend(frameon=False)
-
-
-
-
-
-
-
-

Video 1: Title#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Title
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
# helper functions
-
-
-def pooch_load(filelocation=None, filename=None, processor=None):
-    shared_location = "/home/jovyan/shared/Data/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis"  # this is different for each day
-    user_temp_cache = tempfile.gettempdir()
-
-    if os.path.exists(os.path.join(shared_location, filename)):
-        file = os.path.join(shared_location, filename)
-    else:
-        file = pooch.retrieve(
-            filelocation,
-            known_hash=None,
-            fname=os.path.join(user_temp_cache, filename),
-            processor=processor,
-        )
-
-    return file
-
-
-
-
-
-
-
-

Section 1: Exploring the IPCC’s Socioeconomic Scenarios#

-

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 to 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. In other words, IAMs are models that link human economic activity with climate change.

-

Let’s start by investigating some IAM model output, which will prepare you to explore World3 (which gives similar socioeconomic output) later in this tutorial.

-

All data from the main simulations of the IAMs used in the IPCC reports is freely available for viewing here. The simulations are labeled by both the Shared Socioeconomic Pathway (SSP1, SSP2, SSP3, SSP4, and SSP5) and the forcing level (greenhouse gas forcing of 2.6, 7.0, 8.5 W m2 etc. by 2100). The 5 SSPS are:

-
    -
  • SSP1: Sustainability (Taking the Green Road)

  • -
  • SSP2: Middle of the Road

  • -
  • SSP3: Regional Rivalry (A Rocky Road)

  • -
  • SSP4: Inequality (A Road divided)

  • -
  • SSP5: Fossil-fueled Development (Taking the Highway) -You will learn more about how these 5 SSPs were determined in future tutorials.

  • -
-

In previous days, you have looked at climate model data for projections of sea surface temperature change under different SSPs. We saw that applying different greenhouse gas forcings to a climate model affects global temperature projections and also influences other parts of the climate system, such as precipitation. In this section, we will take a look at the modelled socio-economic impacts associated with such changes to the physical climate system.

-

It is possible to download the IAM data if you provide an email address, but for this tutorial the following files have already been downloaded:

-
    -
  • Climate forcing

  • -
  • World population

  • -
  • Total CO2 emissions

  • -
-

Since the files all have the same name, iamc_db.xlsx, we have added ‘_forcing’, ‘_pop’, and ‘_CO2’ to differentiate the files and have stored them in our OSF repository.

-

Let’s load and plot this data to explore the forcing, population and CO2 emissions across the different SSP scenarios. You can utilize the pre-defined plotting function from above.

-
-
-
var_names = ["forcing", "pop", "CO2"]
-filenames = ["iamc_db_forcing.xlsx", "iamc_db_pop.xlsx", "iamc_db_CO2.xlsx"]
-paths = [
-    "https://osf.io/download/tkrf7/",
-    "https://osf.io/download/ed9aq/",
-    "https://osf.io/download/gcb79/",
-]
-files = [pooch_load(path, filename) for path, filename in zip(paths, filenames)]
-axis_size = 4
-fig, ax = plt.subplots(
-    1, len(var_names), figsize=(axis_size * len(var_names), axis_size)
-)
-for ax_idx, var_name in enumerate(var_names):
-    data_df = get_IPCC_data(var_name, files[ax_idx])
-    sns.lineplot(
-        ax=ax[ax_idx], data=data_df, x="year", y=var_name, hue="Scenario"
-    )  # plot the data
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 8
-      2 filenames = ["iamc_db_forcing.xlsx", "iamc_db_pop.xlsx", "iamc_db_CO2.xlsx"]
-      3 paths = [
-      4     "https://osf.io/download/tkrf7/",
-      5     "https://osf.io/download/ed9aq/",
-      6     "https://osf.io/download/gcb79/",
-      7 ]
-----> 8 files = [pooch_load(path, filename) for path, filename in zip(paths, filenames)]
-      9 axis_size = 4
-     10 fig, ax = plt.subplots(
-     11     1, len(var_names), figsize=(axis_size * len(var_names), axis_size)
-     12 )
-
-Cell In[6], line 8, in <listcomp>(.0)
-      2 filenames = ["iamc_db_forcing.xlsx", "iamc_db_pop.xlsx", "iamc_db_CO2.xlsx"]
-      3 paths = [
-      4     "https://osf.io/download/tkrf7/",
-      5     "https://osf.io/download/ed9aq/",
-      6     "https://osf.io/download/gcb79/",
-      7 ]
-----> 8 files = [pooch_load(path, filename) for path, filename in zip(paths, filenames)]
-      9 axis_size = 4
-     10 fig, ax = plt.subplots(
-     11     1, len(var_names), figsize=(axis_size * len(var_names), axis_size)
-     12 )
-
-Cell In[5], line 6, in pooch_load(filelocation, filename, processor)
-      4 def pooch_load(filelocation=None, filename=None, processor=None):
-      5     shared_location = "/home/jovyan/shared/Data/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis"  # this is different for each day
-----> 6     user_temp_cache = tempfile.gettempdir()
-      8     if os.path.exists(os.path.join(shared_location, filename)):
-      9         file = os.path.join(shared_location, filename)
-
-NameError: name 'tempfile' is not defined
-
-
-
-
-

The projections in the plots you just created show changes in climate forcing (left), population (middle) and CO2 emissions (right) across the five different SSP scenarios computed at thier baseline forcing level (different for each scenario), which are each represented by a distinct color in each plot.

-

The projections for each SSP are created by optimizing economic activity within the constraint of a given level of greenhouse gas forcing at 2100. This activity drives distinct temperature changes via the emissions it produces, which are inputted into a socioeconomic model component to compute economic damages. These damages feedback into the model to limit emissions-producing economic activity. The forcing constraint ensures the amount of emissions produced is consistent for that particular scenario. In other words, the projected temperature change under different scenarios is fed to a socioeconomic model component in order to assess the socioeconomic impacts resulting from the temperature change associated with each SSP.

-

Not every variable in IAMs is endogenous (i.e. determined by other variables in the model). Some variables, like population or technology growth, are exogeneous (i.e. variables whose time course is given to the model). In this case, the time course of population and economic growth, are derived from simple growth models.

-
-

Question 1#

-
    -
  1. Having watched the video on the limits of growth, why might the continued growth in both population and economy not be assured?

  2. -
-

Click for solution

-
-
-
-

Section 2: World Models and World3#

-

In this section you will take a step back from IAMs and use another model class, world models, to first explore how socioeconomic system variables like population, capital and pollution co-vary. You’ve already seen world models in the video for this tutorial, but let’s recap what they are and why they are interesting.

-

World models are computational models that incorporate natural physical limits in the economy. For example, world models can help to assess the impact of an economy based on growth-oriented extraction of a finite resource. All variables in world model are endogeneous. Recall that endogeneous variables determined by other variables in the model, rather than being given to the model. Therefore, world models are self-contained and simply run as a dynamical system: given an initial condition (a value for all variables) and the equations describing rates of change of the variables, they output the subsequent time series of these variables. The important variables in a world model are similar to those of Integrated Assessment Models: capital, production, population, pollution etc.

-

World3 is a world model that was developed in the 1970s and doesn’t have an explicit climate component (perhaps its developers were unaware of climate change at the time, as many were back then). However, World3 does have a pollution variable that is driven by industrial activity, and this pollution negatively impacts food production and directly increases mortality rates via health effects. If we were developing World3 today with our knowledge of human-driven climate change, we would add greenhouse gas emissions as a component of the pollution variable, which is the place in World3 representing the damaging waste of our industrial activity.

-

The reason we are looking at World3 here in this first tutorial, is that:

-
    -
  1. World3 is an instructive world model of the resource depletion and pollution problem. It is essential to understand the forcings, feedbacks and results associated with these problems because they directly contribute to climate change. More specifically, understanding these problems helps us understand the socioeconomic forces driving the emissions that are the source of the climate change problem.

  2. -
  3. World models provide an alternative modelling tradition not steeped in the neoclassical economics on which IAMs are based. This provides some diversity in perspective.

  4. -
-

Note: the model in World3 is not only wrong (i.e. missing many variables), but is a poor idealization. In other words, the World3 model is not necessarily qualitatively predictive because it is missing some determining variables/model features (e.g. technology innovation/adaptation). It is thus almost certainly not predictive, but is still useful for thinking about ‘world systems’ because it includes important relationships between some key natural and socio-economic variables that we will look at here. In later tutorials, we will learn about similr critiques of elements of IAMs (e.g. for lacking important variables).

-
-

Section 2.1: A Complete Map of World3#

-

Now that we have a basic understanding of World3, we can start to explore some more specific components and interactions of the model.

-

Welcome to World3! Here is a stock-flow diagram of the full model:

-
-
-
display(Image(url="https://osf.io/download/hzrsn/", width=1000, unconfined=True))
-# copyrighted image from the textbook:
-# Meadows, D.L.; Behrens, W.W.; Meadows, D.L.; Naill, R.F.; Randers, J.; Zahn, E.K.O. The Dynamics of Growth in a Finite World; Wright-Allen Press: Cambridge, MA, USA, 1974.
-# Source: https://www.mdpi.com/sustainability/sustainability-07-09864/article_deploy/html/images/sustainability-07-09864-g001.png
-# Alternate image from the precursor model: Jay Forrester's world dynamic model: https://petterholdotme.files.wordpress.com/2022/04/world-dynamics.png
-
-
-
-
-
-
-
-

Question 2.1#

-
    -
  1. Increase the width of this image to 3000.

  2. -
  3. Scroll around the larger image you just created to see what words you find in the node labels of the different parts of the model. Suggest a category label for each quadrant of the model.

  4. -
-
-
-
#################################################
-## TODO for students: details of what they should do ##
-# Fill out function and remove
-raise NotImplementedError("1. Increase the width of this image to 3000.")
-#################################################
-
-display(Image(url="https://osf.io/download/hzrsn/", width=..., unconfined=True))
-
-
-
-
-
---------------------------------------------------------------------------
-NotImplementedError                       Traceback (most recent call last)
-Cell In[8], line 4
-      1 #################################################
-      2 ## TODO for students: details of what they should do ##
-      3 # Fill out function and remove
-----> 4 raise NotImplementedError("1. Increase the width of this image to 3000.")
-      5 #################################################
-      7 display(Image(url="https://osf.io/download/hzrsn/", width=..., unconfined=True))
-
-NotImplementedError: 1. Increase the width of this image to 3000.
-
-
-
-
-

Click for solution

-

Click for solution

-
-
-
-

Section 2.2: A Sub-region of the Map of World3#

-

Here is a reduced diagram containing only some major variables in the model and their couplings:

-
-
-
display(Image(url="https://osf.io/download/h3mj2/", width=250))
-# modified from another copyrighted image from Limits To Growth (1972, page 97)
-
-
-
-
-
-
-

This image can be used to follow a pathway describing the flow of model variable dependencies to gain insight into how the model works (note this use of the word ‘pathway’ is distinct from that in ‘socioeconomic pathways’). When a pathway comes back to itself, this is a termed a feedback pathway (or feedback loop) by which changes can be amplified or attenuated by the way the model couples distinct variables. Recall from W1D1 that there are two types of feedbacks: positives feedbacks (change in variable A causes a change in variable B, which in turn causes a change in variable A in the same direction as the initial change) and negative feedbaks (change in variable A causes a change in variable B, which in turn causes a change in variable A in the opposite direction as the initial change).

-

Let’s look at some important feedback pathways in the model that appear in this image (also see pg. 95 of Limits of growth):

-
    -
  • The two positive feedback loops involving births and investment generate the exponential growth behavior of population and capital, respectively.

    -
      -
    • Investment drives industrial capital which drives industrial output which drives investment.

    • -
    • Population drives births drives population.

    • -
    -
  • -
  • The two negative feedback loops involving deaths and depreciation tend to regulate this exponential growth.

    -
      -
    • Industrial capital drives up depreciation which lowers industrial capital.

    • -
    • Population drives deaths which lowers population.

    • -
    -
  • -
-

There is a clear and intricate web of dependencies between these various factors. Changes in one area, such as industrial investment, can have cascading effects through this system, ultimately influencing population size, health, and wellbeing. This underscores the interconnected nature of socio-economic systems and the environment.

-
-

Questions 2.2#

-

Based on the model variable dependancy pathway described above and in the image, can you describe a:

-
    -
  1. Positive feedback loop?

  2. -
  3. Negative feedback loop?

  4. -
-

Click for solution

-
-
-

A note on exponential growth in a bounded system#

-

Consider a bounded system undergoing only positive feedback leading to exponential growth. The characteristic duration of growth until the system state reaches the system boundary is only weakly sensitive to the size of the boundary. For example, in the context of exponential resource-driven economic growth on Earth, reaching the boundary means exhausting its accessible physical resources. Ten times more or less of the starting amount of accessible resources only changes the time at which those resources are exhausted by a factor of 2 up or down, respectively.

-

Physics demands that behind the exponential extraction of resources is an exponential use of an energy resource. In recent times on Earth, this has been fossil fuels, which are non-renewable. Legitimate concerns of peak oil in the late 1990s were quelled by the Shale revolution in the United States and other technological advances in oil and gas exploration and exploitation. These have increased (by a factor between 2 and 4) the total amount of known reserves that can be profitably exploited. While this increase is significant on an linear scale, it is negligible on an exponential scale. Looking forward, the largest estimates for how much larger accessible oil and gas reserves will be are within an order of magnitude of current reserves. Presuming resource-driven growth economics continues, whatever accessible oil and gass is left will then be exhausted within a short period of time (e.g. within a century).

-

Exponential growth in a bounded system will often slow as it reaches the boundary because of boundary-sized feedback effects. In our case, demand growth for fossil fuels is starting to slow with the development of renewable energy sources. There still substantial uncertainty about how these feedbacks will play out. Some questions to consider:

-
    -
  • whether the transition to renewable energy sources can happen before we exhaust the associated non-renewable resources.

  • -
  • Once transitioned, whether the non-renewable resource use (e.g. of rare-earth metals) needed to sustain the renewable energy sector is sustainable in a growth-based economics

  • -
  • Once transitioned, whether this renewable energy resource might not slow, but instead accelerate the extraction of all non-renewable resources (see Jevon’s paradox).

  • -
-
-
-
-
-

Section 3: Working with pyworld3#

-

In this section you will use a python implementation of the World3 called pyworld3. This model is openly accessible here.

-

We have pre-defined a plotting function that also runs pyworld3, that you will use in this section. The plotting function has two inputs:

-
    -
  • nri_factor: the initial amount of non-renewable resources. For example, this could include coal, natural gas and oil.

  • -
  • new_lifetime_industrial_capital: a perturbed value of the lifetime of industrial capital to which the system will be perturbed at the perturbation year. For example, this variable could be used to represent a transition from fossil fuel-burning power plants to lower-emitting technologies.

  • -
-

In addition, you need to set the end year of the simulations you wish to conduct. In this example, you should stop the simulations at 2100, which is also when most IPCC Earth System Model projections end.

-
-
-
maxyear = 2100
-
-
-
-
-

In this section, you will use pyworld3 to assess changes associated with three different scenarios:

-
    -
  1. Business-As-Usual (BAU): assumes continued growth based on historical trends and specified amount of non-renewable resources

  2. -
  3. Abundant Resources (BAU3): same as BAU but with triple the amount of initial non-renewable resources

  4. -
  5. BAU3 with Active Cap on Production: same as BAU3 but a step decrease in the lifetime of industrial capital, by imposing a reduction from 14 to 8 years in 2025.

  6. -
-

For each scenario, you will plot and assess changes in multiple variables:

-
    -
  • Death rate: number of deaths per 1000 people

  • -
  • Deaths: number of deaths

  • -
  • Pollution: index of persistent pollution (fraction of peristent pollution in 1970 = 1.36e8 pollution units)

  • -
  • Population: population (people)

  • -
  • Food: food production per capita (vegetable-equivalent kilograms/person-year)

  • -
  • Industry: industrial output per capita (dollars/person-year)

  • -
  • Resource: nonrenewable resource fraction remaining (of 1e12 resource units). This includes all nonrenewable resources (e.g. ecosystems).

  • -
-
-

Section 3.1: Original (Business-As-Usual - BAU) Scenario#

-

The Business-As-Usual (BAU) scenario assumes continued growth based on historical trends. In this scenario there is specified amount of accessible, remaining non-renewable resources (normalized to 1 in the plots).

-
-
-
world3 = World3(year_max=maxyear)  # default value for nri_factor is 1
-run_and_plot(world3)
-# plt.savefig("world3_timeseries_case_1.png",transparent=True,bbox_inches="tight",dpi=300)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 world3 = World3(year_max=maxyear)  # default value for nri_factor is 1
-      2 run_and_plot(world3)
-      3 # plt.savefig("world3_timeseries_case_1.png",transparent=True,bbox_inches="tight",dpi=300)
-
-NameError: name 'World3' is not defined
-
-
-
-
-

Initially, industrial production (rising orange), food per capita (rising green) and population (rising red) experience growth. However, as non-renewable resources start rapidly decline (falling blue), industrial production begins to decline (falling orange). This decline subsequently causes a decrease in food production (falling green), which causes an increase in the death rate (rising pink) and a decline in population (falling red) during the latter half of the 21st century. This scenario is resource-constrained because the collapse in growth that occured in the middle of the 21st century was initially driven by a decline in available resources.

-

For comparison, the red dashed line represents the population projection for the IPCC baseline scenario of SSP2, a ‘Middle of the road’ scenario in which current trends continue (effecively the business-as-usual SSP scenario). Note the difference with the population projection of world3’s BAU scenario. While a priori unclear, the origin of this discrepancy likely arises from the different values that were chosen for the many parameters as well as which components and interactions were assumed when designing a world model or IAM. One obvious difference is the assumption of continued economic growth (decoupled from resource use) in SSP2. The large prediction uncertainty inherent in this modelling activity limits its predictive power. However, characteristic mechanisms (e.g. feedback pathways) are shared across these very different models and imply characteristic phenomena (e.g. population saturation).

-
-
-

Section 3.2: BAU3 - An Abundant Resource Scenario#

-

The previous scenario was resource-constrained, as the collapse in growth was driven by the limited available resources in the middle of the 21st century. In this section you will create a scenario that is not purely resource-constrained by initializing the pyworld3 with triple the initial non-renewable resources of the BAU scenario. As such, let’s call this new scenario BAU3.

-
-

Coding Exercise 3.2#

-

To create the BAU3 scenario you will need to triple the initial resources (nri_factor). Tripling the initial resources could represent the effect of increased efficiency in resource extraction via approaches such as changes in crop yields (as has been observed over recent decades), or the “learning-by-doing” effect that productivity is achieved through practice and innovations (as seen in the economics of many energy technologies).

-

Based on the input parameters of the run_and_plot() function discussed above, run the BAU3 scenario and plot the output.

-
-
-
run_and_plot(world3, nri_factor=3)
-# plt.savefig("world3_timeseries_case_2.png",transparent=True,bbox_inches="tight",dpi=300)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 1
-----> 1 run_and_plot(world3, nri_factor=3)
-      2 # plt.savefig("world3_timeseries_case_2.png",transparent=True,bbox_inches="tight",dpi=300)
-
-NameError: name 'world3' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -

Notice that the decline in industrial production (orange) still occurs in this scenario, but it is delayed by a few decades due to the larger initial resource pool (blue). However, unlike the previous case that was resource-constrained, the extended period of exponential industrial growth (orange) in this scenario leads to a significant increase in pollution (purple). As a result, the population crash (red), which is now driven by both increased pollution (purple) and diminishing resources (blue), is faster and more substantial than the BAU scenario’s population crash.

-

In this BAU3 scenario, the population growth and crash more closely resembles the population projection for the IPCC baseline scenario of SSP2 than the BAU scenario, but there is still a contrast between the two population projections.

-
-
-
-

Section 3.3: BAU3 with an Active Cap on Production#

-

In the BAU and BAU3 scenarios, we assessed the impact of changes in initial resource availability (nri_factor). However, another important variable to consider is the lifetime of industrial capital (new_lifetime_industrial_capital). Economic growth is likely to result in increaesd energy demand, but it’s essential to find a way to avoid high levels of climate warming while also meeting the growing world energy demands. To do so would require rapidly transforming current capital infrastructure in our energy system so that it relies on technologies that produce significantly less greenhouse gas emissions. For further details of IAM transitioning with reductions in lifetime capital see Rozenberg et al. Environ. Res. Lett. (2015).

-

In this section, you will assess the effects of reducing the lifetime of industrial capital. We will use the same BAU3 scenario with triple the initial resources, but will adjust the new_lifetime_industrial_capital variable to reflect a reduced lifetime of industrial capital. Specifically, this scenario turn down production abruptly via a step decrease in the lifetime of industrial capital, by imposing a reduction from 14 to 8 years in 2025.

-
-
-
world3 = World3(pyear=2025, year_max=2100)
-run_and_plot(world3, nri_factor=3, new_lifetime_industrial_capital=8)
-# plt.savefig("world3_timeseries_case_3.png",transparent=True,bbox_inches="tight",dpi=300)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 1
-----> 1 world3 = World3(pyear=2025, year_max=2100)
-      2 run_and_plot(world3, nri_factor=3, new_lifetime_industrial_capital=8)
-      3 # plt.savefig("world3_timeseries_case_3.png",transparent=True,bbox_inches="tight",dpi=300)
-
-NameError: name 'World3' is not defined
-
-
-
-
-

Notice that by reducing production (orange), pollution levels are also reduced (purple), which in turn limits the decline in population to a plateau (red). This approach preserves a significant amount of non-renewable resource (blue). However, over time, the asymptotic death rate (pink) gradually increases, approaching that of the BAU3 scenario without the reduced production. As a result, the population plateau is not sustained, and the population continues to decline slowly beyond the year 2100.

-

Additionally, dropping industrial output (as we did in this scenario) negatively impacts our ability to develop new technologies, e.g. those needed for decarbonization (c.f. the article Decarbonizing the downturn: Addressing climate change in an age of stagnation by Copley, 2022. This stagnation scenario is a central challenge faced in the narrative of Shared Socio-economic Pathway 3 (SSP3 Regional Rivary).

-
-

Questions 3.3:#

-
    -
  1. What scenarios might lead to a drop in the lifetime of industrial capital?

  2. -
  3. What are some important features of the world, society, and/or economy that are missing in this model?

  4. -
-

Click for solution

-
-
-
-

Section 3.4: Validity and Limitations of pyworld3#

-

Validity analyses for pyworld3 are presented in the pyworld3 github repository. For example, shown below is the pyworld3 standard run simulation output (shown in the same colors we’ve been using throughout this tutorial) compared to the original World3 model output (shown in black):

-
-
-

results|#

-

Overall, the pyworld3 simulation output replicates well the original World3 simulation.

-

Note that there are limitations to the world3 model that are important to remember:

-
    -
  • There is no spatial structure. Spatial structure is important, as it allows for distinct regional solutions that aid or hinder global cooperation

  • -
  • The model ignores technology innovation, including innovations in adaptation and mitigation

  • -
  • There is an ad hoc relationship between economic growth, investment in health services, and changes in life expectancy

  • -
  • The model only includes a monolithic non-renewable resource (e.g. doesn’t break down the resource into renewable and non-renewable classes)

  • -
-
-
-
-

Summary#

-

In this tutorial, you explored a socio-economic model based on resource extraction. This is the conceptual basis of the world models within IAMs used in IPCC projections.

-

You examined this interplay through World3, a World model which is a class of model similar to IAMs. You followed several variable dependency pathways within this model to identify some positive and negative feedback loops, and then you used this model to simulate 3 future scenarios which varied in their amount of initially available non-renewable resources and the lifetime of capital. Through these simulations you explored the factors driving current population growth, and its future projected decline or stabilization. In particular, you found rapid resource consumption can have negative impacts by exhausting these resources and/or by increasing pollution and reducing human health, thus highlighting the potential threats of unregulated resource extraction on a finite planet.

-

Finally, you learned about some of the limitations of models like World3, as they don’t include some important natural and socio-economic variables. By exploring these complex concepts, you are now better equipped to engage with discussions on climate change, resource management, and sustainable economic growth.

-
-
-

Resources#

-

The data for the IAMs used in this tutorial, as well as the main simulations of the IAMs used in the IPCC reports can be accessed hhere.

-

The pyworld3 model and data used in this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2.html b/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2.html deleted file mode 100644 index 9fc1a1dc6..000000000 --- a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial2.html +++ /dev/null @@ -1,1884 +0,0 @@ - - - - - - - - - - - - Tutorial 2: Transition Goals and Integrated Assessment Models — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - - - - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 2: Transition Goals and Integrated Assessment Models#

-

Week 2, Day 3: IPCC Socio-economic Basis

-

Content creators: Maximilian Puelma Touzel

-

Content reviewers: Peter Ohue, Derick Temfack, Zahra Khodakaramimaghsoud, Peizhen Yang, Younkap Nina DuplexLaura Paccini, Sloane Garelick, Abigail Bodner, Manisha Sinha, Agustina Pesce, Dionessa Biton, Cheng Zhang, Jenna Pearson, Chi Zhang, Ohad Zivan

-

Content editors: Jenna Pearson, Chi Zhang, Ohad Zivan

-

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

-

Our 2023 Sponsors: NASA TOPS and Google DeepMind

-
-
-

Tutorial Objectives#

-

In this tutorial, you will learn about the Dynamic Integrated Climate-Economy (DICE) model, a cornerstone in the history of climate economics. This is one the first 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.

-

You will explore the inner workings of the DICE model, starting with the foundational principles of economics: utility and welfare functions. You will also learn how these functions aggregate and weight the satisfaction derived from consumption across different societal groups. You will also learn how the these functions incorporate uncertain future utility into decision-making through discount rates. Valuing future states of the world allows the DICE model to place a value on its projections of future scenarios.

-

Later in the tutorial you will learn about damage functions, which combine climatological and economic knowledge to estimate how climate changes will affect economic productivity and the resultant well-being of society.

-

Finally, you will diagnose optimal planning within the DICE model, determining the best strategies for savings and emissions reduction rates (where best is with respect to a chosen utility and welfare function).

-

The overall objective of this tutorial is to provide a technical understanding of how parameters related to the distribution of value in society impact the optimal climate policy within a relatively simple IAM.

-
-
-

Setup#

-
-
-
# imports
-from IPython.display import display, HTML
-import seaborn as sns
-import matplotlib.pyplot as plt
-import pandas as pd
-import numpy as np
-import dicelib  # https://github.com/mptouzel/PyDICE
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[1], line 3
-      1 # imports
-      2 from IPython.display import display, HTML
-----> 3 import seaborn as sns
-      4 import matplotlib.pyplot as plt
-      5 import pandas as pd
-
-ModuleNotFoundError: No module named 'seaborn'
-
-
-
-
-
-

Figure settings#

-
-
- - -Hide code cell source - -
-
# @title Figure settings
-import ipywidgets as widgets  # interactive display
-
-plt.style.use(
-    "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-)
-
-%matplotlib inline
-sns.set_style("ticks", {"axes.grid": False})
-params = {"lines.linewidth": "3"}
-plt.rcParams.update(params)
-display(HTML("<style>.container { width:100% !important; }</style>"))
-
-
-
-
-
-
---------------------------------------------------------------------------
-ModuleNotFoundError                       Traceback (most recent call last)
-Cell In[2], line 2
-      1 # @title Figure settings
-----> 2 import ipywidgets as widgets  # interactive display
-      4 plt.style.use(
-      5     "https://raw.githubusercontent.com/ClimateMatchAcademy/course-content/main/cma.mplstyle"
-      6 )
-      8 get_ipython().run_line_magic('matplotlib', 'inline')
-
-ModuleNotFoundError: No module named 'ipywidgets'
-
-
-
-
-
-
-

Helper functions#

-
-
- - -Hide code cell source - -
-
# @title Helper functions
-
-
-def plot_future_returns(gamma, random_seed):
-    fig, ax = plt.subplots(1, 2, figsize=(8, 4))
-    np.random.seed(random_seed)
-    undiscounted_utility_time_series = np.random.rand(time_steps)
-    ax[0].plot(undiscounted_utility_time_series)
-
-    discounted_utility_time_series = undiscounted_utility_time_series * np.power(
-        gamma, np.arange(time_steps)
-    )
-    ax[0].plot(discounted_utility_time_series)
-
-    cumulsum_discounted_utility_time_series = np.cumsum(discounted_utility_time_series)
-    ax[1].plot(
-        cumulsum_discounted_utility_time_series * (1 - gamma),
-        color="C1",
-        label=r"discounted on $1/(1-\gamma)=$"
-        + "\n"
-        + r"$"
-        + str(round(1 / (1 - gamma)))
-        + "$-step horizon",
-    )
-    cumulsum_undiscounted_utility_time_series = np.cumsum(
-        undiscounted_utility_time_series
-    )
-    ax[1].plot(
-        cumulsum_undiscounted_utility_time_series
-        / cumulsum_undiscounted_utility_time_series[-1],
-        label="undiscounted",
-        color="C0",
-    )
-    ax[1].axvline(1 / (1 - gamma), ls="--", color="k")
-
-    ax[0].set_ylabel("utility at step t")
-    ax[0].set_xlim(0, time_steps)
-    ax[0].set_xlabel("time steps into the future")
-    ax[1].legend(frameon=False)
-    ax[1].set_ylabel("future return (normalized)")
-    ax[1].set_xlabel("time steps into the future")
-    ax[1].set_xlim(0, time_steps)
-    fig.tight_layout()
-
-
-
-
-
-
-
-

Video 1: Title#

-
-
- - -Hide code cell source - -
-
# @title Video 1: Title
-# Tech team will add code to format and display the video
-
-
-
-
-
-
-
-
-

Section 1: Background on IAM Economics and the DICE Model#

-

The Dynamic Integrated Climate-Economy (DICE) was the first prominent Integrated Assessment Model (IAM), a class of models economists use to inform policy decisions. Recall that IAMs couple a climate model to an economic model, allowing us to evaluate the two-way coupling between economic productivity and climate change severity. DICE is too idealized to be predictive, like world3, but DICE is still useful as a sandbox for exploring climate policy ideas, which is how we will use it here.

-

Let’s begin with a brief description of IAMs and the DICE model:

-
    -
  • DICE is a fully aggregated (i.e., non-spatial) model, but otherwise contains the essence of many key components of more complex IAMs.

  • -
  • Unlike world3, which we encountered in Tutorial 1, the world models used in IAMs usually have exogeneous (externally set) times series for variables, in addition to fixed world system parameters. These exogeneous variables are assumed to be under our society’s control (e.g. mitigation).

  • -
  • 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 time series of these exogeneous variables. In this sense, the objective function is what defines “good” in “good climate policy”.

  • -
  • The computation in an IAM is then an optimization of this objective as a function of the time series of these exogeneous variables over some fixed time window. In DICE, there are two exogeneous parameters:

    -
      -
    • \(\mu(t)\): time-dependent mitigation rate (i.e. emissions reduction), which limits warming-caused damages

    • -
    • \(S(t)\): savings rate, which drives capital investment

    • -
    -
  • -
  • The choices for the standard values of the parameters used in the DICE models have been critisized, and updated versions have been analyzed and proposed (Hansel et al. 2020;Barrage & Nordhaus 2023). Here, we look at the standard DICE2016 version of the model.

  • -
-

All DICE models (and 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. To understand this approach and how it is used in the DICE model, it is important to begin with a brief overview of some fundamental concepts. One such 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).

-
-

Section 1.1: Utility#

-

Utility, or economic value, is the total degree of satisfaction someone gets from using a product or service. In the context of socioeconomic climate impacts, utility of a state of the world for an individual is quantified by the consumption conferred (i.e. capital consumed; you can think of money as a placeholder for capital).

-

Reducing value to consumption may seem restrictive, and it is, but it’s how most economists see the world (not all! c.f. Hüttel, Balderjahn, & Hoffmann,Welfare Beyond Consumption: The Benefits of Having Less Ecological Economics (2020)). That said, economists don’t think utility is identical to consumption. Let’s work through the assumptions in a standard presentation of the economics that links the two.

-
-

Section 1.1.1: Utilities at Different Levels of Consumption#

-

It’s natural that the utility of consumption is relative to the level of consumption. A crude illustration here is that the value of a meal is higher to those who haven’t eaten recently than for those who have. Thus, we assume units of consumption at low values confer more utility than those at high values. In other words:

-
    -
  • A unit of consumption has less value to an individual, the more that individual tends to consume overall

  • -
-

The one parameter for the utility function is elasticity (\(\alpha\)), which is the measure of a variable’s sensitivity to change in another variable, in this case, how utility changes with consumption.

-

We can plot the utility function for different values of elasticity to assess how the sensitivity of utility to changes in comsumption varies with different elasticity values.

-
-
-
fig, ax = plt.subplots()
-c = np.linspace(0, 10, 1000)
-for alpha in [0, 0.1, 0.5, 1.0, 1.45]:
-    if alpha == 1:
-        ax.plot(c, np.log(1 + c), label=r"$\alpha=" + str(alpha) + "$")
-    elif alpha == 1.45:
-        ax.plot(
-            c,
-            ((c + 1) ** (1 - alpha) - 1) / (1 - alpha),
-            label=r"$\alpha=" + str(alpha) + "$(DICE)",
-        )
-    else:
-        ax.plot(
-            c,
-            ((c + 1) ** (1 - alpha) - 1) / (1 - alpha),
-            label=r"$\alpha=" + str(alpha) + "$",
-        )
-
-ax.plot([0, 10], [0, 10], "k--")
-ax.legend(frameon=False)
-ax.set_xlabel("consumption, c")
-ax.set_ylabel("utility, u(c)")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[5], line 1
-----> 1 fig, ax = plt.subplots()
-      2 c = np.linspace(0, 10, 1000)
-      3 for alpha in [0, 0.1, 0.5, 1.0, 1.45]:
-
-NameError: name 'plt' is not defined
-
-
-
-
-

The plot you just made shows the relationship between consumption and utility for four different values of elasticity. For all values of elasticity, as consumption increases, the utility also increases, as we discussed above. However, let’s make some observations about how changes in elasticity affect this relationship. For lower elasticity values (i.e. \(\alpha\) = 1 shown in blue) an increase in consumption results in a stronger increase in utility. In constrast, for high elasticity values (i.e. \(\alpha\) = 1.45 shown in red), such as what is used in the DICE model, an increase in consumption results in only a smaller increase in utility.

-
-

Questions 1.1.1#

-
    -
  1. What do you think the function looks like for \(\alpha=0\)?

  2. -
-

Click for solution

-
-
-
-

Section 1.1.2: Utilities Over a Population#

-

In the case that individuals are of the same type, i.e. a population of such individuals, we assume that

-
    -
  • Utilities of individuals of the same type sum

  • -
-
-
-

Section 1.1.3: Utilities Over Time#

-

Since our actions now affect those in the future (the socalled intertemporal choice problem), we can’t decide what is best to do at each time point by looking only at how it affects the world at that time. We need to incorporate utilities from the future into our value definition to know what is best to do now. How should we combine these?

-

Economists and decision theorists generally operate under the assumption that the value of a unit of utility decreases as it is received further into the future. This assumption is based on the recognition of the inherent uncertainty surrounding future events and the finite probability that they may not materialize. In other words:

-
    -
  • Utilities in the near future are valued more than those in the far future

  • -
-

This devaluation of the future is called temporal discounting. You can imagine that there is a lot of debate about how and even whether to do this in climate policy design!

-

The standard approach to incorporate temporal discounting into the model is to multiply the utilities of future benefits and costs by a discount factor (\(\gamma\) (‘gamma’), which is a number just less than 1, e.g. 0.95). The discount factor is raised to the power of time (in years) into the future to give the discount rate at that future time:

-
    -
  • after 1 year \((0.95)^1=0.95\)

  • -
  • after 2 years \((0.95)^2=0.90\)

  • -
  • after 10 years \((0.95)\)10\(=0.60\)

  • -
-

The return is the sum of future utilities, which is taken as the value of that future projection. If these utilies are discounted, their sum is called the discounted return. The following code will show an illustration of the effect of temporal discounting on future utilities and the return up to a given number of time steps into the future for a discount factor of \(\gamma\) = 0.95.

-
-
-
time_steps = 300
-gamma = 0.95
-random_seed = 1
-plot_future_returns(gamma, random_seed)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[6], line 4
-      2 gamma = 0.95
-      3 random_seed = 1
-----> 4 plot_future_returns(gamma, random_seed)
-
-Cell In[3], line 5, in plot_future_returns(gamma, random_seed)
-      4 def plot_future_returns(gamma, random_seed):
-----> 5     fig, ax = plt.subplots(1, 2, figsize=(8, 4))
-      6     np.random.seed(random_seed)
-      7     undiscounted_utility_time_series = np.random.rand(time_steps)
-
-NameError: name 'plt' is not defined
-
-
-
-
-

In both plots, the blue lines are undiscounted case (i.e. without the effect of temporal discounting) and the orange lines are the discounted case (i.e. including the effect of temporal discounting).

-

The figure on the left shows utility at each time step. In both the undiscounted scenario (blue) and the discounted scenario (orange), projected utilities are variable and uncertain. Notice that in the unsidcounted case, the average size of these utilities stays the same. In contrast, in the discounted case the typical size of utility rapidly decreases to zero, reflecting the effect of temporal discounting (i.e. the devaluation of utilities in the far future).

-

The figure on the right shows changes in return (i.e. the cumulative sum of future utilities) over time. The black dashed line shows the effective time horizon beyond which rewards are ignored in the discounted case for this chosen value of the discount factor, \(\gamma\) (this time is set by the natural convention of when the return gets to a fraction (\(1-1/e\approx0.64\)) of the final value). Beyond the time horizon, the future discounted return (orange) reaches saturation, and no additional utility from further time steps contributes to the overall value. In contrast, in the undiscounted case (blue), all future times are equally important, and the return grows linearly with the maximum time considered for computing utilities.

-
-
-
-
-

Section 2: Damage Functions#

-

Now that we have familiarized ourselves with some of the main components of IAMs and the DICE model, we can begin to explore another important component: the damage function. The damage function is a central model component that connects climate and socio-economic processes in integrated assessment models.

-

Damage functions are the objects in IAMs that dictate how changes in temperature affect production (e.g. through direct weather-related damages). They play a crucial role in determining the model’s projections.

-

The standard form is a deterministic continuous function that maps changes in temperature, \(\Delta T\), to the fraction of productivity that is destroyed by climate change every year, \(\Omega\). The standard parametrization is a quadratic dependence -$\(\Omega=a \times (\Delta T)^2\)\( -where \)a$ is some small constant (e.g. 0.001) whose value is set by regression of GDP and temperature over geographic and historical variation. Let’s plot this function.

-
-
-
fig, ax = plt.subplots()
-T = np.linspace(0, 4, 1000)
-a1DICE = 0.00236
-a2 = 2.00
-for a1 in [a1DICE, 1e-2, 1e-1]:
-    ax.plot(
-        T,
-        a1 * (T**a2),
-        label=r"$a_1=" + str(a1) + "$" + ("(DICE2023)" if a1 == a1DICE else ""),
-    )
-ax.legend(frameon=False)
-ax.set_xlabel("temperature change, $\Delta T$")
-ax.set_ylabel("fraction productivity destroyed")
-ax.set_ylim(0, 0.5)
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[7], line 1
-----> 1 fig, ax = plt.subplots()
-      2 T = np.linspace(0, 4, 1000)
-      3 a1DICE = 0.00236
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Observe how larger temperature changes lead to a larger fraction of productivity destroyed due to the damages caused by that temperature. The damage at a given temperature scales linearly with the parameter \(a_1\), and exponentially with the parameters \(a_2\).

-

There are at least two fundamental problems with damage functions (for more see The appallingly bad neoclassical economics of climate change by S. Keen in Globalizations (2020)):

-
    -
  1. As mathematical model objects, they are likely too simple to be useful predictors in characterizing climate damages in sufficient complexity.

  2. -
  3. They arise from a poorly validated model-fitting procedure. In particular, it relies on ad hoc functional forms and the relevance of historical and geographical variability to future variability.

  4. -
-
-

Questions 2#

-
    -
  1. Pick an assumption that is made about the relationship between temperature and economic damage in arriving at a conventional damage function (e.g. that it is: deterministic, continuous, constant in time, functional (instead of dynamical), …) and explain why you think that assumption might be unrealistic for a specific sector of the economy or a specific region of the planet.

  2. -
  3. Can you think of a specific way that temperature variation might cause variation in GDP that could have been significant in structuring the historical and/or geographical covariation of the two variables? How about a causal relationship that will not have been significant in historical or geographic variation up to now, but is likely to be significant as temperatures continue to rise and we experience more extreme climates?

  4. -
-

Click for solution

-

Despite these problems highlighting a pressing need to improve how we formulate climate damages, damage functions allow economists within the neoclassical paradigm to start seriously considering the damaging effects of climate change. After a few decades of economists using overly optimistic damage functions that downplayed the damaging effects of climate change, current research on damage functions is striving to incorporate more realism and better estimation.

-

For more contemporary damage functions see van der Wijst et al. Nat. Clim. Change (2023). Note that even this modern publication is hindered by the McNamara Fallacy of leaving out things that are hard to measure. The authors state: “The climate change impacts did not include potential losses originated in ecosystems or in the health sector. This is motivated by the difficulty in addressing the non-market dimension of those impacts with a ‘market-transaction-based’ model such as CGE. Also, catastrophic events were not considered, even though some ‘extremes’ (riverine floods) were included.”

-
-
-

Section 2.1: IAM Model Summary#

-

We’ve now explored both the utility function and damage function components of IAMs. Before we move on to actually running the DICE model, let’s summarize what we’ve learned so far about IAMs, specifically regarding the economy and climate models:

-

The economy model in most IAMs is a capital accumulation model.

-
    -
  • Capital (\(K\)) combines with a laboring population and technology to generate productivity (\(Y\)) that is hindered by climate damage.

  • -
  • A savings rate, \(S\), drives capital accumulation, while the rest is consumed. Welfare is determined by consumption.

  • -
  • Climate action is formulated by a mitigation rate, \(\mu\), which along with the savings rate, \(S\), are the two exogeneous control parameters in the model and are used to maximize welfare.

  • -
-

The climate model in DICE interacts with the economy model via the following equation: -$\(E_\mathrm{ind}=(1-\mu)\sigma Y,\)$

-
    -
  • Productivity (\(Y\)) generates industrial emissions (\(E_\mathrm{ind}\)), where the \(1-\mu\) factor accounts for a reduction of the carbon intensity of production, \(\sigma\), via supply-side mitigation measures (e.g. increased efficiency).

  • -
  • The productivity \(Y\) rather than output production (\(Q\)) is used here because damages aren’t included.

  • -
  • Damages aren’t included because the emissions produced in the process of capital production occur before climate change has a chance to inflict damage on the produced output.

  • -
  • These industrial emissions combine with natural emissions to drive the temperature changes appearing in the damage function, closing the economy-climate loop.

  • -
-
-
-

Section 2.2: Optimal Planning#

-

The goal of the model is to maximize the overall value of a projected future, \(V\), within the bounds of mitigation rate, \(\mu\), and savings rate, \(S\), time courses (while considering constraints on \(\mu\) and \(S\)). This approach is known as optimal planning. But why does this “sweet spot” in which overall value is maximized exist? Increasing savings boosts investment and productivity, but higher production leads to higher emissions, resulting in increased temperature and damages that reduce production. Mitigation costs counterbalance this effect, creating a trade-off. As a result, there typically exists a meaningful joint time series of \(\mu_t\) and \(S_t\) that maximizes \(V\). Due to the discount factor \(\gamma\), \(V\) depends on the future consumption sequence (non-invested production) within a few multiples of the time horizon, approximately \(1/(1-\gamma)\) time steps into the future.

-

We gone over many variables so far in this tutorial. Here is a list of variables used fore easier reference:

-
    -
  • \(K\) capital

  • -
  • \(Y\) productivity

  • -
  • \(S\) savings rate

  • -
  • \(\mu\) mitigation rate

  • -
  • \(E\) emissions

  • -
  • \(\sigma\) carbon intensity of production

  • -
  • \(Q\) production

  • -
  • \(\gamma\) discount factor

  • -
  • \(V\) value

  • -
-

If you’d like to explore the mathematical equations behind these models in more detail, please refer to the information in the “Further Reading” section for this day.

-
-
-
-

Section 3: DICE Simulations#

-

Now, let’s move to the DICE model that gives us some control over our emissions and consumption to see the effect of varying the parameters arising from the above design choices.

-

I’ve forked an existing Python implementation of the DICE2016 model and refactored it into a class (defined in dicelib.py) and made a few other changes to make it easier to vary parameters. We’ll use that forked version in this tutorial. -Note that the DICE model was recently updated (DICE2023).

-

The model equations are described in a document associated with the exising Python implementation.

-
-

Section 3.1: Case 1 Standard Run#

-

Let’s run the standard run of the DICE model:

-
-
-
dice_std = dicelib.DICE()  # create an instance of the model
-dice_std.init_parameters()
-dice_std.init_variables()
-controls_start_std, controls_bounds_std = dice_std.get_control_bounds_and_startvalue()
-dice_std.optimize_controls(controls_start_std, controls_bounds_std);
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[8], line 1
-----> 1 dice_std = dicelib.DICE()  # create an instance of the model
-      2 dice_std.init_parameters()
-      3 dice_std.init_variables()
-
-NameError: name 'dicelib' is not defined
-
-
-
-
-

Before assessing the results, let’s first check that the optimal control solution is within the bounds we set. To do so, let’s assess the mitigation rate and savings rate:

-
-
-
fig, ax = plt.subplots(1, 2)
-max_year = 2100
-TT = dice_std.TT
-NT = dice_std.NT
-upp, low = zip(*controls_bounds_std[:NT])
-ax[0].plot(TT, dice_std.optimal_controls[:NT], label="optimal")
-ax[0].plot(TT, upp, "k--", label="bounds")
-ax[0].plot(TT, low, "k--")
-ax[0].set_ylabel("mitigation rate")
-ax[0].set_xlim(2000, max_year)
-ax[0].legend(frameon=False)
-upp, low = zip(*controls_bounds_std[NT:])
-ax[1].plot(TT, dice_std.optimal_controls[NT:])
-ax[1].plot(TT, upp, "k--")
-ax[1].plot(TT, low, "k--")
-ax[1].set_ylabel("savings rate")
-ax[1].set_xlabel("year")
-ax[1].set_xlim(2000, max_year)
-
-fig.tight_layout()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[9], line 1
-----> 1 fig, ax = plt.subplots(1, 2)
-      2 max_year = 2100
-      3 TT = dice_std.TT
-
-NameError: name 'plt' is not defined
-
-
-
-
-
-

Coding Exercise 3.1#

-
    -
  1. Please change max_year to 2500 in the cell above to see what happens after 2100. What does the mitigation rate do?

  2. -
-
-
-
fig, ax = plt.subplots(1, 2)
-max_year = ...
-TT = dice_std.TT
-NT = dice_std.NT
-upp, low = zip(*controls_bounds_std[:NT])
-ax[0].plot(TT, dice_std.optimal_controls[:NT], label="optimal")
-ax[0].plot(TT, upp, "k--", label="bounds")
-ax[0].plot(TT, low, "k--")
-ax[0].set_ylabel("mitigation rate")
-# Set limits
-_ = ...
-ax[0].legend(frameon=False)
-upp, low = zip(*controls_bounds_std[NT:])
-ax[1].plot(TT, dice_std.optimal_controls[NT:])
-ax[1].plot(TT, upp, "k--")
-ax[1].plot(TT, low, "k--")
-ax[1].set_ylabel("savings rate")
-ax[1].set_xlabel("year")
-# Set limits
-_ = ...
-
-fig.tight_layout()
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[10], line 1
-----> 1 fig, ax = plt.subplots(1, 2)
-      2 max_year = ...
-      3 TT = dice_std.TT
-
-NameError: name 'plt' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -

Click for solution

-

The model incorporates the effects of negative emission technologies by allowing the mitigation rate (via the bounds) to exceed 1 around the year 2140. It is worth noting that the solution explicitly utilizes this feature and would do so even before 2100 if permitted. The decision to include this behavior was made by the modellers who realized that it enabled feasible solutions for the higher forcing SSP scenarios that were previously unattainable.

-

At the time, there was a lively debate surrounding this decision, although it was largely in favor of allowing mitigation rates greater than 1. As a result, such rates have become a standard feature in many models for high forcing regimes. However, it is important to acknowledge that there have been arguments against this practice, as discussed in Anderson & Peters, 2006.

-

In the final two tutorials, we will explore sociological aspects such as these.

-

Now, let’s examine the remaining variables of the DICE model:

-
-
-
dice_std.roll_out(dice_std.optimal_controls)
-dice_std.plot_run("standard run")
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[11], line 1
-----> 1 dice_std.roll_out(dice_std.optimal_controls)
-      2 dice_std.plot_run("standard run")
-
-NameError: name 'dice_std' is not defined
-
-
-
-
-

In this plot, the mitigation rate we looked at earlier is now referred to as the “Em rate” (orange line), which closely follows the patter of the carbon price (green line). Similarly, the rate of CO2 emissions (gray line) aligns with the industrial emissions (red line). Cumulative emissions (pink line) reach their peak around 2090, considering that negative emission technologies (NETs) are not employed until 2140.

-
-
-
-

Section 3.2: Case 2 Damage Functions#

-

The rate at which we increase our mitigation efforts in the standard scenario depends on the projected damage caused by climate change (brown line in the plot above), which is determined by the parameters of the damage function. The question is, how responsive is our response to these parameters?

-
-

Coding Exercise 3.2#

-

Change the strength of the nonlinearity in the damage function by changing the exponent from 2 to 3.

-
-
-
for a3 in [2, 3]:
-    dice = dicelib.DICE()
-    dice.init_parameters(a3=a3)
-    dice.init_variables()
-    controls_start, controls_bounds = dice.get_control_bounds_and_startvalue()
-    dice.optimize_controls(controls_start, controls_bounds)
-    dice.roll_out(dice.optimal_controls)
-    dice.plot_run("damage function exponent, a3=" + str(a3))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[12], line 2
-      1 for a3 in [2, 3]:
-----> 2     dice = dicelib.DICE()
-      3     dice.init_parameters(a3=a3)
-      4     dice.init_variables()
-
-NameError: name 'dicelib' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -Solution hint -
-
-

Questions 3.2#

-
    -
  1. What are the main differences between these two projections?

  2. -
-

Click for solution

-

IAMs model climate damages as affecting productivity only in the year in which they occur. What if the negative effects on productivity persist into the future? A persistence time can be added to damages such that damage incurred in one year can continue affecting productivity into following years (c.f. Schultes et al. Environ. Res. Lett. (2021); Hansel et al. Nat. Clim. Change (2020)). These effects are not negligible, but are absent from current IAMs used by the IPCC.

-
-
-
-

Section 3.3: Case 3 Discount Rate#

-

The value definition includes exponential temporal discounting (i.e. devaluation of utilities over time) at a rate of r = 1.5% per year so that utility obtained \(t\) years into the future is scaled down by \(1/(1+r)^t\). What if we set this rate lower so that we don’t down scale as quickly (i.e. utilities have more value for longer) and incorporate more in the value definition of what happens in the future when we make decisions?

-
-

Coding Exercise 3.3#

-

Change the discount rate from 1.5% to 0.5% (c.f. Arrow et al. Science (2013)).

-
-
-
for prstp in [0.015, 0.005]:
-    dice = dicelib.DICE()
-    dice.init_parameters(prstp=prstp)
-    dice.init_variables()
-    controls_start, controls_bounds = dice.get_control_bounds_and_startvalue()
-    dice.optimize_controls(controls_start, controls_bounds)
-    dice.roll_out(dice.optimal_controls)
-    dice.plot_run("discount rate, r=" + str(prstp))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[13], line 2
-      1 for prstp in [0.015, 0.005]:
-----> 2     dice = dicelib.DICE()
-      3     dice.init_parameters(prstp=prstp)
-      4     dice.init_variables()
-
-NameError: name 'dicelib' is not defined
-
-
-
-
-

Click for solution

-

Example output:

-Solution hint -Solution hint -
-
-

Questions 3.3#

-
    -
  1. How are the differences in these two sets of projections consistent with the change in the discount rate?

  2. -
-

Click for solution

-
-
-
-

Section 3.4: Case 4 the Utility Function#

-

These models use an elasticity of consumption when defining the utility function that serves as the basis for the value definition. Recall that elasticity describes the sensitivity of utility to changes in comsumption. Here, the elasticity parameter is the exponent called elasmu.

-

Let’s vary this elasticity exponent:

-
-
-
for elasmu in [1.45, 2.0]:
-    dice = dicelib.DICE()
-    dice.init_parameters(elasmu=elasmu)
-    dice.init_variables()
-    controls_start, controls_bounds = dice.get_control_bounds_and_startvalue()
-    dice.optimize_controls(controls_start, controls_bounds)
-    dice.roll_out(dice.optimal_controls)
-    dice.plot_run("elasticity exponent, elasmu=" + str(elasmu))
-
-
-
-
-
---------------------------------------------------------------------------
-NameError                                 Traceback (most recent call last)
-Cell In[14], line 2
-      1 for elasmu in [1.45, 2.0]:
-----> 2     dice = dicelib.DICE()
-      3     dice.init_parameters(elasmu=elasmu)
-      4     dice.init_variables()
-
-NameError: name 'dicelib' is not defined
-
-
-
-
-
-

Questions 3.4#

-
    -
  1. How are the differences in these two sets of projections consistent with the change in the elasticity?

  2. -
-

Click for solution

-
-
-
-
-

Summary#

-

In this tutorial, you’ve gained a foundational understanding of the DICE model, a basic Integrated Assessment Model in climate economics. You’ve learned how utility and welfare functions quantify societal satisfaction and balance the needs of different groups and near and far futures. You now understand the role of damage functions in relating climatic changes to economic impacts, giving you insight into the economic implications of climate change. Lastly, you’ve explored how the DICE model navigates the challenges of economic growth and climate mitigation through optimal planning. These insights equip you to participate more effectively in dialogues and decisions about our climate future.

-
-
-

Resources#

-

The Python implementation of DICE used in this tutorial can be accessed here.

-
- - - - -
- - - - - - -
- - - - - - -
- - - -
-
-
- - - - - -
-
- - \ No newline at end of file diff --git a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3.html b/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3.html deleted file mode 100644 index ad8ac9b9a..000000000 --- a/book/_build/html/tutorials/W2D3_FutureClimate-IPCCII&IIISocio-EconomicBasis/student/W2D3_Tutorial3.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - - - - - - - Tutorial 3: IAMs and SSPs — Climatematch Academy: Computational Tools for Climate Science - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-
- -
- - - - - - - - - - - - - -
- -
- - - -
- -
-
- -
-
- -
- -
- -
- - -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
-
- - - -
-

Tutorial 3: IAMs and SSPs

- -
-
- -
-
-
- - - - -
- -

Open In Colab   Open in Kaggle

-
-

Tutorial 3: IAMs and SSPs#

-