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