CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
Func.cpp
1 /*******************************************************************
2  * Copyright (C) 2010 by Federico Marulli *
3  * federico.marulli3@unibo.it *
4  * *
5  * This program is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU General Public License as *
7  * published by the Free Software Foundation; either version 2 of *
8  * the License, or (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful,*
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public *
16  * License along with this program; if not, write to the Free *
17  * Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  *******************************************************************/
20 
35 #include "GlobalFunc.h"
36 
37 using namespace std;
38 
39 using namespace cbl;
40 
41 
42 // ============================================================================
43 
44 
45 void cbl::redshift_range (const double mean_redshift, const double boxSide, cosmology::Cosmology &real_cosm, double &redshift_min, double &redshift_max)
46 {
47  coutCBL <<"I'm computing the redshift range..."<<endl;
48 
49  double z_min = 0.;
50  double lll = real_cosm.D_C(mean_redshift)+boxSide;
51  double zf1 = mean_redshift, zf2 = zf1+12.;
52  double z_max = real_cosm.Redshift(lll, zf1, zf2);
53  int step = 50000;
54  double delta_z = (z_max-z_min)/step;
55  double zz1 = z_min, zz2, L1, L2, LL, dist, dist_min = 1.e20;
56 
57  for (int i=0; i<step; i++) {
58  L1 = real_cosm.D_C(zz1);
59  zz2 = 2.*mean_redshift-zz1;
60  if (zz2<zz1) break;
61  L2 = real_cosm.D_C(zz2);
62  LL = L2-L1;
63  dist = fabs(LL-boxSide);
64  if (dist<dist_min) {
65  dist_min = dist;
66  redshift_min = zz1;
67  redshift_max = zz2;
68  }
69  zz1 += delta_z;
70  }
71  coutCBL <<"z1 = "<<redshift_min<<"; z2 = "<<redshift_max<<" (L_subBox = "<<real_cosm.D_C(redshift_max)-real_cosm.D_C(redshift_min)<<" ~ "<<boxSide<<")"<<endl;
72 }
73 
74 
75 // ============================================================================
76 
77 
78 double cbl::volume (const double boxSize, const int frac, const double Bord, const double mean_redshift, cosmology::Cosmology &real_cosm)
79 {
80  double redshift_min, redshift_max;
81  double boxSide = boxSize/double(frac);
82  redshift_range(mean_redshift, boxSide, real_cosm, redshift_min, redshift_max);
83  redshift_min += Bord;
84  redshift_max -= Bord;
85  double Lmin = real_cosm.D_C(redshift_min);
86  double Lmax = real_cosm.D_C(redshift_max);
87  return pow(Lmax-Lmin, 3.);
88 }
89 
90 
91 // ============================================================================
92 
93 
94 void cbl::coord_zSpace (std::vector<double> &ra, std::vector<double> &dec, std::vector<double> &redshift, std::vector<double> &xx, std::vector<double> &yy, std::vector<double> &zz, const std::vector<double> vx, const std::vector<double> vy, const std::vector<double> vz, const double sigmaV, cosmology::Cosmology &real_cosm, const double mean_redshift, const double redshift_min, const double redshift_max, const int seed)
95 {
96  if (ra.size()==0 && xx.size()==0)
97  ErrorCBL("both ra.size() and xx.size() are equal 0!", "coord_zSpace", "GlobalFunc/Func.cpp");
98 
99  vector<double> redshift_bin = linear_bin_vector(10000, redshift_min, redshift_max);
100  vector<double> DC_bin(10000);
101 
102  for (int i=0; i<10000; i++)
103  DC_bin[i] = real_cosm.D_C(redshift_bin[i]);
104 
105  glob::FuncGrid interp_DC(redshift_bin, DC_bin, "Spline");
106  glob::FuncGrid interp_Z(DC_bin, redshift_bin, "Spline");
107 
108  if (ra.size()==0 && xx.size()>0) {
109  ra.resize(xx.size(), 0);
110  dec.resize(xx.size(), 0);
111  redshift.resize(xx.size(), 0);
112  vector<double> dc(xx.size(), 0);
113 
114  cbl::polar_coord(xx, yy, zz, ra, dec, dc);
115  for (size_t i=0; i<dc.size(); ++i)
116  redshift[i] = interp_Z(dc[i]);
117  }
118 
119 
120 
121  // ----- real-space --> redshift-space -----
122 
123  vector<double> dc;
124 
125  double catastrophic_error = sigmaV-int(sigmaV);
126  double SigmaV = sigmaV-catastrophic_error;
127 
128  coutCBL <<"sigmaV = "<<SigmaV<<", catastrophic_error = "<<catastrophic_error<<endl;
129 
130  random::NormalRandomNumbers ran(0., SigmaV, seed);
131  random::UniformRandomNumbers ran2(0., 1., seed);
132 
133  vector<double>::iterator pos;
134  pos = min_element(xx.begin(),xx.end()); double xm = *pos;
135  pos = max_element(xx.begin(),xx.end()); double xM = *pos;
136  pos = min_element(yy.begin(),yy.end()); double ym = *pos;
137  pos = max_element(yy.begin(),yy.end()); double yM = *pos;
138  pos = min_element(zz.begin(),zz.end()); double zm = *pos;
139  pos = max_element(zz.begin(),zz.end()); double zM = *pos;
140 
141 
142  for (size_t i=0; i<ra.size(); i++) {
143 
144  if (ran2()<catastrophic_error) { // catastrophic error
145 
146  /*
147  // test
148  redshift[i] = ran2.doub()*(redshift_max-redshift_min)+redshift_min;
149  dc.push_back(real_cosm.D_C(redshift[i]));
150  */
151 
152  // default
153  double XX = ran2()*(xM-xm)+xm;
154  double YY = ran2()*(yM-ym)+ym;
155  double ZZ = ran2()*(zM-zm)+zm;
156  double Dc = sqrt(XX*XX+YY*YY+ZZ*ZZ);
157  dc.push_back(Dc);
158  ra[i] = atan(XX/YY);
159  dec[i] = asin(ZZ/Dc);
160  double Zguess_min = 0.8*0.5, Zguess_max = 1.2*2.;
161  redshift[i] = real_cosm.Redshift(Dc, Zguess_min, Zguess_max);
162 
163  }
164 
165  else {
166 
167  double vrad = vx[i]*cos(dec[i])*sin(ra[i])+vy[i]*cos(dec[i])*cos(ra[i])+vz[i]*sin(dec[i]);
168 
169  double gerr = (SigmaV>0) ? ran()/par::cc : 0.;
170  redshift[i] += vrad/par::cc*(1.+mean_redshift)+gerr; // peculiar velocities + gaussian error
171 
172  // dc.push_back(real_cosm.D_C(redshift[i]));
173  dc.push_back(interp_DC(redshift[i]));
174 
175  }
176  }
177 
178  cartesian_coord(ra, dec, dc, xx, yy, zz);
179 
180  coutCBL <<"done!"<<endl;
181 }
182 
183 
184 // ============================================================================
185 
186 
187 void cbl::create_mocks (const std::vector<double> xx, const std::vector<double> yy, const std::vector<double> zz, const std::vector<double> vx, const std::vector<double> vy, const std::vector<double> vz, const std::vector<double> var1, const std::vector<double> var2, const std::vector<double> var3, const std::string output_dir, const double boxSize, const int frac, const double Bord, const double mean_redshift, cosmology::Cosmology &real_cosm, const int REAL, const double sigmaV, const int idum, double &Volume)
188 {
189  coutCBL <<endl<<"I'm creating the mock files..."<<endl;
190 
191 
192  // ------- compute the redshift range -------
193 
194  double redshift_min = -1., redshift_max = -1.;
195  double boxSide = boxSize/double(frac);
196  redshift_range(mean_redshift, boxSide, real_cosm, redshift_min, redshift_max);
197 
198  double Lmin = real_cosm.D_C(redshift_min);
199  double Lmax = real_cosm.D_C(redshift_max);
200 
201  vector<double> shift;
202  double SH = 0.;
203  for (int i=0; i<frac; i++) {
204  shift.push_back(SH);
205  SH += boxSize/double(frac);
206  }
207 
208  double fact1 = 1./(boxSize/double(frac)), fact2 = boxSize/double(frac)*0.5;
209  vector<double> ra, dec, red, xx_temp, yy_temp, zz_temp;
210  vector<int> subCube_temp, subCube;
211 
212 
213  for (size_t i=0; i<xx.size(); i++) {
214 
215  double XX = xx[i];
216  double YY = yy[i];
217  double ZZ = zz[i];
218 
219 
220  // ------- divide the box in sub-boxes -------
221 
222  int subx = min(int(XX*fact1), int(shift.size()-1));
223  int suby = min(int(YY*fact1), int(shift.size()-1));
224  int subz = min(int(ZZ*fact1), int(shift.size()-1));
225 
226 
227  // ------- rescale the coordinates -------
228 
229  XX -= (shift[subx]+fact2);
230  YY -= (shift[suby]-Lmin);
231  ZZ -= (shift[subz]+fact2);
232 
233 
234  // ------- store the temporary vectors -------
235 
236  xx_temp.push_back(XX);
237  yy_temp.push_back(YY);
238  zz_temp.push_back(ZZ);
239  subCube_temp.push_back(subx*frac*frac+suby*frac+subz);
240 
241  }
242 
243 
244  // ------- get polar coordinates -------
245 
246  vector<double> ra_temp(xx_temp.size()), dec_temp(xx_temp.size()), dd_temp(xx_temp.size()), red_temp(xx_temp.size());
247  polar_coord (xx_temp, yy_temp, zz_temp, ra_temp, dec_temp, dd_temp);
248 
249  double Zguess_min = redshift_min*0.5, Zguess_max = redshift_max*2.;
250 
251  for (size_t i=0; i<dd_temp.size(); i++) red_temp[i] = real_cosm.Redshift(dd_temp[i], Zguess_min, Zguess_max);
252 
253  vector<double> avx, avy, avz;
254  for (size_t i=0; i<vx.size(); i++) {avx.push_back(fabs(vx[i])); avy.push_back(fabs(vy[i])); avz.push_back(fabs(vz[i]));}
255  coutCBL <<"<|v_x|> = "<<Average(avx)<<", <|v_y|> = "<<Average(avy)<<", <|v_z|> = "<<Average(avz)<<endl;
256 
257 
258  // ------- add redshift-space distortions -------
259 
260  if (REAL==0) coord_zSpace(ra_temp, dec_temp, red_temp, xx_temp, yy_temp, zz_temp, vx, vy, vz, sigmaV, real_cosm, mean_redshift, redshift_min, redshift_max, idum);
261 
262 
263  // ------- cut the borders of the box -------
264 
265  redshift_min += Bord;
266  redshift_max -= Bord;
267  Lmin = real_cosm.D_C(redshift_min);
268  Lmax = real_cosm.D_C(redshift_max);
269  double Lnew = (Lmax-Lmin)*0.5;
270  Volume = pow(Lmax-Lmin, 3.);
271 
272  if (Lnew<0) ErrorCBL("", "create_mocks", "GlobalFunc/Func.cpp");
273 
274  coutCBL <<redshift_min<<" < z < "<<redshift_max<<" --> L = "<<Lnew*2.<<" --> Volume = "<<Volume<<endl;
275 
276  vector<double> vx_new, vy_new, vz_new, var1_new, var2_new, var3_new;
277 
278  for (size_t i=0; i<xx_temp.size(); i++)
279  if (-Lnew<xx_temp[i] && xx_temp[i]<Lnew && Lmin<yy_temp[i] && yy_temp[i]<Lmax && -Lnew<zz_temp[i] && zz_temp[i]<Lnew) {
280  ra.push_back(ra_temp[i]);
281  dec.push_back(dec_temp[i]);
282  red.push_back(red_temp[i]);
283  vx_new.push_back(vx[i]);
284  vy_new.push_back(vy[i]);
285  vz_new.push_back(vz[i]);
286  var1_new.push_back(var1[i]);
287  var2_new.push_back(var2[i]);
288  var3_new.push_back(var3[i]);
289  subCube.push_back(subCube_temp[i]);
290  }
291 
292 
293  // ------- store the data -------
294 
295  string MK = "mkdir -p "+output_dir;
296  if (system(MK.c_str())) {};
297 
298  int nTOT = 0;
299 
300  for (int cub=0; cub<pow(frac,3.); cub++) {
301 
302  string file_out = output_dir+"mock_"+conv(cub,par::fINT)+".dat";
303  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
304 
305  for (size_t i=0; i<ra.size(); i++)
306  if (subCube[i]==cub) {
307  fout <<ra[i]<<" "<<dec[i]<<" "<<red[i]<<" "<<vx_new[i]<<" "<<vy_new[i]<<" "<<vz_new[i]<<" "<<var1_new[i]<<" "<<var2_new[i]<<" "<<var3_new[i]<<endl;
308  nTOT ++;
309  }
310  fout.clear(); fout.close(); coutCBL <<"I wrote the file: "<<file_out<<endl;
311  }
312 
313  coutCBL <<"Total number of haloes in the subcubes: "<<nTOT<<endl;
314 }
Generic functions that use one or more classes of the CosmoBolognaLib.
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class Cosmology.
Definition: Cosmology.h:277
double Redshift(const double d_c=1., const double z1_guess=0., const double z2_guess=10., const double prec=0.0001) const
redshift at a given comoving distance
Definition: Cosmology.cpp:1045
double D_C(const double redshift) const
the comoving line-of-sight distance at a given redshift
Definition: Cosmology.cpp:741
The class FuncGrid.
Definition: FuncGrid.h:55
The class NormalRandomNumbers.
The class UniformRandomNumbers.
static const char fINT[]
conversion symbol for: int -> std::string
Definition: Constants.h:121
static const double cc
: the speed of light in vacuum (the value is exact) [km/sec]
Definition: Constants.h:221
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
std::string conv(const T val, const char *fact)
convert a number to a std::string
Definition: Kernel.h:903
double Average(const std::vector< double > vect)
the average of a std::vector
Definition: Func.cpp:870
std::vector< T > linear_bin_vector(const size_t nn, const T min, const T max)
fill a std::vector with linearly spaced values
Definition: Kernel.h:1604
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
Definition: Kernel.cpp:160
void cartesian_coord(const double ra, const double dec, const double dd, double &XX, double &YY, double &ZZ)
conversion from polar coordinates to Cartesian coordinates
Definition: Func.cpp:221
int ErrorCBL(const std::string msg, const std::string functionCBL, const std::string fileCBL, const cbl::glob::ExitCode exitCode=cbl::glob::ExitCode::_error_)
throw an exception: it is used for handling exceptions inside the CosmoBolognaLib
Definition: Kernel.h:780
void redshift_range(const double mean_redshift, const double boxSide, cosmology::Cosmology &real_cosm, double &redshift_min, double &redshift_max)
compute the redsfhit range of a simulation box centered at z=mean_redshift
Definition: Func.cpp:45
double volume(const double boxSize, const int frac, const double Bord, const double mean_redshift, cosmology::Cosmology &real_cosm)
get the volume of a simulation box
Definition: Func.cpp:78
void coord_zSpace(std::vector< double > &ra, std::vector< double > &dec, std::vector< double > &redshift, std::vector< double > &xx, std::vector< double > &yy, std::vector< double > &zz, const std::vector< double > vx, const std::vector< double > vy, const std::vector< double > vz, const double sigmaV, cosmology::Cosmology &real_cosm, const double mean_redshift, const double redshift_min, const double redshift_max, const int seed=3213)
convert a set of coordinates from real-space to redshift-space
Definition: Func.cpp:94
void create_mocks(const std::vector< double > xx, const std::vector< double > yy, const std::vector< double > zz, const std::vector< double > vx, const std::vector< double > vy, const std::vector< double > vz, const std::vector< double > var1, const std::vector< double > var2, const std::vector< double > var3, const std::string output_dir, const double boxSize, const int frac, const double Bord, const double mean_redshift, cosmology::Cosmology &real_cosm, const int REAL, const double sigmaV, const int idum, double &Volume)
create a mock catalogue, subdividing a box into sub-boxes and recentering
Definition: Func.cpp:187
void polar_coord(const double XX, const double YY, const double ZZ, double &ra, double &dec, double &dd)
conversion from Cartesian coordinates to polar coordinates
Definition: Func.cpp:214