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

Uploaded CPython 3.12Windows x86-64

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

Uploaded CPython 3.12macOS 11.0+ ARM64

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

Uploaded CPython 3.12macOS 10.12+ x86-64

metrust-0.3.0-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.0-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.0-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.0-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.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

Hashes for metrust-0.3.0.tar.gz
Algorithm Hash digest
SHA256 8677a3408bdecabd359c7eb6f48cedc3bbd2ec6bae1280cade5fd46a06ae0a9c
MD5 ce635edc8a8d8438dbe8298927317afa
BLAKE2b-256 acde6aae4118556c0db9b9cdb0d5304601e6252835dcd3bc9580a1bf9f7cc753

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 601c93f71caa9ed429dd0b3c9d4dd227a30126450590f0b0d0180ac191f98f3d
MD5 94eb45bfde30d22a4dedf93599c709d2
BLAKE2b-256 cabf730a5d90ba1aa7ad84f46781a3142a486f8fa87d0c5d707b136443a359e2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d2814046de0bb656e481878bf42beffa7132c057a6a73963c709c845c34f614e
MD5 ed6d8c793aeb112dc5a3f18b60b05454
BLAKE2b-256 14085cfa4008468f5144181de4124b249831a215f1a0c43c3ef033b866609cbd

See more details on using hashes here.

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

Hashes for metrust-0.3.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 8923488042737df6940025f67c8283bf9176a045c7e4c37e652084695d7c8deb
MD5 de3b774930a0ba1eb562edf74985d7d0
BLAKE2b-256 a361893b407cc0712ee2d93f451239f09e19ab1924709cb6bb65f071c3f6340d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b3208869bf9749e7d1725913c4b59d9dfec77c57f6496785f93215e71e4cfc09
MD5 ce142e1354e4e34b1f85c4620113da4a
BLAKE2b-256 edb3aa825ca76c80b62dc4479dd8fa85e3e8a0202cfebc30100425a3e8ab466b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e17879aa6b3f52fa386cf1462b0627cd4580aedf131a3c2c9cbacf0403787f10
MD5 13c9e188f7386b11dfa5f4778d38a3f0
BLAKE2b-256 f831faa794ee4bdf62a0c63cdb1b424be62ad3b7d43d650b36b9a0ced3a055e0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9a1513f57ffea59e4ec54605aa9e14386310c599f6b975d9f62f0169691260ba
MD5 791087b79912b77c2757855e6d302674
BLAKE2b-256 a324a044640e9161321f9320c4b8ad5a68e5da1009710b8aac7728af093e9bb8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp312-cp312-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9820182b56560edccb2db11656e89ea64236d7122ef7739506f686b39cfb359c
MD5 bde45130df6f2f4f300b65ec3aae704c
BLAKE2b-256 8d7b99b0f0bca2eff0267c53393245778898f40ddc7594b8cd858d5e3db92d2b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2103daee8f28d301a11afd58b764f992e78123012d5524d04018c59f98703659
MD5 53ed5e2d589f86cb1b2cba52dbc1e9ea
BLAKE2b-256 94ddb85918d2c4c53512848c67c4e3672aad415f95003852a438f1fc302dd70f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 edfde7cccfa671d454d02c9f2516da636995e19acce0084f09b5bbac31ecf3d2
MD5 ebf70823f28018aefb6857e84757322a
BLAKE2b-256 2948a66b4e39b62c678266247302b66f064e6eafdb5403dd9620790958fe919e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 11abbbf51dd9dc0a4e1f42a9e907f8855b1aaffaeb4cd226ec76eb25c57c279c
MD5 6b1f8a0b010e61b472a3edd1e83043be
BLAKE2b-256 4f59fe2ea5d4dcfbb1dfe2761c396a5f943928dd717c069d98d091ede14fddc2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for metrust-0.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 430b962e50b06118a7674a4e70a9ad20598360c25d2b5d34f9fec4bee01bb03c
MD5 149d0438ef06223fe46aa96254504256
BLAKE2b-256 f29e8806b3ae11739d2b45f219d12fcbb1b8e908cb529befda43a220e94afe36

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