Belle II Software development
PXDRawDataStructs.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/PXDRawDataStructs.h>
10#include <pxd/unpacking/PXDRawDataDefinitions.h>
11#include <framework/logging/Logger.h>
12
13#include <boost/crc.hpp>
14
15
19
20namespace Belle2 {
26 namespace PXD {
27
29 typedef boost::crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhc_crc_32_type;
30
31 using ubig16_t = boost::endian::big_uint16_t;
32 using ubig32_t = boost::endian::big_uint32_t;
33 using namespace Belle2::PXD::PXDError;
35
37 {
38 const char* dhc_type_name[16] = {
39 (const char*)"DHP_RAW",
40 (const char*)"FCE_RAW",
41 (const char*)"GHOST ",
42 (const char*)"H_START",
43 (const char*)"H_END ",
44 (const char*)"DHP_ZSD",
45 (const char*)"COMMODE",
46 (const char*)"undef ",
47 (const char*)"undef ",
48 (const char*)"ONS_FCE",
49 (const char*)"undef ",
50 (const char*)"C_START",
51 (const char*)"C_END ",
52 (const char*)"ONS_DHP",
53 (const char*)"ONS_TRG",
54 (const char*)"ONS_ROI"
55 };
56 B2DEBUG(99, "DHC FRAME TYP $" << std::hex << getFrameType() << " -> " << dhc_type_name[getFrameType()] << " (ERR " << getErrorFlag()
57 << ") data " << data);
58 };
59
61 {
62 if (word0.data != 0x5800) return false;
63 if (trigger_nr_lo != 0) return false;
64 if (trigger_nr_hi != 0) return false;
65 if (time_tag_lo_and_type != 0) return false;
66 if (time_tag_mid != 0) return false;
67 if (time_tag_hi != 0) return false;
68 if (run_subrun != 0) return false;
69 if (exp_run != 0) return false;
70 if (crc32 != 0x4829214d) return false;
71 return true;
72 };
73
74 void dhc_start_frame::print(void) const
75 {
76 word0.print();
77 B2DEBUG(99, "DHC Start Frame TNRLO $" << std::hex << trigger_nr_lo << " TNRHI $" << std::hex << trigger_nr_hi << " TTLO $" <<
78 std::hex <<
80 << " TTMID $" << std::hex << time_tag_mid << " TTHI $" << std::hex << time_tag_hi << " Exp/Run/Subrun $" << std::hex << exp_run <<
81 " $" <<
83 << " CRC $" << std::hex << crc32);
84 };
85
87 {
88 word0.print();
89 B2DEBUG(99, "DHC Event Frame TNRLO $" << std::hex << trigger_nr_lo << " DTTLO $" << std::hex << dhe_time_tag_lo << " DTTHI $" <<
90 std::hex <<
92 << " DHEID $" << std::hex << getDHEId()
93 << " DHPMASK $" << std::hex << getActiveDHPMask()
94 << " SFNR $" << std::hex << getStartFrameNr()
95 << " OFF $" << std::hex << getTriggerGate()
96 << " CRC " << std::hex << crc32);
97 };
98
100 {
101 word0.print();
102 B2DEBUG(99, "DHC Direct Readout (Raw|ZSD|ONS) Frame TNRLO $" << std::hex << trigger_nr_lo << " DHE ID $" << getDHEId() <<
103 " DHP port $" << getDHPPort());
104 };
105
107 {
108 word0.print();
109 B2DEBUG(99, "ONSEN Trigger Frame TNRLO $" << std::hex << trignr0);
110 };
111
112 void dhc_onsen_trigger_frame::check_error(PXDErrorFlags& errorMask, bool ignore_datcon_flag,
113 bool ignore_hltroi_magic_flag,
114 bool ignore_merger_mm_flag) const
115 {
116 if ((magic1 & 0xFFFF0000) != 0xCAFE0000) {
117 if (!ignore_hltroi_magic_flag) B2WARNING("ONSEN Trigger Magic 1 error $" << std::hex << magic1);
118 errorMask[c_nrHLTROI_MAGIC] = true;
119 }
120 if ((magic2 & 0xFFFF0000) != 0xCAFE0000) {
121 if (!ignore_hltroi_magic_flag) B2WARNING("ONSEN Trigger Magic 2 error $" << std::hex << magic2);
122 errorMask[c_nrHLTROI_MAGIC] = true;
123 }
124 if (is_fake_datcon()) {
125 if (!ignore_datcon_flag) B2INFO("ONSEN Trigger Frame: No DATCON data $" << std::hex << trignr1 << "!=$" << trignr2);
126 errorMask[c_nrNO_DATCON] = true;
127 } else {
128 if (trignr1 != trignr2) {
129 if (!ignore_merger_mm_flag) B2WARNING("ONSEN Trigger Frame Trigger Nr Mismatch $" << std::hex << trignr1 << "!=$" << trignr2);
130 errorMask[c_nrMERGER_TRIGNR] = true;
131 }
132 }
133 };
134
135 void dhc_onsen_roi_frame::check_error(PXDErrorFlags& errorMask, int length, bool ignore_inv_size_flag) const
136 {
137 // 4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
138 if (length < getMinSize()) {
139 if (!ignore_inv_size_flag) B2WARNING("DHC ONSEN HLT/ROI Frame too small to hold any ROIs!");
140 errorMask[c_nrROI_PACKET_INV_SIZE] = true;
141 } else if ((length - getMinSize()) % 8 != 0) {
142 if (!ignore_inv_size_flag) B2WARNING("DHC ONSEN HLT/ROI Frame holds fractional ROIs, last ROI might not be saved!");
143 errorMask[c_nrROI_PACKET_INV_SIZE] = true;
144 }
145 };
147 {
148 word0.print();
149 B2DEBUG(99, "DHC HLT/ROI Frame");
150 };
151
152 void dhc_ghost_frame::print(void) const
153 {
154 word0.print();
155 B2DEBUG(99, "DHC Ghost Frame TNRLO $" << std::hex << trigger_nr_lo << " DHE ID $" << getDHEId() << " DHP port $" << getDHPPort() <<
156 " CRC $");
157 };
158
159 unsigned short dhc_ghost_frame::getErrorBits(void) const
160 {
161 unsigned short value = (word0.data & 0xC) >> 2; // lower two bits
162 if (word0.data & 0x0400) value |= 0x4; // high bit
163 return value;
164 };
165
167 {
168 if (word0.data != 0x6000) return false;
169 if (trigger_nr_lo != 0) return false;
170 if (wordsinevent != 0) return false;
171 if (errorinfo != 0) return false;
172 if (crc32 != 0xF7BCA507) return false;
173 return true;
174 };
175 void dhc_end_frame::print(void) const
176 {
177 word0.print();
178 B2DEBUG(99, "DHC End Frame TNRLO $" << std::hex << trigger_nr_lo << " WIEVT $" << std::hex << wordsinevent << " ERR $" << std::hex
179 << errorinfo << " CRC " << std::hex << crc32);
180 };
181
182
184 {
185 word0.print();
186 B2DEBUG(99, "DHC DHE End Frame TNRLO $" << std::hex << trigger_nr_lo << " WIEVT $" << std::hex << wordsineventhi << "." <<
187 wordsineventlo << " ERR $" << std::hex << errorinfo << " CRC " << std::hex << crc32);
188 };
189
190 unsigned int dhc_dhe_end_frame::getErrorStateMachineDHP(int dhpid) const
191 {
192 switch (dhpid) {
193 case 0: return ((uint32_t)errorinfo >> 24) & 0xFF;
194 case 1: return ((uint32_t)errorinfo >> 16) & 0xFF;
195 case 2: return ((uint32_t)errorinfo >> 8) & 0xFF;
196 case 3: return errorinfo & 0xFF;
197 default: return 0;
198 }
199 };
200
202 {
203 switch (dhpid) {
204 case 0: return ((uint32_t)errorinfo >> 24) & 0xF;
205 case 1: return ((uint32_t)errorinfo >> 16) & 0xF;
206 case 2: return ((uint32_t)errorinfo >> 8) & 0xF;
207 case 3: return errorinfo & 0xF;
208 default: return 0;
209 }
210 };
211
213 {
214 switch (dhpid) {
215 case 0: return ((uint32_t)errorinfo >> 28) & 0xF;
216 case 1: return ((uint32_t)errorinfo >> 20) & 0xF;
217 case 2: return ((uint32_t)errorinfo >> 12) & 0xF;
218 case 3: return ((uint32_t)errorinfo >> 4) & 0xF;
219 default: return 0;
220 }
221 };
222
223 void dhc_frames::check_padding(PXDErrorFlags& errorMask)
224 {
225 unsigned int crc = *(ubig32_t*)(((unsigned char*)data) + length - 4);
226 if ((crc & 0xFFFF0000) == 0 || (crc & 0xFFFF) == 0) {
228 B2INFO("Suspicious Padding $" << std::hex << crc);
229 errorMask[c_nrSUSP_PADDING] = true;
230 }
231 };
232
233 void dhc_frames::check_crc(PXDErrorFlags& errorMask, bool ignore_crc_flag)
234 {
235 dhc_crc_32_type bocrc;
236
237 if (length > 65536 * 16) {
238 if (!ignore_crc_flag) B2WARNING("DHC Data Frame CRC not calculated because of too large packet (>1MB)!");
239 return; // such large packets should trigger an error elsewhere
240 } else {
241 bocrc.process_bytes(data, length - 4);
242 }
243 unsigned int c;
244 c = bocrc.checksum();
245
246 ubig32_t crc32;
247 crc32 = *(ubig32_t*)(((unsigned char*)data) + length - 4);
248
249 if (c != crc32) {
250 if (!ignore_crc_flag) {
251 B2WARNING("DHC Data Frame CRC FAIL");
252 B2DEBUG(1, "DHC Data Frame CRC FAIL: " << std::hex << c << "!=" << crc32 << " data "
253 << * (unsigned int*)(((unsigned char*)data) + length - 8) << " "
254 << * (unsigned int*)(((unsigned char*)data) + length - 6) << " "
255 << * (unsigned int*)(((unsigned char*)data) + length - 4) << " len $" << length);
256 }
257 errorMask[c_nrDHE_CRC] = true;
258 }
259 };
260
261
262 unsigned int dhc_frames::getFixedSize(void)
263 {
264 unsigned int s = 0;
265 switch (getFrameType()) {
266 case EDHCFrameHeaderDataType::c_DHP_RAW:
267 s = 0;
268 break;
269 case EDHCFrameHeaderDataType::c_ONSEN_DHP:
270 case EDHCFrameHeaderDataType::c_DHP_ZSD:
271 s = 0;
272 break;
273 case EDHCFrameHeaderDataType::c_ONSEN_FCE:
274 case EDHCFrameHeaderDataType::c_FCE_RAW:
275 s = 0;
276 break;
277 case EDHCFrameHeaderDataType::c_COMMODE:
279 break;
280 case EDHCFrameHeaderDataType::c_GHOST:
282 break;
283 case EDHCFrameHeaderDataType::c_DHE_START:
285 break;
286 case EDHCFrameHeaderDataType::c_DHE_END:
288 break;
289 case EDHCFrameHeaderDataType::c_DHC_START:
291 break;
292 case EDHCFrameHeaderDataType::c_DHC_END:
294 break;
295 case EDHCFrameHeaderDataType::c_ONSEN_ROI:
296 s = 0;
297 break;
298 case EDHCFrameHeaderDataType::c_ONSEN_TRG:
300 break;
301 default:
302 B2INFO("Error: not a valid data frame!");
303 // Error will be set elsewhere in another check
304 s = 0;
305 break;
306 }
307 datasize = s;
308 return s;
309 };
310
311 };
313};
const dhc_ghost_frame * data_ghost_frame
data_ghost_frame
const dhc_end_frame * data_dhc_end_frame
data_dhc_end_frame
const void * data
no type
unsigned int getFixedSize(void)
get fixed size
int getFrameType(void)
get type of frame
const dhc_dhe_start_frame * data_dhe_start_frame
data_dhe_start_frame
const dhc_start_frame * data_dhc_start_frame
data_dhc_start_frame
const dhc_dhe_end_frame * data_dhe_end_frame
data_dhe_end_frame
void check_padding(PXDErrorFlags &errormask)
check padding and return it
const dhc_commode_frame * data_commode_frame
data_commode_frame
void check_crc(PXDErrorFlags &errormask, bool ignore_crc_flag=false)
check crc and return it
unsigned int datasize
datasize
const dhc_onsen_trigger_frame * data_onsen_trigger_frame
data_onsen_trigger_frame
EDHCFrameHeaderDataType
Enums for DHC data frame types.
boost::endian::big_uint32_t ubig32_t
define alias ubig32_t
boost::crc_optimal< 32, 0x04C11DB7, 0, 0, false, false > dhc_crc_32_type
define our CRC function
boost::endian::big_uint16_t ubig16_t
define alias ubig16_t
Abstract base class for different kinds of events.
unsigned int getFixedSize(void) const
100 words
const dhc_frame_header_word0 word0
word0
unsigned int getFixedSize(void) const
get fixed size
const unsigned int crc32
crc32
const ubig16_t trigger_nr_lo
trigger_nr_lo
unsigned int getErrorStateMachineStartDHP(int dhpid) const
get error state machine start DHP
const ubig16_t wordsineventhi
wordsineventhi
unsigned int getErrorStateMachineDHP(int dhpid) const
get error state machine DHP
const ubig16_t wordsineventlo
words swapped... because of DHE 16 bit handling
unsigned int getErrorStateMachineEndDHP(int dhpid) const
get error state machine end DHP
const ubig32_t errorinfo
not well defined yet
const ubig16_t dhe_time_tag_hi
dhe_time_tag_hi
const dhc_frame_header_word0 word0
word0
const ubig16_t dhe_time_tag_lo
dhe_time_tag_lo
unsigned int getFixedSize(void) const
8 words
const ubig16_t trigger_nr_lo
trigger_nr_lo
unsigned int getDHEId(void) const
get DHE Id (from word0)
unsigned short getTriggerGate(void) const
trigger gate (updated to 8 bit, before 10!)
unsigned short getStartFrameNr(void) const
last DHP frame before trigger
unsigned int getActiveDHPMask(void) const
get Active DHP Mask (from word0)
const dhc_frame_header_word0 word0
word0
const ubig16_t trigger_nr_lo
trigger_nr_lo
unsigned short getDHEId(void) const
get DHE Id (from word0)
unsigned short getDHPPort(void) const
get DHP Port (from word0)
void print(void) const
print
const dhc_frame_header_word0 word0
word0
unsigned int getFixedSize(void) const
get fixed size
const unsigned int crc32
crc32
const ubig16_t trigger_nr_lo
trigger_nr_lo
bool isFakedData(void) const
is faked data
const ubig32_t wordsinevent
wordsinevent
const ubig32_t errorinfo
errorinfo
unsigned short getFrameType(void) const
get type of frame
unsigned short getErrorFlag(void) const
get error flag
const dhc_frame_header_word0 word0
word0
unsigned int getFixedSize(void) const
fixed length
const ubig16_t trigger_nr_lo
trigger_nr_lo
unsigned short getErrorBits(void) const
get Error Bits
unsigned short getDHEId(void) const
get DHE Id (from word0)
unsigned short getDHPPort(void) const
get DDHP port (from word0)
const dhc_frame_header_word0 word0
mainly empty
void check_error(PXDErrorFlags &errormask, int length, bool ignore_inv_size_flag=false) const
check error and return error mask
int getMinSize(void) const
4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
const dhc_frame_header_word0 word0
word0
unsigned int getFixedSize(void) const
8*4 bytes might still be changed
const ubig32_t trignr2
redundant, DATCON Trigger/Tag part 1
const ubig32_t magic1
CAFExxxx , redundant.
void check_error(PXDErrorFlags &errormask, bool ignore_datcon_flag=false, bool ignore_hltroi_magic_flag=false, bool ignore_merger_mm_flag=false) const
check error and return error mask
const ubig32_t trignr1
HLT Trigger/Tag part 1.
bool is_fake_datcon(void) const
is fake datcon
const ubig32_t magic2
CAFExxxx, redundant.
void print(void) const
print
const ubig16_t trigger_nr_hi
trigger_nr_hi
const dhc_frame_header_word0 word0
word0
unsigned int getFixedSize(void) const
get fixed size (byte)
const ubig16_t exp_run
exp_run
const unsigned int crc32
crc32
const ubig16_t trigger_nr_lo
trigger_nr_lo
const ubig16_t time_tag_hi
time_tag_hi
const ubig16_t time_tag_mid
time_tag_mid
bool isFakedData(void) const
isFakedData
const ubig16_t run_subrun
run_subrun
const ubig16_t time_tag_lo_and_type
time_tag_lo_and_type