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 {
25
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 // only used in the B2DEBUG below, which expands to a conditional block
39 // cppcheck-suppress variableScope
40 const char* dhc_type_name[16] = {
41 "DHP_RAW",
42 "FCE_RAW",
43 "GHOST ",
44 "H_START",
45 "H_END ",
46 "DHP_ZSD",
47 "COMMODE",
48 "undef ",
49 "undef ",
50 "ONS_FCE",
51 "undef ",
52 "C_START",
53 "C_END ",
54 "ONS_DHP",
55 "ONS_TRG",
56 "ONS_ROI"
57 };
58 B2DEBUG(99, "DHC FRAME TYP $" << std::hex << getFrameType() << " -> " << dhc_type_name[getFrameType()] << " (ERR " << getErrorFlag()
59 << ") data " << data);
60 };
61
63 {
64 if (word0.data != 0x5800) return false;
65 if (trigger_nr_lo != 0) return false;
66 if (trigger_nr_hi != 0) return false;
67 if (time_tag_lo_and_type != 0) return false;
68 if (time_tag_mid != 0) return false;
69 if (time_tag_hi != 0) return false;
70 if (run_subrun != 0) return false;
71 if (exp_run != 0) return false;
72 if (crc32 != 0x4829214d) return false;
73 return true;
74 };
75
76 void dhc_start_frame::print(void) const
77 {
78 word0.print();
79 B2DEBUG(99, "DHC Start Frame TNRLO $" << std::hex << trigger_nr_lo << " TNRHI $" << std::hex << trigger_nr_hi << " TTLO $" <<
80 std::hex <<
82 << " TTMID $" << std::hex << time_tag_mid << " TTHI $" << std::hex << time_tag_hi << " Exp/Run/Subrun $" << std::hex << exp_run <<
83 " $" <<
85 << " CRC $" << std::hex << crc32);
86 };
87
89 {
90 word0.print();
91 B2DEBUG(99, "DHC Event Frame TNRLO $" << std::hex << trigger_nr_lo << " DTTLO $" << std::hex << dhe_time_tag_lo << " DTTHI $" <<
92 std::hex <<
94 << " DHEID $" << std::hex << getDHEId()
95 << " DHPMASK $" << std::hex << getActiveDHPMask()
96 << " SFNR $" << std::hex << getStartFrameNr()
97 << " OFF $" << std::hex << getTriggerGate()
98 << " CRC " << std::hex << crc32);
99 };
100
102 {
103 word0.print();
104 B2DEBUG(99, "DHC Direct Readout (Raw|ZSD|ONS) Frame TNRLO $" << std::hex << trigger_nr_lo << " DHE ID $" << getDHEId() <<
105 " DHP port $" << getDHPPort());
106 };
107
109 {
110 word0.print();
111 B2DEBUG(99, "ONSEN Trigger Frame TNRLO $" << std::hex << trignr0);
112 };
113
114 void dhc_onsen_trigger_frame::check_error(PXDErrorFlags& errorMask, bool ignore_datcon_flag,
115 bool ignore_hltroi_magic_flag,
116 bool ignore_merger_mm_flag) const
117 {
118 if ((magic1 & 0xFFFF0000) != 0xCAFE0000) {
119 if (!ignore_hltroi_magic_flag) B2WARNING("ONSEN Trigger Magic 1 error $" << std::hex << magic1);
120 errorMask[c_nrHLTROI_MAGIC] = true;
121 }
122 if ((magic2 & 0xFFFF0000) != 0xCAFE0000) {
123 if (!ignore_hltroi_magic_flag) B2WARNING("ONSEN Trigger Magic 2 error $" << std::hex << magic2);
124 errorMask[c_nrHLTROI_MAGIC] = true;
125 }
126 if (is_fake_datcon()) {
127 if (!ignore_datcon_flag) B2INFO("ONSEN Trigger Frame: No DATCON data $" << std::hex << trignr1 << "!=$" << trignr2);
128 errorMask[c_nrNO_DATCON] = true;
129 } else {
130 if (trignr1 != trignr2) {
131 if (!ignore_merger_mm_flag) B2WARNING("ONSEN Trigger Frame Trigger Nr Mismatch $" << std::hex << trignr1 << "!=$" << trignr2);
132 errorMask[c_nrMERGER_TRIGNR] = true;
133 }
134 }
135 };
136
137 void dhc_onsen_roi_frame::check_error(PXDErrorFlags& errorMask, int length, bool ignore_inv_size_flag)
138 {
139 // 4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
140 if (length < getMinSize()) {
141 if (!ignore_inv_size_flag) B2WARNING("DHC ONSEN HLT/ROI Frame too small to hold any ROIs!");
142 errorMask[c_nrROI_PACKET_INV_SIZE] = true;
143 } else if ((length - getMinSize()) % 8 != 0) {
144 if (!ignore_inv_size_flag) B2WARNING("DHC ONSEN HLT/ROI Frame holds fractional ROIs, last ROI might not be saved!");
145 errorMask[c_nrROI_PACKET_INV_SIZE] = true;
146 }
147 };
149 {
150 word0.print();
151 B2DEBUG(99, "DHC HLT/ROI Frame");
152 };
153
154 void dhc_ghost_frame::print(void) const
155 {
156 word0.print();
157 B2DEBUG(99, "DHC Ghost Frame TNRLO $" << std::hex << trigger_nr_lo << " DHE ID $" << getDHEId() << " DHP port $" << getDHPPort() <<
158 " CRC $");
159 };
160
161 unsigned short dhc_ghost_frame::getErrorBits(void) const
162 {
163 unsigned short value = (word0.data & 0xC) >> 2; // lower two bits
164 if (word0.data & 0x0400) value |= 0x4; // high bit
165 return value;
166 };
167
169 {
170 if (word0.data != 0x6000) return false;
171 if (trigger_nr_lo != 0) return false;
172 if (wordsinevent != 0) return false;
173 if (errorinfo != 0) return false;
174 if (crc32 != 0xF7BCA507) return false;
175 return true;
176 };
177 void dhc_end_frame::print(void) const
178 {
179 word0.print();
180 B2DEBUG(99, "DHC End Frame TNRLO $" << std::hex << trigger_nr_lo << " WIEVT $" << std::hex << wordsinevent << " ERR $" << std::hex
181 << errorinfo << " CRC " << std::hex << crc32);
182 };
183
184
186 {
187 word0.print();
188 B2DEBUG(99, "DHC DHE End Frame TNRLO $" << std::hex << trigger_nr_lo << " WIEVT $" << std::hex << wordsineventhi << "." <<
189 wordsineventlo << " ERR $" << std::hex << errorinfo << " CRC " << std::hex << crc32);
190 };
191
192 unsigned int dhc_dhe_end_frame::getErrorStateMachineDHP(int dhpid) const
193 {
194 switch (dhpid) {
195 case 0: return ((uint32_t)errorinfo >> 24) & 0xFF;
196 case 1: return ((uint32_t)errorinfo >> 16) & 0xFF;
197 case 2: return ((uint32_t)errorinfo >> 8) & 0xFF;
198 case 3: return errorinfo & 0xFF;
199 default: return 0;
200 }
201 };
202
204 {
205 switch (dhpid) {
206 case 0: return ((uint32_t)errorinfo >> 24) & 0xF;
207 case 1: return ((uint32_t)errorinfo >> 16) & 0xF;
208 case 2: return ((uint32_t)errorinfo >> 8) & 0xF;
209 case 3: return errorinfo & 0xF;
210 default: return 0;
211 }
212 };
213
215 {
216 switch (dhpid) {
217 case 0: return ((uint32_t)errorinfo >> 28) & 0xF;
218 case 1: return ((uint32_t)errorinfo >> 20) & 0xF;
219 case 2: return ((uint32_t)errorinfo >> 12) & 0xF;
220 case 3: return ((uint32_t)errorinfo >> 4) & 0xF;
221 default: return 0;
222 }
223 };
224
225 void dhc_frames::check_padding(PXDErrorFlags& errorMask)
226 {
227 unsigned int crc = *reinterpret_cast<const ubig32_t*>(((reinterpret_cast<const unsigned char*>(data)) + length - 4));
228 if ((crc & 0xFFFF0000) == 0 || (crc & 0xFFFF) == 0) {
230 B2INFO("Suspicious Padding $" << std::hex << crc);
231 errorMask[c_nrSUSP_PADDING] = true;
232 }
233 };
234
235 void dhc_frames::check_crc(PXDErrorFlags& errorMask, bool ignore_crc_flag)
236 {
237 dhc_crc_32_type bocrc;
238
239 if (length > 65536 * 16) {
240 if (!ignore_crc_flag) B2WARNING("DHC Data Frame CRC not calculated because of too large packet (>1MB)!");
241 return; // such large packets should trigger an error elsewhere
242 } else {
243 bocrc.process_bytes(data, length - 4);
244 }
245 unsigned int c;
246 c = bocrc.checksum();
247
248 ubig32_t crc32;
249 crc32 = *reinterpret_cast<const ubig32_t*>(((reinterpret_cast<const unsigned char*>(data)) + length - 4));
250
251 if (c != crc32) {
252 if (!ignore_crc_flag) {
253 B2WARNING("DHC Data Frame CRC FAIL");
254 B2DEBUG(1, "DHC Data Frame CRC FAIL: " << std::hex << c << "!=" << crc32 << " data "
255 << *reinterpret_cast<const unsigned int*>((reinterpret_cast<const unsigned char*>(data)) + length - 8) << " "
256 << *reinterpret_cast<const unsigned int*>((reinterpret_cast<const unsigned char*>(data)) + length - 6) << " "
257 << *reinterpret_cast<const unsigned int*>((reinterpret_cast<const unsigned char*>(data)) + length - 4) << " len $" << length);
258 }
259 errorMask[c_nrDHE_CRC] = true;
260 }
261 };
262
263
264 unsigned int dhc_frames::getFixedSize(void)
265 {
266 unsigned int s = 0;
267 switch (getFrameType()) {
268 case EDHCFrameHeaderDataType::c_DHP_RAW:
269 s = 0;
270 break;
271 case EDHCFrameHeaderDataType::c_ONSEN_DHP:
272 case EDHCFrameHeaderDataType::c_DHP_ZSD:
273 s = 0;
274 break;
275 case EDHCFrameHeaderDataType::c_ONSEN_FCE:
276 case EDHCFrameHeaderDataType::c_FCE_RAW:
277 s = 0;
278 break;
279 case EDHCFrameHeaderDataType::c_COMMODE:
280 s = data_commode_frame->getFixedSize();
281 break;
282 case EDHCFrameHeaderDataType::c_GHOST:
283 s = data_ghost_frame->getFixedSize();
284 break;
285 case EDHCFrameHeaderDataType::c_DHE_START:
286 s = data_dhe_start_frame->getFixedSize();
287 break;
288 case EDHCFrameHeaderDataType::c_DHE_END:
289 s = data_dhe_end_frame->getFixedSize();
290 break;
291 case EDHCFrameHeaderDataType::c_DHC_START:
292 s = data_dhc_start_frame->getFixedSize();
293 break;
294 case EDHCFrameHeaderDataType::c_DHC_END:
295 s = data_dhc_end_frame->getFixedSize();
296 break;
297 case EDHCFrameHeaderDataType::c_ONSEN_ROI:
298 s = 0;
299 break;
300 case EDHCFrameHeaderDataType::c_ONSEN_TRG:
301 s = data_onsen_trigger_frame->getFixedSize();
302 break;
303 default:
304 B2INFO("Error: not a valid data frame!");
305 // Error will be set elsewhere in another check
306 s = 0;
307 break;
308 }
309 datasize = s;
310 return s;
311 };
312
313 };
315};
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
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
boost::endian::big_uint16_t ubig16_t
define alias ubig16_t
EDHCFrameHeaderDataType
Enums for DHC data frame types.
boost::crc_optimal< 32, 0x04C11DB7, 0, 0, false, false > dhc_crc_32_type
define our CRC function
boost::endian::big_uint32_t ubig32_t
define alias ubig32_t
Abstract base class for different kinds of events.
const dhc_frame_header_word0 word0
word0
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
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
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
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
static int getMinSize(void)
4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
static void check_error(PXDErrorFlags &errormask, int length, bool ignore_inv_size_flag=false)
check error and return error mask
const dhc_frame_header_word0 word0
word0
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.
const ubig16_t trigger_nr_hi
trigger_nr_hi
const dhc_frame_header_word0 word0
word0
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