classy-szfast 0.0.0__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.
@@ -0,0 +1,933 @@
1
+ from .utils import *
2
+ from .config import *
3
+ import numpy as np
4
+ from .cosmopower import *
5
+ from .pks_and_sigmas import *
6
+ import scipy
7
+ import time
8
+ from multiprocessing import Process
9
+ from mcfit import TophatVar
10
+ from scipy.interpolate import CubicSpline
11
+ import pickle
12
+
13
+
14
+ H_units_conv_factor = {"1/Mpc": 1, "km/s/Mpc": Const.c_km_s}
15
+
16
+
17
+ import logging
18
+
19
+ def configure_logging(level=logging.INFO):
20
+ logging.basicConfig(
21
+ format='%(levelname)s - %(message)s',
22
+ level=level
23
+ )
24
+
25
+ def set_verbosity(verbosity):
26
+ levels = {
27
+ 'none': logging.CRITICAL,
28
+ 'minimal': logging.INFO,
29
+ 'extensive': logging.DEBUG
30
+ }
31
+ # print(f'Setting verbosity to {verbosity}')
32
+ level = levels.get(verbosity, logging.INFO)
33
+ configure_logging(level)
34
+
35
+
36
+
37
+ def update_params_with_defaults(params_values, default_values):
38
+ """
39
+ Update params_values with default values if they don't already exist.
40
+
41
+ Args:
42
+ params_values (dict): Dictionary containing parameter values.
43
+ default_values (dict): Dictionary containing default parameter values.
44
+ """
45
+
46
+
47
+ # Update params_values with default values if key does not exist
48
+ for key, value in default_values.items():
49
+ if key not in params_values:
50
+ params_values[key] = value
51
+
52
+
53
+ class Class_szfast(object):
54
+ def __init__(self,
55
+ params_settings = {},
56
+ #lowring=False, some options if needed
57
+ **kwargs):
58
+ # some parameters
59
+ # self.xy = xy
60
+ # self.lowring = lowring
61
+
62
+
63
+ self.A_s_fast = 0
64
+ self.logA_fast = 0
65
+
66
+
67
+ set_verbosity(params_settings["classy_sz_verbose"])
68
+ self.logger = logging.getLogger(__name__)
69
+
70
+
71
+
72
+
73
+
74
+
75
+ # cosmopower emulators
76
+ self.cp_path_to_cosmopower_organization = path_to_cosmopower_organization + '/'
77
+ self.cp_tt_nn = cp_tt_nn
78
+ self.cp_te_nn = cp_te_nn
79
+ self.cp_ee_nn = cp_ee_nn
80
+ self.cp_pp_nn = cp_pp_nn
81
+ self.cp_pknl_nn = cp_pknl_nn
82
+ self.cp_pkl_nn = cp_pkl_nn
83
+ self.cp_der_nn = cp_der_nn
84
+ self.cp_da_nn = cp_da_nn
85
+ self.cp_h_nn = cp_h_nn
86
+ self.cp_s8_nn = cp_s8_nn
87
+
88
+ self.emulator_dict = emulator_dict
89
+
90
+ if dofftlog_alphas == True:
91
+ self.cp_pkl_fftlog_alphas_nus = cp_pkl_fftlog_alphas_nus
92
+ self.cp_pkl_fftlog_alphas_real_nn = cp_pkl_fftlog_alphas_real_nn
93
+ self.cp_pkl_fftlog_alphas_imag_nn = cp_pkl_fftlog_alphas_imag_nn
94
+
95
+ self.cosmo_model = 'ede-v2'
96
+ self.use_Amod = 0
97
+ self.Amod = 0
98
+
99
+ self.cp_lmax = cp_l_max_scalars
100
+ self.cp_ls = np.arange(2,self.cp_lmax+1)
101
+
102
+
103
+
104
+
105
+ cosmo_model_dict = {0: 'lcdm',
106
+ 1: 'mnu',
107
+ 2: 'neff',
108
+ 3: 'wcdm',
109
+ 4: 'ede',
110
+ 5: 'mnu-3states',
111
+ 6: 'ede-v2'
112
+ }
113
+
114
+
115
+ if cosmo_model_dict[params_settings['cosmo_model']] == 'ede-v2':
116
+
117
+ self.cp_ndspl_k = 1
118
+ self.cp_nk = 1000
119
+
120
+ else:
121
+
122
+ self.cp_ndspl_k = 10
123
+ self.cp_nk = 5000
124
+
125
+ self.cp_predicted_tt_spectrum =np.zeros(self.cp_lmax)
126
+ self.cp_predicted_te_spectrum =np.zeros(self.cp_lmax)
127
+ self.cp_predicted_ee_spectrum =np.zeros(self.cp_lmax)
128
+ self.cp_predicted_pp_spectrum =np.zeros(self.cp_lmax)
129
+
130
+
131
+ self.cszfast_ldim = 20000 # used for the cls arrays
132
+
133
+ self.cszfast_pk_grid_nz = 100 # has to be same as narraySZ, i.e., ndim_redshifts; it is setup hereafter if ndim_redshifts is passed
134
+
135
+
136
+
137
+ if (cosmo_model_dict[params_settings['cosmo_model']] == 'ede-v2'):
138
+
139
+ self.cszfast_pk_grid_zmax = 20.
140
+ self.cszfast_pk_grid_kmin = 5e-4
141
+ self.cszfast_pk_grid_kmax = 10.
142
+ self.cp_kmax = self.cszfast_pk_grid_kmax
143
+ self.cp_kmin = self.cszfast_pk_grid_kmin
144
+ # self.logger.info(f">>> using kmin = {self.cp_kmin}")
145
+ # self.logger.info(f">>> using kmax = {self.cp_kmax}")
146
+ # self.logger.info(f">>> using zmax = {self.cszfast_pk_grid_zmax}")
147
+
148
+ else:
149
+
150
+ self.cszfast_pk_grid_zmax = 5. # max z of our pk emulators (sept 23)
151
+ self.cszfast_pk_grid_kmin = 1e-4
152
+ self.cszfast_pk_grid_kmax = 50.
153
+ self.cp_kmax = self.cszfast_pk_grid_kmax
154
+ self.cp_kmin = self.cszfast_pk_grid_kmin
155
+ # self.logger.info(f">>> using kmin = {self.cp_kmin}")
156
+ # self.logger.info(f">>> using kmax = {self.cp_kmax}")
157
+ # self.logger.info(f">>> using zmax = {self.cszfast_pk_grid_zmax}")
158
+
159
+ self.cszfast_pk_grid_z = np.linspace(0.,self.cszfast_pk_grid_zmax,self.cszfast_pk_grid_nz)
160
+ self.cszfast_pk_grid_ln1pz = np.log(1.+self.cszfast_pk_grid_z)
161
+
162
+
163
+ self.cszfast_pk_grid_k = np.geomspace(self.cp_kmin,self.cp_kmax,self.cp_nk)[::self.cp_ndspl_k]
164
+
165
+ self.cszfast_pk_grid_lnk = np.log(self.cszfast_pk_grid_k)
166
+
167
+ self.cszfast_pk_grid_nk = len(np.geomspace(self.cp_kmin,self.cp_kmax,self.cp_nk)[::self.cp_ndspl_k]) # has to be same as ndimSZ, and the same as dimension of cosmopower pk emulators
168
+
169
+ for k,v in params_settings.items():
170
+
171
+ if k == 'ndim_redshifts':
172
+
173
+ self.cszfast_pk_grid_nz = v
174
+ self.cszfast_pk_grid_z = np.linspace(0.,self.cszfast_pk_grid_zmax,self.cszfast_pk_grid_nz)
175
+ self.cszfast_pk_grid_ln1pz = np.log(1.+self.cszfast_pk_grid_z)
176
+
177
+ self.cszfast_pk_grid_pknl_flat = np.zeros(self.cszfast_pk_grid_nz*self.cszfast_pk_grid_nk)
178
+ self.cszfast_pk_grid_pkl_flat = np.zeros(self.cszfast_pk_grid_nz*self.cszfast_pk_grid_nk)
179
+
180
+ if k == 'cosmo_model':
181
+
182
+ self.cosmo_model = cosmo_model_dict[v]
183
+
184
+ if k == 'use_Amod':
185
+
186
+ self.use_Amod = v
187
+ self.Amod = params_settings['Amod']
188
+
189
+
190
+
191
+ if cosmo_model_dict[params_settings['cosmo_model']] == 'ede-v2':
192
+
193
+ self.pk_power_fac = self.cszfast_pk_grid_k**-3
194
+
195
+ else:
196
+
197
+ ls = np.arange(2,self.cp_nk+2)[::self.cp_ndspl_k] # jan 10 ndspl
198
+ dls = ls*(ls+1.)/2./np.pi
199
+ self.pk_power_fac= (dls)**-1
200
+
201
+
202
+ self.cp_z_interp = np.linspace(0.,20.,5000)
203
+
204
+ self.csz_base = None
205
+
206
+
207
+ self.cszfast_zgrid_zmin = 0.
208
+ self.cszfast_zgrid_zmax = 4.
209
+ self.cszfast_zgrid_nz = 250
210
+ self.cszfast_zgrid = np.linspace(self.cszfast_zgrid_zmin,
211
+ self.cszfast_zgrid_zmax,
212
+ self.cszfast_zgrid_nz)
213
+
214
+
215
+ self.cszfast_mgrid_mmin = 1e10
216
+ self.cszfast_mgrid_mmax = 1e15
217
+ self.cszfast_mgrid_nm = 50
218
+ self.cszfast_mgrid = np.geomspace(self.cszfast_mgrid_mmin,
219
+ self.cszfast_mgrid_mmax,
220
+ self.cszfast_mgrid_nm)
221
+
222
+ self.cszfast_gas_pressure_xgrid_xmin = 1e-2
223
+ self.cszfast_gas_pressure_xgrid_xmax = 1e2
224
+ self.cszfast_gas_pressure_xgrid_nx = 100
225
+ self.cszfast_gas_pressure_xgrid = np.geomspace(self.cszfast_gas_pressure_xgrid_xmin,
226
+ self.cszfast_gas_pressure_xgrid_xmax,
227
+ self.cszfast_gas_pressure_xgrid_nx)
228
+
229
+ self.params_for_emulators = {}
230
+
231
+ def find_As(self,params_cp):
232
+
233
+ sigma_8_asked = params_cp["sigma8"]
234
+
235
+ update_params_with_defaults(params_cp, self.emulator_dict[self.cosmo_model]['default'])
236
+
237
+ def to_root(ln10_10_As_goal):
238
+ params_cp["ln10^{10}A_s"] = ln10_10_As_goal[0]
239
+ params_dict = {}
240
+ for k,v in params_cp.items():
241
+ params_dict[k]=[v]
242
+
243
+ return self.cp_der_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0][1]-sigma_8_asked
244
+
245
+ lnA_s = optimize.root(to_root,
246
+ x0=3.046,
247
+ #tol = 1e-10,
248
+ method="hybr")
249
+
250
+ params_cp['ln10^{10}A_s'] = lnA_s.x[0]
251
+
252
+ params_cp.pop('sigma8')
253
+
254
+ return 1
255
+
256
+
257
+ def get_H0_from_thetas(self,params_values):
258
+
259
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
260
+
261
+ # print(params_values)
262
+ theta_s_asked = params_values['100*theta_s']
263
+ def fzero(H0_goal):
264
+ params_values['H0'] = H0_goal[0]
265
+ params_dict = {}
266
+ for k,v in params_values.items():
267
+ params_dict[k]=[v]
268
+
269
+ predicted_der_params = self.cp_der_nn[self.cosmo_model].ten_to_predictions_np(params_dict)
270
+ return predicted_der_params[0][0]-theta_s_asked
271
+ sol = optimize.root(fzero,
272
+ #[40., 99.],
273
+ x0 = 100.*(3.54*theta_s_asked**2-5.455*theta_s_asked+2.548),
274
+ #jac=jac,
275
+ tol = 1e-10,
276
+ method='hybr')
277
+
278
+ params_values.pop('100*theta_s')
279
+ params_values['H0'] = sol.x[0]
280
+ return 1
281
+
282
+
283
+ def calculate_pkl_fftlog_alphas(self,zpk = 0.,**params_values_dict):
284
+ params_values = params_values_dict.copy()
285
+ params_dict = {}
286
+ for k,v in params_values.items():
287
+ params_dict[k]=[v]
288
+ params_dict['z_pk_save_nonclass'] = [zpk]
289
+
290
+ predicted_testing_alphas_creal = self.cp_pkl_fftlog_alphas_real_nn[self.cosmo_model].predictions_np(params_dict)[0]
291
+ predicted_testing_alphas_cimag = self.cp_pkl_fftlog_alphas_imag_nn[self.cosmo_model].predictions_np(params_dict)[0]
292
+ predicted_testing_alphas_cimag = np.append(predicted_testing_alphas_cimag,0.)
293
+ creal = predicted_testing_alphas_creal
294
+ cimag = predicted_testing_alphas_cimag
295
+ Nmax = len(self.cszfast_pk_grid_k)
296
+ cnew = np.zeros(Nmax+1,dtype=complex)
297
+ for i in range(Nmax+1):
298
+ if i<int(Nmax/2):
299
+ cnew[i] = complex(creal[i],cimag[i])
300
+ elif i==int(Nmax/2):
301
+ cnew[i] = complex(creal[i],cimag[i])
302
+ else:
303
+ j = i-int(Nmax/2)
304
+ cnew[i] = complex(creal[::-1][j],-cimag[::-1][j])
305
+ # self.predicted_fftlog_pkl_alphas = cnew
306
+ return cnew
307
+
308
+ def get_pkl_reconstructed_from_fftlog(self,zpk = 0.,**params_values_dict):
309
+ #c_n_math = self.predicted_fftlog_pkl_alphas
310
+ c_n_math = self.calculate_pkl_fftlog_alphas(zpk = zpk,**params_values_dict)
311
+ nu_n_math = self.cp_pkl_fftlog_alphas_nus[self.cosmo_model]['arr_0']
312
+ Nmax = int(len(c_n_math)-1)
313
+ term1 = c_n_math[int(Nmax/2)]*self.cszfast_pk_grid_k**(nu_n_math[int(Nmax/2)])
314
+ term2_array = [c_n_math[int(Nmax/2)+i]*self.cszfast_pk_grid_k**(nu_n_math[int(Nmax/2)+i]) for i in range(1, int(Nmax/2)+1)]
315
+ pk_reconstructed = (term1 + 2*np.sum(term2_array,axis=0)).real
316
+ return self.cszfast_pk_grid_k,pk_reconstructed
317
+
318
+ def calculate_cmb(self,
319
+ want_tt=True,
320
+ want_te=True,
321
+ want_ee=True,
322
+ want_pp=1,
323
+ **params_values_dict):
324
+
325
+
326
+ params_values = params_values_dict.copy()
327
+
328
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
329
+
330
+ params_dict = {}
331
+
332
+ for k,v in params_values.items():
333
+ params_dict[k]=[v]
334
+
335
+ if 'm_ncdm' in params_dict.keys():
336
+ if isinstance(params_dict['m_ncdm'][0],str):
337
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
338
+
339
+
340
+
341
+ # if want_tt: for now always want_tt = True
342
+ self.cp_predicted_tt_spectrum = self.cp_tt_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
343
+
344
+ nl = len(self.cp_predicted_tt_spectrum)
345
+ cls = {}
346
+ cls['ell'] = np.arange(20000)
347
+ cls['tt'] = np.zeros(20000)
348
+ cls['te'] = np.zeros(20000)
349
+ cls['ee'] = np.zeros(20000)
350
+ cls['pp'] = np.zeros(20000)
351
+ cls['bb'] = np.zeros(20000)
352
+ lcp = np.asarray(cls['ell'][2:nl+2])
353
+
354
+ # print('cosmo_model:',self.cosmo_model,nl)
355
+ if self.cosmo_model == 'ede-v2':
356
+ factor_ttteee = 1./lcp**2
357
+ factor_pp = 1./lcp**3
358
+ else:
359
+ factor_ttteee = 1./(lcp*(lcp+1.)/2./np.pi)
360
+ factor_pp = 1./(lcp*(lcp+1.))**2.
361
+
362
+ self.cp_predicted_tt_spectrum *= factor_ttteee
363
+
364
+
365
+ if want_te:
366
+ self.cp_predicted_te_spectrum = self.cp_te_nn[self.cosmo_model].predictions_np(params_dict)[0]
367
+ self.cp_predicted_te_spectrum *= factor_ttteee
368
+ if want_ee:
369
+ self.cp_predicted_ee_spectrum = self.cp_ee_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
370
+ self.cp_predicted_ee_spectrum *= factor_ttteee
371
+ if want_pp:
372
+ self.cp_predicted_pp_spectrum = self.cp_pp_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
373
+ self.cp_predicted_pp_spectrum *= factor_pp
374
+
375
+
376
+
377
+
378
+ # print('>>> clssy_szfast.py cmb computed')
379
+
380
+ def load_cmb_cls_from_file(self,**params_values_dict):
381
+ cls_filename = params_values_dict['cmb_cls_filename']
382
+ with open(cls_filename, 'rb') as handle:
383
+ cmb_cls_loaded = pickle.load(handle)
384
+ nl_cls_file = len(cmb_cls_loaded['ell'])
385
+ cls_ls = cmb_cls_loaded['ell']
386
+ dlfac = cls_ls*(cls_ls+1.)/2./np.pi
387
+ cls_tt = cmb_cls_loaded['tt']*dlfac
388
+ cls_te = cmb_cls_loaded['te']*dlfac
389
+ cls_ee = cmb_cls_loaded['ee']*dlfac
390
+ # cls_pp = cmb_cls_loaded['pp']*dlfac # check the normalization.
391
+ nl_cp_cmb = len(self.cp_predicted_tt_spectrum)
392
+ nl_req = min(nl_cls_file,nl_cp_cmb)
393
+
394
+ self.cp_predicted_tt_spectrum[:nl_req-2] = cls_tt[2:nl_req]
395
+ self.cp_predicted_te_spectrum[:nl_req-2] = cls_te[2:nl_req]
396
+ self.cp_predicted_ee_spectrum[:nl_req-2] = cls_ee[2:nl_req]
397
+ # self.cp_predicted_pp_spectrum[:nl_req-2] = cls_pp[2:nl_req]
398
+
399
+
400
+ def calculate_pkl(self,
401
+ # cosmo_model = self.cosmo_model,
402
+ **params_values_dict):
403
+
404
+ z_arr = self.cszfast_pk_grid_z
405
+
406
+
407
+ k_arr = self.cszfast_pk_grid_k
408
+
409
+
410
+ params_values = params_values_dict.copy()
411
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
412
+
413
+
414
+ params_dict = {}
415
+ for k,v in zip(params_values.keys(),params_values.values()):
416
+ params_dict[k]=[v]
417
+
418
+ if 'm_ncdm' in params_dict.keys():
419
+ if isinstance(params_dict['m_ncdm'][0],str):
420
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
421
+
422
+
423
+
424
+ predicted_pk_spectrum_z = []
425
+
426
+ if self.use_Amod:
427
+
428
+ for zp in z_arr:
429
+
430
+ params_dict_pp = params_dict.copy()
431
+ params_dict_pp['z_pk_save_nonclass'] = [zp]
432
+ pkl_p = self.cp_pkl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0]
433
+ pknl_p = self.cp_pknl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0]
434
+ pk_ae = pkl_p + self.Amod*(pknl_p-pkl_p)
435
+ predicted_pk_spectrum_z.append(pk_ae)
436
+
437
+ else:
438
+
439
+ for zp in z_arr:
440
+
441
+ params_dict_pp = params_dict.copy()
442
+ params_dict_pp['z_pk_save_nonclass'] = [zp]
443
+ predicted_pk_spectrum_z.append(self.cp_pkl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0])
444
+
445
+ predicted_pk_spectrum = np.asarray(predicted_pk_spectrum_z)
446
+
447
+
448
+ pk = 10.**predicted_pk_spectrum
449
+
450
+ pk_re = pk*self.pk_power_fac
451
+ pk_re = np.transpose(pk_re)
452
+
453
+ self.pkl_interp = PowerSpectrumInterpolator(z_arr,k_arr,np.log(pk_re).T,logP=True)
454
+
455
+ self.cszfast_pk_grid_pk = pk_re
456
+ self.cszfast_pk_grid_pkl_flat = pk_re.flatten()
457
+
458
+ return pk_re, k_arr, z_arr
459
+
460
+
461
+ def calculate_sigma(self,
462
+
463
+ **params_values_dict):
464
+
465
+ params_values = params_values_dict.copy()
466
+
467
+ k = self.cszfast_pk_grid_k
468
+
469
+ P = self.cszfast_pk_grid_pk
470
+
471
+ var = P.copy()
472
+
473
+ dvar = P.copy()
474
+
475
+ for iz,zp in enumerate(self.cszfast_pk_grid_z):
476
+
477
+ R, var[:,iz] = TophatVar(k, lowring=True)(P[:,iz], extrap=True)
478
+
479
+ dvar[:,iz] = np.gradient(var[:,iz], R)
480
+
481
+ # print(k)
482
+ # print(R)
483
+ # print(k*R)
484
+ # exit(0)
485
+
486
+
487
+ self.cszfast_pk_grid_lnr = np.log(R)
488
+ self.cszfast_pk_grid_sigma2 = var
489
+
490
+ self.cszfast_pk_grid_sigma2_flat = var.flatten()
491
+ self.cszfast_pk_grid_lnsigma2_flat = 0.5*np.log(var.flatten())
492
+
493
+ self.cszfast_pk_grid_dsigma2 = dvar
494
+ self.cszfast_pk_grid_dsigma2_flat = dvar.flatten()
495
+
496
+ return 0
497
+
498
+
499
+ def calculate_sigma8_and_der(self,
500
+ # cosmo_model = self.cosmo_model,
501
+ **params_values_dict):
502
+
503
+ params_values = params_values_dict.copy()
504
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
505
+
506
+
507
+ params_dict = {}
508
+ for k,v in zip(params_values.keys(),params_values.values()):
509
+ params_dict[k]=[v]
510
+
511
+ if 'm_ncdm' in params_dict.keys():
512
+ if isinstance(params_dict['m_ncdm'][0],str):
513
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
514
+
515
+ self.cp_predicted_der = self.cp_der_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
516
+ self.sigma8 = self.cp_predicted_der[1]
517
+ self.Neff = self.cp_predicted_der[4]
518
+ return 0
519
+
520
+
521
+ def calculate_sigma8_at_z(self,
522
+ # cosmo_model = self.cosmo_model,
523
+ **params_values_dict):
524
+ params_values = params_values_dict.copy()
525
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
526
+
527
+
528
+ params_dict = {}
529
+ for k,v in zip(params_values.keys(),params_values.values()):
530
+ params_dict[k]=[v]
531
+
532
+ if 'm_ncdm' in params_dict.keys():
533
+ if isinstance(params_dict['m_ncdm'][0],str):
534
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
535
+
536
+
537
+ s8z = self.cp_s8_nn[self.cosmo_model].predictions_np(params_dict)
538
+ # print(self.s8z)
539
+ self.s8z_interp = scipy.interpolate.interp1d(
540
+ np.linspace(0.,20.,5000),
541
+ s8z[0],
542
+ kind='linear',
543
+ axis=-1,
544
+ copy=True,
545
+ bounds_error=None,
546
+ fill_value=np.nan,
547
+ assume_sorted=False)
548
+
549
+ def calculate_pknl(self,
550
+ # cosmo_model = self.cosmo_model,
551
+ **params_values_dict):
552
+
553
+ z_arr = self.cszfast_pk_grid_z
554
+
555
+
556
+ k_arr = self.cszfast_pk_grid_k
557
+
558
+
559
+ params_values = params_values_dict.copy()
560
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
561
+
562
+
563
+ params_dict = {}
564
+ for k,v in zip(params_values.keys(),params_values.values()):
565
+ params_dict[k]=[v]
566
+
567
+ if 'm_ncdm' in params_dict.keys():
568
+ if isinstance(params_dict['m_ncdm'][0],str):
569
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
570
+
571
+
572
+ predicted_pk_spectrum_z = []
573
+
574
+ for zp in z_arr:
575
+ params_dict_pp = params_dict.copy()
576
+ params_dict_pp['z_pk_save_nonclass'] = [zp]
577
+ predicted_pk_spectrum_z.append(self.cp_pknl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0])
578
+
579
+ predicted_pk_spectrum = np.asarray(predicted_pk_spectrum_z)
580
+
581
+
582
+ pk = 10.**predicted_pk_spectrum
583
+
584
+ pk_re = pk*self.pk_power_fac
585
+ pk_re = np.transpose(pk_re)
586
+
587
+
588
+ self.pknl_interp = PowerSpectrumInterpolator(z_arr,k_arr,np.log(pk_re).T,logP=True)
589
+
590
+
591
+ self.cszfast_pk_grid_pknl = pk_re
592
+ self.cszfast_pk_grid_pknl_flat = pk_re.flatten()
593
+
594
+ return pk_re, k_arr, z_arr
595
+
596
+
597
+ def calculate_pkl_at_z(self,
598
+ z_asked,
599
+ params_values_dict=None):
600
+
601
+ z_arr = self.cszfast_pk_grid_z
602
+
603
+ k_arr = self.cszfast_pk_grid_k
604
+
605
+ if params_values_dict:
606
+
607
+ params_values = params_values_dict.copy()
608
+
609
+ else:
610
+
611
+ params_values = self.params_for_emulators
612
+
613
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
614
+
615
+
616
+ params_dict = {}
617
+ for k,v in zip(params_values.keys(),params_values.values()):
618
+ params_dict[k]=[v]
619
+
620
+ if 'm_ncdm' in params_dict.keys():
621
+ if isinstance(params_dict['m_ncdm'][0],str):
622
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
623
+
624
+
625
+ predicted_pk_spectrum_z = []
626
+
627
+ z_asked = z_asked
628
+ params_dict_pp = params_dict.copy()
629
+ update_params_with_defaults(params_dict_pp, self.emulator_dict[self.cosmo_model]['default'])
630
+
631
+ params_dict_pp['z_pk_save_nonclass'] = [z_asked]
632
+ predicted_pk_spectrum_z.append(self.cp_pkl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0])
633
+
634
+ predicted_pk_spectrum = np.asarray(predicted_pk_spectrum_z)
635
+
636
+
637
+ pk = 10.**predicted_pk_spectrum
638
+ pk_re = pk*self.pk_power_fac
639
+ pk_re = np.transpose(pk_re)
640
+
641
+
642
+ return pk_re, k_arr
643
+
644
+
645
+ def calculate_pknl_at_z(self,
646
+ z_asked,
647
+ params_values_dict=None):
648
+
649
+ z_arr = self.cszfast_pk_grid_z
650
+
651
+ k_arr = self.cszfast_pk_grid_k
652
+
653
+ if params_values_dict:
654
+
655
+ params_values = params_values_dict.copy()
656
+
657
+ else:
658
+
659
+ params_values = self.params_for_emulators
660
+
661
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
662
+
663
+
664
+ params_dict = {}
665
+ for k,v in zip(params_values.keys(),params_values.values()):
666
+ params_dict[k]=[v]
667
+
668
+ if 'm_ncdm' in params_dict.keys():
669
+ if isinstance(params_dict['m_ncdm'][0],str):
670
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
671
+
672
+
673
+ predicted_pk_spectrum_z = []
674
+
675
+ z_asked = z_asked
676
+ params_dict_pp = params_dict.copy()
677
+ update_params_with_defaults(params_dict_pp, self.emulator_dict[self.cosmo_model]['default'])
678
+
679
+ params_dict_pp['z_pk_save_nonclass'] = [z_asked]
680
+ predicted_pk_spectrum_z.append(self.cp_pknl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0])
681
+
682
+ predicted_pk_spectrum = np.asarray(predicted_pk_spectrum_z)
683
+
684
+
685
+ pk = 10.**predicted_pk_spectrum
686
+ pk_re = pk*self.pk_power_fac
687
+ pk_re = np.transpose(pk_re)
688
+
689
+
690
+ return pk_re, k_arr
691
+
692
+
693
+ def calculate_hubble(self,
694
+ **params_values_dict):
695
+
696
+ params_values = params_values_dict.copy()
697
+
698
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
699
+
700
+ params_dict = {}
701
+ for k,v in zip(params_values.keys(),params_values.values()):
702
+ params_dict[k]=[v]
703
+
704
+ if 'm_ncdm' in params_dict.keys():
705
+ if isinstance(params_dict['m_ncdm'][0],str):
706
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
707
+
708
+ self.cp_predicted_hubble = self.cp_h_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
709
+
710
+ self.hz_interp = scipy.interpolate.interp1d(
711
+ self.cp_z_interp,
712
+ self.cp_predicted_hubble,
713
+ kind='linear',
714
+ axis=-1,
715
+ copy=True,
716
+ bounds_error=None,
717
+ fill_value=np.nan,
718
+ assume_sorted=False)
719
+
720
+ def calculate_chi(self,
721
+ **params_values_dict):
722
+
723
+ params_values = params_values_dict.copy()
724
+
725
+ update_params_with_defaults(params_values, self.emulator_dict[self.cosmo_model]['default'])
726
+
727
+ params_dict = {}
728
+
729
+ for k,v in zip(params_values.keys(),params_values.values()):
730
+
731
+ params_dict[k]=[v]
732
+
733
+ if 'm_ncdm' in params_dict.keys():
734
+ if isinstance(params_dict['m_ncdm'][0],str):
735
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
736
+
737
+ # deal with different scaling of DA in different model from emulator training
738
+ if self.cosmo_model == 'ede-v2':
739
+
740
+ self.cp_predicted_da = self.cp_da_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
741
+ self.cp_predicted_da = np.insert(self.cp_predicted_da, 0, 0)
742
+
743
+ else:
744
+
745
+ self.cp_predicted_da = self.cp_da_nn[self.cosmo_model].predictions_np(params_dict)[0]
746
+
747
+
748
+ self.chi_interp = scipy.interpolate.interp1d(
749
+ self.cp_z_interp,
750
+ self.cp_predicted_da*(1.+self.cp_z_interp),
751
+ kind='linear',
752
+ axis=-1,
753
+ copy=True,
754
+ bounds_error=None,
755
+ fill_value=np.nan,
756
+ assume_sorted=False)
757
+
758
+ def get_cmb_cls(self,ell_factor=True,Tcmb_uk = Tcmb_uk):
759
+
760
+ cls = {}
761
+ cls['ell'] = np.arange(self.cszfast_ldim)
762
+ cls['tt'] = np.zeros(self.cszfast_ldim)
763
+ cls['te'] = np.zeros(self.cszfast_ldim)
764
+ cls['ee'] = np.zeros(self.cszfast_ldim)
765
+ cls['pp'] = np.zeros(self.cszfast_ldim)
766
+ cls['bb'] = np.zeros(self.cszfast_ldim)
767
+ cls['tt'][2:self.cp_lmax+1] = (Tcmb_uk)**2.*self.cp_predicted_tt_spectrum.copy()
768
+ cls['te'][2:self.cp_lmax+1] = (Tcmb_uk)**2.*self.cp_predicted_te_spectrum.copy()
769
+ cls['ee'][2:self.cp_lmax+1] = (Tcmb_uk)**2.*self.cp_predicted_ee_spectrum.copy()
770
+ cls['pp'][2:self.cp_lmax+1] = self.cp_predicted_pp_spectrum.copy()/4. ## this is clkk... works for so lensinglite lkl
771
+
772
+
773
+ if ell_factor==False:
774
+ fac_l = np.zeros(self.cszfast_ldim)
775
+ fac_l[2:self.cp_lmax+1] = 1./(cls['ell'][2:self.cp_lmax+1]*(cls['ell'][2:self.cp_lmax+1]+1.)/2./np.pi)
776
+ cls['tt'][2:self.cp_lmax+1] *= fac_l[2:self.cp_lmax+1]
777
+ cls['te'][2:self.cp_lmax+1] *= fac_l[2:self.cp_lmax+1]
778
+ cls['ee'][2:self.cp_lmax+1] *= fac_l[2:self.cp_lmax+1]
779
+ # cls['bb'] = np.zeros(self.cszfast_ldim)
780
+ return cls
781
+
782
+
783
+ def get_pknl_at_k_and_z(self,k_asked,z_asked):
784
+ # def get_pkl_at_k_and_z(self,k_asked,z_asked,method = 'cloughtocher'):
785
+ # if method == 'linear':
786
+ # pk = self.pkl_linearnd_interp(z_asked,np.log(k_asked))
787
+ # elif method == 'cloughtocher':
788
+ # pk = self.pkl_cloughtocher_interp(z_asked,np.log(k_asked))
789
+ # return np.exp(pk)
790
+ return self.pknl_interp.P(z_asked,k_asked)
791
+
792
+
793
+ # def get_pkl_at_k_and_z(self,k_asked,z_asked,method = 'cloughtocher'):
794
+ def get_pkl_at_k_and_z(self,k_asked,z_asked):
795
+ # if method == 'linear':
796
+ # pk = self.pknl_linearnd_interp(z_asked,np.log(k_asked))
797
+ # elif method == 'cloughtocher':
798
+ # pk = self.pknl_cloughtocher_interp(z_asked,np.log(k_asked))
799
+ # return np.exp(pk)
800
+ return self.pkl_interp.P(z_asked,k_asked)
801
+
802
+ # function used to overwrite the classy function in fast mode.
803
+ def get_sigma_at_r_and_z(self,r_asked,z_asked):
804
+ # if method == 'linear':
805
+ # pk = self.pknl_linearnd_interp(z_asked,np.log(k_asked))
806
+ # elif method == 'cloughtocher':
807
+ # pk = self.pknl_cloughtocher_interp(z_asked,np.log(k_asked))
808
+ # return np.exp(pk)
809
+ k = self.cszfast_pk_grid_k
810
+ P_at_z = self.get_pkl_at_k_and_z(k,z_asked)
811
+ R,var = TophatVar(k, lowring=True)(P_at_z, extrap=True)
812
+ varR = CubicSpline(R, var)
813
+ sigma_at_r_and_z = np.sqrt(varR(r_asked))
814
+ return sigma_at_r_and_z
815
+
816
+
817
+
818
+ def get_hubble(self, z,units="1/Mpc"):
819
+ return np.array(self.hz_interp(z)*H_units_conv_factor[units])
820
+
821
+ def get_chi(self, z):
822
+ return np.array(self.chi_interp(z))
823
+
824
+ def get_gas_pressure_profile_x(self,z,m,x):
825
+ return 0#np.vectorize(self.csz_base.get_pressure_P_over_P_delta_at_x_M_z_b12_200c)(x,m,z)
826
+
827
+
828
+ # def get_gas_pressure_profile_x_parallel(self,index_z,param_values_array,**kwargs):
829
+ # # zp = self.cszfast_zgrid[iz]
830
+ # # x = self.get_gas_pressure_profile_x(zp,3e13,self.cszfast_gas_pressure_xgrid)
831
+ # x = 1
832
+ # return x
833
+
834
+
835
+ def tabulate_gas_pressure_profile_k(self):
836
+ z_asked,m_asked,x_asked = 0.2,3e14,np.geomspace(1e-3,1e2,500)
837
+ start = time.time()
838
+ px = self.get_gas_pressure_profile_x(z_asked,m_asked,x_asked)
839
+ end = time.time()
840
+ # print(px)
841
+ # print('end tabuulate pressure profile:',end-start)
842
+ # print('grid tabulate pressure profile')
843
+ start = time.time()
844
+ # px = self.get_gas_pressure_profile_x(self.cszfast_zgrid,self.cszfast_mgrid,self.cszfast_gas_pressure_xgrid)
845
+ # for zp in self.cszfast_zgrid:
846
+ # for mp in self.cszfast_mgrid:
847
+ # zp = mp
848
+ # # px = self.get_gas_pressure_profile_x(zp,mp,self.cszfast_gas_pressure_xgrid)
849
+ # zp,mp = 0.1,2e14
850
+ px = self.get_gas_pressure_profile_x(self.cszfast_zgrid[:,None,None],
851
+ self.cszfast_mgrid[None,:,None],
852
+ self.cszfast_gas_pressure_xgrid[None,None,:])
853
+
854
+ # fn=functools.partial(get_gas_pressure_profile_x_parallel,
855
+ # param_values_array=None)
856
+ # pool = multiprocessing.Pool()
857
+ # results = pool.map(fn,range(self.cszfast_zgrid_nz))
858
+ # pool.close()
859
+ #
860
+ # def task(iz):
861
+ # zp = self.cszfast_zgrid[iz]
862
+ # x = self.get_gas_pressure_profile_x(zp,m_asked,self.cszfast_gas_pressure_xgrid)
863
+ # processes = [Process(target=task, args=(i,)) for i in range(self.cszfast_zgrid_nz)]
864
+ # # start all processes
865
+ # for process in processes:
866
+ # process.start()
867
+ # # wait for all processes to complete
868
+ # for process in processes:
869
+ # process.join()
870
+ # # report that all tasks are completed
871
+ # print('Done', flush=True)
872
+ end = time.time()
873
+
874
+ # print(px)
875
+ # print('end grid tabuulate pressure profile:',end-start)
876
+ #
877
+ # def get_gas_pressure_profile_x_parallel(index_z,param_values_array,**kwargs):
878
+ # # zp = self.cszfast_zgrid[iz]
879
+ # # x = self.get_gas_pressure_profile_x(zp,3e13,self.cszfast_gas_pressure_xgrid)
880
+ # x = 1
881
+ # return x
882
+
883
+
884
+ def get_sigma8_at_z(self,z):
885
+ return self.s8z_interp(z)
886
+
887
+
888
+ def rs_drag(self):
889
+ try:
890
+ return self.cp_predicted_der[13]
891
+ except AttributeError:
892
+ return 0
893
+ #################################
894
+ # gives an estimation of f(z)*sigma8(z) at the scale of 8 h/Mpc, computed as (d sigma8/d ln a)
895
+ # Now used by cobaya wrapper.
896
+ def get_effective_f_sigma8(self, z, z_step=0.1,params_values_dict={}):
897
+ """
898
+ effective_f_sigma8(z)
899
+
900
+ Returns the time derivative of sigma8(z) computed as (d sigma8/d ln a)
901
+
902
+ Parameters
903
+ ----------
904
+ z : float
905
+ Desired redshift
906
+ z_step : float
907
+ Default step used for the numerical two-sided derivative. For z < z_step the step is reduced progressively down to z_step/10 while sticking to a double-sided derivative. For z< z_step/10 a single-sided derivative is used instead.
908
+
909
+ Returns
910
+ -------
911
+ (d ln sigma8/d ln a)(z) (dimensionless)
912
+ """
913
+
914
+ s8z_interp = self.s8z_interp
915
+ # we need d sigma8/d ln a = - (d sigma8/dz)*(1+z)
916
+
917
+ # if possible, use two-sided derivative with default value of z_step
918
+ if z >= z_step:
919
+ result = (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
920
+ # return (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
921
+ else:
922
+ # if z is between z_step/10 and z_step, reduce z_step to z, and then stick to two-sided derivative
923
+ if (z > z_step/10.):
924
+ z_step = z
925
+ result = (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
926
+ # return (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
927
+ # if z is between 0 and z_step/10, use single-sided derivative with z_step/10
928
+ else:
929
+ z_step /=10
930
+ result = (s8z_interp(z)-s8z_interp(z+z_step))/z_step*(1+z)
931
+ # return (s8z_interp(z)-s8z_interp(z+z_step))/z_step*(1+z)
932
+ # print('fsigma8 result : ',result)
933
+ return result