Glaciers as a low-pass filter of climate variations#

In a previous notebook we have talked about the response time of a glacier and how it takes some time for the glacier to respond to changes in its climate. In this notebook we are going to investigate this delayed response further by looking at how glaciers acts as a smoothing filter (low-pass) on variations in the climate forcing.

We will do this by introducing some, for you, new functionality of the OGGM-Edu classes which enables you to assign random, and custom, future temperature biases to the mass balance of your glacier.

First we have to import the minimal set of classes for working with OGGM-Edu glaciers.

from oggm_edu import GlacierBed, MassBalance, Glacier

Then we create a bed. For these examples we can use a fairly simply bed with a single slope. However, feel free to change this as you like.

# Lets create a relatively simple bed.
bed = GlacierBed(widths=[600, 400, 400], 
                 altitudes=[4200, 3400, 2000],
                 slopes=15)
bed.plot()
../_images/f0b889ab08c46e50eff874c567cd1365bf3b6f403a3943b255c291a0ede34d1c.png

Next step is the mass balance. We create a slightly more realistic mass balance profile with a few different gradients.

# A mass balance with the ela at 3600 m. and 4 gradients.
mass_balance = MassBalance(ela=3600, 
                           gradient=[3, 6, 10, 15],
                           breakpoints=[3800, 3200, 2500])

Now we are ready to create the glacier.

glacier = Glacier(bed=bed, mass_balance=mass_balance)

Let’s take a look at the mass balance profile.

glacier.plot_mass_balance()
../_images/a2ad49d8899c6f81f78717a9d2ab9e798d5c66f5bac50a83d95e07cad4dff02f.png

Adding a random climate#

Before we start progressing the glacier assign a random climate to the future of the glacier. Random in this case means that the temperature bias of our glacier will vary randomly from year to year between values specified by us. Internally this has the effect that the ELA of our glacier changes up and down.

We assign a random climate through.add_random_climate(duration, temperature_range), a method of the Glacier object. duration specifies how long the random climate should last, while temperature_range lets the user specify between what temperatures the climate should vary.

# Lets add a random climate for a 1000 years, varying between -2 and 2 degrees.
glacier.add_random_climate(duration=1000, temperature_range=[-2., 2.])

We can take a look at the random climate through the temperature_bias_series attribute of the MassBalance.

# This is a pandas dataframe.
glacier.mass_balance.temp_bias_series
year bias
0 0.0 0.000000
1 1.0 -1.184740
2 2.0 -0.385436
3 3.0 0.136106
4 4.0 -0.735251
... ... ...
996 996.0 -0.949218
997 997.0 -1.841776
998 998.0 1.187378
999 999.0 1.375924
1000 1000.0 -0.917359

1001 rows × 2 columns

And also quickly plot it. This will be pretty messy.

glacier.mass_balance.temp_bias_series.bias.plot();
../_images/5b3141e0d84ab4f98ea26197458d9dd3297fdc39642bf8d7c8f6715aea2df1df.png
Note that if this is series is pre-populated, like in this case, it will act as the climate for the glacier during the progression. When empty, the current, constant, bias will be written to the corresponding year during the progression, creating a history of the temperature bias.

Now we can progress the glacier as usual.

# Progress the glacier to year 1000.
glacier.progress_to_year(1000)
glacier.plot()
../_images/ebcefb7c5d921e0588574f3c5c909417b027a6d863d91c0127c1327ecb3b2334.png

A look at the history#

We plot the history of the glacier length, volume and area with the .plot_history() method. We can also plot the temperature bias history by passing True to the show_bias argument.

glacier.plot_history(show_bias=True)
../_images/6d726d96925d33f97a2b9317c6807e3f3a633be674f0a92f95480c53faf5d748.png

Since the random climate is just random, it is difficult to distinguish any similarities between the noisy bias and the glacier history. However, we can smooth the bias by providing a window size to the window argument. This will perform a rolling mean on the temperature bias series before plotting it.

Here we also specify a time frame to plot in order to get a closer look at the data. By doing this we shrink the range of the y-axis, enhancing the fluctuations in the glacier history.

Try executing the cell below with different window sizes and try to find the size which represent the smoothing that the glacier have on the climate. [Click for a hint] With a window size around 30-40 years, the bias begins to exhibit patterns similar to the glacier history.
# Smooth the bias so that it resembles the history of the glacier attributes.
glacier.plot_history(show_bias=True, window=10,
                     time_range=[100, 1000])
../_images/2fe91eddf80ae591cece40b5f6298b6b50c99caa81bc41f2f4fe6d4caad6ba81.png

Creating a custom climate#

Warning: The following section requires more experience with Python than most of the previous work you've done with OGGM-Edu.

It is possible to create a completely custom climate for the glacier. This is done by creating an array of bias values and assigning it to the .temp_bias_series attribute.

The easiest way to do this is by using one, or a combination, of the numpy-methods generating arrays.

import numpy as np

For this exercise we will create a sinusoidal bias, not because it is very realistic but to show one example of how one can use convenient functions to generate the values. You can essentially use any function returning an array of floats, or do it manually, to create the bias series of your imagination.

# How many cycles and years do we want?
n_cycles = 4
# 1000 years, we add 1 since last number is not included.
n_years = 1000
# Radians.
rads = np.linspace(0, n_cycles * 2 * np.pi, n_years)
# Create the sinus waves.
bias_data = np.sin(rads)

We reset the glacier before adding the new climate, to start fresh.

glacier.reset()

Then we can assign the bias_data to the .temp_bias_series.

glacier.mass_balance.temp_bias_series = bias_data

Progress the glacier as usual.

glacier.progress_to_year(1000)

Take a look at the history of the glacier

glacier.plot_history(show_bias=True)
../_images/8662e8ef4684268ca3603beedd1faea363f94bc5a096ee668c002abf30f34282.png

It is also possible to add a future climate to a glacier that already has some history.

To start over, we first reset the glacier, then we add a linear trend and progress to the end of the climate data.

glacier.reset()
glacier.add_temperature_bias(bias=1.5, duration=200)
glacier.progress_to_year(200)
glacier.plot_history(show_bias=True)
../_images/f2a432c116cc872dcf60fad3ab04198e0024b165f10213ad404906e1d92072dc.png

We can then assign more data to the future climate, just as easy as before. we now want a sinus-wave that oscillates around the current temperature bias.

# How many cycles and years do we want?
n_cycles = 4
# 1000 years, we add 1 since last number is not included.
n_years = 1000
# Radians.
rads = np.linspace(0, n_cycles * 2 * np.pi, n_years)
# Create the sinus wave and add the current temperature bias.
bias_data = np.sin(rads) + glacier.mass_balance.temp_bias

Assign it to the .temp_bias_series. Internally this will append it to the series that already exists.

glacier.mass_balance.temp_bias_series = bias_data
# We progress to year 1154, the current age + 1000.
glacier.progress_to_year(1200)
glacier.plot_history(show_bias=True)
../_images/c0d580af5378caea5510b26ee4d8efe97dadf7f3e86914cadebc49373dd556fe.png

Adding noise to clean data#

Until now, we have either created a completely random climate or very clean and predictable trends. The next step is, of course, to combine the methods to create trends that also have some random variability to them.

We will demonstrate this by manually creating a linear trend and then adding some noise to it.

glacier.reset()
# Create a linear trend, from 0 to 2 degrees in 200 years
trend = np.linspace(0, 2, 200)
# And some noise. Interannual variability of +- 2 degrees 
noise = (np.random.rand(200) * 4) - 2
# Add the noise to the trend
bias = trend + noise

We first add only some noise to get a noisy “spin up” of the glacier.

noise = (np.random.rand(500) * 4) - 2
glacier.mass_balance.temp_bias_series = noise

Then lets add the trend, remember that this will append to the future of the climate.

glacier.mass_balance.temp_bias_series = bias

Progress to the end of the climate data.

glacier.progress_to_year(700)
Again, try running the cell below with different values for the window size.
glacier.plot_history(show_bias=True)
../_images/2ac52228f8d6e39b07f8b2d6e1a187110e320b216e24a854bd5dea2daa1e4fd1.png

Conveniently, the .add_temperature_bias has an argument which adds noise to the trend.

glacier.reset()
glacier.add_temperature_bias(bias=2., duration=500, noise=(-2, 2))
glacier.progress_to_year(500)
glacier.plot_history(show_bias=True)
../_images/41dcdf11ed30e8b422168bb6ed0769a5905b92df9c9d3b8c8972e7ded4cc5e3c.png

Now you should have the tools to create your own climates for OGGM-Edu glaciers and see how they filter the climate.

What’s next?#

Back to the table of contents