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*> trbOutputObjs;
203 std::vector<const conffwk::ConfigObject*> trbSidNetObjs;
204
205 // -- First, we process expected Queue and Network connections and create their objects.
206
207 // Process the queue rules looking for the TriggerRecord queue between TRB and DataWriterModule
208 const QueueDescriptor* trQDesc = nullptr;
209 for (auto rule : get_queue_rules()) {
210 auto destination_class = rule->get_destination_class();
211 if (destination_class == "DataWriterModule") {
212 trQDesc = rule->get_descriptor();
213 }
214 }
215 if (trQDesc == nullptr) { // BadConf if no descriptor between TRB and DataWriterModule
216 throw(BadConf(ERS_HERE, "Could not find queue descriptor rule for TriggerRecords!"));
217 }
218 // Create queue connection config object
219 auto trQueueObj = obj_fac.create_queue_obj(trQDesc, UID());
220
221 // Place trigger record queue object into vector of output objs of TRB module
222 trbOutputObjs.push_back(&trQueueObj);
223
224 // Process the network rules looking for the Fragments and TriggerDecision inputs for TRB
225 const NetworkConnectionDescriptor* fragNetDesc = nullptr;
226 const NetworkConnectionDescriptor* trigdecNetDesc = nullptr;
227 const NetworkConnectionDescriptor* tokenNetDesc = nullptr;
228 for (auto rule : get_network_rules()) {
229 auto descriptor = rule->get_descriptor();
230 auto data_type = descriptor->get_data_type();
231 if (data_type == "Fragment") {
232 fragNetDesc = rule->get_descriptor();
233 } else if (data_type == "TriggerDecision") {
234 trigdecNetDesc = rule->get_descriptor();
235 } else if (data_type == "TriggerDecisionToken") {
236 tokenNetDesc = rule->get_descriptor();
237 }
238 }
239 if (fragNetDesc == nullptr) { // BadConf if no descriptor for Fragments into TRB
240 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input Fragments!"));
241 }
242 if (trigdecNetDesc == nullptr) { // BadCond if no descriptor for TriggerDecisions into TRB
243 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for input TriggerDecisions!"));
244 }
245 if (tokenNetDesc == nullptr) { // BadCond if no descriptor for Tokens out of DataWriterModule
246 throw(BadConf(ERS_HERE, "Could not find network descriptor rule for output TriggerDecisionTokens!"));
247 }
248 if (get_source_id() == nullptr) {
249 throw(BadConf(ERS_HERE, "Could not retrieve SourceIDConf"));
250 }
251 // Create network connection config object
252 auto fragNetObj = obj_fac.create_net_obj(fragNetDesc, UID());
253 auto trigdecNetObj = obj_fac.create_net_obj(trigdecNetDesc, UID());
254 auto tokenNetObj = obj_fac.create_net_obj(tokenNetDesc, "");
255
256 // Process special Network rules!
257 // Looking for DataRequest rules from ReadoutAppplications in current Session
258 auto sessionApps = session->enabled_applications();
259 std::vector<conffwk::ConfigObject> dreqNetObjs;
260 std::vector<conffwk::ConfigObject> sidNetObjs;
261 std::vector<std::shared_ptr<conffwk::ConfigObject>> sidObjs;
262 for (auto app : sessionApps) {
263 auto smartapp = app->cast<appmodel::SmartDaqApplication>();
264 auto roapp = app->cast<appmodel::ReadoutApplication>();
265 auto fdapp = app->cast<appmodel::FakeDataApplication>();
266 auto ctbapp = app->cast<appmodel::CTBApplication>();
267 auto dfapp = app->cast<appmodel::DFApplication>();
268 auto rapp = app->cast<appmodel::TPReplayApplication>();
269 if (smartapp == nullptr || dfapp != nullptr) {
270 continue;
271 }
272 auto src_id_check = smartapp->get_source_id();
273 if (roapp == nullptr
274 && fdapp == nullptr
275 && src_id_check == nullptr
276 && rapp == nullptr
277 && ctbapp == nullptr) {
278 continue;
279 }
280
281 auto roQRules = smartapp->get_network_rules();
282 for (auto rule : roQRules) {
283 auto descriptor = rule->get_descriptor();
284 auto data_type = descriptor->get_data_type();
285 if (data_type == "DataRequest") {
286 if (rapp != nullptr) {
287 fill_sourceid_object_from_app(obj_fac, rapp, &dreqNetObjs, &sidNetObjs, sidObjs, descriptor, smartapp->UID());
288 }
289 // contrary to all the other applications
290 // the CTB has 2 network connections, so this logic has to be splitted
291 else if (ctbapp) {
292 auto sources = ctbapp->get_sources();
293 for ( const auto & s : sources ) {
294 std::string dreqNetUid(descriptor->get_uid_base() + smartapp->UID()+ '_' + s.first);
295 dreqNetObjs.emplace_back( obj_fac.create_net_obj(descriptor, dreqNetUid) );
296
297 std::string sidToNetUid(descriptor->get_uid_base() + smartapp->UID() + "_" + s.first);
298 sidNetObjs.emplace_back( obj_fac.create("SourceIDToNetworkConnection", sidToNetUid ) );
299 sidNetObjs.back().set_obj("netconn", & dreqNetObjs.back());
300 sidNetObjs.back().set_objs("source_ids", { & s.second->config_object() });
301 } // loop over CTB sources
302 } else {
303
304 dreqNetObjs.emplace_back(obj_fac.create_net_obj(descriptor, smartapp->UID()));
305
306 std::string sidToNetUid(descriptor->get_uid_base() + smartapp->UID() + "-sids");
307 sidNetObjs.emplace_back(
308 obj_fac.create("SourceIDToNetworkConnection", sidToNetUid));
309 if (roapp != nullptr) {
310 fill_sourceid_object_from_app(obj_fac, roapp, &dreqNetObjs.back(), sidNetObjs.back(), sidObjs);
311 } else if (fdapp != nullptr) {
312 fill_sourceid_object_from_app(obj_fac, fdapp, &dreqNetObjs.back(), sidNetObjs.back(), sidObjs);
313 } else {
314 fill_sourceid_object_from_app(smartapp, &dreqNetObjs.back(), sidNetObjs.back());
315 }
316 } // else from if (ctbapp)
317 } // If network rule has DataRequest type of data
318 } // Loop over Apps network rules
319 } // loop over Session specific Apps
320
321 // Get pointers to objects here, after vector has been filled so they don't move on us
322 for (auto& obj : dreqNetObjs) {
323 trbOutputObjs.push_back(&obj);
324 }
325 for (auto& obj : sidNetObjs) {
326 trbSidNetObjs.push_back(&obj);
327 }
328
329 // -- Second, we create the Module objects and assign their configs, with the precreated
330 // -- connection config objects above.
331
332 // Get TRB Config Object
333 auto trbConf = get_trb();
334 if (trbConf == nullptr) {
335 throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
336 }
337 auto trbConfObj = trbConf->config_object();
338 trbConfObj.set_by_val<uint32_t>("source_id", get_source_id()->get_sid());
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", { &trigdecNetObj, &fragNetObj });
344 trbObj.set_objs("outputs", trbOutputObjs);
345 trbObj.set_objs("request_connections", trbSidNetObjs);
346 // Push TRB Module Object from confdb
347 modules.push_back(obj_fac.get_dal<TRBModule>(trbUid));
348
349 // Get DataWriterModule Config Object (only one for now, maybe more later?)
350 auto dwrConfs = get_data_writers();
351 if (dwrConfs.size() == 0) {
352 throw(BadConf(ERS_HERE, "No DataWriterModule or TRB configuration given"));
353 }
354 uint dw_idx = 0;
355 for (auto dwrConf : dwrConfs) {
356 // auto fnParamsObj = dwrConf->get_data_store_params()->get_filename_params()->config_object();
357 // fnParamsObj.set_by_val<std::string>("writer_identifier", fmt::format("{}_datawriter-{}", UID(), dw_idx));
358 auto dwrConfObj = dwrConf->config_object();
359
360 // Prepare DataWriterModule Module Object and assign its Config Object.
361 std::string dwrUid(fmt::format("{}-dw-{}", UID(), dw_idx));
362 conffwk::ConfigObject dwrObj = obj_fac.create("DataWriterModule", dwrUid);
363 dwrObj.set_by_val("writer_identifier", fmt::format("{}_dw_{}", UID(), dw_idx));
364 dwrObj.set_obj("configuration", &dwrConfObj);
365 dwrObj.set_objs("inputs", { &trQueueObj });
366 dwrObj.set_objs("outputs", { &tokenNetObj });
367 // Push DataWriterModule Module Object from confdb
368 modules.push_back(obj_fac.get_dal<DataWriterModule>(dwrUid));
369 ++dw_idx;
370 }
371
372 return modules;
373}
374
375} // namespace appmodel
376} // 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.
Definition DataStore.hpp:57
msgpack::object obj