artdaq_demo_hdf5  v1_01_00
highFiveGeoSplitPDSPSample_dataset.cc
1 #include "tracemf.h"
2 #define TRACE_NAME "HighFiveGeoCmpltPDSPSample"
3 #define TLVL_INSERTONE 6
4 #define TLVL_INSERTHEADER 7
5 #define TLVL_WRITEFRAGMENT 8
6 #define TLVL_WRITEFRAGMENT_V 9
7 #define TLVL_READNEXTEVENT 10
8 #define TLVL_READNEXTEVENT_V 11
9 #define TLVL_READFRAGMENT 12
10 #define TLVL_READFRAGMENT_V 13
11 #define TLVL_GETEVENTHEADER 14
12 
13 #include <unordered_map>
14 #include "artdaq-core/Data/ContainerFragmentLoader.hh"
15 #include "artdaq-demo-hdf5/HDF5/FragmentDataset.hh"
16 #include "artdaq-demo-hdf5/HDF5/highFive/HighFive/include/highfive/H5File.hpp"
17 #include "artdaq-core/Utilities/TimeUtils.hh"
18 
19 namespace artdaq {
20 namespace hdf5 {
21 class HighFiveGeoCmpltPDSPSample : public FragmentDataset
22 {
23 public:
24  HighFiveGeoCmpltPDSPSample(fhicl::ParameterSet const& ps);
25  virtual ~HighFiveGeoCmpltPDSPSample();
26 
27  void insertOne(artdaq::Fragment const& frag) override;
28  void insertMany(artdaq::Fragments const& frags) override;
29  void insertHeader(artdaq::detail::RawEventHeader const& hdr) override;
30  std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> readNextEvent() override;
31  std::unique_ptr<artdaq::detail::RawEventHeader> getEventHeader(artdaq::Fragment::sequence_id_t const& seqID) override;
32 
33 private:
34  std::unique_ptr<HighFive::File> file_;
35  size_t eventIndex_;
36  HighFive::DataSetCreateProps fragmentCProps_;
37  HighFive::DataSetAccessProps fragmentAProps_;
38 
39  void writeFragment_(HighFive::Group& group, artdaq::Fragment const& frag);
40  artdaq::FragmentPtr readFragment_(HighFive::DataSet const& dataset);
41 
42  bool typeOfInterest(artdaq::Fragment::type_t theType);
43  std::array<int, 4> typesOfInterest;
44  int apaOfInterest;
45 };
46 } // namespace hdf5
47 } // namespace artdaq
48 
49 artdaq::hdf5::HighFiveGeoCmpltPDSPSample::HighFiveGeoCmpltPDSPSample(fhicl::ParameterSet const& ps)
50  : FragmentDataset(ps, ps.get<std::string>("mode", "write")), file_(nullptr), eventIndex_(0)
51 {
52  TLOG(TLVL_DEBUG) << "HighFiveGeoCmpltPDSPSample CONSTRUCTOR BEGIN";
53  if (mode_ == FragmentDatasetMode::Read)
54  {
55  file_.reset(new HighFive::File(ps.get<std::string>("fileName"), HighFive::File::ReadOnly));
56  }
57  else
58  {
59  file_.reset(new HighFive::File(ps.get<std::string>("fileName"), HighFive::File::OpenOrCreate | HighFive::File::Truncate));
60  }
61 
62  typesOfInterest = ps.get<std::array<int, 4> >("fragmentTypesOfInterest");
63  apaOfInterest = ps.get<int>("apaOfInterest");
64 
65  TLOG(TLVL_DEBUG) << "HighFiveGeoCmpltPDSPSample CONSTRUCTOR END";
66 }
67 
68 artdaq::hdf5::HighFiveGeoCmpltPDSPSample::~HighFiveGeoCmpltPDSPSample()
69 {
70  TLOG(TLVL_DEBUG) << "~HighFiveGeoCmpltPDSPSample Begin/End ";
71  // file_->flush();
72 }
73 
74 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::insertOne(artdaq::Fragment const& frag)
75 {
76  TLOG(TLVL_TRACE) << "insertOne BEGIN";
77  if (!file_->exist(std::to_string(frag.sequenceID())))
78  {
79  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for sequence ID " << frag.sequenceID();
80  file_->createGroup(std::to_string(frag.sequenceID()));
81  }
82  auto eventGroup = file_->getGroup(std::to_string(frag.sequenceID()));
83 
84  if (frag.type() == Fragment::ContainerFragmentType)
85  {
86  TLOG(TLVL_INSERTONE) << "insertOne: Processing ContainerFragment";
87  ContainerFragment cf(frag);
88 
89  if (typeOfInterest(cf.fragment_type()))
90  {
91 
92  if (cf.fragment_type() != 10 && (cf.block_count() > 1 || cf.fragment_type() == 9))
93  {
94  TLOG(TLVL_INSERTONE) << "insertOne: Getting Fragment type name";
95  auto fragPtr = cf.at(0);
96  auto typeName = nameHelper_->GetInstanceNameForFragment(*fragPtr).second;
97  if (!eventGroup.exist(typeName))
98  {
99  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
100  eventGroup.createGroup(typeName);
101  }
102 
103  TLOG(TLVL_INSERTONE) << "insertOne: Creating group and setting attributes";
104  auto typeGroup = eventGroup.getGroup(typeName);
105  std::string containerName = "Container0";
106 
107  int counter = 1;
108  while (typeGroup.exist(containerName))
109  {
110  //TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Duplicate Fragment ID " << frag.fragmentID() << " detected. If this is a ContainerFragment, this is expected, otherwise check configuration!";
111  containerName = "Container" + std::to_string(counter);
112  counter++;
113  }
114 
115  auto containerGroup = typeGroup.createGroup(containerName);
116  containerGroup.createAttribute("version", frag.version());
117  containerGroup.createAttribute("type", frag.type());
118  containerGroup.createAttribute("sequence_id", frag.sequenceID());
119  containerGroup.createAttribute("fragment_id", frag.fragmentID());
120  containerGroup.createAttribute("timestamp", frag.timestamp());
121 
122  containerGroup.createAttribute("container_block_count", cf.block_count());
123  containerGroup.createAttribute("container_fragment_type", cf.fragment_type());
124  containerGroup.createAttribute("container_version", cf.metadata()->version);
125  containerGroup.createAttribute("container_missing_data", cf.missing_data());
126 
127  TLOG(TLVL_INSERTONE) << "insertOne: Writing Container contained Fragments";
128  for (size_t ii = 0; ii < cf.block_count(); ++ii)
129  {
130  if (ii != 0)
131  {
132  fragPtr = cf.at(ii);
133  }
134  writeFragment_(containerGroup, *fragPtr);
135  }
136  }
137  else if (cf.block_count() == 1 || cf.fragment_type() == 10)
138  {
139  TLOG(TLVL_INSERTONE) << "insertOne: Getting Fragment type name";
140  auto fragPtr = cf.at(0);
141  auto typeName = nameHelper_->GetInstanceNameForFragment(*fragPtr).second;
142  if (!eventGroup.exist(typeName))
143  {
144  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
145  eventGroup.createGroup(typeName);
146  }
147 
148  TLOG(TLVL_INSERTONE) << "insertOne: Creating type group";
149  auto typeGroup = eventGroup.getGroup(typeName);
150  for (size_t ii = 0; ii < cf.block_count(); ++ii)
151  {
152  if (ii != 0)
153  {
154  fragPtr = cf.at(ii);
155  }
156  writeFragment_(typeGroup, *fragPtr);
157  }
158  }
159 #if 0
160  else
161  {
162  TLOG(TLVL_INSERTONE) << "insertOne: Writing Empty Container Fragment as standard Fragment";
163  auto typeName = nameHelper_->GetInstanceNameForFragment(frag).second;
164  if (!eventGroup.exist(typeName))
165  {
166  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
167  eventGroup.createGroup(typeName);
168  }
169  auto typeGroup = eventGroup.getGroup(typeName);
170 
171  writeFragment_(typeGroup, frag);
172  }
173 #endif
174  }
175  }
176  else if (frag.type() == 5) // Timing
177  {
178  if (typeOfInterest(frag.type()))
179  {
180 
181  TLOG(TLVL_INSERTONE) << "insertOne: Writing Timing Fragment";
182  writeFragment_(eventGroup, frag);
183 
184  }
185  }
186  else
187  {
188  if (typeOfInterest(frag.type()))
189  {
190 
191  TLOG(TLVL_INSERTONE) << "insertOne: Writing non-Container Fragment";
192  auto typeName = nameHelper_->GetInstanceNameForFragment(frag).second;
193  if (!eventGroup.exist(typeName))
194  {
195  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
196  eventGroup.createGroup(typeName);
197  }
198  auto typeGroup = eventGroup.getGroup(typeName);
199 
200  writeFragment_(typeGroup, frag);
201 
202  }
203  }
204  TLOG(TLVL_TRACE) << "insertOne END";
205 }
206 
207 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::insertMany(artdaq::Fragments const& fs)
208 {
209  TLOG(TLVL_TRACE) << "insertMany BEGIN";
210  for (auto& f : fs) insertOne(f);
211  TLOG(TLVL_TRACE) << "insertMany END";
212 }
213 
214 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::insertHeader(artdaq::detail::RawEventHeader const& hdr)
215 {
216  TLOG(TLVL_TRACE) << "insertHeader BEGIN";
217  if (!file_->exist(std::to_string(hdr.sequence_id)))
218  {
219  TLOG(TLVL_INSERTHEADER) << "insertHeader: Creating group for event " << hdr.sequence_id;
220  file_->createGroup(std::to_string(hdr.sequence_id));
221  }
222  auto eventGroup = file_->getGroup(std::to_string(hdr.sequence_id));
223  eventGroup.createAttribute("run_id", hdr.run_id);
224  eventGroup.createAttribute("subrun_id", hdr.subrun_id);
225  eventGroup.createAttribute("event_id", hdr.event_id);
226  eventGroup.createAttribute("is_complete", hdr.is_complete);
227  TLOG(TLVL_TRACE) << "insertHeader END";
228 }
229 
230 std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> artdaq::hdf5::HighFiveGeoCmpltPDSPSample::readNextEvent()
231 {
232  TLOG(TLVL_DEBUG) << "readNextEvent BEGIN";
233  std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> output;
234 
235  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Finding next event group in file";
236  auto groupNames = file_->listObjectNames();
237  while (eventIndex_ < groupNames.size() && file_->getObjectType(groupNames[eventIndex_]) != HighFive::ObjectType::Group)
238  {
239  eventIndex_++;
240  }
241 
242  if (groupNames.size() <= eventIndex_)
243  {
244  TLOG(TLVL_INFO) << "readNextEvent: No more events in file!";
245  }
246  else
247  {
248  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Getting event group " << groupNames[eventIndex_];
249  auto event_group = file_->getGroup(groupNames[eventIndex_]);
250  auto fragment_type_names = event_group.listObjectNames();
251 
252  for (auto& fragment_type : fragment_type_names)
253  {
254  if (event_group.getObjectType(fragment_type) != HighFive::ObjectType::Group)
255  {
256  continue;
257  }
258  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Reading Fragment type " << fragment_type;
259  auto type_group = event_group.getGroup(fragment_type);
260  auto fragment_names = type_group.listObjectNames();
261 
262  for (auto& fragment_name : fragment_names)
263  {
264  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Reading Fragment " << fragment_name;
265  auto node_type = type_group.getObjectType(fragment_name);
266  if (node_type == HighFive::ObjectType::Group)
267  {
268  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Fragment " << fragment_name << " is a Container";
269  auto container_group = type_group.getGroup(fragment_name);
270  Fragment::type_t type;
271  container_group.getAttribute("type").read<Fragment::type_t>(type);
272  Fragment::sequence_id_t seqID;
273  container_group.getAttribute("sequence_id").read(seqID);
274  Fragment::timestamp_t timestamp;
275  container_group.getAttribute("timestamp").read(timestamp);
276  Fragment::fragment_id_t fragID;
277  container_group.getAttribute("fragment_id").read(fragID);
278  if (!output.count(type))
279  {
280  output[type].reset(new Fragments());
281  }
282  output[type]->emplace_back(seqID, fragID);
283  output[type]->back().setTimestamp(timestamp);
284  output[type]->back().setSystemType(type);
285 
286  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Creating ContainerFragmentLoader for reading Container Fragments";
287  ContainerFragmentLoader cfl(output[type]->back());
288 
289  Fragment::type_t container_fragment_type;
290  int missing_data;
291  container_group.getAttribute("container_fragment_type").read(container_fragment_type);
292  container_group.getAttribute("container_missing_data").read(missing_data);
293 
294  cfl.set_fragment_type(container_fragment_type);
295  cfl.set_missing_data(missing_data);
296 
297  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Reading ContainerFragment Fragments";
298  auto fragments = container_group.listObjectNames();
299  for (auto& fragname : fragments)
300  {
301  if (container_group.getObjectType(fragname) != HighFive::ObjectType::Dataset) continue;
302  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ BEGIN";
303  auto frag = readFragment_(container_group.getDataSet(fragname, fragmentAProps_));
304  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ END";
305 
306  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling addFragment BEGIN";
307  cfl.addFragment(frag);
308  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: addFragment END";
309  }
310  }
311  else if (node_type == HighFive::ObjectType::Dataset)
312  {
313  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ BEGIN";
314  auto frag = readFragment_(type_group.getDataSet(fragment_name, fragmentAProps_));
315  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ END";
316 
317  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Adding Fragment to output";
318  if (!output.count(frag->type()))
319  {
320  output[frag->type()].reset(new artdaq::Fragments());
321  }
322  output[frag->type()]->push_back(*frag.release());
323  }
324  }
325  }
326  }
327  ++eventIndex_;
328 
329  TLOG(TLVL_DEBUG)
330  << "readNextEvent END output.size() = " << output.size();
331  return output;
332 }
333 
334 std::unique_ptr<artdaq::detail::RawEventHeader> artdaq::hdf5::HighFiveGeoCmpltPDSPSample::getEventHeader(artdaq::Fragment::sequence_id_t const& seqID)
335 {
336  TLOG(TLVL_TRACE) << "GetEventHeader BEGIN seqID=" << seqID;
337  if (!file_->exist(std::to_string(seqID)))
338  {
339  TLOG(TLVL_ERROR) << "Sequence ID " << seqID << " not found in input file!";
340  return nullptr;
341  }
342  auto seqIDGroup = file_->getGroup(std::to_string(seqID));
343 
344  uint32_t runID, subrunID, eventID;
345  uint64_t timestamp;
346  seqIDGroup.getAttribute("run_id").read(runID);
347  seqIDGroup.getAttribute("subrun_id").read(subrunID);
348  seqIDGroup.getAttribute("event_id").read(eventID);
349  seqIDGroup.getAttribute("timestamp").read(timestamp);
350 
351  TLOG(TLVL_GETEVENTHEADER) << "Creating EventHeader with runID " << runID << ", subrunID " << subrunID << ", eventID " << eventID << ", timestamp " << timestamp << " (seqID " << seqID << ")";
352  artdaq::detail::RawEventHeader hdr(runID, subrunID, eventID, seqID, timestamp);
353  seqIDGroup.getAttribute("is_complete").read(hdr.is_complete);
354 
355  TLOG(TLVL_TRACE) << "GetEventHeader END";
356  return std::make_unique<artdaq::detail::RawEventHeader>(hdr);
357 }
358 
359 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::writeFragment_(HighFive::Group& group, artdaq::Fragment const& frag)
360 {
361  TLOG(TLVL_TRACE) << "writeFragment_ BEGIN";
362 
363  std::string datasetNameBase = "TimeSlice";
364  std::string datasetName = "TimeSlice0";
365  int apaNumber = -1;
366 
367  switch (frag.type())
368  {
369  case 2: // TPC
370  apaNumber = 3;
371  datasetNameBase = "APA3." + std::to_string( (int) (frag.fragmentID() % 10) );
372  datasetName = datasetNameBase;
373  break;
374  case 3: // Photon
375  apaNumber = (int) (frag.fragmentID() / 10);
376  datasetNameBase = "APA" + std::to_string(apaNumber) + "." + std::to_string( -1 + (int) (frag.fragmentID() % 10) );
377  datasetName = datasetNameBase;
378  break;
379  case 5: // Timing
380  datasetNameBase = "Timing";
381  datasetName = datasetNameBase;
382  break;
383  case 8: // FELIX
384  apaNumber = ((int) (frag.fragmentID() / 10)) % 10;
385  if (apaNumber == 3) {apaNumber = 2;}
386  datasetNameBase = "APA" + std::to_string(apaNumber) + "." + std::to_string( (int) (frag.fragmentID() % 10) );
387  datasetName = datasetNameBase;
388  break;
389  }
390 
391  if (apaNumber != apaOfInterest) {return;}
392 
393  int counter = 1;
394  while (group.exist(datasetName))
395  {
396  //TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Duplicate Fragment ID " << frag.fragmentID() << " detected. If this is a ContainerFragment, this is expected, otherwise check configuration!";
397  datasetName = datasetNameBase + std::to_string(counter);
398  counter++;
399  }
400 
401  TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Creating DataSpace";
402  HighFive::DataSpace fragmentSpace = HighFive::DataSpace({frag.size() - frag.headerSizeWords(), 1});
403  auto fragDset = group.createDataSet<RawDataType>(datasetName, fragmentSpace, fragmentCProps_, fragmentAProps_);
404 
405  TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Creating Attributes from Fragment Header";
406  auto fragHdr = frag.fragmentHeader();
407  fragDset.createAttribute("word_count", fragHdr.word_count);
408  fragDset.createAttribute("fragment_data_size", frag.size() - frag.headerSizeWords());
409  fragDset.createAttribute("version", fragHdr.version);
410  fragDset.createAttribute("type", fragHdr.type);
411  fragDset.createAttribute("metadata_word_count", fragHdr.metadata_word_count);
412 
413  fragDset.createAttribute("sequence_id", fragHdr.sequence_id);
414  fragDset.createAttribute("fragment_id", fragHdr.fragment_id);
415 
416  fragDset.createAttribute("timestamp", fragHdr.timestamp);
417 
418  fragDset.createAttribute("valid", fragHdr.valid);
419  fragDset.createAttribute("complete", fragHdr.complete);
420  //fragDset.createAttribute("atime_ns", fragHdr.atime_ns);
421  //fragDset.createAttribute("atime_s", fragHdr.atime_s);
422 
423  double duneTime = fragHdr.timestamp * 0.000000020;
424  timespec tsp;
425  tsp.tv_sec = (time_t) duneTime;
426  tsp.tv_nsec = (long) ((duneTime - tsp.tv_sec) * 1000000000.0);
427  std::string timeString = artdaq::TimeUtils::convertUnixTimeToString(tsp);
428  fragDset.createAttribute("time_string", timeString);
429 
430  TLOG(TLVL_WRITEFRAGMENT_V) << "writeFragment_: Writing Fragment payload START";
431  fragDset.write(frag.headerBegin() + frag.headerSizeWords());
432  TLOG(TLVL_WRITEFRAGMENT_V) << "writeFragment_: Writing Fragment payload DONE";
433  TLOG(TLVL_TRACE) << "writeFragment_ END";
434 }
435 
436 artdaq::FragmentPtr artdaq::hdf5::HighFiveGeoCmpltPDSPSample::readFragment_(HighFive::DataSet const& dataset)
437 {
438  TLOG(TLVL_TRACE) << "readFragment_ BEGIN";
439  size_t fragSize;
440  dataset.getAttribute("fragment_data_size").read(fragSize);
441  TLOG(TLVL_READFRAGMENT) << "readFragment_: Fragment size " << fragSize << ", dataset size " << dataset.getDimensions()[0];
442 
443  artdaq::FragmentPtr frag(new Fragment(fragSize));
444 
445  artdaq::Fragment::type_t type;
446  size_t metadata_size;
447  artdaq::Fragment::sequence_id_t seqID;
448  artdaq::Fragment::fragment_id_t fragID;
449  artdaq::Fragment::timestamp_t timestamp;
450  int valid, complete, atime_ns, atime_s;
451 
452  TLOG(TLVL_READFRAGMENT) << "readFragment_: Reading Fragment header fields from dataset attributes";
453  dataset.getAttribute("type").read(type);
454  dataset.getAttribute("metadata_word_count").read(metadata_size);
455 
456  dataset.getAttribute("sequence_id").read(seqID);
457  dataset.getAttribute("fragment_id").read(fragID);
458 
459  dataset.getAttribute("timestamp").read(timestamp);
460 
461  dataset.getAttribute("valid").read(valid);
462  dataset.getAttribute("complete").read(complete);
463  dataset.getAttribute("atime_ns").read(atime_ns);
464  dataset.getAttribute("atime_s").read(atime_s);
465 
466  auto fragHdr = frag->fragmentHeader();
467  fragHdr.type = type;
468  fragHdr.metadata_word_count = metadata_size;
469 
470  fragHdr.sequence_id = seqID;
471  fragHdr.fragment_id = fragID;
472 
473  fragHdr.timestamp = timestamp;
474 
475  fragHdr.valid = valid;
476  fragHdr.complete = complete;
477  fragHdr.atime_ns = atime_ns;
478  fragHdr.atime_s = atime_s;
479 
480  TLOG(TLVL_READFRAGMENT) << "readFragment_: Copying header into Fragment";
481  memcpy(frag->headerAddress(), &fragHdr, sizeof(fragHdr));
482 
483  TLOG(TLVL_READFRAGMENT_V) << "readFragment_: Reading payload data into Fragment BEGIN";
484  dataset.read(frag->headerAddress() + frag->headerSizeWords());
485  TLOG(TLVL_READFRAGMENT_V) << "readFragment_: Reading payload data into Fragment END";
486 
487  TLOG(TLVL_TRACE) << "readFragment_ END";
488  return frag;
489 }
490 
491 // fragment_type_map: [[1, "MISSED"], [2, "TPC"], [3, "PHOTON"], [4, "TRIGGER"], [5, "TIMING"], [6, "TOY1"], [7, "TOY2"], [8, "FELIX"], [9, "CRT"], [10, "CTB"], [11, "CPUHITS"], [12, "DEVBOARDHITS"], [13, "UNKNOWN"]]
492 
493 bool artdaq::hdf5::HighFiveGeoCmpltPDSPSample::typeOfInterest(artdaq::Fragment::type_t theType)
494 {
495  for (unsigned int idx = 0; idx < typesOfInterest.size(); ++idx)
496  {
497  if (theType == typesOfInterest[idx]) {return true;}
498  }
499  return false;
500 }
501 
502 DEFINE_ARTDAQ_DATASET_PLUGIN(artdaq::hdf5::HighFiveGeoCmpltPDSPSample)
FragmentDatasetMode mode_
Mode of this FragmentDataset, either FragmentDatasetMode::Write or FragmentDatasetMode::Read.
std::unordered_map< artdaq::Fragment::type_t, std::unique_ptr< artdaq::Fragments > > readNextEvent() override
Read the next event from the Dataset (HDF5 file)
std::unique_ptr< artdaq::detail::RawEventHeader > getEventHeader(artdaq::Fragment::sequence_id_t const &seqID) override
Read a RawEventHeader from the Dataset (HDF5 file)