LCOV - code coverage report
Current view: top level - artdaq/Generators - CompositeDriver_generator.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 0.0 % 124 0
Test Date: 2025-09-04 00:45:34 Functions: 0.0 % 18 0

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

Generated by: LCOV version 2.0-1