Line data Source code
1 : /**
2 : * @file DFO.cpp
3 : *
4 : * Implementation of WIECApplication'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 "conffwk/Configuration.hpp"
14 : #include "logging/Logging.hpp"
15 :
16 : #include "appmodel/NWDetDataReceiver.hpp"
17 : #include "confmodel/NetworkInterface.hpp"
18 : #include "confmodel/DetectorStream.hpp"
19 : #include "confmodel/GeoId.hpp"
20 :
21 : #include "appmodel/appmodelIssues.hpp"
22 : #include "ConfigObjectFactory.hpp"
23 : #include "appmodel/WIECApplication.hpp"
24 :
25 : #include "appmodel/WIBModule.hpp"
26 : #include "appmodel/WIBModuleConf.hpp"
27 : #include "appmodel/WIBSettings.hpp"
28 : #include "appmodel/HermesDataSender.hpp"
29 : #include "appmodel/HermesModule.hpp"
30 : #include "appmodel/HermesModuleConf.hpp"
31 : #include "appmodel/IpbusAddressTable.hpp"
32 : #include "confmodel/DetectorToDaqConnection.hpp"
33 :
34 :
35 : #include <string>
36 : #include <vector>
37 : #include <iostream>
38 : #include <fmt/core.h>
39 :
40 : namespace dunedaq {
41 : namespace appmodel {
42 :
43 : //-----------------------------------------------------------------------------
44 :
45 : std::vector<const confmodel::Resource*>
46 0 : WIECApplication::contained_resources() const {
47 0 : return to_resources(get_detector_connections());
48 : }
49 :
50 :
51 : void
52 0 : WIECApplication::generate_modules(const confmodel::Session* session) const
53 : {
54 0 : ConfigObjectFactory obj_fac(this);
55 0 : conffwk::Configuration* config = &this->configuration();
56 0 : const std::string& dbfile = this->config_object().contained_in();
57 :
58 0 : std::vector<const confmodel::DaqModule*> modules;
59 :
60 0 : std::map<std::string, std::vector<const appmodel::HermesDataSender*>> ctrlhost_sender_map;
61 :
62 :
63 : // uint16_t conn_idx = 0;
64 0 : for (auto d2d_conn : get_detector_connections()) {
65 :
66 : // Are we sure?
67 0 : if (d2d_conn->is_disabled(*session)) {
68 0 : TLOG_DEBUG(7) << "Ignoring disabled DetectorToDaqConnection " << d2d_conn->UID();
69 0 : continue;
70 0 : }
71 :
72 0 : TLOG_DEBUG(6) << "Processing DetectorToDaqConnection " << d2d_conn->UID();
73 :
74 : // Is this check necessary?
75 0 : if (d2d_conn->contained_resources().empty()) {
76 0 : throw(BadConf(ERS_HERE, "DetectorToDaqConnection does not contain senders or receivers"));
77 : }
78 :
79 0 : auto det_senders = d2d_conn->senders();
80 0 : auto det_receiver = d2d_conn->receiver();
81 :
82 : // Ensure that receiver is a nw_receiver
83 0 : const auto* nw_receiver = det_receiver->cast<appmodel::NWDetDataReceiver>();
84 :
85 0 : if ( !nw_receiver ) {
86 0 : throw(BadConf(ERS_HERE, fmt::format("WEICApplication requires NWDetDataReceiver, found {} of class {}", det_receiver->UID(), det_receiver->class_name())));
87 : }
88 :
89 : // Loop over senders
90 0 : for (const auto* sender : det_senders) {
91 :
92 0 : if ( sender->is_disabled(*session) ) {
93 0 : TLOG() << "Skipping disabled sender: " << sender->UID();
94 0 : continue;
95 0 : }
96 :
97 : // Check the sender type, must me a HermesSender
98 0 : const auto* hrms_sender = sender->cast<appmodel::HermesDataSender>();
99 0 : if (!hrms_sender ) {
100 0 : throw(BadConf(ERS_HERE, fmt::format("DataSender {} is not a appmodel::HermesDataSender", sender->UID())));
101 : }
102 :
103 0 : ctrlhost_sender_map[hrms_sender->get_control_host()].push_back(hrms_sender);
104 : }
105 :
106 :
107 0 : for( const auto& [ctrlhost, senders] : ctrlhost_sender_map ) {
108 :
109 : // Create WIBModule
110 0 : if ( this->get_wib_module_conf() ) {
111 :
112 0 : bool enable_fembs[4] = {false, false, false, false};
113 :
114 0 : for ( const auto* sender : senders ){
115 0 : for ( const auto* det_stream : sender->get_streams() ) {
116 : // Loop over streams for this sender
117 : // Retrieve stream_id and calculate the femb_id
118 0 : uint32_t stream_id = det_stream->get_geo_id()->get_stream_id();
119 0 : uint32_t femb_id = (stream_id & 0xf) / 2 + 2*((stream_id >> 6) & 0xf);
120 :
121 : // std::cout << std::format("stream {} -> femb {}", stream_id, femb_id) << std::endl;
122 :
123 : // Enable the femb if any of the associated streams is enabld
124 : // Senders in this senders list should be enabled, but better safe than sorry.
125 0 : enable_fembs[femb_id] |= !det_stream->is_disabled(*session);
126 : }
127 : }
128 0 : std::string wib_uid = fmt::format("wib-ctrl-{}-{}", this->UID(), ctrlhost);
129 0 : conffwk::ConfigObject wib_obj = obj_fac.create("WIBModule", wib_uid);
130 0 : wib_obj.set_by_val<std::string>("wib_addr", fmt::format("{}://{}:{}", this->get_wib_module_conf()->get_communication_type(), ctrlhost, this->get_wib_module_conf()->get_communication_port()));
131 0 : wib_obj.set_by_val<bool>("enabled_femb0", enable_fembs[0]);
132 0 : wib_obj.set_by_val<bool>("enabled_femb1", enable_fembs[1]);
133 0 : wib_obj.set_by_val<bool>("enabled_femb2", enable_fembs[2]);
134 0 : wib_obj.set_by_val<bool>("enabled_femb3", enable_fembs[3]);
135 0 : wib_obj.set_obj("conf", &this->get_wib_module_conf()->get_settings()->config_object());
136 0 : modules.push_back(config->get<appmodel::WIBModule>(wib_obj));
137 0 : }
138 :
139 : // Create Hermes Modules
140 0 : if (this->get_hermes_module_conf()) {
141 0 : std::string hermes_uid = fmt::format("hermes-ctrl-{}-{}", this->UID(), ctrlhost);
142 0 : conffwk::ConfigObject hermes_obj = obj_fac.create("HermesModule", hermes_uid);
143 0 : hermes_obj.set_obj("address_table", &this->get_hermes_module_conf()->get_address_table()->config_object());
144 0 : hermes_obj.set_by_val<std::string>("uri", fmt::format("{}://{}:{}", this->get_hermes_module_conf()->get_ipbus_type(), ctrlhost, this->get_hermes_module_conf()->get_ipbus_port()));
145 0 : hermes_obj.set_by_val<uint32_t>("timeout_ms", this->get_hermes_module_conf()->get_ipbus_timeout_ms());
146 0 : hermes_obj.set_obj("destination", &nw_receiver->get_uses()->config_object());
147 :
148 0 : std::vector< const conffwk::ConfigObject * > links_obj;
149 0 : for ( const auto* sndr : senders ){
150 0 : links_obj.push_back(&sndr->config_object());
151 : }
152 0 : hermes_obj.set_objs("links", links_obj);
153 :
154 0 : modules.push_back(config->get<appmodel::HermesModule>(hermes_obj));
155 0 : }
156 :
157 :
158 : }
159 :
160 0 : }
161 :
162 0 : obj_fac.update_modules(modules);
163 0 : }
164 :
165 : } // namespace appmodel
166 : } // namespace dunedaq
|