Belle II Software development
PXDPackerErrModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <pxd/unpacking/PXDRawDataDefinitions.h>
10#include <pxd/modules/pxdUnpacking/PXDPackerErrModule.h>
11#include <framework/datastore/DataStore.h>
12#include <framework/logging/Logger.h>
13#include <framework/dataobjects/EventMetaData.h>
14#include <framework/datastore/StoreObjPtr.h>
15#include <framework/core/ModuleParam.templateDetails.h>
16
17#include <boost/crc.hpp>
18
19#include <numeric>
20
21#include <TRandom.h>
22
23using namespace std;
24using namespace Belle2;
25using namespace Belle2::PXD;
26using namespace Belle2::PXD::PXDError;
27
28//-----------------------------------------------------------------
29// Register the Module
30//-----------------------------------------------------------------
31REG_MODULE(PXDPackerErr);
32
33
34using boost::crc_optimal;
35typedef crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhc_crc_32_type;
36
40std::vector <PXDErrorFlags> PXDPackerErrModule::m_errors = {
41 // Event 0 does not exist...
42 c_NO_ERROR,
43 /* 1 - HLT-Onsen Trigger differs from Meta (meta changed! thus all differ)
44 * 2 - HLT-Onsen Trigger is zero
45 * 3 - Run Nr differs between HLT-Onsen and Meta
46 * 4 - Subrun Nr differs between HLT-Onsen and Meta
47 * 5 - Exp differs between HLT-Onsen and Meta */
48 c_META_MM | c_META_MM_DHC | c_META_MM_DHE | c_META_MM_ONS_HLT | c_META_MM_ONS_DC,
49 c_META_MM | c_META_MM_DHC | c_META_MM_DHE | c_META_MM_ONS_HLT | c_META_MM_ONS_DC,
50 c_META_MM_DHC_ERS | c_META_MM_ONS_HLT | c_META_MM_ONS_DC,
51 c_META_MM_DHC_ERS | c_META_MM_ONS_HLT | c_META_MM_ONS_DC,
52 c_META_MM_DHC_ERS | c_META_MM_ONS_HLT | c_META_MM_ONS_DC,
53 /* 6 - Wrong ONS Trigger frame length
54 * 7 - Wrong DHC Start frame length
55 * 8 - Wrong DHC End frame length
56 * 9 - Wrong DHE Start frame length
57 * 10 - Wrong DHE End frame length */
58 c_FIX_SIZE, // TODO why mismatch?
59 c_FIX_SIZE, // TODO Problem
60 c_FIX_SIZE, // TODO why is DHC End missing not detected?
61 c_FIX_SIZE, // TODO why is DHE Start missing not detected?
62 c_FIX_SIZE, // TODO why is DHE End missing not detected?
63 /* 11 - Wrong DHE Start frame length (by 2 bytes), unalign 32 bit frame
64 * 12 - Missing ONS Trig frame
65 * 13 - Missing DHC Start frame
66 * 14 - Missing DHC End frame
67 * 15 - Missing DHE Start frame */
68 c_FRAME_SIZE, // TODO can check more errors
69 c_ONSEN_TRG_FIRST | c_DHC_START_SECOND | c_DHE_START_THIRD | c_EVENT_STRUCT, // TODO
70 c_DHC_START_SECOND, // TODO
71 c_DHC_END_MISS,
72 c_DHE_END_WO_START | c_DHE_START_THIRD, // TODO
73 /* 16 - Missing DHE End frame
74 * 17 - Double ONS Trig frame
75 * 18 - Double DHC Start frame
76 * 19 - Double DHC End frame
77 * 20 - Double DHE Start frame*/
78 c_DHE_START_WO_END, // TODO if two DHE, another error condition shoudl trigger, too
79 c_ONSEN_TRG_FIRST | c_DHC_START_SECOND | c_DHE_START_THIRD | c_EVENT_STRUCT, // TODO why data outside of ...
80 c_DHC_START_SECOND | c_DHE_START_THIRD, // TODO why data outside of ...
81 c_DHC_END_DBL, // TODO
82 c_DHE_WRONG_ID_SEQ | c_DHE_START_WO_END, // TODO
83 /* 21 - Double DHE End frame
84 * 22 - DATCON triggernr+1
85 * 23 - HLT Magic broken
86 * 24 - DATCON Magic broken
87 * 25 - HLT with Accepted not set */
88 c_DHE_END_WO_START | c_DHE_START_END_ID, // TODO
89 c_MERGER_TRIGNR | c_META_MM_ONS_DC,
90 c_HLTROI_MAGIC,
91 c_HLTROI_MAGIC,
92 c_NO_ERROR | c_NOTSENDALL_TYPE, // TODO =============================================== CHECK TODO Unpacker is not detecting this yet
93 /* 26 - HLT triggernr+1
94 * 27 - CRC error in second frame (DHC start)
95 * 28 - data for all DHE even if disabled in mask
96 * 29 - no DHE at all, even so mask tell us otherwise
97 * 30 - no DHC at all */
98 c_MERGER_TRIGNR | c_META_MM_ONS_HLT,
99 c_DHE_CRC, // TODO why DHE start missing not detected?
100 c_DHE_ACTIVE, // TODO why | c_DHE_WRONG_ID_SEQ | c_DHE_ID_INVALID,
101 c_DHE_START_THIRD | c_DHE_ACTIVE,
102 c_DHC_END_MISS, // TODO need some better checks
103 /* 31 - DHC end has wrong DHC id
104 * 32 - DHE end has wrong DHE id
105 * 33 - DHC wordcount wrong by 4 bytes
106 * 34 - DHE wordcount wrong by 4 bytes
107 * 35 - DHE Trigger Nr Hi word messed up */
108 c_DHC_DHCID_START_END_MM,
109 c_DHE_START_END_ID,
110 c_DHC_WIE,
111 c_DHE_WIE,
112 c_META_MM_DHE,
113 /* 36 - ONS Trigger Nr Hi word messed up
114 * 37 - DHP data, even if mask says no DHP TODO Check
115 * 38 - No DHP data, even if mask tell otherwise
116 * 39 - DHE id differ in DHE and DHP header
117 * 40 - Chip ID differ in DHE and DHP header */
118 c_META_MM_ONS_HLT | c_MERGER_TRIGNR,
119 c_NO_ERROR, // TODO ===========================================TODO Unpacker is not detecting this
120 c_DHP_ACTIVE,
121 c_DHE_DHP_DHEID,
122 c_DHE_DHP_PORT,
123 /* 41 - Row overflow by 1
124 * 42 - Col overflow by 1
125 * 43 - Missing Start Row (Pixel w/o row)
126 * 44 - No PXD raw packet at all
127 * 45 - No DATCON data */
128 c_ROW_OVERFLOW,
129 c_COL_OVERFLOW,
130 c_DHP_PIX_WO_ROW,
131 c_NO_PXD,
132 c_NO_DATCON,
133 /* 46 - unused frame type: common mode
134 * 47 - unused frame type: FCE
135 * 48 - unused frame type: ONS FCE
136 * 49 - unused frame type: 0x7
137 * 50 - unused frame type: 0x8 */
138 c_UNEXPECTED_FRAME_TYPE,
139 c_UNEXPECTED_FRAME_TYPE,
140 c_UNEXPECTED_FRAME_TYPE,
141 c_DHC_UNKNOWN,
142 c_DHC_UNKNOWN,
143 /* 51 - unused frame type: 0xA
144 * 52 - Rows w/o Pixel (several rows after each other)
145 * 53 - no frames in packet (this should be an error)
146 * 54 - broken PXD packet magic
147 * 55 - exceeding allowed nr of frames by far */
148 c_DHC_UNKNOWN,
149 c_DHP_ROW_WO_PIX,
150 c_NR_FRAMES_TO_SMALL,
151 c_MAGIC,
152 c_FRAME_NR,
153 /* 56 - more frames than actual available, exceeding packet size
154 * 57 - one frame payload exceeding packet size
155 * 58 - DHC Start frame has wrong trigger Nr HI
156 * 59 - DHC Start frame has wrong trigger Nr LO
157 * 60 - DHE Start frame has wrong trigger Nr LO */
158 c_FRAME_SIZE,
159 c_FRAME_SIZE,
160 c_META_MM_DHC,
161 c_FRAME_TNR_MM | c_META_MM | c_META_MM_DHC,
162 c_FRAME_TNR_MM | c_META_MM | c_META_MM_DHE,
163 /* 61 - DHE End frame has wrong trigger Nr LO
164 * 62 - DHE End has different DHE Id
165 * 63 - DHE Z_DHP Header DHE ID differ from Start
166 * 64 - Set ERROR Flag in DHE END
167 * 65 - Invalid DHE ID ($3F) in DHE */
168 c_FRAME_TNR_MM | c_META_MM, // TODO why not |c_META_MM_DHE
169 c_DHE_START_END_ID, // TODO why not c_DHE_START_ID,
170 c_DHE_START_ID | c_DHE_DHP_DHEID,
171 c_HEADER_ERR,
172 c_DHE_ID_INVALID,
173 /* 66 - Doubled DHP Header
174 * 67 - 'FAKE' DHC START/END (=no data)
175 * 68 - wrong readout frame number in DHP header TODO
176 * 69 - DHP frame with too small size
177 * 70 - TimeTag Mismatch for DHC/Meta */
178 c_DHP_DBL_HEADER,
179 c_FAKE_NO_DATA_TRIG,
180 c_NO_ERROR,// TODO ===========================================TODO Unpacker is not detecting this
181 c_DHP_SIZE,
182 c_META_MM_DHC_TT,
183 /*
184 * 71 data outside of DHE
185 * 72 Fake no Fake mix, plus a second DHC
186 * 73 Fake no Fake mix, plus double DHC End
187 * 74 Fake no Fake mix, plus double DHC Start
188 * 75 Fake no Fake mix, replaced DHC End
189 */
190 c_DATA_OUTSIDE,
191 c_FAKE_NO_FAKE_DATA,
192 c_FAKE_NO_FAKE_DATA,
193 c_FAKE_NO_FAKE_DATA,
194 c_FAKE_NO_FAKE_DATA,
195 /*
196 * 76 Fake no Fake mix, replaced DHC Start
197 * 77 ROI Frame without header/content, inside DHC Start/End
198 * 78 ROI Frame without header/content, outside DHC Start/End ... this is not allowed (ONSEN)
199 * 79 TODO ROI Frame with header & content
200 * 80 TODO ROI Frame with header & content but errors
201 */
202 c_FAKE_NO_FAKE_DATA,
203 c_ROI_PACKET_INV_SIZE,
204 c_ROI_PACKET_INV_SIZE,// no error flag for this?
205 c_NO_ERROR,
206 c_NO_ERROR, // not error bit for this?
207};
208
209bool PXDPackerErrModule::CheckErrorMaskInEvent(unsigned int eventnr, PXDErrorFlags mask)
210{
213 PXDErrorFlags expected; // constructed to no error
214 if (eventnr > 0 && eventnr < m_errors.size()) {
215 expected = m_errors[eventnr];
216 }
217 B2INFO("-- PXD Packer Error Check for Event Nr: " << eventnr);
218 for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) {
219 PXDErrorFlags m;
220 m[i] = true;
221 if ((m & (mask | expected)) == m) {
222 if ((m & expected) == m && (m & mask) != m) {
223 B2ERROR("Bit " << i << ": Was NOT Set: " << getPXDBitErrorName(i));
224 m_found_fatal = true;
225 } else if ((m & expected) != m && (m & mask) == m) {
226 B2RESULT("Bit " << i << ": Optional : " << getPXDBitErrorName(i));
227 } else if ((m & expected) == m && (m & mask) == m) {
228 B2INFO("Bit " << i << ": As Expected: " << getPXDBitErrorName(i));
229 }
230 }
231 }
232 bool flag = (mask & expected) == expected;
233 if (expected == PXDErrorFlags(0)) {
234 // special check, this event should not contain any error!
235 if (mask != PXDErrorFlags(0)) {
236 B2ERROR("There should be no error in this event, but there were (see above)!");
237 m_found_fatal = true;
238 }
239 flag = (mask == PXDErrorFlags(0));
240 }
241 B2INFO("-- PXD Packer Error Check END --- ");
242 // Bail out on the first check which fails.
243 if (m_found_fatal) B2FATAL("This check failed (see details above)!");
244 return flag;
245}
246
248 Module(),
249 m_storeRaws()
250{
251 m_trigger_nr = 0;
252 m_packed_events = 0;
253 m_run_nr_word1 = 0;
254 m_run_nr_word2 = 0;
255 //Set module properties
256 setDescription("Create 'broken' PXD raw data to challenge Unpacker");
258
259 addParam("RawPXDsName", m_RawPXDsName, "The name of the StoreArray of generated RawPXDs", std::string(""));
260 addParam("dhe_to_dhc", m_dhe_to_dhc, "DHE to DHC mapping (DHC_ID, DHE1, DHE2, ..., DHE5) ; -1 disable port");
261 addParam("InvertMapping", m_InvertMapping, "Use invers mapping to DHP row/col instead of \"remapped\" coordinates", false);
262 addParam("Clusterize", m_Clusterize, "Use clusterizer (FCE format)", false);
263 addParam("Check", m_Check, "Check the result of Unpacking", false);
264 addParam("PXDDAQEvtStatsName", m_PXDDAQEvtStatsName, "The name of the StoreObjPtr of read PXDDAQEvtStats", std::string(""));
265
266}
267
269{
270 m_found_fatal = false;
271 B2DEBUG(27, "PXD Packer Err --> Init");
272 if (m_Check) {
273 B2WARNING("=== Important! A lot of intentional errors will follow. To find the reason for a failing test, check the lines before the FATAL. ====");
274 m_daqStatus.isRequired();
275 } else {
276 //Register output collections
278 m_packed_events = 0;
279
283 for (auto& it : m_dhe_to_dhc) {
284 bool flag;
285 int dhc_id;
286 B2DEBUG(27, "PXD Packer Err --> DHC/DHE");
287 flag = false;
288 if (it.size() != 6) {
290 B2WARNING("PXD Packer Err --> DHC/DHE maps 1 dhc to 5 dhe (1+5 values), but I found " << it.size());
291 }
292 for (auto& it2 : it) {
293 if (flag) {
294 int v;
295 v = it2;
296 B2DEBUG(27, "PXD Packer Err --> ... DHE " << it2);
297 if (it2 < -1 || it2 >= 64) {
298 if (it2 != -1) B2ERROR("PXD Packer Err --> DHC id " << it2 << " is out of range (0-64 or -1)! disable channel.");
299 v = -1;
300 }
301 m_dhc_mapto_dhe[dhc_id].push_back(v);
302 } else {
303 dhc_id = it2;
304 B2DEBUG(27, "PXD Packer Err --> DHC .. " << it2);
305 if (dhc_id < 0 || dhc_id >= 16) {
306 B2ERROR("PXD Packer Err --> DHC id " << it2 << " is out of range (0-15)! skip");
307 break;
308 }
309 }
310 flag = true;
311 }
312 }
313 B2DEBUG(27, "PXD Packer Err --> DHC/DHE done");
314
315 for (auto& it : m_dhc_mapto_dhe) {
316 int port = 0;
317 B2DEBUG(27, "PXD Packer Err --> DHC " << it.first);
318 for (auto& it2 : it.second) {
319 B2DEBUG(27, "PXD Packer Err --> .. connects to DHE " << it2 << " port " << port);
320 port++;
321 }
322 }
323 }
324}
325
327{
328 if (m_Check) {
329 // Bail out if error detected
330 if (m_found_fatal) B2FATAL("At least one of the checks failed (see details above)!");
331 // Check kindof test coverage
332 B2INFO("Check Test coverage:");
333 PXDErrorFlags mask = c_NO_ERROR;
334 mask = std::accumulate(m_errors.begin(), m_errors.end(), mask, std::bit_or<PXDErrorFlags>());
335 for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) {
336 PXDErrorFlags m;
337 m[i] = true;
338 if ((m & mask) == 0) {
339 B2WARNING("Bit " << i << ": Not Covered : " << getPXDBitErrorName(i));
340 }
341 }
342 }
343}
344
346{
347 B2DEBUG(27, "PXD Packer Err --> Event");
349
350 m_real_trigger_nr = m_trigger_nr = evtPtr->getEvent();
351
352 if (m_Check) {
354 } else {
355
356 // First, throw the dices for a few event-wise properties
357
358 m_trigger_dhp_framenr = gRandom->Integer(0x10000);
359 m_trigger_dhe_gate = gRandom->Integer(192);
360
361
362 if (isErrorIn(1)) m_trigger_nr += 10;
363 if (isErrorIn(2)) m_trigger_nr = 0;
364
365 uint32_t run = evtPtr->getRun();
366 uint32_t exp = evtPtr->getExperiment();
367 uint32_t sub = evtPtr->getSubrun();
368
369 if (isErrorIn(3)) run++;
370 if (isErrorIn(4)) sub++;
371 if (isErrorIn(5)) exp++;
372
373 m_run_nr_word1 = ((run & 0xFF) << 8) | (sub & 0xFF);
374 m_run_nr_word2 = ((exp & 0x3FF) << 6) | ((run >> 8) & 0x3F);
375 m_meta_time = evtPtr->getTime();
376
377 B2INFO("Pack Event : " << evtPtr->getEvent() << "," << evtPtr->getRun() << "," << evtPtr->getSubrun() << "," <<
378 evtPtr->getExperiment() << "," << evtPtr->getTime() << " (MetaInfo)");
379
380 if (!isErrorIn(44)) {
381 pack_event();
383 }
384 }
385}
386
388{
389 int dhe_ids[5] = {0, 0, 0, 0, 0};
390 B2DEBUG(27, "PXD Packer Err --> pack_event");
391
392 // loop for each DHC in system
393 // get active DHCs from a database?
394 for (auto& it : m_dhc_mapto_dhe) {
395 int port = 1, port_inx = 0;
396 int act_port = 0;
397
398 for (auto& it2 : it.second) {
399 if (it2 >= 0) act_port += port;
400 port += port;
401 dhe_ids[port_inx] = it2;
402 port_inx++;
403 if (port_inx == 5) break; // not more than five.. checked above
404 }
405
406 // if(act_port&0x1F) B2ERROR();... checked above
407 // act_port&=0x1F;... checked above
408
409 // get active DHE mask from a database?
410
411 m_onsen_header.clear();// Reset
412 m_onsen_payload.clear();// Reset
413 if (isErrorIn(74)) {
414 // add a faked DHC, "no data"
415 start_frame();
416 append_int32(EDHCFrameHeaderDataType::c_DHC_START << 27);
417 append_int16(0);
418 append_int16(0);
419 append_int16(0);
420 append_int16(0);
421 append_int16(0);
422 append_int16(0);
424 }
425 if (!isErrorIn(53)) pack_dhc(it.first, act_port, dhe_ids);
426 // and write to PxdRaw object
427 // header will be finished and endian swapped by constructor; payload already has be on filling the vector
428 if (isErrorIn(73)) {
429 // add a faked DHC, "no data"
430 start_frame();
431 append_int32(EDHCFrameHeaderDataType::c_DHC_END << 27);
432 append_int32(0);
433 append_int32(0);
435 }
436 if (isErrorIn(72)) {
437 // add a faked DHC, "no data"
438 start_frame();
439 append_int32(EDHCFrameHeaderDataType::c_DHC_START << 27);
440 append_int16(0);
441 append_int16(0);
442 append_int16(0);
443 append_int16(0);
444 append_int16(0);
445 append_int16(0);
447
448 start_frame();
449 append_int32(EDHCFrameHeaderDataType::c_DHC_END << 27);
450 append_int32(0);
451 append_int32(0);
453 }
454 auto objptr = m_storeRaws.appendNew(m_onsen_header, m_onsen_payload);
455 if (isErrorIn(54)) {
456 objptr->data()[0] = 0xDEADBEAF; // invalid magic
457 }
458 if (isErrorIn(55)) {
459 objptr->data()[1] = 0x00110000; // invalid #frames
460 }
461 if (isErrorIn(56)) {
462 objptr->data()[1] = 0x00010000; // valid #frames, but will exceed size
463 }
464 if (isErrorIn(57)) {
465 objptr->data()[2] = 0x01010101; // extremely large frame
466 }
467 }
468
469}
470
472{
473 if (m_current_frame.size() & 0x3) {
474 B2WARNING("Frame is not 32bit aligned!!! Unsupported by Unpacker!");
475 }
476 // checksum frame
477 dhc_crc_32_type current_crc;
478 current_crc.process_bytes(m_current_frame.data(), m_current_frame.size());
479 if (isErrorIn(27) and m_onsen_header.size() == 1) current_crc.process_byte(0x42); // mess up CRC in second frame
480 append_int32(current_crc.checksum());
481
482 // and add it
483 m_onsen_header.push_back(m_current_frame.size());
485}
486
488{
489 m_current_frame.push_back(w);
492}
493
495{
496 m_current_frame.push_back((unsigned char)(w >> 8));
497 m_current_frame.push_back((unsigned char)(w));
498 dhe_byte_count += 2;
499 dhc_byte_count += 2;
500}
501
503{
504 m_current_frame.push_back((unsigned char)(w >> 24));
505 m_current_frame.push_back((unsigned char)(w >> 16));
506 m_current_frame.push_back((unsigned char)(w >> 8));
507 m_current_frame.push_back((unsigned char)(w));
508 dhe_byte_count += 4;
509 dhc_byte_count += 4;
510}
511
512// void PXDPackerErrModule::remove_back_int32(void)
513// {
514// m_current_frame.pop_back();
515// m_current_frame.pop_back();
516// m_current_frame.pop_back();
517// m_current_frame.pop_back();
518// dhe_byte_count -= 4;
519// dhc_byte_count -= 4;
520// }
521
523{
524 m_current_frame.clear();
525}
526
527void PXDPackerErrModule::pack_dhc(int dhc_id, int dhe_active, int* dhe_ids, bool send_all, bool send_roi)
528{
529 B2DEBUG(27, "PXD Packer Err --> pack_dhc ID " << dhc_id << " DHE act: " << dhe_active);
530
532 start_frame();
533 append_int32((EDHCFrameHeaderDataType::c_ONSEN_TRG << 27) | (m_trigger_nr & 0xFFFF));
534 B2INFO("Trigger packet: $" << hex << m_run_nr_word1 << ", $" << m_run_nr_word2);
535 if (isErrorIn(23)) {
536 append_int32(0xDEAD8000);
537 } else if (isErrorIn(25)) {
538 append_int32(0xCAFE0000);// HLT HEADER, NO accepted flag
539 } else {
540 append_int32(0xCAFE8000 | (send_all ? 0x4000 : 0) | (send_roi ? 0x2000 : 0)); // HLT HEADER, accepted flag set
541 }
542 if (isErrorIn(26)) {
544 } else if (isErrorIn(36)) {
545 append_int32(0x10000000 | m_trigger_nr); // HLT Trigger Nr with Hi work messed up
546 } else {
547 append_int32(m_trigger_nr); // HLT Trigger Nr
548 }
549 append_int16(m_run_nr_word2); // HLT Run NR etc
550 append_int16(m_run_nr_word1); // HLT Run NR etc
551 if (isErrorIn(24)) append_int32(0xDEAD0000);
552 else append_int32(0xCAFE0000);// DATCON HEADER ...
553 if (isErrorIn(45)) {
554 // No Datcon
555 append_int32(0x0); // trigger nr
556 append_int32(0x0); // 2*16 trg tag
557 } else {
558 if (isErrorIn(22)) append_int32(m_trigger_nr + 1);
559 else append_int32(m_trigger_nr);// DATCON Trigger Nr
560 if (!isErrorIn(6)) {
561 append_int16(m_run_nr_word2); // DATCON Run NR etc
562 append_int16(m_run_nr_word1); // DATCON Run NR etc
563 }
564 }
566 if (isErrorIn(17)) {
567 // double frame
568 m_onsen_header.push_back(m_current_frame.size());
570 }
571
572 if (isErrorIn(30)) return; // empty event, no DHC frames
573
575 if (!isErrorIn(67)) {
576
577 dhc_byte_count = 0;
578 if (isErrorIn(76)) {
579 // add a faked DHC, "no data"
580 start_frame();
581 append_int32(EDHCFrameHeaderDataType::c_DHC_START << 27);
582 append_int16(0);
583 append_int16(0);
584 append_int16(0);
585 append_int16(0);
586 append_int16(0);
587 append_int16(0);
589 } else {
590 start_frame();
591 uint32_t header = (EDHCFrameHeaderDataType::c_DHC_START << 27) | ((dhc_id & 0xF) << 21) | ((dhe_active & 0x1F) << 16) |
592 (m_trigger_nr & 0xFFFF);
593 if (isErrorIn(59)) header++;
594 append_int32(header);
595 if (!isErrorIn(58)) append_int16(m_trigger_nr >> 16);
596 else append_int16((m_trigger_nr >> 16) + 1);
597
598 uint32_t mm = (unsigned int)std::round((m_meta_time % 1000000000ull) * 0.127216); // in 127MHz Ticks
599 uint32_t ss = (unsigned int)(m_meta_time / 1000000000ull) ; // in seconds
600 if (isErrorIn(70)) mm++;
601 if (isErrorIn(70)) ss++;
602 append_int16(((mm << 4) & 0xFFF0) | 0x1); // TT 11-0 | Type --- fill with something usefull TODO
603 append_int16(((mm >> 12) & 0x7FFF) | ((ss & 1) ? 0x8000 : 0x0)); // TT 27-12 ... not clear if completely filled by DHC
604 append_int16((ss >> 1) & 0xFFFF); // TT 43-28 ... not clear if completely filled by DHC
605 if (!isErrorIn(7)) {
606 append_int16(m_run_nr_word1); // Run Nr 7-0 | Subrunnr 7-0
607 append_int16(m_run_nr_word2); // Exp NR 9-0 | Run Nr 13-8
608 }
610 if (isErrorIn(18)) {
611 // double frame
612 m_onsen_header.push_back(m_current_frame.size());
614 }
615 }
616
617 // loop for each DHE in system
618 // Run & TTT etc are zero until better idea
619
620 if (isErrorIn(29)) dhe_active = 0; // dont send any DHE
621 for (int i = 0; i < 5; i++) {
622 if ((dhe_active & 0x1) or isErrorIn(28)) pack_dhe(dhe_ids[i], 0xF);
623 if (isErrorIn(71) && i == 2) {
624 pack_dhp(1, dhe_ids[i], 1);
625 }
626 dhe_active >>= 1;
627 }
628
630
631 if (isErrorIn(77)) {
632 // TODO add ROI Frame if header bit is set
633 int old = dhc_byte_count;
634 start_frame();
635 append_int32((EDHCFrameHeaderDataType::c_ONSEN_ROI << 27) | (m_trigger_nr & 0xFFFF));
637 dhc_byte_count = old; // dont count
638 }
639
641 if (isErrorIn(75)) {
642 // add a faked DHC, "no data"
643 start_frame();
644 append_int32(EDHCFrameHeaderDataType::c_DHC_END << 27);
645 append_int32(0);
646 append_int32(0);
648 } else {
649 if (isErrorIn(31)) dhc_id += 1;
650 if (isErrorIn(33)) dhc_byte_count += 4;
651 unsigned int dlen = (dhc_byte_count / 4); // 32 bit words
652 start_frame();
653 append_int32((EDHCFrameHeaderDataType::c_DHC_END << 27) | ((dhc_id & 0xF) << 21) | (m_trigger_nr & 0xFFFF));
654 append_int32(dlen); // 32 bit word count
655 if (!isErrorIn(8)) append_int32(0x00000000); // Error Flags
657 if (isErrorIn(19)) {
658 // double frame
659 m_onsen_header.push_back(m_current_frame.size());
661 }
662 }
663 if (isErrorIn(78)) {
664 // TODO add ROI Frame if header bit is set
665 int old = dhc_byte_count;
666 start_frame();
667 append_int32((EDHCFrameHeaderDataType::c_ONSEN_ROI << 27) | (m_trigger_nr & 0xFFFF));
669 dhc_byte_count = old; // dont count
670 }
671
672 } else {
673 // add a faked DHC, "no data"
674 start_frame();
675 append_int32(EDHCFrameHeaderDataType::c_DHC_START << 27);
676 append_int16(0);
677 append_int16(0);
678 append_int16(0);
679 append_int16(0);
680 append_int16(0);
681 append_int16(0);
683
684 start_frame();
685 append_int32(EDHCFrameHeaderDataType::c_DHC_END << 27);
686 append_int32(0);
687 append_int32(0);
689 }
690}
691
692void PXDPackerErrModule::pack_dhe(int dhe_id, int dhp_active)
693{
694 if (isErrorIn(37)) dhp_active = 0; // mark as no DHP, but send them (see below)
695 B2DEBUG(27, "PXD Packer Err --> pack_dhe ID " << dhe_id << " DHP act: " << dhp_active);
696 // dhe_id is not dhe_id ...
697 bool dhe_has_remapped = !m_InvertMapping;
698
699 if (m_InvertMapping) {
700 // problem, we do not have an exact definition of if this bit is set in the new firmware and under which circumstances
701 // and its not clear if we have to translate the coordinates back to "DHP" layout! (look up tabel etc!)
702 B2FATAL("Inverse Mapping not implemented in Packer");
703 }
704
705 if (isErrorIn(65)) dhe_id = 0x3F; // invalid
707 dhe_byte_count = 0;
708 start_frame();
709 uint32_t header = (EDHCFrameHeaderDataType::c_DHE_START << 27) | ((dhe_id & 0x3F) << 20) | ((dhp_active & 0xF) << 16) |
710 (m_trigger_nr & 0xFFFF);
711 if (isErrorIn(60)) header++;
712 append_int32(header);
713
714 if (isErrorIn(35)) append_int16(0x1000);
715 else append_int16(m_trigger_nr >> 16); // Trigger Nr Hi
716 if (!isErrorIn(11)) {
717 append_int16(0x00000000); // DHE Timer Lo
718 }
719 if (!isErrorIn(9)) {
720 append_int16(0x00000000); // DHE Time Hi
721 append_int16(((m_trigger_dhp_framenr & 0x3F) << 10) |
722 (m_trigger_dhe_gate & 0xFF)); // Last DHP Frame Nr 15-10, Reserved 9-8, Trigger Offset 7-0
723 }
725 if (isErrorIn(20)) {
726 // double frame
727 m_onsen_header.push_back(m_current_frame.size());
729 }
730
731 // Now we add some undefined things
732 if (isErrorIn(46)) {
733 start_frame();
734 append_int32((EDHCFrameHeaderDataType::c_COMMODE << 27) | ((dhe_id & 0x3F) << 20) | (m_trigger_nr & 0xFFFF));
736 }
737 if (isErrorIn(47)) {
738 start_frame();
739 append_int32((EDHCFrameHeaderDataType::c_FCE_RAW << 27) | ((dhe_id & 0x3F) << 20) | (m_trigger_nr & 0xFFFF));
741 }
742 if (isErrorIn(48)) {
743 start_frame();
744 append_int32((EDHCFrameHeaderDataType::c_ONSEN_FCE << 27) | ((dhe_id & 0x3F) << 20) | (m_trigger_nr & 0xFFFF));
746 }
747 if (isErrorIn(49)) {
748 start_frame();
749 append_int32((EDHCFrameHeaderDataType::c_UNUSED_7 << 27) | ((dhe_id & 0x3F) << 20) | (m_trigger_nr & 0xFFFF));
751 }
752 if (isErrorIn(50)) {
753 start_frame();
754 append_int32((EDHCFrameHeaderDataType::c_UNUSED_8 << 27) | ((dhe_id & 0x3F) << 20) | (m_trigger_nr & 0xFFFF));
756 }
757 if (isErrorIn(51)) {
758 start_frame();
759 append_int32((EDHCFrameHeaderDataType::c_UNUSED_A << 27) | ((dhe_id & 0x3F) << 20) | (m_trigger_nr & 0xFFFF));
761 }
762
763// now prepare the data from one halfladder
764// do the ROI selection??? optional...
765// then loop for each DHP in system
766// get active DHPs from a database?
767// and pack data per halfladder.
768// we fake the framenr and startframenr until we find some better solution
769
770 if (dhp_active != 0) {
771
773 bzero(halfladder_pixmap, sizeof(halfladder_pixmap));
774
781 unsigned short sensor, ladder, layer;
782 sensor = (dhe_id & 0x1) + 1;
783 ladder = (dhe_id & 0x1E) >> 1; // no +1
784 layer = ((dhe_id & 0x20) >> 5) + 1;
785
786 B2DEBUG(27, "pack_dhe: VxdId: " << VxdID(layer, ladder, sensor) << " " << (int)VxdID(layer, ladder, sensor));
787
788 // Create some fixed hits (not too many, jut a few per ladder)
789 for (auto j = 0; j < 10; j++) {
790 unsigned int row, col;
791 unsigned char charge;
792 row = j * 23;
793 col = j * 23;
794 charge = 20 + j; // 0-255
795 if (!dhe_has_remapped) {
796 do_the_reverse_mapping(row, col, layer, sensor);
797 }
798 halfladder_pixmap[row][col] = charge;
799 }
800
801 if (isErrorIn(38)) dhp_active = 0; // no DHP data even if we expect it
802 if (m_Clusterize) {
803 B2FATAL("Clusterizer not supported in Packer");
804 } else {
805 for (int i = 0; i < 4; i++) {
806 if ((dhp_active & 0x1) or isErrorIn(37)) {
807 pack_dhp(i, dhe_id, dhe_has_remapped ? 1 : 0);
809// if (m_trigger_nr == 0x11) {
810// pack_dhp_raw(i, dhe_id, false);
811// pack_dhp_raw(i, dhe_id, true);
812// }
813 }
814 dhp_active >>= 1;
815 }
816 }
817 }
818
820 if (isErrorIn(32)) dhe_id += 1;
821 if (isErrorIn(34)) dhe_byte_count += 4;
822 unsigned int dlen = (dhe_byte_count / 2); // 16 bit words
823 start_frame();
824 header = (EDHCFrameHeaderDataType::c_DHE_END << 27) | ((dhe_id & 0x3F) << 20) | (m_trigger_nr & 0xFFFF);
825 if (isErrorIn(61)) header++;
826 if (isErrorIn(62)) header += 1 << 20;
827 if (isErrorIn(64)) header |= 0x80000000;
828 append_int32(header);
829 append_int16(dlen & 0xFFFF); // 16 bit word count
830 append_int16((dlen >> 16) & 0xFFFF); // 16 bit word count
831 if (!isErrorIn(10)) append_int32(0x00000000); // Error Flags
833 if (isErrorIn(21)) {
834 // double frame
835 m_onsen_header.push_back(m_current_frame.size());
837 }
838}
839
840void PXDPackerErrModule::do_the_reverse_mapping(unsigned int& /*row*/, unsigned int& /*col*/, unsigned short /*layer*/,
841 unsigned short /*sensor*/)
842{
843 B2FATAL("code needs to be written");
844 // work to be done
845 //
846 // PXDMappingLookup::map_uv_to_rc_IF_OB(unsigned int& v_cellID, unsigned int& u_cellID, unsigned int& dhp_id, unsigned int dhe_ID)
847 // PXDMappingLookup::map_uv_to_rc_IB_OF(unsigned int& v_cellID, unsigned int& u_cellID, unsigned int& dhp_id, unsigned int dhe_ID)
848}
849
850void PXDPackerErrModule::pack_dhp_raw(int chip_id, int dhe_id)
851{
852 B2DEBUG(27, "PXD Packer Err --> pack_dhp Raw Chip " << chip_id << " of DHE id: " << dhe_id);
853 start_frame();
855 append_int32((EDHCFrameHeaderDataType::c_DHP_RAW << 27) | ((dhe_id & 0x3F) << 20) | ((chip_id & 0x03) << 16) |
856 (m_trigger_nr & 0xFFFF));
857 append_int32((EDHPFrameHeaderDataType::c_RAW << 29) | ((dhe_id & 0x3F) << 18) | ((chip_id & 0x03) << 16) |
858 (m_trigger_dhp_framenr & 0xFFFF));
859
860 int c1, c2;
861 c1 = 64 * chip_id;
862 c2 = c1 + 64;
863 if (c2 >= PACKER_NUM_COLS) c2 = PACKER_NUM_COLS;
864
865 // ADC data / memdump for pedestal calculation
866 for (int row = 0; row < PACKER_NUM_ROWS; row++) {
867 for (int col = c1; col < c2; col++) {
869 }
870 // unconnected drain lines -> 0
871 for (int col = c2; col < c1 + 64; col++) {
872 append_int8(0);
873 }
874 }
875
877}
878
879void PXDPackerErrModule::pack_dhp(int chip_id, int dhe_id, int dhe_has_remapped)
880{
881 B2DEBUG(27, "PXD Packer Err --> pack_dhp Chip " << chip_id << " of DHE id: " << dhe_id);
882 // remark: chip_id != port most of the time ...
883 bool empty = true;
884 unsigned short last_rowstart = 0;
885 bool error_done = false;
886
887 if (dhe_has_remapped == 0) {
888 // problem, we do not have an exact definition of if this bit is set in the new firmware and under which circumstances
889 // and its not clear if we have to translate the coordinates back to "DHP" layout! (look up tabel etc!)
890 B2FATAL("dhe_has_remapped == 0");
891 }
892
893 start_frame();
895 uint32_t header = (EDHCFrameHeaderDataType::c_DHP_ZSD << 27) | ((dhe_id & 0x3F) << 20) | ((dhe_has_remapped & 0x1) << 19) | ((
896 chip_id & 0x03) << 16) | (m_trigger_nr & 0xFFFF);
897 if (isErrorIn(63)) header += 1 << 20;
898 append_int32(header);
899
900 if (isErrorIn(69)) {
902 return;
903 }
904
905 if (isErrorIn(39)) dhe_id = 0; // mess up dhe_id in DHP header
906 if (isErrorIn(40)) chip_id = ~chip_id; // mess up chip id
907 header = (EDHPFrameHeaderDataType::c_ZSD << 29) | ((dhe_id & 0x3F) << 18) | ((chip_id & 0x03) << 16) |
908 (m_trigger_dhp_framenr & 0xFFFF);
909 if (isErrorIn(68)) header++;
910 append_int32(header);
911 if (isErrorIn(66)) append_int32(header + 1); // with inc trigger nr
912
913 if (isErrorIn(41) or isErrorIn(42)) {
914 halfladder_pixmap[PACKER_NUM_ROWS - 1][PACKER_NUM_COLS - 1] = 0x42; // make sure we have a hit
915 }
916 for (int row = 0; row < PACKER_NUM_ROWS; row++) { // should be variable
917 bool rowstart;
918 if (isErrorIn(43) && !error_done) rowstart = false;
919 else rowstart = true;
920 int c1, c2;
921 c1 = 64 * chip_id;
922 c2 = c1 + 64;
923 if (c2 >= PACKER_NUM_COLS) c2 = PACKER_NUM_COLS;
924 for (int col = c1; col < c2; col++) {
925 if (halfladder_pixmap[row][col] != 0) {
926 unsigned char charge;
927 charge = halfladder_pixmap[row][col] & 0xFF; // before we make overflow error
928 if (isErrorIn(41) and row == PACKER_NUM_ROWS - 1 and col == PACKER_NUM_COLS - 1 and !error_done) {
929 row = PACKER_NUM_ROWS;
930 rowstart = true; // force a new row
931 error_done = true;
932 }
933 if (isErrorIn(42) and row == PACKER_NUM_ROWS - 1 and col == PACKER_NUM_COLS - 1 and !error_done) {
934 col = PACKER_NUM_COLS; // masked out to modulo 64 anway
935 error_done = true;
936 }
937 if (rowstart) {
938 last_rowstart = ((row & 0x3FE) << (6 - 1)) | 0; // plus common mode 6 bits ... set to 0
939 append_int16(last_rowstart);
940 rowstart = false;
941 }
942 int colout = col;
943 if (!isErrorIn(52)) append_int16(0x8000 | ((row & 0x1) << 14) | ((colout & 0x3F) << 8) | charge);
944 empty = false;
945 }
946 }
947 }
948 if (!empty && (m_current_frame.size() & 0x3)) {
949 B2DEBUG(27, "Repeat last rowstart to align to 32bit.");
950 append_int16(last_rowstart);
951 }
952
953
954 if (empty) {
955 B2DEBUG(27, "Found no data for halfladder! DHEID: " << dhe_id << " Chip: " << chip_id);
956 // we DROP the frame, thus we have to correct DHE and DHC counters
957 dhc_byte_count -= 8; // fixed size of Header
958 dhe_byte_count -= 8; // fixed size of Header
959 start_frame();
961 append_int32((EDHCFrameHeaderDataType::c_GHOST << 27) | ((dhe_id & 0x3F) << 20) | ((chip_id & 0x03) << 16) |
962 (m_trigger_nr & 0xFFFF));
963 } else {
964 //B2DEBUG(20,"Found data for halfladder DHEID: " << dhe_id << " Chip: " << chip_id);
965 }
967
968}
969
971{
972 if (m_real_trigger_nr == enr) return true; // oder modulo, oder oder
973 return false;
974}
@ c_ErrorIfAlreadyRegistered
If the object/array was already registered, produce an error (aborting initialisation).
Definition: DataStore.h:72
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
void do_the_reverse_mapping(unsigned int &row, unsigned int &col, unsigned short layer, unsigned short sensor)
function still to be implemented
std::vector< std::vector< unsigned char > > m_onsen_payload
For one DHC event, we utilize one payload for all DHE/DHP frames.
void initialize() override final
Initialize the module.
bool m_Check
false=Pack Raw Data, true=Check unpacked result
void add_frame_to_payload(void)
Add Frame to Event payload.
unsigned short m_run_nr_word2
Exp+Run Nr.
std::string m_PXDDAQEvtStatsName
The name of the StoreObjPtr of PXDDAQStatus to be read.
void append_int16(unsigned short w)
cat 16bit value to frame
StoreObjPtr< PXDDAQStatus > m_daqStatus
Output array for RawPxds.
void pack_dhe(int dhe_id, int dhp_mask)
Pack one DHE (several DHP) to buffer.
bool m_found_fatal
flag if we found one test failing
void pack_dhp_raw(int dhp_id, int dhe_id)
Pack one DHP RAW to buffer.
std::string m_RawPXDsName
The name of the StoreArray of generated RawPXDs.
bool CheckErrorMaskInEvent(unsigned int eventnr, PXDError::PXDErrorFlags mask)
void pack_event(void)
Pack one event (several DHC) stored in seperate RawPXD object.
void terminate() override final
Terminate the module.
void event() override final
do the packing
PXDPackerErrModule()
Constructor defining the parameters.
unsigned int dhc_byte_count
Byte count in current DHC package.
std::vector< std::vector< int > > m_dhe_to_dhc
Parameter dhc<->dhe list, mapping from steering file.
bool m_Clusterize
Use clusterizer (FCE format)
unsigned short m_run_nr_word1
Run+Subrun Nr.
bool isErrorIn(uint32_t enr)
Check if we want this type of error in this event.
std::vector< unsigned int > m_onsen_header
For one DHC event, we utilize one header (writing out, beware of endianess!)
unsigned int m_real_trigger_nr
Real Trigger Nr.
void append_int32(unsigned int w)
cat 32value value to frame
StoreArray< RawPXD > m_storeRaws
Output array for RawPxds.
unsigned int m_trigger_dhp_framenr
DHP Readout Frame Nr for DHP and DHE headers.
unsigned int dhe_byte_count
Byte count in current DHE package.
static std::vector< PXDErrorFlags > m_errors
The pxd error flags.
void pack_dhp(int dhp_id, int dhe_id, int dhe_reformat)
Pack one DHP to buffer.
std::map< int, std::vector< int > > m_dhc_mapto_dhe
mapping calculated from m_dhe_to_dhc for easier handling
void start_frame(void)
Start with a new Frame.
void append_int8(unsigned char w)
cat 8bit value to frame
unsigned int m_trigger_dhe_gate
DHE Trigger Gate for DHE headers.
unsigned int m_packed_events
Event counter.
bool m_InvertMapping
Flag if we invert mapping to DHP row/col or use premapped coordinates.
unsigned long long int m_meta_time
Time(Tag) from MetaInfo.
std::vector< unsigned char > m_current_frame
For current processed frames.
unsigned char halfladder_pixmap[PACKER_NUM_ROWS][PACKER_NUM_COLS]
temporary hitmap buffer for pixel to raw data conversion
unsigned int m_trigger_nr
Trigger Nr.
void pack_dhc(int dhc_id, int dhe_mask, int *dhe_ids, bool send_all=true, bool send_roi=false)
Pack one DHC (several DHE) stored in one RawPXD object.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
boost::crc_optimal< 32, 0x04C11DB7, 0, 0, false, false > dhc_crc_32_type
define our CRC function
Abstract base class for different kinds of events.
STL namespace.