Belle II Software  release-06-01-15
PostRawCOPPERFormat_latest.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 <rawdata/dataobjects/PostRawCOPPERFormat_latest.h>
10 
11 
12 using namespace std;
13 using namespace Belle2;
14 
15 //#define DESY
16 //#define NO_ERROR_STOP
17 //ClassImp(PostRawCOPPERFormat_latest);
18 
19 PostRawCOPPERFormat_latest::PostRawCOPPERFormat_latest()
20 {
21 }
22 
23 PostRawCOPPERFormat_latest::~PostRawCOPPERFormat_latest()
24 {
25 }
26 
27 unsigned int PostRawCOPPERFormat_latest::CalcDriverChkSum(int n)
28 {
29  char err_buf[500];
30  sprintf(err_buf, "[FATAL] This function is not supported.(block %d) Exiting...: \n%s %s %d\n",
31  n, __FILE__, __PRETTY_FUNCTION__, __LINE__);
32  printf("[DEBUG] %s\n", err_buf);
33  B2FATAL(err_buf);
34  return 0;
35 }
36 
37 
38 
39 
40 
41 unsigned int PostRawCOPPERFormat_latest::GetB2LFEE32bitEventNumber(int n)
42 {
43  char err_buf[500];
44  char hostname[128];
45  GetNodeName(n, hostname, sizeof(hostname));
46  sprintf(err_buf,
47  "[FATAL] %s ch=%d : ERROR_EVENT : No event # in B2LFEE header. (block %d) Exiting... : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
48  hostname, -1,
49  n,
50  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
51  __FILE__, __PRETTY_FUNCTION__, __LINE__);
52  printf("[DEBUG] %s\n", err_buf);
53  B2FATAL(err_buf);
54  return 0;
55 }
56 
57 
58 
59 void PostRawCOPPERFormat_latest::CheckData(int n,
60  unsigned int prev_evenum, unsigned int* cur_evenum_rawcprhdr,
61  unsigned int prev_copper_ctr, unsigned int* cur_copper_ctr,
62  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
63 {
64  char err_buf[500];
65  int err_flag = 0;
66 
67  //
68  // Check incrementation of event #
69  //
70  *cur_evenum_rawcprhdr = GetEveNo(n);
71  *cur_exprunsubrun_no = GetExpRunSubrun(n);
72 
73  if (prev_exprunsubrun_no == *cur_exprunsubrun_no) {
74  if ((unsigned int)(prev_evenum + 1) != *cur_evenum_rawcprhdr) {
75  sprintf(err_buf, "CORRUPTED DATA: Event # jump : i %d prev 0x%x cur 0x%x : Exiting...\n%s %s %d\n",
76  n, prev_evenum, *cur_evenum_rawcprhdr,
77  __FILE__, __PRETTY_FUNCTION__, __LINE__);
78  err_flag = 1;
79  }
80  }
81 
82 
83  //
84  // Check checksum calculated by DeSerializerCOPPER()
85  //
86  tmp_trailer.SetBuffer(GetRawTrlBufPtr(n));
87  unsigned int xor_chksum = CalcXORChecksum(GetBuffer(n), GetBlockNwords(n) - tmp_trailer.GetTrlNwords());
88  if (tmp_trailer.GetChksum() != xor_chksum) {
89  char hostname[128];
90  GetNodeName(n, hostname, sizeof(hostname));
91  sprintf(err_buf,
92  "[FATAL] %s ch=%d : ERROR_EVENT : checksum error : block %d : length %d eve 0x%x : Trailer chksum 0x%.8x : calcd. now 0x%.8x : eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
93  hostname, -1,
94  n, GetBlockNwords(n), *cur_evenum_rawcprhdr, tmp_trailer.GetChksum(), xor_chksum,
95  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
96  __FILE__, __PRETTY_FUNCTION__, __LINE__);
97  err_flag = 1;
98  }
99 
100 
101  if (err_flag == 1) {
102  printf("[DEBUG] %s\n", err_buf);
103  printf("[DEBUG] ========== dump a data blcok : block # %d==========\n", n);
104  PrintData(GetBuffer(n), GetBlockNwords(n));
105  printf("Print out variables to reduce unused-variables-warnings : %u %u\n", prev_copper_ctr, *cur_copper_ctr);
106  B2FATAL(err_buf);
107  }
108 
109  return;
110 
111 }
112 
113 bool PostRawCOPPERFormat_latest::CheckCOPPERMagic(int n)
114 {
115  char err_buf[500];
116  char hostname[128];
117  GetNodeName(n, hostname, sizeof(hostname));
118  sprintf(err_buf,
119  "[FATAL] %s ch=%d : ERROR_EVENT : No magic word # in COPPER header (block %d). Exiting...: eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
120  hostname, -1,
121  n,
122  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
123  __FILE__, __PRETTY_FUNCTION__, __LINE__);
124  printf("[DEBUG] %s\n", err_buf);
125  B2FATAL(err_buf);
126  return false;
127 }
128 
129 void PostRawCOPPERFormat_latest::CheckUtimeCtimeTRGType(int n)
130 {
131  char err_buf[500];
132  sprintf(err_buf, "[FATAL] This function is not supported (block %d). Exiting...\n%s %s %d\n",
133  n, __FILE__, __PRETTY_FUNCTION__, __LINE__);
134  printf("[DEBUG] %s\n", err_buf);
135  B2FATAL(err_buf);
136 }
137 
138 unsigned int PostRawCOPPERFormat_latest::FillTopBlockRawHeader(unsigned int m_node_id, unsigned int prev_eve32,
139  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
140 
141 {
142  char err_buf[500];
143  sprintf(err_buf, "[FATAL] This function should be called by PrePostRawCOPPERFormat_***. Exiting...\n %s %s %d\n",
144  __FILE__, __PRETTY_FUNCTION__, __LINE__);
145  printf("Print out variables to reduce unused-variables-warnings : %u %u %u %u\n",
146  m_node_id, prev_eve32, prev_exprunsubrun_no, *cur_exprunsubrun_no);
147  printf("[DEBUG] %s\n", err_buf);
148  B2FATAL(err_buf);
149 }
150 
151 
152 int PostRawCOPPERFormat_latest::CheckB2LHSLBMagicWords(int* finesse_buf, int finesse_nwords)
153 {
154  char err_buf[500];
155  sprintf(err_buf, "[FATAL] This function should be called by PrePostRawCOPPERFormat_***. Exiting...\n %s %s %d\n",
156  __FILE__, __PRETTY_FUNCTION__, __LINE__);
157  printf("Print out variables to reduce unused-variables-warnings : %p %d\n", finesse_buf, finesse_nwords);
158  printf("[DEBUG] %s\n", err_buf);
159  B2FATAL(err_buf);
160 }
161 
162 int PostRawCOPPERFormat_latest::CheckCRC16(int n, int finesse_num)
163 {
164 
165  //
166  // Calculate CRC16
167  //
168  int finesse_nwords = GetFINESSENwords(n, finesse_num);
169  if (finesse_nwords <= 0) {
170  char err_buf[500];
171  char hostname[128];
172  GetNodeName(n, hostname, sizeof(hostname));
173  sprintf(err_buf,
174  "[FATAL] %s ch=%d : ERROR_EVENT : The specified finesse(%c) seems to be empty(nwords = %d). Cannot calculate CRC16. Exiting...: eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
175  hostname, finesse_num,
176  65 + finesse_num, finesse_nwords,
177  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
178  __FILE__, __PRETTY_FUNCTION__, __LINE__);
179  printf("%s", err_buf); fflush(stdout);
180  B2FATAL(err_buf);
181  }
182 
183  int* copper_buf = GetBuffer(n);
184 
185 
186  unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, &(copper_buf[ tmp_header.POS_TTCTIME_TRGTYPE ]), 1);
187  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, &(copper_buf[ tmp_header.POS_EVE_NO ]), 1);
188  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, &(copper_buf[ tmp_header.POS_TTUTIME ]), 1);
189  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, &(copper_buf[ tmp_header.POS_EXP_RUN_NO ]), 1);
190  int* buf = GetFINESSEBuffer(n, finesse_num) + SIZE_B2LHSLB_HEADER + POS_B2L_CTIME;
191  int pos_nwords = finesse_nwords - (SIZE_B2LHSLB_HEADER + POS_B2L_CTIME + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER);
192  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, buf, pos_nwords);
193 
194  //
195  // Compare CRC16 with B2LCRC16
196  //
197  buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n,
198  finesse_num) - ((SIZE_B2LFEE_TRAILER - POS_B2LFEE_ERRCNT_CRC16) + SIZE_B2LHSLB_TRAILER) ;
199 
200  if (GetEveNo(n) % 100000 == 0) {
201  printf("#### PostRawCOPPER : Eve %.8x block %d finesse %d B2LCRC16 %.8x calculated CRC16 %.8x\n", GetEveNo(n), n, finesse_num,
202  *buf, temp_crc16);
203  }
204 
205  // if ( false ) {
206  if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
207 
208  // dump an event
209  int copper_nwords = copper_buf[ tmp_header.POS_NWORDS ];
210  PrintData(copper_buf, copper_nwords);
211  // Check whether packet-CRC error has occcured or not.
212  if (copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ] & tmp_header.B2LINK_PACKET_CRC_ERROR) {
213  //
214  // Do not stop data
215  //
216  char err_buf[500];
217  char hostname[128];
218  GetNodeName(n, hostname, sizeof(hostname));
219  if ((GetNodeID(n) & DETECTOR_MASK) == ARICH_ID) {
220  sprintf(err_buf,
221  "[WARNING] %s ch=%d : ARICH : POST B2link event CRC16 error with B2link Packet CRC error. data(%x) calc(%x) fns nwords %d type 0x%.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: slot%c eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
222  hostname, finesse_num,
223  *buf , temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
224  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
225  __FILE__, __PRETTY_FUNCTION__, __LINE__);
226  printf("%s", err_buf); fflush(stdout);
227  PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
228  } else {
229  sprintf(err_buf,
230  "[FATAL] %s ch=%d : ERROR_EVENT : POST B2link event CRC16 error with B2link Packet CRC error. data(%x) calc(%x) fns nwords %d type 0x%.8x : slot%c eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
231  hostname, finesse_num,
232  *buf , temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
233  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
234  __FILE__, __PRETTY_FUNCTION__, __LINE__);
235  printf("%s", err_buf); fflush(stdout);
236  PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
237 #ifndef NO_ERROR_STOP
238  B2FATAL(err_buf);
239 #endif
240  }
241 
242 
243 
244  } else {
245  //
246  // Stop taking data
247  //
248  char err_buf[500];
249  char hostname[128];
250  GetNodeName(n, hostname, sizeof(hostname));
251  sprintf(err_buf,
252  "[FATAL] %s ch=%d : ERROR_EVENT : POST B2link event CRC16 error without B2link Packet CRC error. data(%x) calc(%x) fns nwords %d type 0x%.8x: slot%c eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
253  hostname, finesse_num,
254  *buf , temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
255  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
256  __FILE__, __PRETTY_FUNCTION__, __LINE__);
257  printf("%s", err_buf); fflush(stdout);
258  PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
259 #ifndef NO_ERROR_STOP
260  B2FATAL(err_buf);
261 #endif
262  }
263  // Modify XOR checksum due to adding a bit flag
264  copper_buf[ copper_nwords - tmp_trailer.RAWTRAILER_NWORDS + tmp_trailer.POS_CHKSUM ]
265  ^= copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ];
266  copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_EVENT_CRC_ERROR;
267  copper_buf[ copper_nwords - tmp_trailer.RAWTRAILER_NWORDS + tmp_trailer.POS_CHKSUM ]
268  ^= copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ];
269  }
270 
271  return 1;
272 
273 
274 }
275 
276 
277 int* PostRawCOPPERFormat_latest::PackDetectorBuf(int* /*packed_buf_nwords*/,
278  int* /*detector_buf_1st*/, int /*nwords_1st*/,
279  int* /*detector_buf_2nd*/, int /*nwords_2nd*/,
280  int* /*detector_buf_3rd*/, int /*nwords_3rd*/,
281  int* /*detector_buf_4th*/, int /*nwords_4th*/,
282  RawCOPPERPackerInfo rawcpr_info)
283 {
284  char err_buf[500];
285  sprintf(err_buf, "[FATAL] This function is not supported. (%u) Exiting...: \n%s %s %d\n",
286  rawcpr_info.eve_num,
287  __FILE__, __PRETTY_FUNCTION__, __LINE__);
288  printf("[DEBUG] %s\n", err_buf);
289  B2FATAL(err_buf);
290  return NULL;
291 }
292 
293 
294 int* PostRawCOPPERFormat_latest::PackDetectorBuf(int* packed_buf_nwords,
295  int* const(&detector_buf_ch)[MAX_PCIE40_CH],
296  int const(&nwords_ch)[MAX_PCIE40_CH],
297  RawCOPPERPackerInfo rawcpr_info)
298 {
299  int* packed_buf = NULL;
300  int poswords_to = 0;
301 
302  // calculate the event length
303  int length_nwords = tmp_header.GetHdrNwords() + tmp_trailer.GetTrlNwords();
304 
305  for (int i = 0; i < MAX_PCIE40_CH; i++) {
306  if (detector_buf_ch[ i ] == NULL || nwords_ch[ i ] <= 0) continue; // for an empty FINESSE slot
307  length_nwords += nwords_ch[ i ];
308  length_nwords += SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER
309  + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
310  }
311 
312  // allocate buffer
313  packed_buf = new int[ length_nwords ];
314  memset(packed_buf, 0, sizeof(int) * length_nwords);
315 
316  //
317  // Fill RawHeader
318  //
319  tmp_header.SetBuffer(packed_buf);
320 
321  packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
322  packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] =
323  0x7f7f0000
324  | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
325  | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
326  packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << 22)
327  | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
328  packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
329  packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
330  packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
331  packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
332 
333  // fill the positions of finesse buffers
334  int ch = 0;
335  packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = tmp_header.RAWHEADER_NWORDS;
336  for (int i = 1; i < MAX_PCIE40_CH; i++) {
337  ch = i;
338  if (nwords_ch[ ch - 1 ] == 0) {
339  packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = packed_buf[ tmp_header.POS_CH_POS_TABLE + (ch - 1) ];
340  } else {
341  packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = packed_buf[ tmp_header.POS_CH_POS_TABLE + (ch - 1) ] +
342  nwords_ch[ ch - 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
343  }
344  }
345  poswords_to += tmp_header.GetHdrNwords();
346 
347  // Fill FINESSE buffer
348  for (int i = 0; i < MAX_PCIE40_CH; i++) {
349  if (detector_buf_ch[ i ] == NULL || nwords_ch[ i ] <= 0) continue; // for an empty FINESSE slot
350 
351  // Fill b2link HSLB header
352  packed_buf[ poswords_to + POS_B2LHSLB_MAGIC ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
353  poswords_to += SIZE_B2LHSLB_HEADER;
354 
355  // Fill b2link FEE header
356  packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
357  poswords_to += SIZE_B2LFEE_HEADER;
358 
359  // copy the 1st Detector Buffer
360  memcpy(packed_buf + poswords_to, detector_buf_ch[ i ], nwords_ch[ i ]*sizeof(int));
361  poswords_to += nwords_ch[ i ];
362 
363  // Fill b2link FEE trailer
364  unsigned int crc16 = 0;
365  packed_buf[ poswords_to + POS_B2LFEE_ERRCNT_CRC16 ] =
366  ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 &
367  0xffff); // Error count is stored in this buffer for ver.2 format but it is set to zero here.
368  poswords_to += SIZE_B2LFEE_TRAILER;
369 
370  // Fill b2link HSLB trailer
371  packed_buf[ poswords_to + POS_B2LHSLB_TRL_MAGIC ] = 0xff550000;
372  poswords_to += SIZE_B2LHSLB_TRAILER;
373 
374  }
375 
376  // Fill RawTrailer
377  packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
378  poswords_to += tmp_trailer.GetTrlNwords();
379 
380  *packed_buf_nwords = poswords_to;
381 
382  return packed_buf;
383 }
384 
385 
386 
387 
388 
389 
390 
391 
392 
393 
394 
395 
396 
397 
398 
399 
400 
401 
402 
403 
404 
405 
406 
407 
408 
struct to contain header information used by RawCOPPERFormat::Packer()
unsigned int b2l_ctime
32bit unitx time at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user ...
unsigned int eve_num
Run # and subrun # ( 22bit )
unsigned int tt_ctime
Node ID (32bit)
unsigned int tt_utime
27bit clock ticks at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user...
unsigned int node_id
Event Number (32bit)
unsigned int run_subrun_num
Experiment number (10bit)
unsigned int exp_num
Experiment number (10bit)
Abstract base class for different kinds of events.