Program Listing for File h5read_processed.hpp¶
↰ Return to documentation for file (include/dx2/h5/h5read_processed.hpp)
#pragma once
#include "dx2/h5/h5utils.hpp"
#include "dx2/logging.hpp"
#include <cassert>
#include <chrono>
#include <cstring>
#include <experimental/mdspan>
#include <hdf5.h>
#include <hdf5_hl.h>
#include <string>
#include <typeindex>
#include <unordered_set>
#include <vector>
namespace h5read_processed_utils {
#pragma region Internal Structs
template <typename T> struct H5ArrayData {
std::vector<T> data;
std::vector<size_t> shape;
};
struct GroupScanContext {
std::string group_name; // Name of the group being scanned
std::vector<std::string> datasets; // Collected dataset paths
};
struct TraverseData {
std::vector<std::string> *datasets;
std::string current_path;
std::unordered_set<std::string> *visited_groups;
};
#pragma endregion
#pragma region Callbacks
herr_t scan_group_callback(hid_t loc_id, const char *name, const H5L_info2_t *,
void *op_data);
herr_t group_iterator(hid_t loc_id, const char *name, const H5L_info2_t *info,
void *op_data);
#pragma endregion
#pragma region Group Traversal
void traverse_hdf5(hid_t loc_id, const std::string &path,
std::vector<std::string> &datasets,
std::unordered_set<std::string> &visited_groups);
#pragma endregion
} // namespace h5read_processed_utils
#pragma region Public API
std::vector<std::string> get_datasets_in_group(std::string_view filename,
std::string_view group_name);
template <typename T>
h5read_processed_utils::H5ArrayData<T>
read_array_with_shape_from_h5_file(std::string_view filename,
std::string_view dataset_name) {
auto start_time = std::chrono::high_resolution_clock::now();
std::string fname(filename);
std::string dset_name(dataset_name);
// Open the HDF5 file
h5utils::H5File file(H5Fopen(fname.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT));
if (!file) {
throw std::runtime_error("Error: Unable to open file: " + fname);
}
// Open the dataset
h5utils::H5Dataset dataset(H5Dopen(file, dset_name.c_str(), H5P_DEFAULT));
if (!dataset) {
throw std::runtime_error("Error: Unable to open dataset: " + dset_name);
}
// Get the datatype and check size
h5utils::H5Type datatype(H5Dget_type(dataset));
if (H5Tget_size(datatype) != sizeof(T)) {
throw std::runtime_error(
"Error: Dataset type size does not match expected type size.");
}
// Get the dataspace and the number of elements
h5utils::H5Space dataspace(H5Dget_space(dataset));
int ndims = H5Sget_simple_extent_ndims(dataspace);
if (ndims <= 0) {
throw std::runtime_error("Error: Dataset has invalid dimensionality.");
}
// Get the dimensions of the dataset
std::vector<hsize_t> dims(ndims);
H5Sget_simple_extent_dims(dataspace, dims.data(), nullptr);
// Calculate the number of elements
size_t num_elements = 1;
for (auto d : dims)
num_elements *= d;
// Allocate a vector to hold the data
std::vector<T> data_out(num_elements);
// Read the data into the vector
herr_t status = H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT,
data_out.data());
if (status < 0) {
throw std::runtime_error("Error: Unable to read dataset: " + dset_name);
}
auto end_time = std::chrono::high_resolution_clock::now();
double elapsed_time =
std::chrono::duration<double>(end_time - start_time).count();
dx2_log::debug("READ TIME for {} : {:.4f}s", dset_name, elapsed_time);
return {std::move(data_out), std::vector<size_t>(dims.begin(), dims.end())};
}
template <typename T>
std::vector<T> read_array_from_h5_file(std::string_view filename,
std::string_view dataset_name) {
return read_array_with_shape_from_h5_file<T>(filename, dataset_name).data;
}
std::vector<std::string>
get_datasets_in_group_recursive(std::string_view filename,
std::string_view group_name);
void read_experiment_metadata(hid_t group_id,
std::vector<uint64_t> &experiment_ids,
std::vector<std::string> &identifiers);
std::string get_dataset_name(std::string_view path);
#pragma endregion