DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
DaphneApplication.cpp
Go to the documentation of this file.
1
10
12#include "logging/Logging.hpp"
13#include "oks/kernel.hpp"
14
16#include "confmodel/GeoId.hpp"
18
41
42#include <bitset>
43#include <fmt/core.h>
44#include <iostream>
45#include <map>
46#include <set>
47#include <string>
48#include <vector>
49
50namespace dunedaq::appmodel {
51
52std::vector<const confmodel::ExcludableEntity*>
57
58void
59DaphneApplication::generate_modules(std::shared_ptr<appmodel::ConfigurationHelper> helper) const
60{
61 ConfigObjectFactory obj_fac(this);
62
63 std::vector<const confmodel::DaqModule*> modules;
64
65 auto daphne_conf = get_configuration();
66
67 std::map<std::string, const DaphneV2BoardConf*> conf_map;
68 auto confs = daphne_conf->get_boards();
69 for (const auto& c : confs) {
70 conf_map[c->get_key()] = c->get_conf();
71 }
72
73 // these maps are all indexed on the board id {detector].{crate}.{slot}
74 std::map<std::string, bool> v3_map;
75 std::map<std::string, const confmodel::NetworkInterface*> interfaces;
76 std::map<std::string, std::string> ctrl_hosts;
77
78 // map from ctrl_host to senders
79 std::map<std::string, std::vector<const appmodel::HermesDataSender*>> hermes_senders;
80
81 for (auto d2d_conn : get_detector_connections()) {
82
83 // A ExcludableEntity can be disabled and still its application can be enabled because the application can have
84 // multile resources, so we need to check which resources are enabled
85 if (helper->is_excluded(d2d_conn)) {
86 TLOG_DEBUG(7) << "Ignoring disabled DetectorToDaqConnection " << d2d_conn->UID();
87 continue;
88 }
89
90 TLOG_DEBUG(6) << "Processing DetectorToDaqConnection " << d2d_conn->UID();
91 // get the readout groups and the interfaces and streams therein; 1 reaout group corresponds to 1 data reader module
92
93 // Redundant? Schema forbids 0 connections
94 if (d2d_conn->contained_excludable_entities().empty()) {
95 throw(BadConf(ERS_HERE, "DetectorToDaqConnection does not contain senders or receivers"));
96 }
97
98 auto flx_conn = dynamic_cast<const appmodel::FelixDetectorToDaqConnection*>(d2d_conn); // NOLINT(runtime/rtti)
99 auto net_conn = dynamic_cast<const appmodel::NetworkDetectorToDaqConnection*>(d2d_conn); // NOLINT(runtime/rtti)
100
101 if (!net_conn && !flx_conn) {
102 throw BadConf(ERS_HERE, d2d_conn->UID() + " is neither felix or eth connection");
103 }
104
105 if (flx_conn) {
106 auto det_senders = flx_conn->get_felix_senders();
107
108 // Loop over senders
109 for (const auto* felix_sender : det_senders) {
110
111 if (helper->is_excluded(felix_sender)) {
112 TLOG() << "Skipping disabled sender: " << felix_sender->UID();
113 continue;
114 }
115
116 auto ip = felix_sender->get_control_host();
117
118 // from the felix sender we get the DetStream and then the GeoID
119
120 auto streams = felix_sender->get_streams();
121
122 for (const auto* det_s : streams) {
123
124 if (helper->is_excluded(det_s)) {
125 TLOG() << "Skipping disabled DetStream: " << det_s->UID();
126 continue;
127 }
128
129 auto geo_id = det_s->get_geo_id();
130 auto id = fmt::format("{}.{}.{}", geo_id->get_detector_id(), geo_id->get_crate_id(), geo_id->get_slot_id());
131 if (!v3_map.contains(id)) {
132 v3_map[id] = false;
133 }
134
135 } // loop over DetStreams
136
137 } // loop over det_senders
138 } // if flx connection
139
140 if (net_conn) {
141 auto det_senders = net_conn->get_net_senders();
142
143 for (const auto* nw_sender : det_senders) {
144 if (helper->is_excluded(nw_sender)) {
145 TLOG() << "Skipping disabled sender: " << nw_sender->UID();
146 continue;
147 }
148
149 // Check the sender type, must me a HermesSender
150 const auto* hrms_sender = nw_sender->cast<appmodel::HermesDataSender>();
151 if (!hrms_sender) {
152 throw(BadConf(ERS_HERE, fmt::format("DataSender {} is not a appmodel::HermesDataSender", nw_sender->UID())));
153 }
154
155 hermes_senders[hrms_sender->get_control_host()].push_back(hrms_sender);
156
157 auto streams = nw_sender->get_streams();
158 for (const auto* det_s : streams) {
159
160 if (helper->is_excluded(det_s)) {
161 TLOG() << "Skipping disabled DetStream: " << det_s->UID();
162 continue;
163 }
164
165 auto geo_id = det_s->get_geo_id();
166 auto id = fmt::format("{}.{}.{}", geo_id->get_detector_id(), geo_id->get_crate_id(), geo_id->get_slot_id());
167 if (!v3_map.contains(id)) {
168 v3_map[id] = true;
169 interfaces[id] = net_conn->get_net_receiver()->get_uses();
170 ctrl_hosts[id] = hrms_sender->get_control_host();
171 }
172
173 } // loop over streams
174
175 } // loop over NW senders
176
177 } // if net_connection
178
179 } // loop over det2DAQ Connections
180
181 for (const auto& [id, v3] : v3_map) {
182
183 auto conf_it = conf_map.find(id);
184 if (conf_it == conf_map.end()) {
185 throw MissingDaphne(ERS_HERE, id);
186 }
187 auto conf = conf_it->second;
188
189 conffwk::ConfigObject module_obj =
190 obj_fac.create((v3 ? "DaphneV3ControllerModule" : "DaphneV2ControllerModule"), fmt::format("controller-{}", id));
191 module_obj.set_obj("daphne_conf", &daphne_conf->config_object());
192 module_obj.set_obj("board_conf", &conf->config_object());
193
194 auto module = obj_fac.get_dal<confmodel::DaqModule>(module_obj);
195 modules.push_back(module);
196
197 // Create Hermes Modules
198 if (v3) {
199 std::string hermes_uid = fmt::format("daphne-hermes-ctrl-{}", id);
200 conffwk::ConfigObject hermes_obj = obj_fac.create("HermesModule", hermes_uid);
201 hermes_obj.set_obj("address_table", &this->get_hermes_module_conf()->get_address_table()->config_object());
202 hermes_obj.set_by_val<std::string>("uri",
203 fmt::format("{}://{}:{}",
204 this->get_hermes_module_conf()->get_ipbus_type(),
205 ctrl_hosts[id],
206 this->get_hermes_module_conf()->get_ipbus_port()));
207 hermes_obj.set_by_val<uint32_t>("timeout_ms", this->get_hermes_module_conf()->get_ipbus_timeout_ms()); // NOLINT
208 hermes_obj.set_obj("destination", &interfaces[id]->config_object());
209
210 std::vector<const conffwk::ConfigObject*> links_obj;
211 const auto& senders = hermes_senders[ctrl_hosts[id]];
212 for (const auto* sndr : senders) {
213 links_obj.push_back(&sndr->config_object());
214 }
215 hermes_obj.set_objs("links", links_obj);
216
217 modules.push_back(obj_fac.get_dal<appmodel::HermesModule>(hermes_obj));
218 }
219
220 } // ips
221
222 obj_fac.update_modules(modules);
223} // NOLINT
224
225bool
227{
228
229 for (auto ch_p : get_active_channels()) {
230 if (ch_p->get_channel_id() == ch) {
231 return true;
232 }
233 }
234
235 return false;
236}
237
238const DaphneV2Channel&
240{
241
242 for (auto ch_p : get_active_channels()) {
243 if (ch_p->get_channel_id() == ch) {
244 return *ch_p;
245 }
246 }
247
248 return *get_default_channel();
249}
250
251bool
253{
254
255 auto begin = afe * 8;
256 auto end = (afe + 1) * 8;
257 for (size_t i = begin; i < end; ++i) {
258 if (is_channel_used(i))
259 return true;
260 }
261
262 return false;
263}
264
265const DaphneV2AFE&
267{
268
269 if (!is_afe_used(ch))
270 return *get_default_afe();
271
272 for (auto afe_p : get_active_afes()) {
273 if (afe_p->get_afe_id() == ch) {
274 return *afe_p;
275 }
276 }
277
278 throw appmodel::MissingAFE(ERS_HERE, UID(), ch);
279}
280
281uint16_t
283{
284
285 // ADC, reg 4 has no parsing as it's all made of booleans
286 std::bitset<5> reg4;
287 // bits 0 and 2 are reserved
288 reg4[1] = get_low_resolution();
289 reg4[3] = get_output_offset_binary();
290 reg4[4] = get_MSB_first();
291 return reg4.to_ulong();
292}
293
294uint16_t
296{
297
298 std::bitset<14> reg51(get_lpf_cut_frequency());
299 reg51 <<= 1;
300 reg51[4] = get_integrator_disable();
301 reg51[7] = true; // clamp is always disabled and we are in low noise mode
302 reg51[13] = get_gain();
303
304 return reg51.to_ulong();
305}
306
307uint16_t
309{
310
311 std::bitset<16> reg52;
312
313 decltype(reg52) clamp(get_clamp());
314 clamp <<= 6;
315
316 reg52[12] = get_integrator_disable();
317
318 decltype(reg52) gain(get_gain());
319 clamp <<= 13;
320
321 reg52 |= clamp;
322 reg52 |= gain;
323
324 return reg52.to_ulong();
325}
326
327} // namespace dunedaq::appmodel
#define ERS_HERE
void update_modules(const std::vector< const confmodel::DaqModule * > &modules)
const T * get_dal(std::string uid) const
conffwk::ConfigObject create(const std::string &class_name, const std::string &id) const
const std::vector< const dunedaq::confmodel::DetectorToDaqConnection * > & get_detector_connections() const
Get "detector_connections" relationship value. List of detector components controlled by this applica...
void generate_modules(std::shared_ptr< appmodel::ConfigurationHelper >) const override
virtual std::vector< const ExcludableEntity * > contained_excludable_entities() const override
const dunedaq::appmodel::HermesModuleConf * get_hermes_module_conf() const
Get "hermes_module_conf" relationship value.
const dunedaq::appmodel::DaphneConf * get_configuration() const
Get "configuration" relationship value.
bool get_MSB_first() const
Get "MSB_first" attribute value. Which Significant bit comes first, true=MSB, false=LSB.
bool get_low_resolution() const
Get "low_resolution" attribute value. true=12bit, false=14bit.
bool get_output_offset_binary() const
Get "output_offset_binary" attribute value. true=Offset Binary, false=2s complement.
const std::vector< const dunedaq::appmodel::DaphneV2AFE * > & get_active_afes() const
Get "active_afes" relationship value.
const DaphneV2AFE & get_afe(size_t id) const
const DaphneV2Channel & get_channel(size_t ch) const
const dunedaq::appmodel::DaphneV2Channel * get_default_channel() const
Get "default_channel" relationship value.
const std::vector< const dunedaq::appmodel::DaphneV2Channel * > & get_active_channels() const
Get "active_channels" relationship value.
const dunedaq::appmodel::DaphneV2AFE * get_default_afe() const
Get "default_afe" relationship value.
bool get_integrator_disable() const
Get "integrator_disable" attribute value.
uint8_t get_clamp() const
Get "clamp" attribute value. 0=auto setting, 1=1.5 Vpp, 2=1.15 Vpp, 3=0.6 Vpp.
uint8_t get_gain() const
Get "gain" attribute value. 0=18 dB, 1=24 dB, 2=12 dB.
bool get_integrator_disable() const
Get "integrator_disable" attribute value.
uint8_t get_lpf_cut_frequency() const
Get "lpf_cut_frequency" attribute value. cut frequency, only 4 values acceptable. 0=15MHz,...
bool get_gain() const
Get "gain" attribute value. rue=30 dB, false=24 dB.
uint32_t get_ipbus_timeout_ms() const
Get "ipbus_timeout_ms" 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 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
#define TLOG(...)
Definition macro.hpp:21