metrust 0.4.2__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {metrust-0.4.2 → metrust-0.4.3}/.github/workflows/ci.yml +55 -11
- {metrust-0.4.2 → metrust-0.4.3}/.github/workflows/docs.yml +4 -4
- {metrust-0.4.2 → metrust-0.4.3}/.github/workflows/release.yml +12 -12
- {metrust-0.4.2 → metrust-0.4.3}/Cargo.lock +1 -1
- {metrust-0.4.2 → metrust-0.4.3}/Cargo.toml +1 -1
- {metrust-0.4.2 → metrust-0.4.3}/PKG-INFO +1 -1
- {metrust-0.4.2 → metrust-0.4.3}/benches/bench_python.py +18 -1
- {metrust-0.4.2 → metrust-0.4.3}/docs/compatibility.md +19 -9
- metrust-0.4.3/docs/delegation-ledger.md +29 -0
- {metrust-0.4.2 → metrust-0.4.3}/mkdocs.yml +1 -0
- {metrust-0.4.2 → metrust-0.4.3}/pyproject.toml +1 -1
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/calc/__init__.py +63 -18
- metrust-0.4.3/tests/run_ci_mode.py +45 -0
- metrust-0.4.3/tests/test_cookbook_replays.py +282 -0
- metrust-0.4.3/tests/test_delegation_ledger.py +187 -0
- {metrust-0.4.2 → metrust-0.4.3}/.gitignore +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/BENCHMARKS.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/README.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/VERIFICATION.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/benches/bench_hrrr.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/benches/bench_hrrr_vs_metpy.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/Cargo.toml +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/benches/calc_bench.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/atmo.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/kinematics.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/severe.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/smooth.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/thermo.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/utils.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/calc/wind.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/constants.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/interpolate/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/gempak.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/gempak_dm.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/gempak_sounding.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/gempak_surface.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/gini.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/level3.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/metar.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/station.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/io/wpc.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/lib.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/plots/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/projections.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/src/units.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/tests/test_gempak.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/metrust/tests/test_new_functions.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/Cargo.toml +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/composite.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/cache.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/catalog.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/client.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/fallback.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/idx.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/sources.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/download/streaming.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/dynamics.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/error.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/grid.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/ops.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/parser.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/search.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/streaming.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/tables.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/tests.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/unpack.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/grib2/writer.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/gridmath.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/lib.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/metfuncs.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/cfs.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/ecmwf.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/era5.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/gefs.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/gfs.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/href.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/hrrr.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/hrrr_ak.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/latest.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/mrms.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/nam.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/nbm.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/rap.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/rrfs.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/rtma.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/sref.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/urma.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/models/wpc.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/products.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/projection.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/regrid.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/ansi.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/colormap.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/contour.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/cross_section.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/encode.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/filled_contour.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/hodograph.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/mod.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/overlay.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/raster.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/skewt.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-core/src/render/station.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/Cargo.toml +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/error.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/field.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/lib.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/meta.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/projection.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/radial.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/site.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/sounding.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-field/src/time.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/Cargo.toml +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/src/composite.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/src/dynamics.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/src/gridmath.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/src/interpolate.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/src/lib.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/src/regrid.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-math/src/thermo.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/Cargo.toml +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/cells.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/color_table.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/derived.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/detection.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/level2.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/lib.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/products.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/render.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/crates/wx-radar/src/sites.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/demos/hrrr_diffusion_training.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/atmospheric.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/grid-composites.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/io.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/kinematics.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/moisture.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/severe.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/smoothing.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/thermodynamics.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/units.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/api/wind.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/guides/arrays.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/guides/installation.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/guides/migration.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/index.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/architecture.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/grid-kinematics.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/index.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/interpolation.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/io-formats.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/metpy-compatibility.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/moisture.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/parallelism.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/severe-weather.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/smoothing.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/thermodynamics.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/units-and-pint.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/methodology/wind.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/performance.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/tutorials/first-grid.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/tutorials/first-sounding.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/tutorials/reading-the-numbers.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/tutorials/recipes.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/docs/tutorials/weather-101.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/examples/cookbook_500hpa_grid.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/examples/cookbook_sounding.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/examples/sounderpy_dropin.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/__init__.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/constants/__init__.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/interpolate/__init__.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/io/__init__.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/plots/__init__.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/units.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/python/metrust/xarray.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/lib.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_atmo.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_constants.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_interpolate.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_io.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_kinematics.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_severe.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_smooth.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_thermo.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_utils.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/src/py_wind.rs +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/api_audit_calc.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/api_audit_other.md +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmark.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmark_gpu.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_01_hrrr_severe.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_02_gfs_upper_air.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_03_rap_warm_front.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_04_nam_winter.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_05_hrrr_supercell.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_06_gfs_jet.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_07_hrrr_fire.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_08_era5_tropical.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_09_rap_aviation.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_10_hrrr_squall.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_11_gfs_cold_air.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/benchmarks/bench_12_hrrr_pbl.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/sounding_3way.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/sounding_comparison.png +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_gpu_backend.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_metpy_dropin_compat.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_python_compat.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity_interp_dataset.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity_kinematics_extra.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity_remaining.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity_sounding_core.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity_thermo_layers.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity_utils_misc.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_runtime_parity_wind_profiles.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/test_signature_parity.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_constants.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_edge_cases.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_kinematics.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_severe_atmo.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_smooth_interp.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_thermo.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_units.py +0 -0
- {metrust-0.4.2 → metrust-0.4.3}/tests/verify_wind.py +0 -0
|
@@ -5,23 +5,31 @@ on:
|
|
|
5
5
|
branches: [master, main]
|
|
6
6
|
pull_request:
|
|
7
7
|
|
|
8
|
+
env:
|
|
9
|
+
METPY_VERSION: "1.7.1"
|
|
10
|
+
|
|
8
11
|
jobs:
|
|
9
|
-
|
|
12
|
+
smoke:
|
|
13
|
+
name: Smoke (${{ matrix.os }}, py${{ matrix.python-version }})
|
|
10
14
|
runs-on: ${{ matrix.os }}
|
|
11
15
|
strategy:
|
|
16
|
+
fail-fast: false
|
|
12
17
|
matrix:
|
|
13
|
-
os: [ubuntu-latest, windows-latest, macos-
|
|
14
|
-
python-version: ["3.
|
|
18
|
+
os: [ubuntu-latest, windows-latest, macos-14]
|
|
19
|
+
python-version: ["3.12"]
|
|
15
20
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
21
|
+
- uses: actions/checkout@v5
|
|
17
22
|
|
|
18
|
-
- uses: actions/setup-python@
|
|
23
|
+
- uses: actions/setup-python@v6
|
|
19
24
|
with:
|
|
20
25
|
python-version: ${{ matrix.python-version }}
|
|
21
26
|
|
|
22
27
|
- name: Install Rust
|
|
23
28
|
uses: dtolnay/rust-toolchain@stable
|
|
24
29
|
|
|
30
|
+
- name: Rust cache
|
|
31
|
+
uses: Swatinem/rust-cache@v2
|
|
32
|
+
|
|
25
33
|
- name: Install package and test deps
|
|
26
34
|
run: |
|
|
27
35
|
python -m pip install --upgrade pip
|
|
@@ -33,11 +41,47 @@ jobs:
|
|
|
33
41
|
- name: Run Python compatibility tests
|
|
34
42
|
run: python -m pytest tests/test_python_compat.py -q
|
|
35
43
|
|
|
44
|
+
differential:
|
|
45
|
+
name: Differential (${{ matrix.mode }}, py${{ matrix.python-version }})
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
strategy:
|
|
48
|
+
fail-fast: false
|
|
49
|
+
matrix:
|
|
50
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
51
|
+
mode: ["metrust-only", "metpy", "metpy-xarray"]
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/checkout@v5
|
|
54
|
+
|
|
55
|
+
- uses: actions/setup-python@v6
|
|
56
|
+
with:
|
|
57
|
+
python-version: ${{ matrix.python-version }}
|
|
58
|
+
|
|
59
|
+
- name: Install Rust
|
|
60
|
+
uses: dtolnay/rust-toolchain@stable
|
|
61
|
+
|
|
62
|
+
- name: Rust cache
|
|
63
|
+
uses: Swatinem/rust-cache@v2
|
|
64
|
+
|
|
65
|
+
- name: Install test dependencies
|
|
66
|
+
shell: bash
|
|
67
|
+
run: |
|
|
68
|
+
python -m pip install --upgrade pip
|
|
69
|
+
python -m pip install -e "." pytest numpy pint pandas
|
|
70
|
+
if [[ "${{ matrix.mode }}" != "metrust-only" ]]; then
|
|
71
|
+
python -m pip install "MetPy==${METPY_VERSION}"
|
|
72
|
+
fi
|
|
73
|
+
if [[ "${{ matrix.mode }}" == "metpy-xarray" ]]; then
|
|
74
|
+
python -m pip install xarray
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
- name: Run differential test mode
|
|
78
|
+
run: python tests/run_ci_mode.py ${{ matrix.mode }}
|
|
79
|
+
|
|
36
80
|
bench-rust:
|
|
37
81
|
name: Rust Benchmarks
|
|
38
82
|
runs-on: ubuntu-latest
|
|
39
83
|
steps:
|
|
40
|
-
- uses: actions/checkout@
|
|
84
|
+
- uses: actions/checkout@v5
|
|
41
85
|
|
|
42
86
|
- name: Install Rust
|
|
43
87
|
uses: dtolnay/rust-toolchain@stable
|
|
@@ -49,7 +93,7 @@ jobs:
|
|
|
49
93
|
run: cargo bench --package metrust --bench calc_bench
|
|
50
94
|
|
|
51
95
|
- name: Upload criterion artifacts
|
|
52
|
-
uses: actions/upload-artifact@
|
|
96
|
+
uses: actions/upload-artifact@v7
|
|
53
97
|
if: always()
|
|
54
98
|
with:
|
|
55
99
|
name: criterion-report
|
|
@@ -60,9 +104,9 @@ jobs:
|
|
|
60
104
|
name: Python Benchmarks
|
|
61
105
|
runs-on: ubuntu-latest
|
|
62
106
|
steps:
|
|
63
|
-
- uses: actions/checkout@
|
|
107
|
+
- uses: actions/checkout@v5
|
|
64
108
|
|
|
65
|
-
- uses: actions/setup-python@
|
|
109
|
+
- uses: actions/setup-python@v6
|
|
66
110
|
with:
|
|
67
111
|
python-version: "3.12"
|
|
68
112
|
|
|
@@ -75,13 +119,13 @@ jobs:
|
|
|
75
119
|
- name: Install metrust and MetPy
|
|
76
120
|
run: |
|
|
77
121
|
python -m pip install --upgrade pip
|
|
78
|
-
python -m pip install -e "." numpy pint
|
|
122
|
+
python -m pip install -e "." numpy pint "MetPy==${METPY_VERSION}"
|
|
79
123
|
|
|
80
124
|
- name: Run three-tier benchmark
|
|
81
125
|
run: python benches/bench_python.py --json
|
|
82
126
|
|
|
83
127
|
- name: Upload benchmark results
|
|
84
|
-
uses: actions/upload-artifact@
|
|
128
|
+
uses: actions/upload-artifact@v7
|
|
85
129
|
if: always()
|
|
86
130
|
with:
|
|
87
131
|
name: python-bench-results
|
|
@@ -18,13 +18,13 @@ jobs:
|
|
|
18
18
|
build:
|
|
19
19
|
runs-on: ubuntu-latest
|
|
20
20
|
steps:
|
|
21
|
-
- uses: actions/checkout@
|
|
22
|
-
- uses: actions/setup-python@
|
|
21
|
+
- uses: actions/checkout@v5
|
|
22
|
+
- uses: actions/setup-python@v6
|
|
23
23
|
with:
|
|
24
24
|
python-version: "3.12"
|
|
25
25
|
- run: pip install mkdocs-material
|
|
26
26
|
- run: mkdocs build
|
|
27
|
-
- uses: actions/upload-pages-artifact@
|
|
27
|
+
- uses: actions/upload-pages-artifact@v4
|
|
28
28
|
with:
|
|
29
29
|
path: site
|
|
30
30
|
|
|
@@ -36,4 +36,4 @@ jobs:
|
|
|
36
36
|
url: ${{ steps.deployment.outputs.page_url }}
|
|
37
37
|
steps:
|
|
38
38
|
- id: deployment
|
|
39
|
-
uses: actions/deploy-pages@
|
|
39
|
+
uses: actions/deploy-pages@v5
|
|
@@ -22,8 +22,8 @@ jobs:
|
|
|
22
22
|
- runner: ubuntu-22.04
|
|
23
23
|
target: aarch64
|
|
24
24
|
steps:
|
|
25
|
-
- uses: actions/checkout@
|
|
26
|
-
- uses: actions/setup-python@
|
|
25
|
+
- uses: actions/checkout@v5
|
|
26
|
+
- uses: actions/setup-python@v6
|
|
27
27
|
with:
|
|
28
28
|
python-version: '3.12'
|
|
29
29
|
- name: Build wheels
|
|
@@ -33,7 +33,7 @@ jobs:
|
|
|
33
33
|
args: --release --out dist -i python3.10 python3.11 python3.12 python3.13
|
|
34
34
|
manylinux: auto
|
|
35
35
|
- name: Upload wheels
|
|
36
|
-
uses: actions/upload-artifact@
|
|
36
|
+
uses: actions/upload-artifact@v7
|
|
37
37
|
with:
|
|
38
38
|
name: wheels-linux-${{ matrix.platform.target }}
|
|
39
39
|
path: dist
|
|
@@ -50,8 +50,8 @@ jobs:
|
|
|
50
50
|
- runner: macos-14
|
|
51
51
|
target: aarch64
|
|
52
52
|
steps:
|
|
53
|
-
- uses: actions/checkout@
|
|
54
|
-
- uses: actions/setup-python@
|
|
53
|
+
- uses: actions/checkout@v5
|
|
54
|
+
- uses: actions/setup-python@v6
|
|
55
55
|
with:
|
|
56
56
|
python-version: '3.12'
|
|
57
57
|
- name: Build wheels
|
|
@@ -60,7 +60,7 @@ jobs:
|
|
|
60
60
|
target: ${{ matrix.platform.target }}
|
|
61
61
|
args: --release --out dist
|
|
62
62
|
- name: Upload wheels
|
|
63
|
-
uses: actions/upload-artifact@
|
|
63
|
+
uses: actions/upload-artifact@v7
|
|
64
64
|
with:
|
|
65
65
|
name: wheels-macos-${{ matrix.platform.target }}
|
|
66
66
|
path: dist
|
|
@@ -72,8 +72,8 @@ jobs:
|
|
|
72
72
|
matrix:
|
|
73
73
|
target: [x64]
|
|
74
74
|
steps:
|
|
75
|
-
- uses: actions/checkout@
|
|
76
|
-
- uses: actions/setup-python@
|
|
75
|
+
- uses: actions/checkout@v5
|
|
76
|
+
- uses: actions/setup-python@v6
|
|
77
77
|
with:
|
|
78
78
|
python-version: '3.12'
|
|
79
79
|
architecture: ${{ matrix.target }}
|
|
@@ -82,7 +82,7 @@ jobs:
|
|
|
82
82
|
with:
|
|
83
83
|
args: --release --out dist
|
|
84
84
|
- name: Upload wheels
|
|
85
|
-
uses: actions/upload-artifact@
|
|
85
|
+
uses: actions/upload-artifact@v7
|
|
86
86
|
with:
|
|
87
87
|
name: wheels-windows-${{ matrix.target }}
|
|
88
88
|
path: dist
|
|
@@ -91,14 +91,14 @@ jobs:
|
|
|
91
91
|
sdist:
|
|
92
92
|
runs-on: ubuntu-latest
|
|
93
93
|
steps:
|
|
94
|
-
- uses: actions/checkout@
|
|
94
|
+
- uses: actions/checkout@v5
|
|
95
95
|
- name: Build sdist
|
|
96
96
|
uses: PyO3/maturin-action@v1
|
|
97
97
|
with:
|
|
98
98
|
command: sdist
|
|
99
99
|
args: --out dist
|
|
100
100
|
- name: Upload sdist
|
|
101
|
-
uses: actions/upload-artifact@
|
|
101
|
+
uses: actions/upload-artifact@v7
|
|
102
102
|
with:
|
|
103
103
|
name: wheels-sdist
|
|
104
104
|
path: dist
|
|
@@ -115,7 +115,7 @@ jobs:
|
|
|
115
115
|
id-token: write # trusted publishing
|
|
116
116
|
steps:
|
|
117
117
|
- name: Download all wheels
|
|
118
|
-
uses: actions/download-artifact@
|
|
118
|
+
uses: actions/download-artifact@v8
|
|
119
119
|
with:
|
|
120
120
|
pattern: wheels-*
|
|
121
121
|
merge-multiple: true
|
|
@@ -127,6 +127,7 @@ _raw_calc = None # metrust._metrust.calc (T1)
|
|
|
127
127
|
_mr_calc = None # metrust.calc (T2 -- Pint wrapper)
|
|
128
128
|
_mp_calc = None # metpy.calc (T3)
|
|
129
129
|
_mp_units = None # metpy.units.units
|
|
130
|
+
_mr_units = None # metrust.units.units
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
def _import_raw():
|
|
@@ -145,6 +146,14 @@ def _import_metrust():
|
|
|
145
146
|
return _mr_calc
|
|
146
147
|
|
|
147
148
|
|
|
149
|
+
def _import_metrust_units():
|
|
150
|
+
global _mr_units
|
|
151
|
+
if _mr_units is None:
|
|
152
|
+
from metrust.units import units as mu
|
|
153
|
+
_mr_units = mu
|
|
154
|
+
return _mr_units
|
|
155
|
+
|
|
156
|
+
|
|
148
157
|
def _import_metpy():
|
|
149
158
|
global _mp_calc, _mp_units
|
|
150
159
|
if _mp_calc is None:
|
|
@@ -345,8 +354,16 @@ def _bench_wind(tiers):
|
|
|
345
354
|
lambda: rc.storm_relative_helicity(u_p, v_p, z_p, 1000.0, 10.0, 5.0)))
|
|
346
355
|
if 2 in tiers:
|
|
347
356
|
mc = _import_metrust()
|
|
357
|
+
mu = _import_metrust_units()
|
|
348
358
|
results.append(run_bench(name, 2, "T2 metrust+Pint",
|
|
349
|
-
lambda: mc.storm_relative_helicity(
|
|
359
|
+
lambda: mc.storm_relative_helicity(
|
|
360
|
+
z_p * mu.meter,
|
|
361
|
+
u_p * mu("m/s"),
|
|
362
|
+
v_p * mu("m/s"),
|
|
363
|
+
1000 * mu.meter,
|
|
364
|
+
storm_u=10 * mu("m/s"),
|
|
365
|
+
storm_v=5 * mu("m/s"),
|
|
366
|
+
)))
|
|
350
367
|
if 3 in tiers:
|
|
351
368
|
try:
|
|
352
369
|
mpc, mu = _import_metpy()
|
|
@@ -17,13 +17,23 @@ calculation surface.
|
|
|
17
17
|
| Tier | Description |
|
|
18
18
|
|------|-------------|
|
|
19
19
|
| **Native Rust** | Function is implemented entirely in Rust. The Python wrapper strips Pint units, calls the Rust function, and re-attaches units. No MetPy dependency. |
|
|
20
|
+
| **Native + Optional MetPy Delegation** | Function uses the Rust path by default, but can delegate specific parity-sensitive call forms to MetPy when MetPy is installed. |
|
|
20
21
|
| **Native + Rust Array Binding** | Same as Native Rust, but the function also exposes a vectorized `_array` variant in the Rust extension so that array inputs are processed in a single FFI call instead of element-wise Python loops. 28 functions have this optimization. |
|
|
21
22
|
| **MetPy Shim** | Module forwards attribute lookups to the corresponding MetPy module via lazy import. MetPy must be installed separately. Used for `plots`, `xarray`, and `io.Level2File`. |
|
|
22
23
|
|
|
23
|
-
When MetPy is not installed, all `metrust.calc` functions still work
|
|
24
|
-
|
|
24
|
+
When MetPy is not installed, all `metrust.calc` functions still work through
|
|
25
|
+
their local metrust implementations. Only the shimmed surfaces (`metrust.plots`,
|
|
25
26
|
`metrust.xarray`, `metrust.io.Level2File`) require MetPy at runtime.
|
|
26
27
|
|
|
28
|
+
Current differential-CI target:
|
|
29
|
+
|
|
30
|
+
- `MetPy 1.7.1`
|
|
31
|
+
- Python `3.10` through `3.13`
|
|
32
|
+
- dependency modes: `metrust-only`, `metrust + MetPy`, and `metrust + MetPy + xarray`
|
|
33
|
+
|
|
34
|
+
For the exact list of parity-sensitive `metrust.calc` paths that may delegate
|
|
35
|
+
to MetPy when available, see the [delegation ledger](delegation-ledger.md).
|
|
36
|
+
|
|
27
37
|
---
|
|
28
38
|
|
|
29
39
|
## 2. metrust.calc Function Matrix
|
|
@@ -69,15 +79,15 @@ never import MetPy). Only the shimmed surfaces (`metrust.plots`,
|
|
|
69
79
|
| `mixing_ratio_from_specific_humidity` | Native + Array | `metpy.calc.mixing_ratio_from_specific_humidity` | |
|
|
70
80
|
| `specific_humidity_from_mixing_ratio` | Native + Array | `metpy.calc.specific_humidity_from_mixing_ratio` | |
|
|
71
81
|
| `lcl` | Native | `metpy.calc.lcl` | Scalar only. Returns (p_lcl, t_lcl). Rust also exposes `lcl_pressure` and `lcl_pressure_array` internally. See section 5 for approximation differences. |
|
|
72
|
-
| `lfc` | Native (profile) | `metpy.calc.lfc` |
|
|
73
|
-
| `el` | Native (profile) | `metpy.calc.el` |
|
|
74
|
-
| `cape_cin` | Native (profile) | `metpy.calc.cape_cin` | Extended signature
|
|
82
|
+
| `lfc` | Native (profile) | `metpy.calc.lfc` | Native by default; optionally delegates to MetPy for quantity-profile parity-sensitive cases. |
|
|
83
|
+
| `el` | Native (profile) | `metpy.calc.el` | Native by default; optionally delegates to MetPy for quantity-profile parity-sensitive cases. |
|
|
84
|
+
| `cape_cin` | Native (profile) | `metpy.calc.cape_cin` | Native by default; MetPy parcel-profile form can optionally delegate for exact parity. Extended signature supports parcel_type, ml_depth, mu_depth, top_m, and returns (CAPE, CIN, LCL height, LFC height). |
|
|
75
85
|
| `surface_based_cape_cin` | Native (profile) | `metpy.calc.surface_based_cape_cin` | |
|
|
76
86
|
| `mixed_layer_cape_cin` | Native (profile) | `metpy.calc.mixed_layer_cape_cin` | |
|
|
77
87
|
| `most_unstable_cape_cin` | Native (profile) | `metpy.calc.most_unstable_cape_cin` | |
|
|
78
|
-
| `downdraft_cape` | Native (profile) | `metpy.calc.downdraft_cape` | |
|
|
88
|
+
| `downdraft_cape` | Native (profile) | `metpy.calc.downdraft_cape` | Native by default; optionally delegates on quantity-profile calls when MetPy is available. |
|
|
79
89
|
| `parcel_profile` | Native (profile) | `metpy.calc.parcel_profile` | |
|
|
80
|
-
| `parcel_profile_with_lcl` | Native (profile) | `metpy.calc.parcel_profile_with_lcl` | |
|
|
90
|
+
| `parcel_profile_with_lcl` | Native (profile) | `metpy.calc.parcel_profile_with_lcl` | Native by default; optionally delegates on quantity-profile calls when MetPy is available. |
|
|
81
91
|
| `dry_lapse` | Native (profile) | `metpy.calc.dry_lapse` | |
|
|
82
92
|
| `moist_lapse` | Native (profile) | `metpy.calc.moist_lapse` | |
|
|
83
93
|
| `ccl` | Native (profile) | `metpy.calc.ccl` | Convective Condensation Level. |
|
|
@@ -178,7 +188,7 @@ major moisture conversions:
|
|
|
178
188
|
| `frontogenesis` | Native (grid) | `metpy.calc.frontogenesis` | Petterssen frontogenesis. |
|
|
179
189
|
| `geostrophic_wind` | Native (grid) | `metpy.calc.geostrophic_wind` | |
|
|
180
190
|
| `ageostrophic_wind` | Native (grid) | `metpy.calc.ageostrophic_wind` | |
|
|
181
|
-
| `potential_vorticity_baroclinic` | Native (grid) | `metpy.calc.potential_vorticity_baroclinic` | Ertel PV. |
|
|
191
|
+
| `potential_vorticity_baroclinic` | Native (grid) | `metpy.calc.potential_vorticity_baroclinic` | Ertel PV. Native by default with optional MetPy delegation on parity-sensitive quantity/DataArray calls. |
|
|
182
192
|
| `potential_vorticity_barotropic` | Native (grid) | `metpy.calc.potential_vorticity_barotropic` | |
|
|
183
193
|
| `normal_component` | Native (profile) | `metpy.calc.normal_component` | Cross-section decomposition. |
|
|
184
194
|
| `tangential_component` | Native (profile) | `metpy.calc.tangential_component` | Cross-section decomposition. |
|
|
@@ -196,7 +206,7 @@ major moisture conversions:
|
|
|
196
206
|
| `stretching_deformation` | Native (grid) | `metpy.calc.stretching_deformation` | |
|
|
197
207
|
| `total_deformation` | Native (grid) | `metpy.calc.total_deformation` | |
|
|
198
208
|
| `geospatial_gradient` | Native (grid) | (no direct MetPy equivalent) | Gradient on lat/lon grids with spherical corrections. |
|
|
199
|
-
| `geospatial_laplacian` | Native (grid) | (no direct MetPy equivalent) | Laplacian on lat/lon grids with spherical corrections. |
|
|
209
|
+
| `geospatial_laplacian` | Native (grid) | (no direct MetPy equivalent) | Laplacian on lat/lon grids with spherical corrections. Native by default with optional MetPy delegation on parity-sensitive quantity/DataArray calls. |
|
|
200
210
|
| `advection_3d` | Native (grid) | (no direct MetPy equivalent) | 3-D advection including vertical term. |
|
|
201
211
|
|
|
202
212
|
### 2.5 Severe Weather Parameters
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Optional MetPy Delegation Ledger
|
|
2
|
+
|
|
3
|
+
`metrust.calc` is Rust-first by default, but a small parity-sensitive subset can
|
|
4
|
+
delegate to `metpy.calc` when MetPy is installed. This page is the explicit
|
|
5
|
+
ledger for that behavior.
|
|
6
|
+
|
|
7
|
+
Current compatibility target:
|
|
8
|
+
|
|
9
|
+
- MetPy `1.7.1`
|
|
10
|
+
- Python `3.10` to `3.13`
|
|
11
|
+
- CI modes: `metrust-only`, `metrust + MetPy`, `metrust + MetPy + xarray`
|
|
12
|
+
|
|
13
|
+
## Calc Delegations
|
|
14
|
+
|
|
15
|
+
| Function | Delegates When | Local Fallback |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `lfc` | Quantity profile inputs, especially MetPy's more complex `which=` handling | metrust native profile intersection solver |
|
|
18
|
+
| `el` | Quantity profile inputs, especially MetPy's more complex `which=` handling | metrust native profile intersection solver |
|
|
19
|
+
| `cape_cin` | MetPy parcel-profile form where the 4th positional argument is temperature-like | metrust native CAPE/CIN integration |
|
|
20
|
+
| `downdraft_cape` | Quantity profile inputs when MetPy is available | metrust native DCAPE layer selection and integration |
|
|
21
|
+
| `parcel_profile_with_lcl` | Quantity profile inputs in the MetPy profile-returning form | metrust native interpolation and parcel-trace construction |
|
|
22
|
+
| `potential_vorticity_baroclinic` | Quantity/DataArray inputs in the MetPy-style baroclinic-PV form | metrust native PV computation with local dx/dy and latitude handling |
|
|
23
|
+
| `geospatial_laplacian` | Quantity/DataArray geospatial-laplacian inputs when MetPy is available | metrust native geospatial gradient and derivative path |
|
|
24
|
+
|
|
25
|
+
## CI Guarantees
|
|
26
|
+
|
|
27
|
+
- `tests/test_delegation_ledger.py` verifies the ledger stays in sync with the code.
|
|
28
|
+
- The same test file verifies delegated functions still run with MetPy blocked.
|
|
29
|
+
- Differential CI runs the relevant suites against pinned MetPy `1.7.1`.
|
|
@@ -43,6 +43,49 @@ class InvalidSoundingError(Exception):
|
|
|
43
43
|
_BACKEND = "cpu"
|
|
44
44
|
_GPU_CALC = None
|
|
45
45
|
|
|
46
|
+
METPY_COMPATIBILITY_TARGET = {
|
|
47
|
+
"metpy": "1.7.1",
|
|
48
|
+
"python": ("3.10", "3.11", "3.12", "3.13"),
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
METPY_OPTIONAL_CALC_DELEGATIONS = (
|
|
52
|
+
{
|
|
53
|
+
"function": "lfc",
|
|
54
|
+
"trigger": "Quantity profile inputs, with MetPy-preferred handling for complex which selections.",
|
|
55
|
+
"fallback": "Native profile intersection solver in metrust.",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"function": "el",
|
|
59
|
+
"trigger": "Quantity profile inputs, with MetPy-preferred handling for complex which selections.",
|
|
60
|
+
"fallback": "Native profile intersection solver in metrust.",
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"function": "cape_cin",
|
|
64
|
+
"trigger": "MetPy parcel-profile form where the 4th positional argument is temperature-like.",
|
|
65
|
+
"fallback": "Native CAPE/CIN integration path in metrust.",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"function": "downdraft_cape",
|
|
69
|
+
"trigger": "Quantity profile inputs when MetPy is available.",
|
|
70
|
+
"fallback": "Native metrust DCAPE layer-selection and integration path.",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"function": "parcel_profile_with_lcl",
|
|
74
|
+
"trigger": "Quantity profile inputs in the profile-returning MetPy form.",
|
|
75
|
+
"fallback": "Native metrust profile interpolation and parcel trace path.",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"function": "potential_vorticity_baroclinic",
|
|
79
|
+
"trigger": "Quantity/DataArray inputs in the MetPy-style baroclinic PV calling form.",
|
|
80
|
+
"fallback": "Native metrust PV computation with local dx/dy and latitude handling.",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"function": "geospatial_laplacian",
|
|
84
|
+
"trigger": "Quantity/DataArray geospatial laplacian inputs when MetPy is available.",
|
|
85
|
+
"fallback": "Native metrust geospatial gradient and derivative path.",
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
|
|
46
89
|
|
|
47
90
|
def _normalize_backend_name(backend):
|
|
48
91
|
name = str(backend).strip().lower()
|
|
@@ -5386,6 +5429,12 @@ def geospatial_laplacian(f, *args, dx=None, dy=None, x_dim=-1, y_dim=-2,
|
|
|
5386
5429
|
dx, dy = _resolve_dx_dy(f, dx=dx, dy=dy, latitude=latitude, longitude=longitude)
|
|
5387
5430
|
if dx is None or dy is None:
|
|
5388
5431
|
raise TypeError("geospatial_laplacian requires dx/dy or inferable latitude/longitude coordinates")
|
|
5432
|
+
if hasattr(f, "magnitude"):
|
|
5433
|
+
f_arr = np.asarray(f.magnitude, dtype=np.float64)
|
|
5434
|
+
elif _is_dataarray_like(f):
|
|
5435
|
+
f_arr = np.asarray(f.values, dtype=np.float64)
|
|
5436
|
+
else:
|
|
5437
|
+
f_arr = np.asarray(f, dtype=np.float64)
|
|
5389
5438
|
if parallel_scale is None and meridional_scale is None:
|
|
5390
5439
|
ps, ms = _get_scale_factors(f)
|
|
5391
5440
|
parallel_scale = ps if ps is not None else parallel_scale
|
|
@@ -5403,13 +5452,13 @@ def geospatial_laplacian(f, *args, dx=None, dy=None, x_dim=-1, y_dim=-2,
|
|
|
5403
5452
|
longitude=longitude,
|
|
5404
5453
|
crs=crs,
|
|
5405
5454
|
)
|
|
5406
|
-
x_axis = x_dim %
|
|
5407
|
-
y_axis = y_dim %
|
|
5455
|
+
x_axis = x_dim % f_arr.ndim
|
|
5456
|
+
y_axis = y_dim % f_arr.ndim
|
|
5408
5457
|
term_x = first_derivative(grad_u, delta=dx, axis=x_axis)
|
|
5409
5458
|
term_y = first_derivative(grad_v, delta=dy, axis=y_axis)
|
|
5410
5459
|
return term_x + term_y
|
|
5411
|
-
x_axis = x_dim %
|
|
5412
|
-
y_axis = y_dim %
|
|
5460
|
+
x_axis = x_dim % f_arr.ndim
|
|
5461
|
+
y_axis = y_dim % f_arr.ndim
|
|
5413
5462
|
return second_derivative(f, delta=dx, axis=x_axis) + second_derivative(f, delta=dy, axis=y_axis)
|
|
5414
5463
|
|
|
5415
5464
|
|
|
@@ -6164,12 +6213,15 @@ def smooth_window(scalar_grid, window, passes=1, normalize_weights=True):
|
|
|
6164
6213
|
)
|
|
6165
6214
|
|
|
6166
6215
|
data_units = getattr(scalar_grid, "units", None)
|
|
6216
|
+
unit_str = str(data_units) if data_units is not None else None
|
|
6217
|
+
if unit_str is None:
|
|
6218
|
+
unit_str = getattr(getattr(scalar_grid, "attrs", None), "get", lambda *_: None)("units")
|
|
6167
6219
|
data = np.array(getattr(scalar_grid, "magnitude", scalar_grid))
|
|
6168
6220
|
for _ in range(int(passes)):
|
|
6169
6221
|
data[inner_full_index] = sum(
|
|
6170
6222
|
weights[index] * data[offset_full_index(index)] for index in weight_indexes
|
|
6171
6223
|
)
|
|
6172
|
-
return data
|
|
6224
|
+
return _wrap_result_like(scalar_grid, data, unit_str=unit_str)
|
|
6173
6225
|
|
|
6174
6226
|
|
|
6175
6227
|
def _gradient_axes_and_positions(f, axes, coordinates, deltas):
|
|
@@ -8222,19 +8274,12 @@ class _MetPyCalcSignatureHook(importlib.abc.MetaPathFinder, importlib.abc.Loader
|
|
|
8222
8274
|
if fullname != "metpy.calc":
|
|
8223
8275
|
return None
|
|
8224
8276
|
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
spec = find_spec(fullname, path, target)
|
|
8232
|
-
if spec is None:
|
|
8233
|
-
continue
|
|
8234
|
-
self._wrapped_loader = spec.loader
|
|
8235
|
-
spec.loader = self
|
|
8236
|
-
return spec
|
|
8237
|
-
return None
|
|
8277
|
+
spec = importlib.machinery.PathFinder.find_spec(fullname, path)
|
|
8278
|
+
if spec is None:
|
|
8279
|
+
return None
|
|
8280
|
+
self._wrapped_loader = spec.loader
|
|
8281
|
+
spec.loader = self
|
|
8282
|
+
return spec
|
|
8238
8283
|
|
|
8239
8284
|
def create_module(self, spec):
|
|
8240
8285
|
if self._wrapped_loader is not None and hasattr(self._wrapped_loader, "create_module"):
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
MODE_TESTS = {
|
|
8
|
+
"metrust-only": [
|
|
9
|
+
"tests/test_python_compat.py",
|
|
10
|
+
"tests/test_delegation_ledger.py",
|
|
11
|
+
],
|
|
12
|
+
"metpy": [
|
|
13
|
+
"tests/test_signature_parity.py",
|
|
14
|
+
"tests/test_runtime_parity.py",
|
|
15
|
+
"tests/test_runtime_parity_sounding_core.py",
|
|
16
|
+
"tests/test_runtime_parity_thermo_layers.py",
|
|
17
|
+
"tests/test_runtime_parity_wind_profiles.py",
|
|
18
|
+
"tests/test_runtime_parity_remaining.py",
|
|
19
|
+
"tests/test_delegation_ledger.py",
|
|
20
|
+
"tests/test_cookbook_replays.py::test_cookbook_sounding_workflow_replay",
|
|
21
|
+
],
|
|
22
|
+
"metpy-xarray": [
|
|
23
|
+
"tests/test_metpy_dropin_compat.py",
|
|
24
|
+
"tests/test_runtime_parity_interp_dataset.py",
|
|
25
|
+
"tests/test_runtime_parity_kinematics_extra.py",
|
|
26
|
+
"tests/test_runtime_parity_utils_misc.py",
|
|
27
|
+
"tests/test_delegation_ledger.py",
|
|
28
|
+
"tests/test_cookbook_replays.py::test_cookbook_grid_workflow_replay",
|
|
29
|
+
"tests/test_cookbook_replays.py::test_cookbook_xarray_workflow_replay",
|
|
30
|
+
],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def main() -> int:
|
|
35
|
+
if len(sys.argv) != 2 or sys.argv[1] not in MODE_TESTS:
|
|
36
|
+
valid = ", ".join(sorted(MODE_TESTS))
|
|
37
|
+
raise SystemExit(f"usage: {sys.argv[0]} <mode>; valid modes: {valid}")
|
|
38
|
+
|
|
39
|
+
mode = sys.argv[1]
|
|
40
|
+
cmd = [sys.executable, "-m", "pytest", "-q", *MODE_TESTS[mode]]
|
|
41
|
+
return subprocess.call(cmd)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == "__main__":
|
|
45
|
+
raise SystemExit(main())
|