00001 #include <errno.h>
00002 #include <sstream>
00003 #include <iomanip>
00004 #include <bitset>
00005
00006 #include <boost/tokenizer.hpp>
00007 #include <boost/filesystem.hpp>
00008 #include <boost/algorithm/string.hpp>
00009 #include <boost/exception/all.hpp>
00010 #include <boost/throw_exception.hpp>
00011
00012 #include "fhiclcpp/ParameterSet.h"
00013
00014 #define TRACE_NAME "DispatcherCore"
00015 #include "tracemf.h"
00016
00017 #include "artdaq-core/Core/SimpleMemoryReader.hh"
00018 #include "artdaq-core/Data/RawEvent.hh"
00019
00020 #include "artdaq/Application/DispatcherCore.hh"
00021 #include "artdaq/TransferPlugins/MakeTransferPlugin.hh"
00022
00023
00024
00025 artdaq::DispatcherCore::DispatcherCore()
00026 : DataReceiverCore()
00027 {}
00028
00029 artdaq::DispatcherCore::~DispatcherCore()
00030 {
00031 TLOG_DEBUG(app_name) << "Destructor" << TLOG_ENDL;
00032 }
00033
00034 bool artdaq::DispatcherCore::initialize(fhicl::ParameterSet const& pset)
00035 {
00036 TLOG_DEBUG(app_name) << "initialize method called with DAQ " << "ParameterSet = \"" << pset.to_string() << "\"." << TLOG_ENDL;
00037
00038 pset_ = pset;
00039 pset_.erase("outputs");
00040 pset_.erase("physics");
00041 pset_.erase("daq");
00042
00043
00044 fhicl::ParameterSet daq_pset;
00045 try
00046 {
00047 daq_pset = pset.get<fhicl::ParameterSet>("daq");
00048 }
00049 catch (...)
00050 {
00051 TLOG_ERROR(app_name)
00052 << "Unable to find the DAQ parameters in the initialization "
00053 << "ParameterSet: \"" + pset.to_string() + "\"." << TLOG_ENDL;
00054 return false;
00055 }
00056 fhicl::ParameterSet agg_pset;
00057 try
00058 {
00059 agg_pset = daq_pset.get<fhicl::ParameterSet>("dispatcher", daq_pset.get<fhicl::ParameterSet>("aggregator"));
00060 }
00061 catch (...)
00062 {
00063 TLOG_ERROR(app_name)
00064 << "Unable to find the Dispatcher parameters in the DAQ "
00065 << "initialization ParameterSet: \"" + daq_pset.to_string() + "\"." << TLOG_ENDL;
00066 return false;
00067 }
00068
00069 broadcast_mode_ = agg_pset.get<bool>("broadcast_mode", true);
00070 if (broadcast_mode_ && !agg_pset.has_key("broadcast_mode"))
00071 {
00072 agg_pset.put<bool>("broadcast_mode", true);
00073 agg_pset.put<int>("art_analyzer_count", 0);
00074 }
00075
00076
00077 fhicl::ParameterSet metric_pset;
00078
00079 try
00080 {
00081 metric_pset = daq_pset.get<fhicl::ParameterSet>("metrics");
00082 }
00083 catch (...) {}
00084
00085 return initializeDataReceiver(pset, agg_pset, metric_pset);
00086 }
00087
00088 std::string artdaq::DispatcherCore::register_monitor(fhicl::ParameterSet const& pset)
00089 {
00090 TLOG_DEBUG(app_name) << "DispatcherCore::register_monitor called with argument \"" << pset.to_string() << "\"" << TLOG_ENDL;
00091 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
00092
00093 try
00094 {
00095 TLOG_DEBUG(app_name) << "Getting unique_label from input ParameterSet" << TLOG_ENDL;
00096 auto label = pset.get<std::string>("unique_label");
00097 TLOG_DEBUG(app_name) << "Unique label is " << label << TLOG_ENDL;
00098 if (registered_monitors_.count(label))
00099 {
00100 throw cet::exception("DispatcherCore") << "Unique label already exists!";
00101 }
00102
00103 registered_monitors_[label] = pset;
00104 if (event_store_ptr_ != nullptr)
00105 {
00106 if (broadcast_mode_) {
00107 fhicl::ParameterSet ps = merge_parameter_sets_(pset_, label, pset);
00108 TLOG_DEBUG(app_name) << "Starting art process with received fhicl" << TLOG_ENDL;
00109 registered_monitor_pids_[label] = event_store_ptr_->StartArtProcess(ps);
00110 }
00111 else
00112 {
00113 TLOG_DEBUG(app_name) << "Generating new fhicl and reconfiguring art" << TLOG_ENDL;
00114 event_store_ptr_->ReconfigureArt(generate_filter_fhicl_());
00115 }
00116 }
00117 else
00118 {
00119 TLOG_ERROR(app_name) << "Unable to add monitor as there is no SharedMemoryEventManager instance!" << TLOG_ENDL;
00120 }
00121 }
00122 catch (const cet::exception& e)
00123 {
00124 std::stringstream errmsg;
00125 errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
00126 errmsg << "Exception: " << e.what();
00127 TLOG_ERROR(app_name) << errmsg.str() << TLOG_ENDL;
00128 return errmsg.str();
00129 }
00130 catch (const boost::exception& e)
00131 {
00132 std::stringstream errmsg;
00133 errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
00134 errmsg << "Exception: " << boost::diagnostic_information(e);
00135 TLOG_ERROR(app_name) << errmsg.str() << TLOG_ENDL;
00136 return errmsg.str();
00137 }
00138 catch (const std::exception& e)
00139 {
00140 std::stringstream errmsg;
00141 errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered" << std::endl;
00142 errmsg << "Exception: " << e.what();
00143 TLOG_ERROR(app_name) << errmsg.str() << TLOG_ENDL;
00144 return errmsg.str();
00145 }
00146 catch (...)
00147 {
00148 std::stringstream errmsg;
00149 errmsg << "Unable to create a Transfer plugin with the FHiCL code \"" << pset.to_string() << "\", a new monitor has not been registered";
00150 TLOG_ERROR(app_name) << errmsg.str() << TLOG_ENDL;
00151 return errmsg.str();
00152 }
00153
00154 return "Success";
00155 }
00156
00157 std::string artdaq::DispatcherCore::unregister_monitor(std::string const& label)
00158 {
00159 TLOG_DEBUG(app_name) << "DispatcherCore::unregister_monitor called with argument \"" << label << "\"" << TLOG_ENDL;
00160 std::lock_guard<std::mutex> lock(dispatcher_transfers_mutex_);
00161
00162 try
00163 {
00164 if (registered_monitors_.count(label) == 0)
00165 {
00166 std::stringstream errmsg;
00167 errmsg << "Warning in DispatcherCore::unregister_monitor: unable to find requested transfer plugin with "
00168 << "label \"" << label << "\"";
00169 TLOG_WARNING(app_name) << errmsg.str() << TLOG_ENDL;
00170 return errmsg.str();
00171 }
00172
00173 registered_monitors_.erase(label);
00174 if (event_store_ptr_ != nullptr)
00175 {
00176 if(broadcast_mode_) {
00177 std::set<pid_t> pids;
00178 pids.insert(registered_monitor_pids_[label]);
00179 event_store_ptr_->ShutdownArtProcesses(pids);
00180 registered_monitor_pids_.erase(label);
00181 }
00182 else
00183 {
00184 event_store_ptr_->ReconfigureArt(generate_filter_fhicl_());
00185 }
00186 }
00187 }
00188 catch (...)
00189 {
00190 std::stringstream errmsg;
00191 errmsg << "Unable to unregister transfer plugin with label \"" << label << "\"";
00192 return errmsg.str();
00193 }
00194
00195 return "Success";
00196 }
00197
00198 fhicl::ParameterSet artdaq::DispatcherCore::merge_parameter_sets_(fhicl::ParameterSet skel,std::string label, fhicl::ParameterSet pset)
00199 {
00200 fhicl::ParameterSet generated_pset = skel;
00201 fhicl::ParameterSet generated_outputs;
00202 fhicl::ParameterSet generated_physics;
00203 fhicl::ParameterSet generated_physics_analyzers;
00204 fhicl::ParameterSet generated_physics_producers;
00205 fhicl::ParameterSet generated_physics_filters;
00206
00207 TLOG_DEBUG(app_name) << "merge_parameter_sets_: Generating fhicl for monitor " << label << TLOG_ENDL;
00208
00209 try
00210 {
00211 auto path = pset.get<std::vector<std::string>>("path");
00212
00213
00214 auto outputs = pset.get<fhicl::ParameterSet>("outputs");
00215 if (outputs.get_pset_names().size() > 1 || outputs.get_pset_names().size() == 0)
00216 {
00217
00218 }
00219 auto output_name = outputs.get_pset_names()[0];
00220 auto output_pset = outputs.get<fhicl::ParameterSet>(output_name);
00221 generated_outputs.put(label + output_name, output_pset);
00222 bool outputInPath = false;
00223 for (size_t ii = 0; ii < path.size(); ++ii)
00224 {
00225 if (path[ii] == output_name)
00226 {
00227 path[ii] = label + output_name;
00228 outputInPath = true;
00229 }
00230 }
00231 if (!outputInPath)
00232 {
00233 path.push_back(label + output_name);
00234 }
00235
00236
00237 auto physics_pset = pset.get<fhicl::ParameterSet>("physics");
00238 if (physics_pset.has_key("analyzers"))
00239 {
00240 auto analyzers = physics_pset.get<fhicl::ParameterSet>("analyzers");
00241 for (auto key : analyzers.get_pset_names())
00242 {
00243 if (generated_physics_analyzers.has_key(key) && analyzers.get<fhicl::ParameterSet>(key) == generated_physics_analyzers.get<fhicl::ParameterSet>(key))
00244 {
00245
00246 continue;
00247 }
00248 else if (generated_physics_analyzers.has_key(key))
00249 {
00250
00251 auto newkey = label + key;
00252 generated_physics_analyzers.put<fhicl::ParameterSet>(newkey, analyzers.get<fhicl::ParameterSet>(key));
00253 for (size_t ii = 0; ii < path.size(); ++ii)
00254 {
00255 if (path[ii] == key)
00256 {
00257 path[ii] = newkey;
00258 }
00259 }
00260 }
00261 else
00262 {
00263 generated_physics_analyzers.put<fhicl::ParameterSet>(key, analyzers.get<fhicl::ParameterSet>(key));
00264 }
00265 }
00266 }
00267 if (physics_pset.has_key("producers"))
00268 {
00269 auto producers = physics_pset.get<fhicl::ParameterSet>("producers");
00270 for (auto key : producers.get_pset_names())
00271 {
00272 if (generated_physics_producers.has_key(key) && producers.get<fhicl::ParameterSet>(key) == generated_physics_producers.get<fhicl::ParameterSet>(key))
00273 {
00274
00275 continue;
00276 }
00277 else if (generated_physics_producers.has_key(key))
00278 {
00279
00280 auto newkey = label + key;
00281 generated_physics_producers.put<fhicl::ParameterSet>(newkey, producers.get<fhicl::ParameterSet>(key));
00282 for (size_t ii = 0; ii < path.size(); ++ii)
00283 {
00284 if (path[ii] == key)
00285 {
00286 path[ii] = newkey;
00287 }
00288 }
00289 }
00290 else
00291 {
00292 generated_physics_producers.put<fhicl::ParameterSet>(key, producers.get<fhicl::ParameterSet>(key));
00293 }
00294 }
00295 }
00296 if (physics_pset.has_key("filters"))
00297 {
00298 auto filters = physics_pset.get<fhicl::ParameterSet>("filters");
00299 for (auto key : filters.get_pset_names())
00300 {
00301 if (generated_physics_filters.has_key(key) && filters.get<fhicl::ParameterSet>(key) == generated_physics_filters.get<fhicl::ParameterSet>(key))
00302 {
00303
00304 continue;
00305 }
00306 else if (generated_physics_filters.has_key(key))
00307 {
00308
00309 auto newkey = label + key;
00310 generated_physics_filters.put<fhicl::ParameterSet>(newkey, filters.get<fhicl::ParameterSet>(key));
00311 for (size_t ii = 0; ii < path.size(); ++ii)
00312 {
00313 if (path[ii] == key)
00314 {
00315 path[ii] = newkey;
00316 }
00317 }
00318 }
00319 else
00320 {
00321 generated_physics_filters.put<fhicl::ParameterSet>(key, filters.get<fhicl::ParameterSet>(key));
00322 }
00323 }
00324 }
00325 generated_physics.put<std::vector<std::string>>(label, path);
00326 }
00327 catch (cet::exception& e)
00328 {
00329
00330 TLOG_ERROR(app_name) << "merge_parameter_sets_: Error processing input fhicl: " << e.what() << TLOG_ENDL;
00331 }
00332
00333 TLOG_DEBUG(app_name) << "merge_parameter_sets_: Building final ParameterSet" << TLOG_ENDL;
00334 generated_pset.put("outputs", generated_outputs);
00335
00336 generated_physics.put("analyzers", generated_physics_analyzers);
00337 generated_physics.put("producers", generated_physics_producers);
00338 generated_physics.put("filters", generated_physics_filters);
00339
00340 generated_pset.put("physics", generated_physics);
00341
00342 return generated_pset;
00343 }
00344
00345 fhicl::ParameterSet artdaq::DispatcherCore::generate_filter_fhicl_()
00346 {
00347 TLOG_DEBUG(app_name) << "generate_filter_fhicl_ BEGIN" << TLOG_ENDL;
00348 fhicl::ParameterSet generated_pset = pset_;
00349
00350 for (auto& monitor : registered_monitors_)
00351 {
00352 auto label = monitor.first;
00353 auto pset = monitor.second;
00354 generated_pset = merge_parameter_sets_(generated_pset, label, pset);
00355 }
00356
00357
00358 TLOG_DEBUG(app_name) << "generate_filter_fhicl_ returning ParameterSet: " << generated_pset.to_string() << TLOG_ENDL;
00359 return generated_pset;
00360 }