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