$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "canvas/Utilities/Exception.h" 00002 #include "art/Framework/Art/artapp.h" 00003 00004 #define TRACE_NAME (app_name + "_DataReceiverCore").c_str() // include these 2 first - 00005 #include "artdaq/DAQdata/Globals.hh" 00006 #include "artdaq-core/Core/SimpleMemoryReader.hh" 00007 #include "artdaq-core/Utilities/ExceptionHandler.hh" 00008 00009 #include "artdaq/Application/DataReceiverCore.hh" 00010 #include "artdaq/TransferPlugins/TransferInterface.hh" 00011 00012 #include <iomanip> 00013 00014 artdaq::DataReceiverCore::DataReceiverCore() 00015 : stop_requested_(false) 00016 , pause_requested_(false) 00017 , run_is_paused_(false) 00018 , config_archive_entries_() 00019 { 00020 TLOG(TLVL_DEBUG) << "Constructor" ; 00021 } 00022 00023 artdaq::DataReceiverCore::~DataReceiverCore() 00024 { 00025 TLOG(TLVL_DEBUG) << "Destructor" ; 00026 } 00027 00028 bool artdaq::DataReceiverCore::initializeDataReceiver(fhicl::ParameterSet const& pset, fhicl::ParameterSet const& data_pset, fhicl::ParameterSet const& metric_pset) 00029 { 00030 // other parameters 00031 verbose_ = data_pset.get<bool>("verbose", true); 00032 00033 // TRACE here so that mftrace_module and mftrace_iteration are ready by mftrace...should set it for all subsequent traces 00034 TLOG(TLVL_INFO) << "Initializing Data Receiver"; 00035 00036 if (metric_pset.is_empty()) 00037 { 00038 TLOG(TLVL_INFO) << "No metric plugins appear to be defined" ; 00039 } 00040 try 00041 { 00042 metricMan->initialize(metric_pset, app_name); 00043 } 00044 catch (...) 00045 { 00046 ExceptionHandler(ExceptionHandlerRethrow::no, 00047 "Error loading metrics in DataReceiverCore::initialize()"); 00048 } 00049 00050 fhicl::ParameterSet art_pset = pset; 00051 if(art_pset.has_key("art")) 00052 { 00053 art_pset = art_pset.get<fhicl::ParameterSet>("art"); 00054 } 00055 else 00056 { 00057 art_pset.erase("daq"); 00058 } 00059 00060 fhicl::ParameterSet art_source_pset = art_pset.get<fhicl::ParameterSet>("source"); 00061 art_source_pset.put<fhicl::ParameterSet>("metrics", metric_pset); 00062 art_pset.erase("source"); 00063 art_pset.put<fhicl::ParameterSet>("source", art_source_pset); 00064 00065 fhicl::ParameterSet data_tmp = data_pset; 00066 if (data_pset.has_key("expected_events_per_bunch")) 00067 { 00068 data_tmp.put<int>("expected_fragments_per_event", data_pset.get<int>("expected_events_per_bunch")); 00069 } 00070 00071 if (data_pset.has_key("rank")) 00072 { 00073 if (my_rank >= 0 && data_pset.get<int>("rank") != my_rank) { 00074 TLOG(TLVL_WARNING) << "Rank specified at startup is different than rank specified at configure! Using rank received at configure!"; 00075 } 00076 my_rank = data_pset.get<int>("rank"); 00077 } 00078 if (my_rank == -1) 00079 { 00080 TLOG(TLVL_ERROR) << "Rank not specified at startup or in configuration! Aborting"; 00081 exit(1); 00082 } 00083 00084 event_store_ptr_.reset(new SharedMemoryEventManager(data_tmp, art_pset)); 00085 art_pset_ = art_pset; 00086 00087 receiver_ptr_.reset(new artdaq::DataReceiverManager(data_tmp, event_store_ptr_)); 00088 00089 return true; 00090 } 00091 00092 bool artdaq::DataReceiverCore::start(art::RunID id) 00093 { 00094 logMessage_("Starting run " + boost::lexical_cast<std::string>(id.run())); 00095 00096 // 13-Jul-2018, KAB: added code to update the art_pset inside the event store 00097 // with configuration archive information 00098 // so that the config info will be stored in the output art/ROOT file. 00099 // (Note that we don't bother looping over the config_archive_entries if that 00100 // map is empty, but we *do* still update the art configuration with art_pset_ 00101 // at each begin-run because the config archive may be non-empty one time through 00102 // and then empty the next time.) 00103 fhicl::ParameterSet temp_pset = art_pset_; 00104 if (! config_archive_entries_.empty()) 00105 { 00106 fhicl::ParameterSet config_pset; 00107 for (auto& entry : config_archive_entries_) 00108 { 00109 config_pset.put(entry.first, entry.second); 00110 } 00111 temp_pset.put_or_replace("configuration_documents", config_pset); 00112 } 00113 event_store_ptr_->UpdateArtConfiguration(temp_pset); 00114 00115 stop_requested_.store(false); 00116 pause_requested_.store(false); 00117 run_is_paused_.store(false); 00118 metricMan->do_start(); 00119 event_store_ptr_->startRun(id.run()); 00120 receiver_ptr_->start_threads(); 00121 00122 logMessage_("Completed the Start transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID())); 00123 return true; 00124 } 00125 00126 bool artdaq::DataReceiverCore::stop() 00127 { 00128 logMessage_("Stopping run " + boost::lexical_cast<std::string>(event_store_ptr_->runID())); 00129 bool endSucceeded = false; 00130 int attemptsToEnd; 00131 receiver_ptr_->stop_threads(); 00132 00133 // 21-Jun-2013, KAB - the stop_requested_ variable must be set 00134 // before the flush lock so that the processFragments loop will 00135 // exit (after the timeout), the lock will be released (in the 00136 // processFragments method), and this method can continue. 00137 stop_requested_.store(true); 00138 00139 TLOG(TLVL_DEBUG) << "Ending run " << event_store_ptr_->runID(); 00140 attemptsToEnd = 1; 00141 endSucceeded = event_store_ptr_->endRun(); 00142 while (!endSucceeded && attemptsToEnd < 3) 00143 { 00144 ++attemptsToEnd; 00145 TLOG(TLVL_DEBUG) << "Retrying EventStore::endRun()" ; 00146 endSucceeded = event_store_ptr_->endRun(); 00147 } 00148 if (!endSucceeded) 00149 { 00150 TLOG(TLVL_ERROR) 00151 << "EventStore::endRun in stop method failed after three tries." ; 00152 } 00153 TLOG(TLVL_DEBUG) << "Done Ending run " << event_store_ptr_->runID(); 00154 00155 attemptsToEnd = 1; 00156 TLOG(TLVL_DEBUG) << "stop: Calling EventStore::endOfData" ; 00157 endSucceeded = event_store_ptr_->endOfData(); 00158 while (!endSucceeded && attemptsToEnd < 3) 00159 { 00160 ++attemptsToEnd; 00161 TLOG(TLVL_DEBUG) << "Retrying EventStore::endOfData()" ; 00162 endSucceeded = event_store_ptr_->endOfData(); 00163 } 00164 00165 run_is_paused_.store(false); 00166 logMessage_("Completed the Stop transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID())); 00167 return true; 00168 } 00169 00170 bool artdaq::DataReceiverCore::pause() 00171 { 00172 logMessage_("Pausing run " + boost::lexical_cast<std::string>(event_store_ptr_->runID())); 00173 pause_requested_.store(true); 00174 run_is_paused_.store(true); 00175 logMessage_("Completed the Pause transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID())); 00176 return true; 00177 } 00178 00179 bool artdaq::DataReceiverCore::resume() 00180 { 00181 logMessage_("Resuming run " + boost::lexical_cast<std::string>(event_store_ptr_->runID())); 00182 pause_requested_.store(false); 00183 metricMan->do_start(); 00184 event_store_ptr_->rolloverSubrun(); 00185 run_is_paused_.store(false); 00186 logMessage_("Completed the Resume transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID())); 00187 return true; 00188 } 00189 00190 bool artdaq::DataReceiverCore::shutdown() 00191 { 00192 logMessage_("Starting Shutdown transition"); 00193 00194 /* We don't care about flushing data here. The only way to transition to the 00195 shutdown state is from a state where there is no data taking. All we have 00196 to do is signal the art input module that we're done taking data so that 00197 it can wrap up whatever it needs to do. */ 00198 00199 TLOG(TLVL_DEBUG) << "shutdown: Shutting down DataReceiverManager" ; 00200 receiver_ptr_.reset(nullptr); 00201 00202 bool endSucceeded = false; 00203 int attemptsToEnd = 1; 00204 TLOG(TLVL_DEBUG) << "shutdown: Calling EventStore::endOfData" ; 00205 endSucceeded = event_store_ptr_->endOfData(); 00206 while (!endSucceeded && attemptsToEnd < 3) 00207 { 00208 ++attemptsToEnd; 00209 TLOG(TLVL_DEBUG) << "Retrying EventStore::endOfData()" ; 00210 endSucceeded = event_store_ptr_->endOfData(); 00211 } 00212 00213 TLOG(TLVL_DEBUG) << "shutdown: Shutting down SharedMemoryEventManager" ; 00214 event_store_ptr_.reset(); 00215 00216 TLOG(TLVL_DEBUG) << "shutdown: Shutting down MetricManager" ; 00217 metricMan->shutdown(); 00218 00219 TLOG(TLVL_DEBUG) << "shutdown: Complete" ; 00220 logMessage_("Completed Shutdown transition"); 00221 return endSucceeded; 00222 } 00223 00224 bool artdaq::DataReceiverCore::soft_initialize(fhicl::ParameterSet const& pset) 00225 { 00226 TLOG(TLVL_DEBUG) << "soft_initialize method called with DAQ " 00227 << "ParameterSet = \"" << pset.to_string() 00228 << "\"." ; 00229 return true; 00230 } 00231 00232 bool artdaq::DataReceiverCore::reinitialize(fhicl::ParameterSet const& pset) 00233 { 00234 TLOG(TLVL_DEBUG) << "reinitialize method called with DAQ " 00235 << "ParameterSet = \"" << pset.to_string() 00236 << "\"." ; 00237 event_store_ptr_ = nullptr; 00238 return initialize(pset); 00239 } 00240 00241 bool artdaq::DataReceiverCore::rollover_subrun(uint64_t boundary, uint32_t subrun) 00242 { 00243 if (event_store_ptr_) 00244 { 00245 event_store_ptr_->rolloverSubrun(boundary, subrun); 00246 return true; 00247 } 00248 return false; 00249 } 00250 00251 std::string artdaq::DataReceiverCore::report(std::string const& which) const 00252 { 00253 if (which == "incomplete_event_count") 00254 { 00255 if (event_store_ptr_ != nullptr) 00256 { 00257 return boost::lexical_cast<std::string>(event_store_ptr_->GetIncompleteEventCount()); 00258 } 00259 else 00260 { 00261 return "-1"; 00262 } 00263 } 00264 if (which == "event_count") 00265 { 00266 if (receiver_ptr_ != nullptr) 00267 return boost::lexical_cast<std::string>(receiver_ptr_->GetReceivedFragmentCount()->count()); 00268 00269 return "0"; 00270 } 00271 00272 // lots of cool stuff that we can do here 00273 // - report on the number of fragments received and the number 00274 // of events built (in the current or previous run 00275 // - report on the number of incomplete events in the EventStore 00276 // (if running) 00277 std::string tmpString; 00278 if (event_store_ptr_ != nullptr) tmpString.append(app_name + " run number = " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) + ".\n"); 00279 tmpString.append("Command \"" + which + "\" is not currently supported."); 00280 return tmpString; 00281 } 00282 00283 void artdaq::DataReceiverCore::logMessage_(std::string const& text) 00284 { 00285 if (verbose_) 00286 { 00287 TLOG(TLVL_INFO) << text ; 00288 } 00289 else 00290 { 00291 TLOG(TLVL_DEBUG) << text ; 00292 } 00293 }