{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"[](https://colab.research.google.com/github/ClimateMatchAcademy/course-content/blob/main/tutorials/W1D4_Paleoclimate/student/W1D4_Tutorial4.ipynb)
"
]
},
{
"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"
]
},
{
"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": {},
"outputs": [],
"source": [
"# installations ( uncomment and run this cell ONLY when using google colab or kaggle )\n",
"\n",
"# !pip install pyleoclim\n",
"# !pip install cartopy"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"execution": {}
},
"outputs": [],
"source": [
"# imports\n",
"import pandas as pd\n",
"import pooch\n",
"import os\n",
"import tempfile\n",
"import pyleoclim as pyleo"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# @title Helper functions\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": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {},
"tags": []
},
"outputs": [],
"source": [
"# @title Video 1: Atmospheric Climate Proxies\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', 'y5zom-8iKv4'), ('Bilibili', 'BV1Uh4y1Z7dg')]\n",
"tab_contents = display_videos(video_ids, W=730, H=410)\n",
"tabs = widgets.Tab()\n",
"tabs.children = tab_contents\n",
"for i in range(len(tab_contents)):\n",
" tabs.set_title(i, video_ids[i][0])\n",
"display(tabs)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"execution": {},
"pycharm": {
"name": "#%%\n"
},
"tags": [
"remove-input"
]
},
"outputs": [],
"source": [
"# @markdown\n",
"from ipywidgets import widgets\n",
"from IPython.display import IFrame\n",
"\n",
"link_id = \"szyhp\"\n",
"\n",
"download_link = f\"https://osf.io/download/{link_id}/\"\n",
"render_link = f\"https://mfr.ca-1.osf.io/render?url=https://osf.io/{link_id}/?direct%26mode=render%26action=download%26mode=render\"\n",
"# @markdown\n",
"out = widgets.Output()\n",
"with out:\n",
" print(f\"If you want to download the slides: {download_link}\")\n",
" display(IFrame(src=f\"{render_link}\", width=730, height=410))\n",
"display(out)\n"
]
},
{
"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",
"\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?"
]
},
{
"cell_type": "markdown",
"metadata": {
"execution": {}
},
"source": [
"# Section 2: Exploring the relationship between δD and atmospheric CO2"
]
},
{
"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": {
"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.8"
}
},
"nbformat": 4,
"nbformat_minor": 4
}