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