artdaq  v3_06_00
BinaryNetOutput_module.cc
1 #define TRACE_NAME "BinaryNetOutput"
2 #include "artdaq/DAQdata/Globals.hh"
3 
4 #include "art/Framework/Core/ModuleMacros.h"
5 #include "art/Framework/Core/OutputModule.h"
6 #include "art/Framework/Principal/EventPrincipal.h"
7 #include "art/Framework/Principal/Handle.h"
8 #include "art/Framework/Principal/RunPrincipal.h"
9 #include "art/Framework/Principal/Selector.h"
10 #include "art/Framework/Principal/SubRunPrincipal.h"
11 #include "art/Persistency/Common/GroupQueryResult.h"
12 #include "canvas/Utilities/DebugMacros.h"
13 #include "canvas/Utilities/Exception.h"
14 #include "fhiclcpp/ParameterSet.h"
15 
16 #include "artdaq-core/Data/Fragment.hh"
17 #include "artdaq/DAQrate/DataSenderManager.hh"
18 
19 #include <unistd.h>
20 #include <iomanip>
21 #include <iostream>
22 #include <memory>
23 #include <sstream>
24 #include <string>
25 #include <vector>
26 
27 namespace art {
28  class BinaryNetOutput;
29 }
30 
32 using fhicl::ParameterSet;
33 
39 class art::BinaryNetOutput final : public OutputModule {
40 public:
53  explicit BinaryNetOutput(ParameterSet const& ps);
54 
58  virtual ~BinaryNetOutput();
59 
60 private:
61  void beginJob() override;
62 
63  void endJob() override;
64 
65  void write(EventPrincipal&) override;
66 
67  void writeRun(RunPrincipal&) override {};
68  void writeSubRun(SubRunPrincipal&) override {};
69 
70  void initialize_MPI_();
71 
72  void deinitialize_MPI_();
73 
74  bool readParameterSet_(fhicl::ParameterSet const& pset);
75 
76 private:
77  ParameterSet data_pset_;
78  std::string name_ = "BinaryNetOutput";
79  int rt_priority_ = 0;
80  std::unique_ptr<artdaq::DataSenderManager> sender_ptr_ = {nullptr};
81 };
82 
83 art::BinaryNetOutput::BinaryNetOutput(ParameterSet const& ps) : OutputModule(ps) {
84  TLOG(TLVL_DEBUG) << "Begin: BinaryNetOutput::BinaryNetOutput(ParameterSet const& ps)\n";
85  readParameterSet_(ps);
86  TLOG(TLVL_DEBUG) << "End: BinaryNetOutput::BinaryNetOutput(ParameterSet const& ps)\n";
87 }
88 
89 art::BinaryNetOutput::~BinaryNetOutput() { TLOG(TLVL_DEBUG) << "Begin/End: BinaryNetOutput::~BinaryNetOutput()\n"; }
90 
91 void art::BinaryNetOutput::beginJob() {
92  TLOG(TLVL_DEBUG) << "Begin: BinaryNetOutput::beginJob()\n";
93  initialize_MPI_();
94  TLOG(TLVL_DEBUG) << "End: BinaryNetOutput::beginJob()\n";
95 }
96 
97 void art::BinaryNetOutput::endJob() {
98  TLOG(TLVL_DEBUG) << "Begin: BinaryNetOutput::endJob()\n";
99  deinitialize_MPI_();
100  TLOG(TLVL_DEBUG) << "End: BinaryNetOutput::endJob()\n";
101 }
102 
103 void art::BinaryNetOutput::initialize_MPI_() {
104  if (rt_priority_ > 0) {
105 #pragma GCC diagnostic push
106 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
107  sched_param s_param = {};
108  s_param.sched_priority = rt_priority_;
109  int status = pthread_setschedparam(pthread_self(), SCHED_RR, &s_param);
110  if (status != 0) {
111  TLOG(TLVL_ERROR) << name_ << "Failed to set realtime priority to " << rt_priority_
112  << ", return code = " << status;
113  }
114 #pragma GCC diagnostic pop
115  }
116 
117  sender_ptr_ = std::make_unique<artdaq::DataSenderManager>(data_pset_);
118  assert(sender_ptr_);
119 }
120 
121 void art::BinaryNetOutput::deinitialize_MPI_() { sender_ptr_.reset(nullptr); }
122 
123 bool art::BinaryNetOutput::readParameterSet_(fhicl::ParameterSet const& pset) {
124  TLOG(TLVL_DEBUG) << name_ << "BinaryNetOutput::readParameterSet_ method called with "
125  << "ParameterSet = \"" << pset.to_string() << "\".";
126 
127  // determine the data sending parameters
128  data_pset_ = pset;
129  name_ = pset.get<std::string>("module_name", "BinaryNetOutput");
130  rt_priority_ = pset.get<int>("rt_priority", 0);
131 
132  TLOG(TLVL_TRACE) << "BinaryNetOutput::readParameterSet()";
133 
134  return true;
135 }
136 
137 void art::BinaryNetOutput::write(EventPrincipal& ep) {
138  assert(sender_ptr_);
139 
140  using RawEvent = artdaq::Fragments;
141  ;
142  using RawEvents = std::vector<RawEvent>;
143  using RawEventHandle = art::Handle<RawEvent>;
144  using RawEventHandles = std::vector<RawEventHandle>;
145 
146  auto result_handles = std::vector<art::GroupQueryResult>();
147 
148  auto const& wrapped = art::WrappedTypeID::make<RawEvent>();
149 #if ART_HEX_VERSION >= 0x30000
150  ModuleContext const mc{moduleDescription()};
151  ProcessTag const processTag{"", mc.moduleDescription().processName()};
152 
153  result_handles = ep.getMany(mc, wrapped, art::MatchAllSelector{}, processTag);
154 #else
155  result_handles = ep.getMany(wrapped, art::MatchAllSelector{});
156 #endif
157 
158  for (auto const& result_handle : result_handles) {
159  auto const raw_event_handle = RawEventHandle(result_handle);
160 
161  if (!raw_event_handle.isValid()) continue;
162 
163  for (auto const& fragment : *raw_event_handle) {
164  auto fragment_copy = fragment;
165  auto fragid_id = fragment_copy.fragmentID();
166  auto sequence_id = fragment_copy.sequenceID();
167  TLOG(TLVL_DEBUG) << "BinaryNetOutput::write seq=" << sequence_id << " frag=" << fragid_id << " start";
168  sender_ptr_->sendFragment(std::move(fragment_copy));
169  TLOG(TLVL_DEBUG) << "BinaryNetOutput::write seq=" << sequence_id << " frag=" << fragid_id << " done";
170  // Events are unique in art, so this will be the only send with this sequence ID!
171  sender_ptr_->RemoveRoutingTableEntry(sequence_id);
172  }
173  }
174 
175  return;
176 }
177 
178 DEFINE_ART_MODULE(art::BinaryNetOutput)
BinaryNetOutput(ParameterSet const &ps)
BinaryNetOutput Constructor.
An art::OutputModule which sends Fragments using DataSenderManager. This module produces output ident...
virtual ~BinaryNetOutput()
BinaryNetOutput Destructor.