artdaq  v2_03_02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
CompositeDriver_generator.cc
1 #include "artdaq/Application/CompositeDriver.hh"
2 
3 #include "artdaq/Application/GeneratorMacros.hh"
4 #include "artdaq/Application/makeCommandableFragmentGenerator.hh"
5 #include "canvas/Utilities/Exception.h"
6 #include "cetlib/exception.h"
7 #include <boost/algorithm/string.hpp>
8 
9 using fhicl::ParameterSet;
10 
13 {
14  std::vector<ParameterSet> psetList =
15  ps.get<std::vector<ParameterSet>>("generator_config_list");
16  for (auto pset : psetList)
17  {
18  if (! makeChildGenerator_(pset))
19  {
20  throw cet::exception("CompositeDriver")
21  << "Unable to create child generator for PSet= \""
22  << pset.to_string() << "\"";
23  }
24  }
25 
26  std::string compositeMetricName;
27  for (auto& generator : generator_list_)
28  {
29  if (compositeMetricName.length() > 0) { compositeMetricName.append(", "); }
30  compositeMetricName.append(generator->metricsReportingInstanceName());
31  }
32  this->metricsReportingInstanceName(compositeMetricName);
33 }
34 
36 {
37  // 15-Feb-2014, KAB - explicitly destruct the generators so that
38  // we can control the order in which they are destructed
39  size_t listSize = generator_list_.size();
40  while (listSize > 0)
41  {
42  --listSize;
43  try
44  {
45  generator_list_.resize(listSize);
46  }
47  catch (...)
48  {
49  TLOG_ERROR("CompositeDriver")
50  << "Unknown exception when destructing the generator at index "
51  << (listSize + 1) << TLOG_ENDL;
52  }
53  }
54 }
55 
57 {
58  for (size_t idx = 0; idx < generator_active_list_.size(); ++idx)
59  {
60  generator_active_list_[idx] = true;
61  }
62  for (auto& generator : generator_list_)
63  {
64  generator->StartCmd(run_number(), timeout(), timestamp());
65  }
66 }
67 
69 {
70  std::vector<std::unique_ptr<CommandableFragmentGenerator>>::reverse_iterator riter;
71  for (riter = generator_list_.rbegin(); riter != generator_list_.rend(); ++riter)
72  {
73  (*riter)->StopCmd(timeout(), timestamp());
74  }
75 }
76 
78 {
79  // 02/17/16 ELF: This logic is now handled in stopNoMutex
80  /*
81  std::vector<std::unique_ptr<CommandableFragmentGenerator>>::reverse_iterator riter;
82  for (riter = generator_list_.rbegin(); riter != generator_list_.rend(); ++riter) {
83  (*riter)->StopCmd( timeout(), timestamp() );
84  }
85  */
86 }
87 
89 {
90  std::vector<std::unique_ptr<CommandableFragmentGenerator>>::reverse_iterator riter;
91  for (riter = generator_list_.rbegin(); riter != generator_list_.rend(); ++riter)
92  {
93  (*riter)->PauseCmd(timeout(), timestamp());
94  }
95 }
96 
98 {
99  for (size_t idx = 0; idx < generator_active_list_.size(); ++idx)
100  {
101  generator_active_list_[idx] = true;
102  }
103  for (auto& generator : generator_list_)
104  {
105  generator->ResumeCmd(timeout(), timestamp());
106  }
107 }
108 
109 std::vector<artdaq::Fragment::fragment_id_t> artdaq::CompositeDriver::fragmentIDs()
110 {
111  std::vector<artdaq::Fragment::fragment_id_t> workList;
112  for (size_t idx = 0; idx < generator_list_.size(); ++idx)
113  {
114  std::vector<artdaq::Fragment::fragment_id_t> tempList =
115  generator_list_[idx]->fragmentIDs();
116  workList.insert(workList.end(), tempList.begin(), tempList.end());
117  }
118  return workList;
119 }
120 
121 bool artdaq::CompositeDriver::getNext_(artdaq::FragmentPtrs& frags)
122 {
123  bool anyGeneratorIsActive = false;
124  for (size_t idx = 0; idx < generator_list_.size(); ++idx)
125  {
126  if (generator_active_list_[idx])
127  {
128  bool status = generator_list_[idx]->getNext(frags);
129 
130  // 08-May-2015, KAB & JCF: if the generator getNext() method returns
131  // false (which indicates that the data flow has stopped) *and* the
132  // reason that it has stopped is because there was an exception that
133  // wasn't handled by the experiment-specific FragmentGenerator class,
134  // we throw an exception so that the process will move to the
135  // InRunError state. We do our best to try to reproduce the original
136  // exception message.
137  if (! status && generator_list_[idx]->exception())
138  {
139  std::string reportString =
140  generator_list_[idx]->ReportCmd("latest_exception");
141  if (std::string::npos !=
142  boost::algorithm::to_lower_copy(reportString).find("exception"))
143  {
144  throw cet::exception("CompositeDriver_generator")
145  << "The FragmentGenerator for "
146  << generator_list_[idx]->metricsReportingInstanceName()
147  << " threw an exception: " << reportString;
148  }
149  else
150  {
151  throw cet::exception("CompositeDriver_generator")
152  << "The FragmentGenerator for "
153  << generator_list_[idx]->metricsReportingInstanceName()
154  << " threw an exception.";
155  }
156  }
157  generator_active_list_[idx] = status;
158  if (status) { anyGeneratorIsActive = true; }
159  }
160  }
161  return anyGeneratorIsActive;
162 }
163 
164 bool artdaq::CompositeDriver::makeChildGenerator_(fhicl::ParameterSet const& pset)
165 {
166  // pull out the relevant parts of the ParameterSet
167  fhicl::ParameterSet daq_pset;
168  try
169  {
170  daq_pset = pset.get<fhicl::ParameterSet>("daq");
171  }
172  catch (...)
173  {
174  TLOG_ERROR("CompositeDriver::makeChildGenerator_")
175  << "Unable to find the DAQ parameters in the initialization "
176  << "ParameterSet: \"" + pset.to_string() + "\"." << TLOG_ENDL;
177  return false;
178  }
179  fhicl::ParameterSet fr_pset;
180  try
181  {
182  fr_pset = daq_pset.get<fhicl::ParameterSet>("fragment_receiver");
183  }
184  catch (...)
185  {
186  TLOG_ERROR("CompositeDriver::makeChildGenerator_")
187  << "Unable to find the fragment_receiver parameters in the DAQ "
188  << "initialization ParameterSet: \"" + daq_pset.to_string() + "\"." << TLOG_ENDL;
189  return false;
190  }
191 
192  // create the requested FragmentGenerator
193  std::string frag_gen_name = fr_pset.get<std::string>("generator", "");
194  if (frag_gen_name.length() == 0)
195  {
196  TLOG_ERROR("CompositeDriver::makeChildGenerator_")
197  << "No fragment generator (parameter name = \"generator\") was "
198  << "specified in the fragment_receiver ParameterSet. The "
199  << "DAQ initialization PSet was \"" << daq_pset.to_string() << "\"." << TLOG_ENDL;
200  return false;
201  }
202 
203  std::unique_ptr<artdaq::CommandableFragmentGenerator> tmp_gen_ptr;
204  try
205  {
206  tmp_gen_ptr = artdaq::makeCommandableFragmentGenerator(frag_gen_name, fr_pset);
207  }
208  catch (art::Exception& excpt)
209  {
210  TLOG_ERROR("CompositeDriver::makeChildGenerator_")
211  << "Exception creating a FragmentGenerator of type \""
212  << frag_gen_name << "\" with parameter set \"" << fr_pset.to_string()
213  << "\", exception = " << excpt << TLOG_ENDL;
214  return false;
215  }
216  catch (cet::exception& excpt)
217  {
218  TLOG_ERROR("CompositeDriver::makeChildGenerator_")
219  << "Exception creating a FragmentGenerator of type \""
220  << frag_gen_name << "\" with parameter set \"" << fr_pset.to_string()
221  << "\", exception = " << excpt << TLOG_ENDL;
222  return false;
223  }
224  catch (...)
225  {
226  TLOG_ERROR("CompositeDriver::makeChildGenerator_")
227  << "Unknown exception creating a FragmentGenerator of type \""
228  << frag_gen_name << "\" with parameter set \"" << fr_pset.to_string()
229  << "\"." << TLOG_ENDL;
230  return false;
231  }
232 
233  std::unique_ptr<CommandableFragmentGenerator> generator_ptr;
234  generator_ptr.reset(nullptr);
235  try
236  {
237  CommandableFragmentGenerator* tmp_cmdablegen_bareptr =
238  dynamic_cast<CommandableFragmentGenerator*>(tmp_gen_ptr.get());
239  if (tmp_cmdablegen_bareptr)
240  {
241  tmp_gen_ptr.release();
242  generator_ptr.reset(tmp_cmdablegen_bareptr);
243  }
244  }
245  catch (...) {}
246  if (! generator_ptr)
247  {
248  TLOG_ERROR("CompositeDriver::makeChildGenerator_")
249  << "Error: The requested fragment generator type (" << frag_gen_name
250  << ") is not a CommandableFragmentGenerator, and only "
251  << "CommandableFragmentGenerators are currently supported." << TLOG_ENDL;
252  return false;
253  }
254 
255  generator_list_.push_back(std::move(generator_ptr));
256  generator_active_list_.push_back(true);
257  return true;
258 }
259 
260 DEFINE_ARTDAQ_COMMANDABLE_GENERATOR(artdaq::CompositeDriver)
void start() override
Start all configured CommandableFragmentGenerators.
virtual ~CompositeDriver() noexcept
Destructor. Calls the destructors for each configured CommandableFragmentGenerator.
CompositeDriver handles a set of lower-level generators.
void pause() override
Pause all configured CommandableFragmentGenerators.
std::unique_ptr< CommandableFragmentGenerator > makeCommandableFragmentGenerator(std::string const &generator_plugin_spec, fhicl::ParameterSet const &ps)
Load a CommandableFragmentGenerator plugin.
virtual std::string metricsReportingInstanceName() const
Get the name used when reporting metrics.
void stop() override
Call stop methods for all configured CommandableFragmentGenerators. Currently handled by stopNoMutex...
CommandableFragmentGenerator is a FragmentGenerator-derived abstract class that defines the interface...
CompositeDriver(fhicl::ParameterSet const &ps)
CompositeDriver Constructor.
void resume() override
Resume all configured CommandableFragmentGenerators.
void stopNoMutex() override
Call non-locked stop methods for all configured CommandableFragmentGenerators.