GLAMERDOC++
Gravitational Lensing Code Library
Loading...
Searching...
No Matches
particle_halo.h
1//
2// particle_halo.h
3// GLAMER
4//
5// Created by bmetcalf on 16/06/15.
6//
7//
8
9#ifndef GLAMER_particle_halo_h
10#define GLAMER_particle_halo_h
11
12#include "geometry.h"
13#include "quadTree.h"
14#include "simpleTree.h"
15#include "particle_types.h"
16#include "utilities_slsim.h"
17#include "lens_halos.h"
18#include "quadTreeHalos.h"
19
39template<typename PType>
41{
42public:
43
44 LensHaloParticles(const std::string& simulation_filename
45 ,SimFileFormat format
46 ,PosType redshift
47 ,int Nsmooth
48 ,const COSMOLOGY& cosmo
49 ,Point_2d theta_rotate
50 ,bool recenter
51 ,bool my_multimass
52 ,double inv_area
53 ,PosType MinPSize=0
54 ,PosType rescale_mass = 1.0
55 ,bool verbose=false
56 );
57
58 LensHaloParticles(std::vector<PType> &pvector
59 ,float redshift
60 ,const COSMOLOGY& cosmo
61 ,Point_2d theta_rotate
62 ,bool recenter
63 ,double my_inv_area
64 ,float MinPSize = 0
65 ,double max_range = -1
66 ,bool verbose=false
67 ):LensHalo(redshift,cosmo),min_size(MinPSize),multimass(true),inv_area(my_inv_area)
68 {
69 Npoints = pvector.size();
70
71 std::swap(pvector,trash_collector);
72 pp = trash_collector.data();
73
74 set_up(redshift,cosmo,theta_rotate,max_range,recenter,verbose);
75 }
76
79 PType *begin
80 ,size_t n
81 ,float redshift
82 ,const COSMOLOGY& cosmo
83 ,Point_2d theta_rotate
84 ,bool recenter
85 ,double my_inv_area
86 ,float MinPSize = 0
87 ,double max_range = -1
88 ,bool verbose=false
89 ):LensHalo(redshift,cosmo),min_size(MinPSize),multimass(true),inv_area(my_inv_area),Npoints(n)
90 {
91 pp = begin;
92 set_up(redshift,cosmo,theta_rotate,max_range,recenter,verbose);
93 }
95
97 mcenter = h.mcenter;
98 densest_point = h.densest_point;
99 trash_collector =std::move(h.trash_collector);
100 pp = trash_collector.data();
101 h.pp = nullptr;
102
103 min_size = h.min_size;
104 multimass = h.multimass;
105 center = h.center;
106 Npoints = h.Npoints;
107 simfile = h.simfile;
108 sizefile = h.sizefile;
109 inv_area = h.inv_area;
110
111 qtree = h.qtree;
112 h.qtree = nullptr;
113 }
115
116
117 void force_halo(double *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,double const *xcm
118 ,bool subtract_point=false,PosType screening = 1.0);
119
120 size_t getN() const { return Npoints; };
121
123 void rotate(Point_2d theta);
124
126 Point_3d<> CenterOfMass(){return mcenter;}
128 Point_3d<> DensestPoint(){return densest_point;}
129
134 static void makeSIE(
135 std::string new_filename
136 ,PosType redshift
137 ,double particle_mass
138 ,double total_mass
139 ,double sigma
140 ,double q
142 );
143
149 PosType redshift
150 ,double particle_mass
151 ,double total_mass
152 ,double sigma
153 ,double q
154 ,int Nneighbors
155 ,COSMOLOGY &cosmo
157
158
159 static void calculate_smoothing(int Nsmooth
160 ,PType *pp
161 ,size_t Npoints
162 ,bool verbose = false);
163
164 void readPositionFileASCII(const std::string &filename);
165
166 static void writeSizes(const std::string &filename
167 ,int Nsmooth
168 ,const PType *pp
169 ,size_t Npoints
170 );
171
172 static bool readSizesFile(const std::string &filename
173 ,PType * pp
174 ,size_t Npoints
175 ,int Nsmooth
176 ,PosType min_size);
177
178 friend class MakeParticleLenses;
179
180protected:
181 // constructure for derived classes
182 LensHaloParticles(float redshift
183 ,const COSMOLOGY& cosmo
184 ): LensHalo(redshift,cosmo){}
185
186 // This constructor is really only for use by MakeParticleLenses. It does not take
187 // possession of the data and so they will not be deleted on destruction
188 LensHaloParticles(PType *pdata
189 ,size_t Nparticles
190 ,float redshift
191 ,const COSMOLOGY& cosmo
192 ,Point_2d theta_rotate
193 ,bool recenter
194 ,double my_inv_area
195 ,bool verbose = false
196 ):LensHalo(redshift,cosmo),pp(pdata),min_size(0),multimass(true),Npoints(Nparticles),inv_area(my_inv_area)
197 {
198 set_up(redshift,cosmo,theta_rotate,-1,recenter,verbose);
199 }
200
201 void rotate_particles(PosType theta_x,PosType theta_y);
202 static void smooth_(TreeSimple<PType> *tree3d,PType *xp,size_t N,int Nsmooth);
203 void assignParams(InputParams& params);
204
205 Point_3d<> mcenter;
206 Point_3d<> densest_point;
207
208 PType *pp;
209 std::vector<PType> trash_collector;
210
211 PosType min_size; // minimum allowed size
212 bool multimass;
213
215
216 size_t Npoints;
217 PosType inv_area;
218
219 std::string simfile;
220 std::string sizefile;
221
222
224 void set_up(float redshift,const COSMOLOGY& cosmo,Point_2d theta_rotate,double max_range,bool recenter,bool verbose);
225};
226
227template<typename PType>
228LensHaloParticles<PType>::LensHaloParticles(const std::string& simulation_filename
229 ,SimFileFormat format
230 ,PosType redshift
231 ,int Nsmooth
232 ,const COSMOLOGY& cosmo
233 ,Point_2d theta_rotate
234 ,bool recenter
235 ,bool my_multimass
236 ,double my_inv_area
237 ,PosType MinPSize
238 ,PosType massscaling
239 ,bool verbose
240 )
241:LensHalo(redshift,cosmo),min_size(MinPSize),multimass(my_multimass),simfile(simulation_filename),inv_area(my_inv_area)
242{
243
244 LensHalo::setZlens(redshift,cosmo);
246 LensHalo::set_flag_elliptical(false);
247
248 //stars_N = 0;
249 //stars_implanted = false;
250
251 Rmax = 1.0e3;
252 LensHalo::setRsize(Rmax);
253
254 switch (format) {
256 readPositionFileASCII(simulation_filename);
257 break;
258 default:
259 std::cerr << "LensHaloParticles does not accept format of particle data file." << std::endl;
260 throw std::invalid_argument("bad format");
261 }
262
263 sizefile = simfile + "." + std::to_string(Nsmooth) + "sizes";
264
265 if(!readSizesFile(sizefile,pp,Npoints,Nsmooth,min_size)){
266
267 // calculate sizes
268 calculate_smoothing(Nsmooth,pp,Npoints);
269
270 // save result to a file for future use
271 writeSizes(sizefile,Nsmooth,pp,Npoints);
272 //for(size_t i=0; i<Npoints ; ++i) if(sizes[i] < min_size) sizes[i] = min_size;
273 for(size_t i=0; i<Npoints ; ++i) if(pp[i].size() < min_size) pp[i].Size = min_size;
274 }
275
276 double min_s = pp[0].Size;
277 size_t smallest_part = 0;
278 for(size_t i = 1 ; i<Npoints ; ++i){
279 if(pp[i].Size < min_s){
280 min_s = pp[i].Size;
281 smallest_part = i;
282 }
283 pp[i].Mass *= massscaling;
284 }
285
286 densest_point[0] = pp[smallest_part].x[0];
287 densest_point[1] = pp[smallest_part].x[1];
288 densest_point[2] = pp[smallest_part].x[2];
289
290
291 // convert from comoving to physical coordinates
292 PosType scale_factor = 1/(1+redshift);
293 mcenter *= 0.0;
294 PosType max_mass = 0.0,min_mass = HUGE_VALF,mass=0;
295 for(size_t i=0;i<Npoints;++i){
296 pp[i][0] *= scale_factor;
297 pp[i][1] *= scale_factor;
298 pp[i][2] *= scale_factor;
299
300 mcenter[0] += pp[i][0]*pp[multimass*i].mass();
301 mcenter[1] += pp[i][1]*pp[multimass*i].mass();
302 mcenter[2] += pp[i][2]*pp[multimass*i].mass();
303
304 mass += pp[multimass*i].mass();
305
306 max_mass = (pp[multimass*i].mass() > max_mass) ? pp[multimass*i].mass() : max_mass;
307 min_mass = (pp[multimass*i].mass() < min_mass) ? pp[multimass*i].mass() : min_mass;
308 }
309 LensHalo::setMass(mass);
310
311 mcenter /= mass;
312
313 if(verbose) std::cout << " Particle mass range : " << min_mass << " to " << max_mass << " ratio of : " << max_mass/min_mass << std::endl;
314
315
316 if(recenter){
317 PosType r2,r2max=0;
318 for(size_t i=0;i<Npoints;++i){
319 pp[i][0] -= mcenter[0];
320 pp[i][1] -= mcenter[1];
321 pp[i][2] -= mcenter[2];
322
323 r2 = pp[i][0]*pp[i][0] + pp[i][1]*pp[i][1] + pp[i][2]*pp[i][2];
324 if(r2 > r2max) r2max = r2;
325 }
326
327 LensHalo::setRsize( sqrt(r2max) );
328
329 densest_point -= mcenter;
330
331 mcenter *= 0;
332 }
333
334 // rotate positions
335 rotate_particles(theta_rotate[0],theta_rotate[1]);
336
337 qtree = new TreeQuadParticles<PType>(pp,Npoints,-1,-1,inv_area,20);
338
339}
340
341template<typename PType>
343 float redshift
344 ,const COSMOLOGY& cosmo
345 ,Point_2d theta_rotate
346 ,double max_range
347 ,bool recenter
348 ,bool verbose
349){
350
351 //LensHalo::setZlens(redshift);
352 //LensHalo::setCosmology(cosmo);
353 LensHalo::set_flag_elliptical(false);
354
355 //stars_N = 0;
356 //stars_implanted = false;
357
358 Rmax = 1.0e100;
359 LensHalo::setRsize(Rmax);
360
361 double min_s = pp[0].Size;
362 size_t smallest_part = 0;
363 for(size_t i =0 ; i<Npoints ; ++i){
364 if(pp[i].Size < min_s){
365 min_s = pp[i].Size;
366 smallest_part = i;
367 }
368 }
369
370 densest_point[0] = pp[smallest_part].x[0];
371 densest_point[1] = pp[smallest_part].x[1];
372 densest_point[2] = pp[smallest_part].x[2];
373
374 // convert from comoving to physical coordinates
375 //PosType scale_factor = 1/(1+redshift);
376 mcenter *= 0.0;
377 PosType max_mass = 0.0,min_mass = HUGE_VALF,mass=0;
378 for(size_t i=0;i<Npoints;++i){
379
380 mcenter[0] += pp[i][0]*pp[i].mass();
381 mcenter[1] += pp[i][1]*pp[i].mass();
382 mcenter[2] += pp[i][2]*pp[i].mass();
383
384 mass += pp[i].mass();
385
386 max_mass = (pp[i].mass() > max_mass) ? pp[i].mass() : max_mass;
387 min_mass = (pp[i].mass() < min_mass) ? pp[i].mass() : min_mass;
388 }
389 LensHalo::setMass(mass);
390
391 mcenter /= mass;
392
393 if(verbose) std::cout << " Particle mass range : " << min_mass << " to " << max_mass << " ratio of : " << max_mass/min_mass << std::endl;
394
395 if(recenter){
396 PosType r2,r2max=0;
397 for(size_t i=0;i<Npoints;++i){
398 pp[i][0] -= mcenter[0];
399 pp[i][1] -= mcenter[1];
400 pp[i][2] -= mcenter[2];
401
402 r2 = pp[i][0]*pp[i][0] + pp[i][1]*pp[i][1] + pp[i][2]*pp[i][2];
403 if(r2 > r2max) r2max = r2;
404
405 densest_point -= mcenter;
406
407 mcenter *= 0;
408 }
409
410 LensHalo::setRsize( sqrt(r2max) );
411 }
412
413 // rotate positions
414 rotate_particles(theta_rotate[0],theta_rotate[1]);
415
416 qtree = new TreeQuadParticles<PType>(pp,Npoints,-1,-1,inv_area,20,0.1,false,max_range);
417}
418
419
420
421template<typename PType>
423 delete qtree;
424}
425
426template<typename PType>
427void LensHaloParticles<PType>::force_halo(double *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi
428 ,double const *xcm
429 ,bool subtract_point,PosType screening){
430 qtree->force2D_recur(xcm,alpha,kappa,gamma,phi);
431
432 alpha[0] *= -1;
433 alpha[1] *= -1;
434}
435
437template<typename PType>
439 rotate_particles(theta[0],theta[1]);
440 delete qtree;
441
442 qtree = new TreeQuadParticles<ParticleType<float> >(pp,Npoints,-1,-1,inv_area,20);
443}
444
452template<typename PType>
454 ){
455
456 int ncoll = Utilities::IO::CountColumns(filename);
457 if(!multimass && ncoll != 3 ){
458 std::cerr << filename << " should have three columns!" << std::endl;
459 }
460 if(multimass && ncoll != 4 ){
461 std::cerr << filename << " should have four columns!" << std::endl;
462 }
463
464 std::ifstream myfile(filename);
465
466 //size_t Npoints = 0;
467
468 // find number of particles
469
470 if (myfile.is_open()){
471
472 float tmp_mass = 0.0;
473 std::string str,label;
474 int count =0;
475 while(std::getline(myfile, str)){
476 std::stringstream ss(str);
477 ss >> label;
478 if(label == "#"){
479 ss >> label;
480 if(label == "nparticles"){
481 ss >> Npoints;
482 ++count;
483 }
484 if(!multimass){
485 if(label == "mass"){
486 ss >> tmp_mass;
487 ++count;
488 }
489 }
490 }else break;
491 if(multimass && count == 1 ) break;
492 if(!multimass && count == 2 ) break;
493 }
494
495 if(count == 0){
496 if(multimass) std::cerr << "File " << filename << " must have the header lines: " << std::endl
497 << "# nparticles ****" << std::endl << "# mass ****" << std::endl;
498 if(!multimass) std::cerr << "File " << filename << " must have the header lines: " << std::endl
499 << "# nparticles ****" << std::endl;
500 throw std::runtime_error("file reading error");
501 }
502
503 trash_collector.resize(Npoints); // this is here just to make sure this is deleted
504 pp = trash_collector.data();
505 //xp = Utilities::PosTypeMatrix(Npoints,3);
506 //if(multimass) masses.resize(Npoints);
507 //else masses.push_back(tmp_mass);
508
509 size_t row = 0;
510
511 // read in particle positions
512 if(!multimass){
513 while(std::getline(myfile, str) && row < Npoints){
514 if(str[0] == '#') continue; //for comments
515 std::stringstream ss(str);
516
517 ss >> pp[row][0];
518 if(!(ss >> pp[row][1])) std::cerr << "3 columns are expected in line " << row
519 << " of " << filename << std::endl;
520 if(!(ss >> pp[row][2])) std::cerr << "3 columns are expected in line " << row
521 << " of " << filename << std::endl;
522
523 row++;
524 }
525 }else{
526 while(std::getline(myfile, str) && row < Npoints){
527 if(str[0] == '#') continue; //for comments
528 std::stringstream ss(str);
529
530 ss >> pp[row][0];
531 if(!(ss >> pp[row][1])) std::cerr << "4 columns are expected in line " << row
532 << " of " << filename << std::endl;
533 if(!(ss >> pp[row][2])) std::cerr << "4 columns are expected in line " << row
534 << " of " << filename << std::endl;
535 if(!(ss >> pp[row].Mass)) std::cerr << "4 columns are expected in line " << row
536 << " of " << filename << std::endl;
537
538 row++;
539 }
540 }
541
542 if(row != Npoints){
543 std::cerr << "Number of data rows in " << filename << " does not match expected number of particles."
544 << std::endl;
545 throw std::runtime_error("file reading error");
546 }
547 }else{
548 std::cerr << "Unable to open file " << filename << std::endl;
549 throw std::runtime_error("file reading error");
550 }
551
552 std::cout << Npoints << " particle positions read from file " << filename << std::endl;
553
554}
555
556template<typename PType>
557bool LensHaloParticles<PType>::readSizesFile(const std::string &filename
558 ,PType * pp
559 ,size_t Npoints
560 ,int Nsmooth
561 ,PosType min_size){
562
563 std::ifstream myfile(filename);
564
565 // find number of particles
566
567 PosType min=HUGE_VALF,max=0.0;
568 if (myfile.is_open()){
569
570 std::string str,label;
571 int count =0;
572 size_t Ntmp;
573 int NStmp;
574 while(std::getline(myfile, str)){
575 std::stringstream ss(str);
576 ss >> label;
577 if(label == "#"){
578 ss >> label;
579 if(label == "nparticles"){
580 ss >> Ntmp;
581 if(Ntmp != Npoints){
582 std::cerr << "Number of particles in " << filename << " does not match expected number" << std::endl;
583 throw std::runtime_error("file reading error");
584 }
585 ++count;
586 }
587 if(label == "nsmooth"){
588 ss >> NStmp;
589 if(NStmp != Nsmooth) return false;
590 ++count;
591 }
592
593 }else break;
594 if(count == 2) break;
595 }
596
597 if(count != 2){
598 std::cerr << "File " << filename << " must have the header lines: " << std::endl
599 << "# nparticles ****" << std::endl;
600 throw std::runtime_error("file reading error");
601 }
602
603 size_t row = 0;
604
605 std::cout << "reading in particle sizes from " << filename << "..." << std::endl;
606
607 // read in particle sizes
608 while(std::getline(myfile, str)){
609 if(str[0] == '#') continue; //for comments
610 std::stringstream ss(str);
611
612 ss >> pp[row].Size;
613 if(min_size > pp[row].size() ) pp[row].Size = min_size;
614 min = min < pp[row].size() ? min : pp[row].size();
615 max = max > pp[row].size() ? max : pp[row].size();
616 row++;
617 }
618
619 if(row != Npoints){
620 std::cerr << "Number of data rows in " << filename << " does not match expected number of particles."
621 << std::endl;
622 throw std::runtime_error("file reading error");
623 }
624 }else{
625 return false;
626 }
627
628 std::cout << Npoints << " particle sizes read from file " << filename << std::endl;
629 std::cout << " maximun particle sizes " << max << " minimum " << min << " Mpc" << std::endl;
630
631 return true;
632}
633
634template<typename PType>
635void LensHaloParticles<PType>::rotate_particles(PosType theta_x,PosType theta_y){
636
637 if(theta_x == 0.0 && theta_y == 0.0) return;
638
639 PosType coord[3][3];
640 PosType cx,cy,sx,sy;
641
642 cx = cos(theta_x); sx = sin(theta_x);
643 cy = cos(theta_y); sy = sin(theta_y);
644
645 coord[0][0] = cy; coord[1][0] = -sy*sx; coord[2][0] = cx;
646 coord[0][1] = 0; coord[1][1] = cx; coord[2][1] = sx;
647 coord[0][2] = -sy; coord[1][2] = -cy*sx; coord[2][2] = cy*cx;
648
649 //PosType tmp[3];
650 Point_3d<> tmp;
651 int j;
652 // rotate particle positions */
653 for(size_t i=0;i<Npoints;++i){
654 tmp *= 0;
655 for(j=0;j<3;++j){
656 tmp[0] += coord[0][j]*pp[i][j];
657 tmp[1] += coord[1][j]*pp[i][j];
658 tmp[2] += coord[2][j]*pp[i][j];
659 }
660 for(j=0;j<3;++j) pp[i][j]=tmp[j];
661 }
662
663 // rotate center of mass
664 tmp *= 0.0;
665 for(j=0;j<3;++j){
666 tmp[0] += coord[0][j]*mcenter[j];
667 tmp[1] += coord[1][j]*mcenter[j];
668 tmp[2] += coord[2][j]*mcenter[j];
669 }
670 mcenter = tmp;
671
672 // rotate center of mass
673 tmp *= 0.0;
674 for(j=0;j<3;++j){
675 tmp[0] += coord[0][j]*densest_point[j];
676 tmp[1] += coord[1][j]*densest_point[j];
677 tmp[2] += coord[2][j]*densest_point[j];
678 }
679 densest_point = tmp;
680}
681
682template<typename PType>
683void LensHaloParticles<PType>::calculate_smoothing(int Nsmooth,PType *pp
684 ,size_t Npoints
685 ,bool verbose
686 ){
687
688 int nthreads = Utilities::GetNThreads();
689
690 if(verbose) std::cout << "Calculating smoothing of particles ..." << std::endl
691 << Nsmooth << " neighbors. If there are a lot of particles this could take a while." << std::endl;
692
693 time_t to,t;
694 time(&to);
695
696 // make 3d tree of particle postions
697 TreeSimple<PType> tree3d(pp,Npoints,2*Nsmooth,3,true);
698 // find distance to nth neighbour for every particle
699 if(Npoints < 1000){
700 //IndexType neighbors[Nsmooth];
701 for(size_t i=0;i<Npoints;++i){
702 pp[i].Size = tree3d.NNDistance(&pp[i][0],Nsmooth + 1);
703 }
704 }else{
705 size_t chunksize = Npoints/nthreads;
706 std::vector<std::thread> thr(nthreads);
707
708 size_t N;
709 for(int ii = 0; ii < nthreads ;++ii){
710 if(ii == nthreads - 1){
711 N = Npoints - ii*chunksize;
712 }else N = chunksize;
713
714 thr[ii] = std::thread(LensHaloParticles<PType>::smooth_,&tree3d
715 ,&(pp[ii*chunksize]),N,Nsmooth);
716 }
717 for(int ii = 0; ii < nthreads ;++ii) thr[ii].join();
718 }
719 time(&t);
720 if(verbose) std::cout << "done in " << difftime(t,to) << " secs" << std::endl;
721}
722
723template<typename PType>
724void LensHaloParticles<PType>::smooth_(TreeSimple<PType> *tree3d,PType *pp,size_t N,int Nsmooth){
725
726 //IndexType neighbors[Nsmooth];
727 for(size_t i=0;i<N;++i){
728 pp[i].Size = tree3d->NNDistance(&(pp[i][0]),Nsmooth + 1);
729 }
730}
731
732
733template<typename PType>
734void LensHaloParticles<PType>::writeSizes(const std::string &filename,int Nsmooth
735 ,const PType *pp,size_t Npoints
736 ){
737
738 std::ofstream myfile(filename);
739
740 // find number of particles
741
742 if (myfile.is_open()){
743
744 std::cout << "Writing particle size information to file " << filename << " ...." << std::endl;
745
746 myfile << "# nparticles " << Npoints << std::endl;
747 myfile << "# nsmooth " << Nsmooth << std::endl;
748 for(size_t i=0;i<Npoints;++i){
749 myfile << pp[i].Size << std::endl;
750 if(!myfile){
751 std::cerr << "Unable to write to file " << filename << std::endl;
752 throw std::runtime_error("file writing error");
753 }
754 }
755
756 std::cout << "done" << std::endl;
757
758 }else{
759 std::cerr << "Unable to write to file " << filename << std::endl;
760 throw std::runtime_error("file writing error");
761 }
762}
763
764template<typename PType>
766 std::string new_filename
767 ,PosType redshift
768 ,double particle_mass
769 ,double total_mass
770 ,double sigma
771 ,double q
773 ){
774
775 size_t Npoints = total_mass/particle_mass;
776 PosType Rmax = (1+redshift)*total_mass*Grav*lightspeed*lightspeed/sigma/sigma/2;
777 Point_3d<> point;
778 double qq = sqrt(q);
779
780 std::ofstream datafile;
781 datafile.open(new_filename);
782
783 datafile << "# nparticles " << Npoints << std::endl;
784 datafile << "# mass " << particle_mass << std::endl;
785 // create particles
786 for(size_t i=0; i< Npoints ;++i){
787 point[0] = ran.gauss();
788 point[1] = ran.gauss();
789 point[2] = ran.gauss();
790
791 point *= Rmax*ran()/point.length();
792
793 point[0] *= qq;
794 point[1] /= qq;
795
796 datafile << point[0] << " " << point[1] << " "
797 << point[2] << " " << std::endl;
798
799 }
800
801 datafile.close();
802}
803
804 template<typename PType>
806 PosType redshift
807 ,double particle_mass
808 ,double total_mass
809 ,double sigma
810 ,double q
811 ,int Nneighbors
812 ,COSMOLOGY &cosmo
814 ){
815
816 size_t Npoints = total_mass/particle_mass;
817 PosType Rmax = total_mass*Grav*lightspeed*lightspeed/sigma/sigma/2;
818
819 double qq = sqrt(q);
820
821 std::cout << "making SIE LensHaloParticles..." << std::endl;
822 std::cout << "# nparticles " << Npoints << std::endl;
823 std::cout << "# mass " << particle_mass << std::endl;
824
825 std::vector<ParticleTypeSimple> parts(Npoints);
826 // create particles
827 for(auto &p : parts){
828 p[0] = ran.gauss();
829 p[1] = ran.gauss();
830 p[2] = ran.gauss();
831
832 double s = Rmax*ran()/sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2] );
833 p[0] *= s;
834 p[1] *= s;
835 p[2] *= s;
836
837 p[0] *= qq;
838 p[1] /= qq;
839
840 p.Mass = particle_mass;
841 }
842
844
845 return LensHaloParticles<ParticleTypeSimple>(parts,redshift
846 ,cosmo,Point_2d(0,0),false,0);
847 }
848
849template<typename PType>
851 if(this == &h) return *this;
852 LensHalo::operator=(std::move(h));
853 mcenter = h.mcenter;
854 densest_point = h.densest_point;
855 trash_collector =std::move(h.trash_collector);
856 pp = h.pp; // note: this depends on std:move keeping the pointer valid if it is constructed with the public constructor
857 h.pp = nullptr;
858
859 min_size = h.min_size;
860 multimass = h.multimass;
861 center = h.center;
862 Npoints = h.Npoints;
863 simfile = h.simfile;
864 sizefile = h.sizefile;
865 inv_area = h.inv_area;
866
867 qtree = h.qtree;
868 h.qtree = nullptr;
869
870 return *this;
871}
872
873
965
966public:
967
969 std::vector<LensHaloParticles<ParticleType<float> > *> halos;
970
972 std::vector<size_t> getnp(){return nparticles;}
973
975 std::vector<float> getmp(){return masses;}
976
978 double sim_redshift(){return z_original;}
979
980 MakeParticleLenses(const std::string &filename
981 ,SimFileFormat format
982 ,int Nsmooth
983 ,bool recenter
984 //,bool compensate=false /// if true a negative mass will be included so that the region wil have zero massl
985 ,bool ignore_type_in_smoothing = false
986 );
987
988 MakeParticleLenses(const std::string &filename
989 ,bool recenter
990 //,bool compensate=false /// if true a negative mass will be included so that the region wil have zero massl
991 );
992
994 for(auto p : halos) delete p;
995 }
996
998
999 void Recenter(Point_3d<> x);
1000
1001 void CreateHalos(const COSMOLOGY &cosmo,double redshift,double inv_area);
1002
1004 void radialCut(Point_3d<> center,double radius);
1006 void cylindricalCut(Point_2d center,double radius);
1007
1009 Point_3d<> getCenterOfMass() const{return cm;}
1010
1012 Point_3d<> densest_particle() const;
1013
1015 void getBoundingBox(Point_3d<> &Xmin,Point_3d<> &Xmax) const{
1016 Xmin = bbox_ll;
1017 Xmax = bbox_ur;
1018 }
1019
1020 double getZoriginal(){return z_original;}
1021
1022 std::vector<ParticleType<float> > data;
1023private:
1024 const std::string filename;
1025 int Nsmooth;
1026 //bool compensate;
1027
1028 Point_3d<> bbox_ll; // minumum coordinate values of particles
1029 Point_3d<> bbox_ur; // maximim coordinate values of particles
1030
1031 double z_original = -1;
1032 std::vector<size_t> nparticles;
1033 std::vector<float> masses;
1034 Point_3d<> cm;
1035
1036 // write a glamB format file with all required particle data
1037 static void writeSizesB(const std::string &filename
1038 ,std::vector<ParticleType<float> > &pv
1039 ,int Nsmooth,std::vector<size_t> numbytype,double redshift){
1040
1041 assert(numbytype.size() == 6);
1042 size_t ntot = pv.size();
1043 std::ofstream myfile(filename, std::ios::out | std::ios::binary);
1044 if(!myfile.write((char*)&Nsmooth,sizeof(int))){
1045 std::cerr << "Unable to write to file " << filename << std::endl;
1046 throw std::runtime_error("file writing error");
1047 }else{
1048 myfile.write((char*)&ntot,sizeof(size_t));
1049 myfile.write((char*)(numbytype.data()),sizeof(size_t)*6);
1050 myfile.write((char*)&redshift,sizeof(double));
1051 myfile.write((char*)(pv.data()),sizeof(ParticleType<float>)*ntot);
1052 }
1053 }
1054
1055 // read a glamB format file
1056 static bool readSizesB(const std::string &filename
1057 ,std::vector<ParticleType<float> > &pv
1058 ,int &Nsmooth,std::vector<size_t> &numbytype,double &redshift){
1059
1060 numbytype.resize(6);
1061 size_t ntot = pv.size();
1062 std::ifstream myfile(filename, std::ios::in | std::ios::binary);
1063 if(!myfile.read((char*)&Nsmooth,sizeof(int))){
1064 return false;
1065 }else{
1066 myfile.read((char*)&ntot,sizeof(size_t));
1067 myfile.read((char*)(numbytype.data()),sizeof(size_t)*6);
1068 myfile.read((char*)&redshift,sizeof(double));
1069 pv.resize(ntot);
1070 myfile.read((char*)(pv.data()),sizeof(ParticleType<float>)*ntot);
1071 }
1072 return true;
1073 }
1074
1075 // Read particle from Gadget-2 format file
1076 bool readGadget2(bool ignore_type);
1077
1078 // Reads particles from first 4 columns of csv file
1079 bool readCSV(int columns_used);
1080
1081#ifdef ENABLE_HDF5
1082 bool readHDF5();
1083#endif
1084
1085};
1086
1091template<typename HType>
1092class LensHaloHalos : public LensHalo
1093{
1094public:
1095
1096 LensHaloHalos(std::vector<HType> &pvector
1097 ,float redshift
1098 ,const COSMOLOGY& cosmo
1099 ,float inv_area
1100 ,float my_theta_force=0.1
1101 ,bool mu_periodic_buffer = false
1102 ,bool verbose=false
1103 ):LensHalo(redshift,cosmo),inv_area(inv_area),theta_force(my_theta_force),periodic_buffer(mu_periodic_buffer)
1104 {
1105 std::swap(pvector,trash_collector);
1106 Nhalos = trash_collector.size();
1107 vpp.resize(Nhalos);
1108
1109 for(size_t ii = 0 ; ii < Nhalos ; ++ii) vpp[ii] = &trash_collector[ii];
1110 set_up(redshift,cosmo,verbose);
1111 }
1112 ~LensHaloHalos();
1113
1114 LensHaloHalos(LensHaloHalos &&h):LensHalo(std::move(h)){
1115 mcenter = h.mcenter;
1116 trash_collector =std::move(h.trash_collector);
1117 vpp = std::move(h.vpp);
1118
1119 center = h.center;
1120 Nhalos = h.Nhalos;
1121
1122 qtree = h.qtree;
1123 h.qtree = nullptr;
1124
1125 inv_area = h.inv_area;
1126 }
1127 LensHaloHalos & operator=(LensHaloHalos &&h);
1128
1129
1130 void force_halo(double *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi
1131 ,double const *xcm
1132 ,bool subtract_point=false,PosType screening = 1.0);
1133
1134 size_t getN() const { return Nhalos; };
1135
1137 Point_2d CenterOfMass(){return mcenter;}
1138
1139protected:
1140 Point_2d mcenter;
1141 double inv_area;
1142
1143 std::vector<HType *> vpp;
1144 std::vector<HType> trash_collector;
1145
1147
1148 size_t Nhalos;
1149
1150 float theta_force;
1151 bool periodic_buffer;
1152
1153 TreeQuadHalos<HType> * qtree;
1154
1155 void set_up(float redshift,const COSMOLOGY& cosmo,bool verbose);
1156};
1157
1158template<typename HType>
1159void LensHaloHalos<HType>::set_up(
1160 float redshift
1161 ,const COSMOLOGY& cosmo
1162 ,bool verbose
1163){
1164
1165 LensHalo::set_flag_elliptical(false);
1166
1167 Rmax = 1.0e100; // ????
1168 LensHalo::setRsize(Rmax);
1169
1170 // convert from comoving to physical coordinates
1171 //PosType scale_factor = 1/(1+redshift);
1172 mcenter *= 0.0;
1173 PosType max_mass = 0.0,min_mass = HUGE_VALF,mass=0;
1174
1175 for(HType &h : trash_collector){
1176
1177 mcenter[0] += h[0]*h.get_mass();
1178 mcenter[1] += h[1]*h.get_mass();
1179
1180 mass += h.get_mass();
1181
1182 max_mass = (h.get_mass() > max_mass) ? h.get_mass() : max_mass;
1183 min_mass = (h.get_mass() < min_mass) ? h.get_mass() : min_mass;
1184 }
1185 LensHalo::setMass(mass);
1186
1187 mcenter /= mass;
1188
1189 if(verbose) std::cout << " Particle mass range : " << min_mass << " to " << max_mass << " ratio of : " << max_mass/min_mass << std::endl;
1190
1191 qtree = new TreeQuadHalos<HType>(vpp.data(),Nhalos,inv_area,5,theta_force,periodic_buffer);
1192}
1193
1194template<typename HType>
1195LensHaloHalos<HType>::~LensHaloHalos(){
1196 delete qtree;
1197}
1198
1199template<typename HType>
1200void LensHaloHalos<HType>::force_halo(double *alpha,KappaType *kappa
1201 ,KappaType *gamma,KappaType *phi
1202 ,double const *xcm
1203 ,bool subtract_point,PosType screening){
1204 qtree->force2D(xcm,alpha,kappa,gamma,phi);
1205
1206 // ?????
1207 alpha[0] *= -1;
1208 alpha[1] *= -1;
1209}
1210
1211template<typename HType>
1212LensHaloHalos<HType> & LensHaloHalos<HType>::operator=(LensHaloHalos<HType> &&h){
1213 if(this == &h) return *this;
1214 LensHalo::operator=(std::move(h));
1215 mcenter = h.mcenter;
1216
1217 trash_collector =std::move(h.trash_collector);
1218 vpp = std::move(h.vpp); // note: this depends on std:move keeping the pointer valid if it is constructed with the public constructor
1219
1220 center = h.center;
1221 Nhalos = h.Nhalos;
1222
1223 qtree = h.qtree;
1224 h.qtree = nullptr;
1225
1226 return *this;
1227}
1228
1229#endif
The cosmology and all the functions required to calculated quantities based on the cosmology.
Definition cosmo.h:52
Structure for reading and writing parameters to and from a parameter file as well as a container for ...
Definition InputParams.h:99
A base class for all types of lensing "halos" which are any mass distribution that cause lensing.
Definition lens_halos.h:56
void setZlens(PosType my_zlens, const COSMOLOGY &cosmo)
set redshift
Definition lens_halos.h:137
LensHalo & operator=(const LensHalo &h)
Definition lens_halos.cpp:169
virtual void setCosmology(const COSMOLOGY &cosmo)
used for elliptical NFWs only, in that case get_switch_flag==true
Definition lens_halos.h:163
A class that represents the lensing by a collection of simulation particles.
Definition particle_halo.h:41
Point_3d DensestPoint()
get the densistt point in input coordinates
Definition particle_halo.h:128
LensHaloParticles(float redshift, const COSMOLOGY &cosmo)
Definition particle_halo.h:182
LensHaloParticles(PType *pdata, size_t Nparticles, float redshift, const COSMOLOGY &cosmo, Point_2d theta_rotate, bool recenter, double my_inv_area, bool verbose=false)
Definition particle_halo.h:188
static LensHaloParticles< ParticleTypeSimple > SIE(PosType redshift, double particle_mass, double total_mass, double sigma, double q, int Nneighbors, COSMOLOGY &cosmo, Utilities::RandomNumbers_NR &ran)
This is a test static function that makes a truncated SIE out of particles and puts it into a file in...
Definition particle_halo.h:805
LensHaloParticles(PType *begin, size_t n, float redshift, const COSMOLOGY &cosmo, Point_2d theta_rotate, bool recenter, double my_inv_area, float MinPSize=0, double max_range=-1, bool verbose=false)
this constructor does not take possession of the particles
Definition particle_halo.h:78
void readPositionFileASCII(const std::string &filename)
Reads number of particle and particle positons into Npoint and xp from a ASCII file.
Definition particle_halo.h:453
Point_3d CenterOfMass()
get current center of mass in input coordinates
Definition particle_halo.h:126
void rotate(Point_2d theta)
rotate the simulation around the origin of the simulation coordinates, (radians)
Definition particle_halo.h:438
static void makeSIE(std::string new_filename, PosType redshift, double particle_mass, double total_mass, double sigma, double q, Utilities::RandomNumbers_NR &ran)
This is a test static function that makes a truncated SIE out of particles and puts it into a file in...
Definition particle_halo.h:765
void set_up(float redshift, const COSMOLOGY &cosmo, Point_2d theta_rotate, double max_range, bool recenter, bool verbose)
Definition particle_halo.h:342
LensHaloParticles(const std::string &simulation_filename, SimFileFormat format, PosType redshift, int Nsmooth, const COSMOLOGY &cosmo, Point_2d theta_rotate, bool recenter, bool my_multimass, double inv_area, PosType MinPSize=0, PosType rescale_mass=1.0, bool verbose=false)
Definition particle_halo.h:228
LensHaloParticles(std::vector< PType > &pvector, float redshift, const COSMOLOGY &cosmo, Point_2d theta_rotate, bool recenter, double my_inv_area, float MinPSize=0, double max_range=-1, bool verbose=false)
Definition particle_halo.h:58
A class for constructing LensHalos from particles in a data file.
Definition particle_halo.h:964
Point_3d getCenterOfMass() const
returns the original center of mass of all the particles
Definition particle_halo.h:1009
std::vector< size_t > getnp()
returns number of particles of each type
Definition particle_halo.h:972
double sim_redshift()
returns original redshift of snapshot, redshifts of the halos can be changed
Definition particle_halo.h:978
MakeParticleLenses(const std::string &filename, SimFileFormat format, int Nsmooth, bool recenter, bool ignore_type_in_smoothing=false)
Definition particle_lens.cpp:22
std::vector< LensHaloParticles< ParticleType< float > > * > halos
vector of LensHalos, one for each type of particle type
Definition particle_halo.h:969
void cylindricalCut(Point_2d center, double radius)
remove particles that are beyond cylindrical radius (Mpc/h) of center
Definition particle_lens.cpp:497
void CreateHalos(const COSMOLOGY &cosmo, double redshift, double inv_area)
Definition particle_lens.cpp:153
std::vector< float > getmp()
returns mass of particles of each type, if 0 they can have different masses
Definition particle_halo.h:975
void Recenter(Point_3d<> x)
recenter the particles to 3d point in physical Mpc/h units If the halos have already been created the...
Definition particle_lens.cpp:139
void radialCut(Point_3d<> center, double radius)
remove particles that are beyond radius (Mpc/h) from center
Definition particle_lens.cpp:447
Point_3d densest_particle() const
returns the location of the densest particle in (Mpc/h)
Definition particle_lens.cpp:480
void getBoundingBox(Point_3d<> &Xmin, Point_3d<> &Xmax) const
return the maximum and minimum coordinates of the particles in each dimension in for the original sim...
Definition particle_halo.h:1015
TreeQuadParticles is a class for calculating the deflection, kappa and gamma by tree method.
Definition quadTree.h:47
A C++ class wrapper for the bianary treeNB used in the Nbody force calculation, but also useful for g...
Definition simpleTree.h:86
T NNDistance(T *ray, int Nneighbors) const
Finds the nearest N neighbors and puts their index numbers in an array, also returns the distance to ...
Definition simpleTree.h:483
represents a point in spherical coordinates, theta = 0 is equator
Definition geometry.h:30
This is a class for generating random numbers. It simplifies and fool proofs initialization and allow...
Definition utilities_slsim.h:1059
PosType gauss()
generates a Gaussian distributed number with unit variance by polar Box-Muller transform
Definition utilities_slsim.h:1068
int CountColumns(std::string filename, char comment_char='#', char deliniator=' ')
Count the number of columns in a ASCII data file.
Definition utilities.cpp:614
int GetNThreads()
returns the compiler variable N_THREADS that is maximum number of threads to be used.
Definition utilities.cpp:553
SimFileFormat
Definition particle_types.h:32
@ ascii
the original ascii GLAMER format.
Class for representing points or vectors in 2 dimensions. Not that the dereferencing operator is over...
Definition point.h:48