Belle II Software  release-08-01-10
PreRawCOPPERFormat_v2.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/PreRawCOPPERFormat_v2.h>
10 
11 
12 using namespace std;
13 using namespace Belle2;
14 
15 //#define NO_ERROR_STOP
16 //#define WO_FIRST_EVENUM_CHECK
17 
18 //ClassImp(PreRawCOPPERFormat_v2);
19 
20 PreRawCOPPERFormat_v2::PreRawCOPPERFormat_v2()
21 {
22 
23 }
24 
25 PreRawCOPPERFormat_v2::~PreRawCOPPERFormat_v2()
26 {
27 }
28 
29 unsigned int PreRawCOPPERFormat_v2::CalcDriverChkSum(int n)
30 {
31  int min = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS;
32  int max = GetBufferPos(n) + GetBlockNwords(n)
33  - tmp_trailer.RAWTRAILER_NWORDS - SIZE_COPPER_DRIVER_TRAILER;
34  unsigned int chksum = 0;
35  for (int i = min; i < max; i++) {
36  chksum ^= m_buffer[ i ];
37  }
38  return chksum;
39 }
40 
41 
42 
43 int PreRawCOPPERFormat_v2::GetDetectorNwords(int n, int finesse_num)
44 {
45 
46  int nwords = 0;
47  if (GetFINESSENwords(n, finesse_num) > 0) {
48  nwords = GetFINESSENwords(n, finesse_num)
49  - (static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LHSLB_TRAILER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER);
50  }
51  return nwords;
52 
53 }
54 
55 
56 int PreRawCOPPERFormat_v2::GetFINESSENwords(int n, int finesse_num)
57 {
58  if (!CheckCOPPERMagic(n)) {
59  char err_buf[500];
60  char hostname[128];
61  GetNodeName(n, hostname, sizeof(hostname));
62  sprintf(err_buf,
63  "[FATAL] %s ch=%d : ERROR_EVENT : COPPER's magic word is invalid. Exiting... Maybe it is due to data corruption or different version of the data format. : slot%c eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
64  hostname, finesse_num,
65  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
66  __FILE__, __PRETTY_FUNCTION__, __LINE__);
67  printf("[DEBUG] %s", err_buf); fflush(stdout);
68  PrintData(m_buffer, m_nwords);
69 
70  for (int i = 0; i < 4; i++) {
71  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
72  if (GetFINESSENwords(n, i) > 0) {
73  CheckCRC16(n, i);
74  }
75  }
76  printf("[DEBUG] ========== No CRC error. : block %d =========\n", n);
77  // string err_str = err_buf; throw (err_str);
78  B2FATAL(err_buf); // to reduce multiple error messages
79  }
80  int pos_nwords;
81  switch (finesse_num) {
82  case 0 :
83  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_A_DATA_LENGTH;
84  break;
85  case 1 :
86  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_B_DATA_LENGTH;
87  break;
88  case 2 :
89  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_C_DATA_LENGTH;
90  break;
91  case 3 :
92  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_D_DATA_LENGTH;
93  break;
94  default :
95  char err_buf[500];
96  char hostname[128];
97  GetNodeName(n, hostname, sizeof(hostname));
98  sprintf(err_buf,
99  "[FATAL] %s ch=%d : ERROR_EVENT : Specified FINESSE number( = %d ) is invalid. Exiting... : slot%c eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
100  hostname, finesse_num,
101  finesse_num,
102  65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
103  __FILE__, __PRETTY_FUNCTION__, __LINE__);
104  printf("%s", err_buf); fflush(stdout);
105  // string err_str = err_buf; throw (err_str);
106  B2FATAL(err_buf); // to reduce multiple error messages
107  }
108  return m_buffer[ pos_nwords ];
109 
110 }
111 
112 
113 unsigned int PreRawCOPPERFormat_v2::GetB2LFEE32bitEventNumber(int n)
114 {
115 
116 #ifndef READ_OLD_B2LFEE_FORMAT_FILE
117 
118  int err_flag = 0;
119  unsigned int eve_num = 0;
120  int flag = 0;
121  unsigned int eve[4];
122  for (int i = 0; i < 4 ; i++) {
123  eve[ i ] = 0xbaadf00d;
124  if (GetFINESSENwords(n, i) > 0) {
125  int pos_nwords = GetOffsetFINESSE(n, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
126  eve[ i ] = m_buffer[ pos_nwords ];
127  if (flag != 1) eve_num = eve[ i ];
128  if (eve_num != eve[ i ]) err_flag = 1;
129  flag = 1;
130  }
131  }
132 
133  if (flag == 0) {
134  PrintData(m_buffer, m_nwords);
135  char err_buf[500];
136  char hostname[128];
137  GetNodeName(n, hostname, sizeof(hostname));
138  sprintf(err_buf,
139  "[FATAL] %s ch=%d : ERROR_EVENT : No HSLB data in COPPER data. Exiting... : eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
140  hostname, -1,
141  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
142  __FILE__, __PRETTY_FUNCTION__, __LINE__);
143  printf("%s", err_buf); fflush(stdout);
144  // string err_str = err_buf; throw (err_str);
145  B2FATAL(err_buf); // to reduce multiple error messages
146  }
147 
148  if (err_flag == 1) {
149  char err_buf[500];
150  char hostname[128];
151  GetNodeName(n, hostname, sizeof(hostname));
152  sprintf(err_buf,
153  "[FATAL] %s ch=%d : ERROR_EVENT : CORRUPTED DATA: Different event number over HSLBs : slot A 0x%.8x : B 0x%.8x :C 0x%.8x : D 0x%.8x : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
154  hostname, -1,
155  eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
156  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
157  __FILE__, __PRETTY_FUNCTION__, __LINE__);
158  printf("[DEBUG] %s\n", err_buf);
159  PrintData(m_buffer, m_nwords);
160  for (int i = 0; i < 4; i++) {
161  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
162  if (GetFINESSENwords(n, i) > 0) {
163  CheckCRC16(n, i);
164  }
165  }
166  printf("[DEBUG] ========== No CRC error. : block %d =========\n", n);
167 #ifndef NO_ERROR_STOP
168  // string err_str = err_buf; throw (err_str);
169  B2FATAL(err_buf); // to reduce multiple error messages
170 #endif //NO_ERROR_STOP
171  }
172  return eve_num;
173 
174 #else // READ_OLD_B2LFEE_FORMAT_FILE
175 
176  char err_buf[500];
177  sprintf(err_buf, "[FATAL] You need comment out READ_OLD_B2LFEE_FORMAT_FILE if you are handling a new data format\n%s %s %d\n",
178  __FILE__, __PRETTY_FUNCTION__, __LINE__);
179  printf("%s", err_buf); fflush(stdout);
180  B2FATAL(err_buf); // to reduce multiple error messages
181 #endif // READ_OLD_B2LFEE_FORMAT_FILE
182 
183 }
184 
185 
186 void PreRawCOPPERFormat_v2::CheckData(int n,
187  unsigned int prev_evenum, unsigned int* cur_evenum_rawcprhdr,
188  unsigned int prev_copper_ctr, unsigned int* cur_copper_ctr,
189  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
190 {
191 
192  char err_buf[1000];
193  int err_flag = 0;
194  //
195  // check Magic words
196  //
197  if (!CheckCOPPERMagic(n)) {
198  char hostname[128];
199  GetNodeName(n, hostname, sizeof(hostname));
200  sprintf(err_buf,
201  "[FATAL] %s ch=%d : ERROR_EVENT : Invalid Magic word 0x7FFFF0008=%u 0xFFFFFAFA=%u 0xFFFFF5F5=%u 0x7FFF0009=%u : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
202  hostname, -1,
203  GetMagicDriverHeader(n), GetMagicFPGAHeader(n), GetMagicFPGATrailer(n), GetMagicDriverTrailer(n),
204  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
205  __FILE__, __PRETTY_FUNCTION__, __LINE__);
206  err_flag = 1;
207  }
208 
209  //
210  // Event # check
211  //
212  *cur_evenum_rawcprhdr = GetEveNo(n);
213  unsigned int evenum_feehdr = GetB2LFEE32bitEventNumber(n);
214  if (*cur_evenum_rawcprhdr != evenum_feehdr) {
215 
216  char hostname[128];
217  GetNodeName(n, hostname, sizeof(hostname));
218  sprintf(err_buf,
219  "[FATAL] %s ch=%d : ERROR_EVENT : Event # in PreRawCOPPERFormat_v2 header and FEE header is different : cprhdr 0x%x feehdr 0x%x : Exiting... : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
220  hostname, -1,
221  *cur_evenum_rawcprhdr, evenum_feehdr,
222  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
223  __FILE__, __PRETTY_FUNCTION__, __LINE__);
224  err_flag = 1;
225  }
226 
227  //
228  // Check incrementation of event #
229  //
230  *cur_exprunsubrun_no = GetExpRunSubrun(n);
231  *cur_copper_ctr = GetCOPPERCounter(n);
232  if (prev_exprunsubrun_no == *cur_exprunsubrun_no) {
233  if ((unsigned int)(prev_evenum + 1) != *cur_evenum_rawcprhdr) {
234  char hostname[128];
235  GetNodeName(n, hostname, sizeof(hostname));
236  sprintf(err_buf,
237  "[FATAL] %s ch=%d : ERROR_EVENT : Event # jump : i %d prev 0x%x cur 0x%x : prevrun %.8x currun %.8x: Exiting... : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
238  hostname, -1,
239  n, prev_evenum, *cur_evenum_rawcprhdr, prev_exprunsubrun_no, *cur_exprunsubrun_no,
240  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
241  __FILE__, __PRETTY_FUNCTION__, __LINE__);
242  err_flag = 1;
243  }
244  if ((unsigned int)(prev_copper_ctr + 1) != *cur_copper_ctr) {
245  char hostname[128];
246  GetNodeName(n, hostname, sizeof(hostname));
247  sprintf(err_buf,
248  "[FATAL] %s ch=%d : ERROR_EVENT : COPPER counter jump : i %d prev 0x%x cur 0x%x : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
249  hostname, -1,
250  n, prev_copper_ctr, *cur_copper_ctr,
251  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
252  __FILE__, __PRETTY_FUNCTION__, __LINE__);
253  err_flag = 1;
254  }
255  } else {
256  printf("[DEBUG] New run started. cur run %.8x prev. run %.8x cur eve %.8x prev eve %8.x : eve 0x%x exp %d run %d sub %d\n",
257  *cur_exprunsubrun_no, prev_exprunsubrun_no, *cur_evenum_rawcprhdr, prev_evenum,
258  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n));
259 
260  // Check if the first event of a run is zero.
261  if ((unsigned int)GetRunNo(n) != (prev_exprunsubrun_no & RawHeader_v2::RUNNO_MASK) >> RawHeader_v2::RUNNO_SHIFT) {
262  if (*cur_evenum_rawcprhdr != 0) {
263 
264  unsigned int eve[4];
265  for (int i = 0; i < 4 ; i++) {
266  eve[ i ] = 0xbaadf00d;
267  if (GetFINESSENwords(n, i) > 0) {
268  int pos_nwords = GetOffsetFINESSE(n, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
269  eve[ i ] = m_buffer[ pos_nwords ];
270  }
271  }
272 
273  char hostname[128];
274  GetNodeName(n, hostname, sizeof(hostname));
275  sprintf(err_buf,
276  "[FATAL] %s ch=%d : ERROR_EVENT : Invalid Event # at the beginning of the run (It should be zero.): preveve 0x%x cureve 0x%x : prev(exp %u run %u sub %u ) cur(exp %u run %u sub %u ) ( A:0x%.8x B:0x%.8x C:0x%.8x D:0x%.8x ) Exiting... : eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
277  hostname, -1,
278  prev_evenum, *cur_evenum_rawcprhdr,
279  prev_exprunsubrun_no >> 22, (prev_exprunsubrun_no >> 8) & 0x3FFF, prev_exprunsubrun_no & 0xFF,
280  *cur_exprunsubrun_no >> 22, (*cur_exprunsubrun_no >> 8) & 0x3FFF, *cur_exprunsubrun_no & 0xFF,
281  eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
282  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
283  __FILE__, __PRETTY_FUNCTION__, __LINE__);
284  err_flag = 1;
285  }
286  }
287 
288  }
289 
290 
291 
292  //
293  // Check is utime and ctime_trgtype same over different FINESSE data
294  //
295  CheckUtimeCtimeTRGType(n);
296 
297  //
298  // Check checksum calculated by COPPER driver
299  //
300  if (GetDriverChkSum(n) != CalcDriverChkSum(n)) {
301  char hostname[128];
302  GetNodeName(n, hostname, sizeof(hostname));
303  sprintf(err_buf,
304  "[FATAL] %s ch=%d : ERROR_EVENT : COPPER driver 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",
305  hostname, -1,
306  n, GetBlockNwords(n), *cur_evenum_rawcprhdr, GetDriverChkSum(n), CalcDriverChkSum(n),
307  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
308  __FILE__, __PRETTY_FUNCTION__, __LINE__);
309  err_flag = 1;
310  }
311 
312  //
313  // Check checksum calculated by DeSerializerCOPPER()
314  //
315  tmp_trailer.SetBuffer(GetRawTrlBufPtr(n));
316  unsigned int xor_chksum = CalcXORChecksum(GetBuffer(n), GetBlockNwords(n) - tmp_trailer.GetTrlNwords());
317  if (tmp_trailer.GetChksum() != xor_chksum) {
318  char hostname[128];
319  GetNodeName(n, hostname, sizeof(hostname));
320  sprintf(err_buf,
321  "[FATAL] %s ch=%d : ERROR_EVENT : PreRawCOPPERFormat_v2 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",
322  hostname, -1,
323  n, GetBlockNwords(n), *cur_evenum_rawcprhdr, tmp_trailer.GetChksum(), xor_chksum,
324  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
325  __FILE__, __PRETTY_FUNCTION__, __LINE__);
326  err_flag = 1;
327  }
328 
329  if (err_flag == 1) {
330  printf("%s", err_buf); fflush(stdout);
331  printf("[DEBUG] ========== dump a data blcok : block # %d==========\n", n);
332  PrintData(GetBuffer(n), GetBlockNwords(n));
333  for (int i = 0; i < 4; i++) {
334  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
335  if (GetFINESSENwords(n, i) > 0) {
336  CheckCRC16(n, i);
337  }
338  }
339  printf("[DEBUG] ========== No CRC error : block %d =========\n", n);
340  // string err_str = err_buf; throw (err_str);
341  B2FATAL(err_buf); // to reduce multiple error messages
342  }
343 
344  return;
345 
346 }
347 
348 bool PreRawCOPPERFormat_v2::CheckCOPPERMagic(int n)
349 {
350  if (GetMagicDriverHeader(n) != COPPER_MAGIC_DRIVER_HEADER) {
351  return false;
352  } else if (GetMagicFPGAHeader(n) != COPPER_MAGIC_FPGA_HEADER) {
353  return false;
354  } else if (GetMagicFPGATrailer(n) != COPPER_MAGIC_FPGA_TRAILER) {
355  return false;
356  } else if (GetMagicDriverTrailer(n) != COPPER_MAGIC_DRIVER_TRAILER) {
357  return false;
358  }
359  return true;
360 }
361 
362 void PreRawCOPPERFormat_v2::CheckUtimeCtimeTRGType(int n)
363 {
364 
365 #ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
366  CheckB2LFEEHeaderVersion(n);
367 #endif
368  int err_flag = 0;
369  int flag = 0;
370  unsigned int temp_utime = 0, temp_ctime_trgtype = 0, temp_eve = 0, temp_exprun = 0;
371  unsigned int temp_ctime_trgtype_footer, temp_eve_footer;
372  unsigned int utime[4], ctime_trgtype[4], eve[4], exprun[4];
373  char err_buf[4000];
374  int first_ch = 0;
375 
376  memset(utime, 0, sizeof(utime));
377  memset(ctime_trgtype, 0, sizeof(ctime_trgtype));
378  memset(eve, 0, sizeof(eve));
379  memset(exprun, 0, sizeof(exprun));
380 
381 
382  for (int i = 0; i < 4; i++) {
383  int finesse_nwords = GetFINESSENwords(n, i);
384  if (finesse_nwords > 0) {
385  int offset_finesse = GetOffsetFINESSE(n, i);
386  ctime_trgtype[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_CTIME_TYPE ];
387  utime[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_UTIME ];
388  eve[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_TAG ];
389  exprun[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_EXP_RUN ];
390  temp_ctime_trgtype_footer =
391  m_buffer[ offset_finesse + finesse_nwords - (static_cast<int>(SIZE_B2LFEE_TRAILER) + SIZE_B2LHSLB_TRAILER) + POS_TT_CTIME_B2LFEE ];
392  temp_eve_footer =
393  m_buffer[ offset_finesse + finesse_nwords - (static_cast<int>(SIZE_B2LFEE_TRAILER) + SIZE_B2LHSLB_TRAILER) + POS_CHKSUM_B2LFEE ];
394 
395  if (flag == 0) {
396  temp_ctime_trgtype = ctime_trgtype[ i ];
397  temp_utime = utime[ i ];
398  temp_eve = eve[ i ];
399  temp_exprun = exprun[ i ];
400  flag = 1;
401  first_ch = i;
402  } else {
403  if (temp_ctime_trgtype != ctime_trgtype[ i ] || temp_utime != utime[ i ] ||
404  temp_eve != eve[ i ] || temp_exprun != exprun[ i ]) {
405  char hostname[128];
406  GetNodeName(n, hostname, sizeof(hostname));
407  if (err_flag == 0) {
408  for (int j = 0; j < 4; j++) {
409  printf("[DEBUG] %s ch=%d : FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x\n",
410  hostname, -1,
411  j, GetFINESSENwords(n, j), ctime_trgtype[ j ], utime[ j ], eve[ j ], exprun[ j ]);
412  }
413  }
414 
415  char err_buf_1[2500], err_buf_2[3000], err_buf_3[3500];
416  sprintf(err_buf_1,
417  "[FATAL] %s ch=%d : ERROR_EVENT : mismatch header value over FINESSEs. Exiting...",
418  hostname, -1);
419  sprintf(err_buf_2,
420  "%s FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x",
421  err_buf_1,
422  first_ch, GetFINESSENwords(n, first_ch), ctime_trgtype[ first_ch ], utime[ first_ch ], eve[ first_ch ], exprun[ first_ch ]);
423  sprintf(err_buf_3,
424  "%s FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x",
425  err_buf_2,
426  i, GetFINESSENwords(n, i), ctime_trgtype[ i ], utime[ i ], eve[ i ], exprun[ i ]);
427  sprintf(err_buf, "%s\n %s %s %d\n",
428  err_buf_3,
429  __FILE__, __PRETTY_FUNCTION__, __LINE__);
430  printf("%s", err_buf); fflush(stdout);
431 
432  err_flag = 1;
433  break;
434  } else if (temp_ctime_trgtype != temp_ctime_trgtype_footer ||
435  (temp_eve & 0xffff) != ((temp_eve_footer >> 16) & 0xffff)) {
436  char hostname[128];
437  GetNodeName(n, hostname, sizeof(hostname));
438  sprintf(err_buf,
439  "[FATAL] %s ch=%d : ERROR_EVENT : mismatch(finesse %d) between header(ctime %.8x eve %.8x) and footer(ctime %.8x eve_crc16 %.8x). Exiting...\n %s %s %d\n",
440  hostname, i,
441  i, temp_ctime_trgtype, temp_eve, temp_ctime_trgtype_footer, temp_eve_footer,
442  __FILE__, __PRETTY_FUNCTION__, __LINE__);
443  printf("%s", err_buf); fflush(stdout);
444  err_flag = 1;
445  }
446  }
447  }
448  }
449 
450  if (err_flag != 0) {
451  for (int i = 0; i < 4; i++) {
452  if (GetFINESSENwords(n, i) > 0) {
453  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
454  CheckCRC16(n, i);
455  printf("[DEBUG] ========== CRC check is done. : block %d =========\n", n);
456  }
457  }
458 #ifndef NO_ERROR_STOP
459  // string err_str = err_buf; throw (err_str);
460  B2FATAL(err_buf); // to reduce multiple error messages
461 #endif
462  }
463  return;
464 }
465 
466 unsigned int PreRawCOPPERFormat_v2::FillTopBlockRawHeader(unsigned int m_node_id, unsigned int prev_eve32,
467  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
468 {
469  const int datablock_id = 0;
470  // m_temp_value = 12345678;
471  //
472  // This function only fills RawHeader contents for the first datablock.
473  // # of block should be 1
474  if (m_num_nodes * m_num_events != 1) {
475  char err_buf[500];
476  sprintf(err_buf,
477  "[FATAL] This function should be used for PreRawCOPPERFormat_v2 containing only one datablock, while. this object has num_nodes of %d and num_events of %d\n %s %s %d\n",
478  m_num_nodes, m_num_events, __FILE__, __PRETTY_FUNCTION__, __LINE__);
479  printf("%s", err_buf); fflush(stdout);
480  // string err_str = err_buf; throw (err_str);
481  B2FATAL(err_buf); // to reduce multiple error messages
482  }
483 
485  //
486  // Fill info in RawHeader
487  //
489 
490  //
491  // Initialize a RawHeader part
492  //
493  memset(m_buffer, 0, sizeof(int) * tmp_header.RAWHEADER_NWORDS);
494  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] = static_cast<int>(tmp_header.RAWHEADER_NWORDS) & tmp_header.HDR_NWORDS_MASK;
495  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) &
496  tmp_header.FORMAT_VERSION__MASK;
497  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (0x80 << tmp_header.FORMAT_VERSION_SHIFT); // PreFormat
498  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= tmp_header.MAGIC_WORD;
499 
500  //
501  // Check FINESSEs which containes data
502  //
503  int* copper_buf = &(m_buffer[ tmp_header.RAWHEADER_NWORDS ]);
504  if (copper_buf[ POS_CH_A_DATA_LENGTH ] == 0 &&
505  copper_buf[ POS_CH_B_DATA_LENGTH ] == 0 &&
506  copper_buf[ POS_CH_C_DATA_LENGTH ] == 0 &&
507  copper_buf[ POS_CH_D_DATA_LENGTH ] == 0) {
508  char err_buf[500];
509  char hostname[128];
510  GetNodeName(hostname, m_node_id, sizeof(hostname));
511  sprintf(err_buf,
512  "[FATAL] %s ch=%d : ERROR_EVENT : No FINESSE data in a copper data block. Exiting...\n %s %s %d\n",
513  hostname, -1,
514  __FILE__, __PRETTY_FUNCTION__, __LINE__);
515  printf("%s", err_buf); fflush(stdout);
516  // string err_str = err_buf; throw (err_str);
517  B2FATAL(err_buf); // to reduce multiple error messages
518  }
519 
520  //
521  // Set total words info
522  //
523  int datablock_nwords =
524  tmp_header.RAWHEADER_NWORDS +
525  (copper_buf[ POS_DATA_LENGTH ]
526  + SIZE_COPPER_DRIVER_HEADER
527  + SIZE_COPPER_DRIVER_TRAILER)
528  + tmp_trailer.RAWTRAILER_NWORDS;
529  m_buffer[ tmp_header.POS_NWORDS ] = datablock_nwords;
530 
531 
532  //
533  // Check the consistency between data length and length in RawHeader
534  //
535  if (m_buffer[ tmp_header.POS_NWORDS ] != m_nwords) {
536  char err_buf[500];
537 
538  char hostname[128];
539  GetNodeName(hostname, m_node_id, sizeof(hostname));
540  sprintf(err_buf,
541  "[FATAL] %s ch=%d : ERROR_EVENT : Data length is inconsistent m_nwords %d : nwords from COPPER data %d\n %s %s %d\n",
542  hostname, -1,
543  m_nwords, m_buffer[ tmp_header.POS_NWORDS ],
544  __FILE__, __PRETTY_FUNCTION__, __LINE__);
545  printf("%s", err_buf); fflush(stdout);
546  // string err_str = err_buf; throw (err_str);
547  B2FATAL(err_buf); // to reduce multiple error messages
548  }
549 
550  //
551  // Fill offset values
552  //
553  int offset_1st_finesse = static_cast<int>(tmp_header.RAWHEADER_NWORDS) + SIZE_COPPER_HEADER;
554  int offset_2nd_finesse = offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ];
555  int offset_3rd_finesse = offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ];
556  int offset_4th_finesse = offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ];
557  m_buffer[ tmp_header.POS_OFFSET_1ST_FINESSE ] = offset_1st_finesse;
558  m_buffer[ tmp_header.POS_OFFSET_2ND_FINESSE ] = offset_2nd_finesse;
559  m_buffer[ tmp_header.POS_OFFSET_3RD_FINESSE ] = offset_3rd_finesse;
560  m_buffer[ tmp_header.POS_OFFSET_4TH_FINESSE ] = offset_4th_finesse;
561 
562  //
563  // Fill Exp/Run value
564  //
565  int* finesse_buf = &
566  (m_buffer[ offset_1st_finesse ]); // In any finesse implementations, the top finesse buffer should be at offset_1st_finesse;
567  m_buffer[ tmp_header.POS_EXP_RUN_NO ] = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_EXP_RUN ];
568 
569 
570  //
571  // Fill event #
572  //
573  unsigned int cur_ftsw_eve32 = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_TT_TAG ];
574  m_buffer[ tmp_header.POS_EVE_NO ] = cur_ftsw_eve32;
575 
576  //
577  // Copy FTSW words from B2LFEE header
578  //
579  m_buffer[ tmp_header.POS_TTCTIME_TRGTYPE ] = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_TT_CTIME_TYPE ];
580  m_buffer[ tmp_header.POS_TTUTIME ] = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_TT_UTIME ];
581 
582  //
583  // Set node ID, trunc_mask, data_type
584  //
585  m_buffer[ tmp_header.POS_NODE_ID ] = m_node_id;
586 
587  //
588  // Check error counts of b2link-packet CRC
589  //
590  // m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] = ((m_trunc_mask << 31) & 0x80000000) | (m_data_type & 0x7FFFFFFF);
591  // printf("%.8x %.8x %.8x %.8x : %.8x\n",
592  // copper_buf[ POS_CH_A_DATA_LENGTH ], copper_buf[ POS_CH_B_DATA_LENGTH ],
593  // copper_buf[ POS_CH_C_DATA_LENGTH ], copper_buf[ POS_CH_D_DATA_LENGTH ], m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] );
594 
595  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] = 0;
596  unsigned int ff55_higher_bits, ff55_lower_bits;
597 
598  if (copper_buf[ POS_CH_A_DATA_LENGTH ] != 0) {
599  ff55_higher_bits = (unsigned int)(m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
600  0xFFFF0000;
601 
602  ff55_lower_bits = m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF;
603 
604  if (ff55_higher_bits != 0xff550000) {
605  char err_buf[500];
606  char hostname[128];
607  GetNodeName(hostname, m_node_id, sizeof(hostname));
608  sprintf(err_buf,
609  "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotA's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
610  hostname, 0,
611  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
612  m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
613  __FILE__, __PRETTY_FUNCTION__, __LINE__);
614  printf("%s", err_buf); fflush(stdout);
615  PrintData(m_buffer, m_nwords); fflush(stdout);
616  B2FATAL(err_buf);
617  }
618 
619  if (ff55_lower_bits != 0) {
620  const int linkdown_bit = 15;
621  // const int packet_crcerr_bit = 8;
622  char err_buf[1000];
623  char hostname[128];
624  GetNodeName(hostname, m_node_id, sizeof(hostname));
625 
626  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
627  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot A eve %8u foooter %.8x : %s %s %d\n",
628  hostname, 0,
629  cur_ftsw_eve32,
630  m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
631  __FILE__, __PRETTY_FUNCTION__, __LINE__);
632  printf("%s", err_buf); fflush(stdout);
633  PrintData(m_buffer, m_nwords);
634  fflush(stdout);
635  B2FATAL(err_buf);
636  } else {
637  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
638  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
639  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x1 << 28);
640  sprintf(err_buf,
641  "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot A eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
642  hostname, 0,
643  cur_ftsw_eve32,
644  m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
645  __FILE__, __PRETTY_FUNCTION__, __LINE__);
646  printf("%s", err_buf); fflush(stdout);
647  PrintData(m_buffer, m_nwords);
648  fflush(stdout);
649  } else {
650  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
651  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x1 << 28);
652  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot A eve %8u foooter %.8x : %s %s %d\n",
653  hostname, 0,
654  cur_ftsw_eve32,
655  m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
656  __FILE__, __PRETTY_FUNCTION__, __LINE__);
657  printf("%s", err_buf); fflush(stdout);
658  PrintData(m_buffer, m_nwords);
659  fflush(stdout);
660  B2FATAL(err_buf);
661  }
662  }
663  }
664  }
665 
666  if (copper_buf[ POS_CH_B_DATA_LENGTH ] != 0) {
667  ff55_higher_bits = (unsigned int)(m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
668  0xFFFF0000;
669 
670  ff55_lower_bits = (m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
671  char hostname[128];
672  GetNodeName(hostname, m_node_id, sizeof(hostname));
673  if (ff55_higher_bits != 0xff550000) {
674  char err_buf[500];
675  sprintf(err_buf,
676  "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotB's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
677  hostname, 1,
678  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
679  m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
680  __FILE__, __PRETTY_FUNCTION__, __LINE__);
681  printf("%s", err_buf); fflush(stdout);
682  PrintData(m_buffer, m_nwords); fflush(stdout);
683  B2FATAL(err_buf);
684  }
685 
686  if (ff55_lower_bits != 0) {
687  char err_buf[1000];
688  const int linkdown_bit = 15;
689  // const int packet_crcerr_bit = 8;
690  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
691  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot B eve %8u foooter %.8x : %s %s %d\n",
692  hostname, 1,
693  cur_ftsw_eve32,
694  m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
695  __FILE__, __PRETTY_FUNCTION__, __LINE__);
696  printf("%s", err_buf); fflush(stdout);
697  PrintData(m_buffer, m_nwords);
698  fflush(stdout);
699  B2FATAL(err_buf);
700  } else {
701  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
702  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
703  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x2 << 28);
704  sprintf(err_buf,
705  "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot B eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
706  hostname, 1,
707  cur_ftsw_eve32,
708  m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
709  __FILE__, __PRETTY_FUNCTION__, __LINE__);
710  printf("%s", err_buf); fflush(stdout);
711  PrintData(m_buffer, m_nwords);
712  fflush(stdout);
713  } else {
714  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
715  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x2 << 28);
716  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot B eve %8u foooter %.8x : %s %s %d\n",
717  hostname, 1,
718  cur_ftsw_eve32,
719  m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
720  __FILE__, __PRETTY_FUNCTION__, __LINE__);
721  printf("%s", err_buf); fflush(stdout);
722  PrintData(m_buffer, m_nwords);
723  fflush(stdout);
724  B2FATAL(err_buf);
725  }
726  }
727  }
728  }
729 
730  if (copper_buf[ POS_CH_C_DATA_LENGTH ] != 0) {
731  ff55_higher_bits = (unsigned int)(m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
732  0xFFFF0000;
733 
734  ff55_lower_bits = (m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
735  char hostname[128];
736  GetNodeName(hostname, m_node_id, sizeof(hostname));
737  if (ff55_higher_bits != 0xff550000) {
738  char err_buf[500];
739  sprintf(err_buf,
740  "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotC's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
741  hostname, 2,
742  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
743  m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
744  __FILE__, __PRETTY_FUNCTION__, __LINE__);
745  printf("%s", err_buf); fflush(stdout);
746  PrintData(m_buffer, m_nwords); fflush(stdout);
747  B2FATAL(err_buf);
748  }
749 
750  if (ff55_lower_bits != 0) {
751  char err_buf[1000];
752  const int linkdown_bit = 15;
753 
754  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
755  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot C eve %8u foooter %.8x : %s %s %d\n",
756  hostname, 2,
757  cur_ftsw_eve32,
758  m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
759  __FILE__, __PRETTY_FUNCTION__, __LINE__);
760  printf("%s", err_buf); fflush(stdout);
761  PrintData(m_buffer, m_nwords);
762  fflush(stdout);
763  B2FATAL(err_buf);
764  } else {
765  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
766  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
767  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x4 << 28);
768  sprintf(err_buf,
769  "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot C eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
770  hostname, 2,
771  cur_ftsw_eve32,
772  m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
773  __FILE__, __PRETTY_FUNCTION__, __LINE__);
774  printf("%s", err_buf); fflush(stdout);
775  PrintData(m_buffer, m_nwords);
776  fflush(stdout);
777  } else {
778  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
779  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x4 << 28);
780  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot C eve %8u foooter %.8x : %s %s %d\n",
781  hostname, 2,
782  cur_ftsw_eve32,
783  m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
784  __FILE__, __PRETTY_FUNCTION__, __LINE__);
785  printf("%s", err_buf); fflush(stdout);
786  PrintData(m_buffer, m_nwords);
787  fflush(stdout);
788  B2FATAL(err_buf);
789  }
790  }
791 
792  }
793  }
794 
795  if (copper_buf[ POS_CH_D_DATA_LENGTH ] != 0) {
796  ff55_higher_bits = (unsigned int)(m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
797  0xFFFF0000;
798 
799  ff55_lower_bits = (m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
800  char hostname[128];
801  GetNodeName(hostname, m_node_id, sizeof(hostname));
802  if (ff55_higher_bits != 0xff550000) {
803  char err_buf[500];
804  sprintf(err_buf,
805  "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotD's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
806  hostname, 3,
807  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
808  m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
809  __FILE__, __PRETTY_FUNCTION__, __LINE__);
810  printf("%s", err_buf); fflush(stdout);
811  PrintData(m_buffer, m_nwords); fflush(stdout);
812  B2FATAL(err_buf);
813  }
814 
815  if (ff55_lower_bits != 0) {
816  char err_buf[1000];
817  const int linkdown_bit = 15;
818 
819  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
820  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot D eve %8u foooter %.8x : %s %s %d\n",
821  hostname, 3,
822  cur_ftsw_eve32,
823  m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
824  __FILE__, __PRETTY_FUNCTION__, __LINE__);
825  printf("%s", err_buf); fflush(stdout);
826  PrintData(m_buffer, m_nwords);
827  fflush(stdout);
828  B2FATAL(err_buf);
829  } else {
830  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
831  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
832  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x8) << 28;
833  sprintf(err_buf,
834  "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot D eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
835  hostname, 3,
836  cur_ftsw_eve32,
837  m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
838  __FILE__, __PRETTY_FUNCTION__, __LINE__);
839  printf("%s", err_buf); fflush(stdout);
840  PrintData(m_buffer, m_nwords);
841  fflush(stdout);
842  } else {
843  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
844  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x8) << 28;
845  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot D eve %8u foooter %.8x : %s %s %d\n",
846  hostname, 3,
847  cur_ftsw_eve32,
848  m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
849  __FILE__, __PRETTY_FUNCTION__, __LINE__);
850  printf("%s", err_buf); fflush(stdout);
851  PrintData(m_buffer, m_nwords);
852  fflush(stdout);
853  B2FATAL(err_buf);
854  }
855  }
856  }
857  }
858 
859 
861  //
862  // Fill info in RawTrailer
863  //
865 
866  //
867  // Calculate XOR checksum
868  //
869  unsigned int chksum_top = 0, chksum_body = 0, chksum_bottom = 0;
870 
871  int top_end = tmp_header.RAWHEADER_NWORDS;
872  for (int i = 0; i < top_end; i++) {
873  chksum_top ^= m_buffer[ i ];
874  }
875  int body_end = datablock_nwords - SIZE_COPPER_DRIVER_TRAILER - tmp_trailer.RAWTRAILER_NWORDS;
876  for (int i = top_end; i < body_end; i++) {
877  chksum_body ^= m_buffer[ i ];
878  }
879 
880  int bottom_end = datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS;
881  for (int i = body_end; i < bottom_end; i++) {
882  chksum_bottom ^= m_buffer[ i ];
883  }
884 
885  //
886  // check COPPER driver checksum
887  //
888  if (chksum_body != (unsigned int)(m_buffer[ body_end ])) {
889  char err_buf[500];
890  char hostname[128];
891  GetNodeName(hostname, m_node_id, sizeof(hostname));
892  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : COPPER driver checksum is not consistent.: calcd. %.8x data %.8x\n %s %s %d\n",
893  hostname, -1,
894  chksum_body, m_buffer[ body_end ],
895  __FILE__, __PRETTY_FUNCTION__, __LINE__);
896  printf("%s", err_buf); fflush(stdout);
897  B2FATAL(err_buf); // to reduce multiple error messages
898  }
899 
900  //
901  // Fill trailer info (checksum, magic word)
902  //
903  unsigned int chksum = chksum_top ^ chksum_body ^ chksum_bottom;
904  int* trl = &(m_buffer[ datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS ]);
905  trl[ tmp_trailer.POS_CHKSUM ] = chksum;
906  trl[ tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
907 
908 
910  //
911  // Data check ( magic word, event incrementation )
912  //
914 
915 
916  //
917  // check magic words
918  //
919  int* fpga_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_3);
920  int* driver_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_4);
921  int err_flag = 0;
922  if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_1 ]) != COPPER_MAGIC_DRIVER_HEADER) {
923  err_flag = 1;
924  } else if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_2 ]) != COPPER_MAGIC_FPGA_HEADER) {
925  err_flag = 1;
926  } else if ((unsigned int)(*fpga_trailer_magic) != COPPER_MAGIC_FPGA_TRAILER) {
927  err_flag = 1;
928  } else if ((unsigned int)(*driver_trailer_magic) != COPPER_MAGIC_DRIVER_TRAILER) {
929  err_flag = 1;
930  }
931  if (err_flag == 1) {
932  char err_buf[500];
933  char hostname[128];
934  GetNodeName(hostname, m_node_id, sizeof(hostname));
935  sprintf(err_buf,
936  "[FATAL] %s ch=%d : ERROR_EVENT : Invalid Magic word 0x7FFFF0008=%u 0xFFFFFAFA=%u 0xFFFFF5F5=%u 0x7FFF0009=%u\n %s %s %d\n",
937  hostname, -1,
938  GetMagicDriverHeader(datablock_id),
939  GetMagicFPGAHeader(datablock_id),
940  GetMagicFPGATrailer(datablock_id),
941  GetMagicDriverTrailer(datablock_id),
942  __FILE__, __PRETTY_FUNCTION__, __LINE__);
943  printf("[DEBUG] %s\n", err_buf);
944 #ifndef NO_ERROR_STOP
945  B2FATAL(err_buf); // to reduce multiple error messages
946 #endif
947  }
948 
949  //
950  // check incrementation of event #
951  //
952 
953 
954  *cur_exprunsubrun_no = GetExpRunSubrun(datablock_id);
955 
956  // if ((unsigned int)cur_ftsw_eve32 < 50) {
957  // printf("EVENT OUTPUT ########## %u\n", cur_ftsw_eve32);
958  // PrintData(GetBuffer(datablock_id), TotalBufNwords());
959  // }
960  if (prev_exprunsubrun_no == *cur_exprunsubrun_no) {
961  if (prev_eve32 + 1 != cur_ftsw_eve32) {
962  unsigned int eve[4] = {0xbaadf00d, 0xbaadf00d, 0xbaadf00d, 0xbaadf00d };
963 #ifndef NO_ERROR_STOP
964  if (m_num_nodes * m_num_events != 1) {
965  char err_buf[500];
966  sprintf(err_buf,
967  "[FATAL] This function should be used for PreRawCOPPERFormat_v2 containing only one datablock, while. this object has num_nodes of %d and num_events of %d\n %s %s %d\n",
968  m_num_nodes, m_num_events, __FILE__, __PRETTY_FUNCTION__, __LINE__);
969  printf("%s", err_buf); fflush(stdout);
970  // string err_str = err_buf; throw (err_str);
971  B2FATAL(err_buf); // to reduce multiple error messages
972  } else {
973  for (int i = 0; i < 4 ; i++) {
974  // Only one block is in this m_buffer[] when m_num_nodes*m_num_events=1
975  // 0 is specified as a block number
976  if (GetFINESSENwords(0, i) > 0) {
977  int pos_nwords = GetOffsetFINESSE(0, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
978  eve[ i ] = m_buffer[ pos_nwords ];
979  }
980  }
981  }
982 
983  char err_buf[500];
984  char hostname[128];
985  GetNodeName(hostname, m_node_id, sizeof(hostname));
986  sprintf(err_buf,
987  "[FATAL] %s ch=%d : ERROR_EVENT : Invalid event_number. Exiting...: cur 32bit eve %u preveve %u ( A:0x%.8x B:0x%.8x C:0x%.8x D:0x%.8x ) prun %u crun %u\n %s %s %d\n",
988  hostname, -1,
989  cur_ftsw_eve32, prev_eve32,
990  eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
991  prev_exprunsubrun_no, *cur_exprunsubrun_no,
992  __FILE__, __PRETTY_FUNCTION__, __LINE__);
993  printf("[DEBUG] %s\n", err_buf);
994 
995  // string err_str = err_buf;
996  printf("[DEBUG] i= %d : num entries %d : Tot words %d\n", 0, GetNumEntries(), TotalBufNwords());
997  PrintData(GetBuffer(datablock_id), TotalBufNwords());
998 
999  for (int i = 0; i < 4; i++) {
1000  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", datablock_id, i);
1001  if (GetFINESSENwords(datablock_id, i) > 0) {
1002  CheckCRC16(datablock_id, i);
1003  }
1004  }
1005  printf("[DEBUG] ========== No CRC error : block %d =========\n", datablock_id);
1006  // throw (err_str);
1007  B2FATAL(err_buf); // to reduce multiple error messages
1008 #endif
1009 
1010  }
1011  }
1012 
1013  return cur_ftsw_eve32;
1014 
1015 }
1016 
1017 
1018 
1019 #ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
1020 void PreRawCOPPERFormat_v2::CheckB2LFEEHeaderVersion(int n)
1021 {
1022  int* temp_buf;
1023  for (int i = 0; i < 4; i++) {
1024  if (GetFINESSENwords(n, i) > 0) {
1025  temp_buf = GetFINESSEBuffer(n, i);
1026  if ((temp_buf[ 3 ] & 0x40000000) == 0) {
1027 #ifdef TEMP
1028  // this word for exp/run
1029  // old one (ver.1) used for SPring8 test in 2013
1030  printf("[DEBUG] \033[31m");
1031  printf("[DEBUG] ===Firmware ver. ERROR===\n ");
1032  printf("[DEBUG] FTSW and b2tt firmwares was updated on Nov.22, 2013 and the header format attached by B2link was changed in the new firmwares.\n");
1033  printf("[DEBUG] If you are going to take data now, Please update the firmware.\n");
1034  printf("[DEBUG] For details, please see Nakao-san's e-mail [b2link_ml:0111] Re: [daq2ml:0159] beta version of trigger timing receiver firmware (b2tt) on bdaq SVN\n");
1035  printf("[DEBUG] Or if you are going to read data taken before the update, please use basf2 software before svn revision 7419\n");
1036  printf("[DEBUG] About the format please see Nakao-san's B2GM slides(p. 13 and 15) http://kds.kek.jp/getFile.py/access?contribId=143&sessionId=38&resId=0&materialId=slides&confId=13911.\n");
1037  printf("[DEBUG] Sorry for inconvenience.\n");
1038  printf("[DEBUG] \033[0m");
1039  fflush(stderr);
1040  char err_buf[500];
1041  char hostname[128];
1042  GetNodeName(n, hostname, sizeof(hostname));
1043  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : FTSW and b2tt firmwares are old. Exiting...\n %s %s %d\n",
1044  hostname, i,
1045  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1046  B2FATAL(err_buf);
1047 #endif
1048  } else {
1049  // this word for 32bit unixtime
1050  // new one (ver.2)
1051  break;
1052  }
1053  }
1054 
1055  if (i == 3) {
1056 #ifdef TEMP
1057  char err_buf[500];
1058  char hostname[128];
1059  GetNodeName(n, hostname, sizeof(hostname));
1060  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : PreRawCOPPERFormat_v2 contains no FINESSE data. Exiting...\n %s %s %d\n",
1061  hostname, i,
1062  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1063  printf("%s", err_buf); fflush(stdout);
1064  // string err_str = err_buf; throw (err_str);
1065  B2FATAL(err_buf); // to reduce multiple error messages
1066 #endif
1067  }
1068  }
1069  return;
1070 }
1071 #endif
1072 
1073 //int PreRawCOPPERFormat_v2::CalcReducedDataSize(RawDataBlock* raw_datablk)
1074 int PreRawCOPPERFormat_v2::CalcReducedDataSize(int* bufin, int nwords, int num_events, int num_nodes)
1075 {
1076  //
1077  // Calculate reduced length for a total RawDataBlock (containing multiple data blocks)
1078  //
1079  RawDataBlockFormat radblk_fmt;
1080  int delete_flag = 0;
1081  radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
1082 
1083  int reduced_nwords = 0;
1084  for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
1085  int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
1086  for (int l = 0; l < num_nodes_in_sendblock; l++) {
1087  int entry_id = l + k * num_nodes_in_sendblock;
1088 
1089  if (radblk_fmt.CheckFTSWID(entry_id) || radblk_fmt.CheckTLUID(entry_id)) {
1090  reduced_nwords += radblk_fmt.GetBlockNwords(entry_id);
1091  } else {
1092  PreRawCOPPERFormat_v2 temp_prerawcpr;
1093  int temp_delete_flag = 0, temp_num_eve = 1, temp_num_nodes = 1;
1094 
1095  // Call CalcReducedNwords
1096  temp_prerawcpr.SetBuffer(radblk_fmt.GetBuffer(entry_id),
1097  radblk_fmt.GetBlockNwords(entry_id),
1098  temp_delete_flag, temp_num_eve,
1099  temp_num_nodes);
1100  reduced_nwords += temp_prerawcpr.CalcReducedNwords(0);
1101  }
1102  }
1103  }
1104  return reduced_nwords;
1105 
1106 }
1107 
1108 //void PreRawCOPPERFormat_v2::CopyReducedData(RawDataBlock* raw_datablk, int* buf_to, int delete_flag_from)
1109 void PreRawCOPPERFormat_v2::CopyReducedData(int* bufin, int nwords, int num_events, int num_nodes, int* buf_to, int* nwords_to)
1110 {
1111  //
1112  // Make a reduced buffer a total RawDataBlock (containing multiple data blocks)
1113  //
1114  RawDataBlockFormat radblk_fmt;
1115  int delete_flag = 0;
1116  radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
1117 
1118  int pos_nwords_to = 0;
1119  for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
1120  int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
1121  for (int l = 0; l < num_nodes_in_sendblock; l++) {
1122  int entry_id = l + k * num_nodes_in_sendblock;
1123  if (radblk_fmt.CheckFTSWID(entry_id) ||
1124  radblk_fmt.CheckTLUID(entry_id)) {
1125  radblk_fmt.CopyBlock(entry_id, buf_to + pos_nwords_to);
1126  pos_nwords_to += radblk_fmt.GetBlockNwords(entry_id);
1127 
1128  } else {
1129  SetBuffer(radblk_fmt.GetBuffer(entry_id),
1130  radblk_fmt.GetBlockNwords(entry_id), 0, 1, 1);
1131 
1132  pos_nwords_to += CopyReducedBuffer(0, buf_to + pos_nwords_to);
1133 
1134 
1135  }
1136  }
1137  }
1138 
1139  *nwords_to = pos_nwords_to;
1140 
1141  return ;
1142 }
1143 
1144 
1145 int PreRawCOPPERFormat_v2::CalcReducedNwords(int n)
1146 {
1147  //
1148  // Calculate reduced length for one data block which is a part of a RawDataBlock
1149  //
1150 
1151  int nwords_to = 0;
1152 
1153  //RawCOPPER header
1154  nwords_to += tmp_header.RAWHEADER_NWORDS;
1155 
1156  for (int j = 0; j < 4; j++) {
1157 
1158  int finesse_nwords = GetFINESSENwords(n, j);
1159  if (finesse_nwords > 0) {
1160  //
1161  // B2L(HSLB/FEE) header and trailers are resized
1162  // m_reduced_rawcpr should be PostRawCOPPERFormat_v2
1163  //
1164  nwords_to +=
1165  finesse_nwords
1166  - (static_cast<int>(SIZE_B2LHSLB_HEADER) - m_reduced_rawcpr.SIZE_B2LHSLB_HEADER)
1167  - (static_cast<int>(SIZE_B2LFEE_HEADER) - m_reduced_rawcpr.SIZE_B2LFEE_HEADER)
1168  - (static_cast<int>(SIZE_B2LFEE_TRAILER) - m_reduced_rawcpr.SIZE_B2LFEE_TRAILER)
1169  - (static_cast<int>(SIZE_B2LHSLB_TRAILER) - m_reduced_rawcpr.SIZE_B2LHSLB_TRAILER);
1170  }
1171 
1172  }
1173 
1174  //RawCOPPER Trailer
1175  nwords_to += tmp_trailer.GetTrlNwords();
1176 
1177  return nwords_to;
1178 }
1179 
1180 
1181 
1182 
1183 
1184 
1185 int PreRawCOPPERFormat_v2::CopyReducedBuffer(int n, int* buf_to)
1186 {
1187  //
1188  // Make a reduced buffer for one data block which is a part of a RawDataBlock
1189  //
1190 
1191  int* buf_from = NULL;
1192  int nwords_buf_to = CalcReducedNwords(n);
1193  int pos_nwords_to = 0;
1194  int copy_nwords = 0;
1195 
1196  unsigned int removed_xor_chksum = 0;
1197 
1198  // copyt to ReducedRawCOPPER
1199  // ReducedRawCOPPER m_reduced_rawcpr;
1200  //Header copy
1201  copy_nwords = tmp_header.RAWHEADER_NWORDS;
1202  buf_from = GetBuffer(n);
1203  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1204 
1205 
1206  //calcurate XOR checksum diff.( depends on data-format )
1207  removed_xor_chksum ^= buf_from[ tmp_header.POS_VERSION_HDRNWORDS ];
1208 
1209  // Unset the PreFormat bit ( 15th bit )
1210  buf_to[ tmp_header.POS_VERSION_HDRNWORDS ] &= 0xFFFF7FFF;
1211 
1212  //calcurate XOR checksum diff.( depends on data-format )
1213  removed_xor_chksum ^= buf_to[ tmp_header.POS_VERSION_HDRNWORDS ];
1214  for (int i = 0; i < SIZE_COPPER_HEADER; i++) {
1215  removed_xor_chksum ^= buf_from[ tmp_header.RAWHEADER_NWORDS + i ];
1216  }
1217 
1218  //Check Header
1219  // m_reduced_rawcpr.tmp_header.CheckHeader(buf_to + pos_nwords_to - copy_nwords);
1220 
1221 
1222  // copy FINESSE buffer
1223  int pos_nwords_finesse[ 4 ];
1224  for (int j = 0; j < 4; j++) {
1225  pos_nwords_finesse[ j ] = pos_nwords_to;
1226  if (GetFINESSENwords(n, j) > 0) {
1227  int* finesse_buf = GetFINESSEBuffer(n, j);
1228  int finesse_nwords = GetFINESSENwords(n, j);
1229 
1230 
1231  CheckB2LHSLBMagicWords(finesse_buf, finesse_nwords);
1232  // copy the whole B2LHSLB header (1word)
1233  buf_to[ pos_nwords_to ] = finesse_buf[ POS_MAGIC_B2LHSLB ];
1234  pos_nwords_to++;
1235 
1236  // copy the last word of B2LFEE and body( DetectorBuffer )
1237  buf_from =
1238  finesse_buf
1239  + SIZE_B2LHSLB_HEADER
1240  + POS_B2L_CTIME; //the last word of B2LFEE
1241 
1242 
1243  // check finesse buffer size : ( When dumhslb was used, this type of error
1244  // occured and RecvStream0.py died by Segmentation Fault. ) 2014.12.01.
1245  if (finesse_nwords - SIZE_B2LHSLB_HEADER - SIZE_B2LFEE_HEADER
1246  - SIZE_B2LFEE_TRAILER - SIZE_B2LHSLB_TRAILER < 0) {
1247  char err_buf[500];
1248  char hostname[128];
1249  GetNodeName(n, hostname, sizeof(hostname));
1250  sprintf(err_buf,
1251  "[FATAL] %s ch=%d : ERROR_EVENT : Finesse buffer size is too small( %d words < %d words). May be the data are corrupted. Exiting...\n %s %s %d\n",
1252  hostname, j,
1253  finesse_nwords, static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER,
1254  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1255  printf("%s", err_buf); fflush(stdout);
1256  // string err_str = err_buf; throw (err_str);
1257  B2FATAL(err_buf); // to reduce multiple error messages
1258  }
1259 
1260  //calcurate XOR checksum diff.( depends on data-format )
1261  for (int k = 1; k <= 4 ; k++) {
1262  removed_xor_chksum ^= finesse_buf[ k ];
1263  }
1264 
1265  copy_nwords =
1266  finesse_nwords
1267  - SIZE_B2LHSLB_HEADER // already copied
1268  - POS_B2L_CTIME // only one word copied ( SIZE_B2LFEE_HEADER - 1 = POS_B2L_CTIME )
1269  - SIZE_B2LFEE_TRAILER // will be copied later
1270  - SIZE_B2LHSLB_TRAILER; // Not copied
1271  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1272  // printf("pos %d nwords %d nwords to %d\n", pos_nwords_to, copy_nwords, nwords_buf_to );
1273 
1274  //copy B2LFEE trailer(CRC info)
1275  buf_to[ pos_nwords_to ] = 0xffff & finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER - (SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) ];
1276  //copy B2LHSLB trailer(packet CRC error count)
1277  buf_to[ pos_nwords_to ] |= (finesse_buf[ finesse_nwords - (static_cast<int>(SIZE_B2LHSLB_TRAILER) - POS_MAGIC_B2LHSLB) ] << 16) &
1278  0xFFFF0000;
1279 
1280  //calcurate XOR checksum diff. ( depends on data-format )
1281  for (int k = 0; k <= 2 ; k++) {
1282  removed_xor_chksum ^= finesse_buf[ finesse_nwords - SIZE_B2LFEE_TRAILER - SIZE_B2LHSLB_TRAILER + k ];
1283  }
1284  removed_xor_chksum ^= buf_to[ pos_nwords_to ];
1285 
1286  pos_nwords_to++;
1287 
1288  // check CRC data
1289  // CheckCRC16( n, j );
1290  }
1291  }
1292 
1293  // copy RawCOPPER trailer
1294  buf_from =
1295  GetBuffer(n)
1296  + GetBlockNwords(n)
1297  - tmp_trailer.GetTrlNwords();
1298  copy_nwords = tmp_trailer.GetTrlNwords();
1299  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1300 
1301  //calcurate XOR checksum diff.( depends on data-format )
1302  unsigned int old_rawcopper_chksum = buf_from[ tmp_trailer.POS_CHKSUM ];
1303  for (int i = 0; i < SIZE_COPPER_TRAILER; i++) {
1304  removed_xor_chksum ^= (unsigned int) * (buf_from - SIZE_COPPER_TRAILER + i);
1305  }
1306 
1307 
1308  // length check
1309  if (pos_nwords_to != nwords_buf_to) {
1310  char err_buf[500];
1311  sprintf(err_buf, "Buffer overflow. Exiting... %d %d\n", pos_nwords_to, nwords_buf_to);
1312  printf("%s", err_buf); fflush(stdout);
1313  B2FATAL(err_buf);
1314  }
1315 
1316 
1317  // Recalculate XOR checksum in a RawCOPPER trailer
1318  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS);
1319  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE);
1320  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE);
1321  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE);
1322  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE);
1323 
1324  //
1325  // Apply changes followed by data size reduction
1326  //
1327  *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS) = nwords_buf_to;
1328  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE) = pos_nwords_finesse[ 0 ];
1329  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE) = pos_nwords_finesse[ 1 ];
1330  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE) = pos_nwords_finesse[ 2 ];
1331  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE) = pos_nwords_finesse[ 3 ];
1332 
1333  // Recalculate XOR checksum in a RawCOPPER trailer
1334  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS);
1335  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE);
1336  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE);
1337  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE);
1338  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE);
1339 
1340  // Recalculate XOR checksum in a RawCOPPER trailer
1341  unsigned int new_rawcopper_chksum = CalcXORChecksum(buf_to, pos_nwords_to - tmp_trailer.GetTrlNwords());
1342 
1343 
1344  if ((old_rawcopper_chksum ^ removed_xor_chksum) != new_rawcopper_chksum) {
1345  char err_buf[500];
1346  char hostname[128];
1347  GetNodeName(n, hostname, sizeof(hostname));
1348  sprintf(err_buf,
1349  "[FATAL] %s ch=%d : ERROR_EVENT : RawCOPPER XOR checksum is inconsistent between before/after data reduction.(%.8x != %.8x ^ %.8x = %.8x ) Exiting...\n %s %s %d\n",
1350  hostname, -1,
1351  new_rawcopper_chksum, old_rawcopper_chksum, removed_xor_chksum, old_rawcopper_chksum ^ removed_xor_chksum,
1352  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1353  printf("%s", err_buf); fflush(stdout);
1354  B2FATAL(err_buf); // to reduce multiple error messages
1355  }
1356 
1357  *(buf_to + pos_nwords_to - tmp_trailer.GetTrlNwords() + tmp_trailer.POS_CHKSUM) = new_rawcopper_chksum;
1358 
1359 
1360 
1361  //
1362  // data block # check
1363  //
1364  m_reduced_rawcpr.SetBuffer(buf_to, nwords_buf_to, 0, GetNumEvents(), GetNumNodes());
1365  if (m_reduced_rawcpr.GetNumEvents() * m_reduced_rawcpr.GetNumNodes() <= 0) {
1366  char err_buf[500];
1367  sprintf(err_buf, "Invalid data block numbers.(# of events %d, # of nodes %d) Exiting...\n",
1368  m_reduced_rawcpr.GetNumEvents(), m_reduced_rawcpr.GetNumNodes());
1369  printf("%s", err_buf); fflush(stdout);
1370  B2FATAL(err_buf);
1371  }
1372 
1373  //
1374  // check no-data buffer
1375  //
1376  for (int i = 0; i < m_reduced_rawcpr.GetNumEvents() * m_reduced_rawcpr.GetNumNodes(); i++) {
1377  int nonzero_finesse_buf = 0;
1378  for (int j = 0; j < 4; j++) {
1379 
1380  if (GetFINESSENwords(n, j) > 0) {
1381  // m_reduced_rawcpr.CheckCRC16(i, j);
1382  nonzero_finesse_buf++;
1383  }
1384  }
1385  if (nonzero_finesse_buf == 0) {
1386  char err_buf[500];
1387  sprintf(err_buf, "No non-zero FINESSE buffer. Exiting...\n");
1388  printf("%s", err_buf); fflush(stdout);
1389  B2FATAL(err_buf);
1390  }
1391  }
1392 
1393  // post_rawcopper_v2.CheckCRC16(0, 0);
1394  // printf("fROM =======================================\n");
1395  // for (int k = 0; k < nwords_buf_to; k++) {
1396  // printf(" %.8x", GetBuffer(n)[ k ]);
1397  // if ( ( k + 1 ) % 10 == 0) {
1398  // printf("\n");
1399  // }
1400  // }
1401  // printf("\n");
1402 
1403  // printf("tO =======================================\n");
1404  // for (int k = 0; k < nwords_buf_to; k++) {
1405  // printf(" %.8x", buf_to[ k ]);
1406  // if ( ( k + 1 ) % 10 == 0) {
1407  // printf("\n");
1408  // }
1409  // }
1410  // printf("\n");
1411  // printf("=============================================\n");
1412  return pos_nwords_to;
1413 }
1414 
1415 
1416 int PreRawCOPPERFormat_v2::CheckB2LHSLBMagicWords(int* finesse_buf, int finesse_nwords)
1417 {
1418 
1419  if ((finesse_buf[ POS_MAGIC_B2LHSLB ] & 0xFFFF0000) == B2LHSLB_HEADER_MAGIC &&
1420  ((finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ] & 0xFFFF0000)
1421  == B2LHSLB_TRAILER_MAGIC)) {
1422  return 1;
1423  } else {
1424  PrintData(m_buffer, m_nwords);
1425  char err_buf[500];
1426  sprintf(err_buf,
1427  "Invalid B2LHSLB magic words : header 0x%x (= should be ffaa**** ) or trailer 0x%x (= should be ff55**** ). Exiting... :%s %s %d\n",
1428  finesse_buf[ POS_MAGIC_B2LHSLB ],
1429  finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ],
1430  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1431 #ifndef NO_ERROR_STOP
1432  printf("%s", err_buf); fflush(stdout);
1433  B2FATAL(err_buf);
1434 #endif
1435  }
1436 }
1437 
1438 
1439 
1440 int PreRawCOPPERFormat_v2::CheckCRC16(int n, int finesse_num)
1441 {
1442  //
1443  // Calculate CRC16
1444  //
1445  int* buf = GetFINESSEBuffer(n, finesse_num) + SIZE_B2LHSLB_HEADER;
1446  int nwords = GetFINESSENwords(n, finesse_num) - (static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_TRAILER +
1447  SIZE_B2LHSLB_TRAILER);
1448  unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, buf, nwords);
1449 
1450  //
1451  // Compare CRC16 with B2LCRC16
1452  //
1453  buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n, finesse_num)
1454  - ((SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) + SIZE_B2LHSLB_TRAILER) ;
1455 
1456  if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
1457  PrintData(GetBuffer(n), *(GetBuffer(n) + tmp_header.POS_NWORDS));
1458  char err_buf[500];
1459  char hostname[128];
1460  GetNodeName(n, hostname, sizeof(hostname));
1461  printf("[FATAL] %s ch=%d : ERROR_EVENT : PRE CRC16 error : slot %c : B2LCRC16 %x Calculated CRC16 %x : Nwords of FINESSE buf %d\n",
1462  hostname, finesse_num,
1463  65 + finesse_num, *buf, temp_crc16, GetFINESSENwords(n, finesse_num));
1464  int* temp_buf = GetFINESSEBuffer(n, finesse_num);
1465  for (int k = 0; k < GetFINESSENwords(n, finesse_num); k++) {
1466  printf("%.8x ", temp_buf[ k ]);
1467  if ((k + 1) % 10 == 0) {
1468  printf("\n");
1469  }
1470  }
1471  printf("\n");
1472  fflush(stdout);
1473  sprintf(err_buf,
1474  "[FATAL] %s ch=%d : ERROR_EVENT : slot %c : B2LCRC16 (%.4x) differs from one ( %.4x) calculated by PreRawCOPPERfromat class. Exiting...\n %s %s %d\n",
1475  hostname, finesse_num,
1476  65 + finesse_num, (unsigned short)(*buf & 0xFFFF), temp_crc16,
1477  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1478  printf("%s", err_buf); fflush(stdout);
1479  B2FATAL(err_buf); // to reduce multiple error messages
1480  }
1481  return 1;
1482 
1483 }
1484 
1485 int* PreRawCOPPERFormat_v2::PackDetectorBuf(int* packed_buf_nwords,
1486  int* detector_buf_1st, int nwords_1st,
1487  int* detector_buf_2nd, int nwords_2nd,
1488  int* detector_buf_3rd, int nwords_3rd,
1489  int* detector_buf_4th, int nwords_4th,
1490  RawCOPPERPackerInfo rawcpr_info)
1491 {
1492  int* packed_buf = NULL;
1493 
1494  int poswords_to = 0;
1495  int* detector_buf[ 4 ] = { detector_buf_1st, detector_buf_2nd, detector_buf_3rd, detector_buf_4th };
1496  const int nwords[ 4 ] = { nwords_1st, nwords_2nd, nwords_3rd, nwords_4th };
1497 
1498  // calculate the event length
1499  int length_nwords = tmp_header.GetHdrNwords() + SIZE_COPPER_HEADER + SIZE_COPPER_TRAILER + tmp_trailer.GetTrlNwords();
1500 
1501  for (int i = 0; i < 4; i++) {
1502  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1503  length_nwords += nwords[ i ];
1504  length_nwords += static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER
1505  + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1506  }
1507 
1508  // allocate buffer
1509  packed_buf = new int[ length_nwords ];
1510  memset(packed_buf, 0, sizeof(int) * length_nwords);
1511 
1512  //
1513  // Fill RawHeader
1514  //
1515  tmp_header.SetBuffer(packed_buf);
1516 
1517  packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
1518  packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] = 0x7f7f8000
1519  | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
1520  | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
1521  packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT)
1522  | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
1523  packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
1524  packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
1525  packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
1526  packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
1527 
1528 
1529 
1530 
1531  // fill the positions of finesse buffers
1532  packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ] = static_cast<int>(tmp_header.RAWHEADER_NWORDS) + SIZE_COPPER_HEADER;
1533 
1534  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ];
1535  if (nwords[ 0 ] > 0) {
1536  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] +=
1537  nwords[ 0 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1538  }
1539 
1540  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ];
1541  if (nwords[ 1 ] > 0) {
1542  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] +=
1543  nwords[ 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1544  }
1545 
1546  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ];
1547  if (nwords[ 2 ] > 0) {
1548  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] += nwords[ 2 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER +
1549  SIZE_B2LHSLB_TRAILER;
1550  }
1551  poswords_to += tmp_header.GetHdrNwords();
1552 
1553  // Fill COPPER header
1554  packed_buf[ poswords_to + POS_MAGIC_COPPER_1 ] = COPPER_MAGIC_DRIVER_HEADER;
1555  packed_buf[ poswords_to + POS_MAGIC_COPPER_2 ] = COPPER_MAGIC_FPGA_HEADER;
1556  packed_buf[ poswords_to + POS_EVE_NUM_COPPER ] = rawcpr_info.eve_num;
1557 
1558  int size_b2l_hdrtrl = static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1559  if (nwords[ 0 ] != 0) packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] = nwords[ 0 ] + size_b2l_hdrtrl;
1560  if (nwords[ 1 ] != 0) packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] = nwords[ 1 ] + size_b2l_hdrtrl;
1561  if (nwords[ 2 ] != 0) packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] = nwords[ 2 ] + size_b2l_hdrtrl;
1562  if (nwords[ 3 ] != 0) packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] = nwords[ 3 ] + size_b2l_hdrtrl;
1563 
1564  packed_buf[ poswords_to + POS_DATA_LENGTH ] =
1565  packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] +
1566  packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] +
1567  packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] +
1568  packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] +
1569  (static_cast<int>(SIZE_COPPER_HEADER) - SIZE_COPPER_DRIVER_HEADER) +
1570  (static_cast<int>(SIZE_COPPER_TRAILER) - SIZE_COPPER_DRIVER_TRAILER);
1571 
1572  poswords_to += SIZE_COPPER_HEADER;
1573 
1574  // Fill FINESSE buffer
1575  for (int i = 0; i < 4; i++) {
1576 
1577  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1578 
1579  // Fill b2link HSLB header
1580  packed_buf[ poswords_to + POS_MAGIC_B2LHSLB ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
1581  poswords_to += SIZE_B2LHSLB_HEADER;
1582  int* crc16_start = &(packed_buf[ poswords_to ]);
1583 
1584  // Fill b2link FEE header
1585 
1586  packed_buf[ poswords_to + POS_TT_CTIME_TYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4;
1587  unsigned int temp_ctime_type = packed_buf[ poswords_to + POS_TT_CTIME_TYPE ];
1588  packed_buf[ poswords_to + POS_TT_TAG ] = rawcpr_info.eve_num;
1589  packed_buf[ poswords_to + POS_TT_UTIME ] = rawcpr_info.tt_utime;
1590  packed_buf[ poswords_to + POS_EXP_RUN ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT) | (rawcpr_info.run_subrun_num &
1591  0x003FFFFF); // exp. and run #
1592  packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
1593  poswords_to += SIZE_B2LFEE_HEADER;
1594 
1595  // copy the 1st Detector Buffer
1596  memcpy(packed_buf + poswords_to, detector_buf[ i ], nwords[ i ]*sizeof(int));
1597  poswords_to += nwords[ i ];
1598 
1599  // Fill b2link b2tt-tag trailer
1600  packed_buf[ poswords_to + POS_TT_CTIME_B2LFEE ] = temp_ctime_type;
1601 
1602  // Fill b2link FEE trailer
1603  unsigned short crc16 = CalcCRC16LittleEndian(0xffff, crc16_start, nwords[ i ] + SIZE_B2LFEE_HEADER);
1604  packed_buf[ poswords_to + POS_CHKSUM_B2LFEE ] = ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 & 0xffff);
1605  poswords_to += SIZE_B2LFEE_TRAILER;
1606 
1607  // Fill b2link HSLB trailer
1608  packed_buf[ poswords_to + POS_CHKSUM_B2LHSLB ] = 0xff550000;
1609  poswords_to += SIZE_B2LHSLB_TRAILER;
1610 
1611  }
1612 
1613  // Fill COPPER trailer
1614  packed_buf[ poswords_to + POS_MAGIC_COPPER_3 ] = COPPER_MAGIC_FPGA_TRAILER;
1615  packed_buf[ poswords_to + POS_MAGIC_COPPER_4 ] = COPPER_MAGIC_DRIVER_TRAILER;
1616  unsigned int chksum = 0;
1617  for (int i = tmp_header.GetHdrNwords(); i < poswords_to + (static_cast<int>(SIZE_COPPER_TRAILER) - SIZE_COPPER_DRIVER_TRAILER);
1618  i++) {
1619  chksum ^= packed_buf[ i ];
1620  }
1621  packed_buf[ poswords_to + POS_CHKSUM_COPPER ] = chksum;
1622  poswords_to += SIZE_COPPER_TRAILER;
1623 
1624  // Calculate RawCOPPER checksum and fill RawTrailer
1625  chksum = 0;
1626  for (int i = 0; i < poswords_to; i++) {
1627  chksum ^= packed_buf[ i ];
1628  }
1629  packed_buf[ poswords_to + tmp_trailer.POS_CHKSUM ] = chksum;
1630 
1631  packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
1632  poswords_to += tmp_trailer.GetTrlNwords();
1633 
1634  *packed_buf_nwords = poswords_to;
1635  return packed_buf;
1636 }
The Raw COPPER class ver.1 ( the latest version since May, 2014 ) This class stores data received by ...
int CalcReducedNwords(int n)
calculate reduced data size
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)
The RawDataBlockFormat class Format information for rawdata handling.
virtual int GetBlockNwords(int n)
get size of a data block
virtual int CheckFTSWID(int n)
get FTSW ID to check whether this data block is FTSW data or not
virtual void CopyBlock(int n, int *buf_to)
Copy one datablock to buffer.
virtual void SetBuffer(int *bufin, int nwords, int delete_flag, int num_events, int num_nodes)
set buffer ( delete_flag : m_buffer is freeed( = 0 )/ not freeed( = 1 ) in Destructer )
virtual int GetNumNodes()
get # of data sources(e.g. # of COPPER boards) in m_buffer
virtual int * GetBuffer(int n)
get nth buffer pointer
virtual int GetNumEvents()
get # of events in m_buffer
virtual int CheckTLUID(int n)
get FTSW ID to check whether this data block is FTSW data or not
Abstract base class for different kinds of events.