[![DOI](https://zenodo.org/badge/1026267765.svg)](https://zenodo.org/badge/latestdoi/1026267765)
# GlowPython2
The FORTRAN GLobal airglOW ([GLOW](https://github.com/NCAR/GLOW)) Model in Python &ge; 3.9.

A Fortran compiler is **REQUIRED**.

<b>Note:</b> This version uses `meson` and `ninja` as the build system, and does not rely on `distutils`,
and is Python 3.12 compatible.

<b>This library also allows parallelization of model evaluation using the [multiprocessing](https://docs.python.org/3/library/multiprocessing.html) module.</b>

Additionally, the `GlowModel` class exposes complete control over model evaluation, which is divided
into the following fundamental steps:
1. `initialize`: Set the altitude, energy grids and solar flux model (Hinteregger, EUVAC, custom).
2. `setup`: Set the model up for evaluation, specifying time, location, and optionally geomagnetic parameters. If geomagnetic parameters are not specified, they are retrieved using [`geomagdata`](https://pypi.org/project/geomagdata/).
3. `precipitation` (optional): Evaluate the energy and flux of precipitating electrons (Maxwellian or monoenergetic).
4. `atmosphere`: Evaluate the neutral atmosphere (MSISE-00) and ionosphere (IRI-90).
5. `radtrans`: Evaluate the GLOW radiative transfer model to calculate volume emission rates and ion composition.
6. `result`: Retrieve the model output as a [xarray.Dataset](http://xarray.pydata.org/en/stable/generated/xarray.Dataset.html).

<b>Note:</b> Between the `atmosphere` and `radtrans` steps, the intermediate dataset can be accessed using the `result` method by passing `copy=False`. This returns a reference to the internal dataset. Modifying the dataset in place allows for modifying the atmosphere and ionosphere presented to the `radtrans` step.

## Prerequisites
A Fortran compiler is **REQUIRED**.
### Linux
Ensure that you have the following development packages installed:
- `build-essential` (for `gcc`, `g++`, `make`, etc.)
- `gfortran` (Fortran compiler)
### macOS
Ensure that you have the Xcode Command Line Tools installed. You can install them by running:
```sh
xcode-select --install
```
Install [`homebrew`](https://brew.sh/) if you haven't already, and then install `gfortran`:
```sh
brew install gfortran
```
<b>Note:</b> For macOS Big Sur and above, you may need to add the following line to your environment script (`~/.zshrc` if using ZSH, or the relevant shell init script):
```sh
export LIBRARY_PATH="$LIBRARY_PATH:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib"
```
Then reopen the terminal. This fixes the issue where `-lSystem` fails for `gfortran`.
 
### Windows (amd64 or x86_64 targets)
On Windows, MSYS2 is the preferred distribution for installing the Fortran compiler toolchain (for GNU Compiler Collection).
- Install [MSYS2](https://www.msys2.org/).
  Note the directory where MSYS2 was installed (defaults to `C:\msys64`) [referred to as `MSYS_INSTALL_DIR`].
  It is not recommended to change this directory.
- Launch the MSYS2 terminal (MSYS2 MSYS application on the start menu)
- Update MSYS2 environment (assuming fresh install):
  ```sh
  pacman -Syu # Restart the terminal
  pacman -Su  # Update packages
  ```
- Install the GNU Compiler Collection:
  ```sh
  pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-gcc-fortran
  ```
- Add `MSYS_INSTALL_DIR\ucrt64\bin` (defaults to `C:\msys64\ucrt64\bin`) to `PATH`:
  - Search for `env` in the Start menu,
  - Select "Edit the system environment variables",
  - Click "Environment Variables",
  - Double click 'Path' under 'User variables for USER'
  - Click "New"
  - Type in, or paste the full path to `ucrt64\bin` (defaults to `C:\msys64\ucrt64\bin`)
  - Click "Ok" on the environment variable windows to save the changes.
- Continue with installation instructions for the Python packages below, in a new, regular terminal (e.g. Command Prompt or PowerShell with Python installed).

> [!NOTE] 
> Change the toolchain names accordingly for Windows arm64.
> This platform has not been tested and is not officially supported.

## Installation
Direct installation using pip:
```sh
pip install glowpython2
```

Install from source repository:
```sh
pip install glowpython2@git+https://github.com/sunipkm/glowpython2
```

Requires (and installs) [geomagdata](https://pypi.org/project/geomagdata/) for timezone aware geomagnetic parameter retrieval.
## Usage
### Command-line examples
* `Glow2Maxwellian`: asdf
* `Glow2NoPrecip`: asdf

### Pre-defined examples

* [`Maxwellian.py`](https://raw.githubusercontent.com/sunipkm/glowpython2/refs/heads/master/Examples/Maxwellian.py): Maxwellian precipitation, specify Q (flux) and E0 (characteristic energy).
* [`NoPrecipitation.py`](https://raw.githubusercontent.com/sunipkm/glowpython2/refs/heads/master/Examples/NoPrecipitation.py): No precipitating electrons.
* [`test_glow.py`](https://raw.githubusercontent.com/sunipkm/glowpython2/refs/heads/master/tests/test_glow.py): Compares GLOW results between `glowpython` and `glowpython2` modules without precipitation, as well as with NRLMSISE-2.1 atmosphere and IRI-2020 ionosphere.

These examples are also available on the command line: `Glow2Maxwellian` and `Glow2NoPrecip`.

### Using `glowpython2` module
In Python source code, import the module and call the `maxwellian` function:
```python
import glowpython2 as glow

iono = glow.maxwellian(time, glat, glon, Nbins, Q, Echar)
```

Read the module documentation for more information.

### Example Plots
| Densities | Temperatures |
| :---: | :---: |
| ![Comparison of [`glowpython`](https://pypi.org/project/glowpython/) and `glowpython2` densities with no precipitation.](https://raw.githubusercontent.com/sunipkm/glowpython2/refs/heads/master/tests/glow_den.png) | ![Comparison of [`glowpython`](https://pypi.org/project/glowpython/) and `glowpython2` temperatures with no precipitation.](https://raw.githubusercontent.com/sunipkm/glowpython2/refs/heads/master/tests/glow_temp.png) |

| Volume Emission Rates |
| :---: |
| ![Comparison of [`glowpython`](https://pypi.org/project/glowpython/) and `glowpython2` volume emission rates with no precipitation.](https://raw.githubusercontent.com/sunipkm/glowpython2/refs/heads/master/tests/glow_ver.png) |
### Options
GlowPython2 has a few configuration options at runtime - 
- Magnetic field model: Use `POGO68` for GLOW 0.98 behavior, `IGRF14` for the [IGRF-14](https://www.ncei.noaa.gov/products/international-geomagnetic-reference-field) model (extracted from [IRI-2020](https://irimodel.org/)).
- Atmosphere and ionosphere model: Use `MSIS00_IRI90` for GLOW 0.98 behavior, `MSIS21_IRI20` for [NRLMSIS 2.1](https://map.nrl.navy.mil/map/pub/nrl/NRLMSIS/NRLMSIS2.1/) and [IRI-2020](https://irimodel.org/).
- New coefficients from [ModGLOW implementation](https://agupubs.onlinelibrary.wiley.com/doi/full/10.1002/2017JA025026): Set `newcoeffs` to `True`. This updates the reaction rates with data from newer publications.
### Model Output
The returned output is a
[xarray.Dataset](http://xarray.pydata.org/en/stable/generated/xarray.Dataset.html)
containing outputs from GLOW:
- Coordinates:
    - `alt_km`: Altitude grid (km)
    - `energy`: Energy grid (eV)
    - `state`: Neutral/Ionic excitation states (string)
    - `wavelength`: Wavelength of emission features in Angstrom (string). Represented as strings to accommodate the LBH band.
    - `tecscale`: TEC scale factor (float)
- Data:
    - Dimension (`alt_km`):
        - `O`: Neutral atomic oxygen density (cm^-3)
        - `O2`: Neutral molecular oxygen density (cm^-3)
        - `N2`: Neutral molecular nitrogen density (cm^-3)
        - `NO`: Neutral nitric oxide density (cm^-3)
        - `NS`: N(4S) density (cm^-3)
        - `ND`: N(2D) density (not used, set to zero) (cm^-3)
        - `NeIn`: Electron density (IRI-90), input to GLOW radiative transfer model. (cm^-3)
        - `O+`: Ion atomic oxygen (4S) density (cm^-3)
        - `O+(2P)`: Ion atomic oxygen (2P) density (cm^-3)
        - `O+(2D)`: Ion atomic oxygen (2D) density (cm^-3)
        - `O2+`: Ion molecular oxygen density (cm^-3)
        - `N+`: Ion molecular nitrogen density (cm^-3)
        - `N2+`: Ion molecular nitrogen density (cm^-3)
        - `NO+`: Ion nitric oxide density (cm^-3)
        - `N2(A)`: Molecular nitrogen (GLOW) density (cm^-3)
        - `N(2P)`: N(2P) density (cm^-3)
        - `N(2D)`: N(2D) density (cm^-3)
        - `O(1S)`: O(1S) density (cm^-3)
        - `O(1D)`: O(1D) density (cm^-3)
        - `NeOut`: Electron density (calculated below 200 km for `kchem=4` using GLOW model, cm^-3) 
        - `Te`: Electron temperature (K)
        - `Ti`: Ion temperature (K)
        - `Tn`: Neutral temperature (K)
        - `ionrate`: Ionization rate (s^-1)
        - `pederson`: Pederson conductivity (S/m)
        - `hall`: Hall conductivity (S/m)
        - `eHeat`: Ambient electron heating rate (eV/cm^3/s)
        - `Tez`: Total energetic electron energy deposition (eV/cm^3/s)
    - Dimension (`alt_km`, `wavelength`):
        - `ver`: Volume emission rate of various features (1/cm^3/s)
    - Dimension (`alt_km`, `state`):
        - `production`: Production rate of various species  (1/cm^3/s)
        - `loss`: Fractional loss rate of various species (1/s)
    - Dimension (`energy`):
        - `precip`: Precipitation flux (cm^-2/s/eV)
- Attributes:
    - `time`: Time of evaluation (ISO 8601 formatted string)
    - `glatlon`: Geographic latitude and longitude of evaluation (degrees)
    - `Q`: Flux of precipitating electrons (erg/cm^2/s)
    - `Echar`: Characteristic energy of precipitating electrons (eV)
    - `iscale`: Solar flux model. 0: Hinteregger, 1: EUVAC
    - `xuvfac`: XUV enhancement factor. 
    - `itail`: Low energy tail enabled/disabled. 0: disabled, 1: enabled
    - `fmono`: Monoenergetic energy flux (erg/cm^2).
    - `emono`: Monoenergetic characteristic energy (keV).
    - `jlocal`: Local calculation only (disable electron transport).
    - `kchem`: GLOW chemistry level.

All available keys carry unit and description.

# Acknowledgement
Sincerest gratitude to Dr. Stan Solomon for developing, and open-sourcing the GLOW model.

We are very thankful to Guy Gribbs for providing the [`gchem_modglow.f90`](https://raw.githubusercontent.com/sunipkm/glowpython2/refs/heads/master/src/GLOW/gchem_modglow.f90) file with the modified reaction rate coefficients for the `GCHEM` subroutine. His prompt response saved us many hours of work.

# Citation
If you use this code in your work, please cite the repository:
```bibtex
@software{sunipkm_glowpython2_2025,
  author       = {Sunip K. Mukherjee},
  title        = {{glowpython2}: A Python Wrapper for the GLOW Model},
  month        = nov,
  year         = 2025,
  publisher    = {GitHub},
  version      = {v0.0.1},
  doi          = {https://zenodo.org/badge/latestdoi/1026267765},
  url          = {https://github.com/sunipkm/glowpython2},
}
```

# Changelog
- <b>2026-01-09</b>
  - Version bumped to 0.0.3
  - BREAKING: Dataset structure changed. 
