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