LCOV - code coverage report
Current view: top level - appmodel/src - MLTApplication.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 148 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 3 0

            Line data    Source code
       1              : /**
       2              :  * @file MLTApplication.cpp
       3              :  *
       4              :  * Implementation of MLTApplication's generate_modules dal method
       5              :  *
       6              :  * This is part of the DUNE DAQ Software Suite, copyright 2023.
       7              :  * Licensing/copyright details are in the COPYING file that you should have
       8              :  * received with this code.
       9              :  */
      10              : 
      11              : #include "ConfigObjectFactory.hpp"
      12              : 
      13              : #include "appmodel/ConfigurationHelper.hpp"
      14              : #include "conffwk/Configuration.hpp"
      15              : 
      16              : #include "confmodel/Connection.hpp"
      17              : #include "confmodel/NetworkConnection.hpp"
      18              : 
      19              : #include "appmodel/CIBApplication.hpp"
      20              : #include "appmodel/CTBApplication.hpp"
      21              : #include "appmodel/DataHandlerConf.hpp"
      22              : #include "appmodel/DataHandlerModule.hpp"
      23              : #include "appmodel/DataReaderConf.hpp"
      24              : #include "appmodel/DataRecorderConf.hpp"
      25              : #include "appmodel/DataSubscriberModule.hpp"
      26              : #include "appmodel/FakeDataApplication.hpp"
      27              : #include "appmodel/FakeDataProdConf.hpp"
      28              : #include "appmodel/MLTApplication.hpp"
      29              : #include "appmodel/MLTConf.hpp"
      30              : #include "appmodel/MLTModule.hpp"
      31              : #include "appmodel/NetworkConnectionDescriptor.hpp"
      32              : #include "appmodel/NetworkConnectionRule.hpp"
      33              : #include "appmodel/QueueConnectionRule.hpp"
      34              : #include "appmodel/QueueDescriptor.hpp"
      35              : #include "appmodel/SourceIDConf.hpp"
      36              : #include "appmodel/StandaloneTCMakerConf.hpp"
      37              : #include "appmodel/StandaloneTCMakerModule.hpp"
      38              : #include "appmodel/TCDataProcessor.hpp"
      39              : #include "appmodel/TPStreamConf.hpp"
      40              : #include "appmodel/TriggerApplication.hpp"
      41              : #include "appmodel/appmodelIssues.hpp"
      42              : 
      43              : #include "logging/Logging.hpp"
      44              : 
      45              : #include <string>
      46              : #include <vector>
      47              : 
      48              : namespace dunedaq {
      49              : namespace appmodel {
      50              : 
      51              : void
      52            0 : MLTApplication::generate_modules(std::shared_ptr<appmodel::ConfigurationHelper> helper) const
      53              : {
      54            0 :   std::vector<const confmodel::DaqModule*> modules;
      55              : 
      56            0 :   ConfigObjectFactory obj_fac(this);
      57              : 
      58              :   // auto mlt_conf = get_mlt_conf();
      59              :   // auto mlt_class = mlt_conf->get_template_for();
      60              : 
      61            0 :   auto tch_conf = get_trigger_inputs_handler();
      62            0 :   auto tch_class = tch_conf->get_template_for();
      63              : 
      64            0 :   auto mlt_conf = get_mlt_conf();
      65            0 :   auto mlt_class = mlt_conf->get_template_for();
      66            0 :   std::string handler_name(tch_conf->UID());
      67              : 
      68            0 :   if (!mlt_conf) {
      69              :     throw(BadConf(ERS_HERE, "No MLT configuration in MLTApplication given"));
      70              :   }
      71              : 
      72              :   // Queue descriptors
      73              :   // Process the queue rules looking for inputs to our trigger handler modules
      74            0 :   const QueueDescriptor* tc_inputq_desc = nullptr;
      75            0 :   const QueueDescriptor* td_outputq_desc = nullptr;
      76              : 
      77            0 :   for (auto rule : get_queue_rules()) {
      78            0 :     auto destination_class = rule->get_destination_class();
      79            0 :     auto data_type = rule->get_descriptor()->get_data_type();
      80            0 :     if (destination_class == tch_class) {
      81            0 :       tc_inputq_desc = rule->get_descriptor();
      82            0 :     } else if (destination_class == mlt_class) {
      83            0 :       td_outputq_desc = rule->get_descriptor();
      84              :     }
      85            0 :   }
      86              : 
      87            0 :   if (tc_inputq_desc == nullptr) {
      88            0 :     throw(BadConf(ERS_HERE, "No TC input queue descriptor given"));
      89              :   }
      90            0 :   if (td_outputq_desc == nullptr) {
      91            0 :     throw(BadConf(ERS_HERE, "No TD output-input queue descriptor given"));
      92              :   }
      93              : 
      94              :   // Create queues
      95            0 :   auto input_queue_obj = obj_fac.create_queue_obj(tc_inputq_desc);
      96            0 :   auto output_queue_obj = obj_fac.create_queue_obj(td_outputq_desc);
      97              : 
      98              :   // Net descriptors
      99            0 :   const NetworkConnectionDescriptor* req_net_desc = nullptr;
     100            0 :   const NetworkConnectionDescriptor* tc_net_desc = nullptr;
     101            0 :   const NetworkConnectionDescriptor* ti_net_desc = nullptr;
     102            0 :   const NetworkConnectionDescriptor* td_net_desc = nullptr;
     103            0 :   const NetworkConnectionDescriptor* timesync_net_desc = nullptr;
     104              : 
     105            0 :   for (auto rule : get_network_rules()) {
     106            0 :     std::string data_type = rule->get_descriptor()->get_data_type();
     107              : 
     108              :     // Network connections for the MLT
     109            0 :     if (data_type == "TriggerInhibit") {
     110            0 :       ti_net_desc = rule->get_descriptor();
     111              :     }
     112            0 :     if (data_type == "TriggerDecision") {
     113            0 :       td_net_desc = rule->get_descriptor();
     114              :     }
     115            0 :     if (data_type == "TriggerCandidate") {
     116            0 :       tc_net_desc = rule->get_descriptor();
     117              :     }
     118            0 :     if (data_type == "TimeSync") {
     119            0 :       timesync_net_desc = rule->get_descriptor();
     120              :     }
     121            0 :     if (data_type == "DataRequest") {
     122            0 :       req_net_desc = rule->get_descriptor();
     123              :     }
     124              : 
     125            0 :     TLOG_DEBUG(3) << "Endpoint class (currently not used in for networkconnections): data_type: " << data_type;
     126            0 :   }
     127              : 
     128            0 :   if (!td_net_desc) {
     129            0 :     throw(BadConf(ERS_HERE, "No MLT network connection for the output TriggerDecision given"));
     130              :   }
     131            0 :   if (!ti_net_desc) {
     132            0 :     throw(BadConf(ERS_HERE, "No MLT network connection for the output TriggerInhibit given"));
     133              :   }
     134            0 :   if (!tc_net_desc) {
     135            0 :     throw(BadConf(ERS_HERE, "No MLT network connection for the Input of TriggerCandidates given"));
     136              :   }
     137            0 :   if (!req_net_desc) {
     138            0 :     throw(BadConf(ERS_HERE, "No MLT network connection for the Input of DataRequests given"));
     139              :   }
     140              :   // Network connection for input TriggerInhibit, input TCs
     141              : 
     142            0 :   conffwk::ConfigObject ti_net_obj = obj_fac.create_net_obj(ti_net_desc, "");
     143              : 
     144            0 :   conffwk::ConfigObject tc_net_obj = obj_fac.create_net_obj(tc_net_desc, ".*");
     145              : 
     146              :   // Network connection for output TriggerDecision
     147            0 :   conffwk::ConfigObject td_net_obj = obj_fac.create_net_obj(td_net_desc, "");
     148              : 
     149              :   // Network conection for the input Data Requests
     150            0 :   conffwk::ConfigObject dr_net_obj = obj_fac.create_net_obj(req_net_desc, UID());
     151              : 
     152            0 :   conffwk::ConfigObject timesync_net_obj;
     153            0 :   if (timesync_net_desc != nullptr) {
     154            0 :     timesync_net_obj = obj_fac.create_net_obj(timesync_net_desc, ".*");
     155              :   }
     156              : 
     157              :   /**************************************************************
     158              :    * Instantiate standalone TC generator modules (e.g. random TC generator)
     159              :    **************************************************************/
     160              : 
     161            0 :   auto standalone_TC_maker_confs = get_standalone_candidate_maker_confs();
     162            0 :   std::vector<conffwk::ConfigObject> generated_tc_conns;
     163            0 :   generated_tc_conns.reserve(standalone_TC_maker_confs.size());
     164            0 :   for (auto gen_conf : standalone_TC_maker_confs) {
     165            0 :     conffwk::ConfigObject gen_obj = obj_fac.create(gen_conf->get_template_for(), gen_conf->UID());
     166            0 :     gen_obj.set_obj("configuration", &(gen_conf->config_object()));
     167            0 :     if (gen_conf->get_timestamp_method() == "kTimeSync" && !timesync_net_obj.is_null()) {
     168            0 :       gen_obj.set_objs("inputs", { &timesync_net_obj });
     169              :     }
     170              : 
     171            0 :     auto tc_net_gen = obj_fac.create_net_obj(tc_net_desc, gen_conf->UID());
     172            0 :     generated_tc_conns.push_back(tc_net_gen);
     173              : 
     174            0 :     gen_obj.set_objs("outputs", { &generated_tc_conns.back() });
     175            0 :     modules.push_back(obj_fac.get_dal<StandaloneTCMakerModule>(gen_conf->UID()));
     176            0 :   }
     177              : 
     178              :   /**************************************************************
     179              :    * Create the Data Reader
     180              :    **************************************************************/
     181            0 :   auto rdr_conf = get_data_subscriber();
     182            0 :   if (rdr_conf == nullptr) {
     183              :     throw(BadConf(ERS_HERE, "No DataReaderModule configuration given"));
     184              :   }
     185              : 
     186            0 :   std::string reader_uid("data-reader-" + UID());
     187            0 :   std::string reader_class = rdr_conf->get_template_for();
     188            0 :   TLOG_DEBUG(7) << "creating OKS configuration object for Data subscriber class " << reader_class;
     189            0 :   conffwk::ConfigObject reader_obj = obj_fac.create(reader_class, reader_uid);
     190            0 :   reader_obj.set_objs("inputs", { &tc_net_obj });
     191            0 :   reader_obj.set_objs("outputs", { &input_queue_obj });
     192            0 :   reader_obj.set_obj("configuration", &rdr_conf->config_object());
     193              : 
     194            0 :   modules.push_back(obj_fac.get_dal<DataSubscriberModule>(reader_uid));
     195              : 
     196              :   /**************************************************************
     197              :    * Create the readout map
     198              :    **************************************************************/
     199              : 
     200            0 :   std::vector<const conffwk::ConfigObject*> sourceIds;
     201            0 :   for (auto [uid, source_ids] : helper->get_stream_source_ids()) {
     202            0 :     for (auto src_id : source_ids) {
     203              :       // Create SourceIDConf object for the MLT
     204            0 :       std::string sourceIdConfUID = "dro-mlt-stream-config-" + std::to_string(src_id);
     205            0 :       conffwk::ConfigObject* sourceIdConf = new conffwk::ConfigObject(obj_fac.create("SourceIDConf", sourceIdConfUID));
     206            0 :       sourceIdConf->set_by_val<uint32_t>("sid", src_id);
     207              :       // https://github.com/DUNE-DAQ/daqdataformats/blob/5b99506675a586c8a09123900e224f2371d96df9/include/daqdataformats/detail/SourceID.hxx#L108
     208            0 :       sourceIdConf->set_by_val<std::string>("subsystem", "Detector_Readout");
     209            0 :       sourceIds.push_back(sourceIdConf);
     210            0 :     }
     211            0 :   }
     212            0 :   for (auto [uid, source_ids] : helper->get_tp_source_ids()) {
     213            0 :     for (auto src_id : source_ids) {
     214            0 :       sourceIds.push_back(&(src_id->config_object()));
     215              :     }
     216            0 :   }
     217              : 
     218              :   // set the CTB sources
     219            0 :   for (const auto& [uid, sources] : helper->get_all_app_source_ids("CTBApplication")) {
     220            0 :     for (const auto& [source_name, source_conf] : sources) {
     221            0 :       auto final_name = uid;
     222            0 :       final_name += source_name.find("LLT") != std::string::npos ? "_LLT" : "_HLT";
     223            0 :       auto tcSourceIdConf = new conffwk::ConfigObject(obj_fac.create("SourceIDConf", final_name));
     224            0 :       tcSourceIdConf->set_by_val<uint32_t>("sid", source_conf->get_sid());
     225            0 :       tcSourceIdConf->set_by_val<std::string>("subsystem", source_conf->get_subsystem());
     226            0 :       sourceIds.push_back(tcSourceIdConf);
     227            0 :     }
     228            0 :   }
     229              : 
     230            0 :   for (auto app_class : { "TriggerApplication", "FakeHSIApplication", "DTSHSIApplication", "CIBApplication" }) {
     231            0 :     for (auto [uid, src_id] : helper->get_app_source_ids(app_class)) {
     232            0 :       auto tcSourceIdConf =
     233            0 :         new conffwk::ConfigObject(obj_fac.create("SourceIDConf", uid + "-" + std::to_string(src_id->get_sid())));
     234            0 :       tcSourceIdConf->set_by_val<uint32_t>("sid", src_id->get_sid());
     235            0 :       tcSourceIdConf->set_by_val<std::string>("subsystem", src_id->get_subsystem());
     236            0 :       sourceIds.push_back(tcSourceIdConf);
     237            0 :     }
     238              :   }
     239              : 
     240              :   // Get mandatory links
     241            0 :   std::vector<const conffwk::ConfigObject*> mandatory_sids;
     242            0 :   const TCDataProcessor* tc_dp = tch_conf->get_data_processor()->cast<TCDataProcessor>();
     243            0 :   if (tc_dp != nullptr) {
     244            0 :     for (auto m : tc_dp->get_mandatory_links()) {
     245            0 :       mandatory_sids.push_back(&m->config_object());
     246              :     }
     247              :   }
     248              : 
     249              :   /**************************************************************
     250              :    * Create the TC handler
     251              :    **************************************************************/
     252              : 
     253              :   // Process special Network rules!
     254              :   // Looking for Fragment rules from DFAppplications in current Session
     255              : 
     256              :   // auto sessionApps = session->get_included_applications();
     257              :   // std::vector<conffwk::ConfigObject> fragOutObjs;
     258              :   // for (auto app : sessionApps) {
     259              :   //   auto dfapp = app->cast<appmodel::DFApplication>();
     260              :   //   if (dfapp == nullptr)
     261              :   //     continue;
     262              : 
     263              :   //   auto dfNRules = dfapp->get_network_rules();
     264              :   //   for (auto rule : dfNRules) {
     265              :   //     auto descriptor = rule->get_descriptor();
     266              :   //     auto data_type = descriptor->get_data_type();
     267              :   //     if (data_type == "Fragment") {
     268              :   //       std::string dreqNetUid(descriptor->get_uid_base() + dfapp->UID());
     269              :   //       conffwk::ConfigObject frag_conn;
     270              :   //       confdb->create(dbfile, "NetworkConnection", dreqNetUid, frag_conn);
     271              : 
     272              :   //       frag_conn.set_by_val<std::string>("data_type", descriptor->get_data_type());
     273              :   //       frag_conn.set_by_val<std::string>("connection_type", descriptor->get_connection_type());
     274              : 
     275              :   //       auto serviceObj = descriptor->get_associated_service()->config_object();
     276              :   //       frag_conn.set_obj("associated_service", &serviceObj);
     277              :   //       fragOutObjs.push_back(frag_conn);
     278              :   //     } // If network rule has TriggerDecision type of data
     279              :   //   }   // Loop over Apps network rules
     280              :   // }     // loop over Session specific Apps
     281              : 
     282            0 :   std::vector<conffwk::ConfigObject> fragOutObjs;
     283            0 :   for (auto [uid, descriptor] : helper->get_netdescriptors("Fragment", "DFApplication")) {
     284            0 :     fragOutObjs.emplace_back(obj_fac.create_net_obj(descriptor, uid));
     285            0 :   }
     286              : 
     287              :   // build up the full list of outputs
     288            0 :   std::vector<const conffwk::ConfigObject*> ti_output_objs;
     289            0 :   for (auto& fNet : fragOutObjs) {
     290            0 :     ti_output_objs.push_back(&fNet);
     291              :   }
     292            0 :   ti_output_objs.push_back(&output_queue_obj);
     293              : 
     294            0 :   auto tch_conf_obj = tch_conf->config_object();
     295            0 :   if (get_source_id() == nullptr) {
     296            0 :     throw(BadConf(ERS_HERE, "No source_id associated with this TriggerApplication!"));
     297              :   }
     298            0 :   uint32_t source_id = get_source_id()->get_sid();
     299            0 :   std::string ti_uid(handler_name + "-" + std::to_string(source_id));
     300            0 :   conffwk::ConfigObject ti_obj = obj_fac.create(tch_class, ti_uid);
     301            0 :   ti_obj.set_by_val<uint32_t>("source_id", source_id);
     302            0 :   ti_obj.set_by_val<uint32_t>("detector_id", 1); // 1 == kDAQ
     303            0 :   ti_obj.set_obj("module_configuration", &tch_conf_obj);
     304            0 :   ti_obj.set_objs("enabled_source_ids", sourceIds);
     305            0 :   ti_obj.set_objs("mandatory_source_ids", mandatory_sids);
     306            0 :   ti_obj.set_objs("inputs", { &input_queue_obj, &dr_net_obj });
     307            0 :   ti_obj.set_objs("outputs", ti_output_objs);
     308              : 
     309              :   // Add to our list of modules to return
     310            0 :   modules.push_back(obj_fac.get_dal<DataHandlerModule>(ti_uid));
     311              : 
     312              :   /**************************************************************
     313              :    * Instantiate the MLTModule module
     314              :    **************************************************************/
     315              : 
     316            0 :   conffwk::ConfigObject mlt_obj = obj_fac.create(mlt_conf->get_template_for(), mlt_conf->UID());
     317            0 :   mlt_obj.set_obj("configuration", &(mlt_conf->config_object()));
     318            0 :   mlt_obj.set_objs("inputs", { &output_queue_obj, &ti_net_obj });
     319            0 :   mlt_obj.set_objs("outputs", { &td_net_obj });
     320            0 :   modules.push_back(obj_fac.get_dal<MLTModule>(mlt_conf->UID()));
     321              : 
     322            0 :   obj_fac.update_modules(modules);
     323            0 : }
     324              : 
     325              : } // namespace appmodel
     326              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1