Belle II Software  release-08-01-10
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  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 <<
79  time_tag_lo_and_type
80  << " TTMID $" << std::hex << time_tag_mid << " TTHI $" << std::hex << time_tag_hi << " Exp/Run/Subrun $" << std::hex << exp_run <<
81  " $" <<
82  run_subrun
83  << " CRC $" << std::hex << crc32);
84  };
85 
86  void dhc_dhe_start_frame::print(void) const
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 <<
91  dhe_time_tag_hi
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  };
146  void dhc_onsen_roi_frame::print(void) const
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 
166  bool dhc_end_frame::isFakedData(void) const
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 
183  void dhc_dhe_end_frame::print(void) const
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 
212  unsigned int dhc_dhe_end_frame::getErrorStateMachineEndDHP(int dhpid) const
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:
278  s = data_commode_frame->getFixedSize();
279  break;
280  case EDHCFrameHeaderDataType::c_GHOST:
281  s = data_ghost_frame->getFixedSize();
282  break;
283  case EDHCFrameHeaderDataType::c_DHE_START:
284  s = data_dhe_start_frame->getFixedSize();
285  break;
286  case EDHCFrameHeaderDataType::c_DHE_END:
287  s = data_dhe_end_frame->getFixedSize();
288  break;
289  case EDHCFrameHeaderDataType::c_DHC_START:
290  s = data_dhc_start_frame->getFixedSize();
291  break;
292  case EDHCFrameHeaderDataType::c_DHC_END:
293  s = data_dhc_end_frame->getFixedSize();
294  break;
295  case EDHCFrameHeaderDataType::c_ONSEN_ROI:
296  s = 0;
297  break;
298  case EDHCFrameHeaderDataType::c_ONSEN_TRG:
299  s = data_onsen_trigger_frame->getFixedSize();
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 };
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