mesytec_data 1.1.1
Toolkit for parsing Mesytec VME module data
All Classes Functions Variables Typedefs Enumerations Enumerator Pages
mesytec_data.h
1#ifndef MESYTEC_DATA_H
2#define MESYTEC_DATA_H
3
4#include <vector>
5#include <string>
6#include <iostream>
7#include <fstream>
8#include <algorithm>
9#include <cassert>
10#include "mesytec_experimental_setup.h"
11
12#define MESYTEC_DATA_NO_MDPP_NAMESPACE
13#define MESYTEC_DATA_NO_PUBLIC_MEMBERS
14
15namespace mesytec {
16 const uint16_t mfm_frame_type = 0x4adf;
17
23 uint32_t data_word;
24 uint16_t data;
25 uint8_t bus_number;
26 uint8_t channel;
27 bool ovflw;
28 module::datatype_t data_type;
29 public:
30 channel_data() = default;
31 ~channel_data() = default;
32 channel_data(uint32_t _dw)
33 : data_word{std::move(_dw)}
34 {}
35 channel_data(module::datatype_t _type, uint8_t _chan, uint16_t _data, uint32_t _dw, bool _ovflw=false)
36 : data_type{_type}, data_word{_dw}, data{_data}, bus_number{0}, channel{_chan}, ovflw{_ovflw}
37 {}
38 channel_data(module::datatype_t _type, uint8_t _bus, uint8_t _chan, uint16_t _data, uint32_t _dw, bool _ovflw=false)
39 : data_type{_type}, data_word{_dw}, data{_data}, bus_number{_bus}, channel{_chan}, ovflw{_ovflw}
40 {}
41 channel_data(channel_data&& other) = default;
42 channel_data(const channel_data&) = delete;
43 channel_data& operator=(const channel_data&) = delete;
44 channel_data& operator=(channel_data&& other) = default;
45 void ls(const mesytec::experimental_setup& cfg, uint8_t mod_id) const
46 {
47 auto& mod = cfg.get_module(mod_id);
48 mod.set_data_word(data_word);
49 mod.print_data();
50 }
51 void add_data_to_buffer(std::vector<uint32_t>& buf) const
52 {
53 buf.push_back(data_word);
54 }
55
59 uint32_t get_data_word() const
60 {
61 return data_word;
62 }
66 uint16_t get_data() const
67 {
68 return data;
69 }
73 bool get_overflow() const
74 {
75 return ovflw;
76 }
80 uint8_t get_bus_number() const
81 {
82 return bus_number;
83 }
87 uint8_t get_channel_number() const
88 {
89 return channel;
90 }
95 return data_type;
96 }
97 };
98
115 friend class buffer_reader;
116
117 std::vector<channel_data> data;
118 uint32_t event_counter;
119 uint32_t header_word;
120 uint32_t eoe_word;
121 uint16_t data_words; // number of data items + 1 EOE
122 uint8_t module_id{UNKNOWN};
123 public:
127 void dump_module_data() const
128 {
129 std::cout << std::hex << std::showbase << header_word << std::endl;
130 for (auto& v : data) std::cout << v.get_data_word() << std::endl;
131 }
132
133 uint32_t get_header_word() const
134 {
135 return header_word;
136 }
137
141 uint8_t get_module_id() const
142 {
143 return module_id;
144 }
148 const std::vector<channel_data>& get_channel_data() const
149 {
150 return data;
151 }
152 void clear()
153 {
154 data.clear();
155 event_counter = 0;
156 header_word = 0;
157 data_words = 0;
158 module_id = 0;
159 eoe_word = 0;
160 }
161
166 {
167 //assert(data_words);
168 return data_words ? data_words - 1 : 0;
169 }
170 void set_header_word(uint32_t _header_word, module& mod)
171 {
172 clear();
173 header_word = _header_word;
174 mod.set_data_word(_header_word);
175 mod.set_infos_from_header_word();
176 module_id = mod.id;
177 data_words = mod.length_of_data();
178 if (data_words) data.reserve(data_words); // max number of data words for 1 module
179 }
180
181 module_data() = default;
182 ~module_data() = default;
183 module_data(module_data&&) = default;
184 module_data(const module_data&) = delete;
185 module_data& operator=(const module_data&) = delete;
186 module_data& operator=(module_data&&) = default;
187 void add_data(module::datatype_t type, uint8_t channel, uint16_t datum, uint32_t data_word, bool ovflw=false)
188 {
189 data.emplace_back(type, channel, datum, data_word, ovflw);
190 }
191 void add_data(module::datatype_t type, uint8_t busnum, uint8_t channel, uint16_t datum, uint32_t data_word, bool ovflw=false)
192 {
193 data.emplace_back(type, busnum, channel, datum, data_word, ovflw);
194 }
195 void add_data(uint32_t data_word)
196 {
197 data.emplace_back(data_word);
198 }
199 void ls(const mesytec::experimental_setup& cfg) const
200 {
201 auto& mod = cfg.get_module(module_id);
202 if (mod.is_mesytec_module()) {
203 //std::cout << " [data words:" << data.size() << "]\n";
204 for (auto& d : data) d.ls(cfg, module_id);
205 }
206 else if (mod.is_mvlc_scaler()) {
207 // 4 data words of 16 bits (least significant is first word) => 64 bit scaler
208 assert(data.size() == 4);
209 uint64_t x = 0;
210 int i = 0;
211 for (auto& d : data) x += ((uint64_t)d.get_data_word()) << (16 * (i++));
212 std::cout << "mvlc_scaler::" << mod.name << " = " << std::hex << std::showbase << x << std::endl;
213 }
214 else
215 std::cout << std::endl;
216 }
217 void add_data_to_buffer(std::vector<uint32_t>& buf) const
218 {
219 // reconstruct mesytec data buffer for this module i.e. series of 32 bit words
220 // HEADER - N x DATA (in total, N+1 words)
221 //
222 // if no data words are present for the module, no data is added to buffer
223 // (not even the header)
224
225 if (data.size()) {
226 buf.push_back(header_word);
227 for (auto& v : data) v.add_data_to_buffer(buf);
228 }
229 }
230 size_t size_of_buffer() const
231 {
232 // returns size (in 4-byte words) of buffer required to hold all data for this module
233 // corresponding to header + N data words.
234 //
235 // if no data words are present for the module, this is 0
236 return data.size() ? data.size() + 1 : 0;
237 }
238 bool has_data() const
239 {
240 return data.size() > 0;
241 }
242 };
243
265 class event {
266 friend class buffer_reader;
267
268 std::vector<module_data> modules;
269 uint32_t event_counter = 0;
270
271 bool with_tgv_timestamp = false;
272 bool with_agava_timestamp = false;
273 bool with_vtc_timestamp = false;
274 uint16_t tgv_ts_lo{0}, tgv_ts_mid{0}, tgv_ts_hi{0};
275 uint32_t agava_ts_lo{0}, agava_ts_hi{0};
276 uint32_t vtc_ts_lo{0};
277 uint16_t vtc_ts_hi{0};
278 bool _is_scaler_event = false;
279
280 public:
281
282
286 uint32_t get_event_counter() const
287 {
288 return event_counter;
289 }
294 {
295 return event_counter;
296 }
297 event()
298 {
299 // reserve capacity for data from up to 25 modules (> capacity of 1 VME crate)
300 // to avoid reallocations as data is 'pushed back' in to the vector
301 modules.reserve(25);
302 }
303 void clear()
304 {
305 modules.clear();
306 with_agava_timestamp=with_tgv_timestamp=_is_scaler_event=false;
307 tgv_ts_lo = tgv_ts_mid = tgv_ts_hi = 0;
308 agava_ts_hi = agava_ts_lo = 0;
309 vtc_ts_hi = vtc_ts_lo = 0;
310 }
314 const std::vector<module_data>& get_module_data() const
315 {
316 return modules;
317 }
318
319 void add_module_data(module_data& d)
320 {
321 modules.push_back(std::move(d));
322 }
323 bool is_full(unsigned int number_of_modules) const
324 {
325 return (modules.size() == number_of_modules);
326 }
327 void ls(const mesytec::experimental_setup& cfg) const
328 {
329 std::cout << " Event# " << event_counter << std::endl;
330 for (auto& m : modules) m.ls(cfg);
331 }
332 size_t size_of_buffer() const
333 {
334 // returns size (in 4-byte words) of buffer required to hold all data for this event
335 size_t s = 0;
336 for (auto& v : modules) s += v.size_of_buffer();
337 return s;
338 }
339 std::vector<uint32_t> get_output_buffer() const
340 {
341 // return full representation of all data for event
342
343 std::vector<uint32_t> buf;
344 buf.reserve(size_of_buffer());
345 for (auto& m : modules) m.add_data_to_buffer(buf);
346 return buf;
347 }
348 bool has_data() const
349 {
350 return modules.size() > 0;
351 }
352 bool get_with_tgv_timestamp() const
353 {
354 return with_tgv_timestamp;
355 }
356 void set_with_tgv_timestamp(const bool& _with_tgv_timestamp)
357 {
358 with_tgv_timestamp = _with_tgv_timestamp;
359 }
360 bool get_with_vtc_timestamp() const
361 {
362 return with_vtc_timestamp;
363 }
364 void set_with_vtc_timestamp(const bool& _with_vtc_timestamp)
365 {
366 with_vtc_timestamp = _with_vtc_timestamp;
367 }
368 bool get_with_agava_timestamp() const
369 {
370 return with_agava_timestamp;
371 }
372 void set_with_agava_timestamp(const bool& _with_agava_timestamp)
373 {
374 with_agava_timestamp = _with_agava_timestamp;
375 }
376 uint16_t get_tgv_ts_lo() const
377 {
378 return tgv_ts_lo;
379 }
380 void set_tgv_ts_lo(const uint16_t& _tgv_ts_lo)
381 {
382 tgv_ts_lo = _tgv_ts_lo;
383 }
384 uint16_t get_tgv_ts_mid() const
385 {
386 return tgv_ts_mid;
387 }
388 void set_tgv_ts_mid(const uint16_t& _tgv_ts_mid)
389 {
390 tgv_ts_mid = _tgv_ts_mid;
391 }
392 uint16_t get_tgv_ts_hi() const
393 {
394 return tgv_ts_hi;
395 }
396 void set_tgv_ts_hi(const uint16_t& _tgv_ts_hi)
397 {
398 tgv_ts_hi = _tgv_ts_hi;
399 }
400 uint32_t get_agava_ts_lo() const
401 {
402 return agava_ts_lo;
403 }
404 void set_agava_ts_lo(const uint32_t& _agava_ts_lo)
405 {
406 agava_ts_lo = _agava_ts_lo;
407 }
408 uint32_t get_agava_ts_hi() const
409 {
410 return agava_ts_hi;
411 }
412 void set_agava_ts_hi(const uint32_t& _agava_ts_hi)
413 {
414 agava_ts_hi = _agava_ts_hi;
415 }
416 uint32_t get_vtc_ts_lo() const
417 {
418 return vtc_ts_lo;
419 }
420 void set_vtc_ts_lo(const uint32_t& _vtc_ts_lo)
421 {
422 vtc_ts_lo = _vtc_ts_lo;
423 }
424 uint16_t get_vtc_ts_hi() const
425 {
426 return vtc_ts_hi;
427 }
428 void set_vtc_ts_hi(const uint16_t& _vtc_ts_hi)
429 {
430 vtc_ts_hi = _vtc_ts_hi;
431 }
432 bool is_scaler_event() const
433 {
434 // returns true if event ONLY contains scaler data
435 return _is_scaler_event;
436 }
437 void set_is_scaler_event(bool newIs_scaler_event = true)
438 {
439 _is_scaler_event = newIs_scaler_event;
440 }
441 };
442}
443#endif // READ_LISTFILE_H
parse mesytec data in buffers
a single item of data read from a module, corresponding to a given bus number, channel number and dat...
module::datatype_t get_data_type() const
uint32_t get_data_word() const
uint16_t get_data() const
bool get_overflow() const
uint8_t get_channel_number() const
uint8_t get_bus_number() const
collection of data read out from the VME crate
uint32_t get_event_counter() const
uint32_t & get_event_counter()
const std::vector< module_data > & get_module_data() const
Description of modules contained in VME crate & connected detectors.
module & get_module(uint8_t mod_id) const
get_module
collects together all channel_data read from a single module in one event
const std::vector< channel_data > & get_channel_data() const
void dump_module_data() const
uint16_t get_number_of_data_words() const
uint8_t get_module_id() const
Abstract base class for Mesytec modules.
std::string name
human-readable name of module
void set_data_word(const uint32_t &data)
uint8_t id
HW address of module in VME crate.
datatype_t
Different types of data which Mesytec modules may produce.