classy-szfast 0.0.3__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,745 @@
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
+ H_units_conv_factor = {"1/Mpc": 1, "km/s/Mpc": Const.c_km_s}
14
+
15
+ class Class_szfast(object):
16
+ def __init__(self,
17
+ #lowring=False, some options if needed
18
+ **kwargs):
19
+ # some parameters
20
+ # self.xy = xy
21
+ # self.lowring = lowring
22
+
23
+ # cosmopower emulators
24
+ self.cp_path_to_cosmopower_organization = path_to_cosmopower_organization + '/'
25
+ self.cp_tt_nn = cp_tt_nn
26
+ self.cp_te_nn = cp_te_nn
27
+ self.cp_ee_nn = cp_ee_nn
28
+ self.cp_pp_nn = cp_pp_nn
29
+ self.cp_pknl_nn = cp_pknl_nn
30
+ self.cp_pkl_nn = cp_pkl_nn
31
+ self.cp_der_nn = cp_der_nn
32
+ self.cp_da_nn = cp_da_nn
33
+ self.cp_h_nn = cp_h_nn
34
+ self.cp_s8_nn = cp_s8_nn
35
+
36
+ if dofftlog_alphas == True:
37
+ self.cp_pkl_fftlog_alphas_nus = cp_pkl_fftlog_alphas_nus
38
+ self.cp_pkl_fftlog_alphas_real_nn = cp_pkl_fftlog_alphas_real_nn
39
+ self.cp_pkl_fftlog_alphas_imag_nn = cp_pkl_fftlog_alphas_imag_nn
40
+
41
+ self.cosmo_model = 'lcdm'
42
+ self.use_Amod = 0
43
+ self.Amod = 0
44
+
45
+ self.cp_lmax = cp_l_max_scalars
46
+ self.cp_ls = np.arange(2,self.cp_lmax+1)
47
+
48
+ self.cp_kmax = 50.
49
+ self.cp_kmin = 1e-4
50
+ self.cp_nk = 5000
51
+ self.cp_ndspl_k = 10
52
+
53
+ self.cp_predicted_tt_spectrum =np.zeros(self.cp_lmax)
54
+ self.cp_predicted_te_spectrum =np.zeros(self.cp_lmax)
55
+ self.cp_predicted_ee_spectrum =np.zeros(self.cp_lmax)
56
+ self.cp_predicted_pp_spectrum =np.zeros(self.cp_lmax)
57
+
58
+
59
+ self.cszfast_ldim = 20000 # used for the cls arrays
60
+
61
+ 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
62
+ self.cszfast_pk_grid_zmax = 5. # current max z of our pk emulators (sept 23)
63
+ self.cszfast_pk_grid_z = np.linspace(0.,self.cszfast_pk_grid_zmax,self.cszfast_pk_grid_nz)
64
+ self.cszfast_pk_grid_ln1pz = np.log(1.+self.cszfast_pk_grid_z)
65
+
66
+ self.cszfast_pk_grid_kmin = 1e-4
67
+ self.cszfast_pk_grid_kmax = 50.
68
+ self.cszfast_pk_grid_k = np.geomspace(self.cp_kmin,self.cp_kmax,self.cp_nk)[::self.cp_ndspl_k]
69
+ self.cszfast_pk_grid_lnk = np.log(self.cszfast_pk_grid_k)
70
+ 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
71
+ for k,v in kwargs.items():
72
+ # if k == 'ndim_masses':
73
+ # self.cszfast_pk_grid_nk = v
74
+ # self.cszfast_pk_grid_k = np.geomspace(self.cszfast_pk_grid_kmin,self.cszfast_pk_grid_kmax,self.cszfast_pk_grid_nk)
75
+ if k == 'ndim_redshifts':
76
+ self.cszfast_pk_grid_nz = v
77
+ self.cszfast_pk_grid_z = np.linspace(0.,self.cszfast_pk_grid_zmax,self.cszfast_pk_grid_nz)
78
+ self.cszfast_pk_grid_ln1pz = np.log(1.+self.cszfast_pk_grid_z)
79
+ self.cszfast_pk_grid_pknl_flat = np.zeros(self.cszfast_pk_grid_nz*self.cszfast_pk_grid_nk)
80
+ self.cszfast_pk_grid_pkl_flat = np.zeros(self.cszfast_pk_grid_nz*self.cszfast_pk_grid_nk)
81
+
82
+ if k == 'cosmo_model':
83
+ # print('updating cosmo model')
84
+ cosmo_model_dict = {0: 'lcdm',
85
+ 1: 'mnu',
86
+ 2: 'neff',
87
+ 3: 'wcdm',
88
+ 4: 'ede',
89
+ 5: 'mnu-3states'}
90
+ self.cosmo_model = cosmo_model_dict[v]
91
+
92
+ if k == 'use_Amod':
93
+ self.use_Amod = v
94
+ self.Amod = kwargs['Amod']
95
+ # print('self.cosmo_model',self.cosmo_model)
96
+ # print('self.cszfast_pk_grid_nk',self.cszfast_pk_grid_nk)
97
+ # print('self.cszfast_pk_grid_nz',self.cszfast_pk_grid_nz)
98
+
99
+ # exit(0)
100
+ self.cp_z_interp = np.linspace(0.,20.,5000)
101
+
102
+ self.csz_base = None
103
+ # self.csz_base.compute()
104
+
105
+
106
+ # z_arr = np.linspace(0.,zmax,nz) # z-array of redshift data [21oct22] oct 26 22: nz = 1000, zmax = 20
107
+ #
108
+ # nk = self.cp_nk
109
+ # ndspl = self.cp_ndspl_k
110
+ # k_arr = np.geomspace(self.cp_kmin,self.cp_kmax,nk)[::ndspl] # oct 26 22 : (1e-4,50.,5000), jan 10: ndspl
111
+
112
+
113
+ self.cszfast_zgrid_zmin = 0.
114
+ self.cszfast_zgrid_zmax = 4.
115
+ self.cszfast_zgrid_nz = 250
116
+ self.cszfast_zgrid = np.linspace(self.cszfast_zgrid_zmin,
117
+ self.cszfast_zgrid_zmax,
118
+ self.cszfast_zgrid_nz)
119
+
120
+
121
+ self.cszfast_mgrid_mmin = 1e10
122
+ self.cszfast_mgrid_mmax = 1e15
123
+ self.cszfast_mgrid_nm = 50
124
+ self.cszfast_mgrid = np.geomspace(self.cszfast_mgrid_mmin,
125
+ self.cszfast_mgrid_mmax,
126
+ self.cszfast_mgrid_nm)
127
+
128
+ self.cszfast_gas_pressure_xgrid_xmin = 1e-2
129
+ self.cszfast_gas_pressure_xgrid_xmax = 1e2
130
+ self.cszfast_gas_pressure_xgrid_nx = 100
131
+ self.cszfast_gas_pressure_xgrid = np.geomspace(self.cszfast_gas_pressure_xgrid_xmin,
132
+ self.cszfast_gas_pressure_xgrid_xmax,
133
+ self.cszfast_gas_pressure_xgrid_nx)
134
+
135
+
136
+ def find_As(self,params_cp):
137
+ # params_cp = self.params_cp
138
+ t0 = time.time()
139
+
140
+ sigma_8_asked = params_cp["sigma8"]
141
+ # print(params_cp)
142
+ def to_root(ln10_10_As_goal):
143
+ params_cp["ln10^{10}A_s"] = ln10_10_As_goal[0]
144
+ params_dict = {}
145
+ for k,v in params_cp.items():
146
+ params_dict[k]=[v]
147
+ return self.cp_der_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0][1]-sigma_8_asked
148
+
149
+ lnA_s = optimize.root(to_root,
150
+ x0=3.046,
151
+ #tol = 1e-10,
152
+ method="hybr")
153
+ params_cp['ln10^{10}A_s'] = lnA_s.x[0]# .x[0]
154
+ params_cp.pop('sigma8')
155
+ # print("T total in find As",time.time()-t0)#self.t_total)
156
+ # print(params_cp)
157
+ return 1
158
+
159
+
160
+ def get_H0_from_thetas(self,params_values):
161
+ # print(params_values)
162
+ theta_s_asked = params_values['100*theta_s']
163
+ def fzero(H0_goal):
164
+ params_values['H0'] = H0_goal[0]
165
+ params_dict = {}
166
+ for k,v in params_values.items():
167
+ params_dict[k]=[v]
168
+ # print(params_dict)
169
+ predicted_der_params = self.cp_der_nn[self.cosmo_model].ten_to_predictions_np(params_dict)
170
+ return predicted_der_params[0][0]-theta_s_asked
171
+ sol = optimize.root(fzero,
172
+ #[40., 99.],
173
+ x0 = 100.*(3.54*theta_s_asked**2-5.455*theta_s_asked+2.548),
174
+ #jac=jac,
175
+ tol = 1e-10,
176
+ method='hybr')
177
+
178
+ params_values.pop('100*theta_s')
179
+ params_values['H0'] = sol.x[0]
180
+ return 1
181
+
182
+
183
+ def calculate_pkl_fftlog_alphas(self,zpk = 0.,**params_values_dict):
184
+ params_values = params_values_dict.copy()
185
+ params_dict = {}
186
+ for k,v in params_values.items():
187
+ params_dict[k]=[v]
188
+ params_dict['z_pk_save_nonclass'] = [zpk]
189
+
190
+ predicted_testing_alphas_creal = self.cp_pkl_fftlog_alphas_real_nn[self.cosmo_model].predictions_np(params_dict)[0]
191
+ predicted_testing_alphas_cimag = self.cp_pkl_fftlog_alphas_imag_nn[self.cosmo_model].predictions_np(params_dict)[0]
192
+ predicted_testing_alphas_cimag = np.append(predicted_testing_alphas_cimag,0.)
193
+ creal = predicted_testing_alphas_creal
194
+ cimag = predicted_testing_alphas_cimag
195
+ Nmax = len(self.cszfast_pk_grid_k)
196
+ cnew = np.zeros(Nmax+1,dtype=complex)
197
+ for i in range(Nmax+1):
198
+ if i<int(Nmax/2):
199
+ cnew[i] = complex(creal[i],cimag[i])
200
+ elif i==int(Nmax/2):
201
+ cnew[i] = complex(creal[i],cimag[i])
202
+ else:
203
+ j = i-int(Nmax/2)
204
+ cnew[i] = complex(creal[::-1][j],-cimag[::-1][j])
205
+ # self.predicted_fftlog_pkl_alphas = cnew
206
+ return cnew
207
+
208
+ def get_pkl_reconstructed_from_fftlog(self,zpk = 0.,**params_values_dict):
209
+ #c_n_math = self.predicted_fftlog_pkl_alphas
210
+ c_n_math = self.calculate_pkl_fftlog_alphas(zpk = zpk,**params_values_dict)
211
+ nu_n_math = self.cp_pkl_fftlog_alphas_nus[self.cosmo_model]['arr_0']
212
+ Nmax = int(len(c_n_math)-1)
213
+ term1 = c_n_math[int(Nmax/2)]*self.cszfast_pk_grid_k**(nu_n_math[int(Nmax/2)])
214
+ 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)]
215
+ pk_reconstructed = (term1 + 2*np.sum(term2_array,axis=0)).real
216
+ return self.cszfast_pk_grid_k,pk_reconstructed
217
+
218
+ def calculate_cmb(self,
219
+ want_tt=True,
220
+ want_te=True,
221
+ want_ee=True,
222
+ want_pp=1,
223
+ **params_values_dict):
224
+ params_values = params_values_dict.copy()
225
+ # params_values['ln10^{10}A_s'] = params_values.pop("logA")
226
+ # print('in cmb:',params_values)
227
+ params_dict = {}
228
+ # print('cosmo_model',self.cosmo_model)
229
+ for k,v in params_values.items():
230
+ params_dict[k]=[v]
231
+
232
+ if 'm_ncdm' in params_dict.keys():
233
+ if isinstance(params_dict['m_ncdm'][0],str):
234
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
235
+
236
+ # print('params_dict',params_dict)
237
+
238
+ if want_tt:
239
+ self.cp_predicted_tt_spectrum = self.cp_tt_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
240
+ if want_te:
241
+ self.cp_predicted_te_spectrum = self.cp_te_nn[self.cosmo_model].predictions_np(params_dict)[0]
242
+ if want_ee:
243
+ self.cp_predicted_ee_spectrum = self.cp_ee_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
244
+ if want_pp:
245
+ self.cp_predicted_pp_spectrum = self.cp_pp_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
246
+ # print('>>> clssy_szfast.py cmb computed')
247
+
248
+ def load_cmb_cls_from_file(self,**params_values_dict):
249
+ cls_filename = params_values_dict['cmb_cls_filename']
250
+ with open(cls_filename, 'rb') as handle:
251
+ cmb_cls_loaded = pickle.load(handle)
252
+ nl_cls_file = len(cmb_cls_loaded['ell'])
253
+ cls_ls = cmb_cls_loaded['ell']
254
+ dlfac = cls_ls*(cls_ls+1.)/2./np.pi
255
+ cls_tt = cmb_cls_loaded['tt']*dlfac
256
+ cls_te = cmb_cls_loaded['te']*dlfac
257
+ cls_ee = cmb_cls_loaded['ee']*dlfac
258
+ # cls_pp = cmb_cls_loaded['pp']*dlfac # check the normalization.
259
+ nl_cp_cmb = len(self.cp_predicted_tt_spectrum)
260
+ nl_req = min(nl_cls_file,nl_cp_cmb)
261
+
262
+ self.cp_predicted_tt_spectrum[:nl_req-2] = cls_tt[2:nl_req]
263
+ self.cp_predicted_te_spectrum[:nl_req-2] = cls_te[2:nl_req]
264
+ self.cp_predicted_ee_spectrum[:nl_req-2] = cls_ee[2:nl_req]
265
+ # self.cp_predicted_pp_spectrum[:nl_req-2] = cls_pp[2:nl_req]
266
+
267
+
268
+ def calculate_pkl(self,
269
+ # cosmo_model = self.cosmo_model,
270
+ **params_values_dict):
271
+ nz = self.cszfast_pk_grid_nz # number of z-points in redshift data [21oct22] --> set to 80
272
+ zmax = self.cszfast_pk_grid_zmax # max redshift of redshift data [21oct22] --> set to 4 because boltzmannbase.py wants to extrapolate
273
+ z_arr = np.linspace(0.,zmax,nz) # z-array of redshift data [21oct22] oct 26 22: nz = 1000, zmax = 20
274
+
275
+ nk = self.cp_nk
276
+ ndspl = self.cp_ndspl_k
277
+ k_arr = np.geomspace(self.cp_kmin,self.cp_kmax,nk)[::ndspl] # oct 26 22 : (1e-4,50.,5000), jan 10: ndspl
278
+
279
+
280
+ params_values = params_values_dict.copy()
281
+ # print('in pkl:',params_values)
282
+
283
+ params_dict = {}
284
+ for k,v in zip(params_values.keys(),params_values.values()):
285
+ params_dict[k]=[v]
286
+
287
+ if 'm_ncdm' in params_dict.keys():
288
+ if isinstance(params_dict['m_ncdm'][0],str):
289
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
290
+
291
+
292
+
293
+ predicted_pk_spectrum_z = []
294
+
295
+ if self.use_Amod:
296
+ # print(">>> using Amod :",self.Amod)
297
+ for zp in z_arr:
298
+ params_dict_pp = params_dict.copy()
299
+ params_dict_pp['z_pk_save_nonclass'] = [zp]
300
+ pkl_p = self.cp_pkl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0]
301
+ pknl_p = self.cp_pknl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0]
302
+ pk_ae = pkl_p + self.Amod*(pknl_p-pkl_p)
303
+ predicted_pk_spectrum_z.append(pk_ae)
304
+ else:
305
+ for zp in z_arr:
306
+ params_dict_pp = params_dict.copy()
307
+ params_dict_pp['z_pk_save_nonclass'] = [zp]
308
+ predicted_pk_spectrum_z.append(self.cp_pkl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0])
309
+
310
+ predicted_pk_spectrum = np.asarray(predicted_pk_spectrum_z)
311
+
312
+ # weird scaling to get rid off
313
+ # scaling factor for the pk emulator:
314
+ ls = np.arange(2,self.cp_nk+2)[::ndspl] # jan 10 ndspl
315
+ dls = ls*(ls+1.)/2./np.pi
316
+ pk = 10.**predicted_pk_spectrum
317
+ pk_re = ((dls)**-1*pk)
318
+ pk_re = np.transpose(pk_re)
319
+
320
+ # print(z_arr,np.log(k_arr),np.log(pk_re))
321
+ # print(np.log(pk_re).min())
322
+ # print(np.log(pk_re).max())
323
+ # print(np.shape(np.log(pk_re)))
324
+ # print('coordinates')
325
+ # # z_coords, k_coords = np.meshgrid(z_arr, np.log(k_arr), indexing='ij')
326
+ # # z_coords, k_coords = z_coords.flatten(), k_coords.flatten()
327
+ # z_coords, k_coords = z_arr,np.log(k_arr)
328
+ # print(len(z_coords),len(k_coords))
329
+ # #
330
+ # # print(np.shape(list(zip(z_arr,np.log(k_arr)))))
331
+ # pk_values = np.log(pk_re).T
332
+ # # pk_values = pk_values.ravel()
333
+ # print(np.shape(pk_values),pk_values)
334
+ #
335
+ # self.pkl_linearnd_interp = LinearNDInterpolator(np.asarray(z_coords),np.asarray(k_coords), pk_values)
336
+ # exit(0)
337
+ # # self.pkl_cloughtocher_interp = CloughTocher2DInterpolator(list(zip(z_arr,np.log(k_arr))), np.log(pk_re).T)
338
+ # exit(0)
339
+ # self.pkl_cloughtocher_interp = CloughTocher2DInterpolator(list(zip(z_arr,np.log(k_arr))), pk_value)
340
+ # is this line making things slower?
341
+ self.pkl_interp = PowerSpectrumInterpolator(z_arr,k_arr,np.log(pk_re).T,logP=True)
342
+ # self.pkl_interp = None
343
+ self.cszfast_pk_grid_pk = pk_re
344
+ self.cszfast_pk_grid_pkl_flat = pk_re.flatten()
345
+ return pk_re, k_arr, z_arr
346
+
347
+
348
+ def calculate_sigma(self,
349
+ # cosmo_model = self.cosmo_model,
350
+ # z_asked = None,
351
+ # r_asked = None,
352
+ **params_values_dict):
353
+ params_values = params_values_dict.copy()
354
+ k = self.cszfast_pk_grid_k
355
+ # self.cszfast_pk_grid_z
356
+ # print(self.cszfast_pk_grid_pk,np.shape(self.cszfast_pk_grid_pk))
357
+ P = self.cszfast_pk_grid_pk
358
+ var = P.copy()
359
+ dvar = P.copy()
360
+ for iz,zp in enumerate(self.cszfast_pk_grid_z):
361
+ R, var[:,iz] = TophatVar(k, lowring=True)(P[:,iz], extrap=True)
362
+ # dvar[:,iz] = np.gradient(var[:,iz], np.log(R))
363
+ # if params_values_dict['sigma_derivative'] == 1: ## need more points here !!
364
+ # rds,dvar[:,iz] = TophatVar(k,lowring=True,deriv=1)(P[:,iz]*k,extrap=True)
365
+ # else:
366
+ # dvar[:,iz] = np.gradient(var[:,iz], R)
367
+
368
+ dvar[:,iz] = np.gradient(var[:,iz], R)
369
+ # from inigo: R_vec,self.dvar = TophatVar(k,lowring=True,deriv=1)(P[:,iz]*k,extrap=True)
370
+ # from inigo: self.dsigma_vec = self.dvar/(2.*self.sigma_vec)
371
+ # print('R:',R,np.shape(R))
372
+ # varR = CubicSpline(R, var[:,iz])
373
+ # print(zp,np.sqrt(varR(8)))
374
+ # print(params_values)
375
+ # print('in sigma:',params_values)
376
+ # h = params_values['H0']/100.
377
+ # var = var.T
378
+ # dvar = dvar.T
379
+
380
+ self.cszfast_pk_grid_lnr = np.log(R)
381
+ self.cszfast_pk_grid_sigma2 = var
382
+ self.cszfast_pk_grid_sigma2_flat = var.flatten()
383
+ self.cszfast_pk_grid_lnsigma2_flat = 0.5*np.log(var.flatten())
384
+ # self.cszfast_pk_grid_lnsigma2_flat = self.cszfast_pk_grid_lnsigma2_flat.T
385
+ self.cszfast_pk_grid_dsigma2 = dvar
386
+ self.cszfast_pk_grid_dsigma2_flat = dvar.flatten()
387
+ # if z_asked != None and r_asked != None:
388
+ # print(z_asked[0],r_asked[0])
389
+ # return z_asked, r_asked
390
+ # else:
391
+ # return 0
392
+ return 0
393
+
394
+
395
+ def calculate_sigma8_and_der(self,
396
+ # cosmo_model = self.cosmo_model,
397
+ **params_values_dict):
398
+ params_values = params_values_dict.copy()
399
+ # print('in pkl:',params_values)
400
+
401
+ params_dict = {}
402
+ for k,v in zip(params_values.keys(),params_values.values()):
403
+ params_dict[k]=[v]
404
+
405
+ if 'm_ncdm' in params_dict.keys():
406
+ if isinstance(params_dict['m_ncdm'][0],str):
407
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
408
+
409
+ self.cp_predicted_der = self.cp_der_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
410
+ self.sigma8 = self.cp_predicted_der[1]
411
+ return 0
412
+
413
+
414
+ def calculate_sigma8_at_z(self,
415
+ # cosmo_model = self.cosmo_model,
416
+ **params_values_dict):
417
+ params_values = params_values_dict.copy()
418
+ # print('in pkl:',params_values)
419
+
420
+ params_dict = {}
421
+ for k,v in zip(params_values.keys(),params_values.values()):
422
+ params_dict[k]=[v]
423
+
424
+ if 'm_ncdm' in params_dict.keys():
425
+ if isinstance(params_dict['m_ncdm'][0],str):
426
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
427
+
428
+
429
+ s8z = self.cp_s8_nn[self.cosmo_model].predictions_np(params_dict)
430
+ # print(self.s8z)
431
+ self.s8z_interp = scipy.interpolate.interp1d(
432
+ np.linspace(0.,20.,5000),
433
+ s8z[0],
434
+ kind='linear',
435
+ axis=-1,
436
+ copy=True,
437
+ bounds_error=None,
438
+ fill_value=np.nan,
439
+ assume_sorted=False)
440
+
441
+ def calculate_pknl(self,
442
+ # cosmo_model = self.cosmo_model,
443
+ **params_values_dict):
444
+ nz = self.cszfast_pk_grid_nz # number of z-points in redshift data [21oct22] --> set to 80
445
+ zmax = self.cszfast_pk_grid_zmax # max redshift of redshift data [21oct22] --> set to 4 because boltzmannbase.py wants to extrapolate
446
+ z_arr = np.linspace(0.,zmax,nz) # z-array of redshift data [21oct22] oct 26 22: nz = 1000, zmax = 20
447
+
448
+ nk = self.cp_nk
449
+ ndspl = self.cp_ndspl_k
450
+ k_arr = np.geomspace(self.cp_kmin,self.cp_kmax,nk)[::ndspl] # oct 26 22 : (1e-4,50.,5000), jan 10: ndspl
451
+
452
+
453
+ params_values = params_values_dict.copy()
454
+ # print('in pknl:',params_values)
455
+
456
+ params_dict = {}
457
+ for k,v in zip(params_values.keys(),params_values.values()):
458
+ params_dict[k]=[v]
459
+
460
+ if 'm_ncdm' in params_dict.keys():
461
+ if isinstance(params_dict['m_ncdm'][0],str):
462
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
463
+
464
+
465
+ predicted_pk_spectrum_z = []
466
+
467
+ for zp in z_arr:
468
+ params_dict_pp = params_dict.copy()
469
+ params_dict_pp['z_pk_save_nonclass'] = [zp]
470
+ predicted_pk_spectrum_z.append(self.cp_pknl_nn[self.cosmo_model].predictions_np(params_dict_pp)[0])
471
+
472
+ predicted_pk_spectrum = np.asarray(predicted_pk_spectrum_z)
473
+
474
+ # weird scaling to get rid off
475
+ # scaling factor for the pk emulator:
476
+ ls = np.arange(2,self.cp_nk+2)[::ndspl] # jan 10 ndspl
477
+ dls = ls*(ls+1.)/2./np.pi
478
+ pk = 10.**predicted_pk_spectrum
479
+ pk_re = ((dls)**-1*pk)
480
+ pk_re = np.transpose(pk_re)
481
+
482
+ # print(z_arr,np.log(k_arr),np.log(pk_re))
483
+ # exit(0)
484
+ # self.pknl_linearnd_interp = LinearNDInterpolator(list(zip(z_arr,np.log(k_arr))), pk_re.T)
485
+ # self.pknl_cloughtocher_interp = CloughTocher2DInterpolator(list(zip(z_arr,np.log(k_arr))), pk_re.T)
486
+
487
+ # is this line making things slower?
488
+ self.pknl_interp = PowerSpectrumInterpolator(z_arr,k_arr,np.log(pk_re).T,logP=True)
489
+ # self.pknl_interp = None
490
+ self.cszfast_pk_grid_pknl = pk_re
491
+ self.cszfast_pk_grid_pknl_flat = pk_re.flatten()
492
+ return pk_re, k_arr, z_arr
493
+
494
+
495
+ def calculate_hubble(self,
496
+ # cosmo_model = self.cosmo_model,
497
+ **params_values_dict):
498
+ params_values = params_values_dict.copy()
499
+
500
+ params_dict = {}
501
+ for k,v in zip(params_values.keys(),params_values.values()):
502
+ params_dict[k]=[v]
503
+
504
+ if 'm_ncdm' in params_dict.keys():
505
+ if isinstance(params_dict['m_ncdm'][0],str):
506
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
507
+
508
+
509
+
510
+ self.cp_predicted_hubble = self.cp_h_nn[self.cosmo_model].ten_to_predictions_np(params_dict)[0]
511
+ # print(self.cp_predicted_hubble)
512
+ # z_interp =
513
+ self.hz_interp = scipy.interpolate.interp1d(
514
+ self.cp_z_interp,
515
+ self.cp_predicted_hubble,
516
+ kind='linear',
517
+ axis=-1,
518
+ copy=True,
519
+ bounds_error=None,
520
+ fill_value=np.nan,
521
+ assume_sorted=False)
522
+
523
+ def calculate_chi(self,
524
+ # cosmo_model = self.cosmo_model,
525
+ **params_values_dict):
526
+ # def test_integrand_func(x, alpha, beta, i, j, k, l):
527
+ # return x * alpha * beta + i * j * k
528
+ #
529
+ #
530
+ # grid = np.random.random((5000, 2))
531
+ #
532
+ # res, err = pyquad.quad_grid(test_integrand_func, 0, 1, grid, (1.0, 1.0, 1.0, 1.0))
533
+ #
534
+ # print(res,err)
535
+ # def integrand_chi(z,alpha, beta, i, j, k, l):
536
+ # z = z-1.
537
+ # return 1./self.get_Hubble(z)
538
+ # zmax = 1.
539
+ # grid = np.random.random((10000000, 2))
540
+ # chiz,err = pyquad.quad_grid(integrand_chi, 1., 1.+zmax, grid, (1.0, 1.0, 1.0, 1.0))
541
+ # print(chiz)
542
+ params_values = params_values_dict.copy()
543
+
544
+ params_dict = {}
545
+ for k,v in zip(params_values.keys(),params_values.values()):
546
+ params_dict[k]=[v]
547
+
548
+ if 'm_ncdm' in params_dict.keys():
549
+ if isinstance(params_dict['m_ncdm'][0],str):
550
+ params_dict['m_ncdm'] = [float(params_dict['m_ncdm'][0].split(',')[0])]
551
+
552
+
553
+ self.cp_predicted_da = self.cp_da_nn[self.cosmo_model].predictions_np(params_dict)[0]
554
+ self.chi_interp = scipy.interpolate.interp1d(
555
+ self.cp_z_interp,
556
+ self.cp_predicted_da*(1.+self.cp_z_interp),
557
+ kind='linear',
558
+ axis=-1,
559
+ copy=True,
560
+ bounds_error=None,
561
+ fill_value=np.nan,
562
+ assume_sorted=False)
563
+
564
+ def get_cmb_cls(self,ell_factor=True,Tcmb_uk = Tcmb_uk):
565
+ cls = {}
566
+ cls['ell'] = np.arange(self.cszfast_ldim)
567
+ cls['tt'] = np.zeros(self.cszfast_ldim)
568
+ cls['te'] = np.zeros(self.cszfast_ldim)
569
+ cls['ee'] = np.zeros(self.cszfast_ldim)
570
+ cls['pp'] = np.zeros(self.cszfast_ldim)
571
+ cls['bb'] = np.zeros(self.cszfast_ldim)
572
+ cls['tt'][2:self.cp_lmax+1] = (Tcmb_uk)**2.*self.cp_predicted_tt_spectrum.copy()
573
+ cls['te'][2:self.cp_lmax+1] = (Tcmb_uk)**2.*self.cp_predicted_te_spectrum.copy()
574
+ cls['ee'][2:self.cp_lmax+1] = (Tcmb_uk)**2.*self.cp_predicted_ee_spectrum.copy()
575
+ cls['pp'][2:self.cp_lmax+1] = self.cp_predicted_pp_spectrum.copy()/4. ## this is clkk... works for so lensinglite lkl
576
+ # cls['bb'][2:self.cp_lmax+1] = self.cp_predicted_pp_spectrum.copy()/4. ## this is clkk... works for so lensinglite lkl
577
+ # print('doing gets')
578
+ # For planck likelihood:
579
+ # lcp = np.asarray(cls['ell'][2:nl+2])
580
+ # cls['pp'][2:nl+2] = self.pp_spectra[0].copy()/(lcp*(lcp+1.))**2.
581
+ # cls['pp'][2:nl+2] *= (lcp*(lcp+1.))**2./2./np.pi
582
+
583
+
584
+
585
+ if ell_factor==False:
586
+ fac_l = np.zeros(self.cszfast_ldim)
587
+ 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)
588
+ cls['tt'][2:self.cp_lmax+1] *= fac_l[2:self.cp_lmax+1]
589
+ cls['te'][2:self.cp_lmax+1] *= fac_l[2:self.cp_lmax+1]
590
+ cls['ee'][2:self.cp_lmax+1] *= fac_l[2:self.cp_lmax+1]
591
+ # cls['bb'] = np.zeros(self.cszfast_ldim)
592
+ return cls
593
+
594
+
595
+ def get_pknl_at_k_and_z(self,k_asked,z_asked):
596
+ # def get_pkl_at_k_and_z(self,k_asked,z_asked,method = 'cloughtocher'):
597
+ # if method == 'linear':
598
+ # pk = self.pkl_linearnd_interp(z_asked,np.log(k_asked))
599
+ # elif method == 'cloughtocher':
600
+ # pk = self.pkl_cloughtocher_interp(z_asked,np.log(k_asked))
601
+ # return np.exp(pk)
602
+ return self.pknl_interp.P(z_asked,k_asked)
603
+
604
+
605
+ # def get_pkl_at_k_and_z(self,k_asked,z_asked,method = 'cloughtocher'):
606
+ def get_pkl_at_k_and_z(self,k_asked,z_asked):
607
+ # if method == 'linear':
608
+ # pk = self.pknl_linearnd_interp(z_asked,np.log(k_asked))
609
+ # elif method == 'cloughtocher':
610
+ # pk = self.pknl_cloughtocher_interp(z_asked,np.log(k_asked))
611
+ # return np.exp(pk)
612
+ return self.pkl_interp.P(z_asked,k_asked)
613
+
614
+ # function used to overwrite the classy function in fast mode.
615
+ def get_sigma_at_r_and_z(self,r_asked,z_asked):
616
+ # if method == 'linear':
617
+ # pk = self.pknl_linearnd_interp(z_asked,np.log(k_asked))
618
+ # elif method == 'cloughtocher':
619
+ # pk = self.pknl_cloughtocher_interp(z_asked,np.log(k_asked))
620
+ # return np.exp(pk)
621
+ k = self.cszfast_pk_grid_k
622
+ P_at_z = self.get_pkl_at_k_and_z(k,z_asked)
623
+ R,var = TophatVar(k, lowring=True)(P_at_z, extrap=True)
624
+ varR = CubicSpline(R, var)
625
+ sigma_at_r_and_z = np.sqrt(varR(r_asked))
626
+ return sigma_at_r_and_z
627
+
628
+
629
+
630
+ def get_hubble(self, z,units="1/Mpc"):
631
+ return np.array(self.hz_interp(z)*H_units_conv_factor[units])
632
+
633
+ def get_chi(self, z):
634
+ return np.array(self.chi_interp(z))
635
+
636
+ def get_gas_pressure_profile_x(self,z,m,x):
637
+ return 0#np.vectorize(self.csz_base.get_pressure_P_over_P_delta_at_x_M_z_b12_200c)(x,m,z)
638
+
639
+
640
+ # def get_gas_pressure_profile_x_parallel(self,index_z,param_values_array,**kwargs):
641
+ # # zp = self.cszfast_zgrid[iz]
642
+ # # x = self.get_gas_pressure_profile_x(zp,3e13,self.cszfast_gas_pressure_xgrid)
643
+ # x = 1
644
+ # return x
645
+
646
+
647
+ def tabulate_gas_pressure_profile_k(self):
648
+ z_asked,m_asked,x_asked = 0.2,3e14,np.geomspace(1e-3,1e2,500)
649
+ start = time.time()
650
+ px = self.get_gas_pressure_profile_x(z_asked,m_asked,x_asked)
651
+ end = time.time()
652
+ # print(px)
653
+ # print('end tabuulate pressure profile:',end-start)
654
+ # print('grid tabulate pressure profile')
655
+ start = time.time()
656
+ # px = self.get_gas_pressure_profile_x(self.cszfast_zgrid,self.cszfast_mgrid,self.cszfast_gas_pressure_xgrid)
657
+ # for zp in self.cszfast_zgrid:
658
+ # for mp in self.cszfast_mgrid:
659
+ # zp = mp
660
+ # # px = self.get_gas_pressure_profile_x(zp,mp,self.cszfast_gas_pressure_xgrid)
661
+ # zp,mp = 0.1,2e14
662
+ px = self.get_gas_pressure_profile_x(self.cszfast_zgrid[:,None,None],
663
+ self.cszfast_mgrid[None,:,None],
664
+ self.cszfast_gas_pressure_xgrid[None,None,:])
665
+
666
+ # fn=functools.partial(get_gas_pressure_profile_x_parallel,
667
+ # param_values_array=None)
668
+ # pool = multiprocessing.Pool()
669
+ # results = pool.map(fn,range(self.cszfast_zgrid_nz))
670
+ # pool.close()
671
+ #
672
+ # def task(iz):
673
+ # zp = self.cszfast_zgrid[iz]
674
+ # x = self.get_gas_pressure_profile_x(zp,m_asked,self.cszfast_gas_pressure_xgrid)
675
+ # processes = [Process(target=task, args=(i,)) for i in range(self.cszfast_zgrid_nz)]
676
+ # # start all processes
677
+ # for process in processes:
678
+ # process.start()
679
+ # # wait for all processes to complete
680
+ # for process in processes:
681
+ # process.join()
682
+ # # report that all tasks are completed
683
+ # print('Done', flush=True)
684
+ end = time.time()
685
+
686
+ # print(px)
687
+ # print('end grid tabuulate pressure profile:',end-start)
688
+ #
689
+ # def get_gas_pressure_profile_x_parallel(index_z,param_values_array,**kwargs):
690
+ # # zp = self.cszfast_zgrid[iz]
691
+ # # x = self.get_gas_pressure_profile_x(zp,3e13,self.cszfast_gas_pressure_xgrid)
692
+ # x = 1
693
+ # return x
694
+
695
+
696
+ def get_sigma8_at_z(self,z):
697
+ return self.s8z_interp(z)
698
+
699
+
700
+ def rs_drag(self):
701
+ try:
702
+ return self.cp_predicted_der[13]
703
+ except AttributeError:
704
+ return 0
705
+ #################################
706
+ # gives an estimation of f(z)*sigma8(z) at the scale of 8 h/Mpc, computed as (d sigma8/d ln a)
707
+ # Now used by cobaya wrapper.
708
+ def get_effective_f_sigma8(self, z, z_step=0.1,params_values_dict={}):
709
+ """
710
+ effective_f_sigma8(z)
711
+
712
+ Returns the time derivative of sigma8(z) computed as (d sigma8/d ln a)
713
+
714
+ Parameters
715
+ ----------
716
+ z : float
717
+ Desired redshift
718
+ z_step : float
719
+ 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.
720
+
721
+ Returns
722
+ -------
723
+ (d ln sigma8/d ln a)(z) (dimensionless)
724
+ """
725
+
726
+ s8z_interp = self.s8z_interp
727
+ # we need d sigma8/d ln a = - (d sigma8/dz)*(1+z)
728
+
729
+ # if possible, use two-sided derivative with default value of z_step
730
+ if z >= z_step:
731
+ result = (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
732
+ # return (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
733
+ else:
734
+ # if z is between z_step/10 and z_step, reduce z_step to z, and then stick to two-sided derivative
735
+ if (z > z_step/10.):
736
+ z_step = z
737
+ result = (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
738
+ # return (s8z_interp(z-z_step)-s8z_interp(z+z_step))/(2.*z_step)*(1+z)
739
+ # if z is between 0 and z_step/10, use single-sided derivative with z_step/10
740
+ else:
741
+ z_step /=10
742
+ result = (s8z_interp(z)-s8z_interp(z+z_step))/z_step*(1+z)
743
+ # return (s8z_interp(z)-s8z_interp(z+z_step))/z_step*(1+z)
744
+ # print('fsigma8 result : ',result)
745
+ return result