DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
WIECApplication.cpp
Go to the documentation of this file.
1
10
13#include "logging/Logging.hpp"
14
17#include "confmodel/GeoId.hpp"
19
22
31
32#include <fmt/core.h>
33#include <iostream>
34#include <string>
35#include <vector>
36
37namespace dunedaq {
38namespace appmodel {
39
40//-----------------------------------------------------------------------------
41
42std::vector<const confmodel::ExcludableEntity*>
47
48void
49WIECApplication::generate_modules(std::shared_ptr<appmodel::ConfigurationHelper> helper) const
50{
51 ConfigObjectFactory obj_fac(this);
53 const std::string& dbfile = this->config_object().contained_in();
54
55 std::vector<const confmodel::DaqModule*> modules;
56
57 std::map<std::string, std::vector<const appmodel::HermesDataSender*>> ctrlhost_sender_map;
58
59 // uint16_t conn_idx = 0;
60 for (auto d2d_conn : get_detector_connections()) {
61
62 // Are we sure?
63 if (helper->is_excluded(d2d_conn)) {
64 TLOG_DEBUG(7) << "Ignoring excluded DetectorToDaqConnection " << d2d_conn->UID();
65 continue;
66 }
67
68 TLOG_DEBUG(6) << "Processing DetectorToDaqConnection " << d2d_conn->UID();
69
70 // Is this check necessary?
71 if (d2d_conn->contained_excludable_entities().empty()) {
72 throw(BadConf(ERS_HERE, "DetectorToDaqConnection does not contain senders or receivers"));
73 }
74
75 auto det_senders = d2d_conn->senders();
76 auto det_receiver = d2d_conn->receiver();
77
78 // Ensure that receiver is a nw_receiver
79 const auto* nw_receiver = det_receiver->cast<appmodel::NWDetDataReceiver>();
80
81 if (!nw_receiver) {
82 throw(BadConf(ERS_HERE,
83 fmt::format("WEICApplication requires NWDetDataReceiver, found {} of class {}",
84 det_receiver->UID(),
85 det_receiver->class_name())));
86 }
87
88 // Note on how to exclude the senders.
89 // The hardware interface requires that all the physical links be configured, even if not used for a run.
90 // Consequently, at the configuration level, we should never remove senders from a detector to daq connection.
91 // At most, we should exclude them at the level of the session.
92 // For the same reason, in this code, we create a map of control hosts to senders, without checking if the senders
93 // are excluded. Once the map is created, if all the senders associated to a control hosts are excluded, then we
94 // skip the creation of all related modules.
95
96 // Loop over senders to create the map of control hosts to senders.
97 for (const auto* sender : det_senders) {
98
99 // Check the sender type, must be a HermesSender
100 const auto* hrms_sender = sender->cast<appmodel::HermesDataSender>();
101 if (!hrms_sender) {
102 throw(BadConf(ERS_HERE, fmt::format("DataSender {} is not a appmodel::HermesDataSender", sender->UID())));
103 }
104
105 ctrlhost_sender_map[hrms_sender->get_control_host()].push_back(hrms_sender);
106 }
107
108 for (const auto& [ctrlhost, senders] : ctrlhost_sender_map) {
109
110 // If all senders for this control host are excluded, skip creating related modules.
111 // Of course the opposite logic is faster: check if any sender is included.
112 bool any_included = false;
113 for (const auto* sender : senders) {
114 if (helper->is_included(sender)) {
115 any_included = true;
116 break;
117 }
118 }
119 if (!any_included) {
120 TLOG_DEBUG(6) << "Skipping control host " << ctrlhost << " whose senders are all excluded.";
121 continue;
122 }
123
124 // Create WIBModule
125 if (this->get_wib_module_conf()) {
126
127 bool enable_fembs[4] = { false, false, false, false };
128
129 for (const auto* sender : senders) {
130 for (const auto* det_stream : sender->get_streams()) {
131 // Loop over streams for this sender
132 // Retrieve stream_id and calculate the femb_id
133 uint32_t stream_id = det_stream->get_geo_id()->get_stream_id();
134 uint32_t femb_id = (stream_id & 0xf) / 2 + 2 * ((stream_id >> 6) & 0xf);
135
136 // std::cout << std::format("stream {} -> femb {}", stream_id, femb_id) << std::endl;
137
138 // Enable the femb if any of the associated streams is enabled
139 enable_fembs[femb_id] |= helper->is_included(det_stream);
140 } // loop over streams
141 } // loop over senders for this control host
142
143 std::string wib_uid = fmt::format("wib-ctrl-{}-{}", this->UID(), ctrlhost);
144 conffwk::ConfigObject wib_obj = obj_fac.create("WIBModule", wib_uid);
145 wib_obj.set_by_val<std::string>("wib_addr",
146 fmt::format("{}://{}:{}",
147 this->get_wib_module_conf()->get_communication_type(),
148 ctrlhost,
149 this->get_wib_module_conf()->get_communication_port()));
150 for (int i = 0; i < 4; ++i) {
151 wib_obj.set_by_val<bool>(fmt::format("enabled_femb{}", i), enable_fembs[i]);
152 }
153 wib_obj.set_obj("conf", &this->get_wib_module_conf()->get_settings()->config_object());
154 modules.push_back(config->get<appmodel::WIBModule>(wib_obj));
155 } // if we have a module configuration for the WIB module
156
157 // Create Hermes Modules
158 if (this->get_hermes_module_conf()) {
159 std::string hermes_uid = fmt::format("hermes-ctrl-{}-{}", this->UID(), ctrlhost);
160 conffwk::ConfigObject hermes_obj = obj_fac.create("HermesModule", hermes_uid);
161 hermes_obj.set_obj("address_table", &this->get_hermes_module_conf()->get_address_table()->config_object());
162 hermes_obj.set_by_val<std::string>("uri",
163 fmt::format("{}://{}:{}",
164 this->get_hermes_module_conf()->get_ipbus_type(),
165 ctrlhost,
166 this->get_hermes_module_conf()->get_ipbus_port()));
167 hermes_obj.set_by_val<uint32_t>("timeout_ms", this->get_hermes_module_conf()->get_ipbus_timeout_ms());
168 hermes_obj.set_obj("destination", &nw_receiver->get_uses()->config_object());
169
170 std::vector<const conffwk::ConfigObject*> links_obj;
171 for (const auto* sndr : senders) {
172 // Note that it is OK that some of these senders might be excluded
173 // The hardware interface in HermesModule requires that all links be configured, even if not used for a run
174 links_obj.push_back(&sndr->config_object());
175 }
176 hermes_obj.set_objs("links", links_obj);
177
178 modules.push_back(config->get<appmodel::HermesModule>(hermes_obj));
179 } // If we have a module configuration for the Hermes module
180
181 } // loop over control hosts
182
183 } // loop over detector to daq connections
184
185 obj_fac.update_modules(modules);
186}
187
188} // namespace appmodel
189} // namespace dunedaq
#define ERS_HERE
void update_modules(const std::vector< const confmodel::DaqModule * > &modules)
conffwk::ConfigObject create(const std::string &class_name, const std::string &id) const
uint32_t get_ipbus_timeout_ms() const
Get "ipbus_timeout_ms" attribute value.
virtual std::vector< const ExcludableEntity * > contained_excludable_entities() const override
const dunedaq::appmodel::WIBModuleConf * get_wib_module_conf() const
Get "wib_module_conf" relationship value.
const std::vector< const dunedaq::confmodel::DetectorToDaqConnection * > & get_detector_connections() const
Get "detector_connections" relationship value.
const dunedaq::appmodel::HermesModuleConf * get_hermes_module_conf() const
Get "hermes_module_conf" relationship value.
void generate_modules(std::shared_ptr< appmodel::ConfigurationHelper >) const override
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 contained_in() const
Return the name of the database file this object belongs to.
Configuration & configuration() const noexcept
const ConfigObject & config_object() const
const std::string & UID() const noexcept
conffwk entry point
std::vector< const dunedaq::confmodel::ExcludableEntity * > to_resources(const std::vector< T * > &vector_of_children)
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
The DUNE-DAQ namespace.