Triumvirate C++ API 0.5.0
Three-point clustering measurements in large-scale structure analyses.
Loading...
Searching...
No Matches
triumvirate.cpp
Go to the documentation of this file.
1// Copyright (C) [GPLv3 Licence]
2//
3// This file is part of the Triumvirate program. See the COPYRIGHT
4// and LICENCE files at the top-level directory of this distribution
5// for details of copyright and licensing.
6//
7// This program is free software: you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15// See the GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program. If not, see <https://www.gnu.org/licenses/>.
19
28#include <cstdio>
29#include <stdexcept>
30#include <string>
31
32#include "monitor.hpp"
33#include "parameters.hpp"
34#include "particles.hpp"
35#include "dataobjs.hpp"
36#include "io.hpp"
37#include "twopt.hpp"
38#include "threept.hpp"
39
50 // Clear any existing binning.
51 _binning.bin_edges.clear();
52 _binning.bin_centres.clear();
53 _binning.bin_widths.clear();
54
55 // Implement 'custom' binning scheme for 'fourier' space.
56 if (_binning.space == "fourier") {
57 throw std::domain_error("No custom binning specified in Fourier space.");
58 }
59
60 // Implement 'custom' binning scheme for 'config' space.
61 double dbin_pad = 10.;
62 int nbin_pad = 5;
63
64 _binning.bin_edges.push_back(0.);
65 _binning.bin_centres.push_back(0.5);
66 _binning.bin_widths.push_back(1.);
67
68 _binning.bin_edges.push_back(1.);
69 _binning.bin_centres.push_back(5.);
70 _binning.bin_widths.push_back(9.);
71
72 for (int ibin = 1; ibin < nbin_pad; ibin++) {
73 double edge_left = dbin_pad * ibin;
74 double centre = edge_left + dbin_pad / 2.;
75
76 _binning.bin_edges.push_back(edge_left);
77 _binning.bin_centres.push_back(centre);
78 _binning.bin_widths.push_back(dbin_pad);
79 }
80
81 double bin_min = dbin_pad * nbin_pad;
82
83 double dlnbin = (std::log(_binning.bin_max) - std::log(bin_min))
84 / double(_binning.num_bins - nbin_pad);
85
86 for (int ibin = nbin_pad; ibin < _binning.num_bins; ibin++) {
87 double edge_left = bin_min * std::exp(dlnbin * (ibin - nbin_pad));
88 double edge_right = bin_min * std::exp(dlnbin * (ibin - nbin_pad + 1));
89 double centre = (edge_left + edge_right) / 2.;
90
91 _binning.bin_edges.push_back(edge_left);
92 _binning.bin_centres.push_back(centre);
93 _binning.bin_widths.push_back(edge_right - edge_left);
94 }
95
96 _binning.bin_edges.push_back(_binning.bin_max);
97}
98
107int main(int argc, char* argv[]) {
108#ifdef TRV_DISP
109 if (trv::sys::currTask == 0) {
113 }
114#endif // TRV_DISP
115
116 if (trv::sys::currTask == 0) {
118 }
119
120 // =====================================================================
121 // A Initialisation
122 // =====================================================================
123
124 if (trv::sys::currTask == 0) {
126 "[MAIN:TRV:A] Parameters and source data are being initialised."
127 );
128 }
129
130 // ---------------------------------------------------------------------
131 // A.1 Parameter I/O
132 // ---------------------------------------------------------------------
133
134 if (trv::sys::currTask == 0) {
135 trv::sys::logger.stat("[MAIN:TRV:A] Reading parameters...");
136 }
137
138 if (argc < 2) {
139 if (trv::sys::currTask == 0) {
141 "Failed to initialise program: missing parameter file."
142 );
143 throw trv::sys::IOError(
144 "Failed to initialise program: missing parameter file.\n"
145 );
146 }
147 }
148
149 trv::ParameterSet params; // program parameters
150 if (params.read_from_file(argv[1])) {
151 if (trv::sys::currTask == 0) {
153 "Failed to initialise program: invalidated parameters."
154 );
155 throw trv::sys::IOError(
156 "Failed to initialise program: invalidated parameters.\n"
157 );
158 }
159 }
160
162 if (params.print_to_file()) {
163 if (trv::sys::currTask == 0) {
165 "Failed to print used parameters to file "
166 "in the measurement output directory."
167 );
168 }
169 }
170
171 if (trv::sys::currTask == 0) {
172 trv::sys::logger.stat("[MAIN:TRV:A] ... read parameters.");
173 }
174
176
177 // ---------------------------------------------------------------------
178 // A.2 Data I/O
179 // ---------------------------------------------------------------------
180
181 if (params.catalogue_type != "none") {
182 if (trv::sys::currTask == 0) {
183 trv::sys::logger.stat("[MAIN:TRV:A] Reading catalogues...");
184 }
185 }
186
187 trv::ParticleCatalogue catalogue_data; // data-source catalogue
188 std::string flag_data = "false"; // data-source catalogue status
189 if (params.catalogue_type == "survey" || params.catalogue_type == "sim") {
191 if (trv::sys::currTask == 0) {
193 "Failed to initialise program: "
194 "unspecified data-source catalogue file."
195 );
196 throw trv::sys::IOError(
197 "Failed to initialise program: "
198 "unspecified data-source catalogue file.\n"
199 );
200 }
201 }
202 if (catalogue_data.load_catalogue_file(
203 params.data_catalogue_file, params.catalogue_columns, params.volume
204 )) {
205 if (trv::sys::currTask == 0) {
207 "Failed to initialise program: "
208 "unloadable data-source catalogue file."
209 );
210 throw trv::sys::IOError(
211 "Failed to initialise program: "
212 "unloadable data-source catalogue file.\n"
213 );
214 }
215 }
216 flag_data = "true";
217 }
218
219 trv::ParticleCatalogue catalogue_rand; // random-source catalogue
220 std::string flag_rand = "false"; // random-source catalogue status
221 if (params.catalogue_type == "survey" || params.catalogue_type == "random") {
223 if (trv::sys::currTask == 0) {
225 "Failed to initialise program: "
226 "unspecified random-source catalogue file."
227 );
228 throw trv::sys::IOError(
229 "Failed to initialise program: "
230 "unspecified random-source catalogue file.\n"
231 );
232 }
233 }
234 if (catalogue_rand.load_catalogue_file(
235 params.rand_catalogue_file, params.catalogue_columns, params.volume
236 )) {
237 if (trv::sys::currTask == 0) {
239 "Failed to initialise program: "
240 "unloadable random-source catalogue file."
241 );
242 throw trv::sys::IOError(
243 "Failed to initialise program: "
244 "unloadable random-source catalogue file.\n"
245 );
246 }
247 }
248 flag_rand = "true";
249 }
250
251 if (params.catalogue_type != "none") {
252 if (trv::sys::currTask == 0) {
253 trv::sys::logger.stat("[MAIN:TRV:A] ... read catalogues.");
254 }
255 }
256
257 if (params.use_fftw_wisdom != "") {
259 }
260
261 // =====================================================================
262 // B Measurements
263 // =====================================================================
264
265 if (trv::sys::currTask == 0) {
267 "[MAIN:TRV:B] Clustering statistics are being measured."
268 );
269 }
270
271 // ---------------------------------------------------------------------
272 // B.1 Binning
273 // ---------------------------------------------------------------------
274
275 if (trv::sys::currTask == 0) {
276 trv::sys::logger.stat("[MAIN:TRV:B] Setting up binning...");
277 }
278
279 trv::Binning binning(params); // binning
280 if (params.binning == "custom") {
281 _set_custom_bins(binning);
282 } else {
283 binning.set_bins();
284 }
285
286 if (trv::sys::currTask == 0) {
287 trv::sys::logger.stat("[MAIN:TRV:B] ... set up binning.");
288 }
289
290 // ---------------------------------------------------------------------
291 // B.2 Line of sight
292 // ---------------------------------------------------------------------
293
294 if (params.catalogue_type != "none") {
295 if (trv::sys::currTask == 0) {
296 trv::sys::logger.stat("[MAIN:TRV:B] Computing lines of sight...");
297 }
298 }
299
300 trv::LineOfSight* los_data = nullptr;
301 if (flag_data == "true") {
302 // data-source LoS
303 los_data = new trv::LineOfSight[catalogue_data.ntotal];
307
308#ifdef TRV_USE_OMP
309#pragma omp parallel for
310#endif // TRV_USE_OMP
311 for (int pid = 0; pid < catalogue_data.ntotal; pid++) {
312 double los_mag =
313 trv::maths::get_vec3d_magnitude(catalogue_data[pid].pos);
314
315 if (los_mag == 0.) {
317 "A data-catalogue particle coincides with the origin."
318 );
319 los_mag = 1.;
320 }
321
322 los_data[pid].pos[0] = catalogue_data[pid].pos[0] / los_mag;
323 los_data[pid].pos[1] = catalogue_data[pid].pos[1] / los_mag;
324 los_data[pid].pos[2] = catalogue_data[pid].pos[2] / los_mag;
325 }
326 }
327
328 trv::LineOfSight* los_rand = nullptr;
329 if (flag_rand == "true") {
330 // random-source LoS
331 los_rand = new trv::LineOfSight[catalogue_rand.ntotal];
335
336#ifdef TRV_USE_OMP
337#pragma omp parallel for
338#endif // TRV_USE_OMP
339 for (int pid = 0; pid < catalogue_rand.ntotal; pid++) {
340 double los_mag =
341 trv::maths::get_vec3d_magnitude(catalogue_rand[pid].pos);
342
343 if (los_mag == 0.) {
345 "A random-catalogue particle coincides with the origin."
346 );
347 los_mag = 1.;
348 }
349
350 los_rand[pid].pos[0] = catalogue_rand[pid].pos[0] / los_mag;
351 los_rand[pid].pos[1] = catalogue_rand[pid].pos[1] / los_mag;
352 los_rand[pid].pos[2] = catalogue_rand[pid].pos[2] / los_mag;
353 }
354 }
355
356 if (params.catalogue_type != "none") {
357 if (trv::sys::currTask == 0) {
358 trv::sys::logger.stat("[MAIN:TRV:B] ... computed lines of sight.");
359 }
360 }
361
362 // ---------------------------------------------------------------------
363 // B.3 Box alignment
364 // ---------------------------------------------------------------------
365
366 if (params.catalogue_type != "none") {
367 if (trv::sys::currTask == 0) {
369 "[MAIN:TRV:B] Aligning catalogues inside measurement box..."
370 );
371 }
372 }
373
374 if (params.catalogue_type == "survey") {
375 if (params.alignment == "pad") {
376 if (params.padscale == "grid") {
377 double ngrid_pad[3] = {
378 params.padfactor, params.padfactor, params.padfactor
379 };
381 catalogue_data, catalogue_rand,
382 params.boxsize, params.ngrid,
383 ngrid_pad
384 );
385 } else
386 if (params.padscale == "box") {
387 double boxsize_pad[3] = {
388 params.padfactor, params.padfactor, params.padfactor
389 };
391 catalogue_data, catalogue_rand,
392 params.boxsize, boxsize_pad
393 );
394 }
395 } else
396 if (params.alignment == "centre") {
398 catalogue_data, catalogue_rand, params.boxsize
399 );
400 }
401 } else
402 if (params.catalogue_type == "sim") {
403 catalogue_data.offset_coords_for_periodicity(params.boxsize);
404 } else
405 if (params.catalogue_type == "random") {
406 if (params.alignment == "pad") {
407 if (params.padscale == "grid") {
408 double ngrid_pad[3] = {
409 params.padfactor, params.padfactor, params.padfactor
410 };
412 catalogue_rand, params.boxsize, params.ngrid, ngrid_pad
413 );
414 } else
415 if (params.padscale == "box") {
416 double boxsize_pad[3] = {
417 params.padfactor, params.padfactor, params.padfactor
418 };
420 catalogue_rand, params.boxsize, boxsize_pad
421 );
422 }
423 } else
424 if (params.alignment == "centre") {
426 catalogue_rand, params.boxsize
427 );
428 catalogue_rand.offset_coords_for_periodicity(params.boxsize);
429 }
430 }
431
432 if (params.catalogue_type != "none") {
433 if (trv::sys::currTask == 0) {
435 "[MAIN:TRV:B] ... aligned catalogues inside measurement box."
436 );
437 }
438 }
439
440 // ---------------------------------------------------------------------
441 // B.4 Constants
442 // ---------------------------------------------------------------------
443
444 double alpha; // alpha contrast
445 if (flag_data == "true" && flag_rand == "true") {
446 alpha = catalogue_data.wstotal / catalogue_rand.wstotal;
447 } else {
448 alpha = 1.;
449 }
450
451 if (params.catalogue_type != "none") {
452 if (trv::sys::currTask == 0) {
453 trv::sys::logger.info("Alpha contrast: %.6e.", alpha);
454 }
455 }
456
457 trv::ParticleCatalogue& catalogue_for_norm =
458 (flag_rand == "true") ? catalogue_rand : catalogue_data;
459 double alpha_for_norm = (flag_rand == "true") ? alpha : 1.;
460 double norm_factor_part = 0., norm_factor_mesh = 0., norm_factor_meshes = 0.;
461
462 if (params.npoint == "2pt") {
464 catalogue_for_norm, alpha_for_norm
465 );
467 catalogue_for_norm, params, alpha_for_norm
468 );
469 // Mixed-mesh normalisation is only implemented for
470 // paired survey-like catalogues.
471 if (params.catalogue_type == "survey") {
472 // Use default parameters for mixed-mesh normalisation in `pypower`.
473 const double PADDING = 0.1;
474 const double CELLSIZE = 10.;
475 const std::string ASSIGNMENT = "cic";
476 // Box size for normalisation is internally set and as such,
477 // the current alignment of the catalogues is not applicable, but
478 // this should have no effect on the normalisation.
480 catalogue_data, catalogue_rand, params, alpha,
481 PADDING, CELLSIZE, ASSIGNMENT
482 );
483 }
484 } else
485 if (params.npoint == "3pt") {
487 catalogue_for_norm, alpha_for_norm
488 );
490 catalogue_for_norm, params, alpha_for_norm
491 );
492 }
493
494 double norm_factor = 0.;
495 if (params.npoint != "none") {
496 if (params.norm_convention == "none") {
497 norm_factor = 1.;
498 if (trv::sys::currTask == 0) {
500 "Normalisation factors: "
501 "%.6e (particle), %.6e (mesh), %.6e (mesh-mixed) (none used).",
502 norm_factor_part, norm_factor_mesh, norm_factor_meshes
503 );
504 }
505 } else
506 if (params.norm_convention == "particle") {
507 norm_factor = norm_factor_part;
508 if (trv::sys::currTask == 0) {
510 "Normalisation factors: "
511 "%.6e (particle; used), %.6e (mesh), %.6e (mesh-mixed).",
512 norm_factor, norm_factor_mesh, norm_factor_meshes
513 );
514 }
515 } else
516 if (params.norm_convention == "mesh") {
517 norm_factor = norm_factor_mesh;
518 if (trv::sys::currTask == 0) {
520 "Normalisation factors: "
521 "%.6e (particle), %.6e (mesh; used), %.6e (mesh-mixed).",
522 norm_factor_part, norm_factor, norm_factor_meshes
523 );
524 }
525 } else
526 if (params.norm_convention == "mesh-mixed") {
527 norm_factor = norm_factor_meshes;
528 if (trv::sys::currTask == 0) {
530 "Normalisation factors: "
531 "%.6e (particle), %.6e (mesh), %.6e (mesh-mixed; used).",
532 norm_factor_part, norm_factor_mesh, norm_factor
533 );
534 }
535 }
536 }
537
538 // ---------------------------------------------------------------------
539 // B.5 Clustering algorithms
540 // ---------------------------------------------------------------------
541
542 char save_filepath[1024];
543 if (params.statistic_type == "powspec") {
544 std::snprintf(
545 save_filepath, sizeof(save_filepath), "%s/pk%d%s",
546 params.measurement_dir.c_str(), params.ELL, params.output_tag.c_str()
547 );
548 std::FILE* save_fileptr = nullptr;
549 trv::PowspecMeasurements meas_powspec; // power spectrum
550 if (params.catalogue_type == "survey") {
551 meas_powspec = trv::compute_powspec(
552 catalogue_data, catalogue_rand, los_data, los_rand,
553 params, binning, norm_factor
554 );
555 save_fileptr = std::fopen(save_filepath, "w");
557 save_fileptr, params, catalogue_data, catalogue_rand,
558 norm_factor_part, norm_factor_mesh, norm_factor_meshes
559 );
560 } else
561 if (params.catalogue_type == "sim") {
562 meas_powspec = trv::compute_powspec_in_gpp_box(
563 catalogue_data, params, binning, norm_factor
564 );
565 save_fileptr = std::fopen(save_filepath, "w");
567 save_fileptr, params, catalogue_data,
568 norm_factor_part, norm_factor_mesh, norm_factor_meshes
569 );
570 }
572 save_fileptr, params, meas_powspec
573 );
574 std::fclose(save_fileptr);
575 } else
576 if (params.statistic_type == "2pcf") {
577 std::snprintf(
578 save_filepath, sizeof(save_filepath), "%s/xi%d%s",
579 params.measurement_dir.c_str(), params.ELL, params.output_tag.c_str()
580 );
581 std::FILE* save_fileptr = nullptr;
582 trv::TwoPCFMeasurements meas_2pcf; // two-point correlation function
583 if (params.catalogue_type == "survey") {
584 meas_2pcf = trv::compute_corrfunc(
585 catalogue_data, catalogue_rand, los_data, los_rand,
586 params, binning, norm_factor
587 );
588 save_fileptr = std::fopen(save_filepath, "w");
590 save_fileptr, params, catalogue_data, catalogue_rand,
591 norm_factor_part, norm_factor_mesh, norm_factor_meshes
592 );
593 } else
594 if (params.catalogue_type == "sim") {
596 catalogue_data, params, binning, norm_factor
597 );
598 save_fileptr = std::fopen(save_filepath, "w");
600 save_fileptr, params, catalogue_data,
601 norm_factor_part, norm_factor_mesh, norm_factor_meshes
602 );
603 }
605 save_fileptr, params, meas_2pcf
606 );
607 std::fclose(save_fileptr);
608 } else
609 if (params.statistic_type == "2pcf-win") {
610 std::snprintf(
611 save_filepath, sizeof(save_filepath), "%s/xiw%d%s",
612 params.measurement_dir.c_str(), params.ELL, params.output_tag.c_str()
613 );
614
616 catalogue_rand, los_rand, params, binning, alpha, norm_factor
617 ); // two-point correlation function window
618 std::FILE* save_fileptr = std::fopen(save_filepath, "w");
620 save_fileptr, params, catalogue_rand,
621 norm_factor_part, norm_factor_mesh, norm_factor_meshes
622 );
624 save_fileptr, params, meas_2pcf_win
625 );
626 std::fclose(save_fileptr);
627 } else
628 if (params.statistic_type == "bispec") {
629 if (params.form == "full" || params.form == "diag") {
630 std::snprintf(
631 save_filepath, sizeof(save_filepath), "%s/bk%d%d%d_%s%s",
632 params.measurement_dir.c_str(),
633 params.ell1, params.ell2, params.ELL,
634 params.form.c_str(),
635 params.output_tag.c_str()
636 );
637 } else
638 if (params.form == "off-diag") {
639 std::snprintf(
640 save_filepath, sizeof(save_filepath), "%s/bk%d%d%d_offdiag%d%s",
641 params.measurement_dir.c_str(),
642 params.ell1, params.ell2, params.ELL, params.idx_bin,
643 params.output_tag.c_str()
644 );
645 } else
646 if (params.form == "row") {
647 std::snprintf(
648 save_filepath, sizeof(save_filepath), "%s/bk%d%d%d_row%d%s",
649 params.measurement_dir.c_str(),
650 params.ell1, params.ell2, params.ELL, params.idx_bin,
651 params.output_tag.c_str()
652 );
653 }
654 std::FILE* save_fileptr = nullptr;
655 trv::BispecMeasurements meas_bispec; // bispectrum
656 if (params.catalogue_type == "survey") {
657 meas_bispec = trv::compute_bispec(
658 catalogue_data, catalogue_rand, los_data, los_rand,
659 params, binning, norm_factor
660 );
661 save_fileptr = std::fopen(save_filepath, "w");
663 save_fileptr, params, catalogue_data, catalogue_rand,
664 norm_factor_part, norm_factor_mesh, norm_factor_meshes
665 );
666 } else
667 if (params.catalogue_type == "sim") {
668 meas_bispec = trv::compute_bispec_in_gpp_box(
669 catalogue_data, params, binning, norm_factor
670 );
671 save_fileptr = std::fopen(save_filepath, "w");
673 save_fileptr, params, catalogue_data,
674 norm_factor_part, norm_factor_mesh, norm_factor_meshes
675 );
676 }
678 save_fileptr, params, meas_bispec
679 );
680 std::fclose(save_fileptr);
681 } else
682 if (params.statistic_type == "3pcf") {
683 if (params.form == "full" || params.form == "diag") {
684 std::snprintf(
685 save_filepath, sizeof(save_filepath), "%s/zeta%d%d%d_%s%s",
686 params.measurement_dir.c_str(),
687 params.ell1, params.ell2, params.ELL,
688 params.form.c_str(),
689 params.output_tag.c_str()
690 );
691 } else
692 if (params.form == "off-diag") {
693 std::snprintf(
694 save_filepath, sizeof(save_filepath), "%s/zeta%d%d%d_offdiag%d%s",
695 params.measurement_dir.c_str(),
696 params.ell1, params.ell2, params.ELL, params.idx_bin,
697 params.output_tag.c_str()
698 );
699 } else
700 if (params.form == "row") {
701 std::snprintf(
702 save_filepath, sizeof(save_filepath), "%s/zeta%d%d%d_row%d%s",
703 params.measurement_dir.c_str(),
704 params.ell1, params.ell2, params.ELL, params.idx_bin,
705 params.output_tag.c_str()
706 );
707 }
708 std::FILE* save_fileptr = nullptr;
709 trv::ThreePCFMeasurements meas_3pcf; // three-point correlation function
710 if (params.catalogue_type == "survey") {
711 meas_3pcf = trv::compute_3pcf(
712 catalogue_data, catalogue_rand, los_data, los_rand,
713 params, binning, norm_factor
714 );
715 save_fileptr = std::fopen(save_filepath, "w");
717 save_fileptr, params, catalogue_data, catalogue_rand,
718 norm_factor_part, norm_factor_mesh, norm_factor_meshes
719 );
720 } else
721 if (params.catalogue_type == "sim") {
723 catalogue_data, params, binning, norm_factor
724 );
725 save_fileptr = std::fopen(save_filepath, "w");
727 save_fileptr, params, catalogue_data,
728 norm_factor_part, norm_factor_mesh, norm_factor_meshes
729 );
730 }
732 save_fileptr, params, meas_3pcf
733 );
734 std::fclose(save_fileptr);
735 } else
736 if (params.statistic_type == "3pcf-win") {
737 if (params.form == "full" || params.form == "diag") {
738 std::snprintf(
739 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_%s%s",
740 params.measurement_dir.c_str(),
741 params.ell1, params.ell2, params.ELL,
742 params.form.c_str(),
743 params.output_tag.c_str()
744 );
745 } else
746 if (params.form == "off-diag") {
747 std::snprintf(
748 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_offdiag%d%s",
749 params.measurement_dir.c_str(),
750 params.ell1, params.ell2, params.ELL, params.idx_bin,
751 params.output_tag.c_str()
752 );
753 } else
754 if (params.form == "row") {
755 std::snprintf(
756 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_row%d%s",
757 params.measurement_dir.c_str(),
758 params.ell1, params.ell2, params.ELL, params.idx_bin,
759 params.output_tag.c_str()
760 );
761 }
762 bool wa = false;
763
765 catalogue_rand, los_rand, params, binning, alpha, norm_factor, wa
766 ); // three-point correlation function window
767 std::FILE* save_fileptr = std::fopen(save_filepath, "w");
769 save_fileptr, params, catalogue_rand,
770 norm_factor_part, norm_factor_mesh, norm_factor_meshes
771 );
773 save_fileptr, params, meas_3pcf_win
774 );
775 std::fclose(save_fileptr);
776 } else
777 if (params.statistic_type == "3pcf-win-wa") {
778 if (params.form == "full" || params.form == "diag") {
779 std::snprintf(
780 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_wa%d%d_%s%s",
781 params.measurement_dir.c_str(),
782 params.ell1, params.ell2, params.ELL, params.i_wa, params.j_wa,
783 params.form.c_str(),
784 params.output_tag.c_str()
785 );
786 } else
787 if (params.form == "off-diag") {
788 std::snprintf(
789 save_filepath, sizeof(save_filepath),
790 "%s/zetaw%d%d%d_wa%d%d_offdiag%d%s",
791 params.measurement_dir.c_str(),
792 params.ell1, params.ell2, params.ELL, params.i_wa, params.j_wa,
793 params.idx_bin,
794 params.output_tag.c_str()
795 );
796 } else
797 if (params.form == "row") {
798 std::snprintf(
799 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_wa%d%d_row%d%s",
800 params.measurement_dir.c_str(),
801 params.ell1, params.ell2, params.ELL, params.i_wa, params.j_wa,
802 params.idx_bin,
803 params.output_tag.c_str()
804 );
805 }
806
807 bool wa = true;
808
809 trv::ThreePCFWindowMeasurements meas_3pcf_win_wa =
811 catalogue_rand, los_rand, params, binning, alpha, norm_factor, wa
812 ); // three-point correlation function window wide-angle corrections
813 std::FILE* save_fileptr = std::fopen(save_filepath, "w");
815 save_fileptr, params, catalogue_rand,
816 norm_factor_part, norm_factor_mesh, norm_factor_meshes
817 );
819 save_fileptr, params, meas_3pcf_win_wa
820 );
821 std::fclose(save_fileptr);
822 }
823
824 if (params.save_binned_vectors != "") {
825 trv::FieldStats binning_meshgrid(params, false);
826 trv::BinnedVectors binned_vectors = binning_meshgrid.record_binned_vectors(
827 binning, params.save_binned_vectors
828 );
829 if (params.statistic_type == "modes" || params.statistic_type == "pairs") {
830 std::snprintf(
831 save_filepath, sizeof(save_filepath), "%s",
832 params.save_binned_vectors.c_str()
833 );
834 }
835 }
836
837 if (trv::sys::currTask == 0) {
838 trv::sys::logger.info("Measurements saved to: %s", save_filepath);
839 }
840
841 // =====================================================================
842 // C Finalisation
843 // =====================================================================
844
845 if (trv::sys::currTask == 0) {
846 trv::sys::logger.stat("[MAIN:TRV:C] Data objects are being cleared.");
847 }
848
849 // Clear persistent and dynamic memory.
850#if defined(TRV_USE_OMP) && defined(TRV_USE_FFTWOMP)
851 fftw_cleanup_threads();
852#else // !TRV_USE_OMP || !TRV_USE_FFTWOMP
853 fftw_cleanup();
854#endif // TRV_USE_OMP && TRV_USE_FFTWOMP
855
856 catalogue_data.finalise_particles();
857 catalogue_rand.finalise_particles();
858
859 if (los_data != nullptr) {
860 delete[] los_data; los_data = nullptr;
861 }
862 if (los_rand != nullptr) {
863 delete[] los_rand; los_rand = nullptr;
864 }
866 (catalogue_data.ntotal + catalogue_rand.ntotal)
867 );
868
870 if (trv::sys::currTask == 0) {
872 "Number of FFTs: %d forward, %d backward.",
874 );
875 }
876 }
877
878 if (
882 ) {
883 if (trv::sys::currTask == 0) {
885 "Maximum number of concurrent 3-d grids: "
886 "%.1f complex-equivalent, %d complex, %d real.",
889 );
890 }
891 }
892
893 if (trv::sys::currTask == 0) {
895 "Minimal estimate of peak memory usage: %.1f gibibytes.",
897 );
898 }
899 if (trv::sys::gbytesMem > 0.) {
900 if (trv::sys::currTask == 0) {
902 "Uncleared dynamically allocated memory: %.1f gibibytes.",
904 );
905 }
906 }
907
908 if (trv::sys::currTask == 0) {
910 }
911
912 return 0;
913}
Isotropic coordinate binning.
Definition dataobjs.hpp:56
std::vector< double > bin_widths
bin widths
Definition dataobjs.hpp:65
std::vector< double > bin_edges
bin edges
Definition dataobjs.hpp:63
std::vector< double > bin_centres
bin centres
Definition dataobjs.hpp:64
std::string space
coordinate space
Definition dataobjs.hpp:58
double bin_max
highest bin edge
Definition dataobjs.hpp:61
void set_bins(double coord_min, double coord_max, int nbin)
Set bins.
Definition dataobjs.cpp:56
int num_bins
number of bins
Definition dataobjs.hpp:62
Field (pseudo-two-point) statistics.
Definition field.hpp:550
trv::BinnedVectors record_binned_vectors(trv::Binning &binning, const std::string &save_file)
Record binned vectors given a binning scheme.
Definition field.cpp:1890
Parameter set.
std::string alignment
box alignment: {"centre" (default), "pad"}
std::string catalogue_columns
catalogue data columns (comma-separated without space)
std::string output_tag
output tag
std::string save_binned_vectors
int ELL
spherical degree associated with the line of sight
int i_wa
first order of the wide-angle correction term
double padfactor
padding factor
double volume
box volume (in Mpc^3/h^3)
int print_to_file(char *out_parameter_filepath)
Print out extracted parameters to a file in the output measurement directory.
int read_from_file(char *parameter_filepath)
Read parameters from a file.
std::string norm_convention
std::string statistic_type
std::string measurement_dir
measurement/output directory
std::string catalogue_type
catalogue type: {"survey", "random", "sim", "none"}
int ell1
spherical degree associated with the first wavevector
std::string padscale
padding scale (if alignment is "pad"): {"box" (default), "grid"}
std::string binning
int ell2
spherical degree associated with the second wavevector
int ngrid[3]
grid number in each dimension
std::string data_catalogue_file
data catalogue file
std::string npoint
N-point case: {"2pt", "3pt", "none"}
std::string rand_catalogue_file
random catalogue file
int idx_bin
fixed bin index in "off-fiag"/"row" form three-point measurements
int j_wa
second order of the wide-angle correction term
double boxsize[3]
box size (in Mpc/h) in each dimension
std::string use_fftw_wisdom
use FFTW wisdom: {"false" (default), <path-to-dir>}
Particle catalogue.
Definition particles.hpp:68
static void centre_in_box(ParticleCatalogue &catalogue, const double boxsize[3])
Centre a catalogue in a box.
void finalise_particles()
Finalise particle data container.
Definition particles.cpp:77
static void pad_grids(ParticleCatalogue &catalogue, const double boxsize[3], const int ngrid[3], const double ngrid_pad[3])
Pad a catalogue in a box.
int load_catalogue_file(const std::string &catalogue_filepath, const std::string &catalogue_columns, double volume=0.)
Read in a catalogue file.
int ntotal
total number of particles
Definition particles.hpp:74
void offset_coords_for_periodicity(const double boxsize[3])
Offset particle positions for periodic boundary conditions.
static void pad_in_box(ParticleCatalogue &catalogue, const double boxsize[3], const double boxsize_pad[3])
Pad a catalogue in a box.
double wstotal
total sample weight of particles
Definition particles.hpp:76
Exception raised when an input/output operation fails.
Definition monitor.hpp:408
void info(const char *fmt_string,...)
Emit a information-level message.
Definition monitor.cpp:264
void error(const char *fmt_string,...)
Emit a warning-level message.
Definition monitor.cpp:282
void warn(const char *fmt_string,...)
Emit a warning-level message.
Definition monitor.cpp:273
void stat(const char *fmt_string,...)
Emit a status-level message.
Definition monitor.cpp:255
void reset_level(LogLevel level)
Reset the logger threshold level.
Definition monitor.cpp:156
Clustering measurement data objects.
I/O support including custom exceptions and utility functions.
Provide tracking of program resources and exceptions.
void print_measurement_header_to_file(std::FILE *fileptr, trv::ParameterSet &params, trv::ParticleCatalogue &catalogue_data, trv::ParticleCatalogue &catalogue_rand, double norm_factor_part, double norm_factor_mesh, double norm_factor_meshes)
Print the pre-measurement header to a file including information about the catalogue(s) and mesh grid...
Definition io.cpp:100
void print_measurement_datatab_to_file(std::FILE *fileptr, trv::ParameterSet &params, trv::PowspecMeasurements &meas_powspec)
Print measurements as a data table to a file.
Definition io.cpp:358
double get_vec3d_magnitude(std::vector< double > vec)
Return the magnitude of a 3-d vector.
Definition maths.cpp:51
double gbytesMem
current memory usage in gibibytes
Definition monitor.cpp:46
double size_in_gb(long long num)
Return size in gibibytes.
Definition monitor.hpp:101
void update_maxmem()
Update the maximum memory usage estimate.
Definition monitor.cpp:68
void display_prog_licence()
Display program licence in stdout.
Definition monitor.cpp:489
void display_prog_logo()
Display program logo in stdout.
Definition monitor.cpp:475
float max_count_grid
maximum number of grids
Definition monitor.cpp:54
Logger logger
default logger (at NSET logging level)
int max_count_rgrid
maximum number of 3-d real grids
Definition monitor.cpp:52
void make_write_dir(std::string dirstr)
Make write directory.
Definition io.cpp:57
bool if_filepath_is_set(const std::string &pathstr)
Check if a file path is set.
Definition io.cpp:37
int max_count_cgrid
maximum number of 3-d complex grids
Definition monitor.cpp:53
int currTask
current task
Definition monitor.cpp:44
void display_prog_logbars(int endpoint)
Display program log bars in stdout.
Definition monitor.cpp:534
int count_fft
number of FFTs
Definition monitor.cpp:56
double gbytesMaxMem
maximum memory usage in gibibytes
Definition monitor.cpp:47
int count_ifft
number of IFFTs
Definition monitor.cpp:57
void display_prog_info()
Display program information in stdout.
Definition monitor.cpp:508
double calc_bispec_normalisation_from_particles(ParticleCatalogue &particles, double alpha=1.)
Calculate particle-based bispectrum normalisation.
Definition threept.cpp:94
trv::ThreePCFMeasurements compute_3pcf_in_gpp_box(ParticleCatalogue &catalogue_data, trv::ParameterSet &params, trv::Binning &rbinning, double norm_factor)
Compute three-point correlation function in a periodic box in the global plane-parallel approximation...
Definition threept.cpp:2115
trv::TwoPCFWindowMeasurements compute_corrfunc_window(trv::ParticleCatalogue &catalogue_rand, trv::LineOfSight *los_rand, trv::ParameterSet &params, trv::Binning rbinning, double alpha, double norm_factor)
Compute two-point correlation function window from a random catalogue and optionally save the results...
Definition twopt.cpp:761
trv::TwoPCFMeasurements compute_corrfunc(ParticleCatalogue &catalogue_data, ParticleCatalogue &catalogue_rand, LineOfSight *los_data, LineOfSight *los_rand, trv::ParameterSet &params, trv::Binning &rbinning, double norm_factor)
Compute two-point correlation function from paired survey-type catalogues.
Definition twopt.cpp:454
trv::PowspecMeasurements compute_powspec_in_gpp_box(ParticleCatalogue &catalogue_data, trv::ParameterSet &params, trv::Binning kbinning, double norm_factor)
Compute power spectrum in a periodic box in the global plane-parallel approximation.
Definition twopt.cpp:568
trv::BispecMeasurements compute_bispec_in_gpp_box(ParticleCatalogue &catalogue_data, trv::ParameterSet &params, trv::Binning kbinning, double norm_factor)
Compute bispectrum in a periodic box in the global plane-parallel approximation.
Definition threept.cpp:1423
trv::ThreePCFWindowMeasurements compute_3pcf_window(ParticleCatalogue &catalogue_rand, LineOfSight *los_rand, trv::ParameterSet &params, trv::Binning &rbinning, double alpha, double norm_factor, bool wide_angle=false)
Compute three-point correlation function window from a random catalogue.
Definition threept.cpp:2525
double calc_powspec_normalisation_from_particles(ParticleCatalogue &particles, double alpha=1.)
Calculate particle-based power spectrum normalisation.
Definition twopt.cpp:54
double calc_bispec_normalisation_from_mesh(ParticleCatalogue &particles, trv::ParameterSet &params, double alpha=1.)
Calculate mesh-based bispectrum normalisation.
Definition threept.cpp:136
double calc_powspec_normalisation_from_mesh(trv::ParticleCatalogue &particles, trv::ParameterSet &params, double alpha=1.)
Calculate mesh-based power spectrum normalisation.
Definition twopt.cpp:96
trv::PowspecMeasurements compute_powspec(ParticleCatalogue &catalogue_data, ParticleCatalogue &catalogue_rand, LineOfSight *los_data, LineOfSight *los_rand, trv::ParameterSet &params, trv::Binning &kbinning, double norm_factor)
Compute power spectrum from paired survey-type catalogues.
Definition twopt.cpp:340
trv::BispecMeasurements compute_bispec(ParticleCatalogue &catalogue_data, ParticleCatalogue &catalogue_rand, LineOfSight *los_data, LineOfSight *los_rand, trv::ParameterSet &params, trv::Binning &kbinning, double norm_factor)
Compute bispectrum from paired survey-type catalogues.
Definition threept.cpp:246
trv::ThreePCFMeasurements compute_3pcf(ParticleCatalogue &catalogue_data, ParticleCatalogue &catalogue_rand, LineOfSight *los_data, LineOfSight *los_rand, trv::ParameterSet &params, trv::Binning &rbinning, double norm_factor)
Compute three-point correlation function from paired survey-type catalogues.
Definition threept.cpp:986
trv::TwoPCFMeasurements compute_corrfunc_in_gpp_box(ParticleCatalogue &catalogue_data, trv::ParameterSet &params, trv::Binning &rbinning, double norm_factor)
Compute two-point correlation function in a periodic box in the global plane-parallel approximation.
Definition twopt.cpp:666
double calc_powspec_normalisation_from_meshes(trv::ParticleCatalogue &particles_data, trv::ParticleCatalogue &particles_rand, trv::ParameterSet &params, double alpha)
Calculate power spectrum normalisation from mixed meshes.
Definition twopt.cpp:109
Program parameter configuration.
Particle containers with I/O methods and operations.
Binned vectors.
Definition dataobjs.hpp:164
Bispectrum measurements.
Definition dataobjs.hpp:247
Line-of-sight vector.
Definition dataobjs.hpp:184
double pos[3]
3-d position vector
Definition dataobjs.hpp:185
Power spectrum measurements.
Definition dataobjs.hpp:200
Three-point correlation function measurements.
Definition dataobjs.hpp:265
Three-point correlation function window measurements.
Definition dataobjs.hpp:286
Two-point correlation function measurements.
Definition dataobjs.hpp:215
Two-point correlation function window measurements.
Definition dataobjs.hpp:228
Three-point statistic computations.
int main(int argc, char *argv[])
A 'black-box' program for measuring two- and three-point clustering statistics.
void _set_custom_bins(trv::Binning &_binning)
Set 'custom' binning.
Two-point statistic computations.