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
15#include "confmodel/GeoId.hpp"
17
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::Resource*>
48
49
50std::vector<const confmodel::DaqModule*>
52{
53 ConfigObjectFactory obj_fac(this);
54
55 std::vector<const confmodel::DaqModule*> modules;
56
57 auto daphne_conf = get_configuration();
58
59 std::map<std::string, const confmodel::GeoId*> geo_ids;
60
61 for (auto d2d_conn : get_detector_connections()) {
62
63 // 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
64 if (d2d_conn->is_disabled(*session)) {
65 TLOG_DEBUG(7) << "Ignoring disabled DetectorToDaqConnection " << d2d_conn->UID();
66 continue;
67 }
68
69 TLOG_DEBUG(6) << "Processing DetectorToDaqConnection " << d2d_conn->UID();
70 // get the readout groups and the interfaces and streams therein; 1 reaout group corresponds to 1 data reader module
71
72 // Redundant? Schema forbids 0 connections
73 if (d2d_conn->contained_resources().empty()) {
74 throw(BadConf(ERS_HERE, "DetectorToDaqConnection does not contain senders or receivers"));
75 }
76
77 auto det_senders = d2d_conn->get_felix_senders();
78
79 // Loop over senders
80 for (const auto* felix_sender : det_senders) {
81
82 if ( felix_sender->is_disabled(*session) ) {
83 TLOG() << "Skipping disabled sender: " << felix_sender->UID();
84 continue;
85 }
86
87 auto ip = felix_sender -> get_control_host();
88
89 // from the felix sender we get the DetStream and then the GeoID
90
91 auto streams = felix_sender -> get_streams();
92
93 for ( const auto * det_s : streams ) {
94
95 if ( det_s->is_disabled(*session) ) {
96 TLOG() << "Skipping disabled DetStream: " << det_s->UID();
97 continue;
98 }
99
100 if (!geo_ids.contains(ip)) {
101 geo_ids[ip] = det_s->get_geo_id();
102 }
103
104 } // loop over DetStreams
105
106 } // loop over det_senders
107
108 } // loop over det2DAQ Connections
109
110 for ( const auto & [ip, geo] : geo_ids ) {
111
112 auto slot = geo->get_slot_id();
113
114 const auto raw_conf = daphne_conf->get_json().at(ip);
115
116 // setup channels
117 std::vector<const conffwk::ConfigObject*> channels;
118 const auto raw_channels = raw_conf["channel_analog_conf"];
119 const auto raw_ids = raw_channels["ids"].get<std::vector<uint8_t>>();
120 const auto raw_gains = raw_channels["gains"].get<std::vector<uint8_t>>();
121 const auto raw_offsets = raw_channels["offsets"].get<std::vector<uint16_t>>();
122 const auto raw_trims = raw_channels["trims"].get<std::vector<uint16_t>>();
123 for ( size_t i = 0; i < raw_ids.size(); ++i ) {
124 auto id = raw_ids[i];
125 conffwk::ConfigObject channel_obj = obj_fac.create("DaphneV2Channel", fmt::format("daphne-{}-channel-{}", slot, id));
126 channel_obj.set_by_val<uint8_t>("channel_id", id);
127 channel_obj.set_by_val<uint8_t>("gain", raw_gains[i]);
128 channel_obj.set_by_val<uint16_t>("offset", raw_offsets[i]);
129 channel_obj.set_by_val<uint16_t>("trim", raw_trims[i]);
130 auto ch = obj_fac.get_dal<appmodel::DaphneV2Channel>(channel_obj);
131 channels.push_back(& ch -> config_object());
132 }
133
134 //setup afes
135 std::vector<const conffwk::ConfigObject*> afes;
136 const auto raw_afes = raw_conf["afes"];
137 const auto raw_afe_ids = raw_afes["ids"].get<std::vector<size_t>>();
138 const auto raw_afe_attenuators = raw_afes["attenuators"].get<std::vector<uint16_t>>();
139 const auto raw_afe_biases = raw_afes["v_biases"].get<std::vector<uint16_t>>();
140 const auto raw_adcs = raw_afes["adcs"];
141 const auto raw_adc_res = raw_adcs["resolution"].get<std::vector<uint16_t>>();
142 const auto raw_adc_format = raw_adcs["output_format"].get<std::vector<uint16_t>>();
143 const auto raw_adc_SB = raw_adcs["SB_first"].get<std::vector<uint16_t>>();
144 const auto raw_lnas = raw_afes["lnas"];
145 const auto raw_lna_clamps = raw_lnas["clamp"].get<std::vector<uint8_t>>();
146 const auto raw_lna_gains = raw_lnas["gain"].get<std::vector<uint8_t>>();
147 const auto raw_lna_integrators = raw_lnas["integrator_disable"].get<std::vector<uint16_t>>();
148 const auto raw_pgas = raw_afes["pgas"];
149 const auto raw_pga_cuts = raw_pgas["lpf_cut_frequency"].get<std::vector<uint8_t>>();
150 const auto raw_pga_integrators = raw_pgas["integrator_disable"].get<std::vector<uint16_t>>();
151 const auto raw_pga_gains = raw_pgas["gain"].get<std::vector<uint16_t>>();
152 for ( size_t i = 0; i < raw_afe_ids.size(); ++i ) {
153 auto id = raw_afe_ids[i];
154
155 // create the adc
156 conffwk::ConfigObject adc_obj = obj_fac.create("DaphneV2ADC", fmt::format("daphne-{}-adc-{}", slot, id));
157 adc_obj.set_by_val<bool>("low_resolution", raw_adc_res[i] > 0);
158 adc_obj.set_by_val<bool>("output_offset_binary", raw_adc_format[i] > 0 );
159 adc_obj.set_by_val<bool>("MSB_first", raw_adc_SB[i] > 0);
160 auto adc = obj_fac.get_dal<appmodel::DaphneV2ADC>(adc_obj);
161
162 // create the lna
163 conffwk::ConfigObject lna_obj = obj_fac.create("DaphneV2LNA", fmt::format("daphne-{}-lna-{}", slot, id));
164 lna_obj.set_by_val<uint8_t>("clamp", raw_lna_clamps[i]);
165 lna_obj.set_by_val<uint8_t>("gain", raw_lna_gains[i]);
166 lna_obj.set_by_val<bool>("integrator_disable", raw_lna_integrators[i]>0);
167 auto lna = obj_fac.get_dal<appmodel::DaphneV2LNA>(lna_obj);
168
169 // create the pga
170 conffwk::ConfigObject pga_obj = obj_fac.create("DaphneV2PGA", fmt::format("daphne-{}-pga-{}", slot, id));
171 pga_obj.set_by_val<uint8_t>("lpf_cut_frequency", raw_pga_cuts[i]);
172 pga_obj.set_by_val<bool>("gain", raw_pga_gains[i]>0);
173 pga_obj.set_by_val<bool>("integrator_disable", raw_pga_integrators[i]>0);
174 auto pga = obj_fac.get_dal<appmodel::DaphneV2PGA>(pga_obj);
175
176 // finally create the afe
177 conffwk::ConfigObject afe_obj = obj_fac.create("DaphneV2AFE", fmt::format("daphne-{}-afe-{}", slot, id) );
178 afe_obj.set_by_val<uint8_t>("afe_id", id);
179 afe_obj.set_by_val<uint16_t>("attenuator", raw_afe_attenuators[i]);
180 afe_obj.set_by_val<uint16_t>("v_bias", raw_afe_biases[i]);
181 afe_obj.set_obj("adc", & adc -> config_object() );
182 afe_obj.set_obj("lna", & lna -> config_object() );
183 afe_obj.set_obj("pga", & pga -> config_object() );
184 auto afe = obj_fac.get_dal<appmodel::DaphneV2AFE>(afe_obj);
185 afes.push_back( & afe-> config_object());
186 }
187
188
189 conffwk::ConfigObject board_obj = obj_fac.create("DaphneV2BoardConf", fmt::format("daphne-{}-conf", slot));
190 board_obj.set_by_val<uint16_t>("bias_ctrl", raw_conf.at("bias_ctrl"));
191 board_obj.set_by_val<uint64_t>("self_trigger_threshold", raw_conf.at("self_trigger_threshold"));
192 board_obj.set_by_val<std::vector<uint8_t>>("full_stream_channels",
193 raw_conf.at("full_stream_channels").get<std::vector<uint8_t>>());
194 board_obj.set_by_val<uint64_t>("self_trigger_xcorr", raw_conf.at("self_trigger_xcorr"));
195 board_obj.set_by_val<uint32_t>("tp_conf", raw_conf.at("tp_conf"));
196 board_obj.set_by_val<uint64_t>("compensator", raw_conf.at("compensator"));
197 board_obj.set_by_val<uint64_t>("inverter", raw_conf.at("inverter"));
198 board_obj.set_by_val<uint16_t>("slot_id", geo->get_slot_id());
199 board_obj.set_by_val<uint16_t>("crate_id", geo->get_crate_id());
200 board_obj.set_by_val<uint16_t>("detector_id", geo->get_detector_id());
201 board_obj.set_objs("active_channels", channels);
202 board_obj.set_objs("active_afes", afes);
203 board_obj.set_obj("default_channel", & daphne_conf->get_default_v2_settings()->get_default_channel()->config_object());
204 board_obj.set_obj("default_afe", & daphne_conf->get_default_v2_settings()->get_default_afe()->config_object());
205 auto conf = obj_fac.get_dal<appmodel::DaphneV2BoardConf>(board_obj);
206
207 conffwk::ConfigObject module_obj = obj_fac.create( "DaphneV2ControllerModule", fmt::format("controller-{}", slot) );;
208 module_obj.set_by_val<std::string>("address", ip);
209 module_obj.set_obj("daphne_conf", & daphne_conf -> config_object() );
210 module_obj.set_obj("board_conf", & conf -> config_object() );
211
212 auto module = obj_fac.get_dal<appmodel::DaphneV2ControllerModule>(module_obj);
213 modules.push_back(module);
214
215 } // ips
216
217 return modules;
218}
219
220
221uint16_t DaphneConf::get_board_slot(const std::string & ip) const {
222
223 auto conf_dict = get_json();
224 auto it = conf_dict.find(ip);
225 if ( it == conf_dict.end() ) {
226 throw MissingIP(ERS_HERE, ip);
227 }
228
229 return it->at("slot").get<uint16_t>();
230}
231
232bool
234
235 for ( auto ch_p : get_active_channels() ) {
236 if ( ch_p->get_channel_id() == ch ) {
237 return true;
238 }
239 }
240
241 return false;
242}
243
244const DaphneV2Channel &
246
247 for ( auto ch_p : get_active_channels() ) {
248 if ( ch_p->get_channel_id() == ch ) {
249 return *ch_p;
250 }
251 }
252
253 return *get_default_channel();
254}
255
256bool
258
259 auto begin = afe*8;
260 auto end = (afe+1)*8;
261 for ( size_t i = begin; i < end; ++i) {
262 if( is_channel_used(i) ) return true;
263 }
264
265 return false;
266}
267
268const DaphneV2AFE &
270
271 if ( ! is_afe_used(ch) ) return *get_default_afe();
272
273 for ( auto afe_p : get_active_afes() ) {
274 if ( afe_p->get_afe_id() == ch ) {
275 return *afe_p;
276 }
277 }
278
279 throw appmodel::MissingDaphne(ERS_HERE, ch);
280}
281
282
283uint16_t
285
286 // ADC, reg 4 has no parsing as it's all made of booleans
287 std::bitset<5> reg4;
288 // bits 0 and 2 are reserved
289 reg4[1] = get_low_resolution();
290 reg4[3] = get_output_offset_binary();
291 reg4[4] = get_MSB_first();
292 return reg4.to_ulong();
293}
294
295uint16_t
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 std::bitset<16> reg52;
311
312 decltype(reg52) clamp(get_clamp());
313 clamp <<= 6;
314
315 reg52[12] = get_integrator_disable();
316
317 decltype(reg52) gain(get_gain());
318 clamp <<= 13;
319
320 reg52 |= clamp;
321 reg52 |= gain;
322
323 return reg52.to_ulong();
324}
325
326} // namespace appmodel
327} // 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
const std::vector< const dunedaq::appmodel::FelixDetectorToDaqConnection * > & get_detector_connections() const
Get "detector_connections" relationship value. List of detector components controlled by this applica...
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...
virtual std::vector< const Resource * > contained_resources() const override
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
conffwk entry point
std::vector< const dunedaq::confmodel::Resource * > to_resources(const std::vector< T * > &vector_of_children)
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
#define TLOG(...)
Definition macro.hpp:22
The DUNE-DAQ namespace.
Definition DataStore.hpp:57
PDS Frame with unphysical timestamp detected with ch