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