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.6.tar.gz (613.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.2.6-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.6-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.6-cp312-cp312-win_amd64.whl (1.3 MB view details)

Uploaded CPython 3.12Windows x86-64

metrust-0.2.6-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.6-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.6-cp312-cp312-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

metrust-0.2.6-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.6-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.6-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.6-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.6.tar.gz.

File metadata

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

File hashes

Hashes for metrust-0.2.6.tar.gz
Algorithm Hash digest
SHA256 c96561a205b5e2ec2de8c11e9649f00bbb4481ecdfac07c1c5cf08c22aba3268
MD5 be8a80b36ae8463838e521692e7ed9c9
BLAKE2b-256 a69dc0961351c61d95b887ce9bca309cfe9548aa7aaec161b67661ae4581f8c7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d2b778c6e575e1f7b57556d59011ddc790c48b88927c943050434a0a39f3663d
MD5 b53bda2d17550eecdbd3558cfb4f9496
BLAKE2b-256 5df34062cb5bddde279ad0a82484992086040a92a44c7514c7da7d14023ee191

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 960c1af04efe08cf1b2ea171dd53bea83d88221a08f867489d9de58e1fbf94eb
MD5 6bcb1a181b7360ef0a12c93057fecc0c
BLAKE2b-256 5f59a7d9e63fdca0fec5bfe7e9a254047013eb55571284a7795c23eaa78f079f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: metrust-0.2.6-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.6-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 ab6d256486f8b3ba83c8675094bb2236d735c52be0756fff9dd244fd85391e71
MD5 870ed376af529ff09b71543ca8f29b2b
BLAKE2b-256 96732093545752be68227a40102874868e5287c53e3caa3cce92edb432d90824

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0713298ae111e9fa0964815d07262985307fa5e414489eb162d6640e6e591c12
MD5 a182231d8bc8c1a83a3c71320b794c96
BLAKE2b-256 b43e0b5bcc0b10ea846e0fc8eedb6a48589bb972a51699af8965de8683dbdb0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0617643d474a5b900cbcf720ad3b993778df325f40db860b780c9750d579c695
MD5 d72e2c8f82842ec1a053e804b2c1256b
BLAKE2b-256 6bb8df03cdc9634c40569fc884379e1c3795f4e40738c3a2a0175a9408308fc7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f384b972f9df03b6b5442f9e25f5f419346f6ae29da445680588b2222601dfcf
MD5 0c1f52e2c5b91bdb9341d75481500d7a
BLAKE2b-256 ce380394ca94802c7e6be2a6a0763f84f03ec0021e08477170c2d0b6d4f5c10a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 7ff50101b064889ed1377e9f4655744d63fa7cdd787a4b0ddf08ae31e02eb2e6
MD5 b313e79d96405073ef9e00b6666dfee1
BLAKE2b-256 5599c92cc2faa72f78f82814c83d55a6d308a53a96b14284f5c59da6ddd93dab

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d86bb5894bcac0f72c8f8bae3a066b4319d1483dda50bee234eb3daa1ce6633d
MD5 76b0158fc11f946b247acd59c0b8c0b9
BLAKE2b-256 ed004b7e2a64d75ad662f2b959eeed9c6412e84dcf0a854377d6c79a08d08e34

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 a09d3dd22f76e226cdf95dad6d39fcd353e6d4e20eeb17854ef14f551c3eaa3b
MD5 c605db3c3abd6cb93cf6dd9d2c0696d2
BLAKE2b-256 54a2dfa2df8cc4e13f1a5fd60a68a51c214638cce6ad26ffce13484ab2375ce3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1bc107e67d5a7804f2c226c99bf022b4e45f2e62d0aaf91cbf81ebc59fba2ce3
MD5 956ab9727c15994cd7f7ccb5a4c0f0b0
BLAKE2b-256 4ca5e3ad311a63bbdf8b44f29977a948e7fe1deb80ee311a4e019450d8a64fca

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d76e0ef079d9456ab02dc503f8d4fa722d9f336ef3adc950b82786bcb60a7c9f
MD5 a2ac84ff03c830f77106e1f4948fb1f2
BLAKE2b-256 f596000846887f2545c16f4b7809279f487e8f861669220d351d874cf845e62f

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