DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
MLTApplication.cpp
Go to the documentation of this file.
1
13
15
18// #include "confmodel/ReadoutGroup.hpp"
19// #include "confmodel/ReadoutInterface.hpp"
20// #include "confmodel/DetectorStream.hpp"
24#include "confmodel/Service.hpp"
25#include "confmodel/Session.hpp"
26
39#include "appmodel/MLTConf.hpp"
55
56#include "logging/Logging.hpp"
57
58#include <string>
59#include <vector>
60
61namespace dunedaq {
62namespace appmodel {
63
64
65std::vector<const confmodel::DaqModule*>
67{
68
69 std::vector<const confmodel::DaqModule*> modules;
70
71 ConfigObjectFactory obj_fac(this);
72
73 // auto mlt_conf = get_mlt_conf();
74 // auto mlt_class = mlt_conf->get_template_for();
75
76 auto tch_conf = get_trigger_inputs_handler();
77 auto tch_class = tch_conf->get_template_for();
78
79 auto mlt_conf = get_mlt_conf();
80 auto mlt_class = mlt_conf->get_template_for();
81 std::string handler_name(tch_conf->UID());
82
83 if (!mlt_conf) {
84 throw(BadConf(ERS_HERE, "No MLT configuration in MLTApplication given"));
85 }
86
87 // Queue descriptors
88 // Process the queue rules looking for inputs to our trigger handler modules
89 const QueueDescriptor* tc_inputq_desc = nullptr;
90 const QueueDescriptor* td_outputq_desc = nullptr;
91
92 for (auto rule : get_queue_rules()) {
93 auto destination_class = rule->get_destination_class();
94 auto data_type = rule->get_descriptor()->get_data_type();
95 if (destination_class == tch_class) {
96 tc_inputq_desc = rule->get_descriptor();
97 } else if (destination_class == mlt_class) {
98 td_outputq_desc = rule->get_descriptor();
99 }
100 }
101
102 if (tc_inputq_desc == nullptr) {
103 throw(BadConf(ERS_HERE, "No TC input queue descriptor given"));
104 }
105 if (td_outputq_desc == nullptr) {
106 throw(BadConf(ERS_HERE, "No TD output-input queue descriptor given"));
107 }
108
109 // Create queues
110 auto input_queue_obj = obj_fac.create_queue_obj(tc_inputq_desc);
111 auto output_queue_obj = obj_fac.create_queue_obj(td_outputq_desc);
112
113 // Net descriptors
114 const NetworkConnectionDescriptor* req_net_desc = nullptr;
115 const NetworkConnectionDescriptor* tc_net_desc = nullptr;
116 const NetworkConnectionDescriptor* ti_net_desc = nullptr;
117 const NetworkConnectionDescriptor* td_net_desc = nullptr;
118 const NetworkConnectionDescriptor* timesync_net_desc = nullptr;
119
120 for (auto rule : get_network_rules()) {
121 std::string data_type = rule->get_descriptor()->get_data_type();
122
123 // Network connections for the MLT
124 if (data_type == "TriggerInhibit") {
125 ti_net_desc = rule->get_descriptor();
126 }
127 if (data_type == "TriggerDecision") {
128 td_net_desc = rule->get_descriptor();
129 }
130 if (data_type == "TriggerCandidate") {
131 tc_net_desc = rule->get_descriptor();
132 }
133 if (data_type == "TimeSync") {
134 timesync_net_desc = rule->get_descriptor();
135 }
136 if (data_type == "DataRequest") {
137 req_net_desc = rule->get_descriptor();
138 }
139
140 TLOG_DEBUG(3) << "Endpoint class (currently not used in for networkconnections): data_type: " << data_type;
141 }
142
143 if (!td_net_desc) {
144 throw(BadConf(ERS_HERE, "No MLT network connection for the output TriggerDecision given"));
145 }
146 if (!ti_net_desc) {
147 throw(BadConf(ERS_HERE, "No MLT network connection for the output TriggerInhibit given"));
148 }
149 if (!tc_net_desc) {
150 throw(BadConf(ERS_HERE, "No MLT network connection for the Input of TriggerCandidates given"));
151 }
152 if (!req_net_desc) {
153 throw(BadConf(ERS_HERE, "No MLT network connection for the Input of DataRequests given"));
154 }
155 // Network connection for input TriggerInhibit, input TCs
156
157 conffwk::ConfigObject ti_net_obj =
158 obj_fac.create_net_obj(ti_net_desc, "");
159
160 conffwk::ConfigObject tc_net_obj =
161 obj_fac.create_net_obj(tc_net_desc, ".*");
162
163 // Network connection for output TriggerDecision
164 conffwk::ConfigObject td_net_obj =
165 obj_fac.create_net_obj(td_net_desc, "");
166
167 // Network conection for the input Data Requests
168 conffwk::ConfigObject dr_net_obj =
169 obj_fac.create_net_obj(req_net_desc, UID());
170
171 conffwk::ConfigObject timesync_net_obj;
172 if (timesync_net_desc != nullptr) {
173 timesync_net_obj =
174 obj_fac.create_net_obj(timesync_net_desc, ".*");
175 }
176
177 /**************************************************************
178 * Instantiate standalone TC generator modules (e.g. random TC generator)
179 **************************************************************/
180
181 auto standalone_TC_maker_confs = get_standalone_candidate_maker_confs();
182 std::vector<conffwk::ConfigObject> generated_tc_conns;
183 generated_tc_conns.reserve(standalone_TC_maker_confs.size());
184 for (auto gen_conf : standalone_TC_maker_confs) {
185 conffwk::ConfigObject gen_obj = obj_fac.create(gen_conf->get_template_for(),
186 gen_conf->UID());
187 gen_obj.set_obj("configuration", &(gen_conf->config_object()));
188 if (gen_conf->get_timestamp_method() == "kTimeSync" && !timesync_net_obj.is_null()) {
189 gen_obj.set_objs("inputs", { &timesync_net_obj });
190 }
191
192 auto tc_net_gen = obj_fac.create_net_obj(tc_net_desc, gen_conf->UID());
193 generated_tc_conns.push_back(tc_net_gen);
194
195 gen_obj.set_objs("outputs", { &generated_tc_conns.back() });
196 modules.push_back(obj_fac.get_dal<StandaloneTCMakerModule>(gen_conf->UID()));
197 }
198
199 /**************************************************************
200 * Create the Data Reader
201 **************************************************************/
202 auto rdr_conf = get_data_subscriber();
203 if (rdr_conf == nullptr) {
204 throw(BadConf(ERS_HERE, "No DataReaderModule configuration given"));
205 }
206
207 std::string reader_uid("data-reader-" + UID());
208 std::string reader_class = rdr_conf->get_template_for();
209 TLOG_DEBUG(7) << "creating OKS configuration object for Data subscriber class " << reader_class;
210 conffwk::ConfigObject reader_obj = obj_fac.create(reader_class, reader_uid);
211 reader_obj.set_objs("inputs", { &tc_net_obj });
212 reader_obj.set_objs("outputs", { &input_queue_obj });
213 reader_obj.set_obj("configuration", &rdr_conf->config_object());
214
215 modules.push_back(obj_fac.get_dal<DataSubscriberModule>(reader_uid));
216
217 /**************************************************************
218 * Create the readout map
219 **************************************************************/
220
221 std::vector<const dunedaq::confmodel::Application*> apps = session->enabled_applications();
222
223 std::vector<const conffwk::ConfigObject*> sourceIds;
224
225 for (auto app : apps) {
226 auto ro_app = app->cast<appmodel::ReadoutApplication>();
227 if (ro_app != nullptr) {
228 auto connections = ro_app->get_detector_connections();
229 // Interate over all the readout groups
230 for (auto d2d_conn : connections) {
231 if (d2d_conn->is_disabled(*session)) {
232 TLOG_DEBUG(7) << "Ignoring disabled Detector2DaqConnection " << d2d_conn->UID();
233 continue;
234 }
235
236 if (d2d_conn->contained_resources().empty()) {
237 throw(BadConf(ERS_HERE, "DetectorToDaqConnection does not contain interfaces"));
238 }
239
240 // Interate over all the streams
241 for (auto stream : d2d_conn->streams()) {
242 if (stream == nullptr) {
243 throw(BadConf(ERS_HERE, "ReadoutInterface contains something other than DetectorStream"));
244 }
245 if (stream->is_disabled(*session)) {
246 TLOG_DEBUG(7) << "Ignoring disabled DetectorStream " << stream->UID();
247 continue;
248 }
249
250 // Create SourceIDConf object for the MLT
251 auto id = stream->get_source_id();
252 std::string sourceIdConfUID = "dro-mlt-stream-config-" + std::to_string(id);
254 obj_fac.create("SourceIDConf", sourceIdConfUID));
255 sourceIdConf->set_by_val<uint32_t>("sid", id);
256 // https://github.com/DUNE-DAQ/daqdataformats/blob/5b99506675a586c8a09123900e224f2371d96df9/include/daqdataformats/detail/SourceID.hxx#L108
257 sourceIdConf->set_by_val<std::string>("subsystem", "Detector_Readout");
258 sourceIds.push_back(sourceIdConf);
259 }
260 }
261 if (ro_app->get_tp_generation_enabled()) {
262 for (auto sid : ro_app->get_tp_source_ids()) {
263 sourceIds.push_back(&(sid->config_object()));
264 }
265 // conffwk::ConfigObject* tpSourceIdConf = new conffwk::ConfigObject();
266 // confdb->create(dbfile, "SourceIDConf", ro_app->UID()+"-"+ std::to_string(ro_app->get_tp_source_id()),
267 // *tpSourceIdConf); tpSourceIdConf->set_by_val<uint32_t>("sid", ro_app->get_tp_source_id());
268 // tpSourceIdConf->set_by_val<std::string>("subsystem", "Trigger");
269 // sourceIds.push_back(tpSourceIdConf);
270 }
271 }
272
273 auto tpreplay_app = app->cast<appmodel::TPReplayApplication>();
274 if (tpreplay_app != nullptr) {
275 for (auto sid : tpreplay_app->get_tp_source_ids()) {
276 sourceIds.push_back(&(sid->config_object()));
277 }
278 }
279
280 auto fd_app = app->cast<appmodel::FakeDataApplication>();
281 if (fd_app != nullptr) {
282
283 auto producers = fd_app->get_producers();
284 // Interate over all the FakeDataProd modules
285 for (auto stream : producers) {
286
287 if (stream->is_disabled(*session)) {
288 TLOG_DEBUG(7) << "Ignoring disabled FakeDataProdConf " << stream->UID();
289 continue;
290 }
291
292 // Create SourceIDConf object for the MLT
293 auto id = stream->get_source_id();
294 std::string sourceIdConfUID = "dro-mlt-stream-config-" + std::to_string(id);
296 obj_fac.create("SourceIDConf", sourceIdConfUID));
297 sourceIdConf->set_by_val<uint32_t>("sid", id);
298 // https://github.com/DUNE-DAQ/daqdataformats/blob/5b99506675a586c8a09123900e224f2371d96df9/include/daqdataformats/detail/SourceID.hxx#L108
299 sourceIdConf->set_by_val<std::string>("subsystem", "Detector_Readout");
300 sourceIds.push_back(sourceIdConf);
301 }
302 }
303
304 // SmartDaqApplication now has source_id member, might want to use that but make sure that it's actually a data
305 // source somehow...
306 auto trg_app = app->cast<appmodel::TriggerApplication>();
307 if (trg_app != nullptr && trg_app->get_source_id() != nullptr) {
308 conffwk::ConfigObject* tcSourceIdConf = new conffwk::ConfigObject(
309 obj_fac.create(
310 "SourceIDConf",
311 trg_app->UID() + "-" + std::to_string(trg_app->get_source_id()->get_sid())
312 ));
313 tcSourceIdConf->set_by_val<uint32_t>("sid", trg_app->get_source_id()->get_sid());
314 tcSourceIdConf->set_by_val<std::string>("subsystem", trg_app->get_source_id()->get_subsystem());
315 sourceIds.push_back(tcSourceIdConf);
316 }
317
318 // FIXME: add here same logics for HSI application(s)
319 //
320 auto hsi_app = app->cast<appmodel::FakeHSIApplication>();
321 if (hsi_app != nullptr && hsi_app->get_source_id() != nullptr) {
322 conffwk::ConfigObject* hsEventSourceIdConf = new conffwk::ConfigObject(
323 obj_fac.create(
324 "SourceIDConf",
325 hsi_app->UID() + "-" + std::to_string(hsi_app->get_source_id()->get_sid())));
326 hsEventSourceIdConf->set_by_val<uint32_t>("sid", hsi_app->get_source_id()->get_sid());
327 hsEventSourceIdConf->set_by_val<std::string>("subsystem", hsi_app->get_source_id()->get_subsystem());
328 sourceIds.push_back(hsEventSourceIdConf);
329 }
330
331 auto dts_hsi_app = app->cast<appmodel::DTSHSIApplication>();
332 if (dts_hsi_app != nullptr && dts_hsi_app->get_source_id() != nullptr) {
333 conffwk::ConfigObject* hsEventSourceIdConf = new conffwk::ConfigObject(
334 obj_fac.create(
335 "SourceIDConf",
336 dts_hsi_app->UID() + "-" + std::to_string(dts_hsi_app->get_source_id()->get_sid())
337 )
338 );
339 hsEventSourceIdConf->set_by_val<uint32_t>("sid", dts_hsi_app->get_source_id()->get_sid());
340 hsEventSourceIdConf->set_by_val<std::string>("subsystem", dts_hsi_app->get_source_id()->get_subsystem());
341 sourceIds.push_back(hsEventSourceIdConf);
342 }
343
344 auto ctb_app = app->cast<appmodel::CTBApplication>();
345 if (ctb_app) {
346 auto sources = ctb_app->get_sources();
347 for ( const auto & s : sources ) {
348 auto src_id_conf_ptr = new conffwk::ConfigObject( obj_fac.create("SourceIDConf",
349 ctb_app->UID() + "-" + s.first ) );
350 src_id_conf_ptr->set_by_val<uint32_t>("sid", s.second->get_sid());
351 src_id_conf_ptr->set_by_val<std::string>("subsystem", s.second->get_subsystem());
352 sourceIds.push_back(src_id_conf_ptr);
353 } // loop over CTB sources
354 } // CTB app
355
356 } // loop over applications
357
358 // Get mandatory links
359 std::vector<const conffwk::ConfigObject*> mandatory_sids;
360 const TCDataProcessor* tc_dp = tch_conf->get_data_processor()->cast<TCDataProcessor>();
361 if (tc_dp != nullptr) {
362 for (auto m : tc_dp->get_mandatory_links()) {
363 mandatory_sids.push_back(&m->config_object());
364 }
365 }
366
367 /**************************************************************
368 * Create the TC handler
369 **************************************************************/
370
371 // Process special Network rules!
372 // Looking for Fragment rules from DFAppplications in current Session
373 auto sessionApps = session->enabled_applications();
374 std::vector<conffwk::ConfigObject> fragOutObjs;
375 for (auto app : sessionApps) {
376 auto dfapp = app->cast<appmodel::DFApplication>();
377 if (dfapp == nullptr)
378 continue;
379
380 auto dfNRules = dfapp->get_network_rules();
381 for (auto rule : dfNRules) {
382 auto descriptor = rule->get_descriptor();
383 auto data_type = descriptor->get_data_type();
384 if (data_type == "Fragment") {
385 fragOutObjs.emplace_back(obj_fac.create_net_obj(descriptor, dfapp->UID()));
386 } // If network rule has TriggerDecision type of data
387 } // Loop over Apps network rules
388 } // loop over Session specific Apps
389
390 // build up the full list of outputs
391 std::vector<const conffwk::ConfigObject*> ti_output_objs;
392 for (auto& fNet : fragOutObjs) {
393 ti_output_objs.push_back(&fNet);
394 }
395 ti_output_objs.push_back(&output_queue_obj);
396
397 auto tch_conf_obj = tch_conf->config_object();
398 if (get_source_id() == nullptr) {
399 throw(BadConf(ERS_HERE, "No source_id associated with this TriggerApplication!"));
400 }
401 uint32_t source_id = get_source_id()->get_sid();
402 std::string ti_uid(handler_name + "-" + std::to_string(source_id));
403 conffwk::ConfigObject ti_obj = obj_fac.create(tch_class, ti_uid);
404 ti_obj.set_by_val<uint32_t>("source_id", source_id);
405 ti_obj.set_by_val<uint32_t>("detector_id", 1); // 1 == kDAQ
406 ti_obj.set_obj("module_configuration", &tch_conf_obj);
407 ti_obj.set_objs("enabled_source_ids", sourceIds);
408 ti_obj.set_objs("mandatory_source_ids", mandatory_sids);
409 ti_obj.set_objs("inputs", { &input_queue_obj, &dr_net_obj });
410 ti_obj.set_objs("outputs", ti_output_objs);
411
412 // Add to our list of modules to return
413 modules.push_back(obj_fac.get_dal<DataHandlerModule>(ti_uid));
414
415 /**************************************************************
416 * Instantiate the MLTModule module
417 **************************************************************/
418
419 conffwk::ConfigObject mlt_obj = obj_fac.create(mlt_conf->get_template_for(),
420 mlt_conf->UID());
421 mlt_obj.set_obj("configuration", &(mlt_conf->config_object()));
422 mlt_obj.set_objs("inputs", { &output_queue_obj, &ti_net_obj });
423 mlt_obj.set_objs("outputs", { &td_net_obj });
424 modules.push_back(obj_fac.get_dal<MLTModule>(mlt_conf->UID()));
425
426 return modules;
427}
428
429} // namespace appmodel
430} // 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::StandaloneTCMakerConf * > & get_standalone_candidate_maker_confs() const
Get "standalone_candidate_maker_confs" relationship value.
const dunedaq::appmodel::MLTConf * get_mlt_conf() const
Get "mlt_conf" relationship value.
std::vector< const dunedaq::confmodel::DaqModule * > generate_modules(const confmodel::Session *) 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.
const std::vector< const dunedaq::appmodel::SourceIDConf * > & get_mandatory_links() const
Get "mandatory_links" relationship value. Source Ids that will always be included in a trigger decisi...
const dunedaq::appmodel::DataHandlerConf * get_trigger_inputs_handler() const
Get "trigger_inputs_handler" relationship value.
const dunedaq::appmodel::DataReaderConf * get_data_subscriber() const
Get "data_subscriber" 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.
bool is_null() const noexcept
Check if object's implementation points to null.
const TARGET * cast() const noexcept
Casts object to different class.
const std::string & UID() const noexcept
conffwk entry point
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
The DUNE-DAQ namespace.
Definition DataStore.hpp:57