$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_01
$projectbrief
|
$projectbrief
|
$searchbox |
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 // 15-Feb-2014, KAB - explicitly destruct the generators so that 00040 // we can control the order in which they are destructed 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 // 02/17/16 ELF: This logic is now handled in stopNoMutex 00082 /* 00083 std::vector<std::unique_ptr<CommandableFragmentGenerator>>::reverse_iterator riter; 00084 for (riter = generator_list_.rbegin(); riter != generator_list_.rend(); ++riter) { 00085 (*riter)->StopCmd( timeout(), timestamp() ); 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 // 08-May-2015, KAB & JCF: if the generator getNext() method returns 00133 // false (which indicates that the data flow has stopped) *and* the 00134 // reason that it has stopped is because there was an exception that 00135 // wasn't handled by the experiment-specific FragmentGenerator class, 00136 // we throw an exception so that the process will move to the 00137 // InRunError state. We do our best to try to reproduce the original 00138 // exception message. 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 // pull out the relevant parts of the ParameterSet 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 // create the requested FragmentGenerator 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)