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