Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ad51f08
(doc): Update install instructions in README.md
abukowski21 Jun 29, 2026
39b9735
(deps): tidy up pyproject.toml dependencies
abukowski21 Jun 29, 2026
d81dff4
(test): Create GitHub CI test workflow
abukowski21 Jun 29, 2026
00112ff
(deps): Strip python-dateutil dependency, bump min python version
abukowski21 Jun 29, 2026
5c4bbef
(test): Install gfortran via conda on Windows runners, not MSYS2
abukowski21 Jun 29, 2026
2d4a0f1
(test): Activate conda env for Windows install test
abukowski21 Jun 29, 2026
b687acb
(test): Tweak how Windows activates & uses conda during install
abukowski21 Jun 29, 2026
09a0ceb
(test): Try forcing pip to use shorter paths on windows in CI workflow
abukowski21 Jun 29, 2026
6ebdcf3
(doc) bump version in README (00112ff7660cd)
abukowski21 Jun 29, 2026
47d578b
(doc) README.md whitespace around section headers
abukowski21 Jun 29, 2026
11fc40e
(doc): Update README Windows install instructions
abukowski21 Jun 29, 2026
82fc23d
(doc): Create contributing.md, placeholder mostly
abukowski21 Jun 29, 2026
6feabef
(doc/maint): Create changelog, update readme + contributing + changelog
abukowski21 Jun 29, 2026
d5e23af
(doc): update readme with info about editable pip-installs being broken
abukowski21 Jun 29, 2026
50818e9
(test): Move "tests/" to Examples, start drafting feature tests
abukowski21 Jun 29, 2026
8002b17
(test): Create functionality tests
abukowski21 Jun 29, 2026
931ce28
Update README and example plots
abukowski21 Jun 29, 2026
7ef7dc7
(test): Add tests to CI, update pyproject + contributing with pytest …
abukowski21 Jun 29, 2026
1ad7f63
(chores): Update changelog, CI test names, readme python version
abukowski21 Jun 29, 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
93 changes: 93 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Contributing Guidelines

Thank you for your interest in the project. Everything is still a work in progress and
your assistance/feedback will inform future development!

## Opening an issue

If you find a bug, want a new feature, or anything else, please create an issue.
Remember to:

- **Be descriptive.**
If you are reporting a bug, include instructions on how to replicate it.
If you had an installation error, include the exact steps you were trying & details on your system.
- **Search for relevant issues.**
Look through the open (and recently closed) issues to see if others have reported something similar.

## Testing

`glowpython2` is tested on Linux, MacOS and Windows.
Currently three Python versions are used (stable, latest, and experimental).

The tests are run as a GitHub action, where the source file & instructions are located in [.github/workflows/ci.yml](workflows/ci.yml)

### Installation for running tests

Because `glowpython2` uses meson-python as its build backend,
**editable installs (`pip install -e .`) do not work correctly for running the test suite**.
Data files required by the Fortran backend are not placed where the package expects them.
Use a regular install instead:

```bash
pip install .[test]
```

**After modifying Fortran source**, you must reinstall for changes to take effect:

```bash
pip install .
```

### Running tests locally

From the repo root:

```bash
pytest tests/
```

You may run an individual test file if the tests are taking too long.

### Test layout

- **`tests/test_examples.py`** — automatically runs every script in `Examples/` as a subprocess smoke test. No maintenance needed; new examples are picked up automatically.
- **`tests/test_no_precip.py`**, **`test_maxwellian.py`** — structure and physics assertions for the top-level GLOW functions.
- **`tests/test_iri.py`** — assertions for both `Iri90` and `Iri2020`.
- **`tests/test_msis.py`** — assertions for both `NrlMsis00` and `NrlMsis21`.
- **`tests/conftest.py`** — shared fixtures (`sample_time`, `sample_lat`, `sample_lon`).

### Adding or modifying tests

- **New example script**: drop a `.py` file in `Examples/` — it will be picked up by `test_examples.py` automatically.
- **New assertion test**: add a `test_*.py` file in `tests/`, or add a test function to an existing file. Use the fixtures from `conftest.py` for the standard time/location inputs.
- **Physics assertions** should check that outputs are physically reasonable (positive densities, sane temperature ranges, expected species present) rather than matching exact numerical values, so tests stay valid across minor model updates.

## Changelog

All notable changes should be recorded in `CHANGELOG.md` before a release is tagged.

**During development:** add entries under the `[Unreleased]` section at the top of `CHANGELOG.md` as you work. Use the appropriate subsection:

- **Added** — new features or capabilities
- **Changed** — changes to existing behavior
- **Fixed** — bug fixes
- **Removed** — removed features or APIs
- **Deprecated** — features that will be removed in a future release

**At release time:**
1. Rename `[Unreleased]` to `[x.y.z] - YYYY-MM-DD` matching the version tag you're about to create.
2. Add a new empty `[Unreleased]` section above it.
3. Tag the release in git: `git tag vx.y.z`.

**Example entry:**

```markdown
## [Unreleased]
### Added
- Support for custom altitude grids

### Fixed
- Incorrect electron density below 80 km under certain solar conditions
```

Do not list every commit — only changes a user of the library would care about. Trivial internal refactors, test updates, and CI fixes can be omitted.
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: CI

on:
push:
branches: [master, develop]
pull_request:
branches: [master]

jobs:
test:
name: Run tests (${{ matrix.os }}, Python ${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.11", "3.12", "3.14"]

steps:
- uses: actions/checkout@v4

- name: Set up Python (Linux/macOS)
if: runner.os != 'Windows'
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install gfortran (Linux)
if: runner.os == 'Linux'
run: sudo apt-get install -y gfortran

- name: Install gfortran (macOS)
if: runner.os == 'macOS'
run: brew install gcc

- name: Set up conda with Python (Windows)
if: runner.os == 'Windows'
uses: conda-incubator/setup-miniconda@v3
with:
miniforge-version: latest
python-version: ${{ matrix.python-version }}

- name: Create short temp directory (Windows)
if: runner.os == 'Windows'
run: New-Item -ItemType Directory -Force -Path C:\T | Out-Null

- name: Install gfortran + glowpython2 (Windows)
if: runner.os == 'Windows'
env:
TEMP: C:\T
TMP: C:\T
run: |
conda install -c conda-forge gfortran -y
conda run --no-capture-output pip install .[test]
conda run python -c "import glowpython2; print(glowpython2.__version__)"

- name: Install (Linux/macOS)
if: runner.os != 'Windows'
run: pip install .[test]

- name: Tests (Linux/macOS)
if: runner.os != 'Windows'
run: python -m pytest tests

- name: Tests (Windows)
# Running all tests on Windows for now...
# If the runtime starts getting too long, this can be changed to just one test
if: runner.os == 'Windows'
run: conda run --no-capture-output python -m pytest tests
# run: conda run --no-capture-output python -m pytest tests/test_no_precip.py
# ^^ If we just want to run one test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ OLDGLOW/
# Others
*.txt
*.png
!Examples/*.png
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Changelog

All notable changes to glowpython2 are documented here.

## [Unreleased]
### Added
- `CHANGELOG.md` with history migrated from README
- GitHub Actions CI workflow for Linux, macOS, and Windows
- Functionality test suite with `pytest`

### Changed
- `CONTRIBUTING.md` expanded with changelog workflow and guidelines
- Changelog section removed from `README.md`
- README install instructions updated for Windows and general clarity
- `python-dateutil` dependency removed; minimum Python version bumped
- `pyproject.toml` dependencies tidied
- Moved files from tests/ to Examples & updates README to use local versions of some images

### Fixed
- Windows install:
- gfortran now recommended to be installed via conda instead of MSYS2
- pip forced to use shorter paths to avoid path-length issues

## [0.0.3] - 2026-01-09
### Changed
- Dataset structure changed (**breaking**)

### Fixed
- Version bumped to 0.0.3

## [0.0.1] - 2025-11-01
### Added
- Initial release
56 changes: 56 additions & 0 deletions Examples/IriComparison.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python
"""
Compare IRI-1990 and IRI-2020 ion densities and temperatures.
"""
import matplotlib
import matplotlib.pyplot as plt
from datetime import datetime, UTC

from glowpython2 import Iri90
from glowpython2.utils import alt_grid
from iri20py import Iri2020

matplotlib.rcParams.update({'mathtext.fontset': 'cm'})
matplotlib.rc('font', **{'family': 'serif', 'serif': ['Times New Roman']})

time = datetime(2015, 12, 13, 10, 0, 0, tzinfo=UTC)
lat = 42.6
lon = -71.2
alt = alt_grid()

_, ds90 = Iri90().evaluate(time=time, lat=lat, lon=lon, alt=alt)
_, ds20 = Iri2020().evaluate(time=time, lat=lat, lon=lon, alt=alt)

fig, ax = plt.subplots(figsize=(8, 6), dpi=300)
tax = ax.twiny()

species = ['O+', 'O2+', 'N+', 'NO+']
descs = ['O^+', 'O_2^+', 'N^+', 'NO^+']
colors = ['r', 'g', 'b', 'm']
lines, labels = [], []

for spec, color, desc in zip(species, colors, descs):
l20, = ds20[spec].plot(y='alt_km', ax=ax, color=color)
l90, = ds90[spec].plot(y='alt_km', ax=ax, linestyle='--', color=color)
lines += [l20, l90]
labels += [f'IRI-20 ${desc}$', f'IRI-90 ${desc}$']

for ds, ls, label_te, label_ti in [
(ds20, '-', 'IRI-20 $T_e$', 'IRI-20 $T_i$'),
(ds90, '--', 'IRI-90 $T_e$', 'IRI-90 $T_i$'),
]:
l_te, = ds['Te'].plot(y='alt_km', ax=tax, color='k', linestyle=ls)
l_ti, = ds['Ti'].plot(y='alt_km', ax=tax, color='c', alpha=0.7, linestyle=ls)
lines += [l_te, l_ti]
labels += [label_te, label_ti]

ax.set_title('IRI-90 vs IRI-20')
ax.set_xscale('log')
ax.set_xlabel('Number Density [cm$^{-3}$]')
tax.set_xlabel('Temperature [K]')
ax.set_xlim(1e-3, None)
tax.set_xlim(100, None)
ax.legend(lines, labels, loc='upper left', fontsize='small')

plt.savefig('iri_comparison.png', dpi=300, bbox_inches='tight')
plt.show()
Loading
Loading