Skip to main content

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() returns Pa
  • saturation_mixing_ratio() returns dimensionless kg/kg
  • relative_humidity_from_dewpoint() returns a dimensionless fraction
  • Common MetPy signatures such as cape_cin(p, t, td, parcel_profile=...) are accepted
  • compute_cape_cin supports top_m parameter 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.Level2File forwards to MetPy when available
  • metrust.plots forwards to metpy.plots
  • metrust.xarray forwards to metpy.xarray
  • Core metrust.calc functions 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_speed at 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 C gaussian_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.plots and metrust.xarray are 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_lapse still needs more scrutiny before being treated as high-confidence parity work
  • Grid kinematics (divergence, vorticity, etc.) require scalar dx/dy grid 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:

  1. The Rust workspace itself via cargo test --workspace
  2. 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
  • plots and xarray shim 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


Download files

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

Source Distribution

metrust-0.3.3.tar.gz (619.3 kB view details)

Uploaded Source

Built Distributions

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

metrust-0.3.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

metrust-0.3.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

metrust-0.3.3-cp312-cp312-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.12Windows x86-64

metrust-0.3.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

metrust-0.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

metrust-0.3.3-cp312-cp312-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

metrust-0.3.3-cp312-cp312-macosx_10_12_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.12macOS 10.12+ x86-64

metrust-0.3.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

metrust-0.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

metrust-0.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

metrust-0.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

File details

Details for the file metrust-0.3.3.tar.gz.

File metadata

  • Download URL: metrust-0.3.3.tar.gz
  • Upload date:
  • Size: 619.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.12.6

File hashes

Hashes for metrust-0.3.3.tar.gz
Algorithm Hash digest
SHA256 bd6a8ffe89ab4c72576e6d09e9e20677374c46b502073dec2e7b5aa60c26e03e
MD5 a211de96b17d6c532cef0147be6693ce
BLAKE2b-256 a5ffefebf0c99e6105593efa02ff6e6b2bccc336a425ae29ca602d9c2cc9432f

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6bbd7f3d269d3e114846351de18fd2f8deb610dfdccf7e84e5f9ede235444cf1
MD5 f011c8234abb24c7cde2448093cbf0f3
BLAKE2b-256 148bbe7ccdbd56812223a4630b45e229606e8c3cdf739242416d22176b0cff13

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0c69f9ee1b2354e13d3d258d8d728f114bd460b47a7bb0fa82b46830d71d2703
MD5 bd10b491e8483655f61104f21ce0b8f8
BLAKE2b-256 0afa41d88654fab92a6d88539de9edbcd695dd702c37c28d359be664664fdd3b

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: metrust-0.3.3-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

Hashes for metrust-0.3.3-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 3bca056d98ff0420226ccc328ca28699e21fdbe13615ec5191a279a690f72302
MD5 e0cf6484780bb24002180d36a73b215c
BLAKE2b-256 067284202e4d4b95e1fb882b8f683513eda0894e6281a8de9df57a92e97907c0

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9d2633e600516b45d6cebbae06a67208e78253b43ec0414b13bad392e5027bfc
MD5 ff4f29343a4a4bcbe1f8b0d4d5d6768c
BLAKE2b-256 527b7f6595b6871e7e239a745574676dffb193972baefa518152bc4f5cb07f6b

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 48d4da27b8c0bc09bad91a974b7e4c78ba9bd8d84fa96306c7f2c6aeb7273bd9
MD5 b0769e5b15141fc228aaa2a808557243
BLAKE2b-256 67a69f6f46c4cc078714160dc1375b2176ad4da22b54e77eca279c82d9009224

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 567c14ed9f0afaa38ebfa685643559f624eafdf80999668ec4b27027c4515fe2
MD5 f088b828958f5150b29cf56057175e76
BLAKE2b-256 b3e1dbaeb239180ae86ddc259d2ae17b2bb00cd6809a6531308ef7e006eb135a

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp312-cp312-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a1ed46ab3f4d55246ed6dccaa839c46001e0a1f1ccbcd4be73782cbff30f78bb
MD5 a1b93086cccbf1a58a81e6ad6c48088c
BLAKE2b-256 c63bb1c646b6e44f0ed641e354c84982f010ba99cecb46488dae52d877e55df8

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 507a437f49cfc91da18acbf71f0a255ad050ed56270a456ebb43f9ec9c04f80b
MD5 8f4d2484627f90d1a2931a930e46f2a4
BLAKE2b-256 cfd9927f1d6625cb1d4e4f318b0d6a10b712d15610284a570b20cf407ebf830a

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d956d1eedef886608ad4f887234f77c6995c7df6d0fbe3d4e63b603593470a45
MD5 0661058267e816d51987dec4115588bf
BLAKE2b-256 329420e02367640a666c340ffe24ea009a565100fa26b156a84ff8f8598e9699

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 00a24b385740ecdc216afe7fb491c24d6c328602a40d7d54a3de044fcb6c8426
MD5 d722cc40819899b7514950204eb48c66
BLAKE2b-256 e9f9fd3d99eb4506acc6c8937d775b819ece2ae2a17441525f2df15bf0626883

See more details on using hashes here.

File details

Details for the file metrust-0.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for metrust-0.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 bc1b0e0e8cdfe76f347aeac03bb4b16e7ad2539628675e4937551b809376cca5
MD5 9579b79741d9df656ae0d3f1fee19e51
BLAKE2b-256 614dc817cbb1a79cc09307cf4e8a0b8c56eff7bce828cd36898afddd0bf76fe6

See more details on using hashes here.

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