DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
DaphneApplication.cpp
Go to the documentation of this file.
1
12#include "oks/kernel.hpp"
13#include "logging/Logging.hpp"
14
17#include "confmodel/GeoId.hpp"
19
32
33
34#include <string>
35#include <vector>
36#include <bitset>
37#include <iostream>
38#include <fmt/core.h>
39#include <set>
40
41namespace dunedaq {
42namespace appmodel {
43
44std::vector<const confmodel::DaqModule*>
46{
47 ConfigObjectFactory obj_fac(this);
48
49 std::vector<const confmodel::DaqModule*> modules;
50
51 auto daphne_conf = get_configuration();
52
53 std::map<std::string, const confmodel::GeoId*> geo_ids;
54
55 for (auto d2d_conn_res : get_contains()) {
56
57 // A Resource can be disabled and still its application can be enabled because the application can have multile resources, so we need to check which resources are enabled
58 if (d2d_conn_res->disabled(*session)) {
59 TLOG_DEBUG(7) << "Ignoring disabled DetectorToDaqConnection " << d2d_conn_res->UID();
60 continue;
61 }
62
63 TLOG_DEBUG(6) << "Processing DetectorToDaqConnection " << d2d_conn_res->UID();
64 // get the readout groups and the interfaces and streams therein; 1 reaout group corresponds to 1 data reader module
65 auto d2d_conn = d2d_conn_res->cast<confmodel::DetectorToDaqConnection>();
66
67 if (!d2d_conn) {
68 throw(BadConf(ERS_HERE, "DaphneApplication contains something other than DetectorToDaqConnection"));
69 }
70
71 if (d2d_conn->get_contains().empty()) {
72 throw(BadConf(ERS_HERE, "DetectorToDaqConnection does not contain senders or receivers"));
73 }
74
75 auto det_senders = d2d_conn->get_senders();
76
77 // Loop over senders
78 for (const auto* sender : det_senders) {
79
80 if ( sender->disabled(*session) ) {
81 TLOG() << "Skipping disabled sender: " << sender->UID();
82 continue;
83 }
84 // Check the sender type, must me a FelixDataSender
85 const auto* felix_sender = sender->cast<appmodel::FelixDataSender>();
86 if (!felix_sender ) {
87 //throw(BadConf(ERS_HERE, fmt::format("DataSender {} is not a appmodel::HermesDataSender", sender->UID())));
88 continue;
89 // MaR: I don't think we should throw here because there can be other connections other than felix
90 // MaR: should we be worried that we assume that a Felix connection is a Daphne?
91 }
92
93 auto ip = felix_sender -> get_control_host();
94
95 // from the felix sender we get the DetStream and then the GeoID
96
97 auto streams = felix_sender -> get_contains();
98
99 for ( const auto * det_s : streams ) {
100
101 if ( det_s->disabled(*session) ) {
102 TLOG() << "Skipping disabled DetStream: " << det_s->UID();
103 continue;
104 }
105
106 if (!geo_ids.contains(ip)) {
107 const auto * temp_stream = det_s->cast<confmodel::DetectorStream>();
108 geo_ids[ip] = temp_stream->get_geo_id();
109 }
110
111 } // loop over DetStreams
112
113 } // loop over det_senders
114
115 } // loop over det2DAQ Connections
116
117 for ( const auto & [ip, geo] : geo_ids ) {
118
119 auto slot = geo->get_slot_id();
120
121 const auto raw_conf = daphne_conf->get_json().at(ip);
122
123 // setup channels
124 std::vector<const conffwk::ConfigObject*> channels;
125 const auto raw_channels = raw_conf["channel_analog_conf"];
126 const auto raw_ids = raw_channels["ids"].get<std::vector<uint8_t>>();
127 const auto raw_gains = raw_channels["gains"].get<std::vector<uint8_t>>();
128 const auto raw_offsets = raw_channels["offsets"].get<std::vector<uint16_t>>();
129 const auto raw_trims = raw_channels["trims"].get<std::vector<uint16_t>>();
130 for ( size_t i = 0; i < raw_ids.size(); ++i ) {
131 auto id = raw_ids[i];
132 conffwk::ConfigObject channel_obj = obj_fac.create("DaphneV2Channel", fmt::format("daphne-{}-channel-{}", slot, id));
133 channel_obj.set_by_val<uint8_t>("channel_id", id);
134 channel_obj.set_by_val<uint8_t>("gain", raw_gains[i]);
135 channel_obj.set_by_val<uint16_t>("offset", raw_offsets[i]);
136 channel_obj.set_by_val<uint16_t>("trim", raw_trims[i]);
137 auto ch = obj_fac.get_dal<appmodel::DaphneV2Channel>(channel_obj);
138 channels.push_back(& ch -> config_object());
139 }
140
141 //setup afes
142 std::vector<const conffwk::ConfigObject*> afes;
143 const auto raw_afes = raw_conf["afes"];
144 const auto raw_afe_ids = raw_afes["ids"].get<std::vector<size_t>>();
145 const auto raw_afe_attenuators = raw_afes["attenuators"].get<std::vector<uint16_t>>();
146 const auto raw_afe_biases = raw_afes["v_biases"].get<std::vector<uint16_t>>();
147 const auto raw_adcs = raw_afes["adcs"];
148 const auto raw_adc_res = raw_adcs["resolution"].get<std::vector<uint16_t>>();
149 const auto raw_adc_format = raw_adcs["output_format"].get<std::vector<uint16_t>>();
150 const auto raw_adc_SB = raw_adcs["SB_first"].get<std::vector<uint16_t>>();
151 const auto raw_lnas = raw_afes["lnas"];
152 const auto raw_lna_clamps = raw_lnas["clamp"].get<std::vector<uint8_t>>();
153 const auto raw_lna_gains = raw_lnas["gain"].get<std::vector<uint8_t>>();
154 const auto raw_lna_integrators = raw_lnas["integrator_disable"].get<std::vector<uint16_t>>();
155 const auto raw_pgas = raw_afes["pgas"];
156 const auto raw_pga_cuts = raw_pgas["lpf_cut_frequency"].get<std::vector<uint8_t>>();
157 const auto raw_pga_integrators = raw_pgas["integrator_disable"].get<std::vector<uint16_t>>();
158 const auto raw_pga_gains = raw_pgas["gain"].get<std::vector<uint16_t>>();
159 for ( size_t i = 0; i < raw_afe_ids.size(); ++i ) {
160 auto id = raw_afe_ids[i];
161
162 // create the adc
163 conffwk::ConfigObject adc_obj = obj_fac.create("DaphneV2ADC", fmt::format("daphne-{}-adc-{}", slot, id));
164 adc_obj.set_by_val<bool>("low_resolution", raw_adc_res[i] > 0);
165 adc_obj.set_by_val<bool>("output_offset_binary", raw_adc_format[i] > 0 );
166 adc_obj.set_by_val<bool>("MSB_first", raw_adc_SB[i] > 0);
167 auto adc = obj_fac.get_dal<appmodel::DaphneV2ADC>(adc_obj);
168
169 // create the lna
170 conffwk::ConfigObject lna_obj = obj_fac.create("DaphneV2LNA", fmt::format("daphne-{}-lna-{}", slot, id));
171 lna_obj.set_by_val<uint8_t>("clamp", raw_lna_clamps[i]);
172 lna_obj.set_by_val<uint8_t>("gain", raw_lna_gains[i]);
173 lna_obj.set_by_val<bool>("integrator_disable", raw_lna_integrators[i]>0);
174 auto lna = obj_fac.get_dal<appmodel::DaphneV2LNA>(lna_obj);
175
176 // create the pga
177 conffwk::ConfigObject pga_obj = obj_fac.create("DaphneV2PGA", fmt::format("daphne-{}-pga-{}", slot, id));
178 pga_obj.set_by_val<uint8_t>("lpf_cut_frequency", raw_pga_cuts[i]);
179 pga_obj.set_by_val<bool>("gain", raw_pga_gains[i]>0);
180 pga_obj.set_by_val<bool>("integrator_disable", raw_pga_integrators[i]>0);
181 auto pga = obj_fac.get_dal<appmodel::DaphneV2PGA>(pga_obj);
182
183 // finally create the afe
184 conffwk::ConfigObject afe_obj = obj_fac.create("DaphneV2AFE", fmt::format("daphne-{}-afe-{}", slot, id) );
185 afe_obj.set_by_val<uint8_t>("afe_id", id);
186 afe_obj.set_by_val<uint16_t>("attenuator", raw_afe_attenuators[i]);
187 afe_obj.set_by_val<uint16_t>("v_bias", raw_afe_biases[i]);
188 afe_obj.set_obj("adc", & adc -> config_object() );
189 afe_obj.set_obj("lna", & lna -> config_object() );
190 afe_obj.set_obj("pga", & pga -> config_object() );
191 auto afe = obj_fac.get_dal<appmodel::DaphneV2AFE>(afe_obj);
192 afes.push_back( & afe-> config_object());
193 }
194
195
196 conffwk::ConfigObject board_obj = obj_fac.create("DaphneV2BoardConf", fmt::format("daphne-{}-conf", slot));
197 board_obj.set_by_val<uint16_t>("bias_ctrl", raw_conf.at("bias_ctrl"));
198 board_obj.set_by_val<uint64_t>("self_trigger_threshold", raw_conf.at("self_trigger_threshold"));
199 board_obj.set_by_val<std::vector<uint8_t>>("full_stream_channels",
200 raw_conf.at("full_stream_channels").get<std::vector<uint8_t>>());
201 board_obj.set_by_val<uint64_t>("self_trigger_xcorr", raw_conf.at("self_trigger_xcorr"));
202 board_obj.set_by_val<uint32_t>("tp_conf", raw_conf.at("tp_conf"));
203 board_obj.set_by_val<uint64_t>("compensator", raw_conf.at("compensator"));
204 board_obj.set_by_val<uint64_t>("inverter", raw_conf.at("inverter"));
205 board_obj.set_by_val<uint16_t>("slot_id", geo->get_slot_id());
206 board_obj.set_by_val<uint16_t>("crate_id", geo->get_crate_id());
207 board_obj.set_by_val<uint16_t>("detector_id", geo->get_detector_id());
208 board_obj.set_objs("active_channels", channels);
209 board_obj.set_objs("active_afes", afes);
210 board_obj.set_obj("default_channel", & daphne_conf->get_default_v2_settings()->get_default_channel()->config_object());
211 board_obj.set_obj("default_afe", & daphne_conf->get_default_v2_settings()->get_default_afe()->config_object());
212 auto conf = obj_fac.get_dal<appmodel::DaphneV2BoardConf>(board_obj);
213
214 conffwk::ConfigObject module_obj = obj_fac.create( "DaphneV2ControllerModule", fmt::format("controller-{}", slot) );;
215 module_obj.set_by_val<std::string>("address", ip);
216 module_obj.set_obj("daphne_conf", & daphne_conf -> config_object() );
217 module_obj.set_obj("board_conf", & conf -> config_object() );
218
219 auto module = obj_fac.get_dal<appmodel::DaphneV2ControllerModule>(module_obj);
220 modules.push_back(module);
221
222 } // ips
223
224 return modules;
225}
226
227
228uint16_t DaphneConf::get_board_slot(const std::string & ip) const {
229
230 auto conf_dict = get_json();
231 auto it = conf_dict.find(ip);
232 if ( it == conf_dict.end() ) {
233 throw MissingIP(ERS_HERE, ip);
234 }
235
236 return it->at("slot").get<uint16_t>();
237}
238
239bool
241
242 for ( auto ch_p : get_active_channels() ) {
243 if ( ch_p->get_channel_id() == ch ) {
244 return true;
245 }
246 }
247
248 return false;
249}
250
251const DaphneV2Channel &
253
254 for ( auto ch_p : get_active_channels() ) {
255 if ( ch_p->get_channel_id() == ch ) {
256 return *ch_p;
257 }
258 }
259
260 return *get_default_channel();
261}
262
263bool
265
266 auto begin = afe*8;
267 auto end = (afe+1)*8;
268 for ( size_t i = begin; i < end; ++i) {
269 if( is_channel_used(i) ) return true;
270 }
271
272 return false;
273}
274
275const DaphneV2AFE &
277
278 if ( ! is_afe_used(ch) ) return *get_default_afe();
279
280 for ( auto afe_p : get_active_afes() ) {
281 if ( afe_p->get_afe_id() == ch ) {
282 return *afe_p;
283 }
284 }
285
286 throw appmodel::MissingDaphne(ERS_HERE, ch);
287}
288
289
290uint16_t
292
293 // ADC, reg 4 has no parsing as it's all made of booleans
294 std::bitset<5> reg4;
295 // bits 0 and 2 are reserved
296 reg4[1] = get_low_resolution();
297 reg4[3] = get_output_offset_binary();
298 reg4[4] = get_MSB_first();
299 return reg4.to_ulong();
300}
301
302uint16_t
304
305 std::bitset<14> reg51(get_lpf_cut_frequency());
306 reg51 <<= 1;
307 reg51[4] = get_integrator_disable();
308 reg51[7] = true; // clamp is always disabled and we are in low noise mode
309 reg51[13] = get_gain();
310
311 return reg51.to_ulong() ;
312}
313
314uint16_t
316
317 std::bitset<16> reg52;
318
319 decltype(reg52) clamp(get_clamp());
320 clamp <<= 6;
321
322 reg52[12] = get_integrator_disable();
323
324 decltype(reg52) gain(get_gain());
325 clamp <<= 13;
326
327 reg52 |= clamp;
328 reg52 |= gain;
329
330 return reg52.to_ulong();
331}
332
333} // namespace appmodel
334} // namespace dunedaq
#define ERS_HERE
const T * get_dal(std::string uid) const
conffwk::ConfigObject create(const std::string &class_name, const std::string &id) const
std::vector< const dunedaq::confmodel::DaqModule * > generate_modules(const confmodel::Session *) const override
virtual std::vector< const dunedaq::conffwk::DalObject * > get(const std::string &name, bool upcast_unregistered=true) const
Get values of relationships and results of some algorithms as a vector of dunedaq::conffwk::DalObject...
const dunedaq::appmodel::DaphneConf * get_configuration() const
Get "configuration" relationship value.
nlohmann::json get_json() const
uint16_t get_board_slot(const std::string &ip) const
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.
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
std::vector< const confmodel::DetDataSender * > get_senders() const
const std::vector< const dunedaq::confmodel::ResourceBase * > & get_contains() const
Get "contains" relationship value. A resource set is a container of resources to easily implement gro...
conffwk entry point
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
#define TLOG(...)
Definition macro.hpp:22
Including Qt Headers.
PDS Frame with unphysical timestamp detected with ch