90 std::string param_filepath = parameter_filepath;
92 std::ifstream fin(param_filepath.c_str());
95 char catalogue_dir_[1024] =
"";
96 char measurement_dir_[1024] =
"";
97 char data_catalogue_file_[1024] =
"";
98 char rand_catalogue_file_[1024] =
"";
99 char catalogue_columns_[1024] =
"";
100 char output_tag_[1024] =
"";
102 double boxsize_x, boxsize_y, boxsize_z;
103 int ngrid_x, ngrid_y, ngrid_z;
105 char alignment_[16] =
"";
106 char padscale_[16] =
"";
107 char assignment_[16] =
"";
108 char interlace_[16] =
"";
110 char catalogue_type_[16] =
"";
111 char statistic_type_[16] =
"";
113 char norm_convention_[16] =
"";
114 char binning_[16] =
"";
116 char fftw_scheme_[16] =
"";
117 char use_fftw_wisdom_[1024] =
"";
118 char save_binned_vectors_[1024] =
"";
124 std::string line_str;
125 char dummy_str[1024], dummy_equal[1024];
126 while (std::getline(fin, line_str)) {
128 if (line_str.find(
"#") == 0) {
133 line_str.data(),
"%1023s %1023s %1023s",
134 dummy_str, dummy_equal, dummy_str
139 if (std::strcmp(dummy_equal,
"=") != 0) {
144 auto scan_par_str = [line_str, dummy_str, dummy_equal](
145 const char* par_name,
const char* fmt,
const char* par_value
147 if (line_str.find(par_name) != std::string::npos) {
149 line_str.data(), fmt, dummy_str, dummy_equal, par_value
156 scan_par_str(
"catalogue_dir",
"%s %s %s", catalogue_dir_);
157 scan_par_str(
"measurement_dir",
"%s %s %s", measurement_dir_);
158 scan_par_str(
"data_catalogue_file",
"%s %s %s", data_catalogue_file_);
159 scan_par_str(
"rand_catalogue_file",
"%s %s %s", rand_catalogue_file_);
160 scan_par_str(
"catalogue_columns",
"%s %s %s", catalogue_columns_);
161 scan_par_str(
"output_tag",
"%s %s %s", output_tag_);
165 if (line_str.find(
"boxsize_x") != std::string::npos) {
167 line_str.data(),
"%1023s %1023s %lg",
168 dummy_str, dummy_equal, &boxsize_x
171 if (line_str.find(
"boxsize_y") != std::string::npos) {
173 line_str.data(),
"%1023s %1023s %lg",
174 dummy_str, dummy_equal, &boxsize_y
177 if (line_str.find(
"boxsize_z") != std::string::npos) {
179 line_str.data(),
"%1023s %1023s %lg",
180 dummy_str, dummy_equal, &boxsize_z
184 if (line_str.find(
"ngrid_x") != std::string::npos) {
186 line_str.data(),
"%1023s %1023s %d",
187 dummy_str, dummy_equal, &ngrid_x
190 if (line_str.find(
"ngrid_y") != std::string::npos) {
192 line_str.data(),
"%1023s %1023s %d",
193 dummy_str, dummy_equal, &ngrid_y
196 if (line_str.find(
"ngrid_z") != std::string::npos) {
198 line_str.data(),
"%1023s %1023s %d", dummy_str, dummy_equal, &ngrid_z
202 scan_par_str(
"alignment",
"%1023s %1023s %1023s", alignment_);
203 scan_par_str(
"padscale",
"%1023s %1023s %1023s", padscale_);
205 if (line_str.find(
"padfactor") != std::string::npos) {
207 line_str.data(),
"%1023s %1023s %lg",
208 dummy_str, dummy_equal, &this->padfactor
212 scan_par_str(
"assignment",
"%1023s %1023s %1023s", assignment_);
213 scan_par_str(
"interlace",
"%1023s %1023s %1023s", interlace_);
217 scan_par_str(
"catalogue_type",
"%1023s %1023s %1023s", catalogue_type_);
218 scan_par_str(
"statistic_type",
"%1023s %1023s %1023s", statistic_type_);
219 scan_par_str(
"form",
"%1023s %1023s %1023s", form_);
220 scan_par_str(
"norm_convention",
"%1023s %1023s %1023s", norm_convention_);
221 scan_par_str(
"binning",
"%1023s %1023s %1023s", binning_);
223 if (line_str.find(
"ell1") != std::string::npos) {
225 line_str.data(),
"%1023s %1023s %d",
226 dummy_str, dummy_equal, &this->ell1
229 if (line_str.find(
"ell2") != std::string::npos) {
231 line_str.data(),
"%1023s %1023s %d",
232 dummy_str, dummy_equal, &this->ell2
235 if (line_str.find(
"ELL") != std::string::npos) {
237 line_str.data(),
"%1023s %1023s %d",
238 dummy_str, dummy_equal, &this->ELL
242 if (line_str.find(
"i_wa") != std::string::npos) {
244 line_str.data(),
"%1023s %1023s %d",
245 dummy_str, dummy_equal, &this->i_wa
248 if (line_str.find(
"j_wa") != std::string::npos) {
250 line_str.data(),
"%1023s %1023s %d",
251 dummy_str, dummy_equal, &this->j_wa
255 if (line_str.find(
"bin_min") != std::string::npos) {
257 line_str.data(),
"%1023s %1023s %lg",
258 dummy_str, dummy_equal, &this->bin_min
261 if (line_str.find(
"bin_max") != std::string::npos) {
263 line_str.data(),
"%1023s %1023s %lg",
264 dummy_str, dummy_equal, &this->bin_max
268 if (line_str.find(
"num_bins") != std::string::npos) {
270 line_str.data(),
"%1023s %1023s %d",
271 dummy_str, dummy_equal, &this->num_bins
274 if (line_str.find(
"idx_bin") != std::string::npos) {
276 line_str.data(),
"%1023s %1023s %d",
277 dummy_str, dummy_equal, &this->idx_bin
283 scan_par_str(
"fftw_scheme",
"%1023s %1023s %1023s", fftw_scheme_);
284 scan_par_str(
"use_fftw_wisdom",
"%1023s %1023s %1023s", use_fftw_wisdom_);
286 "save_binned_vectors",
"%1023s %1023s %1023s", save_binned_vectors_
289 if (line_str.find(
"verbose") != std::string::npos) {
291 line_str.data(),
"%1023s %1023s %d",
292 dummy_str, dummy_equal, &this->verbose
331 this->
ngrid[0] = ngrid_x;
332 this->
ngrid[1] = ngrid_y;
333 this->
ngrid[2] = ngrid_z;
335 this->
volume = boxsize_x * boxsize_y * boxsize_z;
336 this->
nmesh = ngrid_x * ngrid_y * ngrid_z;
344 auto debug_par_str = [](
const std::string& name,
const std::string& value) {
345 std::cout << name <<
": " << value << std::endl;
347 auto debug_par_int = [](
const std::string& name,
int value) {
348 std::cout << name <<
": " << value << std::endl;
350 auto debug_par_longlong = [](
const std::string& name,
long long value) {
351 std::cout << name <<
": " << value << std::endl;
353 auto debug_par_double = [](
const std::string& name,
double value) {
354 std::cout << name <<
": " << value << std::endl;
363 debug_par_str(
"output_tag", this->
output_tag);
365 debug_par_str(
"alignment", this->
alignment);
366 debug_par_str(
"padscale", this->
padscale);
367 debug_par_str(
"assignment", this->
assignment);
368 debug_par_str(
"interlace", this->
interlace);
372 debug_par_str(
"form", this->
form);
374 debug_par_str(
"binning", this->
binning);
380 debug_par_int(
"ngrid[0]", this->
ngrid[0]);
381 debug_par_int(
"ngrid[1]", this->
ngrid[1]);
382 debug_par_int(
"ngrid[2]", this->
ngrid[2]);
384 debug_par_longlong(
"nmesh", this->
nmesh);
386 debug_par_int(
"ell1", this->
ell1);
387 debug_par_int(
"ell2", this->
ell2);
388 debug_par_int(
"ELL", this->
ELL);
389 debug_par_int(
"i_wa", this->
i_wa);
390 debug_par_int(
"j_wa", this->
j_wa);
392 debug_par_int(
"num_bins", this->
num_bins);
393 debug_par_int(
"idx_bin", this->
idx_bin);
395 debug_par_double(
"boxsize[0]", this->
boxsize[0]);
396 debug_par_double(
"boxsize[1]", this->
boxsize[1]);
397 debug_par_double(
"boxsize[2]", this->
boxsize[2]);
398 debug_par_double(
"volume", this->
volume);
399 debug_par_double(
"padfactor", this->
padfactor);
400 debug_par_double(
"bin_min", this->
bin_min);
401 debug_par_double(
"bin_max", this->
bin_max);
413 this->
catalogue_dir.find_first_not_of(
" \t\n\r\v\f") != std::string::npos
418 this->
measurement_dir.find_first_not_of(
" \t\n\r\v\f") == std::string::npos
462 "Catalogue type must be 'survey', 'random', 'sim' or 'none: "
463 "`catalogue_type` = '%s'.",
468 "Catalogue type must be 'survey', 'random', 'sim' or 'none': "
469 "`catalogue_type` = '%s'.\n",
478 "Box alignment must be 'centre' or 'pad': `alignment` = '%s'.",
483 "Box alignment must be 'centre' or 'pad': `alignment` = '%s'.\n",
490 "Pad scale must be 'box' or 'grid': `padscale` = '%s'.",
495 "Pad scale must be 'box' or 'grid': `padscale` = '%s'.\n",
514 "Mesh assignment scheme must be "
515 "'ngp', 'cic', 'tsc' or 'pcs': `assignment` = '%s'.",
520 "Mesh assignment scheme must be "
521 "'ngp', 'cic', 'tsc' or 'pcs': `assignment` = '%s'.\n",
533 "Interlacing must be 'true'/'on' or 'false'/'off': "
534 "`interlace` = '%s'.",
539 "Interlacing must be 'true'/'on' or 'false'/'off': "
540 "`interlace` = '%s'.\n",
550 "Power spectrum requires 'sim' or 'survey' catalogue(s): "
551 "`catalogue_type` = '%s'.",
556 "Power spectrum requires 'sim' or 'survey' catalogue(s): "
557 "`catalogue_type` = '%s'.\n",
567 "Two-point correlation function requires 'sim' or 'survey' "
568 "catalogue(s): `catalogue_type` = '%s'.",
573 "Two-point correlation function requires 'sim' or 'survey' "
574 "catalogue(s): `catalogue_type` = '%s'.\n",
584 "Two-point correlation function window requires 'random' catalogue: "
585 "`catalogue_type` = '%s'.",
590 "Two-point correlation function window requires 'random' catalogue: "
591 "`catalogue_type` = '%s'.\n",
601 "Bispectrum requires 'sim' or 'survey' catalogue(s): "
602 "`catalogue_type` = '%s'.",
607 "Bispectrum requires 'sim' or 'survey' catalogue(s): "
608 "`catalogue_type` = '%s'.\n",
618 "Three-point correlation function requires 'sim' or 'survey' "
619 "catalogue(s): `catalogue_type` = '%s'.",
624 "Three-point correlation function requires 'sim' or 'survey' "
625 "catalogue(s): `catalogue_type` = '%s'.\n",
638 "Three-point correlation function window requires 'random' "
639 "catalogue: `catalogue_type` = '%s'.",
644 "Three-point correlation function window requires 'random' "
645 "catalogue: `catalogue_type` = '%s'.\n",
659 "Statistic type is not recognised: `statistic_type` = '%s'.",
664 "Statistic type is not recognised: `statistic_type` = '%s'.\n",
671 || this->
form ==
"diag"
672 || this->
form ==
"off-diag"
673 || this->
form ==
"row"
677 "Three-point statistic form is not recognised: `form` = '%s'.",
682 "Three-point statistic form is not recognised: `form` = '%s'.\n",
687 this->
shape =
"triu";
700 "Normalisation convention must be 'mesh', 'particle', "
701 "'mesh' or 'mesh-mixed': `norm_convention` = '%s'.",
706 "Normalisation convention must be 'mesh', 'particle', "
707 "'mesh' or 'mesh-mixed': `norm_convention` = '%s'.\n",
714 "Normalisation convention 'mesh-mixed' only applies to "
715 "two-point statistics: `npoint` = '%s'.",
720 "Normalisation convention 'mesh-mixed' only applies to "
721 "two-point statistics: `npoint` = '%s'.\n",
734 "Binning scheme is unrecognised: `binning` = '%s'.",
739 "Binning scheme is unrecognised: `binning` = '%s'.\n",
756 "FFTW planner scheme is not supported: `fftw_scheme` = '%s'.",
761 "FFTW planner scheme is not supported: `fftw_scheme` = '%s'.\n",
776 "FFTW wisdom is enabled but the planner scheme "
777 "is not 'measure' or 'patient': "
778 "`fftw_scheme` = '%s'.",
783 "FFTW wisdom is enabled but the planner scheme "
784 "is not 'measure' or 'patient': "
785 "`fftw_scheme` = '%s'.\n",
790 char fftw_wisdom_file_f_[1024];
791 char fftw_wisdom_file_b_[1024];
793#if defined(TRV_USE_OMP) && defined(TRV_USE_FFTWOMP)
795 fftw_wisdom_file_f_,
sizeof(fftw_wisdom_file_f_),
796 "%sfftw_omp_cif_%dx%dx%d.wisdom",
798 this->ngrid[0], this->ngrid[1], this->ngrid[2]
801 fftw_wisdom_file_b_,
sizeof(fftw_wisdom_file_b_),
802 "%sfftw_omp_cib_%dx%dx%d.wisdom",
804 this->ngrid[0], this->ngrid[1], this->ngrid[2]
808 fftw_wisdom_file_f_,
sizeof(fftw_wisdom_file_f_),
809 "%sfftw_cif_%dx%dx%d.wisdom",
811 this->ngrid[0], this->ngrid[1], this->ngrid[2]
814 fftw_wisdom_file_b_,
sizeof(fftw_wisdom_file_b_),
815 "%sfftw_cib_%dx%dx%d.wisdom",
817 this->ngrid[0], this->ngrid[1], this->ngrid[2]
825 char default_bvec_sfilepath[1024];
827 default_bvec_sfilepath,
sizeof(default_bvec_sfilepath),
828 "%s/binned_vectors%s",
848 this->
nmesh =
static_cast<long long>(this->
ngrid[0])
854 "Derived total box volume is non-positive: `volume` = '%.6e'. "
855 "Possible numerical overflow due to large `boxsize`, "
856 "or `boxsize` is unset.",
861 "Derived total box volume is non-positive: `volume` = '%.6e'. "
862 "Possible numerical overflow due to large `boxsize`, "
863 "or `boxsize` is unset.\n",
867 if (this->
nmesh <= 0) {
870 "Derived total mesh grid number is non-positive: `nmesh` = '%lld'. "
871 "Possible numerical overflow due to large `ngrid`, "
872 "or `ngrid` is unset.",
877 "Derived total mesh grid number is non-positive: `nmesh` = '%lld'. "
878 "Possible numerical overflow due to large `ngrid`, "
879 "or `ngrid` is unset.\n",
888 "Padding is enabled but the padding factor is negative: "
889 "`padfactor` = '%lg'.",
894 "Padding is enabled but the padding factor is negative: "
895 "`padfactor` = '%lg'.\n",
902 "Padding is enabled but the %s padding factor is too large "
903 "for the box size: `padfactor` = '%lg'.",
904 this->
padscale.c_str(), this->padfactor
908 "Padding is enabled but the %s padding factor is too large "
909 "for the box size: `padfactor` = '%lg'.\n",
910 this->
padscale.c_str(), this->padfactor
920 "Padding is enabled but the %s padding factor is too large "
921 "for the mesh grid numbers: `padfactor` = '%lg'.",
922 this->
padscale.c_str(), this->padfactor
926 "Padding is enabled but the %s padding factor is too large "
927 "for the mesh grid numbers: `padfactor` = '%lg'.\n",
928 this->
padscale.c_str(), this->padfactor
938 "Lower bin edge must be non-negative.\n"
944 "Lower bin edge must be less than the upper bin edge."
948 "Lower bin edge must be less than the upper bin edge.\n"
951 if (this->
space ==
"fourier") {
952 double wavenum_nyquist = M_PI
953 * *std::min_element(this->
ngrid, this->
ngrid + 3)
954 / *std::max_element(this->boxsize, this->boxsize + 3);
955 if (this->
bin_min > wavenum_nyquist) {
958 "Lower wavenumber limit exceeds the Nyquist wavenumber %.4f.",
964 if (this->
space ==
"config") {
965 double separation_nyquist = 2
966 * *std::max_element(this->boxsize, this->boxsize + 3)
967 / *std::min_element(this->
ngrid, this->
ngrid + 3);
968 if (this->
bin_max < separation_nyquist) {
971 "Upper separation limit undershoots the Nyquist scale %.4f.",
983 "Number of bins `num_bins` must be >= 2.\n"
990 && this->
form ==
"row"
996 "Fixed row bin index `idx_bin` must be >= 0.\n"
1005 if (this->
num_bins < nbin_pad + 2) {
1008 "Binning scheme '%s' requires `num_bins` >= %d.",
1009 this->
binning.c_str(), nbin_pad + 2
1013 "Binning scheme '%s' requires `num_bins` >= %d.\n",
1014 this->
binning.c_str(), nbin_pad + 2
1022 "Bin index `idx_bin` must be < `num_bins` in absolute value."
1026 "Bin index `idx_bin` must be < `num_bins` in absolute value.\n"
1035 "Interlacing is unsupported for three-point measurements. "
1036 "`interlace` is set to 'false'."
1048 "`save_binned_vectors` is overridden, as `statistic_type` is '%s' "
1049 "so binned vectors are saved as the output to the default path.",