From a3f831dc9eb213ae1082e57411955c6a8666c33c Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 5 Jun 2025 00:38:27 +0200 Subject: [PATCH] efficiently read in one hyperslab read instead of multiple reads in a loop --- include/aare/Hdf5File.hpp | 10 ++++---- src/Hdf5File.cpp | 49 +++++++++++++++++---------------------- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/include/aare/Hdf5File.hpp b/include/aare/Hdf5File.hpp index 0b7d306..0c5d643 100644 --- a/include/aare/Hdf5File.hpp +++ b/include/aare/Hdf5File.hpp @@ -38,8 +38,9 @@ struct H5Handles { offset[0] = static_cast(frame_index); } - void get_data_into(size_t frame_index, std::byte *frame_buffer) { + void get_data_into(size_t frame_index, std::byte *frame_buffer, size_t n_frames = 1) { seek(frame_index); + count[0] = static_cast(n_frames); //std::cout << "offset:" << offset << " count:" << count << std::endl; dataspace.selectHyperslab(H5S_SELECT_SET, count.data(), offset.data()); dataset.read(frame_buffer, datatype, *memspace, dataspace); @@ -137,17 +138,18 @@ class Hdf5File : public FileInterface { /** * @brief read the frame at the given frame index into the image buffer * @param frame_number frame number to read + * @param n_frames number of frames to read (default is 1) * @param image_buf buffer to store the frame */ - void get_frame_into(size_t frame_index, std::byte *frame_buffer, - DetectorHeader *header = nullptr); + void get_frame_into(size_t frame_index, std::byte *frame_buffer, size_t n_frames = 1, DetectorHeader *header = nullptr); /** * @brief read the frame at the given frame index into the image buffer * @param frame_index frame number to read + * @param n_frames number of frames to read (default is 1) * @param frame_buffer buffer to store the frame */ - void get_data_into(size_t frame_index, std::byte *frame_buffer); + void get_data_into(size_t frame_index, std::byte *frame_buffer, size_t n_frames = 1); /** * @brief read the header at the given frame index into the header buffer diff --git a/src/Hdf5File.cpp b/src/Hdf5File.cpp index a10341a..c829d51 100644 --- a/src/Hdf5File.cpp +++ b/src/Hdf5File.cpp @@ -27,30 +27,21 @@ Frame Hdf5File::read_frame(size_t frame_number) { } void Hdf5File::read_into(std::byte *image_buf, size_t n_frames) { - // TODO: implement this in a more efficient way - - for (size_t i = 0; i < n_frames; i++) { - get_frame_into(m_current_frame++, image_buf); - image_buf += bytes_per_frame(); - } + get_frame_into(m_current_frame++, image_buf, n_frames); } void Hdf5File::read_into(std::byte *image_buf) { - return get_frame_into(m_current_frame++, image_buf); + get_frame_into(m_current_frame++, image_buf); } void Hdf5File::read_into(std::byte *image_buf, DetectorHeader *header) { - return get_frame_into(m_current_frame++, image_buf, header); + get_frame_into(m_current_frame, image_buf, 1, header); } void Hdf5File::read_into(std::byte *image_buf, size_t n_frames, DetectorHeader *header) { - for (size_t i = 0; i < n_frames; i++) { - get_frame_into(m_current_frame++, image_buf, header); - image_buf += bytes_per_frame(); - header += n_modules(); - } + get_frame_into(m_current_frame++, image_buf, n_frames, header); } size_t Hdf5File::bytes_per_frame() { @@ -119,30 +110,25 @@ DetectorHeader Hdf5File::read_header(const std::filesystem::path &fname) { } -Frame Hdf5File::get_frame(size_t frame_index) { - auto f = Frame(m_rows, m_cols, Dtype::from_bitdepth(m_master.bitdepth())); - std::byte *frame_buffer = f.data(); - get_frame_into(frame_index, frame_buffer); - return f; -} - -void Hdf5File::get_frame_into(size_t frame_index, std::byte *frame_buffer, - DetectorHeader *header) { - if (frame_index >= m_master.frames_in_file()) { +void Hdf5File::get_frame_into(size_t frame_index, std::byte *frame_buffer, size_t n_frames, DetectorHeader *header) { + if ((frame_index + n_frames - 1) >= m_master.frames_in_file()) { throw std::runtime_error(LOCATION + "Frame number out of range"); } get_data_into(frame_index, frame_buffer); + m_current_frame += n_frames; if (header) { - for (size_t part_idx = 0; part_idx != m_master.n_modules(); ++part_idx) { - get_header_into(frame_index, part_idx, header); - header++; + for (size_t i = 0; i < n_frames; i++) { + for (size_t part_idx = 0; part_idx != m_master.n_modules(); ++part_idx) { + get_header_into(frame_index + i, part_idx, header); + header++; + } } } } -void Hdf5File::get_data_into(size_t frame_index, std::byte *frame_buffer) { - m_data_file->get_data_into(frame_index, frame_buffer); +void Hdf5File::get_data_into(size_t frame_index, std::byte *frame_buffer, size_t n_frames) { + m_data_file->get_data_into(frame_index, frame_buffer, n_frames); } void Hdf5File::get_header_into(size_t frame_index, int part_index, DetectorHeader *header) { @@ -170,6 +156,13 @@ void Hdf5File::get_header_into(size_t frame_index, int part_index, DetectorHeade } } +Frame Hdf5File::get_frame(size_t frame_index) { + auto f = Frame(m_rows, m_cols, Dtype::from_bitdepth(m_master.bitdepth())); + std::byte *frame_buffer = f.data(); + get_frame_into(frame_index, frame_buffer); + return f; +} + std::vector Hdf5File::read_n(size_t n_frames) { // TODO: implement this in a more efficient way std::vector frames;