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