Triumvirate C++ API 0.5.0.post1.dev301+g026f21751
Three-point clustering measurements in large-scale structure analyses.
Loading...
Searching...
No Matches
parameters.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
28
29#include "parameters.hpp"
30
31namespace trvs = trv::sys;
32
33namespace trv {
34
36 // Copy I/O parameters.
37 this->catalogue_dir = other.catalogue_dir;
38 this->measurement_dir = other.measurement_dir;
43 this->output_tag = other.output_tag;
44
45 // Copy mesh sampling parameters.
46 for (int i = 0; i < 3; i++) {
47 this->boxsize[i] = other.boxsize[i];
48 this->ngrid[i] = other.ngrid[i];
49 }
50 this->expand = other.expand;
51 this->alignment = other.alignment;
52 this->padscale = other.padscale;
53 this->padfactor = other.padfactor;
54 this->assignment = other.assignment;
55 this->interlace = other.interlace;
56 this->volume = other.volume;
57 this->nmesh = other.nmesh;
59
60 // Copy measurement parameters.
61 this->catalogue_type = other.catalogue_type;
62 this->statistic_type = other.statistic_type;
63 this->npoint = other.npoint;
64 this->space = other.space;
65 this->ell1 = other.ell1;
66 this->ell2 = other.ell2;
67 this->ELL = other.ELL;
68 this->i_wa = other.i_wa;
69 this->j_wa = other.j_wa;
70 this->form = other.form;
71 this->norm_convention = other.norm_convention;
72 this->binning = other.binning;
73 this->bin_min = other.bin_min;
74 this->bin_max = other.bin_max;
75 this->num_bins = other.num_bins;
76 this->idx_bin = other.idx_bin;
77 this->cutoff_nyq = other.cutoff_nyq;
78
79 // Copy misc parameters.
80 this->fftw_scheme = other.fftw_scheme;
82 this->use_fftw_wisdom = other.use_fftw_wisdom;
86 this->verbose = other.verbose;
87 this->progbar = other.progbar;
88
89 // Copy private parameters.
90 this->data_catalogue_files = other.data_catalogue_files;
91 this->rand_catalogue_files = other.rand_catalogue_files;
92}
93
94int ParameterSet::read_from_file(char* parameter_filepath) {
95 // ---------------------------------------------------------------------
96 // Initialisation
97 // ---------------------------------------------------------------------
98
99 // Load parameter file.
100 std::string param_filepath = parameter_filepath;
101
102 std::ifstream fin(param_filepath.c_str());
103
104 // Initialise temporary variables to hold the extracted parameters.
105 // NOTE: Assume file systems allow path character lengths up to 4096,
106 // and up to 64 files of this maximum lengths are stored in the
107 // char arrays.
108 char catalogue_dir_[1024] = "";
109 char measurement_dir_[1024] = "";
110 char data_catalogue_file_[262144] = "";
111 char rand_catalogue_file_[262144] = "";
112 char catalogue_columns_[1024] = "";
113 char catalogue_dataset_[1024] = "";
114 char output_tag_[1024] = "";
115
116 double boxsize_x, boxsize_y, boxsize_z;
117 int ngrid_x, ngrid_y, ngrid_z;
118
119 char alignment_[16] = "";
120 char padscale_[16] = "";
121 char assignment_[16] = "";
122 char interlace_[16] = "";
123
124 char catalogue_type_[16] = "";
125 char statistic_type_[16] = "";
126 char form_[16] = "";
127 char norm_convention_[16] = "";
128 char binning_[16] = "";
129
130 char fftw_scheme_[16] = "";
131 char use_fftw_wisdom_[1024] = "";
132 char save_binned_vectors_[1024] = "";
133 char progbar_[16] = "";
134
135 // ---------------------------------------------------------------------
136 // Extraction
137 // ---------------------------------------------------------------------
138
139 std::string line_str;
140 char dummy_str[1024], dummy_equal[1024];
141 while (std::getline(fin, line_str)) {
142 // Check if the line is a parameter assignment.
143 if (line_str.find("#") == 0) {
144 continue;
145 } // skip comment lines
146 if (
147 std::sscanf(
148 line_str.data(), "%1023s %1023s %1023s",
149 dummy_str, dummy_equal, dummy_str
150 ) != 3
151 ) {
152 continue;
153 } // skip non-relation lines
154 if (std::strcmp(dummy_equal, "=") != 0) {
155 continue;
156 } // skip non-assignment lines
157
158 // Define convenience function for scanning string parameters.
159 auto scan_par_str = [line_str, dummy_str, dummy_equal](
160 const char* par_name, const char* fmt, const char* par_value
161 ) {
162 if (line_str.find(par_name) != std::string::npos) {
163 std::sscanf(
164 line_str.data(), fmt, dummy_str, dummy_equal, par_value
165 );
166 }
167 };
168
169 // -- I/O ------------------------------------------------------------
170
171 scan_par_str("catalogue_dir", "%s %s %s", catalogue_dir_);
172 scan_par_str("measurement_dir", "%s %s %s", measurement_dir_);
173 scan_par_str("data_catalogue_file", "%s %s %s", data_catalogue_file_);
174 scan_par_str("rand_catalogue_file", "%s %s %s", rand_catalogue_file_);
175 scan_par_str("catalogue_columns", "%s %s %s", catalogue_columns_);
176 scan_par_str("catalogue_dataset", "%s %s %s", catalogue_dataset_);
177 scan_par_str("output_tag", "%s %s %s", output_tag_);
178
179 // -- Mesh sampling --------------------------------------------------
180
181 if (line_str.find("boxsize_x") != std::string::npos) {
182 std::sscanf(
183 line_str.data(), "%1023s %1023s %lg",
184 dummy_str, dummy_equal, &boxsize_x
185 );
186 }
187 if (line_str.find("boxsize_y") != std::string::npos) {
188 std::sscanf(
189 line_str.data(), "%1023s %1023s %lg",
190 dummy_str, dummy_equal, &boxsize_y
191 );
192 }
193 if (line_str.find("boxsize_z") != std::string::npos) {
194 std::sscanf(
195 line_str.data(), "%1023s %1023s %lg",
196 dummy_str, dummy_equal, &boxsize_z
197 );
198 }
199
200 if (line_str.find("ngrid_x") != std::string::npos) {
201 std::sscanf(
202 line_str.data(), "%1023s %1023s %d",
203 dummy_str, dummy_equal, &ngrid_x
204 );
205 }
206 if (line_str.find("ngrid_y") != std::string::npos) {
207 std::sscanf(
208 line_str.data(), "%1023s %1023s %d",
209 dummy_str, dummy_equal, &ngrid_y
210 );
211 }
212 if (line_str.find("ngrid_z") != std::string::npos) {
213 std::sscanf(
214 line_str.data(), "%1023s %1023s %d", dummy_str, dummy_equal, &ngrid_z
215 );
216 }
217
218 if (line_str.find("expand") != std::string::npos) {
219 std::sscanf(
220 line_str.data(), "%1023s %1023s %lg",
221 dummy_str, dummy_equal, &this->expand
222 );
223 }
224
225 scan_par_str("alignment", "%1023s %1023s %1023s", alignment_);
226 scan_par_str("padscale", "%1023s %1023s %1023s", padscale_);
227
228 if (line_str.find("padfactor") != std::string::npos) {
229 std::sscanf(
230 line_str.data(), "%1023s %1023s %lg",
231 dummy_str, dummy_equal, &this->padfactor
232 );
233 }
234
235 scan_par_str("assignment", "%1023s %1023s %1023s", assignment_);
236 scan_par_str("interlace", "%1023s %1023s %1023s", interlace_);
237
238 // -- Measurement ----------------------------------------------------
239
240 scan_par_str("catalogue_type", "%1023s %1023s %1023s", catalogue_type_);
241 scan_par_str("statistic_type", "%1023s %1023s %1023s", statistic_type_);
242 scan_par_str("form", "%1023s %1023s %1023s", form_);
243 scan_par_str("norm_convention", "%1023s %1023s %1023s", norm_convention_);
244 scan_par_str("binning", "%1023s %1023s %1023s", binning_);
245
246 if (line_str.find("ell1") != std::string::npos) {
247 std::sscanf(
248 line_str.data(), "%1023s %1023s %d",
249 dummy_str, dummy_equal, &this->ell1
250 );
251 }
252 if (line_str.find("ell2") != std::string::npos) {
253 std::sscanf(
254 line_str.data(), "%1023s %1023s %d",
255 dummy_str, dummy_equal, &this->ell2
256 );
257 }
258 if (line_str.find("ELL") != std::string::npos) {
259 std::sscanf(
260 line_str.data(), "%1023s %1023s %d",
261 dummy_str, dummy_equal, &this->ELL
262 );
263 }
264
265 if (line_str.find("i_wa") != std::string::npos) {
266 std::sscanf(
267 line_str.data(), "%1023s %1023s %d",
268 dummy_str, dummy_equal, &this->i_wa
269 );
270 }
271 if (line_str.find("j_wa") != std::string::npos) {
272 std::sscanf(
273 line_str.data(), "%1023s %1023s %d",
274 dummy_str, dummy_equal, &this->j_wa
275 );
276 }
277
278 if (line_str.find("bin_min") != std::string::npos) {
279 std::sscanf(
280 line_str.data(), "%1023s %1023s %lg",
281 dummy_str, dummy_equal, &this->bin_min
282 );
283 }
284 if (line_str.find("bin_max") != std::string::npos) {
285 std::sscanf(
286 line_str.data(), "%1023s %1023s %lg",
287 dummy_str, dummy_equal, &this->bin_max
288 );
289 }
290
291 if (line_str.find("num_bins") != std::string::npos) {
292 std::sscanf(
293 line_str.data(), "%1023s %1023s %d",
294 dummy_str, dummy_equal, &this->num_bins
295 );
296 }
297 if (line_str.find("idx_bin") != std::string::npos) {
298 std::sscanf(
299 line_str.data(), "%1023s %1023s %d",
300 dummy_str, dummy_equal, &this->idx_bin
301 );
302 }
303
304 if (line_str.find("cutoff_nyq") != std::string::npos) {
305 std::sscanf(
306 line_str.data(), "%1023s %1023s %lg",
307 dummy_str, dummy_equal, &this->cutoff_nyq
308 );
309 }
310
311 // -- Misc -------------------------------------------------------------
312
313 scan_par_str("fftw_scheme", "%1023s %1023s %1023s", fftw_scheme_);
314 scan_par_str("use_fftw_wisdom", "%1023s %1023s %1023s", use_fftw_wisdom_);
315 scan_par_str(
316 "save_binned_vectors", "%1023s %1023s %1023s", save_binned_vectors_
317 );
318 scan_par_str("progbar", "%1023s %1023s %1023s", progbar_);
319
320 if (line_str.find("verbose") != std::string::npos) {
321 std::sscanf(
322 line_str.data(), "%1023s %1023s %d",
323 dummy_str, dummy_equal, &this->verbose
324 );
325 }
326 }
327
328 // ---------------------------------------------------------------------
329 // Attribution
330 // ---------------------------------------------------------------------
331
332 // Attribute numerical parameters (directly extracted above).
333
334 // Attribute string parameters.
335 this->catalogue_dir = catalogue_dir_;
336 this->measurement_dir = measurement_dir_;
337 this->data_catalogue_file = data_catalogue_file_;
338 this->rand_catalogue_file = rand_catalogue_file_;
339 this->catalogue_columns = catalogue_columns_;
340 this->catalogue_dataset = catalogue_dataset_;
341 this->output_tag = output_tag_;
342
343 if (strlen(alignment_) > 0) {
344 this->alignment = alignment_;
345 }
346 if (strlen(padscale_) > 0) {
347 this->padscale = padscale_;
348 }
349 if (strlen(assignment_) > 0) {
350 this->assignment = assignment_;
351 }
352 if (strlen(interlace_) > 0) {
353 this->interlace = interlace_;
354 }
355
356 this->catalogue_type = catalogue_type_;
357 this->statistic_type = statistic_type_;
358 if (strlen(form_) > 0) {
359 this->form = form_;
360 }
361 if (strlen(norm_convention_) > 0) {
362 this->norm_convention = norm_convention_;
363 }
364 if (strlen(binning_) > 0) {
365 this->binning = binning_;
366 }
367
368 if (strlen(fftw_scheme_) > 0) {
369 this->fftw_scheme = fftw_scheme_;
370 }
371 if (strlen(use_fftw_wisdom_) > 0) {
372 this->use_fftw_wisdom = use_fftw_wisdom_;
373 }
374 if (strlen(save_binned_vectors_) > 0) {
375 this->save_binned_vectors = save_binned_vectors_;
376 }
377 if (strlen(progbar_) > 0) {
378 this->progbar = progbar_;
379 }
380
381 // Attribute derived parameters.
382 this->boxsize[0] = boxsize_x;
383 this->boxsize[1] = boxsize_y;
384 this->boxsize[2] = boxsize_z;
385
386 this->ngrid[0] = ngrid_x;
387 this->ngrid[1] = ngrid_y;
388 this->ngrid[2] = ngrid_z;
389
390 this->volume = boxsize_x * boxsize_y * boxsize_z;
391 this->nmesh = ngrid_x * ngrid_y * ngrid_z;
392
393 // ---------------------------------------------------------------------
394 // Debugging mode
395 // ---------------------------------------------------------------------
396
397#ifdef DBG_PARS
398 // Define convenience function for displaying debugged parameters.
399 auto debug_par_str = [](const std::string& name, const std::string& value) {
400 std::cout << name << ": " << value << std::endl;
401 };
402 auto debug_par_int = [](const std::string& name, int value) {
403 std::cout << name << ": " << value << std::endl;
404 };
405 auto debug_par_longlong = [](const std::string& name, long long value) {
406 std::cout << name << ": " << value << std::endl;
407 };
408 auto debug_par_double = [](const std::string& name, double value) {
409 std::cout << name << ": " << value << std::endl;
410 };
411
412 // Display debugged parameters.
413 debug_par_str("catalogue_dir", this->catalogue_dir);
414 debug_par_str("measurement_dir", this->measurement_dir);
415 debug_par_str("data_catalogue_file", this->data_catalogue_file);
416 debug_par_str("rand_catalogue_file", this->rand_catalogue_file);
417 debug_par_str("catalogue_columns", this->catalogue_columns);
418 debug_par_str("catalogue_dataset", this->catalogue_dataset);
419 debug_par_str("output_tag", this->output_tag);
420
421 debug_par_str("alignment", this->alignment);
422 debug_par_str("padscale", this->padscale);
423 debug_par_str("assignment", this->assignment);
424 debug_par_str("interlace", this->interlace);
425
426 debug_par_str("catalogue_type", this->catalogue_type);
427 debug_par_str("statistic_type", this->statistic_type);
428 debug_par_str("form", this->form);
429 debug_par_str("norm_convention", this->norm_convention);
430 debug_par_str("binning", this->binning);
431
432 debug_par_str("fftw_scheme", this->fftw_scheme);
433 debug_par_str("use_fftw_wisdom", this->use_fftw_wisdom);
434 debug_par_str("save_binned_vectors", this->save_binned_vectors);
435 debug_par_str("progbar", this->progbar);
436
437 debug_par_int("ngrid[0]", this->ngrid[0]);
438 debug_par_int("ngrid[1]", this->ngrid[1]);
439 debug_par_int("ngrid[2]", this->ngrid[2]);
440
441 debug_par_longlong("nmesh", this->nmesh);
442
443 debug_par_int("ell1", this->ell1);
444 debug_par_int("ell2", this->ell2);
445 debug_par_int("ELL", this->ELL);
446 debug_par_int("i_wa", this->i_wa);
447 debug_par_int("j_wa", this->j_wa);
448
449 debug_par_int("num_bins", this->num_bins);
450 debug_par_int("idx_bin", this->idx_bin);
451
452 debug_par_double("boxsize[0]", this->boxsize[0]);
453 debug_par_double("boxsize[1]", this->boxsize[1]);
454 debug_par_double("boxsize[2]", this->boxsize[2]);
455 debug_par_double("expand", this->expand);
456 debug_par_double("volume", this->volume);
457 debug_par_double("padfactor", this->padfactor);
458 debug_par_double("bin_min", this->bin_min);
459 debug_par_double("bin_max", this->bin_max);
460 debug_par_double("cutoff_nyq", this->cutoff_nyq);
461#endif // DBG_PARS
462
463 return this->validate(true);
464}
465
467 trvs::logger.reset_level(this->verbose);
468
469 // Validate and derive string parameters.
470 // Any duplicate '/' has no effect.
471 if (
472 this->catalogue_dir.find_first_not_of(" \t\n\r\v\f") != std::string::npos
473 && init
474 ) {
475 this->catalogue_dir += "/"; // transmutation
476 }
477 if (
478 this->measurement_dir.find_first_not_of(" \t\n\r\v\f") == std::string::npos
479 ) {
480 this->measurement_dir = "./"; // transmutation
481 } else
482 if (init) {
483 this->measurement_dir += "/"; // transmutation
484 }
487
488 // Parse catalogue filenames by delimiter.
489 if (
490 this->data_catalogue_file.find_first_not_of(" \t\n\r\v\f")
491 != std::string::npos
492 ) {
493 if (!trvs::has_extension(this->data_catalogue_file, trvs::fn_delimiter)) {
494 this->data_catalogue_file += trvs::fn_delimiter; // transmutation
495 }
496 }
497 if (
498 this->rand_catalogue_file.find_first_not_of(" \t\n\r\v\f")
499 != std::string::npos
500 ) {
501 if (!trvs::has_extension(this->rand_catalogue_file, trvs::fn_delimiter)) {
502 this->rand_catalogue_file += trvs::fn_delimiter; // transmutation
503 }
504 }
505
506 this->data_catalogue_files.clear();
507 this->rand_catalogue_files.clear();
508
509 std::string data_ctlg_files, rand_ctlg_files;
510 std::string data_ctlg_file_, rand_ctlg_file_;
511 size_t dlpos = 0;
512
513 if (this->catalogue_type == "survey") {
514 if (this->data_catalogue_file != "") {
515 data_ctlg_files = this->data_catalogue_file;
516 dlpos = 0;
517 while (
518 (dlpos = data_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
519 ) {
520 data_ctlg_file_ = data_ctlg_files.substr(0, dlpos);
521 data_ctlg_files.erase(0, dlpos + trvs::fn_delimiter.length());
522 if (data_ctlg_file_.rfind("/", 0) != 0 && init) {
523 data_ctlg_file_ = this->catalogue_dir + data_ctlg_file_;
524 } // transmutation
525 trvs::expand_envar_in_path(data_ctlg_file_);
526 this->data_catalogue_files.push_back(data_ctlg_file_);
527 }
528 // if (this->data_catalogue_files.empty()) {
529 // if (this->data_catalogue_file.rfind("/", 0) != 0 && init) {
530 // this->data_catalogue_file =
531 // this->catalogue_dir + this->data_catalogue_file;
532 // } // transmutation
533 // this->data_catalogue_files.push_back(this->data_catalogue_file);
534 // }
535 }
536 if (this->rand_catalogue_file != "") {
537 rand_ctlg_files = this->rand_catalogue_file;
538 dlpos = 0;
539 while (
540 (dlpos = rand_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
541 ) {
542 rand_ctlg_file_ = rand_ctlg_files.substr(0, dlpos);
543 rand_ctlg_files.erase(0, dlpos + trvs::fn_delimiter.length());
544 if (rand_ctlg_file_.rfind("/", 0) != 0 && init) {
545 rand_ctlg_file_ = this->catalogue_dir + rand_ctlg_file_;
546 } // transmutation
547 trvs::expand_envar_in_path(rand_ctlg_file_);
548 this->rand_catalogue_files.push_back(rand_ctlg_file_);
549 }
550 // if (this->rand_catalogue_files.empty()) {
551 // if (this->rand_catalogue_file.rfind("/", 0) != 0 && init) {
552 // this->rand_catalogue_file =
553 // this->catalogue_dir + this->rand_catalogue_file;
554 // } // transmutation
555 // this->rand_catalogue_files.push_back(this->rand_catalogue_file);
556 // }
557 }
558 } else
559 if (this->catalogue_type == "random") {
560 this->data_catalogue_file = ""; // transmutation
561 if (this->rand_catalogue_file != "") {
562 rand_ctlg_files = this->rand_catalogue_file;
563 dlpos = 0;
564 while (
565 (dlpos = rand_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
566 ) {
567 rand_ctlg_file_ = rand_ctlg_files.substr(0, dlpos);
568 rand_ctlg_files.erase(0, dlpos + trvs::fn_delimiter.length());
569 if (rand_ctlg_file_.rfind("/", 0) != 0 && init) {
570 rand_ctlg_file_ = this->catalogue_dir + rand_ctlg_file_;
571 } // transmutation
572 trvs::expand_envar_in_path(rand_ctlg_file_);
573 this->rand_catalogue_files.push_back(rand_ctlg_file_);
574 }
575 // if (this->rand_catalogue_files.empty()) {
576 // if (this->rand_catalogue_file.rfind("/", 0) != 0 && init) {
577 // this->rand_catalogue_file =
578 // this->catalogue_dir + this->rand_catalogue_file;
579 // } // transmutation
580 // this->rand_catalogue_files.push_back(this->rand_catalogue_file);
581 // }
582 }
583 } else
584 if (this->catalogue_type == "sim") {
585 if (this->data_catalogue_file != "") {
586 data_ctlg_files = this->data_catalogue_file;
587 dlpos = 0;
588 while (
589 (dlpos = data_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
590 ) {
591 data_ctlg_file_ = data_ctlg_files.substr(0, dlpos);
592 data_ctlg_files.erase(0, dlpos + trvs::fn_delimiter.length());
593 if (data_ctlg_file_.rfind("/", 0) != 0 && init) {
594 data_ctlg_file_ = this->catalogue_dir + data_ctlg_file_;
595 } // transmutation
596 trvs::expand_envar_in_path(data_ctlg_file_);
597 this->data_catalogue_files.push_back(data_ctlg_file_);
598 }
599 // if (this->data_catalogue_files.empty()) {
600 // if (this->data_catalogue_file.rfind("/", 0) != 0 && init) {
601 // this->data_catalogue_file =
602 // this->catalogue_dir + this->data_catalogue_file;
603 // } // transmutation
604 // this->data_catalogue_files.push_back(this->data_catalogue_file);
605 // }
606 }
607 this->rand_catalogue_file = ""; // transmutation
608 } else
609 if (this->catalogue_type == "none") {
610 // Nothing should happen.
611 } else {
612#ifndef TRV_EXTCALL
613 if (trvs::currTask == 0) {
614 trvs::logger.error(
615 "Catalogue type must be 'survey', 'random', 'sim' or 'none: "
616 "`catalogue_type` = '%s'.",
617 this->catalogue_type.c_str()
618 );
619 }
621 "Catalogue type must be 'survey', 'random', 'sim' or 'none': "
622 "`catalogue_type` = '%s'.",
623 this->catalogue_type.c_str()
624 );
625#endif // !TRV_EXTCALL
626 }
628 this->data_catalogue_files, trvs::fn_delimiter
629 );
631 this->rand_catalogue_files, trvs::fn_delimiter
632 );
633
634 if (!(this->alignment == "centre" || this->alignment == "pad")) {
635 if (trvs::currTask == 0) {
636 trvs::logger.error(
637 "Box alignment must be 'centre' or 'pad': `alignment` = '%s'.",
638 this->alignment.c_str()
639 );
640 }
642 "Box alignment must be 'centre' or 'pad': `alignment` = '%s'.",
643 this->alignment.c_str()
644 );
645 }
646 if (!(this->padscale == "box" || this->padscale == "grid")) {
647 if (trvs::currTask == 0) {
648 trvs::logger.error(
649 "Pad scale must be 'box' or 'grid': `padscale` = '%s'.",
650 this->padscale.c_str()
651 );
652 }
654 "Pad scale must be 'box' or 'grid': `padscale` = '%s'.",
655 this->padscale.c_str()
656 );
657 }
658
659 if (this->assignment == "ngp") {
660 this->assignment_order = 1;
661 } else
662 if (this->assignment == "cic") {
663 this->assignment_order = 2;
664 } else
665 if (this->assignment == "tsc") {
666 this->assignment_order = 3;
667 } else
668 if (this->assignment == "pcs") {
669 this->assignment_order = 4;
670 } else {
671 if (trvs::currTask == 0) {
672 trvs::logger.error(
673 "Mesh assignment scheme must be "
674 "'ngp', 'cic', 'tsc' or 'pcs': `assignment` = '%s'.",
675 this->assignment.c_str()
676 );
677 }
679 "Mesh assignment scheme must be "
680 "'ngp', 'cic', 'tsc' or 'pcs': `assignment` = '%s'.",
681 this->assignment.c_str()
682 );
683 }
684 if (this->interlace == "true" || this->interlace == "on") {
685 this->interlace = "true"; // transmutation
686 } else
687 if (this->interlace == "false" || this->interlace == "off") {
688 this->interlace = "false"; // transmutation
689 } else {
690 if (trvs::currTask == 0) {
691 trvs::logger.error(
692 "Interlacing must be 'true'/'on' or 'false'/'off': "
693 "`interlace` = '%s'.",
694 this->interlace.c_str()
695 );
696 }
698 "Interlacing must be 'true'/'on' or 'false'/'off': "
699 "`interlace` = '%s'.",
700 this->interlace.c_str()
701 );
702 }
703
704 if (this->statistic_type == "powspec") {
705 this->npoint = "2pt"; this->space = "fourier"; // derivation
706 if (this->catalogue_type == "random" || this->catalogue_type == "none") {
707 if (trvs::currTask == 0) {
708 trvs::logger.error(
709 "Power spectrum requires 'sim' or 'survey' catalogue(s): "
710 "`catalogue_type` = '%s'.",
711 this->catalogue_type.c_str()
712 );
713 }
715 "Power spectrum requires 'sim' or 'survey' catalogue(s): "
716 "`catalogue_type` = '%s'.",
717 this->catalogue_type.c_str()
718 );
719 }
720 } else
721 if (this->statistic_type == "2pcf") {
722 this->npoint = "2pt"; this->space = "config"; // derivation
723 if (this->catalogue_type == "random" || this->catalogue_type == "none") {
724 if (trvs::currTask == 0) {
725 trvs::logger.error(
726 "Two-point correlation function requires 'sim' or 'survey' "
727 "catalogue(s): `catalogue_type` = '%s'.",
728 this->catalogue_type.c_str()
729 );
730 }
732 "Two-point correlation function requires 'sim' or 'survey' "
733 "catalogue(s): `catalogue_type` = '%s'.",
734 this->catalogue_type.c_str()
735 );
736 }
737 } else
738 if (this->statistic_type == "2pcf-win") {
739 this->npoint = "2pt"; this->space = "config"; // derivation
740 if (this->catalogue_type != "random") {
741 if (trvs::currTask == 0) {
742 trvs::logger.error(
743 "Two-point correlation function window requires 'random' catalogue: "
744 "`catalogue_type` = '%s'.",
745 this->catalogue_type.c_str()
746 );
747 }
749 "Two-point correlation function window requires 'random' catalogue: "
750 "`catalogue_type` = '%s'.",
751 this->catalogue_type.c_str()
752 );
753 }
754 } else
755 if (this->statistic_type == "bispec") {
756 this->npoint = "3pt"; this->space = "fourier"; // derivation
757 if (this->catalogue_type == "random" || this->catalogue_type == "none") {
758 if (trvs::currTask == 0) {
759 trvs::logger.error(
760 "Bispectrum requires 'sim' or 'survey' catalogue(s): "
761 "`catalogue_type` = '%s'.",
762 this->catalogue_type.c_str()
763 );
764 }
766 "Bispectrum requires 'sim' or 'survey' catalogue(s): "
767 "`catalogue_type` = '%s'.",
768 this->catalogue_type.c_str()
769 );
770 }
771 } else
772 if (this->statistic_type == "3pcf") {
773 this->npoint = "3pt"; this->space = "config"; // derivation
774 if (this->catalogue_type == "random" || this->catalogue_type == "none") {
775 if (trvs::currTask == 0) {
776 trvs::logger.error(
777 "Three-point correlation function requires 'sim' or 'survey' "
778 "catalogue(s): `catalogue_type` = '%s'.",
779 this->catalogue_type.c_str()
780 );
781 }
783 "Three-point correlation function requires 'sim' or 'survey' "
784 "catalogue(s): `catalogue_type` = '%s'.",
785 this->catalogue_type.c_str()
786 );
787 }
788 } else
789 if (
790 this->statistic_type == "3pcf-win"
791 || this->statistic_type == "3pcf-win-wa"
792 ) {
793 this->npoint = "3pt"; this->space = "config"; // derivation
794 if (this->catalogue_type != "random") {
795 if (trvs::currTask == 0) {
796 trvs::logger.error(
797 "Three-point correlation function window requires 'random' "
798 "catalogue: `catalogue_type` = '%s'.",
799 this->catalogue_type.c_str()
800 );
801 }
803 "Three-point correlation function window requires 'random' "
804 "catalogue: `catalogue_type` = '%s'.",
805 this->catalogue_type.c_str()
806 );
807 }
808 } else
809 if (this->statistic_type == "modes") {
810 this->npoint = "none"; this->space = "fourier"; // derivation
811 } else
812 if (this->statistic_type == "pairs") {
813 this->npoint = "none"; this->space = "config"; // derivation
814 } else {
815#ifndef TRV_EXTCALL
816 if (trvs::currTask == 0) {
817 trvs::logger.error(
818 "Statistic type is not recognised: `statistic_type` = '%s'.",
819 this->statistic_type.c_str()
820 );
821 }
823 "Statistic type is not recognised: `statistic_type` = '%s'.",
824 this->statistic_type.c_str()
825 );
826#endif // !TRV_EXTCALL
827 }
828 if (!(
829 this->form == "full"
830 || this->form == "diag"
831 || this->form == "off-diag"
832 || this->form == "row"
833 )) {
834 if (trvs::currTask == 0) {
835 trvs::logger.error(
836 "Three-point statistic form is not recognised: `form` = '%s'.",
837 this->form.c_str()
838 );
839 }
841 "Three-point statistic form is not recognised: `form` = '%s'.",
842 this->form.c_str()
843 );
844 } else {
845 if (this->form == "full" && this->ell1 == this->ell2) {
846 this->shape = "triu"; // derivation
847 } else {
848 this->shape = this->form; // derivation
849 }
850 }
851 if (!(
852 this->norm_convention == "none"
853 || this->norm_convention == "particle"
854 || this->norm_convention == "mesh"
855 || this->norm_convention == "mesh-mixed"
856 )) {
857 if (trvs::currTask == 0) {
858 trvs::logger.error(
859 "Normalisation convention must be 'mesh', 'particle', "
860 "'mesh' or 'mesh-mixed': `norm_convention` = '%s'.",
861 this->norm_convention.c_str()
862 );
863 }
865 "Normalisation convention must be 'mesh', 'particle', "
866 "'mesh' or 'mesh-mixed': `norm_convention` = '%s'.",
867 this->norm_convention.c_str()
868 );
869 }
870 if (this->norm_convention == "mesh-mixed" && this->npoint != "2pt") {
871 if (trvs::currTask == 0) {
872 trvs::logger.error(
873 "Normalisation convention 'mesh-mixed' only applies to "
874 "two-point statistics: `npoint` = '%s'.",
875 this->npoint.c_str()
876 );
877 }
879 "Normalisation convention 'mesh-mixed' only applies to "
880 "two-point statistics: `npoint` = '%s'.",
881 this->npoint.c_str()
882 );
883 }
884 if (!(
885 this->binning == "lin"
886 || this->binning == "log"
887 || this->binning == "linpad"
888 || this->binning == "logpad"
889 || this->binning == "custom"
890 )) {
891 if (trvs::currTask == 0) {
892 trvs::logger.error(
893 "Binning scheme is unrecognised: `binning` = '%s'.",
894 this->binning.c_str()
895 );
896 }
898 "Binning scheme is unrecognised: `binning` = '%s'.",
899 this->binning.c_str()
900 );
901 }
902
903 if (!trvs::is_gpu_enabled()) {
904 if (this->fftw_scheme == "estimate") {
905 this->fftw_planner_flag = FFTW_ESTIMATE; // derivation
906 } else
907 if (this->fftw_scheme == "measure") {
908 this->fftw_planner_flag = FFTW_MEASURE; // derivation
909 } else
910 if (this->fftw_scheme == "patient") {
911 this->fftw_planner_flag = FFTW_PATIENT; // derivation
912 } else {
913 if (trvs::currTask == 0) {
914 trvs::logger.error(
915 "FFTW planner scheme is not supported: `fftw_scheme` = '%s'.",
916 this->fftw_scheme.c_str()
917 );
918 }
920 "FFTW planner scheme is not supported: `fftw_scheme` = '%s'.",
921 this->fftw_scheme.c_str()
922 );
923 }
924 } else {
925 if (!(this->fftw_scheme == "measure" || this->fftw_scheme == "")) {
926 if (trvs::currTask == 0) {
927 trvs::logger.info(
928 "FFTW planner scheme is ignored in GPU mode: `fftw_scheme` = '%s'.",
929 this->fftw_scheme.c_str()
930 );
931 }
932 }
933 this->fftw_scheme = ""; // transmutation
934 }
935
936 if (trvs::is_gpu_enabled()) {
937 if (!(this->use_fftw_wisdom == "false")) {
938 if (trvs::currTask == 0) {
939 trvs::logger.info("FFTW wisdom is disabled in GPU mode.");
940 }
941 }
942 this->use_fftw_wisdom = ""; // transmutation
943 } else {
944 if (this->use_fftw_wisdom == "false") {
945 this->use_fftw_wisdom = ""; // transmutation
946 } else
947 if (init) {
948 this->use_fftw_wisdom += "/"; // transmutation
949 }
950 }
952
953 if (this->use_fftw_wisdom != "") {
954 if (this->fftw_scheme != "measure" && this->fftw_scheme != "patient") {
955 if (trvs::currTask == 0) {
956 trvs::logger.error(
957 "FFTW wisdom is enabled but the planner scheme "
958 "is not 'measure' or 'patient': "
959 "`fftw_scheme` = '%s'.",
960 this->fftw_scheme.c_str()
961 );
962 }
964 "FFTW wisdom is enabled but the planner scheme "
965 "is not 'measure' or 'patient': "
966 "`fftw_scheme` = '%s'.",
967 this->fftw_scheme.c_str()
968 );
969 }
970
971 char fftw_wisdom_file_f_[1024];
972 char fftw_wisdom_file_b_[1024];
973
974#if defined(TRV_USE_OMP) && defined(TRV_USE_FFTWOMP)
975 std::snprintf(
976 fftw_wisdom_file_f_, sizeof(fftw_wisdom_file_f_),
977 "%sfftw_omp_cif_%dx%dx%d.wisdom",
978 this->use_fftw_wisdom.c_str(),
979 this->ngrid[0], this->ngrid[1], this->ngrid[2]
980 );
981 std::snprintf(
982 fftw_wisdom_file_b_, sizeof(fftw_wisdom_file_b_),
983 "%sfftw_omp_cib_%dx%dx%d.wisdom",
984 this->use_fftw_wisdom.c_str(),
985 this->ngrid[0], this->ngrid[1], this->ngrid[2]
986 );
987#else // !TRV_USE_OMP || !TRV_USE_FFTWOMP
988 std::snprintf(
989 fftw_wisdom_file_f_, sizeof(fftw_wisdom_file_f_),
990 "%sfftw_cif_%dx%dx%d.wisdom",
991 this->use_fftw_wisdom.c_str(),
992 this->ngrid[0], this->ngrid[1], this->ngrid[2]
993 );
994 std::snprintf(
995 fftw_wisdom_file_b_, sizeof(fftw_wisdom_file_b_),
996 "%sfftw_cib_%dx%dx%d.wisdom",
997 this->use_fftw_wisdom.c_str(),
998 this->ngrid[0], this->ngrid[1], this->ngrid[2]
999 );
1000#endif // TRV_USE_OMP && TRV_USE_FFTWOMP
1001
1002 this->fftw_wisdom_file_f = fftw_wisdom_file_f_;
1003 this->fftw_wisdom_file_b = fftw_wisdom_file_b_;
1004 }
1005
1006 char default_bvec_sfilepath[1024];
1007 std::snprintf(
1008 default_bvec_sfilepath, sizeof(default_bvec_sfilepath),
1009 "%sbinned_vectors%s",
1010 this->measurement_dir.c_str(), this->output_tag.c_str()
1011 );
1012 if (this->save_binned_vectors == "false") {
1013 this->save_binned_vectors = ""; // transmutation
1014 } else
1015 if (this->save_binned_vectors == "true") {
1016 this->save_binned_vectors = default_bvec_sfilepath; // transmutation
1017 } else
1018 if (this->save_binned_vectors != "") {
1019 // Check whether path is absolute.
1020 if (this->save_binned_vectors.rfind("/", 0) != 0 && init) {
1022 + this->save_binned_vectors;
1023 } // transmutation
1024 }
1026
1027 // Validate and derive numerical parameters.
1028 this->volume =
1029 this->boxsize[0] * this->boxsize[1] * this->boxsize[2]; // derivation
1030 this->nmesh = static_cast<long long>(this->ngrid[0])
1031 * this->ngrid[1] * this->ngrid[2]; // derivation
1032
1033 if (this->volume <= 0.) {
1034 if (trvs::currTask == 0) {
1035 trvs::logger.warn(
1036 "Derived total box volume is non-positive: `volume` = %.6e. "
1037 "Possible numerical overflow due to large `boxsize`, "
1038 "or `boxsize` is unset. "
1039 "In the latter case, the box size will be calculated using "
1040 "the particle coordinate spans and the box expansion factor.",
1041 this->volume
1042 );
1043 }
1044 if (this->expand < 1.) {
1045 if (trvs::currTask == 0) {
1046 trvs::logger.error(
1047 "The box expansion factor must be >= 1: `expand` = %lg",
1048 this->expand
1049 );
1050 }
1052 "The box expansion factor must be >= 1: `expand` = %lg",
1053 this->expand
1054 );
1055 }
1056 if (this->expand > 1. and this->catalogue_type == "sim") {
1057 if (trvs::currTask == 0) {
1058 trvs::logger.info(
1059 "The box expansion factor is expected to be unity "
1060 "for 'sim' catalogue(s): `expand` = %lg",
1061 this->expand
1062 );
1063 }
1064 }
1065 }
1066 if (this->nmesh <= 0) {
1067 if (trvs::currTask == 0) {
1068 trvs::logger.warn(
1069 "Derived total mesh grid number is non-positive: `nmesh` = %lld. "
1070 "Possible numerical overflow due to large `ngrid`, "
1071 "or `ngrid` is unset. "
1072 "In the latter case, the grid cell number will be calculated using "
1073 "the Nyquist cutoff and the box size.",
1074 this->nmesh
1075 );
1076 }
1077 if (this->cutoff_nyq < 0.) {
1078 if (trvs::currTask == 0) {
1079 trvs::logger.error(
1080 "The Nyquist cutoff must be non-negative: `cutoff_nyq` = %lg",
1081 this->cutoff_nyq
1082 );
1083 }
1085 "The Nyquist cutoff must be non-negative: `cutoff_nyq` = %lg",
1086 this->cutoff_nyq
1087 );
1088 }
1089 if (this->volume > 0.) {
1090 set_ngrid_from_cutoff(*this);
1091 }
1092 }
1093
1094 if (this->alignment == "pad") {
1095 if (this->padfactor < 0.) {
1096 if (trvs::currTask == 0) {
1097 trvs::logger.error(
1098 "Padding is enabled but the padding factor is negative: "
1099 "`padfactor` = %lg",
1100 this->padfactor
1101 );
1102 }
1104 "Padding is enabled but the padding factor is negative: "
1105 "`padfactor` = %lg",
1106 this->padfactor
1107 );
1108 }
1109 if (this->padscale == "box" && this->padfactor >= 1.) {
1110 if (trvs::currTask == 0) {
1111 trvs::logger.error(
1112 "Padding is enabled but the %s padding factor is too large "
1113 "for the box size: `padfactor` = %lg",
1114 this->padscale.c_str(), this->padfactor
1115 );
1116 }
1118 "Padding is enabled but the %s padding factor is too large "
1119 "for the box size: `padfactor` = %lg",
1120 this->padscale.c_str(), this->padfactor
1121 );
1122 }
1123 if (this->padscale == "grid" && (
1124 this->padfactor >= this->ngrid[0]
1125 || this->padfactor >= this->ngrid[1]
1126 || this->padfactor >= this->ngrid[2]
1127 )) {
1128 if (trvs::currTask == 0) {
1129 trvs::logger.error(
1130 "Padding is enabled but the %s padding factor is too large "
1131 "for the mesh grid numbers: `padfactor` = %lg",
1132 this->padscale.c_str(), this->padfactor
1133 );
1134 }
1136 "Padding is enabled but the %s padding factor is too large "
1137 "for the mesh grid numbers: `padfactor` = %lg",
1138 this->padscale.c_str(), this->padfactor
1139 );
1140 }
1141 }
1142
1143 if (this->bin_min < 0.) {
1144 if (trvs::currTask == 0) {
1145 trvs::logger.error("Lower bin edge must be non-negative.");
1146 }
1148 "Lower bin edge must be non-negative.\n"
1149 );
1150 }
1151 if (this->bin_min >= this->bin_max) {
1152 if (trvs::currTask == 0) {
1153 trvs::logger.error(
1154 "Lower bin edge must be less than the upper bin edge."
1155 );
1156 }
1158 "Lower bin edge must be less than the upper bin edge.\n"
1159 );
1160 }
1161 if (this->space == "fourier") {
1162 double wavenum_nyquist = M_PI
1163 * *std::min_element(this->ngrid, this->ngrid + 3)
1164 / *std::max_element(this->boxsize, this->boxsize + 3);
1165 if (this->bin_min > wavenum_nyquist) {
1166 if (trvs::currTask == 0) {
1167 trvs::logger.warn(
1168 "Lower wavenumber limit exceeds the Nyquist wavenumber %.4f.",
1169 wavenum_nyquist
1170 );
1171 }
1172 }
1173 } else
1174 if (this->space == "config") {
1175 double separation_nyquist = 2
1176 * *std::max_element(this->boxsize, this->boxsize + 3)
1177 / *std::min_element(this->ngrid, this->ngrid + 3);
1178 if (this->bin_max < separation_nyquist) {
1179 if (trvs::currTask == 0) {
1180 trvs::logger.warn(
1181 "Upper separation limit undershoots the Nyquist scale %.4f.",
1182 separation_nyquist
1183 );
1184 }
1185 }
1186 }
1187
1188 if (this->num_bins < 2) {
1189 if (trvs::currTask == 0) {
1190 trvs::logger.error("Number of bins `num_bins` must be >= 2.");
1191 }
1193 "Number of bins `num_bins` must be >= 2.\n"
1194 );
1195 }
1196
1197 if (
1198 this->idx_bin < 0
1199 && this->npoint == "3pt"
1200 && this->form == "row"
1201 ) {
1202 if (trvs::currTask == 0) {
1203 trvs::logger.error("Fixed row bin index `idx_bin` must be >= 0.");
1204 }
1206 "Fixed row bin index `idx_bin` must be >= 0.\n"
1207 );
1208 }
1209
1210 // Check for parameter conflicts.
1211 if (this->binning == "linpad" || this->binning == "logpad") {
1212 // CAVEAT: See @ref trv::Binning.
1213 int nbin_pad = 5;
1214
1215 if (this->num_bins < nbin_pad + 2) {
1216 if (trvs::currTask == 0) {
1217 trvs::logger.error(
1218 "Binning scheme '%s' requires `num_bins` >= %d.",
1219 this->binning.c_str(), nbin_pad + 2
1220 );
1221 }
1223 "Binning scheme '%s' requires `num_bins` >= %d.",
1224 this->binning.c_str(), nbin_pad + 2
1225 );
1226 }
1227 }
1228
1229 if (std::abs(this->idx_bin) >= this->num_bins) {
1230 if (trvs::currTask == 0) {
1231 trvs::logger.error(
1232 "Bin index `idx_bin` must be < `num_bins` in absolute value."
1233 );
1234 }
1236 "Bin index `idx_bin` must be < `num_bins` in absolute value.\n"
1237 );
1238 }
1239
1240 if (this->npoint == "3pt" && this->interlace == "true") {
1241 this->interlace = "false"; // transmutation
1242
1243 if (trvs::currTask == 0) {
1244 trvs::logger.info(
1245 "Interlacing is unsupported for three-point measurements. "
1246 "`interlace` is set to 'false'."
1247 );
1248 }
1249 }
1250
1251 if (
1252 (this->statistic_type == "modes" || this->statistic_type == "pairs")
1253 && this->save_binned_vectors == ""
1254 ) {
1255 this->save_binned_vectors = default_bvec_sfilepath; // transmutation
1256 if (trvs::currTask == 0) {
1257 trvs::logger.info(
1258 "`save_binned_vectors` is overridden, as `statistic_type` is '%s' "
1259 "so binned vectors are saved as the output to the default path.",
1260 this->statistic_type.c_str()
1261 );
1262 }
1263 }
1264
1265 if (trvs::currTask == 0) {
1266 trvs::logger.stat("Parameters validated.");
1267 }
1268
1269 return 0;
1270}
1271
1272int ParameterSet::print_to_file(char* out_parameter_filepath) {
1273 // Create output file.
1274 std::FILE* ofileptr;
1275 if (!(ofileptr = std::fopen(out_parameter_filepath, "w"))) {
1276 if (trvs::currTask == 0) {
1277 trvs::logger.error(
1278 "Non-existent or unwritable output directory: %s",
1279 this->measurement_dir.c_str()
1280 );
1281 }
1282 throw trvs::IOError(
1283 "Non-existent or unwritable output directory: %s",
1284 this->measurement_dir.c_str()
1285 );
1286 }
1287
1288 // Define convenience function for printing parameters.
1289 auto print_par_str = [ofileptr](
1290 const char* fmt, const std::string& par_val
1291 ) {
1292 std::fprintf(ofileptr, fmt, par_val.c_str());
1293 };
1294 auto print_par_int = [ofileptr](const char* fmt, int par_val) {
1295 std::fprintf(ofileptr, fmt, par_val);
1296 };
1297 auto print_par_double = [ofileptr](const char* fmt, double par_val) {
1298 std::fprintf(ofileptr, fmt, par_val);
1299 };
1300
1301 // Print parameters to file.
1302 print_par_str("catalogue_dir = %s\n", this->catalogue_dir);
1303 print_par_str("measurement_dir = %s\n", this->measurement_dir);
1304 print_par_str("data_catalogue_file = %s\n", this->data_catalogue_file);
1305 print_par_str("rand_catalogue_file = %s\n", this->rand_catalogue_file);
1306 print_par_str("catalogue_columns = %s\n", this->catalogue_columns);
1307 print_par_str("catalogue_dataset = %s\n", this->catalogue_dataset);
1308 print_par_str("output_tag = %s\n", this->output_tag);
1309
1310 print_par_double("boxsize_x = %.3f\n", this->boxsize[0]);
1311 print_par_double("boxsize_y = %.3f\n", this->boxsize[1]);
1312 print_par_double("boxsize_z = %.3f\n", this->boxsize[2]);
1313 print_par_int("ngrid_x = %d\n", this->ngrid[0]);
1314 print_par_int("ngrid_y = %d\n", this->ngrid[1]);
1315 print_par_int("ngrid_z = %d\n", this->ngrid[2]);
1316
1317 print_par_double("volume = %.6e\n", this->volume);
1318 print_par_int("nmesh = %lld\n", this->nmesh);
1319
1320 print_par_double("expand = %.4f\n", this->expand);
1321 print_par_str("alignment = %s\n", this->alignment);
1322 print_par_str("padscale = %s\n", this->padscale);
1323 print_par_double("padfactor = %.4f\n", this->padfactor);
1324
1325 print_par_str("assignment = %s\n", this->assignment);
1326 print_par_str("interlace = %s\n", this->interlace);
1327 print_par_int("assignment_order = %d\n", this->assignment_order);
1328
1329 print_par_str("catalogue_type = %s\n", this->catalogue_type);
1330 print_par_str("statistic_type = %s\n", this->statistic_type);
1331 print_par_str("npoint = %s\n", this->npoint);
1332 print_par_str("space = %s\n", this->space);
1333
1334 print_par_int("ell1 = %d\n", this->ell1);
1335 print_par_int("ell2 = %d\n", this->ell2);
1336 print_par_int("ELL = %d\n", this->ELL);
1337
1338 print_par_int("i_wa = %d\n", this->i_wa);
1339 print_par_int("j_wa = %d\n", this->j_wa);
1340
1341 print_par_str("form = %s\n", this->form);
1342 print_par_str("norm_convention = %s\n", this->norm_convention);
1343 print_par_str("binning = %s\n", this->binning);
1344 print_par_str("shape = %s\n", this->shape);
1345
1346 print_par_double("bin_min = %.4f\n", this->bin_min);
1347 print_par_double("bin_max = %.4f\n", this->bin_max);
1348 print_par_int("num_bins = %d\n", this->num_bins);
1349 print_par_int("idx_bin = %d\n", this->idx_bin);
1350
1351 print_par_str("fftw_scheme = %s\n", this->fftw_scheme);
1352 print_par_str("use_fftw_wisdom = %s\n", this->use_fftw_wisdom.c_str());
1353 print_par_str("fftw_wisdom_file_f = %s\n", this->fftw_wisdom_file_f.c_str());
1354 print_par_str("fftw_wisdom_file_b = %s\n", this->fftw_wisdom_file_b.c_str());
1355 print_par_str("save_binned_vectors = %s\n", this->save_binned_vectors);
1356 print_par_str("progbar = %s\n", this->progbar);
1357 print_par_int("verbose = %d\n", this->verbose);
1358 print_par_int("fftw_planner_flag = %d\n", this->fftw_planner_flag);
1359
1360 std::fclose(ofileptr);
1361
1362 if (trvs::currTask == 0) {
1363 trvs::logger.info(
1364 "Check used-parameter file for reference: %s", out_parameter_filepath
1365 );
1366 }
1367
1368 return 0;
1369}
1370
1372 // Set output file path to default.
1373 char ofilepath[1024];
1374 std::snprintf(
1375 ofilepath, sizeof(ofilepath), "%sparameters_used%s",
1376 this->measurement_dir.c_str(), this->output_tag.c_str()
1377 );
1378
1379 return ParameterSet::print_to_file(ofilepath);
1380}
1381
1383 // Override the output tag.
1384 char* ev_tag = std::getenv("TRV_OVERRIDE_OUTPUT_TAG");
1385 if (ev_tag != nullptr) {
1386 params.output_tag = std::string(ev_tag);
1387 }
1388
1389 // Override the FFTW scheme.
1390 char* ev_fftw_scheme = std::getenv("TRV_OVERRIDE_FFTW_SCHEME");
1391 if (ev_fftw_scheme != nullptr && !trvs::is_gpu_enabled()) {
1392 params.fftw_scheme = std::string(ev_fftw_scheme);
1393 }
1394
1395 // Override the FFTW wisdom option.
1396 char* ev_use_fftw_wisdom = std::getenv("TRV_OVERRIDE_USE_FFTW_WISDOM");
1397 if (ev_use_fftw_wisdom != nullptr && !trvs::is_gpu_enabled()) {
1398 params.use_fftw_wisdom = std::string(ev_use_fftw_wisdom);
1399 }
1400
1401 // Override the verbosity level.
1402 char* ev_verbose = std::getenv("TRV_OVERRIDE_VERBOSE");
1403 if (ev_verbose != nullptr) {
1404 params.verbose = std::stoi(ev_verbose);
1405 }
1406
1407 // Override the progress bar.
1408 char* ev_progbar = std::getenv("TRV_OVERRIDE_PROGBAR");
1409 if (ev_progbar != nullptr) {
1410 params.progbar = std::string(ev_progbar);
1411 }
1412
1413 params.validate();
1414}
1415
1417 const double* spans, trv::ParameterSet& params
1418) {
1419 for (int iaxis = 0; iaxis < 3; iaxis++) {
1420 params.boxsize[iaxis] = spans[iaxis] * params.expand;
1421 }
1422
1423 params.validate();
1424
1425 if (trvs::currTask == 0) {
1426 trvs::logger.info(
1427 "Box size has been set from particle coordinate spans and "
1428 "expansion factor: (%.3f, %.3f, %.3f).",
1429 params.boxsize[0], params.boxsize[1], params.boxsize[2]
1430 );
1431 }
1432}
1433
1435 for (int iaxis = 0; iaxis < 3; iaxis++) {
1436 int ngrid_;
1437 if (params.space == "fourier") {
1438 ngrid_ = static_cast<int>(std::ceil(
1439 params.boxsize[iaxis] * params.cutoff_nyq / M_PI
1440 ));
1441 } else
1442 if (params.space == "config") {
1443 ngrid_ = static_cast<int>(std::ceil(
1444 2. * params.boxsize[iaxis] / params.cutoff_nyq
1445 ));
1446 } else {
1448 "Space must be 'fourier' or 'config': `space` = '%s'.",
1449 params.space.c_str()
1450 );
1451 }
1452 params.ngrid[iaxis] = ngrid_ + (ngrid_ % 2);
1453 }
1454
1455 params.validate();
1456
1457 if (trvs::currTask == 0) {
1458 trvs::logger.info(
1459 "Mesh grid numbers have been set from Nyquist cutoff and "
1460 "box size: (%d, %d, %d).",
1461 params.ngrid[0], params.ngrid[1], params.ngrid[2]
1462 );
1463 }
1464}
1465
1466} // namespace trv
Parameter set.
std::string alignment
box alignment: {"centre" (default), "pad"}
std::string shape
std::string catalogue_columns
long long nmesh
number of mesh grid cells
double bin_min
measurement range minimum (in Mpc/h or h/Mpc)
std::string output_tag
output tag
std::string catalogue_dataset
catalogue dataset name/path (HDF5 catalogue files only)
double cutoff_nyq
Nyquist cutoff wavenumber or separation (in Mpc/h or h/Mpc)
std::string assignment
mesh assignment scheme: {"ngp", "cic", "tsc" (default), "pcs"}
std::string save_binned_vectors
int ELL
spherical degree associated with the line of sight
unsigned fftw_planner_flag
derived FFTW planner flag
int i_wa
first order of the wide-angle correction term
int print_to_file()
Print out extracted parameters to the default file path in the output measurement directory.
std::string catalogue_dir
catalogue directory
double padfactor
padding factor
ParameterSet()=default
Construct a parameter set.
std::string fftw_scheme
FFTW scheme: {"estimate", "measure" (default), "patient"}.
double volume
box volume (in Mpc^3/h^3)
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 space
coordinate space: {"fourier", "config"}
std::string catalogue_type
catalogue type: {"survey", "random", "sim", "none"}
int ell1
spherical degree associated with the first wavevector
std::string fftw_wisdom_file_b
backward-transform wisdom file path
int num_bins
number of measurement bins
std::string padscale
padding scale (if alignment is "pad"): {"box" (default), "grid"}
std::string interlace
interlacing switch: {"true"/"on", "false"/"off" (default)}
double expand
box expansion factor (if boxsize is not given)
int assignment_order
order of the assignment scheme
std::string binning
std::string fftw_wisdom_file_f
derived FFTW wisdom file paths
int ell2
spherical degree associated with the second wavevector
int ngrid[3]
grid cell number in each dimension
std::string progbar
display a progress bar: {"true", "false" (default), <int-%-point>}
std::string data_catalogue_file
data catalogue file
std::string npoint
N-point case: {"2pt", "3pt", "none"}
int validate(bool init=false)
Validate parameters.
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>}
double bin_max
measurement range maximum (in Mpc/h or h/Mpc)
Exception raised when an input/output operation fails.
Definition monitor.hpp:707
Exception raised when parameters are invalid.
Definition monitor.hpp:731
bool has_extension(const std::string &fname, const std::string &fext)
Check if a file has a given extension.
Definition monitor.cpp:38
void expand_envar_in_path(std::string &path_str)
Expand environment variables in a path string.
Definition monitor.cpp:1012
bool is_gpu_enabled()
Check if GPU mode is enabled.
Definition monitor.cpp:297
Logger logger
default logger (at NSET logging level)
int currTask
current task
Definition monitor.cpp:92
std::string join_strings(const std::vector< std::string > &strings, const std::string &delimiter)
Join a vector of strings with a delimiter.
Definition monitor.cpp:45
void set_ngrid_from_cutoff(trv::ParameterSet &params)
Set the grid cell numbers from the box size and the Nyquist cutoff.
void set_boxsize_from_expand(const double *spans, trv::ParameterSet &params)
Set the box size parameters from the box expansion factor.
void override_paramset_by_envvars(trv::ParameterSet &params)
Override parameter set by environment variables.
Program parameter configuration.