mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-12-26 15:01:25 +01:00
refactoring, removing redundant functiosn to read header fields
This commit is contained in:
@@ -83,6 +83,24 @@ struct H5Handles {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Fn>
|
||||||
|
void read_hdf5_header_fields(DetectorHeader *header, Fn &&fn_read_field) {
|
||||||
|
fn_read_field(0, reinterpret_cast<std::byte *>(&(header->frameNumber)));
|
||||||
|
fn_read_field(1, reinterpret_cast<std::byte *>(&(header->expLength)));
|
||||||
|
fn_read_field(2, reinterpret_cast<std::byte *>(&(header->packetNumber)));
|
||||||
|
fn_read_field(3, reinterpret_cast<std::byte *>(&(header->bunchId)));
|
||||||
|
fn_read_field(4, reinterpret_cast<std::byte *>(&(header->timestamp)));
|
||||||
|
fn_read_field(5, reinterpret_cast<std::byte *>(&(header->modId)));
|
||||||
|
fn_read_field(6, reinterpret_cast<std::byte *>(&(header->row)));
|
||||||
|
fn_read_field(7, reinterpret_cast<std::byte *>(&(header->column)));
|
||||||
|
fn_read_field(8, reinterpret_cast<std::byte *>(&(header->reserved)));
|
||||||
|
fn_read_field(9, reinterpret_cast<std::byte *>(&(header->debug)));
|
||||||
|
fn_read_field(10, reinterpret_cast<std::byte *>(&(header->roundRNumber)));
|
||||||
|
fn_read_field(11, reinterpret_cast<std::byte *>(&(header->detType)));
|
||||||
|
fn_read_field(12, reinterpret_cast<std::byte *>(&(header->version)));
|
||||||
|
fn_read_field(13, reinterpret_cast<std::byte *>(&(header->packetMask)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to read .h5 files. The class will parse the master file
|
* @brief Class to read .h5 files. The class will parse the master file
|
||||||
* to find the correct geometry for the frames.
|
* to find the correct geometry for the frames.
|
||||||
@@ -97,6 +115,11 @@ class Hdf5File : public FileInterface {
|
|||||||
size_t m_rows{};
|
size_t m_rows{};
|
||||||
size_t m_cols{};
|
size_t m_cols{};
|
||||||
|
|
||||||
|
static const std::string metadata_group_name;
|
||||||
|
static const std::vector<std::string> header_dataset_names;
|
||||||
|
std::unique_ptr<H5Handles> m_data_file{nullptr};
|
||||||
|
std::vector<std::unique_ptr<H5Handles>> m_header_files;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Hdf5File constructor
|
* @brief Hdf5File constructor
|
||||||
@@ -135,36 +158,39 @@ class Hdf5File : public FileInterface {
|
|||||||
DetectorType detector_type() const override;
|
DetectorType detector_type() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @brief get the frame at the given frame index
|
||||||
|
* @param frame_number frame number to read
|
||||||
|
* @return Frame
|
||||||
|
*/
|
||||||
|
Frame get_frame(size_t frame_index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief read the frame at the given frame index into the image buffer
|
* @brief read the frame at the given frame index into the image buffer
|
||||||
* @param frame_number frame number to read
|
* @param frame_number frame number to read
|
||||||
* @param n_frames number of frames to read (default is 1)
|
* @param n_frames number of frames to read (default is 1)
|
||||||
* @param image_buf buffer to store the frame
|
* @param image_buf buffer to store the frame
|
||||||
*/
|
*/
|
||||||
void get_frame_into(size_t frame_index, std::byte *frame_buffer, size_t n_frames = 1, 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
|
* @brief read the frame at the given frame index into the image buffer
|
||||||
* @param frame_index frame number to read
|
* @param frame_index frame number to read
|
||||||
* @param n_frames number of frames to read (default is 1)
|
* @param n_frames number of frames to read (default is 1)
|
||||||
* @param frame_buffer buffer to store the frame
|
* @param frame_buffer buffer to store the frame
|
||||||
*/
|
*/
|
||||||
void get_data_into(size_t frame_index, std::byte *frame_buffer, size_t n_frames = 1);
|
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
|
* @brief read the header at the given frame index into the header buffer
|
||||||
* @param frame_index frame number to read
|
* @param frame_index frame number to read
|
||||||
* @param part_index part index to read (for virtual datasets)
|
* @param part_index part index to read (for virtual datasets)
|
||||||
* @param header buffer to store the header
|
* @param header buffer to store the header
|
||||||
*/
|
*/
|
||||||
void get_header_into(size_t frame_index, int part_index, DetectorHeader *header);
|
void get_header_into(size_t frame_index, int part_index,
|
||||||
|
DetectorHeader *header);
|
||||||
/**
|
|
||||||
* @brief get the frame at the given frame index
|
|
||||||
* @param frame_number frame number to read
|
|
||||||
* @return Frame
|
|
||||||
*/
|
|
||||||
Frame get_frame(size_t frame_index);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief read the header of the file
|
* @brief read the header of the file
|
||||||
@@ -173,12 +199,6 @@ class Hdf5File : public FileInterface {
|
|||||||
*/
|
*/
|
||||||
static DetectorHeader read_header(const std::filesystem::path &fname);
|
static DetectorHeader read_header(const std::filesystem::path &fname);
|
||||||
|
|
||||||
static const std::string metadata_group_name;
|
|
||||||
static const std::vector<std::string> header_dataset_names;
|
|
||||||
|
|
||||||
std::unique_ptr<H5Handles> m_data_file{nullptr};
|
|
||||||
std::vector<std::unique_ptr<H5Handles>> m_header_files;
|
|
||||||
|
|
||||||
void open_data_file();
|
void open_data_file();
|
||||||
void open_header_files();
|
void open_header_files();
|
||||||
};
|
};
|
||||||
|
|||||||
182
src/Hdf5File.cpp
182
src/Hdf5File.cpp
@@ -26,6 +26,16 @@ Frame Hdf5File::read_frame(size_t frame_number) {
|
|||||||
return read_frame();
|
return read_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Frame> Hdf5File::read_n(size_t n_frames) {
|
||||||
|
// TODO: implement this in a more efficient way
|
||||||
|
std::vector<Frame> frames;
|
||||||
|
for (size_t i = 0; i < n_frames; i++) {
|
||||||
|
frames.push_back(this->get_frame(m_current_frame));
|
||||||
|
m_current_frame++;
|
||||||
|
}
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
void Hdf5File::read_into(std::byte *image_buf, size_t n_frames) {
|
void Hdf5File::read_into(std::byte *image_buf, size_t n_frames) {
|
||||||
get_frame_into(m_current_frame++, image_buf, n_frames);
|
get_frame_into(m_current_frame++, image_buf, n_frames);
|
||||||
}
|
}
|
||||||
@@ -44,14 +54,26 @@ void Hdf5File::read_into(std::byte *image_buf, size_t n_frames,
|
|||||||
get_frame_into(m_current_frame++, image_buf, n_frames, header);
|
get_frame_into(m_current_frame++, image_buf, n_frames, header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Hdf5File::frame_number(size_t frame_index) {
|
||||||
|
// TODO: check if it should check total_Frames() at any point
|
||||||
|
// check why this->read_into.. as in RawFile
|
||||||
|
// refactor multiple frame reads into a single one using hyperslab
|
||||||
|
if (frame_index >= m_master.frames_in_file()) {
|
||||||
|
throw std::runtime_error(LOCATION + " Frame number out of range");
|
||||||
|
}
|
||||||
|
uint64_t fnum{0};
|
||||||
|
int part_index = 0; // assuming first part
|
||||||
|
m_header_files[0]->get_header_into(frame_index, part_index,
|
||||||
|
reinterpret_cast<std::byte *>(&fnum));
|
||||||
|
return fnum;
|
||||||
|
}
|
||||||
|
|
||||||
size_t Hdf5File::bytes_per_frame() {
|
size_t Hdf5File::bytes_per_frame() {
|
||||||
return m_rows * m_cols * m_master.bitdepth() / 8;
|
return m_rows * m_cols * m_master.bitdepth() / 8;
|
||||||
}
|
}
|
||||||
size_t Hdf5File::pixels_per_frame() { return m_rows * m_cols; }
|
|
||||||
|
|
||||||
DetectorType Hdf5File::detector_type() const {
|
size_t Hdf5File::pixels_per_frame() { return m_rows * m_cols; }
|
||||||
return m_master.detector_type();
|
size_t Hdf5File::bytes_per_pixel() const { return m_master.bitdepth() / 8; }
|
||||||
}
|
|
||||||
|
|
||||||
void Hdf5File::seek(size_t frame_index) {
|
void Hdf5File::seek(size_t frame_index) {
|
||||||
m_data_file->seek(frame_index);
|
m_data_file->seek(frame_index);
|
||||||
@@ -62,7 +84,6 @@ void Hdf5File::seek(size_t frame_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t Hdf5File::tell() { return m_current_frame; }
|
size_t Hdf5File::tell() { return m_current_frame; }
|
||||||
|
|
||||||
size_t Hdf5File::total_frames() const { return m_total_frames; }
|
size_t Hdf5File::total_frames() const { return m_total_frames; }
|
||||||
size_t Hdf5File::rows() const { return m_rows; }
|
size_t Hdf5File::rows() const { return m_rows; }
|
||||||
size_t Hdf5File::cols() const { return m_cols; }
|
size_t Hdf5File::cols() const { return m_cols; }
|
||||||
@@ -70,33 +91,69 @@ size_t Hdf5File::bitdepth() const { return m_master.bitdepth(); }
|
|||||||
xy Hdf5File::geometry() { return m_master.geometry(); }
|
xy Hdf5File::geometry() { return m_master.geometry(); }
|
||||||
size_t Hdf5File::n_modules() const { return m_master.n_modules(); }
|
size_t Hdf5File::n_modules() const { return m_master.n_modules(); }
|
||||||
Hdf5MasterFile Hdf5File::master() const { return m_master; }
|
Hdf5MasterFile Hdf5File::master() const { return m_master; }
|
||||||
size_t Hdf5File::bytes_per_pixel() const { return m_master.bitdepth() / 8; }
|
|
||||||
|
|
||||||
|
DetectorType Hdf5File::detector_type() const {
|
||||||
|
return m_master.detector_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
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 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,
|
||||||
|
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) {
|
||||||
|
try {
|
||||||
|
read_hdf5_header_fields(header,
|
||||||
|
[&](size_t iParameter, std::byte *dest) {
|
||||||
|
m_header_files[iParameter]->get_header_into(
|
||||||
|
frame_index, part_index, dest);
|
||||||
|
});
|
||||||
|
LOG(logDEBUG5) << "Read 1D header for frame " << frame_index;
|
||||||
|
} catch (const H5::Exception &e) {
|
||||||
|
fmt::print("Exception type: {}\n", typeid(e).name());
|
||||||
|
e.printErrorStack();
|
||||||
|
throw std::runtime_error(
|
||||||
|
LOCATION + "\nCould not to access header datasets in given file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DetectorHeader Hdf5File::read_header(const std::filesystem::path &fname) {
|
DetectorHeader Hdf5File::read_header(const std::filesystem::path &fname) {
|
||||||
DetectorHeader h{};
|
DetectorHeader h{};
|
||||||
std::vector<std::unique_ptr<H5Handles>> handles;
|
std::vector<std::unique_ptr<H5Handles>> handles;
|
||||||
try {
|
try {
|
||||||
for (size_t i = 0; i != header_dataset_names.size(); ++i) {
|
for (size_t i = 0; i != header_dataset_names.size(); ++i) {
|
||||||
handles.push_back(std::make_unique<H5Handles>(fname.string(), metadata_group_name+ header_dataset_names[i]));
|
handles.push_back(std::make_unique<H5Handles>(
|
||||||
|
fname.string(), metadata_group_name + header_dataset_names[i]));
|
||||||
}
|
}
|
||||||
// reading first header and assuming first part
|
read_hdf5_header_fields(&h, [&](size_t iParameter, std::byte *dest) {
|
||||||
size_t frame_index = 0;
|
handles[iParameter]->get_header_into(0, 0, dest);
|
||||||
int part_index = 0;
|
});
|
||||||
handles[0]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.frameNumber)));
|
|
||||||
handles[1]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.expLength)));
|
|
||||||
handles[2]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.packetNumber)));
|
|
||||||
handles[3]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.bunchId)));
|
|
||||||
handles[4]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.timestamp)));
|
|
||||||
handles[5]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.modId)));
|
|
||||||
handles[6]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.row)));
|
|
||||||
handles[7]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.column)));
|
|
||||||
handles[8]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.reserved)));
|
|
||||||
handles[9]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.debug)));
|
|
||||||
handles[10]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.roundRNumber)));
|
|
||||||
handles[11]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.detType)));
|
|
||||||
handles[12]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.version)));
|
|
||||||
handles[13]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(h.packetMask)));
|
|
||||||
LOG(logDEBUG5) << "Read 1D header for frame 0";
|
LOG(logDEBUG5) << "Read 1D header for frame 0";
|
||||||
} catch (const H5::Exception &e) {
|
} catch (const H5::Exception &e) {
|
||||||
handles.clear();
|
handles.clear();
|
||||||
@@ -109,83 +166,6 @@ DetectorHeader Hdf5File::read_header(const std::filesystem::path &fname) {
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 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, 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) {
|
|
||||||
try {
|
|
||||||
m_header_files[0]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->frameNumber)));
|
|
||||||
m_header_files[1]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->expLength)));
|
|
||||||
m_header_files[2]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->packetNumber)));
|
|
||||||
m_header_files[3]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->bunchId)));
|
|
||||||
m_header_files[4]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->timestamp)));
|
|
||||||
m_header_files[5]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->modId)));
|
|
||||||
m_header_files[6]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->row)));
|
|
||||||
m_header_files[7]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->column)));
|
|
||||||
m_header_files[8]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->reserved)));
|
|
||||||
m_header_files[9]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->debug)));
|
|
||||||
m_header_files[10]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->roundRNumber)));
|
|
||||||
m_header_files[11]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->detType)));
|
|
||||||
m_header_files[12]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->version)));
|
|
||||||
m_header_files[13]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&(header->packetMask)));
|
|
||||||
LOG(logDEBUG) << "Read 1D header for frame " << frame_index;
|
|
||||||
} catch (const H5::Exception &e) {
|
|
||||||
fmt::print("Exception type: {}\n", typeid(e).name());
|
|
||||||
e.printErrorStack();
|
|
||||||
throw std::runtime_error(
|
|
||||||
LOCATION + "\nCould not to access header datasets in given file.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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<Frame> Hdf5File::read_n(size_t n_frames) {
|
|
||||||
// TODO: implement this in a more efficient way
|
|
||||||
std::vector<Frame> frames;
|
|
||||||
for (size_t i = 0; i < n_frames; i++) {
|
|
||||||
frames.push_back(this->get_frame(m_current_frame));
|
|
||||||
m_current_frame++;
|
|
||||||
}
|
|
||||||
return frames;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Hdf5File::frame_number(size_t frame_index) {
|
|
||||||
//TODO: check if it should check total_Frames() at any point
|
|
||||||
// check why this->read_into.. as in RawFile
|
|
||||||
// refactor multiple frame reads into a single one using hyperslab
|
|
||||||
if (frame_index >= m_master.frames_in_file()) {
|
|
||||||
throw std::runtime_error(LOCATION + " Frame number out of range");
|
|
||||||
}
|
|
||||||
uint64_t fnum{0};
|
|
||||||
int part_index = 0; // assuming first part
|
|
||||||
m_header_files[0]->get_header_into(frame_index, part_index, reinterpret_cast<std::byte *>(&fnum));
|
|
||||||
return fnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
Hdf5File::~Hdf5File() {}
|
Hdf5File::~Hdf5File() {}
|
||||||
|
|
||||||
const std::string Hdf5File::metadata_group_name = "/entry/data/";
|
const std::string Hdf5File::metadata_group_name = "/entry/data/";
|
||||||
|
|||||||
Reference in New Issue
Block a user