00001 #include "canvas/Utilities/Exception.h"
00002 #include "art/Framework/Art/artapp.h"
00003
00004 #define TRACE_NAME "DataReceiverCore"
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_DEBUG(app_name) << "Constructor" << TLOG_ENDL;
00020 metricMan = &metricMan_;
00021 }
00022
00023 artdaq::DataReceiverCore::~DataReceiverCore()
00024 {
00025 TLOG_DEBUG(app_name) << "Destructor" << TLOG_ENDL;
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_ = pset.get<bool>("verbose", false);
00032
00033 if (metric_pset.is_empty())
00034 {
00035 TLOG_INFO(app_name) << "No metric plugins appear to be defined" << TLOG_ENDL;
00036 }
00037 try
00038 {
00039 metricMan_.initialize(metric_pset, app_name + "." + std::to_string(my_rank));
00040 }
00041 catch (...)
00042 {
00043 ExceptionHandler(ExceptionHandlerRethrow::no,
00044 "Error loading metrics in DataReceiverCore::initialize()");
00045 }
00046
00047 fhicl::ParameterSet tmp = pset;
00048 tmp.erase("daq");
00049
00050 fhicl::ParameterSet data_tmp = data_pset;
00051 if (data_pset.has_key("expected_events_per_bunch"))
00052 {
00053 data_tmp.put<int>("expected_fragments_per_event", data_pset.get<int>("expected_events_per_bunch"));
00054 }
00055
00056 event_store_ptr_.reset(new SharedMemoryEventManager(data_tmp, tmp));
00057
00058 receiver_ptr_.reset(new artdaq::DataReceiverManager(data_tmp, event_store_ptr_));
00059
00060 return true;
00061 }
00062
00063 bool artdaq::DataReceiverCore::start(art::RunID id)
00064 {
00065 stop_requested_.store(false);
00066 pause_requested_.store(false);
00067 run_is_paused_.store(false);
00068 metricMan_.do_start();
00069 event_store_ptr_->startRun(id.run());
00070 receiver_ptr_->start_threads();
00071
00072 logMessage_("Started run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00073 return true;
00074 }
00075
00076 bool artdaq::DataReceiverCore::stop()
00077 {
00078 logMessage_("Stopping run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
00079 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00080 bool endSucceeded;
00081 int attemptsToEnd;
00082
00083
00084
00085
00086
00087 stop_requested_.store(true);
00088
00089 if (!run_is_paused_.load())
00090 {
00091 endSucceeded = false;
00092 attemptsToEnd = 1;
00093 endSucceeded = event_store_ptr_->endSubrun();
00094 while (!endSucceeded && attemptsToEnd < 3)
00095 {
00096 ++attemptsToEnd;
00097 TLOG_DEBUG(app_name) << "Retrying EventStore::endSubrun()" << TLOG_ENDL;
00098 endSucceeded = event_store_ptr_->endSubrun();
00099 }
00100 if (!endSucceeded)
00101 {
00102 TLOG_ERROR(app_name)
00103 << "EventStore::endSubrun in stop method failed after three tries." << TLOG_ENDL;
00104 }
00105 }
00106
00107 endSucceeded = false;
00108 attemptsToEnd = 1;
00109 endSucceeded = event_store_ptr_->endRun();
00110 while (!endSucceeded && attemptsToEnd < 3)
00111 {
00112 ++attemptsToEnd;
00113 TLOG_DEBUG(app_name) << "Retrying EventStore::endRun()" << TLOG_ENDL;
00114 endSucceeded = event_store_ptr_->endRun();
00115 }
00116 if (!endSucceeded)
00117 {
00118 TLOG_ERROR(app_name)
00119 << "EventStore::endRun in stop method failed after three tries." << TLOG_ENDL;
00120 }
00121
00122 endSucceeded = false;
00123 attemptsToEnd = 1;
00124 TLOG_DEBUG("DataReceiverCore") << "stop: Calling EventStore::endOfData" << TLOG_ENDL;
00125 endSucceeded = event_store_ptr_->endOfData();
00126 while (!endSucceeded && attemptsToEnd < 3)
00127 {
00128 ++attemptsToEnd;
00129 TLOG_DEBUG(app_name) << "Retrying EventStore::endOfData()" << TLOG_ENDL;
00130 endSucceeded = event_store_ptr_->endOfData();
00131 }
00132
00133 run_is_paused_.store(false);
00134 return true;
00135 }
00136
00137 bool artdaq::DataReceiverCore::pause()
00138 {
00139 logMessage_("Pausing run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) +
00140 ", subrun " + boost::lexical_cast<std::string>(event_store_ptr_->subrunID()));
00141 pause_requested_.store(true);
00142
00143 bool endSucceeded = false;
00144 int attemptsToEnd = 1;
00145 endSucceeded = event_store_ptr_->endSubrun();
00146 while (!endSucceeded && attemptsToEnd < 3)
00147 {
00148 ++attemptsToEnd;
00149 TLOG_DEBUG(app_name) << "Retrying EventStore::endSubrun()" << TLOG_ENDL;
00150 endSucceeded = event_store_ptr_->endSubrun();
00151 }
00152 if (!endSucceeded)
00153 {
00154 TLOG_ERROR(app_name)
00155 << "EventStore::endSubrun in pause method failed after three tries." << TLOG_ENDL;
00156 }
00157
00158 run_is_paused_.store(true);
00159 return true;
00160 }
00161
00162 bool artdaq::DataReceiverCore::resume()
00163 {
00164 logMessage_("Resuming run " + boost::lexical_cast<std::string>(event_store_ptr_->runID()));
00165 pause_requested_.store(false);
00166 metricMan_.do_start();
00167 event_store_ptr_->startSubrun();
00168 run_is_paused_.store(false);
00169 return true;
00170 }
00171
00172 bool artdaq::DataReceiverCore::shutdown()
00173 {
00174
00175
00176
00177
00178
00179 TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down DataReceiverManager" << TLOG_ENDL;
00180 receiver_ptr_.reset(nullptr);
00181
00182 bool endSucceeded = false;
00183 int attemptsToEnd = 1;
00184 TLOG_DEBUG("DataReceiverCore") << "shutdown: Calling EventStore::endOfData" << TLOG_ENDL;
00185 endSucceeded = event_store_ptr_->endOfData();
00186 while (!endSucceeded && attemptsToEnd < 3)
00187 {
00188 ++attemptsToEnd;
00189 TLOG_DEBUG(app_name) << "Retrying EventStore::endOfData()" << TLOG_ENDL;
00190 endSucceeded = event_store_ptr_->endOfData();
00191 }
00192
00193 TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down SharedMemoryEventManager" << TLOG_ENDL;
00194 event_store_ptr_.reset();
00195
00196 TLOG_DEBUG("DataReceiverCore") << "shutdown: Shutting down MetricManager" << TLOG_ENDL;
00197 metricMan_.shutdown();
00198
00199 TLOG_DEBUG("DataReceiverCore") << "shutdown: Complete" << TLOG_ENDL;
00200 return endSucceeded;
00201 }
00202
00203 bool artdaq::DataReceiverCore::soft_initialize(fhicl::ParameterSet const& pset)
00204 {
00205 TLOG_DEBUG(app_name) << "soft_initialize method called with DAQ "
00206 << "ParameterSet = \"" << pset.to_string()
00207 << "\"." << TLOG_ENDL;
00208 return true;
00209 }
00210
00211 bool artdaq::DataReceiverCore::reinitialize(fhicl::ParameterSet const& pset)
00212 {
00213 TLOG_DEBUG(app_name) << "reinitialize method called with DAQ "
00214 << "ParameterSet = \"" << pset.to_string()
00215 << "\"." << TLOG_ENDL;
00216 event_store_ptr_ = nullptr;
00217 return initialize(pset);
00218 }
00219
00220 std::string artdaq::DataReceiverCore::report(std::string const& which) const
00221 {
00222 if (which == "incomplete_event_count")
00223 {
00224 if (event_store_ptr_ != nullptr)
00225 {
00226 return boost::lexical_cast<std::string>(event_store_ptr_->GetIncompleteEventCount());
00227 }
00228 else
00229 {
00230 return "-1";
00231 }
00232 }
00233 if (which == "event_count")
00234 {
00235 if (receiver_ptr_ != nullptr)
00236 return boost::lexical_cast<std::string>(receiver_ptr_->GetReceivedFragmentCount()->count());
00237
00238 return "0";
00239 }
00240
00241
00242
00243
00244
00245
00246 std::string tmpString;
00247 if (event_store_ptr_ != nullptr) tmpString.append(app_name + " run number = " + boost::lexical_cast<std::string>(event_store_ptr_->runID()) + ".\n");
00248 tmpString.append("Command \"" + which + "\" is not currently supported.");
00249 return tmpString;
00250 }
00251
00252 void artdaq::DataReceiverCore::logMessage_(std::string const& text)
00253 {
00254 if (verbose_)
00255 {
00256 TLOG_INFO(app_name) << text << TLOG_ENDL;
00257 }
00258 else
00259 {
00260 TLOG_DEBUG(app_name) << text << TLOG_ENDL;
00261 }
00262 }