From 755a8fb2b70668778bbaa6eb2121694b78ce45f3 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Mon, 9 Jun 2025 14:41:07 +0200 Subject: [PATCH] added exptime, period in hdf5, also added print for chrono and StringTo --- CMakeLists.txt | 1 + include/aare/Hdf5MasterFile.hpp | 21 ++++---- include/aare/defs.hpp | 91 ++++++++++++++++++++++++++++++++- include/aare/type_traits.hpp | 26 ++++++++++ src/Hdf5MasterFile.cpp | 64 ++++++++++++++++++++--- src/defs.cpp | 13 +++++ 6 files changed, 197 insertions(+), 19 deletions(-) create mode 100644 include/aare/type_traits.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f768086..8d0d953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -357,6 +357,7 @@ set(PUBLICHEADERS include/aare/CtbRawFile.hpp include/aare/ClusterVector.hpp include/aare/decode.hpp + include/aare/type_traits.hpp include/aare/defs.hpp include/aare/Dtype.hpp include/aare/File.hpp diff --git a/include/aare/Hdf5MasterFile.hpp b/include/aare/Hdf5MasterFile.hpp index f127d92..9f4d038 100644 --- a/include/aare/Hdf5MasterFile.hpp +++ b/include/aare/Hdf5MasterFile.hpp @@ -7,8 +7,10 @@ #include + namespace aare { +using ns = std::chrono::nanoseconds; /** * @brief Implementation used in Hdf5MasterFile to parse the file name */ @@ -44,6 +46,7 @@ class Hdf5FileNameComponents { * .Hdf5 format */ class Hdf5MasterFile { + Hdf5FileNameComponents m_fnc; std::string m_version; DetectorType m_type; @@ -57,16 +60,16 @@ class Hdf5MasterFile { size_t m_frame_padding{}; ScanParameters m_scan_parameters; size_t m_total_frames_expected{}; - // exptime - // period + std::optional m_exptime{}; + std::optional m_period{}; // burst mode // num udp interfaces size_t m_bitdepth{}; // ten giga // thresholdenergy // thresholdall energy - // subexptime - // subperiod + std::optional m_subexptime{}; + std::optional m_subperiod{}; std::optional m_quad; std::optional m_number_of_rows; // ratecorr @@ -115,16 +118,16 @@ class Hdf5MasterFile { size_t frame_padding() const; ScanParameters scan_parameters() const; size_t total_frames_expected() const; - // exptime - // period + std::optional exptime() const; + std::optional period() const; // burst mode // num udp interfaces size_t bitdepth() const; - // ten giga + // ten giga // thresholdenergy // thresholdall energy - // subexptime - // subperiod + std::optional subexptime() const; + std::optional subperiod() const; std::optional quad() const; std::optional number_of_rows() const; // ratecorr diff --git a/include/aare/defs.hpp b/include/aare/defs.hpp index 4427d64..37906a7 100644 --- a/include/aare/defs.hpp +++ b/include/aare/defs.hpp @@ -1,6 +1,7 @@ #pragma once #include "aare/Dtype.hpp" +#include "aare/type_traits.hpp" #include #include @@ -14,6 +15,7 @@ #include #include #include +#include /** * @brief LOCATION macro to get the current location in the code @@ -294,11 +296,86 @@ enum class DetectorType { enum class TimingMode { Auto, Trigger }; enum class FrameDiscardPolicy { NoDiscard, Discard, DiscardPartial }; +std::string RemoveUnit(std::string &str); +/** Convert std::chrono::duration with specified output unit */ +template +typename std::enable_if::value, std::string>::type +ToString(T t, const std::string &unit) { + using std::chrono::duration; + using std::chrono::duration_cast; + std::ostringstream os; + if (unit == "ns") + os << duration_cast>(t).count() << unit; + else if (unit == "us") + os << duration_cast>(t).count() << unit; + else if (unit == "ms") + os << duration_cast>(t).count() << unit; + else if (unit == "s") + os << duration_cast>(t).count() << unit; + else + throw std::runtime_error("Unknown unit: " + unit); + return os.str(); +} -template T StringTo(const std::string &arg) { return T(arg); } +/** Convert std::chrono::duration automatically selecting the unit */ +template +typename std::enable_if::value, std::string>::type +ToString(From t) { -template std::string ToString(T arg) { return T(arg); } + using std::chrono::duration_cast; + using std::chrono::abs; + using std::chrono::nanoseconds; + using std::chrono::microseconds; + using std::chrono::milliseconds; + auto tns = duration_cast(t); + if (abs(tns) +T StringTo(const std::string &t, const std::string &unit) { + double tval{0}; + try { + tval = std::stod(t); + } catch (const std::invalid_argument &e) { + throw std::invalid_argument("[ERROR] Could not convert string to time"); + } + + using std::chrono::duration; + using std::chrono::duration_cast; + if (unit == "ns") { + return duration_cast(duration(tval)); + } else if (unit == "us") { + return duration_cast(duration(tval)); + } else if (unit == "ms") { + return duration_cast(duration(tval)); + } else if (unit == "s" || unit.empty()) { + return duration_cast(std::chrono::duration(tval)); + } else { + throw std::invalid_argument("[ERROR] Invalid unit in conversion from string to std::chrono::duration"); + } +} + +template ::value, int> = 0 > +T StringTo(const std::string &t) { + std::string tmp{t}; + auto unit = RemoveUnit(tmp); + return StringTo(tmp, unit); +} + +template ::value, int> = 0 > +T StringTo(const std::string &arg) { return T(arg); } + +template ::value>> +std::string ToString(T arg) { return T(arg); } template <> DetectorType StringTo(const std::string & /*name*/); template <> std::string ToString(DetectorType arg); @@ -338,4 +415,14 @@ std::ostream &operator<<(std::ostream &os, const std::optional &opt) { } +template +std::string ToString(const std::optional& opt) +{ + return opt ? ToString(*opt) : "nullopt"; +} + + + + + } // namespace aare \ No newline at end of file diff --git a/include/aare/type_traits.hpp b/include/aare/type_traits.hpp new file mode 100644 index 0000000..20a8d8d --- /dev/null +++ b/include/aare/type_traits.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace aare { + +/** + * Type trait to check if a template parameter is a std::chrono::duration + */ + +template +struct is_duration : std::false_type {}; + +template struct is_duration_helper {}; + +template +struct is_duration().min()), + decltype(std::declval().max()), + decltype(std::declval().zero())>, + void>::type> : public std::true_type {}; + +} // namsespace aare \ No newline at end of file diff --git a/src/Hdf5MasterFile.cpp b/src/Hdf5MasterFile.cpp index 79ffd18..d41abfd 100644 --- a/src/Hdf5MasterFile.cpp +++ b/src/Hdf5MasterFile.cpp @@ -106,16 +106,24 @@ ScanParameters Hdf5MasterFile::scan_parameters() const { size_t Hdf5MasterFile::total_frames_expected() const { return m_total_frames_expected; } -// exptime -// period +std::optional Hdf5MasterFile::exptime() const { + return m_exptime; +} +std::optional Hdf5MasterFile::period() const { + return m_period; +} // burst mode // num udp interfaces size_t Hdf5MasterFile::bitdepth() const { return m_bitdepth; } // ten giga // thresholdenergy // thresholdall energy -// subexptime -// subperiod +std::optional Hdf5MasterFile::subexptime() const { + return m_subexptime; +} +std::optional Hdf5MasterFile::subperiod() const { + return m_subperiod; +} std::optional Hdf5MasterFile::quad() const { return m_quad; } std::optional Hdf5MasterFile::number_of_rows() const { return m_number_of_rows; @@ -272,8 +280,28 @@ void Hdf5MasterFile::parse_acquisition_metadata( file, std::string(metadata_group_name + "Total Frames")); LOG(logDEBUG) << "Total Frames: " << m_total_frames_expected; - // exptime - // period + // Exptime + H5::Exception::dontPrint(); + try { + m_exptime = StringTo(h5_get_scalar_dataset( + file, std::string(metadata_group_name + "Exposure Time"))); + } catch (H5::FileIException &e) { + // keep the optional empty + } + LOG(logDEBUG) << "Exptime: " << ToString(m_exptime); + H5Eset_auto(H5E_DEFAULT, reinterpret_cast(H5Eprint2), stderr); + + // Period + H5::Exception::dontPrint(); + try { + m_period = StringTo(h5_get_scalar_dataset( + file, std::string(metadata_group_name + "Acquisition Period"))); + } catch (H5::FileIException &e) { + // keep the optional empty + } + LOG(logDEBUG) << "Period: " << ToString(m_period); + H5Eset_auto(H5E_DEFAULT, reinterpret_cast(H5Eprint2), stderr); + // burst mode // num udp interfaces @@ -293,8 +321,28 @@ void Hdf5MasterFile::parse_acquisition_metadata( // ten giga // thresholdenergy // thresholdall energy - // subexptime - // subperiod + + // Subexptime + H5::Exception::dontPrint(); + try { + m_subexptime = StringTo(h5_get_scalar_dataset( + file, std::string(metadata_group_name + "Sub Exposure Time"))); + } catch (H5::FileIException &e) { + // keep the optional empty + } + LOG(logDEBUG) << "Subexptime: " << ToString(m_subexptime); + H5Eset_auto(H5E_DEFAULT, reinterpret_cast(H5Eprint2), stderr); + + // Subperiod + H5::Exception::dontPrint(); + try { + m_subperiod = StringTo(h5_get_scalar_dataset( + file, std::string(metadata_group_name + "Sub Period"))); + } catch (H5::FileIException &e) { + // keep the optional empty + } + LOG(logDEBUG) << "Subperiod: " << ToString(m_subperiod); + H5Eset_auto(H5E_DEFAULT, reinterpret_cast(H5Eprint2), stderr); // Quad H5::Exception::dontPrint(); diff --git a/src/defs.cpp b/src/defs.cpp index d08ee06..cb44cd3 100644 --- a/src/defs.cpp +++ b/src/defs.cpp @@ -203,6 +203,19 @@ std::ostream &operator<<(std::ostream &os, const ROI &roi) { return os << ToString(roi); } +std::string RemoveUnit(std::string &str) { + auto it = str.begin(); + while (it != str.end()) { + if (std::isalpha(*it)) + break; + ++it; + } + auto pos = it - str.begin(); + auto unit = str.substr(pos); + str.erase(it, end(str)); + return unit; +} + // template <> TimingMode StringTo(std::string mode); } // namespace aare \ No newline at end of file