artdaq  v3_01_00
DispatcherCore.cc
1 #include <errno.h>
2 #include <sstream>
3 #include <iomanip>
4 #include <bitset>
5 
6 #include <boost/tokenizer.hpp>
7 #include <boost/filesystem.hpp>
8 #include <boost/algorithm/string.hpp>
9 #include <boost/exception/all.hpp>
10 #include <boost/throw_exception.hpp>
11 
12 #include "fhiclcpp/ParameterSet.h"
13 
14 #define TRACE_NAME (app_name + "_DispatcherCore").c_str() // include these 2 first -
15 #include "artdaq/DAQdata/Globals.hh"
16 
17 #include "artdaq-core/Core/SimpleMemoryReader.hh"
18 #include "artdaq-core/Data/RawEvent.hh"
19 
20 #include "artdaq/Application/DispatcherCore.hh"
21 #include "artdaq/TransferPlugins/MakeTransferPlugin.hh"
22 
23 
24 
27 {}
28 
30 {
31  TLOG(TLVL_DEBUG) << "Destructor" ;
32 }
33 
34 bool artdaq::DispatcherCore::initialize(fhicl::ParameterSet const& pset)
35 {
36  TLOG(TLVL_DEBUG) << "initialize method called with DAQ " << "ParameterSet = \"" << pset.to_string() << "\"." ;
37 
38  pset_ = pset;
39  pset_.erase("outputs");
40  pset_.erase("physics");
41  pset_.erase("daq");
42 
43  // pull out the relevant parts of the ParameterSet
44  fhicl::ParameterSet daq_pset;
45  try
46  {
47  daq_pset = pset.get<fhicl::ParameterSet>("daq");
48  }
49  catch (...)
50  {
51  TLOG(TLVL_ERROR)
52  << "Unable to find the DAQ parameters in the initialization "
53  << "ParameterSet: \"" + pset.to_string() + "\"." ;
54  return false;
55  }
56  fhicl::ParameterSet agg_pset;
57  try
58  {
59  agg_pset = daq_pset.get<fhicl::ParameterSet>("dispatcher", daq_pset.get<fhicl::ParameterSet>("aggregator"));
60  }
61  catch (...)
62  {
63  TLOG(TLVL_ERROR)
64  << "Unable to find the Dispatcher parameters in the DAQ "
65  << "initialization ParameterSet: \"" + daq_pset.to_string() + "\"." ;
66  return false;
67  }
68 
69  broadcast_mode_ = agg_pset.get<bool>("broadcast_mode", true);
70  if (broadcast_mode_ && !agg_pset.has_key("broadcast_mode"))
71  {
72  agg_pset.put<bool>("broadcast_mode", true);
73  }
74 
75  agg_pset.erase("art_analyzer_count");
76  agg_pset.put<int>("art_analyzer_count", 0);
77 
78  // initialize the MetricManager and the names of our metrics
79  fhicl::ParameterSet metric_pset;
80 
81  try
82  {
83  metric_pset = daq_pset.get<fhicl::ParameterSet>("metrics");
84  }
85  catch (...) {} // OK if there's no metrics table defined in the FHiCL
86 
87  return initializeDataReceiver(pset, agg_pset, metric_pset);
88 }
89 
90 std::string artdaq::DispatcherCore::register_monitor(fhicl::ParameterSet const& pset)
91 {
92  TLOG(TLVL_DEBUG) << "DispatcherCore::register_monitor called with argument \"" << pset.to_string() << "\"" ;
93  std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
94 
95  try
96  {
97  TLOG(TLVL_DEBUG) << "Getting unique_label from input ParameterSet" ;
98  auto label = pset.get<std::string>("unique_label");
99  TLOG(TLVL_DEBUG) << "Unique label is " << label ;
100  if (registered_monitors_.count(label))
101  {
102  throw cet::exception("DispatcherCore") << "Unique label already exists!";
103  }
104 
105  registered_monitors_[label] = pset;
106  if (event_store_ptr_ != nullptr)
107  {
108  if (broadcast_mode_) {
109  fhicl::ParameterSet ps = merge_parameter_sets_(pset_, label, pset);
110  TLOG(TLVL_DEBUG) << "Starting art process with received fhicl" ;
111  registered_monitor_pids_[label] = event_store_ptr_->StartArtProcess(ps);
112  }
113  else
114  {
115  TLOG(TLVL_DEBUG) << "Generating new fhicl and reconfiguring art" ;
116  event_store_ptr_->ReconfigureArt(generate_filter_fhicl_());
117  }
118  }
119  else
120  {
121  TLOG(TLVL_ERROR) << "Unable to add monitor as there is no SharedMemoryEventManager instance!" ;
122  }
123  }
124  catch (const cet::exception& e)
125  {
126  std::stringstream errmsg;
127  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
128  errmsg << "Exception: " << e.what();
129  TLOG(TLVL_ERROR) << errmsg.str() ;
130  return errmsg.str();
131  }
132  catch (const boost::exception& e)
133  {
134  std::stringstream errmsg;
135  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
136  errmsg << "Exception: " << boost::diagnostic_information(e);
137  TLOG(TLVL_ERROR) << errmsg.str() ;
138  return errmsg.str();
139  }
140  catch (const std::exception& e)
141  {
142  std::stringstream errmsg;
143  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
144  errmsg << "Exception: " << e.what();
145  TLOG(TLVL_ERROR) << errmsg.str() ;
146  return errmsg.str();
147  }
148  catch (...)
149  {
150  std::stringstream errmsg;
151  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered";
152  TLOG(TLVL_ERROR) << errmsg.str() ;
153  return errmsg.str();
154  }
155 
156  return "Success";
157 }
158 
159 std::string artdaq::DispatcherCore::unregister_monitor(std::string const& label)
160 {
161  TLOG(TLVL_DEBUG) << "DispatcherCore::unregister_monitor called with argument \"" << label << "\"" ;
162  std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
163 
164  try
165  {
166  if (registered_monitors_.count(label) == 0)
167  {
168  std::stringstream errmsg;
169  errmsg << "Warning in DispatcherCore::unregister_monitor: unable to find requested transfer plugin with "
170  << "label \"" << label << "\"";
171  TLOG(TLVL_WARNING) << errmsg.str() ;
172  return errmsg.str();
173  }
174 
175  registered_monitors_.erase(label);
176  if (event_store_ptr_ != nullptr)
177  {
178  if(broadcast_mode_) {
179  std::set<pid_t> pids;
180  pids.insert(registered_monitor_pids_[label]);
181  event_store_ptr_->ShutdownArtProcesses(pids);
182  registered_monitor_pids_.erase(label);
183  }
184  else
185  {
186  event_store_ptr_->ReconfigureArt(generate_filter_fhicl_());
187  }
188  }
189  }
190  catch (...)
191  {
192  std::stringstream errmsg;
193  errmsg << "Unable to unregister transfer plugin with label \"" << label << "\"";
194  return errmsg.str();
195  }
196 
197  return "Success";
198 }
199 
200 fhicl::ParameterSet artdaq::DispatcherCore::merge_parameter_sets_(fhicl::ParameterSet skel,std::string label, fhicl::ParameterSet pset)
201 {
202  fhicl::ParameterSet generated_pset = skel;
203  fhicl::ParameterSet generated_outputs;
204  fhicl::ParameterSet generated_physics;
205  fhicl::ParameterSet generated_physics_analyzers;
206  fhicl::ParameterSet generated_physics_producers;
207  fhicl::ParameterSet generated_physics_filters;
208 
209  TLOG(TLVL_DEBUG) << "merge_parameter_sets_: Generating fhicl for monitor " << label ;
210 
211  try
212  {
213  auto path = pset.get<std::vector<std::string>>("path");
214 
215  // outputs section
216  auto outputs = pset.get<fhicl::ParameterSet>("outputs");
217  if (outputs.get_pset_names().size() > 1 || outputs.get_pset_names().size() == 0)
218  {
219  // Only one output allowed per monitor
220  }
221  auto output_name = outputs.get_pset_names()[0];
222  auto output_pset = outputs.get<fhicl::ParameterSet>(output_name);
223  generated_outputs.put(label + output_name, output_pset);
224  bool outputInPath = false;
225  for (size_t ii = 0; ii < path.size(); ++ii)
226  {
227  if (path[ii] == output_name)
228  {
229  path[ii] = label + output_name;
230  outputInPath = true;
231  }
232  }
233  if (!outputInPath)
234  {
235  path.push_back(label + output_name);
236  }
237 
238  //physics section
239  auto physics_pset = pset.get<fhicl::ParameterSet>("physics");
240  if (physics_pset.has_key("analyzers"))
241  {
242  auto analyzers = physics_pset.get<fhicl::ParameterSet>("analyzers");
243  for (auto key : analyzers.get_pset_names())
244  {
245  if (generated_physics_analyzers.has_key(key) && analyzers.get<fhicl::ParameterSet>(key) == generated_physics_analyzers.get<fhicl::ParameterSet>(key))
246  {
247  // Module is already configured
248  continue;
249  }
250  else if (generated_physics_analyzers.has_key(key))
251  {
252  // Module already exists with name, rename
253  auto newkey = label + key;
254  generated_physics_analyzers.put<fhicl::ParameterSet>(newkey, analyzers.get<fhicl::ParameterSet>(key));
255  for (size_t ii = 0; ii < path.size(); ++ii)
256  {
257  if (path[ii] == key)
258  {
259  path[ii] = newkey;
260  }
261  }
262  }
263  else
264  {
265  generated_physics_analyzers.put<fhicl::ParameterSet>(key, analyzers.get<fhicl::ParameterSet>(key));
266  }
267  }
268  }
269  if (physics_pset.has_key("producers"))
270  {
271  auto producers = physics_pset.get<fhicl::ParameterSet>("producers");
272  for (auto key : producers.get_pset_names())
273  {
274  if (generated_physics_producers.has_key(key) && producers.get<fhicl::ParameterSet>(key) == generated_physics_producers.get<fhicl::ParameterSet>(key))
275  {
276  // Module is already configured
277  continue;
278  }
279  else if (generated_physics_producers.has_key(key))
280  {
281  // Module already exists with name, rename
282  auto newkey = label + key;
283  generated_physics_producers.put<fhicl::ParameterSet>(newkey, producers.get<fhicl::ParameterSet>(key));
284  for (size_t ii = 0; ii < path.size(); ++ii)
285  {
286  if (path[ii] == key)
287  {
288  path[ii] = newkey;
289  }
290  }
291  }
292  else
293  {
294  generated_physics_producers.put<fhicl::ParameterSet>(key, producers.get<fhicl::ParameterSet>(key));
295  }
296  }
297  }
298  if (physics_pset.has_key("filters"))
299  {
300  auto filters = physics_pset.get<fhicl::ParameterSet>("filters");
301  for (auto key : filters.get_pset_names())
302  {
303  if (generated_physics_filters.has_key(key) && filters.get<fhicl::ParameterSet>(key) == generated_physics_filters.get<fhicl::ParameterSet>(key))
304  {
305  // Module is already configured
306  continue;
307  }
308  else if (generated_physics_filters.has_key(key))
309  {
310  // Module already exists with name, rename
311  auto newkey = label + key;
312  generated_physics_filters.put<fhicl::ParameterSet>(newkey, filters.get<fhicl::ParameterSet>(key));
313  for (size_t ii = 0; ii < path.size(); ++ii)
314  {
315  if (path[ii] == key)
316  {
317  path[ii] = newkey;
318  }
319  }
320  }
321  else
322  {
323  generated_physics_filters.put<fhicl::ParameterSet>(key, filters.get<fhicl::ParameterSet>(key));
324  }
325  }
326  }
327  generated_physics.put<std::vector<std::string>>(label, path);
328  }
329  catch (cet::exception& e)
330  {
331  // Error in parsing input fhicl
332  TLOG(TLVL_ERROR) << "merge_parameter_sets_: Error processing input fhicl: " << e.what() ;
333  }
334 
335  TLOG(TLVL_DEBUG) << "merge_parameter_sets_: Building final ParameterSet" ;
336  generated_pset.put("outputs", generated_outputs);
337 
338  generated_physics.put("analyzers", generated_physics_analyzers);
339  generated_physics.put("producers", generated_physics_producers);
340  generated_physics.put("filters", generated_physics_filters);
341 
342  generated_pset.put("physics", generated_physics);
343 
344  return generated_pset;
345 }
346 
347 fhicl::ParameterSet artdaq::DispatcherCore::generate_filter_fhicl_()
348 {
349  TLOG(TLVL_DEBUG) << "generate_filter_fhicl_ BEGIN" ;
350  fhicl::ParameterSet generated_pset = pset_;
351 
352  for (auto& monitor : registered_monitors_)
353  {
354  auto label = monitor.first;
355  auto pset = monitor.second;
356  generated_pset = merge_parameter_sets_(generated_pset, label, pset);
357  }
358 
359 
360  TLOG(TLVL_DEBUG) << "generate_filter_fhicl_ returning ParameterSet: " << generated_pset.to_string() ;
361  return generated_pset;
362 }
DataReceiverCore implements the state machine for the DataReceiver artdaq application. DataReceiverCore receives Fragment objects from the DataReceiverManager, and sends them to the EventStore.
std::string unregister_monitor(std::string const &label)
Delete the TransferInterface having the given unique label.
std::string register_monitor(fhicl::ParameterSet const &pset)
Create a new TransferInterface instance using the given configuration.
DispatcherCore()
DispatcherCore Constructor.
bool initialize(fhicl::ParameterSet const &pset) override
Processes the initialize request.