artdaq_demo_hdf5  v1_01_05
highFiveTimeBasedPDSPSample_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-core/Utilities/TimeUtils.hh"
16 #include "artdaq-demo-hdf5/HDF5/FragmentDataset.hh"
17 #include "artdaq-demo-hdf5/HDF5/highFive/HighFive/include/highfive/H5File.hpp"
18 
19 namespace artdaq {
20 namespace hdf5 {
24 class HighFiveGeoCmpltPDSPSample : public FragmentDataset
25 {
26 public:
31  HighFiveGeoCmpltPDSPSample(fhicl::ParameterSet const& ps);
36 
41  void insertOne(artdaq::Fragment const& frag) override;
46  void insertMany(artdaq::Fragments const& frags) override;
51  void insertHeader(artdaq::detail::RawEventHeader const& hdr) override;
56  std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> readNextEvent() override;
62  std::unique_ptr<artdaq::detail::RawEventHeader> getEventHeader(artdaq::Fragment::sequence_id_t const& seqID) override;
63 
64 private:
65  std::unique_ptr<HighFive::File> file_;
66  size_t eventIndex_;
67  HighFive::DataSetCreateProps fragmentCProps_;
68  HighFive::DataSetAccessProps fragmentAProps_;
69 
70  void writeFragment_(HighFive::Group& group, artdaq::Fragment const& frag);
71  artdaq::FragmentPtr readFragment_(HighFive::DataSet const& dataset);
72 
73  uint64_t windowOfInterestStart;
74  uint64_t windowOfInterestSize;
75  uint64_t outputTimeStampDelta;
76  uint64_t overallFirstFrameTimeStamp;
77  uint64_t overallLastFrameTimeStamp;
78 };
79 
80 std::string createTimeString(const uint64_t& timeValue);
81 
82 } // namespace hdf5
83 } // namespace artdaq
84 
86  : FragmentDataset(ps, ps.get<std::string>("mode", "write")), file_(nullptr), eventIndex_(0)
87 {
88  TLOG(TLVL_DEBUG) << "HighFiveGeoCmpltPDSPSample CONSTRUCTOR BEGIN";
89  if (mode_ == FragmentDatasetMode::Read)
90  {
91  file_.reset(new HighFive::File(ps.get<std::string>("fileName"), HighFive::File::ReadOnly));
92  }
93  else
94  {
95  file_.reset(new HighFive::File(ps.get<std::string>("fileName"), HighFive::File::OpenOrCreate | HighFive::File::Truncate));
96  }
97 
98  windowOfInterestStart = ps.get<uint64_t>("windowOfInterestStart");
99  windowOfInterestSize = ps.get<uint64_t>("windowOfInterestSize", 50000);
100  outputTimeStampDelta = ps.get<uint64_t>("outputTimeStampDelta", 0);
101 
102  overallFirstFrameTimeStamp = 0x0fffffffffffffff;
103  overallLastFrameTimeStamp = 0;
104 
105  TLOG(TLVL_DEBUG) << "HighFiveGeoCmpltPDSPSample CONSTRUCTOR END";
106 }
107 
109 {
110  TLOG(TLVL_DEBUG) << "~HighFiveGeoCmpltPDSPSample Begin/End ";
111  // file_->flush();
112 }
113 
114 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::insertOne(artdaq::Fragment const& frag)
115 {
116  TLOG(TLVL_TRACE) << "insertOne BEGIN";
117  uint64_t timeSliceGroupTimeStamp = windowOfInterestStart - outputTimeStampDelta;
118  if (!file_->exist(std::to_string(timeSliceGroupTimeStamp)))
119  {
120  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for windowOfInterest " << timeSliceGroupTimeStamp;
121  file_->createGroup(std::to_string(timeSliceGroupTimeStamp));
122  }
123  auto timeSliceGroup = file_->getGroup(std::to_string(timeSliceGroupTimeStamp));
124 
125  // 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"]]
126 
127  if (frag.type() == Fragment::ContainerFragmentType)
128  {
129  TLOG(TLVL_INSERTONE) << "insertOne: Processing ContainerFragment";
130  ContainerFragment cf(frag);
131 
132  if (cf.fragment_type() == 8)
133  {
134  if (cf.fragment_type() != 10 && (cf.block_count() > 1 || cf.fragment_type() == 9))
135  {
136  TLOG(TLVL_INSERTONE) << "insertOne: Getting Fragment type name";
137  auto fragPtr = cf.at(0);
138  auto typeName = nameHelper_->GetInstanceNameForFragment(*fragPtr).second;
139  if (!timeSliceGroup.exist(typeName))
140  {
141  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
142  timeSliceGroup.createGroup(typeName);
143  }
144 
145  TLOG(TLVL_INSERTONE) << "insertOne: Creating group and setting attributes";
146  auto typeGroup = timeSliceGroup.getGroup(typeName);
147  std::string containerName = "Container0";
148 
149  int counter = 1;
150  while (typeGroup.exist(containerName))
151  {
152  //TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Duplicate Fragment ID " << frag.fragmentID() << " detected. If this is a ContainerFragment, this is expected, otherwise check configuration!";
153  containerName = "Container" + std::to_string(counter);
154  counter++;
155  }
156 
157  auto containerGroup = typeGroup.createGroup(containerName);
158  containerGroup.createAttribute("version", frag.version());
159  containerGroup.createAttribute("type", frag.type());
160  containerGroup.createAttribute("sequence_id", frag.sequenceID());
161  containerGroup.createAttribute("fragment_id", frag.fragmentID());
162  containerGroup.createAttribute("timestamp", frag.timestamp());
163 
164  containerGroup.createAttribute("container_block_count", cf.block_count());
165  containerGroup.createAttribute("container_fragment_type", cf.fragment_type());
166  containerGroup.createAttribute("container_version", cf.metadata()->version);
167  containerGroup.createAttribute("container_missing_data", cf.missing_data());
168 
169  TLOG(TLVL_INSERTONE) << "insertOne: Writing Container contained Fragments";
170  for (size_t ii = 0; ii < cf.block_count(); ++ii)
171  {
172  if (ii != 0)
173  {
174  fragPtr = cf.at(ii);
175  }
176  writeFragment_(containerGroup, *fragPtr);
177  }
178  }
179  else if (cf.block_count() == 1 || cf.fragment_type() == 10)
180  {
181  TLOG(TLVL_INSERTONE) << "insertOne: Getting Fragment type name";
182  auto fragPtr = cf.at(0);
183  auto typeName = nameHelper_->GetInstanceNameForFragment(*fragPtr).second;
184  if (!timeSliceGroup.exist(typeName))
185  {
186  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
187  timeSliceGroup.createGroup(typeName);
188  }
189 
190  TLOG(TLVL_INSERTONE) << "insertOne: Creating type group";
191  auto typeGroup = timeSliceGroup.getGroup(typeName);
192  for (size_t ii = 0; ii < cf.block_count(); ++ii)
193  {
194  if (ii != 0)
195  {
196  fragPtr = cf.at(ii);
197  }
198  writeFragment_(typeGroup, *fragPtr);
199  }
200  }
201 #if 0
202  else
203  {
204  TLOG(TLVL_INSERTONE) << "insertOne: Writing Empty Container Fragment as standard Fragment";
205  auto typeName = nameHelper_->GetInstanceNameForFragment(frag).second;
206  if (!timeSliceGroup.exist(typeName))
207  {
208  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
209  timeSliceGroup.createGroup(typeName);
210  }
211  auto typeGroup = timeSliceGroup.getGroup(typeName);
212 
213  writeFragment_(typeGroup, frag);
214  }
215 #endif
216  }
217  }
218  else if (frag.type() == 5) // Timing
219  {
220  //TLOG(TLVL_INSERTONE) << "insertOne: Writing Timing Fragment";
221  //writeFragment_(timeSliceGroup, frag);
222  }
223  else
224  {
225  TLOG(TLVL_INSERTONE) << "insertOne: Writing non-Container Fragment";
226  auto typeName = nameHelper_->GetInstanceNameForFragment(frag).second;
227  if (!timeSliceGroup.exist(typeName))
228  {
229  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for type " << typeName;
230  timeSliceGroup.createGroup(typeName);
231  }
232  auto typeGroup = timeSliceGroup.getGroup(typeName);
233 
234  writeFragment_(typeGroup, frag);
235  }
236  TLOG(TLVL_TRACE) << "insertOne END";
237 }
238 
239 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::insertMany(artdaq::Fragments const& fs)
240 {
241  TLOG(TLVL_TRACE) << "insertMany BEGIN";
242 
243  for (auto& f : fs) insertOne(f);
244  TLOG(TLVL_TRACE) << "insertMany END";
245 }
246 
247 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::insertHeader(artdaq::detail::RawEventHeader const& hdr)
248 {
249  TLOG(TLVL_TRACE) << "insertHeader BEGIN";
250  uint64_t timeSliceGroupTimeStamp = windowOfInterestStart - outputTimeStampDelta;
251  if (!file_->exist(std::to_string(timeSliceGroupTimeStamp)))
252  {
253  TLOG(TLVL_INSERTONE) << "insertOne: Creating group for windowOfInterest " << timeSliceGroupTimeStamp;
254  file_->createGroup(std::to_string(timeSliceGroupTimeStamp));
255  }
256  auto timeSliceGroup = file_->getGroup(std::to_string(timeSliceGroupTimeStamp));
257  timeSliceGroup.createAttribute("run_id", hdr.run_id);
258  //timeSliceGroup.createAttribute("subrun_id", hdr.subrun_id);
259  //timeSliceGroup.createAttribute("event_id", hdr.event_id);
260  timeSliceGroup.createAttribute("source_event_id", hdr.event_id);
261 
262  timeSliceGroup.createAttribute("time_slice_start", timeSliceGroupTimeStamp);
263  timeSliceGroup.createAttribute("start_time_string", createTimeString(timeSliceGroupTimeStamp));
264 
265  uint64_t timeSliceGroupEnd = timeSliceGroupTimeStamp + windowOfInterestSize;
266  timeSliceGroup.createAttribute("time_slice_end", timeSliceGroupEnd);
267  timeSliceGroup.createAttribute("end_time_string", createTimeString(timeSliceGroupEnd));
268  TLOG(TLVL_DEBUG) << "overallFrameTimeStamps " << std::hex << overallFirstFrameTimeStamp << " and " << overallLastFrameTimeStamp << std::dec;
269  timeSliceGroup.createAttribute("first_frame_timestamp", overallFirstFrameTimeStamp);
270  timeSliceGroup.createAttribute("last_frame_timestamp", overallLastFrameTimeStamp);
271  timeSliceGroup.createAttribute("is_complete", 0);
272 
273  TLOG(TLVL_TRACE) << "insertHeader END";
274 }
275 
276 std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> artdaq::hdf5::HighFiveGeoCmpltPDSPSample::readNextEvent()
277 {
278  TLOG(TLVL_DEBUG) << "readNextEvent BEGIN";
279  std::unordered_map<artdaq::Fragment::type_t, std::unique_ptr<artdaq::Fragments>> output;
280 
281  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Finding next event group in file";
282  auto groupNames = file_->listObjectNames();
283  while (eventIndex_ < groupNames.size() && file_->getObjectType(groupNames[eventIndex_]) != HighFive::ObjectType::Group)
284  {
285  eventIndex_++;
286  }
287 
288  if (groupNames.size() <= eventIndex_)
289  {
290  TLOG(TLVL_INFO) << "readNextEvent: No more events in file!";
291  }
292  else
293  {
294  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Getting event group " << groupNames[eventIndex_];
295  auto event_group = file_->getGroup(groupNames[eventIndex_]);
296  auto fragment_type_names = event_group.listObjectNames();
297 
298  for (auto& fragment_type : fragment_type_names)
299  {
300  if (event_group.getObjectType(fragment_type) != HighFive::ObjectType::Group)
301  {
302  continue;
303  }
304  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Reading Fragment type " << fragment_type;
305  auto type_group = event_group.getGroup(fragment_type);
306  auto fragment_names = type_group.listObjectNames();
307 
308  for (auto& fragment_name : fragment_names)
309  {
310  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Reading Fragment " << fragment_name;
311  auto node_type = type_group.getObjectType(fragment_name);
312  if (node_type == HighFive::ObjectType::Group)
313  {
314  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Fragment " << fragment_name << " is a Container";
315  auto container_group = type_group.getGroup(fragment_name);
316  Fragment::type_t type;
317  container_group.getAttribute("type").read<Fragment::type_t>(type);
318  Fragment::sequence_id_t seqID;
319  container_group.getAttribute("sequence_id").read(seqID);
320  Fragment::timestamp_t timestamp;
321  container_group.getAttribute("timestamp").read(timestamp);
322  Fragment::fragment_id_t fragID;
323  container_group.getAttribute("fragment_id").read(fragID);
324  if (!output.count(type))
325  {
326  output[type].reset(new Fragments());
327  }
328  output[type]->emplace_back(seqID, fragID);
329  output[type]->back().setTimestamp(timestamp);
330  output[type]->back().setSystemType(type);
331 
332  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Creating ContainerFragmentLoader for reading Container Fragments";
333  ContainerFragmentLoader cfl(output[type]->back());
334 
335  Fragment::type_t container_fragment_type;
336  int missing_data;
337  container_group.getAttribute("container_fragment_type").read(container_fragment_type);
338  container_group.getAttribute("container_missing_data").read(missing_data);
339 
340  cfl.set_fragment_type(container_fragment_type);
341  cfl.set_missing_data(missing_data);
342 
343  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Reading ContainerFragment Fragments";
344  auto fragments = container_group.listObjectNames();
345  for (auto& fragname : fragments)
346  {
347  if (container_group.getObjectType(fragname) != HighFive::ObjectType::Dataset) continue;
348  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ BEGIN";
349  auto frag = readFragment_(container_group.getDataSet(fragname, fragmentAProps_));
350  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ END";
351 
352  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling addFragment BEGIN";
353  cfl.addFragment(frag);
354  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: addFragment END";
355  }
356  }
357  else if (node_type == HighFive::ObjectType::Dataset)
358  {
359  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ BEGIN";
360  auto frag = readFragment_(type_group.getDataSet(fragment_name, fragmentAProps_));
361  TLOG(TLVL_READNEXTEVENT_V) << "readNextEvent: Calling readFragment_ END";
362 
363  TLOG(TLVL_READNEXTEVENT) << "readNextEvent: Adding Fragment to output";
364  if (!output.count(frag->type()))
365  {
366  output[frag->type()].reset(new artdaq::Fragments());
367  }
368  output[frag->type()]->push_back(*frag.release());
369  }
370  }
371  }
372  }
373  ++eventIndex_;
374 
375  TLOG(TLVL_DEBUG)
376  << "readNextEvent END output.size() = " << output.size();
377  return output;
378 }
379 
380 std::unique_ptr<artdaq::detail::RawEventHeader> artdaq::hdf5::HighFiveGeoCmpltPDSPSample::getEventHeader(artdaq::Fragment::sequence_id_t const& seqID)
381 {
382  TLOG(TLVL_TRACE) << "GetEventHeader BEGIN seqID=" << seqID;
383  if (!file_->exist(std::to_string(seqID)))
384  {
385  TLOG(TLVL_ERROR) << "Sequence ID " << seqID << " not found in input file!";
386  return nullptr;
387  }
388  auto seqIDGroup = file_->getGroup(std::to_string(seqID));
389 
390  uint32_t runID, subrunID, eventID;
391  uint64_t timestamp;
392  seqIDGroup.getAttribute("run_id").read(runID);
393  seqIDGroup.getAttribute("subrun_id").read(subrunID);
394  seqIDGroup.getAttribute("event_id").read(eventID);
395  seqIDGroup.getAttribute("timestamp").read(timestamp);
396 
397  TLOG(TLVL_GETEVENTHEADER) << "Creating EventHeader with runID " << runID << ", subrunID " << subrunID << ", eventID " << eventID << ", timestamp " << timestamp << " (seqID " << seqID << ")";
398  artdaq::detail::RawEventHeader hdr(runID, subrunID, eventID, seqID, timestamp);
399  seqIDGroup.getAttribute("is_complete").read(hdr.is_complete);
400 
401  TLOG(TLVL_TRACE) << "GetEventHeader END";
402  return std::make_unique<artdaq::detail::RawEventHeader>(hdr);
403 }
404 
405 void artdaq::hdf5::HighFiveGeoCmpltPDSPSample::writeFragment_(HighFive::Group& group, artdaq::Fragment const& frag)
406 {
407  TLOG(TLVL_TRACE) << "writeFragment_ BEGIN";
408 
409  uint64_t windowOfInterestEnd = windowOfInterestStart + windowOfInterestSize;
410  int firstFrameOfInterest = -1;
411  int lastFrameOfInterest = -1;
412  uint64_t firstFrameTimeStamp = 0;
413  uint64_t lastFrameTimeStamp = 0;
414 
415  std::string datasetNameBase = "TimeSlice";
416  std::string datasetName = "TimeSlice0";
417 
418  switch (frag.type())
419  {
420  case 2: // TPC
421  datasetNameBase = "APA3." + std::to_string((int)(frag.fragmentID() % 10));
422  datasetName = datasetNameBase;
423  break;
424  case 3: // Photon
425  datasetNameBase = "APA" + std::to_string((int)(frag.fragmentID() / 10)) + "." + std::to_string(-1 + (int)(frag.fragmentID() % 10));
426  datasetName = datasetNameBase;
427  break;
428  case 5: // Timing
429  datasetNameBase = "Timing";
430  datasetName = datasetNameBase;
431  break;
432  case 8: // FELIX
433  int apaNumber = ((int)(frag.fragmentID() / 10)) % 10;
434  if (apaNumber == 3) { apaNumber = 2; }
435  datasetNameBase = "APA" + std::to_string(apaNumber) + "." + std::to_string((int)(frag.fragmentID() % 10));
436  datasetName = datasetNameBase;
437  TLOG(TLVL_DEBUG) << "Dataset Name: " << datasetName << ", fragment size=" << frag.size();
438 
439  const uint8_t* tmpBeginPtr = frag.dataBeginBytes();
440  const uint8_t* tmpEndPtr = frag.dataEndBytes();
441  const uint64_t* beginPtr = reinterpret_cast<const uint64_t*>(tmpBeginPtr);
442  const uint64_t* endPtr = reinterpret_cast<const uint64_t*>(tmpEndPtr);
443  TLOG(TLVL_DEBUG) << "Data addresses in hex: " << std::hex << tmpBeginPtr << ", " << tmpEndPtr << ", " << beginPtr << ", " << endPtr << std::dec;
444 
445  uint64_t* mdPtr = reinterpret_cast<uint64_t*>(const_cast<uint8_t*>(frag.headerBeginBytes()) + frag.headerSizeBytes());
446  TLOG(TLVL_DEBUG) << "Metadata address and data: " << std::hex << mdPtr << ", " << *mdPtr << std::dec;
447  ++mdPtr;
448  TLOG(TLVL_DEBUG) << "Metadata address and data: " << std::hex << mdPtr << ", " << *mdPtr << std::dec;
449 
450  if (frag.size() == 349397)
451  {
452  uint64_t* dataPtr = const_cast<uint64_t*>(beginPtr);
453  ++dataPtr;
454  for (int idx = 0; idx < 20; ++idx)
455  {
456  TLOG(TLVL_DEBUG) << std::hex << *dataPtr << std::dec;
457  TLOG(TLVL_DEBUG) << "Frame time is " << createTimeString(*dataPtr);
458  dataPtr += 58;
459  }
460  dataPtr += 347072;
461  while (dataPtr <= endPtr)
462  {
463  TLOG(TLVL_DEBUG) << std::hex << *dataPtr << std::dec;
464  TLOG(TLVL_DEBUG) << "Frame time is " << createTimeString(*dataPtr);
465  dataPtr += 58;
466  }
467 
468  dataPtr = const_cast<uint64_t*>(beginPtr);
469  ++dataPtr;
470  int loopCounter = 0;
471  while (dataPtr <= endPtr)
472  {
473  if (firstFrameOfInterest == -1 && (*dataPtr) >= windowOfInterestStart)
474  {
475  firstFrameOfInterest = loopCounter;
476  firstFrameTimeStamp = *dataPtr;
477  if (firstFrameTimeStamp < overallFirstFrameTimeStamp)
478  {
479  overallFirstFrameTimeStamp = firstFrameTimeStamp;
480  }
481  }
482 
483  if (firstFrameOfInterest >= 0 && lastFrameOfInterest == -1 && (*dataPtr) >= windowOfInterestEnd)
484  {
485  lastFrameOfInterest = loopCounter - 1;
486  }
487 
488  if (firstFrameOfInterest >= 0 && lastFrameOfInterest >= 0)
489  {
490  break;
491  }
492 
493  lastFrameTimeStamp = *dataPtr;
494  ++loopCounter;
495  dataPtr += 58;
496  }
497  if (lastFrameOfInterest == -1) { lastFrameOfInterest = loopCounter - 1; }
498  TLOG(TLVL_DEBUG) << "lastFrameTimeStamps (1) " << std::hex << lastFrameTimeStamp << " and " << overallLastFrameTimeStamp << std::dec;
499  if (lastFrameTimeStamp > overallLastFrameTimeStamp)
500  {
501  overallLastFrameTimeStamp = lastFrameTimeStamp;
502  }
503  TLOG(TLVL_DEBUG) << "lastFrameTimeStamps (2) " << std::hex << lastFrameTimeStamp << " and " << overallLastFrameTimeStamp << std::dec;
504  TLOG(TLVL_DEBUG) << "first and last frames of interest are " << firstFrameOfInterest << " and " << lastFrameOfInterest;
505  TLOG(TLVL_DEBUG) << "first and last frame timestamps are " << std::hex << firstFrameTimeStamp << " and " << lastFrameTimeStamp << std::dec;
506  }
507  else
508  {
509  TLOG(TLVL_DEBUG) << "Skipping Dataset: " << datasetName << ", fragment size=" << frag.size();
510  }
511 
512  break;
513  }
514 
515  if (firstFrameOfInterest == -1 || lastFrameOfInterest == -1) { return; }
516  int numberOfFrames = lastFrameOfInterest - firstFrameOfInterest + 1;
517 
518  int counter = 1;
519  while (group.exist(datasetName))
520  {
521  //TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Duplicate Fragment ID " << frag.fragmentID() << " detected. If this is a ContainerFragment, this is expected, otherwise check configuration!";
522  datasetName = datasetNameBase + std::to_string(counter);
523  counter++;
524  }
525 
526  TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Creating DataSpace";
527  HighFive::DataSpace fragmentSpace = HighFive::DataSpace({((uint32_t)(numberOfFrames * 58)), 1});
528  auto fragDset = group.createDataSet<RawDataType>(datasetName, fragmentSpace, fragmentCProps_, fragmentAProps_);
529 
530  TLOG(TLVL_WRITEFRAGMENT) << "writeFragment_: Creating Attributes from Fragment Header";
531  auto fragHdr = frag.fragmentHeader();
532  //fragDset.createAttribute("word_count", fragHdr.word_count);
533  //fragDset.createAttribute("fragment_data_size", frag.size() - frag.headerSizeWords());
534  //fragDset.createAttribute("version", fragHdr.version);
535  fragDset.createAttribute("fragment_type", fragHdr.type);
536  //fragDset.createAttribute("metadata_word_count", fragHdr.metadata_word_count);
537 
538  fragDset.createAttribute("number_of_frames", numberOfFrames);
539  fragDset.createAttribute("size_in_bytes", (numberOfFrames * 58));
540 
541  //fragDset.createAttribute("fragment_id", fragHdr.fragment_id);
542 
543  //fragDset.createAttribute("timestamp", fragHdr.timestamp);
544 
545  //fragDset.createAttribute("valid", fragHdr.valid);
546  //fragDset.createAttribute("complete", fragHdr.complete);
547  //fragDset.createAttribute("atime_ns", fragHdr.atime_ns);
548  //fragDset.createAttribute("atime_s", fragHdr.atime_s);
549 
550  fragDset.createAttribute("first_frame_timestamp", firstFrameTimeStamp);
551  fragDset.createAttribute("first_frame_time_string", createTimeString(firstFrameTimeStamp));
552  fragDset.createAttribute("last_frame_timestamp", lastFrameTimeStamp);
553  fragDset.createAttribute("last_frame_time_string", createTimeString(lastFrameTimeStamp));
554 
555  const uint8_t* tmpBeginPtr = frag.dataBeginBytes();
556  const uint64_t* beginPtr = reinterpret_cast<const uint64_t*>(tmpBeginPtr);
557 
558  TLOG(TLVL_WRITEFRAGMENT_V) << "writeFragment_: Writing Fragment payload START";
559  fragDset.write(beginPtr + (firstFrameOfInterest * 58));
560  TLOG(TLVL_WRITEFRAGMENT_V) << "writeFragment_: Writing Fragment payload DONE";
561  TLOG(TLVL_TRACE) << "writeFragment_ END";
562 }
563 
564 artdaq::FragmentPtr artdaq::hdf5::HighFiveGeoCmpltPDSPSample::readFragment_(HighFive::DataSet const& dataset)
565 {
566  TLOG(TLVL_TRACE) << "readFragment_ BEGIN";
567  size_t fragSize;
568  dataset.getAttribute("fragment_data_size").read(fragSize);
569  TLOG(TLVL_READFRAGMENT) << "readFragment_: Fragment size " << fragSize << ", dataset size " << dataset.getDimensions()[0];
570 
571  artdaq::FragmentPtr frag(new Fragment(fragSize));
572 
573  artdaq::Fragment::type_t type;
574  size_t metadata_size;
575  artdaq::Fragment::sequence_id_t seqID;
576  artdaq::Fragment::fragment_id_t fragID;
577  artdaq::Fragment::timestamp_t timestamp;
578  int valid, complete, atime_ns, atime_s;
579 
580  TLOG(TLVL_READFRAGMENT) << "readFragment_: Reading Fragment header fields from dataset attributes";
581  dataset.getAttribute("type").read(type);
582  dataset.getAttribute("metadata_word_count").read(metadata_size);
583 
584  dataset.getAttribute("sequence_id").read(seqID);
585  dataset.getAttribute("fragment_id").read(fragID);
586 
587  dataset.getAttribute("timestamp").read(timestamp);
588 
589  dataset.getAttribute("valid").read(valid);
590  dataset.getAttribute("complete").read(complete);
591  dataset.getAttribute("atime_ns").read(atime_ns);
592  dataset.getAttribute("atime_s").read(atime_s);
593 
594  auto fragHdr = frag->fragmentHeader();
595  fragHdr.type = type;
596  fragHdr.metadata_word_count = metadata_size;
597 
598  fragHdr.sequence_id = seqID;
599  fragHdr.fragment_id = fragID;
600 
601  fragHdr.timestamp = timestamp;
602 
603  fragHdr.valid = valid;
604  fragHdr.complete = complete;
605  fragHdr.atime_ns = atime_ns;
606  fragHdr.atime_s = atime_s;
607 
608  TLOG(TLVL_READFRAGMENT) << "readFragment_: Copying header into Fragment";
609  memcpy(frag->headerAddress(), &fragHdr, sizeof(fragHdr));
610 
611  TLOG(TLVL_READFRAGMENT_V) << "readFragment_: Reading payload data into Fragment BEGIN";
612  dataset.read(frag->headerAddress() + frag->headerSizeWords());
613  TLOG(TLVL_READFRAGMENT_V) << "readFragment_: Reading payload data into Fragment END";
614 
615  TLOG(TLVL_TRACE) << "readFragment_ END";
616  return frag;
617 }
618 
619 std::string artdaq::hdf5::createTimeString(const uint64_t& timeValue)
620 {
621  timespec tsp;
622  tsp.tv_sec = (time_t)(((double)timeValue) * 0.000000020);
623  tsp.tv_nsec = (long)((timeValue % 50000000) * 20);
624  return artdaq::TimeUtils::convertUnixTimeToString(tsp);
625 }
626 
627 DEFINE_ARTDAQ_DATASET_PLUGIN(artdaq::hdf5::HighFiveGeoCmpltPDSPSample)
void insertMany(artdaq::Fragments const &frags) override
Write Fragments to HDF5.
void insertOne(artdaq::Fragment const &frag) override
Write a Fragment to HDF5.
void insertHeader(artdaq::detail::RawEventHeader const &hdr) override
Write a RawEventHeader to HDF5.
Sample ProtoDUNE HDF5 output which writes all data indexed by sequence ID.
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 event data from HDF5.
virtual ~HighFiveGeoCmpltPDSPSample()
HighFiveGeoCmpltPDSPSample Destructor.
std::unique_ptr< artdaq::detail::RawEventHeader > getEventHeader(artdaq::Fragment::sequence_id_t const &seqID) override
Read an Event Header from HDF55.
HighFiveGeoCmpltPDSPSample(fhicl::ParameterSet const &ps)
HighFiveGeoCmpltPDSPSample Constructor.