Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
6f419b6
updated compactifier notebook to the latest version
ray-chew May 13, 2024
8749a22
icon_usgs_test.py: checked output, it runs
ray-chew May 13, 2024
2a117af
icon grid with merit data works
ray-chew May 13, 2024
52a446d
ICON regional MERIT run with CSAM implemented
ray-chew May 13, 2024
39ca7e4
added ICON regional run parameters file
ray-chew May 13, 2024
7305202
moved (kks,lls) computation from physics.py to var.py entirely
ray-chew May 13, 2024
969bb3a
updated .gitignore file
ray-chew May 13, 2024
6f8171d
implemented NetCDF4 writer class; outputs data structure according to…
ray-chew May 13, 2024
c1a8739
utils.py:pick_cell is required in the prepare_orog notebook
ray-chew May 14, 2024
7dbb127
latest prepare_orog notebook
ray-chew May 14, 2024
df9274f
updated io.py to support reading of REMA datasets (#5)
ray-chew May 14, 2024
034cda8
remove hard-coded paths and filenames
ray-chew May 14, 2024
5ac0be0
minor changes to vis.plotter and wrappers.diagnostics
ray-chew May 14, 2024
4d1fa53
intermediate commit for global run script
ray-chew May 14, 2024
78ee0b6
made all imports relative; package now works with pip install
ray-chew May 20, 2024
eaf1a83
improved src.delaunay.get_land_cells documentation
ray-chew May 20, 2024
82bc4f5
ICON merit global run script seems to give sensible results now
ray-chew May 20, 2024
1d815da
updated relative import paths in diagnostics.py
ray-chew May 20, 2024
ef2d8ae
updated global ICON script to latest machinery
ray-chew May 20, 2024
d87c0d6
icon_merit_global: removed commented code
ray-chew May 20, 2024
2d37f93
icon_merit_global: fixed bug in the is_land indexing
ray-chew May 21, 2024
b53b06c
intermediate commit for parallel runs
ray-chew May 21, 2024
5ee9e01
parallel run seems to work now
ray-chew May 22, 2024
ab1b992
updated icon_merit_regional to latest imports
ray-chew May 22, 2024
fe6cdf8
this is an interim commit with parallelisation switched off
ray-chew May 23, 2024
dbf7915
intermediate commit for robust MERIT I/O across E-W split
ray-chew May 27, 2024
e04e117
the I/O for MERIT REMA seems to work for tricky grid cells now
ray-chew May 27, 2024
f2b9e9a
I/O routine survived till approx. 15500/21000 grid cells; updated plo…
ray-chew May 28, 2024
fe661f6
intermediate commit before tackling discrepancies in MERIT and REMA l…
ray-chew May 29, 2024
e03aefd
i/o routine now works for all cells on the ICON R2B4 grid
ray-chew Jun 11, 2024
0fd44ea
changed dask delayed to dask bag
ray-chew Jun 11, 2024
405d3aa
there is a memory leak somewhere; I think it's because I am not closi…
ray-chew Jun 11, 2024
53b4831
chunked the grid cells and writing output for each chunk
ray-chew Jun 12, 2024
46fcc26
coarse grain cells below 85 degrees south by five additional times
ray-chew Jun 18, 2024
b8bb8a3
fixed bug with parallel iteration over last chunk
ray-chew Jun 19, 2024
155bf80
wrote a simple consolidator script for the chunked outputs
ray-chew Jun 19, 2024
caeef5e
Generate ICON runs
ray-chew Oct 21, 2025
a9e6c3c
Gitignored some more stuff
ray-chew Oct 21, 2025
1bad488
(#3) Made pyCSA structure pip-installable
ray-chew Oct 21, 2025
e61afa8
(#10) Added simple tests
ray-chew Oct 21, 2025
0109d57
Updated package name to CSA everywhere
ray-chew Oct 21, 2025
9c1ba3c
(#7) Add support for ETOPO 15 arc sec
ray-chew Oct 22, 2025
0dfc1d4
(#7) Verified support for ETOPO inputs
ray-chew Oct 22, 2025
cf96e3e
(#13) Added test for MERIT edge cases
ray-chew Oct 22, 2025
b4a3fe9
(#3) More cleaning up and restructuring
ray-chew Oct 22, 2025
614cfe1
(#3) Fixed local_paths import
ray-chew Oct 23, 2025
e8f424b
(#11) Open NetCDFs are cached
ray-chew Oct 23, 2025
9290e9f
(#7, #13) Added test for parallel ETOPO runs with ICON grid
ray-chew Oct 23, 2025
a323620
(#11) First attempt at some optimisation
ray-chew Oct 23, 2025
2b5a169
(#11, #13) Buffer pool for efficient memory handling
ray-chew Oct 23, 2025
f47b0c1
Fixed bug in lin_reg module
ray-chew Oct 23, 2025
4d4b622
(#13) Getting closer to global ETOPO runs
ray-chew Oct 23, 2025
9501be3
(#13) Testing ETOPO global ICON runs
ray-chew Oct 23, 2025
cde6624
(#13) Chunking by NetCDF outputs
ray-chew Oct 23, 2025
6fd7d98
(#8) Attempt at improving planar projection
ray-chew Oct 24, 2025
41c47b1
(#8, #13) Validated global run with centered projection
ray-chew Oct 24, 2025
68cec16
Restructured tests
ray-chew Oct 24, 2025
550d1d5
(#7, #8) Fixed bugs in ETOPO planar projection
ray-chew Oct 24, 2025
f3ec037
(#3) Updated some straggler imports
ray-chew Oct 24, 2025
8a008a0
(#17) Mask out elevation below -200m
ray-chew Oct 24, 2025
4dde4a6
(#18) Implement dynamic workers and memory allocation
ray-chew Oct 25, 2025
1d85321
(#19) Added sanity check for loaded topography
ray-chew Oct 25, 2025
d05ebe8
(#14) Added logging function
ray-chew Oct 25, 2025
ad1a4cc
(#13) Added hardware specific configurations
ray-chew Oct 25, 2025
0f7759e
(#15) Fresh HPC install
ray-chew Oct 25, 2025
35ad5ac
(#13) Threadsafe I/O support
ray-chew Oct 26, 2025
37b6f10
(#13) Resolve bug in diagnostic plotter
ray-chew Oct 27, 2025
e6a6a26
(#13) If only 1 worker, use all available memory.
ray-chew Oct 27, 2025
84ef0a3
(#13) Added outputs merge and verification
ray-chew Oct 30, 2025
e3bb690
(#25) Add cell_area metadata to outputs and merge pipeline
ray-chew May 2, 2026
6373fd8
(#26) Make HPC run restartable and HDF5-safe
ray-chew May 2, 2026
7d0b30e
(#27) Add tile_cache module for parallel topography access
ray-chew May 2, 2026
5f75717
(#28) Add HPC SLURM submit and operational scripts
ray-chew May 2, 2026
7b9c051
(#22) Stub cartopy in tests/conftest.py when not installed
ray-chew May 11, 2026
fdad227
(#23) Add ETOPO support to TopographyTileCache
ray-chew May 11, 2026
494c87b
(#24) Wire TopographyTileCache into the ICON+ETOPO main loop
ray-chew May 12, 2026
5e6c6ca
(#30) Blacked
ray-chew May 12, 2026
7e550b8
(#30) Replace documentation.yml with ci.yml; add black format check
ray-chew May 12, 2026
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
59 changes: 59 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: CI Workflow

on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:

permissions:
contents: write

jobs:
format-check:
name: Run Black Formatter
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install Black
run: pip install black==26.3.0

- name: Run Black
run: black --check .

docs:
name: Build Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ConorMacBride/install-package@v1
with:
apt: libgeos-dev graphviz
- uses: actions/setup-python@v5
with:
python-version: "3.10.5"
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install sphinx furo sphinx-changelog
- name: Sphinx build
run: |
sphinx-build docs/source _build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
with:
publish_branch: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: _build/
force_orphan: true
33 changes: 0 additions & 33 deletions .github/workflows/documentation.yml

This file was deleted.

17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@
*.pdf
*.png
*.json
*.bat
*.log
*.egg-info
*.swp
*.bak

/docs/build/*
.VSCodeCounter/*
/notebooks/*
/preprint/*
/poster/*
*submission/*
manuscript/*
first_revision/*
outputs/*
local_archive/*

# Local configuration (never commit!)
pycsa/local_paths.py
setup_paths_local.sh
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<p align="center">
<a href="https://ray-chew.github.io/pyCSAM/index.html">
<img alt="CSAM Logo" src="https://ray-chew.github.io/pyCSAM/_static/logo.png">
<a href="https://ray-chew.github.io/pyCSA/index.html">
<img alt="CSA Logo" src="https://ray-chew.github.io/pyCSA/_static/logo.png">
</a>
</p>

<h2 align="center">Constrained Spectral Approximation Method</h2>
<h2 align="center">Constrained Spectral Approximation</h2>


<p align="center">
<a href="https://github.com/ray-chew/pyCSAM/actions/workflows/documentation.yml">
<img alt="GitHub Actions: docs" src=https://img.shields.io/github/actions/workflow/status/ray-chew/pyCSAM/documentation.yml?logo=github&label=docs>
<a href="https://github.com/ray-chew/pyCSA/actions/workflows/documentation.yml">
<img alt="GitHub Actions: docs" src=https://img.shields.io/github/actions/workflow/status/ray-chew/pyCSA/documentation.yml?logo=github&label=docs>
</a>
<a href="https://www.gnu.org/licenses/gpl-3.0">
<img alt="License: GPL v3" src=https://img.shields.io/badge/License-GPLv3-blue.svg>
Expand All @@ -20,7 +20,7 @@
</p>


The Constrained Spectral Approximation Method (CSAM) is a physically sound and robust method for approximating the spectrum of subgrid-scale orography. It operates under the following constraints:
The Constrained Spectral Approximation (CSA) method is a physically sound and robust method for approximating the spectrum of subgrid-scale orography. It operates under the following constraints:

* Utilises a limited number of spectral modes (no more than 100)
* Significantly reduces the complexity of physical terrain by over 500 times
Expand All @@ -32,15 +32,15 @@ This method is primarily used to represent terrain for weather forecasting purpo

---

**[Read the documentation here](https://ray-chew.github.io/pyCSAM/index.html)**
**[Read the documentation here](https://ray-chew.github.io/pyCSA/index.html)**

---

## Requirements

See [`requirements.txt`](https://github.com/ray-chew/pyCSAM/blob/main/requirements.txt)
See [`requirements.txt`](https://github.com/ray-chew/pyCSA/blob/main/requirements.txt)

> **NOTE:** The Sphinx dependencies can be found in [`docs/conf.py`](https://github.com/ray-chew/pyCSAM/blob/main/docs/source/conf.py).
> **NOTE:** The Sphinx dependencies can be found in [`docs/conf.py`](https://github.com/ray-chew/pyCSA/blob/main/docs/source/conf.py).


## Usage
Expand All @@ -51,17 +51,17 @@ Fork this repository and clone your remote fork.

### Configuration

The user-defined input parameters are in the [`inputs`](https://github.com/ray-chew/pyCSAM/tree/main/inputs) subpackage. These parameters are imported into the run scripts in [`runs`](https://github.com/ray-chew/pyCSAM/tree/main/runs).
The user-defined input parameters are in the [`inputs`](https://github.com/ray-chew/pyCSA/tree/main/inputs) subpackage. These parameters are imported into the run scripts in [`runs`](https://github.com/ray-chew/pyCSA/tree/main/runs).

### Execution

A simple setup can be found in [`runs.idealised_isosceles`](https://github.com/ray-chew/pyCSAM/blob/main/runs/idealised_isosceles.py). To execute this run script:
A simple setup can be found in [`runs.idealised_isosceles`](https://github.com/ray-chew/pyCSA/blob/main/runs/idealised_isosceles.py). To execute this run script:

```console
python3 ./runs/idealised_isosceles.py
```

However, the codebase is structured such that the user can easily assemble a run script to define their own experiments. Refer to the documentation for the [available APIs](https://ray-chew.github.io/pyCSAM/api.html).
However, the codebase is structured such that the user can easily assemble a run script to define their own experiments. Refer to the documentation for the [available APIs](https://ray-chew.github.io/pyCSA/api.html).

## License

Expand Down
6 changes: 3 additions & 3 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@

# -- Project information -----------------------------------------------------

project = "CSAM"
copyright = "2024, Ray Chew, Stamen Dolaptchiev, Maja-Sophie Wedel, Ulrich Achatz"
author = "Ray Chew, Stamen Dolaptchiev, Maja-Sophie Wedel, Ulrich Achatz"
project = "CSA"
copyright = "2024, Ray Chew"
author = "Ray Chew"

# The full version, including alpha/beta/rc tags
release = "v0.95.1"
Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CSAM's Home
CSA's Home
===========

.. toctree::
Expand All @@ -19,7 +19,7 @@ CSAM's Home



This page documents the codebase for the Constrained Spectral Approximation Method (CSAM). CSAM is a physically sound and robust method for approximating the spectrum of subgrid-scale orography. It operates under the following constraints:
This page documents the codebase for the Constrained Spectral Approximation Method (CSA). CSA is a physically sound and robust method for approximating the spectrum of subgrid-scale orography. It operates under the following constraints:

* Utilises a limited number of spectral modes (no more than 100)
* Significantly reduces the complexity of physical terrain by over 500 times
Expand Down
2 changes: 1 addition & 1 deletion docs/source/modules/runs.icon_usgs_test.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
runs.icon_usgs_test
===================

Run script for CSAM experiments involving the ICON grid and the USGS GMTED 2010 orographic dataset.
Run script for CSA experiments involving the ICON grid and the USGS GMTED 2010 orographic dataset.



Expand Down
12 changes: 6 additions & 6 deletions docs/source/quick_start.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Quickstart
==========
A quick and dirty guide to using the CSAM codebase
A quick and dirty guide to using the CSA codebase

Requirements
^^^^^^^^^^^^
Expand All @@ -13,9 +13,9 @@ To run the code, make sure the following packages are installed, preferably in a

Overview
^^^^^^^^
The CSAM codebase is structured modularly, see :numref:`structure` for a graphical overview.
The CSA codebase is structured modularly, see :numref:`structure` for a graphical overview.

The package :mod:`wrappers` provides interfaces to the core code components in :mod:`src` and :mod:`vis`. For example, it defines the First and Second Approximation steps in the CSAM algorithm and applies the tapering of the physical data. Refer to the :doc:`APIs <api>` for more details.
The package :mod:`wrappers` provides interfaces to the core code components in :mod:`src` and :mod:`vis`. For example, it defines the First and Second Approximation steps in the CSA algorithm and applies the tapering of the physical data. Refer to the :doc:`APIs <api>` for more details.

Helper functions and data structures are provided for the processing of user-defined topographies (:mod:`src.var.topo`), grids (:mod:`src.var.grid`), and input parameters (:mod:`src.var.params`).

Expand All @@ -24,8 +24,8 @@ These *building blocks* are the assembled for different kinds of experiments in
.. graphviz::
:align: center
:name: structure
:alt: CSAM program structure
:caption: CSAM program structure
:alt: CSA program structure
:caption: CSA program structure

digraph {
graph [
Expand Down Expand Up @@ -209,4 +209,4 @@ Alternatively, the run script could be executed via ``ipython``.

.. note::

The development of the CSAM codebase frontend is currently ongoing. The current design approach of the program structure aims to simplify debugging and diagnostics using an ``ipython`` environment.
The development of the CSA codebase frontend is currently ongoing. The current design approach of the program structure aims to simplify debugging and diagnostics using an ``ipython`` environment.
96 changes: 96 additions & 0 deletions examples/etopo_loader_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"""
Example script demonstrating how to use the ETOPO 2022 15 arc-second loader

This script shows how to:
1. Set up parameters for ETOPO data loading
2. Load a regional topography dataset
3. Apply coarse-graining for different resolutions
"""

import numpy as np
from pycsa.core import io, var


class params:
"""Simple parameter class for ETOPO loading"""

def __init__(self):
# Path to ETOPO data directory (must end with /)
self.path_etopo = "/home/ray/git-projects/spec_appx/data/etopo_15s/"

# Define region of interest [lat_min, lat_max]
self.lat_extent = [30.0, 45.0]

# Define region of interest [lon_min, lon_max]
self.lon_extent = [-120.0, -105.0]

# Coarse-graining factor (1 = no coarse-graining, 2 = 2x2 average, etc.)
# ETOPO 15" has ~3600 points per 15 degrees, so coarse-graining is useful
# etopo_cg = 2 -> ~30" resolution
# etopo_cg = 4 -> ~60" resolution (1 arc-minute)
# etopo_cg = 8 -> ~120" resolution (2 arc-minutes)
self.etopo_cg = 1 # Default: no coarse-graining


# Example 1: Load high-resolution data (15 arc-seconds, no coarse-graining)
print("Example 1: Loading high-resolution ETOPO data...")
params1 = params()
params1.etopo_cg = 1
cell1 = var.topo_cell()

loader1 = io.ncdata.read_etopo_topo(cell1, params1, verbose=True)
print(f"Loaded: {len(cell1.lat)} x {len(cell1.lon)} = {cell1.topo.shape}")
print(f"Lat range: {cell1.lat.min():.4f} to {cell1.lat.max():.4f}")
print(f"Lon range: {cell1.lon.min():.4f} to {cell1.lon.max():.4f}")
print(f"Elevation range: {cell1.topo.min():.1f} to {cell1.topo.max():.1f} meters")
print()


# Example 2: Load with 4x coarse-graining (~60" resolution)
print("Example 2: Loading with 4x coarse-graining...")
params2 = params()
params2.etopo_cg = 4
cell2 = var.topo_cell()

loader2 = io.ncdata.read_etopo_topo(cell2, params2)
print(f"Loaded: {len(cell2.lat)} x {len(cell2.lon)} = {cell2.topo.shape}")
print(f"Data reduction factor: {cell1.topo.size / cell2.topo.size:.1f}x")
print()


# Example 3: Load a small region
print("Example 3: Loading a small region (35-37°N, -115 to -110°W)...")
params3 = params()
params3.lat_extent = [35.0, 37.0]
params3.lon_extent = [-115.0, -110.0]
params3.etopo_cg = 1
cell3 = var.topo_cell()

loader3 = io.ncdata.read_etopo_topo(cell3, params3)
print(f"Loaded: {len(cell3.lat)} x {len(cell3.lon)} = {cell3.topo.shape}")
print(f"Elevation range: {cell3.topo.min():.1f} to {cell3.topo.max():.1f} meters")
print()


# Example 4: Cross-dateline region (if needed)
print("Example 4: Region spanning across dateline...")
params4 = params()
params4.lat_extent = [40.0, 50.0]
params4.lon_extent = [170.0, -170.0] # Crosses dateline
params4.etopo_cg = 8
cell4 = var.topo_cell()

try:
loader4 = io.ncdata.read_etopo_topo(cell4, params4)
print(f"Loaded: {len(cell4.lat)} x {len(cell4.lon)} = {cell4.topo.shape}")
except Exception as e:
print(f"Note: Dateline crossing may need verification: {e}")
print()


print("Done! All loaders completed successfully.")
print("\nUsage tips:")
print('- Set etopo_cg = 1 for full 15" resolution (very high-res!)')
print('- Set etopo_cg = 4 for ~60" (~1.8 km at equator)')
print('- Set etopo_cg = 8 for ~120" (~3.6 km at equator)')
print("- Coarse-graining reduces memory and speeds up processing")
3 changes: 1 addition & 2 deletions inputs/archive/debug_run.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""User-defined parameters used in the debugger
"""
"""User-defined parameters used in the debugger"""

import numpy as np
from src import var
Expand Down
1 change: 0 additions & 1 deletion inputs/archive/lam_alaska_pmf_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import matplotlib.pyplot as plt
import pandas as pd


# %%
pmf_diffs = [
-0.0652774741607357,
Expand Down
Loading
Loading