Belle II Software  release-05-01-25
PXDRawDataStructs.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2017 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Bjoern Spruck *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <pxd/unpacking/PXDRawDataStructs.h>
12 #include <pxd/unpacking/PXDRawDataDefinitions.h>
13 #include <framework/logging/Logger.h>
14 
15 #include <boost/crc.hpp>
16 
17 
21 
22 namespace Belle2 {
28  namespace PXD {
29 
31  typedef boost::crc_optimal<32, 0x04C11DB7, 0, 0, false, false> dhc_crc_32_type;
32 
33  using boost::spirit::endian::ubig16_t;
34  using boost::spirit::endian::ubig32_t;
35  using namespace Belle2::PXD::PXDError;
37 
38  void dhc_frame_header_word0::print(void) const
39  {
40  const char* dhc_type_name[16] = {
41  (const char*)"DHP_RAW",
42  (const char*)"FCE_RAW",
43  (const char*)"GHOST ",
44  (const char*)"H_START",
45  (const char*)"H_END ",
46  (const char*)"DHP_ZSD",
47  (const char*)"COMMODE",
48  (const char*)"undef ",
49  (const char*)"undef ",
50  (const char*)"ONS_FCE",
51  (const char*)"undef ",
52  (const char*)"C_START",
53  (const char*)"C_END ",
54  (const char*)"ONS_DHP",
55  (const char*)"ONS_TRG",
56  (const char*)"ONS_ROI"
57  };
58  B2DEBUG(99, "DHC FRAME TYP $" << std::hex << getFrameType() << " -> " << dhc_type_name[getFrameType()] << " (ERR " << getErrorFlag()
59  << ") data " << data);
60  };
61 
62  bool dhc_start_frame::isFakedData(void) const
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 <<
81  time_tag_lo_and_type
82  << " TTMID $" << std::hex << time_tag_mid << " TTHI $" << std::hex << time_tag_hi << " Exp/Run/Subrun $" << std::hex << exp_run <<
83  " $" <<
84  run_subrun
85  << " CRC $" << std::hex << crc32);
86  };
87 
88  void dhc_dhe_start_frame::print(void) const
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 <<
93  dhe_time_tag_hi
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 
101  void dhc_direct_readout_frame::print(void) const
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 
108  void dhc_onsen_trigger_frame::print(void) const
109  {
110  word0.print();
111  B2DEBUG(99, "ONSEN Trigger Frame TNRLO $" << std::hex << trignr0);
112  };
113 
114  PXDError::PXDErrorFlags dhc_onsen_trigger_frame::check_error(bool ignore_datcon_flag, bool ignore_hltroi_magic_flag,
115  bool ignore_merger_mm_flag) const
116  {
117  PXDError::PXDErrorFlags m_errorMask = PXDError::EPXDErrMask::c_NO_ERROR;
118  if ((magic1 & 0xFFFF0000) != 0xCAFE0000) {
119  if (!ignore_hltroi_magic_flag) B2WARNING("ONSEN Trigger Magic 1 error $" << std::hex << magic1);
120  m_errorMask |= PXDError::EPXDErrMask::c_HLTROI_MAGIC;
121  }
122  if ((magic2 & 0xFFFF0000) != 0xCAFE0000) {
123  if (!ignore_hltroi_magic_flag) B2WARNING("ONSEN Trigger Magic 2 error $" << std::hex << magic2);
124  m_errorMask |= PXDError::EPXDErrMask::c_HLTROI_MAGIC;
125  }
126  if (is_fake_datcon()) {
127  if (!ignore_datcon_flag) B2INFO("ONSEN Trigger Frame: No DATCON data $" << std::hex << trignr1 << "!=$" << trignr2);
128  m_errorMask |= PXDError::EPXDErrMask::c_NO_DATCON;
129  } else {
130  if (trignr1 != trignr2) {
131  if (!ignore_merger_mm_flag) B2WARNING("ONSEN Trigger Frame Trigger Nr Mismatch $" << std::hex << trignr1 << "!=$" << trignr2);
132  m_errorMask |= PXDError::EPXDErrMask::c_MERGER_TRIGNR;
133  }
134  }
135  return m_errorMask;
136  };
137 
138  PXDError::PXDErrorFlags dhc_onsen_roi_frame::check_error(int length, bool ignore_inv_size_flag) const
139  {
140  PXDError::PXDErrorFlags m_errorMask = PXDError::EPXDErrMask::c_NO_ERROR;
141  // 4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
142  if (length < getMinSize()) {
143  if (!ignore_inv_size_flag) B2WARNING("DHC ONSEN HLT/ROI Frame too small to hold any ROIs!");
144  m_errorMask |= PXDError::c_ROI_PACKET_INV_SIZE;
145  } else if ((length - getMinSize()) % 8 != 0) {
146  if (!ignore_inv_size_flag) B2WARNING("DHC ONSEN HLT/ROI Frame holds fractional ROIs, last ROI might not be saved!");
147  m_errorMask |= PXDError::c_ROI_PACKET_INV_SIZE;
148  }
149  return m_errorMask;
150  };
151  void dhc_onsen_roi_frame::print(void) const
152  {
153  word0.print();
154  B2DEBUG(99, "DHC HLT/ROI Frame");
155  };
156 
157  void dhc_ghost_frame::print(void) const
158  {
159  word0.print();
160  B2DEBUG(99, "DHC Ghost Frame TNRLO $" << std::hex << trigger_nr_lo << " DHE ID $" << getDHEId() << " DHP port $" << getDHPPort() <<
161  " CRC $");
162  };
163 
164  unsigned short dhc_ghost_frame::getErrorBits(void) const
165  {
166  unsigned short value = (word0.data & 0xC) >> 2; // lower two bits
167  if (word0.data & 0x0400) value |= 0x4; // high bit
168  return value;
169  };
170 
171  bool dhc_end_frame::isFakedData(void) const
172  {
173  if (word0.data != 0x6000) return false;
174  if (trigger_nr_lo != 0) return false;
175  if (wordsinevent != 0) return false;
176  if (errorinfo != 0) return false;
177  if (crc32 != 0xF7BCA507) return false;
178  return true;
179  };
180  void dhc_end_frame::print(void) const
181  {
182  word0.print();
183  B2DEBUG(99, "DHC End Frame TNRLO $" << std::hex << trigger_nr_lo << " WIEVT $" << std::hex << wordsinevent << " ERR $" << std::hex
184  << errorinfo << " CRC " << std::hex << crc32);
185  };
186 
187 
188  void dhc_dhe_end_frame::print(void) const
189  {
190  word0.print();
191  B2DEBUG(99, "DHC DHE End Frame TNRLO $" << std::hex << trigger_nr_lo << " WIEVT $" << std::hex << wordsineventhi << "." <<
192  wordsineventlo << " ERR $" << std::hex << errorinfo << " CRC " << std::hex << crc32);
193  };
194 
195  unsigned int dhc_dhe_end_frame::getErrorStateMachineDHP(int dhpid) const
196  {
197  switch (dhpid) {
198  case 0: return ((uint32_t)errorinfo >> 24) & 0xFF;
199  case 1: return ((uint32_t)errorinfo >> 16) & 0xFF;
200  case 2: return ((uint32_t)errorinfo >> 8) & 0xFF;
201  case 3: return errorinfo & 0xFF;
202  default: return 0;
203  }
204  };
205 
206  unsigned int dhc_dhe_end_frame::getErrorStateMachineStartDHP(int dhpid) const
207  {
208  switch (dhpid) {
209  case 0: return ((uint32_t)errorinfo >> 24) & 0xF;
210  case 1: return ((uint32_t)errorinfo >> 16) & 0xF;
211  case 2: return ((uint32_t)errorinfo >> 8) & 0xF;
212  case 3: return errorinfo & 0xF;
213  default: return 0;
214  }
215  };
216 
217  unsigned int dhc_dhe_end_frame::getErrorStateMachineEndDHP(int dhpid) const
218  {
219  switch (dhpid) {
220  case 0: return ((uint32_t)errorinfo >> 28) & 0xF;
221  case 1: return ((uint32_t)errorinfo >> 20) & 0xF;
222  case 2: return ((uint32_t)errorinfo >> 12) & 0xF;
223  case 3: return ((uint32_t)errorinfo >> 4) & 0xF;
224  default: return 0;
225  }
226  };
227 
228  PXDError::PXDErrorFlags dhc_frames::check_padding(void)
229  {
230  unsigned int crc = *(ubig32_t*)(((unsigned char*)data) + length - 4);
231  if ((crc & 0xFFFF0000) == 0 || (crc & 0xFFFF) == 0) {
233  B2INFO("Suspicious Padding $" << std::hex << crc);
234  return PXDError::EPXDErrMask::c_SUSP_PADDING;
235  }
236  return PXDError::EPXDErrMask::c_NO_ERROR;
237  };
238 
239  PXDError::PXDErrorFlags dhc_frames::check_crc(bool ignore_crc_flag)
240  {
241  dhc_crc_32_type bocrc;
242 
243  if (length > 65536 * 16) {
244  if (!ignore_crc_flag) B2WARNING("DHC Data Frame CRC not calculated because of too large packet (>1MB)!");
245  return PXDError::EPXDErrMask::c_NO_ERROR; // such large packets should trigger an error elsewhere
246  } else {
247  bocrc.process_bytes(data, length - 4);
248  }
249  unsigned int c;
250  c = bocrc.checksum();
251 
252  ubig32_t crc32;
253  crc32 = *(ubig32_t*)(((unsigned char*)data) + length - 4);
254 
255  if (c != crc32) {
256  if (!ignore_crc_flag) {
257  B2WARNING("DHC Data Frame CRC FAIL");
258  B2DEBUG(1, "DHC Data Frame CRC FAIL: " << std::hex << c << "!=" << crc32 << " data "
259  << * (unsigned int*)(((unsigned char*)data) + length - 8) << " "
260  << * (unsigned int*)(((unsigned char*)data) + length - 6) << " "
261  << * (unsigned int*)(((unsigned char*)data) + length - 4) << " len $" << length);
262  }
263  return PXDError::EPXDErrMask::c_DHE_CRC;
264  }
265  return PXDError::EPXDErrMask::c_NO_ERROR;
266  };
267 
268 
269  unsigned int dhc_frames::getFixedSize(void)
270  {
271  unsigned int s = 0;
272  switch (getFrameType()) {
273  case EDHCFrameHeaderDataType::c_DHP_RAW:
274  s = 0;
275  break;
276  case EDHCFrameHeaderDataType::c_ONSEN_DHP:
277  case EDHCFrameHeaderDataType::c_DHP_ZSD:
278  s = 0;
279  break;
280  case EDHCFrameHeaderDataType::c_ONSEN_FCE:
281  case EDHCFrameHeaderDataType::c_FCE_RAW:
282  s = 0;
283  break;
284  case EDHCFrameHeaderDataType::c_COMMODE:
285  s = data_commode_frame->getFixedSize();
286  break;
287  case EDHCFrameHeaderDataType::c_GHOST:
288  s = data_ghost_frame->getFixedSize();
289  break;
290  case EDHCFrameHeaderDataType::c_DHE_START:
291  s = data_dhe_start_frame->getFixedSize();
292  break;
293  case EDHCFrameHeaderDataType::c_DHE_END:
294  s = data_dhe_end_frame->getFixedSize();
295  break;
296  case EDHCFrameHeaderDataType::c_DHC_START:
297  s = data_dhc_start_frame->getFixedSize();
298  break;
299  case EDHCFrameHeaderDataType::c_DHC_END:
300  s = data_dhc_end_frame->getFixedSize();
301  break;
302  case EDHCFrameHeaderDataType::c_ONSEN_ROI:
303  s = 0;
304  break;
305  case EDHCFrameHeaderDataType::c_ONSEN_TRG:
306  s = data_onsen_trigger_frame->getFixedSize();
307  break;
308  default:
309  B2INFO("Error: not a valid data frame!");
310  // Error will be set elsewhere in another check
311  s = 0;
312  break;
313  }
314  datasize = s;
315  return s;
316  };
317 
318  };
320 };
Belle2::PXD::dhc_frames::check_padding
PXDError::PXDErrorFlags check_padding()
Definition: PXDRawDataStructs.cc:238
Belle2::PXD::dhc_crc_32_type
boost::crc_optimal< 32, 0x04C11DB7, 0, 0, false, false > dhc_crc_32_type
define our CRC function
Definition: PXDRawDataStructs.cc:41
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::PXD::EDHCFrameHeaderDataType
EDHCFrameHeaderDataType
Enums for DHC data frame types.
Definition: PXDRawDataDefinitions.h:38
Belle2::PXD::dhc_frames::getFixedSize
unsigned int getFixedSize(void)
Definition: PXDRawDataStructs.cc:279
Belle2::PXD::dhc_frame_header_word0::print
void print(void) const
print
Definition: PXDRawDataStructs.cc:48