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