DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
DFApplication.cpp
Go to the documentation of this file.
1
10
23#include "appmodel/TRBConf.hpp"
26
29
30#include "logging/Logging.hpp"
31#include "oks/kernel.hpp"
32
33#include <fmt/core.h>
34#include <string>
35#include <vector>
36
37namespace dunedaq {
38namespace appmodel {
39
40static inline void
42 const conffwk::ConfigObject* netConn,
43 const std::string& uid,
44 const std::vector<uint32_t>& stream_source_ids,
45 const std::vector<const SourceIDConf*>& tp_source_ids,
46 conffwk::ConfigObject& sidNetObj,
47 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs)
48{
49 sidNetObj.set_obj("netconn", netConn);
50
51 std::vector<const conffwk::ConfigObject*> source_id_objs;
52
53 for (auto& source_id : stream_source_ids) {
54 std::string streamSidUid(uid + "SourceIDConf" + std::to_string(source_id));
55 auto stream_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", streamSidUid));
56 stream_sid_obj->set_by_val<uint32_t>("sid", source_id);
57 stream_sid_obj->set_by_val<std::string>("subsystem", "Detector_Readout");
58 sidObjs.push_back(stream_sid_obj);
59 source_id_objs.push_back(sidObjs.back().get());
60 }
61
62 for (auto tp_sid : tp_source_ids) {
63 sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(tp_sid->config_object()));
64 source_id_objs.push_back(sidObjs.back().get());
65 }
66 /*
67 std::string trgSidUid(roapp->UID() + "TRGSourceIDConf" + std::to_string(roapp->get_tp_source_id()));
68 auto trig_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", trgSidUid));
69 trig_sid_obj->set_by_val<uint32_t>("sid", roapp->get_tp_source_id());
70 trig_sid_obj->set_by_val<std::string>("subsystem", "Trigger");
71 source_id_objs.push_back(sidObjs.back().get());
72 */
73
74 sidNetObj.set_objs("source_ids", source_id_objs);
75}
76
77inline void
79 const std::string& uid,
80 const std::vector<const SourceIDConf*>& tp_source_ids,
81 std::vector<conffwk::ConfigObject>* netConn,
82 std::vector<conffwk::ConfigObject>* sidNetObj,
84 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs)
85{
86 std::vector<const conffwk::ConfigObject*> source_id_objs;
87
88 for (auto tp_sid : tp_source_ids) {
89 // get name extension
90 std::string name = tp_sid->UID();
91 size_t pos = name.find_last_of('-');
92 std::string ext;
93 if (pos != std::string::npos) {
94 ext = name.substr(pos);
95 }
96
97 // set Network connections
98 std::string dreqNetUid(uid + ext);
99 netConn->emplace_back(obj_fac.create_net_obj(descriptor, dreqNetUid));
100 netConn->back().set_by_val<std::string>("data_type", descriptor->get_data_type());
101 netConn->back().set_by_val<std::string>("connection_type", descriptor->get_connection_type());
102 auto serviceObj = descriptor->get_associated_service()->config_object();
103 netConn->back().set_obj("associated_service", &serviceObj);
104
105 // set SourceID to Network connections
106 std::string sidToNetUid(uid + ext + "-sids");
107 sidNetObj->emplace_back(obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
108 sidNetObj->back().set_obj("netconn", &netConn->back());
109
110 // set SourceID objs
111 sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(tp_sid->config_object()));
112 sidNetObj->back().set_objs("source_ids", { sidObjs.back().get() });
113 }
114}
115
116void
117DFApplication::generate_modules(std::shared_ptr<appmodel::ConfigurationHelper> helper) const
118{
119
120 ConfigObjectFactory obj_fac(this);
121
122 std::vector<const confmodel::DaqModule*> modules;
123
124 // Containers for module specific config objects for output/input
125 // Prepare TRB output objects
126 std::vector<const conffwk::ConfigObject*> trbInputObjs;
127 std::vector<const conffwk::ConfigObject*> trbOutputObjs;
128 std::vector<const conffwk::ConfigObject*> trbSidNetObjs;
129
130 // -- First, we process expected Queue and Network connections and create their objects.
131
132 // Process the queue rules looking for the TriggerRecord queue between TRB and DataWriterModule
133 const QueueDescriptor* trQDesc = nullptr;
134 for (auto rule : get_queue_rules()) {
135 auto destination_class = rule->get_destination_class();
136 if (destination_class == "DataWriterModule") {
137 trQDesc = rule->get_descriptor();
138 }
139 }
140 if (trQDesc == nullptr) { // BadConf if no descriptor between TRB and DataWriterModule
141 throw(BadConf(ERS_HERE, "Could not find queue descriptor rule for TriggerRecords!"));
142 }
143 // Create queue connection config object
144 auto trQueueObj = obj_fac.create_queue_obj(trQDesc, UID());
145
146 // Place trigger record queue object into vector of output objs of TRB module
147 trbOutputObjs.push_back(&trQueueObj);
148
149 // Process the network rules looking for the Fragments and TriggerDecision inputs for TRB
150 const NetworkConnectionDescriptor* fragNetDesc = nullptr;
151 const NetworkConnectionDescriptor* trigdecNetDesc = nullptr;
152 const NetworkConnectionDescriptor* tokenNetDesc = nullptr;
153 const NetworkConnectionDescriptor* trmonReqNetDesc = nullptr;
154 const NetworkConnectionDescriptor* trmonTRNetDesc = nullptr;
155 for (auto rule : get_network_rules()) {
156 auto descriptor = rule->get_descriptor();
157 auto data_type = descriptor->get_data_type();
158 if (data_type == "Fragment") {
159 fragNetDesc = rule->get_descriptor();
160 } else if (data_type == "TriggerDecision") {
161 trigdecNetDesc = rule->get_descriptor();
162 } else if (data_type == "TriggerDecisionToken") {
163 tokenNetDesc = rule->get_descriptor();
164 } else if (data_type == "TRMonRequest") {
165 trmonReqNetDesc = rule->get_descriptor();
166 } else if (data_type == "TriggerRecord") {
167 trmonTRNetDesc = rule->get_descriptor();
168 }
169 }
170 if (fragNetDesc == nullptr) { // BadConf if no descriptor for Fragments into TRB
171 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input Fragments!"));
172 }
173 if (trigdecNetDesc == nullptr) { // BadCond if no descriptor for TriggerDecisions into TRB
174 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input TriggerDecisions!"));
175 }
176 if (tokenNetDesc == nullptr) { // BadCond if no descriptor for Tokens out of DataWriterModule
177 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for output TriggerDecisionTokens!"));
178 }
179 if (get_source_id() == nullptr) {
180 throw(BadConf(ERS_HERE, "Could not retrieve SourceIDConf"));
181 }
182 // Create network connection config object
183 auto fragNetObj = obj_fac.create_net_obj(fragNetDesc, UID());
184 auto trigdecNetObj = obj_fac.create_net_obj(trigdecNetDesc, UID());
185 auto tokenNetObj = obj_fac.create_net_obj(tokenNetDesc, "");
186 conffwk::ConfigObject trmonReqNetObj;
187 conffwk::ConfigObject trmonTRNetObj;
188 if (trmonReqNetDesc != nullptr) {
189 trmonReqNetObj = obj_fac.create_net_obj(trmonReqNetDesc, UID());
190 }
191 if (trmonTRNetDesc != nullptr) {
192 trmonTRNetObj = obj_fac.create_net_obj(trmonTRNetDesc, "");
193 }
194
195 // Process special Network rules!
196 // Looking for DataRequest rules from ReadoutAppplications in current Session
197 std::vector<conffwk::ConfigObject> dreqNetObjs;
198 std::vector<conffwk::ConfigObject> sidNetObjs;
199 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs;
200 std::set<std::string> processed_apps;
201 for (auto uid : helper->get_app_uids("DFApplication")) {
202 processed_apps.insert(uid);
203 }
204
205 auto stream_src_ids = helper->get_stream_source_ids();
206 auto tp_src_ids = helper->get_tp_source_ids();
207 for (auto [uid, descriptor] : helper->get_netdescriptors("DataRequest", "ReadoutApplication")) {
208 dreqNetObjs.emplace_back(obj_fac.create_net_obj(descriptor, uid));
209
210 std::string sidToNetUid(descriptor->get_uid_base() + uid + "-sids");
211 sidNetObjs.emplace_back(obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
212
214 obj_fac, &dreqNetObjs.back(), uid, stream_src_ids.at(uid), tp_src_ids.at(uid), sidNetObjs.back(), sidObjs);
215 processed_apps.insert(uid);
216 }
217
218 for (auto [uid, descriptor] : helper->get_netdescriptors("DataRequest", "TPReplayApplication")) {
219 fill_replay_sourceid_object(obj_fac, uid, tp_src_ids.at(uid), &dreqNetObjs, &sidNetObjs, descriptor, sidObjs);
220 processed_apps.insert(uid);
221 }
222
223 for (auto [uid, descriptor] : helper->get_netdescriptors("DataRequest", "FakeDataApplication")) {
224 dreqNetObjs.emplace_back(obj_fac.create_net_obj(descriptor, uid));
225
226 std::string sidToNetUid(descriptor->get_uid_base() + uid + "-sids");
227 sidNetObjs.emplace_back(obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
228
229 fill_sourceid_object(obj_fac,
230 &dreqNetObjs.back(),
231 uid,
232 stream_src_ids.at(uid),
233 {}, // No tp src_ids for FakeDataApplication
234 sidNetObjs.back(),
235 sidObjs);
236 processed_apps.insert(uid);
237 }
238
239 // now we treat the CTB which has 2 connections related to source IDs
240 const auto ctb_type = "CTBApplication";
241 for (auto [uid, descriptor] : helper->get_netdescriptors("DataRequest", ctb_type)) {
242
243 if (processed_apps.contains(uid)) {
244 continue;
245 }
246
247 for (const auto& [uid, rel_sources] : helper->get_all_app_source_ids(ctb_type)) {
248 for (auto [rel, id] : rel_sources) {
249 std::string local_uid = uid;
250 local_uid += rel.find("LLT") != std::string::npos ? "_LLT" : "_HLT";
251
252 dreqNetObjs.emplace_back(obj_fac.create_net_obj(descriptor, local_uid));
253 sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(id->config_object()));
254
255 std::string sidToNetUid(descriptor->get_uid_base() + local_uid);
256 sidNetObjs.emplace_back(obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
257 sidNetObjs.back().set_objs("source_ids", { sidObjs.back().get() });
258 sidNetObjs.back().set_obj("netconn", &dreqNetObjs.back());
259
260 } // loop on relational sources
261
262 processed_apps.insert(uid);
263 } // loop over CTB apps
264 } // loop over descriptors for the CTB apps
265
266 auto app_sources = helper->get_app_source_ids();
267 // Now look at all Smart apps that are not Readout, FakeData or DF
268 for (auto [uid, descriptor] : helper->get_netdescriptors("DataRequest")) {
269
270 if (processed_apps.contains(uid)) {
271 continue;
272 }
273 if (app_sources.contains(uid)) {
274 dreqNetObjs.emplace_back(obj_fac.create_net_obj(descriptor, uid));
275
276 sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(app_sources.at(uid)->config_object()));
277
278 std::string sidToNetUid(descriptor->get_uid_base() + uid + "-sids");
279 sidNetObjs.emplace_back(obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
280 sidNetObjs.back().set_objs("source_ids", { sidObjs.back().get() });
281 sidNetObjs.back().set_obj("netconn", &dreqNetObjs.back());
282
283 processed_apps.insert(uid);
284 }
285 }
286
287 // Get pointers to objects here, after vector has been filled so they don't move on us
288 for (auto& obj : dreqNetObjs) {
289 trbOutputObjs.push_back(&obj);
290 }
291 for (auto& obj : sidNetObjs) {
292 trbSidNetObjs.push_back(&obj);
293 }
294
295 // -- Second, we create the Module objects and assign their configs, with the precreated
296 // -- connection config objects above.
297
298 // Get TRB Config Object
299 auto trbConf = get_trb();
300 if (trbConf == nullptr) {
301 throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
302 }
303 auto trbConfObj = trbConf->config_object();
304 trbConfObj.set_by_val<uint32_t>("source_id", get_source_id()->get_sid());
305 trbInputObjs = { &trigdecNetObj, &fragNetObj };
306 if (trmonReqNetDesc != nullptr) {
307 trbInputObjs.push_back(&trmonReqNetObj);
308 }
309 if (trmonTRNetDesc != nullptr) {
310 trbOutputObjs.push_back(&trmonTRNetObj);
311 }
312 // Prepare TRB Module Object and assign its Config Object.
313 std::string trbUid(UID() + "-trb");
314 conffwk::ConfigObject trbObj = obj_fac.create("TRBModule", trbUid);
315 trbObj.set_obj("configuration", &trbConfObj);
316 trbObj.set_objs("inputs", trbInputObjs);
317 trbObj.set_objs("outputs", trbOutputObjs);
318 trbObj.set_obj("trigger_record_output", &trQueueObj);
319 trbObj.set_objs("request_connections", trbSidNetObjs);
320 // Push TRB Module Object from confdb
321 modules.push_back(obj_fac.get_dal<TRBModule>(trbUid));
322
323 // Get DataWriterModule Config Object (only one for now, maybe more later?)
324 auto dwrConfs = get_data_writers();
325 if (dwrConfs.size() == 0) {
326 throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
327 }
328 uint dw_idx = 0;
329 for (auto dwrConf : dwrConfs) {
330 // auto fnParamsObj = dwrConf->get_data_store_params()->get_filename_params()->config_object();
331 // fnParamsObj.set_by_val<std::string>("writer_identifier", fmt::format("{}_datawriter-{}", UID(), dw_idx));
332 auto dwrConfObj = dwrConf->config_object();
333
334 // Prepare DataWriterModule Module Object and assign its Config Object.
335 std::string dwrUid(fmt::format("{}-dw-{}", UID(), dw_idx));
336 conffwk::ConfigObject dwrObj = obj_fac.create("DataWriterModule", dwrUid);
337 dwrObj.set_by_val("writer_identifier", fmt::format("{}_dw_{}", UID(), dw_idx));
338 dwrObj.set_obj("configuration", &dwrConfObj);
339 dwrObj.set_objs("inputs", { &trQueueObj });
340 dwrObj.set_objs("outputs", { &tokenNetObj });
341 // Push DataWriterModule Module Object from confdb
342 modules.push_back(obj_fac.get_dal<DataWriterModule>(dwrUid));
343 ++dw_idx;
344 }
345
346 obj_fac.update_modules(modules);
347}
348
349} // namespace appmodel
350} // namespace dunedaq
#define ERS_HERE
void update_modules(const std::vector< const confmodel::DaqModule * > &modules)
conffwk::ConfigObject create_net_obj(const NetworkConnectionDescriptor *ndesc, std::string uid) const
Helper function that gets a network connection config.
const T * get_dal(std::string uid) const
conffwk::ConfigObject create_queue_obj(const QueueDescriptor *qdesc, std::string uid="") const
conffwk::ConfigObject create(const std::string &class_name, const std::string &id) const
const std::vector< const dunedaq::appmodel::DataWriterConf * > & get_data_writers() const
Get "data_writers" relationship value.
const dunedaq::appmodel::TRBConf * get_trb() const
Get "trb" relationship value. Configuration of the TRB to be generated my get_modules().
void generate_modules(std::shared_ptr< appmodel::ConfigurationHelper >) const override
const std::vector< const dunedaq::appmodel::NetworkConnectionRule * > & get_network_rules() const
Get "network_rules" relationship value.
const std::vector< const dunedaq::appmodel::QueueConnectionRule * > & get_queue_rules() const
Get "queue_rules" relationship value.
const dunedaq::appmodel::SourceIDConf * get_source_id() const
Get "source_id" relationship value.
uint32_t get_sid() const
Get "sid" attribute value.
void set_by_val(const std::string &name, T value)
Set attribute value.
void set_objs(const std::string &name, const std::vector< const ConfigObject * > &o, bool skip_non_null_check=false)
Set relationship multi-value.
void set_obj(const std::string &name, const ConfigObject *o, bool skip_non_null_check=false)
Set relationship single-value.
const std::string & UID() const noexcept
static void fill_sourceid_object(const ConfigObjectFactory &obj_fac, const conffwk::ConfigObject *netConn, const std::string &uid, const std::vector< uint32_t > &stream_source_ids, const std::vector< const SourceIDConf * > &tp_source_ids, conffwk::ConfigObject &sidNetObj, std::vector< std::shared_ptr< conffwk::ConfigObject > > sidObjs)
void fill_replay_sourceid_object(const ConfigObjectFactory &obj_fac, const std::string &uid, const std::vector< const SourceIDConf * > &tp_source_ids, std::vector< conffwk::ConfigObject > *netConn, std::vector< conffwk::ConfigObject > *sidNetObj, const NetworkConnectionDescriptor *descriptor, std::vector< std::shared_ptr< conffwk::ConfigObject > > sidObjs)
The DUNE-DAQ namespace.
msgpack::object obj
CIB Buffer std::string descriptor Message from std::string descriptor CIB process std::string descriptor descriptor