CosmoBolognaLib
Free Software C++/Python libraries for cosmological calculations
AngularPowerSpectrum.cpp
Go to the documentation of this file.
1 /*******************************************************************
2  * Copyright (C) 2015 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 "PowerSpectrum_Angular.h"
35 #include "Catalogue.h"
36 #include "Data1D.h"
37 #include <boost/math/special_functions/bessel.hpp>
38 #include <boost/math/special_functions/spherical_harmonic.hpp>
39 #include "LegendrePolynomials.h"
40 
41 using namespace std;
42 using namespace cbl;
43 using namespace measure;
44 using namespace twopt;
45 using namespace boost::math;
46 
47 
48 // ============================================================================================
49 
50 
51 void cbl::measure::angularpk::PowerSpectrum_angular::m_read_angular_mask(const string mask_file, std::string mask_type, double pixel_area, int n_lines_header){
52 
53  double ra_mask, theta_mask; //RA and colatitute of the pixel center of the mask
54 
55  if(mask_type=="Healpix"){ //binary mask produced with pixelfunc.pix2ang in healpix. Colatitude and RA of the centers of the occupied pixel
56  m_pixel_area=pixel_area;
57  ifstream fin(mask_file.c_str()); checkIO(fin, mask_file);
58  string line;
59  // skip the first nlines (in case of header lines)
60  if (n_lines_header>0)
61  for (int i=0; i<n_lines_header; ++i)
62  getline(fin, line);
63 
64  // read the file lines
65  while (getline(fin, line)) {
66 
67  stringstream ss(line);
68  ss >> theta_mask;
69  ss >> ra_mask;
70  m_theta_mask.emplace_back(theta_mask);
71  m_RA_mask.emplace_back(ra_mask);
72 
73  }
74  fin.close();
75 
76  m_survey_area=m_theta_mask.size()*pixel_area; //measure total area of the survey
77 
78  }else{ //mask obtained from the fits file. Colatitude and RA of the pixel centers and edges
79 
80  double ra_mask_min, ra_mask_max;
81  double theta_mask_min, theta_mask_max, pixel_area_file;
82  std::vector<double> area_pixel; //vector of pixel areas
83  ifstream fin(mask_file.c_str()); checkIO(fin, mask_file);
84 
85  string line;
86  // skip the first nlines (in case of header lines)
87  if (n_lines_header>0)
88  for (int i=0; i<n_lines_header; ++i)
89  getline(fin, line);
90 
91  // read the file lines
92  while (getline(fin, line)) {
93 
94  stringstream ss(line);
95  ss >> theta_mask;
96  ss >> theta_mask_min;
97  ss >> theta_mask_max;
98  ss >> ra_mask;
99  ss >> ra_mask_min;
100  ss >> ra_mask_max;
101  ss >> pixel_area_file;
102 
103  m_theta_mask.emplace_back(theta_mask);
104  m_theta_mask_min.emplace_back(theta_mask_min);
105  m_theta_mask_max.emplace_back(theta_mask_max);
106  m_RA_mask.emplace_back(ra_mask);
107  m_RA_mask_min.emplace_back(ra_mask_min);
108  m_RA_mask_max.emplace_back(ra_mask_max);
109  area_pixel.emplace_back(pixel_area_file);
110 
111  }
112  fin.close();
113  m_survey_area=0; //measure total area of the survey
114  for(size_t i=0; i<m_theta_mask.size(); i++) {
115  m_survey_area+=area_pixel[i];
116  }
117 
118  double area_overlap=0; //remove overlap between pixels
119  //pixel_area=(m_RA_mask_max[0]-m_RA_mask_min[0])*(m_theta_mask_max[0]-m_theta_mask_min[0]); //effective pixel area, not normalized with colatitude
120  std::vector<double> theta_side, RA_side;
121  for (size_t i=0; i<m_theta_mask.size(); ++i){ //in case of rectangular and slightly different pixels
122  theta_side.emplace_back(abs(m_theta_mask_max[i]-m_theta_mask_min[i]));
123  RA_side.emplace_back(abs(m_RA_mask_max[i]-m_RA_mask_min[i]));
124  }
125  for(size_t i=0; i<m_theta_mask.size(); i++) {
126  for(size_t j=i; j<m_theta_mask.size(); j++){
127  if(i!=j){
128  if(abs(m_theta_mask[i]-m_theta_mask[j])<cbl::Average(theta_side) && abs(m_RA_mask[i]-m_RA_mask[j])<cbl::Average(RA_side)){
129  area_overlap+=(cbl::Average(theta_side)-abs(m_theta_mask[i]-m_theta_mask[j]))*(cbl::Average(RA_side)-abs(m_RA_mask[i]-m_RA_mask[j]))*sin((m_theta_mask[i]+m_theta_mask[j])/2);
130  }
131  }
132  }
133  }
134  coutCBL<<"Area overlap= "<<area_overlap<<endl;
135  m_survey_area-=area_overlap;
136  }
137  coutCBL<<"Survey area= "<<m_survey_area<<endl;
138 
139 }
140 
141 
142 // ============================================================================================
143 
144 
146 
147  if(m_theta_mask.size()!=0){
148  bool square=true;
149  if(m_theta_mask_min.size()==0 || m_theta_mask_max.size()==0 || m_RA_mask_min.size()==0 || m_RA_mask_max.size()==0) square=false;
150  double masked=0.;
151  if(!square){
152  double radius=sqrt(m_pixel_area/M_PI);
153  for(size_t i=0; i<m_theta_mask.size(); ++i)
154  if(pow(theta-m_theta_mask[i], 2)+pow(RA-m_RA_mask[i], 2)<radius*radius) {
155  masked=1.;
156  break;
157  }
158  }
159  else{
160  for(size_t i=0; i<m_theta_mask.size(); ++i)
161  if(m_theta_mask_min[i]<theta && m_theta_mask_max[i]>theta)
162  if(m_RA_mask_min[i]<RA && m_RA_mask_max[i]>RA){
163  masked=1.;
164  break;
165  }
166  }
167  return masked;
168  }
169  else return 1;
170 }
171 
172 
173 //====================================================================================================
174 
175 
176 cbl::measure::angularpk::PowerSpectrum_angular::PowerSpectrum_angular (const catalogue::Catalogue data, const catalogue::Catalogue random, const double l_min, const double l_max, const int Nl, const BinType binType, const double thetaMin, const double thetaMax, const int nbins, const double shift, const CoordinateUnits angularUnits, const BinType correlation_binType)
177 {
178  m_l_min = l_min;
179  m_l_max = l_max;
180 
181  if(int(Nl)!=Nl || Nl<2) ErrorCBL("In spherical armonic estimator the Nl should be an >=2!","cbl::measure::PowerSpectrum_angular::PowerSpectrum_angular", "AngularPowerSpectrum.cpp" );
182  else m_Nl=Nl;
183  m_binType = correlation_binType;
184  m_angularUnits = angularUnits;
185  m_nbins=nbins;
186  set_l_output(binType);
187  cbl::measure::twopt::TwoPointCorrelation1D_angular TwoPointCorrelation1D_angular(data, random, correlation_binType, thetaMin, thetaMax, nbins, shift, angularUnits);
188  m_TwoPointCorrelation1D_angular = std::make_shared<twopt::TwoPointCorrelation1D_angular>(twopt::TwoPointCorrelation1D_angular(std::move(TwoPointCorrelation1D_angular)));
189 }
190 
191 
192 // ============================================================================================
193 
194 
195 cbl::measure::angularpk::PowerSpectrum_angular::PowerSpectrum_angular (const catalogue::Catalogue data, const double l_min, const double l_max, const int bandwidth, const std::string mask_file, const string mask_type, double pixel_area, int n_lines_header)
196 {
197  m_l_min = l_min;
198  m_l_max = l_max;
199 
200  if(int(bandwidth)!=bandwidth || int(bandwidth)<1) ErrorCBL("In spherical armonic estimator the bandwidth (l_max-l_min)/Nl should be an integer>=2!","cbl::measure::PowerSpectrum_angular::PowerSpectrum_angular", "AngularPowerSpectrum.cpp" );
201  else if(int(bandwidth)==1){
202  }else m_Nl = (l_max-l_min)/bandwidth;
203  set_catalogue(data);
204 
205  if(mask_file!="") m_read_angular_mask(mask_file, mask_type, pixel_area, n_lines_header);
206  else {
207  double pi_2=cbl::par::pi*0.5;
208  m_survey_area=(cos(pi_2-m_catalogue->Max(cbl::catalogue::Var::_Dec_))-cos(pi_2-m_catalogue->Min(cbl::catalogue::Var::_Dec_)))*(m_catalogue->Max(cbl::catalogue::Var::_RA_)-m_catalogue->Min(cbl::catalogue::Var::_RA_));
209  }
210 }
211 
212 
213 // ============================================================================================
214 
215 
217 {
218  m_catalogue = std::make_shared<catalogue::Catalogue>(catalogue::Catalogue(std::move(catalogue)));
219  if(!m_catalogue->isSetVar(cbl::catalogue::Var::_RA_) || !m_catalogue->isSetVar(cbl::catalogue::Var::_Dec_) || !m_catalogue->isSetVar(cbl::catalogue::Var::_Dc_)) ErrorCBL("The catalogue must be in observed coordinates!","cbl::measure::PowerSpectrum_angular::set_catalogue", "AngularPowerSpectrum.cpp" );
220 
221 }
222 
223 
224 //==================================================================================
225 
226 
228 { //Returns dtheta_i * theta_i
229  double value=0;
230  if (binType==cbl::BinType::_linear_) //dtheta * theta
231  value = (m_theta[1]-m_theta[0])*m_theta[i];
232 
233  else if (binType==cbl::BinType::_logarithmic_) // d log theta * theta^2 = d theta / theta * theta^2 = dtheta * theta
234  value = (log(m_theta[1])-log(m_theta[0]))*m_theta[i]*m_theta[i];
235 
236  return value;
237 }
238 
239 
240 // ============================================================================================
241 
242 
244 {
245  if (m_l_min==0) m_l_min=1;
246  double size_bin;
247  if (binType==cbl::BinType::_linear_) { //multipole scale is linear
248  size_bin = (m_l_max-m_l_min)/m_Nl; //if linear binning
249  for(int i=0; i<m_Nl; i++){
250  m_l.emplace_back(m_l_min+size_bin*i);
251  }
252  }
253 
254  if (binType==cbl::BinType::_logarithmic_) { //multipole scale is logarithmic
255  const double l_min_log = std::log10(m_l_min);
256  const double l_max_log = std::log10(m_l_max);
257  const double log_increment = (l_max_log - l_min_log)/ m_Nl;
258 
259  for (int i=0; i<m_Nl+1; ++i) {
260  m_l.emplace_back(std::pow(10, l_min_log+i*log_increment));
261  }
262  }
263 }
264 
265 
266 // ============================================================================================
267 
268 
269 void cbl::measure::angularpk::PowerSpectrum_angular::write (const std::string dir, const std::string file)
270 {
271 
272  string MK = "mkdir -p "+dir; if (system (MK.c_str())) {}
273 
274  string file_out = dir+file;
275  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
276 
277  fout << "#l \t AngularPowerSpectrum \t AngularPowerSpectrum_error"<<endl;
278 
279  for (size_t j=0; j<m_AngularPowerSpectrum.size()/2; j++) {
280  fout<<setiosflags(ios::fixed) << setprecision(5) << setw(10) << right<<m_l[j]<<
281  " " << setiosflags(ios::fixed) << setprecision(9) << setw(15) << right <<m_AngularPowerSpectrum[j] <<
282  " " << setiosflags(ios::fixed) << setprecision(9) << setw(15) << right <<m_AngularPowerSpectrum[m_AngularPowerSpectrum.size()/2+j]<<endl;
283  }
284 
285  fout.clear(); fout.close(); coutCBL << "I wrote the file " << file_out << endl;
286 
287 }
288 
289 
290 // ============================================================================================
291 
292 
293 void cbl::measure::angularpk::PowerSpectrum_angular::write_average (const std::string dir, const std::string file)
294 {
295  if(isSet(m_Nl)){
296  string MK = "mkdir -p "+dir; if (system (MK.c_str())) {}
297 
298  string file_out = dir+file;
299  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
300 
301  fout << "#l \t AngularPowerSpectrum average \t AngularPowerSpectrum_error average"<<endl;
302 
303  for (size_t j=0; j<m_AngularPowerSpectrum_av.size()/2; j++) {
304  fout<<setiosflags(ios::fixed) << setprecision(5) << setw(10) << right<<m_l_av[j]<<
305  " " << setiosflags(ios::fixed) << setprecision(9) << setw(15) << right <<m_AngularPowerSpectrum_av[j] <<
306  " " << setiosflags(ios::fixed) << setprecision(9) << setw(15) << right <<m_AngularPowerSpectrum_av[m_AngularPowerSpectrum_av.size()/2+j]<<endl;
307  }
308 
309  fout.clear(); fout.close(); coutCBL << "I wrote the file " << file_out << endl;
310  }else{
311  ErrorCBL("m_Nl is not set! Specify an integer bandwidth>=2 and use measure with SphericalArmonic estimator!","cbl::measure::PowerSpectrum_angular::measure", "AngularPowerSpectrum.cpp" );
312  }
313 }
314 
315 
316 // ===========================================================================================
317 
318 
319 void cbl::measure::angularpk::PowerSpectrum_angular::write_mixing_matrix(const std::string dir, const std::string file, bool store_window) {
320 
321  string MK = "mkdir -p "+dir; if (system (MK.c_str())) {}
322 
323  string file_out = dir+file;
324  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
325 
326  fout << "#l \t R_ll' "<<endl;
327  for(size_t i=0; i<m_l.size(); ++i){
328  fout<<setiosflags(ios::fixed) << setprecision(5) << setw(10) << right<<m_l[i]<<" ";
329  for(size_t j=0; j<m_l.size(); ++j){
330  fout<<setiosflags(ios::fixed) << setprecision(9) << setw(10) << right<<m_RR[i][j]<<" ";
331  }
332  fout<<setiosflags(ios::fixed) << setprecision(9) << setw(10) << right<<endl;
333  }
334  fout.clear(); fout.close(); coutCBL << "I wrote the file " << file_out << endl;
335 
336  if(store_window){
337  string file_out = dir+"window.dat";
338  ofstream fout(file_out.c_str()); checkIO(fout, file_out);
339 
340  fout << "#l \t W_l"<<endl;
341  for(size_t i=0; i<m_l.size(); ++i){
342  fout<<setiosflags(ios::fixed) << setprecision(5) << setw(10) << right<<m_l[i]<<" " << setiosflags(ios::fixed) << setprecision(9) << setw(10) << right <<m_Wl[i]<<endl;
343  }
344  fout.clear(); fout.close(); coutCBL << "I wrote the file " << file_out << endl;
345  }
346 }
347 
348 
349 // ===========================================================================================
350 
351 
352 void cbl::measure::angularpk::PowerSpectrum_angular::read (const std::string dir, const std::string file, const std::vector<int> column_x, const std::vector<int> column_y, const std::vector<int> column_error, const int n_lines_header)
353 {
354  coutCBL<<"I'm reading the file: "<<dir+file<<endl;
355  const cbl::data::Data1D data(dir+file, n_lines_header,column_x, column_y, column_error);
356  m_x = data.xx();
357  data.get_data(m_y);
358  data.get_error(m_y_err);
359 
360 }
361 
362 
363 // ============================================================================================
364 
365 
366 void cbl::measure::angularpk::read_mixing_matrix (const std::string dir_matrix, const std::string file_matrix, std::vector<double> &ll, std::vector<std::vector<double>> &matrix)
367 {
368  std::ifstream in;
369  in.open(dir_matrix+file_matrix);
370  std::string line;
371  std::vector<double> row;
372  if(in.is_open())
373  {
374  int skipped_lines=1;
375  for (int i=0; i<skipped_lines; ++i) getline(in, line);
376  while(std::getline(in, line)) //get 1 row as a string
377  {
378  std::istringstream iss(line); //put line into stringstream
379  double element;
380  int i=0;
381  while(iss >> element) //read double by double
382  {
383  if (i==0) {i++; //skip first column (multipole)
384  ll.emplace_back(element);
385  continue;
386  }
387  row.emplace_back(element);
388  i++;
389  }
390  matrix.push_back(row);
391  row.erase(row.begin(), row.end());
392  }
393  }
394 }
395 
396 
397 // ======================================================================================================
398 
399 
400 std::vector<double> cbl::measure::angularpk::PowerSpectrum_angular::m_error (const BinType binType, std::vector<double> w_err)
401 {
402  std::vector<double> AngularPowerSpectrum_err(m_l.size(), 0.0);
403  double dlogl = log(m_l[1])-log(m_l[0]); //logarithmic bin amplitude
404  double p0 = 2*cbl::par::pi/dlogl;
405  double d, pref, Gp, fp;
406  for (size_t j=0; j<AngularPowerSpectrum_err.size(); j++) {
407  for (size_t i=0; i<w_err.size();i++) {
408  d = m_dtheta_theta(binType, i);
409  pref = p0*d/(m_theta[i]*m_theta[i]);
410  Gp = m_theta[i]*m_l[j]*sqrt(std::exp(dlogl))*cyl_bessel_j(1,m_theta[i]*m_l[j]*sqrt(std::exp(dlogl)))-m_theta[i]*m_l[j]/sqrt(std::exp(dlogl))*cyl_bessel_j(1,m_theta[i]*m_l[j]/sqrt(std::exp(dlogl)));
411  fp = m_w_err[i]*Gp;
412  AngularPowerSpectrum_err[j] += pref*pref*fp*fp; //square for error propagation
413  }
414  }
415  for (size_t i=0; i<AngularPowerSpectrum_err.size(); i++) {
416  AngularPowerSpectrum_err[i] = sqrt(AngularPowerSpectrum_err[i])/m_l[i]/m_l[i];
417  }
418  return AngularPowerSpectrum_err;
419 }
420 
421 
422 // ============================================================================================
423 
424 
426 {
427  if (inputUnits==cbl::CoordinateUnits::_radians_) {}
428 
429  if (inputUnits==cbl::CoordinateUnits::_degrees_) {
430  const double fact = 1./180.*cbl::par::pi;
431  for(size_t i=0; i<m_theta.size(); i++){
432  m_theta[i] *= fact;
433  }
434  }
435  if (inputUnits==cbl::CoordinateUnits::_arcminutes_) {
436  const double fact = 1./60./180.*cbl::par::pi;
437  for(size_t i=0; i<m_theta.size(); i++){
438  m_theta[i] *= fact;
439  }
440  }
441  if (inputUnits==cbl::CoordinateUnits::_arcseconds_) {
442  const double fact = 1./60./60./180.*cbl::par::pi;
443  for (size_t i=0; i<m_theta.size(); i++)
444  m_theta[i] *= fact;
445  }
446 }
447 
448 // ============================================================================================
449 
450 
451 void cbl::measure::angularpk::PowerSpectrum_angular::measure (const AngularEstimator estimator, const string dir_correlation_input, const string file_correlation_input, const int n_lines_header, CoordinateUnits inputUnits, BinType input_binType, cbl::measure::ErrorType errorType, const string dir_correlation_output, const string file_correlation_output, const int nMocks)
452 {
453 
454  switch (estimator) {
455  case(AngularEstimator::_Fast_):
456  measureFast(dir_correlation_input, file_correlation_input, n_lines_header, inputUnits, input_binType, errorType, dir_correlation_output, file_correlation_output, nMocks);
457  break;
458  case(AngularEstimator::_SphericalArmonic_):
459  measureSphericalArmonic();
460  break;
461  default:
462  ErrorCBL("Invalid AngularEstimator!","cbl::measure::PowerSpectrum_angular::measure", "AngularPowerSpectrum.cpp" );
463  }
464 
465 }
466 
467 
468 //=====================================================================================================
469 
470 
471 void cbl::measure::angularpk::PowerSpectrum_angular::measureFast (const string dir_correlation_input, const string file_correlation_input, const int n_lines_header, CoordinateUnits inputUnits, BinType input_binType, cbl::measure::ErrorType errorType, const string dir_correlation_output, const string file_correlation_output, const int nMocks)
472 {
473  m_AngularPowerSpectrum.erase(std::begin(m_AngularPowerSpectrum), std::end(m_AngularPowerSpectrum));
474 
475 
476  if (file_correlation_input=="") { //if file is not specified the program measures the angular correlation function
477  coutCBL<<"I'm measuring the Angular Two Point Correlation"<<endl;
478  m_TwoPointCorrelation1D_angular->measure(errorType, dir_correlation_output, {}, par::defaultString, nMocks);
479  m_TwoPointCorrelation1D_angular->write(dir_correlation_output, file_correlation_output);
480  inputUnits = m_angularUnits;
481  input_binType = m_binType;
482  read(dir_correlation_output, file_correlation_output, {1}, {2}, {3}, n_lines_header);
483  m_theta=m_x;
484  m_w=m_y;
485  m_w_err=m_y_err;
486 
487  }
488  else {
489 
490  read(dir_correlation_input, file_correlation_input, {1}, {2}, {3}, n_lines_header);
491  m_theta=m_x;
492  m_w=m_y;
493  m_w_err=m_y_err;
494 
495  }
496 
497  m_convert_angular_units(inputUnits); //if read from file, converts the theta units to radians
498  std::vector<double> AngularPowerSpectrum(m_l.size(), 0.0),AngularPowerSpectrum_err(m_l.size(), 0.0);
499  double dlogl = log(m_l[1])-log(m_l[0]); //logarithmic bin amplitude
500  double p0 = 2*cbl::par::pi/dlogl;
501  double d, pref, Gp, fp;
502  for (size_t j=0; j<AngularPowerSpectrum.size(); j++){
503  for (size_t i=0; i<m_w.size();i++){
504  d = m_dtheta_theta(input_binType, i);
505  pref = p0*d/(m_theta[i]*m_theta[i]);
506  Gp = m_theta[i]*m_l[j]*sqrt(std::exp(dlogl))*cyl_bessel_j(1,m_theta[i]*m_l[j]*sqrt(std::exp(dlogl)))-m_theta[i]*m_l[j]/sqrt(std::exp(dlogl))*cyl_bessel_j(1,m_theta[i]*m_l[j]/sqrt(std::exp(dlogl)));
507  fp = m_w[i] * Gp;
508  AngularPowerSpectrum[j] += pref*fp/m_l[j]/m_l[j];
509  }
510  }
511  m_AngularPowerSpectrum.insert(std::end(m_AngularPowerSpectrum), std::begin(AngularPowerSpectrum), std::end(AngularPowerSpectrum));
512  AngularPowerSpectrum_err=m_error(input_binType,m_w_err);
513  m_AngularPowerSpectrum.insert(std::end(m_AngularPowerSpectrum), std::begin(AngularPowerSpectrum_err), std::end(AngularPowerSpectrum_err));
514 
515 }
516 
517 
518 //==================================================================================
519 
520 
522 {
523  double pi_2=cbl::par::pi*0.5;
524  double _pi_4=1./cbl::par::pi*0.25;
525  m_l.erase(std::begin(m_l), std::end(m_l));
526  m_AngularPowerSpectrum.erase(std::begin(m_AngularPowerSpectrum), std::end(m_AngularPowerSpectrum));
527 
528  double survey_area=m_survey_area;
529  double sigma0=m_catalogue->nObjects()/survey_area;
530  double fsky=survey_area*_pi_4; //fraction of the sky covered by the survey
531  coutCBL<<"fsky= "<<fsky<<endl;
532  std::vector<double> W_ll, AngularPowerSpectrum_err;
533  complex<double> Y_lm;
534  cout<<endl;
535  coutCBL<<" l \t C_l "<<endl;
536  for(int l=m_l_min; l<m_l_max; l++){ //works only with l<=879
537  double A_lm, C_lm=0, C_l=0, W_l=0;
538  for(int m=-l; m<l+1; m++){
539  Y_lm=0;
540  for(size_t i=0; i<m_catalogue->nObjects(); i++){
541  Y_lm+=conj(cbl::spherical_harmonics(cbl::CoordinateType::_observed_,l, m, m_catalogue->dec(i), m_catalogue->ra(i), 1.));
542  }
543  if(fsky>0.9){ //total survey
544  A_lm=abs(Y_lm);
545  C_lm=A_lm*A_lm-m_catalogue->nObjects()*_pi_4;
546  C_l+=C_lm;
547  }
548  else{
549  const int ndim = 2;
550  auto integrand_real = [this, &l, &m] (std::vector<double> x) { return angular_mask(x[0], x[1])*pow(-1,m)*boost::math::spherical_harmonic(l, m, x[0], x[1]).real()*sin(x[0]); };
551  auto integrand_im = [this, &l, &m] (std::vector<double> x) { return angular_mask(x[0], x[1])*pow(-1,m)*boost::math::spherical_harmonic(l, m, x[0], x[1]).imag()*sin(x[0]); };
552  auto integrand_J_lm = [this, &l, &m] (std::vector<double> x) { return angular_mask(x[0], x[1])*pow(abs(boost::math::spherical_harmonic(l, m, x[0], x[1])),2)*sin(x[0]); };
553 
554  std::vector<std::vector<double>> integration_limits(2);
555  integration_limits[0] = {pi_2-m_catalogue->Max(cbl::catalogue::Var::_Dec_), pi_2-m_catalogue->Min(cbl::catalogue::Var::_Dec_)};
556  integration_limits[1] = {m_catalogue->Min(cbl::catalogue::Var::_RA_), m_catalogue->Max(cbl::catalogue::Var::_RA_)};
557 
558  // wrapper to CUBA libraries
559  cbl::wrapper::cuba::CUBAwrapper CW_real(integrand_real, ndim);
560  double I_lm_re=CW_real.IntegrateCuhre(integration_limits);
561  cbl::wrapper::cuba::CUBAwrapper CW_im(integrand_im, ndim);
562  double I_lm_im=CW_im.IntegrateCuhre(integration_limits);
563  complex<double> I_lm (I_lm_re, -1.*I_lm_im);//complex conjugate
564  cbl::wrapper::cuba::CUBAwrapper CW_J_lm(integrand_J_lm, ndim);
565  double J_lm=CW_J_lm.IntegrateCuhre(integration_limits);
566  C_lm=abs(Y_lm-m_catalogue->nObjects()/survey_area*I_lm);
567  C_lm=C_lm*C_lm/J_lm-m_catalogue->nObjects()/survey_area;
568  C_l+=C_lm;
569  W_l+=pow(abs(I_lm),2);
570  }
571  }
572  C_l=C_l/(2*l+1);
573  C_l/=pow(sigma0,2);
574  W_l=W_l/(2*l+1);
575  m_l.emplace_back(l);
576  m_Wl.emplace_back(W_l);
577  m_AngularPowerSpectrum.emplace_back(C_l);
578  AngularPowerSpectrum_err.emplace_back(sqrt(2/fsky/(2*l+1))*(C_l+1/sigma0));
579  coutCBL<<l<<" "<<C_l<<endl;
580 
581  }
582 
583  m_AngularPowerSpectrum.insert(std::end(m_AngularPowerSpectrum), std::begin(AngularPowerSpectrum_err), std::end(AngularPowerSpectrum_err));
584  if(isSet(m_Nl)) m_averagePowerSpectrum();
585  // if (fsky<0.9) compute_mixing_matrix();
586 
587 
588 }
589 
590 
591 // ============================================================================================
592 
593 
595 {
596  double size=(m_l_max-m_l_min)/m_Nl;
597  std::vector<double> AngularPowerSpectrum_error_av(m_Nl, 0);
598 
599  for(int i=0; i<m_Nl; i++){
600  m_l_av.emplace_back(0);
601  m_AngularPowerSpectrum_av.emplace_back(0);
602  }
603 
604  for(size_t j=0; j<m_Nl; j++){
605  for(int i=0; i<size; i++){
606  if(i+j*size>=m_l.size()) break;
607  m_l_av[j]+=m_l[j*size+i];
608  m_AngularPowerSpectrum_av[j]+=m_AngularPowerSpectrum[j*size+i];
609  AngularPowerSpectrum_error_av[j]+=m_AngularPowerSpectrum[m_AngularPowerSpectrum.size()/2+j*size+i];
610  }
611  m_l_av[j]/=size;
612  m_AngularPowerSpectrum_av[j]/=size;
613  AngularPowerSpectrum_error_av[j]/=size;
614  }
615  m_AngularPowerSpectrum_av.insert(std::end(m_AngularPowerSpectrum_av), std::begin(AngularPowerSpectrum_error_av), std::end(AngularPowerSpectrum_error_av));
616 }
617 
618 
619 // ============================================================================================
620 
621 
622 void cbl::measure::angularpk::PowerSpectrum_angular::compute_mixing_matrix(string dir_window_input, string file_window_input)
623 {
624  double _pi_4=1./cbl::par::pi*0.25;
625  if(dir_window_input!="" && file_window_input!="") {
626  read(dir_window_input, file_window_input, {1}, {2}, {2}, 1);
627  m_l=m_x;
628  m_Wl=m_y;
629  }
630 
631  std::vector<double> row;
632  double R;
633  for(size_t k=0; k<m_l.size(); ++k) { // l cycle
634  for(size_t j=0; j<m_l.size(); ++j) { // l' cycle
635  R=0;
636  for(size_t i=0; i<m_l.size(); ++i) { // l'' cycle
637  R+=(2*m_l[i]+1)*m_Wl[i]*cbl::wigner3j(m_l[k], m_l[j], m_l[i], 0, 0, 0)*cbl::wigner3j(m_l[k], m_l[j], m_l[i], 0, 0, 0);
638  }
639  R*=(2*m_l[j]+1)*_pi_4;
640  row.emplace_back(R);
641  }
642  m_RR.emplace_back(row);
643  row.erase(row.begin(), row.end());
644  }
645 }
The class Catalogue
The class Data1D.
#define coutCBL
CBL print message.
Definition: Kernel.h:734
Class to manage Legendre polymials computation.
The class PowerSpectrum_angular.
The class Catalogue.
Definition: Catalogue.h:654
The class Data1D.
Definition: Data1D.h:51
void get_data(std::vector< double > &data) const override
get data for Data1D
Definition: Data1D.h:232
double xx(const int i) const override
get the value of x at the i-th bin
Definition: Data1D.h:206
void get_error(std::vector< double > &error) const override
get standard deviation for Data1D
Definition: Data1D.h:239
void compute_mixing_matrix(std::string dir_window_input="", std::string file_window_input="")
compute the mixing matrix
void write_average(const std::string dir, const std::string file)
write the angular power spectrum on file
void read(const std::string dir, const std::string file, const std::vector< int > column_x={1}, const std::vector< int > column_y={2}, const std::vector< int > column_error={3}, const int n_lines_header=1)
read data from file
void m_averagePowerSpectrum()
compute the average of the power spectrum
void set_l_output(const BinType binType)
generate vector which contains the multipoles at which the angular power spectrum is computed
PowerSpectrum_angular()=default
default constructor Power_spectrum_angular
void measureFast(const std::string dir_correlation_input="", const std::string file_correlation_input="", const int n_lines_header=1, CoordinateUnits inputUnits=CoordinateUnits::_arcminutes_, BinType input_binType=BinType::_logarithmic_, cbl::measure::ErrorType errorType=ErrorType::_Poisson_, const std::string dir_correlation_output=par::defaultString, const std::string file_correlation_output="xi_angular.dat", const int nMocks=0)
measure the angular power spectrum with fast estimator
void measureSphericalArmonic()
measure the angular power spectrum with spherical armonic estimator
std::vector< double > m_error(const BinType binType, std::vector< double > w_err)
measure the angular power spectrum errors
void write(const std::string dir, const std::string file)
write the angular power spectrum on file
double m_dtheta_theta(const BinType binType, int i)
compute the dtheta*theta for the integral
void measure(const AngularEstimator estimator=AngularEstimator::_Fast_, const std::string dir_correlation_input="", const std::string file_correlation_input="", const int n_lines_header=1, CoordinateUnits inputUnits=CoordinateUnits::_arcminutes_, BinType input_binType=BinType::_logarithmic_, cbl::measure::ErrorType errorType=ErrorType::_Poisson_, const std::string dir_correlation_output=par::defaultString, const std::string file_correlation_output="xi_angular.dat", const int nMocks=0)
measure the angular power spectrum
void write_mixing_matrix(const std::string dir, const std::string file, bool store_window=false)
write the angular power spectrum on file
void m_convert_angular_units(cbl::CoordinateUnits inputUnits)
converts the input angle in radians
double angular_mask(double theta, double RA)
include the binary angular mask
void m_read_angular_mask(const std::string mask_file, std::string mask_type, double pixel_area, int n_lines_header=1)
read the angular mask from file
void set_catalogue(cbl::catalogue::Catalogue catalogue)
set the catalogue for Spherical armonic estimator
The class CUBAwrapper.
Definition: CUBAwrapper.h:187
double IntegrateCuhre(std::vector< std::vector< double >> integration_limits, const bool parallelize=true)
integrate using the Cuhre routine
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
@ _Dc_
comoving distance
@ _RA_
Right Ascension.
@ _Dec_
Declination.
void read_mixing_matrix(const std::string dir, const std::string file, std::vector< double > &ll, std::vector< std::vector< double >> &matrix)
read mixing matrix from file
AngularEstimator
the angular two-point correlation estimator type
ErrorType
the two-point correlation function error type
Definition: Measure.h:59
The global namespace of the CosmoBolognaLib
Definition: CAMB.h:38
double Average(const std::vector< double > vect)
the average of a std::vector
Definition: Func.cpp:870
@ _observed_
observed coordinates (R.A., Dec, redshift)
bool isSet(const std::string var)
check if the value of a [string] variable has already been set
Definition: Kernel.h:803
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
Definition: Kernel.cpp:160
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
std::vector< double > wigner3j(double l2, double l3, double m1, double m2, double m3)
Wigner symbol.
Definition: Func.cpp:2267
std::complex< double > spherical_harmonics(cbl::CoordinateType coordinate_type, const int l, const int m, const double coord1, const double coord2, const double coord3)
the order l, degree m spherical harmonics
Definition: Func.cpp:1939
CoordinateUnits
the coordinate units
Definition: Kernel.h:562
@ _radians_
angle in radians
@ _arcminutes_
angle in arcminutes
@ _arcseconds_
angle in arcseconds
@ _degrees_
angle in degrees
BinType
the binning type
Definition: Kernel.h:505
@ _logarithmic_
logarithmic binning
@ _linear_
linear binning