Delegate meteoSI.py to the standalone meteo_si package - #64
Merged
Merged
Conversation
python/pyPamtra/meteoSI.py duplicated a lot of general-purpose humidity/ density/temperature formulas that already exist, independently maintained and tested, in maahn/meteo_si (same author, MIT-licensed, on PyPI). This switches the functions that already match to thin delegating wrappers (e2q, q2e, T_virt_q, T_virt_rh, moist_rho_q, moist_rho_rh, rh2q, rh2a, a2rh, q2rh, rh_to_iwv, usStandard), re-exports the shared constants from meteo_si.constants, and keeps only the genuinely PAMTRA-specific adiabatic-LWC cloud physics (detect_liq_cloud, adiab, mod_ad, pseudoAdiabLapseRate, vaphet) implemented locally, since meteo_si has no equivalent for those. One finding shaped the whole refactor: meteoSI.e_sat_gg_water (Goff & Gratch 1946) and meteo_si.humidity.e_sat_gg_water (WMO CIMO Guide 2008) are two different formulas that happen to share a name -- confirmed by diffing both sources, not by name alone. src/e_sat_gg_water.f90 (the Fortran core) uses the same Goff-Gratch formula as the Python side, and the two need to stay numerically consistent since Python builds the profiles the Fortran engine then runs radiative transfer on. So this isn't a plain find-and-replace: meteo_si gained a new, distinctly-named e_sat_goffgratch_water (this repo's own PR to that project, merged and released as meteo_si 0.2.0), and every function here that depends on saturation vapor pressure (rh2q, rh2a, a2rh, q2rh, moist_rho_rh, rh_to_iwv) passes that in explicitly via meteo_si's existing e_sat_func override parameter. PAMTRA's own e_sat_gg_water name is preserved as a one-line alias to it, so nothing calling pyPamtra.meteoSI.e_sat_gg_water (including tests/test_meteosi.py) needs to change. Incidental fix: the old rh_to_iwv was actually broken (referenced the undefined name meteoSI.rh2q/meteoSI.moist_rho_q from inside the same module, and a bare exp that doesn't exist -- would NameError if ever called). It's dead code today (grepped -- nothing in this codebase calls it), but delegating to meteo_si's working version fixes it anyway. usStandard (1976 US Standard Atmosphere) moved to meteo_si too, as a new atmosphere.py module there (also part of the same PR/release) -- the underlying algorithm is Ralph Carmichael's public-domain Fortran (PDAS), and this was Maahn's own Python translation of it, previously living only here. pyproject.toml/pixi.toml: added meteo_si>=0.2 as a dependency (pixi via [pypi-dependencies], since meteo_si isn't on conda-forge yet -- no conda-forge/meteo_si-feedstock exists -- pixi mixes conda + PyPI deps natively). conda-recipe/recipe.yaml also lists it in requirements.run (its --no-deps pip install needs every dependency spelled out there) with a comment on the same conda-forge gap; that recipe isn't usable for an actual conda-forge build until meteo_si has a feedstock, which is a separate submission process out of scope here. Verified: full pytest suite (66/66), specifically test_meteosi.py and test_regression.py (golden-output radiative-transfer regression) -- proof that routing humidity/density conversions through meteo_si with the Goff-Gratch override didn't change a single computed value. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pixi.toml gained a [pypi-dependencies] entry for meteo_si in the previous commit but the lock file was never regenerated, so CI's pixi install --locked (which requires an exact match) failed immediately with "lock file not up-to-date with the workspace". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4 of 5 tasks
maahn
added a commit
that referenced
this pull request
Aug 20, 2026
First real PyPI-availability release -- no functional/physics changes to PAMTRA itself, this is the packaging work from #64/#65 (meteo_si split, static-OpenBLAS/FFTW wheel pipeline, cibuildwheel, Python 3.10 support). Bumped rather than kept at 1.0.3 (the existing conda-forge version) to mark that milestone distinctly. All three places RELEASING.md documents (pyproject.toml, meson.build, conda-recipe/recipe.yaml) updated together. conda-recipe/recipe.yaml's source.sha256 is intentionally left at the old 1.0.3 tarball's checksum for now -- RELEASING.md's own process computes that from the real v1.1.0 tag's generated tarball, which doesn't exist until after this is tagged. That recipe isn't used by this release itself (only PyPI); the conda-forge feedstock update is a separate, later step. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Delegate meteoSI.py to the standalone meteo_si package
python/pyPamtra/meteoSI.py duplicated a lot of general-purpose humidity/
density/temperature formulas that already exist, independently maintained
and tested, in maahn/meteo_si (same author, MIT-licensed, on PyPI). This
switches the functions that already match to thin delegating wrappers
(e2q, q2e, T_virt_q, T_virt_rh, moist_rho_q, moist_rho_rh, rh2q, rh2a,
a2rh, q2rh, rh_to_iwv, usStandard), re-exports the shared constants from
meteo_si.constants, and keeps only the genuinely PAMTRA-specific
adiabatic-LWC cloud physics (detect_liq_cloud, adiab, mod_ad,
pseudoAdiabLapseRate, vaphet) implemented locally, since meteo_si has no
equivalent for those.
One finding shaped the whole refactor: meteoSI.e_sat_gg_water (Goff &
Gratch 1946) and meteo_si.humidity.e_sat_gg_water (WMO CIMO Guide 2008)
are two different formulas that happen to share a name -- confirmed by
diffing both sources, not by name alone. src/e_sat_gg_water.f90 (the
Fortran core) uses the same Goff-Gratch formula as the Python side, and
the two need to stay numerically consistent since Python builds the
profiles the Fortran engine then runs radiative transfer on. So this
isn't a plain find-and-replace: meteo_si gained a new, distinctly-named
e_sat_goffgratch_water (this repo's own PR to that project, merged and
released as meteo_si 0.2.0), and every function here that depends on
saturation vapor pressure (rh2q, rh2a, a2rh, q2rh, moist_rho_rh,
rh_to_iwv) passes that in explicitly via meteo_si's existing e_sat_func
override parameter. PAMTRA's own e_sat_gg_water name is preserved as a
one-line alias to it, so nothing calling pyPamtra.meteoSI.e_sat_gg_water
(including tests/test_meteosi.py) needs to change.
Incidental fix: the old rh_to_iwv was actually broken (referenced the
undefined name meteoSI.rh2q/meteoSI.moist_rho_q from inside the same
module, and a bare exp that doesn't exist -- would NameError if ever
called). It's dead code today (grepped -- nothing in this codebase calls
it), but delegating to meteo_si's working version fixes it anyway.
usStandard (1976 US Standard Atmosphere) moved to meteo_si too, as a new
atmosphere.py module there (also part of the same PR/release) -- the
underlying algorithm is Ralph Carmichael's public-domain Fortran (PDAS),
and this was Maahn's own Python translation of it, previously living only
here.
pyproject.toml/pixi.toml: added meteo_si>=0.2 as a dependency (pixi via
[pypi-dependencies], since meteo_si isn't on conda-forge yet -- no
conda-forge/meteo_si-feedstock exists -- pixi mixes conda + PyPI deps
natively). conda-recipe/recipe.yaml also lists it in requirements.run
(its --no-deps pip install needs every dependency spelled out there) with
a comment on the same conda-forge gap; that recipe isn't usable for an
actual conda-forge build until meteo_si has a feedstock, which is a
separate submission process out of scope here.
Verified: full pytest suite (66/66), specifically test_meteosi.py and
test_regression.py (golden-output radiative-transfer regression) --
proof that routing humidity/density conversions through meteo_si with
the Goff-Gratch override didn't change a single computed value.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com