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/QueueConnectionRule.hpp"
17 : #include "appmodel/QueueDescriptor.hpp"
18 : #include "appmodel/SocketDetectorToDaqConnection.hpp"
19 : #include "appmodel/SocketWriterConf.hpp"
20 : #include "appmodel/SocketWriterModule.hpp"
21 :
22 : #include "ConfigObjectFactory.hpp"
23 :
24 : #include "confmodel/Connection.hpp"
25 : #include "confmodel/DetDataReceiver.hpp"
26 : #include "confmodel/DetDataSender.hpp"
27 : #include "confmodel/DetectorStream.hpp"
28 : #include "confmodel/DetectorToDaqConnection.hpp"
29 :
30 : #include "logging/Logging.hpp"
31 :
32 : #include <fmt/core.h>
33 :
34 : #include <memory>
35 : #include <string>
36 : #include <vector>
37 :
38 : namespace dunedaq::appmodel {
39 :
40 : std::vector<const confmodel::ExcludableEntity*>
41 0 : CRTFrameBuilderApplication::contained_excludable_entities() const
42 : {
43 0 : return to_resources(get_detector_connections());
44 : }
45 :
46 : void
47 0 : CRTFrameBuilderApplication::generate_modules(std::shared_ptr<appmodel::ConfigurationHelper> helper) const
48 : {
49 :
50 0 : TLOG_DEBUG(6) << "Generating modules for application " << this->UID();
51 :
52 0 : std::vector<const confmodel::DaqModule*> modules;
53 :
54 0 : ConfigObjectFactory obj_fac(this);
55 :
56 : //
57 : // Extract basic configuration objects
58 : //
59 :
60 : // Detector frame builder
61 0 : const auto det_frame_builder_conf = get_detector_frame_builder();
62 0 : if (det_frame_builder_conf == nullptr) {
63 : throw(BadConf(ERS_HERE, "No DetectorFrameBuilderModule configuration given"));
64 : }
65 0 : const std::string builder_class = det_frame_builder_conf->get_template_for();
66 :
67 : // Data writer
68 0 : const auto writer_conf = get_data_writer();
69 0 : if (writer_conf == nullptr) {
70 : throw(BadConf(ERS_HERE, "No DataWriterModule configuration given"));
71 : }
72 0 : const std::string writer_class = writer_conf->get_template_for();
73 :
74 : //
75 : // Process the queue rules looking for inputs to our socket writer modules
76 : //
77 0 : const QueueDescriptor* crtframebuilder_output_qdesc = nullptr;
78 0 : auto queue_rules = get_queue_rules();
79 0 : if (queue_rules.size() != 1) {
80 0 : throw(BadConf(ERS_HERE, "Strictly 1 queue rule is expected"));
81 : }
82 0 : crtframebuilder_output_qdesc = queue_rules[0]->get_descriptor();
83 :
84 : //
85 : // Scan Detector 2 DAQ connections to extract sender, receiver and stream information
86 : //
87 :
88 : // Loop over the detector to daq connections and generate:
89 : // - One detector frame builder per data sender
90 : // - One data writer per data sender
91 : // - One queue per data sender
92 :
93 0 : for (auto d2d_conn : get_detector_connections()) {
94 :
95 0 : auto d2d_conn_uid = d2d_conn->UID();
96 :
97 : // Are we sure?
98 0 : if (helper->is_excluded(d2d_conn)) {
99 0 : TLOG_DEBUG(7) << "Ignoring excluded DetectorToDaqConnection " << d2d_conn_uid;
100 0 : continue;
101 0 : }
102 :
103 0 : TLOG_DEBUG(6) << "Processing DetectorToDaqConnection " << d2d_conn_uid;
104 :
105 0 : auto receiver = d2d_conn->receiver();
106 :
107 0 : uint16_t sender_idx = 0; // NOLINT(build/unsigned)
108 :
109 : // Loop over senders
110 0 : for (auto sender : d2d_conn->senders()) {
111 :
112 : // Are we sure?
113 0 : if (helper->is_excluded(sender)) {
114 0 : TLOG_DEBUG(7) << "Ignoring excluded DataSender " << sender->UID();
115 0 : continue;
116 0 : }
117 :
118 0 : bool has_included_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_excluded(stream)) {
124 0 : TLOG_DEBUG(7) << "Ignoring excluded DetectorStream " << stream->UID();
125 0 : continue;
126 0 : }
127 :
128 : has_included_det_stream = true;
129 : break;
130 : }
131 :
132 0 : if (!has_included_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(
164 0 : "creating OKS configuration object for detector frame builder class {} with id {}", builder_class, builder_uid);
165 0 : auto builder_obj = obj_fac.create(builder_class, builder_uid);
166 :
167 : // Populate configuration and interfaces
168 0 : builder_obj.set_obj("configuration", &det_frame_builder_conf->config_object());
169 0 : builder_obj.set_obj("connection", sender_conn_conf_obj);
170 0 : builder_obj.set_objs("outputs", { queue_conf_obj });
171 :
172 0 : modules.push_back(obj_fac.get_dal<confmodel::DaqModule>(builder_obj.UID()));
173 :
174 : //-----------------------------------------------------------------
175 : //
176 : // Create DataWriterModule object
177 : //
178 :
179 : //
180 : // Instantiate DataWriterModule of type SocketWriterModule
181 : //
182 :
183 : // Create the SocketWriterModule object
184 :
185 0 : std::string writer_uid(fmt::format("socket-writer-{}-{}", this->UID(), sender_idx_str));
186 0 : TLOG_DEBUG(6) << fmt::format(
187 0 : "Creating OKS configuration object for socket writer class {} with id {}", writer_class, writer_uid);
188 0 : auto writer_obj = obj_fac.create(writer_class, writer_uid);
189 :
190 : // Populate configuration and interfaces
191 0 : writer_obj.set_obj("configuration", &writer_conf->config_object());
192 0 : writer_obj.set_obj("connection", sender_conn_conf_obj);
193 0 : writer_obj.set_objs("inputs", { queue_conf_obj });
194 :
195 0 : modules.push_back(obj_fac.get_dal<confmodel::DaqModule>(writer_obj.UID()));
196 :
197 0 : ++sender_idx;
198 0 : }
199 0 : }
200 :
201 0 : obj_fac.update_modules(modules);
202 0 : }
203 :
204 : } // namespace dunedaq::appmodel
|