wrf-rust0.4.0

WRF post-processing diagnostics, reimplemented in Rust, with a wrf-python-compatible Python API.

A Rust reimplementation of wrf-python's getvar diagnostics

wrf-rust reads WRF-ARW output files with a pure-Rust NetCDF-4/HDF5 reader and computes the meteorological diagnostics that NCAR's wrf-python provides through getvar() — pressure, height, thermodynamics, CAPE/CIN families, storm-relative helicity, severe-weather composites, reflectivity, and more — plus diagnostics wrf-python does not have, such as effective-inflow-layer products and entraining CAPE. It ships as a Python package (pip install wrf-rust, imported as wrf) backed by the wrf-core Rust crate.

PropertyValueDetail
Registered diagnostics 125 Complete reference table, generated from the source registry at v0.3.0
Reference parity 0 failures Differential harness against pinned wrf-python 1.3.4.1 and SHARPpy 1.4.0a5
Pipeline speedup (0.3.0) ≈3.3× 79-product severe set on a real 800×800×79 case: 185.3 s → ≈57 s class at 24 threads
Interfaces Python + Rust PyPI package wrf-rust; Rust crates under crates/

1 Installation

The Python package installs a module named wrf. No system NetCDF or HDF5 installation is required for normal wheel builds; the default reader path is pure Rust.

pip install wrf-rust

For local development against the repository:

git clone https://github.com/FahrenheitResearch/wrf-rust.git
cd wrf-rust
pip install maturin
maturin develop --release

2 Quickstart: Python

The API mirrors wrf-python's getvar conventions: open a file, request a variable by name, optionally convert units or select all time steps. Results are NumPy arrays, (ny, nx) for 2-D fields and (nz, ny, nx) for 3-D fields.

from wrf import WrfFile, getvar, ALL_TIMES

f = WrfFile("wrfout_d01_2024-01-01_00:00:00")

temp = getvar(f, "temp", timeidx=0, units="degC")   # (nz, ny, nx)
cape = getvar(f, "sbcape", timeidx=0)               # (ny, nx), J/kg
srh  = getvar(f, "srh1", timeidx=0)                 # 0-1 km SRH, Bunkers
slp  = getvar(f, "slp", timeidx=ALL_TIMES, units="hPa")

# Strict NCAR wrf-python/RIP compatibility paths are separately named:
srh_ncar = getvar(f, "srh_wrfpython", timeidx=0, depth_m=3000)
ecape    = getvar(f, "ecape", timeidx=0, storm_motion_type="bunkers_rm")

Layer-configurable diagnostics accept explicit bounds, and raw WRF variables fall through by name:

shear = getvar(f, "bulk_shear", bottom_m=0, top_m=6000)
lr    = getvar(f, "lapse_rate", bottom_p=700, top_p=500)
srh   = getvar(f, "srh", depth_m=1500, storm_motion=(12.0, 8.0))
rain  = getvar(f, "RAINNC", units="in")             # raw variable fallback

list_variables() returns every registered name with description and default units; available_variables() prints the same as a table. interplevel, latlon_coords, get_cartopy, ll_to_xy/xy_to_ll, and multi-file concatenation follow wrf-python semantics.

3 Quickstart: Rust

The same registry is callable from Rust through the wrf-core crate. getvar returns a VarOutput holding a flat Vec<f64>, its shape, the unit string, and a description.

use wrf_core::{getvar, ComputeOpts, WrfFile};

let file = WrfFile::open("wrfout_d01_2024-01-01_00:00:00")?;
let opts = ComputeOpts::default();

let slp = getvar(&file, "slp", Some(0), &opts)?;
assert_eq!(slp.shape, vec![file.ny, file.nx]);
assert_eq!(slp.units, "hPa");

4 Compatibility and scope

wrf-rust separates two kinds of fidelity rather than conflating them:

Unit strings are case-insensitive and cover temperature, pressure, speed, length, precipitation depth, and moisture categories (for example degC, hPa, kt, ft, in, g/kg).

5 Consumers

BowEcho, a desktop weather radar and satellite application, is the flagship consumer: it uses wrf-rust for WRF import, severe-weather diagnostic suites, isobaric volumes, and a synthetic-radar forward operator over WRF output. The repository also contains Rust-native rendering (wrf-products, wrf-render), sounding extraction (wrf-sounding), and ensemble reductions (wrf-ensemble) built on the same core.

6 Further reading