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