artdaq  v3_00_01
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 "DispatcherCore"
15 #include "tracemf.h"
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 
25 artdaq::DispatcherCore::DispatcherCore(int rank, std::string name)
26  : DataReceiverCore(rank, name)
27 {}
28 
30 {
31  TLOG_DEBUG(name_) << "Destructor" << TLOG_ENDL;
32 }
33 
34 bool artdaq::DispatcherCore::initialize(fhicl::ParameterSet const& pset)
35 {
36  TLOG_DEBUG(name_) << "initialize method called with DAQ " << "ParameterSet = \"" << pset.to_string() << "\"." << TLOG_ENDL;
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_ERROR(name_)
52  << "Unable to find the DAQ parameters in the initialization "
53  << "ParameterSet: \"" + pset.to_string() + "\"." << TLOG_ENDL;
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_ERROR(name_)
64  << "Unable to find the Dispatcher parameters in the DAQ "
65  << "initialization ParameterSet: \"" + daq_pset.to_string() + "\"." << TLOG_ENDL;
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  agg_pset.put<int>("art_analyzer_count", 0);
74  }
75 
76  // initialize the MetricManager and the names of our metrics
77  fhicl::ParameterSet metric_pset;
78 
79  try
80  {
81  metric_pset = daq_pset.get<fhicl::ParameterSet>("metrics");
82  }
83  catch (...) {} // OK if there's no metrics table defined in the FHiCL
84 
85  return initializeDataReceiver(pset, agg_pset, metric_pset);
86 }
87 
88 std::string artdaq::DispatcherCore::register_monitor(fhicl::ParameterSet const& pset)
89 {
90  TLOG_DEBUG(name_) << "DispatcherCore::register_monitor called with argument \"" << pset.to_string() << "\"" << TLOG_ENDL;
91  std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
92 
93  try
94  {
95  TLOG_DEBUG(name_) << "Getting unique_label from input ParameterSet" << TLOG_ENDL;
96  auto label = pset.get<std::string>("unique_label");
97  TLOG_DEBUG(name_) << "Unique label is " << label << TLOG_ENDL;
98  if (registered_monitors_.count(label))
99  {
100  throw cet::exception("DispatcherCore") << "Unique label already exists!";
101  }
102 
103  registered_monitors_[label] = pset;
104  if (event_store_ptr_ != nullptr)
105  {
106  if (broadcast_mode_) {
107  fhicl::ParameterSet ps = merge_parameter_sets_(pset_, label, pset);
108  TLOG_DEBUG(name_) << "Starting art process with received fhicl" << TLOG_ENDL;
109  registered_monitor_pids_[label] = event_store_ptr_->StartArtProcess(ps);
110  }
111  else
112  {
113  TLOG_DEBUG(name_) << "Generating new fhicl and reconfiguring art" << TLOG_ENDL;
114  event_store_ptr_->ReconfigureArt(generate_filter_fhicl_());
115  }
116  }
117  else
118  {
119  TLOG_ERROR(name_) << "Unable to add monitor as there is no SharedMemoryEventManager instance!" << TLOG_ENDL;
120  }
121  }
122  catch (const cet::exception& e)
123  {
124  std::stringstream errmsg;
125  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
126  errmsg << "Exception: " << e.what();
127  TLOG_ERROR(name_) << errmsg.str() << TLOG_ENDL;
128  return errmsg.str();
129  }
130  catch (const boost::exception& e)
131  {
132  std::stringstream errmsg;
133  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
134  errmsg << "Exception: " << boost::diagnostic_information(e);
135  TLOG_ERROR(name_) << errmsg.str() << TLOG_ENDL;
136  return errmsg.str();
137  }
138  catch (const std::exception& e)
139  {
140  std::stringstream errmsg;
141  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
142  errmsg << "Exception: " << e.what();
143  TLOG_ERROR(name_) << errmsg.str() << TLOG_ENDL;
144  return errmsg.str();
145  }
146  catch (...)
147  {
148  std::stringstream errmsg;
149  errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered";
150  TLOG_ERROR(name_) << errmsg.str() << TLOG_ENDL;
151  return errmsg.str();
152  }
153 
154  return "Success";
155 }
156 
157 std::string artdaq::DispatcherCore::unregister_monitor(std::string const& label)
158 {
159  TLOG_DEBUG(name_) << "DispatcherCore::unregister_monitor called with argument \"" << label << "\"" << TLOG_ENDL;
160  std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
161 
162  try
163  {
164  if (registered_monitors_.count(label) == 0)
165  {
166  std::stringstream errmsg;
167  errmsg << "Warning in DispatcherCore::unregister_monitor: unable to find requested transfer plugin with "
168  << "label \"" << label << "\"";
169  TLOG_WARNING(name_) << errmsg.str() << TLOG_ENDL;
170  return errmsg.str();
171  }
172 
173  registered_monitors_.erase(label);
174  if (event_store_ptr_ != nullptr)
175  {
176  if(broadcast_mode_) {
177  std::set<pid_t> pids;
178  pids.insert(registered_monitor_pids_[label]);
179  event_store_ptr_->ShutdownArtProcesses(pids);
180  registered_monitor_pids_.erase(label);
181  }
182  else
183  {
184  event_store_ptr_->ReconfigureArt(generate_filter_fhicl_());
185  }
186  }
187  }
188  catch (...)
189  {
190  std::stringstream errmsg;
191  errmsg << "Unable to unregister transfer plugin with label \"" << label << "\"";
192  return errmsg.str();
193  }
194 
195  return "Success";
196 }
197 
198 fhicl::ParameterSet artdaq::DispatcherCore::merge_parameter_sets_(fhicl::ParameterSet skel,std::string label, fhicl::ParameterSet pset)
199 {
200  fhicl::ParameterSet generated_pset = skel;
201  fhicl::ParameterSet generated_outputs;
202  fhicl::ParameterSet generated_physics;
203  fhicl::ParameterSet generated_physics_analyzers;
204  fhicl::ParameterSet generated_physics_producers;
205  fhicl::ParameterSet generated_physics_filters;
206 
207  TLOG_DEBUG(name_) << "merge_parameter_sets_: Generating fhicl for monitor " << label << TLOG_ENDL;
208 
209  try
210  {
211  auto path = pset.get<std::vector<std::string>>("path");
212 
213  // outputs section
214  auto outputs = pset.get<fhicl::ParameterSet>("outputs");
215  if (outputs.get_pset_names().size() > 1 || outputs.get_pset_names().size() == 0)
216  {
217  // Only one output allowed per monitor
218  }
219  auto output_name = outputs.get_pset_names()[0];
220  auto output_pset = outputs.get<fhicl::ParameterSet>(output_name);
221  generated_outputs.put(label + output_name, output_pset);
222  bool outputInPath = false;
223  for (size_t ii = 0; ii < path.size(); ++ii)
224  {
225  if (path[ii] == output_name)
226  {
227  path[ii] = label + output_name;
228  outputInPath = true;
229  }
230  }
231  if (!outputInPath)
232  {
233  path.push_back(label + output_name);
234  }
235 
236  //physics section
237  auto physics_pset = pset.get<fhicl::ParameterSet>("physics");
238  if (physics_pset.has_key("analyzers"))
239  {
240  auto analyzers = physics_pset.get<fhicl::ParameterSet>("analyzers");
241  for (auto key : analyzers.get_pset_names())
242  {
243  if (generated_physics_analyzers.has_key(key) && analyzers.get<fhicl::ParameterSet>(key) == generated_physics_analyzers.get<fhicl::ParameterSet>(key))
244  {
245  // Module is already configured
246  continue;
247  }
248  else if (generated_physics_analyzers.has_key(key))
249  {
250  // Module already exists with name, rename
251  auto newkey = label + key;
252  generated_physics_analyzers.put<fhicl::ParameterSet>(newkey, analyzers.get<fhicl::ParameterSet>(key));
253  for (size_t ii = 0; ii < path.size(); ++ii)
254  {
255  if (path[ii] == key)
256  {
257  path[ii] = newkey;
258  }
259  }
260  }
261  else
262  {
263  generated_physics_analyzers.put<fhicl::ParameterSet>(key, analyzers.get<fhicl::ParameterSet>(key));
264  }
265  }
266  }
267  if (physics_pset.has_key("producers"))
268  {
269  auto producers = physics_pset.get<fhicl::ParameterSet>("producers");
270  for (auto key : producers.get_pset_names())
271  {
272  if (generated_physics_producers.has_key(key) && producers.get<fhicl::ParameterSet>(key) == generated_physics_producers.get<fhicl::ParameterSet>(key))
273  {
274  // Module is already configured
275  continue;
276  }
277  else if (generated_physics_producers.has_key(key))
278  {
279  // Module already exists with name, rename
280  auto newkey = label + key;
281  generated_physics_producers.put<fhicl::ParameterSet>(newkey, producers.get<fhicl::ParameterSet>(key));
282  for (size_t ii = 0; ii < path.size(); ++ii)
283  {
284  if (path[ii] == key)
285  {
286  path[ii] = newkey;
287  }
288  }
289  }
290  else
291  {
292  generated_physics_producers.put<fhicl::ParameterSet>(key, producers.get<fhicl::ParameterSet>(key));
293  }
294  }
295  }
296  if (physics_pset.has_key("filters"))
297  {
298  auto filters = physics_pset.get<fhicl::ParameterSet>("filters");
299  for (auto key : filters.get_pset_names())
300  {
301  if (generated_physics_filters.has_key(key) && filters.get<fhicl::ParameterSet>(key) == generated_physics_filters.get<fhicl::ParameterSet>(key))
302  {
303  // Module is already configured
304  continue;
305  }
306  else if (generated_physics_filters.has_key(key))
307  {
308  // Module already exists with name, rename
309  auto newkey = label + key;
310  generated_physics_filters.put<fhicl::ParameterSet>(newkey, filters.get<fhicl::ParameterSet>(key));
311  for (size_t ii = 0; ii < path.size(); ++ii)
312  {
313  if (path[ii] == key)
314  {
315  path[ii] = newkey;
316  }
317  }
318  }
319  else
320  {
321  generated_physics_filters.put<fhicl::ParameterSet>(key, filters.get<fhicl::ParameterSet>(key));
322  }
323  }
324  }
325  generated_physics.put<std::vector<std::string>>(label, path);
326  }
327  catch (cet::exception& e)
328  {
329  // Error in parsing input fhicl
330  TLOG_ERROR(name_) << "merge_parameter_sets_: Error processing input fhicl: " << e.what() << TLOG_ENDL;
331  }
332 
333  TLOG_DEBUG(name_) << "merge_parameter_sets_: Building final ParameterSet" << TLOG_ENDL;
334  generated_pset.put("outputs", generated_outputs);
335 
336  generated_physics.put("analyzers", generated_physics_analyzers);
337  generated_physics.put("producers", generated_physics_producers);
338  generated_physics.put("filters", generated_physics_filters);
339 
340  generated_pset.put("physics", generated_physics);
341 
342  return generated_pset;
343 }
344 
345 fhicl::ParameterSet artdaq::DispatcherCore::generate_filter_fhicl_()
346 {
347  TLOG_DEBUG(name_) << "generate_filter_fhicl_ BEGIN" << TLOG_ENDL;
348  fhicl::ParameterSet generated_pset = pset_;
349 
350  for (auto& monitor : registered_monitors_)
351  {
352  auto label = monitor.first;
353  auto pset = monitor.second;
354  generated_pset = merge_parameter_sets_(generated_pset, label, pset);
355  }
356 
357 
358  TLOG_DEBUG(name_) << "generate_filter_fhicl_ returning ParameterSet: " << generated_pset.to_string() << TLOG_ENDL;
359  return generated_pset;
360 }
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(int rank, std::string name)
DispatcherCore Constructor.
bool initialize(fhicl::ParameterSet const &pset) override
Processes the initialize request.