DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
DFApplication.cpp
Go to the documentation of this file.
1
28#include "appmodel/TRBConf.hpp"
33
35
40#include "confmodel/Service.hpp"
41
42#include "logging/Logging.hpp"
43#include "oks/kernel.hpp"
44
45#include <fmt/core.h>
46#include <string>
47#include <vector>
48
49namespace dunedaq {
50namespace appmodel {
51
52
53inline void
55 const conffwk::ConfigObject* netConn,
56 conffwk::ConfigObject& sidNetObj)
57{
58 sidNetObj.set_obj("netconn", netConn);
59 sidNetObj.set_objs("source_ids", { &smartapp->get_source_id()->config_object() });
60}
61
62
63inline void
65 const TPReplayApplication* rapp,
66 std::vector<conffwk::ConfigObject>* netConn,
67 std::vector<conffwk::ConfigObject>* sidNetObj,
68 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs,
69 const NetworkConnectionDescriptor* descriptor,
70 std::string smartapp_uid)
71{
72 std::vector<const conffwk::ConfigObject*> source_id_objs;
73
74 for (auto tp_sid : rapp->get_tp_source_ids()) {
75 // get name extension
76 std::string name = tp_sid->UID();
77 size_t pos = name.find_last_of('-');
78 std::string ext;
79 if (pos != std::string::npos) {
80 ext = name.substr(pos);
81 }
82
83 // set Network connections
84 std::string dreqNetUid(smartapp_uid + ext);
85 netConn->emplace_back(
86 obj_fac.create_net_obj(descriptor, dreqNetUid));
87 netConn->back().set_by_val<std::string>("data_type", descriptor->get_data_type());
88 netConn->back().set_by_val<std::string>("connection_type", descriptor->get_connection_type());
89 auto serviceObj = descriptor->get_associated_service()->config_object();
90 netConn->back().set_obj("associated_service", &serviceObj);
91
92 // set SourceID to Network connections
93 std::string sidToNetUid(smartapp_uid + ext + "-sids");
94 sidNetObj->emplace_back(
95 obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
96 sidNetObj->back().set_obj("netconn", &netConn->back());
97
98 // set SourceID objs
99 sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(tp_sid->config_object()));
100 sidNetObj->back().set_objs("source_ids", { sidObjs.back().get() });
101 }
102}
103
104inline void
106 const ReadoutApplication* roapp,
107 const conffwk::ConfigObject* netConn,
108 conffwk::ConfigObject& sidNetObj,
109 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs)
110{
111 sidNetObj.set_obj("netconn", netConn);
112
113 std::vector<const conffwk::ConfigObject*> source_id_objs;
114 std::vector<uint32_t> app_source_ids;
115
116 for (auto d2d_conn_res : roapp->get_detector_connections()) {
117
118 // get the readout groups and the interfaces and streams therein; 1 reaout group corresponds to 1 data reader
119 // module
120 auto d2d_conn = d2d_conn_res->cast<confmodel::DetectorToDaqConnection>();
121
122 if (!d2d_conn) {
123 continue;
124 }
125
126 // Loop over senders
127 for (auto dros : d2d_conn->streams()) {
128
129 auto stream = dros->cast<confmodel::DetectorStream>();
130 if (!stream)
131 continue;
132 app_source_ids.push_back(stream->get_source_id());
133 }
134 }
135
136 for (auto& source_id : app_source_ids) {
137 std::string streamSidUid(roapp->UID() + "SourceIDConf" + std::to_string(source_id));
138 auto stream_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", streamSidUid));
139 stream_sid_obj->set_by_val<uint32_t>("sid", source_id);
140 stream_sid_obj->set_by_val<std::string>("subsystem", "Detector_Readout");
141 sidObjs.push_back(stream_sid_obj);
142 source_id_objs.push_back(sidObjs.back().get());
143 }
144
145 for (auto tp_sid : roapp->get_tp_source_ids()) {
146 sidObjs.push_back(std::make_shared<conffwk::ConfigObject>(tp_sid->config_object()));
147 source_id_objs.push_back(sidObjs.back().get());
148 }
149 /*
150 std::string trgSidUid(roapp->UID() + "TRGSourceIDConf" + std::to_string(roapp->get_tp_source_id()));
151 auto trig_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", trgSidUid));
152 trig_sid_obj->set_by_val<uint32_t>("sid", roapp->get_tp_source_id());
153 trig_sid_obj->set_by_val<std::string>("subsystem", "Trigger");
154 source_id_objs.push_back(sidObjs.back().get());
155 */
156
157 sidNetObj.set_objs("source_ids", source_id_objs);
158}
159
160inline void
162 const FakeDataApplication* fdapp,
163 const conffwk::ConfigObject* netConn,
164 conffwk::ConfigObject& sidNetObj,
165 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs)
166{
167 sidNetObj.set_obj("netconn", netConn);
168
169 std::vector<const conffwk::ConfigObject*> source_id_objs;
170 std::vector<uint32_t> app_source_ids;
171
172 for (auto fdpc : fdapp->get_producers()) {
173
174 // get the readout groups and the interfaces and streams therein; 1 reaout group corresponds to 1 data reader
175 // module
176
177 app_source_ids.push_back(fdpc->get_source_id());
178 }
179
180 for (auto& source_id : app_source_ids) {
181 std::string streamSidUid(fdapp->UID() + "SourceIDConf" + std::to_string(source_id));
182 auto stream_sid_obj = std::make_shared<conffwk::ConfigObject>(obj_fac.create("SourceIDConf", streamSidUid));
183 stream_sid_obj->set_by_val<uint32_t>("sid", source_id);
184 stream_sid_obj->set_by_val<std::string>("subsystem", "Detector_Readout");
185 sidObjs.push_back(stream_sid_obj);
186 source_id_objs.push_back(sidObjs.back().get());
187 }
188
189 sidNetObj.set_objs("source_ids", source_id_objs);
190}
191
192std::vector<const confmodel::DaqModule*>
194{
195
196 ConfigObjectFactory obj_fac(this);
197
198 std::vector<const confmodel::DaqModule*> modules;
199
200 // Containers for module specific config objects for output/input
201 // Prepare TRB output objects
202 std::vector<const conffwk::ConfigObject*> trbInputObjs;
203 std::vector<const conffwk::ConfigObject*> trbOutputObjs;
204 std::vector<const conffwk::ConfigObject*> trbSidNetObjs;
205
206 // -- First, we process expected Queue and Network connections and create their objects.
207
208 // Process the queue rules looking for the TriggerRecord queue between TRB and DataWriterModule
209 const QueueDescriptor* trQDesc = nullptr;
210 for (auto rule : get_queue_rules()) {
211 auto destination_class = rule->get_destination_class();
212 if (destination_class == "DataWriterModule") {
213 trQDesc = rule->get_descriptor();
214 }
215 }
216 if (trQDesc == nullptr) { // BadConf if no descriptor between TRB and DataWriterModule
217 throw(BadConf(ERS_HERE, "Could not find queue descriptor rule for TriggerRecords!"));
218 }
219 // Create queue connection config object
220 auto trQueueObj = obj_fac.create_queue_obj(trQDesc, UID());
221
222 // Place trigger record queue object into vector of output objs of TRB module
223 trbOutputObjs.push_back(&trQueueObj);
224
225 // Process the network rules looking for the Fragments and TriggerDecision inputs for TRB
226 const NetworkConnectionDescriptor* fragNetDesc = nullptr;
227 const NetworkConnectionDescriptor* trigdecNetDesc = nullptr;
228 const NetworkConnectionDescriptor* tokenNetDesc = nullptr;
229 const NetworkConnectionDescriptor* trmonReqNetDesc = nullptr;
230 const NetworkConnectionDescriptor* trmonTRNetDesc = nullptr;
231 for (auto rule : get_network_rules()) {
232 auto descriptor = rule->get_descriptor();
233 auto data_type = descriptor->get_data_type();
234 if (data_type == "Fragment") {
235 fragNetDesc = rule->get_descriptor();
236 } else if (data_type == "TriggerDecision") {
237 trigdecNetDesc = rule->get_descriptor();
238 } else if (data_type == "TriggerDecisionToken") {
239 tokenNetDesc = rule->get_descriptor();
240 } else if (data_type == "TRMonRequest") {
241 trmonReqNetDesc = rule->get_descriptor();
242 } else if (data_type == "TriggerRecord") {
243 trmonTRNetDesc = rule->get_descriptor();
244 }
245 }
246 if (fragNetDesc == nullptr) { // BadConf if no descriptor for Fragments into TRB
247 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input Fragments!"));
248 }
249 if (trigdecNetDesc == nullptr) { // BadCond if no descriptor for TriggerDecisions into TRB
250 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input TriggerDecisions!"));
251 }
252 if (tokenNetDesc == nullptr) { // BadCond if no descriptor for Tokens out of DataWriterModule
253 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for output TriggerDecisionTokens!"));
254 }
255 if (get_source_id() == nullptr) {
256 throw(BadConf(ERS_HERE, "Could not retrieve SourceIDConf"));
257 }
258 // Create network connection config object
259 auto fragNetObj = obj_fac.create_net_obj(fragNetDesc, UID());
260 auto trigdecNetObj = obj_fac.create_net_obj(trigdecNetDesc, UID());
261 auto tokenNetObj = obj_fac.create_net_obj(tokenNetDesc, "");
262 conffwk::ConfigObject trmonReqNetObj;
263 conffwk::ConfigObject trmonTRNetObj;
264 if (trmonReqNetDesc != nullptr) {
265 trmonReqNetObj = obj_fac.create_net_obj(trmonReqNetDesc, UID());
266 }
267 if (trmonTRNetDesc != nullptr) {
268 trmonTRNetObj = obj_fac.create_net_obj(trmonTRNetDesc, "");
269 }
270
271 // Process special Network rules!
272 // Looking for DataRequest rules from ReadoutAppplications in current Session
273 auto sessionApps = session->enabled_applications();
274 std::vector<conffwk::ConfigObject> dreqNetObjs;
275 std::vector<conffwk::ConfigObject> sidNetObjs;
276 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs;
277 for (auto app : sessionApps) {
278 auto smartapp = app->cast<appmodel::SmartDaqApplication>();
279 auto roapp = app->cast<appmodel::ReadoutApplication>();
280 auto fdapp = app->cast<appmodel::FakeDataApplication>();
281 auto ctbapp = app->cast<appmodel::CTBApplication>();
282 auto dfapp = app->cast<appmodel::DFApplication>();
283 auto rapp = app->cast<appmodel::TPReplayApplication>();
284 if (smartapp == nullptr || dfapp != nullptr) {
285 continue;
286 }
287 auto src_id_check = smartapp->get_source_id();
288 if (roapp == nullptr
289 && fdapp == nullptr
290 && src_id_check == nullptr
291 && rapp == nullptr
292 && ctbapp == nullptr) {
293 continue;
294 }
295
296 auto roQRules = smartapp->get_network_rules();
297 for (auto rule : roQRules) {
298 auto descriptor = rule->get_descriptor();
299 auto data_type = descriptor->get_data_type();
300 if (data_type == "DataRequest") {
301 if (rapp != nullptr) {
302 fill_sourceid_object_from_app(obj_fac, rapp, &dreqNetObjs, &sidNetObjs, sidObjs, descriptor, smartapp->UID());
303 }
304 // contrary to all the other applications
305 // the CTB has 2 network connections, so this logic has to be splitted
306 else if (ctbapp) {
307 auto sources = ctbapp->get_sources();
308 for ( const auto & s : sources ) {
309 std::string dreqNetUid(descriptor->get_uid_base() + smartapp->UID()+ '_' + s.first);
310 dreqNetObjs.emplace_back( obj_fac.create_net_obj(descriptor, dreqNetUid) );
311
312 std::string sidToNetUid(descriptor->get_uid_base() + smartapp->UID() + "_" + s.first);
313 sidNetObjs.emplace_back( obj_fac.create("SourceIDToNetworkConnection", sidToNetUid ) );
314 sidNetObjs.back().set_obj("netconn", & dreqNetObjs.back());
315 sidNetObjs.back().set_objs("source_ids", { & s.second->config_object() });
316 } // loop over CTB sources
317 } else {
318
319 dreqNetObjs.emplace_back(obj_fac.create_net_obj(descriptor, smartapp->UID()));
320
321 std::string sidToNetUid(descriptor->get_uid_base() + smartapp->UID() + "-sids");
322 sidNetObjs.emplace_back(
323 obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
324 if (roapp != nullptr) {
325 fill_sourceid_object_from_app(obj_fac, roapp, &dreqNetObjs.back(), sidNetObjs.back(), sidObjs);
326 } else if (fdapp != nullptr) {
327 fill_sourceid_object_from_app(obj_fac, fdapp, &dreqNetObjs.back(), sidNetObjs.back(), sidObjs);
328 } else {
329 fill_sourceid_object_from_app(smartapp, &dreqNetObjs.back(), sidNetObjs.back());
330 }
331 } // else from if (ctbapp)
332 } // If network rule has DataRequest type of data
333 } // Loop over Apps network rules
334 } // loop over Session specific Apps
335
336 // Get pointers to objects here, after vector has been filled so they don't move on us
337 for (auto& obj : dreqNetObjs) {
338 trbOutputObjs.push_back(&obj);
339 }
340 for (auto& obj : sidNetObjs) {
341 trbSidNetObjs.push_back(&obj);
342 }
343
344 // -- Second, we create the Module objects and assign their configs, with the precreated
345 // -- connection config objects above.
346
347 // Get TRB Config Object
348 auto trbConf = get_trb();
349 if (trbConf == nullptr) {
350 throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
351 }
352 auto trbConfObj = trbConf->config_object();
353 trbConfObj.set_by_val<uint32_t>("source_id", get_source_id()->get_sid());
354 trbInputObjs = { &trigdecNetObj, &fragNetObj };
355 if (trmonReqNetDesc != nullptr) {
356 trbInputObjs.push_back(&trmonReqNetObj);
357 }
358 if (trmonTRNetDesc != nullptr) {
359 trbOutputObjs.push_back(&trmonTRNetObj);
360 }
361 // Prepare TRB Module Object and assign its Config Object.
362 std::string trbUid(UID() + "-trb");
363 conffwk::ConfigObject trbObj = obj_fac.create("TRBModule", trbUid);
364 trbObj.set_obj("configuration", &trbConfObj);
365 trbObj.set_objs("inputs", trbInputObjs);
366 trbObj.set_objs("outputs", trbOutputObjs);
367 trbObj.set_obj("trigger_record_output", &trQueueObj);
368 trbObj.set_objs("request_connections", trbSidNetObjs);
369 // Push TRB Module Object from confdb
370 modules.push_back(obj_fac.get_dal<TRBModule>(trbUid));
371
372 // Get DataWriterModule Config Object (only one for now, maybe more later?)
373 auto dwrConfs = get_data_writers();
374 if (dwrConfs.size() == 0) {
375 throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
376 }
377 uint dw_idx = 0;
378 for (auto dwrConf : dwrConfs) {
379 // auto fnParamsObj = dwrConf->get_data_store_params()->get_filename_params()->config_object();
380 // fnParamsObj.set_by_val<std::string>("writer_identifier", fmt::format("{}_datawriter-{}", UID(), dw_idx));
381 auto dwrConfObj = dwrConf->config_object();
382
383 // Prepare DataWriterModule Module Object and assign its Config Object.
384 std::string dwrUid(fmt::format("{}-dw-{}", UID(), dw_idx));
385 conffwk::ConfigObject dwrObj = obj_fac.create("DataWriterModule", dwrUid);
386 dwrObj.set_by_val("writer_identifier", fmt::format("{}_dw_{}", UID(), dw_idx));
387 dwrObj.set_obj("configuration", &dwrConfObj);
388 dwrObj.set_objs("inputs", { &trQueueObj });
389 dwrObj.set_objs("outputs", { &tokenNetObj });
390 // Push DataWriterModule Module Object from confdb
391 modules.push_back(obj_fac.get_dal<DataWriterModule>(dwrUid));
392 ++dw_idx;
393 }
394
395 return modules;
396}
397
398} // namespace appmodel
399} // namespace dunedaq
#define ERS_HERE
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()
std::vector< const dunedaq::confmodel::DaqModule * > generate_modules(const confmodel::Session *) const override
const std::vector< const dunedaq::appmodel::FakeDataProdConf * > & get_producers() const
Get "producers" relationship value. List of configurations of fake data producer modules to be used b...
const std::vector< const dunedaq::confmodel::DetectorToDaqConnection * > & get_detector_connections() const
Get "detector_connections" relationship value. The list of detector channels to be read out by this r...
const std::vector< const dunedaq::appmodel::SourceIDConf * > & get_tp_source_ids() const
Get "tp_source_ids" relationship value.
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.
const std::vector< const dunedaq::appmodel::SourceIDConf * > & get_tp_source_ids() const
Get "tp_source_ids" relationship 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 TARGET * cast() const noexcept
Casts object to different class.
const ConfigObject & config_object() const
const std::string & UID() const noexcept
conffwk entry point
void fill_sourceid_object_from_app(const SmartDaqApplication *smartapp, const conffwk::ConfigObject *netConn, conffwk::ConfigObject &sidNetObj)
The DUNE-DAQ namespace.
msgpack::object obj