Belle II Software  release-05-02-19
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 unsigned int PreRawCOPPERFormat_latest::GetB2LFEE32bitEventNumber(int n)
41 {
42 
43 #ifndef READ_OLD_B2LFEE_FORMAT_FILE
44 
45  int err_flag = 0;
46  unsigned int eve_num = 0;
47  int flag = 0;
48  unsigned int eve[MAX_PCIE40_CH];
49  for (int i = 0; i < MAX_PCIE40_CH; i++) {
50  eve[ i ] = 0xbaadf00d;
51  if (GetFINESSENwords(n, i) > 0) {
52  int pos_nwords = GetOffsetFINESSE(n, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
53  eve[ i ] = m_buffer[ pos_nwords ];
54  if (flag != 1) eve_num = eve[ i ];
55  if (eve_num != eve[ i ]) err_flag = 1;
56  flag = 1;
57  }
58  }
59 
60  if (flag == 0) {
61  PrintData(m_buffer, m_nwords);
62  char err_buf[500];
63  char hostname[128];
64  GetNodeName(n, hostname, sizeof(hostname));
65  sprintf(err_buf,
66  "[FATAL] %s ch=%d : ERROR_EVENT : No HSLB data in COPPER data. Exiting... : eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
67  hostname, -1,
68  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
69  __FILE__, __PRETTY_FUNCTION__, __LINE__);
70  printf("%s", err_buf); fflush(stdout);
71  // string err_str = err_buf; throw (err_str);
72  B2FATAL(err_buf); // to reduce multiple error messages
73  }
74 
75  if (err_flag == 1) {
76  vector<vector<unsigned int>> summary_table;
77  CompareHeaderValue(n, eve, summary_table);
78 
79  char err_buf[2500];
80  char err_buf_temp[2500];
81  char hostname[128];
82  GetNodeName(n, hostname, sizeof(hostname));
83  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : CORRUPTED DATA: Different event number over HSLBs :", hostname, -1);
84  for (int i = 0; i < summary_table.size(); i++) {
85  memcpy(err_buf_temp, err_buf, sizeof(err_buf_temp));
86  sprintf(err_buf, "%s [ch= %u ,val= %u (# of chs= %u )] ",
87  err_buf_temp,
88  summary_table.at(i).at(0), summary_table.at(i).at(2), summary_table.at(i).at(1));
89  }
90  memcpy(err_buf_temp, err_buf, sizeof(err_buf_temp));
91  sprintf(err_buf, "%s : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
92  err_buf_temp,
93  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
94  __FILE__, __PRETTY_FUNCTION__, __LINE__);
95 
96  printf("[DEBUG] %s\n", err_buf);
97  PrintData(m_buffer, m_nwords);
98  for (int i = 0; i < MAX_PCIE40_CH; i++) {
99  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
100  if (GetFINESSENwords(n, i) > 0) {
101  CheckCRC16(n, i);
102  }
103  }
104  printf("[DEBUG] ========== No CRC error. : block %d =========\n", n);
105 #ifndef NO_ERROR_STOP
106  // string err_str = err_buf; throw (err_str);
107  B2FATAL(err_buf); // to reduce multiple error messages
108 #endif //NO_ERROR_STOP
109  }
110  return eve_num;
111 
112 #else // READ_OLD_B2LFEE_FORMAT_FILE
113 
114  char err_buf[500];
115  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",
116  __FILE__, __PRETTY_FUNCTION__, __LINE__);
117  printf("%s", err_buf); fflush(stdout);
118  B2FATAL(err_buf); // to reduce multiple error messages
119 #endif // READ_OLD_B2LFEE_FORMAT_FILE
120 
121 }
122 
123 
124 void PreRawCOPPERFormat_latest::CheckData(int n,
125  unsigned int prev_evenum, unsigned int* cur_evenum_rawcprhdr,
126  unsigned int prev_copper_ctr, unsigned int* cur_copper_ctr,
127  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
128 {
129 
130  char err_buf[2500];
131  int err_flag = 0;
132 
133  //
134  // Event # check
135  //
136  *cur_evenum_rawcprhdr = GetEveNo(n);
137  unsigned int evenum_feehdr = GetB2LFEE32bitEventNumber(n);
138  if (*cur_evenum_rawcprhdr != evenum_feehdr) {
139  char hostname[128];
140  GetNodeName(n, hostname, sizeof(hostname));
141  sprintf(err_buf,
142  "[FATAL] %s ch=%d : 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",
143  hostname, -1,
144  *cur_evenum_rawcprhdr, evenum_feehdr,
145  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
146  __FILE__, __PRETTY_FUNCTION__, __LINE__);
147  err_flag = 1;
148  }
149 
150  //
151  // Check incrementation of event #
152  //
153  *cur_exprunsubrun_no = GetExpRunSubrun(n);
154  *cur_copper_ctr = GetCOPPERCounter(n);
155  if (prev_exprunsubrun_no == *cur_exprunsubrun_no) {
156  if ((unsigned int)(prev_evenum + 1) != *cur_evenum_rawcprhdr) {
157  char hostname[128];
158  GetNodeName(n, hostname, sizeof(hostname));
159  sprintf(err_buf,
160  "[FATAL] %s ch=%d : ERROR_EVENT : Event # jump : i %d prev 0x%x cur 0x%x : prevrun %.8x currun %.8x: Exiting... : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
161  hostname, -1,
162  n, prev_evenum, *cur_evenum_rawcprhdr, prev_exprunsubrun_no, *cur_exprunsubrun_no,
163  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
164  __FILE__, __PRETTY_FUNCTION__, __LINE__);
165  err_flag = 1;
166  }
167  if ((unsigned int)(prev_copper_ctr + 1) != *cur_copper_ctr) {
168  char hostname[128];
169  GetNodeName(n, hostname, sizeof(hostname));
170  sprintf(err_buf,
171  "[FATAL] %s ch=%d : ERROR_EVENT : COPPER counter jump : i %d prev 0x%x cur 0x%x : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
172  hostname, -1,
173  n, prev_copper_ctr, *cur_copper_ctr,
174  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
175  __FILE__, __PRETTY_FUNCTION__, __LINE__);
176  err_flag = 1;
177  }
178  } else {
179  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",
180  *cur_exprunsubrun_no, prev_exprunsubrun_no , *cur_evenum_rawcprhdr, prev_evenum,
181  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n));
182 
183  // Check if the first event of a run is zero.
184  if ((unsigned int)GetRunNo(n) != (prev_exprunsubrun_no & RawHeader_latest::RUNNO_MASK) >> RawHeader_latest::RUNNO_SHIFT) {
185  if (*cur_evenum_rawcprhdr != 0) {
186 
187  unsigned int eve[MAX_PCIE40_CH];
188  for (int i = 0; i < MAX_PCIE40_CH ; i++) {
189  eve[ i ] = 0xbaadf00d;
190  if (GetFINESSENwords(n, i) > 0) {
191  int pos_nwords = GetOffsetFINESSE(n, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
192  eve[ i ] = m_buffer[ pos_nwords ];
193  }
194  }
195 
196  vector<vector<unsigned int>> summary_table;
197  CompareHeaderValue(n, eve, summary_table);
198  char hostname[128];
199  GetNodeName(n, hostname, sizeof(hostname));
200  sprintf(err_buf,
201  "[FATAL] %s ch=%d : ERROR_EVENT : Invalid Event # at the beginning of the run (It should be zero.): preveve 0x%x cureve 0x%x : prev(exp %u run %d sub %u ) cur(exp %u run %d sub %u ) (",
202  hostname, -1,
203  prev_evenum, *cur_evenum_rawcprhdr,
204  prev_exprunsubrun_no >> 22 , (prev_exprunsubrun_no >> 8) & 0x3FFF, prev_exprunsubrun_no & 0xFF,
205  *cur_exprunsubrun_no >> 22 , (*cur_exprunsubrun_no >> 8) & 0x3FFF, *cur_exprunsubrun_no & 0xFF);
206 
207  char err_buf_temp[2500];
208  for (int i = 0; i < summary_table.size(); i++) {
209  memcpy(err_buf_temp, err_buf, sizeof(err_buf_temp));
210  sprintf(err_buf, "%s [ch= %u ,val= %u (# of chs= %u )] ",
211  err_buf_temp,
212  summary_table.at(i).at(0), summary_table.at(i).at(2), summary_table.at(i).at(1));
213  }
214  memcpy(err_buf_temp, err_buf, sizeof(err_buf_temp));
215  sprintf(err_buf, "%s Exiting... : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
216  err_buf_temp,
217  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
218  __FILE__, __PRETTY_FUNCTION__, __LINE__);
219  err_flag = 1;
220  }
221  }
222  }
223 
224 
225 
226  //
227  // Check is utime and ctime_trgtype same over different FINESSE data
228  //
229  CheckUtimeCtimeTRGType(n);
230 
231  //
232  // Check checksum calculated by COPPER driver
233  //
234  if (GetDriverChkSum(n) != CalcDriverChkSum(n)) {
235  char hostname[128];
236  GetNodeName(n, hostname, sizeof(hostname));
237  sprintf(err_buf,
238  "[FATAL] %s ch=%d : ERROR_EVENT : COPPER driver checkSum error : block %d : length %d eve 0x%x : Trailer chksum 0x%.8x : calcd. now 0x%.8x : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
239  hostname, -1,
240  n, GetBlockNwords(n), *cur_evenum_rawcprhdr, GetDriverChkSum(n), CalcDriverChkSum(n),
241  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
242  __FILE__, __PRETTY_FUNCTION__, __LINE__);
243  err_flag = 1;
244  }
245 
246  //
247  // Check checksum calculated by DeSerializerCOPPER()
248  //
249  tmp_trailer.SetBuffer(GetRawTrlBufPtr(n));
250  unsigned int xor_chksum = CalcXORChecksum(GetBuffer(n), GetBlockNwords(n) - tmp_trailer.GetTrlNwords());
251  if (tmp_trailer.GetChksum() != xor_chksum) {
252  char hostname[128];
253  GetNodeName(n, hostname, sizeof(hostname));
254  sprintf(err_buf,
255  "[FATAL] %s ch=%d : 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",
256  hostname, -1,
257  n, GetBlockNwords(n), *cur_evenum_rawcprhdr, tmp_trailer.GetChksum(), xor_chksum,
258  GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
259  __FILE__, __PRETTY_FUNCTION__, __LINE__);
260  err_flag = 1;
261  }
262 
263  if (err_flag == 1) {
264  printf("%s", err_buf); fflush(stdout);
265  printf("[DEBUG] ========== dump a data blcok : block # %d==========\n", n);
266  PrintData(GetBuffer(n), GetBlockNwords(n));
267  for (int i = 0; i < MAX_PCIE40_CH; i++) {
268  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
269  if (GetFINESSENwords(n, i) > 0) {
270  CheckCRC16(n, i);
271  }
272  }
273  printf("[DEBUG] ========== No CRC error : block %d =========\n", n);
274  // string err_str = err_buf; throw (err_str);
275  B2FATAL(err_buf); // to reduce multiple error messages
276  }
277 
278  return;
279 
280 }
281 
282 bool PreRawCOPPERFormat_latest::CheckCOPPERMagic(int n)
283 {
284  char err_buf[500];
285  sprintf(err_buf, "[FATAL] This function is not supported. Exiting...: \n%s %s %d\n",
286  __FILE__, __PRETTY_FUNCTION__, __LINE__);
287  printf("[DEBUG] %s\n", err_buf);
288  B2FATAL(err_buf);
289  return false;
290 }
291 
292 void PreRawCOPPERFormat_latest::CheckUtimeCtimeTRGType(int n)
293 {
294 
295 #ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
296  CheckB2LFEEHeaderVersion(n);
297 #endif
298  int err_flag = 0;
299  int flag = 0;
300  unsigned int temp_utime = 0, temp_ctime_trgtype = 0, temp_eve = 0, temp_exprun = 0;
301  unsigned int temp_ctime_trgtype_footer, temp_eve_footer;
302  unsigned int utime[MAX_PCIE40_CH], ctime_trgtype[MAX_PCIE40_CH], eve[MAX_PCIE40_CH], exprun[MAX_PCIE40_CH];
303  char err_buf[2500];
304 
305  memset(utime, 0, sizeof(utime));
306  memset(ctime_trgtype, 0, sizeof(ctime_trgtype));
307  memset(eve, 0, sizeof(eve));
308  memset(exprun, 0, sizeof(exprun));
309 
310  for (int i = 0; i < MAX_PCIE40_CH; i++) {
311  int finesse_nwords = GetFINESSENwords(n, i);
312  if (finesse_nwords > 0) {
313  int offset_finesse = GetOffsetFINESSE(n, i);
314  ctime_trgtype[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_CTIME_TYPE ];
315  utime[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_UTIME ];
316  eve[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_TAG ];
317  exprun[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_EXP_RUN ];
318  temp_ctime_trgtype_footer =
319  m_buffer[ offset_finesse + finesse_nwords - (SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER) + POS_TT_CTIME_B2LFEE ];
320  temp_eve_footer =
321  m_buffer[ offset_finesse + finesse_nwords - (SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER) + POS_CHKSUM_B2LFEE ];
322 
323  if (flag == 0) {
324  temp_ctime_trgtype = ctime_trgtype[ i ];
325  temp_utime = utime[ i ];
326  temp_eve = eve[ i ];
327  temp_exprun = exprun[ i ];
328  flag = 1;
329  } else {
330  if (temp_ctime_trgtype != ctime_trgtype[ i ] || temp_utime != utime[ i ] ||
331  temp_eve != eve[ i ] || temp_exprun != exprun[ i ]) {
332  if (err_flag == 0) {
333  for (int j = 0; j < MAX_PCIE40_CH; j++) {
334  if (GetFINESSENwords(n, j) > 0) {
335  printf("[DEBUG] FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x\n",
336  j, GetFINESSENwords(n, j), ctime_trgtype[ j ], utime[ j ], eve[ j ], exprun[ j ]);
337  }
338  }
339  }
340 
341  char hostname[128];
342  GetNodeName(n, hostname, sizeof(hostname));
343  sprintf(err_buf,
344  "[FATAL] %s ch=%d : ERROR_EVENT : mismatch header value over FINESSEs. Exiting... : %s %s %d\n",
345  hostname, -1,
346  __FILE__, __PRETTY_FUNCTION__, __LINE__);
347  printf("%s", err_buf); fflush(stdout);
348 
349  err_flag = 1;
350  break;
351  } else if (temp_ctime_trgtype != temp_ctime_trgtype_footer ||
352  (temp_eve & 0xffff) != ((temp_eve_footer >> 16) & 0xffff)) {
353  char hostname[128];
354  GetNodeName(n, hostname, sizeof(hostname));
355  sprintf(err_buf,
356  "[FATAL] %s ch=%d : ERROR_EVENT : mismatch(finesse %d) between header(ctime %.8x eve %.8x) and footer(ctime %.8x eve_crc16 %.8x). Exiting...\n %s %s %d\n",
357  hostname, i,
358  i, temp_ctime_trgtype, temp_eve, temp_ctime_trgtype_footer, temp_eve_footer,
359  __FILE__, __PRETTY_FUNCTION__, __LINE__);
360  printf("%s", err_buf); fflush(stdout);
361  err_flag = 1;
362  }
363  }
364  }
365  }
366 
367  if (err_flag != 0) {
368  for (int i = 0; i < MAX_PCIE40_CH; i++) {
369  if (GetFINESSENwords(n, i) > 0) {
370  printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
371  CheckCRC16(n, i);
372  printf("[DEBUG] ========== CRC check is done. : block %d =========\n", n);
373  }
374  }
375 #ifndef NO_ERROR_STOP
376  // string err_str = err_buf; throw (err_str);
377  B2FATAL(err_buf); // to reduce multiple error messages
378 #endif
379  }
380  return;
381 }
382 
383 unsigned int PreRawCOPPERFormat_latest::FillTopBlockRawHeader(unsigned int /*m_node_id*/, unsigned int /*prev_eve32*/,
384  unsigned int /*prev_exprunsubrun_no*/, unsigned int* /*cur_exprunsubrun_no*/)
385 {
386  char err_buf[500];
387  sprintf(err_buf, "[FATAL] This function is not supported. Exiting...: \n%s %s %d\n",
388  __FILE__, __PRETTY_FUNCTION__, __LINE__);
389  printf("[DEBUG] %s\n", err_buf);
390  B2FATAL(err_buf);
391  return 0;
392 }
393 
394 
395 
396 #ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
397 void PreRawCOPPERFormat_latest::CheckB2LFEEHeaderVersion(int n)
398 {
399  int* temp_buf;
400  for (int i = 0; i < MAX_PCIE40_CH; i++) {
401  if (GetFINESSENwords(n, i) > 0) {
402  temp_buf = GetFINESSEBuffer(n, i);
403  if ((temp_buf[ 3 ] & 0x40000000) == 0) {
404 #ifdef TEMP
405  // this word for exp/run
406  // old one (ver.1) used for SPring8 test in 2013
407  printf("[DEBUG] \033[31m");
408  printf("[DEBUG] ===Firmware ver. ERROR===\n ");
409  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");
410  printf("[DEBUG] If you are going to take data now, Please update the firmware.\n");
411  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");
412  printf("[DEBUG] Or if you are going to read data taken before the update, please use basf2 software before svn revision 7419\n");
413  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");
414  printf("[DEBUG] Sorry for inconvenience.\n");
415  printf("[DEBUG] \033[0m");
416  fflush(stderr);
417  char err_buf[500];
418  char hostname[128];
419  GetNodeName(n, hostname, sizeof(hostname));
420  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : FTSW and b2tt firmwares are old. Exiting...\n %s %s %d\n",
421  hostname, i,
422  __FILE__, __PRETTY_FUNCTION__, __LINE__);
423  B2FATAL(err_buf);
424 #endif
425  } else {
426  // this word for 32bit unixtime
427  // new one (ver.2)
428  break;
429  }
430  }
431 
432  if (i == MAX_PCIE40_CH - 1) {
433 #ifdef TEMP
434  char err_buf[500];
435  char hostname[128];
436  GetNodeName(n, hostname, sizeof(hostname));
437  sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : PreRawCOPPERFormat_latest contains no FINESSE data. Exiting...\n %s %s %d\n",
438  hostname, i,
439  __FILE__, __PRETTY_FUNCTION__, __LINE__);
440  printf("%s", err_buf); fflush(stdout);
441  // string err_str = err_buf; throw (err_str);
442  B2FATAL(err_buf); // to reduce multiple error messages
443 #endif
444  }
445  }
446  return;
447 }
448 #endif
449 
450 //int PreRawCOPPERFormat_latest::CalcReducedDataSize(RawDataBlock* raw_datablk)
451 int PreRawCOPPERFormat_latest::CalcReducedDataSize(int* bufin, int nwords, int num_events, int num_nodes)
452 {
453  //
454  // Calculate reduced length for a total RawDataBlock (containing multiple data blocks)
455  //
456  RawDataBlockFormat radblk_fmt;
457  int delete_flag = 0;
458  radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
459 
460  int reduced_nwords = 0;
461  for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
462  int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
463  for (int l = 0; l < num_nodes_in_sendblock; l++) {
464  int entry_id = l + k * num_nodes_in_sendblock;
465 
466  if (radblk_fmt.CheckFTSWID(entry_id) || radblk_fmt.CheckTLUID(entry_id)) {
467  reduced_nwords += radblk_fmt.GetBlockNwords(entry_id);
468  } else {
469  PreRawCOPPERFormat_latest temp_prerawcpr;
470  int temp_delete_flag = 0, temp_num_eve = 1, temp_num_nodes = 1;
471 
472  // Call CalcReducedNwords
473  temp_prerawcpr.SetBuffer(radblk_fmt.GetBuffer(entry_id),
474  radblk_fmt.GetBlockNwords(entry_id),
475  temp_delete_flag, temp_num_eve,
476  temp_num_nodes);
477  reduced_nwords += temp_prerawcpr.CalcReducedNwords(0);
478  }
479  }
480  }
481  return reduced_nwords;
482 
483 }
484 
485 //void PreRawCOPPERFormat_latest::CopyReducedData(RawDataBlock* raw_datablk, int* buf_to, int delete_flag_from)
486 void PreRawCOPPERFormat_latest::CopyReducedData(int* bufin, int nwords, int num_events, int num_nodes, int* buf_to, int* nwords_to)
487 {
488  //
489  // Make a reduced buffer a total RawDataBlock (containing multiple data blocks)
490  //
491  RawDataBlockFormat radblk_fmt;
492  int delete_flag = 0;
493  radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
494 
495  int pos_nwords_to = 0;
496  for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
497  int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
498  for (int l = 0; l < num_nodes_in_sendblock; l++) {
499  int entry_id = l + k * num_nodes_in_sendblock;
500  if (radblk_fmt.CheckFTSWID(entry_id) ||
501  radblk_fmt.CheckTLUID(entry_id)) {
502  radblk_fmt.CopyBlock(entry_id, buf_to + pos_nwords_to);
503  pos_nwords_to += radblk_fmt.GetBlockNwords(entry_id);
504 
505  } else {
506  SetBuffer(radblk_fmt.GetBuffer(entry_id),
507  radblk_fmt.GetBlockNwords(entry_id), 0, 1, 1);
508 
509  pos_nwords_to += CopyReducedBuffer(0, buf_to + pos_nwords_to);
510 
511 
512  }
513  }
514  }
515 
516  *nwords_to = pos_nwords_to;
517 
518  return ;
519 }
520 
521 
522 int PreRawCOPPERFormat_latest::CalcReducedNwords(int n)
523 {
524  char err_buf[500];
525  sprintf(err_buf, "[FATAL] This function is not supported. Exiting...: \n%s %s %d\n",
526  __FILE__, __PRETTY_FUNCTION__, __LINE__);
527  printf("[DEBUG] %s\n", err_buf);
528  B2FATAL(err_buf);
529  return -1;
530 }
531 
532 
533 int PreRawCOPPERFormat_latest::CopyReducedBuffer(int n, int* buf_to)
534 {
535  char err_buf[500];
536  sprintf(err_buf, "[FATAL] This function is not supported. Exiting...: \n%s %s %d\n",
537  __FILE__, __PRETTY_FUNCTION__, __LINE__);
538  printf("[DEBUG] %s\n", err_buf);
539  B2FATAL(err_buf);
540  return -1;
541 }
542 
543 
544 int PreRawCOPPERFormat_latest::CheckB2LHSLBMagicWords(int* finesse_buf, int finesse_nwords)
545 {
546 
547  if ((finesse_buf[ POS_MAGIC_B2LHSLB ] & 0xFFFF0000) == B2LHSLB_HEADER_MAGIC &&
548  ((finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ] & 0xFFFF0000)
549  == B2LHSLB_TRAILER_MAGIC)) {
550  return 1;
551  } else {
552  PrintData(m_buffer, m_nwords);
553  char err_buf[500];
554  sprintf(err_buf,
555  "Invalid B2LHSLB magic words : header 0x%x (= should be ffaa**** ) or trailer 0x%x (= should be ff55**** ). Exiting... :%s %s %d\n",
556  finesse_buf[ POS_MAGIC_B2LHSLB ],
557  finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ],
558  __FILE__, __PRETTY_FUNCTION__, __LINE__);
559 #ifndef NO_ERROR_STOP
560  printf("%s", err_buf); fflush(stdout);
561  B2FATAL(err_buf);
562 #endif
563  }
564 }
565 
566 
567 
568 int PreRawCOPPERFormat_latest::CheckCRC16(int n, int finesse_num)
569 {
570  //
571  // Calculate CRC16
572  //
573  int* buf = GetFINESSEBuffer(n, finesse_num) + SIZE_B2LHSLB_HEADER;
574  int nwords = GetFINESSENwords(n, finesse_num) - (SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER);
575  unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, buf, nwords);
576 
577  //
578  // Compare CRC16 with B2LCRC16
579  //
580  buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n, finesse_num)
581  - ((SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) + SIZE_B2LHSLB_TRAILER) ;
582 
583  if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
584  char err_buf[500];
585  char hostname[128];
586  GetNodeName(n, hostname, sizeof(hostname));
587  PrintData(GetBuffer(n), *(GetBuffer(n) + tmp_header.POS_NWORDS));
588  printf("[FATAL] %s ch=%d : ERROR_EVENT : PRE CRC16 error : slot %c : B2LCRC16 %x Calculated CRC16 %x : Nwords of FINESSE buf %d\n",
589  hostname, finesse_num,
590  65 + finesse_num, *buf , temp_crc16, GetFINESSENwords(n, finesse_num));
591  int* temp_buf = GetFINESSEBuffer(n, finesse_num);
592  for (int k = 0; k < GetFINESSENwords(n, finesse_num); k++) {
593  printf("%.8x ", temp_buf[ k ]);
594  if ((k + 1) % 10 == 0) {
595  printf("\n");
596  }
597  }
598  printf("\n");
599  fflush(stdout);
600  sprintf(err_buf,
601  "[FATAL] %s ch=%d : ERROR_EVENT : slot %c : B2LCRC16 (%.4x) differs from one ( %.4x) calculated by PreRawCOPPERfromat class. Exiting...\n %s %s %d\n",
602  hostname, finesse_num,
603  65 + finesse_num, (unsigned short)(*buf & 0xFFFF), temp_crc16,
604  __FILE__, __PRETTY_FUNCTION__, __LINE__);
605  printf("%s", err_buf); fflush(stdout);
606  B2FATAL(err_buf); // to reduce multiple error messages
607  }
608  return 1;
609 
610 }
611 
612 int* PreRawCOPPERFormat_latest::PackDetectorBuf(int* /*packed_buf_nwords*/,
613  int* /*detector_buf_1st*/, int /*nwords_1st*/,
614  int* /*detector_buf_2nd*/, int /*nwords_2nd*/,
615  int* /*detector_buf_3rd*/, int /*nwords_3rd*/,
616  int* /*detector_buf_4th*/, int /*nwords_4th*/,
617  RawCOPPERPackerInfo rawcpr_info)
618 {
619  char err_buf[500];
620  sprintf(err_buf, "[FATAL] This function is not supported. (%u) Exiting...: \n%s %s %d\n",
621  rawcpr_info.eve_num,
622  __FILE__, __PRETTY_FUNCTION__, __LINE__);
623  printf("[DEBUG] %s\n", err_buf);
624  B2FATAL(err_buf);
625  return NULL;
626 }
627 
628 int* PreRawCOPPERFormat_latest::PackDetectorBuf(int* packed_buf_nwords,
629  int* const(&detector_buf_ch)[MAX_PCIE40_CH],
630  int const(&nwords_ch)[MAX_PCIE40_CH],
631  RawCOPPERPackerInfo rawcpr_info)
632 {
633  int* packed_buf = NULL;
634  int poswords_to = 0;
635 
636  // calculate the event length
637  int length_nwords = tmp_header.GetHdrNwords() + SIZE_COPPER_HEADER + SIZE_COPPER_TRAILER + tmp_trailer.GetTrlNwords();
638 
639  for (int i = 0; i < MAX_PCIE40_CH; i++) {
640  if (detector_buf_ch[ i ] == NULL || nwords_ch[ i ] <= 0) continue; // for an empty FINESSE slot
641  length_nwords += nwords_ch[ i ];
642  length_nwords += SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER
643  + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
644  }
645 
646  // allocate buffer
647  packed_buf = new int[ length_nwords ];
648  memset(packed_buf, 0, sizeof(int) * length_nwords);
649 
650  //
651  // Fill RawHeader
652  //
653  tmp_header.SetBuffer(packed_buf);
654 
655  packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
656  packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] = 0x7f7f8000
657  | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
658  | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
659  packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT)
660  | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
661  packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
662  packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
663  packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
664  packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
665 
666  // fill the positions of finesse buffers
667  int ch = 0;
668  packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = tmp_header.RAWHEADER_NWORDS;
669  for (int i = 1; i < MAX_PCIE40_CH; i++) {
670  ch = i;
671  if (nwords_ch[ ch - 1 ] == 0) {
672  packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = packed_buf[ tmp_header.POS_CH_POS_TABLE + (ch - 1) ];
673  } else {
674  packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = packed_buf[ tmp_header.POS_CH_POS_TABLE + (ch - 1) ] +
675  nwords_ch[ ch - 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
676  }
677  }
678  poswords_to += tmp_header.GetHdrNwords();
679 
680  // Fill FINESSE buffer
681  for (int i = 0; i < MAX_PCIE40_CH; i++) {
682  if (detector_buf_ch[ i ] == NULL || nwords_ch[ i ] <= 0) continue; // for an empty FINESSE slot
683 
684  // Fill b2link HSLB header
685  packed_buf[ poswords_to + POS_MAGIC_B2LHSLB ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
686  poswords_to += SIZE_B2LHSLB_HEADER;
687  int* crc16_start = &(packed_buf[ poswords_to ]);
688 
689  // Fill b2link FEE header
690  packed_buf[ poswords_to + POS_TT_CTIME_TYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4;
691  unsigned int temp_ctime_type = packed_buf[ poswords_to + POS_TT_CTIME_TYPE ];
692  packed_buf[ poswords_to + POS_TT_TAG ] = rawcpr_info.eve_num;
693  packed_buf[ poswords_to + POS_TT_UTIME ] = rawcpr_info.tt_utime;
694  packed_buf[ poswords_to + POS_EXP_RUN ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT) | (rawcpr_info.run_subrun_num &
695  0x003FFFFF); // exp. and run #
696  packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
697  poswords_to += SIZE_B2LFEE_HEADER;
698 
699  // copy the 1st Detector Buffer
700  memcpy(packed_buf + poswords_to, detector_buf_ch[ i ], nwords_ch[ i ]*sizeof(int));
701  poswords_to += nwords_ch[ i ];
702 
703  // Fill b2link b2tt-tag trailer
704  packed_buf[ poswords_to + POS_TT_CTIME_B2LFEE ] = temp_ctime_type;
705 
706  // Fill b2link FEE trailer
707  unsigned short crc16 = CalcCRC16LittleEndian(0xffff, crc16_start, nwords_ch[ i ] + SIZE_B2LFEE_HEADER);
708  packed_buf[ poswords_to + POS_CHKSUM_B2LFEE ] = ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 & 0xffff);
709  poswords_to += SIZE_B2LFEE_TRAILER;
710 
711  // Fill b2link HSLB trailer
712  packed_buf[ poswords_to + POS_CHKSUM_B2LHSLB ] = 0xff550000;
713  poswords_to += SIZE_B2LHSLB_TRAILER;
714  }
715 
716  // Calculate RawCOPPER checksum and fill RawTrailer
717  unsigned int chksum = 0;
718  for (int i = 0; i < poswords_to; i++) {
719  chksum ^= packed_buf[ i ];
720  }
721  packed_buf[ poswords_to + tmp_trailer.POS_CHKSUM ] = chksum;
722 
723  packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
724  poswords_to += tmp_trailer.GetTrlNwords();
725 
726  *packed_buf_nwords = poswords_to;
727  return packed_buf;
728 }
729 
730 
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:522
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