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 {
00019 TLOG(TLVL_DEBUG) << "Constructor" ;
00020 metricMan = &metricMan_;
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 data_tmp = data_pset;
00061 if (data_pset.has_key("expected_events_per_bunch"))
00062 {
00063 data_tmp.put<int>("expected_fragments_per_event", data_pset.get<int>("expected_events_per_bunch"));
00064 }
00065
00066 if (data_pset.has_key("rank"))
00067 {
00068 if (my_rank >= 0 && data_pset.get<int>("rank") != my_rank) {
00069 TLOG(TLVL_WARNING) << "Rank specified at startup is different than rank specified at configure! Using rank received at configure!";
00070 }
00071 my_rank = data_pset.get<int>("rank");
00072 }
00073 if (my_rank == -1)
00074 {
00075 TLOG(TLVL_ERROR) << "Rank not specified at startup or in configuration! Aborting";
00076 exit(1);
00077 }
00078
00079 event_store_ptr_.reset(new SharedMemoryEventManager(data_tmp, art_pset));
00080
00081 receiver_ptr_.reset(new artdaq::DataReceiverManager(data_tmp, event_store_ptr_));
00082
00083 return true;
00084 }
00085
00086 bool artdaq::DataReceiverCore::start(art::RunID id)
00087 {
00088 logMessage_("Starting run " + boost::lexical_cast<std::string>(id.run()));
00089 stop_requested_.store(false);
00090 pause_requested_.store(false);
00091 run_is_paused_.store(false);
00092 metricMan_.do_start();
00093 event_store_ptr_->startRun(id.run());
00094 receiver_ptr_->start_threads();
00095
00096 logMessage_("Completed the Start transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00097 return true;
00098 }
00099
00100 bool artdaq::DataReceiverCore::stop()
00101 {
00102 logMessage_("Stopping run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
00103 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00104 bool endSucceeded;
00105 int attemptsToEnd;
00106 receiver_ptr_->stop_threads();
00107
00108
00109
00110
00111
00112 stop_requested_.store(true);
00113
00114 if (!run_is_paused_.load())
00115 {
00116 TLOG(TLVL_DEBUG) << "Ending subrun " << event_store_ptr_->subrunID();
00117 endSucceeded = false;
00118 attemptsToEnd = 1;
00119 endSucceeded = event_store_ptr_->endSubrun();
00120 while (!endSucceeded && attemptsToEnd < 3)
00121 {
00122 ++attemptsToEnd;
00123 TLOG(TLVL_DEBUG) << "Retrying EventStore::endSubrun()" ;
00124 endSucceeded = event_store_ptr_->endSubrun();
00125 }
00126 if (!endSucceeded)
00127 {
00128 TLOG(TLVL_ERROR)
00129 << "EventStore::endSubrun in stop method failed after three tries." ;
00130 }
00131 TLOG(TLVL_DEBUG) << "Done Ending subrun " << event_store_ptr_->subrunID();
00132 }
00133
00134 TLOG(TLVL_DEBUG) << "Ending run " << event_store_ptr_->runID();
00135 endSucceeded = false;
00136 attemptsToEnd = 1;
00137 endSucceeded = event_store_ptr_->endRun();
00138 while (!endSucceeded && attemptsToEnd < 3)
00139 {
00140 ++attemptsToEnd;
00141 TLOG(TLVL_DEBUG) << "Retrying EventStore::endRun()" ;
00142 endSucceeded = event_store_ptr_->endRun();
00143 }
00144 if (!endSucceeded)
00145 {
00146 TLOG(TLVL_ERROR)
00147 << "EventStore::endRun in stop method failed after three tries." ;
00148 }
00149 TLOG(TLVL_DEBUG) << "Done Ending run " << event_store_ptr_->runID();
00150
00151 endSucceeded = false;
00152 attemptsToEnd = 1;
00153 TLOG(TLVL_DEBUG) << "stop: Calling EventStore::endOfData" ;
00154 endSucceeded = event_store_ptr_->endOfData();
00155 while (!endSucceeded && attemptsToEnd < 3)
00156 {
00157 ++attemptsToEnd;
00158 TLOG(TLVL_DEBUG) << "Retrying EventStore::endOfData()" ;
00159 endSucceeded = event_store_ptr_->endOfData();
00160 }
00161
00162 run_is_paused_.store(false);
00163 logMessage_("Completed the Stop transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00164 return true;
00165 }
00166
00167 bool artdaq::DataReceiverCore::pause()
00168 {
00169 logMessage_("Pausing run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
00170 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00171 pause_requested_.store(true);
00172
00173 bool endSucceeded = false;
00174 int attemptsToEnd = 1;
00175 endSucceeded = event_store_ptr_->endSubrun();
00176 while (!endSucceeded && attemptsToEnd < 3)
00177 {
00178 ++attemptsToEnd;
00179 TLOG(TLVL_DEBUG) << "Retrying EventStore::endSubrun()" ;
00180 endSucceeded = event_store_ptr_->endSubrun();
00181 }
00182 if (!endSucceeded)
00183 {
00184 TLOG(TLVL_ERROR)
00185 << "EventStore::endSubrun in pause method failed after three tries." ;
00186 }
00187
00188 run_is_paused_.store(true);
00189 logMessage_("Completed the Pause transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00190 return true;
00191 }
00192
00193 bool artdaq::DataReceiverCore::resume()
00194 {
00195 logMessage_("Resuming run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00196 pause_requested_.store(false);
00197 metricMan_.do_start();
00198 event_store_ptr_->startSubrun();
00199 run_is_paused_.store(false);
00200 logMessage_("Completed the Resume transition for run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00201 return true;
00202 }
00203
00204 bool artdaq::DataReceiverCore::shutdown()
00205 {
00206 logMessage_("Starting Shutdown transition");
00207
00208
00209
00210
00211
00212
00213 TLOG(TLVL_DEBUG) << "shutdown: Shutting down DataReceiverManager" ;
00214 receiver_ptr_.reset(nullptr);
00215
00216 bool endSucceeded = false;
00217 int attemptsToEnd = 1;
00218 TLOG(TLVL_DEBUG) << "shutdown: Calling EventStore::endOfData" ;
00219 endSucceeded = event_store_ptr_->endOfData();
00220 while (!endSucceeded && attemptsToEnd < 3)
00221 {
00222 ++attemptsToEnd;
00223 TLOG(TLVL_DEBUG) << "Retrying EventStore::endOfData()" ;
00224 endSucceeded = event_store_ptr_->endOfData();
00225 }
00226
00227 TLOG(TLVL_DEBUG) << "shutdown: Shutting down SharedMemoryEventManager" ;
00228 event_store_ptr_.reset();
00229
00230 TLOG(TLVL_DEBUG) << "shutdown: Shutting down MetricManager" ;
00231 metricMan_.shutdown();
00232
00233 TLOG(TLVL_DEBUG) << "shutdown: Complete" ;
00234 logMessage_("Completed Shutdown transition");
00235 return endSucceeded;
00236 }
00237
00238 bool artdaq::DataReceiverCore::soft_initialize(fhicl::ParameterSet const& pset)
00239 {
00240 TLOG(TLVL_DEBUG) << "soft_initialize method called with DAQ "
00241 << "ParameterSet = \"" << pset.to_string()
00242 << "\"." ;
00243 return true;
00244 }
00245
00246 bool artdaq::DataReceiverCore::reinitialize(fhicl::ParameterSet const& pset)
00247 {
00248 TLOG(TLVL_DEBUG) << "reinitialize method called with DAQ "
00249 << "ParameterSet = \"" << pset.to_string()
00250 << "\"." ;
00251 event_store_ptr_ = nullptr;
00252 return initialize(pset);
00253 }
00254
00255 bool artdaq::DataReceiverCore::rollover_subrun(uint64_t boundary)
00256 {
00257 if (event_store_ptr_)
00258 {
00259 event_store_ptr_->rolloverSubrun(boundary);
00260 return true;
00261 }
00262 return false;
00263 }
00264
00265 std::string artdaq::DataReceiverCore::report(std::string const& which) const
00266 {
00267 if (which == "incomplete_event_count")
00268 {
00269 if (event_store_ptr_ != nullptr)
00270 {
00271 return boost::lexical_cast<std::string>(event_store_ptr_->GetIncompleteEventCount());
00272 }
00273 else
00274 {
00275 return "-1";
00276 }
00277 }
00278 if (which == "event_count")
00279 {
00280 if (receiver_ptr_ != nullptr)
00281 return boost::lexical_cast<std::string>(receiver_ptr_->GetReceivedFragmentCount()->count());
00282
00283 return "0";
00284 }
00285
00286
00287
00288
00289
00290
00291 std::string tmpString;
00292 if (event_store_ptr_ != nullptr) tmpString.append(app_name + " run number = " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) + ".\n");
00293 tmpString.append("Command \"" + which + "\" is not currently supported.");
00294 return tmpString;
00295 }
00296
00297 void artdaq::DataReceiverCore::logMessage_(std::string const& text)
00298 {
00299 if (verbose_)
00300 {
00301 TLOG(TLVL_INFO) << text ;
00302 }
00303 else
00304 {
00305 TLOG(TLVL_DEBUG) << text ;
00306 }
00307 }