Triumvirate C++ API 0.5.0.post1.dev301+g026f21751
Three-point clustering measurements in large-scale structure analyses.
Loading...
Searching...
No Matches
triumvirate.cpp
Go to the documentation of this file.
1// Triumvirate: Three-Point Clustering Measurements in LSS
2//
3// Copyright (C) 2023 Mike S Wang & Naonori S Sugiyama [GPL-3.0-or-later]
4//
5// This file is part of the Triumvirate program. See the COPYRIGHT
6// and LICENCE files at the top-level directory of this distribution
7// for details of copyright and licensing.
8//
9// This program is free software: you can redistribute it and/or modify it
10// under the terms of the GNU General Public License as published by
11// the Free Software Foundation, either version 3 of the License, or
12// (at your option) any later version.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17// See the GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with this program. If not, see <https://www.gnu.org/licenses/>.
21
29
30#include <cstdio>
31#include <stdexcept>
32#include <string>
33
34#include "monitor.hpp"
35#include "parameters.hpp"
36#include "particles.hpp"
37#include "dataobjs.hpp"
38#include "io.hpp"
39#include "twopt.hpp"
40#include "threept.hpp"
41
52 // Clear any existing binning.
53 _binning.bin_edges.clear();
54 _binning.bin_centres.clear();
55 _binning.bin_widths.clear();
56
57 // Implement 'custom' binning scheme for 'fourier' space.
58 if (_binning.space == "fourier") {
59 throw std::domain_error("No custom binning specified in Fourier space.");
60 }
61
62 // Implement 'custom' binning scheme for 'config' space.
63 double dbin_pad = 10.;
64 int nbin_pad = 5;
65
66 _binning.bin_edges.push_back(0.);
67 _binning.bin_centres.push_back(0.5);
68 _binning.bin_widths.push_back(1.);
69
70 _binning.bin_edges.push_back(1.);
71 _binning.bin_centres.push_back(5.);
72 _binning.bin_widths.push_back(9.);
73
74 for (int ibin = 1; ibin < nbin_pad; ibin++) {
75 double edge_left = dbin_pad * ibin;
76 double centre = edge_left + dbin_pad / 2.;
77
78 _binning.bin_edges.push_back(edge_left);
79 _binning.bin_centres.push_back(centre);
80 _binning.bin_widths.push_back(dbin_pad);
81 }
82
83 double bin_min = dbin_pad * nbin_pad;
84
85 double dlnbin = (std::log(_binning.bin_max) - std::log(bin_min))
86 / double(_binning.num_bins - nbin_pad);
87
88 for (int ibin = nbin_pad; ibin < _binning.num_bins; ibin++) {
89 double edge_left = bin_min * std::exp(dlnbin * (ibin - nbin_pad));
90 double edge_right = bin_min * std::exp(dlnbin * (ibin - nbin_pad + 1));
91 double centre = (edge_left + edge_right) / 2.;
92
93 _binning.bin_edges.push_back(edge_left);
94 _binning.bin_centres.push_back(centre);
95 _binning.bin_widths.push_back(edge_right - edge_left);
96 }
97
98 _binning.bin_edges.push_back(_binning.bin_max);
99}
100
109int main(int argc, char* argv[]) {
110
111 for (int idx_arg = 1; idx_arg < argc; idx_arg++) {
112 std::string arg = argv[idx_arg];
113 if (arg == "-h" || arg == "--help") {
115 return 0;
116 }
117 if (arg == "-V" || arg == "--version") {
121 return 0;
122 }
123 if (argc > 2 && arg.rfind("-", 0) == 0) {
124 std::fprintf(stderr, "Unknown option: %s\n\n", arg.c_str());
126 return 1;
127 }
128 }
129
130#ifdef TRV_USE_DISP
131 if (trv::sys::currTask == 0) {
135 }
136#endif // TRV_USE_DISP
137
138 if (trv::sys::currTask == 0) {
140 }
141
142 // =====================================================================
143 // A Initialisation
144 // =====================================================================
145
146 if (trv::sys::currTask == 0) {
147 trv::sys::logger.stat(
148 "[MAIN:TRV:A] Parameters and source data are being initialised."
149 );
150 }
151
152 // ---------------------------------------------------------------------
153 // A.1 Parameter I/O
154 // ---------------------------------------------------------------------
155
156 if (trv::sys::currTask == 0) {
157 trv::sys::logger.stat("[MAIN:TRV:A] Reading parameters...");
158 }
159
160 if (argc < 2) {
161 if (trv::sys::currTask == 0) {
162 trv::sys::logger.error(
163 "Failed to initialise program: missing parameter file."
164 );
166 "Failed to initialise program: missing parameter file."
167 );
168 }
169 }
170
171 trv::ParameterSet params; // program parameters
172 int exit_code = 0;
173 try {
174 exit_code = params.read_from_file(argv[1]);
175 } catch (const trv::sys::InvalidParameterError& err) {
176 exit_code = 1;
177 }
178 if (exit_code != 0) {
179 if (trv::sys::currTask == 0) {
181 "Failed to initialise program: invalidated parameters."
182 );
183 }
184 }
185
187
189 if (params.print_to_file()) {
190 if (trv::sys::currTask == 0) {
191 trv::sys::logger.warn(
192 "Failed to print used parameters to file "
193 "in the measurement output directory."
194 );
195 }
196 }
197
198 if (trv::sys::currTask == 0) {
199 trv::sys::logger.stat("[MAIN:TRV:A] ... read parameters.");
200 }
201
202 trv::sys::logger.reset_level(params.verbose);
203
204 // ---------------------------------------------------------------------
205 // A.2 Data I/O
206 // ---------------------------------------------------------------------
207
208 if (params.catalogue_type != "none") {
209 if (trv::sys::currTask == 0) {
210 trv::sys::logger.stat("[MAIN:TRV:A] Reading catalogues...");
211 }
212 }
213
214 trv::ParticleCatalogue catalogue_data; // data-source catalogue
215 std::string flag_data = "false"; // data-source catalogue status
216 if (params.catalogue_type == "survey" || params.catalogue_type == "sim") {
218 if (trv::sys::currTask == 0) {
219 trv::sys::logger.error(
220 "Failed to initialise program: "
221 "unspecified data-source catalogue file."
222 );
224 "Failed to initialise program: "
225 "unspecified data-source catalogue file."
226 );
227 }
228 }
229 int exit_code = 0;
230 try {
231 exit_code = catalogue_data.load_catalogue_file(
232 params.data_catalogue_file,
233 params.catalogue_columns,
234 params.catalogue_dataset,
235 params.volume
236 );
237 } catch (const trv::sys::IOError& err) {
238 exit_code = 1;
239 }
240 if (exit_code != 0) {
241 if (trv::sys::currTask == 0) {
243 "Failed to initialise program: "
244 "unloadable data-source catalogue file."
245 );
246 }
247 }
248 flag_data = "true";
249 }
250
251 trv::ParticleCatalogue catalogue_rand; // random-source catalogue
252 std::string flag_rand = "false"; // random-source catalogue status
253 if (params.catalogue_type == "survey" || params.catalogue_type == "random") {
255 if (trv::sys::currTask == 0) {
256 trv::sys::logger.error(
257 "Failed to initialise program: "
258 "unspecified random-source catalogue file."
259 );
261 "Failed to initialise program: "
262 "unspecified random-source catalogue file."
263 );
264 }
265 }
266 int exit_code = 0;
267 try {
268 exit_code = catalogue_rand.load_catalogue_file(
269 params.rand_catalogue_file,
270 params.catalogue_columns,
271 params.catalogue_dataset,
272 params.volume
273 );
274 } catch (const trv::sys::IOError& err) {
275 exit_code = 1;
276 }
277 if (exit_code != 0) {
278 if (trv::sys::currTask == 0) {
280 "Failed to initialise program: "
281 "unloadable random-source catalogue file."
282 );
283 }
284 }
285 flag_rand = "true";
286 }
287
288 if (params.catalogue_type != "none") {
289 if (trv::sys::currTask == 0) {
290 trv::sys::logger.stat("[MAIN:TRV:A] ... read catalogues.");
291 }
292 }
293
294 if (params.use_fftw_wisdom != "") {
296 }
297
298 // =====================================================================
299 // B Measurements
300 // =====================================================================
301
302 if (trv::sys::currTask == 0) {
303 trv::sys::logger.stat(
304 "[MAIN:TRV:B] Clustering statistics are being measured."
305 );
306 }
307
308 // ---------------------------------------------------------------------
309 // B.1 Binning
310 // ---------------------------------------------------------------------
311
312 if (trv::sys::currTask == 0) {
313 trv::sys::logger.stat("[MAIN:TRV:B] Setting up binning...");
314 }
315
316 trv::Binning binning(params); // binning
317 if (params.binning == "custom") {
318 _set_custom_bins(binning);
319 } else {
320 binning.set_bins();
321 }
322
323 if (trv::sys::currTask == 0) {
324 trv::sys::logger.stat("[MAIN:TRV:B] ... set up binning.");
325 }
326
327 // ---------------------------------------------------------------------
328 // B.2 Line of sight
329 // ---------------------------------------------------------------------
330
331 if (params.catalogue_type != "none") {
332 if (trv::sys::currTask == 0) {
333 trv::sys::logger.stat("[MAIN:TRV:B] Computing lines of sight...");
334 }
335 }
336
337 trv::LineOfSight* los_data = nullptr;
338 if (flag_data == "true") {
339 // data-source LoS
340 los_data = new trv::LineOfSight[catalogue_data.ntotal];
344
345#ifdef TRV_USE_OMP
346#pragma omp parallel for
347#endif // TRV_USE_OMP
348 for (int pid = 0; pid < catalogue_data.ntotal; pid++) {
349 double los_mag =
350 trv::maths::get_vec3d_magnitude(catalogue_data[pid].pos);
351
352 if (los_mag == 0.) {
353 trv::sys::logger.warn(
354 "A data-catalogue particle coincides with the origin."
355 );
356 los_mag = 1.;
357 }
358
359 los_data[pid].pos[0] = catalogue_data[pid].pos[0] / los_mag;
360 los_data[pid].pos[1] = catalogue_data[pid].pos[1] / los_mag;
361 los_data[pid].pos[2] = catalogue_data[pid].pos[2] / los_mag;
362 }
363 }
364
365 trv::LineOfSight* los_rand = nullptr;
366 if (flag_rand == "true") {
367 // random-source LoS
368 los_rand = new trv::LineOfSight[catalogue_rand.ntotal];
372
373#ifdef TRV_USE_OMP
374#pragma omp parallel for
375#endif // TRV_USE_OMP
376 for (int pid = 0; pid < catalogue_rand.ntotal; pid++) {
377 double los_mag =
378 trv::maths::get_vec3d_magnitude(catalogue_rand[pid].pos);
379
380 if (los_mag == 0.) {
381 trv::sys::logger.warn(
382 "A random-catalogue particle coincides with the origin."
383 );
384 los_mag = 1.;
385 }
386
387 los_rand[pid].pos[0] = catalogue_rand[pid].pos[0] / los_mag;
388 los_rand[pid].pos[1] = catalogue_rand[pid].pos[1] / los_mag;
389 los_rand[pid].pos[2] = catalogue_rand[pid].pos[2] / los_mag;
390 }
391 }
392
393 if (params.catalogue_type != "none") {
394 if (trv::sys::currTask == 0) {
395 trv::sys::logger.stat("[MAIN:TRV:B] ... computed lines of sight.");
396 }
397 }
398
399 // ---------------------------------------------------------------------
400 // B.3 Box alignment
401 // ---------------------------------------------------------------------
402
403 if (params.catalogue_type != "none") {
404 if (trv::sys::currTask == 0) {
405 trv::sys::logger.stat(
406 "[MAIN:TRV:B] Aligning catalogues inside measurement box..."
407 );
408 }
409 }
410
411 if (params.catalogue_type == "survey") {
412 if (params.volume == 0.) {
413 trv::set_boxsize_from_expand(catalogue_data.pos_span, params);
414 if (params.nmesh == 0) {
416 }
417 }
418 if (params.alignment == "pad") {
419 if (params.padscale == "grid") {
420 double ngrid_pad[3] = {
421 params.padfactor, params.padfactor, params.padfactor
422 };
424 catalogue_data, catalogue_rand,
425 params.boxsize, params.ngrid,
426 ngrid_pad
427 );
428 } else
429 if (params.padscale == "box") {
430 double boxsize_pad[3] = {
431 params.padfactor, params.padfactor, params.padfactor
432 };
434 catalogue_data, catalogue_rand,
435 params.boxsize, boxsize_pad
436 );
437 }
438 } else
439 if (params.alignment == "centre") {
441 catalogue_data, catalogue_rand, params.boxsize
442 );
443 }
444 } else
445 if (params.catalogue_type == "sim") {
446 if (params.volume == 0.) {
447 trv::set_boxsize_from_expand(catalogue_data.pos_span, params);
448 if (params.nmesh == 0) {
450 }
451 }
452 catalogue_data.offset_coords_for_periodicity(params.boxsize);
453 } else
454 if (params.catalogue_type == "random") {
455 if (params.volume == 0.) {
456 trv::set_boxsize_from_expand(catalogue_rand.pos_span, params);
457 if (params.nmesh == 0) {
459 }
460 }
461 if (params.alignment == "pad") {
462 if (params.padscale == "grid") {
463 double ngrid_pad[3] = {
464 params.padfactor, params.padfactor, params.padfactor
465 };
467 catalogue_rand, params.boxsize, params.ngrid, ngrid_pad
468 );
469 } else
470 if (params.padscale == "box") {
471 double boxsize_pad[3] = {
472 params.padfactor, params.padfactor, params.padfactor
473 };
475 catalogue_rand, params.boxsize, boxsize_pad
476 );
477 }
478 } else
479 if (params.alignment == "centre") {
481 catalogue_rand, params.boxsize
482 );
483 catalogue_rand.offset_coords_for_periodicity(params.boxsize);
484 }
485 }
486
487 if (params.catalogue_type != "none") {
488 if (trv::sys::currTask == 0) {
489 trv::sys::logger.stat(
490 "[MAIN:TRV:B] ... aligned catalogues inside measurement box."
491 );
492 }
493 }
494
495 // ---------------------------------------------------------------------
496 // B.4 Constants
497 // ---------------------------------------------------------------------
498
499 double alpha; // alpha contrast
500 if (flag_data == "true" && flag_rand == "true") {
501 alpha = catalogue_data.wstotal / catalogue_rand.wstotal;
502 } else {
503 alpha = 1.;
504 }
505
506 if (params.catalogue_type != "none") {
507 if (trv::sys::currTask == 0) {
508 trv::sys::logger.info("Alpha contrast: %.6e.", alpha);
509 }
510 }
511
512 trv::ParticleCatalogue& catalogue_for_norm =
513 (flag_rand == "true") ? catalogue_rand : catalogue_data;
514 double alpha_for_norm = (flag_rand == "true") ? alpha : 1.;
515 double norm_factor_part = 0., norm_factor_mesh = 0., norm_factor_meshes = 0.;
516
517 if (params.npoint == "2pt") {
519 catalogue_for_norm, alpha_for_norm
520 );
522 catalogue_for_norm, params, alpha_for_norm
523 );
524 // Mixed-mesh normalisation is only implemented for
525 // paired survey-like catalogues.
526 if (params.catalogue_type == "survey") {
527 // Use default parameters for mixed-mesh normalisation in `pypower`.
528 const double PADDING = 0.1;
529 const double CELLSIZE = 10.;
530 const std::string ASSIGNMENT = "cic";
531 // Box size for normalisation is internally set and as such,
532 // the current alignment of the catalogues is not applicable, but
533 // this should have no effect on the normalisation.
535 catalogue_data, catalogue_rand, params, alpha,
536 PADDING, CELLSIZE, ASSIGNMENT
537 );
538 }
539 } else
540 if (params.npoint == "3pt") {
542 catalogue_for_norm, alpha_for_norm
543 );
545 catalogue_for_norm, params, alpha_for_norm
546 );
547 }
548
549 double norm_factor = 0.;
550 if (params.npoint != "none") {
551 if (params.norm_convention == "none") {
552 norm_factor = 1.;
553 if (trv::sys::currTask == 0) {
554 trv::sys::logger.info(
555 "Normalisation factors: "
556 "%.6e (particle), %.6e (mesh), %.6e (mesh-mixed) (none used).",
557 norm_factor_part, norm_factor_mesh, norm_factor_meshes
558 );
559 }
560 } else
561 if (params.norm_convention == "particle") {
562 norm_factor = norm_factor_part;
563 if (trv::sys::currTask == 0) {
564 trv::sys::logger.info(
565 "Normalisation factors: "
566 "%.6e (particle; used), %.6e (mesh), %.6e (mesh-mixed).",
567 norm_factor, norm_factor_mesh, norm_factor_meshes
568 );
569 }
570 } else
571 if (params.norm_convention == "mesh") {
572 norm_factor = norm_factor_mesh;
573 if (trv::sys::currTask == 0) {
574 trv::sys::logger.info(
575 "Normalisation factors: "
576 "%.6e (particle), %.6e (mesh; used), %.6e (mesh-mixed).",
577 norm_factor_part, norm_factor, norm_factor_meshes
578 );
579 }
580 } else
581 if (params.norm_convention == "mesh-mixed") {
582 norm_factor = norm_factor_meshes;
583 if (trv::sys::currTask == 0) {
584 trv::sys::logger.info(
585 "Normalisation factors: "
586 "%.6e (particle), %.6e (mesh), %.6e (mesh-mixed; used).",
587 norm_factor_part, norm_factor_mesh, norm_factor
588 );
589 }
590 }
591 }
592
593 // ---------------------------------------------------------------------
594 // B.5 Clustering algorithms
595 // ---------------------------------------------------------------------
596
597 char save_filepath[1024];
598 if (params.statistic_type == "powspec") {
599 std::snprintf(
600 save_filepath, sizeof(save_filepath), "%s/pk%d%s",
601 params.measurement_dir.c_str(), params.ELL, params.output_tag.c_str()
602 );
603 std::FILE* save_fileptr = nullptr;
604 trv::PowspecMeasurements meas_powspec; // power spectrum
605 if (params.catalogue_type == "survey") {
606 meas_powspec = trv::compute_powspec(
607 catalogue_data, catalogue_rand, los_data, los_rand,
608 params, binning, norm_factor
609 );
610 save_fileptr = std::fopen(save_filepath, "w");
612 save_fileptr, params, catalogue_data, catalogue_rand,
613 norm_factor_part, norm_factor_mesh, norm_factor_meshes
614 );
615 } else
616 if (params.catalogue_type == "sim") {
617 meas_powspec = trv::compute_powspec_in_gpp_box(
618 catalogue_data, params, binning, norm_factor
619 );
620 save_fileptr = std::fopen(save_filepath, "w");
622 save_fileptr, params, catalogue_data,
623 norm_factor_part, norm_factor_mesh, norm_factor_meshes
624 );
625 }
627 save_fileptr, params, meas_powspec
628 );
629 std::fclose(save_fileptr);
630 } else
631 if (params.statistic_type == "2pcf") {
632 std::snprintf(
633 save_filepath, sizeof(save_filepath), "%s/xi%d%s",
634 params.measurement_dir.c_str(), params.ELL, params.output_tag.c_str()
635 );
636 std::FILE* save_fileptr = nullptr;
637 trv::TwoPCFMeasurements meas_2pcf; // two-point correlation function
638 if (params.catalogue_type == "survey") {
639 meas_2pcf = trv::compute_corrfunc(
640 catalogue_data, catalogue_rand, los_data, los_rand,
641 params, binning, norm_factor
642 );
643 save_fileptr = std::fopen(save_filepath, "w");
645 save_fileptr, params, catalogue_data, catalogue_rand,
646 norm_factor_part, norm_factor_mesh, norm_factor_meshes
647 );
648 } else
649 if (params.catalogue_type == "sim") {
651 catalogue_data, params, binning, norm_factor
652 );
653 save_fileptr = std::fopen(save_filepath, "w");
655 save_fileptr, params, catalogue_data,
656 norm_factor_part, norm_factor_mesh, norm_factor_meshes
657 );
658 }
660 save_fileptr, params, meas_2pcf
661 );
662 std::fclose(save_fileptr);
663 } else
664 if (params.statistic_type == "2pcf-win") {
665 std::snprintf(
666 save_filepath, sizeof(save_filepath), "%s/xiw%d%s",
667 params.measurement_dir.c_str(), params.ELL, params.output_tag.c_str()
668 );
669
671 catalogue_rand, los_rand, params, binning, alpha, norm_factor
672 ); // two-point correlation function window
673 std::FILE* save_fileptr = std::fopen(save_filepath, "w");
675 save_fileptr, params, catalogue_rand,
676 norm_factor_part, norm_factor_mesh, norm_factor_meshes
677 );
679 save_fileptr, params, meas_2pcf_win
680 );
681 std::fclose(save_fileptr);
682 } else
683 if (params.statistic_type == "bispec") {
684 if (params.form == "full" || params.form == "diag") {
685 std::snprintf(
686 save_filepath, sizeof(save_filepath), "%s/bk%d%d%d_%s%s",
687 params.measurement_dir.c_str(),
688 params.ell1, params.ell2, params.ELL,
689 params.form.c_str(),
690 params.output_tag.c_str()
691 );
692 } else
693 if (params.form == "off-diag") {
694 std::snprintf(
695 save_filepath, sizeof(save_filepath), "%s/bk%d%d%d_offdiag%d%s",
696 params.measurement_dir.c_str(),
697 params.ell1, params.ell2, params.ELL, params.idx_bin,
698 params.output_tag.c_str()
699 );
700 } else
701 if (params.form == "row") {
702 std::snprintf(
703 save_filepath, sizeof(save_filepath), "%s/bk%d%d%d_row%d%s",
704 params.measurement_dir.c_str(),
705 params.ell1, params.ell2, params.ELL, params.idx_bin,
706 params.output_tag.c_str()
707 );
708 }
709 std::FILE* save_fileptr = nullptr;
710 trv::BispecMeasurements meas_bispec; // bispectrum
711 if (params.catalogue_type == "survey") {
712 meas_bispec = trv::compute_bispec(
713 catalogue_data, catalogue_rand, los_data, los_rand,
714 params, binning, norm_factor
715 );
716 save_fileptr = std::fopen(save_filepath, "w");
718 save_fileptr, params, catalogue_data, catalogue_rand,
719 norm_factor_part, norm_factor_mesh, norm_factor_meshes
720 );
721 } else
722 if (params.catalogue_type == "sim") {
723 meas_bispec = trv::compute_bispec_in_gpp_box(
724 catalogue_data, params, binning, norm_factor
725 );
726 save_fileptr = std::fopen(save_filepath, "w");
728 save_fileptr, params, catalogue_data,
729 norm_factor_part, norm_factor_mesh, norm_factor_meshes
730 );
731 }
733 save_fileptr, params, meas_bispec
734 );
735 std::fclose(save_fileptr);
736 } else
737 if (params.statistic_type == "3pcf") {
738 if (params.form == "full" || params.form == "diag") {
739 std::snprintf(
740 save_filepath, sizeof(save_filepath), "%s/zeta%d%d%d_%s%s",
741 params.measurement_dir.c_str(),
742 params.ell1, params.ell2, params.ELL,
743 params.form.c_str(),
744 params.output_tag.c_str()
745 );
746 } else
747 if (params.form == "off-diag") {
748 std::snprintf(
749 save_filepath, sizeof(save_filepath), "%s/zeta%d%d%d_offdiag%d%s",
750 params.measurement_dir.c_str(),
751 params.ell1, params.ell2, params.ELL, params.idx_bin,
752 params.output_tag.c_str()
753 );
754 } else
755 if (params.form == "row") {
756 std::snprintf(
757 save_filepath, sizeof(save_filepath), "%s/zeta%d%d%d_row%d%s",
758 params.measurement_dir.c_str(),
759 params.ell1, params.ell2, params.ELL, params.idx_bin,
760 params.output_tag.c_str()
761 );
762 }
763 std::FILE* save_fileptr = nullptr;
764 trv::ThreePCFMeasurements meas_3pcf; // three-point correlation function
765 if (params.catalogue_type == "survey") {
766 meas_3pcf = trv::compute_3pcf(
767 catalogue_data, catalogue_rand, los_data, los_rand,
768 params, binning, norm_factor
769 );
770 save_fileptr = std::fopen(save_filepath, "w");
772 save_fileptr, params, catalogue_data, catalogue_rand,
773 norm_factor_part, norm_factor_mesh, norm_factor_meshes
774 );
775 } else
776 if (params.catalogue_type == "sim") {
778 catalogue_data, params, binning, norm_factor
779 );
780 save_fileptr = std::fopen(save_filepath, "w");
782 save_fileptr, params, catalogue_data,
783 norm_factor_part, norm_factor_mesh, norm_factor_meshes
784 );
785 }
787 save_fileptr, params, meas_3pcf
788 );
789 std::fclose(save_fileptr);
790 } else
791 if (params.statistic_type == "3pcf-win") {
792 if (params.form == "full" || params.form == "diag") {
793 std::snprintf(
794 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_%s%s",
795 params.measurement_dir.c_str(),
796 params.ell1, params.ell2, params.ELL,
797 params.form.c_str(),
798 params.output_tag.c_str()
799 );
800 } else
801 if (params.form == "off-diag") {
802 std::snprintf(
803 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_offdiag%d%s",
804 params.measurement_dir.c_str(),
805 params.ell1, params.ell2, params.ELL, params.idx_bin,
806 params.output_tag.c_str()
807 );
808 } else
809 if (params.form == "row") {
810 std::snprintf(
811 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_row%d%s",
812 params.measurement_dir.c_str(),
813 params.ell1, params.ell2, params.ELL, params.idx_bin,
814 params.output_tag.c_str()
815 );
816 }
817 bool wa = false;
818
820 catalogue_rand, los_rand, params, binning, alpha, norm_factor, wa
821 ); // three-point correlation function window
822 std::FILE* save_fileptr = std::fopen(save_filepath, "w");
824 save_fileptr, params, catalogue_rand,
825 norm_factor_part, norm_factor_mesh, norm_factor_meshes
826 );
828 save_fileptr, params, meas_3pcf_win
829 );
830 std::fclose(save_fileptr);
831 } else
832 if (params.statistic_type == "3pcf-win-wa") {
833 if (params.form == "full" || params.form == "diag") {
834 std::snprintf(
835 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_wa%d%d_%s%s",
836 params.measurement_dir.c_str(),
837 params.ell1, params.ell2, params.ELL, params.i_wa, params.j_wa,
838 params.form.c_str(),
839 params.output_tag.c_str()
840 );
841 } else
842 if (params.form == "off-diag") {
843 std::snprintf(
844 save_filepath, sizeof(save_filepath),
845 "%s/zetaw%d%d%d_wa%d%d_offdiag%d%s",
846 params.measurement_dir.c_str(),
847 params.ell1, params.ell2, params.ELL, params.i_wa, params.j_wa,
848 params.idx_bin,
849 params.output_tag.c_str()
850 );
851 } else
852 if (params.form == "row") {
853 std::snprintf(
854 save_filepath, sizeof(save_filepath), "%s/zetaw%d%d%d_wa%d%d_row%d%s",
855 params.measurement_dir.c_str(),
856 params.ell1, params.ell2, params.ELL, params.i_wa, params.j_wa,
857 params.idx_bin,
858 params.output_tag.c_str()
859 );
860 }
861
862 bool wa = true;
863
864 trv::ThreePCFWindowMeasurements meas_3pcf_win_wa =
866 catalogue_rand, los_rand, params, binning, alpha, norm_factor, wa
867 ); // three-point correlation function window wide-angle corrections
868 std::FILE* save_fileptr = std::fopen(save_filepath, "w");
870 save_fileptr, params, catalogue_rand,
871 norm_factor_part, norm_factor_mesh, norm_factor_meshes
872 );
874 save_fileptr, params, meas_3pcf_win_wa
875 );
876 std::fclose(save_fileptr);
877 }
878
879 if (params.save_binned_vectors != "") {
880 trv::FieldStats binning_meshgrid(params, false);
881 trv::BinnedVectors binned_vectors = binning_meshgrid.record_binned_vectors(
882 binning, params.save_binned_vectors
883 );
884 if (params.statistic_type == "modes" || params.statistic_type == "pairs") {
885 std::snprintf(
886 save_filepath, sizeof(save_filepath), "%s",
887 params.save_binned_vectors.c_str()
888 );
889 }
890 }
891
892 if (trv::sys::currTask == 0) {
893 trv::sys::logger.info("Measurements saved to: %s", save_filepath);
894 }
895
896 // =====================================================================
897 // C Finalisation
898 // =====================================================================
899
900 if (trv::sys::currTask == 0) {
901 trv::sys::logger.stat("[MAIN:TRV:C] Data objects are being cleared.");
902 }
903
904 // Clear persistent and dynamic memory.
906#if defined(TRV_USE_OMP) && defined(TRV_USE_FFTWOMP)
907 fftw_cleanup_threads();
908#else // !TRV_USE_OMP || !TRV_USE_FFTWOMP
909 fftw_cleanup();
910#endif // TRV_USE_OMP && TRV_USE_FFTWOMP
911 }
912
913 catalogue_data.finalise_particles();
914 catalogue_rand.finalise_particles();
915
916 if (los_data != nullptr) {
917 delete[] los_data; los_data = nullptr;
918 }
919 if (los_rand != nullptr) {
920 delete[] los_rand; los_rand = nullptr;
921 }
923 (catalogue_data.ntotal + catalogue_rand.ntotal)
924 );
925
927 if (trv::sys::currTask == 0) {
928 trv::sys::logger.info(
929 "Number of FFTs: %d forward, %d backward.",
931 );
932 }
933 }
934
935 if (
939 ) {
940 if (trv::sys::currTask == 0) {
941 trv::sys::logger.info(
942 "Maximum number of concurrent 3-d grids: "
943 "%.1f complex-equivalent, %d complex, %d real.",
946 );
947 }
948 }
949
950 if (trv::sys::currTask == 0) {
951 trv::sys::logger.info(
952 "Minimal estimate of peak memory usage: %.1f gibibytes.",
954 );
956 trv::sys::logger.info(
957 "Minimal estimate of peak GPU memory usage: %.1f gibibytes.",
959 );
960 }
961 }
962 if (trv::sys::gbytesMem > 0.) {
963 if (trv::sys::currTask == 0) {
964 trv::sys::logger.warn(
965 "Uncleared dynamically allocated memory: %.1f gibibytes.",
967 );
968 }
969 }
970 if (trv::sys::gbytesMemGPU > 0.) {
971 if (trv::sys::currTask == 0) {
972 trv::sys::logger.warn(
973 "Uncleared dynamically allocated GPU memory: %.1f gibibytes.",
975 );
976 }
977 }
978
979 if (trv::sys::currTask == 0) {
981 }
982
983 return 0;
984}
Isotropic coordinate binning.
Definition dataobjs.hpp:58
std::vector< double > bin_widths
bin widths
Definition dataobjs.hpp:67
std::vector< double > bin_edges
bin edges
Definition dataobjs.hpp:65
std::vector< double > bin_centres
bin centres
Definition dataobjs.hpp:66
std::string space
coordinate space
Definition dataobjs.hpp:60
double bin_max
highest bin edge
Definition dataobjs.hpp:63
void set_bins(double coord_min, double coord_max, int nbin)
Set bins.
Definition dataobjs.cpp:58
int num_bins
number of bins
Definition dataobjs.hpp:64
Field (pseudo-two-point) statistics.
Definition field.hpp:582
trv::BinnedVectors record_binned_vectors(trv::Binning &binning, const std::string &save_file)
Record binned vectors given a binning scheme.
Definition field.cpp:2317
Parameter set.
std::string alignment
box alignment: {"centre" (default), "pad"}
std::string catalogue_columns
long long nmesh
number of mesh grid cells
std::string output_tag
output tag
std::string catalogue_dataset
catalogue dataset name/path (HDF5 catalogue files only)
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 cell 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:78
static void centre_in_box(ParticleCatalogue &catalogue, const double boxsize[3])
Centre a catalogue in a box.
int load_catalogue_file(const std::string &catalogue_filepath, const std::string &catalogue_columns, const std::string &catalogue_dataset="", double volume=0.)
Read in a catalogue file.
Definition particles.cpp:94
void finalise_particles()
Finalise particle data container.
Definition particles.cpp:68
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.
double pos_span[3]
span of particle coordinates
Definition particles.hpp:90
int ntotal
total number of particles
Definition particles.hpp:84
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:86
Exception raised when an input/output operation fails.
Definition monitor.hpp:707
Exception raised when parameters are invalid.
Definition monitor.hpp:731
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:102
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:360
double get_vec3d_magnitude(std::vector< double > vec)
Return the magnitude of a 3-d vector.
Definition maths.cpp:53
double gbytesMem
current memory usage in gibibytes
Definition monitor.cpp:94
void display_help()
Display help message in stdout.
Definition monitor.cpp:856
void update_maxmem(bool gpu=false)
Update the maximum memory usage estimate.
Definition monitor.cpp:165
double size_in_gb(long long num)
Return size in gibibytes.
Definition monitor.hpp:281
bool is_gpu_enabled()
Check if GPU mode is enabled.
Definition monitor.cpp:297
void display_prog_logo()
Display program logo in stdout.
Definition monitor.cpp:871
float max_count_grid
maximum number of grids
Definition monitor.cpp:105
Logger logger
default logger (at NSET logging level)
int max_count_rgrid
maximum number of 3-d real grids
Definition monitor.cpp:103
void make_write_dir(std::string dirstr)
Make write directory.
Definition io.cpp:59
void display_prog_licence(bool brief=false)
Display program licence in stdout.
Definition monitor.cpp:890
double gbytesMemGPU
current (GPU) memory usage in gibibytes
Definition monitor.cpp:97
bool if_filepath_is_set(const std::string &pathstr)
Check if a file path is set.
Definition io.cpp:39
double gbytesMaxMemGPU
maximum (GPU) memory usage in gibibytes
Definition monitor.cpp:98
int max_count_cgrid
maximum number of 3-d complex grids
Definition monitor.cpp:104
int currTask
current task
Definition monitor.cpp:92
void display_prog_logbars(int endpoint)
Display program log bars in stdout.
Definition monitor.cpp:994
int count_fft
number of FFTs
Definition monitor.cpp:107
double gbytesMaxMem
maximum memory usage in gibibytes
Definition monitor.cpp:95
int count_ifft
number of IFFTs
Definition monitor.cpp:108
void display_prog_info(bool runtime=false)
Display program information in stdout.
Definition monitor.cpp:930
void exit_fatal(const std::string &msg)
Terminate the program with exit status EXIT_FAILURE.
Definition monitor.cpp:326
double calc_bispec_normalisation_from_particles(ParticleCatalogue &particles, double alpha=1.)
Calculate particle-based bispectrum normalisation.
Definition threept.cpp:96
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:2190
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:795
void set_ngrid_from_cutoff(trv::ParameterSet &params)
Set the grid cell numbers from the box size and the Nyquist cutoff.
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:498
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:609
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:1473
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:2621
double calc_powspec_normalisation_from_particles(ParticleCatalogue &particles, double alpha=1.)
Calculate particle-based power spectrum normalisation.
Definition twopt.cpp:56
double calc_bispec_normalisation_from_mesh(ParticleCatalogue &particles, trv::ParameterSet &params, double alpha=1.)
Calculate mesh-based bispectrum normalisation.
Definition threept.cpp:138
double calc_powspec_normalisation_from_mesh(trv::ParticleCatalogue &particles, trv::ParameterSet &params, double alpha=1.)
Calculate mesh-based power spectrum normalisation.
Definition twopt.cpp:98
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:388
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:248
void set_boxsize_from_expand(const double *spans, trv::ParameterSet &params)
Set the box size parameters from the box expansion factor.
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:1014
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:703
void override_paramset_by_envvars(trv::ParameterSet &params)
Override parameter set by environment variables.
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:111
Program parameter configuration.
Particle containers with I/O methods and operations.
Binned vectors.
Definition dataobjs.hpp:166
Bispectrum measurements.
Definition dataobjs.hpp:249
Line-of-sight vector.
Definition dataobjs.hpp:186
double pos[3]
3-d position vector
Definition dataobjs.hpp:187
Power spectrum measurements.
Definition dataobjs.hpp:202
Three-point correlation function measurements.
Definition dataobjs.hpp:267
Three-point correlation function window measurements.
Definition dataobjs.hpp:288
Two-point correlation function measurements.
Definition dataobjs.hpp:217
Two-point correlation function window measurements.
Definition dataobjs.hpp:230
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.