Belle II Software  release-08-01-10
PostRawCOPPERFormat_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/PostRawCOPPERFormat_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(PostRawCOPPERFormat_v1);
20 
21 PostRawCOPPERFormat_v1::PostRawCOPPERFormat_v1()
22 {
23 }
24 
25 PostRawCOPPERFormat_v1::~PostRawCOPPERFormat_v1()
26 {
27 }
28 
29 // int PostRawCOPPERFormat_v1::GetBufferPos(int n)
30 // {
31 // if (m_buffer == NULL || m_nwords <= 0) {
32 // char err_buf[500];
33 // sprintf(err_buf, "[DEBUG] [ERROR] RawPacket buffer(%p) is not available or length(%d) is not set.\n %s %s %d\n",
34 // m_buffer, m_nwords, __FILE__, __PRETTY_FUNCTION__, __LINE__);
35 // string err_str = err_buf; throw (err_str);
36 // }
37 
38 // if (n >= (m_num_events * m_num_nodes)) {
39 // char err_buf[500];
40 // sprintf(err_buf, "[DEBUG] Invalid COPPER block No. (%d : max %d ) is specified. Exiting... \n %s %s %d\n",
41 // n, (m_num_events * m_num_nodes), __FILE__, __PRETTY_FUNCTION__, __LINE__);
42 // string err_str = err_buf; throw (err_str);
43 // }
44 // int pos_nwords = 0;
45 
46 
47 // for (int i = 1; i <= n ; i++) {
48 // tmp_header.SetBuffer(&m_buffer[ pos_nwords ]);
49 // pos_nwords += tmp_header.GetNwords();
50 
51 // if (pos_nwords >= m_nwords) {
52 // char err_buf[500];
53 // sprintf(err_buf, "CORRUPTED DATA: value of pos_nwords(%d) is larger than m_nwords(%d). Exiting...\n %s %s %d\n",
54 // pos_nwords, m_nwords, __FILE__, __PRETTY_FUNCTION__, __LINE__);
55 // string err_str = err_buf; throw (err_str);
56 // // exit(1);
57 // }
58 // }
59 // return pos_nwords;
60 // }
61 
62 
63 int PostRawCOPPERFormat_v1::GetDetectorNwords(int n, int finesse_num)
64 {
65 
66  int nwords = 0;
67  if (GetFINESSENwords(n, finesse_num) > 0) {
68  nwords = GetFINESSENwords(n, finesse_num)
69  - (static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LHSLB_TRAILER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER);
70  }
71  return nwords;
72 
73 }
74 
75 
76 unsigned int PostRawCOPPERFormat_v1::CalcDriverChkSum(int n)
77 {
78  char err_buf[500];
79  sprintf(err_buf, "This function is not supported.(block %d) Exiting...: \n%s %s %d\n",
80  n, __FILE__, __PRETTY_FUNCTION__, __LINE__);
81  printf("%s", err_buf); fflush(stdout);
82  B2FATAL(err_buf);
83  return 0;
84 }
85 
86 
87 int PostRawCOPPERFormat_v1::GetFINESSENwords(int n, int finesse_num)
88 {
89  int pos_nwords_0, pos_nwords_1;
90  int nwords = 0;
91  switch (finesse_num) {
92  case 0 :
93  pos_nwords_0 = GetBufferPos(n) + tmp_header.POS_OFFSET_1ST_FINESSE;
94  pos_nwords_1 = GetBufferPos(n) + tmp_header.POS_OFFSET_2ND_FINESSE;
95  nwords = m_buffer[ pos_nwords_1 ] - m_buffer[ pos_nwords_0 ];
96  break;
97  case 1 :
98  pos_nwords_0 = GetBufferPos(n) + tmp_header.POS_OFFSET_2ND_FINESSE;
99  pos_nwords_1 = GetBufferPos(n) + tmp_header.POS_OFFSET_3RD_FINESSE;
100  nwords = m_buffer[ pos_nwords_1 ] - m_buffer[ pos_nwords_0 ];
101  break;
102  case 2 :
103  pos_nwords_0 = GetBufferPos(n) + tmp_header.POS_OFFSET_3RD_FINESSE;
104  pos_nwords_1 = GetBufferPos(n) + tmp_header.POS_OFFSET_4TH_FINESSE;
105  nwords = m_buffer[ pos_nwords_1 ] - m_buffer[ pos_nwords_0 ];
106  break;
107  case 3 :
108  pos_nwords_0 = GetBufferPos(n) + tmp_header.POS_OFFSET_4TH_FINESSE;
109  {
110  int nwords_1 = GetBlockNwords(n)
111  - SIZE_COPPER_DRIVER_TRAILER
112  - tmp_trailer.GetTrlNwords();
113  nwords = nwords_1 - m_buffer[ pos_nwords_0 ];
114  }
115  break;
116  default :
117  char err_buf[500];
118  sprintf(err_buf, "Invalid finesse # : %s %s %d\n",
119  __FILE__, __PRETTY_FUNCTION__, __LINE__);
120  printf("%s", err_buf); fflush(stdout);
121  B2FATAL(err_buf);
122  }
123 
124  if (nwords < 0 || nwords > 1e6) {
125  char err_buf[500];
126  sprintf(err_buf, "# of words is strange. %d : %s %s %d\n", nwords,
127  __FILE__, __PRETTY_FUNCTION__, __LINE__);
128  printf("%s", err_buf); fflush(stdout);
129  B2FATAL(err_buf);
130  }
131 
132  return nwords;
133 
134 }
135 
136 
137 
138 
139 unsigned int PostRawCOPPERFormat_v1::GetB2LFEE32bitEventNumber(int n)
140 {
141  char err_buf[500];
142  sprintf(err_buf, "No event # in B2LFEE header. (block %d) Exiting...\n%s %s %d\n",
143  n, __FILE__, __PRETTY_FUNCTION__, __LINE__);
144  printf("%s", err_buf); fflush(stdout);
145  B2FATAL(err_buf);
146  return 0;
147 }
148 
149 
150 
151 void PostRawCOPPERFormat_v1::CheckData(int n,
152  unsigned int prev_evenum, unsigned int* cur_evenum_rawcprhdr,
153  unsigned int prev_copper_ctr, unsigned int* cur_copper_ctr,
154  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
155 {
156 
157  char err_buf[500];
158  sprintf(err_buf,
159  "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",
160  n, prev_evenum, *cur_evenum_rawcprhdr, prev_copper_ctr, *cur_copper_ctr,
161  prev_exprunsubrun_no, *cur_exprunsubrun_no,
162  __FILE__, __PRETTY_FUNCTION__, __LINE__);
163  printf("%s", err_buf); fflush(stdout);
164  B2FATAL(err_buf);
165 
166 // char err_buf[500];
167 // int err_flag = 0;
168 // //
169 // // Check incrementation of event #
170 // //
171 // *cur_evenum_rawcprhdr = GetEveNo(n);
172 // *cur_exprunsubrun_no = GetExpRunSubrun(n);
173 // if (
174 // prev_exprunsubrun_no == *cur_exprunsubrun_no
175 // #ifdef WO_FIRST_EVENUM_CHECK
176 // && prev_evenum != 0xFFFFFFFF && *cur_evenum_rawcprhdr != 0
177 // #endif
178 // ) {
179 // if ((unsigned int)(prev_evenum + 1) != *cur_evenum_rawcprhdr) {
180 // sprintf(err_buf, "CORRUPTED DATA: Event # jump : i %d prev 0x%x cur 0x%x : Exiting...\n%s %s %d\n",
181 // n, prev_evenum, *cur_evenum_rawcprhdr,
182 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
183 // err_flag = 1;
184 // }
185 // }
186 
187 
188 // //
189 // // Check checksum calculated by DeSerializerCOPPER()
190 // //
191 // tmp_trailer.SetBuffer(GetRawTrlBufPtr(n));
192 // unsigned int xor_chksum = CalcXORChecksum(GetBuffer(n), GetBlockNwords(n) - tmp_trailer.GetTrlNwords());
193 // if (tmp_trailer.GetChksum() != xor_chksum) {
194 // sprintf(err_buf,
195 // "CORRUPTED DATA: checksum error : block %d : length %d eve 0x%x : Trailer chksum 0x%.8x : calcd. now 0x%.8x\n %s %s %d\n",
196 // n, GetBlockNwords(n), *cur_evenum_rawcprhdr, tmp_trailer.GetChksum(), xor_chksum,
197 // __FILE__, __PRETTY_FUNCTION__, __LINE__);
198 // err_flag = 1;
199 // }
200 
201 
202 // if (err_flag == 1) {
203 // printf("[DEBUG] ========== dump a data blcok : block # %d==========\n", n);
204 // PrintData(GetBuffer(n), GetBlockNwords(n));
205 // printf("Print out variables to reduce unused-variables-warnings : %u %u\n", prev_copper_ctr, *cur_copper_ctr);
206 // string err_str = err_buf;
207 // throw (err_str);
208 
209 // // sleep(1234567);
210 // // exit(-1);
211 // }
212 
213  return;
214 
215 }
216 
217 bool PostRawCOPPERFormat_v1::CheckCOPPERMagic(int n)
218 {
219  char err_buf[500];
220  sprintf(err_buf, "No magic word # in COPPER header (block %d). Exiting...\n%s %s %d\n",
221  n, __FILE__, __PRETTY_FUNCTION__, __LINE__);
222  printf("%s", err_buf); fflush(stdout);
223  B2FATAL(err_buf);
224  return false;
225 }
226 
227 void PostRawCOPPERFormat_v1::CheckUtimeCtimeTRGType(int n)
228 {
229  char err_buf[500];
230  sprintf(err_buf, "This function is not supported (block %d). Exiting...\n%s %s %d\n",
231  n, __FILE__, __PRETTY_FUNCTION__, __LINE__);
232  printf("%s", err_buf); fflush(stdout);
233  B2FATAL(err_buf);
234 }
235 
236 
237 unsigned int PostRawCOPPERFormat_v1::FillTopBlockRawHeader(unsigned int m_node_id, unsigned int prev_eve32,
238  unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
239 {
240  char err_buf[500];
241  sprintf(err_buf, "This function should be called by PrePostRawCOPPERFormat_***. Exiting...\n %s %s %d\n",
242  __FILE__, __PRETTY_FUNCTION__, __LINE__);
243  printf("Print out variables to reduce unused-variables-warnings : %u %u %u %u\n",
244  m_node_id, prev_eve32, prev_exprunsubrun_no, *cur_exprunsubrun_no);
245  printf("%s", err_buf); fflush(stdout);
246  B2FATAL(err_buf);
247 }
248 
249 
250 int PostRawCOPPERFormat_v1::CheckB2LHSLBMagicWords(int* finesse_buf, int finesse_nwords)
251 {
252  char err_buf[500];
253  sprintf(err_buf, "This function should be called by PrePostRawCOPPERFormat_***. Exiting...\n %s %s %d\n",
254  __FILE__, __PRETTY_FUNCTION__, __LINE__);
255  printf("Print out variables to reduce unused-variables-warnings : %p %d\n", finesse_buf, finesse_nwords);
256  printf("%s", err_buf); fflush(stdout);
257  B2FATAL(err_buf);
258 }
259 
260 int PostRawCOPPERFormat_v1::CheckCRC16(int n, int finesse_num)
261 {
262 
263  //
264  // Calculate CRC16
265  //
266  int finesse_nwords = GetFINESSENwords(n, finesse_num);
267  if (finesse_nwords <= 0) {
268  char err_buf[500];
269  sprintf(err_buf, "The specified finesse(%d) seems to be empty(nwords = %d). Cannot calculate CRC16. Exiting...\n %s %s %d\n",
270  finesse_num, finesse_nwords, __FILE__, __PRETTY_FUNCTION__, __LINE__);
271  printf("%s", err_buf); fflush(stdout);
272  B2FATAL(err_buf);
273  }
274  unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, &(m_buffer[ tmp_header.POS_TTCTIME_TRGTYPE ]), 1);
275  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, &(m_buffer[ tmp_header.POS_EVE_NO ]), 1);
276  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, &(m_buffer[ tmp_header.POS_TTUTIME ]), 1);
277  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, &(m_buffer[ tmp_header.POS_EXP_RUN_NO ]), 1);
278  int* buf = GetFINESSEBuffer(n, finesse_num) + SIZE_B2LHSLB_HEADER + POS_B2L_CTIME;
279  int pos_nwords = finesse_nwords - (static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_B2L_CTIME + SIZE_B2LFEE_TRAILER +
280  SIZE_B2LHSLB_TRAILER);
281  temp_crc16 = CalcCRC16LittleEndian(temp_crc16, buf, pos_nwords);
282 
283  //
284  // Compare CRC16 with B2LCRC16
285  //
286  buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n,
287  finesse_num) - ((SIZE_B2LFEE_TRAILER - POS_B2LFEE_CRC16) + SIZE_B2LHSLB_TRAILER) ;
288 
289  if (GetEveNo(n) % 10000 == 0) {
290  printf("#### PostRawCOPPER : Eve %.8x block %d finesse %d B2LCRC16 %.8x calculated CRC16 %.8x\n", GetEveNo(n), n, finesse_num,
291  *buf, temp_crc16);
292  }
293  if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
294  // if ( false ) {
295  PrintData(m_buffer, m_nwords);
296  printf("POST CRC16 error %x %x %d\n", *buf, temp_crc16, GetFINESSENwords(n, finesse_num));
297  printf("\n");
298  int* temp_buf = GetFINESSEBuffer(n, finesse_num);
299  printf("%.8x ", 0);
300  for (int k = 0; k < GetFINESSENwords(n, finesse_num); k++) {
301  printf("%.8x ", temp_buf[ k ]);
302  if ((k + 1) % 10 == 0) printf("\n%.8x : ", k);
303  }
304  printf("\n");
305  fflush(stdout);
306  char err_buf[500];
307  sprintf(err_buf,
308  "[DEBUG] [ERROR] B2LCRC16 (%.4x) differs from one ( %.4x) calculated by PostRawCOPPERfromat class. Exiting...\n %s %s %d\n",
309  (unsigned short)(*buf & 0xFFFF), temp_crc16, __FILE__, __PRETTY_FUNCTION__, __LINE__);
310  B2FATAL(err_buf);
311  }
312 
313  return 1;
314 
315 
316 }
317 
318 
319 int* PostRawCOPPERFormat_v1::PackDetectorBuf(int* packed_buf_nwords,
320  int* detector_buf_1st, int nwords_1st,
321  int* detector_buf_2nd, int nwords_2nd,
322  int* detector_buf_3rd, int nwords_3rd,
323  int* detector_buf_4th, int nwords_4th,
324  RawCOPPERPackerInfo rawcpr_info)
325 {
326  int* packed_buf = NULL;
327 
328  int poswords_to = 0;
329  int* detector_buf[ 4 ] = { detector_buf_1st, detector_buf_2nd, detector_buf_3rd, detector_buf_4th };
330  const int nwords[ 4 ] = { nwords_1st, nwords_2nd, nwords_3rd, nwords_4th };
331 
332  // calculate the event length
333  int length_nwords = tmp_header.GetHdrNwords() + SIZE_COPPER_HEADER + SIZE_COPPER_TRAILER + tmp_trailer.GetTrlNwords();
334 
335  for (int i = 0; i < 4; i++) {
336  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
337  length_nwords += nwords[ i ];
338  length_nwords += static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER
339  + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
340  }
341 
342  // allocate buffer
343  packed_buf = new int[ length_nwords ];
344  memset(packed_buf, 0, sizeof(int) * length_nwords);
345 
346  //
347  // Fill RawHeader
348  //
349  tmp_header.SetBuffer(packed_buf);
350  packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
351 
352  packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] =
353  0x7f7f0000
354  | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
355  | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
356 
357  packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << 22)
358  | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
359  packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
360  packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
361  packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
362  packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
363 
364  // fill the positions of finesse buffers
365  packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ] = static_cast<int>(tmp_header.RAWHEADER_NWORDS) + SIZE_COPPER_HEADER;
366 
367  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ];
368  if (nwords[ 0 ] > 0) {
369  packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] +=
370  nwords[ 0 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
371  }
372 
373  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ];
374  if (nwords[ 1 ] > 0) {
375  packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] +=
376  nwords[ 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
377  }
378 
379  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ];
380  if (nwords[ 2 ] > 0) {
381  packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] += nwords[ 2 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER +
382  SIZE_B2LHSLB_TRAILER;
383  }
384  poswords_to += tmp_header.GetHdrNwords();
385 
386  // Fill COPPER header
387  poswords_to += SIZE_COPPER_HEADER;
388 
389  // Fill FINESSE buffer
390  for (int i = 0; i < 4; i++) {
391 
392  if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
393 
394  // Fill b2link HSLB header
395  packed_buf[ poswords_to + POS_B2LHSLB_MAGIC ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
396  poswords_to += SIZE_B2LHSLB_HEADER;
397 
398  // Fill b2link FEE header
399  packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
400  poswords_to += SIZE_B2LFEE_HEADER;
401 
402  // copy the 1st Detector Buffer
403  memcpy(packed_buf + poswords_to, detector_buf[ i ], nwords[ i ]*sizeof(int));
404  poswords_to += nwords[ i ];
405 
406  // Fill b2link FEE trailer
407  unsigned int crc16 = 0;
408  packed_buf[ poswords_to + POS_B2LFEE_CRC16 ] = ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 & 0xffff);
409  poswords_to += SIZE_B2LFEE_TRAILER;
410 
411  // Fill b2link HSLB trailer
412  poswords_to += SIZE_B2LHSLB_TRAILER;
413 
414  }
415 
416  // Fill COPPER trailer
417  poswords_to += SIZE_COPPER_TRAILER;
418 
419  // Fill RawTrailer
420  packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
421  poswords_to += tmp_trailer.GetTrlNwords();
422 
423  *packed_buf_nwords = poswords_to;
424 
425  return packed_buf;
426 }
427 
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)
Abstract base class for different kinds of events.