flipcosmo 1.0.0__py3-none-any.whl → 1.2.1__py3-none-any.whl
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.
- docs/conf.py +154 -0
- flip/__init__.py +4 -11
- flip/covariance/__init__.py +7 -8
- flip/covariance/analytical/__init__.py +11 -0
- flip/covariance/{adamsblake17plane → analytical/adamsblake17}/coefficients.py +1 -1
- flip/covariance/{adamsblake17plane → analytical/adamsblake17}/fisher_terms.py +1 -1
- flip/covariance/{adamsblake17 → analytical/adamsblake17}/flip_terms.py +0 -1
- flip/covariance/{adamsblake17 → analytical/adamsblake17plane}/coefficients.py +1 -1
- flip/covariance/{adamsblake17 → analytical/adamsblake17plane}/fisher_terms.py +1 -1
- flip/covariance/{adamsblake17plane → analytical/adamsblake17plane}/flip_terms.py +0 -1
- flip/covariance/{adamsblake17plane → analytical/adamsblake17plane}/generator.py +103 -19
- flip/covariance/{adamsblake20 → analytical/adamsblake20}/coefficients.py +1 -1
- flip/covariance/{adamsblake20 → analytical/adamsblake20}/fisher_terms.py +1 -1
- flip/covariance/{adamsblake20 → analytical/adamsblake20}/flip_terms.py +0 -1
- flip/covariance/{carreres23 → analytical/carreres23}/coefficients.py +1 -4
- flip/covariance/{ravouxnoanchor25 → analytical/carreres23}/fisher_terms.py +1 -1
- flip/covariance/{carreres23 → analytical/carreres23}/flip_terms.py +0 -1
- flip/covariance/analytical/carreres23/generator.py +198 -0
- flip/covariance/analytical/genericzdep/__init__.py +5 -0
- flip/covariance/analytical/genericzdep/coefficients.py +53 -0
- flip/covariance/analytical/genericzdep/flip_terms.py +99 -0
- flip/covariance/{lai22 → analytical/lai22}/coefficients.py +2 -3
- flip/covariance/{lai22 → analytical/lai22}/fisher_terms.py +1 -1
- flip/covariance/{lai22 → analytical/lai22}/flip_terms.py +0 -1
- flip/covariance/{lai22 → analytical/lai22}/generator.py +263 -58
- flip/covariance/{lai22 → analytical/lai22}/symbolic.py +55 -19
- flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/coefficients.py +1 -1
- flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/fisher_terms.py +1 -1
- flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/flip_terms.py +0 -1
- flip/covariance/{ravouxnoanchor25 → analytical/ravouxnoanchor25}/coefficients.py +3 -2
- flip/covariance/{carreres23 → analytical/ravouxnoanchor25}/fisher_terms.py +1 -1
- flip/covariance/{ravouxnoanchor25 → analytical/ravouxnoanchor25}/flip_terms.py +0 -9
- flip/covariance/{rcrk24 → analytical/rcrk24}/coefficients.py +6 -6
- flip/covariance/{rcrk24 → analytical/rcrk24}/fisher_terms.py +7 -9
- flip/covariance/{rcrk24 → analytical/rcrk24}/flip_terms.py +0 -8
- flip/covariance/contraction.py +82 -40
- flip/covariance/cov_utils.py +89 -81
- flip/covariance/covariance.py +172 -141
- flip/covariance/emulators/__init__.py +1 -1
- flip/covariance/emulators/generator.py +73 -3
- flip/covariance/emulators/gpmatrix.py +40 -1
- flip/covariance/emulators/nnmatrix.py +57 -1
- flip/covariance/emulators/skgpmatrix.py +125 -0
- flip/covariance/fisher.py +307 -0
- flip/{fit_utils.py → covariance/fit_utils.py} +185 -10
- flip/{fitter.py → covariance/fitter.py} +151 -125
- flip/covariance/generator.py +82 -106
- flip/{likelihood.py → covariance/likelihood.py} +286 -64
- flip/{plot_utils.py → covariance/plot_utils.py} +79 -4
- flip/covariance/symbolic.py +89 -44
- flip/data/__init__.py +1 -1
- flip/data/data_density.parquet +0 -0
- flip/data/data_velocity.parquet +0 -0
- flip/data/{grid_window_m.parquet → data_window_density.parquet} +0 -0
- flip/{gridding.py → data/gridding.py} +125 -130
- flip/data/load_data_test.py +102 -0
- flip/data/power_spectrum_mm.txt +2 -2
- flip/data/power_spectrum_mt.txt +2 -2
- flip/data/power_spectrum_tt.txt +2 -2
- flip/data/test_covariance_reference_values.json +145 -0
- flip/data/test_e2e_reference_values.json +14 -0
- flip/data_vector/basic.py +118 -101
- flip/data_vector/cosmo_utils.py +18 -0
- flip/data_vector/galaxypv_vectors.py +58 -94
- flip/data_vector/snia_vectors.py +60 -3
- flip/data_vector/vector_utils.py +47 -1
- flip/power_spectra/class_engine.py +36 -1
- flip/power_spectra/cosmoprimo_engine.py +37 -2
- flip/power_spectra/generator.py +47 -25
- flip/power_spectra/models.py +30 -31
- flip/power_spectra/pyccl_engine.py +36 -1
- flip/simulation/__init__.py +0 -0
- flip/utils.py +62 -91
- flipcosmo-1.2.1.dist-info/METADATA +78 -0
- flipcosmo-1.2.1.dist-info/RECORD +109 -0
- {flipcosmo-1.0.0.dist-info → flipcosmo-1.2.1.dist-info}/WHEEL +1 -1
- flipcosmo-1.2.1.dist-info/top_level.txt +7 -0
- scripts/flip_compute_correlation_model.py +70 -0
- scripts/flip_compute_power_spectra.py +50 -0
- scripts/flip_fisher_forecast_velocity.py +70 -0
- scripts/flip_fisher_rcrk24.py +164 -0
- scripts/flip_launch_minuit_density_fit.py +91 -0
- scripts/flip_launch_minuit_full_fit.py +117 -0
- scripts/flip_launch_minuit_velocity_fit.py +78 -0
- scripts/flip_launch_minuit_velocity_fit_full.py +107 -0
- scripts/flip_launch_minuit_velocity_fit_interpolation.py +93 -0
- test/refresh_reference_values.py +43 -0
- test/test_covariance_assembly.py +102 -0
- test/test_covariance_reference_values.py +125 -0
- test/test_covariance_utils.py +34 -0
- test/test_e2e_density.py +50 -0
- test/test_e2e_joint.py +65 -0
- test/test_e2e_velocity.py +53 -0
- test/test_likelihood_inversions.py +31 -0
- flip/covariance/carreres23/generator.py +0 -132
- flip/data/density_data.parquet +0 -0
- flip/data/velocity_data.parquet +0 -0
- flip/fisher.py +0 -190
- flipcosmo-1.0.0.dist-info/METADATA +0 -32
- flipcosmo-1.0.0.dist-info/RECORD +0 -82
- flipcosmo-1.0.0.dist-info/top_level.txt +0 -1
- /flip/{config.py → _config.py} +0 -0
- /flip/covariance/{adamsblake17 → analytical/adamsblake17}/__init__.py +0 -0
- /flip/covariance/{adamsblake17plane → analytical/adamsblake17plane}/__init__.py +0 -0
- /flip/covariance/{adamsblake20 → analytical/adamsblake20}/__init__.py +0 -0
- /flip/covariance/{carreres23 → analytical/carreres23}/__init__.py +0 -0
- /flip/covariance/{lai22 → analytical/lai22}/__init__.py +0 -0
- /flip/covariance/{lai22 → analytical/lai22}/h_terms.py +0 -0
- /flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/__init__.py +0 -0
- /flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/flip_terms_lmax.py +0 -0
- /flip/covariance/{ravouxnoanchor25 → analytical/ravouxnoanchor25}/__init__.py +0 -0
- /flip/covariance/{rcrk24 → analytical/rcrk24}/__init__.py +0 -0
- {flipcosmo-1.0.0.dist-info → flipcosmo-1.2.1.dist-info}/licenses/LICENSE +0 -0
flip/power_spectra/generator.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import importlib
|
|
1
2
|
import os
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
4
5
|
|
|
5
|
-
from flip.power_spectra import class_engine, cosmoprimo_engine, models, pyccl_engine
|
|
6
|
-
|
|
7
6
|
_available_engines = ["class_engine", "cosmoprimo_engine", "pyccl_engine"]
|
|
8
7
|
_available_power_spectrum_model = ["linearbel", "nonlinearbel", "linear"]
|
|
9
8
|
_available_power_spectrum_normalizaton = [
|
|
@@ -20,6 +19,11 @@ def get_power_spectrum_suffix(
|
|
|
20
19
|
number_points,
|
|
21
20
|
log_space,
|
|
22
21
|
):
|
|
22
|
+
"""Build a filename suffix encoding spectrum sampling settings.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
str: Suffix including z, kmin, kmax, N, and log/lin tag.
|
|
26
|
+
"""
|
|
23
27
|
return f"z{redshift}_kmin{minimal_wavenumber:.4f}_kmax{maximal_wavenumber:.4f}_N{number_points}{'_log' if log_space else '_lin'}"
|
|
24
28
|
|
|
25
29
|
|
|
@@ -28,6 +32,16 @@ def get_power_spectrum_name(
|
|
|
28
32
|
power_spectrum_type,
|
|
29
33
|
suffix,
|
|
30
34
|
):
|
|
35
|
+
"""Construct a power spectrum filename for saving.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
power_spectrum_model (str): Model name, e.g., `linearbel`.
|
|
39
|
+
power_spectrum_type (str): One of `mm`, `mt`, `tt`.
|
|
40
|
+
suffix (str): Sampling suffix from `get_power_spectrum_suffix`.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
str: Filename `power_spectrum_<model>_<type>_<suffix>.txt`.
|
|
44
|
+
"""
|
|
31
45
|
return f"power_spectrum_{power_spectrum_model}_{power_spectrum_type}_{suffix}.txt"
|
|
32
46
|
|
|
33
47
|
|
|
@@ -40,6 +54,17 @@ def save_power_spectrum(
|
|
|
40
54
|
header,
|
|
41
55
|
path,
|
|
42
56
|
):
|
|
57
|
+
"""Save a power spectrum to disk as a two-row text file.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
wavenumber (ndarray): $k$ samples.
|
|
61
|
+
power_spectrum (ndarray): Spectrum values.
|
|
62
|
+
power_spectrum_model (str): Model name.
|
|
63
|
+
power_spectrum_type (str): `mm`, `mt`, or `tt`.
|
|
64
|
+
suffix (str): Sampling suffix.
|
|
65
|
+
header (str): Header string with metadata.
|
|
66
|
+
path (str): Directory where to save.
|
|
67
|
+
"""
|
|
43
68
|
power_spectrum_name = get_power_spectrum_name(
|
|
44
69
|
power_spectrum_model,
|
|
45
70
|
power_spectrum_type,
|
|
@@ -66,29 +91,26 @@ def compute_power_spectra(
|
|
|
66
91
|
power_spectrum_model="linearbel",
|
|
67
92
|
save_path=None,
|
|
68
93
|
):
|
|
69
|
-
"""Compute
|
|
94
|
+
"""Compute and optionally save MM/MT/TT power spectra.
|
|
70
95
|
|
|
71
96
|
Args:
|
|
72
|
-
power_spectrum_engine (str):
|
|
73
|
-
power_spectrum_settings (
|
|
74
|
-
redshift (float):
|
|
75
|
-
minimal_wavenumber (float):
|
|
76
|
-
maximal_wavenumber (float):
|
|
77
|
-
number_points (int):
|
|
78
|
-
logspace (bool
|
|
79
|
-
normalization_power_spectrum (str
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
save_path (str, optional): Path to save the computed power spectrum. Defaults to None.
|
|
84
|
-
|
|
85
|
-
Raises:
|
|
86
|
-
ValueError: power_spectrum_engine is not available
|
|
87
|
-
ValueError: power_spectrum_model is not available
|
|
88
|
-
ValueError: _description_
|
|
97
|
+
power_spectrum_engine (str): Engine module, one of `_available_engines`.
|
|
98
|
+
power_spectrum_settings (dict|object): Engine configuration.
|
|
99
|
+
redshift (float): Target redshift.
|
|
100
|
+
minimal_wavenumber (float): Minimum $k$ in h/Mpc.
|
|
101
|
+
maximal_wavenumber (float): Maximum $k$ in h/Mpc.
|
|
102
|
+
number_points (int): Number of $k$ samples.
|
|
103
|
+
logspace (bool): Sample $k$ in log-space if True.
|
|
104
|
+
normalization_power_spectrum (str): One of `_available_power_spectrum_normalizaton`.
|
|
105
|
+
power_spectrum_non_linear_model (str|None): Non-linear engine flag for CLASS.
|
|
106
|
+
power_spectrum_model (str): One of `_available_power_spectrum_model`.
|
|
107
|
+
save_path (str|None): Directory to save spectra.
|
|
89
108
|
|
|
90
109
|
Returns:
|
|
91
|
-
|
|
110
|
+
tuple: `(k, P_mm, P_mt, P_tt, fiducial_dict)`.
|
|
111
|
+
|
|
112
|
+
Raises:
|
|
113
|
+
ValueError: If engine or model name is unsupported.
|
|
92
114
|
"""
|
|
93
115
|
if power_spectrum_engine not in _available_engines:
|
|
94
116
|
raise ValueError(
|
|
@@ -101,7 +123,7 @@ def compute_power_spectra(
|
|
|
101
123
|
f"PLease choose between {_available_power_spectrum_model}"
|
|
102
124
|
)
|
|
103
125
|
|
|
104
|
-
engine =
|
|
126
|
+
engine = importlib.import_module(f"flip.power_spectra.{power_spectrum_engine}")
|
|
105
127
|
|
|
106
128
|
(
|
|
107
129
|
wavenumber,
|
|
@@ -117,10 +139,10 @@ def compute_power_spectra(
|
|
|
117
139
|
logspace=logspace,
|
|
118
140
|
non_linear_model=power_spectrum_non_linear_model,
|
|
119
141
|
)
|
|
142
|
+
module = importlib.import_module("flip.power_spectra.models")
|
|
143
|
+
model_function = getattr(module, f"get_{power_spectrum_model}_model")
|
|
120
144
|
|
|
121
|
-
power_spectrum_mm, power_spectrum_mt, power_spectrum_tt =
|
|
122
|
-
f"models.get_{power_spectrum_model}_model"
|
|
123
|
-
)(
|
|
145
|
+
power_spectrum_mm, power_spectrum_mt, power_spectrum_tt = model_function(
|
|
124
146
|
wavenumber,
|
|
125
147
|
power_spectrum_linear,
|
|
126
148
|
power_spectrum_non_linear=power_spectrum_non_linear,
|
flip/power_spectra/models.py
CHANGED
|
@@ -2,17 +2,16 @@ import numpy as np
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def bel_coefficients(sigma_8):
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
the
|
|
5
|
+
"""Compute BEL model coefficients as a function of $\sigma_8$.
|
|
6
|
+
|
|
7
|
+
Uses the parameterization from Bel et al. to construct coefficients
|
|
8
|
+
for the non-linear damping terms.
|
|
9
9
|
|
|
10
10
|
Args:
|
|
11
|
-
sigma_8:
|
|
11
|
+
sigma_8 (float): Amplitude of matter fluctuations in 8 Mpc/h spheres.
|
|
12
12
|
|
|
13
13
|
Returns:
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
tuple: `(a1, a2, a3, invkdelta, b)` coefficients.
|
|
16
15
|
"""
|
|
17
16
|
a1 = -0.817 + 3.198 * sigma_8
|
|
18
17
|
a2 = 0.877 - 4.191 * sigma_8
|
|
@@ -27,19 +26,15 @@ def get_bel_model(
|
|
|
27
26
|
power_spectrum_linear,
|
|
28
27
|
**kwargs,
|
|
29
28
|
):
|
|
30
|
-
"""
|
|
31
|
-
The get_bel_model function takes in the linear power spectrum, wavenumber, and sigma_8 value.
|
|
32
|
-
It then calculates the nonlinear matter-matter power spectrum using a fitting function from Bel et al. (2014).
|
|
33
|
-
The function also returns the nonlinear matter-matter cross correlation coefficient.
|
|
29
|
+
"""Apply BEL damping to linear spectrum to get TT and MT forms.
|
|
34
30
|
|
|
35
31
|
Args:
|
|
36
|
-
wavenumber:
|
|
37
|
-
power_spectrum_linear:
|
|
38
|
-
**kwargs:
|
|
39
|
-
: Calculate the nonlinear power spectrum
|
|
32
|
+
wavenumber (ndarray): $k$ values in h/Mpc.
|
|
33
|
+
power_spectrum_linear (ndarray): Linear matter power spectrum $P_{mm}^{lin}(k)$.
|
|
34
|
+
**kwargs: Must include `sigma_8`.
|
|
40
35
|
|
|
41
36
|
Returns:
|
|
42
|
-
|
|
37
|
+
tuple: `(P_mt(k), P_tt(k))` BEL-damped spectra.
|
|
43
38
|
"""
|
|
44
39
|
if "sigma_8" not in kwargs.keys():
|
|
45
40
|
raise ValueError("Fiducial sigma_8 value is needed for nonlinearbel model")
|
|
@@ -62,18 +57,15 @@ def get_nonlinearbel_model(
|
|
|
62
57
|
power_spectrum_linear,
|
|
63
58
|
**kwargs,
|
|
64
59
|
):
|
|
65
|
-
"""
|
|
66
|
-
The get_nonlinearbel_model function returns the nonlinear power spectra for a given linear power spectrum.
|
|
60
|
+
"""Return BEL-damped spectra using an external non-linear $P_{mm}$.
|
|
67
61
|
|
|
68
62
|
Args:
|
|
69
|
-
wavenumber:
|
|
70
|
-
power_spectrum_linear:
|
|
71
|
-
**kwargs:
|
|
72
|
-
: Get the nonlinear power spectrum
|
|
63
|
+
wavenumber (ndarray): $k$ values in h/Mpc.
|
|
64
|
+
power_spectrum_linear (ndarray): Linear $P_{mm}^{lin}(k)$.
|
|
65
|
+
**kwargs: Must include `power_spectrum_non_linear` and `sigma_8`.
|
|
73
66
|
|
|
74
67
|
Returns:
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
tuple: `(P_mm(k), P_mt(k), P_tt(k))` with $P_mm$ taken from engine.
|
|
77
69
|
"""
|
|
78
70
|
if "power_spectrum_non_linear" not in kwargs.keys():
|
|
79
71
|
raise ValueError("Non linear power spectrum is needed for nonlinearbel model")
|
|
@@ -95,17 +87,15 @@ def get_linearbel_model(
|
|
|
95
87
|
power_spectrum_linear,
|
|
96
88
|
**kwargs,
|
|
97
89
|
):
|
|
98
|
-
"""
|
|
99
|
-
The get_linearbel_model function returns the linear BEL model for a given power spectrum.
|
|
90
|
+
"""Return linear spectra with BEL damping applied to MT and TT.
|
|
100
91
|
|
|
101
92
|
Args:
|
|
102
|
-
wavenumber:
|
|
103
|
-
power_spectrum_linear:
|
|
104
|
-
**kwargs:
|
|
105
|
-
: Set the value of the power spectrum
|
|
93
|
+
wavenumber (ndarray): $k$ values in h/Mpc.
|
|
94
|
+
power_spectrum_linear (ndarray): Linear $P_{mm}^{lin}(k)$.
|
|
95
|
+
**kwargs: Must include `sigma_8`.
|
|
106
96
|
|
|
107
97
|
Returns:
|
|
108
|
-
|
|
98
|
+
tuple: `(P_mm, P_mt, P_tt)` with `P_mm = P_lin`.
|
|
109
99
|
"""
|
|
110
100
|
power_spectrum_mt, power_spectrum_tt = get_bel_model(
|
|
111
101
|
wavenumber, power_spectrum_linear, **kwargs
|
|
@@ -120,5 +110,14 @@ def get_linear_model(
|
|
|
120
110
|
power_spectrum_linear,
|
|
121
111
|
**kwargs,
|
|
122
112
|
):
|
|
113
|
+
"""Return purely linear spectra for MM, MT, and TT.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
wavenumber (ndarray): $k$ values (unused).
|
|
117
|
+
power_spectrum_linear (ndarray): Linear $P_{mm}^{lin}(k)$.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
tuple: `(P_mm, P_mt, P_tt)` all equal to `P_lin`.
|
|
121
|
+
"""
|
|
123
122
|
|
|
124
123
|
return power_spectrum_linear, power_spectrum_linear, power_spectrum_linear
|
|
@@ -6,7 +6,7 @@ log = create_log()
|
|
|
6
6
|
|
|
7
7
|
try:
|
|
8
8
|
import pyccl as ccl
|
|
9
|
-
except:
|
|
9
|
+
except ImportError:
|
|
10
10
|
log.add(
|
|
11
11
|
"Install CCL https://github.com/LSSTDESC/CCL to use pyccl_engine.py module",
|
|
12
12
|
level="warning",
|
|
@@ -19,10 +19,28 @@ _pyccl_setting_default = {}
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def get_fiducial_fs8(model, redshift):
|
|
22
|
+
"""Return fiducial $f\sigma_8$ using PyCCL at redshift.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
model (ccl.Cosmology): PyCCL cosmology.
|
|
26
|
+
redshift (float): Target redshift.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
float: $f(z)\,\sigma_8(z)$ (using PyCCL conventions).
|
|
30
|
+
"""
|
|
22
31
|
return model.growth_rate(1 / (1 + redshift))
|
|
23
32
|
|
|
24
33
|
|
|
25
34
|
def get_fiducial_s8(model, redshift):
|
|
35
|
+
"""Return fiducial $\sigma_8$ using PyCCL at redshift.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
model (ccl.Cosmology): PyCCL cosmology.
|
|
39
|
+
redshift (float): Target redshift.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
float: $\sigma_8(z)$.
|
|
43
|
+
"""
|
|
26
44
|
return model.sigmaR(8 / model.to_dict()["h"], 1 / (1 + redshift))
|
|
27
45
|
|
|
28
46
|
|
|
@@ -35,6 +53,23 @@ def compute_power_spectrum(
|
|
|
35
53
|
non_linear_model=None,
|
|
36
54
|
logspace=True,
|
|
37
55
|
):
|
|
56
|
+
"""Compute linear/non-linear $P(k)$ using PyCCL.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
power_spectrum_settings (dict): PyCCL settings (cosmology + flags).
|
|
60
|
+
redshift (float): Redshift for $P(k)$.
|
|
61
|
+
minimal_wavenumber (float): Minimum $k$ in h/Mpc.
|
|
62
|
+
maximal_wavenumber (float): Maximum $k$ in h/Mpc.
|
|
63
|
+
number_points (int): Number of $k$ samples.
|
|
64
|
+
non_linear_model (str|None): PyCCL matter power spectrum model key.
|
|
65
|
+
logspace (bool): Sample $k$ in log-space when True.
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
tuple: `(k, P_lin, P_nl_or_None, fiducial_dict)`.
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
Exception: Propagates PyCCL errors with a helpful message.
|
|
72
|
+
"""
|
|
38
73
|
if logspace:
|
|
39
74
|
wavenumber = np.logspace(
|
|
40
75
|
np.log10(minimal_wavenumber),
|
|
File without changes
|
flip/utils.py
CHANGED
|
@@ -2,29 +2,35 @@ import logging
|
|
|
2
2
|
import time
|
|
3
3
|
|
|
4
4
|
import astropy.constants as acst
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
5
6
|
import numpy as np
|
|
6
7
|
|
|
7
8
|
_C_LIGHT_KMS_ = acst.c.to("km/s").value
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def Du(k, sigmau):
|
|
12
|
+
"""Damping function Du(k, sigma_u) = sin(k sigma_u) / (k sigma_u).
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
k (array-like): Wavenumber values.
|
|
16
|
+
sigmau (float): Velocity dispersion parameter.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
numpy.ndarray: Damping values for each `k`.
|
|
20
|
+
"""
|
|
11
21
|
return np.sin(k * sigmau) / (k * sigmau)
|
|
12
22
|
|
|
13
23
|
|
|
14
24
|
def radec2cart(rcom, ra, dec):
|
|
15
|
-
"""
|
|
16
|
-
The radec2cart function takes in the comoving distance to a galaxy,
|
|
17
|
-
its right ascension and declination, and returns the x, y, z coordinates
|
|
18
|
-
of that galaxy.
|
|
25
|
+
"""Convert spherical (r, ra, dec) to Cartesian (x, y, z).
|
|
19
26
|
|
|
20
27
|
Args:
|
|
21
|
-
rcom:
|
|
22
|
-
ra
|
|
23
|
-
dec:
|
|
28
|
+
rcom (array-like): Comoving distances.
|
|
29
|
+
ra (array-like): Right ascension in radians.
|
|
30
|
+
dec (array-like): Declination in radians.
|
|
24
31
|
|
|
25
32
|
Returns:
|
|
26
|
-
|
|
27
|
-
|
|
33
|
+
tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]: x, y, z coordinates.
|
|
28
34
|
"""
|
|
29
35
|
x = rcom * np.cos(ra) * np.cos(dec)
|
|
30
36
|
y = rcom * np.sin(ra) * np.cos(dec)
|
|
@@ -33,18 +39,15 @@ def radec2cart(rcom, ra, dec):
|
|
|
33
39
|
|
|
34
40
|
|
|
35
41
|
def cart2radec(x, y, z):
|
|
36
|
-
"""
|
|
37
|
-
The cart2radec function converts cartesian coordinates to spherical
|
|
38
|
-
coordinates. The input is a set of x, y, and z values. The output is the
|
|
39
|
-
radius (rcom), right ascension (ra), and declination (dec).
|
|
42
|
+
"""Convert Cartesian (x, y, z) to spherical (r, ra, dec).
|
|
40
43
|
|
|
41
44
|
Args:
|
|
42
|
-
x
|
|
43
|
-
y:
|
|
44
|
-
z:
|
|
45
|
+
x (array-like): X coordinates.
|
|
46
|
+
y (array-like): Y coordinates.
|
|
47
|
+
z (array-like): Z coordinates.
|
|
45
48
|
|
|
46
49
|
Returns:
|
|
47
|
-
|
|
50
|
+
tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]: rcom, ra, dec.
|
|
48
51
|
"""
|
|
49
52
|
rcom = np.sqrt(x**2 + y**2 + z**2)
|
|
50
53
|
ra = np.arctan2(y, x)
|
|
@@ -55,34 +58,49 @@ def cart2radec(x, y, z):
|
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
def return_key(dictionary, string, default_value):
|
|
58
|
-
"""
|
|
59
|
-
The return_key function takes a dictionary, a string, and a default value.
|
|
60
|
-
It returns the value of the key in the dictionary that matches the string if it exists.
|
|
61
|
-
If not, it returns the default_value.
|
|
61
|
+
"""Return value for `string` in `dictionary`, or a default.
|
|
62
62
|
|
|
63
63
|
Args:
|
|
64
|
-
dictionary:
|
|
65
|
-
string:
|
|
66
|
-
default_value:
|
|
64
|
+
dictionary (dict): Input mapping.
|
|
65
|
+
string (str): Key to retrieve.
|
|
66
|
+
default_value (Any): Fallback if key is absent.
|
|
67
67
|
|
|
68
68
|
Returns:
|
|
69
|
-
|
|
69
|
+
Any: `dictionary[string]` if present, else `default_value`.
|
|
70
70
|
"""
|
|
71
71
|
return dictionary[string] if string in dictionary.keys() else default_value
|
|
72
72
|
|
|
73
73
|
|
|
74
|
-
def
|
|
74
|
+
def __secret_logo__(first_album=False):
|
|
75
|
+
"""Show the hidden flip WEBP logo.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
first_album (bool): Show the first album variant.
|
|
75
79
|
"""
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
from PIL import Image
|
|
81
|
+
|
|
82
|
+
from flip import __flip_dir_path__
|
|
83
|
+
|
|
84
|
+
if first_album:
|
|
85
|
+
img = Image.open(f"{__flip_dir_path__}/data/.htmp/flip_first_album.webp")
|
|
86
|
+
else:
|
|
87
|
+
# Load the WEBP image
|
|
88
|
+
img = Image.open(f"{__flip_dir_path__}/data/.htmp/flip_heavy.webp")
|
|
89
|
+
|
|
90
|
+
# Display it with matplotlib
|
|
91
|
+
plt.imshow(img)
|
|
92
|
+
plt.axis("off")
|
|
93
|
+
plt.show()
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def create_log(log_level="info"):
|
|
97
|
+
"""Create and configure a global logger.
|
|
79
98
|
|
|
80
99
|
Args:
|
|
81
|
-
log_level:
|
|
100
|
+
log_level (str): One of `info`, `debug`, `warning`.
|
|
82
101
|
|
|
83
102
|
Returns:
|
|
84
|
-
|
|
85
|
-
|
|
103
|
+
Logger: Configured logger wrapper.
|
|
86
104
|
"""
|
|
87
105
|
log = Logger(log_level=log_level)
|
|
88
106
|
log.setup_logging()
|
|
@@ -94,33 +112,17 @@ _logging_handler = None
|
|
|
94
112
|
|
|
95
113
|
class Logger(object):
|
|
96
114
|
def __init__(self, name="Python_Report", log_level="info"):
|
|
97
|
-
"""
|
|
98
|
-
The __init__ function is called when the class is instantiated.
|
|
99
|
-
It sets up the logger and defines a few variables that will be used later.
|
|
115
|
+
"""Initialize Logger wrapper.
|
|
100
116
|
|
|
101
117
|
Args:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
log_level: Set the log level
|
|
105
|
-
|
|
106
|
-
Returns:
|
|
107
|
-
Nothing
|
|
108
|
-
|
|
118
|
+
name (str): Report filename for file logging.
|
|
119
|
+
log_level (str): Logging level name.
|
|
109
120
|
"""
|
|
110
121
|
self.name = name
|
|
111
122
|
self.log_level = log_level
|
|
112
123
|
|
|
113
124
|
def setup_logging(self):
|
|
114
|
-
"""
|
|
115
|
-
The setup_logging function is used to set up the logging module.
|
|
116
|
-
|
|
117
|
-
Args:
|
|
118
|
-
self: Refer to the current instance of a class
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
Nothing
|
|
122
|
-
|
|
123
|
-
"""
|
|
125
|
+
"""Configure stream logging with formatted timestamps."""
|
|
124
126
|
levels = {
|
|
125
127
|
"info": logging.INFO,
|
|
126
128
|
"debug": logging.DEBUG,
|
|
@@ -149,16 +151,7 @@ class Logger(object):
|
|
|
149
151
|
logger.setLevel(levels[self.log_level])
|
|
150
152
|
|
|
151
153
|
def setup_report_logging(self):
|
|
152
|
-
"""
|
|
153
|
-
The setup_report_logging function is used to set up the logging for a report.
|
|
154
|
-
|
|
155
|
-
Args:
|
|
156
|
-
self: Represent the instance of the class
|
|
157
|
-
|
|
158
|
-
Returns:
|
|
159
|
-
None
|
|
160
|
-
|
|
161
|
-
"""
|
|
154
|
+
"""Configure file logging for reports using basicConfig."""
|
|
162
155
|
levels = {
|
|
163
156
|
"info": logging.INFO,
|
|
164
157
|
"debug": logging.DEBUG,
|
|
@@ -173,19 +166,11 @@ class Logger(object):
|
|
|
173
166
|
|
|
174
167
|
@staticmethod
|
|
175
168
|
def add(line, level="info"):
|
|
176
|
-
"""
|
|
177
|
-
The add function takes a line of text and adds it to the log file.
|
|
178
|
-
It also takes an optional level argument, which can be set to "info", "warning" or "debug".
|
|
179
|
-
If no level is specified, the default value is used ("info").
|
|
180
|
-
|
|
169
|
+
"""Log a message at the given level.
|
|
181
170
|
|
|
182
171
|
Args:
|
|
183
|
-
line:
|
|
184
|
-
level:
|
|
185
|
-
|
|
186
|
-
Returns:
|
|
187
|
-
None
|
|
188
|
-
|
|
172
|
+
line (str): Message to log.
|
|
173
|
+
level (str): One of `info`, `warning`, `debug`.
|
|
189
174
|
"""
|
|
190
175
|
if level == "info":
|
|
191
176
|
logging.info(line)
|
|
@@ -196,16 +181,11 @@ class Logger(object):
|
|
|
196
181
|
|
|
197
182
|
@staticmethod
|
|
198
183
|
def add_array_statistics(arr, char):
|
|
199
|
-
"""
|
|
200
|
-
The add_array_statistics function takes in an array and a character, and prints out the min, max, mean, and standard deviation of that array.
|
|
184
|
+
"""Log min, max, mean, and std of an array with a label.
|
|
201
185
|
|
|
202
186
|
Args:
|
|
203
|
-
arr:
|
|
204
|
-
char:
|
|
205
|
-
|
|
206
|
-
Returns:
|
|
207
|
-
The minimum, maximum, mean and standard deviation of the array
|
|
208
|
-
|
|
187
|
+
arr (array-like): Input array.
|
|
188
|
+
char (str): Label to include in messages.
|
|
209
189
|
"""
|
|
210
190
|
if arr is not None:
|
|
211
191
|
Logger.add(f"Min of {char}: {arr.min()}")
|
|
@@ -215,14 +195,5 @@ class Logger(object):
|
|
|
215
195
|
|
|
216
196
|
@staticmethod
|
|
217
197
|
def close():
|
|
218
|
-
"""
|
|
219
|
-
The close function shuts down the logging module.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
Args:
|
|
223
|
-
|
|
224
|
-
Returns:
|
|
225
|
-
The return value of the logging
|
|
226
|
-
|
|
227
|
-
"""
|
|
198
|
+
"""Shut down the logging module cleanly."""
|
|
228
199
|
logging.shutdown()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flipcosmo
|
|
3
|
+
Version: 1.2.1
|
|
4
|
+
Summary: Field Level Inference Package
|
|
5
|
+
Author-email: Corentin Ravoux <corentin.ravoux.research@gmail.com>, Bastien Carreres <bastien.carreres@duke.edu>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: pandas
|
|
11
|
+
Requires-Dist: numpy
|
|
12
|
+
Requires-Dist: scipy>=1.12
|
|
13
|
+
Requires-Dist: matplotlib
|
|
14
|
+
Requires-Dist: importlib-metadata
|
|
15
|
+
Requires-Dist: emcee
|
|
16
|
+
Requires-Dist: iminuit
|
|
17
|
+
Requires-Dist: astropy
|
|
18
|
+
Requires-Dist: mpmath
|
|
19
|
+
Provides-Extra: docs
|
|
20
|
+
Requires-Dist: markdown; extra == "docs"
|
|
21
|
+
Requires-Dist: sphinx>=5.2.3; extra == "docs"
|
|
22
|
+
Requires-Dist: sphinx-markdown-tables>=0.0.15; extra == "docs"
|
|
23
|
+
Requires-Dist: numpydoc; extra == "docs"
|
|
24
|
+
Requires-Dist: sphinx_book_theme; extra == "docs"
|
|
25
|
+
Requires-Dist: myst-parser; extra == "docs"
|
|
26
|
+
Requires-Dist: sphinx-copybutton; extra == "docs"
|
|
27
|
+
Requires-Dist: sphinx-design; extra == "docs"
|
|
28
|
+
Requires-Dist: sphinx-inline-tabs; extra == "docs"
|
|
29
|
+
Requires-Dist: sphinx-tabs; extra == "docs"
|
|
30
|
+
Requires-Dist: sphinx-autoapi; extra == "docs"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
<img src="docs/_static/flip_logo.webp" width=350>
|
|
34
|
+
|
|
35
|
+
# flip: Field Level Inference Package
|
|
36
|
+
|
|
37
|
+
flip is a Python package that uses the maximum likelihood method to fit the growth rate based on the velocity and density fields. The first part of the software is the computation of a covariance matrix from a model power spectrum and the considered coordinates. This part is generalized to work for any linear power spectrum models, both for velocities, densities, and cross-terms, and it is optimized with Hankel transform for any model. In the second part, the covariance is used to create a likelihood by multiplying it by velocities or densities. Finally, this package includes some integrated fitters such as Minuit and MCMC (with emcee) to fit the growth rate of structures.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
[](https://flip.readthedocs.io/en/latest/?badge=latest)
|
|
41
|
+
|
|
42
|
+
## Quick install
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/corentinravoux/flip.git
|
|
45
|
+
cd flip
|
|
46
|
+
pip install .
|
|
47
|
+
```
|
|
48
|
+
For now, the package requires you to install manually cosmoprimo: pip install git+https://github.com/cosmodesi/cosmoprimo
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## Required packages
|
|
52
|
+
|
|
53
|
+
Mandatory: numpy, scipy, matplotlib, [cosmoprimo](https://github.com/adematti/cosmoprimo), iminuit, emcee, sympy
|
|
54
|
+
|
|
55
|
+
Optional: classy, pyccl, pypower, GPy, tensorflow
|
|
56
|
+
|
|
57
|
+
## Examples
|
|
58
|
+
|
|
59
|
+
For an example with velocity fit check out: <a target="_blank" href="https://colab.research.google.com/github/corentinravoux/flip/blob/main/notebook/fit_velocity.ipynb">
|
|
60
|
+
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
|
|
61
|
+
</a>
|
|
62
|
+
|
|
63
|
+
For density only: <a target="_blank" href="https://colab.research.google.com/github/corentinravoux/flip/blob/main/notebook/fit_density.ipynb">
|
|
64
|
+
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
|
|
65
|
+
</a>
|
|
66
|
+
|
|
67
|
+
For a joint fit: <a target="_blank" href="https://colab.research.google.com/github/corentinravoux/flip/blob/main/notebook/fit_joint.ipynb">
|
|
68
|
+
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
|
|
69
|
+
</a>
|
|
70
|
+
|
|
71
|
+
## Need help?
|
|
72
|
+
Documentation available on [ReadTheDoc](https://flip.readthedocs.io/)
|
|
73
|
+
|
|
74
|
+
## How to cite
|
|
75
|
+
|
|
76
|
+
The full description of the core concepts of this package is given [here](https://arxiv.org/abs/2501.16852).
|
|
77
|
+
This package was started on the previous work of [@bastiencarreres](https://github.com/bastiencarreres), detail in [this article](https://arxiv.org/abs/2303.01198).
|
|
78
|
+
Please cite both paper when using the package.
|