1+ # Standard imports
2+ import sys
3+ import numpy as np
4+ import matplotlib .pyplot as plt
5+
6+ # Project imports
7+ sys .path .append ('../' )
8+
9+ import hmcode
10+ import hmcode .camb_stuff as camb_stuff
11+ import hmcode .utility as util
12+
13+ plotting = True
14+
15+ # Vary these parameters
16+ vary_Omega_k = True
17+ vary_w0 = True
18+ vary_wa = True
19+ vary_m_nu = True
20+
21+ # Parameter ranges
22+ Omega_c_min , Omega_c_max = 0.2 , 0.4
23+ Omega_b_min , Omega_b_max = 0.035 , 0.065
24+ Omega_k_min , Omega_k_max = - 0.05 , 0.05
25+ h_min , h_max = 0.5 , 0.9
26+ ns_min , ns_max = 0.9 , 1.0
27+ sigma_8_min , sigma_8_max = 0.7 , 0.9
28+ w0_min , w0_max = - 1.3 , - 0.7
29+ wa_min , wa_max = - 1.73 , 1.28
30+ m_nu_min , m_nu_max = 0. , 1.
31+ log10T_AGN_min , log10T_AGN_max = 7.6 , 8.3
32+
33+
34+ # Number of cosmological models to test
35+ try :
36+ ncos = int (sys .argv [1 ])
37+ except :
38+ ncos = 5
39+ verbose = (ncos == 1 )
40+
41+ # Wavenumbers [h/Mpc]
42+ kmin , kmax = 1e-3 , 1e1
43+ nk = 128
44+ k = util .logspace (kmin , kmax , nk )
45+
46+ # Redshifts
47+ zs = [1.5 , 1. , 0.5 , 0. ]
48+ zs = np .array (zs )
49+
50+ # Seed random number generator
51+ rng = np .random .default_rng (seed = 42 )
52+
53+ # Loop over cosmologies
54+ max_errors = []
55+ for icos in range (ncos ):
56+
57+ # Cosmology
58+ Omega_c = rng .uniform (Omega_c_min , Omega_c_max )
59+ Omega_b = rng .uniform (Omega_b_min , Omega_b_max )
60+ Omega_k = rng .uniform (Omega_k_min , Omega_k_max ) if vary_Omega_k else 0.
61+ h = rng .uniform (h_min , h_max )
62+ ns = rng .uniform (ns_min , ns_max )
63+ sigma_8 = rng .uniform (sigma_8_min , sigma_8_max )
64+ log10T_AGN = rng .uniform (log10T_AGN_min , log10T_AGN_max )
65+
66+ w0 = rng .uniform (w0_min , w0_max ) if vary_w0 else - 1.
67+ while True : # Ensure that dark energy does not dominate the early universe
68+ wa = rng .uniform (wa_min , wa_max ) if vary_wa else 0.
69+ if w0 + wa < 0. : break
70+ m_nu = rng .uniform (m_nu_min , m_nu_max ) if vary_m_nu else 0.
71+
72+ #Gravity only spectra
73+
74+ # Get stuff from CAMB
75+ _ , results_gravity , _ , _ , _ = camb_stuff .run (zs , Omega_c , Omega_b , Omega_k , h , ns , sigma_8 , m_nu , w0 , wa )
76+ Pk_nonlin_interp = results_gravity .get_matter_power_interpolator (nonlinear = True ).P
77+
78+ # Arrays for CAMB non-linear spectrum
79+ Pk_CAMB_gravity = np .zeros ((len (zs ), len (k )))
80+ for iz , z in enumerate (zs ):
81+ Pk_CAMB_gravity [iz , :] = Pk_nonlin_interp (z , k )
82+
83+ # Get the new pyHMcode spectrum
84+ Pk_HMcode_gravity = hmcode .power (k , zs , results_gravity , verbose = verbose )
85+
86+
87+ # Spectra with feedback
88+
89+ # Get stuff from CAMB
90+ _ , results_feedback , _ , _ , _ = camb_stuff .run (zs , Omega_c , Omega_b , Omega_k , h , ns , sigma_8 , m_nu , w0 , wa , log10_T_AGN = log10T_AGN )
91+ Pk_nonlin_interp = results_feedback .get_matter_power_interpolator (nonlinear = True ).P
92+
93+ # Arrays for CAMB non-linear spectrum
94+ Pk_CAMB_feedback = np .zeros ((len (zs ), len (k )))
95+ for iz , z in enumerate (zs ):
96+ Pk_CAMB_feedback [iz , :] = Pk_nonlin_interp (z , k )
97+
98+ # Get the new pyHMcode spectrum
99+ Pk_HMcode_feedback = hmcode .power (k , zs , results_gravity , verbose = verbose , T_AGN = np .power (10 , log10T_AGN ))
100+
101+ # Calculate suppressions
102+
103+ Rk_CAMB = Pk_CAMB_feedback / Pk_CAMB_gravity
104+ Rk_HMcode = Pk_HMcode_feedback / Pk_HMcode_gravity
105+
106+ if plotting :
107+ fig , axs = plt .subplots (nrows = 2 , sharex = True , figsize = (10 ,7 ))
108+ plt .subplots_adjust (hspace = 0.001 , bottom = 0.2 )
109+
110+ fig .suptitle ('Cosmology: {:d}; (Om_c, Om_b, Om_k, h, ns, sig8, w0, wa, m_nu, log10(T_AGN/K)) = \n \
111+ ({:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2})' .format (icos , Omega_c , Omega_b , Omega_k , h , ns , sigma_8 , w0 , wa , m_nu , log10T_AGN ))
112+ axs [0 ].set_ylabel (r'$R(k)=P(k)/P_\mathrm{no-feedback}(k)$' )
113+ axs [1 ].set_ylabel (r'$R_\mathrm{CAMB}(k)/R_\mathrm{HMcode-Python}(k)-1$' )
114+
115+ for ax in axs :
116+ ax .set_xscale ('log' )
117+ axs [1 ].set_xlabel (r'$k [h/\mathrm{Mpc}]$' )
118+
119+ for i ,z in enumerate (zs ):
120+ axs [0 ].plot (k , Rk_CAMB [i ], label = f"CAMB, z={ z } " , color = f"C{ i } " , ls = '--' )
121+ axs [0 ].plot (k , Rk_HMcode [i ], label = f"HMcode-Python, z={ z } " , color = f"C{ i } " )
122+
123+ axs [1 ].plot (k , 1 - (Rk_CAMB [i ]/ Rk_HMcode [i ]), label = f"z={ z } " , color = f"C{ i } " )
124+
125+ axs [0 ].legend ()
126+ axs [1 ].legend ()
127+ #plt.tight_layout()
128+ plt .savefig (f"Feedback_Cosmology_{ icos } _wo1Hsuppression.png" )
129+
130+
131+ # Calculate maximum deviation between pyHMcode and the version in CAMB
132+ max_error = np .max (np .abs (- 1. + Rk_HMcode / Rk_CAMB ))
133+ max_errors .append (max_error )
134+ print ('Cosmology: {:d}; (Om_c, Om_b, Om_k, h, ns, sig8, w0, wa, m_nu, log10(T_AGN/K)) = \
135+ ({:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}, {:.2}); \
136+ maximum deviation: {:.2%}' .format (icos , Omega_c , Omega_b , Omega_k , h , ns , sigma_8 , w0 , wa , m_nu , log10T_AGN , max_error ))
137+
138+ # Write worst error to screen
139+ max_errors = np .array (max_errors )
140+ print ('Mean error: {:.2%}' .format (max_errors .mean ()))
141+ print ('Std error: {:.2%}' .format (max_errors .std ()))
142+ print ('Worst error: {:.2%}' .format (max_errors .max ()))
0 commit comments