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
64 changes: 64 additions & 0 deletions .github/workflows/docker_pygem.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: 'Build bespoke PyGEM Docker container'

on:
# Trigger when these files change in an open PR
pull_request:
paths:
- '.github/workflows/docker_pygem.yml'
- 'docker/Dockerfile'

# Trigger when these files change on the master or dev branches
push:
branches:
- master
- dev
paths:
- '.github/workflows/docker_pygem.yml'
- 'docker/Dockerfile'

# Trigger every Saturday at 12AM GMT
schedule:
- cron: '0 0 * * 6'

# Manually trigger the workflow
workflow_dispatch:

# Stop the workflow if a new one is started
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
packages: write

jobs:
docker:
name: 'Build and push Docker container'
runs-on: ubuntu-latest

steps:
- name: 'Check out the repo'
uses: actions/checkout@v4

- name: 'Set up Docker buildx'
uses: docker/setup-buildx-action@v3

- name: 'Log into GitHub Container Repository'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
logout: true

- name: 'Build and Push Docker Container'
uses: docker/build-push-action@v5
with:
push: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev' }}
no-cache: true
file: 'docker/Dockerfile'
build-args: |
PYGEM_BRANCH=${{ github.ref == 'refs/heads/master' && 'master' || 'dev' }}
tags: |
ghcr.io/pygem-community/pygem:${{ github.ref == 'refs/heads/master' && 'latest' || github.ref == 'refs/heads/dev' && 'dev' }}
62 changes: 62 additions & 0 deletions .github/workflows/test_suite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: 'Install PyGEM and Run Test Suite'

on:
push:
branches:
- master
- dev
paths:
- '**.py'
- '.github/workflows/test_suite.yml'
- 'pyproject.toml'

pull_request:
paths:
- '**.py'
- '.github/workflows/test_suite.yml'
- 'pyproject.toml'

# Run test suite every Saturday at 1AM GMT (1 hour after the Docker image is updated)
schedule:
- cron: '0 1 * * 6'

# Stop the workflow if a new one is started
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test_suite:
name: 'Test suite'
runs-on: ubuntu-latest
container:
# Use pygem:latest for master branch and pygem:dev otherwise
image: ghcr.io/pygem-community/pygem:${{ github.ref == 'refs/heads/master' && 'latest' || 'dev' }}
options: --user root
env:
# Since we are root we need to set PYTHONPATH to be able to find the installed packages
PYTHONPATH: /home/ubuntu/.local/lib/python3.12/site-packages

steps:
- name: 'Checkout the PyGEM repo'
id: checkout
uses: actions/checkout@v4

- name: 'Reinstall PyGEM'
run: pip install --break-system-packages -e .

- 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

- name: 'Run tests'
run: |
python3 -m coverage erase
python3 -m pytest --cov=pygem -v --durations=20 pygem/tests
49 changes: 3 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,10 @@
## Python Glacier Evolution Model (PyGEM)

Overview: Python Glacier Evolution Model (PyGEM) is an open-source glacier evolution model coded in Python that models the transient evolution of glaciers. Each glacier is modeled independently using a monthly timestep. PyGEM has a modular framework that allows different schemes to be used for model calibration or model physics (e.g., climatic mass balance, glacier dynamics).
The Python Glacier Evolution Model (PyGEM) is an open-source glacier evolution model coded in Python that models the transient evolution of glaciers. Each glacier is modeled independently using a monthly timestep. PyGEM has a modular framework that allows different schemes to be used for model calibration or model physics (e.g., climatic mass balance, glacier dynamics).

Manual: Details concerning the model physics, installation, and running the model may be found [here](https://pygem.readthedocs.io/en/latest/).

Usage: PyGEM is meant for large-scale glacier evolution modeling. PyGEM<1.0.0 are no longer being actively being supported.

***

### Installation
PyGEM can be downloaded from the Python Package Index ([PyPI](https://pypi.org/project/pygem/)). We recommend creating a dedicated [Anaconda](https://anaconda.org/) environment to house PyGEM.
```
conda create --name <environment_name> python=3.12
conda activate <environment_name>
pip install pygem
```
This will install all PyGEM dependencies within your conda environment, and set up PyGEM command line tools to run core model scripts.

***

### Setup
Following installation, an initialization script should to be executed.

The initialization script accomplishes two things:
1. Initializes the PyGEM configuration file *~/PyGEM/config.yaml*. If this file already exists, an overwrite prompt will appear.
2. Downloads and unzips a set of sample data files to *~/PyGEM/*, which can also be manually downloaded [here](https://drive.google.com/file/d/1Wu4ZqpOKxnc4EYhcRHQbwGq95FoOxMfZ/view?usp=drive_link).

Run the initialization script by entering the following in the terminal:
```
initialize
```

***

### Development
Please report any bugs [here](https://github.com/PyGEM-Community/PyGEM/issues).

If you are interested in contributing to further development of PyGEM, we recommend forking [PyGEM](https://github.com/PyGEM-Community/PyGEM) and then [cloning](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) onto your local machine.

Note, if PyGEM was already installed via PyPI, first uninstall:
```
pip uninstall pygem
````

You can then use pip to install your locally cloned fork of PyGEM in 'editable' mode to easily facilitate development like so:
```
pip install -e /path/to/your/cloned/pygem/fork/
```
Details concerning the model installation, physics, and more may be found at [pygem.readthedocs.io](https://pygem.readthedocs.io/en/latest/).

PyGEM versions prior to 1.0.0 are no longer actively supported.

***

Expand Down
26 changes: 26 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM ubuntu:latest

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
sudo curl vim git tree python3-pip python3-venv python3-dev build-essential \
&& rm -rf /var/lib/apt/lists/*

# Add non-root user 'ubuntu' to sudo group
RUN usermod -aG sudo ubuntu && \
echo "ubuntu ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ubuntu

# Switch to non-root user
USER ubuntu
WORKDIR /home/ubuntu

# Add .local/bin to PATH
ENV PATH="/home/ubuntu/.local/bin:${PATH}"

# What PyGEM branch to clone (either master or dev; see docker_pygem.yml)
ARG PYGEM_BRANCH=master

RUN git clone --branch ${PYGEM_BRANCH} https://github.com/PyGEM-Community/PyGEM.git && \
pip install --break-system-packages -e PyGEM

# Clone the PyGEM notebooks repository, which are used for testing
RUN git clone https://github.com/PyGEM-Community/PyGEM-notebooks.git
58 changes: 58 additions & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
(contributing_pygem_target)=
# PyGEM Contribution Guide

Before contributing to PyGEM, it is recommended that you either clone [PyGEM's GitHub repository](https://github.com/PyGEM-Community/PyGEM) directly, or initiate your own fork (as described [here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo)) to then clone.

If PyGEM was already installed in your conda environment (as outlined [here](install_pygem_target)), it is recommended that you first uninstall:
```
pip uninstall pygem
```

Next, clone PyGEM. This will place the code at your current directory, so you may wish to navigate to a desired location in your terminal before cloning:
```
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`

Navigate to root project directory:
```
cd PyGEM
```

Install PyGEM in 'editable' mode:
```
pip install -e .
```

Installing a package in editable mode creates a symbolic link to your source code directory (*/path/to/your/PyGEM/clone*), rather than copying the package files into the site-packages directory. This allows you to modify the package code without reinstalling it.<br>

## General
- The `dev` branch is the repository's working branch and should almost always be the base branch for Pull Requests (PRs). Exceptions include hotfixes that need to be pushed to the `master` branch immediately, or updates to the `README`.
- Do not push to other people's branches. Instead create a new branch and open a PR that merges your new branch into the branch you want to modify.

## Issues
- Check whether an issue describing your problem already exists [here](https://github.com/PyGEM-Community/PyGEM/issues).
- Keep issues simple: try to describe only one problem per issue. Open multiple issues or sub-issues when appropriate.
- Label the issue with the appropriate label (e.g., bug, documentation, etc.).
- If you start working on an issue, assign it to yourself. There is no need to ask for permission unless someone is already assigned to it.

## Pull requests (PRs)
- PRs should be submitted [here](https://github.com/PyGEM-Community/PyGEM/pulls).
- PRs should be linked to issues they address (unless it's a minor fix that doesn't warrant a new issue). Think of Issues like a ticketing system.
- PRs should generally address only one issue. This helps PRs stay shorter, which in turn makes the review process easier.
- Concisely describe what your PR does. Avoid repeating what was already said in the issue.
- Assign the PR to yourself.
- First, open a Draft PR. Then consider:
- Have you finished making changes?
- Have you added tests for all new functionalities you introduced?
- 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).
- You will not be able to merge into `master` and `dev` branches without a reviewer's approval.

### Reviewing PRs and responding to a review
- Reviewers should leave comments on appropriate lines. Then:
- The original author of the PR should address all comments, specifying what was done and in which commit. For example, a short response like "Fixed in [link to commit]." is often sufficient.
- 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.
16 changes: 0 additions & 16 deletions docs/dev.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ with respect to modeling glacier dynamics and ice thickness inversions.
:maxdepth: 1
:caption: Contributing:

dev
contributing
citing

.. Indices and tables
Expand Down
43 changes: 24 additions & 19 deletions docs/install_pygem.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
(install_pygem_target)=
# Installing PyGEM
The Python Glacier Evolution Model has been packaged using Poetry and is hosted on the Python Package Index ([PyPI](https://pypi.org/project/pygem/)), such that all dependencies should install seamlessly. It is recommended that users create a [Anaconda](https://anaconda.org/) environment from which to install the model dependencies and core code.
# 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.

### Setup Conda Environment
Anaconda is a Python dependency management tool. An Anaconda (conda) environment is essentially a directory that contains a specific collection of installed packages. The use of environments reduces issues caused by package dependencies. It is recommended that users first create conda environment from which to install PyGEM and its dependencies (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). We recommend a conda environment with python >=3.10, <3.13.
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.
- [**development**](dev_install_target): this is the development version of PyGEM hosted on [GitHub](https://github.com/PyGEM-Community/PyGEM/tree/dev). It might contain new features and bug fixes, but is also likely to continue to change until a new release is made. This is the recommended option if you want to work with the latest changes to the code. Note, this installation options require [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) software to be installed on your computer.

A new conda environment can be created from the command line such as:
```
conda create --name <environment_name> python=3.12
```
**Copyright note**: PyGEM's installation instructions are modified from that of [OGGM](https://docs.oggm.org/en/stable/installing-oggm.html)

### PyPI installation
Ensure you've activated your PyGEM environment
```
conda activate <environment_name>
(stable_install_target)=
## Stable install
The simplest **stable** installation method is to use an environment file. Right-click and save PyGEM's recommended environment file from [this link](https://github.com/PyGEM-Community/PyGEM/tree/master/docs/pygem_env.yml).

From the folder where you saved the file, run `conda env create -f pygem_environment.yml`.
```{note}
By default the environment will be named `pygem`. A different name can be specified in the environment file.
```

Next, install PyGEM via [PyPI](https://pypi.org/project/pygem/):
(dev_install_target)=
## Development install
Install the [development version](https://github.com/PyGEM-Community/PyGEM/tree/dev) of PyGEM in your conda environment using pip:
```
pip install pygem
pip uninstall pygem
pip install git+https://github.com/PyGEM-Community/pygem/@dev
```

This will install all PyGEM dependencies within your conda environment, and set up PyGEM command line tools to run core model scripts.
If you intend to access and make your own edits to the model's source code, see the [contribution guide](contributing_pygem_target).

### Setup
Following installation, an initialization script should to be executed.
(setup_target)=
# Setup
Following installation, an initialization script should be executed.

The initialization script accomplishes two things:
1. Initializes the PyGEM configuration file *~/PyGEM/config.yaml*. If this file already exists, an overwrite prompt will appear.
Expand All @@ -35,5 +40,5 @@ Run the initialization script by entering the following in the terminal:
initialize
```

### Demonstration Notebooks
A series of accompanying Jupyter notebooks have been produces for demonstrating the functionality of PyGEM. These can be acquired and installed from [GitHub](https://github.com/PyGEM-Community/PyGEM-notebooks).
# Demonstration Notebooks
A series of accompanying Jupyter notebooks has been produced for demonstrating the functionality of PyGEM. These are hosted in the [PyGEM-notebooks repository](https://github.com/PyGEM-Community/PyGEM-notebooks).
6 changes: 6 additions & 0 deletions docs/pygem_environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: pygem
dependencies:
- python>=3.10,<3.13
- pip
- pip:
- pygem
8 changes: 4 additions & 4 deletions pygem/bin/op/duplicate_gdirs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import os
import shutil
# pygem imports
import pygem.setup.config as config
# check for config
config.ensure_config()
from pygem.setup.config import ConfigManager
# instantiate ConfigManager
config_manager = ConfigManager()
# read the config
pygem_prms = config.read_config()
pygem_prms = config_manager.read_config()

def main():
parser = argparse.ArgumentParser(description="Script to make duplicate oggm glacier directories - primarily to avoid corruption if parellelizing runs on a single glacier")
Expand Down
Loading