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