11#ifndef HDF5LIBS_INCLUDE_HDF5LIBS_HDF5RAWDATAFILE_HPP_
12#define HDF5LIBS_INCLUDE_HDF5LIBS_HDF5RAWDATAFILE_HPP_
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>
39#include <sys/statvfs.h>
48 func_name <<
" is deprecated. " << message,
49 ((std::string)func_name)((std::string)message))
53 "Issue when opening file " << file <<
": " << message,
54 ((std::string)file)((std::string)message))
57 IncompatibleOpenFlags,
58 "Issue when opening file " << file <<
": "
59 <<
"bad open flags " << open_flags,
60 ((std::string)file)((
unsigned)open_flags))
64 "No DUNEDAQ FileLayout information available." <<
" Assigning version " <<
version,
68 IncompatibleFileLayoutVersion,
69 "FileLayout version incompatibility. Found version " <<
version <<
" but min allowed version is "
70 << min_allowed <<
" and max allowed version is "
72 ((uint32_t)
version)((uint32_t)min_allowed)((uint32_t)max_allowed))
76 "Record type attribute " << rt_attr <<
" does not match file layout config record name prefix "
78 ((std::string)rt_attr)((std::string)rt_fl))
81 WrongRecordTypeRequested,
82 "Record type requested " << rname <<
" does not match file layout config record name prefix "
84 ((std::string)rname)((std::string)rt_fl))
88 "Record ID with record number=" << rec_num <<
" and sequence number=" << seq_num <<
" not found.",
89 ((uint64_t)rec_num)((uint16_t)seq_num))
95 "The HDF5 Dataset associated with name \"" << data_set <<
"\" is invalid. (file = " << filename
97 ((std::string)data_set)((std::string)filename))
104 InvalidFragmentTypeString,
105 "Fragment type name \"" << name <<
"\" does not map to a valid type.",
109 InvalidSubdetectorString,
110 "Subdetector name \"" << name <<
"\" does not map to a valid detector ID.",
131 typedef std::pair<uint64_t, daqdataformats::sequence_number_t> record_id_t;
132 typedef std::set<record_id_t, std::less<>> record_id_set;
134 inline static const std::string s_inprogress_suffix =
".writing";
137 HDF5RawDataFile(std::string file_name,
140 std::string application_name,
141 HDF5FileLayoutParameters fl_params,
142 HDF5SourceIDHandler::source_id_geo_id_map_t srcid_geoid_map,
143 unsigned compression_level = 0,
144 std::string inprogress_filename_suffix = s_inprogress_suffix,
145 unsigned open_flags = HighFive::File::Create);
148 explicit HDF5RawDataFile(
const std::string& file_name,
bool allow_writing =
false);
152 std::string get_file_name()
const {
return m_file_ptr->getName(); }
153 std::string get_file_name_extension()
const {
return "hdf5"; }
155 size_t get_recorded_size()
const noexcept {
return m_recorded_size; }
156 size_t get_uncompressed_raw_data_size()
const noexcept {
return m_uncompressed_raw_data_size; }
157 size_t get_total_file_size()
const noexcept {
return m_total_file_size; }
158 unsigned get_compression_level()
const noexcept {
return m_compression_level; }
160 std::string get_record_type()
const noexcept {
return m_record_type; }
162 bool is_trigger_record_type()
const noexcept {
return m_record_type.compare(
"TriggerRecord") == 0; }
163 bool is_timeslice_type()
const noexcept {
return m_record_type.compare(
"TimeSlice") == 0; }
165 const HDF5FileLayout& get_file_layout()
const {
return *(m_file_layout_ptr.get()); }
167 uint32_t get_version()
const
169 return m_file_layout_ptr->get_version();
179 HDF5SourceIDHandler::source_id_path_map_t& path_map);
181 HDF5SourceIDHandler::source_id_path_map_t& path_map);
187 void write_attribute(std::string name, T value);
189 void write_attribute(HighFive::Group& grp,
const std::string& name, T value);
191 void write_attribute(HighFive::DataSet& dset,
const std::string& name, T value);
193 std::vector<std::string> get_attribute_names();
195 T get_attribute(
const std::string& name);
197 T get_attribute(
const HighFive::Group& grp,
const std::string& name);
199 T get_attribute(
const HighFive::DataSet& dset, std::string name);
202 T get_attribute_if_exists(
const std::string& name,
const T& default_value);
204 std::vector<std::string> get_dataset_paths(std::string top_level_group_name =
"");
206 record_id_set get_all_record_ids();
207 record_id_set get_all_trigger_record_ids();
208 record_id_set get_all_timeslice_ids();
210 std::set<uint64_t> get_all_record_numbers();
211 std::set<daqdataformats::trigger_number_t> get_all_trigger_record_numbers();
212 std::set<daqdataformats::timeslice_number_t> get_all_timeslice_numbers();
214 std::vector<std::string> get_record_header_dataset_paths();
215 std::vector<std::string> get_trigger_record_header_dataset_paths();
216 std::vector<std::string> get_timeslice_header_dataset_paths();
218 std::string get_record_header_dataset_path(
const record_id_t& rid);
219 std::string get_record_header_dataset_path(
const uint64_t rec_num,
221 std::string get_trigger_record_header_dataset_path(
const record_id_t& rid);
224 std::string get_timeslice_header_dataset_path(
const record_id_t& rid);
228 std::vector<std::string> get_all_fragment_dataset_paths();
231 std::vector<std::string> get_fragment_dataset_paths(
const record_id_t& rid);
232 std::vector<std::string> get_fragment_dataset_paths(
const uint64_t rec_num,
237 std::vector<std::string> get_fragment_dataset_paths(
const std::string& subsystem_name);
240 std::vector<std::string> get_fragment_dataset_paths(
const record_id_t& rid,
242 std::vector<std::string> get_fragment_dataset_paths(
const record_id_t& rid,
const std::string& subsystem_name);
249 std::vector<std::string> get_fragment_dataset_paths(
const std::string& typestring,
253 std::set<daqdataformats::SourceID> get_source_ids(std::vector<std::string>
const& frag_dataset_paths);
256 HDF5SourceIDHandler::source_id_geo_id_map_t get_srcid_geoid_map()
const;
259 std::set<uint64_t> get_all_geo_ids()
const;
262 std::set<uint64_t> get_geo_ids(
const record_id_t& rid);
263 std::set<uint64_t> get_geo_ids(
const uint64_t rec_num,
266 return get_geo_ids(std::make_pair(rec_num, seq_num));
268 std::set<uint64_t> get_geo_ids_for_subdetector(
const record_id_t& rid,
270 std::set<uint64_t> get_geo_ids_for_subdetector(
const uint64_t rec_num,
274 return get_geo_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet);
276 std::set<uint64_t> get_geo_ids_for_subdetector(
const record_id_t& rid,
277 const std::string& subdet_name)
280 return get_geo_ids_for_subdetector(rid, subdet);
282 std::set<uint64_t> get_geo_ids_for_subdetector(
const uint64_t rec_num,
284 const std::string& subdet_name)
286 return get_geo_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet_name);
290 std::set<daqdataformats::SourceID> get_source_ids(
const record_id_t& rid);
291 std::set<daqdataformats::SourceID> get_source_ids(
const uint64_t rec_num,
294 return get_source_ids(std::make_pair(rec_num, seq_num));
301 return get_record_header_source_id(std::make_pair(rec_num, seq_num));
304 std::set<daqdataformats::SourceID> get_fragment_source_ids(
const record_id_t& rid);
305 std::set<daqdataformats::SourceID> get_fragment_source_ids(
const uint64_t rec_num,
308 return get_fragment_source_ids(std::make_pair(rec_num, seq_num));
312 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(
const record_id_t& rid,
314 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(
const record_id_t& rid,
315 const std::string& subsystem_name)
318 return get_source_ids_for_subsystem(rid, subsys);
320 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(
const uint64_t rec_num,
324 return get_source_ids_for_subsystem(std::make_pair(rec_num, seq_num), subsystem);
326 std::set<daqdataformats::SourceID> get_source_ids_for_subsystem(
const uint64_t rec_num,
328 const std::string& subsystem_name)
330 return get_source_ids_for_subsystem(std::make_pair(rec_num, seq_num), subsystem_name);
334 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(
const record_id_t& rid,
336 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(
const record_id_t& rid,
337 const std::string& frag_type_name)
341 throw InvalidFragmentTypeString(
ERS_HERE, frag_type_name);
342 return get_source_ids_for_fragment_type(rid, frag_type);
344 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(
const uint64_t rec_num,
348 return get_source_ids_for_fragment_type(std::make_pair(rec_num, seq_num), frag_type);
350 std::set<daqdataformats::SourceID> get_source_ids_for_fragment_type(
const uint64_t rec_num,
352 const std::string& frag_type_name)
354 return get_source_ids_for_fragment_type(std::make_pair(rec_num, seq_num), frag_type_name);
358 std::set<daqdataformats::SourceID> get_source_ids_for_fragtype_and_subdetector(
const record_id_t& rid,
359 const std::string& frag_type_name,
360 const std::string& subdet_name);
363 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(
const record_id_t& rid,
365 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(
const record_id_t& rid,
366 const std::string& subdet_name)
369 return get_source_ids_for_subdetector(rid, subdet);
371 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(
const uint64_t rec_num,
375 return get_source_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet);
377 std::set<daqdataformats::SourceID> get_source_ids_for_subdetector(
const uint64_t rec_num,
379 const std::string& subdet_name)
381 return get_source_ids_for_subdetector(std::make_pair(rec_num, seq_num), subdet_name);
388 return get_source_ids(get_fragment_dataset_paths(
type));
390 std::set<daqdataformats::SourceID> get_source_ids(
const std::string& typestring)
392 return get_source_ids(get_fragment_dataset_paths(typestring));
396 std::unique_ptr<char[]> get_dataset_raw_data(
const std::string& dataset_path);
398 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const std::string& dataset_name);
399 std::unique_ptr<daqdataformats::TriggerRecordHeader> get_trh_ptr(
const std::string& dataset_name);
400 std::unique_ptr<daqdataformats::TimeSliceHeader> get_tsh_ptr(
const std::string& dataset_name);
402 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const record_id_t& rid,
404 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const uint64_t rec_num,
407 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const record_id_t& rid,
410 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const uint64_t rec_num,
414 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const record_id_t& rid,
415 const std::string& typestring,
417 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const uint64_t rec_num,
419 const std::string& typestring,
422 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const record_id_t& rid,
423 const uint64_t geo_id);
424 std::unique_ptr<daqdataformats::Fragment> get_frag_ptr(
const uint64_t rec_num,
426 const uint64_t geo_id);
428 std::unique_ptr<daqdataformats::TriggerRecordHeader> get_trh_ptr(
const record_id_t& rid);
432 return get_trh_ptr(std::make_pair(trig_num, seq_num));
435 std::unique_ptr<daqdataformats::TimeSliceHeader> get_tsh_ptr(
const record_id_t& rid);
438 return get_tsh_ptr(std::make_pair(ts_num, 0));
445 return get_trigger_record(std::make_pair(trig_num, seq_num));
451 std::vector<uint64_t> get_geo_ids_for_source_id(
const record_id_t& rid,
455 const uint64_t geo_id);
459 const std::string& timeslice_header_path{ m_file_layout_ptr->get_path_string(timeslice.
get_header()) };
460 return m_file_ptr->exist(timeslice_header_path);
464 HDF5RawDataFile(
const HDF5RawDataFile&) =
delete;
465 HDF5RawDataFile& operator=(
const HDF5RawDataFile&) =
delete;
466 HDF5RawDataFile(HDF5RawDataFile&&) =
delete;
467 HDF5RawDataFile& operator=(HDF5RawDataFile&&) =
delete;
469 std::unique_ptr<HighFive::File> m_file_ptr;
470 std::unique_ptr<HDF5FileLayout> m_file_layout_ptr;
471 std::string m_bare_file_name;
472 unsigned m_compression_level;
473 unsigned m_open_flags;
476 size_t m_recorded_size;
477 size_t m_uncompressed_raw_data_size;
478 size_t m_total_file_size;
479 std::string m_record_type;
482 void write_file_layout();
483 void read_file_layout();
484 void check_file_layout();
487 void check_record_type(std::string);
490 std::tuple<size_t, std::string, HighFive::Group> do_write(std::vector<std::string>
const&,
493 unsigned compression_level);
496 void explore_subgroup(
const HighFive::Group& parent_group,
497 std::string relative_path,
498 std::vector<std::string>& path_list);
501 void add_record_level_info_to_caches_if_needed(record_id_t rid);
504 record_id_set m_all_record_ids_in_file;
505 HDF5SourceIDHandler::source_id_geo_id_map_t m_file_level_source_id_geo_id_map;
506 std::map<record_id_t, std::set<daqdataformats::SourceID>> m_source_id_cache;
507 std::map<record_id_t, daqdataformats::SourceID> m_record_header_source_id_cache;
508 std::map<record_id_t, std::set<daqdataformats::SourceID>> m_fragment_source_id_cache;
509 std::map<record_id_t, HDF5SourceIDHandler::source_id_path_map_t> m_source_id_path_cache;
510 std::map<record_id_t, HDF5SourceIDHandler::source_id_geo_id_map_t> m_source_id_geo_id_cache;
511 std::map<record_id_t, HDF5SourceIDHandler::subsystem_source_id_map_t> m_subsystem_source_id_cache;
512 std::map<record_id_t, HDF5SourceIDHandler::fragment_type_source_id_map_t> m_fragment_type_source_id_cache;
513 std::map<record_id_t, HDF5SourceIDHandler::subdetector_source_id_map_t> m_subdetector_source_id_cache;
519HDF5RawDataFile::write_attribute(std::string name, T value)
521 if (!m_file_ptr->hasAttribute(name))
522 m_file_ptr->createAttribute(name, value);
529HDF5RawDataFile::write_attribute(HighFive::Group& grp,
const std::string& name, T value)
531 if (!(grp.hasAttribute(name)))
532 grp.createAttribute<T>(name, value);
539HDF5RawDataFile::write_attribute(HighFive::DataSet& dset,
const std::string& name, T value)
541 if (!dset.hasAttribute(name))
542 dset.createAttribute<T>(name, value);
549HDF5RawDataFile::get_attribute(
const std::string& name)
551 if (!m_file_ptr->hasAttribute(name)) {
552 throw InvalidHDF5Attribute(
ERS_HERE, name);
554 auto attr = m_file_ptr->getAttribute(name);
562HDF5RawDataFile::get_attribute_if_exists(
const std::string& name,
const T& default_value)
564 if (!m_file_ptr->hasAttribute(name)) {
565 TLOG_DEBUG(7) <<
"Debug: Attribute \"" << name <<
"\" not found. Defaulting to " << default_value;
566 return default_value;
568 auto attr = m_file_ptr->getAttribute(name);
571 TLOG_DEBUG(7) <<
"Debug: Attribute \"" << name <<
"\" found. Value: " << value;
577HDF5RawDataFile::get_attribute(
const HighFive::Group& grp,
const std::string& name)
579 if (!(grp.hasAttribute(name))) {
580 throw InvalidHDF5Attribute(
ERS_HERE, name);
582 auto attr = grp.getAttribute(name);
590HDF5RawDataFile::get_attribute(
const HighFive::DataSet& dset, std::string name)
592 if (!dset.hasAttribute(name)) {
593 throw InvalidHDF5Attribute(
ERS_HERE, name);
595 auto attr = dset.getAttribute(name);
#define TLOG_DEBUG(lvl,...)
ERS_DECLARE_ISSUE(cibmodules, CIBCommunicationError, " CIB Hardware Communication Error: "<< descriptor,((std::string) descriptor)) ERS_DECLARE_ISSUE(cibmodules
void warning(const Issue &issue)