Skip to main content

Python wrapper for EPA's AERMOD air dispersion model

Project description

PyAERMOD

Tests Python 3.11+ License: MIT

Python wrapper for EPA's AERMOD atmospheric dispersion model.

PyAERMOD automates input file generation, model execution, output parsing, and result visualization — replacing manual text-file editing with a type-safe Python API.

Installation

pip install pyaermod             # core (input generation + output parsing)
pip install pyaermod[viz]        # + matplotlib/folium visualization
pip install pyaermod[geo]        # + geospatial export (GeoTIFF, Shapefile)
pip install pyaermod[gui]        # + NiceGUI app
pip install pyaermod[all]        # everything

For development:

git clone https://github.com/atmmod/pyaermod.git
cd pyaermod
pip install -e ".[dev,all]"

Quick Start

Generate AERMOD Input

from pyaermod.input_generator import (
    AERMODProject, ControlPathway, SourcePathway, ReceptorPathway,
    MeteorologyPathway, OutputPathway, PointSource, CartesianGrid,
    PollutantType, TerrainType,
)

control = ControlPathway(
    title_one="My Facility",
    pollutant_id=PollutantType.PM25,
    averaging_periods=["ANNUAL", "24"],
    terrain_type=TerrainType.FLAT,
)

sources = SourcePathway()
sources.add_source(PointSource(
    source_id="STACK1", x_coord=500.0, y_coord=500.0,
    base_elevation=10.0, stack_height=50.0, stack_temp=400.0,
    exit_velocity=15.0, stack_diameter=2.0, emission_rate=1.5,
))

receptors = ReceptorPathway()
receptors.add_cartesian_grid(CartesianGrid.from_bounds(
    x_min=0, x_max=2000, y_min=0, y_max=2000, spacing=100,
))

meteorology = MeteorologyPathway(
    surface_file="met_data.sfc", profile_file="met_data.pfl",
)
output = OutputPathway(receptor_table=True, max_table=True)

project = AERMODProject(control, sources, receptors, meteorology, output)
project.write("facility.inp")

Run AERMOD & Parse Results

from pyaermod.runner import run_aermod
from pyaermod.output_parser import parse_aermod_output

result = run_aermod("facility.inp")
results = parse_aermod_output(result.output_file)

df = results.get_concentrations("ANNUAL")
print(results.summary())

Parse POSTFILE Output

from pyaermod.postfile import read_postfile

# Auto-detects text vs binary format
post = read_postfile("postfile.out")
df = post.to_dataframe()

# Binary postfile with deposition data
dep = read_postfile("depo_post.out", has_deposition=True)
print(dep.to_dataframe()[["concentration", "dry_depo", "wet_depo"]])

Features

Source Types (10)

POINT, AREA, AREACIRC, AREAPOLY, VOLUME, LINE, RLINE, RLINEXT, BUOYLINE, OPENPIT

Advanced Modeling

  • Background concentrations — uniform, period-specific, or sector-dependent
  • Deposition — dry, wet, or combined for gas and particle emissions
  • NO2/SO2 chemistry — OLM, PVMRM, ARM2, GRSM with ozone data
  • Source groups — custom groupings with per-group PLOTFILE output
  • EVENT processing — date/receptor-specific analysis

Preprocessors

  • AERMET — meteorological data preprocessing (Stages 1-3)
  • AERMAP — terrain elevation extraction with DEM download pipeline

Analysis & Visualization

  • Output parsing to pandas DataFrames
  • POSTFILE parser for timestep-level results (text and binary formats)
  • Contour plots, interactive Folium maps, 3D surfaces, wind roses
  • Geospatial export: GeoTIFF, GeoPackage, Shapefile, GeoJSON

Validation & Automation

  • Input validation across all AERMOD pathways
  • Building downwash / BPIP integration (point, area, and volume sources)
  • Batch processing with parallel execution
  • Interactive NiceGUI app (pyaermod-app browser, pyaermod-desktop native window)

Project Structure

src/pyaermod/
    __init__.py          # Public API
    input_generator.py   # AERMOD input file generation (all source types)
    validator.py         # Configuration validation
    runner.py            # AERMOD subprocess execution
    output_parser.py     # Output file parsing
    postfile.py          # POSTFILE output parser
    visualization.py     # Matplotlib/Folium plots
    advanced_viz.py      # 3D surfaces, wind roses, animations
    aermet.py            # AERMET preprocessor wrapper
    aermap.py            # AERMAP input generation
    terrain.py           # DEM download + AERMAP pipeline
    geospatial.py        # Coordinate transforms, GIS export
    bpip.py              # Building downwash calculations
    gui_v2/              # NiceGUI app + pywebview desktop wrapper
tests/                   # 1383 tests, 98% coverage
examples/                # Example scripts and Jupyter notebooks
docs/                    # Architecture and quickstart guides

Requirements

  • Python >= 3.11
  • numpy, pandas (core)
  • AERMOD executable (free from EPA SCRAM)

Documentation

License

MIT

Disclaimer

PyAERMOD is a wrapper around AERMOD, not a reimplementation. It uses official EPA binaries for all calculations and maintains regulatory acceptance. Always validate results against EPA test cases for your specific use case.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyaermod-2.0.0.tar.gz (468.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyaermod-2.0.0-py3-none-any.whl (198.7 kB view details)

Uploaded Python 3

File details

Details for the file pyaermod-2.0.0.tar.gz.

File metadata

  • Download URL: pyaermod-2.0.0.tar.gz
  • Upload date:
  • Size: 468.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyaermod-2.0.0.tar.gz
Algorithm Hash digest
SHA256 7e2c56ddf39274fd05bd21ab85d2c8664ec4b03e92c6c1f968afa1d4b10e9603
MD5 835caf7075dd7023f6a0f8be9251bc3b
BLAKE2b-256 51edce390ba3ef153dc431974e44053a000b8a3a3b97ee5c5687c79830cda0fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaermod-2.0.0.tar.gz:

Publisher: publish.yml on atmmod/pyaermod

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyaermod-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: pyaermod-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 198.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyaermod-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3b56554e5b2a42c25dadcf826588ed89e108d3e20f60ff67f56cab31471460c5
MD5 fe3ab1580f34cb8defd83e9e99b531f2
BLAKE2b-256 625806ea4046596348633b196a3cadbd480540d1943a76a2fa4cb312bb8b2f86

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyaermod-2.0.0-py3-none-any.whl:

Publisher: publish.yml on atmmod/pyaermod

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page