added exptime, period in hdf5, also added print for chrono and StringTo

This commit is contained in:
2025-06-09 14:41:07 +02:00
parent dc7f6d44f2
commit 755a8fb2b7
6 changed files with 197 additions and 19 deletions

View File

@ -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

View File

@ -7,8 +7,10 @@
#include <optional>
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<ns> m_exptime{};
std::optional<ns> m_period{};
// burst mode
// num udp interfaces
size_t m_bitdepth{};
// ten giga
// thresholdenergy
// thresholdall energy
// subexptime
// subperiod
std::optional<ns> m_subexptime{};
std::optional<ns> m_subperiod{};
std::optional<uint8_t> m_quad;
std::optional<size_t> 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<ns> exptime() const;
std::optional<ns> period() const;
// burst mode
// num udp interfaces
size_t bitdepth() const;
// ten giga
// ten giga
// thresholdenergy
// thresholdall energy
// subexptime
// subperiod
std::optional<ns> subexptime() const;
std::optional<ns> subperiod() const;
std::optional<uint8_t> quad() const;
std::optional<size_t> number_of_rows() const;
// ratecorr

View File

@ -1,6 +1,7 @@
#pragma once
#include "aare/Dtype.hpp"
#include "aare/type_traits.hpp"
#include <array>
#include <stdexcept>
@ -14,6 +15,7 @@
#include <iostream>
#include <sstream>
#include <optional>
#include <chrono>
/**
* @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 T, typename Rep = double>
typename std::enable_if<is_duration<T>::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<duration<Rep, std::nano>>(t).count() << unit;
else if (unit == "us")
os << duration_cast<duration<Rep, std::micro>>(t).count() << unit;
else if (unit == "ms")
os << duration_cast<duration<Rep, std::milli>>(t).count() << unit;
else if (unit == "s")
os << duration_cast<duration<Rep>>(t).count() << unit;
else
throw std::runtime_error("Unknown unit: " + unit);
return os.str();
}
template <class T> T StringTo(const std::string &arg) { return T(arg); }
/** Convert std::chrono::duration automatically selecting the unit */
template <typename From>
typename std::enable_if<is_duration<From>::value, std::string>::type
ToString(From t) {
template <class T> 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<nanoseconds>(t);
if (abs(tns) <microseconds(1)) {
return ToString(tns, "ns");
} else if (abs(tns) < milliseconds(1)) {
return ToString(tns, "us");
} else if (abs(tns) < milliseconds(99)) {
return ToString(tns, "ms");
} else {
return ToString(tns, "s");
}
}
template <typename T>
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<T>(duration<double, std::nano>(tval));
} else if (unit == "us") {
return duration_cast<T>(duration<double, std::micro>(tval));
} else if (unit == "ms") {
return duration_cast<T>(duration<double, std::milli>(tval));
} else if (unit == "s" || unit.empty()) {
return duration_cast<T>(std::chrono::duration<double>(tval));
} else {
throw std::invalid_argument("[ERROR] Invalid unit in conversion from string to std::chrono::duration");
}
}
template <typename T, std::enable_if_t<is_duration<T>::value, int> = 0 >
T StringTo(const std::string &t) {
std::string tmp{t};
auto unit = RemoveUnit(tmp);
return StringTo<T>(tmp, unit);
}
template <typename T, std::enable_if_t<!is_duration<T>::value, int> = 0 >
T StringTo(const std::string &arg) { return T(arg); }
template <class T, typename = std::enable_if_t<!is_duration<T>::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<T> &opt) {
}
template <class T>
std::string ToString(const std::optional<T>& opt)
{
return opt ? ToString(*opt) : "nullopt";
}
} // namespace aare

View File

@ -0,0 +1,26 @@
#pragma once
#include <type_traits>
namespace aare {
/**
* Type trait to check if a template parameter is a std::chrono::duration
*/
template <typename T, typename _ = void>
struct is_duration : std::false_type {};
template <typename... Ts> struct is_duration_helper {};
template <typename T>
struct is_duration<T,
typename std::conditional<
false,
is_duration_helper<typename T::rep, typename T::period,
decltype(std::declval<T>().min()),
decltype(std::declval<T>().max()),
decltype(std::declval<T>().zero())>,
void>::type> : public std::true_type {};
} // namsespace aare

View File

@ -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<ns> Hdf5MasterFile::exptime() const {
return m_exptime;
}
std::optional<ns> 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<ns> Hdf5MasterFile::subexptime() const {
return m_subexptime;
}
std::optional<ns> Hdf5MasterFile::subperiod() const {
return m_subperiod;
}
std::optional<uint8_t> Hdf5MasterFile::quad() const { return m_quad; }
std::optional<size_t> 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<ns>(h5_get_scalar_dataset<std::string>(
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<H5E_auto2_t>(H5Eprint2), stderr);
// Period
H5::Exception::dontPrint();
try {
m_period = StringTo<ns>(h5_get_scalar_dataset<std::string>(
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<H5E_auto2_t>(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<ns>(h5_get_scalar_dataset<std::string>(
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<H5E_auto2_t>(H5Eprint2), stderr);
// Subperiod
H5::Exception::dontPrint();
try {
m_subperiod = StringTo<ns>(h5_get_scalar_dataset<std::string>(
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<H5E_auto2_t>(H5Eprint2), stderr);
// Quad
H5::Exception::dontPrint();

View File

@ -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<TimingMode>(std::string mode);
} // namespace aare