metrust 0.3.3__tar.gz → 0.3.4__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.
Files changed (187) hide show
  1. {metrust-0.3.3 → metrust-0.3.4}/Cargo.lock +6 -6
  2. {metrust-0.3.3 → metrust-0.3.4}/Cargo.toml +1 -1
  3. metrust-0.3.4/PKG-INFO +157 -0
  4. metrust-0.3.4/README.md +134 -0
  5. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/Cargo.toml +1 -1
  6. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/interpolate/mod.rs +11 -5
  7. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/Cargo.toml +1 -1
  8. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/Cargo.toml +1 -1
  9. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-math/Cargo.toml +1 -1
  10. metrust-0.3.4/crates/wx-math/src/interpolate.rs +174 -0
  11. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-math/src/lib.rs +1 -0
  12. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/Cargo.toml +1 -1
  13. {metrust-0.3.3 → metrust-0.3.4}/docs/index.md +33 -16
  14. {metrust-0.3.3 → metrust-0.3.4}/pyproject.toml +1 -1
  15. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/calc/__init__.py +385 -0
  16. {metrust-0.3.3 → metrust-0.3.4}/src/py_interpolate.rs +59 -2
  17. metrust-0.3.3/PKG-INFO +0 -231
  18. metrust-0.3.3/README.md +0 -208
  19. {metrust-0.3.3 → metrust-0.3.4}/.github/workflows/ci.yml +0 -0
  20. {metrust-0.3.3 → metrust-0.3.4}/.github/workflows/docs.yml +0 -0
  21. {metrust-0.3.3 → metrust-0.3.4}/.github/workflows/release.yml +0 -0
  22. {metrust-0.3.3 → metrust-0.3.4}/.gitignore +0 -0
  23. {metrust-0.3.3 → metrust-0.3.4}/VERIFICATION.md +0 -0
  24. {metrust-0.3.3 → metrust-0.3.4}/benches/bench_hrrr.py +0 -0
  25. {metrust-0.3.3 → metrust-0.3.4}/benches/bench_hrrr_vs_metpy.py +0 -0
  26. {metrust-0.3.3 → metrust-0.3.4}/benches/bench_python.py +0 -0
  27. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/benches/calc_bench.rs +0 -0
  28. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/atmo.rs +0 -0
  29. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/kinematics.rs +0 -0
  30. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/mod.rs +0 -0
  31. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/severe.rs +0 -0
  32. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/smooth.rs +0 -0
  33. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/thermo.rs +0 -0
  34. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/utils.rs +0 -0
  35. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/calc/wind.rs +0 -0
  36. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/constants.rs +0 -0
  37. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/gempak.rs +0 -0
  38. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/gempak_dm.rs +0 -0
  39. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/gempak_sounding.rs +0 -0
  40. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/gempak_surface.rs +0 -0
  41. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/gini.rs +0 -0
  42. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/level3.rs +0 -0
  43. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/metar.rs +0 -0
  44. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/mod.rs +0 -0
  45. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/station.rs +0 -0
  46. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/io/wpc.rs +0 -0
  47. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/lib.rs +0 -0
  48. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/plots/mod.rs +0 -0
  49. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/projections.rs +0 -0
  50. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/src/units.rs +0 -0
  51. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/tests/test_gempak.rs +0 -0
  52. {metrust-0.3.3 → metrust-0.3.4}/crates/metrust/tests/test_new_functions.rs +0 -0
  53. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/composite.rs +0 -0
  54. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/cache.rs +0 -0
  55. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/catalog.rs +0 -0
  56. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/client.rs +0 -0
  57. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/fallback.rs +0 -0
  58. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/idx.rs +0 -0
  59. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/mod.rs +0 -0
  60. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/sources.rs +0 -0
  61. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/download/streaming.rs +0 -0
  62. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/dynamics.rs +0 -0
  63. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/error.rs +0 -0
  64. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/grid.rs +0 -0
  65. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/mod.rs +0 -0
  66. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/ops.rs +0 -0
  67. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/parser.rs +0 -0
  68. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/search.rs +0 -0
  69. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/streaming.rs +0 -0
  70. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/tables.rs +0 -0
  71. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/tests.rs +0 -0
  72. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/unpack.rs +0 -0
  73. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/grib2/writer.rs +0 -0
  74. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/gridmath.rs +0 -0
  75. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/lib.rs +0 -0
  76. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/metfuncs.rs +0 -0
  77. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/cfs.rs +0 -0
  78. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/ecmwf.rs +0 -0
  79. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/era5.rs +0 -0
  80. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/gefs.rs +0 -0
  81. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/gfs.rs +0 -0
  82. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/href.rs +0 -0
  83. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/hrrr.rs +0 -0
  84. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/hrrr_ak.rs +0 -0
  85. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/latest.rs +0 -0
  86. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/mod.rs +0 -0
  87. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/mrms.rs +0 -0
  88. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/nam.rs +0 -0
  89. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/nbm.rs +0 -0
  90. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/rap.rs +0 -0
  91. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/rrfs.rs +0 -0
  92. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/rtma.rs +0 -0
  93. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/sref.rs +0 -0
  94. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/urma.rs +0 -0
  95. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/models/wpc.rs +0 -0
  96. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/products.rs +0 -0
  97. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/projection.rs +0 -0
  98. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/regrid.rs +0 -0
  99. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/ansi.rs +0 -0
  100. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/colormap.rs +0 -0
  101. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/contour.rs +0 -0
  102. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/cross_section.rs +0 -0
  103. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/encode.rs +0 -0
  104. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/filled_contour.rs +0 -0
  105. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/hodograph.rs +0 -0
  106. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/mod.rs +0 -0
  107. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/overlay.rs +0 -0
  108. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/raster.rs +0 -0
  109. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/skewt.rs +0 -0
  110. {metrust-0.3.3 → metrust-0.3.4}/crates/rustmet-core/src/render/station.rs +0 -0
  111. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/error.rs +0 -0
  112. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/field.rs +0 -0
  113. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/lib.rs +0 -0
  114. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/meta.rs +0 -0
  115. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/projection.rs +0 -0
  116. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/radial.rs +0 -0
  117. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/site.rs +0 -0
  118. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/sounding.rs +0 -0
  119. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-field/src/time.rs +0 -0
  120. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-math/src/composite.rs +0 -0
  121. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-math/src/dynamics.rs +0 -0
  122. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-math/src/gridmath.rs +0 -0
  123. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-math/src/regrid.rs +0 -0
  124. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-math/src/thermo.rs +0 -0
  125. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/cells.rs +0 -0
  126. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/color_table.rs +0 -0
  127. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/derived.rs +0 -0
  128. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/detection.rs +0 -0
  129. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/level2.rs +0 -0
  130. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/lib.rs +0 -0
  131. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/products.rs +0 -0
  132. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/render.rs +0 -0
  133. {metrust-0.3.3 → metrust-0.3.4}/crates/wx-radar/src/sites.rs +0 -0
  134. {metrust-0.3.3 → metrust-0.3.4}/docs/api/atmospheric.md +0 -0
  135. {metrust-0.3.3 → metrust-0.3.4}/docs/api/grid-composites.md +0 -0
  136. {metrust-0.3.3 → metrust-0.3.4}/docs/api/io.md +0 -0
  137. {metrust-0.3.3 → metrust-0.3.4}/docs/api/kinematics.md +0 -0
  138. {metrust-0.3.3 → metrust-0.3.4}/docs/api/moisture.md +0 -0
  139. {metrust-0.3.3 → metrust-0.3.4}/docs/api/severe.md +0 -0
  140. {metrust-0.3.3 → metrust-0.3.4}/docs/api/smoothing.md +0 -0
  141. {metrust-0.3.3 → metrust-0.3.4}/docs/api/thermodynamics.md +0 -0
  142. {metrust-0.3.3 → metrust-0.3.4}/docs/api/units.md +0 -0
  143. {metrust-0.3.3 → metrust-0.3.4}/docs/api/wind.md +0 -0
  144. {metrust-0.3.3 → metrust-0.3.4}/docs/compatibility.md +0 -0
  145. {metrust-0.3.3 → metrust-0.3.4}/docs/guides/arrays.md +0 -0
  146. {metrust-0.3.3 → metrust-0.3.4}/docs/guides/installation.md +0 -0
  147. {metrust-0.3.3 → metrust-0.3.4}/docs/guides/migration.md +0 -0
  148. {metrust-0.3.3 → metrust-0.3.4}/docs/performance.md +0 -0
  149. {metrust-0.3.3 → metrust-0.3.4}/docs/tutorials/first-grid.md +0 -0
  150. {metrust-0.3.3 → metrust-0.3.4}/docs/tutorials/first-sounding.md +0 -0
  151. {metrust-0.3.3 → metrust-0.3.4}/docs/tutorials/reading-the-numbers.md +0 -0
  152. {metrust-0.3.3 → metrust-0.3.4}/docs/tutorials/recipes.md +0 -0
  153. {metrust-0.3.3 → metrust-0.3.4}/docs/tutorials/weather-101.md +0 -0
  154. {metrust-0.3.3 → metrust-0.3.4}/examples/cookbook_500hpa_grid.py +0 -0
  155. {metrust-0.3.3 → metrust-0.3.4}/examples/cookbook_sounding.py +0 -0
  156. {metrust-0.3.3 → metrust-0.3.4}/examples/sounderpy_dropin.py +0 -0
  157. {metrust-0.3.3 → metrust-0.3.4}/mkdocs.yml +0 -0
  158. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/__init__.py +0 -0
  159. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/constants/__init__.py +0 -0
  160. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/interpolate/__init__.py +0 -0
  161. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/io/__init__.py +0 -0
  162. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/plots/__init__.py +0 -0
  163. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/units.py +0 -0
  164. {metrust-0.3.3 → metrust-0.3.4}/python/metrust/xarray.py +0 -0
  165. {metrust-0.3.3 → metrust-0.3.4}/src/lib.rs +0 -0
  166. {metrust-0.3.3 → metrust-0.3.4}/src/py_atmo.rs +0 -0
  167. {metrust-0.3.3 → metrust-0.3.4}/src/py_constants.rs +0 -0
  168. {metrust-0.3.3 → metrust-0.3.4}/src/py_io.rs +0 -0
  169. {metrust-0.3.3 → metrust-0.3.4}/src/py_kinematics.rs +0 -0
  170. {metrust-0.3.3 → metrust-0.3.4}/src/py_severe.rs +0 -0
  171. {metrust-0.3.3 → metrust-0.3.4}/src/py_smooth.rs +0 -0
  172. {metrust-0.3.3 → metrust-0.3.4}/src/py_thermo.rs +0 -0
  173. {metrust-0.3.3 → metrust-0.3.4}/src/py_utils.rs +0 -0
  174. {metrust-0.3.3 → metrust-0.3.4}/src/py_wind.rs +0 -0
  175. {metrust-0.3.3 → metrust-0.3.4}/tests/api_audit_calc.md +0 -0
  176. {metrust-0.3.3 → metrust-0.3.4}/tests/api_audit_other.md +0 -0
  177. {metrust-0.3.3 → metrust-0.3.4}/tests/benchmark.py +0 -0
  178. {metrust-0.3.3 → metrust-0.3.4}/tests/test_metpy_dropin_compat.py +0 -0
  179. {metrust-0.3.3 → metrust-0.3.4}/tests/test_python_compat.py +0 -0
  180. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_constants.py +0 -0
  181. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_edge_cases.py +0 -0
  182. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_kinematics.py +0 -0
  183. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_severe_atmo.py +0 -0
  184. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_smooth_interp.py +0 -0
  185. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_thermo.py +0 -0
  186. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_units.py +0 -0
  187. {metrust-0.3.3 → metrust-0.3.4}/tests/verify_wind.py +0 -0
@@ -788,7 +788,7 @@ dependencies = [
788
788
 
789
789
  [[package]]
790
790
  name = "metrust"
791
- version = "0.3.3"
791
+ version = "0.3.4"
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.3"
805
+ version = "0.3.4"
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.3"
1422
+ version = "0.3.4"
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.3"
1937
+ version = "0.3.4"
1938
1938
  dependencies = [
1939
1939
  "chrono",
1940
1940
  ]
1941
1941
 
1942
1942
  [[package]]
1943
1943
  name = "wx-math"
1944
- version = "0.3.3"
1944
+ version = "0.3.4"
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.3"
1952
+ version = "0.3.4"
1953
1953
  dependencies = [
1954
1954
  "byteorder",
1955
1955
  "bzip2",
@@ -8,7 +8,7 @@ license = "MIT"
8
8
 
9
9
  [package]
10
10
  name = "metrust-py"
11
- version = "0.3.3"
11
+ version = "0.3.4"
12
12
  edition.workspace = true
13
13
  description = "Python bindings for metrust — a drop-in replacement for MetPy"
14
14
  readme = "README.md"
metrust-0.3.4/PKG-INFO ADDED
@@ -0,0 +1,157 @@
1
+ Metadata-Version: 2.4
2
+ Name: metrust
3
+ Version: 0.3.4
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
+
@@ -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
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "metrust"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  edition = "2021"
5
5
  description = "A pure-Rust drop-in replacement for MetPy — meteorological calculations, data I/O, and visualization"
6
6
  license = "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
- pub fn inverse_distance_to_points(
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
- inverse_distance_to_points(
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 = inverse_distance_to_points(
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 = inverse_distance_to_points(
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,
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rustmet-core"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  edition = "2021"
5
5
  description = "Pure Rust GRIB2 processor and weather model data library — HRRR, GFS, NAM, RAP"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "wx-field"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  edition = "2021"
5
5
  description = "Shared type foundation for the unified atmospheric engine — fields, projections, metadata"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "wx-math"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  edition = "2021"
5
5
  description = "Meteorological computations and grid math"
6
6
  license = "MIT"
@@ -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
+ }
@@ -8,3 +8,4 @@ pub mod dynamics;
8
8
  pub mod gridmath;
9
9
  pub mod composite;
10
10
  pub mod regrid;
11
+ pub mod interpolate;
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "wx-radar"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  edition = "2021"
5
5
  description = "Radar data processing — NEXRAD Level-II parser, PPI renderer, color tables"
6
6
  license = "MIT"