Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions .github/workflows/test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,26 @@ jobs:
- name: 'Reinstall PyGEM'
run: pip install --break-system-packages -e .

- name: 'Run ruff linting check'
run: ruff check .

- name: 'Run ruff formatting check'
if: ${{ !cancelled() }}
run: ruff format . --check

- name: 'Initialize PyGEM'
run: initialize

- name: 'Clone the PyGEM-notebooks repo'
run: |
# Use PyGEM-notebook:main for master branch and PyGEM-notebooks:dev otherwise
BRANCH=${GITHUB_REF#refs/heads/}
git clone --depth 1 --branch $([[ "$BRANCH" == "master" ]] && echo "main" || echo "dev") \
https://github.com/pygem-community/PyGEM-notebooks.git
echo "PYGEM_NOTEBOOKS_DIRPATH=$(pwd)/PyGEM-notebooks" >> $GITHUB_ENV
if [ "$BRANCH" = "master" ]; then
NOTEBOOK_BRANCH="main"
else
NOTEBOOK_BRANCH="dev"
fi
git clone --depth 1 --branch "$NOTEBOOK_BRANCH" https://github.com/pygem-community/PyGEM-notebooks.git
echo "PYGEM_NOTEBOOKS_DIRPATH=$(pwd)/PyGEM-notebooks" >> "$GITHUB_ENV"

- name: 'Run tests'
run: |
Expand Down
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# pycache
# Subdirectories
__pycache__/

# vscode
sample_data/
.vscode/

# python bytecode
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ To support model testing and demonstration, a suite of Jupyter notebooks can be
<td style="width: 50%;"><b>Citation</b></td>
<td style="width: 50%;">
<a href="https://www.science.org/doi/10.1126/science.abo1324"><img src="https://img.shields.io/badge/citation-Rounce%20et%20al.%20(2023;%20Science)-orange.svg"></a>
&nbsp;
<a href="https://doi.org/10.5281/zenodo.15045308"><img src="https://zenodo.org/badge/DOI/10.5281/zenodo.15045308.svg" alt="DOI"></a>
</td>
</tr>
<tr>
Expand Down
56 changes: 29 additions & 27 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,59 @@

import os
import sys

import tomllib

sys.path.insert(0, os.path.abspath('../pygem/'))

# source pyproject.toml to get release
with open("../pyproject.toml", "rb") as f:
with open('../pyproject.toml', 'rb') as f:
pyproject = tomllib.load(f)

project = 'PyGEM'
copyright = '2023, David Rounce'
author = 'David Rounce'
release = pyproject["tool"]["poetry"]["version"]
release = pyproject['tool']['poetry']['version']

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = ['sphinx_book_theme',
'myst_parser',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
'numpydoc',
'sphinx.ext.viewcode',
'sphinx_togglebutton',
]
extensions = [
'sphinx_book_theme',
'myst_parser',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
'numpydoc',
'sphinx.ext.viewcode',
'sphinx_togglebutton',
]

myst_enable_extensions = [
"amsmath",
"attrs_inline",
"colon_fence",
"deflist",
"dollarmath",
"fieldlist",
"html_admonition",
"html_image",
'amsmath',
'attrs_inline',
'colon_fence',
'deflist',
'dollarmath',
'fieldlist',
'html_admonition',
'html_image',
]

#templates_path = ['_templates']
# templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']



# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output


html_theme = 'sphinx_book_theme'
html_static_path = ['_static']

html_theme_options = {
"repository_url": "https://github.com/PyGEM-Community/PyGEM",
"use_repository_button": True,
"show_nav_level":2,
"navigation_depth":3,
}
'repository_url': 'https://github.com/PyGEM-Community/PyGEM',
'use_repository_button': True,
'show_nav_level': 1,
'navigation_depth': 4,
'toc_title': 'On this page',
}
226 changes: 113 additions & 113 deletions docs/configuration.md

Large diffs are not rendered by default.

22 changes: 21 additions & 1 deletion docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Next, clone PyGEM. This will place the code at your current directory, so you ma
```
git clone https://github.com/PyGEM-Community/PyGEM.git
```
If you opted to create your own fork, clone using appropriate repo URL: `git clone https://github.com/YOUR-USERNAME/PyGEM.git`
If you opted to create your own fork, clone using appropriate repo URL: `git clone https://github.com/<YOUR-USERNAME>/PyGEM.git`

Navigate to root project directory:
```
Expand Down Expand Up @@ -45,6 +45,7 @@ Installing a package in editable mode creates a symbolic link to your source cod
- First, open a Draft PR. Then consider:
- Have you finished making changes?
- Have you added tests for all new functionalities you introduced?
- Have you run the ruff linter and formatter? See [the linting and formatting section below](ruff_target) on how to do that.
- Have all tests passed in the CI? (Check the progress in the Checks tab of the PR.)

If the answer to all of the above is "yes", mark the PR as "Ready for review" and request a review from an appropriate reviewer. If in doubt of which reviewer to assign, assign [drounce](https://github.com/drounce).
Expand All @@ -56,3 +57,22 @@ Installing a package in editable mode creates a symbolic link to your source cod
- After responding to a reviewer's comment, do not mark it as resolved.
- Once all comments are addressed, request a new review from the same reviewer. The reviewer should then resolve the comments they are satisfied with.
- After approving someone else's PR, do not merge it. Let the original author of the PR merge it when they are ready, as they might notice necessary last-minute changes.

(ruff_target)=
## Code linting and formatting
PyGEM **requires** all code to be linted and formatted using [ruff](https://docs.astral.sh/ruff/formatter). Ruff enforces a consistent coding style (based on [Black](https://black.readthedocs.io/en/stable/the_black_code_style/index.html)) and helps prevent potential errors, stylistic issues, or deviations from coding standards. The configuration for Ruff can be found in the `pyproject.toml` file.

⚠️ **Both linting and formatting must be completed before code is merged.** These checks are run automatically in the CI pipeline. If any issues are detected, the pipeline will fail.

### Lint the codebase
To lint the codebase using Ruff, run the following command:
```
ruff check /path/to/code
```
Please address all reported errors. Many errors may be automatically and safely fixed by passing `--fix` to the above command. Other errors will need to be manually addressed.

### Format the codebase
To automatically format the codebase using Ruff, run the following command:
```
ruff format /path/to/code
```
9 changes: 7 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,22 @@ with respect to modeling glacier dynamics and ice thickness inversions.
:caption: Getting Started:

install_pygem
test_pygem
configuration
scripts_overview
test_pygem
model_output

.. toctree::
:maxdepth: 1
:caption: Contributing:

contributing
citing

.. toctree::
:maxdepth: 1
:caption: Citing:

citing
.. Indices and tables
.. ==================

Expand Down
4 changes: 3 additions & 1 deletion docs/install_pygem.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(install_pygem_target)=
# Installation
The Python Glacier Evolution Model has been packaged using Poetry and is hosted on the Python Package Index ([PyPI](https://pypi.org/project/pygem/)), to ensure that all dependencies install seamlessly. It is recommended that users create a [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/index.html) environment from which to install the model dependencies and core code. If you do not yet have conda installed, see [conda's documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install) for instructions.
PyGEM has been tested successfully on Linux and macOS systems. For Windows users (Windows 10/11), we recommend installing the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl) (WSL), and then installing and running PyGEM from there.

PyGEM has been packaged using [Poetry](https://python-poetry.org/) and is hosted on the Python Package Index ([PyPI](https://pypi.org/project/pygem/)), to ensure that all dependencies install seamlessly. It is recommended that users create a [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/index.html) environment from which to install the model dependencies and core code. If you do not yet have conda installed, see [conda's documentation](https://docs.conda.io/projects/conda/en/latest/user-guide/install) for instructions.

Next, choose your preferred PyGEM installation option:<br>
- [**stable**](stable_install_target): this is the latest version that has been officially released to PyPI, with a fixed version number (e.g. v1.0.1). It is intended for general use.
Expand Down
8 changes: 4 additions & 4 deletions docs/mb_ablation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ There are currently two model options for ablation. Both model options use a deg

### Option 1: monthly temperatures
The first calculates ablation ($a$) using the mean monthly temperature:
$$a=f_{snow/ice/firn/debris} \cdot T_{m}^{+} \cdot n$$
$a=f_{snow/ice/firn/debris} \cdot T_{m}^{+} \cdot n$

where $f$ is the degree-day factor of snow, ice, firn, or debris (m w.e. d-1 °C$^{-1}$), $T_{m}^{+}$ is the positive monthly mean temperature (°C), and $n$ is the number of days per month.
where $f$ is the degree-day factor of snow, ice, firn, or debris (m w.e. d$^{-1}$ °C$^{-1}$), $T_{m}^{+}$ is the positive monthly mean temperature (°C), and $n$ is the number of days per month.

### Option 2: monthly temperatures with daily variance
The second option incorporates the daily variance associated with the temperature for each month according to [Huss and Hock (2015)](https://www.frontiersin.org/articles/10.3389/feart.2015.00054/full):
$$a=f_{snow/ice/firn/debris} \cdot \sum_{i=1}^{ndays} T_{d,i}^{+} $$
$a=f_{snow/ice/firn/debris} \cdot \sum_{i=1}^{ndays} T_{d,i}^{+} $

where $T_{d}$ is the daily positive mean air temperature and is estimated by superimposing random variability from the standard deviation of the daily temperature for each month.

The degree-day factors for snow, ice, firn, and debris depend on the surface type option that is chosen by the user (see Section 5). The values of $f$ for these various surface types are assumed to be related to one another to reduce the number of model parameters. The default ratio of the $f_{snow}$ to the $f_{ice}$ is 0.7, and $f_{firn}$ is assumed to be the mean of the $f_{snow}$ and $f_{ice}$; however, the user may change these values in the input file if desired. The values for $f_{debris}$ are equal to $f_{ice}$ multiplied by the mean sub-debris melt enhancement factor [(Rounce et al. 2021)](https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2020GL091311) for the given elevation bin.

### Temperature at elevation bins
Temperature for each elevation bin ($T_{bin}$) is determined by selecting the temperature from the gridded climate data ($T_{gcm}$) based on the nearest neighbor, which is then downscaled to the elevation bins on the glacier according to:
$$T_{bin} = T_{gcm} + lr_{gcm} \cdot (z_{ref} - z_{gcm}) + lr_{glac} \cdot (z_{bin} - z_{ref}) + T_{bias}$$
$T_{bin} = T_{gcm} + lr_{gcm} \cdot (z_{ref} - z_{gcm}) + lr_{glac} \cdot (z_{bin} - z_{ref}) + T_{bias}$

where $lr_{gcm}$ and $lr_{glac}$ are lapse rates (°C m-1) associated with downscaling the climate data to the glacier and then over the glacier elevation bins, respectively; $z_{ref}$, $z_{gcm}$, and $z_{bin}$ are the elevations from the glacier’s reference point (median or mean elevation), the climate data, and the elevation bin, respectively; and $T_{bias}$ is the temperature bias. The temperature bias is one of three model parameters that is calibrated and serves to account for any biases resulting from the use of coarse climate data that is unable to capture local topographic variations. By default, the $lr_{gcm}$ and $lr_{glac}$ are assumed to be equal.
6 changes: 3 additions & 3 deletions docs/mb_accumulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Accumulation ($c$) is calculated for each elevation bin as a function of the pre

### Option 1: Threshold +/- 1$^{\circ}$C
The first (default) option is to estimate the ratio of liquid and solid precipitation based on the air temperature:
$$c = \delta \cdot P_{bin}$$
$c = \delta \cdot P_{bin}$

where $\delta=1$; if $T_{bin} \leq T_{snow}-1$

Expand All @@ -18,9 +18,9 @@ The alternative option is to classify precipitation as snow or rain based on a s

### Precipitation at elevation bins
Precipitation at each elevation bin of the glacier ($P_{bin}$) is determined by selecting the precipitation from the gridded climate data ($P_{gcm}$) based on the nearest neighbor, which is then downscaled to the elevation bins on the glacier:
$$P_{bin} = P_{GCM} \cdot k_{p} \cdot (1 + d_{prec} \cdot (z_{bin} - z_{ref}))$$
$P_{bin} = P_{GCM} \cdot k_{p} \cdot (1 + d_{prec} \cdot (z_{bin} - z_{ref}))$
<br>where $k_{p}$ is the precipitation factor and $d_{prec}$ is the precipitation gradient. The precipitation factor is a model parameter that is used to adjust from the climate data to the glacier, which could be caused by local topographic effects due to differences in elevation, rain shadow effects, etc. The precipitation gradient is another model parameter, which is used to redistribute the precipitation along the glacier and can be thought of as a precipitation lapse rate. Typical values for the precipitation gradient vary from 0.01 – 0.025% m$^{-1}$([Huss and Hock, 2015](https://www.frontiersin.org/articles/10.3389/feart.2015.00054/full) who cited [WGMS, 2012](https://wgms.ch/products_fog/)). The default assumes a precipitation gradient of 0.01% m$^{-1}$ to reduce the number of model parameters.

Additionally, for glaciers with high relief (> 1000 m), the precipitation in the uppermost 25% of the glacier’s elevation is reduced using an exponential function ([Huss and Hock, 2015](https://www.frontiersin.org/articles/10.3389/feart.2015.00054/full)):
$$P_{bin,exp} = P_{bin} \cdot exp(\frac{z_{bin} - z_{75\%}}{z_{max} - z_{75\%}}) $$
$P_{bin,exp} = P_{bin} \cdot exp(\frac{z_{bin} - z_{75\%}}{z_{max} - z_{75\%}}) $
where $P_{bin,exp}$ is the adjusted precipitation, and $z_{max}$ and $z_{75\%}$ are the elevation of the glacier maximum and the glacier’s 75th percentile elevation, respectively. The adjusted precipitation cannot be lower than 87.5% of the maximum precipitation on the glacier. This adjustment accounts for the reduced air moisture and increased wind erosion at higher elevations ([Benn and Lehmkuhl, 2000](https://risweb.st-andrews.ac.uk/portal/en/researchoutput/mass-balance-and-equilibriumline-altitudes-of-glaciers-in-highmountain-environments(080f17fc-33dd-4805-bc97-a5aaa018a457)/export.html)).
2 changes: 1 addition & 1 deletion docs/mb_refreezing.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ There are two model options for computing refreezing. The default option estima

### Option 1: Mean annual air temperature
For the default option, refreezing (R) is calculated for each elevation bin as a function of its weighted annual mean air temperature (Ta) following [Woodward et al. (1997)](https://www.cambridge.org/core/journals/annals-of-glaciology/article/influence-of-superimposedice-formation-on-the-sensitivity-of-glacier-mass-balance-to-climate-change/84DFA08E9CC8F28BE0729F1EBF4DA4E1)):
$$R = -0.0069 \cdot T_{a} + 0.000096$$
$R = -0.0069 \cdot T_{a} + 0.000096$
The weighted annual mean accounts for the number of days in each month. Refreezing cannot be negative. The model assumes that refreezing occurs in the snowpack as opposed to being superimposed ice, so in the ablation zone the refreezing cannot exceed the snow depth. Since this option estimates annual refreezing, the equation above provides the maximum amount of potential refreezing. Each year, the potential refreezing is reset in October as this is the transition season from predominantly summer melt to winter accumulation. Therefore, it is possible that accumulated snow may melt and refreeze diurnally. The model replicates this physical behavior by first determining the amount of snow that has melted in that month. If the refreezing potential is greater than zero, the model assumes the snow melts and refreezes in the snow pack. Refreezing cannot exceed the amount of snow melt in any given month. The amount of refreezing is then subtracted from the potential refreezing until the potential refreezing is fully depleted or reset. Once the snow and refreezing completely melts, the model can melt the underlying ice/firn/snow. This model is used as the default because it is computationally cheap compared to the alternative.

### Option 2: Heat conduction
Expand Down
4 changes: 3 additions & 1 deletion docs/model_output.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
(model_output_overview_target)=
# Model Output
The model outputs a variety of data including monthly mass balance and its components (accumulation, melt, refreezing, frontal ablation, glacier runoff), and annual mass, mass below sea level, and area. Results are written as a netcdf file (.nc) for each glacier. If multiple simulations are performed (e.g., for Monte Carlo simulations), then statistics related to the median and median absolute deviation are output for each parameter. In addition to this standard glacier-wide output, binned output is also available, which include the bins surface elevation, volume, thickness, and climatic mass balance annually.
The model outputs a variety of data including monthly mass balance and its components (accumulation, melt, refreezing, frontal ablation, glacier runoff), and annual mass, mass below sea level, and area. Results are written as a netcdf file (.nc) for each glacier. If multiple simulations are performed (e.g., for Monte Carlo simulations), then statistics related to the median and median absolute deviation are output for each parameter.

In addition to this standard glacier-wide output, binned outputs are also available (by setting `sim["out"]["export_binned_data"]` to `true` in the [PyGEM configuration file](contributing_pygem_target)), which include each bins initial surface elevation, annual area, annual mass, annual thickness, annual climatic mass balance, and monthly climatic mass balance. Monthly climatic mass balance components can also be stored by setting `sim["out"]["export_binned_components"]` to `true`.

## Post-processing Data
PyGEM simulations are output for each glacier individually. For most analyses, it is useful to aggregate or merge analyses to a regional or global scale. PyGEM's *postproc.compile_simulations.py* is designed to do just so.
Expand Down
Loading