95 const std::string& catalogue_filepath,
96 const std::string& catalogue_columns,
97 const std::string& catalogue_dataset,
100 if (!(this->
source.empty())) {
103 "Catalogue already loaded from another source: %s.", this->
source.c_str()
107 "Catalogue already loaded from another source: %s.",
111 this->
source =
"extfile:" + catalogue_filepath;
122 "HDF5 file format is not supported in this build: %s",
123 catalogue_filepath.c_str()
127 "HDF5 file format is not supported in this build: %s",
128 catalogue_filepath.c_str()
138 const std::vector<std::string> names_ordered = {
139 "x",
"y",
"z",
"nz",
"ws",
"wc"
142 std::istringstream iss(catalogue_columns);
143 std::vector<std::string> colnames;
145 while (std::getline(iss, name,
',')) {
146 colnames.push_back(name);
150 std::vector<int> name_indices(names_ordered.size(), -1);
151 for (std::size_t iname = 0; iname < names_ordered.size(); iname++) {
152 std::size_t col_idx =
static_cast<std::size_t
>(std::distance(
154 std::find(colnames.begin(), colnames.end(), names_ordered[iname])
156 if (col_idx < colnames.size()) {
157 name_indices[iname] = col_idx;
166 catalogue_filepath, trvs::fn_delimiter
173 std::vector<std::vector<double>> ctlg_data;
174 for (
const auto& ctlg_subfilepath : catalogue_subfilepaths) {
175 HighFive::File ctlg_subfile(
176 ctlg_subfilepath, HighFive::File::ReadOnly
181 std::vector<std::string> obj_names = ctlg_subfile.listObjectNames();
182 if (obj_names.empty()) {
185 "No objects found in HDF5 file: %s",
186 catalogue_filepath.c_str()
190 "No objects found in HDF5 file: %s",
191 catalogue_filepath.c_str()
195 std::string ctlg_dset_name = catalogue_dataset;
196 if (ctlg_dset_name.empty()) {
197 for (
const auto& obj_name : obj_names) {
198 HighFive::ObjectType obj_type =
199 ctlg_subfile.getObjectType(obj_name);
200 if (obj_type == HighFive::ObjectType::Dataset) {
201 ctlg_dset_name = obj_name;
203 "Catalogue dataset name inferred from HDF5 file: %s",
204 ctlg_dset_name.c_str()
209 if (ctlg_dset_name.empty()) {
212 "No datasets found in HDF5 file: %s",
213 catalogue_filepath.c_str()
217 "No datasets found in HDF5 file: %s",
218 catalogue_filepath.c_str()
223 HighFive::DataSet ctlg_dset = ctlg_subfile.getDataSet(ctlg_dset_name);
227 HighFive::DataType ctlg_dtype = ctlg_dset.getDataType();
229 ctlg_dtype != HighFive::create_datatype<float>()
230 && ctlg_dtype != HighFive::create_datatype<double>()
234 "Unsupported or mixed data type in HDF5 file: %s",
235 catalogue_filepath.c_str()
239 "Unsupported or mixed data type in HDF5 file: %s",
240 catalogue_filepath.c_str()
245 std::vector<std::string> ctlg_colnames;
246 if (colnames.empty()) {
247 std::vector<std::string> dset_attrs = ctlg_dset.listAttributeNames();
248 if (dset_attrs.empty()) {
251 "Catalogue column names are not specified, and "
252 "no attributes found in the dataset: %s",
253 ctlg_dset_name.c_str()
257 "Catalogue column names are not specified, and "
258 "no attributes found in the dataset: %s",
259 ctlg_dset_name.c_str()
263 ctlg_dset.getAttribute(dset_attrs[0]).read(ctlg_colnames);
266 "Catalogue column names inferred from HDF5 file: %s",
267 catalogue_filepath.c_str()
270 for (std::size_t iname = 0; iname < names_ordered.size(); iname++) {
271 std::size_t col_idx =
static_cast<std::size_t
>(std::distance(
272 ctlg_colnames.begin(),
274 ctlg_colnames.begin(), ctlg_colnames.end(), names_ordered[iname]
277 if (col_idx < ctlg_colnames.size()) {
278 name_indices[iname] = col_idx;
280 name_indices[iname] = -1;
284 if (colnames.size() == 1 and colnames[0].find(
"attr::") == 0) {
285 std::string attr_name = colnames[0].substr(6);
286 ctlg_dset.getAttribute(attr_name).read(ctlg_colnames);
289 "Catalogue column names inferred from dataset attribute: %s",
293 for (std::size_t iname = 0; iname < names_ordered.size(); iname++) {
294 std::size_t col_idx =
static_cast<std::size_t
>(std::distance(
295 ctlg_colnames.begin(),
297 ctlg_colnames.begin(), ctlg_colnames.end(), names_ordered[iname]
300 if (col_idx < ctlg_colnames.size()) {
301 name_indices[iname] = col_idx;
303 name_indices[iname] = -1;
307 ctlg_colnames = colnames;
311 std::vector<std::size_t> ctlg_dims = ctlg_dset.getDimensions();
312 int num_rows =
static_cast<int>(ctlg_dims[0]);
315 std::vector<std::vector<double>> ctlg_subdata(num_rows);
316 ctlg_dset.read(ctlg_subdata);
319 ctlg_data.end(), ctlg_subdata.begin(), ctlg_subdata.end()
329 if (name_indices[3] == -1) {
332 "Catalogue 'nz' field is unavailable and "
333 "will be set to the mean density in the bounding box (source=%s).",
339 double nz_box_default = 0.;
341 nz_box_default = this->
ntotal / volume;
346 for (
const auto& row : ctlg_data) {
347 this->
pdata[idx_row].pos[0] = row[name_indices[0]];
348 this->
pdata[idx_row].pos[1] = row[name_indices[1]];
349 this->
pdata[idx_row].pos[2] = row[name_indices[2]];
351 if (name_indices[3] != -1) {
352 nz = row[name_indices[3]];
357 if (name_indices[4] != -1) {
358 ws = row[name_indices[4]];
363 if (name_indices[5] != -1) {
364 wc = row[name_indices[5]];
369 this->
pdata[idx_row].nz = nz;
370 this->
pdata[idx_row].ws = ws;
371 this->
pdata[idx_row].wc = wc;
372 this->
pdata[idx_row].w = ws * wc;
376 }
catch (
const HighFive::Exception& e) {
385 for (
const auto& ctlg_subfilepath : catalogue_subfilepaths) {
388 fin.open(ctlg_subfilepath.c_str(), std::ios::in);
394 "Failed to open file: %s", ctlg_subfilepath.c_str()
398 "Failed to open file: %s", ctlg_subfilepath.c_str()
404 std::string line_str;
405 while (std::getline(fin, line_str)) {
410 if (line_str.empty() || line_str[0] ==
'#') {
continue;}
425 if (name_indices[3] == -1) {
428 "Catalogue 'nz' field is unavailable and "
429 "will be set to the mean density in the bounding box (source=%s).",
435 double nz_box_default = 0.;
437 nz_box_default = this->
ntotal / volume;
441 std::string entry_str;
442 for (
const auto& ctlg_subfilepath : catalogue_subfilepaths) {
444 fin.open(ctlg_subfilepath.c_str(), std::ios::in);
448 while (std::getline(fin, entry_str)) {
453 if (entry_str.empty() || entry_str[0] ==
'#') {
continue;}
456 std::vector<double> row;
458 std::stringstream ss(
460 std::ios_base::out | std::ios_base::in | std::ios_base::binary
462 while (ss >> entry) {row.push_back(entry);}
465 this->
pdata[idx_entry].pos[0] = row[name_indices[0]];
466 this->
pdata[idx_entry].pos[1] = row[name_indices[1]];
467 this->
pdata[idx_entry].pos[2] = row[name_indices[2]];
469 if (name_indices[3] != -1) {
470 nz = row[name_indices[3]];
475 if (name_indices[4] != -1) {
476 ws = row[name_indices[4]];
481 if (name_indices[5] != -1) {
482 wc = row[name_indices[5]];
487 this->
pdata[idx_entry].nz = nz;
488 this->
pdata[idx_entry].ws = ws;
489 this->
pdata[idx_entry].wc = wc;
490 this->
pdata[idx_entry].w = ws * wc;
static void centre_in_box(ParticleCatalogue &catalogue, const double boxsize[3])
Centre a catalogue in a box.
int load_particle_data(std::vector< double > x, std::vector< double > y, std::vector< double > z, std::vector< double > nz, std::vector< double > ws, std::vector< double > wc)
Read in particle data.
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.
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.
static void pad_in_box(ParticleCatalogue &catalogue, const double boxsize[3], const double boxsize_pad[3])
Pad a catalogue in a box.
Particle containers with I/O methods and operations.