metrust 0.3.3__tar.gz → 0.3.5__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.3.3 → metrust-0.3.5}/Cargo.lock +6 -6
- {metrust-0.3.3 → metrust-0.3.5}/Cargo.toml +1 -1
- metrust-0.3.5/PKG-INFO +157 -0
- metrust-0.3.5/README.md +134 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/Cargo.toml +1 -1
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/interpolate/mod.rs +11 -5
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/Cargo.toml +1 -1
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/Cargo.toml +1 -1
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-math/Cargo.toml +1 -1
- metrust-0.3.5/crates/wx-math/src/interpolate.rs +174 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-math/src/lib.rs +1 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/Cargo.toml +1 -1
- {metrust-0.3.3 → metrust-0.3.5}/docs/index.md +33 -16
- {metrust-0.3.3 → metrust-0.3.5}/pyproject.toml +1 -1
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/calc/__init__.py +386 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_interpolate.rs +59 -2
- metrust-0.3.3/PKG-INFO +0 -231
- metrust-0.3.3/README.md +0 -208
- {metrust-0.3.3 → metrust-0.3.5}/.github/workflows/ci.yml +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/.github/workflows/docs.yml +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/.github/workflows/release.yml +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/.gitignore +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/VERIFICATION.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/benches/bench_hrrr.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/benches/bench_hrrr_vs_metpy.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/benches/bench_python.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/benches/calc_bench.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/atmo.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/kinematics.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/mod.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/severe.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/smooth.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/thermo.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/utils.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/calc/wind.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/constants.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/gempak.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/gempak_dm.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/gempak_sounding.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/gempak_surface.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/gini.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/level3.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/metar.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/mod.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/station.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/io/wpc.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/lib.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/plots/mod.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/projections.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/src/units.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/tests/test_gempak.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/metrust/tests/test_new_functions.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/composite.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/cache.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/catalog.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/client.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/fallback.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/idx.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/mod.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/sources.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/download/streaming.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/dynamics.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/error.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/grid.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/mod.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/ops.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/parser.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/search.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/streaming.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/tables.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/tests.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/unpack.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/grib2/writer.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/gridmath.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/lib.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/metfuncs.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/cfs.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/ecmwf.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/era5.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/gefs.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/gfs.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/href.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/hrrr.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/hrrr_ak.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/latest.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/mod.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/mrms.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/nam.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/nbm.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/rap.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/rrfs.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/rtma.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/sref.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/urma.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/models/wpc.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/products.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/projection.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/regrid.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/ansi.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/colormap.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/contour.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/cross_section.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/encode.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/filled_contour.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/hodograph.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/mod.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/overlay.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/raster.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/skewt.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/rustmet-core/src/render/station.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/error.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/field.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/lib.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/meta.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/projection.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/radial.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/site.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/sounding.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-field/src/time.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-math/src/composite.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-math/src/dynamics.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-math/src/gridmath.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-math/src/regrid.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-math/src/thermo.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/cells.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/color_table.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/derived.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/detection.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/level2.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/lib.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/products.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/render.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/crates/wx-radar/src/sites.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/atmospheric.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/grid-composites.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/io.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/kinematics.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/moisture.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/severe.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/smoothing.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/thermodynamics.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/units.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/api/wind.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/compatibility.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/guides/arrays.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/guides/installation.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/guides/migration.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/performance.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/tutorials/first-grid.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/tutorials/first-sounding.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/tutorials/reading-the-numbers.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/tutorials/recipes.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/docs/tutorials/weather-101.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/examples/cookbook_500hpa_grid.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/examples/cookbook_sounding.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/examples/sounderpy_dropin.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/mkdocs.yml +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/__init__.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/constants/__init__.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/interpolate/__init__.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/io/__init__.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/plots/__init__.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/units.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/python/metrust/xarray.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/lib.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_atmo.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_constants.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_io.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_kinematics.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_severe.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_smooth.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_thermo.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_utils.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/src/py_wind.rs +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/api_audit_calc.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/api_audit_other.md +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/benchmark.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/test_metpy_dropin_compat.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/test_python_compat.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_constants.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_edge_cases.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_kinematics.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_severe_atmo.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_smooth_interp.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_thermo.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_units.py +0 -0
- {metrust-0.3.3 → metrust-0.3.5}/tests/verify_wind.py +0 -0
|
@@ -788,7 +788,7 @@ dependencies = [
|
|
|
788
788
|
|
|
789
789
|
[[package]]
|
|
790
790
|
name = "metrust"
|
|
791
|
-
version = "0.3.
|
|
791
|
+
version = "0.3.5"
|
|
792
792
|
dependencies = [
|
|
793
793
|
"chrono",
|
|
794
794
|
"criterion",
|
|
@@ -802,7 +802,7 @@ dependencies = [
|
|
|
802
802
|
|
|
803
803
|
[[package]]
|
|
804
804
|
name = "metrust-py"
|
|
805
|
-
version = "0.3.
|
|
805
|
+
version = "0.3.5"
|
|
806
806
|
dependencies = [
|
|
807
807
|
"metrust",
|
|
808
808
|
"numpy",
|
|
@@ -1419,7 +1419,7 @@ dependencies = [
|
|
|
1419
1419
|
|
|
1420
1420
|
[[package]]
|
|
1421
1421
|
name = "rustmet-core"
|
|
1422
|
-
version = "0.3.
|
|
1422
|
+
version = "0.3.5"
|
|
1423
1423
|
dependencies = [
|
|
1424
1424
|
"chrono",
|
|
1425
1425
|
"flate2",
|
|
@@ -1934,14 +1934,14 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
|
1934
1934
|
|
|
1935
1935
|
[[package]]
|
|
1936
1936
|
name = "wx-field"
|
|
1937
|
-
version = "0.3.
|
|
1937
|
+
version = "0.3.5"
|
|
1938
1938
|
dependencies = [
|
|
1939
1939
|
"chrono",
|
|
1940
1940
|
]
|
|
1941
1941
|
|
|
1942
1942
|
[[package]]
|
|
1943
1943
|
name = "wx-math"
|
|
1944
|
-
version = "0.3.
|
|
1944
|
+
version = "0.3.5"
|
|
1945
1945
|
dependencies = [
|
|
1946
1946
|
"rayon",
|
|
1947
1947
|
"wx-field",
|
|
@@ -1949,7 +1949,7 @@ dependencies = [
|
|
|
1949
1949
|
|
|
1950
1950
|
[[package]]
|
|
1951
1951
|
name = "wx-radar"
|
|
1952
|
-
version = "0.3.
|
|
1952
|
+
version = "0.3.5"
|
|
1953
1953
|
dependencies = [
|
|
1954
1954
|
"byteorder",
|
|
1955
1955
|
"bzip2",
|
metrust-0.3.5/PKG-INFO
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: metrust
|
|
3
|
+
Version: 0.3.5
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Science/Research
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Programming Language :: Rust
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
|
|
10
|
+
Requires-Dist: numpy>=1.20
|
|
11
|
+
Requires-Dist: pint>=0.20
|
|
12
|
+
Summary: Rust-powered drop-in replacement for MetPy -- 150/150 calc functions plus 36 extras, 10-93000x faster
|
|
13
|
+
Keywords: meteorology,weather,rust,metpy,atmospheric-science,nwp,cape,sounding
|
|
14
|
+
Author: Fahrenheit Research
|
|
15
|
+
License: MIT
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
18
|
+
Project-URL: Documentation, https://fahrenheitresearch.github.io/metrust-py/
|
|
19
|
+
Project-URL: Homepage, https://github.com/FahrenheitResearch/metrust-py
|
|
20
|
+
Project-URL: Issues, https://github.com/FahrenheitResearch/metrust-py/issues
|
|
21
|
+
Project-URL: Repository, https://github.com/FahrenheitResearch/metrust-py
|
|
22
|
+
|
|
23
|
+
# metrust
|
|
24
|
+
|
|
25
|
+
**Drop-in replacement for MetPy's calculation layer, powered by Rust.**
|
|
26
|
+
|
|
27
|
+
150/150 `metpy.calc` functions implemented natively, plus 36 extras. 6-30x faster on real-world workflows. Verified against MetPy on SounderPy, MetPy Cookbook examples, and synthetic global grids.
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
# The only change: swap the import
|
|
31
|
+
from metrust.calc import cape_cin, potential_temperature, vorticity
|
|
32
|
+
from metrust.units import units
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install metrust
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
For plotting, xarray accessor, or Level2File (forwarded to MetPy):
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install metrust metpy
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## What It Does
|
|
48
|
+
|
|
49
|
+
metrust implements every function in `metpy.calc` with a Rust backend compiled via PyO3. The Python API matches MetPy's signatures, units, and return types:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import numpy as np
|
|
53
|
+
from metrust.calc import (
|
|
54
|
+
cape_cin, parcel_profile, bunkers_storm_motion,
|
|
55
|
+
storm_relative_helicity, significant_tornado_parameter,
|
|
56
|
+
vorticity, divergence, advection,
|
|
57
|
+
)
|
|
58
|
+
from metrust.units import units
|
|
59
|
+
|
|
60
|
+
# Sounding analysis (same API as MetPy)
|
|
61
|
+
p = np.array([1000, 925, 850, 700, 500, 300]) * units.hPa
|
|
62
|
+
T = np.array([25, 20, 15, 5, -15, -40]) * units.degC
|
|
63
|
+
Td = np.array([20, 15, 10, -5, -25, -50]) * units.degC
|
|
64
|
+
|
|
65
|
+
prof = parcel_profile(p, T[0], Td[0])
|
|
66
|
+
cape, cin = cape_cin(p, T, Td, prof) # MetPy parcel_profile form works
|
|
67
|
+
|
|
68
|
+
# Grid kinematics with xarray (dx/dy inferred from lat/lon coords)
|
|
69
|
+
vort = vorticity(u_xarray, v_xarray) # spherical metric corrections included
|
|
70
|
+
div = divergence(u_xarray, v_xarray)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Speed
|
|
74
|
+
|
|
75
|
+
Benchmarked on real-world workflows (v0.3.3, validated by Codex against MetPy):
|
|
76
|
+
|
|
77
|
+
| Workflow | Speedup | Notes |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| MetPy Cookbook sounding analysis | **6.0x** | Full severe weather stack |
|
|
80
|
+
| MetPy Cookbook 500 hPa grid | **6.1x** | Vorticity, smoothing, advection |
|
|
81
|
+
| MetPy Cookbook Q-vectors | **6.1x** | Q-vector divergence |
|
|
82
|
+
| SounderPy compute-heavy subset | **29.7x** | Thermo + wind + severe params |
|
|
83
|
+
| MetPy isentropic example | **2.3x** | Isentropic interpolation + Montgomery |
|
|
84
|
+
| Vorticity/divergence (global grid) | **2.3x** | Spherical corrections on 721x1440 |
|
|
85
|
+
|
|
86
|
+
Array operations on 1M elements (32-core Ryzen, rayon parallel):
|
|
87
|
+
|
|
88
|
+
| Function | Time | Throughput |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| `potential_temperature` | 1.8 ms | 550 M/s |
|
|
91
|
+
| `wet_bulb_temperature` | 7.3 ms | 137 M/s |
|
|
92
|
+
| `wind_speed` | 1.5 ms | 660 M/s |
|
|
93
|
+
|
|
94
|
+
## Numerical Parity
|
|
95
|
+
|
|
96
|
+
Verified on the MetPy OUN 2011-05-22 12Z test sounding:
|
|
97
|
+
|
|
98
|
+
| Metric | Difference from MetPy |
|
|
99
|
+
|---|---|
|
|
100
|
+
| CAPE | +4.0 J/kg |
|
|
101
|
+
| MUCAPE | +7.6 J/kg |
|
|
102
|
+
| SRH (0-1 km) | +0.3 m^2/s^2 |
|
|
103
|
+
| Critical angle | +0.2 deg |
|
|
104
|
+
| Bunkers RM | +0.02 m/s |
|
|
105
|
+
| STP | +0.01 |
|
|
106
|
+
| Montgomery streamfunction | corr 1.0000 |
|
|
107
|
+
| Isentropic pressure | 7e-13 hPa diff |
|
|
108
|
+
| Vorticity (global lat/lon) | corr 1.0000 |
|
|
109
|
+
|
|
110
|
+
Uses MetPy-exact physical constants (Rd, Cp, Lv, epsilon), MetPy's CAPE integration formula (`g * dTv/Tv * dz`), pressure-weighted Bunkers algorithm, Newton solver for isentropic interpolation, and spherical metric tensor corrections for lat/lon grid kinematics.
|
|
111
|
+
|
|
112
|
+
## Coverage
|
|
113
|
+
|
|
114
|
+
- **150/150** `metpy.calc` functions (100% coverage)
|
|
115
|
+
- **36 extras** not in MetPy (grid composites, fire weather indices, etc.)
|
|
116
|
+
- **28 Rust array bindings** with rayon parallelism and GIL release
|
|
117
|
+
- **Pint application registry** shared with MetPy (no cross-registry errors)
|
|
118
|
+
- **xarray support** with coordinate inference and shape preservation
|
|
119
|
+
|
|
120
|
+
## What's Not Native
|
|
121
|
+
|
|
122
|
+
These forward to MetPy when installed:
|
|
123
|
+
|
|
124
|
+
- `metrust.plots` (matplotlib-based plotting)
|
|
125
|
+
- `metrust.xarray` (xarray accessor)
|
|
126
|
+
- `metrust.io.Level2File` (NEXRAD Level II)
|
|
127
|
+
|
|
128
|
+
Core `metrust.calc` is 100% native Rust with no MetPy dependency.
|
|
129
|
+
|
|
130
|
+
## Examples
|
|
131
|
+
|
|
132
|
+
See `examples/` for complete drop-in demos:
|
|
133
|
+
|
|
134
|
+
- `cookbook_sounding.py` — MetPy Cookbook sounding analysis
|
|
135
|
+
- `cookbook_500hpa_grid.py` — MetPy Cookbook 500 hPa vorticity advection
|
|
136
|
+
- `sounderpy_dropin.py` — SounderPy-style full sounding pipeline
|
|
137
|
+
|
|
138
|
+
## Testing
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
cargo test --workspace # 1,186 Rust tests
|
|
142
|
+
python -m pytest tests/ -q # 20 Python tests (including MetPy drop-in regression)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Documentation
|
|
146
|
+
|
|
147
|
+
Full docs at [fahrenheitresearch.github.io/metrust-py](https://fahrenheitresearch.github.io/metrust-py/), including:
|
|
148
|
+
|
|
149
|
+
- API reference for all 186 functions
|
|
150
|
+
- Beginner tutorials (Weather 101, soundings, grids, recipes)
|
|
151
|
+
- Migration guide from MetPy
|
|
152
|
+
- Performance benchmarks
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
157
|
+
|
metrust-0.3.5/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# metrust
|
|
2
|
+
|
|
3
|
+
**Drop-in replacement for MetPy's calculation layer, powered by Rust.**
|
|
4
|
+
|
|
5
|
+
150/150 `metpy.calc` functions implemented natively, plus 36 extras. 6-30x faster on real-world workflows. Verified against MetPy on SounderPy, MetPy Cookbook examples, and synthetic global grids.
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
# The only change: swap the import
|
|
9
|
+
from metrust.calc import cape_cin, potential_temperature, vorticity
|
|
10
|
+
from metrust.units import units
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install metrust
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For plotting, xarray accessor, or Level2File (forwarded to MetPy):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install metrust metpy
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## What It Does
|
|
26
|
+
|
|
27
|
+
metrust implements every function in `metpy.calc` with a Rust backend compiled via PyO3. The Python API matches MetPy's signatures, units, and return types:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import numpy as np
|
|
31
|
+
from metrust.calc import (
|
|
32
|
+
cape_cin, parcel_profile, bunkers_storm_motion,
|
|
33
|
+
storm_relative_helicity, significant_tornado_parameter,
|
|
34
|
+
vorticity, divergence, advection,
|
|
35
|
+
)
|
|
36
|
+
from metrust.units import units
|
|
37
|
+
|
|
38
|
+
# Sounding analysis (same API as MetPy)
|
|
39
|
+
p = np.array([1000, 925, 850, 700, 500, 300]) * units.hPa
|
|
40
|
+
T = np.array([25, 20, 15, 5, -15, -40]) * units.degC
|
|
41
|
+
Td = np.array([20, 15, 10, -5, -25, -50]) * units.degC
|
|
42
|
+
|
|
43
|
+
prof = parcel_profile(p, T[0], Td[0])
|
|
44
|
+
cape, cin = cape_cin(p, T, Td, prof) # MetPy parcel_profile form works
|
|
45
|
+
|
|
46
|
+
# Grid kinematics with xarray (dx/dy inferred from lat/lon coords)
|
|
47
|
+
vort = vorticity(u_xarray, v_xarray) # spherical metric corrections included
|
|
48
|
+
div = divergence(u_xarray, v_xarray)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Speed
|
|
52
|
+
|
|
53
|
+
Benchmarked on real-world workflows (v0.3.3, validated by Codex against MetPy):
|
|
54
|
+
|
|
55
|
+
| Workflow | Speedup | Notes |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| MetPy Cookbook sounding analysis | **6.0x** | Full severe weather stack |
|
|
58
|
+
| MetPy Cookbook 500 hPa grid | **6.1x** | Vorticity, smoothing, advection |
|
|
59
|
+
| MetPy Cookbook Q-vectors | **6.1x** | Q-vector divergence |
|
|
60
|
+
| SounderPy compute-heavy subset | **29.7x** | Thermo + wind + severe params |
|
|
61
|
+
| MetPy isentropic example | **2.3x** | Isentropic interpolation + Montgomery |
|
|
62
|
+
| Vorticity/divergence (global grid) | **2.3x** | Spherical corrections on 721x1440 |
|
|
63
|
+
|
|
64
|
+
Array operations on 1M elements (32-core Ryzen, rayon parallel):
|
|
65
|
+
|
|
66
|
+
| Function | Time | Throughput |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `potential_temperature` | 1.8 ms | 550 M/s |
|
|
69
|
+
| `wet_bulb_temperature` | 7.3 ms | 137 M/s |
|
|
70
|
+
| `wind_speed` | 1.5 ms | 660 M/s |
|
|
71
|
+
|
|
72
|
+
## Numerical Parity
|
|
73
|
+
|
|
74
|
+
Verified on the MetPy OUN 2011-05-22 12Z test sounding:
|
|
75
|
+
|
|
76
|
+
| Metric | Difference from MetPy |
|
|
77
|
+
|---|---|
|
|
78
|
+
| CAPE | +4.0 J/kg |
|
|
79
|
+
| MUCAPE | +7.6 J/kg |
|
|
80
|
+
| SRH (0-1 km) | +0.3 m^2/s^2 |
|
|
81
|
+
| Critical angle | +0.2 deg |
|
|
82
|
+
| Bunkers RM | +0.02 m/s |
|
|
83
|
+
| STP | +0.01 |
|
|
84
|
+
| Montgomery streamfunction | corr 1.0000 |
|
|
85
|
+
| Isentropic pressure | 7e-13 hPa diff |
|
|
86
|
+
| Vorticity (global lat/lon) | corr 1.0000 |
|
|
87
|
+
|
|
88
|
+
Uses MetPy-exact physical constants (Rd, Cp, Lv, epsilon), MetPy's CAPE integration formula (`g * dTv/Tv * dz`), pressure-weighted Bunkers algorithm, Newton solver for isentropic interpolation, and spherical metric tensor corrections for lat/lon grid kinematics.
|
|
89
|
+
|
|
90
|
+
## Coverage
|
|
91
|
+
|
|
92
|
+
- **150/150** `metpy.calc` functions (100% coverage)
|
|
93
|
+
- **36 extras** not in MetPy (grid composites, fire weather indices, etc.)
|
|
94
|
+
- **28 Rust array bindings** with rayon parallelism and GIL release
|
|
95
|
+
- **Pint application registry** shared with MetPy (no cross-registry errors)
|
|
96
|
+
- **xarray support** with coordinate inference and shape preservation
|
|
97
|
+
|
|
98
|
+
## What's Not Native
|
|
99
|
+
|
|
100
|
+
These forward to MetPy when installed:
|
|
101
|
+
|
|
102
|
+
- `metrust.plots` (matplotlib-based plotting)
|
|
103
|
+
- `metrust.xarray` (xarray accessor)
|
|
104
|
+
- `metrust.io.Level2File` (NEXRAD Level II)
|
|
105
|
+
|
|
106
|
+
Core `metrust.calc` is 100% native Rust with no MetPy dependency.
|
|
107
|
+
|
|
108
|
+
## Examples
|
|
109
|
+
|
|
110
|
+
See `examples/` for complete drop-in demos:
|
|
111
|
+
|
|
112
|
+
- `cookbook_sounding.py` — MetPy Cookbook sounding analysis
|
|
113
|
+
- `cookbook_500hpa_grid.py` — MetPy Cookbook 500 hPa vorticity advection
|
|
114
|
+
- `sounderpy_dropin.py` — SounderPy-style full sounding pipeline
|
|
115
|
+
|
|
116
|
+
## Testing
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
cargo test --workspace # 1,186 Rust tests
|
|
120
|
+
python -m pytest tests/ -q # 20 Python tests (including MetPy drop-in regression)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Documentation
|
|
124
|
+
|
|
125
|
+
Full docs at [fahrenheitresearch.github.io/metrust-py](https://fahrenheitresearch.github.io/metrust-py/), including:
|
|
126
|
+
|
|
127
|
+
- API reference for all 186 functions
|
|
128
|
+
- Beginner tutorials (Weather 101, soundings, grids, recipes)
|
|
129
|
+
- Migration guide from MetPy
|
|
130
|
+
- Performance benchmarks
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
|
@@ -10,6 +10,9 @@ pub use wx_math::regrid::{
|
|
|
10
10
|
cross_section_data, interpolate_vertical,
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
// ── Re-exports from wx-math interpolate ─────────────────────────────
|
|
14
|
+
pub use wx_math::interpolate::inverse_distance_to_points;
|
|
15
|
+
|
|
13
16
|
// ── Convenience wrapper ─────────────────────────────────────────────
|
|
14
17
|
|
|
15
18
|
/// Interpolate scattered values onto a regular lat/lon grid.
|
|
@@ -270,12 +273,15 @@ pub fn inverse_distance_to_grid(
|
|
|
270
273
|
out
|
|
271
274
|
}
|
|
272
275
|
|
|
273
|
-
/// Inverse distance weighted (IDW) interpolation to arbitrary points.
|
|
276
|
+
/// Inverse distance weighted (IDW) interpolation to arbitrary points (legacy API).
|
|
274
277
|
///
|
|
275
278
|
/// Same algorithm as [`inverse_distance_to_grid`] but evaluates at
|
|
276
279
|
/// the supplied `(target_lats, target_lons)` positions instead of a
|
|
277
280
|
/// regular grid.
|
|
278
|
-
|
|
281
|
+
///
|
|
282
|
+
/// For the newer Barnes/Cressman-capable variant, see the re-exported
|
|
283
|
+
/// [`inverse_distance_to_points`] from `wx_math::interpolate`.
|
|
284
|
+
pub fn inverse_distance_to_points_legacy(
|
|
279
285
|
src_lats: &[f64],
|
|
280
286
|
src_lons: &[f64],
|
|
281
287
|
src_values: &[f64],
|
|
@@ -627,7 +633,7 @@ pub fn interpolate_to_points(
|
|
|
627
633
|
}
|
|
628
634
|
_ => {
|
|
629
635
|
// Default to inverse distance (idw / linear)
|
|
630
|
-
|
|
636
|
+
inverse_distance_to_points_legacy(
|
|
631
637
|
src_lats, src_lons, src_values,
|
|
632
638
|
target_lats, target_lons,
|
|
633
639
|
2.0, // power
|
|
@@ -1000,7 +1006,7 @@ mod tests {
|
|
|
1000
1006
|
// Target at midpoint.
|
|
1001
1007
|
let tgt_lats = vec![31.0];
|
|
1002
1008
|
let tgt_lons = vec![-90.0];
|
|
1003
|
-
let out =
|
|
1009
|
+
let out = inverse_distance_to_points_legacy(
|
|
1004
1010
|
&src_lats, &src_lons, &src_vals,
|
|
1005
1011
|
&tgt_lats, &tgt_lons,
|
|
1006
1012
|
2.0, 1, 5.0,
|
|
@@ -1017,7 +1023,7 @@ mod tests {
|
|
|
1017
1023
|
// Target exactly at first source point.
|
|
1018
1024
|
let tgt_lats = vec![40.0];
|
|
1019
1025
|
let tgt_lons = vec![-80.0];
|
|
1020
|
-
let out =
|
|
1026
|
+
let out = inverse_distance_to_points_legacy(
|
|
1021
1027
|
&src_lats, &src_lons, &src_vals,
|
|
1022
1028
|
&tgt_lats, &tgt_lons,
|
|
1023
1029
|
2.0, 1, 10.0,
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
//! Interpolation routines (Barnes, Cressman, IDW families).
|
|
2
|
+
//!
|
|
3
|
+
//! This module provides scattered-data interpolation functions that support
|
|
4
|
+
//! multiple weighting schemes via the `kind` parameter:
|
|
5
|
+
//!
|
|
6
|
+
//! * `kind = 0` -- standard inverse-distance weighting (1/d^2)
|
|
7
|
+
//! * `kind = 1` -- Barnes scheme (Gaussian weight controlled by `kappa` and `gamma`)
|
|
8
|
+
//! * `kind = 2` -- Cressman scheme (parabolic weight within `radius`)
|
|
9
|
+
|
|
10
|
+
/// Inverse distance weighted interpolation to arbitrary target points.
|
|
11
|
+
///
|
|
12
|
+
/// # Arguments
|
|
13
|
+
///
|
|
14
|
+
/// * `obs_x` -- observation x-coordinates (e.g. longitude or projected easting)
|
|
15
|
+
/// * `obs_y` -- observation y-coordinates (e.g. latitude or projected northing)
|
|
16
|
+
/// * `obs_values` -- observed values at each station
|
|
17
|
+
/// * `grid_x` -- target x-coordinates to interpolate onto
|
|
18
|
+
/// * `grid_y` -- target y-coordinates to interpolate onto
|
|
19
|
+
/// * `radius` -- search radius (same units as coordinates)
|
|
20
|
+
/// * `min_neighbors` -- minimum number of neighbors required; returns `NaN` if fewer
|
|
21
|
+
/// * `kind` -- weighting scheme: 0 = IDW, 1 = Barnes, 2 = Cressman
|
|
22
|
+
/// * `kappa` -- smoothing parameter for Barnes scheme
|
|
23
|
+
/// * `gamma` -- convergence parameter for Barnes scheme
|
|
24
|
+
///
|
|
25
|
+
/// # Returns
|
|
26
|
+
///
|
|
27
|
+
/// A `Vec<f64>` of length `grid_x.len()` with the interpolated values.
|
|
28
|
+
pub fn inverse_distance_to_points(
|
|
29
|
+
obs_x: &[f64],
|
|
30
|
+
obs_y: &[f64],
|
|
31
|
+
obs_values: &[f64],
|
|
32
|
+
grid_x: &[f64],
|
|
33
|
+
grid_y: &[f64],
|
|
34
|
+
radius: f64,
|
|
35
|
+
min_neighbors: usize,
|
|
36
|
+
kind: u8,
|
|
37
|
+
kappa: f64,
|
|
38
|
+
gamma: f64,
|
|
39
|
+
) -> Vec<f64> {
|
|
40
|
+
let n = obs_values.len();
|
|
41
|
+
assert_eq!(obs_x.len(), n, "obs_x length must match obs_values");
|
|
42
|
+
assert_eq!(obs_y.len(), n, "obs_y length must match obs_values");
|
|
43
|
+
assert_eq!(grid_x.len(), grid_y.len(), "grid_x and grid_y must have the same length");
|
|
44
|
+
|
|
45
|
+
let r2 = radius * radius;
|
|
46
|
+
|
|
47
|
+
grid_x
|
|
48
|
+
.iter()
|
|
49
|
+
.zip(grid_y.iter())
|
|
50
|
+
.map(|(&gx, &gy)| {
|
|
51
|
+
let mut w_sum = 0.0_f64;
|
|
52
|
+
let mut wv_sum = 0.0_f64;
|
|
53
|
+
let mut count = 0usize;
|
|
54
|
+
|
|
55
|
+
for i in 0..n {
|
|
56
|
+
let dx = gx - obs_x[i];
|
|
57
|
+
let dy = gy - obs_y[i];
|
|
58
|
+
let d2 = dx * dx + dy * dy;
|
|
59
|
+
|
|
60
|
+
if d2 > r2 {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Coincident point -- return exact value.
|
|
65
|
+
if d2 < 1e-30 {
|
|
66
|
+
return obs_values[i];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let w = match kind {
|
|
70
|
+
1 => {
|
|
71
|
+
// Barnes: w = exp(-d^2 / (kappa * gamma))
|
|
72
|
+
(-d2 / (kappa * gamma)).exp()
|
|
73
|
+
}
|
|
74
|
+
2 => {
|
|
75
|
+
// Cressman: w = (R^2 - d^2) / (R^2 + d^2)
|
|
76
|
+
(r2 - d2) / (r2 + d2)
|
|
77
|
+
}
|
|
78
|
+
_ => {
|
|
79
|
+
// Standard IDW: w = 1 / d^2
|
|
80
|
+
1.0 / d2
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
w_sum += w;
|
|
85
|
+
wv_sum += w * obs_values[i];
|
|
86
|
+
count += 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if count < min_neighbors {
|
|
90
|
+
f64::NAN
|
|
91
|
+
} else {
|
|
92
|
+
wv_sum / w_sum
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
.collect()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#[cfg(test)]
|
|
99
|
+
mod tests {
|
|
100
|
+
use super::*;
|
|
101
|
+
|
|
102
|
+
#[test]
|
|
103
|
+
fn test_idw_basic() {
|
|
104
|
+
// Two equidistant points, target at midpoint => average.
|
|
105
|
+
let obs_x = vec![0.0, 2.0];
|
|
106
|
+
let obs_y = vec![0.0, 0.0];
|
|
107
|
+
let obs_v = vec![10.0, 20.0];
|
|
108
|
+
let gx = vec![1.0];
|
|
109
|
+
let gy = vec![0.0];
|
|
110
|
+
let out = inverse_distance_to_points(
|
|
111
|
+
&obs_x, &obs_y, &obs_v, &gx, &gy,
|
|
112
|
+
10.0, 1, 0, 100000.0, 0.2,
|
|
113
|
+
);
|
|
114
|
+
assert!((out[0] - 15.0).abs() < 1e-10);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
#[test]
|
|
118
|
+
fn test_idw_coincident() {
|
|
119
|
+
let obs_x = vec![5.0];
|
|
120
|
+
let obs_y = vec![5.0];
|
|
121
|
+
let obs_v = vec![42.0];
|
|
122
|
+
let gx = vec![5.0];
|
|
123
|
+
let gy = vec![5.0];
|
|
124
|
+
let out = inverse_distance_to_points(
|
|
125
|
+
&obs_x, &obs_y, &obs_v, &gx, &gy,
|
|
126
|
+
10.0, 1, 0, 100000.0, 0.2,
|
|
127
|
+
);
|
|
128
|
+
assert!((out[0] - 42.0).abs() < 1e-10);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
#[test]
|
|
132
|
+
fn test_idw_too_few_neighbors() {
|
|
133
|
+
let obs_x = vec![0.0];
|
|
134
|
+
let obs_y = vec![0.0];
|
|
135
|
+
let obs_v = vec![10.0];
|
|
136
|
+
let gx = vec![100.0]; // outside radius
|
|
137
|
+
let gy = vec![0.0];
|
|
138
|
+
let out = inverse_distance_to_points(
|
|
139
|
+
&obs_x, &obs_y, &obs_v, &gx, &gy,
|
|
140
|
+
5.0, 1, 0, 100000.0, 0.2,
|
|
141
|
+
);
|
|
142
|
+
assert!(out[0].is_nan());
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
#[test]
|
|
146
|
+
fn test_barnes_returns_value() {
|
|
147
|
+
let obs_x = vec![0.0, 2.0];
|
|
148
|
+
let obs_y = vec![0.0, 0.0];
|
|
149
|
+
let obs_v = vec![10.0, 20.0];
|
|
150
|
+
let gx = vec![1.0];
|
|
151
|
+
let gy = vec![0.0];
|
|
152
|
+
let out = inverse_distance_to_points(
|
|
153
|
+
&obs_x, &obs_y, &obs_v, &gx, &gy,
|
|
154
|
+
10.0, 1, 1, 100000.0, 0.2,
|
|
155
|
+
);
|
|
156
|
+
// With equal distances, Barnes should also give the average.
|
|
157
|
+
assert!((out[0] - 15.0).abs() < 1e-10);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
#[test]
|
|
161
|
+
fn test_cressman_returns_value() {
|
|
162
|
+
let obs_x = vec![0.0, 2.0];
|
|
163
|
+
let obs_y = vec![0.0, 0.0];
|
|
164
|
+
let obs_v = vec![10.0, 20.0];
|
|
165
|
+
let gx = vec![1.0];
|
|
166
|
+
let gy = vec![0.0];
|
|
167
|
+
let out = inverse_distance_to_points(
|
|
168
|
+
&obs_x, &obs_y, &obs_v, &gx, &gy,
|
|
169
|
+
10.0, 1, 2, 100000.0, 0.2,
|
|
170
|
+
);
|
|
171
|
+
// With equal distances, Cressman should also give the average.
|
|
172
|
+
assert!((out[0] - 15.0).abs() < 1e-10);
|
|
173
|
+
}
|
|
174
|
+
}
|