LCOV - code coverage report
Current view: top level - appmodel/src - DFApplication.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 211 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 5 0

            Line data    Source code
       1              : /**
       2              :  * @file DFApplication.cpp
       3              :  *
       4              :  * Implementation of DFApplication'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              : #include "appmodel/DFApplication.hpp"
      14              : #include "appmodel/CTBApplication.hpp"
      15              : #include "appmodel/DataStoreConf.hpp"
      16              : #include "appmodel/DataWriterConf.hpp"
      17              : #include "appmodel/DataWriterModule.hpp"
      18              : #include "appmodel/FakeDataApplication.hpp"
      19              : #include "appmodel/FakeDataProdConf.hpp"
      20              : #include "appmodel/FilenameParams.hpp"
      21              : #include "appmodel/NetworkConnectionDescriptor.hpp"
      22              : #include "appmodel/NetworkConnectionRule.hpp"
      23              : #include "appmodel/QueueConnectionRule.hpp"
      24              : #include "appmodel/QueueDescriptor.hpp"
      25              : #include "appmodel/ReadoutApplication.hpp"
      26              : #include "appmodel/SourceIDConf.hpp"
      27              : #include "appmodel/TPStreamConf.hpp"
      28              : #include "appmodel/TRBConf.hpp"
      29              : #include "appmodel/TRBModule.hpp"
      30              : #include "appmodel/TPReplayModuleConf.hpp"
      31              : #include "appmodel/TPReplayApplication.hpp"
      32              : #include "appmodel/appmodelIssues.hpp"
      33              : 
      34              : #include "conffwk/Configuration.hpp"
      35              : 
      36              : #include "confmodel/Connection.hpp"
      37              : #include "confmodel/DetectorStream.hpp"
      38              : #include "confmodel/DetectorToDaqConnection.hpp"
      39              : #include "confmodel/NetworkConnection.hpp"
      40              : #include "confmodel/Service.hpp"
      41              : 
      42              : #include "logging/Logging.hpp"
      43              : #include "oks/kernel.hpp"
      44              : 
      45              : #include <fmt/core.h>
      46              : #include <string>
      47              : #include <vector>
      48              : 
      49              : namespace dunedaq {
      50              : namespace appmodel {
      51              : 
      52              : 
      53              : inline void
      54            0 : fill_sourceid_object_from_app(const SmartDaqApplication* smartapp,
      55              :                               const conffwk::ConfigObject* netConn,
      56              :                               conffwk::ConfigObject& sidNetObj)
      57              : {
      58            0 :   sidNetObj.set_obj("netconn", netConn);
      59            0 :   sidNetObj.set_objs("source_ids", { &smartapp->get_source_id()->config_object() });
      60            0 : }
      61              : 
      62              : 
      63              : inline void
      64            0 : fill_sourceid_object_from_app(const ConfigObjectFactory& obj_fac,
      65              :                               const TPReplayApplication* rapp,
      66              :                               std::vector<conffwk::ConfigObject>* netConn,
      67              :                               std::vector<conffwk::ConfigObject>* sidNetObj,
      68              :                               std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs,
      69              :                               const NetworkConnectionDescriptor* descriptor,
      70              :                               std::string smartapp_uid)
      71              : {
      72            0 :   std::vector<const conffwk::ConfigObject*> source_id_objs;
      73              : 
      74            0 :   for (auto tp_sid : rapp->get_tp_source_ids()) {
      75              :     // get name extension
      76            0 :     std::string name = tp_sid->UID();
      77            0 :     size_t pos = name.find_last_of('-');
      78            0 :     std::string ext;
      79            0 :     if (pos != std::string::npos) {
      80            0 :       ext = name.substr(pos);
      81              :     }
      82              : 
      83              :     // set Network connections
      84            0 :     std::string dreqNetUid(smartapp_uid + ext);
      85            0 :     netConn->emplace_back(
      86            0 :       obj_fac.create_net_obj(descriptor, dreqNetUid));
      87            0 :     netConn->back().set_by_val<std::string>("data_type", descriptor->get_data_type());
      88            0 :     netConn->back().set_by_val<std::string>("connection_type", descriptor->get_connection_type());
      89            0 :     auto serviceObj = descriptor->get_associated_service()->config_object();
      90            0 :     netConn->back().set_obj("associated_service", &serviceObj);
      91              : 
      92              :     // set SourceID to Network connections
      93            0 :     std::string sidToNetUid(smartapp_uid + ext + "-sids");
      94            0 :     sidNetObj->emplace_back(
      95            0 :       obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
      96            0 :     sidNetObj->back().set_obj("netconn", &netConn->back());
      97              : 
      98              :     // set SourceID objs
      99            0 :     sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(tp_sid->config_object()));
     100            0 :     sidNetObj->back().set_objs("source_ids", { sidObjs.back().get() });
     101            0 :   }
     102            0 : }
     103              :     
     104              : inline void
     105            0 : fill_sourceid_object_from_app(const ConfigObjectFactory& obj_fac,
     106              :                               const ReadoutApplication* roapp,
     107              :                               const conffwk::ConfigObject* netConn,
     108              :                               conffwk::ConfigObject& sidNetObj,
     109              :                               std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs)
     110              : {
     111            0 :   sidNetObj.set_obj("netconn", netConn);
     112              : 
     113            0 :   std::vector<const conffwk::ConfigObject*> source_id_objs;
     114            0 :   std::vector<uint32_t> app_source_ids;
     115              : 
     116            0 :   for (auto d2d_conn_res : roapp->get_detector_connections()) {
     117              : 
     118              :     // get the readout groups and the interfaces and streams therein; 1 reaout group corresponds to 1 data reader
     119              :     // module
     120            0 :     auto d2d_conn = d2d_conn_res->cast<confmodel::DetectorToDaqConnection>();
     121              : 
     122            0 :     if (!d2d_conn) {
     123            0 :       continue;
     124              :     }
     125              : 
     126              :     // Loop over senders
     127            0 :     for (auto dros : d2d_conn->streams()) {
     128              : 
     129            0 :       auto stream = dros->cast<confmodel::DetectorStream>();
     130            0 :       if (!stream)
     131            0 :         continue;
     132            0 :       app_source_ids.push_back(stream->get_source_id());
     133            0 :     }
     134              :   }
     135              : 
     136            0 :   for (auto& source_id : app_source_ids) {
     137            0 :     std::string streamSidUid(roapp->UID() + "SourceIDConf" + std::to_string(source_id));
     138            0 :     auto stream_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", streamSidUid));
     139            0 :     stream_sid_obj->set_by_val<uint32_t>("sid", source_id);
     140            0 :     stream_sid_obj->set_by_val<std::string>("subsystem", "Detector_Readout");
     141            0 :     sidObjs.push_back(stream_sid_obj);
     142            0 :     source_id_objs.push_back(sidObjs.back().get());
     143            0 :   }
     144              : 
     145            0 :   for (auto tp_sid : roapp->get_tp_source_ids()) {
     146            0 :     sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(tp_sid->config_object()));
     147            0 :     source_id_objs.push_back(sidObjs.back().get());
     148              :   }
     149              :   /*
     150              :   std::string trgSidUid(roapp->UID() + "TRGSourceIDConf" + std::to_string(roapp->get_tp_source_id()));
     151              :   auto trig_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", trgSidUid));
     152              :   trig_sid_obj->set_by_val<uint32_t>("sid", roapp->get_tp_source_id());
     153              :   trig_sid_obj->set_by_val<std::string>("subsystem", "Trigger");
     154              :   source_id_objs.push_back(sidObjs.back().get());
     155              :   */
     156              : 
     157            0 :   sidNetObj.set_objs("source_ids", source_id_objs);
     158            0 : }
     159              : 
     160              : inline void
     161            0 : fill_sourceid_object_from_app(const ConfigObjectFactory& obj_fac,
     162              :                               const FakeDataApplication* fdapp,
     163              :                               const conffwk::ConfigObject* netConn,
     164              :                               conffwk::ConfigObject& sidNetObj,
     165              :                               std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs)
     166              : {
     167            0 :   sidNetObj.set_obj("netconn", netConn);
     168              : 
     169            0 :   std::vector<const conffwk::ConfigObject*> source_id_objs;
     170            0 :   std::vector<uint32_t> app_source_ids;
     171              : 
     172            0 :   for (auto fdpc : fdapp->get_producers()) {
     173              : 
     174              :     // get the readout groups and the interfaces and streams therein; 1 reaout group corresponds to 1 data reader
     175              :     // module
     176              : 
     177            0 :     app_source_ids.push_back(fdpc->get_source_id());
     178              :   }
     179              : 
     180            0 :   for (auto& source_id : app_source_ids) {
     181            0 :     std::string streamSidUid(fdapp->UID() + "SourceIDConf" + std::to_string(source_id));
     182            0 :     auto stream_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", streamSidUid));
     183            0 :     stream_sid_obj->set_by_val<uint32_t>("sid", source_id);
     184            0 :     stream_sid_obj->set_by_val<std::string>("subsystem", "Detector_Readout");
     185            0 :     sidObjs.push_back(stream_sid_obj);
     186            0 :     source_id_objs.push_back(sidObjs.back().get());
     187            0 :   }
     188              : 
     189            0 :   sidNetObj.set_objs("source_ids", source_id_objs);
     190            0 : }
     191              : 
     192              : void
     193            0 : DFApplication::generate_modules(const confmodel::Session* session) const
     194              : {
     195              : 
     196            0 :   ConfigObjectFactory obj_fac(this);
     197              : 
     198            0 :   std::vector<const confmodel::DaqModule*> modules;
     199              : 
     200              :   // Containers for module specific config objects for output/input
     201              :   // Prepare TRB output objects
     202            0 :   std::vector<const conffwk::ConfigObject*> trbInputObjs;
     203            0 :   std::vector<const conffwk::ConfigObject*> trbOutputObjs;
     204            0 :   std::vector<const conffwk::ConfigObject*> trbSidNetObjs;
     205              : 
     206              :   // -- First, we process expected Queue and Network connections and create their objects.
     207              : 
     208              :   // Process the queue rules looking for the TriggerRecord queue between TRB and DataWriterModule
     209            0 :   const QueueDescriptor* trQDesc = nullptr;
     210            0 :   for (auto rule : get_queue_rules()) {
     211            0 :     auto destination_class = rule->get_destination_class();
     212            0 :     if (destination_class == "DataWriterModule") {
     213            0 :       trQDesc = rule->get_descriptor();
     214              :     }
     215            0 :   }
     216            0 :   if (trQDesc == nullptr) { // BadConf if no descriptor between TRB and DataWriterModule
     217            0 :     throw(BadConf(ERS_HERE, "Could not find queue descriptor rule for TriggerRecords!"));
     218              :   }
     219              :   // Create queue connection config object
     220            0 :   auto trQueueObj = obj_fac.create_queue_obj(trQDesc, UID());
     221              : 
     222              :   // Place trigger record queue object into vector of output objs of TRB module
     223            0 :   trbOutputObjs.push_back(&trQueueObj);
     224              : 
     225              :   // Process the network rules looking for the Fragments and TriggerDecision inputs for TRB
     226            0 :   const NetworkConnectionDescriptor* fragNetDesc = nullptr;
     227            0 :   const NetworkConnectionDescriptor* trigdecNetDesc = nullptr;
     228            0 :   const NetworkConnectionDescriptor* tokenNetDesc = nullptr;
     229            0 :   const NetworkConnectionDescriptor* trmonReqNetDesc = nullptr;
     230            0 :   const NetworkConnectionDescriptor* trmonTRNetDesc = nullptr;
     231            0 :   for (auto rule : get_network_rules()) {
     232            0 :     auto descriptor = rule->get_descriptor();
     233            0 :     auto data_type = descriptor->get_data_type();
     234            0 :     if (data_type == "Fragment") {
     235            0 :       fragNetDesc = rule->get_descriptor();
     236            0 :     } else if (data_type == "TriggerDecision") {
     237            0 :       trigdecNetDesc = rule->get_descriptor();
     238            0 :     } else if (data_type == "TriggerDecisionToken") {
     239            0 :       tokenNetDesc = rule->get_descriptor();
     240            0 :     } else if (data_type == "TRMonRequest") {
     241            0 :       trmonReqNetDesc = rule->get_descriptor();
     242            0 :     } else if (data_type == "TriggerRecord") {
     243            0 :       trmonTRNetDesc = rule->get_descriptor();
     244              :     }
     245            0 :   }
     246            0 :   if (fragNetDesc == nullptr) { // BadConf if no descriptor for Fragments into TRB
     247            0 :     throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input Fragments!"));
     248              :   }
     249            0 :   if (trigdecNetDesc == nullptr) { // BadCond if no descriptor for TriggerDecisions into TRB
     250            0 :     throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input TriggerDecisions!"));
     251              :   }
     252            0 :   if (tokenNetDesc == nullptr) { // BadCond if no descriptor for Tokens out of DataWriterModule
     253            0 :     throw(BadConf(ERS_HERE, "Could not find network descriptor rule for output TriggerDecisionTokens!"));
     254              :   }
     255            0 :   if (get_source_id() == nullptr) {
     256            0 :     throw(BadConf(ERS_HERE, "Could not retrieve SourceIDConf"));
     257              :   }
     258              :   // Create network connection config object
     259            0 :   auto fragNetObj = obj_fac.create_net_obj(fragNetDesc, UID());
     260            0 :   auto trigdecNetObj =  obj_fac.create_net_obj(trigdecNetDesc, UID());
     261            0 :   auto tokenNetObj = obj_fac.create_net_obj(tokenNetDesc, "");
     262            0 :   conffwk::ConfigObject trmonReqNetObj;
     263            0 :   conffwk::ConfigObject trmonTRNetObj;
     264            0 :   if (trmonReqNetDesc != nullptr) {
     265            0 :     trmonReqNetObj = obj_fac.create_net_obj(trmonReqNetDesc, UID());
     266              :   }
     267            0 :   if (trmonTRNetDesc != nullptr) {
     268            0 :     trmonTRNetObj = obj_fac.create_net_obj(trmonTRNetDesc, "");
     269              :   }
     270              : 
     271              :   // Process special Network rules!
     272              :   // Looking for DataRequest rules from ReadoutAppplications in current Session
     273            0 :   auto sessionApps = session->enabled_applications();
     274            0 :   std::vector<conffwk::ConfigObject> dreqNetObjs;
     275            0 :   std::vector<conffwk::ConfigObject> sidNetObjs;
     276            0 :   std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs;
     277            0 :   for (auto app : sessionApps) {
     278            0 :     auto smartapp = app->cast<appmodel::SmartDaqApplication>();
     279            0 :     auto roapp = app->cast<appmodel::ReadoutApplication>();
     280            0 :     auto fdapp = app->cast<appmodel::FakeDataApplication>();
     281            0 :     auto ctbapp = app->cast<appmodel::CTBApplication>();
     282            0 :     auto dfapp = app->cast<appmodel::DFApplication>();
     283            0 :     auto rapp = app->cast<appmodel::TPReplayApplication>();
     284            0 :     if (smartapp == nullptr || dfapp != nullptr) {
     285            0 :       continue;
     286              :     }
     287            0 :     auto src_id_check = smartapp->get_source_id();
     288            0 :     if (roapp == nullptr
     289            0 :         && fdapp == nullptr
     290            0 :         && src_id_check == nullptr
     291            0 :         && rapp == nullptr
     292            0 :         && ctbapp == nullptr) {
     293            0 :       continue;
     294              :     }
     295              : 
     296            0 :     auto roQRules = smartapp->get_network_rules();
     297            0 :     for (auto rule : roQRules) {
     298            0 :       auto descriptor = rule->get_descriptor();
     299            0 :       auto data_type = descriptor->get_data_type();
     300            0 :       if (data_type == "DataRequest") {
     301            0 :         if (rapp != nullptr) {
     302            0 :           fill_sourceid_object_from_app(obj_fac, rapp, &dreqNetObjs, &sidNetObjs, sidObjs, descriptor, smartapp->UID());
     303              :         }
     304              :         // contrary to all the other applications
     305              :         // the CTB has 2 network connections, so this logic has to be splitted
     306            0 :         else if (ctbapp) {
     307            0 :           auto sources = ctbapp->get_sources();
     308            0 :           for ( const auto & s : sources ) {
     309            0 :             std::string dreqNetUid(descriptor->get_uid_base() + smartapp->UID()+ '_' + s.first);
     310            0 :             dreqNetObjs.emplace_back( obj_fac.create_net_obj(descriptor, dreqNetUid) );
     311              : 
     312            0 :             std::string sidToNetUid(descriptor->get_uid_base() + smartapp->UID() + "_" + s.first);
     313            0 :             sidNetObjs.emplace_back( obj_fac.create("SourceIDToNetworkConnection", sidToNetUid ) );
     314            0 :             sidNetObjs.back().set_obj("netconn", & dreqNetObjs.back());
     315            0 :             sidNetObjs.back().set_objs("source_ids", { & s.second->config_object() });
     316            0 :           } // loop over CTB sources
     317            0 :         } else {
     318              : 
     319            0 :           dreqNetObjs.emplace_back(obj_fac.create_net_obj(descriptor, smartapp->UID()));
     320              : 
     321            0 :           std::string sidToNetUid(descriptor->get_uid_base() + smartapp->UID() + "-sids");
     322            0 :           sidNetObjs.emplace_back(
     323            0 :                                     obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
     324            0 :           if (roapp != nullptr) {
     325            0 :             fill_sourceid_object_from_app(obj_fac, roapp, &dreqNetObjs.back(), sidNetObjs.back(), sidObjs);
     326            0 :           } else if (fdapp != nullptr) {
     327            0 :             fill_sourceid_object_from_app(obj_fac, fdapp, &dreqNetObjs.back(), sidNetObjs.back(), sidObjs);
     328              :           } else {
     329            0 :             fill_sourceid_object_from_app(smartapp, &dreqNetObjs.back(), sidNetObjs.back());
     330              :           }
     331            0 :         } // else from if (ctbapp)
     332              :       } // If network rule has DataRequest type of data
     333            0 :     }   // Loop over Apps network rules
     334            0 :   }     // loop over Session specific Apps
     335              : 
     336              :   // Get pointers to objects here, after vector has been filled so they don't move on us
     337            0 :   for (auto& obj : dreqNetObjs) {
     338            0 :     trbOutputObjs.push_back(&obj);
     339              :   }
     340            0 :   for (auto& obj : sidNetObjs) {
     341            0 :     trbSidNetObjs.push_back(&obj);
     342              :   }
     343              : 
     344              :   // -- Second, we create the Module objects and assign their configs, with the precreated
     345              :   // -- connection config objects above.
     346              : 
     347              :   // Get TRB Config Object
     348            0 :   auto trbConf = get_trb();
     349            0 :   if (trbConf == nullptr) {
     350            0 :     throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
     351              :   }
     352            0 :   auto trbConfObj = trbConf->config_object();
     353            0 :   trbConfObj.set_by_val<uint32_t>("source_id", get_source_id()->get_sid());
     354            0 :   trbInputObjs = { &trigdecNetObj, &fragNetObj };
     355            0 :   if (trmonReqNetDesc != nullptr) {
     356            0 :     trbInputObjs.push_back(&trmonReqNetObj);
     357              :   }
     358            0 :   if (trmonTRNetDesc != nullptr) {
     359            0 :     trbOutputObjs.push_back(&trmonTRNetObj);
     360              :   }
     361              :   // Prepare TRB Module Object and assign its Config Object.
     362            0 :   std::string trbUid(UID() + "-trb");
     363            0 :   conffwk::ConfigObject trbObj = obj_fac.create("TRBModule", trbUid);
     364            0 :   trbObj.set_obj("configuration", &trbConfObj);
     365            0 :   trbObj.set_objs("inputs", trbInputObjs);
     366            0 :   trbObj.set_objs("outputs", trbOutputObjs);
     367            0 :   trbObj.set_obj("trigger_record_output", &trQueueObj);
     368            0 :   trbObj.set_objs("request_connections", trbSidNetObjs);
     369              :   // Push TRB Module Object from confdb
     370            0 :   modules.push_back(obj_fac.get_dal<TRBModule>(trbUid));
     371              : 
     372              :   // Get DataWriterModule Config Object (only one for now, maybe more later?)
     373            0 :   auto dwrConfs = get_data_writers();
     374            0 :   if (dwrConfs.size() == 0) {
     375            0 :     throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
     376              :   }
     377            0 :   uint dw_idx = 0;
     378            0 :   for (auto dwrConf : dwrConfs) {
     379              :     // auto fnParamsObj = dwrConf->get_data_store_params()->get_filename_params()->config_object();
     380              :     // fnParamsObj.set_by_val<std::string>("writer_identifier", fmt::format("{}_datawriter-{}", UID(), dw_idx));
     381            0 :     auto dwrConfObj = dwrConf->config_object();
     382              : 
     383              :     // Prepare DataWriterModule Module Object and assign its Config Object.
     384            0 :     std::string dwrUid(fmt::format("{}-dw-{}", UID(), dw_idx));
     385            0 :     conffwk::ConfigObject dwrObj = obj_fac.create("DataWriterModule", dwrUid);
     386            0 :     dwrObj.set_by_val("writer_identifier", fmt::format("{}_dw_{}", UID(), dw_idx));
     387            0 :     dwrObj.set_obj("configuration", &dwrConfObj);
     388            0 :     dwrObj.set_objs("inputs", { &trQueueObj });
     389            0 :     dwrObj.set_objs("outputs", { &tokenNetObj });
     390              :     // Push DataWriterModule Module Object from confdb
     391            0 :     modules.push_back(obj_fac.get_dal<DataWriterModule>(dwrUid));
     392            0 :     ++dw_idx;
     393            0 :   }
     394              : 
     395            0 :   obj_fac.update_modules(modules);
     396            0 : }
     397              : 
     398              : } // namespace appmodel  
     399              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1