Belle II Software development
PreRawCOPPERFormat_v2.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_v2.h>
10
11
12using namespace std;
13using namespace Belle2;
14
15//#define NO_ERROR_STOP
16//#define WO_FIRST_EVENUM_CHECK
17
18//ClassImp(PreRawCOPPERFormat_v2);
19
21{
22
23}
24
26{
27}
28
30{
31 int min = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS;
32 int max = GetBufferPos(n) + GetBlockNwords(n)
33 - tmp_trailer.RAWTRAILER_NWORDS - SIZE_COPPER_DRIVER_TRAILER;
34 unsigned int chksum = 0;
35 for (int i = min; i < max; i++) {
36 chksum ^= m_buffer[ i ];
37 }
38 return chksum;
39}
40
41
42
44{
45
46 int nwords = 0;
47 if (GetFINESSENwords(n, finesse_num) > 0) {
48 nwords = GetFINESSENwords(n, finesse_num)
49 - (static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LHSLB_TRAILER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER);
50 }
51 return nwords;
52
53}
54
55
56int PreRawCOPPERFormat_v2::GetFINESSENwords(int n, int finesse_num)
57{
58 if (!CheckCOPPERMagic(n)) {
59 char err_buf[500];
60 char hostname[128];
61 GetNodeName(n, hostname, sizeof(hostname));
62 sprintf(err_buf,
63 "[FATAL] %s ch=%d : ERROR_EVENT : COPPER's magic word is invalid. Exiting... Maybe it is due to data corruption or different version of the data format. : slot%c eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
64 hostname, finesse_num,
65 65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
66 __FILE__, __PRETTY_FUNCTION__, __LINE__);
67 printf("[DEBUG] %s", err_buf); fflush(stdout);
69
70 for (int i = 0; i < 4; i++) {
71 printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
72 if (GetFINESSENwords(n, i) > 0) {
73 CheckCRC16(n, i);
74 }
75 }
76 printf("[DEBUG] ========== No CRC error. : block %d =========\n", n);
77 // string err_str = err_buf; throw (err_str);
78 B2FATAL(err_buf); // to reduce multiple error messages
79 }
80 int pos_nwords;
81 switch (finesse_num) {
82 case 0 :
83 pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_A_DATA_LENGTH;
84 break;
85 case 1 :
86 pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_B_DATA_LENGTH;
87 break;
88 case 2 :
89 pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_C_DATA_LENGTH;
90 break;
91 case 3 :
92 pos_nwords = GetBufferPos(n) + tmp_header.RAWHEADER_NWORDS + POS_CH_D_DATA_LENGTH;
93 break;
94 default :
95 char err_buf[500];
96 char hostname[128];
97 GetNodeName(n, hostname, sizeof(hostname));
98 sprintf(err_buf,
99 "[FATAL] %s ch=%d : ERROR_EVENT : Specified FINESSE number( = %d ) is invalid. Exiting... : slot%c eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
100 hostname, finesse_num,
101 finesse_num,
102 65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
103 __FILE__, __PRETTY_FUNCTION__, __LINE__);
104 printf("%s", err_buf); fflush(stdout);
105 // string err_str = err_buf; throw (err_str);
106 B2FATAL(err_buf); // to reduce multiple error messages
107 }
108 return m_buffer[ pos_nwords ];
109
110}
111
112
114{
115
116#ifndef READ_OLD_B2LFEE_FORMAT_FILE
117
118 int err_flag = 0;
119 unsigned int eve_num = 0;
120 int flag = 0;
121 unsigned int eve[4];
122 for (int i = 0; i < 4 ; i++) {
123 eve[ i ] = 0xbaadf00d;
124 if (GetFINESSENwords(n, i) > 0) {
125 int pos_nwords = GetOffsetFINESSE(n, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
126 eve[ i ] = m_buffer[ pos_nwords ];
127 if (flag != 1) eve_num = eve[ i ];
128 if (eve_num != eve[ i ]) err_flag = 1;
129 flag = 1;
130 }
131 }
132
133 if (flag == 0) {
135 char err_buf[500];
136 char hostname[128];
137 GetNodeName(n, hostname, sizeof(hostname));
138 sprintf(err_buf,
139 "[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",
140 hostname, -1,
141 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
142 __FILE__, __PRETTY_FUNCTION__, __LINE__);
143 printf("%s", err_buf); fflush(stdout);
144 // string err_str = err_buf; throw (err_str);
145 B2FATAL(err_buf); // to reduce multiple error messages
146 }
147
148 if (err_flag == 1) {
149 char err_buf[500];
150 char hostname[128];
151 GetNodeName(n, hostname, sizeof(hostname));
152 sprintf(err_buf,
153 "[FATAL] %s ch=%d : ERROR_EVENT : CORRUPTED DATA: Different event number over HSLBs : slot A 0x%.8x : B 0x%.8x :C 0x%.8x : D 0x%.8x : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
154 hostname, -1,
155 eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
156 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
157 __FILE__, __PRETTY_FUNCTION__, __LINE__);
158 printf("[DEBUG] %s\n", err_buf);
160 for (int i = 0; i < 4; i++) {
161 printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
162 if (GetFINESSENwords(n, i) > 0) {
163 CheckCRC16(n, i);
164 }
165 }
166 printf("[DEBUG] ========== No CRC error. : block %d =========\n", n);
167#ifndef NO_ERROR_STOP
168 // string err_str = err_buf; throw (err_str);
169 B2FATAL(err_buf); // to reduce multiple error messages
170#endif //NO_ERROR_STOP
171 }
172 return eve_num;
173
174#else // READ_OLD_B2LFEE_FORMAT_FILE
175
176 char err_buf[500];
177 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",
178 __FILE__, __PRETTY_FUNCTION__, __LINE__);
179 printf("%s", err_buf); fflush(stdout);
180 B2FATAL(err_buf); // to reduce multiple error messages
181#endif // READ_OLD_B2LFEE_FORMAT_FILE
182
183}
184
185
187 unsigned int prev_evenum, unsigned int* cur_evenum_rawcprhdr,
188 unsigned int prev_copper_ctr, unsigned int* cur_copper_ctr,
189 unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
190{
191
192 char err_buf[1000];
193 int err_flag = 0;
194 //
195 // check Magic words
196 //
197 if (!CheckCOPPERMagic(n)) {
198 char hostname[128];
199 GetNodeName(n, hostname, sizeof(hostname));
200 sprintf(err_buf,
201 "[FATAL] %s ch=%d : ERROR_EVENT : Invalid Magic word 0x7FFFF0008=%u 0xFFFFFAFA=%u 0xFFFFF5F5=%u 0x7FFF0009=%u : eve 0x%x exp %d run %d sub %d\n%s %s %d\n",
202 hostname, -1,
204 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
205 __FILE__, __PRETTY_FUNCTION__, __LINE__);
206 err_flag = 1;
207 }
208
209 //
210 // Event # check
211 //
212 *cur_evenum_rawcprhdr = GetEveNo(n);
213 unsigned int evenum_feehdr = GetB2LFEE32bitEventNumber(n);
214 if (*cur_evenum_rawcprhdr != evenum_feehdr) {
215
216 char hostname[128];
217 GetNodeName(n, hostname, sizeof(hostname));
218 sprintf(err_buf,
219 "[FATAL] %s ch=%d : ERROR_EVENT : Event # in PreRawCOPPERFormat_v2 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",
220 hostname, -1,
221 *cur_evenum_rawcprhdr, evenum_feehdr,
222 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
223 __FILE__, __PRETTY_FUNCTION__, __LINE__);
224 err_flag = 1;
225 }
226
227 //
228 // Check incrementation of event #
229 //
230 *cur_exprunsubrun_no = GetExpRunSubrun(n);
231 *cur_copper_ctr = GetCOPPERCounter(n);
232 if (prev_exprunsubrun_no == *cur_exprunsubrun_no) {
233 if ((unsigned int)(prev_evenum + 1) != *cur_evenum_rawcprhdr) {
234 char hostname[128];
235 GetNodeName(n, hostname, sizeof(hostname));
236 sprintf(err_buf,
237 "[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",
238 hostname, -1,
239 n, prev_evenum, *cur_evenum_rawcprhdr, prev_exprunsubrun_no, *cur_exprunsubrun_no,
240 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
241 __FILE__, __PRETTY_FUNCTION__, __LINE__);
242 err_flag = 1;
243 }
244 if ((unsigned int)(prev_copper_ctr + 1) != *cur_copper_ctr) {
245 char hostname[128];
246 GetNodeName(n, hostname, sizeof(hostname));
247 sprintf(err_buf,
248 "[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",
249 hostname, -1,
250 n, prev_copper_ctr, *cur_copper_ctr,
251 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
252 __FILE__, __PRETTY_FUNCTION__, __LINE__);
253 err_flag = 1;
254 }
255 } else {
256 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",
257 *cur_exprunsubrun_no, prev_exprunsubrun_no, *cur_evenum_rawcprhdr, prev_evenum,
258 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n));
259
260 // Check if the first event of a run is zero.
261 if ((unsigned int)GetRunNo(n) != (prev_exprunsubrun_no & RawHeader_v2::RUNNO_MASK) >> RawHeader_v2::RUNNO_SHIFT) {
262 if (*cur_evenum_rawcprhdr != 0) {
263
264 unsigned int eve[4];
265 for (int i = 0; i < 4 ; i++) {
266 eve[ i ] = 0xbaadf00d;
267 if (GetFINESSENwords(n, i) > 0) {
268 int pos_nwords = GetOffsetFINESSE(n, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
269 eve[ i ] = m_buffer[ pos_nwords ];
270 }
271 }
272
273 char hostname[128];
274 GetNodeName(n, hostname, sizeof(hostname));
275 sprintf(err_buf,
276 "[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 %u sub %u ) cur(exp %u run %u sub %u ) ( A:0x%.8x B:0x%.8x C:0x%.8x D:0x%.8x ) Exiting... : eve 0x%x exp %d run %d sub %d\n %s %s %d\n",
277 hostname, -1,
278 prev_evenum, *cur_evenum_rawcprhdr,
279 prev_exprunsubrun_no >> 22, (prev_exprunsubrun_no >> 8) & 0x3FFF, prev_exprunsubrun_no & 0xFF,
280 *cur_exprunsubrun_no >> 22, (*cur_exprunsubrun_no >> 8) & 0x3FFF, *cur_exprunsubrun_no & 0xFF,
281 eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
282 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
283 __FILE__, __PRETTY_FUNCTION__, __LINE__);
284 err_flag = 1;
285 }
286 }
287
288 }
289
290
291
292 //
293 // Check is utime and ctime_trgtype same over different FINESSE data
294 //
296
297 //
298 // Check checksum calculated by COPPER driver
299 //
300 if (GetDriverChkSum(n) != CalcDriverChkSum(n)) {
301 char hostname[128];
302 GetNodeName(n, hostname, sizeof(hostname));
303 sprintf(err_buf,
304 "[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",
305 hostname, -1,
306 n, GetBlockNwords(n), *cur_evenum_rawcprhdr, GetDriverChkSum(n), CalcDriverChkSum(n),
307 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
308 __FILE__, __PRETTY_FUNCTION__, __LINE__);
309 err_flag = 1;
310 }
311
312 //
313 // Check checksum calculated by DeSerializerCOPPER()
314 //
316 unsigned int xor_chksum = CalcXORChecksum(GetBuffer(n), GetBlockNwords(n) - tmp_trailer.GetTrlNwords());
317 if (tmp_trailer.GetChksum() != xor_chksum) {
318 char hostname[128];
319 GetNodeName(n, hostname, sizeof(hostname));
320 sprintf(err_buf,
321 "[FATAL] %s ch=%d : ERROR_EVENT : PreRawCOPPERFormat_v2 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",
322 hostname, -1,
323 n, GetBlockNwords(n), *cur_evenum_rawcprhdr, tmp_trailer.GetChksum(), xor_chksum,
324 GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
325 __FILE__, __PRETTY_FUNCTION__, __LINE__);
326 err_flag = 1;
327 }
328
329 if (err_flag == 1) {
330 printf("%s", err_buf); fflush(stdout);
331 printf("[DEBUG] ========== dump a data blcok : block # %d==========\n", n);
333 for (int i = 0; i < 4; i++) {
334 printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
335 if (GetFINESSENwords(n, i) > 0) {
336 CheckCRC16(n, i);
337 }
338 }
339 printf("[DEBUG] ========== No CRC error : block %d =========\n", n);
340 // string err_str = err_buf; throw (err_str);
341 B2FATAL(err_buf); // to reduce multiple error messages
342 }
343
344 return;
345
346}
347
349{
350 if (GetMagicDriverHeader(n) != COPPER_MAGIC_DRIVER_HEADER) {
351 return false;
352 } else if (GetMagicFPGAHeader(n) != COPPER_MAGIC_FPGA_HEADER) {
353 return false;
354 } else if (GetMagicFPGATrailer(n) != COPPER_MAGIC_FPGA_TRAILER) {
355 return false;
356 } else if (GetMagicDriverTrailer(n) != COPPER_MAGIC_DRIVER_TRAILER) {
357 return false;
358 }
359 return true;
360}
361
363{
364
365#ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
366 CheckB2LFEEHeaderVersion(n);
367#endif
368 int err_flag = 0;
369 int flag = 0;
370 unsigned int temp_utime = 0, temp_ctime_trgtype = 0, temp_eve = 0, temp_exprun = 0;
371 unsigned int temp_ctime_trgtype_footer, temp_eve_footer;
372 unsigned int utime[4], ctime_trgtype[4], eve[4], exprun[4];
373 char err_buf[4000];
374 int first_ch = 0;
375
376 memset(utime, 0, sizeof(utime));
377 memset(ctime_trgtype, 0, sizeof(ctime_trgtype));
378 memset(eve, 0, sizeof(eve));
379 memset(exprun, 0, sizeof(exprun));
380
381
382 for (int i = 0; i < 4; i++) {
383 int finesse_nwords = GetFINESSENwords(n, i);
384 if (finesse_nwords > 0) {
385 int offset_finesse = GetOffsetFINESSE(n, i);
386 ctime_trgtype[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_CTIME_TYPE ];
387 utime[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_UTIME ];
388 eve[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_TT_TAG ];
389 exprun[ i ] = m_buffer[ offset_finesse + SIZE_B2LHSLB_HEADER + POS_EXP_RUN ];
390 temp_ctime_trgtype_footer =
391 m_buffer[ offset_finesse + finesse_nwords - (static_cast<int>(SIZE_B2LFEE_TRAILER) + SIZE_B2LHSLB_TRAILER) + POS_TT_CTIME_B2LFEE ];
392 temp_eve_footer =
393 m_buffer[ offset_finesse + finesse_nwords - (static_cast<int>(SIZE_B2LFEE_TRAILER) + SIZE_B2LHSLB_TRAILER) + POS_CHKSUM_B2LFEE ];
394
395 if (flag == 0) {
396 temp_ctime_trgtype = ctime_trgtype[ i ];
397 temp_utime = utime[ i ];
398 temp_eve = eve[ i ];
399 temp_exprun = exprun[ i ];
400 flag = 1;
401 first_ch = i;
402 } else {
403 if (temp_ctime_trgtype != ctime_trgtype[ i ] || temp_utime != utime[ i ] ||
404 temp_eve != eve[ i ] || temp_exprun != exprun[ i ]) {
405 char hostname[128];
406 GetNodeName(n, hostname, sizeof(hostname));
407 if (err_flag == 0) {
408 for (int j = 0; j < 4; j++) {
409 printf("[DEBUG] %s ch=%d : FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x\n",
410 hostname, -1,
411 j, GetFINESSENwords(n, j), ctime_trgtype[ j ], utime[ j ], eve[ j ], exprun[ j ]);
412 }
413 }
414
415 char err_buf_1[2500], err_buf_2[3000], err_buf_3[3500];
416 sprintf(err_buf_1,
417 "[FATAL] %s ch=%d : ERROR_EVENT : mismatch header value over FINESSEs. Exiting...",
418 hostname, -1);
419 sprintf(err_buf_2,
420 "%s FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x",
421 err_buf_1,
422 first_ch, GetFINESSENwords(n, first_ch), ctime_trgtype[ first_ch ], utime[ first_ch ], eve[ first_ch ], exprun[ first_ch ]);
423 sprintf(err_buf_3,
424 "%s FINESSE #=%d buffsize %d ctimeTRGtype 0x%.8x utime 0x%.8x eve 0x%.8x exprun 0x%.8x",
425 err_buf_2,
426 i, GetFINESSENwords(n, i), ctime_trgtype[ i ], utime[ i ], eve[ i ], exprun[ i ]);
427 sprintf(err_buf, "%s\n %s %s %d\n",
428 err_buf_3,
429 __FILE__, __PRETTY_FUNCTION__, __LINE__);
430 printf("%s", err_buf); fflush(stdout);
431
432 err_flag = 1;
433 break;
434 } else if (temp_ctime_trgtype != temp_ctime_trgtype_footer ||
435 (temp_eve & 0xffff) != ((temp_eve_footer >> 16) & 0xffff)) {
436 char hostname[128];
437 GetNodeName(n, hostname, sizeof(hostname));
438 sprintf(err_buf,
439 "[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",
440 hostname, i,
441 i, temp_ctime_trgtype, temp_eve, temp_ctime_trgtype_footer, temp_eve_footer,
442 __FILE__, __PRETTY_FUNCTION__, __LINE__);
443 printf("%s", err_buf); fflush(stdout);
444 err_flag = 1;
445 }
446 }
447 }
448 }
449
450 if (err_flag != 0) {
451 for (int i = 0; i < 4; i++) {
452 if (GetFINESSENwords(n, i) > 0) {
453 printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", n, i);
454 CheckCRC16(n, i);
455 printf("[DEBUG] ========== CRC check is done. : block %d =========\n", n);
456 }
457 }
458#ifndef NO_ERROR_STOP
459 // string err_str = err_buf; throw (err_str);
460 B2FATAL(err_buf); // to reduce multiple error messages
461#endif
462 }
463 return;
464}
465
466unsigned int PreRawCOPPERFormat_v2::FillTopBlockRawHeader(unsigned int m_node_id, unsigned int prev_eve32,
467 unsigned int prev_exprunsubrun_no, unsigned int* cur_exprunsubrun_no)
468{
469 const int datablock_id = 0;
470 // m_temp_value = 12345678;
471 //
472 // This function only fills RawHeader contents for the first datablock.
473 // # of block should be 1
474 if (m_num_nodes * m_num_events != 1) {
475 char err_buf[500];
476 sprintf(err_buf,
477 "[FATAL] This function should be used for PreRawCOPPERFormat_v2 containing only one datablock, while. this object has num_nodes of %d and num_events of %d\n %s %s %d\n",
478 m_num_nodes, m_num_events, __FILE__, __PRETTY_FUNCTION__, __LINE__);
479 printf("%s", err_buf); fflush(stdout);
480 // string err_str = err_buf; throw (err_str);
481 B2FATAL(err_buf); // to reduce multiple error messages
482 }
483
485 //
486 // Fill info in RawHeader
487 //
489
490 //
491 // Initialize a RawHeader part
492 //
493 memset(m_buffer, 0, sizeof(int) * tmp_header.RAWHEADER_NWORDS);
494 m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] = static_cast<int>(tmp_header.RAWHEADER_NWORDS) & tmp_header.HDR_NWORDS_MASK;
495 m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) &
496 tmp_header.FORMAT_VERSION__MASK;
497 m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= (0x80 << tmp_header.FORMAT_VERSION_SHIFT); // PreFormat
498 m_buffer[ tmp_header.POS_VERSION_HDRNWORDS ] |= tmp_header.MAGIC_WORD;
499
500 //
501 // Check FINESSEs which containes data
502 //
503 int* copper_buf = &(m_buffer[ tmp_header.RAWHEADER_NWORDS ]);
504 if (copper_buf[ POS_CH_A_DATA_LENGTH ] == 0 &&
505 copper_buf[ POS_CH_B_DATA_LENGTH ] == 0 &&
506 copper_buf[ POS_CH_C_DATA_LENGTH ] == 0 &&
507 copper_buf[ POS_CH_D_DATA_LENGTH ] == 0) {
508 char err_buf[500];
509 char hostname[128];
510 GetNodeName(hostname, m_node_id, sizeof(hostname));
511 sprintf(err_buf,
512 "[FATAL] %s ch=%d : ERROR_EVENT : No FINESSE data in a copper data block. Exiting...\n %s %s %d\n",
513 hostname, -1,
514 __FILE__, __PRETTY_FUNCTION__, __LINE__);
515 printf("%s", err_buf); fflush(stdout);
516 // string err_str = err_buf; throw (err_str);
517 B2FATAL(err_buf); // to reduce multiple error messages
518 }
519
520 //
521 // Set total words info
522 //
523 int datablock_nwords =
524 tmp_header.RAWHEADER_NWORDS +
525 (copper_buf[ POS_DATA_LENGTH ]
526 + SIZE_COPPER_DRIVER_HEADER
527 + SIZE_COPPER_DRIVER_TRAILER)
528 + tmp_trailer.RAWTRAILER_NWORDS;
529 m_buffer[ tmp_header.POS_NWORDS ] = datablock_nwords;
530
531
532 //
533 // Check the consistency between data length and length in RawHeader
534 //
535 if (m_buffer[ tmp_header.POS_NWORDS ] != m_nwords) {
536 char err_buf[500];
537
538 char hostname[128];
539 GetNodeName(hostname, m_node_id, sizeof(hostname));
540 sprintf(err_buf,
541 "[FATAL] %s ch=%d : ERROR_EVENT : Data length is inconsistent m_nwords %d : nwords from COPPER data %d\n %s %s %d\n",
542 hostname, -1,
543 m_nwords, m_buffer[ tmp_header.POS_NWORDS ],
544 __FILE__, __PRETTY_FUNCTION__, __LINE__);
545 printf("%s", err_buf); fflush(stdout);
546 // string err_str = err_buf; throw (err_str);
547 B2FATAL(err_buf); // to reduce multiple error messages
548 }
549
550 //
551 // Fill offset values
552 //
553 int offset_1st_finesse = static_cast<int>(tmp_header.RAWHEADER_NWORDS) + SIZE_COPPER_HEADER;
554 int offset_2nd_finesse = offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ];
555 int offset_3rd_finesse = offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ];
556 int offset_4th_finesse = offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ];
557 m_buffer[ tmp_header.POS_OFFSET_1ST_FINESSE ] = offset_1st_finesse;
558 m_buffer[ tmp_header.POS_OFFSET_2ND_FINESSE ] = offset_2nd_finesse;
559 m_buffer[ tmp_header.POS_OFFSET_3RD_FINESSE ] = offset_3rd_finesse;
560 m_buffer[ tmp_header.POS_OFFSET_4TH_FINESSE ] = offset_4th_finesse;
561
562 //
563 // Fill Exp/Run value
564 //
565 int* finesse_buf = &
566 (m_buffer[ offset_1st_finesse ]); // In any finesse implementations, the top finesse buffer should be at offset_1st_finesse;
567 m_buffer[ tmp_header.POS_EXP_RUN_NO ] = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_EXP_RUN ];
568
569
570 //
571 // Fill event #
572 //
573 unsigned int cur_ftsw_eve32 = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_TT_TAG ];
574 m_buffer[ tmp_header.POS_EVE_NO ] = cur_ftsw_eve32;
575
576 //
577 // Copy FTSW words from B2LFEE header
578 //
579 m_buffer[ tmp_header.POS_TTCTIME_TRGTYPE ] = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_TT_CTIME_TYPE ];
580 m_buffer[ tmp_header.POS_TTUTIME ] = finesse_buf[ static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_TT_UTIME ];
581
582 //
583 // Set node ID, trunc_mask, data_type
584 //
585 m_buffer[ tmp_header.POS_NODE_ID ] = m_node_id;
586
587 //
588 // Check error counts of b2link-packet CRC
589 //
590 // m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] = ((m_trunc_mask << 31) & 0x80000000) | (m_data_type & 0x7FFFFFFF);
591 // printf("%.8x %.8x %.8x %.8x : %.8x\n",
592 // copper_buf[ POS_CH_A_DATA_LENGTH ], copper_buf[ POS_CH_B_DATA_LENGTH ],
593 // copper_buf[ POS_CH_C_DATA_LENGTH ], copper_buf[ POS_CH_D_DATA_LENGTH ], m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] );
594
595 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] = 0;
596 unsigned int ff55_higher_bits, ff55_lower_bits;
597
598 if (copper_buf[ POS_CH_A_DATA_LENGTH ] != 0) {
599 ff55_higher_bits = (unsigned int)(m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
600 0xFFFF0000;
601
602 ff55_lower_bits = m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF;
603
604 if (ff55_higher_bits != 0xff550000) {
605 char err_buf[500];
606 char hostname[128];
607 GetNodeName(hostname, m_node_id, sizeof(hostname));
608 sprintf(err_buf,
609 "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotA's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
610 hostname, 0,
611 cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
612 m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
613 __FILE__, __PRETTY_FUNCTION__, __LINE__);
614 printf("%s", err_buf); fflush(stdout);
615 PrintData(m_buffer, m_nwords); fflush(stdout);
616 B2FATAL(err_buf);
617 }
618
619 if (ff55_lower_bits != 0) {
620 const int linkdown_bit = 15;
621 // const int packet_crcerr_bit = 8;
622 char err_buf[1000];
623 char hostname[128];
624 GetNodeName(hostname, m_node_id, sizeof(hostname));
625
626 if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
627 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot A eve %8u foooter %.8x : %s %s %d\n",
628 hostname, 0,
629 cur_ftsw_eve32,
630 m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
631 __FILE__, __PRETTY_FUNCTION__, __LINE__);
632 printf("%s", err_buf); fflush(stdout);
634 fflush(stdout);
635 B2FATAL(err_buf);
636 } else {
637 if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
638 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
639 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x1 << 28);
640 sprintf(err_buf,
641 "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot A eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
642 hostname, 0,
643 cur_ftsw_eve32,
644 m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
645 __FILE__, __PRETTY_FUNCTION__, __LINE__);
646 printf("%s", err_buf); fflush(stdout);
648 fflush(stdout);
649 } else {
650 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
651 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x1 << 28);
652 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot A eve %8u foooter %.8x : %s %s %d\n",
653 hostname, 0,
654 cur_ftsw_eve32,
655 m_buffer[ offset_1st_finesse + copper_buf[ POS_CH_A_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
656 __FILE__, __PRETTY_FUNCTION__, __LINE__);
657 printf("%s", err_buf); fflush(stdout);
659 fflush(stdout);
660 B2FATAL(err_buf);
661 }
662 }
663 }
664 }
665
666 if (copper_buf[ POS_CH_B_DATA_LENGTH ] != 0) {
667 ff55_higher_bits = (unsigned int)(m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
668 0xFFFF0000;
669
670 ff55_lower_bits = (m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
671 char hostname[128];
672 GetNodeName(hostname, m_node_id, sizeof(hostname));
673 if (ff55_higher_bits != 0xff550000) {
674 char err_buf[500];
675 sprintf(err_buf,
676 "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotB's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
677 hostname, 1,
678 cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
679 m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
680 __FILE__, __PRETTY_FUNCTION__, __LINE__);
681 printf("%s", err_buf); fflush(stdout);
682 PrintData(m_buffer, m_nwords); fflush(stdout);
683 B2FATAL(err_buf);
684 }
685
686 if (ff55_lower_bits != 0) {
687 char err_buf[1000];
688 const int linkdown_bit = 15;
689 // const int packet_crcerr_bit = 8;
690 if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
691 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot B eve %8u foooter %.8x : %s %s %d\n",
692 hostname, 1,
693 cur_ftsw_eve32,
694 m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
695 __FILE__, __PRETTY_FUNCTION__, __LINE__);
696 printf("%s", err_buf); fflush(stdout);
698 fflush(stdout);
699 B2FATAL(err_buf);
700 } else {
701 if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
702 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
703 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x2 << 28);
704 sprintf(err_buf,
705 "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot B eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
706 hostname, 1,
707 cur_ftsw_eve32,
708 m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
709 __FILE__, __PRETTY_FUNCTION__, __LINE__);
710 printf("%s", err_buf); fflush(stdout);
712 fflush(stdout);
713 } else {
714 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
715 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x2 << 28);
716 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot B eve %8u foooter %.8x : %s %s %d\n",
717 hostname, 1,
718 cur_ftsw_eve32,
719 m_buffer[ offset_2nd_finesse + copper_buf[ POS_CH_B_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
720 __FILE__, __PRETTY_FUNCTION__, __LINE__);
721 printf("%s", err_buf); fflush(stdout);
723 fflush(stdout);
724 B2FATAL(err_buf);
725 }
726 }
727 }
728 }
729
730 if (copper_buf[ POS_CH_C_DATA_LENGTH ] != 0) {
731 ff55_higher_bits = (unsigned int)(m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
732 0xFFFF0000;
733
734 ff55_lower_bits = (m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
735 char hostname[128];
736 GetNodeName(hostname, m_node_id, sizeof(hostname));
737 if (ff55_higher_bits != 0xff550000) {
738 char err_buf[500];
739 sprintf(err_buf,
740 "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotC's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
741 hostname, 2,
742 cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
743 m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
744 __FILE__, __PRETTY_FUNCTION__, __LINE__);
745 printf("%s", err_buf); fflush(stdout);
746 PrintData(m_buffer, m_nwords); fflush(stdout);
747 B2FATAL(err_buf);
748 }
749
750 if (ff55_lower_bits != 0) {
751 char err_buf[1000];
752 const int linkdown_bit = 15;
753
754 if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
755 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot C eve %8u foooter %.8x : %s %s %d\n",
756 hostname, 2,
757 cur_ftsw_eve32,
758 m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
759 __FILE__, __PRETTY_FUNCTION__, __LINE__);
760 printf("%s", err_buf); fflush(stdout);
762 fflush(stdout);
763 B2FATAL(err_buf);
764 } else {
765 if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
766 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
767 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x4 << 28);
768 sprintf(err_buf,
769 "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot C eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
770 hostname, 2,
771 cur_ftsw_eve32,
772 m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
773 __FILE__, __PRETTY_FUNCTION__, __LINE__);
774 printf("%s", err_buf); fflush(stdout);
776 fflush(stdout);
777 } else {
778 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
779 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x4 << 28);
780 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot C eve %8u foooter %.8x : %s %s %d\n",
781 hostname, 2,
782 cur_ftsw_eve32,
783 m_buffer[ offset_3rd_finesse + copper_buf[ POS_CH_C_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
784 __FILE__, __PRETTY_FUNCTION__, __LINE__);
785 printf("%s", err_buf); fflush(stdout);
787 fflush(stdout);
788 B2FATAL(err_buf);
789 }
790 }
791
792 }
793 }
794
795 if (copper_buf[ POS_CH_D_DATA_LENGTH ] != 0) {
796 ff55_higher_bits = (unsigned int)(m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ]) &
797 0xFFFF0000;
798
799 ff55_lower_bits = (m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ] & 0xFFFF);
800 char hostname[128];
801 GetNodeName(hostname, m_node_id, sizeof(hostname));
802 if (ff55_higher_bits != 0xff550000) {
803 char err_buf[500];
804 sprintf(err_buf,
805 "[FATAL] %s ch=%d : ERROR_EVENT : HSLB slotD's trailer magic word(0xff55) is invalid. : eve %8u run %d foooter %.8x : %s %s %d\n",
806 hostname, 3,
807 cur_ftsw_eve32, (m_buffer[ tmp_header.POS_EXP_RUN_NO ] >> 8) & 0x3FFF,
808 m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
809 __FILE__, __PRETTY_FUNCTION__, __LINE__);
810 printf("%s", err_buf); fflush(stdout);
811 PrintData(m_buffer, m_nwords); fflush(stdout);
812 B2FATAL(err_buf);
813 }
814
815 if (ff55_lower_bits != 0) {
816 char err_buf[1000];
817 const int linkdown_bit = 15;
818
819 if ((ff55_lower_bits & (1 << linkdown_bit)) != 0) {
820 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link down on slot D eve %8u foooter %.8x : %s %s %d\n",
821 hostname, 3,
822 cur_ftsw_eve32,
823 m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
824 __FILE__, __PRETTY_FUNCTION__, __LINE__);
825 printf("%s", err_buf); fflush(stdout);
827 fflush(stdout);
828 B2FATAL(err_buf);
829 } else {
830 if (((unsigned int)m_node_id & DETECTOR_MASK) == ARICH_ID) {
831 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
832 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x8) << 28;
833 sprintf(err_buf,
834 "[WARNING] %s ch=%d : ARICH : B2link packet CRC error slot D eve %8u foooter %.8x : This error is ignored and the error event will be recorded in .sroot file acording to request from ARICH group: %s %s %d\n",
835 hostname, 3,
836 cur_ftsw_eve32,
837 m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
838 __FILE__, __PRETTY_FUNCTION__, __LINE__);
839 printf("%s", err_buf); fflush(stdout);
841 fflush(stdout);
842 } else {
843 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_PACKET_CRC_ERROR;
844 m_buffer[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= (unsigned int)(0x8) << 28;
845 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : B2link packet CRC error slot D eve %8u foooter %.8x : %s %s %d\n",
846 hostname, 3,
847 cur_ftsw_eve32,
848 m_buffer[ offset_4th_finesse + copper_buf[ POS_CH_D_DATA_LENGTH ] - SIZE_B2LHSLB_HEADER ],
849 __FILE__, __PRETTY_FUNCTION__, __LINE__);
850 printf("%s", err_buf); fflush(stdout);
852 fflush(stdout);
853 B2FATAL(err_buf);
854 }
855 }
856 }
857 }
858
859
861 //
862 // Fill info in RawTrailer
863 //
865
866 //
867 // Calculate XOR checksum
868 //
869 unsigned int chksum_top = 0, chksum_body = 0, chksum_bottom = 0;
870
871 int top_end = tmp_header.RAWHEADER_NWORDS;
872 for (int i = 0; i < top_end; i++) {
873 chksum_top ^= m_buffer[ i ];
874 }
875 int body_end = datablock_nwords - SIZE_COPPER_DRIVER_TRAILER - tmp_trailer.RAWTRAILER_NWORDS;
876 for (int i = top_end; i < body_end; i++) {
877 chksum_body ^= m_buffer[ i ];
878 }
879
880 int bottom_end = datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS;
881 for (int i = body_end; i < bottom_end; i++) {
882 chksum_bottom ^= m_buffer[ i ];
883 }
884
885 //
886 // check COPPER driver checksum
887 //
888 if (chksum_body != (unsigned int)(m_buffer[ body_end ])) {
889 char err_buf[500];
890 char hostname[128];
891 GetNodeName(hostname, m_node_id, sizeof(hostname));
892 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : COPPER driver checksum is not consistent.: calcd. %.8x data %.8x\n %s %s %d\n",
893 hostname, -1,
894 chksum_body, m_buffer[ body_end ],
895 __FILE__, __PRETTY_FUNCTION__, __LINE__);
896 printf("%s", err_buf); fflush(stdout);
897 B2FATAL(err_buf); // to reduce multiple error messages
898 }
899
900 //
901 // Fill trailer info (checksum, magic word)
902 //
903 unsigned int chksum = chksum_top ^ chksum_body ^ chksum_bottom;
904 int* trl = &(m_buffer[ datablock_nwords - tmp_trailer.RAWTRAILER_NWORDS ]);
905 trl[ tmp_trailer.POS_CHKSUM ] = chksum;
906 trl[ tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
907
908
910 //
911 // Data check ( magic word, event incrementation )
912 //
914
915
916 //
917 // check magic words
918 //
919 int* fpga_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_3);
920 int* driver_trailer_magic = trl - (SIZE_COPPER_TRAILER - POS_MAGIC_COPPER_4);
921 int err_flag = 0;
922 if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_1 ]) != COPPER_MAGIC_DRIVER_HEADER) {
923 err_flag = 1;
924 } else if ((unsigned int)(copper_buf[ POS_MAGIC_COPPER_2 ]) != COPPER_MAGIC_FPGA_HEADER) {
925 err_flag = 1;
926 } else if ((unsigned int)(*fpga_trailer_magic) != COPPER_MAGIC_FPGA_TRAILER) {
927 err_flag = 1;
928 } else if ((unsigned int)(*driver_trailer_magic) != COPPER_MAGIC_DRIVER_TRAILER) {
929 err_flag = 1;
930 }
931 if (err_flag == 1) {
932 char err_buf[500];
933 char hostname[128];
934 GetNodeName(hostname, m_node_id, sizeof(hostname));
935 sprintf(err_buf,
936 "[FATAL] %s ch=%d : ERROR_EVENT : Invalid Magic word 0x7FFFF0008=%u 0xFFFFFAFA=%u 0xFFFFF5F5=%u 0x7FFF0009=%u\n %s %s %d\n",
937 hostname, -1,
938 GetMagicDriverHeader(datablock_id),
939 GetMagicFPGAHeader(datablock_id),
940 GetMagicFPGATrailer(datablock_id),
941 GetMagicDriverTrailer(datablock_id),
942 __FILE__, __PRETTY_FUNCTION__, __LINE__);
943 printf("[DEBUG] %s\n", err_buf);
944#ifndef NO_ERROR_STOP
945 B2FATAL(err_buf); // to reduce multiple error messages
946#endif
947 }
948
949 //
950 // check incrementation of event #
951 //
952
953
954 *cur_exprunsubrun_no = GetExpRunSubrun(datablock_id);
955
956 // if ((unsigned int)cur_ftsw_eve32 < 50) {
957 // printf("EVENT OUTPUT ########## %u\n", cur_ftsw_eve32);
958 // PrintData(GetBuffer(datablock_id), TotalBufNwords());
959 // }
960 if (prev_exprunsubrun_no == *cur_exprunsubrun_no) {
961 if (prev_eve32 + 1 != cur_ftsw_eve32) {
962 unsigned int eve[4] = {0xbaadf00d, 0xbaadf00d, 0xbaadf00d, 0xbaadf00d };
963#ifndef NO_ERROR_STOP
964 if (m_num_nodes * m_num_events != 1) {
965 char err_buf[500];
966 sprintf(err_buf,
967 "[FATAL] This function should be used for PreRawCOPPERFormat_v2 containing only one datablock, while. this object has num_nodes of %d and num_events of %d\n %s %s %d\n",
968 m_num_nodes, m_num_events, __FILE__, __PRETTY_FUNCTION__, __LINE__);
969 printf("%s", err_buf); fflush(stdout);
970 // string err_str = err_buf; throw (err_str);
971 B2FATAL(err_buf); // to reduce multiple error messages
972 } else {
973 for (int i = 0; i < 4 ; i++) {
974 // Only one block is in this m_buffer[] when m_num_nodes*m_num_events=1
975 // 0 is specified as a block number
976 if (GetFINESSENwords(0, i) > 0) {
977 int pos_nwords = GetOffsetFINESSE(0, i) + SIZE_B2LHSLB_HEADER + POS_TT_TAG;
978 eve[ i ] = m_buffer[ pos_nwords ];
979 }
980 }
981 }
982
983 char err_buf[500];
984 char hostname[128];
985 GetNodeName(hostname, m_node_id, sizeof(hostname));
986 sprintf(err_buf,
987 "[FATAL] %s ch=%d : ERROR_EVENT : Invalid event_number. Exiting...: cur 32bit eve %u preveve %u ( A:0x%.8x B:0x%.8x C:0x%.8x D:0x%.8x ) prun %u crun %u\n %s %s %d\n",
988 hostname, -1,
989 cur_ftsw_eve32, prev_eve32,
990 eve[ 0 ], eve[ 1 ], eve[ 2 ], eve[ 3 ],
991 prev_exprunsubrun_no, *cur_exprunsubrun_no,
992 __FILE__, __PRETTY_FUNCTION__, __LINE__);
993 printf("[DEBUG] %s\n", err_buf);
994
995 // string err_str = err_buf;
996 printf("[DEBUG] i= %d : num entries %d : Tot words %d\n", 0, GetNumEntries(), TotalBufNwords());
997 PrintData(GetBuffer(datablock_id), TotalBufNwords());
998
999 for (int i = 0; i < 4; i++) {
1000 printf("[DEBUG] ========== CRC check : block # %d finesse %d ==========\n", datablock_id, i);
1001 if (GetFINESSENwords(datablock_id, i) > 0) {
1002 CheckCRC16(datablock_id, i);
1003 }
1004 }
1005 printf("[DEBUG] ========== No CRC error : block %d =========\n", datablock_id);
1006 // throw (err_str);
1007 B2FATAL(err_buf); // to reduce multiple error messages
1008#endif
1009
1010 }
1011 }
1012
1013 return cur_ftsw_eve32;
1014
1015}
1016
1017
1018
1019#ifdef USE_B2LFEE_FORMAT_BOTH_VER1_AND_2
1020void PreRawCOPPERFormat_v2::CheckB2LFEEHeaderVersion(int n)
1021{
1022 int* temp_buf;
1023 for (int i = 0; i < 4; i++) {
1024 if (GetFINESSENwords(n, i) > 0) {
1025 temp_buf = GetFINESSEBuffer(n, i);
1026 if ((temp_buf[ 3 ] & 0x40000000) == 0) {
1027#ifdef TEMP
1028 // this word for exp/run
1029 // old one (ver.1) used for SPring8 test in 2013
1030 printf("[DEBUG] \033[31m");
1031 printf("[DEBUG] ===Firmware ver. ERROR===\n ");
1032 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");
1033 printf("[DEBUG] If you are going to take data now, Please update the firmware.\n");
1034 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");
1035 printf("[DEBUG] Or if you are going to read data taken before the update, please use basf2 software before svn revision 7419\n");
1036 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");
1037 printf("[DEBUG] Sorry for inconvenience.\n");
1038 printf("[DEBUG] \033[0m");
1039 fflush(stderr);
1040 char err_buf[500];
1041 char hostname[128];
1042 GetNodeName(n, hostname, sizeof(hostname));
1043 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : FTSW and b2tt firmwares are old. Exiting...\n %s %s %d\n",
1044 hostname, i,
1045 __FILE__, __PRETTY_FUNCTION__, __LINE__);
1046 B2FATAL(err_buf);
1047#endif
1048 } else {
1049 // this word for 32bit unixtime
1050 // new one (ver.2)
1051 break;
1052 }
1053 }
1054
1055 if (i == 3) {
1056#ifdef TEMP
1057 char err_buf[500];
1058 char hostname[128];
1059 GetNodeName(n, hostname, sizeof(hostname));
1060 sprintf(err_buf, "[FATAL] %s ch=%d : ERROR_EVENT : PreRawCOPPERFormat_v2 contains no FINESSE data. Exiting...\n %s %s %d\n",
1061 hostname, i,
1062 __FILE__, __PRETTY_FUNCTION__, __LINE__);
1063 printf("%s", err_buf); fflush(stdout);
1064 // string err_str = err_buf; throw (err_str);
1065 B2FATAL(err_buf); // to reduce multiple error messages
1066#endif
1067 }
1068 }
1069 return;
1070}
1071#endif
1072
1073//int PreRawCOPPERFormat_v2::CalcReducedDataSize(RawDataBlock* raw_datablk)
1074int PreRawCOPPERFormat_v2::CalcReducedDataSize(int* bufin, int nwords, int num_events, int num_nodes)
1075{
1076 //
1077 // Calculate reduced length for a total RawDataBlock (containing multiple data blocks)
1078 //
1079 RawDataBlockFormat radblk_fmt;
1080 int delete_flag = 0;
1081 radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
1082
1083 int reduced_nwords = 0;
1084 for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
1085 int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
1086 for (int l = 0; l < num_nodes_in_sendblock; l++) {
1087 int entry_id = l + k * num_nodes_in_sendblock;
1088
1089 if (radblk_fmt.CheckFTSWID(entry_id) || radblk_fmt.CheckTLUID(entry_id)) {
1090 reduced_nwords += radblk_fmt.GetBlockNwords(entry_id);
1091 } else {
1092 PreRawCOPPERFormat_v2 temp_prerawcpr;
1093 int temp_delete_flag = 0, temp_num_eve = 1, temp_num_nodes = 1;
1094
1095 // Call CalcReducedNwords
1096 temp_prerawcpr.SetBuffer(radblk_fmt.GetBuffer(entry_id),
1097 radblk_fmt.GetBlockNwords(entry_id),
1098 temp_delete_flag, temp_num_eve,
1099 temp_num_nodes);
1100 reduced_nwords += temp_prerawcpr.CalcReducedNwords(0);
1101 }
1102 }
1103 }
1104 return reduced_nwords;
1105
1106}
1107
1108//void PreRawCOPPERFormat_v2::CopyReducedData(RawDataBlock* raw_datablk, int* buf_to, int delete_flag_from)
1109void PreRawCOPPERFormat_v2::CopyReducedData(int* bufin, int nwords, int num_events, int num_nodes, int* buf_to, int* nwords_to)
1110{
1111 //
1112 // Make a reduced buffer a total RawDataBlock (containing multiple data blocks)
1113 //
1114 RawDataBlockFormat radblk_fmt;
1115 int delete_flag = 0;
1116 radblk_fmt.SetBuffer(bufin, nwords, delete_flag, num_events, num_nodes);
1117
1118 int pos_nwords_to = 0;
1119 for (int k = 0; k < radblk_fmt.GetNumEvents(); k++) {
1120 int num_nodes_in_sendblock = radblk_fmt.GetNumNodes();
1121 for (int l = 0; l < num_nodes_in_sendblock; l++) {
1122 int entry_id = l + k * num_nodes_in_sendblock;
1123 if (radblk_fmt.CheckFTSWID(entry_id) ||
1124 radblk_fmt.CheckTLUID(entry_id)) {
1125 radblk_fmt.CopyBlock(entry_id, buf_to + pos_nwords_to);
1126 pos_nwords_to += radblk_fmt.GetBlockNwords(entry_id);
1127
1128 } else {
1129 SetBuffer(radblk_fmt.GetBuffer(entry_id),
1130 radblk_fmt.GetBlockNwords(entry_id), 0, 1, 1);
1131
1132 pos_nwords_to += CopyReducedBuffer(0, buf_to + pos_nwords_to);
1133
1134
1135 }
1136 }
1137 }
1138
1139 *nwords_to = pos_nwords_to;
1140
1141 return ;
1142}
1143
1144
1146{
1147 //
1148 // Calculate reduced length for one data block which is a part of a RawDataBlock
1149 //
1150
1151 int nwords_to = 0;
1152
1153 //RawCOPPER header
1154 nwords_to += tmp_header.RAWHEADER_NWORDS;
1155
1156 for (int j = 0; j < 4; j++) {
1157
1158 int finesse_nwords = GetFINESSENwords(n, j);
1159 if (finesse_nwords > 0) {
1160 //
1161 // B2L(HSLB/FEE) header and trailers are resized
1162 // m_reduced_rawcpr should be PostRawCOPPERFormat_v2
1163 //
1164 nwords_to +=
1165 finesse_nwords
1166 - (static_cast<int>(SIZE_B2LHSLB_HEADER) - m_reduced_rawcpr.SIZE_B2LHSLB_HEADER)
1167 - (static_cast<int>(SIZE_B2LFEE_HEADER) - m_reduced_rawcpr.SIZE_B2LFEE_HEADER)
1168 - (static_cast<int>(SIZE_B2LFEE_TRAILER) - m_reduced_rawcpr.SIZE_B2LFEE_TRAILER)
1169 - (static_cast<int>(SIZE_B2LHSLB_TRAILER) - m_reduced_rawcpr.SIZE_B2LHSLB_TRAILER);
1170 }
1171
1172 }
1173
1174 //RawCOPPER Trailer
1175 nwords_to += tmp_trailer.GetTrlNwords();
1176
1177 return nwords_to;
1178}
1179
1180
1181
1182
1183
1184
1186{
1187 //
1188 // Make a reduced buffer for one data block which is a part of a RawDataBlock
1189 //
1190
1191 int* buf_from = NULL;
1192 int nwords_buf_to = CalcReducedNwords(n);
1193 int pos_nwords_to = 0;
1194 int copy_nwords = 0;
1195
1196 unsigned int removed_xor_chksum = 0;
1197
1198 // copyt to ReducedRawCOPPER
1199 // ReducedRawCOPPER m_reduced_rawcpr;
1200 //Header copy
1201 copy_nwords = tmp_header.RAWHEADER_NWORDS;
1202 buf_from = GetBuffer(n);
1203 copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1204
1205
1206 //calcurate XOR checksum diff.( depends on data-format )
1207 removed_xor_chksum ^= buf_from[ tmp_header.POS_VERSION_HDRNWORDS ];
1208
1209 // Unset the PreFormat bit ( 15th bit )
1210 buf_to[ tmp_header.POS_VERSION_HDRNWORDS ] &= 0xFFFF7FFF;
1211
1212 //calcurate XOR checksum diff.( depends on data-format )
1213 removed_xor_chksum ^= buf_to[ tmp_header.POS_VERSION_HDRNWORDS ];
1214 for (int i = 0; i < SIZE_COPPER_HEADER; i++) {
1215 removed_xor_chksum ^= buf_from[ tmp_header.RAWHEADER_NWORDS + i ];
1216 }
1217
1218 //Check Header
1219 // m_reduced_rawcpr.tmp_header.CheckHeader(buf_to + pos_nwords_to - copy_nwords);
1220
1221
1222 // copy FINESSE buffer
1223 int pos_nwords_finesse[ 4 ];
1224 for (int j = 0; j < 4; j++) {
1225 pos_nwords_finesse[ j ] = pos_nwords_to;
1226 if (GetFINESSENwords(n, j) > 0) {
1227 int* finesse_buf = GetFINESSEBuffer(n, j);
1228 int finesse_nwords = GetFINESSENwords(n, j);
1229
1230
1231 CheckB2LHSLBMagicWords(finesse_buf, finesse_nwords);
1232 // copy the whole B2LHSLB header (1word)
1233 buf_to[ pos_nwords_to ] = finesse_buf[ POS_MAGIC_B2LHSLB ];
1234 pos_nwords_to++;
1235
1236 // copy the last word of B2LFEE and body( DetectorBuffer )
1237 buf_from =
1238 finesse_buf
1239 + SIZE_B2LHSLB_HEADER
1240 + POS_B2L_CTIME; //the last word of B2LFEE
1241
1242
1243 // check finesse buffer size : ( When dumhslb was used, this type of error
1244 // occured and RecvStream0.py died by Segmentation Fault. ) 2014.12.01.
1245 if (finesse_nwords - SIZE_B2LHSLB_HEADER - SIZE_B2LFEE_HEADER
1246 - SIZE_B2LFEE_TRAILER - SIZE_B2LHSLB_TRAILER < 0) {
1247 char err_buf[500];
1248 char hostname[128];
1249 GetNodeName(n, hostname, sizeof(hostname));
1250 sprintf(err_buf,
1251 "[FATAL] %s ch=%d : ERROR_EVENT : Finesse buffer size is too small( %d words < %d words). May be the data are corrupted. Exiting...\n %s %s %d\n",
1252 hostname, j,
1253 finesse_nwords, static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER,
1254 __FILE__, __PRETTY_FUNCTION__, __LINE__);
1255 printf("%s", err_buf); fflush(stdout);
1256 // string err_str = err_buf; throw (err_str);
1257 B2FATAL(err_buf); // to reduce multiple error messages
1258 }
1259
1260 //calcurate XOR checksum diff.( depends on data-format )
1261 for (int k = 1; k <= 4 ; k++) {
1262 removed_xor_chksum ^= finesse_buf[ k ];
1263 }
1264
1265 copy_nwords =
1266 finesse_nwords
1267 - SIZE_B2LHSLB_HEADER // already copied
1268 - POS_B2L_CTIME // only one word copied ( SIZE_B2LFEE_HEADER - 1 = POS_B2L_CTIME )
1269 - SIZE_B2LFEE_TRAILER // will be copied later
1270 - SIZE_B2LHSLB_TRAILER; // Not copied
1271 copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1272 // printf("pos %d nwords %d nwords to %d\n", pos_nwords_to, copy_nwords, nwords_buf_to );
1273
1274 //copy B2LFEE trailer(CRC info)
1275 buf_to[ pos_nwords_to ] = 0xffff & finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER - (SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) ];
1276 //copy B2LHSLB trailer(packet CRC error count)
1277 buf_to[ pos_nwords_to ] |= (finesse_buf[ finesse_nwords - (static_cast<int>(SIZE_B2LHSLB_TRAILER) - POS_MAGIC_B2LHSLB) ] << 16) &
1278 0xFFFF0000;
1279
1280 //calcurate XOR checksum diff. ( depends on data-format )
1281 for (int k = 0; k <= 2 ; k++) {
1282 removed_xor_chksum ^= finesse_buf[ finesse_nwords - SIZE_B2LFEE_TRAILER - SIZE_B2LHSLB_TRAILER + k ];
1283 }
1284 removed_xor_chksum ^= buf_to[ pos_nwords_to ];
1285
1286 pos_nwords_to++;
1287
1288 // check CRC data
1289 // CheckCRC16( n, j );
1290 }
1291 }
1292
1293 // copy RawCOPPER trailer
1294 buf_from =
1295 GetBuffer(n)
1296 + GetBlockNwords(n)
1298 copy_nwords = tmp_trailer.GetTrlNwords();
1299 copyData(buf_to, &pos_nwords_to, buf_from, copy_nwords, nwords_buf_to);
1300
1301 //calcurate XOR checksum diff.( depends on data-format )
1302 unsigned int old_rawcopper_chksum = buf_from[ tmp_trailer.POS_CHKSUM ];
1303 for (int i = 0; i < SIZE_COPPER_TRAILER; i++) {
1304 removed_xor_chksum ^= (unsigned int) * (buf_from - SIZE_COPPER_TRAILER + i);
1305 }
1306
1307
1308 // length check
1309 if (pos_nwords_to != nwords_buf_to) {
1310 char err_buf[500];
1311 sprintf(err_buf, "Buffer overflow. Exiting... %d %d\n", pos_nwords_to, nwords_buf_to);
1312 printf("%s", err_buf); fflush(stdout);
1313 B2FATAL(err_buf);
1314 }
1315
1316
1317 // Recalculate XOR checksum in a RawCOPPER trailer
1318 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS);
1319 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE);
1320 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE);
1321 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE);
1322 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE);
1323
1324 //
1325 // Apply changes followed by data size reduction
1326 //
1327 *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS) = nwords_buf_to;
1328 *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE) = pos_nwords_finesse[ 0 ];
1329 *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE) = pos_nwords_finesse[ 1 ];
1330 *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE) = pos_nwords_finesse[ 2 ];
1331 *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE) = pos_nwords_finesse[ 3 ];
1332
1333 // Recalculate XOR checksum in a RawCOPPER trailer
1334 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_NWORDS);
1335 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_1ST_FINESSE);
1336 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_2ND_FINESSE);
1337 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_3RD_FINESSE);
1338 removed_xor_chksum ^= *(buf_to + m_reduced_rawcpr.tmp_header.POS_OFFSET_4TH_FINESSE);
1339
1340 // Recalculate XOR checksum in a RawCOPPER trailer
1341 unsigned int new_rawcopper_chksum = CalcXORChecksum(buf_to, pos_nwords_to - tmp_trailer.GetTrlNwords());
1342
1343
1344 if ((old_rawcopper_chksum ^ removed_xor_chksum) != new_rawcopper_chksum) {
1345 char err_buf[500];
1346 char hostname[128];
1347 GetNodeName(n, hostname, sizeof(hostname));
1348 sprintf(err_buf,
1349 "[FATAL] %s ch=%d : ERROR_EVENT : RawCOPPER XOR checksum is inconsistent between before/after data reduction.(%.8x != %.8x ^ %.8x = %.8x ) Exiting...\n %s %s %d\n",
1350 hostname, -1,
1351 new_rawcopper_chksum, old_rawcopper_chksum, removed_xor_chksum, old_rawcopper_chksum ^ removed_xor_chksum,
1352 __FILE__, __PRETTY_FUNCTION__, __LINE__);
1353 printf("%s", err_buf); fflush(stdout);
1354 B2FATAL(err_buf); // to reduce multiple error messages
1355 }
1356
1357 *(buf_to + pos_nwords_to - tmp_trailer.GetTrlNwords() + tmp_trailer.POS_CHKSUM) = new_rawcopper_chksum;
1358
1359
1360
1361 //
1362 // data block # check
1363 //
1364 m_reduced_rawcpr.SetBuffer(buf_to, nwords_buf_to, 0, GetNumEvents(), GetNumNodes());
1366 char err_buf[500];
1367 sprintf(err_buf, "Invalid data block numbers.(# of events %d, # of nodes %d) Exiting...\n",
1369 printf("%s", err_buf); fflush(stdout);
1370 B2FATAL(err_buf);
1371 }
1372
1373 //
1374 // check no-data buffer
1375 //
1376 for (int i = 0; i < m_reduced_rawcpr.GetNumEvents() * m_reduced_rawcpr.GetNumNodes(); i++) {
1377 int nonzero_finesse_buf = 0;
1378 for (int j = 0; j < 4; j++) {
1379
1380 if (GetFINESSENwords(n, j) > 0) {
1381 // m_reduced_rawcpr.CheckCRC16(i, j);
1382 nonzero_finesse_buf++;
1383 }
1384 }
1385 if (nonzero_finesse_buf == 0) {
1386 char err_buf[500];
1387 sprintf(err_buf, "No non-zero FINESSE buffer. Exiting...\n");
1388 printf("%s", err_buf); fflush(stdout);
1389 B2FATAL(err_buf);
1390 }
1391 }
1392
1393 // post_rawcopper_v2.CheckCRC16(0, 0);
1394 // printf("fROM =======================================\n");
1395 // for (int k = 0; k < nwords_buf_to; k++) {
1396 // printf(" %.8x", GetBuffer(n)[ k ]);
1397 // if ( ( k + 1 ) % 10 == 0) {
1398 // printf("\n");
1399 // }
1400 // }
1401 // printf("\n");
1402
1403 // printf("tO =======================================\n");
1404 // for (int k = 0; k < nwords_buf_to; k++) {
1405 // printf(" %.8x", buf_to[ k ]);
1406 // if ( ( k + 1 ) % 10 == 0) {
1407 // printf("\n");
1408 // }
1409 // }
1410 // printf("\n");
1411 // printf("=============================================\n");
1412 return pos_nwords_to;
1413}
1414
1415
1416int PreRawCOPPERFormat_v2::CheckB2LHSLBMagicWords(int* finesse_buf, int finesse_nwords)
1417{
1418
1419 if ((finesse_buf[ POS_MAGIC_B2LHSLB ] & 0xFFFF0000) == B2LHSLB_HEADER_MAGIC &&
1420 ((finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ] & 0xFFFF0000)
1421 == B2LHSLB_TRAILER_MAGIC)) {
1422 return 1;
1423 } else {
1425 char err_buf[500];
1426 sprintf(err_buf,
1427 "Invalid B2LHSLB magic words : header 0x%x (= should be ffaa**** ) or trailer 0x%x (= should be ff55**** ). Exiting... :%s %s %d\n",
1428 finesse_buf[ POS_MAGIC_B2LHSLB ],
1429 finesse_buf[ finesse_nwords - SIZE_B2LHSLB_TRAILER + POS_CHKSUM_B2LHSLB ],
1430 __FILE__, __PRETTY_FUNCTION__, __LINE__);
1431#ifndef NO_ERROR_STOP
1432 printf("%s", err_buf); fflush(stdout);
1433 B2FATAL(err_buf);
1434#endif
1435 }
1436}
1437
1438
1439
1440int PreRawCOPPERFormat_v2::CheckCRC16(int n, int finesse_num)
1441{
1442 //
1443 // Calculate CRC16
1444 //
1445 int* buf = GetFINESSEBuffer(n, finesse_num) + SIZE_B2LHSLB_HEADER;
1446 int nwords = GetFINESSENwords(n, finesse_num) - (static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_TRAILER +
1447 SIZE_B2LHSLB_TRAILER);
1448 unsigned short temp_crc16 = CalcCRC16LittleEndian(0xffff, buf, nwords);
1449
1450 //
1451 // Compare CRC16 with B2LCRC16
1452 //
1453 buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n, finesse_num)
1454 - ((SIZE_B2LFEE_TRAILER - POS_CHKSUM_B2LFEE) + SIZE_B2LHSLB_TRAILER) ;
1455
1456 if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
1457 PrintData(GetBuffer(n), *(GetBuffer(n) + tmp_header.POS_NWORDS));
1458 char err_buf[500];
1459 char hostname[128];
1460 GetNodeName(n, hostname, sizeof(hostname));
1461 printf("[FATAL] %s ch=%d : ERROR_EVENT : PRE CRC16 error : slot %c : B2LCRC16 %x Calculated CRC16 %x : Nwords of FINESSE buf %d\n",
1462 hostname, finesse_num,
1463 65 + finesse_num, *buf, temp_crc16, GetFINESSENwords(n, finesse_num));
1464 int* temp_buf = GetFINESSEBuffer(n, finesse_num);
1465 for (int k = 0; k < GetFINESSENwords(n, finesse_num); k++) {
1466 printf("%.8x ", temp_buf[ k ]);
1467 if ((k + 1) % 10 == 0) {
1468 printf("\n");
1469 }
1470 }
1471 printf("\n");
1472 fflush(stdout);
1473 sprintf(err_buf,
1474 "[FATAL] %s ch=%d : ERROR_EVENT : slot %c : B2LCRC16 (%.4x) differs from one ( %.4x) calculated by PreRawCOPPERfromat class. Exiting...\n %s %s %d\n",
1475 hostname, finesse_num,
1476 65 + finesse_num, (unsigned short)(*buf & 0xFFFF), temp_crc16,
1477 __FILE__, __PRETTY_FUNCTION__, __LINE__);
1478 printf("%s", err_buf); fflush(stdout);
1479 B2FATAL(err_buf); // to reduce multiple error messages
1480 }
1481 return 1;
1482
1483}
1484
1485int* PreRawCOPPERFormat_v2::PackDetectorBuf(int* packed_buf_nwords,
1486 int* detector_buf_1st, int nwords_1st,
1487 int* detector_buf_2nd, int nwords_2nd,
1488 int* detector_buf_3rd, int nwords_3rd,
1489 int* detector_buf_4th, int nwords_4th,
1490 RawCOPPERPackerInfo rawcpr_info)
1491{
1492 int* packed_buf = NULL;
1493
1494 int poswords_to = 0;
1495 int* detector_buf[ 4 ] = { detector_buf_1st, detector_buf_2nd, detector_buf_3rd, detector_buf_4th };
1496 const int nwords[ 4 ] = { nwords_1st, nwords_2nd, nwords_3rd, nwords_4th };
1497
1498 // calculate the event length
1499 int length_nwords = tmp_header.GetHdrNwords() + SIZE_COPPER_HEADER + SIZE_COPPER_TRAILER + tmp_trailer.GetTrlNwords();
1500
1501 for (int i = 0; i < 4; i++) {
1502 if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1503 length_nwords += nwords[ i ];
1504 length_nwords += static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER
1505 + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1506 }
1507
1508 // allocate buffer
1509 packed_buf = new int[ length_nwords ];
1510 memset(packed_buf, 0, sizeof(int) * length_nwords);
1511
1512 //
1513 // Fill RawHeader
1514 //
1515 tmp_header.SetBuffer(packed_buf);
1516
1517 packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
1518 packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] = 0x7f7f8000
1519 | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
1520 | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
1521 packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT)
1522 | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
1523 packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
1524 packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
1525 packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
1526 packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
1527
1528
1529
1530
1531 // fill the positions of finesse buffers
1532 packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ] = static_cast<int>(tmp_header.RAWHEADER_NWORDS) + SIZE_COPPER_HEADER;
1533
1534 packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_1ST_FINESSE ];
1535 if (nwords[ 0 ] > 0) {
1536 packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ] +=
1537 nwords[ 0 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1538 }
1539
1540 packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_2ND_FINESSE ];
1541 if (nwords[ 1 ] > 0) {
1542 packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ] +=
1543 nwords[ 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1544 }
1545
1546 packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] = packed_buf[ tmp_header.POS_OFFSET_3RD_FINESSE ];
1547 if (nwords[ 2 ] > 0) {
1548 packed_buf[ tmp_header.POS_OFFSET_4TH_FINESSE ] += nwords[ 2 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER +
1549 SIZE_B2LHSLB_TRAILER;
1550 }
1551 poswords_to += tmp_header.GetHdrNwords();
1552
1553 // Fill COPPER header
1554 packed_buf[ poswords_to + POS_MAGIC_COPPER_1 ] = COPPER_MAGIC_DRIVER_HEADER;
1555 packed_buf[ poswords_to + POS_MAGIC_COPPER_2 ] = COPPER_MAGIC_FPGA_HEADER;
1556 packed_buf[ poswords_to + POS_EVE_NUM_COPPER ] = rawcpr_info.eve_num;
1557
1558 int size_b2l_hdrtrl = static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
1559 if (nwords[ 0 ] != 0) packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] = nwords[ 0 ] + size_b2l_hdrtrl;
1560 if (nwords[ 1 ] != 0) packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] = nwords[ 1 ] + size_b2l_hdrtrl;
1561 if (nwords[ 2 ] != 0) packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] = nwords[ 2 ] + size_b2l_hdrtrl;
1562 if (nwords[ 3 ] != 0) packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] = nwords[ 3 ] + size_b2l_hdrtrl;
1563
1564 packed_buf[ poswords_to + POS_DATA_LENGTH ] =
1565 packed_buf[ poswords_to + POS_CH_A_DATA_LENGTH ] +
1566 packed_buf[ poswords_to + POS_CH_B_DATA_LENGTH ] +
1567 packed_buf[ poswords_to + POS_CH_C_DATA_LENGTH ] +
1568 packed_buf[ poswords_to + POS_CH_D_DATA_LENGTH ] +
1569 (static_cast<int>(SIZE_COPPER_HEADER) - SIZE_COPPER_DRIVER_HEADER) +
1570 (static_cast<int>(SIZE_COPPER_TRAILER) - SIZE_COPPER_DRIVER_TRAILER);
1571
1572 poswords_to += SIZE_COPPER_HEADER;
1573
1574 // Fill FINESSE buffer
1575 for (int i = 0; i < 4; i++) {
1576
1577 if (detector_buf[ i ] == NULL || nwords[ i ] <= 0) continue; // for an empty FINESSE slot
1578
1579 // Fill b2link HSLB header
1580 packed_buf[ poswords_to + POS_MAGIC_B2LHSLB ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
1581 poswords_to += SIZE_B2LHSLB_HEADER;
1582 int* crc16_start = &(packed_buf[ poswords_to ]);
1583
1584 // Fill b2link FEE header
1585
1586 packed_buf[ poswords_to + POS_TT_CTIME_TYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4;
1587 unsigned int temp_ctime_type = packed_buf[ poswords_to + POS_TT_CTIME_TYPE ];
1588 packed_buf[ poswords_to + POS_TT_TAG ] = rawcpr_info.eve_num;
1589 packed_buf[ poswords_to + POS_TT_UTIME ] = rawcpr_info.tt_utime;
1590 packed_buf[ poswords_to + POS_EXP_RUN ] = (rawcpr_info.exp_num << tmp_header.EXP_SHIFT) | (rawcpr_info.run_subrun_num &
1591 0x003FFFFF); // exp. and run #
1592 packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
1593 poswords_to += SIZE_B2LFEE_HEADER;
1594
1595 // copy the 1st Detector Buffer
1596 memcpy(packed_buf + poswords_to, detector_buf[ i ], nwords[ i ]*sizeof(int));
1597 poswords_to += nwords[ i ];
1598
1599 // Fill b2link b2tt-tag trailer
1600 packed_buf[ poswords_to + POS_TT_CTIME_B2LFEE ] = temp_ctime_type;
1601
1602 // Fill b2link FEE trailer
1603 unsigned short crc16 = CalcCRC16LittleEndian(0xffff, crc16_start, nwords[ i ] + SIZE_B2LFEE_HEADER);
1604 packed_buf[ poswords_to + POS_CHKSUM_B2LFEE ] = ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 & 0xffff);
1605 poswords_to += SIZE_B2LFEE_TRAILER;
1606
1607 // Fill b2link HSLB trailer
1608 packed_buf[ poswords_to + POS_CHKSUM_B2LHSLB ] = 0xff550000;
1609 poswords_to += SIZE_B2LHSLB_TRAILER;
1610
1611 }
1612
1613 // Fill COPPER trailer
1614 packed_buf[ poswords_to + POS_MAGIC_COPPER_3 ] = COPPER_MAGIC_FPGA_TRAILER;
1615 packed_buf[ poswords_to + POS_MAGIC_COPPER_4 ] = COPPER_MAGIC_DRIVER_TRAILER;
1616 unsigned int chksum = 0;
1617 for (int i = tmp_header.GetHdrNwords(); i < poswords_to + (static_cast<int>(SIZE_COPPER_TRAILER) - SIZE_COPPER_DRIVER_TRAILER);
1618 i++) {
1619 chksum ^= packed_buf[ i ];
1620 }
1621 packed_buf[ poswords_to + POS_CHKSUM_COPPER ] = chksum;
1622 poswords_to += SIZE_COPPER_TRAILER;
1623
1624 // Calculate RawCOPPER checksum and fill RawTrailer
1625 chksum = 0;
1626 for (int i = 0; i < poswords_to; i++) {
1627 chksum ^= packed_buf[ i ];
1628 }
1629 packed_buf[ poswords_to + tmp_trailer.POS_CHKSUM ] = chksum;
1630
1631 packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
1632 poswords_to += tmp_trailer.GetTrlNwords();
1633
1634 *packed_buf_nwords = poswords_to;
1635 return packed_buf;
1636}
The Raw COPPER class ver.1 ( the latest version since May, 2014 ) This class stores data received by ...
int CheckB2LHSLBMagicWords(int *finesse_buf, int finesse_nwords)
check magic words of B2link HSLB header/trailer
int CopyReducedBuffer(int n, int *buf_to)
copy data to reduced buffer
int CheckCRC16(int n, int finesse_num)
check CRC16 in B2LFEE trailer
int * PackDetectorBuf(int *packed_buf_nwords, int *detector_buf_1st, int nwords_1st, int *detector_buf_2nd, int nwords_2nd, int *detector_buf_3rd, int nwords_3rd, int *detector_buf_4th, int nwords_4th, RawCOPPERPackerInfo rawcprpacker_info) OVERRIDE_CPP17
Pack data (format ver. = -1 -> Select the latest format version)
int CalcReducedNwords(int n)
calculate reduced data size
void CheckUtimeCtimeTRGType(int n) OVERRIDE_CPP17
check data contents
void CopyReducedData(int *bufin, int nwords, int num_events, int num_nodes, int *buf_to, int *nwords_to)
reduce and merge header/trailer
unsigned int FillTopBlockRawHeader(unsigned int m_node_id, unsigned int prev_eve32, unsigned int prev_exprunsubrun_no, unsigned int *cur_exprunsubrun_no) OVERRIDE_CPP17
should be called by DeSerializerCOPPER.cc and fill contents in RawHeader
virtual unsigned int GetB2LFEE32bitEventNumber(int n) OVERRIDE_CPP17
get b2l block from "FEE b2link header"
int CalcReducedDataSize(int *bufin, int nwords, int num_events, int num_nodes)
reduce and merge header/trailer
PostRawCOPPERFormat_v2 m_reduced_rawcpr
data fromat after size reduction
virtual ~PreRawCOPPERFormat_v2()
Constructor using existing pointer to raw data buffer.
int GetDetectorNwords(int n, int finesse_num) OVERRIDE_CPP17
get Detector buffer length
bool CheckCOPPERMagic(int n) OVERRIDE_CPP17
Check if COPPER Magic words are correct.
PreRawCOPPERFormat_v2()
Default constructor.
unsigned int CalcDriverChkSum(int n) OVERRIDE_CPP17
calc COPPER driver's checksum value
int GetFINESSENwords(int n, int finesse) OVERRIDE_CPP17
get data size of FINESSE buffer
void CheckData(int n, unsigned int prev_evenum, unsigned int *cur_evenum, unsigned int prev_copper_ctr, unsigned int *cur_copper_ctr, unsigned int prev_exprunsubrun_no, unsigned int *cur_exprunsubrun_no) OVERRIDE_CPP17
check data contents
RawTrailer_v2 tmp_trailer
trailer ( not recorded )
RawHeader_v2 tmp_header
header ( not recorded )
virtual int GetOffsetFINESSE(int n, int finesse)
get # of offset words
virtual unsigned int CalcXORChecksum(int *buf, int nwords)
calc XOR checksum
virtual void GetNodeName(int n, char *node_name, int bufsize)
Get hostname of a node from the RawCOPPER header.
virtual int * GetFINESSEBuffer(int n, int finesse_num)
get FINESSE buffer pointer
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)
The RawDataBlockFormat class Format information for rawdata handling.
int m_num_events
number of events in this object
int m_num_nodes
number of nodes in this object
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 int GetBufferPos(int n)
get position of data block in word
virtual int GetNumEntries()
get # of data blocks = (# of nodes)*(# of events)
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 TotalBufNwords()
Get total length of m_buffer.
virtual int GetNumNodes()
get # of data sources(e.g. # of COPPER boards) in m_buffer
virtual int * GetBuffer(int n)
get nth buffer pointer
int m_nwords
number of words of buffer
virtual int GetNumEvents()
get # of events in m_buffer
virtual void PrintData(int *buf, int nwords)
print data
virtual int CheckTLUID(int n)
get FTSW ID to check whether this data block is FTSW data or not
void SetBuffer(int *bufin)
set buffer
Definition: RawHeader_v2.h:47
unsigned int GetDriverChkSum(int n) OVERRIDE_CPP17
read COPPER driver's checksum value
unsigned int GetCOPPERCounter(int n) OVERRIDE_CPP17
get posistion of COPPER block in unit of word
unsigned int GetEveNo(int n) OVERRIDE_CPP17
get subrun #(8bit)
unsigned int GetMagicFPGATrailer(int n) OVERRIDE_CPP17
get magic word of COPPER FPGA trailer
unsigned int GetMagicDriverTrailer(int n) OVERRIDE_CPP17
get magic word of COPPER driver trailer
int GetHdrNwords()
get contents of header
Definition: RawHeader_v2.h:360
int GetTrlNwords()
Set magic word.
unsigned int GetExpRunSubrun(int n) OVERRIDE_CPP17
get Experimental # from header
unsigned int GetMagicFPGAHeader(int n) OVERRIDE_CPP17
get magic word of COPPER FPGA header
int GetExpNo(int n) OVERRIDE_CPP17
get Experimental # from header
unsigned int GetChksum()
Set # of trailer words.
void SetBuffer(int *bufin)
return buffer
Definition: RawTrailer_v2.h:96
int GetRunNo(int n) OVERRIDE_CPP17
Exp# (10bit) run# (14bit) restart # (8bit)
int * GetRawTrlBufPtr(int n) OVERRIDE_CPP17
get buffer pointer of rawcopper trailer
unsigned int GetMagicDriverHeader(int n) OVERRIDE_CPP17
get magic word of COPPER driver header
int GetSubRunNo(int n) OVERRIDE_CPP17
get run # (14bit)
Abstract base class for different kinds of events.
STL namespace.