Belle II Software  release-08-01-10
PreRawCOPPERFormat_v1.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <rawdata/dataobjects/PreRawCOPPERFormat_v1.h>
10 
11 
12 using namespace std;
13 using namespace Belle2;
14 
15 //#define DESY
16 //#define NO_DATA_CHECK
17 //#define WO_FIRST_EVENUM_CHECK
18 
19 //ClassImp(PreRawCOPPERFormat_v1);
20 
21 PreRawCOPPERFormat_v1::PreRawCOPPERFormat_v1()
22 {
23 }
24 
25 PreRawCOPPERFormat_v1::~PreRawCOPPERFormat_v1()
26 {
27 }
28 
29 
30 // int PreRawCOPPERFormat_v1::GetBufferPos(int n)
31 // {
32 // if (m_buffer == NULL || m_nwords <= 0) {
33 // char err_buf[500];
34 // sprintf(err_buf, "[DEBUG] [ERROR] RawPacket buffer(%p) is not available or length(%d) is not set.\n %s %s %d\n",
35 // m_buffer, m_nwords, __FILE__, __PRETTY_FUNCTION__, __LINE__);
36 // printf("%s", err_buf); fflush(stdout);
37 // string err_str = err_buf; throw (err_str);
38 // }
39 
40 // if (n >= (m_num_events * m_num_nodes)) {
41 // char err_buf[500];
42 // sprintf(err_buf, "[DEBUG] Invalid COPPER block No. (%d : max %d ) is specified. Exiting... \n %s %s %d\n",
43 // n, (m_num_events * m_num_nodes), __FILE__, __PRETTY_FUNCTION__, __LINE__);
44 // printf("%s", err_buf); fflush(stdout);
45 // string err_str = err_buf; throw (err_str);
46 
47 // }
48 // int pos_nwords = 0;
49 // for (int i = 1; i <= n ; i++) {
50 // int size = tmp_header.RAWHEADER_NWORDS
51 // + m_buffer[ pos_nwords + tmp_header.RAWHEADER_NWORDS + POS_DATA_LENGTH ]
52 // + SIZE_COPPER_DRIVER_HEADER
53 // + SIZE_COPPER_DRIVER_TRAILER
54 // + tmp_trailer.RAWTRAILER_NWORDS;
55 // // COPPER's data length include one word from COPPER trailer. so -1 is needed.
56 // pos_nwords += size;
57 // if (pos_nwords >= m_nwords) {
58 // char err_buf[500];
59 
60 // sprintf(err_buf, "CORRUPTED DATA: value of pos_nwords(%d) is larger than m_nwords(%d). Exiting...\n %s %s %d\n",
61 // pos_nwords, m_nwords, __FILE__, __PRETTY_FUNCTION__, __LINE__);
62 // printf("%s", err_buf); fflush(stdout);
63 // string err_str = err_buf; throw (err_str);
64 // // exit(1);
65 // }
66 // }
67 // return pos_nwords;
68 // }
69 
70 
71 
72 unsigned int PreRawCOPPERFormat_v1::CalcDriverChkSum(int n)
73 {
74  int min = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS;
75  int max = GetBufferPos(n) + GetBlockNwords(n)
76  - tmp_trailer.RAWTRAILER_NWORDS - SIZE_COPPER_DRIVER_TRAILER;
77  unsigned int chksum = 0;
78  for (int i = min; i < max; i++) {
79  chksum ^= m_buffer[ i ];
80  }
81  return chksum;
82 }
83 
84 
85 
86 int PreRawCOPPERFormat_v1::GetDetectorNwords(int n, int finesse_num)
87 {
88 
89  int nwords = 0;
90  if (GetFINESSENwords(n, finesse_num) > 0) {
91  nwords = GetFINESSENwords(n, finesse_num)
92  - (static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LHSLB_TRAILER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER);
93  }
94  return nwords;
95 
96 }
97 
98 
99 int PreRawCOPPERFormat_v1::GetFINESSENwords(int n, int finesse_num)
100 {
101  if (!CheckCOPPERMagic(n)) {
102  char err_buf[500];
103  PrintData(m_buffer, m_nwords);
104  sprintf(err_buf,
105  "[ERROR] COPPER's magic word is invalid. Exiting... Maybe it is due to data corruption or different version of the data format.\n %s %s %d\n",
106  __FILE__, __PRETTY_FUNCTION__, __LINE__);
107  printf("%s", err_buf); fflush(stdout);
108  B2FATAL(err_buf);
109  }
110  int pos_nwords;
111  switch (finesse_num) {
112  case 0 :
113  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_A_DATA_LENGTH;
114  break;
115  case 1 :
116  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_B_DATA_LENGTH;
117  break;
118  case 2 :
119  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_C_DATA_LENGTH;
120  break;
121  case 3 :
122  pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_D_DATA_LENGTH;
123  break;
124  default :
125  char err_buf[500];
126  sprintf(err_buf, "Specifined FINESSE number( = %d ) is invalid. Exiting...\n %s %s %d\n",
127  finesse_num, __FILE__, __PRETTY_FUNCTION__, __LINE__);
128  printf("%s", err_buf); fflush(stdout);
129  B2FATAL(err_buf);
130  }
131  return m_buffer[ pos_nwords ];
132 
133 }
134 
135 
136 unsigned int PreRawCOPPERFormat_v1::GetB2LFEE32bitEventNumber(int n)
137 {
138 
139 #ifndef READ_OLD_B2LFEE_FORMAT_FILE
140 
141  int err_flag = 0;
142  unsigned int eve_num = 0;
143  int flag = 0;
144  unsigned int eve[4];
145  for (int i = 0; i < 4 ; i++) {
146  eve[ i ] = 12345678;
147  if (GetFINESSENwords(n, i) > 0) {
148  int pos_nwords = GetOffsetFINESSE(n, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
149  eve[ i ] = m_buffer[ pos_nwords ];
150  if (flag != 1) eve_num = eve[ i ];
151  if (eve_num != eve[ i ]) err_flag = 1;
152  flag = 1;
153  }
154  }
155 
156  if (flag == 0) {
157  PrintData(m_buffer, m_nwords);
158  char err_buf[500];
159  sprintf(err_buf, "No HSLB data in COPPER data. Exiting...\n%s %s %d\n",
160  __FILE__, __PRETTY_FUNCTION__, __LINE__);
161  printf("%s", err_buf); fflush(stdout);
162  B2FATAL(err_buf);
163  }
164 
165  if (err_flag == 1) {
166  PrintData(m_buffer, m_nwords);
167  char err_buf[500];
168  sprintf(err_buf, "CORRUPTED DATA: Different event number over HSLBs : slot A 0x%x : B 0x%x :C 0x%x : D 0x%x\n%s %s %d\n",
169  eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
170  __FILE__, __PRETTY_FUNCTION__, __LINE__);
171  printf("[DEBUG] [ERROR] %s\n", err_buf); fflush(stdout);
172 #ifndef NO_DATA_CHECK
173  B2FATAL(err_buf);
174 #endif //NO_DATA_CHECK
175  }
176  return eve_num;
177 
178 #else // READ_OLD_B2LFEE_FORMAT_FILE
179 
180  char err_buf[500];
181  sprintf(err_buf, "You need comment out READ_OLD_B2LFEE_FORMAT_FILE if you are handling a new data format\n%s %s %d\n",
182  __FILE__, __PRETTY_FUNCTION__, __LINE__);
183  printf("%s", err_buf); fflush(stdout);
184  B2FATAL(err_buf);
185 
186 #endif // READ_OLD_B2LFEE_FORMAT_FILE
187 
188 }
189 
190 
191 void PreRawCOPPERFormat_v1::CheckData(int n,
192  unsigned int prev_evenum, unsigned int* cur_evenum_rawcprhdr,
193  unsigned int prev_copper_ctr, unsigned int* cur_copper_ctr,
194  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
195 {
196 
197  char err_buf[500];
198  sprintf(err_buf,
199  "This function for format ver.1 is not supported. (n %d preveve %u eve %u prectr %u ctr %u prevrun %u run %u) Exiting...\n %s %s %d\n",
200  n, prev_evenum, *cur_evenum_rawcprhdr, prev_copper_ctr, *cur_copper_ctr,
201  prev_exprunsubrun_no, *cur_exprunsubrun_no,
202  __FILE__, __PRETTY_FUNCTION__, __LINE__);
203  printf("%s", err_buf); fflush(stdout);
204  B2FATAL(err_buf);
205 
206 // char err_buf[500];
207 // int err_flag = 0;
208 // //
209 // // check Magic words
210 // //
211 // if (!CheckCOPPERMagic(n)) {
212 // sprintf(err_buf, "CORRUPTED DATA: Invalid Magic word 0x7FFFF0008=%u 0xFFFFFAFA=%u 0xFFFFF5F5=%u 0x7FFF0009=%u\n%s %s %d\n",
213 // GetMagicDriverHeader(n),
214 // GetMagicFPGAHeader(n),
215 // GetMagicFPGATrailer(n),
216 // GetMagicDriverTrailer(n),
217 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
218 // err_flag = 1;
219 // }
220 
221 // //
222 // // Event # check
223 // //
224 // *cur_evenum_rawcprhdr = GetEveNo(n);
225 // unsigned int evenum_feehdr = GetB2LFEE32bitEventNumber(n);
226 // if (*cur_evenum_rawcprhdr != evenum_feehdr) {
227 // sprintf(err_buf,
228 // "CORRUPTED DATA: Event # in PreRawCOPPERFormat_v1 header and FEE header is different : cprhdr 0x%x feehdr 0x%x : Exiting...\n%s %s %d\n",
229 // *cur_evenum_rawcprhdr, evenum_feehdr,
230 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
231 // err_flag = 1;
232 // }
233 
234 // //
235 // // Check incrementation of event #
236 // //
237 // *cur_runsubrun_no = GetRunNoSubRunNo(n);
238 // if (
239 // #ifdef WO_FIRST_EVENUM_CHECK
240 // prev_evenum != 0xFFFFFFFF && *cur_evenum_rawcprhdr != 0
241 // #else
242 // prev_runsubrun_no == *cur_runsubrun_no && prev_runsubrun_no >= 0
243 // #endif
244 // ) {
245 // if ((unsigned int)(prev_evenum + 1) != *cur_evenum_rawcprhdr) {
246 // sprintf(err_buf, "CORRUPTED DATA: Event # jump : i %d prev 0x%x cur 0x%x : Exiting...\n%s %s %d\n",
247 // n, prev_evenum, *cur_evenum_rawcprhdr,
248 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
249 // err_flag = 1;
250 // }
251 // }
252 
253 
254 // *cur_copper_ctr = GetCOPPERCounter(n);
255 // if (
256 // #ifdef WO_FIRST_EVENUM_CHECK
257 // prev_copper_ctr != 0xFFFFFFFF
258 // #else
259 // true
260 // #endif
261 // ) {
262 // if ((unsigned int)(prev_copper_ctr + 1) != *cur_copper_ctr) {
263 // sprintf(err_buf, "COPPER counter jump : i %d prev 0x%x cur 0x%x :\n%s %s %d\n",
264 // n, prev_copper_ctr, *cur_copper_ctr,
265 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
266 
267 // #ifdef DESY
268 // //
269 // // In DESY test, we ignore this error
270 // //
271 // printf("[DEBUG] [INFO] %s", err_buf);
272 // #else
273 // err_flag = 1;
274 // #endif
275 
276 // }
277 // }
278 
279 // //
280 // // Check is utime and ctime_trgtype same over different FINESSE data
281 // //
282 // CheckUtimeCtimeTRGType(n);
283 
284 
285 // //
286 // // Check checksum calculated by COPPER driver
287 // //
288 // if (GetDriverChkSum(n) != CalcDriverChkSum(n)) {
289 // sprintf(err_buf,
290 // "CORRUPTED DATA: COPPER driver checkSum error : block %d : length %d eve 0x%x : Trailer chksum 0x%.8x : calcd. now 0x%.8x\n%s %s %d\n",
291 // n,
292 // GetBlockNwords(n),
293 // *cur_evenum_rawcprhdr,
294 // GetDriverChkSum(n),
295 // CalcDriverChkSum(n),
296 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
297 // err_flag = 1;
298 // }
299 
300 
301 // //
302 // // Check checksum calculated by DeSerializerCOPPER()
303 // //
304 // tmp_trailer.SetBuffer(GetRawTrlBufPtr(n));
305 // unsigned int xor_chksum = CalcXORChecksum(GetBuffer(n), GetBlockNwords(n) - tmp_trailer.GetTrlNwords());
306 // if (tmp_trailer.GetChksum() != xor_chksum) {
307 // sprintf(err_buf,
308 // "CORRUPTED DATA: PreRawCOPPERFormat_v1 checksum error : block %d : length %d eve 0x%x : Trailer chksum 0x%.8x : calcd. now 0x%.8x\n %s %s %d\n",
309 // n, GetBlockNwords(n), *cur_evenum_rawcprhdr, tmp_trailer.GetChksum(), xor_chksum,
310 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
311 // err_flag = 1;
312 // }
313 
314 
315 // #ifdef DEBUG
316 // printf("[DEBUG] eve %d %d %d %d %d\n",
317 // GetEveNo(n),
318 // Get1stDetectorNwords(n),
319 // Get2ndDetectorNwords(n),
320 // Get3rdDetectorNwords(n),
321 // Get4thDetectorNwords(n)
322 // );
323 // printf("[DEBUG] ===COPPER BLOCK==============\n");
324 // printData(GetBuffer(n), GetBlockNwords(n));
325 
326 // printf("[DEBUG] ===FINNESSE A ==============\n");
327 // printData(Get1stDetectorBuffer(n), Get1stDetectorNwords(n));
328 
329 // printf("[DEBUG] ===FINNESSE B ==============\n");
330 // printData(Get2ndDetectorBuffer(n), Get2ndDetectorNwords(n));
331 
332 // printf("[DEBUG] ===FINNESSE C ==============\n");
333 // printData(Get3rdDetectorBuffer(n), Get3rdDetectorNwords(n));
334 
335 // printf("[DEBUG] ===FINNESSE D ==============\n");
336 // printData(Get4thDetectorBuffer(n), Get4thDetectorNwords(n));
337 // printf("[DEBUG] === END ==============\n");
338 
339 // #endif
340 
341 // if (err_flag == 1) {
342 // printf("[DEBUG] ========== dump a data blcok : block # %d==========\n", n);
343 // PrintData(GetBuffer(n), GetBlockNwords(n));
344 // printf("%s", err_buf); fflush(stdout);
345 // string err_str = err_buf;
346 // throw (err_str);
347 
348 // // sleep(1234567);
349 // // exit(-1);
350 // }
351 
352  return;
353 
354 }
355 
356 bool PreRawCOPPERFormat_v1::CheckCOPPERMagic(int n)
357 {
358  if (GetMagicDriverHeader(n) != COPPER_MAGIC_DRIVER_HEADER) {
359  return false;
360  } else if (GetMagicFPGAHeader(n) != COPPER_MAGIC_FPGA_HEADER) {
361  return false;
362  } else if (GetMagicFPGATrailer(n) != COPPER_MAGIC_FPGA_TRAILER) {
363  return false;
364  } else if (GetMagicDriverTrailer(n) != COPPER_MAGIC_DRIVER_TRAILER) {
365  return false;
366  }
367  return true;
368 }
369 
370 void PreRawCOPPERFormat_v1::CheckUtimeCtimeTRGType(int n)
371 {
372 
373 #ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
374  CheckB2LFEEHeaderVersion(n);
375 #endif
376  int err_flag = 0;
377  int flag = 0;
378  unsigned int temp_utime = 0, temp_ctime_trgtype = 0;
379  unsigned int utime[4], ctime_trgtype[4];
380  memset(utime, 0, sizeof(utime));
381  memset(ctime_trgtype, 0, sizeof(ctime_trgtype));
382 
383  for (int i = 0; i < 4; i++) {
384  if (GetFINESSENwords(n, i) > 0) {
385  ctime_trgtype[ i ] = m_buffer[ GetOffsetFINESSE(n, i) +
386  SIZE_B2LHSLB_HEADER + POS_TT_CTIME_TYPE ];
387  utime[ i ] = m_buffer[ GetOffsetFINESSE(n, i) +
388  SIZE_B2LHSLB_HEADER + POS_TT_UTIME ];
389  if (flag == 0) {
390  temp_ctime_trgtype = ctime_trgtype[ i ];
391  temp_utime = utime[ i ];
392  flag = 1;
393  } else {
394  if (temp_ctime_trgtype != ctime_trgtype[ i ]
395  || temp_utime != utime[ i ]) {
396  err_flag = 1;
397  }
398  }
399  }
400  }
401 
402  if (err_flag != 0) {
403  for (int i = 0; i < 4; i++) {
404  printf("[DEBUG] FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x\n",
405  i, GetFINESSENwords(n, i), ctime_trgtype[ i ], utime[ i ]);
406  }
407  char err_buf[500];
408  sprintf(err_buf, "CORRUPTED DATA: mismatch over FINESSEs. Exiting...\n %s %s %d\n",
409  __FILE__, __PRETTY_FUNCTION__, __LINE__);
410  printf("%s", err_buf); fflush(stdout);
411  B2FATAL(err_buf);
412  }
413  return;
414 }
415 
416 
417 unsigned int PreRawCOPPERFormat_v1::FillTopBlockRawHeader(unsigned int m_node_id, unsigned int prev_eve32,
418  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
419 {
420 
421  char err_buf[500];
422  sprintf(err_buf,
423  "This function for format ver.1 is not supported. (node %.8x preveve %u prevrun %u currun %u ) Exiting...\n %s %s %d\n",
424  m_node_id, prev_eve32, prev_exprunsubrun_no, *cur_exprunsubrun_no,
425  __FILE__, __PRETTY_FUNCTION__, __LINE__);
426  printf("%s", err_buf); fflush(stdout);
427  B2FATAL(err_buf);
428 
429  return 0xffffffff;
430 
431 // const int datablock_id = 0;
432 // // m_temp_value = 12345678;
433 // //
434 // // This function only fills RawHeader contents for the first datablock.
435 // // # of block should be 1
436 // if (m_num_nodes * m_num_events != 1) {
437 // char err_buf[500];
438 // sprintf(err_buf,
439 // "This function should be used for PreRawCOPPERFormat_v1 containing only one datablock, while. this object has num_nodes of %d and num_events of %d\n %s %s %d\n",
440 // m_num_nodes, m_num_events, __FILE__, __PRETTY_FUNCTION__, __LINE__);
441 // printf("%s", err_buf); fflush(stdout);
442 // string err_str = err_buf; throw (err_str);
443 
444 // }
445 
446 // //////////////////////////////////////////////////
447 // //
448 // // Fill info in RawHeader
449 // //
450 // //////////////////////////////////////////////////
451 
452 // //
453 // // Initialize a RawHeader part
454 // //
455 // memset(m_buffer, 0, sizeof(int) * tmp_header.RAWHEADER_NWORDS);
456 // m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] = tmp_header.RAWHEADER_NWORDS & tmp_header.HDR_NWORDS_MASK;
457 // m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) &
458 // tmp_header.FORMAT_VERSION__MASK;
459 // m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (0x80 << tmp_header.FORMAT_VERSION_SHIFT); // PreFormat
460 // m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= tmp_header.MAGIC_WORD;
461 
462 // //
463 // // Check FINESSEs which containes data
464 // //
465 // int* copper_buf = &(m_buffer[ tmp_header.RAWHEADER_NWORDS ]);
466 // if (copper_buf[ POS_CH_A_DATA_LENGTH ] == 0 &&
467 // copper_buf[ POS_CH_B_DATA_LENGTH ] == 0 &&
468 // copper_buf[ POS_CH_C_DATA_LENGTH ] == 0 &&
469 // copper_buf[ POS_CH_D_DATA_LENGTH ] == 0) {
470 // char err_buf[500];
471 // sprintf(err_buf,
472 // "No FINESSE data in a copper data block. Exiting...\n %s %s %d\n",
473 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
474 // printf("%s", err_buf); fflush(stdout);
475 // string err_str = err_buf; throw (err_str);
476 // // sleep(12345678);
477 // // exit(-1);
478 // }
479 
480 // //
481 // // Set total words info
482 // //
483 // int datablock_nwords =
484 // tmp_header.RAWHEADER_NWORDS +
485 // (copper_buf[ POS_DATA_LENGTH ]
486 // + SIZE_COPPER_DRIVER_HEADER
487 // + SIZE_COPPER_DRIVER_TRAILER)
488 // + tmp_trailer.RAWTRAILER_NWORDS;
489 // m_buffer[ tmp_header.POS_NWORDS ] = datablock_nwords;
490 
491 
492 // //
493 // // Check the consistency between data length and length in RawHeader
494 // //
495 // if (m_buffer[ tmp_header.POS_NWORDS ] != m_nwords) {
496 // char err_buf[500];
497 // sprintf(err_buf,
498 // "CORRUPTED DATA: Data length is inconsistent m_nwords %d : nwords from COPPER data %d\n %s %s %d\n",
499 // m_nwords, m_buffer[ tmp_header.POS_NWORDS ],
500 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
501 // printf("%s", err_buf); fflush(stdout);
502 // string err_str = err_buf; throw (err_str);
503 // // sleep(12345678);
504 // // exit(-1);
505 // }
506 
507 // //
508 // // Fill offset values
509 // //
510 // int offset_1st_finesse = tmp_header.RAWHEADER_NWORDS + SIZE_COPPER_HEADER;
511 // int offset_2nd_finesse = offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ];
512 // int offset_3rd_finesse = offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ];
513 // int offset_4th_finesse = offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ];
514 // m_buffer[ tmp_header.POS_OFFSET_1ST_FINESSE ] = offset_1st_finesse;
515 // m_buffer[ tmp_header.POS_OFFSET_2ND_FINESSE ] = offset_2nd_finesse;
516 // m_buffer[ tmp_header.POS_OFFSET_3RD_FINESSE ] = offset_3rd_finesse;
517 // m_buffer[ tmp_header.POS_OFFSET_4TH_FINESSE ] = offset_4th_finesse;
518 
519 // //
520 // // Fill Exp/Run value
521 // //
522 // int* finesse_buf = &
523 // (m_buffer[ offset_1st_finesse ]); // In any finesse implementations, the top finesse buffer should be at offset_1st_finesse;
524 // m_buffer[ tmp_header.POS_EXP_RUN_NO ] = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_EXP_RUN ];
525 
526 
527 // //
528 // // Fill event #
529 // //
530 // unsigned int cur_ftsw_eve32 = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_TT_TAG ];
531 // m_buffer[ tmp_header.POS_EVE_NO ] = cur_ftsw_eve32;
532 
533 // //
534 // // Copy FTSW words from B2LFEE header
535 // //
536 // m_buffer[ tmp_header.POS_TTCTIME_TRGTYPE ] = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_TT_CTIME_TYPE ];
537 // m_buffer[ tmp_header.POS_TTUTIME ] = finesse_buf[ SIZE_B2LHSLB_HEADER + POS_TT_UTIME ];
538 
539 // //
540 // // Set node ID, trunc_mask, data_type
541 // //
542 // m_buffer[ tmp_header.POS_NODE_ID ] = m_node_id;
543 // m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] = ((m_trunc_mask << 31) & 0x80000000) | (m_data_type & 0x7FFFFFFF);
544 
545 
546 // //////////////////////////////////////////////////
547 // //
548 // // Fill info in RawTrailer
549 // //
550 // //////////////////////////////////////////////////
551 
552 // //
553 // // Calculate XOR checksum
554 // //
555 // unsigned int chksum_top = 0, chksum_body = 0, chksum_bottom = 0;
556 
557 // int top_end = tmp_header.RAWHEADER_NWORDS;
558 // for (int i = 0; i < top_end; i++) {
559 // chksum_top ^= m_buffer[ i ];
560 // }
561 // int body_end = datablock_nwords - SIZE_COPPER_DRIVER_TRAILER - tmp_trailer.RAWTRAILER_NWORDS;
562 // for (int i = top_end; i < body_end; i++) {
563 // chksum_body ^= m_buffer[ i ];
564 // }
565 
566 // int bottom_end = datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS;
567 // for (int i = body_end; i < bottom_end; i++) {
568 // chksum_bottom ^= m_buffer[ i ];
569 // }
570 
571 // //
572 // // check COPPER driver checksum
573 // //
574 // if (chksum_body != (unsigned int)(m_buffer[ body_end ])) {
575 // char err_buf[500];
576 // sprintf(err_buf, "CORRUPTED DATA: COPPER driver checksum is not consistent.: calcd. %.8x data %.8x\n %s %s %d\n",
577 // chksum_body, m_buffer[ body_end ],
578 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
579 // printf("%s", err_buf); fflush(stdout);
580 // string err_str = err_buf; throw (err_str);
581 // // sleep(12345678);
582 // // exit(-1);
583 // }
584 
585 // //
586 // // Fill trailer info (checksum, magic word)
587 // //
588 // unsigned int chksum = chksum_top ^ chksum_body ^ chksum_bottom;
589 // int* trl = &(m_buffer[ datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS ]);
590 // trl[ tmp_trailer.POS_CHKSUM ] = chksum;
591 // trl[ tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
592 
593 
594 // //////////////////////////////////////////////////
595 // //
596 // // Data check ( magic word, event incrementation )
597 // //
598 // //////////////////////////////////////////////////
599 
600 
601 // //
602 // // check magic words
603 // //
604 // int* fpga_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_3);
605 // int* driver_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_4);
606 // int err_flag = 0;
607 // if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_1 ]) != COPPER_MAGIC_DRIVER_HEADER) {
608 // err_flag = 1;
609 // } else if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_2 ]) != COPPER_MAGIC_FPGA_HEADER) {
610 // err_flag = 1;
611 // } else if ((unsigned int)(*fpga_trailer_magic) != COPPER_MAGIC_FPGA_TRAILER) {
612 // err_flag = 1;
613 // } else if ((unsigned int)(*driver_trailer_magic) != COPPER_MAGIC_DRIVER_TRAILER) {
614 // err_flag = 1;
615 // }
616 // if (err_flag == 1) {
617 // char err_buf[500];
618 // sprintf(err_buf, "CORRUPTED DATA: Invalid Magic word 0x7FFFF0008=%u 0xFFFFFAFA=%u 0xFFFFF5F5=%u 0x7FFF0009=%u\n %s %s %d\n",
619 // GetMagicDriverHeader(datablock_id),
620 // GetMagicFPGAHeader(datablock_id),
621 // GetMagicFPGATrailer(datablock_id),
622 // GetMagicDriverTrailer(datablock_id),
623 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
624 // printf("[DEBUG] [ERROR] %s\n", err_buf);
625 // #ifndef NO_DATA_CHECK
626 // string err_str = err_buf; throw (err_str);
627 
628 // // sleep(12345678);
629 // // exit(-1);
630 // #endif
631 // }
632 
633 // //
634 // // check incrementation of event #
635 // //
636 
637 // if ((unsigned int)(prev_eve32 + 1) < 50) {
638 // // printf("#################EVE cur %.8x prev %.8x\n", cur_ftsw_eve32, prev_eve32);
639 // // fflush(stdout);
640 // }
641 
642 
643 // *cur_runsubrun_no = GetRunNoSubRunNo(datablock_id);
644 // if (prev_runsubrun_no == *cur_runsubrun_no && prev_runsubrun_no >= 0) {
645 // if (
646 // #ifdef WO_FIRST_EVENUM_CHECK
647 // (prev_eve32 + 1 != cur_ftsw_eve32) && (prev_eve32 != 0xFFFFFFFF && cur_ftsw_eve32 != 0)
648 // #else
649 // prev_eve32 + 1 != cur_ftsw_eve32
650 // #endif
651 // ) {
652 // #ifndef NO_DATA_CHECK
653 // char err_buf[500];
654 // sprintf(err_buf, "CORRUPTED DATA: Invalid event_number. Exiting...: cur 32bit eve %u preveve %u prun %d crun %d\n %s %s %d\n",
655 // cur_ftsw_eve32, prev_eve32,
656 // prev_runsubrun_no, *cur_runsubrun_no,
657 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
658 // printf("[DEBUG] [ERROR] %s\n", err_buf);
659 
660 // string err_str = err_buf;
661 // printf("[DEBUG] i= %d : num entries %d : Tot words %d\n", 0 , GetNumEntries(), TotalBufNwords());
662 // PrintData(GetBuffer(datablock_id), TotalBufNwords());
663 
664 // throw (err_str);
665 // // exit(-1);
666 // #endif
667 
668 // }
669 // }
670 
671 // return cur_ftsw_eve32;
672 
673 }
674 
675 
676 
677 #ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
678 void PreRawCOPPERFormat_v1::CheckB2LFEEHeaderVersion(int n)
679 {
680  int* temp_buf;
681  for (int i = 0; i < 4; i++) {
682  if (GetFINESSENwords(n, i) > 0) {
683  temp_buf = GetFINESSEBuffer(n, i);
684  if ((temp_buf[ 3 ] & 0x40000000) == 0) {
685 #ifdef TEMP
686  // this word for exp/run
687  // old one (ver.1) used for SPring8 test in 2013
688  printf("[DEBUG] \033[31m");
689  printf("[DEBUG] ===Firmware ver. ERROR===\n ");
690  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");
691  printf("[DEBUG] If you are going to take data now, Please update the firmware.\n");
692  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");
693  printf("[DEBUG] Or if you are going to read data taken before the update, please use basf2 software before svn rev. 7419\n");
694  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");
695  printf("[DEBUG] Sorry for inconvenience.\n");
696  printf("[DEBUG] \033[0m");
697  fflush(stderr);
698  char err_buf[500];
699  sprintf(err_buf, "FTSW and b2tt firmwares are old. Exiting...\n %s %s %d\n",
700  __FILE__, __PRETTY_FUNCTION__, __LINE__);
701  printf("%s", err_buf); fflush(stdout);
702  B2FATAL(err_buf);
703 #endif
704  } else {
705  // this word for 32bit unixtime
706  // new one (ver.2)
707  break;
708  }
709  }
710 
711  if (i == 3) {
712 #ifdef TEMP
713  char err_buf[500];
714  sprintf(err_buf, "PreRawCOPPERFormat_v1 contains no FINESSE data. Exiting...\n %s %s %d\n",
715  __FILE__, __PRETTY_FUNCTION__, __LINE__);
716  printf("%s", err_buf); fflush(stdout);
717  B2FATAL(err_buf);
718 #endif
719  }
720  }
721  return;
722 }
723 #endif
724 
725 
726 //int PreRawCOPPERFormat_v1::CalcReducedDataSize(RawDataBlock* raw_datablk)
727 int PreRawCOPPERFormat_v1::CalcReducedDataSize(int* bufin, int nwords, int num_events, int num_nodes)
728 {
729  //
730  // Calculate reduced length for a total RawDataBlock (containing multiple data blocks)
731  //
732  PreRawCOPPERFormat_v1 rawcpr_fmt;
733  int delete_flag = 0;
734  rawcpr_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
735 
736  int reduced_nwords = 0;
737  for (int k = 0; k < rawcpr_fmt.GetNumEvents(); k++) {
738  int num_nodes_in_sendblock = rawcpr_fmt.GetNumNodes();
739  for (int l = 0; l < num_nodes_in_sendblock; l++) {
740  int entry_id = l + k * num_nodes_in_sendblock;
741  if (rawcpr_fmt.CheckFTSWID(entry_id) || rawcpr_fmt.CheckTLUID(entry_id)) {
742  // No size reduction for non-COPPER data ( FTSW and TLU data blocks )
743  reduced_nwords += rawcpr_fmt.GetBlockNwords(entry_id);
744  } else {
745  PreRawCOPPERFormat_v1 temp_prerawcpr;
746  int temp_delete_flag = 0, temp_num_eve = 1, temp_num_nodes = 1;
747 
748  // Call CalcReducedNwords
749  temp_prerawcpr.SetBuffer(rawcpr_fmt.GetBuffer(entry_id),
750  rawcpr_fmt.GetBlockNwords(entry_id),
751  temp_delete_flag, temp_num_eve,
752  temp_num_nodes);
753  reduced_nwords += temp_prerawcpr.CalcReducedNwords(0);
754  }
755  }
756  }
757  return reduced_nwords;
758 
759 }
760 
761 //void PreRawCOPPERFormat_v1::CopyReducedData(RawDataBlock* raw_datablk, int* buf_to, int delete_flag_from)
762 void PreRawCOPPERFormat_v1::CopyReducedData(int* bufin, int nwords, int num_events, int num_nodes, int* buf_to, int* nwords_to)
763 {
764  //
765  // Make a reduced buffer a total RawDataBlock (containing multiple data blocks)
766  //
767  PreRawCOPPERFormat_v1 rawcpr_fmt;
768  int delete_flag = 0;
769  rawcpr_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
770 
771  int pos_nwords_to = 0;
772  for (int k = 0; k < rawcpr_fmt.GetNumEvents(); k++) {
773  int num_nodes_in_sendblock = rawcpr_fmt.GetNumNodes();
774  for (int l = 0; l < num_nodes_in_sendblock; l++) {
775  int entry_id = l + k * num_nodes_in_sendblock;
776  if (rawcpr_fmt.CheckFTSWID(entry_id) ||
777  rawcpr_fmt.CheckTLUID(entry_id)) {
778  rawcpr_fmt.CopyBlock(entry_id, buf_to + pos_nwords_to);
779  pos_nwords_to += rawcpr_fmt.GetBlockNwords(entry_id);
780 
781  } else {
782  SetBuffer(rawcpr_fmt.GetBuffer(entry_id),
783  rawcpr_fmt.GetBlockNwords(entry_id), 0, 1, 1);
784 
785  pos_nwords_to += CopyReducedBuffer(0, buf_to + pos_nwords_to);
786 
787 
788  }
789  }
790  }
791 
792 // int* buf_from = raw_datablk->GetWholeBuffer();
793 // raw_datablk->SetBuffer(buf_to, pos_nwords_to, 0,
794 // raw_datablk->GetNumEvents(), raw_datablk->GetNumNodes());
795 // if (delete_flag_from == 1) { delete[] buf_from;}
796  *nwords_to = pos_nwords_to;
797  return ;
798 }
799 
800 
801 int PreRawCOPPERFormat_v1::CalcReducedNwords(int n)
802 {
803  //
804  // Calculate reduced length for one data block which is a part of a RawDataBlock
805  //
806 
807  int nwords_to = 0;
808 
809  //RawCOPPER header
810  nwords_to += tmp_header.RAWHEADER_NWORDS;
811 
812  for (int j = 0; j < 4; j++) {
813 
814  int finesse_nwords = GetFINESSENwords(n, j);
815  if (finesse_nwords > 0) {
816  //
817  // B2L(HSLB/FEE) header and trailers are resized
818  // m_reduced_rawcpr should be PostRawCOPPERFormat_v1
819  //
820  nwords_to +=
821  finesse_nwords
822  - (static_cast<int>(SIZE_B2LHSLB_HEADER) - m_reduced_rawcpr.SIZE_B2LHSLB_HEADER)
823  - (static_cast<int>(SIZE_B2LFEE_HEADER) - m_reduced_rawcpr.SIZE_B2LFEE_HEADER)
824  - (static_cast<int>(SIZE_B2LFEE_TRAILER) - m_reduced_rawcpr.SIZE_B2LFEE_TRAILER)
825  - (static_cast<int>(SIZE_B2LHSLB_TRAILER) - m_reduced_rawcpr.SIZE_B2LHSLB_TRAILER);
826  }
827 
828  }
829 
830  //RawCOPPER Trailer
831  nwords_to += tmp_trailer.GetTrlNwords();
832 
833  return nwords_to;
834 }
835 
836 
837 
838 
839 
840 
841 int PreRawCOPPERFormat_v1::CopyReducedBuffer(int n, int* buf_to)
842 {
843  //
844  // Make a reduced buffer for one data block which is a part of a RawDataBlock
845  //
846 
847  int* buf_from = NULL;
848  int nwords_buf_to = CalcReducedNwords(n);
849  int pos_nwords_to = 0;
850  int copy_nwords = 0;
851 
852  // copyt to ReducedRawCOPPER
853  // ReducedRawCOPPER m_reduced_rawcpr;
854  //Header copy
855  copy_nwords = tmp_header.RAWHEADER_NWORDS;
856  buf_from = GetBuffer(n);
857  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
858 
859  // Unset the PreFormat bit ( 15th bit )
860  buf_to[ tmp_header.POS_VERSION_HDRNWORDS ] &= 0xFFFF7FFF;
861 
862  //Check Header
863  // m_reduced_rawcpr.tmp_header.CheckHeader(buf_to + pos_nwords_to - copy_nwords);
864 
865 
866  // copy FINESSE buffer
867  int pos_nwords_finesse[ 4 ];
868  for (int j = 0; j < 4; j++) {
869  pos_nwords_finesse[ j ] = pos_nwords_to;
870  if (GetFINESSENwords(n, j) > 0) {
871  int* finesse_buf = GetFINESSEBuffer(n, j);
872  int finesse_nwords = GetFINESSENwords(n, j);
873 
874 
875  CheckB2LHSLBMagicWords(finesse_buf, finesse_nwords);
876  // copy the whole B2LHSLB header (1word)
877  buf_to[ pos_nwords_to ] = finesse_buf[ POS_MAGIC_B2LHSLB ];
878  pos_nwords_to++;
879 
880  // copy the last word of B2LFEE and body( DetectorBuffer )
881  buf_from =
882  finesse_buf
883  + SIZE_B2LHSLB_HEADER
884  + POS_B2L_CTIME; //the last word of B2LFEE
885 
886  // check finesse buffer size : ( When dumhslb was used, this type of error occured and RecvStream0.py died by Segmentation Fault. ) 2014.12.01.
887  if (finesse_nwords - SIZE_B2LHSLB_HEADER - SIZE_B2LFEE_HEADER
888  - SIZE_B2LFEE_TRAILER - SIZE_B2LHSLB_TRAILER < 0) {
889  char err_buf[500];
890  sprintf(err_buf,
891  "[ERROR] Finesse buffer size is too small( %d words < %d words). May be the data are corrupted. Exiting...\n %s %s %d\n",
892  finesse_nwords, static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER,
893  __FILE__, __PRETTY_FUNCTION__, __LINE__);
894  printf("%s", err_buf); fflush(stdout);
895  B2FATAL(err_buf);
896  }
897 
898  copy_nwords =
899  finesse_nwords
900  - SIZE_B2LHSLB_HEADER // already copied
901  - POS_B2L_CTIME // only one word copied ( SIZE_B2LFEE_HEADER - 1 = POS_B2L_CTIME )
902  - SIZE_B2LFEE_TRAILER // will be copied later
903  - SIZE_B2LHSLB_TRAILER; // Not copied
904 
905  // printf("pos %d nwords %d nwords to %d\n", pos_nwords_to, copy_nwords, nwords_buf_to );
906  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
907 
908  //copy B2LFEE trailer(CRC info)
909  buf_to[ pos_nwords_to ] =
910  finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER
911  - (SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) ];
912  pos_nwords_to++;
913 
914  // check CRC data
915  // CheckCRC16( n, j );
916  }
917  }
918 
919  // copy RawCOPPER trailer
920  buf_from =
921  GetBuffer(n)
922  + GetBlockNwords(n)
923  - tmp_trailer.GetTrlNwords();
924  copy_nwords = tmp_trailer.GetTrlNwords();
925  copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
926 
927  // length check
928  if (pos_nwords_to != nwords_buf_to) {
929  char err_buf[500];
930  sprintf(err_buf, "Buffer overflow. Exiting... %d %d\n", pos_nwords_to, nwords_buf_to);
931  printf("%s", err_buf); fflush(stdout);
932  B2FATAL(err_buf);
933  }
934 
935  //
936  // Apply changes followed by data size reduction
937  //
938  *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS) = nwords_buf_to;
939  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE) = pos_nwords_finesse[ 0 ];
940  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE) = pos_nwords_finesse[ 1 ];
941  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE) = pos_nwords_finesse[ 2 ];
942  *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE) = pos_nwords_finesse[ 3 ];
943 
944 
945  // Recalculate XOR checksum in a RawCOPPER trailer
946  *(buf_to + pos_nwords_to - tmp_trailer.GetTrlNwords() + tmp_trailer.POS_CHKSUM) =
947  CalcXORChecksum(buf_to, pos_nwords_to - tmp_trailer.GetTrlNwords());
948 
949  //
950  // data block # check
951  //
952  m_reduced_rawcpr.SetBuffer(buf_to, nwords_buf_to, 0, GetNumEvents(), GetNumNodes());
953  if (m_reduced_rawcpr.GetNumEvents() * m_reduced_rawcpr.GetNumNodes() <= 0) {
954  char err_buf[500];
955  sprintf(err_buf, "Invalid data block numbers.(# of events %d, # of nodes %d) Exiting...\n",
956  m_reduced_rawcpr.GetNumEvents(), m_reduced_rawcpr.GetNumNodes());
957  printf("%s", err_buf); fflush(stdout);
958  B2FATAL(err_buf);
959  }
960 
961  //
962  // check no-data buffer
963  //
964  for (int i = 0; i < m_reduced_rawcpr.GetNumEvents() * m_reduced_rawcpr.GetNumNodes(); i++) {
965  int nonzero_finesse_buf = 0;
966  for (int j = 0; j < 4; j++) {
967 
968  if (GetFINESSENwords(n, j) > 0) {
969  // m_reduced_rawcpr.CheckCRC16(i, j);
970  nonzero_finesse_buf++;
971  }
972  }
973  if (nonzero_finesse_buf == 0) {
974  char err_buf[500];
975  sprintf(err_buf, "No non-zero FINESSE buffer. Exiting...\n");
976  printf("%s", err_buf); fflush(stdout);
977  B2FATAL(err_buf);
978  }
979  }
980 
981  // post_rawcopper_v1.CheckCRC16(0, 0);
982  // printf("fROM =======================================\n");
983  // for (int k = 0; k < nwords_buf_to; k++) {
984  // printf(" %.8x", GetBuffer(n)[ k ]);
985  // if ( ( k + 1 ) % 10 == 0) {
986  // printf("\n");
987  // }
988  // }
989  // printf("\n");
990 
991  // printf("tO =======================================\n");
992  // for (int k = 0; k < nwords_buf_to; k++) {
993  // printf(" %.8x", buf_to[ k ]);
994  // if ( ( k + 1 ) % 10 == 0) {
995  // printf("\n");
996  // }
997  // }
998  // printf("\n");
999  // printf("=============================================\n");
1000  return pos_nwords_to;
1001 }
1002 
1003 
1004 int PreRawCOPPERFormat_v1::CheckB2LHSLBMagicWords(int* finesse_buf, int finesse_nwords)
1005 {
1006 
1007  if ((finesse_buf[ POS_MAGIC_B2LHSLB ] & 0xFFFF0000) == B2LHSLB_HEADER_MAGIC &&
1008  ((finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ] & 0xFFFF0000)
1009  == B2LHSLB_TRAILER_MAGIC)) {
1010  return 1;
1011  } else {
1012  PrintData(m_buffer, m_nwords);
1013  char err_buf[500];
1014  sprintf(err_buf, "Invalid B2LHSLB magic words 0x%x 0x%x. Exiting... :%s %s %d\n",
1015  finesse_buf[ POS_MAGIC_B2LHSLB ],
1016  finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ],
1017  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1018  printf("%s", err_buf); fflush(stdout);
1019  B2FATAL(err_buf);
1020  return -1;
1021  }
1022 }
1023 
1024 
1025 
1026 int PreRawCOPPERFormat_v1::CheckCRC16(int n, int finesse_num)
1027 {
1028  //
1029  // Calculate CRC16
1030  //
1031  int* buf = GetFINESSEBuffer(n, finesse_num) + SIZE_B2LHSLB_HEADER;
1032  int nwords = GetFINESSENwords(n, finesse_num) - (static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_TRAILER +
1033  SIZE_B2LHSLB_TRAILER);
1034  unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, buf, nwords);
1035 
1036  //
1037  // Compare CRC16 with B2LCRC16
1038  //
1039  buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n, finesse_num)
1040  - ((SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) + SIZE_B2LHSLB_TRAILER) ;
1041 
1042  // printf("PreRawCOPPER : Eve %.8x B2LCRC16 %.8x calculated CRC16 %.8x\n", GetEveNo(n), *buf, temp_crc16 );
1043 
1044  if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
1045  printf("PRE CRC16 error : B2LCRC16 %x Calculated CRC16 %x : Nwords of FINESSE buf %d\n",
1046  *buf, temp_crc16, GetFINESSENwords(n, finesse_num));
1047  int* temp_buf = GetFINESSEBuffer(n, finesse_num);
1048  for (int k = 0; k < GetFINESSENwords(n, finesse_num); k++) {
1049  printf("%.8x ", temp_buf[ k ]);
1050  if ((k + 1) % 10 == 0) {
1051  printf("\n");
1052  }
1053  }
1054  printf("\n");
1055  fflush(stdout);
1056 
1057  char err_buf[500];
1058  sprintf(err_buf,
1059  "[DEBUG] [ERROR] B2LCRC16 (%.4x) differs from one ( %.4x) calculated by PreRawCOPPERfromat class. Exiting...\n %s %s %d\n",
1060  (unsigned short)(*buf & 0xFFFF), temp_crc16,
1061  __FILE__, __PRETTY_FUNCTION__, __LINE__);
1062  printf("%s", err_buf); fflush(stdout);
1063  B2FATAL(err_buf);
1064  }
1065  return 1;
1066 
1067 }
1068 
1069 int* PreRawCOPPERFormat_v1::PackDetectorBuf(int* packed_buf_nwords,
1070  int* detector_buf_1st, int nwords_1st,
1071  int* detector_buf_2nd, int nwords_2nd,
1072  int* detector_buf_3rd, int nwords_3rd,
1073  int* detector_buf_4th, int nwords_4th,
1074  RawCOPPERPackerInfo rawcpr_info)
1075 {
1076  int* packed_buf = NULL;
1077 
1078  int poswords_to = 0;
1079  int* detector_buf[ 4 ] = { detector_buf_1st, detector_buf_2nd, detector_buf_3rd, detector_buf_4th };
1080  const int nwords[ 4 ] = { nwords_1st, nwords_2nd, nwords_3rd, nwords_4th };
1081 
1082  // calculate the event length
1083  int length_nwords = tmp_header.GetHdrNwords() + SIZE_COPPER_HEADER + SIZE_COPPER_TRAILER + tmp_trailer.GetTrlNwords();
1084 
1085  for (int i = 0; i < 4; i++) {
1086  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1087  length_nwords += nwords[ i ];
1088  length_nwords += static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER
1089  + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1090  }
1091 
1092  // allocate buffer
1093  packed_buf = new int[ length_nwords ];
1094  memset(packed_buf, 0, sizeof(int) * length_nwords);
1095 
1096  //
1097  // Fill RawHeader
1098  //
1099  tmp_header.SetBuffer(packed_buf);
1100 
1101  packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
1102  packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] = 0x7f7f8000
1103  | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
1104  | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
1105 
1106  packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << 22)
1107  | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
1108  packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
1109  packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
1110  packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
1111  packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
1112 
1113 
1114 
1115 
1116  // fill the positions of finesse buffers
1117  packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ] = static_cast<int>(tmp_header.RAWHEADER_NWORDS) + SIZE_COPPER_HEADER;
1118 
1119  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ];
1120  if (nwords[ 0 ] > 0) {
1121  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] +=
1122  nwords[ 0 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1123  }
1124 
1125  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ];
1126  if (nwords[ 1 ] > 0) {
1127  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] +=
1128  nwords[ 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1129  }
1130 
1131  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ];
1132  if (nwords[ 2 ] > 0) {
1133  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] += nwords[ 2 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER +
1134  SIZE_B2LHSLB_TRAILER;
1135  }
1136  poswords_to += tmp_header.GetHdrNwords();
1137 
1138  // Fill COPPER header
1139  packed_buf[ poswords_to + POS_MAGIC_COPPER_1 ] = COPPER_MAGIC_DRIVER_HEADER;
1140  packed_buf[ poswords_to + POS_MAGIC_COPPER_2 ] = COPPER_MAGIC_FPGA_HEADER;
1141  packed_buf[ poswords_to + POS_EVE_NUM_COPPER ] = rawcpr_info.eve_num;
1142 
1143  int size_b2l_hdrtrl = static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1144  if (nwords[ 0 ] != 0) packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] = nwords[ 0 ] + size_b2l_hdrtrl;
1145  if (nwords[ 1 ] != 0) packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] = nwords[ 1 ] + size_b2l_hdrtrl;
1146  if (nwords[ 2 ] != 0) packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] = nwords[ 2 ] + size_b2l_hdrtrl;
1147  if (nwords[ 3 ] != 0) packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] = nwords[ 3 ] + size_b2l_hdrtrl;
1148 
1149  packed_buf[ poswords_to + POS_DATA_LENGTH ] =
1150  packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] +
1151  packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] +
1152  packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] +
1153  packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] +
1154  (static_cast<int>(SIZE_COPPER_HEADER) - SIZE_COPPER_DRIVER_HEADER) +
1155  (static_cast<int>(SIZE_COPPER_TRAILER) - SIZE_COPPER_DRIVER_TRAILER);
1156 
1157  poswords_to += SIZE_COPPER_HEADER;
1158 
1159  // Fill FINESSE buffer
1160  for (int i = 0; i < 4; i++) {
1161 
1162  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1163 
1164  // Fill b2link HSLB header
1165  packed_buf[ poswords_to + POS_MAGIC_B2LHSLB ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
1166  poswords_to += SIZE_B2LHSLB_HEADER;
1167  int* crc16_start = &(packed_buf[ poswords_to ]);
1168 
1169  // Fill b2link FEE header
1170 
1171  packed_buf[ poswords_to + POS_TT_CTIME_TYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4;
1172  packed_buf[ poswords_to + POS_TT_TAG ] = rawcpr_info.eve_num;
1173  packed_buf[ poswords_to + POS_TT_UTIME ] = rawcpr_info.tt_utime;
1174  packed_buf[ poswords_to + POS_EXP_RUN ] = (rawcpr_info.exp_num << 22) | (rawcpr_info.run_subrun_num &
1175  0x003FFFFF); // exp. and run #
1176  packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
1177  poswords_to += SIZE_B2LFEE_HEADER;
1178 
1179  // copy the 1st Detector Buffer
1180  memcpy(packed_buf + poswords_to, detector_buf[ i ], nwords[ i ]*sizeof(int));
1181  poswords_to += nwords[ i ];
1182 
1183  // Fill b2link FEE trailer
1184  unsigned short crc16 = CalcCRC16LittleEndian(0xffff, crc16_start, nwords[ i ] + SIZE_B2LFEE_HEADER);
1185  packed_buf[ poswords_to + POS_CHKSUM_B2LFEE ] = ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 & 0xffff);
1186  poswords_to += SIZE_B2LFEE_TRAILER;
1187 
1188  // Fill b2link HSLB trailer
1189  packed_buf[ poswords_to + POS_CHKSUM_B2LHSLB ] = 0xff550000;
1190  poswords_to += SIZE_B2LHSLB_TRAILER;
1191 
1192  }
1193 
1194  // Fill COPPER trailer
1195  packed_buf[ poswords_to + POS_MAGIC_COPPER_3 ] = COPPER_MAGIC_FPGA_TRAILER;
1196  packed_buf[ poswords_to + POS_MAGIC_COPPER_4 ] = COPPER_MAGIC_DRIVER_TRAILER;
1197  unsigned int chksum = 0;
1198  for (int i = tmp_header.GetHdrNwords(); i < poswords_to + (static_cast<int>(SIZE_COPPER_TRAILER) - SIZE_COPPER_DRIVER_TRAILER);
1199  i++) {
1200  chksum ^= packed_buf[ i ];
1201  }
1202  packed_buf[ poswords_to + POS_CHKSUM_COPPER ] = chksum;
1203  poswords_to += SIZE_COPPER_TRAILER;
1204 
1205  // Calculate RawCOPPER checksum and fill RawTrailer
1206  chksum = 0;
1207  for (int i = 0; i < poswords_to; i++) {
1208  chksum ^= packed_buf[ i ];
1209  }
1210  packed_buf[ poswords_to + tmp_trailer.POS_CHKSUM ] = chksum;
1211 
1212  packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
1213  poswords_to += tmp_trailer.GetTrlNwords();
1214 
1215  *packed_buf_nwords = poswords_to;
1216  return packed_buf;
1217 }
1218 
The Raw COPPER class ver.1 ( the latest version since May, 2014 ) This class stores data received by ...
int CalcReducedNwords(int n)
calculate reduced data size
struct to contain header information used by RawCOPPERFormat::Packer()
unsigned int b2l_ctime
32bit unitx time at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user ...
unsigned int eve_num
Run # and subrun # ( 22bit )
unsigned int tt_ctime
Node ID (32bit)
unsigned int tt_utime
27bit clock ticks at trigger timing distributed by FTSW. For details, see Nakao-san's belle2link user...
unsigned int node_id
Event Number (32bit)
unsigned int run_subrun_num
Experiment number (10bit)
unsigned int exp_num
Experiment number (10bit)
virtual int GetBlockNwords(int n)
get size of a data block
virtual int CheckFTSWID(int n)
get FTSW ID to check whether this data block is FTSW data or not
virtual void CopyBlock(int n, int *buf_to)
Copy one datablock to buffer.
virtual void SetBuffer(int *bufin, int nwords, int delete_flag, int num_events, int num_nodes)
set buffer ( delete_flag : m_buffer is freeed( = 0 )/ not freeed( = 1 ) in Destructer )
virtual int GetNumNodes()
get # of data sources(e.g. # of COPPER boards) in m_buffer
virtual int * GetBuffer(int n)
get nth buffer pointer
virtual int GetNumEvents()
get # of events in m_buffer
virtual int CheckTLUID(int n)
get FTSW ID to check whether this data block is FTSW data or not
Abstract base class for different kinds of events.