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