100 std::string param_filepath = parameter_filepath;
102 std::ifstream fin(param_filepath.c_str());
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] =
"";
116 double boxsize_x, boxsize_y, boxsize_z;
117 int ngrid_x, ngrid_y, ngrid_z;
119 char alignment_[16] =
"";
120 char padscale_[16] =
"";
121 char assignment_[16] =
"";
122 char interlace_[16] =
"";
124 char catalogue_type_[16] =
"";
125 char statistic_type_[16] =
"";
127 char norm_convention_[16] =
"";
128 char binning_[16] =
"";
130 char fftw_scheme_[16] =
"";
131 char use_fftw_wisdom_[1024] =
"";
132 char save_binned_vectors_[1024] =
"";
133 char progbar_[16] =
"";
139 std::string line_str;
140 char dummy_str[1024], dummy_equal[1024];
141 while (std::getline(fin, line_str)) {
143 if (line_str.find(
"#") == 0) {
148 line_str.data(),
"%1023s %1023s %1023s",
149 dummy_str, dummy_equal, dummy_str
154 if (std::strcmp(dummy_equal,
"=") != 0) {
159 auto scan_par_str = [line_str, dummy_str, dummy_equal](
160 const char* par_name,
const char* fmt,
const char* par_value
162 if (line_str.find(par_name) != std::string::npos) {
164 line_str.data(), fmt, dummy_str, dummy_equal, par_value
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_);
181 if (line_str.find(
"boxsize_x") != std::string::npos) {
183 line_str.data(),
"%1023s %1023s %lg",
184 dummy_str, dummy_equal, &boxsize_x
187 if (line_str.find(
"boxsize_y") != std::string::npos) {
189 line_str.data(),
"%1023s %1023s %lg",
190 dummy_str, dummy_equal, &boxsize_y
193 if (line_str.find(
"boxsize_z") != std::string::npos) {
195 line_str.data(),
"%1023s %1023s %lg",
196 dummy_str, dummy_equal, &boxsize_z
200 if (line_str.find(
"ngrid_x") != std::string::npos) {
202 line_str.data(),
"%1023s %1023s %d",
203 dummy_str, dummy_equal, &ngrid_x
206 if (line_str.find(
"ngrid_y") != std::string::npos) {
208 line_str.data(),
"%1023s %1023s %d",
209 dummy_str, dummy_equal, &ngrid_y
212 if (line_str.find(
"ngrid_z") != std::string::npos) {
214 line_str.data(),
"%1023s %1023s %d", dummy_str, dummy_equal, &ngrid_z
218 if (line_str.find(
"expand") != std::string::npos) {
220 line_str.data(),
"%1023s %1023s %lg",
221 dummy_str, dummy_equal, &this->expand
225 scan_par_str(
"alignment",
"%1023s %1023s %1023s", alignment_);
226 scan_par_str(
"padscale",
"%1023s %1023s %1023s", padscale_);
228 if (line_str.find(
"padfactor") != std::string::npos) {
230 line_str.data(),
"%1023s %1023s %lg",
231 dummy_str, dummy_equal, &this->padfactor
235 scan_par_str(
"assignment",
"%1023s %1023s %1023s", assignment_);
236 scan_par_str(
"interlace",
"%1023s %1023s %1023s", interlace_);
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_);
246 if (line_str.find(
"ell1") != std::string::npos) {
248 line_str.data(),
"%1023s %1023s %d",
249 dummy_str, dummy_equal, &this->ell1
252 if (line_str.find(
"ell2") != std::string::npos) {
254 line_str.data(),
"%1023s %1023s %d",
255 dummy_str, dummy_equal, &this->ell2
258 if (line_str.find(
"ELL") != std::string::npos) {
260 line_str.data(),
"%1023s %1023s %d",
261 dummy_str, dummy_equal, &this->ELL
265 if (line_str.find(
"i_wa") != std::string::npos) {
267 line_str.data(),
"%1023s %1023s %d",
268 dummy_str, dummy_equal, &this->i_wa
271 if (line_str.find(
"j_wa") != std::string::npos) {
273 line_str.data(),
"%1023s %1023s %d",
274 dummy_str, dummy_equal, &this->j_wa
278 if (line_str.find(
"bin_min") != std::string::npos) {
280 line_str.data(),
"%1023s %1023s %lg",
281 dummy_str, dummy_equal, &this->bin_min
284 if (line_str.find(
"bin_max") != std::string::npos) {
286 line_str.data(),
"%1023s %1023s %lg",
287 dummy_str, dummy_equal, &this->bin_max
291 if (line_str.find(
"num_bins") != std::string::npos) {
293 line_str.data(),
"%1023s %1023s %d",
294 dummy_str, dummy_equal, &this->num_bins
297 if (line_str.find(
"idx_bin") != std::string::npos) {
299 line_str.data(),
"%1023s %1023s %d",
300 dummy_str, dummy_equal, &this->idx_bin
304 if (line_str.find(
"cutoff_nyq") != std::string::npos) {
306 line_str.data(),
"%1023s %1023s %lg",
307 dummy_str, dummy_equal, &this->cutoff_nyq
313 scan_par_str(
"fftw_scheme",
"%1023s %1023s %1023s", fftw_scheme_);
314 scan_par_str(
"use_fftw_wisdom",
"%1023s %1023s %1023s", use_fftw_wisdom_);
316 "save_binned_vectors",
"%1023s %1023s %1023s", save_binned_vectors_
318 scan_par_str(
"progbar",
"%1023s %1023s %1023s", progbar_);
320 if (line_str.find(
"verbose") != std::string::npos) {
322 line_str.data(),
"%1023s %1023s %d",
323 dummy_str, dummy_equal, &this->verbose
343 if (strlen(alignment_) > 0) {
346 if (strlen(padscale_) > 0) {
349 if (strlen(assignment_) > 0) {
352 if (strlen(interlace_) > 0) {
358 if (strlen(form_) > 0) {
361 if (strlen(norm_convention_) > 0) {
364 if (strlen(binning_) > 0) {
368 if (strlen(fftw_scheme_) > 0) {
371 if (strlen(use_fftw_wisdom_) > 0) {
374 if (strlen(save_binned_vectors_) > 0) {
377 if (strlen(progbar_) > 0) {
386 this->
ngrid[0] = ngrid_x;
387 this->
ngrid[1] = ngrid_y;
388 this->
ngrid[2] = ngrid_z;
390 this->
volume = boxsize_x * boxsize_y * boxsize_z;
391 this->
nmesh = ngrid_x * ngrid_y * ngrid_z;
399 auto debug_par_str = [](
const std::string& name,
const std::string& value) {
400 std::cout << name <<
": " << value << std::endl;
402 auto debug_par_int = [](
const std::string& name,
int value) {
403 std::cout << name <<
": " << value << std::endl;
405 auto debug_par_longlong = [](
const std::string& name,
long long value) {
406 std::cout << name <<
": " << value << std::endl;
408 auto debug_par_double = [](
const std::string& name,
double value) {
409 std::cout << name <<
": " << value << std::endl;
419 debug_par_str(
"output_tag", this->
output_tag);
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);
428 debug_par_str(
"form", this->
form);
430 debug_par_str(
"binning", this->
binning);
435 debug_par_str(
"progbar", this->
progbar);
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]);
441 debug_par_longlong(
"nmesh", this->
nmesh);
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);
449 debug_par_int(
"num_bins", this->
num_bins);
450 debug_par_int(
"idx_bin", this->
idx_bin);
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);
472 this->
catalogue_dir.find_first_not_of(
" \t\n\r\v\f") != std::string::npos
478 this->
measurement_dir.find_first_not_of(
" \t\n\r\v\f") == std::string::npos
506 this->data_catalogue_files.clear();
507 this->rand_catalogue_files.clear();
509 std::string data_ctlg_files, rand_ctlg_files;
510 std::string data_ctlg_file_, rand_ctlg_file_;
518 (dlpos = data_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
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) {
526 this->data_catalogue_files.push_back(data_ctlg_file_);
540 (dlpos = rand_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
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) {
548 this->rand_catalogue_files.push_back(rand_ctlg_file_);
565 (dlpos = rand_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
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) {
573 this->rand_catalogue_files.push_back(rand_ctlg_file_);
589 (dlpos = data_ctlg_files.find(trvs::fn_delimiter)) != std::string::npos
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) {
597 this->data_catalogue_files.push_back(data_ctlg_file_);
615 "Catalogue type must be 'survey', 'random', 'sim' or 'none: "
616 "`catalogue_type` = '%s'.",
621 "Catalogue type must be 'survey', 'random', 'sim' or 'none': "
622 "`catalogue_type` = '%s'.",
628 this->data_catalogue_files, trvs::fn_delimiter
631 this->rand_catalogue_files, trvs::fn_delimiter
637 "Box alignment must be 'centre' or 'pad': `alignment` = '%s'.",
642 "Box alignment must be 'centre' or 'pad': `alignment` = '%s'.",
649 "Pad scale must be 'box' or 'grid': `padscale` = '%s'.",
654 "Pad scale must be 'box' or 'grid': `padscale` = '%s'.",
673 "Mesh assignment scheme must be "
674 "'ngp', 'cic', 'tsc' or 'pcs': `assignment` = '%s'.",
679 "Mesh assignment scheme must be "
680 "'ngp', 'cic', 'tsc' or 'pcs': `assignment` = '%s'.",
692 "Interlacing must be 'true'/'on' or 'false'/'off': "
693 "`interlace` = '%s'.",
698 "Interlacing must be 'true'/'on' or 'false'/'off': "
699 "`interlace` = '%s'.",
709 "Power spectrum requires 'sim' or 'survey' catalogue(s): "
710 "`catalogue_type` = '%s'.",
715 "Power spectrum requires 'sim' or 'survey' catalogue(s): "
716 "`catalogue_type` = '%s'.",
726 "Two-point correlation function requires 'sim' or 'survey' "
727 "catalogue(s): `catalogue_type` = '%s'.",
732 "Two-point correlation function requires 'sim' or 'survey' "
733 "catalogue(s): `catalogue_type` = '%s'.",
743 "Two-point correlation function window requires 'random' catalogue: "
744 "`catalogue_type` = '%s'.",
749 "Two-point correlation function window requires 'random' catalogue: "
750 "`catalogue_type` = '%s'.",
760 "Bispectrum requires 'sim' or 'survey' catalogue(s): "
761 "`catalogue_type` = '%s'.",
766 "Bispectrum requires 'sim' or 'survey' catalogue(s): "
767 "`catalogue_type` = '%s'.",
777 "Three-point correlation function requires 'sim' or 'survey' "
778 "catalogue(s): `catalogue_type` = '%s'.",
783 "Three-point correlation function requires 'sim' or 'survey' "
784 "catalogue(s): `catalogue_type` = '%s'.",
797 "Three-point correlation function window requires 'random' "
798 "catalogue: `catalogue_type` = '%s'.",
803 "Three-point correlation function window requires 'random' "
804 "catalogue: `catalogue_type` = '%s'.",
818 "Statistic type is not recognised: `statistic_type` = '%s'.",
823 "Statistic type is not recognised: `statistic_type` = '%s'.",
830 || this->
form ==
"diag"
831 || this->
form ==
"off-diag"
832 || this->
form ==
"row"
836 "Three-point statistic form is not recognised: `form` = '%s'.",
841 "Three-point statistic form is not recognised: `form` = '%s'.",
846 this->
shape =
"triu";
859 "Normalisation convention must be 'mesh', 'particle', "
860 "'mesh' or 'mesh-mixed': `norm_convention` = '%s'.",
865 "Normalisation convention must be 'mesh', 'particle', "
866 "'mesh' or 'mesh-mixed': `norm_convention` = '%s'.",
873 "Normalisation convention 'mesh-mixed' only applies to "
874 "two-point statistics: `npoint` = '%s'.",
879 "Normalisation convention 'mesh-mixed' only applies to "
880 "two-point statistics: `npoint` = '%s'.",
893 "Binning scheme is unrecognised: `binning` = '%s'.",
898 "Binning scheme is unrecognised: `binning` = '%s'.",
915 "FFTW planner scheme is not supported: `fftw_scheme` = '%s'.",
920 "FFTW planner scheme is not supported: `fftw_scheme` = '%s'.",
928 "FFTW planner scheme is ignored in GPU mode: `fftw_scheme` = '%s'.",
939 trvs::logger.info(
"FFTW wisdom is disabled in GPU mode.");
957 "FFTW wisdom is enabled but the planner scheme "
958 "is not 'measure' or 'patient': "
959 "`fftw_scheme` = '%s'.",
964 "FFTW wisdom is enabled but the planner scheme "
965 "is not 'measure' or 'patient': "
966 "`fftw_scheme` = '%s'.",
971 char fftw_wisdom_file_f_[1024];
972 char fftw_wisdom_file_b_[1024];
974#if defined(TRV_USE_OMP) && defined(TRV_USE_FFTWOMP)
976 fftw_wisdom_file_f_,
sizeof(fftw_wisdom_file_f_),
977 "%sfftw_omp_cif_%dx%dx%d.wisdom",
979 this->ngrid[0], this->ngrid[1], this->ngrid[2]
982 fftw_wisdom_file_b_,
sizeof(fftw_wisdom_file_b_),
983 "%sfftw_omp_cib_%dx%dx%d.wisdom",
985 this->ngrid[0], this->ngrid[1], this->ngrid[2]
989 fftw_wisdom_file_f_,
sizeof(fftw_wisdom_file_f_),
990 "%sfftw_cif_%dx%dx%d.wisdom",
992 this->ngrid[0], this->ngrid[1], this->ngrid[2]
995 fftw_wisdom_file_b_,
sizeof(fftw_wisdom_file_b_),
996 "%sfftw_cib_%dx%dx%d.wisdom",
998 this->ngrid[0], this->ngrid[1], this->ngrid[2]
1006 char default_bvec_sfilepath[1024];
1008 default_bvec_sfilepath,
sizeof(default_bvec_sfilepath),
1009 "%sbinned_vectors%s",
1030 this->
nmesh =
static_cast<long long>(this->
ngrid[0])
1033 if (this->
volume <= 0.) {
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.",
1047 "The box expansion factor must be >= 1: `expand` = %lg",
1052 "The box expansion factor must be >= 1: `expand` = %lg",
1059 "The box expansion factor is expected to be unity "
1060 "for 'sim' catalogue(s): `expand` = %lg",
1066 if (this->
nmesh <= 0) {
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.",
1080 "The Nyquist cutoff must be non-negative: `cutoff_nyq` = %lg",
1085 "The Nyquist cutoff must be non-negative: `cutoff_nyq` = %lg",
1098 "Padding is enabled but the padding factor is negative: "
1099 "`padfactor` = %lg",
1104 "Padding is enabled but the padding factor is negative: "
1105 "`padfactor` = %lg",
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
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
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
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
1145 trvs::logger.error(
"Lower bin edge must be non-negative.");
1148 "Lower bin edge must be non-negative.\n"
1154 "Lower bin edge must be less than the upper bin edge."
1158 "Lower bin edge must be less than the upper bin edge.\n"
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) {
1168 "Lower wavenumber limit exceeds the Nyquist wavenumber %.4f.",
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) {
1181 "Upper separation limit undershoots the Nyquist scale %.4f.",
1190 trvs::logger.error(
"Number of bins `num_bins` must be >= 2.");
1193 "Number of bins `num_bins` must be >= 2.\n"
1200 && this->
form ==
"row"
1203 trvs::logger.error(
"Fixed row bin index `idx_bin` must be >= 0.");
1206 "Fixed row bin index `idx_bin` must be >= 0.\n"
1215 if (this->
num_bins < nbin_pad + 2) {
1218 "Binning scheme '%s' requires `num_bins` >= %d.",
1219 this->
binning.c_str(), nbin_pad + 2
1223 "Binning scheme '%s' requires `num_bins` >= %d.",
1224 this->
binning.c_str(), nbin_pad + 2
1232 "Bin index `idx_bin` must be < `num_bins` in absolute value."
1236 "Bin index `idx_bin` must be < `num_bins` in absolute value.\n"
1245 "Interlacing is unsupported for three-point measurements. "
1246 "`interlace` is set to 'false'."
1258 "`save_binned_vectors` is overridden, as `statistic_type` is '%s' "
1259 "so binned vectors are saved as the output to the default path.",