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

Generated by: LCOV version 2.0-1