artdaq_demo_hdf5  v1_03_02
HDFFileOutput_module.cc
1 #define TRACE_NAME "HDFFileOutput"
2 
3 #include "artdaq-demo-hdf5/HDF5/MakeDatasetPlugin.hh"
4 
5 #include "art/Framework/Core/ModuleMacros.h"
6 #include "art/Framework/Core/OutputModule.h"
7 #include "art/Framework/IO/FileStatsCollector.h"
8 #include "art/Framework/IO/PostCloseFileRenamer.h"
9 #include "art/Framework/Principal/EventPrincipal.h"
10 #include "art/Framework/Principal/Handle.h"
11 #include "art/Framework/Principal/RunPrincipal.h"
12 #include "art/Framework/Principal/SubRunPrincipal.h"
13 #include "art/Persistency/Common/GroupQueryResult.h"
14 #include "art/Persistency/Provenance/ModuleContext.h"
15 #include "canvas/Persistency/Common/Wrapper.h"
16 #include "canvas/Utilities/DebugMacros.h"
17 #include "canvas/Utilities/Exception.h"
18 #if ART_HEX_VERSION < 0x30901
19 #include "canvas/Utilities/WrappedTypeID.h"
20 #else
21 #include "canvas/Persistency/Common/WrappedTypeID.h"
22 #endif
23 #include "fhiclcpp/ParameterSet.h"
24 
25 #include "artdaq/ArtModules/ArtdaqFragmentNamingService.h"
26 #include "artdaq/DAQdata/Globals.hh"
27 
28 #include <unistd.h>
29 #include <cstdio>
30 #include <fstream>
31 #include <iomanip>
32 #include <iostream>
33 #include <memory>
34 #include <sstream>
35 #include <string>
36 #include <vector>
37 
38 namespace art {
39 class HDFFileOutput;
40 }
41 
42 using art::HDFFileOutput;
43 using fhicl::ParameterSet;
44 
48 class art::HDFFileOutput final : public OutputModule
49 {
50 public:
62  explicit HDFFileOutput(ParameterSet const& ps);
63 
67  ~HDFFileOutput() override;
68 
69 private:
70  HDFFileOutput(HDFFileOutput const&) = delete;
71  HDFFileOutput(HDFFileOutput&&) = delete;
72  HDFFileOutput& operator=(HDFFileOutput const&) = delete;
73  HDFFileOutput& operator=(HDFFileOutput&&) = delete;
74 
75  void beginJob() override;
76 
77  void endJob() override;
78 
79  void write(EventPrincipal& /*ep*/) override;
80 
81  void writeRun(RunPrincipal& /*r*/) override{};
82  void writeSubRun(SubRunPrincipal& /*sr*/) override{};
83 
84 private:
85  std::string name_ = "HDFFileOutput";
86  art::FileStatsCollector fstats_;
87 
88  std::unique_ptr<artdaq::hdf5::FragmentDataset> ntuple_;
89 };
90 
91 art::HDFFileOutput::HDFFileOutput(ParameterSet const& ps)
92  : OutputModule(ps)
93  , fstats_{name_, processName()}
94 {
95  TLOG(TLVL_DEBUG) << "Begin: HDFFileOutput::HDFFileOutput(ParameterSet const& ps)\n";
96 
97  ntuple_ = artdaq::hdf5::MakeDatasetPlugin(ps, "dataset");
98  TLOG(TLVL_DEBUG)
99  << "End: HDFFileOutput::HDFFileOutput(ParameterSet const& ps)\n";
100 }
101 
102 art::HDFFileOutput::~HDFFileOutput() { TLOG(TLVL_DEBUG) << "Begin/End: HDFFileOutput::~HDFFileOutput()\n"; }
103 
104 void art::HDFFileOutput::beginJob()
105 {
106  TLOG(TLVL_DEBUG) << "Begin: HDFFileOutput::beginJob()\n";
107  TLOG(TLVL_DEBUG) << "End: HDFFileOutput::beginJob()\n";
108 }
109 
110 void art::HDFFileOutput::endJob()
111 {
112  TLOG(TLVL_DEBUG) << "Begin: HDFFileOutput::endJob()\n";
113  TLOG(TLVL_DEBUG) << "End: HDFFileOutput::endJob()\n";
114 }
115 
116 void art::HDFFileOutput::write(EventPrincipal& ep)
117 {
118  TLOG(TLVL_TRACE) << "Begin: HDFFileOutput::write(EventPrincipal& ep)";
119  using RawEvent = artdaq::Fragments;
120  using RawEvents = std::vector<RawEvent>;
121  using RawEventHandle = art::Handle<RawEvent>;
122  using RawEventHeaderHandle = art::Handle<artdaq::detail::RawEventHeader>;
123 
124  auto hdr_found = false;
125  auto sequence_id = artdaq::Fragment::InvalidSequenceID;
126 
127  TLOG(5) << "write: Retrieving event Fragments";
128  {
129  auto result_handles = std::vector<art::GroupQueryResult>();
130  auto const& wrapped = art::WrappedTypeID::make<RawEvent>();
131  ModuleContext const mc{moduleDescription()};
132  ProcessTag const processTag{"", mc.moduleDescription().processName()};
133 
134  result_handles = ep.getMany(mc, wrapped, art::MatchAllSelector{}, processTag);
135 
136  for (auto const& result_handle : result_handles)
137  {
138  auto const raw_event_handle = RawEventHandle(result_handle);
139 
140  if (raw_event_handle.isValid() && !raw_event_handle.product()->empty())
141  {
142  TLOG(10) << "raw_event_handle labels: branchName:" << raw_event_handle.provenance()->branchName();
143  TLOG(10) << "raw_event_handle labels: friendlyClassName:" << raw_event_handle.provenance()->friendlyClassName();
144  TLOG(10) << "raw_event_handle labels: inputTag:" << raw_event_handle.provenance()->inputTag();
145  TLOG(10) << "raw_event_handle labels: moduleLabel:" << raw_event_handle.provenance()->moduleLabel();
146  TLOG(10) << "raw_event_handle labels: processName:" << raw_event_handle.provenance()->processName();
147  sequence_id = (*raw_event_handle).front().sequenceID();
148 
149  TLOG(5) << "write: Writing to dataset";
150  ntuple_->insertMany(*raw_event_handle);
151  }
152  }
153  }
154  TLOG(5) << "write: Retrieving Event Header";
155  {
156  auto result_handles = std::vector<art::GroupQueryResult>();
157  auto const& wrapped = art::WrappedTypeID::make<artdaq::detail::RawEventHeader>();
158 
159  ModuleContext const mc{moduleDescription()};
160  ProcessTag const processTag{"", mc.moduleDescription().processName()};
161 
162  result_handles = ep.getMany(mc, wrapped, art::MatchAllSelector{}, processTag);
163 
164  for (auto const& result_handle : result_handles)
165  {
166  auto const raw_event_header_handle = RawEventHeaderHandle(result_handle);
167 
168  if (raw_event_header_handle.isValid())
169  {
170  auto const& header = *raw_event_header_handle;
171 
172  auto evt_sequence_id = header.sequence_id;
173  TLOG(TLVL_TRACE) << "HDFFileOutput::write header seq=" << evt_sequence_id;
174 
175  ntuple_->insertHeader(header);
176 
177  hdr_found = true;
178  TLOG(5) << "HDFFileOutput::write header seq=" << evt_sequence_id << " done errno=" << errno;
179  }
180  }
181  }
182  if (!hdr_found)
183  {
184  TLOG(5) << "write: Header not found, autogenerating";
185  artdaq::detail::RawEventHeader hdr(ep.run(), ep.subRun(), ep.event(), sequence_id, 0);
186  hdr.is_complete = true;
187 
188  ntuple_->insertHeader(hdr);
189  }
190 
191  fstats_.recordEvent(ep.eventID());
192 
193  TLOG(TLVL_TRACE) << "End: HDFFileOUtput::write(EventPrincipal& ep)";
194 }
195 
196 DEFINE_ART_MODULE(art::HDFFileOutput) // NOLINT(performance-unnecessary-value-param)
The HDFFileOutput module streams art Events to a binary file, bypassing ROOT.
~HDFFileOutput() override
HDFFileOutput Destructor.
HDFFileOutput(ParameterSet const &ps)
HDFFileOutput Constructor.