ggah-mod 1.0.0__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 (146) hide show
  1. ggah_mod-1.0.0/LICENSE +21 -0
  2. ggah_mod-1.0.0/PKG-INFO +225 -0
  3. ggah_mod-1.0.0/README.md +174 -0
  4. ggah_mod-1.0.0/ggah_mod/__init__.py +41 -0
  5. ggah_mod-1.0.0/ggah_mod/_wip.py +38 -0
  6. ggah_mod-1.0.0/ggah_mod/backend.py +605 -0
  7. ggah_mod-1.0.0/ggah_mod/cosmology/__init__.py +66 -0
  8. ggah_mod-1.0.0/ggah_mod/cosmology/amplitude.py +210 -0
  9. ggah_mod-1.0.0/ggah_mod/cosmology/background.py +268 -0
  10. ggah_mod-1.0.0/ggah_mod/cosmology/constants.py +281 -0
  11. ggah_mod-1.0.0/ggah_mod/cosmology/growth.py +276 -0
  12. ggah_mod-1.0.0/ggah_mod/cosmology/parameters.py +746 -0
  13. ggah_mod-1.0.0/ggah_mod/cosmology/power.py +923 -0
  14. ggah_mod-1.0.0/ggah_mod/covariance/__init__.py +87 -0
  15. ggah_mod-1.0.0/ggah_mod/covariance/gaussian.py +350 -0
  16. ggah_mod-1.0.0/ggah_mod/covariance/geometry.py +387 -0
  17. ggah_mod-1.0.0/ggah_mod/covariance/lensing.py +221 -0
  18. ggah_mod-1.0.0/ggah_mod/covariance/multihalo.py +414 -0
  19. ggah_mod-1.0.0/ggah_mod/covariance/spec.py +725 -0
  20. ggah_mod-1.0.0/ggah_mod/covariance/supersample.py +222 -0
  21. ggah_mod-1.0.0/ggah_mod/covariance/trispectrum.py +471 -0
  22. ggah_mod-1.0.0/ggah_mod/data/apec/apec_cooling.npz +0 -0
  23. ggah_mod-1.0.0/ggah_mod/data/bnl/mdr1_bnl.npz +0 -0
  24. ggah_mod-1.0.0/ggah_mod/halos/__init__.py +180 -0
  25. ggah_mod-1.0.0/ggah_mod/halos/_cemulator_compat.py +273 -0
  26. ggah_mod-1.0.0/ggah_mod/halos/beyond_linear_bias.py +1065 -0
  27. ggah_mod-1.0.0/ggah_mod/halos/calibration.py +392 -0
  28. ggah_mod-1.0.0/ggah_mod/halos/concentration.py +1105 -0
  29. ggah_mod-1.0.0/ggah_mod/halos/field.py +800 -0
  30. ggah_mod-1.0.0/ggah_mod/halos/lensing_profiles.py +523 -0
  31. ggah_mod-1.0.0/ggah_mod/halos/linear_bias.py +249 -0
  32. ggah_mod-1.0.0/ggah_mod/halos/mass_definitions.py +303 -0
  33. ggah_mod-1.0.0/ggah_mod/halos/mass_function.py +1028 -0
  34. ggah_mod-1.0.0/ggah_mod/halos/profiles.py +542 -0
  35. ggah_mod-1.0.0/ggah_mod/halos/variance.py +235 -0
  36. ggah_mod-1.0.0/ggah_mod/interfaces/__init__.py +12 -0
  37. ggah_mod-1.0.0/ggah_mod/interfaces/cobaya.py +380 -0
  38. ggah_mod-1.0.0/ggah_mod/numerics.py +280 -0
  39. ggah_mod-1.0.0/ggah_mod/observables/__init__.py +70 -0
  40. ggah_mod-1.0.0/ggah_mod/observables/beams.py +83 -0
  41. ggah_mod-1.0.0/ggah_mod/observables/kernels.py +307 -0
  42. ggah_mod-1.0.0/ggah_mod/observables/limber.py +128 -0
  43. ggah_mod-1.0.0/ggah_mod/observables/real_space.py +608 -0
  44. ggah_mod-1.0.0/ggah_mod/observables/spec.py +430 -0
  45. ggah_mod-1.0.0/ggah_mod/observables/transforms.py +753 -0
  46. ggah_mod-1.0.0/ggah_mod/sectors/__init__.py +155 -0
  47. ggah_mod-1.0.0/ggah_mod/sectors/agn.py +2155 -0
  48. ggah_mod-1.0.0/ggah_mod/sectors/alignments.py +239 -0
  49. ggah_mod-1.0.0/ggah_mod/sectors/calibration.py +290 -0
  50. ggah_mod-1.0.0/ggah_mod/sectors/census.py +289 -0
  51. ggah_mod-1.0.0/ggah_mod/sectors/clf.py +282 -0
  52. ggah_mod-1.0.0/ggah_mod/sectors/coldgas.py +1318 -0
  53. ggah_mod-1.0.0/ggah_mod/sectors/cooling.py +567 -0
  54. ggah_mod-1.0.0/ggah_mod/sectors/ejecta.py +220 -0
  55. ggah_mod-1.0.0/ggah_mod/sectors/energetics.py +796 -0
  56. ggah_mod-1.0.0/ggah_mod/sectors/galaxies.py +979 -0
  57. ggah_mod-1.0.0/ggah_mod/sectors/gas.py +1083 -0
  58. ggah_mod-1.0.0/ggah_mod/sectors/matter.py +508 -0
  59. ggah_mod-1.0.0/ggah_mod/sectors/miscentering.py +182 -0
  60. ggah_mod-1.0.0/ggah_mod/sectors/occupation.py +803 -0
  61. ggah_mod-1.0.0/ggah_mod/sectors/occupation_params.py +312 -0
  62. ggah_mod-1.0.0/ggah_mod/sectors/params.py +499 -0
  63. ggah_mod-1.0.0/ggah_mod/sectors/png.py +169 -0
  64. ggah_mod-1.0.0/ggah_mod/sectors/protocol.py +364 -0
  65. ggah_mod-1.0.0/ggah_mod/sectors/sham.py +641 -0
  66. ggah_mod-1.0.0/ggah_mod/spectra/__init__.py +60 -0
  67. ggah_mod-1.0.0/ggah_mod/spectra/bnl.py +141 -0
  68. ggah_mod-1.0.0/ggah_mod/spectra/counterterm.py +223 -0
  69. ggah_mod-1.0.0/ggah_mod/spectra/neutrinos.py +101 -0
  70. ggah_mod-1.0.0/ggah_mod/spectra/pair.py +239 -0
  71. ggah_mod-1.0.0/ggah_mod/spectra/pk.py +233 -0
  72. ggah_mod-1.0.0/ggah_mod/spectra/spec.py +337 -0
  73. ggah_mod-1.0.0/ggah_mod/spectra/tracers.py +533 -0
  74. ggah_mod-1.0.0/ggah_mod/spectra/transition.py +257 -0
  75. ggah_mod-1.0.0/ggah_mod.egg-info/PKG-INFO +225 -0
  76. ggah_mod-1.0.0/ggah_mod.egg-info/SOURCES.txt +144 -0
  77. ggah_mod-1.0.0/ggah_mod.egg-info/dependency_links.txt +1 -0
  78. ggah_mod-1.0.0/ggah_mod.egg-info/requires.txt +33 -0
  79. ggah_mod-1.0.0/ggah_mod.egg-info/top_level.txt +1 -0
  80. ggah_mod-1.0.0/pyproject.toml +201 -0
  81. ggah_mod-1.0.0/setup.cfg +4 -0
  82. ggah_mod-1.0.0/tests/test_agn.py +1700 -0
  83. ggah_mod-1.0.0/tests/test_alignments.py +198 -0
  84. ggah_mod-1.0.0/tests/test_amplitude.py +167 -0
  85. ggah_mod-1.0.0/tests/test_backends.py +512 -0
  86. ggah_mod-1.0.0/tests/test_background.py +265 -0
  87. ggah_mod-1.0.0/tests/test_baryon_observables.py +280 -0
  88. ggah_mod-1.0.0/tests/test_beyond_linear_bias.py +875 -0
  89. ggah_mod-1.0.0/tests/test_bnl_build.py +87 -0
  90. ggah_mod-1.0.0/tests/test_census.py +407 -0
  91. ggah_mod-1.0.0/tests/test_clf.py +193 -0
  92. ggah_mod-1.0.0/tests/test_cobaya_interface.py +238 -0
  93. ggah_mod-1.0.0/tests/test_coherence.py +642 -0
  94. ggah_mod-1.0.0/tests/test_coldgas.py +464 -0
  95. ggah_mod-1.0.0/tests/test_coldgas_galaxies.py +437 -0
  96. ggah_mod-1.0.0/tests/test_coldgas_profile.py +430 -0
  97. ggah_mod-1.0.0/tests/test_contract_edges.py +300 -0
  98. ggah_mod-1.0.0/tests/test_cooling.py +481 -0
  99. ggah_mod-1.0.0/tests/test_covariance.py +665 -0
  100. ggah_mod-1.0.0/tests/test_covariance_nongaussian.py +850 -0
  101. ggah_mod-1.0.0/tests/test_cross_repo.py +165 -0
  102. ggah_mod-1.0.0/tests/test_curvature.py +361 -0
  103. ggah_mod-1.0.0/tests/test_curvature_halos.py +648 -0
  104. ggah_mod-1.0.0/tests/test_docs.py +210 -0
  105. ggah_mod-1.0.0/tests/test_downstream_contract.py +153 -0
  106. ggah_mod-1.0.0/tests/test_ejecta.py +224 -0
  107. ggah_mod-1.0.0/tests/test_end_to_end.py +218 -0
  108. ggah_mod-1.0.0/tests/test_energetics.py +644 -0
  109. ggah_mod-1.0.0/tests/test_field.py +1178 -0
  110. ggah_mod-1.0.0/tests/test_galaxies.py +506 -0
  111. ggah_mod-1.0.0/tests/test_gas.py +893 -0
  112. ggah_mod-1.0.0/tests/test_gas_x_ray_temperature.py +104 -0
  113. ggah_mod-1.0.0/tests/test_growth.py +115 -0
  114. ggah_mod-1.0.0/tests/test_halos.py +384 -0
  115. ggah_mod-1.0.0/tests/test_hmf_cache_and_traces.py +104 -0
  116. ggah_mod-1.0.0/tests/test_lensing_goldens.py +414 -0
  117. ggah_mod-1.0.0/tests/test_lensing_profiles.py +125 -0
  118. ggah_mod-1.0.0/tests/test_limber.py +258 -0
  119. ggah_mod-1.0.0/tests/test_matter_neutrinos.py +88 -0
  120. ggah_mod-1.0.0/tests/test_miscentering.py +156 -0
  121. ggah_mod-1.0.0/tests/test_neutrino_split.py +315 -0
  122. ggah_mod-1.0.0/tests/test_nu_convention.py +253 -0
  123. ggah_mod-1.0.0/tests/test_observables_paths.py +152 -0
  124. ggah_mod-1.0.0/tests/test_occupation.py +405 -0
  125. ggah_mod-1.0.0/tests/test_occupation_params.py +237 -0
  126. ggah_mod-1.0.0/tests/test_one_mass_definition.py +165 -0
  127. ggah_mod-1.0.0/tests/test_parameters.py +193 -0
  128. ggah_mod-1.0.0/tests/test_parity_budget.py +532 -0
  129. ggah_mod-1.0.0/tests/test_paths.py +672 -0
  130. ggah_mod-1.0.0/tests/test_pk_correction.py +135 -0
  131. ggah_mod-1.0.0/tests/test_plan_is_true.py +582 -0
  132. ggah_mod-1.0.0/tests/test_png.py +207 -0
  133. ggah_mod-1.0.0/tests/test_power.py +361 -0
  134. ggah_mod-1.0.0/tests/test_priors_match_table.py +188 -0
  135. ggah_mod-1.0.0/tests/test_profiles.py +1189 -0
  136. ggah_mod-1.0.0/tests/test_real_space.py +674 -0
  137. ggah_mod-1.0.0/tests/test_refusals.py +589 -0
  138. ggah_mod-1.0.0/tests/test_sector_coherence.py +464 -0
  139. ggah_mod-1.0.0/tests/test_sectors_paths.py +557 -0
  140. ggah_mod-1.0.0/tests/test_single_precision.py +468 -0
  141. ggah_mod-1.0.0/tests/test_spec.py +566 -0
  142. ggah_mod-1.0.0/tests/test_spectra.py +1726 -0
  143. ggah_mod-1.0.0/tests/test_spectra_paths.py +181 -0
  144. ggah_mod-1.0.0/tests/test_transforms.py +462 -0
  145. ggah_mod-1.0.0/tests/test_universemachine.py +288 -0
  146. ggah_mod-1.0.0/tests/test_work_in_progress.py +48 -0
ggah_mod-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Johan Comparat
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,225 @@
1
+ Metadata-Version: 2.4
2
+ Name: ggah_mod
3
+ Version: 1.0.0
4
+ Summary: A layered, differentiable halo-model forward model for galaxies, gas and AGN
5
+ Author-email: Johan Comparat <jcomparat@lpsc.in2p3.fr>
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://ggah-mod.readthedocs.io
8
+ Project-URL: Source, https://github.com/JohanComparat/ggah_mod
9
+ Project-URL: Issues, https://github.com/JohanComparat/ggah_mod/issues
10
+ Keywords: cosmology,halo model,large-scale structure,galaxy-halo connection,AGN,intracluster medium,JAX,automatic differentiation
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
19
+ Classifier: Topic :: Scientific/Engineering :: Physics
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: numpy
24
+ Requires-Dist: scipy
25
+ Requires-Dist: jax
26
+ Requires-Dist: jaxlib
27
+ Requires-Dist: emu_pk<3,>=2.0.1
28
+ Requires-Dist: emu_hmf<2,>=1.2.0
29
+ Provides-Extra: reference
30
+ Requires-Dist: classy<3.4,>=3.3.4; extra == "reference"
31
+ Provides-Extra: backends
32
+ Requires-Dist: camb; extra == "backends"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest; extra == "dev"
35
+ Requires-Dist: pytest-cov; extra == "dev"
36
+ Requires-Dist: pytest-xdist; extra == "dev"
37
+ Requires-Dist: astropy; extra == "dev"
38
+ Requires-Dist: colossus; extra == "dev"
39
+ Requires-Dist: camb; extra == "dev"
40
+ Provides-Extra: tables
41
+ Requires-Dist: soxs; extra == "tables"
42
+ Provides-Extra: cobaya
43
+ Requires-Dist: cobaya; extra == "cobaya"
44
+ Provides-Extra: docs
45
+ Requires-Dist: sphinx>=7; extra == "docs"
46
+ Requires-Dist: furo; extra == "docs"
47
+ Requires-Dist: myst-nb>=1; extra == "docs"
48
+ Requires-Dist: sphinx-copybutton; extra == "docs"
49
+ Requires-Dist: sphinxcontrib-bibtex>=2.6; extra == "docs"
50
+ Dynamic: license-file
51
+
52
+ # ggah_mod
53
+
54
+ [![PyPI](https://img.shields.io/pypi/v/ggah_mod.svg)](https://pypi.org/project/ggah_mod/)
55
+ [![Python](https://img.shields.io/pypi/pyversions/ggah_mod.svg)](https://pypi.org/project/ggah_mod/)
56
+ [![Documentation](https://readthedocs.org/projects/ggah-mod/badge/?version=latest)](https://ggah-mod.readthedocs.io)
57
+ [![Tests](https://github.com/JohanComparat/ggah_mod/actions/workflows/ci.yml/badge.svg)](https://github.com/JohanComparat/ggah_mod/actions/workflows/ci.yml)
58
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/JohanComparat/ggah_mod/blob/main/LICENSE)
59
+
60
+ **G**alaxies, **g**as, **A**GN and **h**alos: a layered, differentiable
61
+ halo-model forward model.
62
+
63
+ `ggah_mod` predicts the power spectrum of any pair of tracers, and its
64
+ projections, from one set of cosmological and astrophysical parameters.
65
+ It is written in JAX, so every prediction can be differentiated with respect to
66
+ every parameter, exactly.
67
+
68
+ **Documentation: <https://ggah-mod.readthedocs.io>**
69
+
70
+ ## Install
71
+
72
+ <!-- install-start -->
73
+ `ggah_mod` needs Python ≥ 3.11:
74
+
75
+ ```bash
76
+ pip install ggah_mod
77
+ ```
78
+
79
+ or, to work on it, from a clone:
80
+
81
+ ```bash
82
+ git clone https://github.com/JohanComparat/ggah_mod.git
83
+ cd ggah_mod
84
+ pip install -e .
85
+ ```
86
+
87
+ That is the differentiable path, and it needs no compiler: numpy, scipy, JAX, and
88
+ the two emulators it reads, [`emu_pk`](https://github.com/JohanComparat/emu_pk)
89
+ for the linear power spectrum and
90
+ [`emu_hmf`](https://github.com/JohanComparat/emu_hmf) for the mass function, both
91
+ also from PyPI. Check it with
92
+
93
+ ```bash
94
+ python -c "import ggah_mod; print(ggah_mod.__version__)"
95
+ ```
96
+
97
+ Optional extras add the rest, e.g. `pip install "ggah_mod[reference]"`:
98
+
99
+ | extra | installs | for |
100
+ |---|---|---|
101
+ | `reference` | `classy` | CLASS, the linear spectrum of the `ACCURATE` flavour; pip compiles it, so a C compiler is needed |
102
+ | `backends` | `camb` | CAMB, the alternative Boltzmann backend |
103
+ | `cobaya` | `cobaya` | `ggah_mod.interfaces.cobaya`, a cobaya `Theory` |
104
+ | `tables` | `soxs` | regenerating the shipped APEC cooling table |
105
+ | `dev` | `pytest`, `pytest-cov`, `pytest-xdist`, `astropy`, `colossus`, `camb` | the test suite |
106
+ | `docs` | `sphinx`, `furo`, `myst-nb`, `sphinx-copybutton`, `sphinxcontrib-bibtex` | building the documentation |
107
+
108
+ With conda or mamba,
109
+ [`environment.yml`](https://github.com/JohanComparat/ggah_mod/blob/main/environment.yml)
110
+ creates an environment with `ggah_mod`, the CPU build of `jaxlib`, and
111
+ `matplotlib` and a Jupyter kernel for the documentation notebooks:
112
+
113
+ ```bash
114
+ mamba env create -f environment.yml
115
+ mamba activate ggah_mod
116
+ ```
117
+
118
+ JAX installs its CPU build by default; for a GPU, install the matching `jax`
119
+ build first, following the [JAX installation guide](https://docs.jax.dev/en/latest/installation.html).
120
+ <!-- install-end -->
121
+
122
+ ## Quickstart
123
+
124
+ <!-- quickstart-start -->
125
+ ```python
126
+ import jax
127
+ jax.config.update("jax_enable_x64", True) # before the first ggah_mod import
128
+
129
+ import numpy as np
130
+ from ggah_mod import DIFFERENTIABLE
131
+ from ggah_mod.cosmology import PLANCK18, comoving_distance, make_pk, sigma8
132
+ from ggah_mod.halos.field import make_field
133
+
134
+ # Layer 1: the linear power spectrum, and what is read off it.
135
+ pk = make_pk("emu_pk") # "class" needs the [reference] extra
136
+ k = np.logspace(-4, np.log10(200.0), 512) # h/Mpc
137
+ print(sigma8(pk.pk(k, 0.0, PLANCK18), k)) # an output, never an input
138
+ print(comoving_distance(np.array([0.5, 1.0]), PLANCK18)) # h^-1 Mpc
139
+
140
+ # Layer 2: mass function, bias, concentration and profiles on one mass grid.
141
+ field = make_field(PLANCK18, DIFFERENTIABLE, pk, z=0.5)
142
+ print(field.m[::64]) # h^-1 Msun
143
+ print(field.dndm[::64], field.bias[::64]) # dn/dM, b(M)
144
+
145
+ # Everything is differentiable: d sigma_8 / d Omega_m through the emulator.
146
+ d_sigma8 = jax.grad(lambda om: sigma8(pk.pk(k, 0.0, PLANCK18.replace(Omega_m=om)), k))
147
+ print(d_sigma8(0.31))
148
+ ```
149
+ <!-- quickstart-end -->
150
+
151
+ ## The six layers
152
+
153
+ Each layer depends only on the ones above it.
154
+
155
+ | layer | subpackage | computes | documentation |
156
+ |---|---|---|---|
157
+ | 1 | `ggah_mod.cosmology` | parameters and density budget, background and distances, linear `P(k)`, amplitude and growth | [layer 1](https://ggah-mod.readthedocs.io/en/latest/layer1_cosmology.html) |
158
+ | 2 | `ggah_mod.halos` | variance and peak height, mass function, bias, concentration, profiles, the halo field | [layer 2](https://ggah-mod.readthedocs.io/en/latest/layer2_halos.html) |
159
+ | 3 | `ggah_mod.sectors` | the tracers | ⚠️ work in progress |
160
+ | 4 | `ggah_mod.spectra` | power spectra of pairs of tracers | ⚠️ work in progress |
161
+ | 5 | `ggah_mod.observables` | projected observables | ⚠️ work in progress |
162
+ | 6 | `ggah_mod.covariance` | covariances of data vectors | ⚠️ work in progress |
163
+ | — | `ggah_mod.interfaces` | adapters that let other packages drive this one | ⚠️ work in progress |
164
+
165
+ Beside them, `ggah_mod.backend` holds the flavours below, `ggah_mod.numerics` the
166
+ numerical helpers several layers share, and `ggah_mod/data` the distilled tables
167
+ the package ships.
168
+ **Layers 3 to 6 and the interfaces are work in progress**: released as tested
169
+ code ahead of their verification and documentation, so their interface and
170
+ results may change. Importing any of them emits a `ggah_mod.WorkInProgressWarning`
171
+ once; `warnings.filterwarnings("ignore", category=ggah_mod.WorkInProgressWarning)`
172
+ silences it.
173
+
174
+ ## Two flavours of one model
175
+
176
+ The same code runs in two flavours, selected by a `Backend`:
177
+
178
+ - **`ACCURATE`**: a Boltzmann solver (CLASS by default, CAMB as the
179
+ alternative), fine grids, exact quadrature. For fitting.
180
+ - **`DIFFERENTIABLE`**: the `emu_pk` emulator, coarser grids. Differentiable end
181
+ to end. For forecasting. `DIFFERENTIABLE_COARSE` is the same flavour on
182
+ smaller grids.
183
+
184
+ They are not two implementations: only the linear power spectrum forks. The
185
+ disagreement between them is *measured*, row by row, in the parity budget
186
+ (`tests/test_parity_budget.py`), never assumed.
187
+
188
+ ## Decisions fixed once
189
+
190
+ - **One amplitude.** `ln10A_s`. `sigma8` and `S8` are outputs, computed from the
191
+ spectrum. Passing either as an input raises.
192
+ - **`Omega_m` contains the neutrinos.** The budget
193
+ `Omega_b + Omega_cdm + Omega_nu == Omega_m` closes exactly, with `Omega_nu`
194
+ the neutrinos' rest mass.
195
+ - **One neutrino convention, CLASS's.** Three massive states at
196
+ `T_ncdm = 0.71611 T_CMB` plus a massless remainder of `N_eff = 3.044`, on the
197
+ exact energy integral over their relic spectrum: the rest mass is
198
+ `Sigma m/(93.143 eV h^2)`, and at 0.06 eV in the degenerate ordering the
199
+ neutrino density today exceeds it by 5.0e-4, which is their kinetic energy and
200
+ the remainder. `CambPk` is handed the same neutrinos, spelt in CAMB's interface.
201
+ - **Cold and total densities are separately named.** Halos form from
202
+ `rho_cold`; lensing sees `rho_matter`. Neither ever stands in for the other.
203
+ - **One growth route**, with no silent fallback to an approximation.
204
+ - **Nothing is fixed by hard-coding.** A constant a user might want to vary is
205
+ a parameter with a prior and a bound.
206
+
207
+ ## Status
208
+
209
+ Version 1.0 is the first public release. Layers 1 and 2 are verified and
210
+ documented. Layers 3 to 6 are work in progress: implemented and tested, with
211
+ their verification ongoing and their documentation to follow it. Calibrated values of the
212
+ astrophysical parameters are not yet released.
213
+
214
+ Contributing and the development environment are described in
215
+ [`CONTRIBUTING.md`](https://github.com/JohanComparat/ggah_mod/blob/main/CONTRIBUTING.md); changes are listed in
216
+ [`CHANGELOG.md`](https://github.com/JohanComparat/ggah_mod/blob/main/CHANGELOG.md).
217
+
218
+ ## Citing
219
+
220
+ Please cite the technical paper (Comparat, in prep.) and the software, whose
221
+ metadata is in [`CITATION.cff`](https://github.com/JohanComparat/ggah_mod/blob/main/CITATION.cff).
222
+
223
+ ## License
224
+
225
+ MIT; see [`LICENSE`](https://github.com/JohanComparat/ggah_mod/blob/main/LICENSE).
@@ -0,0 +1,174 @@
1
+ # ggah_mod
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/ggah_mod.svg)](https://pypi.org/project/ggah_mod/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/ggah_mod.svg)](https://pypi.org/project/ggah_mod/)
5
+ [![Documentation](https://readthedocs.org/projects/ggah-mod/badge/?version=latest)](https://ggah-mod.readthedocs.io)
6
+ [![Tests](https://github.com/JohanComparat/ggah_mod/actions/workflows/ci.yml/badge.svg)](https://github.com/JohanComparat/ggah_mod/actions/workflows/ci.yml)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/JohanComparat/ggah_mod/blob/main/LICENSE)
8
+
9
+ **G**alaxies, **g**as, **A**GN and **h**alos: a layered, differentiable
10
+ halo-model forward model.
11
+
12
+ `ggah_mod` predicts the power spectrum of any pair of tracers, and its
13
+ projections, from one set of cosmological and astrophysical parameters.
14
+ It is written in JAX, so every prediction can be differentiated with respect to
15
+ every parameter, exactly.
16
+
17
+ **Documentation: <https://ggah-mod.readthedocs.io>**
18
+
19
+ ## Install
20
+
21
+ <!-- install-start -->
22
+ `ggah_mod` needs Python ≥ 3.11:
23
+
24
+ ```bash
25
+ pip install ggah_mod
26
+ ```
27
+
28
+ or, to work on it, from a clone:
29
+
30
+ ```bash
31
+ git clone https://github.com/JohanComparat/ggah_mod.git
32
+ cd ggah_mod
33
+ pip install -e .
34
+ ```
35
+
36
+ That is the differentiable path, and it needs no compiler: numpy, scipy, JAX, and
37
+ the two emulators it reads, [`emu_pk`](https://github.com/JohanComparat/emu_pk)
38
+ for the linear power spectrum and
39
+ [`emu_hmf`](https://github.com/JohanComparat/emu_hmf) for the mass function, both
40
+ also from PyPI. Check it with
41
+
42
+ ```bash
43
+ python -c "import ggah_mod; print(ggah_mod.__version__)"
44
+ ```
45
+
46
+ Optional extras add the rest, e.g. `pip install "ggah_mod[reference]"`:
47
+
48
+ | extra | installs | for |
49
+ |---|---|---|
50
+ | `reference` | `classy` | CLASS, the linear spectrum of the `ACCURATE` flavour; pip compiles it, so a C compiler is needed |
51
+ | `backends` | `camb` | CAMB, the alternative Boltzmann backend |
52
+ | `cobaya` | `cobaya` | `ggah_mod.interfaces.cobaya`, a cobaya `Theory` |
53
+ | `tables` | `soxs` | regenerating the shipped APEC cooling table |
54
+ | `dev` | `pytest`, `pytest-cov`, `pytest-xdist`, `astropy`, `colossus`, `camb` | the test suite |
55
+ | `docs` | `sphinx`, `furo`, `myst-nb`, `sphinx-copybutton`, `sphinxcontrib-bibtex` | building the documentation |
56
+
57
+ With conda or mamba,
58
+ [`environment.yml`](https://github.com/JohanComparat/ggah_mod/blob/main/environment.yml)
59
+ creates an environment with `ggah_mod`, the CPU build of `jaxlib`, and
60
+ `matplotlib` and a Jupyter kernel for the documentation notebooks:
61
+
62
+ ```bash
63
+ mamba env create -f environment.yml
64
+ mamba activate ggah_mod
65
+ ```
66
+
67
+ JAX installs its CPU build by default; for a GPU, install the matching `jax`
68
+ build first, following the [JAX installation guide](https://docs.jax.dev/en/latest/installation.html).
69
+ <!-- install-end -->
70
+
71
+ ## Quickstart
72
+
73
+ <!-- quickstart-start -->
74
+ ```python
75
+ import jax
76
+ jax.config.update("jax_enable_x64", True) # before the first ggah_mod import
77
+
78
+ import numpy as np
79
+ from ggah_mod import DIFFERENTIABLE
80
+ from ggah_mod.cosmology import PLANCK18, comoving_distance, make_pk, sigma8
81
+ from ggah_mod.halos.field import make_field
82
+
83
+ # Layer 1: the linear power spectrum, and what is read off it.
84
+ pk = make_pk("emu_pk") # "class" needs the [reference] extra
85
+ k = np.logspace(-4, np.log10(200.0), 512) # h/Mpc
86
+ print(sigma8(pk.pk(k, 0.0, PLANCK18), k)) # an output, never an input
87
+ print(comoving_distance(np.array([0.5, 1.0]), PLANCK18)) # h^-1 Mpc
88
+
89
+ # Layer 2: mass function, bias, concentration and profiles on one mass grid.
90
+ field = make_field(PLANCK18, DIFFERENTIABLE, pk, z=0.5)
91
+ print(field.m[::64]) # h^-1 Msun
92
+ print(field.dndm[::64], field.bias[::64]) # dn/dM, b(M)
93
+
94
+ # Everything is differentiable: d sigma_8 / d Omega_m through the emulator.
95
+ d_sigma8 = jax.grad(lambda om: sigma8(pk.pk(k, 0.0, PLANCK18.replace(Omega_m=om)), k))
96
+ print(d_sigma8(0.31))
97
+ ```
98
+ <!-- quickstart-end -->
99
+
100
+ ## The six layers
101
+
102
+ Each layer depends only on the ones above it.
103
+
104
+ | layer | subpackage | computes | documentation |
105
+ |---|---|---|---|
106
+ | 1 | `ggah_mod.cosmology` | parameters and density budget, background and distances, linear `P(k)`, amplitude and growth | [layer 1](https://ggah-mod.readthedocs.io/en/latest/layer1_cosmology.html) |
107
+ | 2 | `ggah_mod.halos` | variance and peak height, mass function, bias, concentration, profiles, the halo field | [layer 2](https://ggah-mod.readthedocs.io/en/latest/layer2_halos.html) |
108
+ | 3 | `ggah_mod.sectors` | the tracers | ⚠️ work in progress |
109
+ | 4 | `ggah_mod.spectra` | power spectra of pairs of tracers | ⚠️ work in progress |
110
+ | 5 | `ggah_mod.observables` | projected observables | ⚠️ work in progress |
111
+ | 6 | `ggah_mod.covariance` | covariances of data vectors | ⚠️ work in progress |
112
+ | — | `ggah_mod.interfaces` | adapters that let other packages drive this one | ⚠️ work in progress |
113
+
114
+ Beside them, `ggah_mod.backend` holds the flavours below, `ggah_mod.numerics` the
115
+ numerical helpers several layers share, and `ggah_mod/data` the distilled tables
116
+ the package ships.
117
+ **Layers 3 to 6 and the interfaces are work in progress**: released as tested
118
+ code ahead of their verification and documentation, so their interface and
119
+ results may change. Importing any of them emits a `ggah_mod.WorkInProgressWarning`
120
+ once; `warnings.filterwarnings("ignore", category=ggah_mod.WorkInProgressWarning)`
121
+ silences it.
122
+
123
+ ## Two flavours of one model
124
+
125
+ The same code runs in two flavours, selected by a `Backend`:
126
+
127
+ - **`ACCURATE`**: a Boltzmann solver (CLASS by default, CAMB as the
128
+ alternative), fine grids, exact quadrature. For fitting.
129
+ - **`DIFFERENTIABLE`**: the `emu_pk` emulator, coarser grids. Differentiable end
130
+ to end. For forecasting. `DIFFERENTIABLE_COARSE` is the same flavour on
131
+ smaller grids.
132
+
133
+ They are not two implementations: only the linear power spectrum forks. The
134
+ disagreement between them is *measured*, row by row, in the parity budget
135
+ (`tests/test_parity_budget.py`), never assumed.
136
+
137
+ ## Decisions fixed once
138
+
139
+ - **One amplitude.** `ln10A_s`. `sigma8` and `S8` are outputs, computed from the
140
+ spectrum. Passing either as an input raises.
141
+ - **`Omega_m` contains the neutrinos.** The budget
142
+ `Omega_b + Omega_cdm + Omega_nu == Omega_m` closes exactly, with `Omega_nu`
143
+ the neutrinos' rest mass.
144
+ - **One neutrino convention, CLASS's.** Three massive states at
145
+ `T_ncdm = 0.71611 T_CMB` plus a massless remainder of `N_eff = 3.044`, on the
146
+ exact energy integral over their relic spectrum: the rest mass is
147
+ `Sigma m/(93.143 eV h^2)`, and at 0.06 eV in the degenerate ordering the
148
+ neutrino density today exceeds it by 5.0e-4, which is their kinetic energy and
149
+ the remainder. `CambPk` is handed the same neutrinos, spelt in CAMB's interface.
150
+ - **Cold and total densities are separately named.** Halos form from
151
+ `rho_cold`; lensing sees `rho_matter`. Neither ever stands in for the other.
152
+ - **One growth route**, with no silent fallback to an approximation.
153
+ - **Nothing is fixed by hard-coding.** A constant a user might want to vary is
154
+ a parameter with a prior and a bound.
155
+
156
+ ## Status
157
+
158
+ Version 1.0 is the first public release. Layers 1 and 2 are verified and
159
+ documented. Layers 3 to 6 are work in progress: implemented and tested, with
160
+ their verification ongoing and their documentation to follow it. Calibrated values of the
161
+ astrophysical parameters are not yet released.
162
+
163
+ Contributing and the development environment are described in
164
+ [`CONTRIBUTING.md`](https://github.com/JohanComparat/ggah_mod/blob/main/CONTRIBUTING.md); changes are listed in
165
+ [`CHANGELOG.md`](https://github.com/JohanComparat/ggah_mod/blob/main/CHANGELOG.md).
166
+
167
+ ## Citing
168
+
169
+ Please cite the technical paper (Comparat, in prep.) and the software, whose
170
+ metadata is in [`CITATION.cff`](https://github.com/JohanComparat/ggah_mod/blob/main/CITATION.cff).
171
+
172
+ ## License
173
+
174
+ MIT; see [`LICENSE`](https://github.com/JohanComparat/ggah_mod/blob/main/LICENSE).
@@ -0,0 +1,41 @@
1
+ """ggah_mod -- galaxies, gas, AGN and halos, in layers.
2
+
3
+ A differentiable halo-model forward model, organised so the layer boundaries
4
+ are real:
5
+
6
+ === ====================== =================================================
7
+ L1 :mod:`ggah_mod.cosmology` background, P(k), growth, derived amplitudes
8
+ L2 :mod:`ggah_mod.halos` mass function, bias, concentration, profiles
9
+ L3 ``ggah_mod.sectors`` galaxy occupation, mis-centering, gas, AGN --
10
+ peers, none of them the host of the others
11
+ L4 :mod:`ggah_mod.spectra` one 1-halo + 2-halo integral for any tracer pair
12
+ L5 ``ggah_mod.observables`` projections: w_p, Delta Sigma, C_ell, w(theta)
13
+ === ====================== =================================================
14
+
15
+ Two flavours of the *same* assembly are selected by
16
+ :class:`ggah_mod.backend.Backend`: ``ACCURATE`` for fitting and ``DIFFERENTIABLE`` for
17
+ forecasting. Their disagreement is measured, not assumed.
18
+ """
19
+
20
+ __version__ = "1.0.0"
21
+
22
+ from . import backend, cosmology
23
+ from ._wip import WorkInProgressWarning
24
+ from .backend import (Backend, ACCURATE, DIFFERENTIABLE,
25
+ DIFFERENTIABLE_COARSE, resolve_backend)
26
+
27
+ __all__ = ["backend", "cosmology", "Backend", "ACCURATE", "DIFFERENTIABLE",
28
+ "DIFFERENTIABLE_COARSE", "resolve_backend", "WorkInProgressWarning",
29
+ "__version__"]
30
+
31
+
32
+ def __getattr__(name):
33
+ """Forward the retired flavour names, with their warning.
34
+
35
+ Re-exported through here rather than imported at module scope: importing
36
+ them eagerly would fire the ``DeprecationWarning`` on every
37
+ ``import ggah_mod``, which is a warning about nothing the caller did.
38
+ """
39
+ if name in ("FAST", "REFERENCE"):
40
+ return getattr(backend, name)
41
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@@ -0,0 +1,38 @@
1
+ """The work-in-progress notice of layer 3 and beyond.
2
+
3
+ Layers 1 and 2 (``cosmology``, ``halos``) are verified and documented. The
4
+ tracers, the spectra, the observables and the covariance (layers 3 to 6) and the
5
+ interfaces are released as code, tested, ahead of their verification and their
6
+ documentation. Importing any of them warns once per process, with
7
+ :class:`WorkInProgressWarning`, which can be silenced on its own::
8
+
9
+ import warnings
10
+ import ggah_mod
11
+ warnings.filterwarnings("ignore", category=ggah_mod.WorkInProgressWarning)
12
+ """
13
+ import warnings
14
+
15
+ __all__ = ["WorkInProgressWarning", "warn_work_in_progress"]
16
+
17
+ _warned = False
18
+
19
+
20
+ class WorkInProgressWarning(UserWarning):
21
+ """A subpackage whose interface and results may still change."""
22
+
23
+
24
+ def warn_work_in_progress(module: str) -> None:
25
+ """Warn that ``module`` is work in progress, the first time any such
26
+ subpackage is imported: one import of ``ggah_mod.observables`` loads the
27
+ spectra and the tracers too, and one notice says it."""
28
+ global _warned
29
+ if _warned:
30
+ return
31
+ _warned = True
32
+ warnings.warn(
33
+ f"{module} is work in progress. Layers 3 to 6 of ggah_mod (sectors, "
34
+ f"spectra, observables, covariance) and its interfaces are released as "
35
+ f"tested code ahead of their verification and documentation; their "
36
+ f"interface and results may change. Layers 1 and 2 (cosmology, halos) "
37
+ f"are documented at https://ggah-mod.readthedocs.io.",
38
+ WorkInProgressWarning, stacklevel=2)