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
00031 verbose_ = data_pset.get<bool>("verbose", true);
00032
00033
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
00097
00098
00099
00100
00101
00102
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 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00130 bool endSucceeded = false;
00131 int attemptsToEnd;
00132 receiver_ptr_->stop_threads();
00133
00134
00135
00136
00137
00138 stop_requested_.store(true);
00139
00140 if (!run_is_paused_.load())
00141 {
00142 TLOG(TLVL_DEBUG) << "Ending subrun " << event_store_ptr_->subrunID();
00143 attemptsToEnd = 1;
00144 endSucceeded = event_store_ptr_->endSubrun();
00145 while (!endSucceeded && attemptsToEnd < 3)
00146 {
00147 ++attemptsToEnd;
00148 TLOG(TLVL_DEBUG) << "Retrying EventStore::endSubrun()" ;
00149 endSucceeded = event_store_ptr_->endSubrun();
00150 }
00151 if (!endSucceeded)
00152 {
00153 TLOG(TLVL_ERROR)
00154 << "EventStore::endSubrun in stop method failed after three tries." ;
00155 }
00156 TLOG(TLVL_DEBUG) << "Done Ending subrun " << event_store_ptr_->subrunID();
00157 }
00158
00159 TLOG(TLVL_DEBUG) << "Ending run " << event_store_ptr_->runID();
00160 attemptsToEnd = 1;
00161 endSucceeded = event_store_ptr_->endRun();
00162 while (!endSucceeded && attemptsToEnd < 3)
00163 {
00164 ++attemptsToEnd;
00165 TLOG(TLVL_DEBUG) << "Retrying EventStore::endRun()" ;
00166 endSucceeded = event_store_ptr_->endRun();
00167 }
00168 if (!endSucceeded)
00169 {
00170 TLOG(TLVL_ERROR)
00171 << "EventStore::endRun in stop method failed after three tries." ;
00172 }
00173 TLOG(TLVL_DEBUG) << "Done Ending run " << event_store_ptr_->runID();
00174
00175 attemptsToEnd = 1;
00176 TLOG(TLVL_DEBUG) << "stop: Calling EventStore::endOfData" ;
00177 endSucceeded = event_store_ptr_->endOfData();
00178 while (!endSucceeded && attemptsToEnd < 3)
00179 {
00180 ++attemptsToEnd;
00181 TLOG(TLVL_DEBUG) << "Retrying EventStore::endOfData()" ;
00182 endSucceeded = event_store_ptr_->endOfData();
00183 }
00184
00185 run_is_paused_.store(false);
00186 logMessage_("Completed the Stop transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00187 return true;
00188 }
00189
00190 bool artdaq::DataReceiverCore::pause()
00191 {
00192 logMessage_("Pausing run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
00193 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00194 pause_requested_.store(true);
00195
00196 bool endSucceeded = false;
00197 int attemptsToEnd = 1;
00198 endSucceeded = event_store_ptr_->endSubrun();
00199 while (!endSucceeded && attemptsToEnd < 3)
00200 {
00201 ++attemptsToEnd;
00202 TLOG(TLVL_DEBUG) << "Retrying EventStore::endSubrun()" ;
00203 endSucceeded = event_store_ptr_->endSubrun();
00204 }
00205 if (!endSucceeded)
00206 {
00207 TLOG(TLVL_ERROR)
00208 << "EventStore::endSubrun in pause method failed after three tries." ;
00209 }
00210
00211 run_is_paused_.store(true);
00212 logMessage_("Completed the Pause transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00213 return true;
00214 }
00215
00216 bool artdaq::DataReceiverCore::resume()
00217 {
00218 logMessage_("Resuming run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00219 pause_requested_.store(false);
00220 metricMan->do_start();
00221 event_store_ptr_->startSubrun();
00222 run_is_paused_.store(false);
00223 logMessage_("Completed the Resume transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00224 return true;
00225 }
00226
00227 bool artdaq::DataReceiverCore::shutdown()
00228 {
00229 logMessage_("Starting Shutdown transition");
00230
00231
00232
00233
00234
00235
00236 TLOG(TLVL_DEBUG) << "shutdown: Shutting down DataReceiverManager" ;
00237 receiver_ptr_.reset(nullptr);
00238
00239 bool endSucceeded = false;
00240 int attemptsToEnd = 1;
00241 TLOG(TLVL_DEBUG) << "shutdown: Calling EventStore::endOfData" ;
00242 endSucceeded = event_store_ptr_->endOfData();
00243 while (!endSucceeded && attemptsToEnd < 3)
00244 {
00245 ++attemptsToEnd;
00246 TLOG(TLVL_DEBUG) << "Retrying EventStore::endOfData()" ;
00247 endSucceeded = event_store_ptr_->endOfData();
00248 }
00249
00250 TLOG(TLVL_DEBUG) << "shutdown: Shutting down SharedMemoryEventManager" ;
00251 event_store_ptr_.reset();
00252
00253 TLOG(TLVL_DEBUG) << "shutdown: Shutting down MetricManager" ;
00254 metricMan->shutdown();
00255
00256 TLOG(TLVL_DEBUG) << "shutdown: Complete" ;
00257 logMessage_("Completed Shutdown transition");
00258 return endSucceeded;
00259 }
00260
00261 bool artdaq::DataReceiverCore::soft_initialize(fhicl::ParameterSet const& pset)
00262 {
00263 TLOG(TLVL_DEBUG) << "soft_initialize method called with DAQ "
00264 << "ParameterSet = \"" << pset.to_string()
00265 << "\"." ;
00266 return true;
00267 }
00268
00269 bool artdaq::DataReceiverCore::reinitialize(fhicl::ParameterSet const& pset)
00270 {
00271 TLOG(TLVL_DEBUG) << "reinitialize method called with DAQ "
00272 << "ParameterSet = \"" << pset.to_string()
00273 << "\"." ;
00274 event_store_ptr_ = nullptr;
00275 return initialize(pset);
00276 }
00277
00278 bool artdaq::DataReceiverCore::rollover_subrun(uint64_t boundary)
00279 {
00280 if (event_store_ptr_)
00281 {
00282 event_store_ptr_->rolloverSubrun(boundary);
00283 return true;
00284 }
00285 return false;
00286 }
00287
00288 std::string artdaq::DataReceiverCore::report(std::string const& which) const
00289 {
00290 if (which == "incomplete_event_count")
00291 {
00292 if (event_store_ptr_ != nullptr)
00293 {
00294 return boost::lexical_cast<std::string>(event_store_ptr_->GetIncompleteEventCount());
00295 }
00296 else
00297 {
00298 return "-1";
00299 }
00300 }
00301 if (which == "event_count")
00302 {
00303 if (receiver_ptr_ != nullptr)
00304 return boost::lexical_cast<std::string>(receiver_ptr_->GetReceivedFragmentCount()->count());
00305
00306 return "0";
00307 }
00308
00309
00310
00311
00312
00313
00314 std::string tmpString;
00315 if (event_store_ptr_ != nullptr) tmpString.append(app_name + " run number = " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) + ".\n");
00316 tmpString.append("Command \"" + which + "\" is not currently supported.");
00317 return tmpString;
00318 }
00319
00320 void artdaq::DataReceiverCore::logMessage_(std::string const& text)
00321 {
00322 if (verbose_)
00323 {
00324 TLOG(TLVL_INFO) << text ;
00325 }
00326 else
00327 {
00328 TLOG(TLVL_DEBUG) << text ;
00329 }
00330 }