Line data Source code
1 : /**
2 : * @file CRTFrameBuilderApplication.cpp
3 : *
4 : * Implementation of CRTFrameBuilderApplication'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 "appmodel/CRTFrameBuilderApplication.hpp"
12 :
13 : #include "appmodel/appmodelIssues.hpp"
14 :
15 : #include "appmodel/DetectorFrameBuilderConf.hpp"
16 : #include "appmodel/SocketWriterConf.hpp"
17 : #include "appmodel/SocketWriterModule.hpp"
18 : #include "appmodel/QueueConnectionRule.hpp"
19 : #include "appmodel/QueueDescriptor.hpp"
20 : #include "appmodel/SocketDetectorToDaqConnection.hpp"
21 :
22 : #include "ConfigObjectFactory.hpp"
23 :
24 : #include "confmodel/Connection.hpp"
25 : #include "confmodel/DetectorStream.hpp"
26 : #include "confmodel/DetectorToDaqConnection.hpp"
27 : #include "confmodel/DetDataSender.hpp"
28 : #include "confmodel/DetDataReceiver.hpp"
29 :
30 : #include "logging/Logging.hpp"
31 :
32 : #include <fmt/core.h>
33 :
34 : #include <string>
35 : #include <vector>
36 : #include <memory>
37 :
38 : namespace dunedaq::appmodel {
39 :
40 : std::vector<const confmodel::Resource*>
41 0 : CRTFrameBuilderApplication::contained_resources() const {
42 0 : return to_resources(get_detector_connections());
43 : }
44 :
45 : void
46 0 : CRTFrameBuilderApplication::generate_modules(std::shared_ptr<appmodel::ConfigurationHelper> helper) const
47 : {
48 :
49 0 : TLOG_DEBUG(6) << "Generating modules for application " << this->UID();
50 :
51 0 : std::vector<const confmodel::DaqModule*> modules;
52 :
53 0 : ConfigObjectFactory obj_fac(this);
54 :
55 : //
56 : // Extract basic configuration objects
57 : //
58 :
59 : // Detector frame builder
60 0 : const auto det_frame_builder_conf = get_detector_frame_builder();
61 0 : if (det_frame_builder_conf == nullptr) {
62 : throw(BadConf(ERS_HERE, "No DetectorFrameBuilderModule configuration given"));
63 : }
64 0 : const std::string builder_class = det_frame_builder_conf->get_template_for();
65 :
66 : // Data writer
67 0 : const auto writer_conf = get_data_writer();
68 0 : if (writer_conf == nullptr) {
69 : throw(BadConf(ERS_HERE, "No DataWriterModule configuration given"));
70 : }
71 0 : const std::string writer_class = writer_conf->get_template_for();
72 :
73 : //
74 : // Process the queue rules looking for inputs to our socket writer modules
75 : //
76 0 : const QueueDescriptor* crtframebuilder_output_qdesc = nullptr;
77 0 : auto queue_rules = get_queue_rules();
78 0 : if (queue_rules.size() != 1) {
79 0 : throw(BadConf(ERS_HERE, "Strictly 1 queue rule is expected"));
80 : }
81 0 : crtframebuilder_output_qdesc = queue_rules[0]->get_descriptor();
82 :
83 : //
84 : // Scan Detector 2 DAQ connections to extract sender, receiver and stream information
85 : //
86 :
87 : // Loop over the detector to daq connections and generate:
88 : // - One detector frame builder per data sender
89 : // - One data writer per data sender
90 : // - One queue per data sender
91 :
92 0 : for (auto d2d_conn : get_detector_connections()) {
93 :
94 0 : auto d2d_conn_uid = d2d_conn->UID();
95 :
96 : // Are we sure?
97 0 : if (helper->is_disabled(d2d_conn)) {
98 0 : TLOG_DEBUG(7) << "Ignoring disabled DetectorToDaqConnection " << d2d_conn_uid;
99 0 : continue;
100 0 : }
101 :
102 0 : TLOG_DEBUG(6) << "Processing DetectorToDaqConnection " << d2d_conn_uid;
103 :
104 0 : auto receiver = d2d_conn->receiver();
105 :
106 0 : uint16_t sender_idx = 0; // NOLINT(build/unsigned)
107 :
108 : // Loop over senders
109 0 : for (auto sender : d2d_conn->senders()) {
110 :
111 : // Are we sure?
112 0 : if (helper->is_disabled(sender)) {
113 0 : TLOG_DEBUG(7) << "Ignoring disabled DataSender " << sender->UID();
114 0 : continue;
115 0 : }
116 :
117 :
118 0 : bool has_enabled_det_stream = false;
119 : // Loop over streams
120 0 : for (auto stream : sender->get_streams()) {
121 :
122 : // Are we sure?
123 0 : if (helper->is_disabled(stream)) {
124 0 : TLOG_DEBUG(7) << "Ignoring disabled DetectorStream " << stream->UID();
125 0 : continue;
126 0 : }
127 :
128 : has_enabled_det_stream = true;
129 : break;
130 : }
131 :
132 0 : if (!has_enabled_det_stream) {
133 0 : continue;
134 : }
135 :
136 0 : const auto sender_idx_str = std::to_string(sender_idx);
137 :
138 : // Create a connection that is dedicated to this sender
139 0 : std::string sender_conn_uid(d2d_conn_uid + sender_idx_str);
140 0 : auto sender_conn_obj = obj_fac.create("SocketDetectorToDaqConnection", sender_conn_uid);
141 0 : sender_conn_obj.set_objs("net_senders", { &sender->config_object() });
142 0 : sender_conn_obj.set_obj("net_receiver", &receiver->config_object());
143 0 : const auto* sender_conn = obj_fac.get_dal<appmodel::SocketDetectorToDaqConnection>(sender_conn_obj.UID());
144 0 : const auto* sender_conn_conf_obj = &sender_conn->config_object();
145 :
146 : // Create data queue
147 0 : conffwk::ConfigObject queue_obj = obj_fac.create_queue_obj(crtframebuilder_output_qdesc, sender_idx_str);
148 0 : const auto* queue = obj_fac.get_dal<confmodel::Connection>(queue_obj.UID());
149 0 : const auto* queue_conf_obj = &queue->config_object();
150 :
151 : //-----------------------------------------------------------------
152 : //
153 : // Create DetectorFrameBuilderModule object
154 : //
155 :
156 : //
157 : // Instantiate DetectorFrameBuilderModule of type CRTBernFrameBuilderModule/CRTGrenobleFrameBuilderModule
158 : //
159 :
160 : // Create the detector frame builder object
161 :
162 0 : std::string builder_uid(fmt::format("crt-frame-builder-{}-{}", this->UID(), sender_idx_str));
163 0 : TLOG_DEBUG(6) << fmt::format("creating OKS configuration object for detector frame builder class {} with id {}", builder_class, builder_uid);
164 0 : auto builder_obj = obj_fac.create(builder_class, builder_uid);
165 :
166 : // Populate configuration and interfaces
167 0 : builder_obj.set_obj("configuration", &det_frame_builder_conf->config_object());
168 0 : builder_obj.set_obj("connection", sender_conn_conf_obj);
169 0 : builder_obj.set_objs("outputs", { queue_conf_obj });
170 :
171 0 : modules.push_back(obj_fac.get_dal<confmodel::DaqModule>(builder_obj.UID()));
172 :
173 : //-----------------------------------------------------------------
174 : //
175 : // Create DataWriterModule object
176 : //
177 :
178 : //
179 : // Instantiate DataWriterModule of type SocketWriterModule
180 : //
181 :
182 : // Create the SocketWriterModule object
183 :
184 0 : std::string writer_uid(fmt::format("socket-writer-{}-{}", this->UID(), sender_idx_str));
185 0 : TLOG_DEBUG(6) << fmt::format("Creating OKS configuration object for socket writer class {} with id {}", writer_class, writer_uid);
186 0 : auto writer_obj = obj_fac.create(writer_class, writer_uid);
187 :
188 : // Populate configuration and interfaces
189 0 : writer_obj.set_obj("configuration", &writer_conf->config_object());
190 0 : writer_obj.set_obj("connection", sender_conn_conf_obj);
191 0 : writer_obj.set_objs("inputs", { queue_conf_obj });
192 :
193 0 : modules.push_back(obj_fac.get_dal<confmodel::DaqModule>(writer_obj.UID()));
194 :
195 0 : ++sender_idx;
196 0 : }
197 0 : }
198 :
199 0 : obj_fac.update_modules(modules);
200 0 : }
201 :
202 : } // namespace dunedaq::appmodel
|