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

Uploaded CPython 3.12Windows x86-64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

metrust-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

metrust-0.2.2-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.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

metrust-0.2.2-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.2.tar.gz.

File metadata

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

File hashes

Hashes for metrust-0.2.2.tar.gz
Algorithm Hash digest
SHA256 1c8eda4b294364eef208081b834100fbeee6a96e88bca46129a9332e64b273a6
MD5 c1914594254f7e566fa13fe6fb14ae9e
BLAKE2b-256 d2fa97bb33db38feee65b75c1c6551d7314cc684a8e2d436c19219d9ecbd61d7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9a7919fb64508772dabf981154e460e28a98b5cac0b1d68027a31fbf30597387
MD5 5e1cc65604f6adabe97e9d95af1751d8
BLAKE2b-256 a0e0555df446384e2eb3fa6b5e817aae592756d600a587b5869fcc22149f32c0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c200a14d39012c61c960f058c3993beefc04975d4c27acffee066e77e148389e
MD5 a05eed22211028f513f296785ceb0e62
BLAKE2b-256 6a1d21dc8172f22aaa99f08f2fb0b7a427c6eb2d940167ff2b9dc63f6007ef9d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: metrust-0.2.2-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.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 38b8c6e1a2c4e3cf0df01e86a4673fde84b28c44058b49eb48feb33885423cc7
MD5 95cf16964ee8c72514e7b2bb527ae4cf
BLAKE2b-256 19fe1ed9f150435716ffdde2e98bdff14e0fe2373853f1e0cd045ece13ae591b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4a0759f659ef8f6a2ea27a885d962c18e9f60ebb0c8bf42b3b2e5eb1b59e4e6f
MD5 ea5d75d4f932b4f5f115cd37ab7e9e8a
BLAKE2b-256 f9e7b2ab007c9f93b8ef45aa8602098b45beef5c8f2e38cfe330751b7592debe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 52e19a909fc3e98b889b2977ca078eb324485fbaaf75cf6ed2e544f9c564b98a
MD5 f335fd27f3be106743e15323c73dfe23
BLAKE2b-256 347c0181388446999f165cc2031ef6beb73831f68805733c9a4220c28764ba78

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b350695eb4b9ef630ab24ecd8b21742aa8329e297ec3350ee82d443d70aa1407
MD5 02664f6ec5eba1bb03cbac3836fb3b81
BLAKE2b-256 25894e1411d959365ffae3c023a4e9725e0838025d920d2b38f1de4aa5d04664

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 57552d82595e7864c8d158c0716dbda47de5bfad5f9d94de15ab61cce1dcd388
MD5 330a67dd0a05353e387cdc0bdc34cbe7
BLAKE2b-256 c6556f53b3392ebba281286fddac7f4336da136ec0415fb3dfc4b9d12a541c44

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6973dbbb1ce1297142bf14ab730f576a8941c0bd856337a6a35cad88c633ca26
MD5 4e7ad253070196377abae08e8aebeabc
BLAKE2b-256 791db4d842c2c682744098586536ac15a1b92783d7e41454f457ae31d25f66b4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d8ed668a4988cb79505e83f0e0135e11bed1f62d3634db03b860723be92f8886
MD5 7f66751383515d53caeb206833c8194f
BLAKE2b-256 b374c18425b937ed73f1f01ab41a77149883689bb9d64b881f85e2348e1f517b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 809615686b2a44c27fa905642e9293da2e7fb4dc0c2ee1399b3c8ac25bd7fdea
MD5 4b73d955743a1d2a3c7339073a4e9c2f
BLAKE2b-256 dfedd8b0bb0ad5f670a97761af2f6e1e0369032b945e9be13bfe571b22df59d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 039934af0b05d820e5ef828e5c579ec050d46900830645c9fa12d4c4c50c6b60
MD5 96809b40f07d003aaebf0ead9fe54e3b
BLAKE2b-256 5a789e3a7e410023226458a9fe7d162f1e49d44353178c6f92328ef37061bf77

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