Belle II Software development
PostRawCOPPERFormat_latest.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_latest.h>
10
11
12using namespace std;
13using namespace Belle2;
14
15//#define DESY
16//#define NO_ERROR_STOP
17//ClassImp(PostRawCOPPERFormat_latest);
18
20{
21}
22
24{
25}
26
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
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,
51 __FILE__, __PRETTY_FUNCTION__, __LINE__);
52 printf("[DEBUG] %s\n", err_buf);
53 B2FATAL(err_buf);
54 return 0;
55}
56
57
58
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 //
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,
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);
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
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
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
138unsigned 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
152int 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
162int 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 - (static_cast<int>(SIZE_B2LHSLB_HEADER) + POS_B2L_CTIME + SIZE_B2LFEE_TRAILER +
192 SIZE_B2LHSLB_TRAILER);
193 temp_crc16 = CalcCRC16LittleEndian(temp_crc16, buf, pos_nwords);
194
195 //
196 // Compare CRC16 with B2LCRC16
197 //
198 buf = GetFINESSEBuffer(n, finesse_num) + GetFINESSENwords(n,
199 finesse_num) - ((SIZE_B2LFEE_TRAILER - POS_B2LFEE_ERRCNT_CRC16) + SIZE_B2LHSLB_TRAILER) ;
200
201 if (GetEveNo(n) % 100000 == 0) {
202 printf("#### PostRawCOPPER : Eve %.8x block %d finesse %d B2LCRC16 %.8x calculated CRC16 %.8x\n", GetEveNo(n), n, finesse_num,
203 *buf, temp_crc16);
204 }
205
206 // if ( false ) {
207 if ((unsigned short)(*buf & 0xFFFF) != temp_crc16) {
208
209 // dump an event
210 int copper_nwords = copper_buf[ tmp_header.POS_NWORDS ];
211 PrintData(copper_buf, copper_nwords);
212 // Check whether packet-CRC error has occcured or not.
213 if (copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ] & tmp_header.B2LINK_PACKET_CRC_ERROR) {
214 //
215 // Do not stop data
216 //
217 char err_buf[600];
218 char hostname[128];
219 GetNodeName(n, hostname, sizeof(hostname));
220 if ((GetNodeID(n) & DETECTOR_MASK) == ARICH_ID) {
221 sprintf(err_buf,
222 "[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",
223 hostname, finesse_num,
224 *buf, temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
225 65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
226 __FILE__, __PRETTY_FUNCTION__, __LINE__);
227 printf("%s", err_buf); fflush(stdout);
228 PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
229 } else {
230 sprintf(err_buf,
231 "[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",
232 hostname, finesse_num,
233 *buf, temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
234 65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
235 __FILE__, __PRETTY_FUNCTION__, __LINE__);
236 printf("%s", err_buf); fflush(stdout);
237 PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
238#ifndef NO_ERROR_STOP
239 B2FATAL(err_buf);
240#endif
241 }
242
243
244
245 } else {
246 //
247 // Stop taking data
248 //
249 char err_buf[500];
250 char hostname[128];
251 GetNodeName(n, hostname, sizeof(hostname));
252 sprintf(err_buf,
253 "[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",
254 hostname, finesse_num,
255 *buf, temp_crc16, GetFINESSENwords(n, finesse_num), copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ],
256 65 + finesse_num, GetEveNo(n), GetExpNo(n), GetRunNo(n), GetSubRunNo(n),
257 __FILE__, __PRETTY_FUNCTION__, __LINE__);
258 printf("%s", err_buf); fflush(stdout);
259 PrintData(GetFINESSEBuffer(n, finesse_num), GetFINESSENwords(n, finesse_num));
260#ifndef NO_ERROR_STOP
261 B2FATAL(err_buf);
262#endif
263 }
264 // Modify XOR checksum due to adding a bit flag
265 copper_buf[ copper_nwords - tmp_trailer.RAWTRAILER_NWORDS + tmp_trailer.POS_CHKSUM ]
266 ^= copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ];
267 copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ] |= tmp_header.B2LINK_EVENT_CRC_ERROR;
268 copper_buf[ copper_nwords - tmp_trailer.RAWTRAILER_NWORDS + tmp_trailer.POS_CHKSUM ]
269 ^= copper_buf[ tmp_header.POS_TRUNC_MASK_DATATYPE ];
270 }
271
272 return 1;
273
274
275}
276
277
278int* PostRawCOPPERFormat_latest::PackDetectorBuf(int* /*packed_buf_nwords*/,
279 int* /*detector_buf_1st*/, int /*nwords_1st*/,
280 int* /*detector_buf_2nd*/, int /*nwords_2nd*/,
281 int* /*detector_buf_3rd*/, int /*nwords_3rd*/,
282 int* /*detector_buf_4th*/, int /*nwords_4th*/,
283 RawCOPPERPackerInfo rawcpr_info)
284{
285 char err_buf[500];
286 sprintf(err_buf, "[FATAL] This function is not supported. (%u) Exiting...: \n%s %s %d\n",
287 rawcpr_info.eve_num,
288 __FILE__, __PRETTY_FUNCTION__, __LINE__);
289 printf("[DEBUG] %s\n", err_buf);
290 B2FATAL(err_buf);
291 return NULL;
292}
293
294
296 int* const(&detector_buf_ch)[MAX_PCIE40_CH],
297 int const(&nwords_ch)[MAX_PCIE40_CH],
298 RawCOPPERPackerInfo rawcpr_info)
299{
300 int* packed_buf = NULL;
301 int poswords_to = 0;
302
303 // calculate the event length
304 int length_nwords = tmp_header.GetHdrNwords() + tmp_trailer.GetTrlNwords();
305
306 for (int i = 0; i < MAX_PCIE40_CH; i++) {
307 if (detector_buf_ch[ i ] == NULL || nwords_ch[ i ] <= 0) continue; // for an empty FINESSE slot
308 length_nwords += nwords_ch[ i ];
309 length_nwords += static_cast<int>(SIZE_B2LHSLB_HEADER) + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
310 }
311
312 // allocate buffer
313 packed_buf = new int[ length_nwords ];
314 memset(packed_buf, 0, sizeof(int) * length_nwords);
315
316 //
317 // Fill RawHeader
318 //
319 tmp_header.SetBuffer(packed_buf);
320
321 packed_buf[ tmp_header.POS_NWORDS ] = length_nwords; // total length
322 packed_buf[ tmp_header.POS_VERSION_HDRNWORDS ] =
323 0x7f7f0000
324 | ((DATA_FORMAT_VERSION << tmp_header.FORMAT_VERSION_SHIFT) & tmp_header.FORMAT_VERSION__MASK)
325 | tmp_header.RAWHEADER_NWORDS; // ver.#, header length
326 packed_buf[ tmp_header.POS_EXP_RUN_NO ] = (rawcpr_info.exp_num << 22)
327 | (rawcpr_info.run_subrun_num & 0x003FFFFF); // exp. and run #
328 packed_buf[ tmp_header.POS_EVE_NO ] = rawcpr_info.eve_num; // eve #
329 packed_buf[ tmp_header.POS_TTCTIME_TRGTYPE ] = (rawcpr_info.tt_ctime & 0x7FFFFFF) << 4; // tt_ctime
330 packed_buf[ tmp_header.POS_TTUTIME ] = rawcpr_info.tt_utime; // tt_utime
331 packed_buf[ tmp_header.POS_NODE_ID ] = rawcpr_info.node_id; // node ID
332
333 // fill the positions of finesse buffers
334 int ch = 0;
335 packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = tmp_header.RAWHEADER_NWORDS;
336 for (int i = 1; i < MAX_PCIE40_CH; i++) {
337 ch = i;
338 if (nwords_ch[ ch - 1 ] == 0) {
339 packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = packed_buf[ tmp_header.POS_CH_POS_TABLE + (ch - 1) ];
340 } else {
341 packed_buf[ tmp_header.POS_CH_POS_TABLE + ch ] = packed_buf[ tmp_header.POS_CH_POS_TABLE + (ch - 1) ] +
342 nwords_ch[ ch - 1 ] + SIZE_B2LHSLB_HEADER + SIZE_B2LFEE_HEADER + SIZE_B2LFEE_TRAILER + SIZE_B2LHSLB_TRAILER;
343 }
344 }
345 poswords_to += tmp_header.GetHdrNwords();
346
347 // Fill FINESSE buffer
348 for (int i = 0; i < MAX_PCIE40_CH; i++) {
349 if (detector_buf_ch[ i ] == NULL || nwords_ch[ i ] <= 0) continue; // for an empty FINESSE slot
350
351 // Fill b2link HSLB header
352 packed_buf[ poswords_to + POS_B2LHSLB_MAGIC ] = 0xffaa0000 | (0xffff & rawcpr_info.eve_num);
353 poswords_to += SIZE_B2LHSLB_HEADER;
354
355 // Fill b2link FEE header
356 packed_buf[ poswords_to + POS_B2L_CTIME ] = (rawcpr_info.b2l_ctime & 0x7FFFFFF) << 4;
357 poswords_to += SIZE_B2LFEE_HEADER;
358
359 // copy the 1st Detector Buffer
360 memcpy(packed_buf + poswords_to, detector_buf_ch[ i ], nwords_ch[ i ]*sizeof(int));
361 poswords_to += nwords_ch[ i ];
362
363 // Fill b2link FEE trailer
364 unsigned int crc16 = 0;
365 packed_buf[ poswords_to + POS_B2LFEE_ERRCNT_CRC16 ] =
366 ((0xffff & rawcpr_info.eve_num) << 16) | (crc16 &
367 0xffff); // Error count is stored in this buffer for ver.2 format but it is set to zero here.
368 poswords_to += SIZE_B2LFEE_TRAILER;
369
370 // Fill b2link HSLB trailer
371 packed_buf[ poswords_to + POS_B2LHSLB_TRL_MAGIC ] = 0xff550000;
372 poswords_to += SIZE_B2LHSLB_TRAILER;
373
374 }
375
376 // Fill RawTrailer
377 packed_buf[ poswords_to + tmp_trailer.POS_TERM_WORD ] = tmp_trailer.MAGIC_WORD_TERM_TRAILER;
378 poswords_to += tmp_trailer.GetTrlNwords();
379
380 *packed_buf_nwords = poswords_to;
381
382 return packed_buf;
383}
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
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_latest()
Constructor using existing pointer to raw data buffer.
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
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_latest tmp_trailer
trailer ( not recorded )
RawHeader_latest tmp_header
header ( not recorded )
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.
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 * GetBuffer(int n)
get nth buffer pointer
virtual void PrintData(int *buf, int nwords)
print data
void SetBuffer(int *bufin)
set buffer
unsigned int GetEveNo(int n) OVERRIDE_CPP17
get subrun #(8bit)
int GetHdrNwords()
get contents of header
int GetTrlNwords()
Set magic word.
unsigned int GetExpRunSubrun(int n) OVERRIDE_CPP17
get Experimental # from header
int * GetFINESSEBuffer(int n, int finesse_num) OVERRIDE_CPP17
Get a pointer to a FINESSE buffer.
int GetExpNo(int n) OVERRIDE_CPP17
get Experimental # from header
unsigned int GetChksum()
Set # of trailer words.
void SetBuffer(int *bufin)
return buffer
int GetRunNo(int n) OVERRIDE_CPP17
Exp# (10bit) run# (14bit) restart # (8bit)
unsigned int GetNodeID(int n) OVERRIDE_CPP17
get node-ID from data
int * GetRawTrlBufPtr(int n) OVERRIDE_CPP17
get buffer pointer of rawcopper trailer
int GetFINESSENwords(int n, int finesse_num) OVERRIDE_CPP17
Get the size of a finesse buffer.
int GetSubRunNo(int n) OVERRIDE_CPP17
get run # (14bit)
Abstract base class for different kinds of events.
STL namespace.