Using your own glacier inventory with OGGM#
The Randolph Glacier Inventory is a key dataset to model glaciers at any scale: it includes outlines of the extent of each glacier in the world, an information that is critical in figuring out how much a particular glacier might contribute to rising sea level. These glacier outlines are the starting point of any simulation in OGGM. The RGI’s latest version (v6), as well as v5, are provided and supported by OGGM (see the documentation). However, there are several issues in the RGI that might make you want to use your own corrected glacier outlines.
This notebook describes how to feed OGGM with them. We will show you three case studies about how to give any geometry to OGGM and avoid errors of incompatibility between your shapefile and the model framework.
We have three case studies which should cover a number of applications:
Dividing a glacier into smaller entities (common case, useful for poorly outlined glaciers, which are in reality separate dynamical entities)
Merging two glaciers together (useful for tidewater glaciers in particular, not much elsewhere)
TLDR;#
If you want to use custom data to feed OGGM with, you should:
make a shapefile that resembles the RGI one: same attributes, and the glacier geometries should be in lon/lat projection. The most important attribute is
geometry, of course, but others are used by OGGM as well: refer to the OGGM documentation to decide which ones. The RGI documentation (found in the RGI directory after download) is useful as well! We also have a useful function (oggm.utils.cook_rgidf) which can help you with that.compute and use a new glacier interesects file, or make sure you don’t need one and disable this option in OGGM.
Structure of an RGI file#
import numpy as np
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import oggm
import os
from oggm import cfg, utils, workflow, tasks, graphics
from oggm.core import inversion
cfg.initialize(logging_level='WARNING')
2026-03-09 23:44:25: oggm.cfg: Reading default parameters from the OGGM `params.cfg` configuration file.
2026-03-09 23:44:25: oggm.cfg: Multiprocessing switched OFF according to the parameter file.
2026-03-09 23:44:25: oggm.cfg: Multiprocessing: using all available processors (N=4)
Let’s read a file from the standard RGI:
utils.get_rgi_dir(version='62')
'/github/home/OGGM/rgi/RGIV62'
sh = utils.get_rgi_region_file('11', version='62')
sh
'/github/home/OGGM/rgi/RGIV62/11_rgi62_CentralEurope/11_rgi62_CentralEurope.shp'
Shapefiles are best read and manipulated with geopandas in python (see also our working_with_rgi tutorial):
gdf = gpd.read_file(sh)
gdf.head()
| RGIId | GLIMSId | BgnDate | EndDate | CenLon | CenLat | O1Region | O2Region | Area | Zmin | ... | Lmax | Status | Connect | Form | TermType | Surging | Linkages | Name | check_geom | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | RGI60-11.00001 | G013599E47495N | 20030799 | 20030999 | 13.5987 | 47.4949 | 11 | 1 | 0.122 | 2191 | ... | 461 | 0 | 0 | 0 | 0 | 9 | 9 | NaN | NaN | POLYGON ((13.60035 47.4933, 13.59995 47.49332,... |
| 1 | RGI60-11.00002 | G013614E47485N | 20030799 | 20030999 | 13.6135 | 47.4845 | 11 | 1 | 2.292 | 2203 | ... | 1853 | 0 | 0 | 0 | 0 | 9 | 9 | NaN | NaN | POLYGON ((13.60638 47.47578, 13.60599 47.47579... |
| 2 | RGI60-11.00003 | G013596E47484N | 20030799 | 20030999 | 13.5960 | 47.4835 | 11 | 1 | 0.851 | 2280 | ... | 1140 | 0 | 0 | 0 | 0 | 9 | 9 | NaN | NaN | POLYGON ((13.59765 47.47613, 13.59726 47.47614... |
| 3 | RGI60-11.00004 | G013583E47481N | 20030799 | 20030999 | 13.5829 | 47.4807 | 11 | 1 | 0.053 | 2319 | ... | 382 | 0 | 0 | 0 | 0 | 9 | 9 | NaN | NaN | POLYGON ((13.58283 47.47969, 13.58243 47.47971... |
| 4 | RGI60-11.00005 | G013603E47477N | 20030799 | 20030999 | 13.6026 | 47.4774 | 11 | 1 | 0.057 | 2656 | ... | 202 | 0 | 0 | 0 | 0 | 9 | 9 | NaN | NaN | POLYGON ((13.60076 47.47519, 13.60036 47.47521... |
5 rows × 24 columns
An RGI file contains the actual glacier geometries, but also a number of attribute which are used by OGGM afterwards. Let’s learn how to make our own file now.
Case 1: dividing a glacier into smaller entities#
A typical example of wrongly divided glacier is Hintereisferner, in Austria:
# OGGM set-up
cfg.PATHS['working_dir'] = utils.gettempdir(dirname='rgi-case-1', reset=True)
cfg.PARAMS['border'] = 10
# Get the HEF geometry and plot it
gl = utils.get_rgi_glacier_entities(['RGI60-11.00897'])
gl.plot(edgecolor='k');
2026-03-09 23:44:26: oggm.cfg: PARAMS['border'] changed from `80` to `10`.
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[5], line 6
3 cfg.PARAMS['border'] = 10
5 # Get the HEF geometry and plot it
----> 6 gl = utils.get_rgi_glacier_entities(['RGI60-11.00897'])
7 gl.plot(edgecolor='k');
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1925, in get_rgi_glacier_entities(rgi_ids, version)
1923 selection = []
1924 for reg in sorted(np.unique(regions)):
-> 1925 sh = gpd.read_file(get_rgi_region_file(reg, version=version))
1926 try:
1927 selection.append(sh.loc[sh.RGIId.isin(rgi_ids)])
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1882, in get_rgi_region_file(region, version, reset)
1862 def get_rgi_region_file(region, version=None, reset=False):
1863 """Path to the RGI region file.
1864
1865 If the RGI files are not present, download them.
(...) 1879 path to the RGI shapefile
1880 """
-> 1882 rgi_dir = get_rgi_dir(version=version, reset=reset)
1883 if version in ['70G', '70C']:
1884 f = list(glob.glob(rgi_dir + f"/*/*-{region}_*.shp"))
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1791, in get_rgi_dir(version, reset)
1772 """Path to the RGI directory.
1773
1774 If the RGI files are not present, download them.
(...) 1787 path to the RGI directory
1788 """
1790 with get_lock():
-> 1791 return _get_rgi_dir_unlocked(version=version, reset=reset)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1839, in _get_rgi_dir_unlocked(version, reset)
1837 ofile = file_downloader(dfile, reset=reset)
1838 if ofile is None:
-> 1839 raise RuntimeError(f'Could not download RGI file: {dfile}')
1840 # Extract root
1841 try:
RuntimeError: Could not download RGI file: http://www.glims.org/RGI/rgi60_files/00_rgi60.zip
Obviously, the two smaller tongues used to flow in the main one but this is not the case anymore today. We need updated geometries.
Make a new “RGI file”#
There is no simple way to automate the process of finding these bad geometries, but we are working on this (don’t hold your breath, this has been in development since a long time). Here we use a geometry that we prepared in QGis:
# We simulate the case where we only have the geometry, nothing else
divides = gpd.read_file(utils.get_demo_file('divides_alps.shp'))
divides = divides.loc[divides.RGIId == 'RGI50-11.00897'][['geometry']]
divides
| geometry | |
|---|---|
| 1 | POLYGON ((10.74505 46.80376, 10.7461 46.80293,... |
| 93 | POLYGON ((10.7486 46.80493, 10.74717 46.80529,... |
| 94 | POLYGON ((10.74602 46.80561, 10.74717 46.80529... |
divides.plot(edgecolor='k');
Now we use the RGI entity as template - it’s good to use the same attributes as the original RGI glacier, because most of them are already correct:
template = pd.concat([gl]*3, ignore_index=True)
template
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[8], line 1
----> 1 template = pd.concat([gl]*3, ignore_index=True)
2 template
NameError: name 'gl' is not defined
We change the important ones:
# Attributes
template['RGIId'] = ['RGI60-11.00897_d01', 'RGI60-11.00897_d02', 'RGI60-11.00897_d03']
template['Name'] = ['Hintereisferner d01', 'Hintereisferner d02', 'Hintereisferner d03']
# Geometries
template['geometry'] = divides['geometry'].values
# Center point
for i, geom in template[['geometry']].iterrows():
cenlon, cenlat = geom.geometry.centroid.xy
template.loc[i, 'CenLon'] = np.array(cenlon)
template.loc[i, 'CenLat'] = np.array(cenlat)
# This is important to properly georeference the file
import salem
template.crs = salem.wgs84.srs
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[9], line 2
1 # Attributes
----> 2 template['RGIId'] = ['RGI60-11.00897_d01', 'RGI60-11.00897_d02', 'RGI60-11.00897_d03']
3 template['Name'] = ['Hintereisferner d01', 'Hintereisferner d02', 'Hintereisferner d03']
4 # Geometries
NameError: name 'template' is not defined
template.plot(edgecolor='k');
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[10], line 1
----> 1 template.plot(edgecolor='k');
NameError: name 'template' is not defined
Save it:
hef_new_shape_path = os.path.join(cfg.PATHS['working_dir'], 'hef_divided.shp')
template.to_file(hef_new_shape_path)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[11], line 2
1 hef_new_shape_path = os.path.join(cfg.PATHS['working_dir'], 'hef_divided.shp')
----> 2 template.to_file(hef_new_shape_path)
NameError: name 'template' is not defined
Compute the intersects#
We would have to install rgitools first (e.g. pip install git+https://github.com/OGGM/rgitools.git)
and also networkx (pip install networkx) for this to work.
Hintereisferner has a divide with another glacier as well! Let’s find out which:
intersects_alps = gpd.read_file(utils.get_rgi_intersects_region_file('11'))
intersects_hef = intersects_alps.loc[(intersects_alps.RGIId_1 == 'RGI60-11.00897') | (intersects_alps.RGIId_2 == 'RGI60-11.00897')]
intersects_hef
| RGIId_1 | RGIId_2 | geometry | |
|---|---|---|---|
| 119 | RGI60-11.00846 | RGI60-11.00897 | LINESTRING (10.74826 46.81077, 10.7484 46.8107... |
| 143 | RGI60-11.00897 | RGI60-11.00846 | LINESTRING (10.72557 46.79781, 10.72557 46.797... |
Ok, we can now create a file which has all the glaciers we need to compute the relevant intersects (note that we could also use the full standard RGI with just HEF replaced):
orig = utils.get_rgi_glacier_entities(['RGI60-11.00846'])
template.crs = orig.crs
for_intersects = pd.concat([template, orig], ignore_index=True)
for_intersects.plot(edgecolor='k');
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[13], line 1
----> 1 orig = utils.get_rgi_glacier_entities(['RGI60-11.00846'])
2 template.crs = orig.crs
3 for_intersects = pd.concat([template, orig], ignore_index=True)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1925, in get_rgi_glacier_entities(rgi_ids, version)
1923 selection = []
1924 for reg in sorted(np.unique(regions)):
-> 1925 sh = gpd.read_file(get_rgi_region_file(reg, version=version))
1926 try:
1927 selection.append(sh.loc[sh.RGIId.isin(rgi_ids)])
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1882, in get_rgi_region_file(region, version, reset)
1862 def get_rgi_region_file(region, version=None, reset=False):
1863 """Path to the RGI region file.
1864
1865 If the RGI files are not present, download them.
(...) 1879 path to the RGI shapefile
1880 """
-> 1882 rgi_dir = get_rgi_dir(version=version, reset=reset)
1883 if version in ['70G', '70C']:
1884 f = list(glob.glob(rgi_dir + f"/*/*-{region}_*.shp"))
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1791, in get_rgi_dir(version, reset)
1772 """Path to the RGI directory.
1773
1774 If the RGI files are not present, download them.
(...) 1787 path to the RGI directory
1788 """
1790 with get_lock():
-> 1791 return _get_rgi_dir_unlocked(version=version, reset=reset)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1839, in _get_rgi_dir_unlocked(version, reset)
1837 ofile = file_downloader(dfile, reset=reset)
1838 if ofile is None:
-> 1839 raise RuntimeError(f'Could not download RGI file: {dfile}')
1840 # Extract root
1841 try:
RuntimeError: Could not download RGI file: http://www.glims.org/RGI/rgi60_files/00_rgi60.zip
Good! Let’s use rgitools to compute the intersects for this new situation:
# from rgitools.funcs import compute_intersects
# new_intersects = compute_intersects(for_intersects)
# f, ax = plt.subplots()
# for_intersects.plot(ax=ax, edgecolor='k');
# new_intersects.plot(ax=ax, edgecolor='r');
Good! We can store our intersects to use them with OGGM afterwards:
# hef_intersects_path = os.path.join(cfg.PATHS['working_dir'], 'hef_divided_intersects.shp')
# new_intersects.to_file(hef_intersects_path)
Finally: the OGGM run#
# This is important! We tell OGGM to recompute the glacier area for us
cfg.PARAMS['use_rgi_area'] = False
# Intersects dont work for now
cfg.PARAMS['use_intersects'] = False
# This is important for centerlines - if you have them
# cfg.set_intersects_db(hef_intersects_path)
# This is to avoid a download in the tutorial, you don't need to do this at home
cfg.PATHS['dem_file'] = utils.get_demo_file('hef_srtm.tif')
# This is important again - standard OGGM
rgidf = gpd.read_file(hef_new_shape_path)
gdirs = workflow.init_glacier_directories(rgidf, reset=True, force=True)
2026-03-09 23:44:47: oggm.cfg: PARAMS['use_rgi_area'] changed from `True` to `False`.
2026-03-09 23:44:47: oggm.cfg: PARAMS['use_intersects'] changed from `True` to `False`.
---------------------------------------------------------------------------
DataSourceError Traceback (most recent call last)
Cell In[17], line 13
10 cfg.PATHS['dem_file'] = utils.get_demo_file('hef_srtm.tif')
12 # This is important again - standard OGGM
---> 13 rgidf = gpd.read_file(hef_new_shape_path)
14 gdirs = workflow.init_glacier_directories(rgidf, reset=True, force=True)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/geopandas/io/file.py:316, in _read_file(filename, bbox, mask, columns, rows, engine, **kwargs)
313 filename = response.read()
315 if engine == "pyogrio":
--> 316 return _read_file_pyogrio(
317 filename, bbox=bbox, mask=mask, columns=columns, rows=rows, **kwargs
318 )
320 elif engine == "fiona":
321 if pd.api.types.is_file_like(filename):
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/geopandas/io/file.py:576, in _read_file_pyogrio(path_or_bytes, bbox, mask, rows, **kwargs)
567 warnings.warn(
568 "The 'include_fields' and 'ignore_fields' keywords are deprecated, and "
569 "will be removed in a future release. You can use the 'columns' keyword "
(...) 572 stacklevel=3,
573 )
574 kwargs["columns"] = kwargs.pop("include_fields")
--> 576 return pyogrio.read_dataframe(path_or_bytes, bbox=bbox, **kwargs)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/pyogrio/geopandas.py:382, in read_dataframe(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, fid_as_index, use_arrow, on_invalid, arrow_to_pandas_kwargs, datetime_as_string, mixed_offsets_as_utc, **kwargs)
374 gdal_force_2d = False if use_arrow else force_2d
376 # Always read datetimes as string values to preserve (mixed) time zone info
377 # correctly. If arrow is not used, it is needed because numpy does not
378 # directly support time zones + performance is also a lot better. If arrow
379 # is used, needed because datetime columns don't support mixed time zone
380 # offsets + e.g. for .fgb files time zone info isn't handled correctly even
381 # for unique time zone offsets if datetimes are not read as string.
--> 382 result = read_func(
383 path_or_buffer,
384 layer=layer,
385 encoding=encoding,
386 columns=columns,
387 read_geometry=read_geometry,
388 force_2d=gdal_force_2d,
389 skip_features=skip_features,
390 max_features=max_features,
391 where=where,
392 bbox=bbox,
393 mask=mask,
394 fids=fids,
395 sql=sql,
396 sql_dialect=sql_dialect,
397 return_fids=fid_as_index,
398 datetime_as_string=True,
399 **kwargs,
400 )
402 if use_arrow:
403 import pyarrow as pa
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/pyogrio/raw.py:200, in read(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, return_fids, datetime_as_string, **kwargs)
59 """Read OGR data source into numpy arrays.
60
61 IMPORTANT: non-linear geometry types (e.g., MultiSurface) are converted
(...) 196
197 """
198 dataset_kwargs = _preprocess_options_key_value(kwargs) if kwargs else {}
--> 200 return ogr_read(
201 get_vsi_path_or_buffer(path_or_buffer),
202 layer=layer,
203 encoding=encoding,
204 columns=columns,
205 read_geometry=read_geometry,
206 force_2d=force_2d,
207 skip_features=skip_features,
208 max_features=max_features or 0,
209 where=where,
210 bbox=bbox,
211 mask=_mask_to_wkb(mask),
212 fids=fids,
213 sql=sql,
214 sql_dialect=sql_dialect,
215 return_fids=return_fids,
216 dataset_kwargs=dataset_kwargs,
217 datetime_as_string=datetime_as_string,
218 )
File pyogrio/_io.pyx:1412, in pyogrio._io.ogr_read()
File pyogrio/_io.pyx:262, in pyogrio._io.ogr_open()
DataSourceError: /tmp/OGGM/rgi-case-1/hef_divided.shp: No such file or directory
workflow.execute_entity_task(tasks.define_glacier_region, gdirs)
workflow.execute_entity_task(tasks.glacier_masks, gdirs)
workflow.execute_entity_task(tasks.compute_centerlines, gdirs)
workflow.execute_entity_task(tasks.initialize_flowlines, gdirs)
workflow.execute_entity_task(tasks.catchment_area, gdirs)
workflow.execute_entity_task(tasks.catchment_width_geom, gdirs)
workflow.execute_entity_task(tasks.catchment_width_correction, gdirs);
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[18], line 1
----> 1 workflow.execute_entity_task(tasks.define_glacier_region, gdirs)
2 workflow.execute_entity_task(tasks.glacier_masks, gdirs)
3 workflow.execute_entity_task(tasks.compute_centerlines, gdirs)
NameError: name 'gdirs' is not defined
graphics.plot_catchment_width(gdirs, add_intersects=True, corrected=True)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[19], line 1
----> 1 graphics.plot_catchment_width(gdirs, add_intersects=True, corrected=True)
NameError: name 'gdirs' is not defined
It works!
The intersects in OGGM are used for two main things:
when a grid-point glacier section touches an intersect, it will be attributed a rectangular bed (instead of a parabolic one)
when interpolating the ice thickness to a 2D grid, the boundary condition thickness=0 at the glacier outline is removed where there are intersects
We recommend to use intersects for your runs as well, IF YOU ARE USING CENTERLINES. For elevation bands, intersects are ignored.
Case 2: merging glaciers#
Sometimes, you may want to merge glaciers together. This case is less frequent than Case 1, but might be useful for calving glaciers, which are sometimes divided in the RGI.
Original RGI outlines#
We use a case study for two marine-terminating glaciers in Alaska that have to be merged into a single outline in order to model a correct calving flux for these glaciers (following the methods described in Recinos et al., (2019)). The resulting shapefile is a new one that needs to be adapted in order for OGGM to run.
We will study the Sawyer Glacier (RGI60-01.03890) that is actually connected via the calving front with this other entity (RGI60-01.23664). Visit this link to learn more about the retreat of the Sawyer Glacier and see images illustrating this connection.
gl = utils.get_rgi_glacier_entities(['RGI60-01.03890', 'RGI60-01.23664'])
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[20], line 1
----> 1 gl = utils.get_rgi_glacier_entities(['RGI60-01.03890', 'RGI60-01.23664'])
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1925, in get_rgi_glacier_entities(rgi_ids, version)
1923 selection = []
1924 for reg in sorted(np.unique(regions)):
-> 1925 sh = gpd.read_file(get_rgi_region_file(reg, version=version))
1926 try:
1927 selection.append(sh.loc[sh.RGIId.isin(rgi_ids)])
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1882, in get_rgi_region_file(region, version, reset)
1862 def get_rgi_region_file(region, version=None, reset=False):
1863 """Path to the RGI region file.
1864
1865 If the RGI files are not present, download them.
(...) 1879 path to the RGI shapefile
1880 """
-> 1882 rgi_dir = get_rgi_dir(version=version, reset=reset)
1883 if version in ['70G', '70C']:
1884 f = list(glob.glob(rgi_dir + f"/*/*-{region}_*.shp"))
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1791, in get_rgi_dir(version, reset)
1772 """Path to the RGI directory.
1773
1774 If the RGI files are not present, download them.
(...) 1787 path to the RGI directory
1788 """
1790 with get_lock():
-> 1791 return _get_rgi_dir_unlocked(version=version, reset=reset)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_downloads.py:1839, in _get_rgi_dir_unlocked(version, reset)
1837 ofile = file_downloader(dfile, reset=reset)
1838 if ofile is None:
-> 1839 raise RuntimeError(f'Could not download RGI file: {dfile}')
1840 # Extract root
1841 try:
RuntimeError: Could not download RGI file: http://www.glims.org/RGI/rgi60_files/00_rgi60.zip
Here OGGM downloaded the outlines for both glaciers. If we plot them together, we can see that both glaciers drain into the same fjord. See the google map below:
cfg.initialize(logging_level='WARNING')
cfg.PATHS['working_dir'] = utils.gettempdir(dirname='rgi-case-2-example', reset=True)
cfg.PARAMS['border'] = 80 # previously 10, but this preprocessed gdir is not anymore available
base_url = 'https://cluster.klima.uni-bremen.de/~oggm/gdirs/oggm_v1.6/L3-L5_files/2025.6/elev_bands/W5E5/per_glacier/'
gdirs = workflow.init_glacier_directories(['RGI60-01.03890', 'RGI60-01.23664'], from_prepro_level=3, prepro_base_url=base_url, reset=True, force=True)
graphics.plot_googlemap(gdirs, figsize=(6, 6));
2026-03-09 23:45:00: oggm.cfg: Reading default parameters from the OGGM `params.cfg` configuration file.
2026-03-09 23:45:00: oggm.cfg: Multiprocessing switched OFF according to the parameter file.
2026-03-09 23:45:00: oggm.cfg: Multiprocessing: using all available processors (N=4)
2026-03-09 23:45:00: oggm.workflow: init_glacier_directories from prepro level 3 on 2 glaciers.
2026-03-09 23:45:00: oggm.workflow: Execute entity tasks [gdir_from_prepro] on 2 glaciers
The upper glacier map is a zoom version of the plot below. They share the same glacier’s terminus. Therefore, to estimate a calving flux for these glaciers we need them connected.
Let’s merge these two outlines using geopandas#
merged = gl.dissolve(by='O2Region', as_index=False)
merged = merged[gl.columns]
merged.plot(edgecolor='k');
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[22], line 1
----> 1 merged = gl.dissolve(by='O2Region', as_index=False)
2 merged = merged[gl.columns]
3 merged.plot(edgecolor='k');
NameError: name 'gl' is not defined
RGI attributes#
We now have a new shapefile, which resembles an RGI one but has wrong attributes. Some aren’t relevant, but some are. See the documentation for a list.
The important ones are: RGIId, CenLon, CenLat, TermType, Area. Area and CenLon, Cenlat can be calculated by OGGM later, as we have seen earlier. Here, we prefer to keep the Area computed by the RGI for consistency.
# We use the RGI as template (this avoids strange IO issues)
template = gl.iloc[[0]].copy()
template['geometry'] = merged['geometry'].values
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[23], line 2
1 # We use the RGI as template (this avoids strange IO issues)
----> 2 template = gl.iloc[[0]].copy()
3 template['geometry'] = merged['geometry'].values
NameError: name 'gl' is not defined
# Change CenLon, CenLat
cenlon, cenlat = merged.iloc[0].geometry.representative_point().xy
template['CenLon'] = cenlon
template['CenLat'] = cenlat
# We sum up the areas
template['Area'] = gl.Area.sum()
template['Area']
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[24], line 2
1 # Change CenLon, CenLat
----> 2 cenlon, cenlat = merged.iloc[0].geometry.representative_point().xy
3 template['CenLon'] = cenlon
4 template['CenLat'] = cenlat
NameError: name 'merged' is not defined
In Recinos et al., (2019) we wanted to estimate a frontal ablation flux for this new outline and compare it with previous estimates found in the literature for the Sawyer Glacier (McNabb et al., 2015).
For this reason we kept the Sawyer glacier attributes to the following variables:
RGIId, GLIMSId, Name
The TermType should be equal to 1, for Marine-terminating.
template['TermType'] = 1
template['Name'] = 'Sawyer Glacier merged with RGI60-01.23664'
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[25], line 1
----> 1 template['TermType'] = 1
2 template['Name'] = 'Sawyer Glacier merged with RGI60-01.23664'
NameError: name 'template' is not defined
Now we can write a new shapefile for this glacier. We recommend doing this if you have to make several model runs. You can also integrate this outline to your main RGI shapefile:
cfg.initialize()
cfg.PATHS['working_dir'] = utils.gettempdir(dirname='rgi-case-2', reset=True)
template.crs = salem.wgs84.srs
template.to_file(os.path.join(cfg.PATHS['working_dir'], 'merged.shp'))
2026-03-09 23:45:02: oggm.cfg: Reading default parameters from the OGGM `params.cfg` configuration file.
2026-03-09 23:45:02: oggm.cfg: Multiprocessing switched OFF according to the parameter file.
2026-03-09 23:45:02: oggm.cfg: Multiprocessing: using all available processors (N=4)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[26], line 3
1 cfg.initialize()
2 cfg.PATHS['working_dir'] = utils.gettempdir(dirname='rgi-case-2', reset=True)
----> 3 template.crs = salem.wgs84.srs
4 template.to_file(os.path.join(cfg.PATHS['working_dir'], 'merged.shp'))
NameError: name 'salem' is not defined
Run OGGM with this new glacier#
For simplicity, we do not compute the intersects in this case: however, we recommend you do so (see above). In all cases, do not use the intersects provided automatically with OGGM when using custom inventories, as they are likely to be wrong.
# Set-up the run
cfg.PARAMS['border'] = 10
# We don't use intersects here
cfg.PARAMS['use_intersects'] = False
# We prefer OGGM to use the area we computed ourselves
cfg.PARAMS['use_rgi_area'] = True
# Use our merged file
rgidf = gpd.read_file(os.path.join(cfg.PATHS['working_dir'], 'merged.shp'))
gdirs = workflow.init_glacier_directories(rgidf, reset=True, force=True)
gdirs
2026-03-09 23:45:02: oggm.cfg: PARAMS['border'] changed from `80` to `10`.
2026-03-09 23:45:02: oggm.cfg: PARAMS['use_intersects'] changed from `True` to `False`.
---------------------------------------------------------------------------
DataSourceError Traceback (most recent call last)
Cell In[27], line 11
8 cfg.PARAMS['use_rgi_area'] = True
10 # Use our merged file
---> 11 rgidf = gpd.read_file(os.path.join(cfg.PATHS['working_dir'], 'merged.shp'))
12 gdirs = workflow.init_glacier_directories(rgidf, reset=True, force=True)
13 gdirs
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/geopandas/io/file.py:316, in _read_file(filename, bbox, mask, columns, rows, engine, **kwargs)
313 filename = response.read()
315 if engine == "pyogrio":
--> 316 return _read_file_pyogrio(
317 filename, bbox=bbox, mask=mask, columns=columns, rows=rows, **kwargs
318 )
320 elif engine == "fiona":
321 if pd.api.types.is_file_like(filename):
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/geopandas/io/file.py:576, in _read_file_pyogrio(path_or_bytes, bbox, mask, rows, **kwargs)
567 warnings.warn(
568 "The 'include_fields' and 'ignore_fields' keywords are deprecated, and "
569 "will be removed in a future release. You can use the 'columns' keyword "
(...) 572 stacklevel=3,
573 )
574 kwargs["columns"] = kwargs.pop("include_fields")
--> 576 return pyogrio.read_dataframe(path_or_bytes, bbox=bbox, **kwargs)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/pyogrio/geopandas.py:382, in read_dataframe(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, fid_as_index, use_arrow, on_invalid, arrow_to_pandas_kwargs, datetime_as_string, mixed_offsets_as_utc, **kwargs)
374 gdal_force_2d = False if use_arrow else force_2d
376 # Always read datetimes as string values to preserve (mixed) time zone info
377 # correctly. If arrow is not used, it is needed because numpy does not
378 # directly support time zones + performance is also a lot better. If arrow
379 # is used, needed because datetime columns don't support mixed time zone
380 # offsets + e.g. for .fgb files time zone info isn't handled correctly even
381 # for unique time zone offsets if datetimes are not read as string.
--> 382 result = read_func(
383 path_or_buffer,
384 layer=layer,
385 encoding=encoding,
386 columns=columns,
387 read_geometry=read_geometry,
388 force_2d=gdal_force_2d,
389 skip_features=skip_features,
390 max_features=max_features,
391 where=where,
392 bbox=bbox,
393 mask=mask,
394 fids=fids,
395 sql=sql,
396 sql_dialect=sql_dialect,
397 return_fids=fid_as_index,
398 datetime_as_string=True,
399 **kwargs,
400 )
402 if use_arrow:
403 import pyarrow as pa
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/pyogrio/raw.py:200, in read(path_or_buffer, layer, encoding, columns, read_geometry, force_2d, skip_features, max_features, where, bbox, mask, fids, sql, sql_dialect, return_fids, datetime_as_string, **kwargs)
59 """Read OGR data source into numpy arrays.
60
61 IMPORTANT: non-linear geometry types (e.g., MultiSurface) are converted
(...) 196
197 """
198 dataset_kwargs = _preprocess_options_key_value(kwargs) if kwargs else {}
--> 200 return ogr_read(
201 get_vsi_path_or_buffer(path_or_buffer),
202 layer=layer,
203 encoding=encoding,
204 columns=columns,
205 read_geometry=read_geometry,
206 force_2d=force_2d,
207 skip_features=skip_features,
208 max_features=max_features or 0,
209 where=where,
210 bbox=bbox,
211 mask=_mask_to_wkb(mask),
212 fids=fids,
213 sql=sql,
214 sql_dialect=sql_dialect,
215 return_fids=return_fids,
216 dataset_kwargs=dataset_kwargs,
217 datetime_as_string=datetime_as_string,
218 )
File pyogrio/_io.pyx:1412, in pyogrio._io.ogr_read()
File pyogrio/_io.pyx:262, in pyogrio._io.ogr_open()
DataSourceError: /tmp/OGGM/rgi-case-2/merged.shp: No such file or directory
Here we are not able to use the Pre-processed directories and the respective Processing levels that OGGM provides for an easy run set up. We can’t use this workflow simply because we have a different beginning than OGGM, we have a different RGI! We just need to type more and run all the model task one by one:
from oggm.workflow import execute_entity_task
# Calculate the DEMs and the masks
execute_entity_task(tasks.define_glacier_region, gdirs, source = 'SRTM')
execute_entity_task(tasks.glacier_masks, gdirs)
# Calculate the Pre-processing tasks
task_list = [
tasks.compute_centerlines,
tasks.initialize_flowlines,
tasks.catchment_area,
tasks.catchment_width_geom,
tasks.catchment_width_correction,
]
for task in task_list:
execute_entity_task(task, gdirs)
2026-03-09 23:45:02: oggm.workflow: Execute entity tasks [define_glacier_region] on 2 glaciers
2026-03-09 23:45:02: oggm.core.gis: (RGI60-01.03890) define_glacier_region
2026-03-09 23:45:03: oggm.core.gis: (RGI60-01.23664) define_glacier_region
2026-03-09 23:45:03: oggm.workflow: Execute entity tasks [glacier_masks] on 2 glaciers
2026-03-09 23:45:03: oggm.core.gis: (RGI60-01.03890) glacier_masks
2026-03-09 23:45:03: oggm.core.gis: (RGI60-01.23664) glacier_masks
2026-03-09 23:45:03: oggm.core.gis: ValueError occurred during task glacier_masks on RGI60-01.23664: shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 0 with shape (263, 256) and arg 1 with shape (123, 116).
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[28], line 5
3 # Calculate the DEMs and the masks
4 execute_entity_task(tasks.define_glacier_region, gdirs, source = 'SRTM')
----> 5 execute_entity_task(tasks.glacier_masks, gdirs)
7 # Calculate the Pre-processing tasks
8 task_list = [
9 tasks.compute_centerlines,
10 tasks.initialize_flowlines,
(...) 13 tasks.catchment_width_correction,
14 ]
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/workflow.py:192, in execute_entity_task(task, gdirs, **kwargs)
188 if ng > 3:
189 log.workflow('WARNING: you are trying to run an entity task on '
190 '%d glaciers with multiprocessing turned off. OGGM '
191 'will run faster with multiprocessing turned on.', ng)
--> 192 out = [pc(gdir) for gdir in gdirs]
194 return out
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/workflow.py:109, in _pickle_copier.__call__(self, arg)
107 for func in self.call_func:
108 func, kwargs = func
--> 109 res = self._call_internal(func, arg, kwargs)
110 return res
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/workflow.py:103, in _pickle_copier._call_internal(self, call_func, gdir, kwargs)
100 gdir, gdir_kwargs = gdir
101 kwargs.update(gdir_kwargs)
--> 103 return call_func(gdir, **kwargs)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/utils/_workflow.py:503, in entity_task.__call__.<locals>._entity_task(gdir, reset, print_log, return_value, continue_on_error, add_to_log_file, **kwargs)
501 signal.alarm(cfg.PARAMS['task_timeout'])
502 ex_t = time.time()
--> 503 out = task_func(gdir, **kwargs)
504 ex_t = time.time() - ex_t
505 if cfg.PARAMS['task_timeout'] > 0:
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/core/gis.py:996, in glacier_masks(gdir)
994 else:
995 v = nc.variables['glacier_mask']
--> 996 v[:] = glacier_mask
998 if 'glacier_ext' not in nc.variables:
999 v = nc.createVariable('glacier_ext', 'i1', ('y', 'x', ),
1000 zlib=True)
File src/netCDF4/_netCDF4.pyx:5620, in netCDF4._netCDF4.Variable.__setitem__()
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/netCDF4/utils.py:357, in _StartCountStride(elem, shape, dimensions, grp, datashape, put, use_get_vars)
355 fullslice = False
356 if fullslice and datashape and put and not hasunlim:
--> 357 datashape = broadcasted_shape(shape, datashape)
359 # pad datashape with zeros for dimensions not being sliced (issue #906)
360 # only used when data covers slice over subset of dimensions
361 if datashape and len(datashape) != len(elem) and\
362 len(datashape) == sum(1 for e in elem if type(e) == slice):
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/netCDF4/utils.py:965, in broadcasted_shape(shp1, shp2)
963 a = as_strided(x, shape=shp1, strides=[0] * len(shp1))
964 b = as_strided(x, shape=shp2, strides=[0] * len(shp2))
--> 965 return np.broadcast(a, b).shape
ValueError: shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 0 with shape (263, 256) and arg 1 with shape (123, 116).
note that we used in tasks.define_glacier_region SRTM as DEM source which is not the default one in OGGM.
The default one is NASADEM, but for that you have to register at NASA Earthdata
more info in dem_sources.ipynb/register
graphics.plot_googlemap(gdirs, figsize=(6, 6));
graphics.plot_catchment_width(gdirs, corrected=True);
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[30], line 1
----> 1 graphics.plot_catchment_width(gdirs, corrected=True);
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/graphics.py:157, in _plot_map.<locals>.newplotfunc(gdirs, ax, smap, add_colorbar, title, title_comment, horizontal_colorbar, lonlat_contours_kwargs, cbar_ax, autosave, add_scalebar, figsize, savefig, savefig_kwargs, extend_plot_limit, **kwargs)
155 if add_scalebar:
156 mp.set_scale_bar()
--> 157 out = plotfunc(gdirs, ax=ax, smap=mp, **kwargs)
159 if add_colorbar and 'cbar_label' in out:
160 cbprim = out.get('cbar_primitive', mp)
File /usr/local/pyenv/versions/3.13.12/lib/python3.13/site-packages/oggm/graphics.py:495, in plot_catchment_width(gdirs, ax, smap, corrected, add_intersects, add_touches, lines_cmap)
492 smap.set_geometry(l.line, crs=crs, color=c,
493 linewidth=2.5, zorder=50)
494 if corrected:
--> 495 for wi, cur, (n1, n2) in zip(l.widths, l.line.coords,
496 l.normals):
497 _l = shpg.LineString([shpg.Point(cur + wi / 2. * n1),
498 shpg.Point(cur + wi / 2. * n2)])
500 smap.set_geometry(_l, crs=crs, color=c,
501 linewidth=0.6, zorder=50)
AttributeError: 'NoneType' object has no attribute 'coords'
Case 3: start from a completely independent inventory#
OGGM (since version 1.5.3) now offers a function (utils.cook_rgidf()) to make it easier of using a non-RGI glacier inventory in OGGM. Now, let’s use a non-RGI glacier inventory from the second Chinese glacier inventory (CGI2, https://doi.org/10.3189/2015JoG14J209) to show how it works.
New in OGGM 1.6.1: If you are using outlines consisting of multi polygons and plan to use “elevation band” flowlines (see 10 minutes to… “elevation band” and “centerline” flowlines) you can keep the complete multi polygon area for your simulations by setting cfg.PARAMS['keep_multipolygon_outlines'] = True. That can be useful when working with local glacier inventories with multiple outlines (e.g. older outline single polygon but newer outline multi polygon for the same glacier).
# Let's get the sample CGI2 glacier inventory and see what it looks like
from oggm import utils
import geopandas as gpd
cgidf = gpd.read_file(utils.get_demo_file('cgi2.shp'))
cgidf
| Glc_Name | Drng_Code | FCGI_ID | GLIMS_ID | Mtn_Name | Pref_Name | Glc_Long | Glc_Lati | Glc_Area | Abs_Accu | ... | Mean_Slp | Mean_Asp | Prm_Image | Aux_Image | Rep_Date | Elev_Src | Elev_Date | Compiler | Verifier | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | None | 5X043P | 5X043P0038 | G084892E43502N | 天山 | 新疆维吾尔自治区伊犁哈萨克自治州 | 84.892252 | 43.502473 | 4410738.3 | 154881.40 | ... | 15.1 | 247.5 | Landsat:P144R030,TM,2009-08-08 | NaN | 2009年8月8日 | SRTM V4 | Feb, 2000 | 李萍 | 魏俊锋 | POLYGON ((-1597545.625 4858570.5, -1597500.125... |
| 1 | None | 5Y533B | 5Y533B0022 | G094299E35672N | 昆仑山 | 青海省海西蒙古族藏族自治州 | 94.299430 | 35.671728 | 2569748.4 | 80390.42 | ... | 25.6 | 27.3 | Landsat:P136R035,TM,2006-07-23 | Landsat:P136R035,TM,2010-04-29;P136R035,ETM+,2... | 2006年7月23日 | SRTM V4 | Feb, 2000 | 李萍 | 郭万钦 | POLYGON ((-950552.062 3862119.75, -950515.125 ... |
| 2 | None | 5O282A | 5O282A0750 | G096290E29880N | 念青唐古拉山 | 西藏自治区林芝地区 | 96.289832 | 29.879834 | 320096.7 | 33721.87 | ... | 27.2 | 96.5 | Landsat:P134R039,TM,2005-09-08 | NaN | 2005年9月8日 | SRTM V4 | Feb, 2000 | 李萍 | 李刚 | POLYGON ((-830689.75 3194922.5, -830685.25 319... |
| 3 | None | 5K441M | 5K441M0100 | G092234E32782N | 唐古拉山 | 青海省海西蒙古族藏族自治州 | 92.234420 | 32.781958 | 969356.4 | 43823.40 | ... | 15.2 | 101.3 | Landsat:P137R037,TM,2007-09-19 | NaN | 2007年9月19日 | SRTM V4 | Feb, 2000 | 李萍 | 盖春梅 | POLYGON ((-1173462.875 3559676.75, -1173507.25... |
| 4 | None | 5O291B | 5O291B0528 | G097340E29195N | 横断山 | 西藏自治区林芝地区 | 97.340135 | 29.195439 | 839757.2 | 47341.39 | ... | 14.3 | 329.4 | Landsat:P134R040,TM,2005-09-08 | NaN | 2005年9月8日 | SRTM V4 | Feb, 2000 | 李萍 | 李刚 | POLYGON ((-735850.625 3109206.75, -735851.312 ... |
5 rows × 30 columns
Ha! There are some Chinese characters! But it should not influence our work. Now, let’s try with the simplest case:
rgidf_simple = utils.cook_rgidf(cgidf, o1_region='13')
rgidf_simple
| RGIId | CenLon | CenLat | GLIMSId | BgnDate | EndDate | O1Region | O2Region | Area | Zmin | ... | Lmax | Status | Connect | Form | TermType | Surging | Linkages | check_geom | Name | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | RGI60-13.00001 | 84.897508 | 43.504834 | 20009999 | 9999999 | 13 | 01 | -9999.0 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((84.88765 43.51793, 84.8882 43.51803,... | ||
| 1 | RGI60-13.00002 | 94.301049 | 35.673427 | 20009999 | 9999999 | 13 | 01 | -9999.0 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((94.28628 35.67243, 94.28669 35.67247... | ||
| 2 | RGI60-13.00003 | 96.293274 | 29.880223 | 20009999 | 9999999 | 13 | 01 | -9999.0 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((96.28739 29.88241, 96.28744 29.88235... | ||
| 3 | RGI60-13.00004 | 92.233827 | 32.781994 | 20009999 | 9999999 | 13 | 01 | -9999.0 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((92.23549 32.77855, 92.23501 32.77851... | ||
| 4 | RGI60-13.00005 | 97.340065 | 29.196493 | 20009999 | 9999999 | 13 | 01 | -9999.0 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((97.34704 29.18993, 97.34703 29.18993... |
5 rows × 24 columns
In this case, we fake all the columns values except for geometry. With this rgidf_simple, we can handle most of the OGGM procedure after set cfg.PARAMS['use_rgi_area'] = False. Let’s have a try:
from oggm import cfg, workflow
cfg.initialize()
cfg.PARAMS['use_multiprocessing'] = True
cfg.PARAMS['use_rgi_area'] = False
cfg.PARAMS['use_intersects'] = False
cfg.PATHS['working_dir'] = utils.gettempdir(dirname='cook_rgidf', reset=True)
gdirs = workflow.init_glacier_directories(rgidf_simple)
# The tasks below require downloading new data - we comment them for the tutorial, but it should work for you!
# todo--> these tasks below are old, they need to be updated to oggm v1.6
# workflow.gis_prepro_tasks(gdirs)
# workflow.download_ref_tstars('https://cluster.klima.uni-bremen.de/~oggm/ref_mb_params/oggm_v1.4/RGIV62/CRU/centerlines/qc3/pcp2.5')
# workflow.climate_tasks(gdirs)
# workflow.inversion_tasks(gdirs)
utils.compile_glacier_statistics(gdirs)
2026-03-09 23:45:06: oggm.cfg: Reading default parameters from the OGGM `params.cfg` configuration file.
2026-03-09 23:45:06: oggm.cfg: Multiprocessing switched OFF according to the parameter file.
2026-03-09 23:45:06: oggm.cfg: Multiprocessing: using all available processors (N=4)
2026-03-09 23:45:06: oggm.cfg: Multiprocessing switched ON after user settings.
2026-03-09 23:45:06: oggm.cfg: PARAMS['use_rgi_area'] changed from `True` to `False`.
2026-03-09 23:45:06: oggm.cfg: PARAMS['use_intersects'] changed from `True` to `False`.
2026-03-09 23:45:06: oggm.workflow: Execute entity tasks [GlacierDirectory] on 5 glaciers
2026-03-09 23:45:06: pyogrio._io: Created 1 records
2026-03-09 23:45:06: pyogrio._io: Created 1 records
2026-03-09 23:45:06: pyogrio._io: Created 1 records
2026-03-09 23:45:06: pyogrio._io: Created 1 records
2026-03-09 23:45:06: pyogrio._io: Created 1 records
2026-03-09 23:45:06: oggm.utils: Applying global task compile_glacier_statistics on 5 glaciers
2026-03-09 23:45:06: oggm.workflow: Execute entity tasks [glacier_statistics] on 5 glaciers
2026-03-09 23:45:06: oggm.utils: (RGI60-13.00002) glacier_statistics
2026-03-09 23:45:06: oggm.utils: (RGI60-13.00004) glacier_statistics
2026-03-09 23:45:06: oggm.utils: (RGI60-13.00003) glacier_statistics
2026-03-09 23:45:06: oggm.utils: (RGI60-13.00001) glacier_statistics
2026-03-09 23:45:07: oggm.utils: (RGI60-13.00005) glacier_statistics
| rgi_region | rgi_subregion | name | cenlon | cenlat | rgi_area_km2 | rgi_year | glacier_type | terminus_type | is_tidewater | status | geometry_type | geometry_is_valid | geometry_area_km2 | error_task | error_msg | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| rgi_id | ||||||||||||||||
| RGI60-13.00001 | 13 | 13-01 | 84.897508 | 43.504834 | 4.407211 | 2000 | Glacier | Land-terminating | False | Glacier or ice cap | Polygon | True | 4.410738 | None | None | |
| RGI60-13.00002 | 13 | 13-01 | 94.301049 | 35.673427 | 2.567693 | 2000 | Glacier | Land-terminating | False | Glacier or ice cap | Polygon | True | 2.569750 | None | None | |
| RGI60-13.00003 | 13 | 13-01 | 96.293274 | 29.880223 | 0.319841 | 2000 | Glacier | Land-terminating | False | Glacier or ice cap | Polygon | True | 0.320097 | None | None | |
| RGI60-13.00004 | 13 | 13-01 | 92.233827 | 32.781994 | 0.968581 | 2000 | Glacier | Land-terminating | False | Glacier or ice cap | Polygon | True | 0.969356 | None | None | |
| RGI60-13.00005 | 13 | 13-01 | 97.340065 | 29.196493 | 0.839086 | 2000 | Glacier | Land-terminating | False | Glacier or ice cap | Polygon | True | 0.839757 | None | None |
Sometimes, the information in the original glacier inventory also covered what RGI need, but with different name. For example, both CGI2 and RGI include Lon-lat coordinate to indicate the location of the glacier but with different names. CGI2 used Glc_Long and Glc_Lati, while RGI6 used CenLon and CenLat. Also, CGI2 include glacier area information with name Glc_Area, while RGI named glacier area as Area. If we want to keep those values but rename them following RGI, we can use the assign_column_values keyword argument:
rgidf_save_columns = utils.cook_rgidf(cgidf, o1_region='13', assign_column_values={'Glc_Long': 'CenLon', 'Glc_Lati': 'CenLat', 'Glc_Area': 'Area', 'GLIMS_ID': 'GLIMSId'})
rgidf_save_columns
| RGIId | CenLon | CenLat | GLIMSId | BgnDate | EndDate | O1Region | O2Region | Area | Zmin | ... | Lmax | Status | Connect | Form | TermType | Surging | Linkages | check_geom | Name | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | RGI60-13.00001 | 84.892252 | 43.502473 | G084892E43502N | 20009999 | 9999999 | 13 | 01 | 4410738.3 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((84.88765 43.51793, 84.8882 43.51803,... | |
| 1 | RGI60-13.00002 | 94.299430 | 35.671728 | G094299E35672N | 20009999 | 9999999 | 13 | 01 | 2569748.4 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((94.28628 35.67243, 94.28669 35.67247... | |
| 2 | RGI60-13.00003 | 96.289832 | 29.879834 | G096290E29880N | 20009999 | 9999999 | 13 | 01 | 320096.7 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((96.28739 29.88241, 96.28744 29.88235... | |
| 3 | RGI60-13.00004 | 92.234420 | 32.781958 | G092234E32782N | 20009999 | 9999999 | 13 | 01 | 969356.4 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((92.23549 32.77855, 92.23501 32.77851... | |
| 4 | RGI60-13.00005 | 97.340135 | 29.195439 | G097340E29195N | 20009999 | 9999999 | 13 | 01 | 839757.2 | -9999.0 | ... | -9999 | 0 | 0 | 0 | 0 | 0 | 1 | None | POLYGON ((97.34704 29.18993, 97.34703 29.18993... |
5 rows × 24 columns
Seems perfect! However, the glacier area in CGI2 is in \(m^2\), but it is in \(km^2\) for RGI. So, we need to correct the Area values right:
rgidf_save_columns['Area'] = rgidf_save_columns.Area * 1e-6
rgidf_save_columns.Area
0 4.410738
1 2.569748
2 0.320097
3 0.969356
4 0.839757
Name: Area, dtype: float64
Note:#
Despite that cook_rgidf() can handle most of the cases for OGGM, there are some limitations. Here, we try to point out some of the cases in which the rgidf sourced from cook_rgidf() might get you in trouble:
in
cook_rgidf(), we assign the glacier form with ‘0’ (Glacier) for all the glaciers in the original data. OGGM assigns different parameters for glaciers (form ‘0’) and ice caps (form ‘1’).termtypewas also assign as ‘0’ which means ‘land-terminating’. Here again, OGGM treats ‘Marine-terminating’ glaciers differently (see ‘Frontal ablation’).
For these kinds of attribution, there is nothing we can do automatically. Users need to assign the right values according the actual condition of their glaciers, if the attribution is important to their use cases.
What’s next?#
return to the OGGM documentation
back to the table of contents