CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
RandomCatalogue.cpp
Go to the documentation of this file.
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 
34 #include "Catalogue.h"
35 #include "Histogram.h"
36 
37 using namespace std;
38 
39 using namespace cbl;
40 
41 
42 // ============================================================================
43 
44 
45 cbl::catalogue::Catalogue::Catalogue (const RandomType type, const cosmology::Cosmology &real_cosm, const cosmology::Cosmology &test_cosm, const std::string dir_in, const double Zguess_min, const double Zguess_max)
46 {
47  if (type!=RandomType::_createRandom_box_) ErrorCBL("the random catalogue has to be cubic!", "Catalogue", "RandomCatalogue.cpp");
48 
49  coutCBL << "I'm creating a random catalogue with warped cubic geometry, due to geometric distortions: the undistorted random catalogue is read from a file..." << endl;
50 
51  string file_in = dir_in+"random_catalogue";
52  coutCBL << "file_in = " << file_in << endl;
53  ifstream fin(file_in.c_str()); checkIO(fin, file_in);
54 
55  string line; double NUM;
56  vector<double> random_X, random_Y, random_Z;
57 
58  while (getline(fin, line)) {
59  stringstream ss(line);
60  ss >> NUM; random_X.push_back(NUM);
61  ss >> NUM; random_Y.push_back(NUM);
62  ss >> NUM; random_Z.push_back(NUM);
63  }
64 
65  fin.clear(); fin.close();
66 
67 
68  // ------ warp the random box introducing geometrical distortios ------
69 
70  vector<double> random_ra(random_X.size()), random_dec(random_X.size()), random_dc(random_X.size()), random_dc_warped(random_X.size()), random_redshift(random_X.size());
71  polar_coord(random_X, random_Y, random_Z, random_ra, random_dec, random_dc);
72  for (size_t i=0; i<random_X.size(); i++) random_redshift[i] = real_cosm.Redshift(random_dc[i], Zguess_min, Zguess_max);
73  for (size_t i=0; i<random_X.size(); i++) random_dc_warped[i] = test_cosm.D_C(random_redshift[i]);
74  cartesian_coord(random_ra, random_dec, random_dc_warped, random_X, random_Y, random_Z);
75 
76  // ------ create the new random catalogue ------
77 
78  for (size_t i=0; i<random_X.size(); i++) {
79  comovingCoordinates coord = {random_X[i], random_Y[i], random_Z[i]};
80  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord)));
81  }
82 
83 }
84 
85 
86 // ============================================================================
87 
88 cbl::catalogue::Catalogue::Catalogue (const RandomType type, const Catalogue catalogue, const double N_R, const int nbin, const cosmology::Cosmology &cosm, const bool conv, const double sigma, const std::vector<double> redshift, const std::vector<double> RA, const std::vector<double> Dec, const int z_ndigits, const int seed)
89 {
90  size_t nRandom = int(N_R*catalogue.nObjects());
91 
92  vector<double> ra, dec;
93  if (RA.size()>0) ra = RA;
94  if (Dec.size()>0) dec = Dec;
95  if (ra.size()!=dec.size()) ErrorCBL("the dimension of observed random coordinates read in input is wrong!", "Catalogue", "RandomCatalogue.cpp");
96  if (ra.size()>0 && ra.size()!=nRandom) nRandom = ra.size();
97 
98  if (type==RandomType::_createRandom_box_) {
99 
100  coutCBL << "* * * I'm creating a random catalogue with cubic geometry * * *" << endl;
101 
102  double Xmin = catalogue.Min(Var::_X_), Xmax = catalogue.Max(Var::_X_);
103  double Ymin = catalogue.Min(Var::_Y_), Ymax = catalogue.Max(Var::_Y_);
104  double Zmin = catalogue.Min(Var::_Z_), Zmax = catalogue.Max(Var::_Z_);
105 
106  if (Xmin>Xmax || Ymin>Ymax || Zmin>Zmax) ErrorCBL("wrong values of the coordinates in the construction of the random catalogue; the following conditions have to be satisfied: Xmin<=Xmax, Ymin<=Ymax and Zmin<=Zmax!", "Catalogue", "RandomCatalogue.cpp");
107 
108  random::UniformRandomNumbers ran(0., 1., seed);
109 
110  for (size_t i=0; i<nRandom; ++i) {
111  comovingCoordinates coord;
112  coord.xx = ran()*(Xmax-Xmin)+Xmin;
113  coord.yy = ran()*(Ymax-Ymin)+Ymin;
114  coord.zz = ran()*(Zmax-Zmin)+Zmin;
115  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord)));
116  }
117 
118  }
119 
120  else if (type==RandomType::_createRandom_shuffleTOT_) {
121 
122  if (ra.size()==0) {
123  ra = catalogue.var(Var::_RA_);
124  dec = catalogue.var(Var::_Dec_);
125  vector<double> raB = ra, decB = dec;
126 
127  // the R.A.-Dec coordinates of the random catalogue will be the same as the ones of the real catalogue
128  for (int i=0; i<max(0, int(N_R)-1); i++) { // use N_R times more random objects
129  ra.insert(ra.end(), raB.begin(), raB.end());
130  dec.insert(dec.end(), decB.begin(), decB.end());
131  }
132  }
133 
134  random::UniformRandomNumbers ran(0., catalogue.nObjects()-1, seed);
135 
136  // constructing the random sample
137  for (size_t i=0; i<ra.size(); i++) {
138  observedCoordinates coord = {ra[i], dec[i], round_to_precision(catalogue.redshift(ran()), z_ndigits)};
139  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord, cosm)));
140  }
141  }
142 
143  else {
144 
145  if (ra.size()==0) {
146 
147  ra = catalogue.var(Var::_RA_);
148  dec = catalogue.var(Var::_Dec_);
149  vector<double> raB = ra , decB = dec;
150 
151  if (type==RandomType::_createRandom_shuffle_) {
152 
153  coutCBL << "I'm creating a random catalogue with the 'shuffle' method..." << endl;
154 
155  // the R.A.-Dec coordinates of the random catalogue will be the same as the ones of the real catalogue
156 
157  for (int i=0; i<max(0, int(N_R)-1); i++) { // use N_R times more random objects
158  ra.insert(ra.end(), raB.begin(), raB.end());
159  dec.insert(dec.end(), decB.begin(), decB.end());
160  }
161  }
162 
163  else if (type==RandomType::_createRandom_square_) {
164  coutCBL << "I'm creating a random catalogue in a RA-Dec square..." << endl;
165 
166  ra.erase(ra.begin(), ra.end());
167  dec.erase(dec.begin(), dec.end());
168 
169  random::UniformRandomNumbers ran(0., 1., seed);
170 
171  const double ra_min = catalogue.Min(Var::_RA_),
172  ra_max = catalogue.Max(Var::_RA_),
173  sin_dec_min = sin(catalogue.Min(Var::_Dec_)),
174  sin_dec_max = sin(catalogue.Max(Var::_Dec_));
175 
176  for (size_t i=0; i<nRandom; i++) {
177  ra.push_back((ra_max-ra_min)*ran()+ra_min);
178  dec.push_back(asin((sin_dec_max-sin_dec_min)*ran()+sin_dec_min));
179 
180  /*
181  const double cos_ra_min = cos(catalogue.Min(Var::_RA_)),
182  cos_ra_max = cos(catalogue.Max(Var::_RA_)),
183  dec_min = catalogue.Min(Var::_Dec_),
184  dec_max = catalogue.Max(Var::_Dec_);
185 
186  for (size_t i=0; i<nRandom; i++) {
187  ra.push_back(acos(cos_ra_min+(cos_ra_max-cos_ra_min)*ran()));
188  dec.push_back((dec_max-dec_min)*ran()+dec_min);
189  */
190 
191  }
192  }
193  else
194  ErrorCBL("the chosen random catalogue type is not allowed!", "Catalogue", "RandomCatalogue.cpp");
195  }
196 
197 
198  // compute the redshifts of the random objects
199 
200  vector<double> random_redshift = (redshift.size()>0) ? redshift : catalogue.var(Var::_Redshift_);
201 
202  if (cbl::Max(random_redshift)-cbl::Min(random_redshift)>1.e-30) {
203 
204  // extract the redshift distribution of the input catalogue
205  vector<double> xx, yy, err;
206  distribution(xx, yy, err, random_redshift, {}, nbin, true, par::defaultString, 1., cbl::Min(random_redshift), cbl::Max(random_redshift), "Linear", conv, sigma);
207 
208  // extract the random redshifts from the distribution
209  random_redshift.resize(ra.size());
210  random_redshift = vector_from_distribution(ra.size(), xx, yy, catalogue.Min(Var::_Redshift_), catalogue.Max(Var::_Redshift_), 13);
211 
212  }
213 
214  // constructing the random sample
215  for (size_t i=0; i<random_redshift.size(); i++) {
216  observedCoordinates coord = {ra[i], dec[i], round_to_precision(random_redshift[i], z_ndigits)};
217  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord, cosm)));
218  }
219  }
220 }
221 
222 
223 // ============================================================================
224 
225 cbl::catalogue::Catalogue::Catalogue (const RandomType type, const int N_R, const double z_step, const Catalogue catalogue, const cosmology::Cosmology &cosm, const std::vector<double> RA, const std::vector<double> Dec, const double sigma_kernel, const int nbins, const int z_ndigits, const int times_default, double times_change, const double tolerance, const std::string out_path_nz, const std::string out_file_nz, const int seed)
226 {
227 
228  size_t nRandom = int(N_R*catalogue.nObjects());
229 
230  vector<double> ra, dec;
231  if (RA.size()>0) ra = RA;
232  if (Dec.size()>0) dec = Dec;
233  if (ra.size()!=dec.size()) ErrorCBL("the dimension of observed random coordinates read in input is wrong!", "Catalogue", "RandomCatalogue.cpp");
234  if (ra.size()>0 && ra.size()!=nRandom) nRandom = ra.size();
235 
236  if (ra.size()==0) {
237  ra = catalogue.var(Var::_RA_);
238  dec = catalogue.var(Var::_Dec_);
239  vector<double> raB = ra, decB = dec;
240 
241  // the R.A.-Dec coordinates of the random catalogue will be the same as the ones of the real catalogue
242  for (int i=0; i<max(0, int(N_R)-1); i++) { // use N_R times more random objects
243  ra.insert(ra.end(), raB.begin(), raB.end());
244  dec.insert(dec.end(), decB.begin(), decB.end());
245  }
246  }
247 
248  if (type==RandomType::_createRandom_shuffleTOT_) {
249 
250  random::UniformRandomNumbers ran(0., catalogue.nObjects()-1, seed);
251 
252  // construct the random sample
253  for (size_t i=0; i<ra.size(); i++) {
254  observedCoordinates coord = {ra[i], dec[i], round_to_precision(catalogue.redshift(ran()), z_ndigits)};
255  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord, cosm)));
256  }
257  }
258 
259  else if (type==RandomType::_createRandom_shuffle_) {
260 
261  // build the preliminary redshift bin edges
262  const double zMin = catalogue.Min(cbl::catalogue::Var::_Redshift_);
263  const double zMax = catalogue.Max(cbl::catalogue::Var::_Redshift_);
264  std::vector<double> z_binEdges = {zMin};
265 
266  double z_position = zMin;
267  while (z_position <= zMax) {
268  z_position += z_step;
269  z_binEdges.emplace_back(z_position);
270  }
271 
272  // find the redshift bins containing at least one object in the data sample
273  std::vector<bool> good_zbin(z_binEdges.size()-1,false);
274  for (size_t j=0; j<z_binEdges.size()-1; j++)
275  for (size_t i=0; i<catalogue.nObjects(); i++)
276  if (catalogue.redshift(i)>=z_binEdges[j] && catalogue.redshift(i)<z_binEdges[j+1]) {
277  good_zbin[j] = true;
278  break;
279  }
280 
281  std::vector<double> good_z_binEdges;
282  for (size_t j=0; j<z_binEdges.size()-1; j++) {
283  if (good_zbin[j]) {
284 
285  const bool found = std::find(good_z_binEdges.begin(), good_z_binEdges.end(), z_binEdges[j]) != good_z_binEdges.end();
286 
287  if (found==false)
288  good_z_binEdges.emplace_back(z_binEdges[j]);
289  good_z_binEdges.emplace_back(z_binEdges[j+1]);
290  }
291  }
292 
293  // convolve the redshift distribution of the data
294  std::vector<double> z_preliminary = catalogue.var(Var::_Redshift_);
295  vector<double> xx, yy, err;
296  distribution(xx, yy, err, z_preliminary, {}, nbins, true, par::defaultString, 1., zMin, zMax, "Linear", true, sigma_kernel);
297 
298  // loop until the random redshift distribution is ok
299  std::vector<double> z;
300  int times = times_default;
301  bool ok_random = false, been_higher = false, been_lower = false;
302 
303  coutCBL << "I'm searching for the best number of extractions from the smoothed n(z)..." << endl;
304  int i_counter = 0;
305 
306  while (ok_random==false) {
307  z.resize(0);
308  i_counter ++;
309  if (i_counter == 100)
310  ErrorCBL("Reached 100 iterations: I couldn't find a good way to build the random redshifts! Play with the following parameters: times_default, times_change, tolerance.", "Catalogue", "RandomCatalogue.cpp");
311 
312  // extract the random redshifts from the smoothed distribution
313  z_preliminary.resize(ra.size()*times);
314  z_preliminary = vector_from_distribution(ra.size()*times, xx, yy, zMin, zMax, seed);
315 
316  // select only the random redshifts in the good z bins
317  for (size_t i=0; i<z_preliminary.size(); i++) {
318  for (size_t j=0; j<good_z_binEdges.size()-1; j++) {
319  if ( (good_z_binEdges[j+1]-good_z_binEdges[j]<1.5*z_step) &&
320  (good_z_binEdges[j]<=z_preliminary[i]) && (z_preliminary[i]<good_z_binEdges[j+1]) ) {
321  z.emplace_back(z_preliminary[i]);
322  }
323  }
324  }
325 
326  if (z.size() < ra.size()) {
327  been_lower = true;
328  times = (int)(times*(1+times_change));
329  }
330  else if (z.size() > ra.size()*(1+tolerance)) {
331  been_higher = true;
332  times = (int)(times*(1-times_change));
333  } else
334  ok_random = true;
335  if (been_higher && been_lower) {
336  been_lower = false;
337  been_higher = false;
338  times_change -= 0.1;
339  if (times_change<=0.015)
340  ErrorCBL("I couldn't find a good way to build the random redshifts! Play with the following parameters: times_default, times_change, tolerance.", "Catalogue", "RandomCatalogue.cpp");
341  }
342  }
343  coutCBL << "I've built the random redshifts vector." << endl;
344 
345  // uniformly erase the random redshifts in excess
346  const int nExcess = (int)(z.size()-ra.size());
347 
348  for (int i=0; i<nExcess; i++) {
349  random::UniformRandomNumbers_Int rand(0., z.size()-1, seed);
350  z.erase(z.begin()+rand());
351  }
352 
353  // If requested, write the n(z) file
354  if (out_path_nz != par::defaultString && out_file_nz != par::defaultString) {
355 
356  // Normalise the original smoothed distribution (without holes)
357  std::vector<double> yy_norm (yy.size());
358  double yy_sum = 0, bin_width = xx[1]-xx[0];
359 
360  for (size_t j=0; j<xx.size(); j++)
361  yy_sum += yy[j];
362 
363  for (size_t j=0; j<xx.size(); j++)
364  yy_norm[j] = yy[j]/yy_sum/bin_width;
365 
366  // Build the normalised histogram of the extracted n(z) (without holes)
367  glob::Histogram1D hist_obj;
368  hist_obj.set(nbins, xx[0], xx[xx.size()-1], 0.5, BinType::_linear_);
369 
370  std::vector<double> weight (z_preliminary.size(), 1.);
371  hist_obj.put(z_preliminary, weight);
372 
373  std::vector<double> hist = hist_obj.operator()(glob::HistogramType::_N_V_);
374 
375  yy_sum = 0;
376  for (size_t j=0; j<hist.size(); j++)
377  yy_sum += hist[j];
378 
379  std::vector<double> yy2_norm (hist.size());
380  for (size_t j=0; j<hist.size(); j++)
381  yy2_norm[j] = hist[j]/yy_sum/bin_width;
382 
383  // Build the normalised histogram of the final n(z) (with holes)
384  hist_obj.set(nbins, xx[0], xx[xx.size()-1], 0.5, BinType::_linear_);
385  weight.resize(z.size(), 1.);
386  hist_obj.put(z, weight);
387 
388  hist = hist_obj.operator()(glob::HistogramType::_N_V_);
389 
390  yy_sum = 0;
391  for (size_t j=0; j<hist.size(); j++)
392  yy_sum += hist[j];
393 
394  std::vector<double> yy3_norm (hist.size());
395  for (size_t j=0; j<hist.size(); j++)
396  yy3_norm[j] = hist[j]/yy_sum/bin_width;
397 
398  // Write the file
399  std::string mkdir = "mkdir -p "+out_path_nz;
400  if (system(mkdir.c_str())) {}
401 
402  std::ofstream myfile;
403  myfile.open(out_path_nz+out_file_nz);
404 
405  for (size_t j=0; j<xx.size(); j++)
406  myfile << xx[j] << std::setw(20) << yy_norm[j] << std::setw(20) << yy2_norm[j] << std::setw(20) << yy3_norm[j] << std::endl;
407  myfile.close();
408  coutCBL<<"I wrote the file "+out_path_nz+out_file_nz<<std::endl;
409  }
410 
411  // finalise the random Catalogue instance
412  for (size_t i=0; i<ra.size(); i++) {
413  observedCoordinates coord = {ra[i], dec[i], round_to_precision(z[i], z_ndigits)};
414  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord, cosm)));
415  }
416  }
417  else
418  ErrorCBL("the chosen random catalogue type is not allowed!", "Catalogue", "RandomCatalogue.cpp");
419 }
420 
421 
422 // ============================================================================
423 
424 
425 cbl::catalogue::Catalogue::Catalogue (const RandomType type, const Catalogue catalogue, const double N_R, const int nbin, const double Angle, const std::vector<double> redshift, const cosmology::Cosmology &cosm, const bool conv, const double sigma, const int seed)
426 {
427  if (type!=RandomType::_createRandom_cone_) ErrorCBL("the random catalogue has to be conic!", "Catalogue", "RandomCatalogue.cpp");
428 
429  coutCBL << "I'm creating a random catalogue in a cone..." << endl;
430  const int nRandom = int(catalogue.nObjects()*N_R);
431  random::UniformRandomNumbers ran(0., 1., seed);
432 
433  // extract the redshift distribution
434 
435  vector<double> xx, yy, err;
436  distribution(xx, yy, err, redshift, {}, nbin, true, par::defaultString, 1., cbl::Min(redshift), cbl::Max(redshift), "Linear", conv, sigma);
437 
438  // extract the random redshifts from the distribution
439 
440  vector<double> random_redshift = vector_from_distribution(nRandom, xx, yy, catalogue.Min(Var::_Redshift_), catalogue.Max(Var::_Redshift_), 13);
441 
442  // set the comoving distances
443 
444  vector<double> DD;
445  for (auto &&red : random_redshift)
446  DD.emplace_back(cosm.D_C(red));
447 
448  // constructing the random sample
449 
450  const double rMax = cosm.D_C(catalogue.Max(Var::_Redshift_))*tan(Angle);
451  const double Dm = cbl::Min(DD)*0.999;
452  const double DM = cbl::Max(DD)*1.001;
453  const double fact = 1./DM;
454 
455  for (size_t i=0; i<DD.size(); ++i) {
456  comovingCoordinates coord;
457  bool OK = false;
458  while (!OK) {
459 
460  coord.xx = fact*DD[i]*rMax*2.*(ran()-0.5);
461  coord.yy = DD[i];
462  coord.zz = fact*DD[i]*rMax*2.*(ran()-0.5);
463 
464  const double r1 = sqrt(coord.xx*coord.xx+coord.zz*coord.zz);
465  const double r2 = sqrt(coord.xx*coord.xx+coord.zz*coord.zz+DD[i]*DD[i]);
466 
467  if (r1<fact*DD[i]*rMax && Dm<r2 && r2<DM) OK = true;
468  }
469 
470  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord)));
471  }
472 
473  computePolarCoordinates();
474 
475 }
476 
477 
478 // ============================================================================
479 
480 
481 cbl::catalogue::Catalogue::Catalogue (const RandomType type, const std::vector<std::string> mangle_mask, const Catalogue catalogue, const double N_R, const int nbin, const cosmology::Cosmology cosm, const bool conv, const double sigma, const int seed)
482 {
483  if (type!=RandomType::_createRandom_MANGLE_) ErrorCBL("the random catalogue has to be of type _MANGLE_!", "Catalogue", "RandomCatalogue.cpp");
484 
485  cbl::Path path;
486  string mangle_dir = path.DirCosmo()+"/External/mangle/";
487 
488  string mangle_working_dir = mangle_dir+"output/";
489  string mkdir = "mkdir -p "+mangle_working_dir;
490  if (system(mkdir.c_str())) {}
491 
492  string mangle_mask_list;
493  for (size_t i=0; i<mangle_mask.size(); i++)
494  mangle_mask_list += mangle_mask[i]+" ";
495 
496  string random_output = mangle_working_dir+"temporary_random_output.dat";
497 
498 
499  // generate the angular random distribution with mangle
500 
501  double nrandom = N_R*catalogue.nObjects();
502  string nrandom_str = cbl::conv(nrandom, par::fDP1);
503 
504  string ransack = mangle_dir+"/bin/ransack -r"+nrandom_str+" "+mangle_mask_list+" "+random_output;
505  if (system(ransack.c_str())) {}
506 
507  vector<double> random_ra, random_dec, random_redshift;
508 
509  ifstream fin(random_output.c_str()); checkIO(fin, random_output);
510  string line;
511 
512  getline(fin, line);
513 
514  while (getline(fin, line)) {
515  stringstream ss(line);
516  double ra, dec;
517  ss >> ra; ss >> dec;
518  random_ra.push_back(ra);
519  random_dec.push_back(dec);
520  }
521  fin.clear(); fin.close();
522 
523 
524  // generate the redshift distribution from the input catalogue
525 
526  vector<double> redshift = catalogue.var(Var::_Redshift_);
527  vector<double> xx, yy, err;
528  distribution(xx, yy, err, redshift, {}, nbin, true, par::defaultString, 1., cbl::Min(redshift), cbl::Max(redshift), "Linear", conv, sigma);
529 
530 
531  // extract the random redshifts from the distribution
532 
533  random_redshift = vector_from_distribution(random_ra.size(), xx, yy, catalogue.Min(Var::_Redshift_), catalogue.Max(Var::_Redshift_), seed);
534 
535  for (size_t i =0; i<random_ra.size(); i++) {
536  observedCoordinates coord = {radians(random_ra[i]), radians(random_dec[i]), random_redshift[i]};
537  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord, cosm)));
538  }
539 
540 }
541 
542 
543 // ============================================================================
544 
545 
546 cbl::catalogue::Catalogue::Catalogue (const RandomType type, const Catalogue catalogue, const double N_R, const bool dndz_per_stripe, const int nbin, const cosmology::Cosmology cosm, const bool conv, const double sigma, const int seed)
547 {
548  if (type!=RandomType::_createRandom_SDSS_stripes_) ErrorCBL("the random catalogue has to be of type _SDSS_stripe_!", "Catalogue", "RandomCatalogue.cpp");
549 
550  vector<double> lambda, eta;
551  vector<int> stripe, stripe_list;
552 
553  vector<double> ra, dec;
554 
555  for (size_t i=0; i<catalogue.nObjects(); i++) {
556  ra.push_back(catalogue.ra(i));
557  dec.push_back(catalogue.dec(i));
558  }
559 
560  eq2sdss(ra, dec, lambda, eta);
561 
562  sdss_stripe(eta, lambda, stripe, stripe_list);
563 
564  std::map<int, vector<double>> lambda_stripe, eta_stripe, redshift_stripe;
565  std::map<int, int> nObj_stripe;
566 
567  for (size_t i=0; i<catalogue.nObjects(); i++) {
568  nObj_stripe[stripe[i]] ++;
569  lambda_stripe[stripe[i]].push_back(lambda[i]);
570  eta_stripe[stripe[i]].push_back(eta[i]);
571  if (dndz_per_stripe)
572  redshift_stripe[stripe[i]].push_back(catalogue.redshift(i));
573  }
574 
575 
576  // extract random points
577 
578  random::UniformRandomNumbers random(0., 1., seed);
579 
580  vector<double> random_lambda, random_eta, random_ra, random_dec, random_redshift;
581 
582  for (auto &&ss : stripe_list) {
583  const double MinL = sin(cbl::Min(lambda_stripe[ss])*par::pi/180);
584  const double MaxL = sin(cbl::Max(lambda_stripe[ss])*par::pi/180);
585  const double deltaL = MaxL-MinL;
586  const double MinE = cbl::Min(eta_stripe[ss]);
587  const double MaxE = cbl::Max(eta_stripe[ss]);
588  const double deltaE = MaxE-MinE;
589 
590  const int nObj = lambda_stripe[ss].size();
591  const int nRan = int(N_R*nObj);
592 
593  for (int j=0; j<nRan; j++) {
594  random_lambda.push_back(asin(MinL+deltaL*random())*180/par::pi);
595  random_eta.push_back(MinE+deltaE*random());
596  if (dndz_per_stripe)
597  random_redshift.push_back(redshift_stripe[ss][int(random()*(nObj-1))]);
598  }
599  }
600 
601  sdss2eq(random_lambda, random_eta, random_ra, random_dec);
602 
603  if (!dndz_per_stripe) {
604  // generate the redshift distribution from the input catalogue
605 
606  vector<double> redshift = catalogue.var(Var::_Redshift_);
607  vector<double> xx, yy, err;
608  distribution(xx, yy, err, redshift, {}, nbin, true, par::defaultString, 1., cbl::Min(redshift), cbl::Max(redshift), "Linear", conv, sigma);
609 
610  // extract the random redshifts from the distribution
611 
612  random_redshift = vector_from_distribution(random_ra.size(), xx, yy, catalogue.Min(Var::_Redshift_), catalogue.Max(Var::_Redshift_), seed);
613  }
614 
615  for (size_t i =0; i<random_ra.size(); i++) {
616  observedCoordinates coord = {radians(random_ra[i]), radians(random_dec[i]), random_redshift[i]};
617  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord, cosm)));
618  }
619 }
620 
621 //=========================================================================
622 
623 cbl::catalogue::Catalogue::Catalogue(const RandomType type, Catalogue catalogue, const double N_R, const cosmology::Cosmology cosm, const std::vector<double> RA_range, const std::vector<double> DEC_range, const unsigned int nbin, const int seed)
624 {
625  if (type != RandomType::_createRandom_homogeneous_LC_)
626  ErrorCBL("the random catalogue has to be of type _homogeneous_LC_!", "Catalogue", "RandomCatalogue.cpp");
627 
628  auto prop = catalogue.compute_catalogueProperties_lightCone(cosm, RA_range, DEC_range, nbin);
629  vector<double> nObj(nbin+1);
630  nObj[0] = 1;
631  vector<double> zbins = linear_bin_vector(nbin+1, catalogue.Min(Var::_Redshift_), catalogue.Max(Var::_Redshift_));
632  for (size_t i=1; i<nbin+1; i++)
633  nObj[i]=nObj[i-1]+prop[1][i-1];
634 
635  std::default_random_engine generator;
636  generator.seed(seed);
637  std::uniform_int_distribution<int> distribution(1,catalogue.nObjects());
638  random::UniformRandomNumbers randomDec(sin(DEC_range[0]), sin(DEC_range[1]), seed+1);
639  random::UniformRandomNumbers randomRA(RA_range[0], RA_range[1], seed+2);
640 
641  for (int i=0; i<int(catalogue.nObjects()*N_R); i++) {
642  observedCoordinates coord = {randomRA(), asin(randomDec()), interpolated(distribution(generator), nObj, zbins, "Linear")};
643  m_object.push_back(move(Object::Create(ObjectType::_Random_, coord, cosm)));
644  }
645 
646 }
647 
648 //=========================================================================
649 
650 void cbl::catalogue::Catalogue::equalize_random_lightCone (cbl::catalogue::Catalogue tracer_catalogue, cbl::cosmology::Cosmology cosm, const std::vector<double> RA_range, const std::vector<double> DEC_range, const int seed)
651 {
652  if (nObjects()>tracer_catalogue.nObjects()) {
653  std::default_random_engine generator;
654  generator.seed(seed);
655  std::uniform_int_distribution<int> distribution(0,nObjects()-1);
656 
657  vector<bool> mask(nObjects(), false);
658 
659  size_t erased=0;
660  while (erased<nObjects()-tracer_catalogue.nObjects()) {
661  int rand = distribution(generator);
662  if (mask[rand] == false) {
663  mask[rand] = true;
664  erased++;
665  }
666  }
667 
668  remove_objects(mask);
669  }
670  else {
671 
672  auto prop = tracer_catalogue.compute_catalogueProperties_lightCone(cosm, RA_range, DEC_range, 100);
673  vector<double> nObj = {1.};
674  vector<double> zbins = linear_bin_vector(101, cbl::Min(var(Var::_Redshift_)), cbl::Max(var(Var::_Redshift_)));
675  for (size_t i=0; i<100; i++)
676  nObj.emplace_back(prop[1][i]);
677 
678  std::default_random_engine generator;
679  generator.seed(seed);
680  std::uniform_int_distribution<int> distribution(1,tracer_catalogue.nObjects());
681  random::UniformRandomNumbers randomDec(sin(DEC_range[0]), sin(DEC_range[1]), seed+1);
682  random::UniformRandomNumbers randomRA(RA_range[0], RA_range[1], seed+2);
683 
684  int nObjec = nObjects();
685  for (int i=0; i<int(tracer_catalogue.nObjects()-nObjec); i++) {
686  observedCoordinates coord = {randomRA(), asin(randomDec()), interpolated(distribution(generator), nObj, zbins, "Linear")};
687  add_object(move(Object::Create(ObjectType::_Random_, coord, cosm)));
688  }
689  }
690 }
691 
692 //=========================================================================
693 
695 {
696  if (nObjects()>tracer_catalogue.nObjects()) {
697  std::default_random_engine generator;
698  generator.seed(seed);
699  std::uniform_int_distribution<int> distribution(0,nObjects()-1);
700 
701  vector<bool> mask(nObjects(), false);
702 
703  size_t erased=0;
704  while (erased<nObjects()-tracer_catalogue.nObjects()) {
705  int rand = distribution(generator);
706  if (mask[rand] == false) {
707  mask[rand] = true;
708  erased++;
709  }
710  }
711 
712  remove_objects(mask);
713  }
714  else {
715  random::UniformRandomNumbers randomX(tracer_catalogue.Min(Var::_X_), tracer_catalogue.Max(Var::_X_), seed);
716  random::UniformRandomNumbers randomY(tracer_catalogue.Min(Var::_Y_), tracer_catalogue.Max(Var::_Y_), seed+1);
717  random::UniformRandomNumbers randomZ(tracer_catalogue.Min(Var::_Z_), tracer_catalogue.Max(Var::_Z_), seed+2);
718 
719  int nObjec = nObjects();
720  for (int i=0; i<int(tracer_catalogue.nObjects()-nObjec); i++) {
721  comovingCoordinates coord = {randomX(), randomY(), randomZ()};
722  add_object(move(Object::Create(ObjectType::_Random_, coord)));
723  }
724  }
725 }
The class Catalogue
Class used to handle binned variables.
#define coutCBL
CBL print message.
Definition: Kernel.h:734
The class Path.
Definition: Path.h:145
std::string DirCosmo()
get the directory where the CosmoBolognaLbi are stored
Definition: Path.h:178
The class Catalogue.
Definition: Catalogue.h:654
Catalogue()=default
default constructor
double Min(const Var var_name) const
get the minimum value of a variable of the catalogue objects
Definition: Catalogue.h:2287
size_t nObjects() const
get the number of objects of the catalogue
Definition: Catalogue.h:2264
double dec(const int i) const
get the private member Catalogue::m_object[i]->m_dec
Definition: Catalogue.h:1863
double redshift(const int i) const
get the private member Catalogue::m_object[i]->m_redshift
Definition: Catalogue.h:1891
double ra(const int i) const
get the private member Catalogue::m_object[i]->m_ra
Definition: Catalogue.h:1856
double var(const int index, const Var var_name) const
get the value of the i-th object variable
Definition: Catalogue.cpp:449
std::vector< std::vector< double > > compute_catalogueProperties_lightCone(cbl::cosmology::Cosmology cosmology, const std::vector< double > RA_range, const std::vector< double > DEC_range, const unsigned int nbin)
compute catalogue volume, number density and mean particle separation in light cones
Definition: Catalogue.cpp:2595
double Max(const Var var_name) const
get the maximum value of a variable of the catalogue objects
Definition: Catalogue.h:2295
void equalize_random_box(cbl::catalogue::Catalogue tracer_catalogue, const int seed)
equalize the number of objects in two Box catalogues
void equalize_random_lightCone(cbl::catalogue::Catalogue tracer_catalogue, cbl::cosmology::Cosmology cosm, const std::vector< double > RA_range, const std::vector< double > DEC_range, const int seed)
equalize the number of objects in two Light Cones catalogues
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 UniformRandomNumbers_Int.
The class UniformRandomNumbers.
static const char fDP1[]
conversion symbol for: double -> std::string
Definition: Constants.h:130
static const std::string defaultString
default std::string value
Definition: Constants.h:336
static const double pi
: the ratio of a circle's circumference to its diameter
Definition: Constants.h:199
RandomType
the type of random catalogue
Definition: Catalogue.h:345
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
void distribution(std::vector< double > &xx, std::vector< double > &fx, std::vector< double > &err, const std::vector< double > FF, const std::vector< double > WW, const int nbin, const bool linear=true, const std::string file_out=par::defaultString, const double fact=1., const double V1=par::defaultDouble, const double V2=par::defaultDouble, const std::string bin_type="Linear", const bool conv=false, const double sigma=0.)
derive and store the number distribution of a given std::vector
Definition: Func.cpp:1654
T Min(const std::vector< T > vect)
minimum element of a std::vector
Definition: Kernel.h:1324
std::string conv(const T val, const char *fact)
convert a number to a std::string
Definition: Kernel.h:903
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
T Max(const std::vector< T > vect)
maximum element of a std::vector
Definition: Kernel.h:1336
double radians(const double angle, const CoordinateUnits inputUnits=CoordinateUnits::_degrees_)
conversion to radians
Definition: Func.cpp:126
double interpolated(const double _xx, const std::vector< double > xx, const std::vector< double > yy, const std::string type)
1D interpolation
Definition: Func.cpp:445
void sdss2eq(const std::vector< double > lambda, const std::vector< double > eta, std::vector< double > &ra, std::vector< double > &dec)
convert sdss coordinates to R.A., Dec.
Definition: Func.cpp:1397
void sdss_stripe(const std::vector< double > eta, const std::vector< double > lambda, std::vector< int > &stripe, std::vector< int > &str_u)
compute the SDSS stripe given SDSS coordinates
Definition: Func.cpp:1420
std::vector< double > vector_from_distribution(const int nRan, const std::vector< double > xx, const std::vector< double > fx, const double xmin, const double xmax, const int seed)
return a std::vector of numbers sampled from a given distribution
Definition: Func.cpp:1455
double round_to_precision(const double num, const int ndigits)
reduce the precision of an input double
Definition: Kernel.cpp:150
void eq2sdss(const std::vector< double > ra, const std::vector< double > dec, std::vector< double > &lambda, std::vector< double > &eta)
convert from equatorial coordinates R.A., Dec to sdss coordinates
Definition: Func.cpp:1373
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