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