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.2.7.tar.gz (613.9 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.2.7-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.2.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.12Windows x86-64

metrust-0.2.7-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.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

metrust-0.2.7-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.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

metrust-0.2.7-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.2.7-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.2.7.tar.gz.

File metadata

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

File hashes

Hashes for metrust-0.2.7.tar.gz
Algorithm Hash digest
SHA256 229719cd53976c24836047beb0194cd0547e27272ebc2cbbd25b9df03b7e791a
MD5 d3c41b9fc3b92882748a4a7967a88a28
BLAKE2b-256 5f09711c1b64428265953a343d20fd989e8e23977bb615268ec4b47bf66f488d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 21ad6df4367e27d604da486acd4ff8997f031d8d979ff78149c79d1b5449a360
MD5 f415cc9b49bbdd2127e34af97aba28ac
BLAKE2b-256 237a5f864c1e456f9260e82b5f999726b737126a0a5bec831c339b7307390d89

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 607cdc8832355bd92d599486eb69226e8177a56f26ac62a84149dbb4808cca9c
MD5 c8cafa76abf71740382fc687fa0ba81a
BLAKE2b-256 4cff28a4ff28398ff1fee0ddc152acbf7e1de2f4f2c2cc149531d2986bfb6ed9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: metrust-0.2.7-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.2.7-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 f3455ab5e405e2781b191ba4a846fc7efd14740180c8e691e4dd588764416de6
MD5 c19b171a6b68153c6435573372fdd2b1
BLAKE2b-256 ee61836612508d66c5d56104944dfcf0704cd44477128aeef95ff803deeb9233

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 757941a079460b02928de541b9cff9458ed257148fa371e8d91e1758985fba5b
MD5 86c58656a5cb807fdbba10466e78af4c
BLAKE2b-256 02c312701712bcb71a589c985084083be520983945fabb7569bb9bc8a1e3a738

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b232d0d631f334b604466b010784032bb506cc8e246ea796677c02ad357820b2
MD5 ea7db1dab4c236cc07ada13911afdbfb
BLAKE2b-256 acabcb151da5da1fb677292c28b3f46c8b50e5cd359eb24bf13fdb703d1a4dee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 be15fb66d9f1dd761799b35625650df5ab409feae1dd12a73f2e3d02deda2d11
MD5 67e27129fccfd73ff8512fc12546b6b0
BLAKE2b-256 636c6a54beea60df08af82a815bae43b6a66fbd60613555b4c987531031c77aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 31cd928c25cfd693d73e42fbcae8bd141283015cf10fb25ba1c6d812075ff994
MD5 559302ae18e903863fda14de914e8b18
BLAKE2b-256 5ddfac495554f1a48a79ec2b08721edefc907b83f588c4b29eb1cbfc1fea8c15

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e16da85b6275c211b6f12a33266b71f92206663f74a0ecc8d3d40c4e2912f00a
MD5 498c559dfaf2f26c6a8881d8de7526ee
BLAKE2b-256 0b8874c465fd4ef2ebc266fb7f2908ffbec16995b3813614ff7674c18efd3541

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 25ed19a43a33dcf58cddc917bfb7734bacdd09a2a3716fdf1bfe6e83576753a4
MD5 90fa8f954018f181e9369ec8f76457e0
BLAKE2b-256 c1eb0f809df52bf3a8981f2d88d3ed2650471041b2935aae42a910ca60bf69a0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3464d5ba51525842b4773c3dbe835074ac187158822b40af456fcc83eb55a061
MD5 72332c802253929ede7f87ee2a521b7d
BLAKE2b-256 a562899fefb2d693802250193d277fcb8ef1cffb15b6cf7b9c0d46cce36fa64c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 9b54dfaa2a4a66bab2e5730ffd8cde74c19165a9a67d16068ffc498a74640bf3
MD5 94a39a0c1a79cec5672fb4aab35569fb
BLAKE2b-256 c545c2c083ef1b688ea49ae0fbbe2aa9f99847bdd17ca3496f298b838dc5e742

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