31 #ifndef GLAMER_particle_halo2_h
32 #define GLAMER_particle_halo2_h
38 #include "simpleTree.h"
40 #include "utilities_slsim.h"
41 #include "lens_halos.h"
66 template<
typename DType =
float >
71 const std::string& simulation_filename
74 ,
double my_inv_area_phys
75 ,PosType mass_particle
76 ,
const COSMOLOGY& cosmo
80 ,
bool recenter =
false
83 ,inv_area(my_inv_area_phys),
Nsmooth(my_Nsmooth),
theta2(theta*theta)
89 readPositionFileASCII(simulation_filename);
92 std::cerr <<
"LensHaloParticles does not accept format of particle data file." << std::endl;
93 throw std::invalid_argument(
"bad format");
95 if(verbose) std::cout <<
" Read " << pp.size() <<
" particles from " << simulation_filename << std::endl;
98 double scale_factor = 1.0/(1 + redshift);
100 p[0] *= scale_factor;
101 p[1] *= scale_factor;
102 p[2] *= scale_factor;
104 setUp(recenter,verbose);
111 ,
double my_inv_area_phys
112 ,PosType mass_particle
113 ,
const COSMOLOGY& cosmo
117 ,
bool recenter =
false
118 ,
bool verbose =
false
120 ,inv_area(my_inv_area_phys),
Nsmooth(my_Nsmooth),
theta2(theta*theta)
123 std::swap(pp, pvector);
124 setUp(recenter,verbose);
135 ,
bool subtract_point=
false,PosType screening = 1
139 ,alpha,kappa,gamma,phi);
142 size_t getN()
const {
return pp.size(); };
149 pp = std::move(h.pp);
150 inv_area = h.inv_area;
155 otree = std::move(h.otree);
158 if(
this == &h)
return *
this;
161 pp = std::move(h.pp);
162 inv_area = h.inv_area;
167 otree = std::move(h.otree);
179 void resetForceAngle(
double theta){
205 static std::vector< LensHaloParticles<DType> >
make(
211 ,
const COSMOLOGY& cosmo
217 ,
bool verbose =
false
219 double r2max= rmax*rmax;
225 std::vector<Point_3d<DType> > tmpdata;
226 GadgetFile<Point_3d<DType> > gadget_file(filename,tmpdata);
227 gadget_file.openFile();
228 gadget_file.readPOS();
229 gadget_file.closeFile();
233 xo[0] = gadget_file.boxl/2;
234 xo[1] = gadget_file.boxl/2;
235 xo[2] = gadget_file.boxl/2;
238 const double a = ulength*1.0e-6/(1 + gadget_file.redshift)/gadget_file.hubble;
244 for(
int i=0; i<6 ; ++i){
245 pos[i].resize(gadget_file.npart[i]);
246 if(gadget_file.npart[i] > 0) ++ntypes;
249 for(
size_t j=0; j<gadget_file.npart[i]; ++j){
250 pos[i][k] = tmpdata[n++];
252 if(dx.length_sqr() < r2max){
259 gadget_file.npart[i] = k;
261 for(
size_t j=0; j<gadget_file.npart[i]; ++j){
262 pos[i][j] = (tmpdata[n++]-xo)*a;
268 std::vector< LensHaloParticles<DType> > halos;
270 for(
int i=0; i<6 ; ++i){
271 if(gadget_file.npart[i] > 0){
274 ,gadget_file.redshift
276 ,gadget_file.masstab[i]*umass/gadget_file.hubble
291 std::cerr <<
"LensHaloParticles does not accept format of particle data file." << std::endl;
292 throw std::invalid_argument(
"bad format");
300 otree->getBoundingBox(p1,p2);
305 std::swap(pp, pvector);
311 std::vector<Point_3d<DType> > pp;
318 std::unique_ptr<OTreeNB<Point_3d<DType>, DType > > otree;
320 void readPositionFileASCII(
const std::string &filename);
330 ,
double my_inv_area_phys
331 ,PosType mass_particle
332 ,
const COSMOLOGY& cosmo
336 ,
bool recenter =
false
337 ,
bool verbose =
false
339 ,inv_area(my_inv_area_phys),
Nsmooth(my_Nsmooth),
theta2(theta*theta)
346 template<
typename DType>
351 long Npoints = pp.size();
361 mcenter /= pp.size();
363 if(verbose) std::cout <<
" Center of mass : " << mcenter << std::endl;
376 LensHalo::mass = particle_mass * pp.size();
377 LensHalo::set_flag_elliptical(
false);
379 if(verbose) std::cout <<
" Creating particle tree ... " << std::endl;
381 otree->build(Nbucket);
382 if(verbose) std::cout <<
"done." << std::endl;
385 template<
typename DType>
391 std::cerr << filename <<
" should have three columns!" << std::endl;
394 std::cerr << filename <<
" Warning! : LensHaloParticles is not using masses." << std::endl;
397 std::ifstream myfile(filename);
400 if (myfile.is_open()){
402 float tmp_mass = 0.0;
403 std::string str,label;
405 while(std::getline(myfile, str)){
406 std::stringstream ss(str);
410 if(label ==
"nparticles"){
421 if(count == 2 )
break;
425 std::cerr <<
"File " << filename <<
" must have the header lines: " << std::endl
426 <<
"# nparticles ****" << std::endl;
427 throw std::runtime_error(
"file reading error");
436 if(str[0] ==
'#')
continue;
437 std::stringstream ss(str);
440 if(!(ss >> pp[row][1])) std::cerr <<
"3 columns are expected in line " << row
441 <<
" of " << filename << std::endl;
442 if(!(ss >> pp[row][2])) std::cerr <<
"3 columns are expected in line " << row
443 <<
" of " << filename << std::endl;
446 }
while(std::getline(myfile, str) && row < Npoints);
449 std::cerr <<
"Number of data rows in " << filename <<
" does not match expected number of particles."
451 throw std::runtime_error(
"file reading error");
454 std::cerr <<
"Unable to open file " << filename << std::endl;
455 throw std::runtime_error(
"file reading error");
458 std::cout << Npoints <<
" particle positions read from file " << filename << std::endl;
461 template<
typename DType>
465 if(theta_x == 0.0 && theta_y == 0.0)
return;
470 cx = cos(theta_x); sx = sin(theta_x);
471 cy = cos(theta_y); sy = sin(theta_y);
473 coord[0][0] = cy; coord[1][0] = -sy*sx; coord[2][0] = cx;
474 coord[0][1] = 0; coord[1][1] = cx; coord[2][1] = sx;
475 coord[0][2] = -sy; coord[1][2] = -cy*sx; coord[2][2] = cy*cx;
481 for(
int j=0;j<3;++j){
482 double tmp2 = p[j] - xo[j];
483 tmp[0] += coord[0][j]*tmp2;
484 tmp[1] += coord[1][j]*tmp2;
485 tmp[2] += coord[2][j]*tmp2;
487 for(
int j=0;j<3;++j) p[j]=tmp[j] + xo[j];
492 for(
int j=0;j<3;++j){
493 tmp[0] += coord[0][j]*(mcenter[j] - xo[j]);
494 tmp[1] += coord[1][j]*(mcenter[j] - xo[j]);
495 tmp[2] += coord[2][j]*(mcenter[j] - xo[j]);
500 otree->build(Nbucket);
503 template<
typename DType>
506 if(xo[0] == 0.0 && xo[1] == 0.0)
return;
510 for(
int j=0;j<3;++j) p[j] += xo[j];
517 otree->build(Nbucket);
523 template<
typename DType =
float >
531 ,
double my_inv_area_phys
532 ,std::vector<DType> Masses
533 ,
const COSMOLOGY& cosmo
537 ,
bool recenter =
false
538 ,
bool verbose =
false
539 ) :
LensHaloParticles<DType>(pvector,redshift,my_inv_area_phys,1,cosmo,my_Nsmooth
540 ,
Nbucket,theta,recenter,verbose)
542 std::swap(masses,Masses);
543 this->otree->calcMoments(masses.data());
548 masses(std::move(h.masses))
553 if (
this == &h)
return *
this;
555 masses = std::move(h.masses);
564 ,
bool subtract_point=
false
565 ,PosType screening = 1
568 this->otree->force2D(xcm,masses.data(),this->Nsmooth,this->theta2,this->inv_area
569 ,alpha,kappa,gamma,phi);
573 std::swap(masses, Mvector);
574 this->otree->calcMoments(masses.data());
577 std::vector<DType> masses;
584 template<
typename DType =
float >
589 const std::string& simulation_filename
592 ,
double my_inv_area_phys
593 ,PosType mass_particle
596 ,
const COSMOLOGY& cosmo
600 ,
bool recenter =
false
601 ,
bool verbose =
false
602 ) :
LensHaloParticles<DType>(simulation_filename,format,redshift,my_inv_area_phys,mass_particle,cosmo,my_Nsmooth,
Nbucket,theta,recenter,verbose)
603 ,xc(x_hole),rhole(hole_radius)
609 ,
double my_inv_area_phys
610 ,PosType mass_particle
613 ,
const COSMOLOGY& cosmo
617 ,
bool recenter =
false
618 ,
bool verbose =
false
619 ) :
LensHaloParticles<DType>(pvector,redshift,my_inv_area_phys,mass_particle,cosmo,my_Nsmooth
620 ,
Nbucket,theta,recenter,verbose),xc(x_hole),rhole(hole_radius)
631 if (
this == &h)
return *
this;
633 xc = std::move(h.xc);
643 ,
bool subtract_point=
false
644 ,PosType screening = 1
649 ,alpha,kappa,gamma,phi);
670 template<
typename DType =
float >
675 const std::string& simulation_filename
678 ,
double my_inv_area_phys
679 ,PosType mass_particle
682 ,
const COSMOLOGY& cosmo
686 ,
bool recenter =
false
687 ,
bool verbose =
false
688 ) :
LensHaloParticles<DType>(simulation_filename,format,redshift,my_inv_area_phys,mass_particle,cosmo,my_Nsmooth,
Nbucket,theta,recenter,verbose)
689 ,length(upper_right-lower_left)
692 this->otree->getBoundingBox(p1,p2);
693 double Dl = cosmo.angDist(redshift);
697 if( lower_left[0] > p1[0]
698 || lower_left[1] > p1[1]
699 || upper_right[0] < p2[0]
700 || upper_right[1] < p2[1]
703 std::cerr <<
"Error : LensParticlesP bounding box does not contain all the particles"
705 std::cerr <<
" angular field " << lower_left <<
" " << upper_right << std::endl;
706 std::cerr <<
" bounding box " << p1 <<
" " << p2 << std::endl;
707 throw std::runtime_error(
"Bad bounding box.");
714 ,
double my_inv_area_phys
715 ,PosType mass_particle
718 ,
const COSMOLOGY& cosmo
722 ,
bool recenter =
false
723 ,
bool verbose =
false
724 ) :
LensHaloParticles<DType>(pvector,redshift,my_inv_area_phys,mass_particle,cosmo,my_Nsmooth
725 ,
Nbucket,theta,recenter,verbose),length(upper_right-lower_left)
729 this->otree->getBoundingBox(p1,p2);
730 double Dl = cosmo.angDist(redshift);
734 if( lower_left[0] > p1[0]
735 || lower_left[1] > p1[1]
736 || upper_right[0] < p2[0]
737 || upper_right[1] < p2[1]
740 std::cerr <<
"Error : LensParticlesP bounding box does not contain all the particles"
742 std::cerr <<
" angular field " << lower_left <<
" " << upper_right << std::endl;
743 std::cerr <<
" bounding box " << p1 <<
" " << p2 << std::endl;
744 throw std::runtime_error(
"Bad bounding box.");
754 if (
this == &h)
return *
this;
765 ,
bool subtract_point=
false
766 ,PosType screening = 1
770 for(
int i = -1 ; i <= 1 ; ++i ){
771 xx[0] = xcm[0] + i*length[0];
772 for(
int j = -1 ; j <= 1 ; ++j ){
773 xx[1] = xcm[1] + j*length[1];
774 this->otree->force2D(xx.x,this->particle_mass,this->Nsmooth,this->theta2,this->inv_area
775 ,alpha,kappa,gamma,phi);
787 template<
typename DType =
float >
795 ,
double my_inv_area_phys
796 ,std::vector<DType> Masses
799 ,
const COSMOLOGY& cosmo
803 ,
bool recenter =
false
804 ,
bool verbose =
false
805 ) :
LensHaloParticles<DType>(pvector,redshift,my_inv_area_phys,1,cosmo,my_Nsmooth
806 ,
Nbucket,theta,recenter,verbose),xc(x_hole),rhole(hole_radius)
808 std::swap(masses,Masses);
809 this->otree->calcMoments(masses.data());
816 masses(std::move(h.masses))
822 if (
this == &h)
return *
this;
824 xc = std::move(h.xc);
826 masses = std::move(h.masses);
835 ,
bool subtract_point=
false
836 ,PosType screening = 1
839 this->otree->force2D_hole(xcm,masses.data(),this->Nsmooth,this->theta2,this->inv_area
841 ,alpha,kappa,gamma,phi);
855 std::vector<DType> masses;
863 template<
typename HType >
869 std::vector<HType> &halo_vector
871 ,
double my_inv_area_phys
872 ,
float hole_radius_angle
873 ,
const COSMOLOGY& cosmo
876 ,
bool recenter =
false
877 ,
bool verbose =
false
879 ,
Nbucket,theta,recenter,verbose),rhole(hole_radius_angle*cosmo.angDist(redshift))
881 std::swap(halo_vector,halos);
882 size_t N = halos.size();
884 double Dl = cosmo.angDist(redshift);
886 for(
size_t i=0 ; i<N ; ++i){
887 p = halos[i].getTheta();
888 this->pp[i][0] = p[0]*Dl;
889 this->pp[i][1] = p[1]*Dl;
891 halos[i].setRsize(1.0e3);
894 this->
setUp(recenter,verbose);
895 this->otree->calcMoments(halos);
901 halos(std::move(h.halos))
906 if (
this == &h)
return *
this;
909 halos = std::move(h.halos);
918 ,
bool subtract_point=
false
919 ,PosType screening = 1
923 this->otree->force2D_halo(xcm,halos.data()
924 ,this->theta2,this->inv_area
926 ,alpha,kappa,gamma,phi);
931 std::swap(halos, hvector);
936 std::vector<HType> halos;
947 template<
typename HType >
953 std::vector<HType> &halo_vector
957 ,
float hole_radius_angle
958 ,
const COSMOLOGY& cosmo
962 ,
bool recenter =
false
963 ,
bool verbose =
false
965 ,0,1,cosmo,my_Nsmooth
966 ,
Nbucket,theta,recenter,verbose),rhole(hole_radius_angle*cosmo.angDist(redshift))
967 ,length(upper_right-lower_left)
969 std::swap(halo_vector,halos);
970 size_t N = halos.size();
972 double Dl = cosmo.angDist(redshift);
975 for(
size_t i=0 ; i<N ; ++i){
976 p = halos[i].getTheta();
977 this->pp[i][0] = p[0]*Dl;
978 this->pp[i][1] = p[1]*Dl;
980 halos[i].setRsize(1.0e3);
984 this->
setUp(recenter,verbose);
985 this->otree->calcMoments(halos);
989 this->otree->getBoundingBox(p1,p2);
992 if( lower_left[0] > p1[0]
993 || lower_left[1] > p1[1]
994 || upper_right[0] < p2[0]
995 || upper_right[1] < p2[1]
998 std::cerr <<
"Error : LensHaloHP bounding box does not contain all the halos"
1000 std::cerr <<
" angular field " << lower_left <<
" " << upper_right << std::endl;
1001 std::cerr <<
" bounding box " << p1 <<
" " << p2 << std::endl;
1002 throw std::runtime_error(
"Bad bounding box.");
1009 halos(std::move(h.halos)),
1015 if (
this == &h)
return *
this;
1018 halos = std::move(h.halos);
1028 ,
bool subtract_point=
false
1029 ,PosType screening = 1
1033 for(
int i = -1 ; i <= 1 ; ++i ){
1034 xx[0] = xcm[0] + i*length[0];
1035 for(
int j = -1 ; j <= 1 ; ++j ){
1036 xx[1] = xcm[1] + j*length[1];;
1039 this->otree->force2D_halo(xx.x,halos.data(),this->theta2,this->inv_area
1041 ,alpha,kappa,gamma,phi);
1048 std::vector<HType> halos;