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