Rust-powered drop-in replacement for MetPy -- 150/150 calc functions plus 36 extras, 10-93000x faster
Project description
metrust
Rust-powered meteorology toolkit with MetPy-compatible Python APIs.
metrust uses a Rust backend for core meteorological calculations and exposes a Python surface that aims to feel familiar to MetPy users. The core metrust.calc module covers the large majority of metpy.calc with native Rust — no MetPy dependency required for typical calc workflows. A handful of MetPy-specific surfaces (plots, xarray accessor, Level2File) optionally forward to MetPy when it is installed.
# Before
from metpy.calc import cape_cin, potential_temperature
from metpy.units import units
# After — same code, faster results
from metrust.calc import cape_cin, potential_temperature
from metrust.units import units
p = [1000, 925, 850, 700, 500] * units.hPa
T = [25, 20, 15, 5, -15] * units.degC
Td = [20, 15, 10, -5, -25] * units.degC
Scalars and arrays both work — pass a single value or a full grid:
import numpy as np
from metrust.calc import potential_temperature, saturation_vapor_pressure
from metrust.units import units
# Scalar
theta = potential_temperature(850 * units.hPa, 20 * units.degC)
# 2D grid (e.g., HRRR 1059x1799)
p_grid = np.full((1059, 1799), 850.0) * units.hPa
t_grid = np.random.uniform(15, 30, (1059, 1799)) * units.degC
theta_grid = potential_temperature(p_grid, t_grid) # shape preserved
Installation
Core install:
pip install metrust
For optional features (plots, xarray accessor, Level2File), install MetPy separately:
pip install metpy
From source:
git clone https://github.com/FahrenheitResearch/metrust-py
cd metrust-py
python -m pip install -e .
What Works Well Today
Native Rust implementations cover a large portion of the day-to-day meteorology surface:
- Thermodynamics: potential temperature, equivalent potential temperature, CAPE/CIN, parcel profiles, LCL/LFC/EL, virtual temperature, wet bulb, precipitable water, thickness, stability indices
- Wind and severe weather: wind components, bulk shear, storm-relative helicity, Bunkers storm motion, Corfidi vectors, STP, SCP, critical angle
- Kinematics: divergence, vorticity, advection, frontogenesis, geostrophic and ageostrophic wind, potential vorticity, deformation
- Smoothing and interpolation: Gaussian, rectangular, circular, n-point, generic window convolution, 1-D interpolation, log interpolation, NaN fill, isosurface, IDW, natural neighbor
- I/O: Level-III, METAR parsing, station lookup, GINI, GEMPAK grid/sounding/surface, WPC surface bulletin parsing
- Constants: the core meteorological constants used by the calculation layer
On the Python side, metrust normalizes wrapper mismatches that previously blocked MetPy-style use:
- All thermodynamic and humidity functions accept scalars, 1D arrays, and 2D grids with shape preservation
- 28 hot-path functions have dedicated Rust array bindings (zero Python loop overhead)
- Remaining functions use a Python-side vectorizer (
_vec_call) for automatic scalar/array dispatch - Offset temperatures work with Pint quantities like
20 * units.degC saturation_vapor_pressure()returnsPasaturation_mixing_ratio()returns dimensionlesskg/kgrelative_humidity_from_dewpoint()returns a dimensionless fraction- Common MetPy signatures such as
cape_cin(p, t, td, parcel_profile=...)are accepted compute_cape_cinsupportstop_mparameter for capped CAPE (e.g., SB3CAPE at 3 km AGL)
Compatibility Model
metrust is best thought of as:
- A fast Rust-backed replacement for much of
metpy.calc - A MetPy-compatible Python package for common workflows
- A partial shim over MetPy for surfaces that are still Python-specific
That last point is important. Some compatibility paths intentionally delegate to MetPy when it is installed. This keeps the public API usable while the native Rust/PyO3 surface catches up.
Current shimmed surfaces:
metrust.io.Level2Fileforwards to MetPy when availablemetrust.plotsforwards tometpy.plotsmetrust.xarrayforwards tometpy.xarray- Core
metrust.calcfunctions are 100% native Rust with no MetPy fallback
Performance
The benchmark suite (benches/) measures performance at three tiers to give an honest picture:
| Tier | What it measures | Import path |
|---|---|---|
| T1: Raw Rust | Pure FFI, no Pint overhead | metrust._metrust.calc |
| T2: metrust + Pint | Rust backend with Pint unit wrappers | metrust.calc |
| T3: MetPy + Pint | Pure Python + Pint baseline | metpy.calc |
The fair comparison is T3 vs T2 (both use Pint). T1 shows the raw Rust ceiling.
Representative numbers (p50, AMD Ryzen 9):
| Operation | MetPy (T3) | metrust+Pint (T2) | Raw Rust (T1) | Fair speedup (T3/T2) |
|---|---|---|---|---|
potential_temperature (scalar) |
129 us | 7.4 us | 60 ns | 17x |
equivalent_potential_temperature |
300 us | 7.5 us | 95 ns | 40x |
wet_bulb_temperature (scalar) |
724 us | 8.1 us | 201 ns | 90x |
dewpoint_from_rh (scalar) |
120 us | 2.7 us | 76 ns | 44x |
parcel_profile (100 levels) |
2.55 ms | 71 us | 56 us | 36x |
cape_cin (100-level sounding) |
1.60 ms | 137 us | 20 us | 12x |
divergence (100x100 grid) |
994 us | 12.6 us | 12.6 us | 79x |
storm_relative_helicity (100 levels) |
579 us | 16.5 us | 532 ns | 35x |
A few operations are not faster — this is expected and the benchmarks don't hide it:
wind_speedat small arrays (1k elements): metrust+Pint is ~2x slower than MetPy because Pint wrapper overhead dominates a sub-microsecond Rust call. At 10k+ elements they converge.smooth_gaussian: MetPy delegates to scipy's heavily-optimized Cgaussian_filter. The pure Rust implementation is ~10x slower on large grids. The raw Rust API (T1) avoids any Pint cost but the algorithm itself is less optimized.
Run the benchmarks yourself:
# Rust (Criterion, HTML reports in target/criterion/)
cargo bench --package metrust
# Python three-tier (requires metrust; MetPy optional for T3)
python benches/bench_python.py # T1+T2 only
python benches/bench_python.py --tier 1,2,3 # all three tiers
python benches/bench_python.py --json # machine-readable output
Known Limits
This is not a full package-level replacement for all of MetPy yet.
metrust.plotsandmetrust.xarrayare compatibility shims, not native reimplementations- Level-II access currently relies on MetPy from the Python surface
- Numerical agreement is close for most shared calculations, but not bit-identical
moist_lapsestill needs more scrutiny before being treated as high-confidence parity work- Grid kinematics (divergence, vorticity, etc.) require scalar
dx/dygrid spacings — variable-resolution grids are not yet supported
Known numerical differences include:
- Saturation vapor pressure and saturation mixing ratio use different empirical fits than MetPy on the native Rust path
- LCL and wet-bulb calculations use different approximations than MetPy
- STP and SCP cutoff behavior is not identical in every weak-shear environment
- Some constants come from slightly different textbook/reference values
Verification
The repo currently verifies two different things:
- The Rust workspace itself via
cargo test --workspace - Python compatibility expectations via
tests/test_python_compat.py
The Python compatibility tests cover the specific wrapper issues that most affect "drop-in" use:
- Offset temperature handling
- Wrapper return units for key thermodynamic functions
- MetPy-style function signatures such as
cape_cin(..., parcel_profile=...) - Public I/O exports
plotsandxarrayshim forwarding
The older tests/verify_*.py scripts are still useful for exploratory comparisons, but they are reference scripts, not the authoritative CI gate.
Running Checks
cargo test --workspace
python -m pytest tests/test_python_compat.py -q
Optional exploratory comparisons:
python tests/verify_thermo.py
python tests/verify_wind.py
python tests/verify_kinematics.py
python tests/verify_severe_atmo.py
python tests/verify_smooth_interp.py
Should You Use It
Use metrust if:
- You want MetPy-style calculations with much lower runtime overhead
- Your workload is dominated by
metpy.calc-type operations - You are comfortable with a project that is converging toward broader MetPy compatibility
Keep MetPy in the loop if:
- You depend heavily on the full plotting stack
- You rely on the xarray accessor layer
- You need exact behavioral parity rather than close compatibility
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file metrust-0.3.0.tar.gz.
File metadata
- Download URL: metrust-0.3.0.tar.gz
- Upload date:
- Size: 618.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8677a3408bdecabd359c7eb6f48cedc3bbd2ec6bae1280cade5fd46a06ae0a9c
|
|
| MD5 |
ce635edc8a8d8438dbe8298927317afa
|
|
| BLAKE2b-256 |
acde6aae4118556c0db9b9cdb0d5304601e6252835dcd3bc9580a1bf9f7cc753
|
File details
Details for the file metrust-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: metrust-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
601c93f71caa9ed429dd0b3c9d4dd227a30126450590f0b0d0180ac191f98f3d
|
|
| MD5 |
94eb45bfde30d22a4dedf93599c709d2
|
|
| BLAKE2b-256 |
cabf730a5d90ba1aa7ad84f46781a3142a486f8fa87d0c5d707b136443a359e2
|
File details
Details for the file metrust-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: metrust-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.13, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2814046de0bb656e481878bf42beffa7132c057a6a73963c709c845c34f614e
|
|
| MD5 |
ed6d8c793aeb112dc5a3f18b60b05454
|
|
| BLAKE2b-256 |
14085cfa4008468f5144181de4124b249831a215f1a0c43c3ef033b866609cbd
|
File details
Details for the file metrust-0.3.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: metrust-0.3.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 1.3 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8923488042737df6940025f67c8283bf9176a045c7e4c37e652084695d7c8deb
|
|
| MD5 |
de3b774930a0ba1eb562edf74985d7d0
|
|
| BLAKE2b-256 |
a361893b407cc0712ee2d93f451239f09e19ab1924709cb6bb65f071c3f6340d
|
File details
Details for the file metrust-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: metrust-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b3208869bf9749e7d1725913c4b59d9dfec77c57f6496785f93215e71e4cfc09
|
|
| MD5 |
ce142e1354e4e34b1f85c4620113da4a
|
|
| BLAKE2b-256 |
edb3aa825ca76c80b62dc4479dd8fa85e3e8a0202cfebc30100425a3e8ab466b
|
File details
Details for the file metrust-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: metrust-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e17879aa6b3f52fa386cf1462b0627cd4580aedf131a3c2c9cbacf0403787f10
|
|
| MD5 |
13c9e188f7386b11dfa5f4778d38a3f0
|
|
| BLAKE2b-256 |
f831faa794ee4bdf62a0c63cdb1b424be62ad3b7d43d650b36b9a0ced3a055e0
|
File details
Details for the file metrust-0.3.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: metrust-0.3.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.3 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a1513f57ffea59e4ec54605aa9e14386310c599f6b975d9f62f0169691260ba
|
|
| MD5 |
791087b79912b77c2757855e6d302674
|
|
| BLAKE2b-256 |
a324a044640e9161321f9320c4b8ad5a68e5da1009710b8aac7728af093e9bb8
|
File details
Details for the file metrust-0.3.0-cp312-cp312-macosx_10_12_x86_64.whl.
File metadata
- Download URL: metrust-0.3.0-cp312-cp312-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.12, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9820182b56560edccb2db11656e89ea64236d7122ef7739506f686b39cfb359c
|
|
| MD5 |
bde45130df6f2f4f300b65ec3aae704c
|
|
| BLAKE2b-256 |
8d7b99b0f0bca2eff0267c53393245778898f40ddc7594b8cd858d5e3db92d2b
|
File details
Details for the file metrust-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: metrust-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2103daee8f28d301a11afd58b764f992e78123012d5524d04018c59f98703659
|
|
| MD5 |
53ed5e2d589f86cb1b2cba52dbc1e9ea
|
|
| BLAKE2b-256 |
94ddb85918d2c4c53512848c67c4e3672aad415f95003852a438f1fc302dd70f
|
File details
Details for the file metrust-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: metrust-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edfde7cccfa671d454d02c9f2516da636995e19acce0084f09b5bbac31ecf3d2
|
|
| MD5 |
ebf70823f28018aefb6857e84757322a
|
|
| BLAKE2b-256 |
2948a66b4e39b62c678266247302b66f064e6eafdb5403dd9620790958fe919e
|
File details
Details for the file metrust-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: metrust-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.5 MB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11abbbf51dd9dc0a4e1f42a9e907f8855b1aaffaeb4cd226ec76eb25c57c279c
|
|
| MD5 |
6b1f8a0b010e61b472a3edd1e83043be
|
|
| BLAKE2b-256 |
4f59fe2ea5d4dcfbb1dfe2761c396a5f943928dd717c069d98d091ede14fddc2
|
File details
Details for the file metrust-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: metrust-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.10, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
430b962e50b06118a7674a4e70a9ad20598360c25d2b5d34f9fec4bee01bb03c
|
|
| MD5 |
149d0438ef06223fe46aa96254504256
|
|
| BLAKE2b-256 |
f29e8806b3ae11739d2b45f219d12fcbb1b8e908cb529befda43a220e94afe36
|