A Python library or procesing CALPUFF (version > 7.2.1) output files
This library is capable of:
- Read CALPUFF output files such as
CONC.DAT - Read
CALMET.DATmeteorological files - Quick inspection of metadata,
- Simple matplotlib animations for concentration and wind fields.
External Python dependencies:
numpymatplotlib
- calpost/calpuff_reader.py CALPUFF output reader and concentration animation
- calpost/calmet_reader.py CALMET reader and wind animation
- calpost/utils.py Shared binary/parsing helpers
This repository is not packaged on PyPI. Use it directly from the repo root or add the repo parent directory to PYTHONPATH.
Example:
pip install numpy matplotlibThen run Python from the directory that contains the calpost package:
cd /path/to/calpuff-post
python3from calpost import CalpuffOutput, CalmetDatasetfrom calpost import CalpuffOutput
puff = CalpuffOutput.read("CONC.DAT")
print(puff.info())Available methods and properties:
CalpuffOutput.read(path)puff.info()puff.get_coordinates()puff.get_data(specie)puff.get_2d_field(specie)puff.get_gridded_data(specie)puff.get_discrete_data(specie)puff.get_time_bounds()puff.get_time_avg_max(specie, interval, rank=1)puff.plot_concentration_animation(...)puff.nt
from calpost import CalmetDataset
met = CalmetDataset.read("calmet.dat")
print(met.info())Available methods and properties:
CalmetDataset.read(path)met.info()met.get_time_bounds()met.get_static_field(label)met.get_2d_field(label)met.get_3d_field(label, level=None)met.plot_wind_animation(...)met.nx,met.ny,met.nz,met.nt
from calpost import CalpuffOutput
puff = CalpuffOutput.read("CONC.DAT")
print(puff.info())
specie = puff.species[0]
conc = puff.get_data(specie)
print(conc.shape) # [time, y, x] for gridded receptorsX, Y = puff.get_coordinates()For gridded receptors, X and Y are meshgrids. For discrete receptors, they are the receptor coordinates.
specie = puff.species[0]
c_24hr_2nd_max = puff.get_time_avg_max(specie, interval=24, rank=2)from calpost import CalmetDataset
met = CalmetDataset.read("calmet.dat")
print(met.info())
u = met.get_3d_field("U", level=1) # [time, y, x]
v = met.get_3d_field("V", level=1)
z0 = met.get_static_field("Z0") # [y, x]import matplotlib.pyplot as plt
from calpost import CalpuffOutput
puff = CalpuffOutput.read("CONC.DAT")
fig, anim = puff.plot_concentration_animation("SO2")
plt.show()Discrete receptor files are also supported:
- if the receptors form a complete regular grid, interpolation uses bilinear interpolation;
- otherwise it falls back to inverse-distance weighting.
Optional interpolation controls:
fig, anim = puff.plot_concentration_animation(
"SO2",
grid_shape=(120, 80),
cell_size=(250.0, 250.0),
)import matplotlib.pyplot as plt
from calpost import CalmetDataset
met = CalmetDataset.read("calmet.dat")
fig, anim = met.plot_wind_animation(level=1, stride=4)
plt.show()Read metadata only:
python3 -m calpost.calpuff_reader CONC.DATAnimate a species:
python3 -m calpost.calpuff_reader CONC.DAT SO2 --animateAnimation options:
python3 -m calpost.calpuff_reader CONC.DAT SO2 --animate --interval 150 --cmap plasma
python3 -m calpost.calpuff_reader CONC.DAT SO2 --animate --grid-shape 120 80
python3 -m calpost.calpuff_reader CONC.DAT SO2 --animate --cell-size 500
python3 -m calpost.calpuff_reader CONC.DAT SO2 --animate --grid-shape 120 80 --cell-size 250 250Notes:
--grid-shape NX NYis optional and mostly useful for discrete-receptor interpolation.--cell-size DXuses the same spacing in both directions.--cell-size DX DYuses differentdx,dy.
Read metadata only:
python3 -m calpost.calmet_reader calmet.datAnimate winds:
python3 -m calpost.calmet_reader calmet.dat --animate
python3 -m calpost.calmet_reader calmet.dat --animate --level 2- CALPUFF plotting depends on
matplotlib; parsing and extraction do not. - CALMET parsing targets the
CALMET.DATlayout extracted from thecalmet.forwriter path currently in this repo. - The CALPUFF reader is aimed at post-processing and inspection, not full model validation.
- Discrete-receptor animation is meant for visualization; interpolated concentration surfaces should not be treated as authoritative without checking the receptor layout and interpolation assumptions.
- Add real tests with sample CONC.DAT and CALMET.DAT files covering header parsing, field extraction, and animations.
- Validate CALPUFF support on more output types beyond concentration-oriented use cases, especially DFLX, WFLX, VIS, and related variants.
- Add save-to-file support for animations (gif/mp4) instead of only interactive display.
- Add optional static plotting helpers for common quicklooks, not only animations.
- Improve interpolation controls for discrete CALPUFF receptors, including clearer handling of extrapolation and missing areas.
- Add support for complex-terrain receptor extraction and plotting in the CALPUFF reader.
- Add example notebooks or scripts for typical workflows: extraction, maxima, concentration animation, wind animation.