Belle II Software  release-05-02-19
PreRawCOPPERFormat_v2.cc
1 //+
2 // File : PreRawCOPPERFormat_v2.cc
3 // Description : Module to handle raw data from COPPER.
4 //
5 // Author : Satoru Yamada, IPNS, KEK
6 // Date : 2 - Aug - 2013
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 %d sub %u ) cur(exp %u run %d 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 
374  memset(utime, 0, sizeof(utime));
375  memset(ctime_trgtype, 0, sizeof(ctime_trgtype));
376  memset(eve, 0, sizeof(eve));
377  memset(exprun, 0, sizeof(exprun));
378 
379 
380  for (int i = 0; i < 4; i++) {
381  int finesse_nwords = GetFINESSENwords(n, i);
382  if (finesse_nwords > 0) {
383  int offset_finesse = GetOffsetFINESSE(n, i);
384  ctime_trgtype[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_CTIME_TYPE ];
385  utime[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_UTIME ];
386  eve[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_TAG ];
387  exprun[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_EXP_RUN ];
388  temp_ctime_trgtype_footer =
389  m_buffer[ offset_finesse + finesse_nwords - (SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER) + POS_TT_CTIME_B2LFEE ];
390  temp_eve_footer =
391  m_buffer[ offset_finesse + finesse_nwords - (SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER) + POS_CHKSUM_B2LFEE ];
392 
393  if (flag == 0) {
394  temp_ctime_trgtype = ctime_trgtype[ i ];
395  temp_utime = utime[ i ];
396  temp_eve = eve[ i ];
397  temp_exprun = exprun[ i ];
398  flag = 1;
399  } else {
400  if (temp_ctime_trgtype != ctime_trgtype[ i ] || temp_utime != utime[ i ] ||
401  temp_eve != eve[ i ] || temp_exprun != exprun[ i ]) {
402  if (err_flag == 0) {
403  for (int j = 0; j < 4; j++) {
404  printf("[DEBUG] FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x\n",
405  j, GetFINESSENwords(n, j), ctime_trgtype[ j ], utime[ j ], eve[ j ], exprun[ j ]);
406  }
407  }
408 
409  char hostname[128];
410  GetNodeName(n, hostname, sizeof(hostname));
411  sprintf(err_buf,
412  "[FATAL] %s ch=%d : ERROR_EVENT : mismatch header value over FINESSEs. Exiting... FINESSE #=0 buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x FINESSE #=1 buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x FINESSE #=2 buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x FINESSE #=3 buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x\n %s %s %d\n",
413  hostname, -1,
414  GetFINESSENwords(n, 0), ctime_trgtype[ 0 ], utime[ 0 ], eve[ 0 ], exprun[ 0 ],
415  GetFINESSENwords(n, 1), ctime_trgtype[ 1 ], utime[ 1 ], eve[ 1 ], exprun[ 1 ],
416  GetFINESSENwords(n, 2), ctime_trgtype[ 2 ], utime[ 2 ], eve[ 2 ], exprun[ 2 ],
417  GetFINESSENwords(n, 3), ctime_trgtype[ 3 ], utime[ 3 ], eve[ 3 ], exprun[ 3 ],
418  __FILE__, __PRETTY_FUNCTION__, __LINE__);
419  printf("%s", err_buf); fflush(stdout);
420 
421  err_flag = 1;
422  break;
423  } else if (temp_ctime_trgtype != temp_ctime_trgtype_footer ||
424  (temp_eve & 0xffff) != ((temp_eve_footer >> 16) & 0xffff)) {
425  char hostname[128];
426  GetNodeName(n, hostname, sizeof(hostname));
427  sprintf(err_buf,
428  "[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",
429  hostname, i,
430  i, temp_ctime_trgtype, temp_eve, temp_ctime_trgtype_footer, temp_eve_footer,
431  __FILE__, __PRETTY_FUNCTION__, __LINE__);
432  printf("%s", err_buf); fflush(stdout);
433  err_flag = 1;
434  }
435  }
436  }
437  }
438 
439  if (err_flag != 0) {
440  for (int i = 0; i < 4; i++) {
441  if (GetFINESSENwords(n, i) > 0) {
442  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
443  CheckCRC16(n, i);
444  printf("[DEBUG] ========== CRC check is done. : block %d =========\n", n);
445  }
446  }
447 #ifndef NO_ERROR_STOP
448  // string err_str = err_buf; throw (err_str);
449  B2FATAL(err_buf); // to reduce multiple error messages
450 #endif
451  }
452  return;
453 }
454 
455 unsigned int PreRawCOPPERFormat_v2::FillTopBlockRawHeader(unsigned int m_node_id, unsigned int prev_eve32,
456  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
457 {
458  const int datablock_id = 0;
459  // m_temp_value = 12345678;
460  //
461  // This function only fills RawHeader contents for the first datablock.
462  // # of block should be 1
463  if (m_num_nodes * m_num_events != 1) {
464  char err_buf[500];
465  sprintf(err_buf,
466  "[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",
467  m_num_nodes, m_num_events, __FILE__, __PRETTY_FUNCTION__, __LINE__);
468  printf("%s", err_buf); fflush(stdout);
469  // string err_str = err_buf; throw (err_str);
470  B2FATAL(err_buf); // to reduce multiple error messages
471  }
472 
474  //
475  // Fill info in RawHeader
476  //
478 
479  //
480  // Initialize a RawHeader part
481  //
482  memset(m_buffer, 0, sizeof(int) * tmp_header.RAWHEADER_NWORDS);
483  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] = tmp_header.RAWHEADER_NWORDS & tmp_header.HDR_NWORDS_MASK;
484  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) &
485  tmp_header.FORMAT_VERSION__MASK;
486  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (0x80 << tmp_header.FORMAT_VERSION_SHIFT); // PreFormat
487  m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= tmp_header.MAGIC_WORD;
488 
489  //
490  // Check FINESSEs which containes data
491  //
492  int* copper_buf = &(m_buffer[ tmp_header.RAWHEADER_NWORDS ]);
493  if (copper_buf[ POS_CH_A_DATA_LENGTH ] == 0 &&
494  copper_buf[ POS_CH_B_DATA_LENGTH ] == 0 &&
495  copper_buf[ POS_CH_C_DATA_LENGTH ] == 0 &&
496  copper_buf[ POS_CH_D_DATA_LENGTH ] == 0) {
497  char err_buf[500];
498  char hostname[128];
499  GetNodeName(hostname, m_node_id , sizeof(hostname));
500  sprintf(err_buf,
501  "[FATAL] %s ch=%d : ERROR_EVENT : No FINESSE data in a copper data block. Exiting...\n %s %s %d\n",
502  hostname, -1,
503  __FILE__, __PRETTY_FUNCTION__, __LINE__);
504  printf("%s", err_buf); fflush(stdout);
505  // string err_str = err_buf; throw (err_str);
506  B2FATAL(err_buf); // to reduce multiple error messages
507  }
508 
509  //
510  // Set total words info
511  //
512  int datablock_nwords =
513  tmp_header.RAWHEADER_NWORDS +
514  (copper_buf[ POS_DATA_LENGTH ]
515  + SIZE_COPPER_DRIVER_HEADER
516  + SIZE_COPPER_DRIVER_TRAILER)
517  + tmp_trailer.RAWTRAILER_NWORDS;
518  m_buffer[ tmp_header.POS_NWORDS ] = datablock_nwords;
519 
520 
521  //
522  // Check the consistency between data length and length in RawHeader
523  //
524  if (m_buffer[ tmp_header.POS_NWORDS ] != m_nwords) {
525  char err_buf[500];
526 
527  char hostname[128];
528  GetNodeName(hostname, m_node_id , sizeof(hostname));
529  sprintf(err_buf,
530  "[FATAL] %s ch=%d : ERROR_EVENT : Data length is inconsistent m_nwords %d : nwords from COPPER data %d\n %s %s %d\n",
531  hostname, -1,
532  m_nwords, m_buffer[ tmp_header.POS_NWORDS ],
533  __FILE__, __PRETTY_FUNCTION__, __LINE__);
534  printf("%s", err_buf); fflush(stdout);
535  // string err_str = err_buf; throw (err_str);
536  B2FATAL(err_buf); // to reduce multiple error messages
537  }
538 
539  //
540  // Fill offset values
541  //
542  int offset_1st_finesse = tmp_header.RAWHEADER_NWORDS + SIZE_COPPER_HEADER;
543  int offset_2nd_finesse = offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ];
544  int offset_3rd_finesse = offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ];
545  int offset_4th_finesse = offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ];
546  m_buffer[ tmp_header.POS_OFFSET_1ST_FINESSE ] = offset_1st_finesse;
547  m_buffer[ tmp_header.POS_OFFSET_2ND_FINESSE ] = offset_2nd_finesse;
548  m_buffer[ tmp_header.POS_OFFSET_3RD_FINESSE ] = offset_3rd_finesse;
549  m_buffer[ tmp_header.POS_OFFSET_4TH_FINESSE ] = offset_4th_finesse;
550 
551  //
552  // Fill Exp/Run value
553  //
554  int* finesse_buf = &
555  (m_buffer[ offset_1st_finesse ]); // In any finesse implementations, the top finesse buffer should be at offset_1st_finesse;
556  m_buffer[ tmp_header.POS_EXP_RUN_NO ] = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_EXP_RUN ];
557 
558 
559  //
560  // Fill event #
561  //
562  unsigned int cur_ftsw_eve32 = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_TT_TAG ];
563  m_buffer[ tmp_header.POS_EVE_NO ] = cur_ftsw_eve32;
564 
565  //
566  // Copy FTSW words from B2LFEE header
567  //
568  m_buffer[ tmp_header.POS_TTCTIME_TRGTYPE ] = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_TT_CTIME_TYPE ];
569  m_buffer[ tmp_header.POS_TTUTIME ] = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_TT_UTIME ];
570 
571  //
572  // Set node ID, trunc_mask, data_type
573  //
574  m_buffer[ tmp_header.POS_NODE_ID ] = m_node_id;
575 
576  //
577  // Check error counts of b2link-packet CRC
578  //
579  // m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] = ((m_trunc_mask << 31) & 0x80000000) | (m_data_type & 0x7FFFFFFF);
580  // printf("%.8x %.8x %.8x %.8x : %.8x\n",
581  // copper_buf[ POS_CH_A_DATA_LENGTH ], copper_buf[ POS_CH_B_DATA_LENGTH ],
582  // 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 ] );
583 
584  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] = 0;
585  unsigned int ff55_higher_bits, ff55_lower_bits;
586 
587  if (copper_buf[ POS_CH_A_DATA_LENGTH ] != 0) {
588  ff55_higher_bits = (unsigned int)(m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
589  0xFFFF0000;
590 
591  ff55_lower_bits = m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF;
592 
593  if (ff55_higher_bits != 0xff550000) {
594  char err_buf[500];
595  char hostname[128];
596  GetNodeName(hostname, m_node_id , sizeof(hostname));
597  sprintf(err_buf,
598  "[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",
599  hostname, 0,
600  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
601  m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
602  __FILE__, __PRETTY_FUNCTION__, __LINE__);
603  printf("%s", err_buf); fflush(stdout);
604  PrintData(m_buffer, m_nwords); fflush(stdout);
605  B2FATAL(err_buf);
606  }
607 
608  if (ff55_lower_bits != 0) {
609  const int linkdown_bit = 15;
610  // const int packet_crcerr_bit = 8;
611  char err_buf[500];
612  char hostname[128];
613  GetNodeName(hostname, m_node_id , sizeof(hostname));
614 
615  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
616  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot A eve %8u foooter %.8x : %s %s %d\n",
617  hostname, 0,
618  cur_ftsw_eve32,
619  m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
620  __FILE__, __PRETTY_FUNCTION__, __LINE__);
621  printf("%s", err_buf); fflush(stdout);
622  PrintData(m_buffer, m_nwords);
623  fflush(stdout);
624  B2FATAL(err_buf);
625  } else {
626  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
627  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
628  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x1 << 28);
629  sprintf(err_buf,
630  "[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",
631  hostname, 0,
632  cur_ftsw_eve32,
633  m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
634  __FILE__, __PRETTY_FUNCTION__, __LINE__);
635  printf("%s", err_buf); fflush(stdout);
636  PrintData(m_buffer, m_nwords);
637  fflush(stdout);
638  } else {
639  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
640  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x1 << 28);
641  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot A eve %8u foooter %.8x : %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  B2FATAL(err_buf);
650  }
651  }
652  }
653  }
654 
655  if (copper_buf[ POS_CH_B_DATA_LENGTH ] != 0) {
656  ff55_higher_bits = (unsigned int)(m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
657  0xFFFF0000;
658 
659  ff55_lower_bits = (m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
660  char hostname[128];
661  GetNodeName(hostname, m_node_id , sizeof(hostname));
662  if (ff55_higher_bits != 0xff550000) {
663  char err_buf[500];
664  sprintf(err_buf,
665  "[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",
666  hostname, 1,
667  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
668  m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
669  __FILE__, __PRETTY_FUNCTION__, __LINE__);
670  printf("%s", err_buf); fflush(stdout);
671  PrintData(m_buffer, m_nwords); fflush(stdout);
672  B2FATAL(err_buf);
673  }
674 
675  if (ff55_lower_bits != 0) {
676  char err_buf[500];
677  const int linkdown_bit = 15;
678  // const int packet_crcerr_bit = 8;
679  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
680  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot B eve %8u foooter %.8x : %s %s %d\n",
681  hostname, 1,
682  cur_ftsw_eve32,
683  m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
684  __FILE__, __PRETTY_FUNCTION__, __LINE__);
685  printf("%s", err_buf); fflush(stdout);
686  PrintData(m_buffer, m_nwords);
687  fflush(stdout);
688  B2FATAL(err_buf);
689  } else {
690  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
691  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
692  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x2 << 28);
693  sprintf(err_buf,
694  "[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",
695  hostname, 1,
696  cur_ftsw_eve32,
697  m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
698  __FILE__, __PRETTY_FUNCTION__, __LINE__);
699  printf("%s", err_buf); fflush(stdout);
700  PrintData(m_buffer, m_nwords);
701  fflush(stdout);
702  } else {
703  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
704  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x2 << 28);
705  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot B eve %8u foooter %.8x : %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  B2FATAL(err_buf);
714  }
715  }
716  }
717  }
718 
719  if (copper_buf[ POS_CH_C_DATA_LENGTH ] != 0) {
720  ff55_higher_bits = (unsigned int)(m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
721  0xFFFF0000;
722 
723  ff55_lower_bits = (m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
724  char hostname[128];
725  GetNodeName(hostname, m_node_id , sizeof(hostname));
726  if (ff55_higher_bits != 0xff550000) {
727  char err_buf[500];
728  sprintf(err_buf,
729  "[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",
730  hostname, 2,
731  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
732  m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
733  __FILE__, __PRETTY_FUNCTION__, __LINE__);
734  printf("%s", err_buf); fflush(stdout);
735  PrintData(m_buffer, m_nwords); fflush(stdout);
736  B2FATAL(err_buf);
737  }
738 
739  if (ff55_lower_bits != 0) {
740  char err_buf[500];
741  const int linkdown_bit = 15;
742 
743  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
744  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot C eve %8u foooter %.8x : %s %s %d\n",
745  hostname, 2,
746  cur_ftsw_eve32,
747  m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
748  __FILE__, __PRETTY_FUNCTION__, __LINE__);
749  printf("%s", err_buf); fflush(stdout);
750  PrintData(m_buffer, m_nwords);
751  fflush(stdout);
752  B2FATAL(err_buf);
753  } else {
754  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
755  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
756  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x4 << 28);
757  sprintf(err_buf,
758  "[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",
759  hostname, 2,
760  cur_ftsw_eve32,
761  m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
762  __FILE__, __PRETTY_FUNCTION__, __LINE__);
763  printf("%s", err_buf); fflush(stdout);
764  PrintData(m_buffer, m_nwords);
765  fflush(stdout);
766  } else {
767  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
768  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x4 << 28);
769  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot C eve %8u foooter %.8x : %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  B2FATAL(err_buf);
778  }
779  }
780 
781  }
782  }
783 
784  if (copper_buf[ POS_CH_D_DATA_LENGTH ] != 0) {
785  ff55_higher_bits = (unsigned int)(m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
786  0xFFFF0000;
787 
788  ff55_lower_bits = (m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
789  char hostname[128];
790  GetNodeName(hostname, m_node_id , sizeof(hostname));
791  if (ff55_higher_bits != 0xff550000) {
792  char err_buf[500];
793  sprintf(err_buf,
794  "[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",
795  hostname, 3,
796  cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
797  m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
798  __FILE__, __PRETTY_FUNCTION__, __LINE__);
799  printf("%s", err_buf); fflush(stdout);
800  PrintData(m_buffer, m_nwords); fflush(stdout);
801  B2FATAL(err_buf);
802  }
803 
804  if (ff55_lower_bits != 0) {
805  char err_buf[500];
806  const int linkdown_bit = 15;
807 
808  if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
809  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot D eve %8u foooter %.8x : %s %s %d\n",
810  hostname, 3,
811  cur_ftsw_eve32,
812  m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
813  __FILE__, __PRETTY_FUNCTION__, __LINE__);
814  printf("%s", err_buf); fflush(stdout);
815  PrintData(m_buffer, m_nwords);
816  fflush(stdout);
817  B2FATAL(err_buf);
818  } else {
819  if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
820  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
821  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x8 << 28);
822  sprintf(err_buf,
823  "[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",
824  hostname, 3,
825  cur_ftsw_eve32,
826  m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
827  __FILE__, __PRETTY_FUNCTION__, __LINE__);
828  printf("%s", err_buf); fflush(stdout);
829  PrintData(m_buffer, m_nwords);
830  fflush(stdout);
831  } else {
832  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
833  m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x8 << 28);
834  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot D eve %8u foooter %.8x : %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  B2FATAL(err_buf);
843  }
844  }
845  }
846  }
847 
848 
850  //
851  // Fill info in RawTrailer
852  //
854 
855  //
856  // Calculate XOR checksum
857  //
858  unsigned int chksum_top = 0, chksum_body = 0, chksum_bottom = 0;
859 
860  int top_end = tmp_header.RAWHEADER_NWORDS;
861  for (int i = 0; i < top_end; i++) {
862  chksum_top ^= m_buffer[ i ];
863  }
864  int body_end = datablock_nwords - SIZE_COPPER_DRIVER_TRAILER - tmp_trailer.RAWTRAILER_NWORDS;
865  for (int i = top_end; i < body_end; i++) {
866  chksum_body ^= m_buffer[ i ];
867  }
868 
869  int bottom_end = datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS;
870  for (int i = body_end; i < bottom_end; i++) {
871  chksum_bottom ^= m_buffer[ i ];
872  }
873 
874  //
875  // check COPPER driver checksum
876  //
877  if (chksum_body != (unsigned int)(m_buffer[ body_end ])) {
878  char err_buf[500];
879  char hostname[128];
880  GetNodeName(hostname, m_node_id , sizeof(hostname));
881  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : COPPER driver checksum is not consistent.: calcd. %.8x data %.8x\n %s %s %d\n",
882  hostname, -1,
883  chksum_body, m_buffer[ body_end ],
884  __FILE__, __PRETTY_FUNCTION__, __LINE__);
885  printf("%s", err_buf); fflush(stdout);
886  B2FATAL(err_buf); // to reduce multiple error messages
887  }
888 
889  //
890  // Fill trailer info (checksum, magic word)
891  //
892  unsigned int chksum = chksum_top ^ chksum_body ^ chksum_bottom;
893  int* trl = &(m_buffer[ datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS ]);
894  trl[ tmp_trailer.POS_CHKSUM ] = chksum;
895  trl[ tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
896 
897 
899  //
900  // Data check ( magic word, event incrementation )
901  //
903 
904 
905  //
906  // check magic words
907  //
908  int* fpga_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_3);
909  int* driver_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_4);
910  int err_flag = 0;
911  if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_1 ]) != COPPER_MAGIC_DRIVER_HEADER) {
912  err_flag = 1;
913  } else if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_2 ]) != COPPER_MAGIC_FPGA_HEADER) {
914  err_flag = 1;
915  } else if ((unsigned int)(*fpga_trailer_magic) != COPPER_MAGIC_FPGA_TRAILER) {
916  err_flag = 1;
917  } else if ((unsigned int)(*driver_trailer_magic) != COPPER_MAGIC_DRIVER_TRAILER) {
918  err_flag = 1;
919  }
920  if (err_flag == 1) {
921  char err_buf[500];
922  char hostname[128];
923  GetNodeName(hostname, m_node_id , sizeof(hostname));
924  sprintf(err_buf,
925  "[FATAL] %s ch=%d : ERROR_EVENT : Invalid Magic word 0x7FFFF0008=%u 0xFFFFFAFA=%u 0xFFFFF5F5=%u 0x7FFF0009=%u\n %s %s %d\n",
926  hostname, -1,
927  GetMagicDriverHeader(datablock_id),
928  GetMagicFPGAHeader(datablock_id),
929  GetMagicFPGATrailer(datablock_id),
930  GetMagicDriverTrailer(datablock_id),
931  __FILE__, __PRETTY_FUNCTION__, __LINE__);
932  printf("[DEBUG] %s\n", err_buf);
933 #ifndef NO_ERROR_STOP
934  B2FATAL(err_buf); // to reduce multiple error messages
935 #endif
936  }
937 
938  //
939  // check incrementation of event #
940  //
941 
942 
943  *cur_exprunsubrun_no = GetExpRunSubrun(datablock_id);
944 
945  // if ((unsigned int)cur_ftsw_eve32 < 50) {
946  // printf("EVENT OUTPUT ########## %u\n", cur_ftsw_eve32);
947  // PrintData(GetBuffer(datablock_id), TotalBufNwords());
948  // }
949  if (prev_exprunsubrun_no == *cur_exprunsubrun_no) {
950  if (prev_eve32 + 1 != cur_ftsw_eve32) {
951  unsigned int eve[4] = {0xbaadf00d, 0xbaadf00d, 0xbaadf00d, 0xbaadf00d };
952 #ifndef NO_ERROR_STOP
953  if (m_num_nodes * m_num_events != 1) {
954  char err_buf[500];
955  sprintf(err_buf,
956  "[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",
957  m_num_nodes, m_num_events, __FILE__, __PRETTY_FUNCTION__, __LINE__);
958  printf("%s", err_buf); fflush(stdout);
959  // string err_str = err_buf; throw (err_str);
960  B2FATAL(err_buf); // to reduce multiple error messages
961  } else {
962  for (int i = 0; i < 4 ; i++) {
963  // Only one block is in this m_buffer[] when m_num_nodes*m_num_events=1
964  // 0 is specified as a block number
965  if (GetFINESSENwords(0 , i) > 0) {
966  int pos_nwords = GetOffsetFINESSE(0, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
967  eve[ i ] = m_buffer[ pos_nwords ];
968  }
969  }
970  }
971 
972  char err_buf[500];
973  char hostname[128];
974  GetNodeName(hostname, m_node_id , sizeof(hostname));
975  sprintf(err_buf,
976  "[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",
977  hostname, -1,
978  cur_ftsw_eve32, prev_eve32,
979  eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
980  prev_exprunsubrun_no, *cur_exprunsubrun_no,
981  __FILE__, __PRETTY_FUNCTION__, __LINE__);
982  printf("[DEBUG] %s\n", err_buf);
983 
984  // string err_str = err_buf;
985  printf("[DEBUG] i= %d : num entries %d : Tot words %d\n", 0 , GetNumEntries(), TotalBufNwords());
986  PrintData(GetBuffer(datablock_id), TotalBufNwords());
987 
988  for (int i = 0; i < 4; i++) {
989  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", datablock_id, i);
990  if (GetFINESSENwords(datablock_id, i) > 0) {
991  CheckCRC16(datablock_id, i);
992  }
993  }
994  printf("[DEBUG] ========== No CRC error : block %d =========\n", datablock_id);
995  // throw (err_str);
996  B2FATAL(err_buf); // to reduce multiple error messages
997 #endif
998 
999  }
1000  }
1001 
1002  return cur_ftsw_eve32;
1003 
1004 }
1005 
1006 
1007 
1008 #ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
1009 void PreRawCOPPERFormat_v2::CheckB2LFEEHeaderVersion(int n)
1010 {
1011  int* temp_buf;
1012  for (int i = 0; i < 4; i++) {
1013  if (GetFINESSENwords(n, i) > 0) {
1014  temp_buf = GetFINESSEBuffer(n, i);
1015  if ((temp_buf[ 3 ] & 0x40000000) == 0) {
1016 #ifdef TEMP
1017  // this word for exp/run
1018  // old one (ver.1) used for SPring8 test in 2013
1019  printf("[DEBUG] \033[31m");
1020  printf("[DEBUG] ===Firmware ver. ERROR===\n ");
1021  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");
1022  printf("[DEBUG] If you are going to take data now, Please update the firmware.\n");
1023  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");
1024  printf("[DEBUG] Or if you are going to read data taken before the update, please use basf2 software before svn revision 7419\n");
1025  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");
1026  printf("[DEBUG] Sorry for inconvenience.\n");
1027  printf("[DEBUG] \033[0m");
1028  fflush(stderr);
1029  char err_buf[500];
1030  char hostname[128];
1031  GetNodeName(n, hostname, sizeof(hostname));
1032  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : FTSW and b2tt firmwares are old. Exiting...\n %s %s %d\n",
1033  hostname, i,
1034  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1035  B2FATAL(err_buf);
1036 #endif
1037  } else {
1038  // this word for 32bit unixtime
1039  // new one (ver.2)
1040  break;
1041  }
1042  }
1043 
1044  if (i == 3) {
1045 #ifdef TEMP
1046  char err_buf[500];
1047  char hostname[128];
1048  GetNodeName(n, hostname, sizeof(hostname));
1049  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : PreRawCOPPERFormat_v2 contains no FINESSE data. Exiting...\n %s %s %d\n",
1050  hostname, i,
1051  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1052  printf("%s", err_buf); fflush(stdout);
1053  // string err_str = err_buf; throw (err_str);
1054  B2FATAL(err_buf); // to reduce multiple error messages
1055 #endif
1056  }
1057  }
1058  return;
1059 }
1060 #endif
1061 
1062 //int PreRawCOPPERFormat_v2::CalcReducedDataSize(RawDataBlock* raw_datablk)
1063 int PreRawCOPPERFormat_v2::CalcReducedDataSize(int* bufin, int nwords, int num_events, int num_nodes)
1064 {
1065  //
1066  // Calculate reduced length for a total RawDataBlock (containing multiple data blocks)
1067  //
1068  RawDataBlockFormat radblk_fmt;
1069  int delete_flag = 0;
1070  radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
1071 
1072  int reduced_nwords = 0;
1073  for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
1074  int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
1075  for (int l = 0; l < num_nodes_in_sendblock; l++) {
1076  int entry_id = l + k * num_nodes_in_sendblock;
1077 
1078  if (radblk_fmt.CheckFTSWID(entry_id) || radblk_fmt.CheckTLUID(entry_id)) {
1079  reduced_nwords += radblk_fmt.GetBlockNwords(entry_id);
1080  } else {
1081  PreRawCOPPERFormat_v2 temp_prerawcpr;
1082  int temp_delete_flag = 0, temp_num_eve = 1, temp_num_nodes = 1;
1083 
1084  // Call CalcReducedNwords
1085  temp_prerawcpr.SetBuffer(radblk_fmt.GetBuffer(entry_id),
1086  radblk_fmt.GetBlockNwords(entry_id),
1087  temp_delete_flag, temp_num_eve,
1088  temp_num_nodes);
1089  reduced_nwords += temp_prerawcpr.CalcReducedNwords(0);
1090  }
1091  }
1092  }
1093  return reduced_nwords;
1094 
1095 }
1096 
1097 //void PreRawCOPPERFormat_v2::CopyReducedData(RawDataBlock* raw_datablk, int* buf_to, int delete_flag_from)
1098 void PreRawCOPPERFormat_v2::CopyReducedData(int* bufin, int nwords, int num_events, int num_nodes, int* buf_to, int* nwords_to)
1099 {
1100  //
1101  // Make a reduced buffer a total RawDataBlock (containing multiple data blocks)
1102  //
1103  RawDataBlockFormat radblk_fmt;
1104  int delete_flag = 0;
1105  radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
1106 
1107  int pos_nwords_to = 0;
1108  for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
1109  int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
1110  for (int l = 0; l < num_nodes_in_sendblock; l++) {
1111  int entry_id = l + k * num_nodes_in_sendblock;
1112  if (radblk_fmt.CheckFTSWID(entry_id) ||
1113  radblk_fmt.CheckTLUID(entry_id)) {
1114  radblk_fmt.CopyBlock(entry_id, buf_to + pos_nwords_to);
1115  pos_nwords_to += radblk_fmt.GetBlockNwords(entry_id);
1116 
1117  } else {
1118  SetBuffer(radblk_fmt.GetBuffer(entry_id),
1119  radblk_fmt.GetBlockNwords(entry_id), 0, 1, 1);
1120 
1121  pos_nwords_to += CopyReducedBuffer(0, buf_to + pos_nwords_to);
1122 
1123 
1124  }
1125  }
1126  }
1127 
1128  *nwords_to = pos_nwords_to;
1129 
1130  return ;
1131 }
1132 
1133 
1134 int PreRawCOPPERFormat_v2::CalcReducedNwords(int n)
1135 {
1136  //
1137  // Calculate reduced length for one data block which is a part of a RawDataBlock
1138  //
1139 
1140  int nwords_to = 0;
1141 
1142  //RawCOPPER header
1143  nwords_to += tmp_header.RAWHEADER_NWORDS;
1144 
1145  for (int j = 0; j < 4; j++) {
1146 
1147  int finesse_nwords = GetFINESSENwords(n, j);
1148  if (finesse_nwords > 0) {
1149  //
1150  // B2L(HSLB/FEE) header and trailers are resized
1151  // m_reduced_rawcpr should be PostRawCOPPERFormat_v2
1152  //
1153  nwords_to +=
1154  finesse_nwords
1155  - (SIZE_B2LHSLB_HEADER - m_reduced_rawcpr.SIZE_B2LHSLB_HEADER)
1156  - (SIZE_B2LFEE_HEADER - m_reduced_rawcpr.SIZE_B2LFEE_HEADER)
1157  - (SIZE_B2LFEE_TRAILER - m_reduced_rawcpr.SIZE_B2LFEE_TRAILER)
1158  - (SIZE_B2LHSLB_TRAILER - m_reduced_rawcpr.SIZE_B2LHSLB_TRAILER);
1159  }
1160 
1161  }
1162 
1163  //RawCOPPER Trailer
1164  nwords_to += tmp_trailer.GetTrlNwords();
1165 
1166  return nwords_to;
1167 }
1168 
1169 
1170 
1171 
1172 
1173 
1174 int PreRawCOPPERFormat_v2::CopyReducedBuffer(int n, int* buf_to)
1175 {
1176  //
1177  // Make a reduced buffer for one data block which is a part of a RawDataBlock
1178  //
1179 
1180  int* buf_from = NULL;
1181  int nwords_buf_to = CalcReducedNwords(n);
1182  int pos_nwords_to = 0;
1183  int copy_nwords = 0;
1184 
1185  unsigned int removed_xor_chksum = 0;
1186 
1187  // copyt to ReducedRawCOPPER
1188  // ReducedRawCOPPER m_reduced_rawcpr;
1189  //Header copy
1190  copy_nwords = tmp_header.RAWHEADER_NWORDS;
1191  buf_from = GetBuffer(n);
1192  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1193 
1194 
1195  //calcurate XOR checksum diff.( depends on data-format )
1196  removed_xor_chksum ^= buf_from[ tmp_header.POS_VERSION_HDRNWORDS ];
1197 
1198  // Unset the PreFormat bit ( 15th bit )
1199  buf_to[ tmp_header.POS_VERSION_HDRNWORDS ] &= 0xFFFF7FFF;
1200 
1201  //calcurate XOR checksum diff.( depends on data-format )
1202  removed_xor_chksum ^= buf_to[ tmp_header.POS_VERSION_HDRNWORDS ];
1203  for (int i = 0; i < SIZE_COPPER_HEADER; i++) {
1204  removed_xor_chksum ^= buf_from[ tmp_header.RAWHEADER_NWORDS + i ];
1205  }
1206 
1207  //Check Header
1208  // m_reduced_rawcpr.tmp_header.CheckHeader(buf_to + pos_nwords_to - copy_nwords);
1209 
1210 
1211  // copy FINESSE buffer
1212  int pos_nwords_finesse[ 4 ];
1213  for (int j = 0; j < 4; j++) {
1214  pos_nwords_finesse[ j ] = pos_nwords_to;
1215  if (GetFINESSENwords(n, j) > 0) {
1216  int* finesse_buf = GetFINESSEBuffer(n, j);
1217  int finesse_nwords = GetFINESSENwords(n, j);
1218 
1219 
1220  CheckB2LHSLBMagicWords(finesse_buf, finesse_nwords);
1221  // copy the whole B2LHSLB header (1word)
1222  buf_to[ pos_nwords_to ] = finesse_buf[ POS_MAGIC_B2LHSLB ];
1223  pos_nwords_to++;
1224 
1225  // copy the last word of B2LFEE and body( DetectorBuffer )
1226  buf_from =
1227  finesse_buf
1228  + SIZE_B2LHSLB_HEADER
1229  + POS_B2L_CTIME; //the last word of B2LFEE
1230 
1231 
1232  // check finesse buffer size : ( When dumhslb was used, this type of error
1233  // occured and RecvStream0.py died by Segmentation Fault. ) 2014.12.01.
1234  if (finesse_nwords - SIZE_B2LHSLB_HEADER - SIZE_B2LFEE_HEADER
1235  - SIZE_B2LFEE_TRAILER - SIZE_B2LHSLB_TRAILER < 0) {
1236  char err_buf[500];
1237  char hostname[128];
1238  GetNodeName(n, hostname, sizeof(hostname));
1239  sprintf(err_buf,
1240  "[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",
1241  hostname, j,
1242  finesse_nwords, SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER,
1243  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1244  printf("%s", err_buf); fflush(stdout);
1245  // string err_str = err_buf; throw (err_str);
1246  B2FATAL(err_buf); // to reduce multiple error messages
1247  }
1248 
1249  //calcurate XOR checksum diff.( depends on data-format )
1250  for (int k = 1; k <= 4 ; k++) {
1251  removed_xor_chksum ^= finesse_buf[ k ];
1252  }
1253 
1254  copy_nwords =
1255  finesse_nwords
1256  - SIZE_B2LHSLB_HEADER // already copied
1257  - POS_B2L_CTIME // only one word copied ( SIZE_B2LFEE_HEADER - 1 = POS_B2L_CTIME )
1258  - SIZE_B2LFEE_TRAILER // will be copied later
1259  - SIZE_B2LHSLB_TRAILER; // Not copied
1260  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1261  // printf("pos %d nwords %d nwords to %d\n", pos_nwords_to, copy_nwords, nwords_buf_to );
1262 
1263  //copy B2LFEE trailer(CRC info)
1264  buf_to[ pos_nwords_to ] = 0xffff & finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER - (SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) ];
1265  //copy B2LHSLB trailer(packet CRC error count)
1266  buf_to[ pos_nwords_to ] |= (finesse_buf[ finesse_nwords - (SIZE_B2LHSLB_TRAILER - POS_MAGIC_B2LHSLB) ] << 16) & 0xFFFF0000;
1267 
1268  //calcurate XOR checksum diff. ( depends on data-format )
1269  for (int k = 0; k <= 2 ; k++) {
1270  removed_xor_chksum ^= finesse_buf[ finesse_nwords - SIZE_B2LFEE_TRAILER - SIZE_B2LHSLB_TRAILER + k ];
1271  }
1272  removed_xor_chksum ^= buf_to[ pos_nwords_to ];
1273 
1274  pos_nwords_to++;
1275 
1276  // check CRC data
1277  // CheckCRC16( n, j );
1278  }
1279  }
1280 
1281  // copy RawCOPPER trailer
1282  buf_from =
1283  GetBuffer(n)
1284  + GetBlockNwords(n)
1285  - tmp_trailer.GetTrlNwords();
1286  copy_nwords = tmp_trailer.GetTrlNwords();
1287  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1288 
1289  //calcurate XOR checksum diff.( depends on data-format )
1290  unsigned int old_rawcopper_chksum = buf_from[ tmp_trailer.POS_CHKSUM ];
1291  for (int i = 0; i < SIZE_COPPER_TRAILER; i++) {
1292  removed_xor_chksum ^= (unsigned int) * (buf_from - SIZE_COPPER_TRAILER + i);
1293  }
1294 
1295 
1296  // length check
1297  if (pos_nwords_to != nwords_buf_to) {
1298  char err_buf[500];
1299  sprintf(err_buf, "Buffer overflow. Exiting... %d %d\n", pos_nwords_to, nwords_buf_to);
1300  printf("%s", err_buf); fflush(stdout);
1301  B2FATAL(err_buf);
1302  }
1303 
1304 
1305  // Recalculate XOR checksum in a RawCOPPER trailer
1306  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS);
1307  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE);
1308  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE);
1309  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE);
1310  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE);
1311 
1312  //
1313  // Apply changes followed by data size reduction
1314  //
1315  *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS) = nwords_buf_to;
1316  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE) = pos_nwords_finesse[ 0 ];
1317  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE) = pos_nwords_finesse[ 1 ];
1318  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE) = pos_nwords_finesse[ 2 ];
1319  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE) = pos_nwords_finesse[ 3 ];
1320 
1321  // Recalculate XOR checksum in a RawCOPPER trailer
1322  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS);
1323  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE);
1324  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE);
1325  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE);
1326  removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE);
1327 
1328  // Recalculate XOR checksum in a RawCOPPER trailer
1329  unsigned int new_rawcopper_chksum = CalcXORChecksum(buf_to, pos_nwords_to - tmp_trailer.GetTrlNwords());
1330 
1331 
1332  if ((old_rawcopper_chksum ^ removed_xor_chksum) != new_rawcopper_chksum) {
1333  char err_buf[500];
1334  char hostname[128];
1335  GetNodeName(n, hostname, sizeof(hostname));
1336  sprintf(err_buf,
1337  "[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",
1338  hostname, -1,
1339  new_rawcopper_chksum, old_rawcopper_chksum, removed_xor_chksum, old_rawcopper_chksum ^ removed_xor_chksum,
1340  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1341  printf("%s", err_buf); fflush(stdout);
1342  B2FATAL(err_buf); // to reduce multiple error messages
1343  }
1344 
1345  *(buf_to + pos_nwords_to - tmp_trailer.GetTrlNwords() + tmp_trailer.POS_CHKSUM) = new_rawcopper_chksum;
1346 
1347 
1348 
1349  //
1350  // data block # check
1351  //
1352  m_reduced_rawcpr.SetBuffer(buf_to, nwords_buf_to, 0, GetNumEvents(), GetNumNodes());
1353  if (m_reduced_rawcpr.GetNumEvents() * m_reduced_rawcpr.GetNumNodes() <= 0) {
1354  char err_buf[500];
1355  sprintf(err_buf, "Invalid data block numbers.(# of events %d, # of nodes %d) Exiting...\n",
1356  m_reduced_rawcpr.GetNumEvents(), m_reduced_rawcpr.GetNumNodes());
1357  printf("%s", err_buf); fflush(stdout);
1358  B2FATAL(err_buf);
1359  }
1360 
1361  //
1362  // check no-data buffer
1363  //
1364  for (int i = 0; i < m_reduced_rawcpr.GetNumEvents() * m_reduced_rawcpr.GetNumNodes(); i++) {
1365  int nonzero_finesse_buf = 0;
1366  for (int j = 0; j < 4; j++) {
1367 
1368  if (GetFINESSENwords(n, j) > 0) {
1369  // m_reduced_rawcpr.CheckCRC16(i, j);
1370  nonzero_finesse_buf++;
1371  }
1372  }
1373  if (nonzero_finesse_buf == 0) {
1374  char err_buf[500];
1375  sprintf(err_buf, "No non-zero FINESSE buffer. Exiting...\n");
1376  printf("%s", err_buf); fflush(stdout);
1377  B2FATAL(err_buf);
1378  }
1379  }
1380 
1381  // post_rawcopper_v2.CheckCRC16(0, 0);
1382  // printf("fROM =======================================\n");
1383  // for (int k = 0; k < nwords_buf_to; k++) {
1384  // printf(" %.8x", GetBuffer(n)[ k ]);
1385  // if ( ( k + 1 ) % 10 == 0) {
1386  // printf("\n");
1387  // }
1388  // }
1389  // printf("\n");
1390 
1391  // printf("tO =======================================\n");
1392  // for (int k = 0; k < nwords_buf_to; k++) {
1393  // printf(" %.8x", buf_to[ k ]);
1394  // if ( ( k + 1 ) % 10 == 0) {
1395  // printf("\n");
1396  // }
1397  // }
1398  // printf("\n");
1399  // printf("=============================================\n");
1400  return pos_nwords_to;
1401 }
1402 
1403 
1404 int PreRawCOPPERFormat_v2::CheckB2LHSLBMagicWords(int* finesse_buf, int finesse_nwords)
1405 {
1406 
1407  if ((finesse_buf[ POS_MAGIC_B2LHSLB ] & 0xFFFF0000) == B2LHSLB_HEADER_MAGIC &&
1408  ((finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ] & 0xFFFF0000)
1409  == B2LHSLB_TRAILER_MAGIC)) {
1410  return 1;
1411  } else {
1412  PrintData(m_buffer, m_nwords);
1413  char err_buf[500];
1414  sprintf(err_buf,
1415  "Invalid B2LHSLB magic words : header 0x%x (= should be ffaa**** ) or trailer 0x%x (= should be ff55**** ). Exiting... :%s %s %d\n",
1416  finesse_buf[ POS_MAGIC_B2LHSLB ],
1417  finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ],
1418  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1419 #ifndef NO_ERROR_STOP
1420  printf("%s", err_buf); fflush(stdout);
1421  B2FATAL(err_buf);
1422 #endif
1423  }
1424 }
1425 
1426 
1427 
1428 int PreRawCOPPERFormat_v2::CheckCRC16(int n, int finesse_num)
1429 {
1430  //
1431  // Calculate CRC16
1432  //
1433  int* buf = GetFINESSEBuffer(n, finesse_num) + SIZE_B2LHSLB_HEADER;
1434  int nwords = GetFINESSENwords(n, finesse_num) - (SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER);
1435  unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, buf, nwords);
1436 
1437  //
1438  // Compare CRC16 with B2LCRC16
1439  //
1440  buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n, finesse_num)
1441  - ((SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) + SIZE_B2LHSLB_TRAILER) ;
1442 
1443  if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
1444  PrintData(GetBuffer(n), *(GetBuffer(n) + tmp_header.POS_NWORDS));
1445  char err_buf[500];
1446  char hostname[128];
1447  GetNodeName(n, hostname, sizeof(hostname));
1448  printf("[FATAL] %s ch=%d : ERROR_EVENT : PRE CRC16 error : slot %c : B2LCRC16 %x Calculated CRC16 %x : Nwords of FINESSE buf %d\n",
1449  hostname, finesse_num,
1450  65 + finesse_num, *buf , temp_crc16, GetFINESSENwords(n, finesse_num));
1451  int* temp_buf = GetFINESSEBuffer(n, finesse_num);
1452  for (int k = 0; k < GetFINESSENwords(n, finesse_num); k++) {
1453  printf("%.8x ", temp_buf[ k ]);
1454  if ((k + 1) % 10 == 0) {
1455  printf("\n");
1456  }
1457  }
1458  printf("\n");
1459  fflush(stdout);
1460  sprintf(err_buf,
1461  "[FATAL] %s ch=%d : ERROR_EVENT : slot %c : B2LCRC16 (%.4x) differs from one ( %.4x) calculated by PreRawCOPPERfromat class. Exiting...\n %s %s %d\n",
1462  hostname, finesse_num,
1463  65 + finesse_num, (unsigned short)(*buf & 0xFFFF), temp_crc16,
1464  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1465  printf("%s", err_buf); fflush(stdout);
1466  B2FATAL(err_buf); // to reduce multiple error messages
1467  }
1468  return 1;
1469 
1470 }
1471 
1472 int* PreRawCOPPERFormat_v2::PackDetectorBuf(int* packed_buf_nwords,
1473  int* detector_buf_1st, int nwords_1st,
1474  int* detector_buf_2nd, int nwords_2nd,
1475  int* detector_buf_3rd, int nwords_3rd,
1476  int* detector_buf_4th, int nwords_4th,
1477  RawCOPPERPackerInfo rawcpr_info)
1478 {
1479  int* packed_buf = NULL;
1480 
1481  int poswords_to = 0;
1482  int* detector_buf[ 4 ] = { detector_buf_1st, detector_buf_2nd, detector_buf_3rd, detector_buf_4th };
1483  int nwords[ 4 ] = { nwords_1st, nwords_2nd, nwords_3rd, nwords_4th };
1484 
1485  // calculate the event length
1486  int length_nwords = tmp_header.GetHdrNwords() + SIZE_COPPER_HEADER + SIZE_COPPER_TRAILER + tmp_trailer.GetTrlNwords();
1487 
1488  for (int i = 0; i < 4; i++) {
1489  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1490  length_nwords += nwords[ i ];
1491  length_nwords += SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER
1492  + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1493  }
1494 
1495  // allocate buffer
1496  packed_buf = new int[ length_nwords ];
1497  memset(packed_buf, 0, sizeof(int) * length_nwords);
1498 
1499  //
1500  // Fill RawHeader
1501  //
1502  tmp_header.SetBuffer(packed_buf);
1503 
1504  packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
1505  packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] = 0x7f7f8000
1506  | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
1507  | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
1508  packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT)
1509  | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
1510  packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
1511  packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
1512  packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
1513  packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
1514 
1515 
1516 
1517 
1518  // fill the positions of finesse buffers
1519  packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ] = tmp_header.RAWHEADER_NWORDS + SIZE_COPPER_HEADER;
1520 
1521  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ];
1522  if (nwords[ 0 ] > 0) {
1523  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] +=
1524  nwords[ 0 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1525  }
1526 
1527  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ];
1528  if (nwords[ 1 ] > 0) {
1529  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] +=
1530  nwords[ 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1531  }
1532 
1533  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ];
1534  if (nwords[ 2 ] > 0) {
1535  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] += nwords[ 2 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER +
1536  SIZE_B2LHSLB_TRAILER;
1537  }
1538  poswords_to += tmp_header.GetHdrNwords();
1539 
1540  // Fill COPPER header
1541  packed_buf[ poswords_to + POS_MAGIC_COPPER_1 ] = COPPER_MAGIC_DRIVER_HEADER;
1542  packed_buf[ poswords_to + POS_MAGIC_COPPER_2 ] = COPPER_MAGIC_FPGA_HEADER;
1543  packed_buf[ poswords_to + POS_EVE_NUM_COPPER ] = rawcpr_info.eve_num;
1544 
1545  int size_b2l_hdrtrl = SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1546  if (nwords[ 0 ] != 0) packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] = nwords[ 0 ] + size_b2l_hdrtrl;
1547  if (nwords[ 1 ] != 0) packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] = nwords[ 1 ] + size_b2l_hdrtrl;
1548  if (nwords[ 2 ] != 0) packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] = nwords[ 2 ] + size_b2l_hdrtrl;
1549  if (nwords[ 3 ] != 0) packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] = nwords[ 3 ] + size_b2l_hdrtrl;
1550 
1551  packed_buf[ poswords_to + POS_DATA_LENGTH ] =
1552  packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] +
1553  packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] +
1554  packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] +
1555  packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] +
1556  (SIZE_COPPER_HEADER - SIZE_COPPER_DRIVER_HEADER) +
1557  (SIZE_COPPER_TRAILER - SIZE_COPPER_DRIVER_TRAILER);
1558 
1559  poswords_to += SIZE_COPPER_HEADER;
1560 
1561  // Fill FINESSE buffer
1562  for (int i = 0; i < 4; i++) {
1563 
1564  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1565 
1566  // Fill b2link HSLB header
1567  packed_buf[ poswords_to + POS_MAGIC_B2LHSLB ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
1568  poswords_to += SIZE_B2LHSLB_HEADER;
1569  int* crc16_start = &(packed_buf[ poswords_to ]);
1570 
1571  // Fill b2link FEE header
1572 
1573  packed_buf[ poswords_to + POS_TT_CTIME_TYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4;
1574  unsigned int temp_ctime_type = packed_buf[ poswords_to + POS_TT_CTIME_TYPE ];
1575  packed_buf[ poswords_to + POS_TT_TAG ] = rawcpr_info.eve_num;
1576  packed_buf[ poswords_to + POS_TT_UTIME ] = rawcpr_info.tt_utime;
1577  packed_buf[ poswords_to + POS_EXP_RUN ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT) | (rawcpr_info.run_subrun_num &
1578  0x003FFFFF); // exp. and run #
1579  packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
1580  poswords_to += SIZE_B2LFEE_HEADER;
1581 
1582  // copy the 1st Detector Buffer
1583  memcpy(packed_buf + poswords_to, detector_buf[ i ], nwords[ i ]*sizeof(int));
1584  poswords_to += nwords[ i ];
1585 
1586  // Fill b2link b2tt-tag trailer
1587  packed_buf[ poswords_to + POS_TT_CTIME_B2LFEE ] = temp_ctime_type;
1588 
1589  // Fill b2link FEE trailer
1590  unsigned short crc16 = CalcCRC16LittleEndian(0xffff, crc16_start, nwords[ i ] + SIZE_B2LFEE_HEADER);
1591  packed_buf[ poswords_to + POS_CHKSUM_B2LFEE ] = ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 & 0xffff);
1592  poswords_to += SIZE_B2LFEE_TRAILER;
1593 
1594  // Fill b2link HSLB trailer
1595  packed_buf[ poswords_to + POS_CHKSUM_B2LHSLB ] = 0xff550000;
1596  poswords_to += SIZE_B2LHSLB_TRAILER;
1597 
1598  }
1599 
1600  // Fill COPPER trailer
1601  packed_buf[ poswords_to + POS_MAGIC_COPPER_3 ] = COPPER_MAGIC_FPGA_TRAILER;
1602  packed_buf[ poswords_to + POS_MAGIC_COPPER_4 ] = COPPER_MAGIC_DRIVER_TRAILER;
1603  unsigned int chksum = 0;
1604  for (int i = tmp_header.GetHdrNwords(); i < poswords_to + (SIZE_COPPER_TRAILER - SIZE_COPPER_DRIVER_TRAILER); i++) {
1605  chksum ^= packed_buf[ i ];
1606  }
1607  packed_buf[ poswords_to + POS_CHKSUM_COPPER ] = chksum;
1608  poswords_to += SIZE_COPPER_TRAILER;
1609 
1610  // Calculate RawCOPPER checksum and fill RawTrailer
1611  chksum = 0;
1612  for (int i = 0; i < poswords_to; i++) {
1613  chksum ^= packed_buf[ i ];
1614  }
1615  packed_buf[ poswords_to + tmp_trailer.POS_CHKSUM ] = chksum;
1616 
1617  packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
1618  poswords_to += tmp_trailer.GetTrlNwords();
1619 
1620  *packed_buf_nwords = poswords_to;
1621  return packed_buf;
1622 }
Belle2::RawCOPPERPackerInfo::tt_utime
unsigned int tt_utime
27bit clock ticks at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user...
Definition: RawCOPPERPackerInfo.h:28
Belle2::RawCOPPERPackerInfo
struct to contain header information used by RawCOPPERFormat::Packer()
Definition: RawCOPPERPackerInfo.h:12
Belle2::RawCOPPERPackerInfo::exp_num
unsigned int exp_num
Experiment number (10bit)
Definition: RawCOPPERPackerInfo.h:16
Belle2::RawDataBlockFormat::SetBuffer
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 )
Definition: RawDataBlockFormat.cc:131
Belle2::RawCOPPERPackerInfo::node_id
unsigned int node_id
Event Number (32bit)
Definition: RawCOPPERPackerInfo.h:22
Belle2::RawCOPPERPackerInfo::b2l_ctime
unsigned int b2l_ctime
32bit unitx time at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user ...
Definition: RawCOPPERPackerInfo.h:31
Belle2::RawDataBlockFormat::GetBuffer
virtual int * GetBuffer(int n)
get nth buffer pointer
Definition: RawDataBlockFormat.cc:124
Belle2::RawDataBlockFormat::CopyBlock
virtual void CopyBlock(int n, int *buf_to)
Copy one datablock to buffer.
Definition: RawDataBlockFormat.cc:173
Belle2::RawDataBlockFormat::GetNumNodes
virtual int GetNumNodes()
get # of data sources(e.g. # of COPPER boards) in m_buffer
Definition: RawDataBlockFormat.h:52
Belle2::RawCOPPERPackerInfo::eve_num
unsigned int eve_num
Run # and subrun # ( 22bit )
Definition: RawCOPPERPackerInfo.h:20
Belle2::PreRawCOPPERFormat_v2
The Raw COPPER class ver.1 ( the latest version since May, 2014 ) This class stores data received by ...
Definition: PreRawCOPPERFormat_v2.h:30
Belle2::PreRawCOPPERFormat_v2::CalcReducedNwords
int CalcReducedNwords(int n)
calculate reduced data size
Definition: PreRawCOPPERFormat_v2.cc:1134
Belle2::RawDataBlockFormat
The RawDataBlockFormat class Format information for rawdata handling.
Definition: RawDataBlockFormat.h:25
Belle2::RawCOPPERPackerInfo::tt_ctime
unsigned int tt_ctime
Node ID (32bit)
Definition: RawCOPPERPackerInfo.h:25
Belle2::RawDataBlockFormat::GetNumEvents
virtual int GetNumEvents()
get # of events in m_buffer
Definition: RawDataBlockFormat.h:55
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::RawCOPPERPackerInfo::run_subrun_num
unsigned int run_subrun_num
Experiment number (10bit)
Definition: RawCOPPERPackerInfo.h:18
Belle2::RawDataBlockFormat::GetBlockNwords
virtual int GetBlockNwords(int n)
get size of a data block
Definition: RawDataBlockFormat.cc:107
Belle2::RawDataBlockFormat::CheckFTSWID
virtual int CheckFTSWID(int n)
get FTSW ID to check whether this data block is FTSW data or not
Definition: RawDataBlockFormat.cc:73
Belle2::RawDataBlockFormat::CheckTLUID
virtual int CheckTLUID(int n)
get FTSW ID to check whether this data block is FTSW data or not
Definition: RawDataBlockFormat.cc:88