00001 #include "artdaq/Application/CompositeDriver.hh"
00002
00003 #include "artdaq/Application/GeneratorMacros.hh"
00004 #include "artdaq/Application/makeCommandableFragmentGenerator.hh"
00005 #include "canvas/Utilities/Exception.h"
00006 #include "cetlib_except/exception.h"
00007 #include <boost/algorithm/string.hpp>
00008
00009 using fhicl::ParameterSet;
00010
00011 artdaq::CompositeDriver::CompositeDriver(ParameterSet const& ps):
00012 CommandableFragmentGenerator(ps)
00013 {
00014 std::vector<ParameterSet> psetList =
00015 ps.get<std::vector<ParameterSet>>("generator_config_list");
00016 for (auto pset : psetList)
00017 {
00018 if (! makeChildGenerator_(pset))
00019 {
00020 throw cet::exception("CompositeDriver")
00021 << "Unable to create child generator for PSet= \""
00022 << pset.to_string() << "\"";
00023 }
00024 }
00025
00026 std::string compositeMetricName;
00027 for (auto& generator : generator_list_)
00028 {
00029 if (compositeMetricName.length() > 0) { compositeMetricName.append(", "); }
00030 compositeMetricName.append(generator->metricsReportingInstanceName());
00031 }
00032 this->metricsReportingInstanceName(compositeMetricName);
00033 }
00034
00035 artdaq::CompositeDriver::~CompositeDriver() noexcept
00036 {
00037
00038
00039 size_t listSize = generator_list_.size();
00040 while (listSize > 0)
00041 {
00042 --listSize;
00043 try
00044 {
00045 generator_list_.resize(listSize);
00046 }
00047 catch (...)
00048 {
00049 TLOG_ERROR("CompositeDriver")
00050 << "Unknown exception when destructing the generator at index "
00051 << (listSize + 1) << TLOG_ENDL;
00052 }
00053 }
00054 }
00055
00056 void artdaq::CompositeDriver::start()
00057 {
00058 for (size_t idx = 0; idx < generator_active_list_.size(); ++idx)
00059 {
00060 generator_active_list_[idx] = true;
00061 }
00062 for (auto& generator : generator_list_)
00063 {
00064 generator->StartCmd(run_number(), timeout(), timestamp());
00065 }
00066 }
00067
00068 void artdaq::CompositeDriver::stopNoMutex()
00069 {
00070 std::vector<std::unique_ptr<CommandableFragmentGenerator>>::reverse_iterator riter;
00071 for (riter = generator_list_.rbegin(); riter != generator_list_.rend(); ++riter)
00072 {
00073 (*riter)->StopCmd(timeout(), timestamp());
00074 }
00075 }
00076
00077 void artdaq::CompositeDriver::stop()
00078 {
00079
00080
00081
00082
00083
00084
00085
00086 }
00087
00088 void artdaq::CompositeDriver::pause()
00089 {
00090 std::vector<std::unique_ptr<CommandableFragmentGenerator>>::reverse_iterator riter;
00091 for (riter = generator_list_.rbegin(); riter != generator_list_.rend(); ++riter)
00092 {
00093 (*riter)->PauseCmd(timeout(), timestamp());
00094 }
00095 }
00096
00097 void artdaq::CompositeDriver::resume()
00098 {
00099 for (size_t idx = 0; idx < generator_active_list_.size(); ++idx)
00100 {
00101 generator_active_list_[idx] = true;
00102 }
00103 for (auto& generator : generator_list_)
00104 {
00105 generator->ResumeCmd(timeout(), timestamp());
00106 }
00107 }
00108
00109 std::vector<artdaq::Fragment::fragment_id_t> artdaq::CompositeDriver::fragmentIDs()
00110 {
00111 std::vector<artdaq::Fragment::fragment_id_t> workList;
00112 for (size_t idx = 0; idx < generator_list_.size(); ++idx)
00113 {
00114 std::vector<artdaq::Fragment::fragment_id_t> tempList =
00115 generator_list_[idx]->fragmentIDs();
00116 workList.insert(workList.end(), tempList.begin(), tempList.end());
00117 }
00118 return workList;
00119 }
00120
00121 bool artdaq::CompositeDriver::getNext_(artdaq::FragmentPtrs& frags)
00122 {
00123 bool anyGeneratorIsActive = false;
00124 for (size_t idx = 0; idx < generator_list_.size(); ++idx)
00125 {
00126 if (generator_active_list_[idx])
00127 {
00128 bool status = generator_list_[idx]->getNext(frags);
00129
00130
00131
00132
00133
00134
00135
00136
00137 if (! status && generator_list_[idx]->exception())
00138 {
00139 std::string reportString =
00140 generator_list_[idx]->ReportCmd("latest_exception");
00141 if (std::string::npos !=
00142 boost::algorithm::to_lower_copy(reportString).find("exception"))
00143 {
00144 throw cet::exception("CompositeDriver_generator")
00145 << "The FragmentGenerator for "
00146 << generator_list_[idx]->metricsReportingInstanceName()
00147 << " threw an exception: " << reportString;
00148 }
00149 else
00150 {
00151 throw cet::exception("CompositeDriver_generator")
00152 << "The FragmentGenerator for "
00153 << generator_list_[idx]->metricsReportingInstanceName()
00154 << " threw an exception.";
00155 }
00156 }
00157 generator_active_list_[idx] = status;
00158 if (status) { anyGeneratorIsActive = true; }
00159 }
00160 }
00161 return anyGeneratorIsActive;
00162 }
00163
00164 bool artdaq::CompositeDriver::makeChildGenerator_(fhicl::ParameterSet const& pset)
00165 {
00166
00167 fhicl::ParameterSet daq_pset;
00168 try
00169 {
00170 daq_pset = pset.get<fhicl::ParameterSet>("daq");
00171 }
00172 catch (...)
00173 {
00174 TLOG_ERROR("CompositeDriver::makeChildGenerator_")
00175 << "Unable to find the DAQ parameters in the initialization "
00176 << "ParameterSet: \"" + pset.to_string() + "\"." << TLOG_ENDL;
00177 return false;
00178 }
00179 fhicl::ParameterSet fr_pset;
00180 try
00181 {
00182 fr_pset = daq_pset.get<fhicl::ParameterSet>("fragment_receiver");
00183 }
00184 catch (...)
00185 {
00186 TLOG_ERROR("CompositeDriver::makeChildGenerator_")
00187 << "Unable to find the fragment_receiver parameters in the DAQ "
00188 << "initialization ParameterSet: \"" + daq_pset.to_string() + "\"." << TLOG_ENDL;
00189 return false;
00190 }
00191
00192
00193 std::string frag_gen_name = fr_pset.get<std::string>("generator", "");
00194 if (frag_gen_name.length() == 0)
00195 {
00196 TLOG_ERROR("CompositeDriver::makeChildGenerator_")
00197 << "No fragment generator (parameter name = \"generator\") was "
00198 << "specified in the fragment_receiver ParameterSet. The "
00199 << "DAQ initialization PSet was \"" << daq_pset.to_string() << "\"." << TLOG_ENDL;
00200 return false;
00201 }
00202
00203 std::unique_ptr<artdaq::CommandableFragmentGenerator> tmp_gen_ptr;
00204 try
00205 {
00206 tmp_gen_ptr = artdaq::makeCommandableFragmentGenerator(frag_gen_name, fr_pset);
00207 }
00208 catch (art::Exception& excpt)
00209 {
00210 TLOG_ERROR("CompositeDriver::makeChildGenerator_")
00211 << "Exception creating a FragmentGenerator of type \""
00212 << frag_gen_name << "\" with parameter set \"" << fr_pset.to_string()
00213 << "\", exception = " << excpt << TLOG_ENDL;
00214 return false;
00215 }
00216 catch (cet::exception& excpt)
00217 {
00218 TLOG_ERROR("CompositeDriver::makeChildGenerator_")
00219 << "Exception creating a FragmentGenerator of type \""
00220 << frag_gen_name << "\" with parameter set \"" << fr_pset.to_string()
00221 << "\", exception = " << excpt << TLOG_ENDL;
00222 return false;
00223 }
00224 catch (...)
00225 {
00226 TLOG_ERROR("CompositeDriver::makeChildGenerator_")
00227 << "Unknown exception creating a FragmentGenerator of type \""
00228 << frag_gen_name << "\" with parameter set \"" << fr_pset.to_string()
00229 << "\"." << TLOG_ENDL;
00230 return false;
00231 }
00232
00233 std::unique_ptr<CommandableFragmentGenerator> generator_ptr;
00234 generator_ptr.reset(nullptr);
00235 try
00236 {
00237 CommandableFragmentGenerator* tmp_cmdablegen_bareptr =
00238 dynamic_cast<CommandableFragmentGenerator*>(tmp_gen_ptr.get());
00239 if (tmp_cmdablegen_bareptr)
00240 {
00241 tmp_gen_ptr.release();
00242 generator_ptr.reset(tmp_cmdablegen_bareptr);
00243 }
00244 }
00245 catch (...) {}
00246 if (! generator_ptr)
00247 {
00248 TLOG_ERROR("CompositeDriver::makeChildGenerator_")
00249 << "Error: The requested fragment generator type (" << frag_gen_name
00250 << ") is not a CommandableFragmentGenerator, and only "
00251 << "CommandableFragmentGenerators are currently supported." << TLOG_ENDL;
00252 return false;
00253 }
00254
00255 generator_list_.push_back(std::move(generator_ptr));
00256 generator_active_list_.push_back(true);
00257 return true;
00258 }
00259
00260 DEFINE_ARTDAQ_COMMANDABLE_GENERATOR(artdaq::CompositeDriver)