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