Fast Methods for Cosmological Simulations
FastSim serves as a tool for quick N-body simulations in modified gravity.
ccl_redshifts.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 
5 #include <gsl/gsl_integration.h>
6 #include <gsl/gsl_spline.h>
7 #include <gsl/gsl_errno.h>
8 
9 #include "ccl.h"
10 #include "ccl_params.h"
11 #include "ccl_redshifts.h"
12 
13 // ---- LSST redshift distributions & current specs -----
14 // ---- Consider spline for input dN/dz - pending
15 
16 /*------ ROUTINE: ccl_create_photoz_info ------
17 INPUT: void * params, (double *) pz_func (double, double, void *)
18 TASK: create a structure amalgamating the user-input information on the photo-z model.
19 The structure holds a pointer to the function which returns the probability of getting a certain z_ph (first double)
20 given a z_spec (second double), and a pointer to the parameters which get passed to that function (other than z_ph and z_sp); */
22  double (*pz_func)(double, double,void*, int*))
23 {
24  pz_info * this_info = malloc(sizeof(pz_info));
25  this_info ->your_pz_params = params;
26  this_info -> your_pz_func = pz_func;
27 
28  return this_info;
29 }
30 
31 /*------ ROUTINE: ccl_photoz -----
32 INPUT: double z_ph, void *params
33 TASK: Returns the value of p(z_photo, z). Change this function to
34  change the way true-z and photo-z's are related.
35  This has to be in a form that gsl can integrate.
36 */
37 // struct of parameters to pass to photo_z
38 struct pz_params{
39  double z_true; // Gives the true redshift at which to evaluate
40  pz_info * pz_information; //Calls the photo-z scatter model
41  int *status;
42 };
43 
44 static double ccl_photoz(double z_ph, void * params)
45 {
46  struct pz_params * p = (struct pz_params *) params;
47  pz_info * user_stuff = (pz_info*) p->pz_information;
48  double z_s = p->z_true;
49 
50  return (user_stuff->your_pz_func)(z_ph, z_s, user_stuff->your_pz_params,p->status);
51 }
52 
53 // Gaussian photo-z function
54 double gaussian_pz(double z_ph, double z_s, void* params, int *status){
55  double sigma_z0 = *((double*) params);
56 
57  double sigma_z = sigma_z0 * (1. + z_s);
58  return exp(- (z_ph - z_s)*(z_ph - z_s) / (2.*sigma_z*sigma_z)) \
59  / (sqrt(2.*M_PI) *sigma_z);
60 }
61 
62 /*------ ROUTINE: ccl_specs_create_gaussian_photoz_info ------
63 INPUT: void * user_pz_params, (double *) user_pz_func (double, double, void *)
64 TASK: Convenience function for creating a Gaussian photo-z model with error
65 sigma(z) = sigma_z0 (1 + z). */
66 
68 
69  // Allocate memory so that this value persists
70  double* sigma_z0_copy = malloc(sizeof(double));
71  *sigma_z0_copy = sigma_z0;
72 
73  // Construct pz_info struct
74  pz_info * this_info = malloc(sizeof(pz_info));
75  this_info->your_pz_params = sigma_z0_copy;
76  this_info->your_pz_func = &gaussian_pz;
77  return this_info;
78 }
79 
80 /* ------ ROUTINE: ccl_free_photoz_info -------
81 INPUT: pz_info my_photoz_info
82 TASK: free memory holding the structure containing user-input photoz information */
83 
84 void ccl_free_photoz_info(pz_info *my_photoz_info)
85 {
86  free(my_photoz_info);
87 }
88 
89 /*------ ROUTINE: ccl_create_dNdz_info ------
90 INPUT: void * params, (double *) dNdz_func (double, void *, int*)
91 TASK: create a structure amalgamating the information on an analytic true dNdz model.
92 The structure holds a pointer to the function which returns the analytic dNdz
93 * and a pointer to the parameters which get passed to that function (other than z); */
94 dNdz_info* ccl_create_dNdz_info(void * params, double(*dNdz_func)(double,void*,int*))
95 {
96  dNdz_info * this_info = malloc(sizeof(dNdz_info));
97  this_info ->your_dN_params = params;
98  this_info -> your_dN_func = dNdz_func;
99 
100  return this_info;
101 }
102 
103 /*------ ROUTINE: dNdz_smail ----------
104  * INPUT: z, params (containing: alpha, beta, z0), status
105  * OUTPUT: Analytic Smail et al. type dNdz (NOT normalized) */
106 
107 double dNdz_smail(double z, void* params, int *status){
108  double alpha = ((smail_params*) params)->alpha;
109  double beta = ((smail_params*) params)->beta;
110  double z0 = ((smail_params*) params)->z0;
111 
112  return pow(z, alpha) * exp(- pow(z/z0, beta) );
113 }
114 
115 /*------ ROUTINE: ccl_create_smail_dNdz_info ------
116 INPUT: alpha, beta, z0
117 TASK: Convenience function for creating an analytic dNdz wrt true z
118 * of the 'smail' form: dNdz ~ z^alpha exp(- (z/z0)^beta) */
119 
120 dNdz_info* ccl_create_Smail_dNdz_info(double alpha, double beta, double z0){
121 
122  // Allocate a smail type parmaeter structure
123  smail_params * smail_par = malloc(sizeof(smail_params));
124  smail_par->alpha = alpha;
125  smail_par->beta = beta;
126  smail_par->z0 = z0;
127 
128  // Construct dNdz_info struct
129  dNdz_info * this_info = malloc(sizeof(dNdz_info));
130  this_info->your_dN_params = smail_par;
131  this_info->your_dN_func = &dNdz_smail;
132  return this_info;
133 }
134 
135 /*------ ROUTINE: ccl_dNdz -----
136 INPUT: double z, void *params
137 TASK: Returns the value of dNdz(z). Change this function to
138  change the way true-z and photo-z's are related.
139  This has to be in a form that gsl can integrate.
140 */
141 
142 static double ccl_dNdz(double z, dNdz_info* params, int* status)
143 {
144 
145  return (params->your_dN_func)(z, params->your_dN_params, status);
146 }
147 
148 /* ------ ROUTINE: ccl_free_dNdz_info -------
149 INPUT: dNdz_info my_dNdz_info
150 TASK: free memory holding the structure containing dNdz information */
151 
152 void ccl_free_dNdz_info(dNdz_info *my_dNdz_info)
153 {
154  free(my_dNdz_info);
155 }
156 
157 /*------ ROUTINE: ccl_specs_norm_integrand -----
158 INPUT: double z_ph, void *params
159 TASK: Returns the integrand which is integrated to get the normalization of
160  dNdz in a given photometric redshift bin (the denominator from dNdz_sources_tomog).
161  This has to be an separate function that gsl can integrate.
162 */
163 
164 // struct of parameters to pass to norm_integrand
165 struct norm_params {
166  double bin_zmin_;
167  double bin_zmax_;
170  int *status;
171 };
172 
173 static double ccl_norm_integrand(double z, void* params)
174 {
175 
176  // This is a struct that contains a true redshift and a pointer to the information about the photo_z model
177  struct pz_params pz_val_p; // parameters for the photoz pdf wrt true-z
178 
179  double pz_int=0; // pointer to the value of the integral over the photoz model
180  struct norm_params *p = (struct norm_params *) params; // parameters of the current function (because of form required for gsl integration)
181 
182  double z_min = p->bin_zmin_;
183  double z_max = p->bin_zmax_;
184 
185  // Check whether ccl_splines and ccl_gsl exist; exit gracefully if they
186  // can't be loaded
187  if(ccl_splines==NULL || ccl_gsl==NULL) ccl_cosmology_read_config();
188  if(ccl_splines==NULL || ccl_gsl==NULL) {
190  "ccl_redshift.c: Failed to read config file.");
191  return NAN;
192  }
193 
194  // Set up parameters for the pz part of the intermediary integral.
195  pz_val_p.z_true = z;
196  pz_val_p.status = p->status;
197  pz_val_p.pz_information = p-> pz_information;
198 
199  // Do the intermediary integral over the model relating photo-z to true-z
200  gsl_integration_cquad_workspace * workspace = gsl_integration_cquad_workspace_alloc(ccl_gsl->N_ITERATION);
201  gsl_function F;
202  F.function = ccl_photoz;
203  F.params = &pz_val_p;
204  int gslstatus = gsl_integration_cquad(&F, z_min, z_max, 0.0,ccl_gsl->INTEGRATION_DNDZ_EPSREL,workspace,&pz_int, NULL, NULL);
205  if(gslstatus != GSL_SUCCESS) {
206  ccl_raise_gsl_warning(gslstatus, "ccl_redshifts.c: ccl_specs_norm_integrand():");
207  *p->status|= gslstatus;
208  }
209  gsl_integration_cquad_workspace_free(workspace);
210 
211  return ccl_dNdz(z, p->dN_information, p->status) * pz_int ;
212 }
213 
214 /*------ ROUTINE: ccl_specs_dNdz_tomog -----
215 INPUT: double z, , double bin_zmin, double bin_zmax, dNdz function pointer, sigma_z function pointer
216  tomographic boundaries are [bin_zmin,bin_zmax]
217 TASK: dNdz in a particular tomographic bin,
218  convolved with a photo-z model (defined by the user), and normalized.
219  returns a status integer 0 if called with an allowable type of dNdz, non-zero otherwise
220  (this is different from the regular status handling procedure because we don't pass a cosmology to this function)
221 */
222 void ccl_dNdz_tomog(double z, double bin_zmin, double bin_zmax,
223  pz_info * photo_info, dNdz_info * dN_info, double *tomoout, int *status)
224 {
225  // This uses equation 33 of Joachimi & Schneider 2009, arxiv:0905.0393
226  double numerator_integrand=0, denom_integrand=0, dNdz_t;
227  // This struct contains a spec redshift and a pointer to a photoz information struct.
228  struct pz_params pz_p_val; //parameters for the integral over the photoz's
229  struct norm_params norm_p_val;
230 
231  // Check whether ccl_splines and ccl_gsl exist; exit gracefully if they
232  // can't be loaded
233  if(ccl_splines==NULL || ccl_gsl==NULL) ccl_cosmology_read_config();
234  if(ccl_splines==NULL || ccl_gsl==NULL) {
236  "ccl_redshifts.c: Failed to read config file.");
238  return;
239  }
240 
241  // Set up the parameters to pass to the normalising integral (of type struct norm_params
242  norm_p_val.bin_zmin_=bin_zmin;
243  norm_p_val.bin_zmax_=bin_zmax;
244  norm_p_val.pz_information = photo_info;
245  norm_p_val.status = status;
246  norm_p_val.dN_information = dN_info;
247 
248  dNdz_t = ccl_dNdz(z, dN_info, status);
249 
250  // Set up the parameters for the integral over the photo z function in the numerator (of type struct pz_params)
251  pz_p_val.z_true = z;
252  pz_p_val.status = status;
253  pz_p_val.pz_information = photo_info; // pointer to user information
254 
255  // Integrate over the assumed pdf of photo-z wrt true-z in this bin (this goes in the numerator of the result):
256  gsl_integration_cquad_workspace * workspace = gsl_integration_cquad_workspace_alloc(ccl_gsl->N_ITERATION);
257  gsl_function F;
258  F.function = ccl_photoz;
259  F.params = &pz_p_val;
260  int gslstatus = gsl_integration_cquad(&F, bin_zmin, bin_zmax, 0.0,ccl_gsl->INTEGRATION_DNDZ_EPSREL,workspace,&numerator_integrand, NULL, NULL);
261  if(gslstatus != GSL_SUCCESS) {
262  ccl_raise_gsl_warning(gslstatus, "ccl_redshifts.c: ccl_norm_integrand():");
263  *status |= gslstatus;
264  }
265  gsl_integration_cquad_workspace_free(workspace);
266 
267  // Now get the denominator, which normalizes dNdz over the photometric bin
268  workspace = gsl_integration_cquad_workspace_alloc(ccl_gsl->N_ITERATION);
269  F.function = ccl_norm_integrand;
270  F.params = &norm_p_val;
271  gslstatus = gsl_integration_cquad(&F, Z_MIN_SOURCES, Z_MAX_SOURCES, 0.0,ccl_gsl->INTEGRATION_DNDZ_EPSREL,workspace,&denom_integrand, NULL, NULL);
272  if(gslstatus != GSL_SUCCESS) {
273  ccl_raise_gsl_warning(gslstatus, "ccl_redshifts.c: ccl_norm_integrand():");
274  *status |= gslstatus;
275  }
276 
277  gsl_integration_cquad_workspace_free(workspace);
278  if (*status) {
279  *status = CCL_ERROR_INTEG;
280  return;
281  }
282  *tomoout = dNdz_t * numerator_integrand / denom_integrand;
283 
284 }
static double ccl_dNdz(double z, dNdz_info *params, int *status)
#define CCL_ERROR_INTEG
Definition: ccl_error.h:15
double dNdz_smail(double z, void *params, int *status)
#define Z_MAX_SOURCES
Definition: ccl_redshifts.h:13
dNdz_info * ccl_create_Smail_dNdz_info(double alpha, double beta, double z0)
void * your_dN_params
Definition: ccl_redshifts.h:35
void ccl_raise_gsl_warning(int gslstatus, const char *msg,...)
Definition: ccl_error.c:75
void * your_pz_params
Definition: ccl_redshifts.h:24
pz_info * pz_information
Definition: ccl_redshifts.c:40
pz_info * pz_information
double(* your_dN_func)(double, void *, int *)
Definition: ccl_redshifts.h:33
#define CCL_ERROR_MISSING_CONFIG_FILE
Definition: ccl_error.h:28
void ccl_free_dNdz_info(dNdz_info *my_dNdz_info)
ccl_spline_params * ccl_splines
Definition: ccl_core.c:47
double INTEGRATION_DNDZ_EPSREL
Definition: ccl_params.h:66
#define M_PI
Definition: ccl_constants.h:22
int * status
Definition: ccl_redshifts.c:41
double(* your_pz_func)(double, double, void *, int *)
Definition: ccl_redshifts.h:22
ccl_gsl_params * ccl_gsl
Definition: ccl_core.c:48
Grid< NDIM, T > sqrt(Grid< NDIM, T > lhs)
Definition: grid.h:231
static double beta[2][28][8]
Definition: ccl_emu17.c:32
#define Z_MIN_SOURCES
Definition: ccl_redshifts.h:12
static double ccl_norm_integrand(double z, void *params)
void ccl_cosmology_read_config(void)
Definition: ccl_core.c:50
dNdz_info * ccl_create_dNdz_info(void *params, double(*dNdz_func)(double, void *, int *))
Definition: ccl_redshifts.c:94
double gaussian_pz(double z_ph, double z_s, void *params, int *status)
Definition: ccl_redshifts.c:54
double z_true
Definition: ccl_redshifts.c:39
pz_info * ccl_create_gaussian_photoz_info(double sigma_z0)
Definition: ccl_redshifts.c:67
size_t N_ITERATION
Definition: ccl_params.h:55
dictionary params
Definition: halomod_bm.py:27
static double z[8]
double bin_zmin_
static int p
Definition: ccl_emu17.c:25
double bin_zmax_
void ccl_free_photoz_info(pz_info *my_photoz_info)
Definition: ccl_redshifts.c:84
float pow(float base, unsigned long int exp)
Definition: precision.hpp:39
dNdz_info * dN_information
static double ccl_photoz(double z_ph, void *params)
Definition: ccl_redshifts.c:44
void ccl_dNdz_tomog(double z, double bin_zmin, double bin_zmax, pz_info *photo_info, dNdz_info *dN_info, double *tomoout, int *status)
void ccl_raise_exception(int err, const char *msg,...)
Definition: ccl_error.c:35
pz_info * ccl_create_photoz_info(void *params, double(*pz_func)(double, double, void *, int *))
Definition: ccl_redshifts.c:21