Belle II Software  release-08-01-10
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 - (static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_B2L_CTIME + SIZE_B2LFEE_TRAILER +
192  SIZE_B2LHSLB_TRAILER);
193  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, buf, pos_nwords);
194 
195  //
196  // Compare CRC16 with B2LCRC16
197  //
198  buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n,
199  finesse_num) - ((SIZE_B2LFEE_TRAILER - POS_B2LFEE_ERRCNT_CRC16) + SIZE_B2LHSLB_TRAILER) ;
200 
201  if (GetEveNo(n) % 100000 == 0) {
202  printf("#### PostRawCOPPER : Eve %.8x block %d finesse %d B2LCRC16 %.8x calculated CRC16 %.8x\n", GetEveNo(n), n, finesse_num,
203  *buf, temp_crc16);
204  }
205 
206  // if ( false ) {
207  if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
208 
209  // dump an event
210  int copper_nwords = copper_buf[ tmp_header.POS_NWORDS ];
211  PrintData(copper_buf, copper_nwords);
212  // Check whether packet-CRC error has occcured or not.
213  if (copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ] & tmp_header.B2LINK_PACKET_CRC_ERROR) {
214  //
215  // Do not stop data
216  //
217  char err_buf[600];
218  char hostname[128];
219  GetNodeName(n, hostname, sizeof(hostname));
220  if ((GetNodeID(n) & DETECTOR_MASK) == ARICH_ID) {
221  sprintf(err_buf,
222  "[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",
223  hostname, finesse_num,
224  *buf, temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
225  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
226  __FILE__, __PRETTY_FUNCTION__, __LINE__);
227  printf("%s", err_buf); fflush(stdout);
228  PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
229  } else {
230  sprintf(err_buf,
231  "[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",
232  hostname, finesse_num,
233  *buf, temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
234  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
235  __FILE__, __PRETTY_FUNCTION__, __LINE__);
236  printf("%s", err_buf); fflush(stdout);
237  PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
238 #ifndef NO_ERROR_STOP
239  B2FATAL(err_buf);
240 #endif
241  }
242 
243 
244 
245  } else {
246  //
247  // Stop taking data
248  //
249  char err_buf[500];
250  char hostname[128];
251  GetNodeName(n, hostname, sizeof(hostname));
252  sprintf(err_buf,
253  "[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",
254  hostname, finesse_num,
255  *buf, temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
256  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
257  __FILE__, __PRETTY_FUNCTION__, __LINE__);
258  printf("%s", err_buf); fflush(stdout);
259  PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
260 #ifndef NO_ERROR_STOP
261  B2FATAL(err_buf);
262 #endif
263  }
264  // Modify XOR checksum due to adding a bit flag
265  copper_buf[ copper_nwords - tmp_trailer.RAWTRAILER_NWORDS + tmp_trailer.POS_CHKSUM ]
266  ^= copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ];
267  copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_EVENT_CRC_ERROR;
268  copper_buf[ copper_nwords - tmp_trailer.RAWTRAILER_NWORDS + tmp_trailer.POS_CHKSUM ]
269  ^= copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ];
270  }
271 
272  return 1;
273 
274 
275 }
276 
277 
278 int* PostRawCOPPERFormat_latest::PackDetectorBuf(int* /*packed_buf_nwords*/,
279  int* /*detector_buf_1st*/, int /*nwords_1st*/,
280  int* /*detector_buf_2nd*/, int /*nwords_2nd*/,
281  int* /*detector_buf_3rd*/, int /*nwords_3rd*/,
282  int* /*detector_buf_4th*/, int /*nwords_4th*/,
283  RawCOPPERPackerInfo rawcpr_info)
284 {
285  char err_buf[500];
286  sprintf(err_buf, "[FATAL] This function is not supported. (%u) Exiting...: \n%s %s %d\n",
287  rawcpr_info.eve_num,
288  __FILE__, __PRETTY_FUNCTION__, __LINE__);
289  printf("[DEBUG] %s\n", err_buf);
290  B2FATAL(err_buf);
291  return NULL;
292 }
293 
294 
295 int* PostRawCOPPERFormat_latest::PackDetectorBuf(int* packed_buf_nwords,
296  int* const(&detector_buf_ch)[MAX_PCIE40_CH],
297  int const(&nwords_ch)[MAX_PCIE40_CH],
298  RawCOPPERPackerInfo rawcpr_info)
299 {
300  int* packed_buf = NULL;
301  int poswords_to = 0;
302 
303  // calculate the event length
304  int length_nwords = tmp_header.GetHdrNwords() + tmp_trailer.GetTrlNwords();
305 
306  for (int i = 0; i < MAX_PCIE40_CH; i++) {
307  if (detector_buf_ch[ i ] == NULL || nwords_ch[ i ] <= 0) continue; // for an empty FINESSE slot
308  length_nwords += nwords_ch[ i ];
309  length_nwords += static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + 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.