54 using namespace catalogue;
64 const double start_time = omp_get_wtime();
65 shared_ptr<Catalogue> tracer_cat, random_cat;
66 vector<Catalogue> displacement_catalogue(n_rec);
67 vector<vector<unsigned int>> randoms;
69 CatalogueChainMesh ChainMesh_tracers;
70 CatalogueChainMesh ChainMesh_randoms;
72 if (algorithm==VoidAlgorithm::_LaZeVo_) {
78 int rndd = (int)chrono::steady_clock::now().time_since_epoch().count()%1000000;
80 if (random_catalogue.
nObjects()==0) {
81 random_catalogue =
Catalogue(RandomType::_createRandom_box_, tracer_catalogue, 1., 10, cosm,
false, 10., {}, {}, {}, 10, rndd);
85 coutCBL <<
"* * * Reading random catalogue of " << random_catalogue.
nObjects() <<
" objects provides by user * * *" << endl << endl;
86 random_catalogue = random_catalogue;
89 coutCBL <<
"* * * Reading random catalogue of " << random_catalogue.
nObjects() <<
" objects provides by user * * *" << endl;
93 diff <<
" more objects than the tracers catalogue. The number will be equalized by the function catalogue::equalize_random_LC" << endl << endl;
95 -diff <<
" less objects than the tracers catalogue. The number will be equalized by the function catalogue::equalize_random_LC" << endl << endl;
102 unsigned int num_objects = tracer_cat->nObjects();
103 std::vector<unsigned int> index_tracer_cat(num_objects);
104 std::iota (std::begin(index_tracer_cat), std::end(index_tracer_cat), 0);
106 coutCBL <<
"* * * ChainMesh setting * * *" << flush;
107 vector<Var> variables = {Var::_X_, Var::_Y_, Var::_Z_};
108 ChainMesh_tracers = CatalogueChainMesh(variables, cellsize, tracer_cat);
109 ChainMesh_randoms = CatalogueChainMesh(variables, cellsize, random_cat);
110 cout << endl << endl;
112 unsigned int N_near_obj = 3*3*4*
par::pi;
113 coutCBL <<
"* * * Searching close particles * * * " << flush;
114 vector<vector<unsigned int>> near_part = ChainMesh_tracers.N_nearest_objects_cat(N_near_obj);
115 randoms.resize(n_rec, vector<unsigned int>(num_objects));
116 for(
int rec=0; rec<n_rec; rec++) {
117 std::iota (std::begin(randoms[rec]), std::end(randoms[rec]), 0);
118 auto time = (
long int)chrono::steady_clock::now().time_since_epoch().count()%1000000;
119 std::shuffle(randoms[rec].begin(), randoms[rec].end(), default_random_engine(time));
122 cout << endl << endl;
123 coutCBL <<
"* * * Setting starting configuration * * *" << flush;
125 double dist = 4*tracer_cat->mps();
126 double minX = ChainMesh_tracers.lim()[0][0]+dist/10, maxX = ChainMesh_tracers.lim()[0][1]-dist/10;
127 double minY = ChainMesh_tracers.lim()[1][0]+dist/10, maxY = ChainMesh_tracers.lim()[1][1]-dist/10;
128 double minZ = ChainMesh_tracers.lim()[2][0]+dist/10, maxZ = ChainMesh_tracers.lim()[2][1]-dist/10;
130 for (
int rec=0; rec<n_rec; rec++) {
132 auto timeS = ((
long int)chrono::steady_clock::now().time_since_epoch().count())%1000000;
137 CatalogueChainMesh ChM_tracer_copy = ChainMesh_tracers;
138 CatalogueChainMesh ChM_random_copy = ChainMesh_randoms;
139 unsigned int removed = 0;
141 while (removed < num_objects) {
142 vector<double> pos = {randX(), randY(), randZ()};
143 vector<unsigned int> close=ChM_tracer_copy.Close_objects(pos, dist);
144 unsigned int tr_to_rmv = std::min(100, (
int)close.size());
146 vector<unsigned int> close_random = ChM_random_copy.N_nearest_objects(pos, close.size());
147 std::random_device dev;
148 std::mt19937 rng(dev());
149 removed += tr_to_rmv;
150 while (tr_to_rmv > 0) {
151 std::uniform_int_distribution<std::mt19937::result_type> dist(0, tr_to_rmv-1);
152 int rnd1 = dist(rng), rnd2 = dist(rng);
153 randoms[rec][close[rnd1]] = close_random[rnd2];
154 ChM_tracer_copy.deletePart(close[rnd1]);
155 ChM_random_copy.deletePart(close_random[rnd2]);
156 close.erase(close.begin()+rnd1);
157 close_random.erase(close_random.begin()+rnd2);
164 cout << endl << endl;
166 coutCBL <<
"* * * Performing the iterations * * *" << endl << endl;
168 for (
int rec=0; rec<n_rec; rec++) {
169 auto index_tracer_cat_copy = index_tracer_cat;
171 unsigned int n_iter = 0;
173 while (ratio > threshold) {
175 auto time = (
long int)chrono::steady_clock::now().time_since_epoch().count()%1000000;
176 std::shuffle(index_tracer_cat_copy.begin(), index_tracer_cat_copy.end(), default_random_engine(time));
177 std::random_device dev;
178 std::mt19937 rng(dev());
179 std::uniform_int_distribution<std::mt19937::result_type> dist(1,N_near_obj-1);
180 vector<bool> index_bool(num_objects,
false), used(num_objects,
false);
182 #pragma omp parallel num_threads(omp_get_max_threads())
184 #pragma omp for schedule(static)
185 for (
size_t i=0; i<num_objects; i++) {
186 vector<unsigned int> H(4), R_def(4), R(4), R_copy(4);
187 unsigned int rand1 = dist(rng), rand2 = dist(rng), rand3 = dist(rng);
188 while (rand1 == rand2 || rand1==rand3 || rand2 == rand3) {
192 if (used[near_part[index_tracer_cat_copy[i]][0]] ==
false && used[near_part[index_tracer_cat_copy[i]][rand1]] ==
false &&
193 used[near_part[index_tracer_cat_copy[i]][rand2]] ==
false && used[near_part[index_tracer_cat_copy[i]][rand3]] ==
false) {
194 used[near_part[index_tracer_cat_copy[i]][0]] =
true;
195 used[near_part[index_tracer_cat_copy[i]][rand1]] =
true;
196 used[near_part[index_tracer_cat_copy[i]][rand2]] =
true;
197 used[near_part[index_tracer_cat_copy[i]][rand3]] =
true;
198 H[0]=near_part[index_tracer_cat_copy[i]][0];
199 H[1]=near_part[index_tracer_cat_copy[i]][rand1];
200 H[2]=near_part[index_tracer_cat_copy[i]][rand2];
201 H[3]=near_part[index_tracer_cat_copy[i]][rand3];
202 R[0]=randoms[rec][H[0]];
203 R[1]=randoms[rec][H[1]];
204 R[2]=randoms[rec][H[2]];
205 R[3]=randoms[rec][H[3]];
208 double dist_min = 1000000.;
212 for (
size_t j=0; j<R.size(); j++)
213 dist +=
cbl::Euclidean_distance(tracer_cat->xx(H[j]), random_cat->xx(R[j]), tracer_cat->yy(H[j]), random_cat->yy(R[j]), tracer_cat->zz(H[j]), random_cat->zz(R[j]));
215 if (dist < dist_min) {
219 }
while(std::next_permutation(R.begin(), R.end()));
221 if(R_def != R_copy) index_bool[i] =
true;
222 for (
size_t j=0; j<4; j++) randoms[rec][H[j]] = R_def[j];
232 unsigned int changed_couples = count(index_bool.begin(), index_bool.end(),
true);
233 ratio = (double)changed_couples/num_objects;
234 if (n_iter%1==0)
coutCBL <<
"Realisation " << rec+1 <<
" of " << n_rec <<
" | " <<
"Iteration N°: " << n_iter <<
" - " <<
"current ratio: " << fixed << setprecision(6) << ratio <<
" - " <<
235 "final threshold: " << threshold <<
"\r"; cout.flush();
241 vector<shared_ptr<cbl::catalogue::Object>> displ_catalogue_object;
242 for (
size_t ii = 0; ii<randoms[rec].size(); ii++) {
243 cbl::comovingCoordinates displacement_values = {random_cat->xx(randoms[rec][ii])-tracer_cat->xx(ii), random_cat->yy(randoms[rec][ii])-tracer_cat->yy(ii), random_cat->zz(randoms[rec][ii])-tracer_cat->zz(ii)};
244 auto tracer_displ = make_shared<cbl::catalogue::Halo>(displacement_values);
245 displ_catalogue_object.push_back(tracer_displ);
248 displacement_catalogue[rec].add_objects(displ_catalogue_object);
250 if (rec == n_rec-1 && print[0]) {
251 string name =
"../output/Displacement";
254 ofstream fout_displ(name.c_str());
255 cout << endl << endl;
257 coutCBL <<
"Writing the displacement field in " << name <<
" ..." << endl;
259 for (
unsigned int i=0; i<num_objects; i++) {
260 fout_displ.precision(7);
261 fout_displ << tracer_cat->xx(i) <<
" " << tracer_cat->yy(i) <<
" " << tracer_cat->zz(i) <<
" "
262 << random_cat->xx(randoms[rec][i]) <<
" " << random_cat->yy(randoms[rec][i]) <<
" " << random_cat->zz(randoms[rec][i]) <<
" "
263 << displacement_catalogue[rec].xx(i) <<
" " << displacement_catalogue[rec].yy(i) <<
" " << displacement_catalogue[rec].zz(i) << endl;
265 fout_displ.clear(); fout_displ.close();
269 else if (algorithm==VoidAlgorithm::_Exact_) {
273 randoms.resize(n_rec, vector<unsigned int>(tracer_catalogue.
nObjects()));
274 for(
int rec=0; rec<n_rec; rec++)
275 std::iota (std::begin(randoms[rec]), std::end(randoms[rec]), 0);
278 ErrorCBL (
"Random catalogue must have the same dimension of the tracers one!",
"Catalogue",
"VoidCatalogue.cpp");
282 vector<Var> variables = {Var::_X_, Var::_Y_, Var::_Z_};
284 coutCBL <<
"* * * ChainMesh setting * * *" << endl;
285 ChainMesh_tracers = CatalogueChainMesh(variables, cellsize, tracer_cat);
287 for (
int rec=0; rec<n_rec; rec++) {
288 vector<shared_ptr<cbl::catalogue::Object>> displ_catalogue_object;
289 for (
size_t ii = 0; ii<randoms[rec].size(); ii++) {
290 cbl::comovingCoordinates displacement_values = {random_cat->xx(randoms[rec][ii])-tracer_cat->xx(ii), random_cat->yy(randoms[rec][ii])-tracer_cat->yy(ii), random_cat->zz(randoms[rec][ii])-tracer_cat->zz(ii)};
291 auto tracer_displ = make_shared<cbl::catalogue::Halo>(displacement_values);
292 displ_catalogue_object.push_back(tracer_displ);
294 displacement_catalogue[rec].add_objects(displ_catalogue_object);
296 if (rec == n_rec-1 && print[0]) {
297 string name = dir_output +
"Displacement";
300 ofstream fout_displ(name.c_str());
303 coutCBL <<
"Writing the displacement field in " << name <<
" ..." << endl;
304 for (
size_t i=0; i<tracer_cat->nObjects(); i++) {
305 fout_displ.precision(7);
306 fout_displ << tracer_cat->xx(i) <<
" " << tracer_cat->yy(i) <<
" " << tracer_cat->zz(i) <<
" "
307 << random_cat->xx(randoms[rec][i]) <<
" " << random_cat->yy(randoms[rec][i]) <<
" " << random_cat->zz(randoms[rec][i]) <<
" "
308 << displacement_catalogue[rec].xx(i) <<
" " << displacement_catalogue[rec].yy(i) <<
" " << displacement_catalogue[rec].zz(i) << endl;
310 fout_displ.clear(); fout_displ.close();
314 else ErrorCBL (
"algorithm type is not correct!",
"Catalogue",
"VoidCatalogue.cpp");
320 vector<shared_ptr<Catalogue>> displ_cat(n_rec);
321 for (
int i=0; i<n_rec; i++) displ_cat[i] = make_shared<Catalogue>(
Catalogue(move(displacement_catalogue[i])));
323 double density = tracer_cat->numdensity();
324 double step = step_size*tracer_cat->mps();
326 vector<double> min_X = {random_cat->Min(Var::_X_)-0.5*step, tracer_cat->Min(Var::_X_)-0.5*step};
327 vector<double> min_Y = {random_cat->Min(Var::_Y_)-0.5*step, tracer_cat->Min(Var::_Y_)-0.5*step};
328 vector<double> min_Z = {random_cat->Min(Var::_Z_)-0.5*step, tracer_cat->Min(Var::_Z_)-0.5*step};
329 vector<double> min = {*min_element(min_X.begin(),min_X.end()), *min_element(min_Y.begin(),min_Y.end()), *min_element(min_Z.begin(),min_Z.end())};
330 vector<double> max_X = {random_cat->Max(Var::_X_)+0.5*step, tracer_cat->Max(Var::_X_)+0.5*step};
331 vector<double> max_Y = {random_cat->Max(Var::_Y_)+0.5*step, tracer_cat->Max(Var::_Y_)+0.5*step};
332 vector<double> max_Z = {random_cat->Max(Var::_Z_)+0.5*step, tracer_cat->Max(Var::_Z_)+0.5*step};
333 vector<double> max = {*max_element(max_X.begin(),max_X.end()), *max_element(max_Y.begin(),max_Y.end()), *max_element(max_Z.begin(),max_Z.end())};
335 vector<double> cells(3);
336 for(
unsigned int&& i=0; i<3; i++) cells[i] = (max[i]-min[i])/step;
337 unsigned int nCells = *max_element(cells.begin(), cells.end());
339 for(
unsigned int&& i=0; i<3; i++) {
340 min[i] = min_copy[i] - (step*nCells-(max[i]-min_copy[i]))/2;
341 max[i] = max[i] + (step*nCells-(max[i]-min_copy[i]))/2;
344 vector<vector<vector<double>>> Divergence(nCells, vector<vector<double>>(nCells, vector<double>(nCells, 0.)));
347 coutCBL <<
"* * * Estimation of the Divergence field * * *" << endl;
350 for (
int rec=0; rec<n_rec; rec++) {
351 for (
size_t i=0; i<randoms[rec].size(); i++) {
352 vector<vector<double>> coord_part(2);
353 coord_part[0] = {random_cat->xx(randoms[rec][i]), random_cat->yy(randoms[rec][i]), random_cat->zz(randoms[rec][i])};
354 coord_part[1] = {tracer_cat->xx(i), tracer_cat->yy(i), tracer_cat->zz(i)};
355 vector<double> displ = {displ_cat[rec]->xx(i), displ_cat[rec]->yy(i), displ_cat[rec]->zz(i)};
356 vector<vector<unsigned int>> inds(2, vector<unsigned int>(3));
357 for (
unsigned int&& j=0; j<3; j++) {
358 inds[0][j] = (coord_part[0][j]-min[j])/step;
359 inds[1][j] = (coord_part[1][j]-min[j])/step;
361 if(inds[0]!=inds[1]) {
362 for (
unsigned int part=0; part<2; part++) {
363 for (
unsigned int j=0; j<2; j++) {
364 for (
unsigned int&& k=0; k<3; k++) {
365 double t = (coord_part[0][k]-((inds[part][k]+j)*step+min[k]))/displ[k];
366 if (t>=0. && t<=1.) {
367 vector<double> inters_coord = {coord_part[0][0]-(coord_part[0][0]-coord_part[1][0])*t,
368 coord_part[0][1]-(coord_part[0][1]-coord_part[1][1])*t,
369 coord_part[0][2]-(coord_part[0][2]-coord_part[1][2])*t};
370 if ((k==0) ? (inters_coord[1]>(inds[part][1]*step+min[1]) && inters_coord[1] <= ((inds[part][1]+1)*step+min[1]) &&
371 inters_coord[2]>(inds[part][2]*step+min[2]) && inters_coord[2] <= ((inds[part][2]+1)*step+min[2])) :
372 ((k==1) ? (inters_coord[0]>(inds[part][0]*step+min[0]) && inters_coord[0] <= ((inds[part][0]+1)*step+min[0]) &&
373 inters_coord[2]>(inds[part][2]*step+min[2]) && inters_coord[2] <= ((inds[part][2]+1)*step+min[2])) :
374 (inters_coord[0]>(inds[part][0]*step+min[0]) && inters_coord[0] <= ((inds[part][0]+1)*step+min[0]) &&
375 inters_coord[1]>(inds[part][1]*step+min[1]) && inters_coord[1] <= ((inds[part][1]+1)*step+min[1])))) {
376 if(part==0) Divergence[inds[part][0]][inds[part][1]][inds[part][2]] -= abs(displ[k])/step;
377 if(part==1) Divergence[inds[part][0]][inds[part][1]][inds[part][2]] += abs(displ[k])/step;
388 coutCBL <<
"* * * Smoothing * * *" << endl << endl;
390 vector<vector<vector<double>>> Divergence_copy = Divergence;
392 for (
unsigned int i=0; i<nCells; i++) {
393 for (
unsigned int j=0; j<nCells; j++) {
394 for (
unsigned int k=0; k<nCells; k++) {
395 Divergence_copy[i][k][j] = Divergence_copy[i][k][j]/n_rec;
400 for (
unsigned int i=0; i<nCells; i++) {
401 for (
unsigned int j=0; j<nCells; j++) {
402 for (
unsigned int k=0; k<nCells; k++) {
405 for (
int ii=std::max(0,(
int)i-1); ii<std::min((
int)nCells,(
int)i+2); ii++) {
406 for (
int jj=std::max(0,(
int)j-1); jj<std::min((
int)nCells,(
int)j+2); jj++) {
407 for (
int kk=std::max(0,(
int)k-1); kk<std::min((
int)nCells,(
int)k+2); kk++) {
408 double ex = exp(-pow(
Euclidean_distance(min[0]+step*(i+0.5), min[0]+step*(ii+0.5), min[1]+step*(j+0.5), min[1]+step*(jj+0.5), min[2]+step*(k+0.5), min[2]+step*(kk+0.5)),2)/(2*step*step));
410 sum_div += Divergence_copy[ii][jj][kk]*ex;
414 Divergence[i][j][k] = sum_div/sum;
419 coutCBL <<
"* * * Identification of voids * * *" << endl << endl;
423 name = dir_output +
"Divergence";
426 ofstream fout_divergence(name.c_str());
428 fout_divergence.precision(7);
430 coutCBL <<
"Writing the divergence field in " << name <<
" ..." << endl;
433 for (
unsigned int&& i=0; i<nCells; i++)
434 for (
unsigned int&& j=0; j<nCells; j++)
435 for (
unsigned int&& k=0; k<nCells; k++) {
436 fout_divergence << min[0]+step*(i+0.5) <<
" " << min[1]+step*(j+0.5) <<
" " << min[2]+step*(k+0.5) <<
" " << Divergence[i][j][k] << endl;
438 fout_divergence.clear(); fout_divergence.close();
441 vector<vector<double>> coord_locmin(6);
442 unsigned int cont = 0;
444 for (
unsigned int&& i=0; i<nCells; i++) {
445 for (
unsigned int&& j=0; j<nCells; j++) {
446 for (
unsigned int&& k=0; k<nCells; k++) {
447 if (Divergence[i][j][k] < 0. && i>0 && j>0 && k>0 && i<nCells-1 && j<nCells-1 && k<nCells-1) {
448 bool control =
false;
450 vector<double> num(3, 0.), den(3, 0.);
451 vector<int> delta_cells(3, 0);
453 for (
unsigned int&& ii=i-1; ii<i+2; ii++) {
454 delta_cells[0] = i-ii;
455 for (
unsigned int&& jj=j-1; jj<j+2; jj++) {
456 delta_cells[1] = j-jj;
457 for (
unsigned int&& kk=k-1; kk<k+2; kk++) {
458 delta_cells[2] = k-kk;
459 if (!(ii==i && jj==j && kk==k)) {
460 sum += Divergence[ii][jj][kk];
461 for (
unsigned int&& t=0; t<3; t++) {
462 num[t] += Divergence[ii][jj][kk]*(step/
Euclidean_distance((
double)i, (
double)ii, (
double)j, (
double)jj, (
double)k, (
double)kk))*delta_cells[t];
463 den[t] += abs(Divergence[ii][jj][kk]);
465 if (Divergence[ii][jj][kk]<=Divergence[i][j][k] || Divergence[ii][jj][kk] > 0.) {
471 if (control==
true)
break;
473 if (control==
true)
break;
475 if (control==
false) {
476 coord_locmin[0].push_back(min[0]+step*(i+0.5)+num[0]/den[0]);
477 coord_locmin[1].push_back(min[1]+step*(j+0.5)+num[1]/den[1]);
478 coord_locmin[2].push_back(min[2]+step*(k+0.5)+num[2]/den[2]);
479 coord_locmin[3].push_back(i);
480 coord_locmin[4].push_back(j);
481 coord_locmin[5].push_back(k);
488 coutCBL <<
"Number of cells with negative divergence: " << cont << endl;
490 if (coord_locmin[0].size()==0)
491 ErrorCBL(
"No local minima found!",
"Catalogue",
"VoidCatalogue.cpp");
493 coutCBL <<
"Number of voids: " << coord_locmin[0].size() << endl << endl;
499 coutCBL <<
"* * * Voids rescaling * * *" << endl << endl;
501 vector<double> radius_void(coord_locmin[0].size());
502 double mps = tracer_cat->mps();
504 for (
size_t i=0; i<coord_locmin[0].size(); i++) {
505 vector<double> pos = {coord_locmin[0][i], coord_locmin[1][i], coord_locmin[2][i]};
506 vector<unsigned int> close = ChainMesh_tracers.Close_objects(pos, 5*mps);
507 vector<double> distances(close.size());
508 for (
size_t j=0; j<close.size(); j++) distances[j] =
Euclidean_distance(tracer_cat->xx(close[j]), pos[0], tracer_cat->yy(close[j]), pos[1],
509 tracer_cat->zz(close[j]), pos[2]);
510 std::sort(close.begin(), close.end());
511 vector<vector<double>> data(2, vector<double>(distances.size()));
513 for (
size_t i=0; i<distances.size()-1; i++) {
514 data[0][i]=(distances[i]+distances[i+1])/2;
518 data[0][distances.size()-1] = 2*data[0][distances.size()-2] - data[0][distances.size()-3];
519 data[1][distances.size()-1] = distances.size()/(
volume_sphere(data[0][distances.size()-1])*density);
522 while (!(data[1][N] < threshold && data[1][N+1] > threshold) && N < distances.size()-1) N++;
523 if (N == distances.size()-1) {
524 int index = distances.size()-1;
525 double max = data[1][distances.size()-1];
526 for (
size_t k=0; k<data[0].size()-1; k++) {
527 if (data[1][k]<data[1][k+1] && data[1][k+1]<0.5 && data[1][k+1]>max) {
532 radius_void[i] =
interpolated(0.5, {0., data[1][index]}, {0., data[0][index]},
"Linear");
535 radius_void[i] =
interpolated(0.5, {data[1][N], data[1][N+1]}, {data[0][N], data[0][N+1]},
"Linear");
539 name = dir_output+
"Voids_";
541 ofstream fout_voids(name.c_str());
542 for(
int&& i=0; i<(int)radius_void.size(); ++i) fout_voids << coord_locmin[0][i] <<
" " << coord_locmin[1][i] <<
" " << coord_locmin[2][i] <<
" " << radius_void[i] << endl;
543 fout_voids.clear(); fout_voids.close();
550 double seconds = omp_get_wtime() - start_time;
553 coutCBL <<
"Time spent to compute: " << seconds <<
" seconds " << endl ;
554 coutCBL <<
"Time spent to compute: " << seconds/60. <<
" minutes " << endl ;
555 coutCBL <<
"Time spent to compute: " << seconds/3600. <<
" hours " << endl ;
561 cbl::catalogue::Catalogue::Catalogue (
const VoidAlgorithm algorithm,
Catalogue tracer_catalogue,
Catalogue random_catalogue,
const std::string dir_output,
const std::string output,
const double cellsize,
const cbl::cosmology::Cosmology cosm,
const std::vector<double> RA_range,
const std::vector<double> DEC_range,
const int n_rec,
const double step_size,
const double threshold)
564 ErrorCBL (
"Still not avaiable!",
"Catalogue",
"VoidCatalogue.cpp");
565 cout << dir_output << output << cellsize << n_rec << step_size << threshold << cosm.
Omega_baryon() << endl;
568 if (algorithm == VoidAlgorithm::_LaZeVo_) cout <<
"aaa" << endl;
569 if (tracer_catalogue.
nObjects() == 0) cout <<
"aaa" << endl;
570 if (random_catalogue.
nObjects() == 0) cout <<
"aaa" << endl;
1330 const double start_time = omp_get_wtime();
1338 coutCBL <<
"Voids in the initial Catalogue: " << nObjects() << endl << endl;
1339 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1342 coutCBL <<
"Removed voids: " << endl;
1344 double spurious_time = omp_get_wtime();
1345 if (initial_radius) {
1346 vector<bool> remove(nObjects(),
false);
1347 for (
size_t i=0; i<nObjects(); i++)
1348 if (radius(i) < delta_r[0] || delta_r[1] < radius(i)) remove[i] =
true;
1350 remove_objects(remove);
1351 cout <<
"\t r_min-r_max criterion: " << count(remove.begin(), remove.end(),
true) << endl;
1354 compute_centralDensity(tracers_catalogue, ChM, threshold);
1355 coutCBL <<
"Voids in the Catalogue: " << nObjects() << endl;
1356 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1357 coutCBL <<
"Time spent by the spurious voids-checking procedure: " << fixed << setprecision(3) << omp_get_wtime()-spurious_time <<
" seconds" << endl;
1366 double density = tracers_catalogue->numdensity();
1371 double rescaling_time = omp_get_wtime();
1373 vector<bool> remove(nObjects(),
false), bad_rescale(nObjects(),
false);
1375 double min_X = tracers_catalogue->Min(Var::_X_), max_X = tracers_catalogue->Max(Var::_X_);
1376 double min_Y = tracers_catalogue->Min(Var::_Y_), max_Y = tracers_catalogue->Max(Var::_Y_);
1377 double min_Z = tracers_catalogue->Min(Var::_Z_), max_Z = tracers_catalogue->Max(Var::_Z_);
1379 #pragma omp parallel num_threads(omp_get_max_threads())
1381 #pragma omp for ordered schedule(dynamic)
1382 for (
size_t j=0; j<nObjects(); j++) {
1383 vector<double> temp_val = {3.*radius(j), xx(j)-min_X, max_X-xx(j), yy(j)-min_Y, max_Y-yy(j), zz(j)-min_Z, max_Z-zz(j), delta_r[1]};
1384 double value = *min_element(temp_val.begin(), temp_val.end());
1388 vector<double> radii;
1389 for (
auto&& k : close) {
1390 double distance = Catalogue::distance(j, tracers_catalogue->catalogue_object(k));
1391 if (distance < value) radii.emplace_back(distance);
1393 if (radii.size() < 3) {
1395 bad_rescale[j] =
true;
1399 std::sort(radii.begin(), radii.end());
1400 vector<vector<double>> data(2, vector<double>(radii.size()));
1401 for (
size_t i=0; i<radii.size()-1; i++) {
1402 data[0][i] = (radii[i]+radii[i+1])*0.5;
1405 data[0][radii.size()-1] = 2*data[0][radii.size()-2] - data[0][radii.size()-3];
1406 data[1][radii.size()-1] = radii.size()/(
volume_sphere(data[0][radii.size()-1])*density);
1408 unsigned int N = std::round(radii.size()*0.25);
1409 bool expand =
false;
1412 while (!(data[1][N-2] < threshold && data[1][N-1] > threshold))
1420 N = std::round(radii.size()*0.25);
1421 while (!(data[1][N-2] < threshold && data[1][N-1] > threshold))
1422 if (N<radii.size()-2) N++;
1428 if (N<=2 or N>=radii.size()-2) {
1430 bad_rescale[j] =
true;
1434 new_radius =
interpolated(threshold, {data[1][N-1], data[1][N]}, {data[0][N-1], data[0][N]},
"Linear");
1436 if (new_radius > 0) set_var(j, Var::_Radius_, new_radius);
1439 bad_rescale[j] =
true;
1445 N = std::round(radii.size()*0.25);
1449 while (!(data[1][N-2] < 0.5 && data[1][N-1] > 0.5))
1457 N = std::round(radii.size()*0.25);
1458 while (!(data[1][N-2] < 0.5 && data[1][N-1] > 0.5))
1459 if (N<radii.size()-2)
1467 if (N<=2 or N>=radii.size()-2) {
1469 bad_rescale[j] =
true;
1473 new_generic =
interpolated(threshold, {data[1][N-1], data[1][N]}, {data[0][N-1], data[0][N]},
"Linear");
1475 if (new_generic > 0) set_var(j, Var::_Generic_, new_generic);
1478 bad_rescale[j] =
true;
1484 remove_objects(remove);
1485 coutCBL <<
"Removed voids:" << endl;
1486 cout <<
"\t Bad rescaled: " << count(bad_rescale.begin(), bad_rescale.end(),
true) << endl;
1488 vector<bool> remove_outofrange(nObjects(),
false);
1489 for (
size_t ii = 0; ii<nObjects(); ii++)
1490 if (radius(ii) < delta_r[0] || delta_r[1] < radius(ii))
1491 remove_outofrange[ii] =
true;
1493 remove_objects(remove_outofrange);
1494 cout <<
"\t Out of range ["+
conv(delta_r[0],
par::fDP2)+
","+
conv(delta_r[1],
par::fDP2)+
"]: " << count(remove_outofrange.begin(), remove_outofrange.end(),
true) << endl;
1496 compute_densityContrast(tracers_catalogue, ChM, ratio);
1498 coutCBL <<
"Time spent by the rescaling procedure: " << omp_get_wtime()-rescaling_time <<
" seconds" << endl;
1502 coutCBL <<
"Voids in the Catalogue: " << nObjects() << endl;
1503 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1513 double ol_time = omp_get_wtime();
1514 vector<bool> remove(nObjects(),
false);
1515 vector<double> criteriumOrder(nObjects());
1518 if (ol_criterion == Var::_CentralDensity_) {
1519 criteriumOrder = var(Var::_CentralDensity_);
1520 criterium =
"central density";
1522 else if (ol_criterion == Var::_DensityContrast_) {
1523 criteriumOrder = var(Var::_DensityContrast_);
1524 criterium =
"density contrast";
1527 else ErrorCBL(
"allowed overlap criteria are '_CentralDensity_' or '_DensityContrast_' .",
"Catalogue",
"VoidCatalogue.cpp");
1529 std::vector<int> indices(nObjects(), 0);
1530 std::iota(indices.begin(), indices.end(), 0);
1531 std::sort(indices.begin(), indices.end(), [&](
int A,
int B)
1532 ->
bool {return (ol_criterion == Var::_CentralDensity_) ? criteriumOrder[A] < criteriumOrder[B] : criteriumOrder[A] > criteriumOrder[B];});
1535 coutCBL <<
"Catalogue ordered according to the " << criterium << endl << endl;
1536 coutCBL <<
"* * * Generating ChainMesh for void centres * * *" << endl;
1540 for (
size_t i=0; i<nObjects(); i++) {
1542 vector<long> close = ChM_voids.
close_objects(coordinate(i));
1543 std::sort(close.begin(), close.end());
1544 for (
auto && j : close) {
1546 double distance = Catalogue::distance(i, catalogue_object(j));
1547 if (distance < radius(i)+radius(j) && (
long)i!=j) {
1548 if (ol_criterion == Var::_CentralDensity_) {
1549 if (centralDensity(i) < centralDensity(j)) {
1552 else if (centralDensity(i) > centralDensity(j)) {
1556 else if (centralDensity(i) == centralDensity(j)) {
1557 if (densityContrast(i) < densityContrast(j)) {
1565 else if (ol_criterion == Var::_DensityContrast_) {
1566 if (densityContrast(i) < densityContrast(j)) {
1570 else if (densityContrast(i) > densityContrast(j))
1572 else if (densityContrast(i) == densityContrast(j)) {
1573 if (centralDensity(i) < centralDensity(j))
1587 remove_objects(remove);
1590 coutCBL <<
"Voids removed to avoid overlap: " << count(remove.begin(), remove.end(),
true) << endl;
1591 coutCBL <<
"Time spent by the overlap-checking procedure: " << omp_get_wtime()-ol_time <<
" seconds" << endl;
1595 coutCBL <<
"Voids in the final Catalogue: " << nObjects() << endl;
1596 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1599 coutCBL <<
"Total time spent: " << omp_get_wtime()-start_time <<
" seconds \n" << endl;
1607 const double start_time = omp_get_wtime();
1615 coutCBL <<
"Voids in the initial Catalogue: " << nObjects() << endl << endl;
1616 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1619 coutCBL <<
"Removed voids: " << endl;
1621 if (initial_radius) {
1622 vector<bool> remove(nObjects(),
false);
1623 for (
size_t i=0; i<nObjects(); i++)
1624 if (radius(i) < delta_r[0] || delta_r[1] < radius(i)) remove[i] =
true;
1626 remove_objects(remove);
1627 cout <<
"\t r_min-r_max criterion: " << count(remove.begin(), remove.end(),
true) << endl;
1630 compute_centralDensity(tracers_catalogue, ChM, par_numdensity, threshold);
1631 coutCBL <<
"Voids in the Catalogue: " << nObjects() << endl;
1632 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1643 double rescaling_time = omp_get_wtime();
1645 vector<bool> remove(nObjects(),
false), bad_rescale(nObjects(),
false);
1647 #pragma omp parallel num_threads(omp_get_max_threads())
1649 #pragma omp for ordered schedule(dynamic)
1650 for (
size_t j=0; j<nObjects(); j++) {
1651 double value = 2*radius(j);
1655 vector<double> radii;
1656 for (
auto&& k : close) {
1657 double distance = Catalogue::distance(j, tracers_catalogue->catalogue_object(k));
1658 if (distance < value) radii.emplace_back(distance);
1660 if (radii.size() < 3) {
1662 bad_rescale[j] =
true;
1666 double zz = redshift(j);
1667 double density = 0.;
1668 for (
size_t N=par_numdensity.size(); N-->0;) density += par_numdensity[par_numdensity.size()-1-N]*pow(zz,N);
1670 std::sort(radii.begin(), radii.end());
1672 vector<vector<double>> data(2, vector<double>(radii.size()));
1673 for (
size_t i=0; i<radii.size()-1; i++) {
1674 data[0][i] = (radii[i]+radii[i+1])*0.5;
1677 data[0][radii.size()-1] = 2*data[0][radii.size()-2] - data[0][radii.size()-3];
1678 data[1][radii.size()-1] = radii.size()/(
volume_sphere(data[0][radii.size()-1])*density);
1680 unsigned int N = std::round(radii.size()*0.25);
1681 bool expand =
false;
1684 while (!(data[1][N-2] < threshold && data[1][N-1] > threshold))
1691 N = std::round(radii.size()*0.25);
1692 while (!(data[1][N-2] < threshold && data[1][N-1] > threshold))
1693 if (N<radii.size()-2) N++;
1699 if (N<=2 or N>=radii.size()-2) {
1701 bad_rescale[j] =
true;
1705 new_radius =
interpolated(threshold, {data[1][N-1], data[1][N]}, {data[0][N-1], data[0][N]},
"Linear");
1707 if (new_radius > 0) set_var(j, Var::_Radius_, new_radius);
1710 bad_rescale[j] =
true;
1716 N = std::round(radii.size()*0.25);
1720 while (!(data[1][N-2] < 0.5 && data[1][N-1] > 0.5))
1728 N = std::round(radii.size()*0.25);
1729 while (!(data[1][N-2] < 0.5 && data[1][N-1] > 0.5))
1730 if (N<radii.size()-2)
1738 if (N<=2 or N>=radii.size()-2) {
1740 bad_rescale[j] =
true;
1744 new_generic =
interpolated(threshold, {data[1][N-1], data[1][N]}, {data[0][N-1], data[0][N]},
"Linear");
1746 if (new_generic > 0) set_var(j, Var::_Generic_, new_generic);
1749 bad_rescale[j] =
true;
1755 remove_objects(remove);
1756 coutCBL <<
"Removed voids:" << endl;
1757 cout <<
"\t Bad rescaled: " << count(bad_rescale.begin(), bad_rescale.end(),
true) << endl;
1759 vector<bool> remove_outofrange(nObjects(),
false);
1760 for (
size_t ii = 0; ii<nObjects(); ii++)
1761 if (radius(ii) < delta_r[0] || delta_r[1] < radius(ii))
1762 remove_outofrange[ii] =
true;
1764 remove_objects(remove_outofrange);
1765 cout <<
"\t Out of range ["+
conv(delta_r[0],
par::fDP2)+
","+
conv(delta_r[1],
par::fDP2)+
"]: " << count(remove_outofrange.begin(), remove_outofrange.end(),
true) << endl;
1767 compute_densityContrast(tracers_catalogue, ChM, ratio);
1769 coutCBL <<
"Time spent by the rescaling procedure: " << omp_get_wtime()-rescaling_time <<
" seconds \n" << endl;
1773 coutCBL <<
"Voids in the Catalogue: " << nObjects() << endl;
1774 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1784 double ol_time = omp_get_wtime();
1785 vector<bool> remove(nObjects(),
false);
1787 vector<double> criteriumOrder(nObjects());
1790 if (ol_criterion == Var::_CentralDensity_) {
1791 criteriumOrder = var(Var::_CentralDensity_);
1792 criterium =
"central density";
1794 else if (ol_criterion == Var::_DensityContrast_) {
1795 criteriumOrder = var(Var::_DensityContrast_);
1796 criterium =
"density contrast";
1799 else ErrorCBL(
"allowed overlap criteria are '_CentralDensity_' or '_DensityContrast_' .",
"Catalogue",
"VoidCatalogue.cpp");
1801 std::vector<int> indices(nObjects(), 0);
1802 std::iota(indices.begin(), indices.end(), 0);
1803 std::sort(indices.begin(), indices.end(), [&](
int A,
int B)
1804 ->
bool {return (ol_criterion == Var::_CentralDensity_) ? criteriumOrder[A] < criteriumOrder[B] : criteriumOrder[A] > criteriumOrder[B];});
1807 coutCBL <<
"Catalogue ordered according to the " << criterium << endl << endl;
1808 coutCBL <<
"* * * Generating ChainMesh for void centres * * *" << endl;
1812 for (
size_t i=0; i<nObjects(); i++) {
1814 vector<long> close = ChM_voids.
close_objects(coordinate(i));
1815 std::sort(close.begin(), close.end());
1816 for (
auto &&j : close) {
1818 double distance = Catalogue::distance(i, catalogue_object(j));
1819 if (distance<radius(i)+radius(j) && (
long)i!=j) {
1820 if (ol_criterion == Var::_CentralDensity_) {
1821 if (centralDensity(i) < centralDensity(j)) {
1824 else if (centralDensity(i) > centralDensity(j)) {
1828 else if (centralDensity(i) == centralDensity(j)) {
1829 if (densityContrast(i) < densityContrast(j)) {
1837 else if (ol_criterion == Var::_DensityContrast_) {
1838 if (densityContrast(i) < densityContrast(j)) {
1842 else if (densityContrast(i) > densityContrast(j))
1844 else if (densityContrast(i) == densityContrast(j)) {
1845 if (centralDensity(i) < centralDensity(j))
1859 remove_objects(remove);
1862 coutCBL <<
"Voids removed to avoid overlap: " << count(remove.begin(), remove.end(),
true) << endl;
1863 coutCBL <<
"Time spent by the overlap-checking procedure: " << omp_get_wtime()-ol_time <<
" seconds" << endl;
1867 coutCBL <<
"Voids in the final Catalogue: " << nObjects() << endl;
1868 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1871 coutCBL <<
"Total time spent: " << omp_get_wtime()-start_time <<
" seconds \n" << endl;
1878 void cbl::catalogue::Catalogue::clean_void_catalogue (
const std::vector<std::vector<double>> data_numdensity,
const std::string method_interpolation,
const bool initial_radius,
const std::vector<double> delta_r,
const double threshold,
bool rescale,
const std::shared_ptr<Catalogue> tracers_catalogue,
chainmesh::ChainMesh3D ChM,
const double ratio,
const bool checkoverlap,
const Var ol_criterion)
1881 const double start_time = omp_get_wtime();
1889 coutCBL <<
"Voids in the initial Catalogue: " << nObjects() << endl << endl;
1890 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1893 coutCBL <<
"Removed voids: " << endl;
1895 if (initial_radius) {
1896 vector<bool> remove(nObjects(),
false);
1897 for (
size_t i=0; i<nObjects(); i++)
1898 if (radius(i) < delta_r[0] || delta_r[1] < radius(i)) remove[i] =
true;
1900 remove_objects(remove);
1901 cout <<
"\t r_min-r_max criterion: " << count(remove.begin(), remove.end(),
true) << endl;
1904 compute_centralDensity(tracers_catalogue, ChM, data_numdensity, method_interpolation, threshold);
1905 coutCBL <<
"Voids in the Catalogue: " << nObjects() << endl;
1906 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
1917 double rescaling_time = omp_get_wtime();
1919 vector<bool> remove(nObjects(),
false), bad_rescale(nObjects(),
false);
1921 #pragma omp parallel num_threads(omp_get_max_threads())
1923 #pragma omp for ordered schedule(dynamic)
1924 for (
size_t j=0; j<nObjects(); j++) {
1925 double value = 2*radius(j);
1929 vector<double> radii;
1930 for (
auto&& k : close) {
1931 double distance = Catalogue::distance(j, tracers_catalogue->catalogue_object(k));
1932 if (distance < value) radii.emplace_back(distance);
1934 if (radii.size() < 3) {
1936 bad_rescale[j] =
true;
1940 double zz = redshift(j);
1941 double density =
interpolated(zz, data_numdensity[0], data_numdensity[1], method_interpolation);
1943 std::sort(radii.begin(), radii.end());
1945 vector<vector<double>> data(2, vector<double>(radii.size()));
1946 for (
size_t i=0; i<radii.size()-1; i++) {
1947 data[0][i] = (radii[i]+radii[i+1])*0.5;
1950 data[0][radii.size()-1] = 2*data[0][radii.size()-2] - data[0][radii.size()-3];
1951 data[1][radii.size()-1] = radii.size()/(
volume_sphere(data[0][radii.size()-1])*density);
1953 unsigned int N = std::round(radii.size()*0.25);
1954 bool expand =
false;
1957 while (!(data[1][N-2] < threshold && data[1][N-1] > threshold))
1964 N = std::round(radii.size()*0.25);
1965 while (!(data[1][N-2] < threshold && data[1][N-1] > threshold))
1966 if (N<radii.size()-2) N++;
1972 if (N<=2 or N>=radii.size()-2) {
1974 bad_rescale[j] =
true;
1978 new_radius =
interpolated(threshold, {data[1][N-1], data[1][N]}, {data[0][N-1], data[0][N]},
"Linear");
1980 if (new_radius > 0) set_var(j, Var::_Radius_, new_radius);
1983 bad_rescale[j] =
true;
1989 N = std::round(radii.size()*0.25);
1993 while (!(data[1][N-2] < 0.5 && data[1][N-1] > 0.5))
2001 N = std::round(radii.size()*0.25);
2002 while (!(data[1][N-2] < 0.5 && data[1][N-1] > 0.5))
2003 if (N<radii.size()-2)
2011 if (N<=2 or N>=radii.size()-2) {
2013 bad_rescale[j] =
true;
2017 new_generic =
interpolated(threshold, {data[1][N-1], data[1][N]}, {data[0][N-1], data[0][N]},
"Linear");
2019 if (new_generic > 0) set_var(j, Var::_Generic_, new_generic);
2022 bad_rescale[j] =
true;
2028 remove_objects(remove);
2029 coutCBL <<
"Removed voids:" << endl;
2030 cout <<
"\t Bad rescaled: " << count(bad_rescale.begin(), bad_rescale.end(),
true) << endl;
2032 vector<bool> remove_outofrange(nObjects(),
false);
2033 for (
size_t ii = 0; ii<nObjects(); ii++)
2034 if (radius(ii) < delta_r[0] || delta_r[1] < radius(ii))
2035 remove_outofrange[ii] =
true;
2037 remove_objects(remove_outofrange);
2038 cout <<
"\t Out of range ["+
conv(delta_r[0],
par::fDP2)+
","+
conv(delta_r[1],
par::fDP2)+
"]: " << count(remove_outofrange.begin(), remove_outofrange.end(),
true) << endl;
2040 compute_densityContrast(tracers_catalogue, ChM, ratio);
2042 coutCBL <<
"Time spent by the rescaling procedure: " << omp_get_wtime()-rescaling_time <<
" seconds \n" << endl;
2046 coutCBL <<
"Voids in the Catalogue: " << nObjects() << endl;
2047 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
2057 double ol_time = omp_get_wtime();
2058 vector<bool> remove(nObjects(),
false);
2060 vector<double> criteriumOrder(nObjects());
2063 if (ol_criterion == Var::_CentralDensity_) {
2064 criteriumOrder = var(Var::_CentralDensity_);
2065 criterium =
"central density";
2067 else if (ol_criterion == Var::_DensityContrast_) {
2068 criteriumOrder = var(Var::_DensityContrast_);
2069 criterium =
"density contrast";
2072 else ErrorCBL(
"allowed overlap criteria are '_CentralDensity_' or '_DensityContrast_' .",
"Catalogue",
"VoidCatalogue.cpp");
2074 std::vector<int> indices(nObjects(), 0);
2075 std::iota(indices.begin(), indices.end(), 0);
2076 std::sort(indices.begin(), indices.end(), [&](
int A,
int B)
2077 ->
bool {return (ol_criterion == Var::_CentralDensity_) ? criteriumOrder[A] < criteriumOrder[B] : criteriumOrder[A] > criteriumOrder[B];});
2080 coutCBL <<
"Catalogue ordered according to the " << criterium << endl << endl;
2081 coutCBL <<
"* * * Generating ChainMesh for void centres * * *" << endl;
2085 for (
size_t i=0; i<nObjects(); i++) {
2087 vector<long> close = ChM_voids.
close_objects(coordinate(i));
2088 std::sort(close.begin(), close.end());
2089 for (
auto &&j : close) {
2091 double distance = Catalogue::distance(i, catalogue_object(j));
2092 if (distance < radius(i)+radius(j) && (
long)i!=j) {
2093 if (ol_criterion == Var::_CentralDensity_) {
2094 if (centralDensity(i) < centralDensity(j)) {
2097 else if (centralDensity(i) > centralDensity(j)) {
2101 else if (centralDensity(i) == centralDensity(j)) {
2102 if (densityContrast(i) < densityContrast(j)) {
2110 else if (ol_criterion == Var::_DensityContrast_) {
2111 if (densityContrast(i) < densityContrast(j)) {
2115 else if (densityContrast(i) > densityContrast(j))
2117 else if (densityContrast(i) == densityContrast(j)) {
2118 if (centralDensity(i) < centralDensity(j))
2132 remove_objects(remove);
2135 coutCBL <<
"Voids removed to avoid overlap: " << count(remove.begin(), remove.end(),
true) << endl;
2136 coutCBL <<
"Time spent by the overlap-checking procedure: " << omp_get_wtime()-ol_time <<
" seconds" << endl;
2140 coutCBL <<
"Voids in the final Catalogue: " << nObjects() << endl;
2141 if (nObjects()==0)
ErrorCBL(
"Empty void catalogue!",
"Catalogue",
"VoidCatalogue.cpp");
2144 coutCBL <<
"Total time spent: " << omp_get_wtime()-start_time <<
" seconds \n" << endl;
2152 const double density = tracers_catalogue->numdensity();
2153 const double mps = tracers_catalogue->mps();
2154 vector<bool> remove(nObjects(),
false);
2156 for (
size_t j=0; j<nObjects(); j++) {
2160 for (
auto&& k : close) {
2162 if (distance <= 2*mps) cont++;
2165 if (cont/(
volume_sphere(2*mps)*density) > threshold) remove[j]=
true;
2167 set_var(j, Var::_CentralDensity_, cont/(
volume_sphere(2*mps)*density));
2169 remove_objects(remove);
2170 cout <<
"\t High central density: " << std::count(remove.begin(), remove.end(),
true) << endl;
2178 vector<bool> remove(nObjects(),
false);
2179 for (
size_t j=0; j<nObjects(); j++) {
2181 double zz = m_object[j]->redshift();
2182 double density = 0.;
2183 for (
size_t N=par_numdensity.size(); N-->0;) density += par_numdensity[par_numdensity.size()-1-N]*pow(zz,N);
2184 double mps = pow(density, -1./3.);
2189 for (
auto&& k : close) {
2191 if (distance <= 2.*mps) cont++;
2194 if (cont/(
volume_sphere(2*mps)*density) > threshold) remove[j]=
true;
2196 set_var(j, Var::_CentralDensity_, cont/(
volume_sphere(2*mps)*density));
2198 remove_objects(remove);
2199 cout <<
"\t High central density: " << std::count(remove.begin(), remove.end(),
true) << endl;
2206 vector<bool> remove(nObjects(),
false);
2207 for (
size_t j=0; j<nObjects(); j++) {
2209 double zz = m_object[j]->redshift();
2210 double density =
interpolated(zz, data_numdensity[0], data_numdensity[1], method_interpolation);
2211 double mps = pow(density, -1./3.);
2216 for (
auto&& k : close) {
2218 if (distance <= 2.*mps) cont++;
2221 if (cont/(
volume_sphere(2*mps)*density) > threshold) remove[j]=
true;
2223 set_var(j, Var::_CentralDensity_, cont/(
volume_sphere(2*mps)*density));
2225 remove_objects(remove);
2226 cout <<
"\t High central density: " << std::count(remove.begin(), remove.end(),
true) << endl;
2235 if (ratio==0. or ratio==1. or ratio>3.)
2236 ErrorCBL (
"Please choose an appropriate value for the parameter ratio!",
"compute_densityContrast",
"VoidCatalogue.cpp");
2238 vector<bool> remove(nObjects(),
false), void_voids(nObjects(),
false), cloud_in_void(nObjects(),
false);
2240 #pragma omp parallel num_threads(omp_get_max_threads())
2242 #pragma omp for ordered schedule(static)
2243 for (
size_t j = 0; j<nObjects(); j++) {
2245 double outer_radius = std::max(radius(j)*ratio, radius(j));
2246 double inner_radius = std::min(radius(j)*ratio, radius(j));
2253 vector<double> distances;
2254 for (
auto&& k : close) {
2255 double distance = Catalogue::distance(j, tracers_catalogue->catalogue_object(k));
2256 if (distance <= outer_radius) distances.emplace_back(distance);
2259 std::sort(distances.begin(), distances.end());
2261 if (distances.size() > 1) {
2267 while (distances[NN_in]<inner_radius && NN_in<(
int)distances.size()-1) NN_in++;
2268 while (distances[NN_out]<outer_radius && NN_out<(
int)distances.size()-1) NN_out++;
2274 double compare = delta_out/delta_in;
2277 void_voids[j] =
true;
2279 else if (compare>=1.)
2280 set_var(j, Var::_DensityContrast_, compare);
2282 else if (compare<1.) {
2284 cloud_in_void[j] =
true;
2287 else set_var(j, Var::_DensityContrast_, 9999.);
2292 remove_objects(remove);
2294 cout <<
"\t Cloud-in-void: " << std::count(cloud_in_void.begin(), cloud_in_void.end(),
true) << endl;
2295 cout <<
"\t Empty voids: " << std::count(cloud_in_void.begin(), cloud_in_void.end(),
true) << endl;
The class catalogue::CatalogueChainMesh.
Implementation of the chain-mesh data structure.
Useful generic functions.
#define coutCBL
CBL print message.
The class TwoPointCorrelation1D_monopole.
The class TwoPointCorrelation.
Catalogue()=default
default constructor
void compute_centralDensity(const std::shared_ptr< Catalogue > tracers_catalogue, chainmesh::ChainMesh3D ChM, const double threshold)
compute the central density of each object in a void catalogue. We define as central density the dens...
size_t nObjects() const
get the number of objects of the catalogue
void compute_densityContrast(const std::shared_ptr< Catalogue > tracers_catalogue, chainmesh::ChainMesh3D ChM, const double ratio=0.1)
compute density contrast of cosmic voids in catalogue as the ratio between an inner and an outer sphe...
void equalize_random_box(cbl::catalogue::Catalogue tracer_catalogue, const int seed)
equalize the number of objects in two Box catalogues
void clean_void_catalogue(const bool initial_radius=false, const std::vector< double > delta_r={-1, 1000}, const double threshold=0.205, const bool rescale=true, const std::shared_ptr< Catalogue > tracers_catalogue={}, chainmesh::ChainMesh3D ChM={}, const double ratio=1.5, const bool checkoverlap=true, const Var ol_criterion=Var::_CentralDensity_)
function that modifies a void catalogue according to a set of user selected criteria....
double distance(const int i, std::shared_ptr< Object > obj) const
get the distrance between the i-th object of the catalogue and another object
std::vector< long > close_objects(std::vector< double > center, long ii=-1) const
get the indeces of the objects close to an object
void get_searching_region(const double r_max, const double r_min=-1.)
set the internal variable m_search_region, the list of cell around a generic center
double Omega_baryon() const
get the private member Cosmology::m_Omega_baryon
static const std::string col_green
green colour (used when printing something on the screen)
static const std::string col_default
default colour (used when printing something on the screen)
static const std::string col_blue
blue colour (used when printing something on the screen)
static const char fDP2[]
conversion symbol for: double -> std::string
static const double pi
: the ratio of a circle's circumference to its diameter
Var
the catalogue variables
VoidAlgorithm
the algorithm used to look for Voids
The global namespace of the CosmoBolognaLib
T Min(const std::vector< T > vect)
minimum element of a std::vector
std::string conv(const T val, const char *fact)
convert a number to a std::string
double Euclidean_distance(const double x1, const double x2, const double y1, const double y2, const double z1, const double z2)
the Euclidean distance in 3D relative to the origin (0,0,0), i.e. the Euclidean norm
void Print(const T value, const int prec, const int ww, const std::string header="", const std::string end="\n", const bool use_coutCBL=true, std::ostream &stream=std::cout, const std::string colour=cbl::par::col_default)
function to print values with a proper homegenised format
T volume_sphere(const T RR)
the volume of a sphere of a given radius
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
T Max(const std::vector< T > vect)
maximum element of a std::vector
double interpolated(const double _xx, const std::vector< double > xx, const std::vector< double > yy, const std::string type)
1D interpolation