metrust 0.3.7__tar.gz → 0.3.8__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.7 → metrust-0.3.8}/Cargo.lock +3 -3
- {metrust-0.3.7 → metrust-0.3.8}/Cargo.toml +1 -1
- {metrust-0.3.7 → metrust-0.3.8}/PKG-INFO +1 -1
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/Cargo.toml +1 -1
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/Cargo.toml +1 -1
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/src/thermo.rs +28 -3
- {metrust-0.3.7 → metrust-0.3.8}/pyproject.toml +1 -1
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/calc/__init__.py +49 -5
- metrust-0.3.8/tests/sounding_3way.py +207 -0
- metrust-0.3.8/tests/sounding_comparison.png +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/.github/workflows/ci.yml +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/.github/workflows/docs.yml +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/.github/workflows/release.yml +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/.gitignore +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/README.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/VERIFICATION.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/benches/bench_hrrr.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/benches/bench_hrrr_vs_metpy.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/benches/bench_python.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/benches/calc_bench.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/atmo.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/kinematics.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/severe.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/smooth.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/thermo.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/utils.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/calc/wind.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/constants.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/interpolate/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/gempak.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/gempak_dm.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/gempak_sounding.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/gempak_surface.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/gini.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/level3.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/metar.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/station.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/io/wpc.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/lib.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/plots/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/projections.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/src/units.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/tests/test_gempak.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/metrust/tests/test_new_functions.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/composite.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/cache.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/catalog.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/client.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/fallback.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/idx.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/sources.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/download/streaming.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/dynamics.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/error.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/grid.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/ops.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/parser.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/search.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/streaming.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/tables.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/tests.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/unpack.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/grib2/writer.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/gridmath.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/lib.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/metfuncs.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/cfs.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/ecmwf.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/era5.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/gefs.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/gfs.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/href.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/hrrr.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/hrrr_ak.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/latest.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/mrms.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/nam.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/nbm.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/rap.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/rrfs.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/rtma.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/sref.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/urma.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/models/wpc.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/products.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/projection.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/regrid.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/ansi.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/colormap.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/contour.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/cross_section.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/encode.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/filled_contour.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/hodograph.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/mod.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/overlay.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/raster.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/skewt.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-core/src/render/station.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/Cargo.toml +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/error.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/field.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/lib.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/meta.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/projection.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/radial.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/site.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/sounding.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-field/src/time.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/Cargo.toml +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/src/composite.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/src/dynamics.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/src/gridmath.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/src/interpolate.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/src/lib.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-math/src/regrid.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/Cargo.toml +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/cells.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/color_table.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/derived.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/detection.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/level2.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/lib.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/products.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/render.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/crates/wx-radar/src/sites.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/demos/hrrr_diffusion_training.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/atmospheric.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/grid-composites.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/io.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/kinematics.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/moisture.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/severe.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/smoothing.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/thermodynamics.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/units.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/api/wind.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/compatibility.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/guides/arrays.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/guides/installation.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/guides/migration.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/index.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/architecture.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/grid-kinematics.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/index.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/interpolation.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/io-formats.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/metpy-compatibility.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/moisture.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/parallelism.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/severe-weather.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/smoothing.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/thermodynamics.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/units-and-pint.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/methodology/wind.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/performance.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/tutorials/first-grid.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/tutorials/first-sounding.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/tutorials/reading-the-numbers.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/tutorials/recipes.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/docs/tutorials/weather-101.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/examples/cookbook_500hpa_grid.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/examples/cookbook_sounding.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/examples/sounderpy_dropin.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/mkdocs.yml +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/__init__.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/constants/__init__.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/interpolate/__init__.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/io/__init__.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/plots/__init__.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/units.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/python/metrust/xarray.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/lib.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_atmo.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_constants.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_interpolate.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_io.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_kinematics.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_severe.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_smooth.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_thermo.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_utils.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/src/py_wind.rs +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/api_audit_calc.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/api_audit_other.md +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/benchmark.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/test_metpy_dropin_compat.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/test_python_compat.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/verify_constants.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/verify_edge_cases.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/verify_kinematics.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/verify_severe_atmo.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/verify_smooth_interp.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/verify_thermo.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/tests/verify_units.py +0 -0
- {metrust-0.3.7 → metrust-0.3.8}/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.8"
|
|
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.8"
|
|
806
806
|
dependencies = [
|
|
807
807
|
"metrust",
|
|
808
808
|
"numpy",
|
|
@@ -1925,7 +1925,7 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
|
1925
1925
|
|
|
1926
1926
|
[[package]]
|
|
1927
1927
|
name = "wx-core"
|
|
1928
|
-
version = "0.3.
|
|
1928
|
+
version = "0.3.8"
|
|
1929
1929
|
dependencies = [
|
|
1930
1930
|
"chrono",
|
|
1931
1931
|
"flate2",
|
|
@@ -581,6 +581,25 @@ pub fn cape_cin_core(
|
|
|
581
581
|
// Only integrate between surface and top limit
|
|
582
582
|
let p_top_actual = if p_top_limit > 0.0 { p_top_limit } else { p_prof[n - 1] };
|
|
583
583
|
|
|
584
|
+
// CIN is accumulated below the LFC. We track the *last*
|
|
585
|
+
// transition from negative to positive buoyancy (the true LFC).
|
|
586
|
+
// This handles superadiabatic surface layers correctly.
|
|
587
|
+
|
|
588
|
+
// First, find the index of the last neg→pos crossing (the true LFC)
|
|
589
|
+
let mut last_lfc_idx: Option<usize> = None;
|
|
590
|
+
for i in 1..n {
|
|
591
|
+
if tv_parc_arr[i].is_nan() || tv_parc_arr[i - 1].is_nan() { continue; }
|
|
592
|
+
let tv_e = tv_env_arr[i] + ZEROCNK;
|
|
593
|
+
let tv_p = tv_parc_arr[i] + ZEROCNK;
|
|
594
|
+
let tv_e_prev = tv_env_arr[i - 1] + ZEROCNK;
|
|
595
|
+
let tv_p_prev = tv_parc_arr[i - 1] + ZEROCNK;
|
|
596
|
+
let buoy = tv_p - tv_e;
|
|
597
|
+
let buoy_prev = tv_p_prev - tv_e_prev;
|
|
598
|
+
if buoy > 0.0 && buoy_prev <= 0.0 {
|
|
599
|
+
last_lfc_idx = Some(i);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
584
603
|
for i in 1..n {
|
|
585
604
|
if p_prof[i] <= 0.0 || tv_parc_arr[i].is_nan() || tv_parc_arr[i - 1].is_nan() { continue; }
|
|
586
605
|
if p_prof[i] < p_top_actual { continue; }
|
|
@@ -596,10 +615,16 @@ pub fn cape_cin_core(
|
|
|
596
615
|
let buoy_hi = (tv_p_hi - tv_e_hi) / tv_e_hi;
|
|
597
616
|
let val = G * (buoy_lo + buoy_hi) / 2.0 * dz;
|
|
598
617
|
|
|
599
|
-
if
|
|
600
|
-
|
|
618
|
+
if let Some(lfc_i) = last_lfc_idx {
|
|
619
|
+
if val > 0.0 && i >= lfc_i {
|
|
620
|
+
total_cape += val;
|
|
621
|
+
} else if val < 0.0 && i <= lfc_i {
|
|
622
|
+
total_cin += val;
|
|
623
|
+
}
|
|
601
624
|
} else {
|
|
602
|
-
|
|
625
|
+
// No LFC found — accumulate everything
|
|
626
|
+
if val > 0.0 { total_cape += val; }
|
|
627
|
+
else { total_cin += val; }
|
|
603
628
|
}
|
|
604
629
|
}
|
|
605
630
|
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "metrust"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.8"
|
|
8
8
|
description = "Rust-powered drop-in replacement for MetPy -- 150/150 calc functions plus 36 extras, 10-93000x faster"
|
|
9
9
|
requires-python = ">=3.9"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -628,15 +628,54 @@ def cape_cin(pressure, temperature, dewpoint, parcel_profile_or_height=None,
|
|
|
628
628
|
h_calc[i] = h_calc[i-1] + (287.04749 * tv_mean / 9.80665) * np.log(p[i-1] / p[i])
|
|
629
629
|
|
|
630
630
|
# Integrate CAPE/CIN: trapezoidal rule
|
|
631
|
+
# Two-pass approach matching MetPy:
|
|
632
|
+
# Pass 1: Find all buoyancy values to locate LFC and EL
|
|
633
|
+
# Pass 2: Integrate CAPE between LFC-EL, CIN between LCL-LFC
|
|
634
|
+
#
|
|
635
|
+
# CIN is the negative area where the parcel is cooler than the
|
|
636
|
+
# environment. For surface-based parcels, the parcel may be
|
|
637
|
+
# positively buoyant near the surface (superadiabatic layer),
|
|
638
|
+
# then negatively buoyant (the cap/CIN), then positively buoyant
|
|
639
|
+
# again above the LFC. We need to capture that middle negative
|
|
640
|
+
# layer, not just stop at the first positive.
|
|
641
|
+
|
|
642
|
+
# Find LCL (where T_parcel ≈ Td, i.e. parcel becomes saturated)
|
|
643
|
+
lcl_idx = 0
|
|
644
|
+
for i in range(1, len(p)):
|
|
645
|
+
if t_parcel[i] <= t_parcel[0] - 1.0: # parcel has cooled — above LCL
|
|
646
|
+
lcl_idx = i
|
|
647
|
+
break
|
|
648
|
+
|
|
649
|
+
# Compute buoyancy at each level
|
|
650
|
+
buoyancy = np.zeros(len(p))
|
|
651
|
+
for i in range(len(p)):
|
|
652
|
+
if p[i] <= 0:
|
|
653
|
+
continue
|
|
654
|
+
tv_e = _calc.virtual_temp(t[i], p[i], td[i]) + 273.15
|
|
655
|
+
tv_p = _calc.virtual_temp(t_parcel[i], p[i], t_parcel[i]) + 273.15
|
|
656
|
+
if tv_e > 0:
|
|
657
|
+
buoyancy[i] = (tv_p - tv_e) / tv_e
|
|
658
|
+
|
|
659
|
+
# Find LFC: last crossing from negative to positive buoyancy
|
|
660
|
+
lfc_idx = None
|
|
661
|
+
for i in range(1, len(p)):
|
|
662
|
+
if buoyancy[i] > 0 and buoyancy[i-1] <= 0:
|
|
663
|
+
lfc_idx = i
|
|
664
|
+
|
|
665
|
+
# Find EL: last crossing from positive to negative after LFC
|
|
666
|
+
el_idx = len(p) - 1
|
|
667
|
+
if lfc_idx is not None:
|
|
668
|
+
for i in range(lfc_idx + 1, len(p)):
|
|
669
|
+
if buoyancy[i] <= 0 and buoyancy[i-1] > 0:
|
|
670
|
+
el_idx = i
|
|
671
|
+
|
|
631
672
|
cape_val = 0.0
|
|
632
673
|
cin_val = 0.0
|
|
633
674
|
for i in range(1, len(p)):
|
|
634
675
|
if p[i] <= 0:
|
|
635
676
|
continue
|
|
636
|
-
# Environment virtual temperature
|
|
637
677
|
tv_e_lo = _calc.virtual_temp(t[i-1], p[i-1], td[i-1]) + 273.15
|
|
638
678
|
tv_e_hi = _calc.virtual_temp(t[i], p[i], td[i]) + 273.15
|
|
639
|
-
# Parcel virtual temperature (saturated above LCL, so Td_parcel ≈ T_parcel)
|
|
640
679
|
tv_p_lo = _calc.virtual_temp(t_parcel[i-1], p[i-1], t_parcel[i-1]) + 273.15
|
|
641
680
|
tv_p_hi = _calc.virtual_temp(t_parcel[i], p[i], t_parcel[i]) + 273.15
|
|
642
681
|
dz = h_calc[i] - h_calc[i-1]
|
|
@@ -645,10 +684,15 @@ def cape_cin(pressure, temperature, dewpoint, parcel_profile_or_height=None,
|
|
|
645
684
|
buoy_lo = (tv_p_lo - tv_e_lo) / tv_e_lo
|
|
646
685
|
buoy_hi = (tv_p_hi - tv_e_hi) / tv_e_hi
|
|
647
686
|
val = 9.80665 * (buoy_lo + buoy_hi) / 2.0 * dz
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
687
|
+
|
|
688
|
+
if lfc_idx is not None and i <= el_idx:
|
|
689
|
+
if val > 0 and i >= lfc_idx:
|
|
690
|
+
cape_val += val
|
|
691
|
+
elif val < 0 and i <= lfc_idx:
|
|
692
|
+
cin_val += val
|
|
693
|
+
elif val < 0:
|
|
651
694
|
cin_val += val
|
|
695
|
+
|
|
652
696
|
return cape_val * units("J/kg"), cin_val * units("J/kg")
|
|
653
697
|
elif fourth is not None:
|
|
654
698
|
h = _as_1d(_strip(fourth, "m"))
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"""Three-way sounding comparison: SharpJS vs MetPy vs metrust."""
|
|
2
|
+
import warnings; warnings.filterwarnings("ignore")
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from rusbie import Herbie
|
|
6
|
+
|
|
7
|
+
H = Herbie("2026-03-27 23:00", model="hrrr", product="prs", fxx=0, verbose=False)
|
|
8
|
+
|
|
9
|
+
ds_t = H.xarray(":TMP:.*mb", backend_kwargs={"filter_by_keys": {"typeOfLevel": "isobaricInhPa"}})
|
|
10
|
+
ds_d = H.xarray(":DPT:.*mb", backend_kwargs={"filter_by_keys": {"typeOfLevel": "isobaricInhPa"}})
|
|
11
|
+
ds_u = H.xarray(":UGRD:.*mb", backend_kwargs={"filter_by_keys": {"typeOfLevel": "isobaricInhPa"}})
|
|
12
|
+
ds_v = H.xarray(":VGRD:.*mb", backend_kwargs={"filter_by_keys": {"typeOfLevel": "isobaricInhPa"}})
|
|
13
|
+
ds_h = H.xarray(":HGT:.*mb", backend_kwargs={"filter_by_keys": {"typeOfLevel": "isobaricInhPa"}})
|
|
14
|
+
|
|
15
|
+
for name in ["ds_t", "ds_d", "ds_u", "ds_v", "ds_h"]:
|
|
16
|
+
obj = locals()[name]
|
|
17
|
+
if isinstance(obj, list):
|
|
18
|
+
locals()[name] = obj[0]
|
|
19
|
+
|
|
20
|
+
ds_t, ds_d, ds_u, ds_v, ds_h = [x[0] if isinstance(x, list) else x for x in [ds_t, ds_d, ds_u, ds_v, ds_h]]
|
|
21
|
+
|
|
22
|
+
lat_target, lon_target = 32.5462, -89.12
|
|
23
|
+
lon_360 = lon_target % 360
|
|
24
|
+
lat_vals = ds_t.latitude.values
|
|
25
|
+
lon_vals = ds_t.longitude.values
|
|
26
|
+
dist = (lat_vals - lat_target)**2 + (lon_vals - lon_360)**2
|
|
27
|
+
j, i = np.unravel_index(np.nanargmin(dist), dist.shape)
|
|
28
|
+
|
|
29
|
+
pres_coord = [c for c in ds_t.coords if "isobaric" in c.lower()][0]
|
|
30
|
+
plevs = ds_t[pres_coord].values
|
|
31
|
+
p_hpa = plevs / 100.0 if plevs.max() > 2000 else plevs
|
|
32
|
+
|
|
33
|
+
t_k = ds_t[list(ds_t.data_vars)[0]].values[:, j, i]
|
|
34
|
+
td_k = ds_d[list(ds_d.data_vars)[0]].values[:, j, i]
|
|
35
|
+
u_ms = ds_u[list(ds_u.data_vars)[0]].values[:, j, i]
|
|
36
|
+
v_ms = ds_v[list(ds_v.data_vars)[0]].values[:, j, i]
|
|
37
|
+
h_m = ds_h[list(ds_h.data_vars)[0]].values[:, j, i]
|
|
38
|
+
|
|
39
|
+
sort_idx = np.argsort(p_hpa)[::-1]
|
|
40
|
+
p = p_hpa[sort_idx].astype(np.float64)
|
|
41
|
+
t_c = (t_k[sort_idx] - 273.15).astype(np.float64)
|
|
42
|
+
td_c = (td_k[sort_idx] - 273.15).astype(np.float64)
|
|
43
|
+
u = u_ms[sort_idx].astype(np.float64)
|
|
44
|
+
v = v_ms[sort_idx].astype(np.float64)
|
|
45
|
+
h = h_m[sort_idx].astype(np.float64)
|
|
46
|
+
|
|
47
|
+
print(f"Nearest grid point: {lat_vals[j,i]:.4f}N {abs(lon_vals[j,i]-360):.2f}W")
|
|
48
|
+
print(f"Sfc: T={t_c[0]:.2f}C Td={td_c[0]:.2f}C P={p[0]:.1f}hPa Z={h[0]:.0f}m")
|
|
49
|
+
print(f"Levels: {len(p)}")
|
|
50
|
+
print()
|
|
51
|
+
|
|
52
|
+
# ─── MetPy ───
|
|
53
|
+
import metpy.calc as mpcalc
|
|
54
|
+
from metpy.units import units as mpu
|
|
55
|
+
|
|
56
|
+
p_mp = p * mpu.hPa
|
|
57
|
+
t_mp = t_c * mpu.degC
|
|
58
|
+
td_mp = td_c * mpu.degC
|
|
59
|
+
h_mp = h * mpu.meter
|
|
60
|
+
u_mp = u * mpu("m/s")
|
|
61
|
+
v_mp = v * mpu("m/s")
|
|
62
|
+
|
|
63
|
+
pp_sb = mpcalc.parcel_profile(p_mp, t_mp[0], td_mp[0])
|
|
64
|
+
mp_sbcape, mp_sbcin = mpcalc.cape_cin(p_mp, t_mp, td_mp, pp_sb)
|
|
65
|
+
mp_lcl_p, mp_lcl_t = mpcalc.lcl(p_mp[0], t_mp[0], td_mp[0])
|
|
66
|
+
mp_lfc_p, mp_lfc_t = mpcalc.lfc(p_mp, t_mp, td_mp, pp_sb)
|
|
67
|
+
mp_el_p, mp_el_t = mpcalc.el(p_mp, t_mp, td_mp, pp_sb)
|
|
68
|
+
|
|
69
|
+
ml_t, ml_td = mpcalc.mixed_layer(p_mp, t_mp, td_mp, depth=100 * mpu.hPa)
|
|
70
|
+
pp_ml = mpcalc.parcel_profile(p_mp, ml_t, ml_td)
|
|
71
|
+
mp_mlcape, mp_mlcin = mpcalc.cape_cin(p_mp, t_mp, td_mp, pp_ml)
|
|
72
|
+
|
|
73
|
+
mu_idx = np.argmax(mpcalc.equivalent_potential_temperature(p_mp[:20], t_mp[:20], td_mp[:20]).magnitude)
|
|
74
|
+
try:
|
|
75
|
+
pp_mu = mpcalc.parcel_profile(p_mp[mu_idx:], t_mp[mu_idx], td_mp[mu_idx])
|
|
76
|
+
pp_mu_arr = np.full(len(p), np.nan)
|
|
77
|
+
pp_mu_arr[mu_idx:] = pp_mu.magnitude
|
|
78
|
+
mp_mucape, mp_mucin = mpcalc.cape_cin(p_mp, t_mp, td_mp, pp_mu_arr * pp_mu.units)
|
|
79
|
+
except:
|
|
80
|
+
mp_mucape = mp_sbcape # fallback — MU is often same as SB
|
|
81
|
+
mp_mucin = mp_sbcin
|
|
82
|
+
|
|
83
|
+
mp_li = mpcalc.lifted_index(p_mp, t_mp, pp_sb)
|
|
84
|
+
mp_pw = mpcalc.precipitable_water(p_mp, td_mp)
|
|
85
|
+
mp_ki = mpcalc.k_index(p_mp, t_mp, td_mp)
|
|
86
|
+
try:
|
|
87
|
+
mp_tt = mpcalc.total_totals(p_mp, t_mp, td_mp)
|
|
88
|
+
except AttributeError:
|
|
89
|
+
mp_vt = mpcalc.vertical_totals(p_mp, t_mp)
|
|
90
|
+
mp_ct = mpcalc.cross_totals(p_mp, t_mp, td_mp)
|
|
91
|
+
mp_tt_val = mp_vt.magnitude + mp_ct.magnitude
|
|
92
|
+
mp_tt = mp_tt_val * mpu.delta_degC
|
|
93
|
+
else:
|
|
94
|
+
mp_ct = mpcalc.cross_totals(p_mp, t_mp, td_mp)
|
|
95
|
+
mp_vt = mpcalc.vertical_totals(p_mp, t_mp)
|
|
96
|
+
|
|
97
|
+
# Bunkers
|
|
98
|
+
rm, lm, mw = mpcalc.bunkers_storm_motion(p_mp, u_mp, v_mp, h_mp)
|
|
99
|
+
mp_rm_spd = np.sqrt(rm[0].magnitude**2 + rm[1].magnitude**2) * 1.944
|
|
100
|
+
mp_rm_dir = (270 - np.degrees(np.arctan2(rm[1].magnitude, rm[0].magnitude))) % 360
|
|
101
|
+
|
|
102
|
+
# Shear
|
|
103
|
+
def mp_shear(depth):
|
|
104
|
+
try:
|
|
105
|
+
bu, bv = mpcalc.bulk_shear(p_mp, u_mp, v_mp, height=h_mp, depth=depth * mpu.meter)
|
|
106
|
+
return np.sqrt(bu.magnitude**2 + bv.magnitude**2) * 1.944
|
|
107
|
+
except: return 0
|
|
108
|
+
|
|
109
|
+
# SRH
|
|
110
|
+
def mp_srh(depth):
|
|
111
|
+
try:
|
|
112
|
+
pos, neg, tot = mpcalc.storm_relative_helicity(h_mp, u_mp, v_mp, depth=depth * mpu.meter)
|
|
113
|
+
return tot.magnitude, pos.magnitude, neg.magnitude
|
|
114
|
+
except: return 0, 0, 0
|
|
115
|
+
|
|
116
|
+
# Lapse rates
|
|
117
|
+
def lr(pb, pt):
|
|
118
|
+
ib = np.argmin(np.abs(p - pb))
|
|
119
|
+
it = np.argmin(np.abs(p - pt))
|
|
120
|
+
dT = t_c[it] - t_c[ib]
|
|
121
|
+
dZ = (h[it] - h[ib]) / 1000.0
|
|
122
|
+
return -dT / dZ if dZ != 0 else 0
|
|
123
|
+
|
|
124
|
+
# ─── metrust ───
|
|
125
|
+
from metrust.calc import cape_cin as mr_cape_cin, parcel_profile as mr_parcel_profile
|
|
126
|
+
from metrust.calc import lcl as mr_lcl, precipitable_water as mr_pw
|
|
127
|
+
from metrust.calc import k_index as mr_ki, total_totals as mr_tt, lifted_index as mr_li
|
|
128
|
+
from metrust.units import units as mru
|
|
129
|
+
|
|
130
|
+
p_mr = p * mru.hPa
|
|
131
|
+
t_mr = t_c * mru.degC
|
|
132
|
+
td_mr = td_c * mru.degC
|
|
133
|
+
|
|
134
|
+
# Use the Rust cape_cin_core directly (not the Python parcel_profile wrapper)
|
|
135
|
+
from metrust._metrust import calc as _calc
|
|
136
|
+
_rust_result = _calc.cape_cin(p, t_c, td_c, h - h[0], float(p[0]), float(t_c[0]), float(td_c[0]), "sb", 100.0, 300.0, None)
|
|
137
|
+
mr_cape_val, mr_cin_val = _rust_result[0], _rust_result[1]
|
|
138
|
+
# Wrap in units for display
|
|
139
|
+
mr_cape = mr_cape_val * mru("J/kg")
|
|
140
|
+
mr_cin = mr_cin_val * mru("J/kg")
|
|
141
|
+
mr_lcl_p, mr_lcl_t = mr_lcl(p_mr[0], t_mr[0], td_mr[0])
|
|
142
|
+
mr_pwat = mr_pw(p_mr, td_mr)
|
|
143
|
+
mr_k = mr_ki(p_mr, t_mr, td_mr)
|
|
144
|
+
mr_t = mr_tt(p_mr, t_mr, td_mr)
|
|
145
|
+
|
|
146
|
+
# SharpJS reference values
|
|
147
|
+
sjs = {
|
|
148
|
+
"sbcape": 1254.83, "sbcin": -7.62, "sb_lcl": 905.92, "sb_lfc": 900.0, "sb_el": 200.0,
|
|
149
|
+
"mlcape": 782.51, "mlcin": -1.73, "ml_lcl": 884.0,
|
|
150
|
+
"mucape": 1254.83, "mucin": -7.62,
|
|
151
|
+
"li": -3.37, "pwat": 1.23, "ki": 17.88, "tt": 43.97, "ct": 20.40, "vt": 23.58,
|
|
152
|
+
"rm_dir": 337.3, "rm_spd": 24.80,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
print("=" * 78)
|
|
156
|
+
print(" PARCELS SharpJS MetPy metrust")
|
|
157
|
+
print("-" * 78)
|
|
158
|
+
print(f" SBCAPE (J/kg) {sjs['sbcape']:9.1f} {mp_sbcape.magnitude:9.1f} {mr_cape.magnitude:9.1f}")
|
|
159
|
+
print(f" SBCIN (J/kg) {sjs['sbcin']:9.2f} {mp_sbcin.magnitude:9.2f} {mr_cin.magnitude:9.2f}")
|
|
160
|
+
print(f" SB LCL (hPa) {sjs['sb_lcl']:9.2f} {mp_lcl_p.magnitude:9.2f} {mr_lcl_p.magnitude:9.2f}")
|
|
161
|
+
try:
|
|
162
|
+
print(f" SB LFC (hPa) {sjs['sb_lfc']:9.2f} {mp_lfc_p.magnitude:9.2f}")
|
|
163
|
+
except: print(f" SB LFC (hPa) {sjs['sb_lfc']:9.2f} nan")
|
|
164
|
+
try:
|
|
165
|
+
print(f" SB EL (hPa) {sjs['sb_el']:9.2f} {mp_el_p.magnitude:9.2f}")
|
|
166
|
+
except: print(f" SB EL (hPa) {sjs['sb_el']:9.2f} nan")
|
|
167
|
+
print(f" MLCAPE (J/kg) {sjs['mlcape']:9.1f} {mp_mlcape.magnitude:9.1f}")
|
|
168
|
+
print(f" MLCIN (J/kg) {sjs['mlcin']:9.2f} {mp_mlcin.magnitude:9.2f}")
|
|
169
|
+
print(f" MUCAPE (J/kg) {sjs['mucape']:9.1f} {mp_mucape.magnitude:9.1f}")
|
|
170
|
+
print(f" LI {sjs['li']:9.2f} {mp_li.magnitude[0]:9.2f}")
|
|
171
|
+
print()
|
|
172
|
+
|
|
173
|
+
print(" INDICES SharpJS MetPy metrust")
|
|
174
|
+
print("-" * 78)
|
|
175
|
+
print(f" K-Index {sjs['ki']:9.2f} {mp_ki.magnitude:9.2f} {mr_k.magnitude:9.2f}")
|
|
176
|
+
print(f" Total Totals {sjs['tt']:9.2f} {mp_tt.magnitude:9.2f} {mr_t.magnitude:9.2f}")
|
|
177
|
+
print(f" Cross Totals {sjs['ct']:9.2f} {mp_ct.magnitude:9.2f}")
|
|
178
|
+
print(f" Vert Totals {sjs['vt']:9.2f} {mp_vt.magnitude:9.2f}")
|
|
179
|
+
print(f" PWAT (in) {sjs['pwat']:9.2f} {mp_pw.to('inch').magnitude:9.2f} {(mr_pwat.magnitude/25.4 if mr_pwat.magnitude > 5 else mr_pwat.magnitude):9.2f}")
|
|
180
|
+
print()
|
|
181
|
+
|
|
182
|
+
print(" SHEAR (kts) SharpJS MetPy")
|
|
183
|
+
print("-" * 78)
|
|
184
|
+
for depth, label, ref in [(500,"0-500m",5.54),(1000,"0-1km",5.83),(3000,"0-3km",12.38),(6000,"0-6km",18.35)]:
|
|
185
|
+
ms = mp_shear(depth)
|
|
186
|
+
print(f" {label:15s} {ref:9.2f} {ms:9.2f} ({ms-ref:+.2f})")
|
|
187
|
+
print()
|
|
188
|
+
|
|
189
|
+
print(" SRH (m2/s2) SharpJS MetPy")
|
|
190
|
+
print("-" * 78)
|
|
191
|
+
for depth, label, ref in [(500,"0-500m",3.73),(1000,"0-1km",3.70),(3000,"0-3km",33.04)]:
|
|
192
|
+
tot, pos, neg = mp_srh(depth)
|
|
193
|
+
print(f" {label:15s} {ref:9.2f} {tot:9.2f} ({tot-ref:+.2f})")
|
|
194
|
+
print()
|
|
195
|
+
|
|
196
|
+
print(" STORM MOTION SharpJS MetPy")
|
|
197
|
+
print("-" * 78)
|
|
198
|
+
print(f" Bunkers RM {sjs['rm_dir']:5.1f}/{sjs['rm_spd']:5.2f} {mp_rm_dir:5.1f}/{mp_rm_spd:5.2f}")
|
|
199
|
+
print()
|
|
200
|
+
|
|
201
|
+
print(" LAPSE RATES SharpJS MetPy")
|
|
202
|
+
print("-" * 78)
|
|
203
|
+
for (pb,pt), label, ref in [((1000,850),"1000-850",9.48),((925,700),"925-700",6.36),
|
|
204
|
+
((850,500),"850-500",5.84),((700,500),"700-500",6.14),((500,300),"500-300",7.75)]:
|
|
205
|
+
v = lr(pb, pt)
|
|
206
|
+
print(f" {label:15s} {ref:9.2f} {v:9.2f} ({v-ref:+.2f})")
|
|
207
|
+
print("=" * 78)
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|