From e6b14bc67d491a3c2efffe1c728cfc0ef7f068b9 Mon Sep 17 00:00:00 2001 From: Dimitri Vlachos Date: Tue, 28 Jan 2025 18:02:49 +0000 Subject: [PATCH] Enhance HDF5 dataset reading function with improved error handling --- include/dx2/h5/h5read_processed.h | 95 +++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/include/dx2/h5/h5read_processed.h b/include/dx2/h5/h5read_processed.h index 1b636ca..5118641 100644 --- a/include/dx2/h5/h5read_processed.h +++ b/include/dx2/h5/h5read_processed.h @@ -7,34 +7,79 @@ #include #include +/** + * @brief Reads a dataset from an HDF5 file into an std::vector. + * + * @tparam T The type of data to read (e.g., int, double). + * @param filename The path to the HDF5 file. + * @param dataset_name The name of the dataset to read. + * @return A std::vector containing the data from the dataset. + * @throws std::runtime_error If the file, dataset, or datatype cannot be opened + * or read. + */ template -std::vector read_array_from_h5_file(std::string filename, - std::string array_name) { +std::vector read_array_from_h5_file(const std::string &filename, + const std::string &dataset_name) { + // Start measuring time auto start_time = std::chrono::high_resolution_clock::now(); + + // Open the HDF5 file hid_t file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); if (file < 0) { - std::cout << "Error: Unable to open " << filename.c_str() - << " as a hdf5 reflection table" << std::endl; - std::exit(1); + throw std::runtime_error("Error: Unable to open file: " + filename); } - hid_t dataset = H5Dopen(file, array_name.c_str(), H5P_DEFAULT); - hid_t datatype = H5Dget_type(dataset); - size_t datatype_size = H5Tget_size(datatype); - assert((datatype_size == sizeof(T))); - hid_t dataspace = H5Dget_space(dataset); - size_t num_elements = H5Sget_simple_extent_npoints(dataspace); - hid_t space = H5Dget_space(dataset); - std::vector data_out(num_elements); - - H5Dread(dataset, datatype, H5S_ALL, space, H5P_DEFAULT, &data_out[0]); - float total_time = std::chrono::duration_cast>( - std::chrono::high_resolution_clock::now() - start_time) - .count(); - std::cout << "READ TIME for " << array_name << " : " << total_time << "s" - << std::endl; - - H5Dclose(dataset); - H5Fclose(file); - return data_out; -} + try { + // Open the dataset + hid_t dataset = H5Dopen(file, dataset_name.c_str(), H5P_DEFAULT); + if (dataset < 0) { + throw std::runtime_error("Error: Unable to open dataset: " + + dataset_name); + } + + try { + // Get the datatype and check size + hid_t datatype = H5Dget_type(dataset); + size_t datatype_size = H5Tget_size(datatype); + if (datatype_size != sizeof(T)) { + throw std::runtime_error( + "Error: Dataset type size does not match expected type size."); + } + + // Get the dataspace and the number of elements + hid_t dataspace = H5Dget_space(dataset); + size_t num_elements = H5Sget_simple_extent_npoints(dataspace); + + // Allocate a vector to hold the data + std::vector 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: " + + dataset_name); + } + + // Close the dataset and return the data + H5Dclose(dataset); + H5Fclose(file); + + // Log timing + auto end_time = std::chrono::high_resolution_clock::now(); + double elapsed_time = + std::chrono::duration(end_time - start_time).count(); + std::cout << "READ TIME for " << dataset_name << " : " << elapsed_time + << "s" << std::endl; + + return data_out; + + } catch (...) { + H5Dclose(dataset); // Ensure dataset is closed in case of failure + throw; + } + } catch (...) { + H5Fclose(file); // Ensure file is closed in case of failure + throw; + } +} \ No newline at end of file