DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
HDF5RawDataFile.cpp
Go to the documentation of this file.
1
7
9
10#include "logging/Logging.hpp"
11
12#include <algorithm>
13#include <filesystem>
14#include <map>
15#include <memory>
16#include <set>
17#include <sstream>
18#include <string>
19#include <utility>
20#include <vector>
21
22namespace dunedaq {
23namespace hdf5libs {
24
25constexpr uint32_t MAX_FILELAYOUT_VERSION = 4294967295; // NOLINT(build/unsigned)
26
30HDF5RawDataFile::HDF5RawDataFile(const std::string file_name,
31 const daqdataformats::run_number_t run_number,
32 const size_t file_index,
33 const std::string application_name,
34 const HDF5FileLayoutParameters fl_params,
36 const unsigned compression_level,
37 const std::string inprogress_filename_suffix,
38 const unsigned open_flags)
39 : m_bare_file_name(file_name)
40 , m_compression_level(compression_level)
41 , m_open_flags(open_flags)
42{
43
44 // check and make sure that the file isn't ReadOnly
45 if (m_open_flags == HighFive::File::ReadOnly) {
46 throw IncompatibleOpenFlags(ERS_HERE, file_name, m_open_flags);
47 }
48
49 auto filename_to_open = m_bare_file_name + inprogress_filename_suffix;
50
51 // do the file open
52 try {
53 m_file_ptr.reset(new HighFive::File(filename_to_open, m_open_flags));
54 } catch (std::exception const& excpt) {
55 throw FileOpenFailed(ERS_HERE, filename_to_open, excpt.what());
56 }
57
58 m_recorded_size = 0;
59 m_uncompressed_raw_data_size = 0;
60 m_total_file_size = 0;
61
62 size_t file_creation_timestamp =
63 std::chrono::duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count();
64
65 TLOG_DEBUG(TLVL_BASIC) << "Created HDF5 file (" << file_name << ") at time " << file_creation_timestamp << " .";
66
67 // write some file attributes
68 write_attribute("run_number", run_number);
69 write_attribute("file_index", file_index);
70 write_attribute("creation_timestamp", file_creation_timestamp);
71 write_attribute("application_name", application_name);
72
73 // set the file layout contents
74 m_file_layout_ptr.reset(new HDF5FileLayout(fl_params));
75 write_file_layout();
76
77 // write the SourceID-related attributes
78 // HDF5SourceIDHandler::populate_source_id_geo_id_map(srcid_geoid_map, m_file_level_source_id_geo_id_map);
79 m_file_level_source_id_geo_id_map = srcid_geoid_map;
80 HDF5SourceIDHandler::store_file_level_geo_id_info(*m_file_ptr, m_file_level_source_id_geo_id_map);
81
82 // write the record type
83 m_record_type = fl_params.record_name_prefix;
84 write_attribute("record_type", m_record_type);
85
86 // write the compression level
87 write_attribute("compression_level", m_compression_level);
88}
89
90HDF5RawDataFile::~HDF5RawDataFile()
91{
92 if (m_file_ptr.get() != nullptr && m_open_flags != HighFive::File::ReadOnly) {
93 if (!m_file_ptr->hasAttribute("recorded_size")) {
94 write_attribute("recorded_size", m_recorded_size);
95 }
96
97 if (!m_file_ptr->hasAttribute("uncompressed_raw_data_size")) {
98 write_attribute("uncompressed_raw_data_size", m_uncompressed_raw_data_size);
99 }
100
101 if (!m_file_ptr->hasAttribute("total_file_size")) {
102 write_attribute("total_file_size", m_total_file_size);
103 }
104
105 if (!m_file_ptr->hasAttribute("closing_timestamp")) {
106 size_t file_closing_timestamp =
107 std::chrono::duration_cast<std::chrono::milliseconds>(system_clock::now().time_since_epoch()).count();
108 write_attribute("closing_timestamp", file_closing_timestamp);
109 }
110
111 m_file_ptr->flush();
112
113 // rename file to the bare name, if needed
114 if (m_file_ptr->getName() != m_bare_file_name) {
115 std::filesystem::rename(m_file_ptr->getName(), m_bare_file_name);
116 }
117 }
118
119 // explicit destruction; not really needed, but nice to be clear...
120 m_file_ptr.reset();
121 m_file_layout_ptr.reset();
122}
123
127std::vector<std::string>
128HDF5RawDataFile::HDF5RawDataFile::get_attribute_names()
129{
130 return m_file_ptr->listAttributeNames();
131}
132
136void
137HDF5RawDataFile::write(const daqdataformats::TriggerRecord& tr)
138{
139 // the source_id_path map that we will build up as we write the TR header
140 // and fragments (and then write the map into the HDF5 TR_record Group)
141 HDF5SourceIDHandler::source_id_path_map_t source_id_path_map;
142
143 // the map of fragment types to SourceIDS
144 HDF5SourceIDHandler::fragment_type_source_id_map_t fragment_type_source_id_map;
145
146 // the map of subdetectors to SourceIDS
147 HDF5SourceIDHandler::subdetector_source_id_map_t subdetector_source_id_map;
148
149 // write the record header into the HDF5 file/group
150 HighFive::Group record_level_group = write(tr.get_header_ref(), source_id_path_map);
151
152 // store the SourceID of the record header in the HDF5 file/group
153 // (since there should only be one entry in the map at this point, we'll take advantage of that...)
154 for (auto const& source_id_path : source_id_path_map) {
155 HDF5SourceIDHandler::store_record_header_source_id(record_level_group, source_id_path.first);
156 }
157
158 // write all of the fragments into the HDF5 file/group
159 for (auto const& frag_ptr : tr.get_fragments_ref()) {
160 write(*frag_ptr, source_id_path_map);
161 HDF5SourceIDHandler::add_fragment_type_source_id_to_map(
162 fragment_type_source_id_map, frag_ptr->get_fragment_type(), frag_ptr->get_element_id());
163 HDF5SourceIDHandler::add_subdetector_source_id_to_map(
164 subdetector_source_id_map,
165 static_cast<detdataformats::DetID::Subdetector>(frag_ptr->get_detector_id()),
166 frag_ptr->get_element_id());
167 }
168
169 // store all of the record-level maps in the HDF5 file/group
170 HDF5SourceIDHandler::store_record_level_path_info(record_level_group, source_id_path_map);
171 HDF5SourceIDHandler::store_record_level_fragment_type_map(record_level_group, fragment_type_source_id_map);
172 HDF5SourceIDHandler::store_record_level_subdetector_map(record_level_group, subdetector_source_id_map);
173}
174
178void
179HDF5RawDataFile::write(const daqdataformats::TimeSlice& ts)
180{
181 // the source_id_path map that we will build up as we write the TR header
182 // and fragments (and then write the map into the HDF5 TR_record Group)
183 HDF5SourceIDHandler::source_id_path_map_t source_id_path_map;
184
185 // the map of fragment types to SourceIDS
186 HDF5SourceIDHandler::fragment_type_source_id_map_t fragment_type_source_id_map;
187
188 // the map of subdetectors to SourceIDS
189 HDF5SourceIDHandler::subdetector_source_id_map_t subdetector_source_id_map;
190
191 // write the record header into the HDF5 file/group
192 HighFive::Group record_level_group = write(ts.get_header(), source_id_path_map);
193
194 // store the SourceID of the record header in the HDF5 file/group
195 // (since there should only be one entry in the map at this point, we'll take advantage of that...)
196 for (auto const& source_id_path : source_id_path_map) {
197 HDF5SourceIDHandler::store_record_header_source_id(record_level_group, source_id_path.first);
198 }
199
200 // write all of the fragments into the HDF5 file/group
201 for (auto const& frag_ptr : ts.get_fragments_ref()) {
202 write(*frag_ptr, source_id_path_map);
203 HDF5SourceIDHandler::add_fragment_type_source_id_to_map(
204 fragment_type_source_id_map, frag_ptr->get_fragment_type(), frag_ptr->get_element_id());
205 HDF5SourceIDHandler::add_subdetector_source_id_to_map(
206 subdetector_source_id_map,
207 static_cast<detdataformats::DetID::Subdetector>(frag_ptr->get_detector_id()),
208 frag_ptr->get_element_id());
209 }
210
211 // store all of the record-level maps in the HDF5 file/group
212 HDF5SourceIDHandler::store_record_level_path_info(record_level_group, source_id_path_map);
213 HDF5SourceIDHandler::store_record_level_fragment_type_map(record_level_group, fragment_type_source_id_map);
214 HDF5SourceIDHandler::store_record_level_subdetector_map(record_level_group, subdetector_source_id_map);
215}
216
220HighFive::Group
221HDF5RawDataFile::write(const daqdataformats::TriggerRecordHeader& trh,
222 HDF5SourceIDHandler::source_id_path_map_t& path_map)
223{
224 std::tuple<size_t, std::string, HighFive::Group> write_results =
225 do_write(m_file_layout_ptr->get_path_elements(trh),
226 static_cast<const char*>(trh.get_storage_location()),
227 trh.get_total_size_bytes(),
228 m_compression_level);
229 m_recorded_size += std::get<0>(write_results);
230 HDF5SourceIDHandler::add_source_id_path_to_map(path_map, trh.get_header().element_id, std::get<1>(write_results));
231 return std::get<2>(write_results);
232}
233
237HighFive::Group
238HDF5RawDataFile::write(const daqdataformats::TimeSliceHeader& tsh, HDF5SourceIDHandler::source_id_path_map_t& path_map)
239{
240 std::tuple<size_t, std::string, HighFive::Group> write_results = do_write(m_file_layout_ptr->get_path_elements(tsh),
241 (const char*)(&tsh),
243 m_compression_level);
244 m_recorded_size += std::get<0>(write_results);
245 HDF5SourceIDHandler::add_source_id_path_to_map(path_map, tsh.element_id, std::get<1>(write_results));
246 return std::get<2>(write_results);
247}
248
252void
253HDF5RawDataFile::write(const daqdataformats::Fragment& frag, HDF5SourceIDHandler::source_id_path_map_t& path_map)
254{
255 std::tuple<size_t, std::string, HighFive::Group> write_results =
256 do_write(m_file_layout_ptr->get_path_elements(frag.get_header()),
257 static_cast<const char*>(frag.get_storage_location()),
258 frag.get_size(),
259 m_compression_level);
260 m_recorded_size += std::get<0>(write_results);
261
262 daqdataformats::SourceID source_id = frag.get_element_id();
263 HDF5SourceIDHandler::add_source_id_path_to_map(path_map, source_id, std::get<1>(write_results));
264}
265
269void
270HDF5RawDataFile::write_file_layout()
271{
272 auto fl_json = m_file_layout_ptr->get_file_layout_params().to_json();
273 write_attribute("filelayout_params", fl_json.dump());
274 write_attribute("filelayout_version", m_file_layout_ptr->get_version());
275}
276
280std::tuple<size_t, std::string, HighFive::Group>
281HDF5RawDataFile::do_write(std::vector<std::string> const& group_and_dataset_path_elements,
282 const char* raw_data_ptr,
283 size_t raw_data_size_bytes,
284 unsigned compression_level)
285{
286 const std::string dataset_name = group_and_dataset_path_elements.back();
287
288 // create top level group if needed
289 std::string const& top_level_group_name = group_and_dataset_path_elements.at(0);
290 if (!m_file_ptr->exist(top_level_group_name))
291 m_file_ptr->createGroup(top_level_group_name);
292
293 // setup sub_group to work with
294 HighFive::Group sub_group = m_file_ptr->getGroup(top_level_group_name);
295 if (!sub_group.isValid()) {
296 throw InvalidHDF5Group(ERS_HERE, top_level_group_name);
297 }
298 HighFive::Group top_level_group = sub_group;
299
300 // Create the remaining subgroups
301 for (size_t idx = 1; idx < group_and_dataset_path_elements.size() - 1; ++idx) {
302 // group_dataset.size()-1 because the last element is the dataset
303 std::string const& child_group_name = group_and_dataset_path_elements[idx];
304 if (child_group_name.empty()) {
305 throw InvalidHDF5Group(ERS_HERE, child_group_name);
306 }
307 if (!sub_group.exist(child_group_name)) {
308 sub_group.createGroup(child_group_name);
309 }
310 HighFive::Group child_group = sub_group.getGroup(child_group_name);
311 if (!child_group.isValid()) {
312 throw InvalidHDF5Group(ERS_HERE, child_group_name);
313 }
314 sub_group = child_group;
315 }
316
317 // Create dataset
318 HighFive::DataSpace data_space = HighFive::DataSpace({ raw_data_size_bytes, 1 });
319 HighFive::DataSetCreateProps data_set_create_props;
320 HighFive::DataSetAccessProps data_set_access_props;
321
322 if (compression_level > 0) {
323 std::vector<hsize_t> chunk_size = { raw_data_size_bytes, 1 };
324 data_set_create_props.add(HighFive::Chunking(chunk_size));
325 data_set_create_props.add(HighFive::Deflate(compression_level));
326 }
327
328 m_uncompressed_raw_data_size += raw_data_size_bytes;
329
330 auto data_set = sub_group.createDataSet<char>(dataset_name, data_space, data_set_create_props, data_set_access_props);
331
332 if (data_set.isValid()) {
333 data_set.write_raw(raw_data_ptr);
334 m_total_file_size = m_file_ptr->getFileSize();
335 m_file_ptr->flush();
336 return std::make_tuple(data_set.getStorageSize(), data_set.getPath(), top_level_group);
337 } else {
338 throw InvalidHDF5Dataset(ERS_HERE, dataset_name, m_file_ptr->getName());
339 }
340}
341
345HDF5RawDataFile::HDF5RawDataFile(const std::string& file_name, bool allow_writing)
346 : m_open_flags(HighFive::File::ReadOnly)
347{
348 if (allow_writing) {
349 m_open_flags = HighFive::File::ReadWrite;
350 }
351 m_bare_file_name = file_name;
352 size_t pos = m_bare_file_name.rfind(s_inprogress_suffix);
353 if (pos != std::string::npos) {
354 m_bare_file_name.erase(pos);
355 }
356
357 // do the file open
358 try {
359 m_file_ptr = std::make_unique<HighFive::File>(file_name, m_open_flags);
360 } catch (std::exception const& excpt) {
361 throw FileOpenFailed(ERS_HERE, file_name, excpt.what());
362 }
363
364 if (m_file_ptr->hasAttribute("recorded_size"))
365 m_recorded_size = get_attribute<size_t>("recorded_size");
366 else
367 m_recorded_size = 0;
368
369 if (m_file_ptr->hasAttribute("uncompressed_raw_data_size"))
370 m_uncompressed_raw_data_size = get_attribute<size_t>("uncompressed_raw_data_size");
371 else
372 m_uncompressed_raw_data_size = 0;
373
374 if (m_file_ptr->hasAttribute("total_file_size"))
375 m_total_file_size = get_attribute<size_t>("total_file_size");
376 else
377 m_total_file_size = 0;
378
379 if (m_file_ptr->hasAttribute("compression_level"))
380 m_compression_level = get_attribute<unsigned>("compression_level");
381 else
382 m_compression_level = 0;
383
384 read_file_layout();
385
386 if (m_file_ptr->hasAttribute("record_type"))
387 m_record_type = get_attribute<std::string>("record_type");
388 else
389 m_record_type = m_file_layout_ptr->get_record_name_prefix();
390
391 check_file_layout();
392
393 // HDF5SourceIDHandler operations need to come *after* read_file_layout()
394 // because they count on the filelayout_version, which is set in read_file_layout().
395 HDF5SourceIDHandler sid_handler(get_version());
396 sid_handler.fetch_file_level_geo_id_info(*m_file_ptr, m_file_level_source_id_geo_id_map);
397}
398
399void
400HDF5RawDataFile::read_file_layout()
401{
402 HDF5FileLayoutParameters fl_params;
403 uint32_t version = 0; // NOLINT(build/unsigned)
404
405 std::string fl_str;
406 try {
407 fl_str = get_attribute<std::string>("filelayout_params");
408 nlohmann::json fl_json = nlohmann::json::parse(fl_str);
409 fl_params = HDF5FileLayoutParameters(fl_json);
410
411 version = get_attribute<uint32_t>("filelayout_version"); // NOLINT(build/unsigned)
412
413 } catch (InvalidHDF5Attribute const&) {
414 ers::info(MissingFileLayout(ERS_HERE, version));
415 }
416
417 // now reset the HDF5Filelayout object
418 m_file_layout_ptr.reset(new HDF5FileLayout(fl_params, version));
419}
420
421void
422HDF5RawDataFile::check_file_layout()
423{
424 if (get_version() < 2)
425 return;
426
427 std::string record_type = get_attribute<std::string>("record_type");
428 if (record_type.compare(m_file_layout_ptr->get_record_name_prefix()) != 0)
429 throw BadRecordType(ERS_HERE, record_type, m_file_layout_ptr->get_record_name_prefix());
430}
431
432void
433HDF5RawDataFile::check_record_type(std::string rt_name)
434{
435 if (get_version() < 2)
436 return;
437
438 if (m_file_layout_ptr->get_record_name_prefix().compare(rt_name) != 0)
439 throw WrongRecordTypeRequested(ERS_HERE, rt_name, m_file_layout_ptr->get_record_name_prefix());
440}
441
442// HDF5 Utility function to recursively traverse a file
443void
444HDF5RawDataFile::explore_subgroup(const HighFive::Group& parent_group,
445 std::string relative_path,
446 std::vector<std::string>& path_list)
447{
448 if (relative_path.size() > 0 && relative_path.compare(relative_path.size() - 1, 1, "/") == 0)
449 relative_path.pop_back();
450
451 std::vector<std::string> childNames = parent_group.listObjectNames();
452
453 for (auto& child_name : childNames) {
454 std::string full_path = relative_path + "/" + child_name;
455 HighFive::ObjectType child_type = parent_group.getObjectType(child_name);
456
457 if (child_type == HighFive::ObjectType::Dataset) {
458 path_list.push_back(full_path);
459 } else if (child_type == HighFive::ObjectType::Group) {
460 HighFive::Group child_group = parent_group.getGroup(child_name);
461 // start the recusion
462 std::string new_path = relative_path + "/" + child_name;
463 explore_subgroup(child_group, new_path, path_list);
464 }
465 }
466}
467
468void
469HDF5RawDataFile::add_record_level_info_to_caches_if_needed(record_id_t rid)
470{
471 // we should probably check that all relevant caches have an entry for the
472 // specified record ID, but we will just check one, in the interest of
473 // performance, and trust the "else" part of this routine to fill in *all*
474 // of the appropriate caches
475 if (m_source_id_path_cache.count(rid) != 0) {
476 return;
477 }
478
479 // create the handler to do the work
480 HDF5SourceIDHandler sid_handler(get_version());
481
482 // determine the HDF5 Group that corresponds to the specified record
483 std::string record_level_group_name = m_file_layout_ptr->get_record_number_string(rid.first, rid.second);
484 HighFive::Group record_group = m_file_ptr->getGroup(record_level_group_name);
485 if (!record_group.isValid()) {
486 throw InvalidHDF5Group(ERS_HERE, record_level_group_name);
487 }
488
489 // start with a copy of the file-level source-id-to-geo-id map and give the
490 // handler an opportunity to add any record-level additions
491 HDF5SourceIDHandler::source_id_geo_id_map_t local_source_id_geo_id_map = m_file_level_source_id_geo_id_map;
492 sid_handler.fetch_record_level_geo_id_info(record_group, local_source_id_geo_id_map);
493
494 // fetch the record-level source-id-to-path map
495 HDF5SourceIDHandler::source_id_path_map_t source_id_path_map;
496 sid_handler.fetch_source_id_path_info(record_group, source_id_path_map);
497
498 // fetch the record-level fragment-type-to-source-id map
499 HDF5SourceIDHandler::fragment_type_source_id_map_t fragment_type_source_id_map;
500 sid_handler.fetch_fragment_type_source_id_info(record_group, fragment_type_source_id_map);
501
502 // fetch the record-level subdetector-to-source-id map
503 HDF5SourceIDHandler::subdetector_source_id_map_t subdetector_source_id_map;
504 sid_handler.fetch_subdetector_source_id_info(record_group, subdetector_source_id_map);
505
506 // loop through the source-id-to-path map to create various lists of SourceIDs in the record
507 daqdataformats::SourceID rh_sid = sid_handler.fetch_record_header_source_id(record_group);
508 std::set<daqdataformats::SourceID> full_source_id_set;
509 std::set<daqdataformats::SourceID> fragment_source_id_set;
510 HDF5SourceIDHandler::subsystem_source_id_map_t subsystem_source_id_map;
511 for (auto const& source_id_path : source_id_path_map) {
512 full_source_id_set.insert(source_id_path.first);
513 if (source_id_path.first != rh_sid) {
514 fragment_source_id_set.insert(source_id_path.first);
515 }
516 HDF5SourceIDHandler::add_subsystem_source_id_to_map(
517 subsystem_source_id_map, source_id_path.first.subsystem, source_id_path.first);
518 }
519
520 // note that even if the "fetch" methods above fail to add anything to the specified
521 // maps, the maps will still be valid (though, possibly empty), and once we add them
522 // to the caches here, we will be assured that lookups from the caches will not fail.
523 m_source_id_cache[rid] = full_source_id_set;
524 m_record_header_source_id_cache[rid] = rh_sid;
525 m_fragment_source_id_cache[rid] = fragment_source_id_set;
526 m_source_id_geo_id_cache[rid] = local_source_id_geo_id_map;
527 m_source_id_path_cache[rid] = source_id_path_map;
528 m_subsystem_source_id_cache[rid] = subsystem_source_id_map;
529 m_fragment_type_source_id_cache[rid] = fragment_type_source_id_map;
530 m_subdetector_source_id_cache[rid] = subdetector_source_id_map;
531}
532
536std::vector<std::string>
537HDF5RawDataFile::get_dataset_paths(std::string top_level_group_name)
538{
539 if (top_level_group_name.empty())
540 top_level_group_name = m_file_ptr->getPath();
541
542 // Vector containing the path list to the HDF5 datasets
543 std::vector<std::string> path_list;
544
545 HighFive::Group parent_group = m_file_ptr->getGroup(top_level_group_name);
546 if (!parent_group.isValid())
547 throw InvalidHDF5Group(ERS_HERE, top_level_group_name);
548
549 explore_subgroup(parent_group, top_level_group_name, path_list);
550
551 return path_list;
552}
553
557HDF5RawDataFile::record_id_set // NOLINT(build/unsigned)
558HDF5RawDataFile::get_all_record_ids()
559{
560 if (!m_all_record_ids_in_file.empty())
561 return m_all_record_ids_in_file;
562
563 // records are at the top level
564
565 HighFive::Group parent_group = m_file_ptr->getGroup(m_file_ptr->getPath());
566
567 std::vector<std::string> childNames = parent_group.listObjectNames();
568 const std::string record_prefix = m_file_layout_ptr->get_record_name_prefix();
569 const size_t record_prefix_size = record_prefix.size();
570
571 for (auto const& name : childNames) {
572 auto loc = name.find(record_prefix);
573
574 if (loc == std::string::npos)
575 continue;
576
577 auto rec_num_string = name.substr(loc + record_prefix_size);
578
579 loc = rec_num_string.find(".");
580 if (loc == std::string::npos) {
581 m_all_record_ids_in_file.insert(std::make_pair(std::stoll(rec_num_string), 0));
582 } else {
583 auto seq_num_string = rec_num_string.substr(loc + 1);
584 rec_num_string.resize(loc); // remove anything from '.' onwards
585 m_all_record_ids_in_file.insert(std::make_pair(std::stoll(rec_num_string), std::stoi(seq_num_string)));
586 }
587
588 } // end loop over childNames
589
590 return m_all_record_ids_in_file;
591}
592
593std::set<uint64_t>
594HDF5RawDataFile::get_all_record_numbers() // NOLINT(build/unsigned)
595{
596 ers::warning(DeprecatedUsage(ERS_HERE,
597 "get_all_record_numbers()",
598 "Use get_all_record_ids(), which returns a record_number,sequence_number pair."));
599
600 std::set<uint64_t> record_numbers; // NOLINT(build/unsigned)
601 for (auto const& rid : get_all_record_ids())
602 record_numbers.insert(rid.first);
603
604 return record_numbers;
605}
606
607HDF5RawDataFile::record_id_set
608HDF5RawDataFile::get_all_trigger_record_ids()
609{
610 check_record_type("TriggerRecord");
611 return get_all_record_ids();
612}
613
614std::set<daqdataformats::trigger_number_t>
615HDF5RawDataFile::get_all_trigger_record_numbers()
616{
618 DeprecatedUsage(ERS_HERE,
619 "get_all_trigger_record_numbers()",
620 "Use get_all_trigger_record_ids(), which returns a record_number,sequence_number pair."));
621
622 return get_all_record_numbers();
623}
624
625HDF5RawDataFile::record_id_set
626HDF5RawDataFile::get_all_timeslice_ids()
627{
628 check_record_type("TimeSlice");
629 return get_all_record_ids();
630}
631
632std::set<daqdataformats::timeslice_number_t>
633HDF5RawDataFile::get_all_timeslice_numbers()
634{
635 check_record_type("TimeSlice");
636 return get_all_record_numbers();
637}
638
642std::vector<std::string>
643HDF5RawDataFile::get_record_header_dataset_paths()
644{
645
646 std::vector<std::string> rec_paths;
647
648 if (get_version() >= 2) {
649 for (auto const& rec_id : get_all_record_ids())
650 rec_paths.push_back(get_record_header_dataset_path(rec_id));
651 } else {
652 for (auto const& path : get_dataset_paths()) {
653 if (path.find(m_file_layout_ptr->get_record_header_dataset_name()) != std::string::npos) {
654 rec_paths.push_back(path);
655 }
656 }
657 }
658
659 return rec_paths;
660}
661
662std::vector<std::string>
663HDF5RawDataFile::get_trigger_record_header_dataset_paths()
664{
665 check_record_type("TriggerRecord");
666 return get_record_header_dataset_paths();
667}
668
669std::vector<std::string>
670HDF5RawDataFile::get_timeslice_header_dataset_paths()
671{
672 check_record_type("TimeSlice");
673 return get_record_header_dataset_paths();
674}
675
676std::string
677HDF5RawDataFile::get_record_header_dataset_path(const record_id_t& rid)
678{
679 auto rec_id = get_all_record_ids().find(rid);
680 if (rec_id == get_all_record_ids().end())
681 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
682
683 if (get_version() <= 2) {
684 return (m_file_ptr->getPath() + m_file_layout_ptr->get_record_header_path(rid.first, rid.second));
685 } else {
686 daqdataformats::SourceID source_id = get_record_header_source_id(rid);
687 return m_source_id_path_cache[rid][source_id];
688 }
689}
690
691std::string
692HDF5RawDataFile::get_record_header_dataset_path(const uint64_t rec_num, // NOLINT (build/unsigned)
694{
695 return get_record_header_dataset_path(std::make_pair(rec_num, seq_num));
696}
697
698std::string
699HDF5RawDataFile::get_trigger_record_header_dataset_path(const record_id_t& rid)
700{
701 check_record_type("TriggerRecord");
702 return get_record_header_dataset_path(rid);
703}
704
705std::string
706HDF5RawDataFile::get_trigger_record_header_dataset_path(const daqdataformats::trigger_number_t trig_num,
708{
709 check_record_type("TriggerRecord");
710 return get_record_header_dataset_path(trig_num, seq_num);
711}
712
713std::string
714HDF5RawDataFile::get_timeslice_header_dataset_path(const record_id_t& rid)
715{
716 check_record_type("TimeSlice");
717 return get_record_header_dataset_path(rid.first, 0);
718}
719
720std::string
721HDF5RawDataFile::get_timeslice_header_dataset_path(const daqdataformats::timeslice_number_t ts_num)
722{
723 check_record_type("TimeSlice");
724 return get_record_header_dataset_path(ts_num);
725}
726
733std::vector<std::string>
734HDF5RawDataFile::get_all_fragment_dataset_paths()
735{
736 std::vector<std::string> frag_paths;
737
738 for (auto const& path : get_dataset_paths()) {
739 if (path.find(m_file_layout_ptr->get_record_header_dataset_name()) == std::string::npos)
740 frag_paths.push_back(path);
741 }
742
743 return frag_paths;
744}
745
746// get all fragment dataset paths for given record ID
747std::vector<std::string>
748HDF5RawDataFile::get_fragment_dataset_paths(const record_id_t& rid)
749{
750 auto rec_id = get_all_record_ids().find(rid);
751 if (rec_id == get_all_record_ids().end())
752 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
753
754 std::vector<std::string> frag_paths;
755 if (get_version() <= 2) {
756 std::string record_group_path =
757 m_file_ptr->getPath() + m_file_layout_ptr->get_record_number_string(rid.first, rid.second);
758
759 for (auto const& path : get_dataset_paths(record_group_path)) {
760 if (path.find(m_file_layout_ptr->get_record_header_dataset_name()) == std::string::npos)
761 frag_paths.push_back(path);
762 }
763 } else {
764 std::set<daqdataformats::SourceID> source_id_list = get_fragment_source_ids(rid);
765 for (auto const& source_id : source_id_list) {
766 frag_paths.push_back(m_source_id_path_cache[rid][source_id]);
767 }
768 }
769 return frag_paths;
770}
771
772// get all fragment dataset paths for given record ID
773std::vector<std::string>
774HDF5RawDataFile::get_fragment_dataset_paths(const uint64_t rec_num, // NOLINT (build/unsigned)
776{
777 return get_fragment_dataset_paths(std::make_pair(rec_num, seq_num));
778}
779
780// get all fragment dataset paths for a Subsystem
781std::vector<std::string>
782HDF5RawDataFile::get_fragment_dataset_paths(const daqdataformats::SourceID::Subsystem subsystem)
783{
784 std::vector<std::string> frag_paths;
785 for (auto const& rid : get_all_record_ids()) {
786 if (get_version() <= 2) {
787 auto datasets = get_dataset_paths(m_file_ptr->getPath() +
788 m_file_layout_ptr->get_fragment_type_path(rid.first, rid.second, subsystem));
789 frag_paths.insert(frag_paths.end(), datasets.begin(), datasets.end());
790 } else {
791 std::set<daqdataformats::SourceID> source_id_list = get_source_ids_for_subsystem(rid, subsystem);
792 for (auto const& source_id : source_id_list) {
793 frag_paths.push_back(m_source_id_path_cache[rid][source_id]);
794 }
795 }
796 }
797 return frag_paths;
798}
799
800std::vector<std::string>
801HDF5RawDataFile::get_fragment_dataset_paths(const std::string& subsystem_name)
802{
804 return get_fragment_dataset_paths(subsystem);
805}
806
807std::vector<std::string>
808HDF5RawDataFile::get_fragment_dataset_paths(const record_id_t& rid, const daqdataformats::SourceID::Subsystem subsystem)
809{
810 auto rec_id = get_all_record_ids().find(rid);
811 if (rec_id == get_all_record_ids().end())
812 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
813
814 if (get_version() <= 2) {
815 return get_dataset_paths(m_file_ptr->getPath() +
816 m_file_layout_ptr->get_fragment_type_path(rid.first, rid.second, subsystem));
817 } else {
818 std::vector<std::string> frag_paths;
819 std::set<daqdataformats::SourceID> source_id_list = get_source_ids_for_subsystem(rid, subsystem);
820 for (auto const& source_id : source_id_list) {
821 frag_paths.push_back(m_source_id_path_cache[rid][source_id]);
822 }
823 return frag_paths;
824 }
825}
826
827std::vector<std::string>
828HDF5RawDataFile::get_fragment_dataset_paths(const record_id_t& rid, const std::string& subsystem_name)
829{
831 return get_fragment_dataset_paths(rid, subsystem);
832}
833
834#if 0
835// get all fragment dataset paths for a SourceID
836std::vector<std::string>
837HDF5RawDataFile::get_fragment_dataset_paths(const daqdataformats::SourceID& source_id)
838{
839 std::vector<std::string> frag_paths;
840
841 for (auto const& rid : get_all_record_ids())
842 frag_paths.push_back(m_file_ptr->getPath() +
843 m_file_layout_ptr->get_fragment_path(rid.first, rid.second, source_id));
844
845 return frag_paths;
846}
847
848std::vector<std::string>
849HDF5RawDataFile::get_fragment_dataset_paths(const daqdataformats::SourceID::Subsystem type,
850 const uint32_t id) // NOLINT(build/unsigned)
851{
852 return get_fragment_dataset_paths(daqdataformats::SourceID(type, source_id));
853}
854std::vector<std::string>
855HDF5RawDataFile::get_fragment_dataset_paths(const std::string& typestring,
856 const uint32_t id) // NOLINT(build/unsigned)
857{
858 return get_fragment_dataset_paths(
860}
861
862std::set<daqdataformats::SourceID>
863HDF5RawDataFile::get_source_ids(std::vector<std::string> const& frag_dataset_paths)
864{
865 std::set<daqdataformats::SourceID> source_ids;
866 std::vector<std::string> path_elements;
867 std::string s;
868 for (auto const& frag_dataset : frag_dataset_paths) {
869 path_elements.clear();
870 std::istringstream iss(frag_dataset);
871 while (std::getline(iss, s, '/')) {
872 if (s.size() > 0)
873 path_elements.push_back(s);
874 }
875 source_ids.insert(m_file_layout_ptr->get_source_id_from_path_elements(path_elements));
876 }
877
878 return source_ids;
879}
880#endif
881
882HDF5SourceIDHandler::source_id_geo_id_map_t
883HDF5RawDataFile::get_srcid_geoid_map() const
884{
885
886 return m_file_level_source_id_geo_id_map;
887}
888
889std::set<uint64_t> // NOLINT(build/unsigned)
890HDF5RawDataFile::get_all_geo_ids() const
891{
892 std::set<uint64_t> set_of_geo_ids;
893 // 13-Sep-2022, KAB
894 // It would be safer, but slower, to fetch all of the geo_ids from the
895 // individual records, and we'll go with faster, for now. If/when we
896 // change the way that we determine the file-level and record-level
897 // source_id-to-geo_id maps, we may need to change this code.
898 for (auto const& map_entry : m_file_level_source_id_geo_id_map) {
899 for (auto const& geo_id : map_entry.second) {
900 set_of_geo_ids.insert(geo_id);
901 }
902 }
903 return set_of_geo_ids;
904}
905
906std::set<uint64_t> // NOLINT(build/unsigned)
907HDF5RawDataFile::get_geo_ids(const record_id_t& rid)
908{
909 auto rec_id = get_all_record_ids().find(rid);
910 if (rec_id == get_all_record_ids().end())
911 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
912
913 add_record_level_info_to_caches_if_needed(rid);
914
915 std::set<uint64_t> set_of_geo_ids;
916 for (auto const& map_entry : m_source_id_geo_id_cache[rid]) {
917 for (auto const& geo_id : map_entry.second) {
918 set_of_geo_ids.insert(geo_id);
919 }
920 }
921 return set_of_geo_ids;
922}
923
924std::set<uint64_t> // NOLINT(build/unsigned)
925HDF5RawDataFile::get_geo_ids_for_subdetector(const record_id_t& rid, const detdataformats::DetID::Subdetector subdet)
926{
927 auto rec_id = get_all_record_ids().find(rid);
928 if (rec_id == get_all_record_ids().end())
929 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
930
931 add_record_level_info_to_caches_if_needed(rid);
932
933 std::set<uint64_t> set_of_geo_ids;
934 for (auto const& map_entry : m_source_id_geo_id_cache[rid]) {
935 for (auto const& geo_id : map_entry.second) {
936 // FIXME: replace with a proper coder/decoder
937
938 uint16_t det_id = 0xffff & geo_id;
939 if (det_id == static_cast<uint16_t>(subdet)) {
940 set_of_geo_ids.insert(geo_id);
941 }
942 }
943 }
944 return set_of_geo_ids;
945}
946
947// get all SourceIDs for given record ID
948std::set<daqdataformats::SourceID>
949HDF5RawDataFile::get_source_ids(const record_id_t& rid)
950{
951 auto rec_id = get_all_record_ids().find(rid);
952 if (rec_id == get_all_record_ids().end())
953 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
954
955 add_record_level_info_to_caches_if_needed(rid);
956
957 return m_source_id_cache[rid];
958}
959
961HDF5RawDataFile::get_record_header_source_id(const record_id_t& rid)
962{
963 auto rec_id = get_all_record_ids().find(rid);
964 if (rec_id == get_all_record_ids().end())
965 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
966
967 add_record_level_info_to_caches_if_needed(rid);
968
969 return m_record_header_source_id_cache[rid];
970}
971
972std::set<daqdataformats::SourceID>
973HDF5RawDataFile::get_fragment_source_ids(const record_id_t& rid)
974{
975 auto rec_id = get_all_record_ids().find(rid);
976 if (rec_id == get_all_record_ids().end())
977 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
978
979 add_record_level_info_to_caches_if_needed(rid);
980
981 return m_fragment_source_id_cache[rid];
982}
983
984std::set<daqdataformats::SourceID>
985HDF5RawDataFile::get_source_ids_for_subsystem(const record_id_t& rid,
987{
988 auto rec_id = get_all_record_ids().find(rid);
989 if (rec_id == get_all_record_ids().end())
990 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
991
992 add_record_level_info_to_caches_if_needed(rid);
993
994 return m_subsystem_source_id_cache[rid][subsystem];
995}
996
997std::set<daqdataformats::SourceID>
998HDF5RawDataFile::get_source_ids_for_fragment_type(const record_id_t& rid, const daqdataformats::FragmentType frag_type)
999{
1000 auto rec_id = get_all_record_ids().find(rid);
1001 if (rec_id == get_all_record_ids().end())
1002 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1003
1004 add_record_level_info_to_caches_if_needed(rid);
1005
1006 return m_fragment_type_source_id_cache[rid][frag_type];
1007}
1008
1009std::set<daqdataformats::SourceID>
1010HDF5RawDataFile::get_source_ids_for_fragtype_and_subdetector(const record_id_t& rid,
1011 const std::string& frag_type_name,
1012 const std::string& subdet_name)
1013{
1016 throw InvalidFragmentTypeString(ERS_HERE, frag_type_name);
1019 throw InvalidSubdetectorString(ERS_HERE, subdet_name);
1020
1021 auto rec_id = get_all_record_ids().find(rid);
1022 if (rec_id == get_all_record_ids().end())
1023 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1024
1025 add_record_level_info_to_caches_if_needed(rid);
1026
1027 std::set<daqdataformats::SourceID> fragtype_match_sids = m_fragment_type_source_id_cache[rid][frag_type];
1028 std::set<daqdataformats::SourceID> detid_match_sids = m_subdetector_source_id_cache[rid][subdet];
1029 std::set<daqdataformats::SourceID> combined_set_sids;
1030 for (auto ftsid : fragtype_match_sids) {
1031 if (detid_match_sids.contains(ftsid)) {
1032 combined_set_sids.insert(ftsid);
1033 }
1034 }
1035 return combined_set_sids;
1036}
1037
1038std::set<daqdataformats::SourceID>
1039HDF5RawDataFile::get_source_ids_for_subdetector(const record_id_t& rid, const detdataformats::DetID::Subdetector subdet)
1040{
1041 auto rec_id = get_all_record_ids().find(rid);
1042 if (rec_id == get_all_record_ids().end())
1043 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1044
1045 add_record_level_info_to_caches_if_needed(rid);
1046
1047 return m_subdetector_source_id_cache[rid][subdet];
1048}
1049
1050std::unique_ptr<char[]>
1051HDF5RawDataFile::get_dataset_raw_data(const std::string& dataset_path)
1052{
1053 HighFive::Group parent_group = m_file_ptr->getGroup("/");
1054 HighFive::DataSet data_set = parent_group.getDataSet(dataset_path);
1055
1056 if (!data_set.isValid())
1057 throw InvalidHDF5Dataset(ERS_HERE, dataset_path, get_file_name());
1058
1059 size_t data_size = data_set.getSpace().getElementCount() * sizeof(char);
1060
1061 auto membuffer = std::make_unique<char[]>(data_size);
1062
1063 data_set.read(membuffer.get());
1064 return membuffer;
1065}
1066
1067std::unique_ptr<daqdataformats::Fragment>
1068HDF5RawDataFile::get_frag_ptr(const std::string& dataset_name)
1069{
1070 auto membuffer = get_dataset_raw_data(dataset_name);
1071 auto frag_ptr = std::make_unique<daqdataformats::Fragment>(
1073 return frag_ptr;
1074}
1075
1076std::unique_ptr<daqdataformats::Fragment>
1077HDF5RawDataFile::get_frag_ptr(const record_id_t& rid, const daqdataformats::SourceID& source_id)
1078{
1079 if (get_version() < 2)
1080 throw IncompatibleFileLayoutVersion(ERS_HERE, get_version(), 2, MAX_FILELAYOUT_VERSION);
1081
1082 auto rec_id = get_all_record_ids().find(rid);
1083 if (rec_id == get_all_record_ids().end())
1084 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1085
1086 add_record_level_info_to_caches_if_needed(rid);
1087
1088 return get_frag_ptr(m_source_id_path_cache[rid][source_id]);
1089}
1090
1091std::unique_ptr<daqdataformats::Fragment>
1092HDF5RawDataFile::get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
1094 const daqdataformats::SourceID& source_id)
1095{
1096 record_id_t rid = std::make_pair(rec_num, seq_num);
1097 return get_frag_ptr(rid, source_id);
1098}
1099
1100std::unique_ptr<daqdataformats::Fragment>
1101HDF5RawDataFile::get_frag_ptr(const record_id_t& rid,
1103 const uint32_t id) // NOLINT(build/unsigned)
1104{
1105 daqdataformats::SourceID source_id(type, id);
1106 return get_frag_ptr(rid, source_id);
1107}
1108
1109std::unique_ptr<daqdataformats::Fragment>
1110HDF5RawDataFile::get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
1113 const uint32_t id) // NOLINT(build/unsigned)
1114{
1115 record_id_t rid = std::make_pair(rec_num, seq_num);
1116 daqdataformats::SourceID source_id(type, id);
1117 return get_frag_ptr(rid, source_id);
1118}
1119
1120std::unique_ptr<daqdataformats::Fragment>
1121HDF5RawDataFile::get_frag_ptr(const record_id_t& rid,
1122 const std::string& typestring,
1123 const uint32_t id) // NOLINT(build/unsigned)
1124{
1126 return get_frag_ptr(rid, source_id);
1127}
1128
1129std::unique_ptr<daqdataformats::Fragment>
1130HDF5RawDataFile::get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
1132 const std::string& typestring,
1133 const uint32_t id) // NOLINT(build/unsigned)
1134{
1135 record_id_t rid = std::make_pair(rec_num, seq_num);
1137 return get_frag_ptr(rid, source_id);
1138}
1139
1140std::unique_ptr<daqdataformats::Fragment>
1141HDF5RawDataFile::get_frag_ptr(const record_id_t& rid,
1142 const uint64_t geo_id) // NOLINT(build/unsigned)
1143{
1144 daqdataformats::SourceID sid = get_source_id_for_geo_id(rid, geo_id);
1145 return get_frag_ptr(rid, sid);
1146}
1147
1148std::unique_ptr<daqdataformats::Fragment>
1149HDF5RawDataFile::get_frag_ptr(const uint64_t rec_num, // NOLINT(build/unsigned)
1151 const uint64_t geo_id) // NOLINT(build/unsigned)
1152{
1153 record_id_t rid = std::make_pair(rec_num, seq_num);
1154 return get_frag_ptr(rid, geo_id);
1155}
1156
1157std::unique_ptr<daqdataformats::TriggerRecordHeader>
1158HDF5RawDataFile::get_trh_ptr(const std::string& dataset_name)
1159{
1160 auto membuffer = get_dataset_raw_data(dataset_name);
1161 auto trh_ptr = std::make_unique<daqdataformats::TriggerRecordHeader>(membuffer.release(), true);
1162 return trh_ptr;
1163}
1164
1165std::unique_ptr<daqdataformats::TriggerRecordHeader>
1166HDF5RawDataFile::get_trh_ptr(const record_id_t& rid)
1167{
1168 if (get_version() < 2)
1169 throw IncompatibleFileLayoutVersion(ERS_HERE, get_version(), 2, MAX_FILELAYOUT_VERSION);
1170
1171 auto rec_id = get_all_record_ids().find(rid);
1172 if (rec_id == get_all_record_ids().end())
1173 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1174
1175 add_record_level_info_to_caches_if_needed(rid);
1176
1177 daqdataformats::SourceID rh_source_id = m_record_header_source_id_cache[rid];
1178 return get_trh_ptr(m_source_id_path_cache[rid][rh_source_id]);
1179}
1180
1181std::unique_ptr<daqdataformats::TimeSliceHeader>
1182HDF5RawDataFile::get_tsh_ptr(const std::string& dataset_name)
1183{
1184 auto membuffer = get_dataset_raw_data(dataset_name);
1185 auto tsh_ptr = std::make_unique<daqdataformats::TimeSliceHeader>(
1186 *(reinterpret_cast<daqdataformats::TimeSliceHeader*>(membuffer.release()))); // NOLINT
1187 return tsh_ptr;
1188}
1189
1190std::unique_ptr<daqdataformats::TimeSliceHeader>
1191HDF5RawDataFile::get_tsh_ptr(const record_id_t& rid)
1192{
1193 if (get_version() < 2)
1194 throw IncompatibleFileLayoutVersion(ERS_HERE, get_version(), 2, MAX_FILELAYOUT_VERSION);
1195
1196 auto rec_id = get_all_record_ids().find(rid);
1197 if (rec_id == get_all_record_ids().end())
1198 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1199
1200 add_record_level_info_to_caches_if_needed(rid);
1201
1202 daqdataformats::SourceID rh_source_id = m_record_header_source_id_cache[rid];
1203 return get_tsh_ptr(m_source_id_path_cache[rid][rh_source_id]);
1204}
1205
1207HDF5RawDataFile::get_trigger_record(const record_id_t& rid)
1208{
1209 daqdataformats::TriggerRecord trigger_record(*get_trh_ptr(rid));
1210 for (auto const& frag_path : get_fragment_dataset_paths(rid)) {
1211 trigger_record.add_fragment(get_frag_ptr(frag_path));
1212 }
1213
1214 return trigger_record;
1215}
1216
1218HDF5RawDataFile::get_timeslice(const daqdataformats::timeslice_number_t ts_num)
1219{
1220 daqdataformats::TimeSlice timeslice(*get_tsh_ptr(ts_num));
1221 for (auto const& frag_path : get_fragment_dataset_paths(ts_num)) {
1222 timeslice.add_fragment(get_frag_ptr(frag_path));
1223 }
1224
1225 return timeslice;
1226}
1227
1228std::vector<uint64_t> // NOLINT(build/unsigned)
1229HDF5RawDataFile::get_geo_ids_for_source_id(const record_id_t& rid, const daqdataformats::SourceID& source_id)
1230{
1231 auto rec_id = get_all_record_ids().find(rid);
1232 if (rec_id == get_all_record_ids().end())
1233 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1234
1235 add_record_level_info_to_caches_if_needed(rid);
1236
1237 return m_source_id_geo_id_cache[rid][source_id];
1238}
1239
1241HDF5RawDataFile::get_source_id_for_geo_id(const record_id_t& rid,
1242 const uint64_t requested_geo_id) // NOLINT(build/unsigned)
1243{
1244 auto rec_id = get_all_record_ids().find(rid);
1245 if (rec_id == get_all_record_ids().end())
1246 throw RecordIDNotFound(ERS_HERE, rid.first, rid.second);
1247
1248 add_record_level_info_to_caches_if_needed(rid);
1249
1250 // if we want to make this faster, we could build a reverse lookup cache in
1251 // add_record_level_info_to_caches_if_needed() and just look up the requested geo_id here
1252 for (auto const& map_entry : m_source_id_geo_id_cache[rid]) {
1253 auto geoid_list = map_entry.second;
1254 for (auto const& geoid_from_list : geoid_list) {
1255 if (geoid_from_list == requested_geo_id) {
1256 return map_entry.first;
1257 }
1258 }
1259 }
1260
1261 daqdataformats::SourceID empty_sid;
1262 return empty_sid;
1263}
1264
1265} // namespace hdf5libs
1266} // namespace dunedaq
#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
@ kTakeOverBuffer
Take over control of the buffer.
Definition Fragment.hpp:43
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...
std::map< daqdataformats::SourceID, std::vector< uint64_t > > source_id_geo_id_map_t
static void store_file_level_geo_id_info(HighFive::File &h5_file, const source_id_geo_id_map_t &the_map)
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
void write(gtool::t_graph const &, std::string const &)
Definition gtool.cpp:202
FragmentType
All defined Fragment types.
uint64_t trigger_number_t
Definition Types.hpp:18
FragmentType string_to_fragment_type(const std::string &name)
uint16_t sequence_number_t
Type used to represent sequence within a trigger record.
Definition Types.hpp:38
uint64_t timeslice_number_t
Definition Types.hpp:40
constexpr uint32_t MAX_FILELAYOUT_VERSION
The DUNE-DAQ namespace.
void warning(const Issue &issue)
Definition ers.hpp:150
void info(const Issue &issue)
Definition ers.hpp:121
SourceID is a generalized representation of the source of a piece of data in the DAQ....
Definition SourceID.hpp:32
static Subsystem string_to_subsystem(const std::string &typestring)
Definition SourceID.hxx:81
Subsystem
The Subsystem enum describes the kind of source we're dealing with.
Definition SourceID.hpp:40
Data fields associated with a TimeSliceHeader.
static Subdetector string_to_subdetector(const std::string &typestring)
Definition DetID.hxx:95
Subdetector
The Subdetector enum describes the kind of source we're dealing with.
Definition DetID.hpp:36