This guide covers installation, command-line and Python use, sample data, and development commands. For scientific details, see the architecture, Hodges/TRACK implementation, HEALPix support, and TrackJSON documentation.
- Python 3.12+
- Message Passing Interface (MPI):
- Linux/macOS: OpenMPI is recommended and included as a development dependency.
- Windows: use
winget install -e --id Microsoft.msmpior install MS-MPI.
- Spherical harmonic operations on rectangular GL/CC grids use
spharmgrid; PyStormTracker uses directducc0for reduced-grid transforms, HEALPix geometry, polar projection, regional DCT, and explicit-lmaxvector kinematics. - Python 3.15 and free-threaded Python 3.14t/3.15t are experimental.
CI tests core dependencies on free-threaded interpreters and the
netcdf4extra on regular Python 3.15; remaining extras are tested on earlier versions.
pip install PyStormTrackerOptional components can be installed with extras:
pip install "PyStormTracker[mpi]" # mpi4py
pip install "PyStormTracker[grib]" # GRIB support
pip install "PyStormTracker[netcdf4]" # NetCDF4 backend
pip install "PyStormTracker[zarr]" # Zarr and remote stores
pip install "PyStormTracker[eof]" # xeofs for CCA/PCA analysis
pip install "PyStormTracker[all]" # non-visualization optional componentsWith uv:
# CLI tool
uv tool install "PyStormTracker[mpi]"
# Library dependency
uv add "PyStormTracker[mpi]"mamba install -c conda-forge pystormtrackeror:
conda install -c conda-forge pystormtrackergit clone https://github.com/mwyau/PyStormTracker.git
cd PyStormTracker
uv syncThe stormtracker command provides tracking, sampling, comparison, and conversion subcommands.
Track mean sea-level pressure minima with the Hodges tracker:
stormtracker track \
-i data.nc \
--variable msl \
-o tracks.trackjson \
-m min \
-a hodgesFor example, calculate mean precipitation within 500 km of existing storm centers:
stormtracker sample \
-i tracks.trackjson \
-d precip.nc \
--variable pr \
-o tracks_enriched.trackjson \
--method mean \
--radius 500stormtracker compare \
-r era5.trackjson \
-c gfs.trackjson \
-s 2.0 \
-l 0.6 \
--variable vo \
-m max \
--jsonstormtracker convert \
-i tracks.trackjson \
-o tracks.imilast \
-F imilastUse stormtracker <command> --help for the full argument reference. -v and -vv select INFO and DEBUG logging; -V prints the version.
Important track options include:
| Argument | Short | Description |
|---|---|---|
--input |
-i |
Input NetCDF/GRIB file. |
--variable |
Variable name such as msl or vo. |
|
--output |
-o |
Output trajectory file. |
--algorithm |
-a |
simple, hodges, or healpix. |
--format |
-f |
auto, json, track, or imilast; recognized extensions are inferred automatically. |
--detection-mode |
-m |
auto, min, or max. |
--backend |
-b |
serial, dask, or mpi. |
--workers |
-w |
Number of parallel workers where applicable. |
--lmin, --lmax |
Optional spectral-filter bounds; supply both to filter. | |
--taper-points |
Independent spatial taper width; zero disables tapering. | |
--spectral-taper |
Hodges/HEALPix high-wavenumber coefficient taper. | |
--nside |
Target HEALPix resolution; omitted values are derived from the source grid. | |
--feature-refinement |
Tracker-dependent feature-point location method. | |
--no-progress |
Disable the interactive Hodges Dask progress display. |
See the CLI reference for all commands and options.
import pystormtracker as pst
tracker = pst.HodgesTracker()
tracks = tracker.track(
data="data.nc",
variable="vo",
detection_mode="max",
)Tracks is iterable:
for track in tracks:
if len(track) >= 8:
print(f"Track {track.track_id} lived for {len(track)} steps.")Write trajectories in a supported format:
tracks.write("output.txt", format="imilast")See the API reference for the full Python interface.
PyStormTracker separates preprocessing, feature detection and refinement, and trajectory linking.
- Preprocessing can apply spherical-harmonic filtering on global grids, DCT filtering on regional grids, spectral tapering, and projection/regridding to polar or HEALPix coordinates.
- SimpleTracker uses local-extrema detection and deterministic nearest-neighbor linking.
- HodgesTracker uses thresholded objects, local extrema, optional feature-point refinement, and Modified Greedy Exchange trajectory linking. The default
bsplinerefinement follows the reconciled rectangular TRACK/SMOOPY workflow. - HealpixTracker performs object detection on HEALPix topology and uses the Hodges MGE linker.
- Serial, Dask, and MPI execution are supported by the implemented tracker paths.
Implementation details are documented in Architecture, TRACK Implementation and Comparison, and HEALPix Support.
PyStormTracker reads IMILAST and TrackJSON trajectory data and writes IMILAST, TRACK tdump, and TrackJSON. Analysis functionality includes variable sampling, trajectory comparison, gridded cyclone and track metrics, Eulerian variance and wind indices, CORMAX, and CCA/PCA truncation cross-validation.
TrackJSON is the native compact array-oriented format; see TrackJSON.
The repository includes one integration input:
tests/data/era5/era5_msl_2025-12_2.5x2.5.nc
Specialized GRIB, reduced-Gaussian, and broader reference datasets are stored in PyStormTracker-Data v0.2.0-data. Small references use raw Git paths, large files use Release assets, and Git-tracked Zarr stores use their raw store paths.
The bundled NCL T5-42 scalar spectral parity reference is:
tests/data/ncl/era5_msl_2025-12-01_0000_2.5x2.5_t5-42.nc
The bundled NCL case tests scalar T5-42 filtering.
Set up the complete development environment with:
uv sync --all-extrasRun the fast default unit suite:
uv run pytestRun code-quality checks with:
uv run prek run --all-files
uv run mypy
uv run python scripts/generate_trackjson_schema.py --checkTesting is tiered:
- Unit tests are the default fast offline suite.
- Integration tests exercise PyStormTracker components together on real data.
- Parity tests compare package behavior with static external or earlier PyStormTracker results, including the bundled NCL T5-42 scalar spectral case.
Examples:
# Unit tests
uv run pytest
# Non-slow, bundled integration tests
uv run pytest tests/integration -m "not slow and not data"
# Non-slow, bundled parity tests
uv run pytest tests/parity -m "not slow and not data"See CONTRIBUTING.md and the testing guide for contributor workflows and test taxonomy.