DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
HDF5RawDataFile.hpp
Go to the documentation of this file.
1
11#ifndef HDF5LIBS_INCLUDE_HDF5LIBS_HDF5RAWDATAFILE_HPP_
12#define HDF5LIBS_INCLUDE_HDF5LIBS_HDF5RAWDATAFILE_HPP_
13
14// DUNE-DAQ
17
21#include "logging/Logging.hpp" // NOTE: if ISSUES ARE DECLARED BEFORE include logging/Logging.hpp, TLOG_DEBUG<<issue wont work.
22
23// External Packages
24#include <highfive/H5DataSet.hpp>
25#include <highfive/H5File.hpp>
26#include <highfive/H5Group.hpp>
27#include <highfive/H5Object.hpp>
28#include <nlohmann/json.hpp>
29
30// System
31#include <filesystem>
32#include <functional>
33#include <iostream>
34#include <map>
35#include <memory>
36#include <set>
37#include <string>
38#include <sys/statvfs.h>
39#include <utility>
40#include <variant>
41#include <vector>
42#include <optional>
43
44namespace dunedaq {
45
47 DeprecatedUsage,
48 func_name << " is deprecated. " << message,
49 ((std::string)func_name)((std::string)message))
50
53 "Issue when opening file " << file << ": " << message,
54 ((std::string)file)((std::string)message))
55
57 IncompatibleOpenFlags,
58 "Issue when opening file " << file << ": "
59 << "bad open flags " << open_flags,
60 ((std::string)file)((unsigned)open_flags))
61
63 MissingFileLayout,
64 "No DUNEDAQ FileLayout information available."
65 << " Assigning version " << version,
66 ((uint32_t)version)) // NOLINT(build/unsigned)
67
69 IncompatibleFileLayoutVersion,
70 "FileLayout version incompatibility. Found version " << version << " but min allowed version is "
71 << min_allowed << " and max allowed version is "
72 << max_allowed,
73 ((uint32_t)version)((uint32_t)min_allowed)((uint32_t)max_allowed)) // NOLINT(build/unsigned)
74
76 BadRecordType,
77 "Record type attribute " << rt_attr << " does not match file layout config record name prefix "
78 << rt_fl,
79 ((std::string)rt_attr)((std::string)rt_fl))
80
82 WrongRecordTypeRequested,
83 "Record type requested " << rname << " does not match file layout config record name prefix "
84 << rt_fl,
85 ((std::string)rname)((std::string)rt_fl))
86
88 RecordIDNotFound,
89 "Record ID with record number=" << rec_num << " and sequence number=" << seq_num << " not found.",
90 ((uint64_t)rec_num)((uint16_t)seq_num)) // NOLINT(build/unsigned)
91
92ERS_DECLARE_ISSUE(hdf5libs, InvalidHDF5Group, "Group " << name << " is invalid.", ((std::string)name))
93
95 InvalidHDF5Dataset,
96 "The HDF5 Dataset associated with name \"" << data_set << "\" is invalid. (file = " << filename
97 << ")",
98 ((std::string)data_set)((std::string)filename))
99
100ERS_DECLARE_ISSUE(hdf5libs, InvalidHDF5Attribute, "Attribute " << name << " not found.", ((std::string)name))
101
102ERS_DECLARE_ISSUE(hdf5libs, HDF5AttributeExists, "Attribute " << name << " already exists.", ((std::string)name))
103
104ERS_DECLARE_ISSUE(hdf5libs, TimeSliceAlreadyExists, "The TimeSlice record for " << name << " already exists.", ((std::string)name))
105
106ERS_DECLARE_ISSUE(hdf5libs, InvalidFragmentTypeString,
107 "Fragment type name \"" << name << "\" does not map to a valid type.", ((std::string)name))
108
109ERS_DECLARE_ISSUE(hdf5libs, InvalidSubdetectorString,
110 "Subdetector name \"" << name << "\" does not map to a valid detector ID.", ((std::string)name))
111
112namespace hdf5libs {
113
118class HDF5RawDataFile
119{
120
121public:
122 enum
123 {
124 TLVL_BASIC = 2,
125 TLVL_FILE_SIZE = 5
126 };
127
128 // define a record number type
129 // that is a pair of the trigger record or timeslice number and sequence number
130 typedef std::pair<uint64_t, daqdataformats::sequence_number_t> record_id_t; // NOLINT(build/unsigned)
131 typedef std::set<record_id_t, std::less<>> record_id_set;
132
133 inline static const std::string s_inprogress_suffix = ".writing";
134
135 // constructor for writing
136 HDF5RawDataFile(std::string file_name,
138 size_t file_index,
139 std::string application_name,
140 HDF5FileLayoutParameters fl_params,
141 HDF5SourceIDHandler::source_id_geo_id_map_t srcid_geoid_map,
142 unsigned compression_level = 0,
143 std::string inprogress_filename_suffix = s_inprogress_suffix,
144 unsigned open_flags = HighFive::File::Create);
145
146 // constructor for reading and optional writing
147 explicit HDF5RawDataFile(const std::string& file_name, bool allow_writing = false);
148
149 ~HDF5RawDataFile();
150
151 std::string get_file_name() const { return m_file_ptr->getName(); }
152
153 size_t get_recorded_size() const noexcept { return m_recorded_size; }
154 size_t get_uncompressed_raw_data_size() const noexcept { return m_uncompressed_raw_data_size; }
155 size_t get_total_file_size() const noexcept { return m_total_file_size; }
156 unsigned get_compression_level() const noexcept { return m_compression_level; }
157
158 std::string get_record_type() const noexcept { return m_record_type; }
159
160 bool is_trigger_record_type() const noexcept { return m_record_type.compare("TriggerRecord") == 0; }
161 bool is_timeslice_type() const noexcept { return m_record_type.compare("TimeSlice") == 0; }
162
163 const HDF5FileLayout& get_file_layout() const { return *(m_file_layout_ptr.get()); }
164
165 uint32_t get_version() const // NOLINT(build/unsigned)
166 {
167 return m_file_layout_ptr->get_version();
168 }
169
170 // basic data writing methods
171public:
172 void write(const daqdataformats::TriggerRecord& tr);
173 void write(const daqdataformats::TimeSlice& ts);
174
175private:
176 HighFive::Group write(const daqdataformats::TriggerRecordHeader& trh,
177 HDF5SourceIDHandler::source_id_path_map_t& path_map);
178 HighFive::Group write(const daqdataformats::TimeSliceHeader& tsh,
179 HDF5SourceIDHandler::source_id_path_map_t& path_map);
180 void write(const daqdataformats::Fragment& frag, HDF5SourceIDHandler::source_id_path_map_t& path_map);
181
182public:
183 // attribute writers/getters
184 template<typename T>
185 void write_attribute(std::string name, T value);
186 template<typename T>
187 void write_attribute(HighFive::Group& grp, const std::string& name, T value);
188 template<typename T>
189 void write_attribute(HighFive::DataSet& dset, const std::string& name, T value);
190
191 std::vector<std::string> get_attribute_names();
192 template<typename T>
193 T get_attribute(const std::string& name);
194 template<typename T>
195 T get_attribute(const HighFive::Group& grp, const std::string& name);
196 template<typename T>
197 T get_attribute(const HighFive::DataSet& dset, std::string name);
198 // For backwards compatibility with files created before compression_level existed
199 template<typename T>
200 T get_attribute_if_exists(const std::string& name, const T& default_value);
201
202 std::vector<std::string> get_dataset_paths(std::string top_level_group_name = "");
203
204 record_id_set get_all_record_ids();
205 record_id_set get_all_trigger_record_ids();
206 record_id_set get_all_timeslice_ids();
207
208 std::set<uint64_t> get_all_record_numbers(); // NOLINT(build/unsigned)
209 std::set<daqdataformats::trigger_number_t> get_all_trigger_record_numbers();
210 std::set<daqdataformats::timeslice_number_t> get_all_timeslice_numbers();
211
212 std::vector<std::string> get_record_header_dataset_paths();
213 std::vector<std::string> get_trigger_record_header_dataset_paths();
214 std::vector<std::string> get_timeslice_header_dataset_paths();
215
216 std::string get_record_header_dataset_path(const record_id_t& rid);
217 std::string get_record_header_dataset_path(const uint64_t rec_num, // NOLINT (build/unsigned)
218 const daqdataformats::sequence_number_t seq_num = 0);
219 std::string get_trigger_record_header_dataset_path(const record_id_t& rid);
220 std::string get_trigger_record_header_dataset_path(const daqdataformats::trigger_number_t trig_num,
221 const daqdataformats::sequence_number_t seq_num = 0);
222 std::string get_timeslice_header_dataset_path(const record_id_t& rid);
223 std::string get_timeslice_header_dataset_path(const daqdataformats::timeslice_number_t trig_num);
224
225 // get all fragment dataset paths
226 std::vector<std::string> get_all_fragment_dataset_paths();
227
228 // get all fragment dataset paths for given record ID
229 std::vector<std::string> get_fragment_dataset_paths(const record_id_t& rid);
230 std::vector<std::string> get_fragment_dataset_paths(const uint64_t rec_num, // NOLINT (build/unsigned)
231 const daqdataformats::sequence_number_t seq_num = 0);
232
233 // get all fragment dataset paths for a Subsystem
234 std::vector<std::string> get_fragment_dataset_paths(const daqdataformats::SourceID::Subsystem subsystem);
235 std::vector<std::string> get_fragment_dataset_paths(const std::string& subsystem_name);
236
237 // get all fragment dataset paths for a record ID and Subsystem
238 std::vector<std::string> get_fragment_dataset_paths(const record_id_t& rid,
240 std::vector<std::string> get_fragment_dataset_paths(const record_id_t& rid, const std::string& subsystem_name);
241
242#if 0
243 // get all fragment dataset paths for a SourceID
244 std::vector<std::string> get_fragment_dataset_paths(const daqdataformats::SourceID& source_id);
245 std::vector<std::string> get_fragment_dataset_paths(const daqdataformats::SourceID::Subsystem type,
246 const uint32_t id); // NOLINT(build/unsigned)
247 std::vector<std::string> get_fragment_dataset_paths(const std::string& typestring,
248 const uint32_t id); // NOLINT(build/unsigned)
249
250 // get a list of all the source ids from a list of fragment dataset paths
251 std::set<daqdataformats::SourceID> get_source_ids(std::vector<std::string> const& frag_dataset_paths);
252#endif
253
254 HDF5SourceIDHandler::source_id_geo_id_map_t get_srcid_geoid_map() const;
255
256 //get a list of all the geo ids anywhere in the file
257 std::set<uint64_t> get_all_geo_ids() const; // NOLINT(build/unsigned)
258
259 //get GeoIDs in a record
260 std::set<uint64_t> get_geo_ids(const record_id_t& rid); // NOLINT(build/unsigned)
261 std::set<uint64_t> get_geo_ids(const uint64_t rec_num, //NOLINT(build/unsigned)
262 const daqdataformats::sequence_number_t seq_num = 0)
263 {
264 return get_geo_ids(std::make_pair(rec_num, seq_num));
265 }
266 std::set<uint64_t> get_geo_ids_for_subdetector(const record_id_t& rid, // NOLINT(build/unsigned)
268 std::set<uint64_t> get_geo_ids_for_subdetector(const uint64_t rec_num, //NOLINT(build/unsigned)
271 {
272 return get_geo_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet);
273 }
274 std::set<uint64_t> get_geo_ids_for_subdetector(const record_id_t& rid, // NOLINT(build/unsigned)
275 const std::string& subdet_name)
276 {
277 detdataformats::DetID::Subdetector subdet = detdataformats::DetID::string_to_subdetector(subdet_name);
278 return get_geo_ids_for_subdetector(rid, subdet);
279 }
280 std::set<uint64_t> get_geo_ids_for_subdetector(const uint64_t rec_num, //NOLINT(build/unsigned)
282 const std::string& subdet_name)
283 {
284 return get_geo_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet_name);
285 }
286
287 // get SourceIDs in a record
288 std::set<daqdataformats::SourceID> get_source_ids(const record_id_t& rid);
289 std::set<daqdataformats::SourceID> get_source_ids(const uint64_t rec_num, // NOLINT(build/unsigned)
290 const daqdataformats::sequence_number_t seq_num = 0)
291 {
292 return get_source_ids(std::make_pair(rec_num, seq_num));
293 }
294
295 daqdataformats::SourceID get_record_header_source_id(const record_id_t& rid);
296 daqdataformats::SourceID get_record_header_source_id(const uint64_t rec_num, // NOLINT(build/unsigned)
297 const daqdataformats::sequence_number_t seq_num = 0)
298 {
299 return get_record_header_source_id(std::make_pair(rec_num, seq_num));
300 }
301
302 std::set<daqdataformats::SourceID> get_fragment_source_ids(const record_id_t& rid);
303 std::set<daqdataformats::SourceID> get_fragment_source_ids(const uint64_t rec_num, // NOLINT(build/unsigned)
304 const daqdataformats::sequence_number_t seq_num = 0)
305 {
306 return get_fragment_source_ids(std::make_pair(rec_num, seq_num));
307 }
308
309 // get SourceIDs for given subsystem in a record
310 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(const record_id_t& rid,
312 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(const record_id_t& rid,
313 const std::string& subsystem_name)
314 {
315 daqdataformats::SourceID::Subsystem subsys = daqdataformats::SourceID::string_to_subsystem(subsystem_name);
316 return get_source_ids_for_subsystem(rid, subsys);
317 }
318 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(const uint64_t rec_num, // NOLINT(build/unsigned)
321 {
322 return get_source_ids_for_subsystem(std::make_pair(rec_num, seq_num), subsystem);
323 }
324 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(const uint64_t rec_num, // NOLINT(build/unsigned)
326 const std::string& subsystem_name)
327 {
328 return get_source_ids_for_subsystem(std::make_pair(rec_num, seq_num), subsystem_name);
329 }
330
331 // get SourceIDs for given fragment type in a record
332 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(const record_id_t& rid,
333 const daqdataformats::FragmentType frag_type);
334 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(const record_id_t& rid,
335 const std::string& frag_type_name)
336 {
337 daqdataformats::FragmentType frag_type = daqdataformats::string_to_fragment_type(frag_type_name);
338 if (frag_type == daqdataformats::FragmentType::kUnknown)
339 throw InvalidFragmentTypeString(ERS_HERE, frag_type_name);
340 return get_source_ids_for_fragment_type(rid, frag_type);
341 }
342 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(const uint64_t rec_num, // NOLINT(build/unsigned)
344 const daqdataformats::FragmentType frag_type)
345 {
346 return get_source_ids_for_fragment_type(std::make_pair(rec_num, seq_num), frag_type);
347 }
348 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(const uint64_t rec_num, // NOLINT(build/unsigned)
350 const std::string& frag_type_name)
351 {
352 return get_source_ids_for_fragment_type(std::make_pair(rec_num, seq_num), frag_type_name);
353 }
354
355 // get SourceIDs for given fragment type and subdetector in a record
356 std::set<daqdataformats::SourceID> get_source_ids_for_fragtype_and_subdetector(const record_id_t& rid,
357 const std::string& frag_type_name,
358 const std::string& subdet_name);
359
360 // get SourceIDs for given subdetector in a record
361 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(const record_id_t& rid,
363 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(const record_id_t& rid,
364 const std::string& subdet_name)
365 {
366 detdataformats::DetID::Subdetector subdet = detdataformats::DetID::string_to_subdetector(subdet_name);
367 return get_source_ids_for_subdetector(rid, subdet);
368 }
369 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(const uint64_t rec_num, // NOLINT(build/unsigned)
372 {
373 return get_source_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet);
374 }
375 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(const uint64_t rec_num, // NOLINT(build/unsigned)
377 const std::string& subdet_name)
378 {
379 return get_source_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet_name);
380 }
381
382#if 0
383 // get SourceIDs for a system type
384 std::set<daqdataformats::SourceID> get_source_ids(const daqdataformats::SourceID::Subsystem type)
385 {
386 return get_source_ids(get_fragment_dataset_paths(type));
387 }
388 std::set<daqdataformats::SourceID> get_source_ids(const std::string& typestring)
389 {
390 return get_source_ids(get_fragment_dataset_paths(typestring));
391 }
392#endif
393
394 std::unique_ptr<char[]> get_dataset_raw_data(const std::string& dataset_path);
395
396 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const std::string& dataset_name);
397 std::unique_ptr<daqdataformats::TriggerRecordHeader> get_trh_ptr(const std::string& dataset_name);
398 std::unique_ptr<daqdataformats::TimeSliceHeader> get_tsh_ptr(const std::string& dataset_name);
399
400 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const record_id_t& rid,
401 const daqdataformats::SourceID& source_id);
402 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
404 const daqdataformats::SourceID& source_id);
405 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const record_id_t& rid,
407 const uint32_t id); // NOLINT(build/unsigned)
408 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
411 const uint32_t id); // NOLINT(build/unsigned)
412 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const record_id_t& rid,
413 const std::string& typestring,
414 const uint32_t id); // NOLINT(build/unsigned)
415 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
417 const std::string& typestring,
418 const uint32_t id); // NOLINT(build/unsigned)
419
420 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const record_id_t& rid,
421 const uint64_t geo_id); // NOLINT(build/unsigned)
422 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
424 const uint64_t geo_id); // NOLINT(build/unsigned)
425
426 std::unique_ptr<daqdataformats::TriggerRecordHeader> get_trh_ptr(const record_id_t& rid);
427 std::unique_ptr<daqdataformats::TriggerRecordHeader> get_trh_ptr(const daqdataformats::trigger_number_t trig_num,
428 const daqdataformats::sequence_number_t seq_num = 0)
429 {
430 return get_trh_ptr(std::make_pair(trig_num, seq_num));
431 }
432
433 std::unique_ptr<daqdataformats::TimeSliceHeader> get_tsh_ptr(const record_id_t& rid);
434 std::unique_ptr<daqdataformats::TimeSliceHeader> get_tsh_ptr(const daqdataformats::timeslice_number_t ts_num)
435 {
436 return get_tsh_ptr(std::make_pair(ts_num, 0));
437 }
438
439 daqdataformats::TriggerRecord get_trigger_record(const record_id_t& rid);
440 daqdataformats::TriggerRecord get_trigger_record(const daqdataformats::trigger_number_t trig_num,
441 const daqdataformats::sequence_number_t seq_num = 0)
442 {
443 return get_trigger_record(std::make_pair(trig_num, seq_num));
444 }
445
447 daqdataformats::TimeSlice get_timeslice(const record_id_t& rid) { return get_timeslice(rid.first); }
448
449 std::vector<uint64_t> get_geo_ids_for_source_id(const record_id_t& rid, // NOLINT(build/unsigned)
450 const daqdataformats::SourceID& source_id);
451
452 daqdataformats::SourceID get_source_id_for_geo_id(const record_id_t& rid,
453 const uint64_t geo_id); // NOLINT(build/unsigned)
454
455private:
456 HDF5RawDataFile(const HDF5RawDataFile&) = delete;
457 HDF5RawDataFile& operator=(const HDF5RawDataFile&) = delete;
458 HDF5RawDataFile(HDF5RawDataFile&&) = delete;
459 HDF5RawDataFile& operator=(HDF5RawDataFile&&) = delete;
460
461 std::unique_ptr<HighFive::File> m_file_ptr;
462 std::unique_ptr<HDF5FileLayout> m_file_layout_ptr;
463 std::string m_bare_file_name;
464 unsigned m_compression_level;
465 unsigned m_open_flags;
466
467 // Total size of data being written
468 size_t m_recorded_size;
469 size_t m_uncompressed_raw_data_size;
470 size_t m_total_file_size;
471 std::string m_record_type;
472
473 // file layout writing/reading
474 void write_file_layout();
475 void read_file_layout();
476 void check_file_layout();
477
478 // checking function
479 void check_record_type(std::string);
480
481 // writing to datasets
482 std::tuple<size_t, std::string, HighFive::Group> do_write(std::vector<std::string> const&, const char*, size_t, unsigned compression_level);
483
484 // unpacking groups when reading
485 void explore_subgroup(const HighFive::Group& parent_group,
486 std::string relative_path,
487 std::vector<std::string>& path_list);
488
489 // adds record-level information to caches, if needed
490 void add_record_level_info_to_caches_if_needed(record_id_t rid);
491
492 // caches of full-file and record-specific information
493 record_id_set m_all_record_ids_in_file;
494 HDF5SourceIDHandler::source_id_geo_id_map_t m_file_level_source_id_geo_id_map;
495 std::map<record_id_t, std::set<daqdataformats::SourceID>> m_source_id_cache;
496 std::map<record_id_t, daqdataformats::SourceID> m_record_header_source_id_cache;
497 std::map<record_id_t, std::set<daqdataformats::SourceID>> m_fragment_source_id_cache;
498 std::map<record_id_t, HDF5SourceIDHandler::source_id_path_map_t> m_source_id_path_cache;
499 std::map<record_id_t, HDF5SourceIDHandler::source_id_geo_id_map_t> m_source_id_geo_id_cache;
500 std::map<record_id_t, HDF5SourceIDHandler::subsystem_source_id_map_t> m_subsystem_source_id_cache;
501 std::map<record_id_t, HDF5SourceIDHandler::fragment_type_source_id_map_t> m_fragment_type_source_id_cache;
502 std::map<record_id_t, HDF5SourceIDHandler::subdetector_source_id_map_t> m_subdetector_source_id_cache;
503};
504
505// HDF5RawDataFile attribute writers/getters definitions
506template<typename T>
507void
508HDF5RawDataFile::write_attribute(std::string name, T value)
509{
510 if (!m_file_ptr->hasAttribute(name))
511 m_file_ptr->createAttribute(name, value);
512 else
513 ers::warning(HDF5AttributeExists(ERS_HERE, name));
514}
515
516template<typename T>
517void
518HDF5RawDataFile::write_attribute(HighFive::Group& grp, const std::string& name, T value)
519{
520 if (!(grp.hasAttribute(name)))
521 grp.createAttribute<T>(name, value);
522 else
523 ers::warning(HDF5AttributeExists(ERS_HERE, name));
524}
525
526template<typename T>
527void
528HDF5RawDataFile::write_attribute(HighFive::DataSet& dset, const std::string& name, T value)
529{
530 if (!dset.hasAttribute(name))
531 dset.createAttribute<T>(name, value);
532 else
533 ers::warning(HDF5AttributeExists(ERS_HERE, name));
534}
535
536template<typename T>
537T
538HDF5RawDataFile::get_attribute(const std::string& name)
539{
540 if (!m_file_ptr->hasAttribute(name)) {
541 throw InvalidHDF5Attribute(ERS_HERE, name);
542 }
543 auto attr = m_file_ptr->getAttribute(name);
544 T value;
545 attr.read(value);
546 return value;
547}
548
549template<typename T>
550T
551HDF5RawDataFile::get_attribute_if_exists(const std::string& name, const T& default_value)
552{
553 if (!m_file_ptr->hasAttribute(name)) {
554 TLOG_DEBUG(7) << "Debug: Attribute \"" << name << "\" not found. Defaulting to " << default_value;
555 return default_value;
556 }
557 auto attr = m_file_ptr->getAttribute(name);
558 T value;
559 attr.read(value);
560 TLOG_DEBUG(7) << "Debug: Attribute \"" << name << "\" found. Value: " << value;
561 return value;
562}
563
564template<typename T>
565T
566HDF5RawDataFile::get_attribute(const HighFive::Group& grp, const std::string& name)
567{
568 if (!(grp.hasAttribute(name))) {
569 throw InvalidHDF5Attribute(ERS_HERE, name);
570 }
571 auto attr = grp.getAttribute(name);
572 T value;
573 attr.read(value);
574 return value;
575}
576
577template<typename T>
578T
579HDF5RawDataFile::get_attribute(const HighFive::DataSet& dset, std::string name)
580{
581 if (!dset.hasAttribute(name)) {
582 throw InvalidHDF5Attribute(ERS_HERE, name);
583 }
584 auto attr = dset.getAttribute(name);
585 T value;
586 attr.read(value);
587 return value;
588}
589
590} // namespace hdf5libs
591
592} // namespace dunedaq
593
594#endif // HDF5LIBS_INCLUDE_HDF5LIBS_HDF5RAWDATAFILE_HPP_
595
596// Local Variables:
597// c-basic-offset: 2
598// End:
#define ERS_DECLARE_ISSUE(namespace_name, class_name, message, attributes)
#define ERS_HERE
C++ Representation of a DUNE Fragment, wrapping the flat byte array that is the Fragment's "actual" f...
Definition Fragment.hpp:38
C++ Representation of a DUNE TimeSlice, consisting of a TimeSliceHeader object and a vector of pointe...
Definition TimeSlice.hpp:27
C++ representation of a TriggerRecordHeader, which wraps a flat array that is the TriggerRecordHeader...
C++ Representation of a DUNE TriggerRecord, consisting of a TriggerRecordHeader object and a vector o...
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
uint32_t run_number_t
Type used to represent run number.
Definition Types.hpp:20
FragmentType
This enumeration should list all defined Fragment types.
uint64_t trigger_number_t
Type used to represent trigger number.
Definition Types.hpp:24
uint16_t sequence_number_t
Type used to represent sequence within a trigger record.
Definition Types.hpp:45
uint64_t timeslice_number_t
Type used to represent timeslice number.
Definition Types.hpp:49
Including Qt Headers.
PDS Frame with unphysical timestamp detected with ts
void warning(const Issue &issue)
Definition ers.hpp:115
SourceID is a generalized representation of the source of a piece of data in the DAQ....
Definition SourceID.hpp:32
Subsystem
The Subsystem enum describes the kind of source we're dealing with.
Definition SourceID.hpp:43
Additional data fields associated with a TimeSliceHeader.
Subdetector
The Subdetector enum describes the kind of source we're dealing with.
Definition DetID.hpp:40