37 #include <boost/math/special_functions/bessel.hpp>
38 #include <boost/math/special_functions/spherical_harmonic.hpp>
43 using namespace measure;
44 using namespace twopt;
45 using namespace boost::math;
53 double ra_mask, theta_mask;
55 if(mask_type==
"Healpix"){
56 m_pixel_area=pixel_area;
57 ifstream fin(mask_file.c_str());
checkIO(fin, mask_file);
61 for (
int i=0; i<n_lines_header; ++i)
65 while (getline(fin, line)) {
67 stringstream ss(line);
70 m_theta_mask.emplace_back(theta_mask);
71 m_RA_mask.emplace_back(ra_mask);
76 m_survey_area=m_theta_mask.size()*pixel_area;
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;
83 ifstream fin(mask_file.c_str());
checkIO(fin, mask_file);
88 for (
int i=0; i<n_lines_header; ++i)
92 while (getline(fin, line)) {
94 stringstream ss(line);
101 ss >> pixel_area_file;
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);
114 for(
size_t i=0; i<m_theta_mask.size(); i++) {
115 m_survey_area+=area_pixel[i];
118 double area_overlap=0;
120 std::vector<double> theta_side, RA_side;
121 for (
size_t i=0; i<m_theta_mask.size(); ++i){
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]));
125 for(
size_t i=0; i<m_theta_mask.size(); i++) {
126 for(
size_t j=i; j<m_theta_mask.size(); 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);
134 coutCBL<<
"Area overlap= "<<area_overlap<<endl;
135 m_survey_area-=area_overlap;
137 coutCBL<<
"Survey area= "<<m_survey_area<<endl;
147 if(m_theta_mask.size()!=0){
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;
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) {
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){
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)
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" );
183 m_binType = correlation_binType;
184 m_angularUnits = angularUnits;
186 set_l_output(binType);
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;
205 if(mask_file!=
"") m_read_angular_mask(mask_file, mask_type, pixel_area, n_lines_header);
218 m_catalogue = std::make_shared<catalogue::Catalogue>(
catalogue::Catalogue(std::move(catalogue)));
231 value = (m_theta[1]-m_theta[0])*m_theta[i];
234 value = (log(m_theta[1])-log(m_theta[0]))*m_theta[i]*m_theta[i];
245 if (m_l_min==0) m_l_min=1;
248 size_bin = (m_l_max-m_l_min)/m_Nl;
249 for(
int i=0; i<m_Nl; i++){
250 m_l.emplace_back(m_l_min+size_bin*i);
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;
259 for (
int i=0; i<m_Nl+1; ++i) {
260 m_l.emplace_back(std::pow(10, l_min_log+i*log_increment));
272 string MK =
"mkdir -p "+dir;
if (system (MK.c_str())) {}
274 string file_out = dir+file;
275 ofstream fout(file_out.c_str());
checkIO(fout, file_out);
277 fout <<
"#l \t AngularPowerSpectrum \t AngularPowerSpectrum_error"<<endl;
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;
285 fout.clear(); fout.close();
coutCBL <<
"I wrote the file " << file_out << endl;
296 string MK =
"mkdir -p "+dir;
if (system (MK.c_str())) {}
298 string file_out = dir+file;
299 ofstream fout(file_out.c_str());
checkIO(fout, file_out);
301 fout <<
"#l \t AngularPowerSpectrum average \t AngularPowerSpectrum_error average"<<endl;
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;
309 fout.clear(); fout.close();
coutCBL <<
"I wrote the file " << file_out << endl;
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" );
321 string MK =
"mkdir -p "+dir;
if (system (MK.c_str())) {}
323 string file_out = dir+file;
324 ofstream fout(file_out.c_str());
checkIO(fout, file_out);
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]<<
" ";
332 fout<<setiosflags(ios::fixed) << setprecision(9) << setw(10) << right<<endl;
334 fout.clear(); fout.close();
coutCBL <<
"I wrote the file " << file_out << endl;
337 string file_out = dir+
"window.dat";
338 ofstream fout(file_out.c_str());
checkIO(fout, file_out);
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;
344 fout.clear(); fout.close();
coutCBL <<
"I wrote the file " << file_out << endl;
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);
369 in.open(dir_matrix+file_matrix);
371 std::vector<double> row;
375 for (
int i=0; i<skipped_lines; ++i) getline(in, line);
376 while(std::getline(in, line))
378 std::istringstream iss(line);
381 while(iss >> element)
384 ll.emplace_back(element);
387 row.emplace_back(element);
390 matrix.push_back(row);
391 row.erase(row.begin(), row.end());
402 std::vector<double> AngularPowerSpectrum_err(m_l.size(), 0.0);
403 double dlogl = log(m_l[1])-log(m_l[0]);
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)));
412 AngularPowerSpectrum_err[j] += pref*pref*fp*fp;
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];
418 return AngularPowerSpectrum_err;
431 for(
size_t i=0; i<m_theta.size(); i++){
437 for(
size_t i=0; i<m_theta.size(); i++){
443 for (
size_t i=0; i<m_theta.size(); i++)
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);
458 case(AngularEstimator::_SphericalArmonic_):
459 measureSphericalArmonic();
462 ErrorCBL(
"Invalid AngularEstimator!",
"cbl::measure::PowerSpectrum_angular::measure",
"AngularPowerSpectrum.cpp" );
473 m_AngularPowerSpectrum.erase(std::begin(m_AngularPowerSpectrum), std::end(m_AngularPowerSpectrum));
476 if (file_correlation_input==
"") {
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);
490 read(dir_correlation_input, file_correlation_input, {1}, {2}, {3}, n_lines_header);
497 m_convert_angular_units(inputUnits);
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]);
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)));
508 AngularPowerSpectrum[j] += pref*fp/m_l[j]/m_l[j];
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));
525 m_l.erase(std::begin(m_l), std::end(m_l));
526 m_AngularPowerSpectrum.erase(std::begin(m_AngularPowerSpectrum), std::end(m_AngularPowerSpectrum));
528 double survey_area=m_survey_area;
529 double sigma0=m_catalogue->nObjects()/survey_area;
530 double fsky=survey_area*_pi_4;
532 std::vector<double> W_ll, AngularPowerSpectrum_err;
533 complex<double> Y_lm;
536 for(
int l=m_l_min; l<m_l_max; l++){
537 double A_lm, C_lm=0, C_l=0, W_l=0;
538 for(
int m=-l; m<l+1; m++){
540 for(
size_t i=0; i<m_catalogue->nObjects(); i++){
545 C_lm=A_lm*A_lm-m_catalogue->nObjects()*_pi_4;
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]); };
554 std::vector<std::vector<double>> integration_limits(2);
563 complex<double> I_lm (I_lm_re, -1.*I_lm_im);
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;
569 W_l+=pow(abs(I_lm),2);
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));
583 m_AngularPowerSpectrum.insert(std::end(m_AngularPowerSpectrum), std::begin(AngularPowerSpectrum_err), std::end(AngularPowerSpectrum_err));
584 if(
isSet(m_Nl)) m_averagePowerSpectrum();
596 double size=(m_l_max-m_l_min)/m_Nl;
597 std::vector<double> AngularPowerSpectrum_error_av(m_Nl, 0);
599 for(
int i=0; i<m_Nl; i++){
600 m_l_av.emplace_back(0);
601 m_AngularPowerSpectrum_av.emplace_back(0);
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];
612 m_AngularPowerSpectrum_av[j]/=size;
613 AngularPowerSpectrum_error_av[j]/=size;
615 m_AngularPowerSpectrum_av.insert(std::end(m_AngularPowerSpectrum_av), std::begin(AngularPowerSpectrum_error_av), std::end(AngularPowerSpectrum_error_av));
625 if(dir_window_input!=
"" && file_window_input!=
"") {
626 read(dir_window_input, file_window_input, {1}, {2}, {2}, 1);
631 std::vector<double> row;
633 for(
size_t k=0; k<m_l.size(); ++k) {
634 for(
size_t j=0; j<m_l.size(); ++j) {
636 for(
size_t i=0; i<m_l.size(); ++i) {
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);
639 R*=(2*m_l[j]+1)*_pi_4;
642 m_RR.emplace_back(row);
643 row.erase(row.begin(), row.end());
#define coutCBL
CBL print message.
Class to manage Legendre polymials computation.
The class PowerSpectrum_angular.
void get_data(std::vector< double > &data) const override
get data for Data1D
double xx(const int i) const override
get the value of x at the i-th bin
void get_error(std::vector< double > &error) const override
get standard deviation for Data1D
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 TwoPointCorrelation1D_angular.
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
static const double pi
: the ratio of a circle's circumference to its diameter
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
The global namespace of the CosmoBolognaLib
double Average(const std::vector< double > vect)
the average of a std::vector
@ _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
void checkIO(const std::ifstream &fin, const std::string file="NULL")
check if an input file can be opened
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
std::vector< double > wigner3j(double l2, double l3, double m1, double m2, double m3)
Wigner symbol.
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
CoordinateUnits
the coordinate units
@ _radians_
angle in radians
@ _arcminutes_
angle in arcminutes
@ _arcseconds_
angle in arcseconds
@ _degrees_
angle in degrees
@ _logarithmic_
logarithmic binning