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.
Files changed (113) hide show
  1. docs/conf.py +154 -0
  2. flip/__init__.py +4 -11
  3. flip/covariance/__init__.py +7 -8
  4. flip/covariance/analytical/__init__.py +11 -0
  5. flip/covariance/{adamsblake17plane → analytical/adamsblake17}/coefficients.py +1 -1
  6. flip/covariance/{adamsblake17plane → analytical/adamsblake17}/fisher_terms.py +1 -1
  7. flip/covariance/{adamsblake17 → analytical/adamsblake17}/flip_terms.py +0 -1
  8. flip/covariance/{adamsblake17 → analytical/adamsblake17plane}/coefficients.py +1 -1
  9. flip/covariance/{adamsblake17 → analytical/adamsblake17plane}/fisher_terms.py +1 -1
  10. flip/covariance/{adamsblake17plane → analytical/adamsblake17plane}/flip_terms.py +0 -1
  11. flip/covariance/{adamsblake17plane → analytical/adamsblake17plane}/generator.py +103 -19
  12. flip/covariance/{adamsblake20 → analytical/adamsblake20}/coefficients.py +1 -1
  13. flip/covariance/{adamsblake20 → analytical/adamsblake20}/fisher_terms.py +1 -1
  14. flip/covariance/{adamsblake20 → analytical/adamsblake20}/flip_terms.py +0 -1
  15. flip/covariance/{carreres23 → analytical/carreres23}/coefficients.py +1 -4
  16. flip/covariance/{ravouxnoanchor25 → analytical/carreres23}/fisher_terms.py +1 -1
  17. flip/covariance/{carreres23 → analytical/carreres23}/flip_terms.py +0 -1
  18. flip/covariance/analytical/carreres23/generator.py +198 -0
  19. flip/covariance/analytical/genericzdep/__init__.py +5 -0
  20. flip/covariance/analytical/genericzdep/coefficients.py +53 -0
  21. flip/covariance/analytical/genericzdep/flip_terms.py +99 -0
  22. flip/covariance/{lai22 → analytical/lai22}/coefficients.py +2 -3
  23. flip/covariance/{lai22 → analytical/lai22}/fisher_terms.py +1 -1
  24. flip/covariance/{lai22 → analytical/lai22}/flip_terms.py +0 -1
  25. flip/covariance/{lai22 → analytical/lai22}/generator.py +263 -58
  26. flip/covariance/{lai22 → analytical/lai22}/symbolic.py +55 -19
  27. flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/coefficients.py +1 -1
  28. flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/fisher_terms.py +1 -1
  29. flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/flip_terms.py +0 -1
  30. flip/covariance/{ravouxnoanchor25 → analytical/ravouxnoanchor25}/coefficients.py +3 -2
  31. flip/covariance/{carreres23 → analytical/ravouxnoanchor25}/fisher_terms.py +1 -1
  32. flip/covariance/{ravouxnoanchor25 → analytical/ravouxnoanchor25}/flip_terms.py +0 -9
  33. flip/covariance/{rcrk24 → analytical/rcrk24}/coefficients.py +6 -6
  34. flip/covariance/{rcrk24 → analytical/rcrk24}/fisher_terms.py +7 -9
  35. flip/covariance/{rcrk24 → analytical/rcrk24}/flip_terms.py +0 -8
  36. flip/covariance/contraction.py +82 -40
  37. flip/covariance/cov_utils.py +89 -81
  38. flip/covariance/covariance.py +172 -141
  39. flip/covariance/emulators/__init__.py +1 -1
  40. flip/covariance/emulators/generator.py +73 -3
  41. flip/covariance/emulators/gpmatrix.py +40 -1
  42. flip/covariance/emulators/nnmatrix.py +57 -1
  43. flip/covariance/emulators/skgpmatrix.py +125 -0
  44. flip/covariance/fisher.py +307 -0
  45. flip/{fit_utils.py → covariance/fit_utils.py} +185 -10
  46. flip/{fitter.py → covariance/fitter.py} +151 -125
  47. flip/covariance/generator.py +82 -106
  48. flip/{likelihood.py → covariance/likelihood.py} +286 -64
  49. flip/{plot_utils.py → covariance/plot_utils.py} +79 -4
  50. flip/covariance/symbolic.py +89 -44
  51. flip/data/__init__.py +1 -1
  52. flip/data/data_density.parquet +0 -0
  53. flip/data/data_velocity.parquet +0 -0
  54. flip/data/{grid_window_m.parquet → data_window_density.parquet} +0 -0
  55. flip/{gridding.py → data/gridding.py} +125 -130
  56. flip/data/load_data_test.py +102 -0
  57. flip/data/power_spectrum_mm.txt +2 -2
  58. flip/data/power_spectrum_mt.txt +2 -2
  59. flip/data/power_spectrum_tt.txt +2 -2
  60. flip/data/test_covariance_reference_values.json +145 -0
  61. flip/data/test_e2e_reference_values.json +14 -0
  62. flip/data_vector/basic.py +118 -101
  63. flip/data_vector/cosmo_utils.py +18 -0
  64. flip/data_vector/galaxypv_vectors.py +58 -94
  65. flip/data_vector/snia_vectors.py +60 -3
  66. flip/data_vector/vector_utils.py +47 -1
  67. flip/power_spectra/class_engine.py +36 -1
  68. flip/power_spectra/cosmoprimo_engine.py +37 -2
  69. flip/power_spectra/generator.py +47 -25
  70. flip/power_spectra/models.py +30 -31
  71. flip/power_spectra/pyccl_engine.py +36 -1
  72. flip/simulation/__init__.py +0 -0
  73. flip/utils.py +62 -91
  74. flipcosmo-1.2.1.dist-info/METADATA +78 -0
  75. flipcosmo-1.2.1.dist-info/RECORD +109 -0
  76. {flipcosmo-1.0.0.dist-info → flipcosmo-1.2.1.dist-info}/WHEEL +1 -1
  77. flipcosmo-1.2.1.dist-info/top_level.txt +7 -0
  78. scripts/flip_compute_correlation_model.py +70 -0
  79. scripts/flip_compute_power_spectra.py +50 -0
  80. scripts/flip_fisher_forecast_velocity.py +70 -0
  81. scripts/flip_fisher_rcrk24.py +164 -0
  82. scripts/flip_launch_minuit_density_fit.py +91 -0
  83. scripts/flip_launch_minuit_full_fit.py +117 -0
  84. scripts/flip_launch_minuit_velocity_fit.py +78 -0
  85. scripts/flip_launch_minuit_velocity_fit_full.py +107 -0
  86. scripts/flip_launch_minuit_velocity_fit_interpolation.py +93 -0
  87. test/refresh_reference_values.py +43 -0
  88. test/test_covariance_assembly.py +102 -0
  89. test/test_covariance_reference_values.py +125 -0
  90. test/test_covariance_utils.py +34 -0
  91. test/test_e2e_density.py +50 -0
  92. test/test_e2e_joint.py +65 -0
  93. test/test_e2e_velocity.py +53 -0
  94. test/test_likelihood_inversions.py +31 -0
  95. flip/covariance/carreres23/generator.py +0 -132
  96. flip/data/density_data.parquet +0 -0
  97. flip/data/velocity_data.parquet +0 -0
  98. flip/fisher.py +0 -190
  99. flipcosmo-1.0.0.dist-info/METADATA +0 -32
  100. flipcosmo-1.0.0.dist-info/RECORD +0 -82
  101. flipcosmo-1.0.0.dist-info/top_level.txt +0 -1
  102. /flip/{config.py → _config.py} +0 -0
  103. /flip/covariance/{adamsblake17 → analytical/adamsblake17}/__init__.py +0 -0
  104. /flip/covariance/{adamsblake17plane → analytical/adamsblake17plane}/__init__.py +0 -0
  105. /flip/covariance/{adamsblake20 → analytical/adamsblake20}/__init__.py +0 -0
  106. /flip/covariance/{carreres23 → analytical/carreres23}/__init__.py +0 -0
  107. /flip/covariance/{lai22 → analytical/lai22}/__init__.py +0 -0
  108. /flip/covariance/{lai22 → analytical/lai22}/h_terms.py +0 -0
  109. /flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/__init__.py +0 -0
  110. /flip/covariance/{ravouxcarreres → analytical/ravouxcarreres}/flip_terms_lmax.py +0 -0
  111. /flip/covariance/{ravouxnoanchor25 → analytical/ravouxnoanchor25}/__init__.py +0 -0
  112. /flip/covariance/{rcrk24 → analytical/rcrk24}/__init__.py +0 -0
  113. {flipcosmo-1.0.0.dist-info → flipcosmo-1.2.1.dist-info}/licenses/LICENSE +0 -0
@@ -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 the power spectrum.
94
+ """Compute and optionally save MM/MT/TT power spectra.
70
95
 
71
96
  Args:
72
- power_spectrum_engine (str): engine to use to compute the power spectrum, see _available_engines.
73
- power_spectrum_settings (dic or cosmo): configuration for the engine.
74
- redshift (float): the redshift at which compute the power spectrum.
75
- minimal_wavenumber (float): minimum k in h/Mpc.
76
- maximal_wavenumber (float): maximum k in h/Mpc.
77
- number_points (int): Sampling of the power spectrum.
78
- logspace (bool, optional): Sample the power spectrum in logspace or linspace. Defaults to True.
79
- normalization_power_spectrum (str, optional): which normalisation to use. Defaults to "no_normalization".
80
- Available options are: "no_normalization", "growth_rate" or "growth_amplitude".
81
- power_spectrum_non_linear_model (str, optional): Non-linear model to compute. Defaults to None.
82
- power_spectrum_model (str, optional): Non-linear model to apply to the computed power spectrum, see _available_power_spectrum_model. Defaults to "linearbel".
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
- _type_: _description_
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 = eval(power_spectrum_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 = eval(
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,
@@ -2,17 +2,16 @@ import numpy as np
2
2
 
3
3
 
4
4
  def bel_coefficients(sigma_8):
5
- """
6
- The bel_coefficients function takes in a value for sigma_8 and returns the values of the coefficients
7
- a_i, i = 1, 2, 3 and invkdelta as well as b. These are used to calculate the non-linear power spectrum using
8
- the fitting formula from Bel et al. (2007). The function is called by Class when calculating P(k)
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: Calculate the coefficients of the bessel function
11
+ sigma_8 (float): Amplitude of matter fluctuations in 8 Mpc/h spheres.
12
12
 
13
13
  Returns:
14
- The coefficients a_i, i = 1,
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: Calculate the power spectrum
37
- power_spectrum_linear: Calculate the nonlinear power spectrum
38
- **kwargs: Pass a variable number of keyword arguments to a function
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
- The nonlinear matter power spectrum and the nonlinear galaxy clustering power spectrum
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: Get the wavenumber of the power spectrum
70
- power_spectrum_linear: Calculate the power_spectrum_mt and power_spectrum_tt
71
- **kwargs: Pass a variable number of keyword arguments to a function
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
- The nonlinear power spectrum of matter, the cross power spectrum of matter and tracers and the auto-power spectrum of tracers
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: Calculate the wavenumber in h/mpc
103
- power_spectrum_linear: Calculate the power spectrum of the matter field
104
- **kwargs: Pass a variable number of keyword arguments to the function
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
- The linear power spectrum and the
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: Convert the ra and dec to cartesian coordinates
22
- ra: Calculate the x-coordinate of a point in space
23
- dec: Calculate the z coordinate
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
- The x, y and z coordinates of each galaxy
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: Represent the x-coordinate of a point in space
43
- y: Calculate the right ascension
44
- z: Calculate the declination
45
+ x (array-like): X coordinates.
46
+ y (array-like): Y coordinates.
47
+ z (array-like): Z coordinates.
45
48
 
46
49
  Returns:
47
- The radius, right ascension and declination of a point in cartesian coordinates
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: Pass in a dictionary to the function
65
- string: Specify the key to look up in the dictionary
66
- default_value: Return a default value if the key is not in the dictionary
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
- A value from a dictionary
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 create_log(log_level="info"):
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
- The create_log function creates a logger object that can be used to log messages.
77
- The function takes one argument, the log_level, which is set to &quot;info&quot; by default.
78
- The function returns a Logger object with the specified logging level.
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: Set the logging level
100
+ log_level (str): One of `info`, `debug`, `warning`.
82
101
 
83
102
  Returns:
84
- A logger object
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
- self: Represent the instance of the class
103
- name: Set the name of the report
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 &quot;info&quot;, &quot;warning&quot; or &quot;debug&quot;.
179
- If no level is specified, the default value is used (&quot;info&quot;).
180
-
169
+ """Log a message at the given level.
181
170
 
182
171
  Args:
183
- line: Pass the line of text to be logged
184
- level: Determine the type of log message
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: Store the array that is passed to the function
204
- char: Specify which array is being used
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
+ [![Documentation Status](https://readthedocs.org/projects/flip/badge/?version=latest)](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.