ATLAS Offline Software
Loading...
Searching...
No Matches
TileRawChannel2Bytes5.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include <algorithm>
8#include <cmath>
9
10#define UINT32 uint32_t
11#define UINT16 uint16_t
12#define INT32 int32_t
13#define INT16 int16_t
14
15#define verb false
16
17#define code_ped4 TileRawChannel2Bytes5::code_ped4
18#define code_ped5 TileRawChannel2Bytes5::code_ped5
19#define code_amp5 TileRawChannel2Bytes5::code_amp5
20#define code_amp6 TileRawChannel2Bytes5::code_amp6
21#define code_raws TileRawChannel2Bytes5::code_raws
22#define code_rawf TileRawChannel2Bytes5::code_rawf
23#define code_full TileRawChannel2Bytes5::code_full
24#define code_dump TileRawChannel2Bytes5::code_dump
25#define code_null TileRawChannel2Bytes5::code_null
26
27
28namespace {
29
30
31// 0 - ADC, 1 - pC, 2 - CspC, 3 - MeV
32const int OF_E_FRACBITS[4] = { 4, 5, 5, -5 };
33
34// ampcorr lookup table, step = 0.5 ns, scale = 2^14,
35// time = [-32 .. 31], index = time + 32
36const unsigned short ampcorr_lookup[64] = {
37 0x505A, 0x4F62, 0x4E71, 0x4D87, 0x4CA4, 0x4BC8, 0x4AF4, 0x4A26,
38 0x4960, 0x48A1, 0x47EA, 0x473A, 0x4692, 0x45F1, 0x4558, 0x44C7,
39 0x443D, 0x43BC, 0x4342, 0x42D0, 0x4267, 0x4205, 0x41AC, 0x415B,
40 0x4112, 0x40D2, 0x409A, 0x406B, 0x4044, 0x4026, 0x4011, 0x4004,
41 0x4000, 0x4005, 0x4013, 0x402A, 0x404A, 0x4073, 0x40A6, 0x40E2,
42 0x4127, 0x4175, 0x41CD, 0x422F, 0x429A, 0x430E, 0x438D, 0x4415,
43 0x44A7, 0x4543, 0x45E9, 0x4699, 0x4753, 0x4817, 0x48E6, 0x49BF,
44 0x4AA2, 0x4B8F, 0x4C87, 0x4D8A, 0x4E97, 0x4FAF, 0x50D2, 0x51FF
45};
46
47// ========== DSP Intrinstic Functions ========== //
48
49int32_t _ext(int32_t d, uint32_t a, uint32_t b) {
50 a = a & 0x1F; b = b & 0x1F;
51 return ((int32_t)((d << a) & 0xFFFFFFFF)) >> b;
52}
53uint32_t _extu(uint32_t d, uint32_t a, uint32_t b) {
54 a = a & 0x1F; b = b & 0x1F;
55 return ((d << a) & 0xFFFFFFFF) >> b;
56}
57int32_t _extr(int32_t d, uint32_t ab) {
58 return _ext(d, ab >> 5, ab);
59}
60
61#if 0
62uint32_t _hi(uint32_t d) { return (d >> 16) & 0xFFFF; }
63uint32_t _lo(uint32_t d) { return d & 0xFFFF; }
64#endif
65uint32_t _pack2(uint32_t a, uint32_t b) { return (a & 0xFFFF) << 16 | (b & 0xFFFF); }
66#if 0
67uint32_t _packh2(uint32_t a, uint32_t b) { return _pack2(a >> 16, b >> 16); }
68uint32_t _sub2(uint32_t a, uint32_t b) { return _pack2(_hi(a) - _hi(b), _lo(a) - _lo(b)); }
69uint32_t _set(uint32_t d, int a, int b) { return d | _extu(0xFFFFFFFF, a, b); }
70uint32_t _clr(uint32_t d, int a, int b) { return d & ~_extu(0xFFFFFFFF, a, b); }
71uint32_t _setr(int a, int b) { return _set(0, a, b); }
72#endif
73
74unsigned char getbyte(const unsigned char* ptr) {
75 //uint64_t u = (uint64_t) ptr;
76 uintptr_t u = reinterpret_cast<uintptr_t> (ptr);
77 u = u + 3 - 2*(u % 4);
78 ptr = reinterpret_cast<const unsigned char*> (u);
79 return *ptr;
80}
81
82#if 0
83uint8_t _mem1(const unsigned char* ptr) {
84 unsigned char b0;
85 b0 = getbyte(ptr);
86 return b0;
87}
88uint8_t _mem1(const char* ptr) { return _mem1((const unsigned char*) ptr); }
89#endif
90
91
92#if 0
93uint16_t _mem2(const unsigned char* ptr) {
94 unsigned char b0, b1;
95 b0 = getbyte(ptr++);
96 b1 = getbyte(ptr++);
97 return (b0 << 8) | b1;
98}
99uint16_t _mem2(const char* ptr) { return _mem2((const unsigned char*) ptr); }
100#endif
101
102uint32_t _mem4(const unsigned char* ptr) {
103 unsigned char b0, b1, b2, b3;
104 b0 = getbyte(ptr++);
105 b1 = getbyte(ptr++);
106 b2 = getbyte(ptr++);
107 b3 = getbyte(ptr++);
108 return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
109}
110
111#if 0
112uint32_t _mem4(const char* ptr) { return _mem4((const unsigned char*) ptr); }
113#endif
114
115uint32_t _packhl2(uint32_t a, uint32_t b) { return (a & 0xFFFF0000) | (b & 0x0000FFFF); }
116
117
118#if 0
119uint32_t _norm(uint32_t d) {
120 uint32_t u = d & 0x80000000;
121 int n = 0;
122 d = d << 1;
123 while ((u == (d & 0x80000000)) && (n < 31)) {
124 d = d << 1;
125 n++;
126 }
127 return n;
128}
129#endif
130
131
132int32_t _sadd(int32_t a, int32_t b) {
133 int32_t u = a + b;
134 if (a > 0 && b > 0 && u < 0) u = 0x7FFFFFFF; else
135 if (a < 0 && b < 0 && u > 0) u = 0x80000000;
136 return u;
137}
138
139int32_t _sshl(int32_t a, uint32_t b) {
140 b = b & 0x1F;
141 int32_t u = a << b;
142 if ((u >> b) != a) {
143 if (a > 0) u = 0x7FFFFFFF; else u = 0x80000000;
144 }
145 return u;
146}
147
148int32_t _mpy(uint32_t a, uint32_t b) {
149 int16_t a16 = (a & 0xFFFF), b16 = (b & 0xFFFF);
150 int32_t a32 = a16, b32 = b16;
151 return a32*b32;
152}
153int32_t _mpyh(uint32_t a, uint32_t b) { return _mpy(a >> 16, b >> 16); }
154int32_t _mpyhl(uint32_t a, uint32_t b) { return _mpy(a >> 16, b); }
155
156int32_t _dotp2(uint32_t a, uint32_t b) {
157 return _mpy(a, b) + _mpyh(a, b);
158}
159uint32_t _ssub(int32_t a, int32_t b) {
160 int64_t a64 = a, b64 = b;
161 int64_t u = 0x100000000LL;
162 if (a64 - b64 > u - 1) return (u - 1) & 0xFFFFFFFF;
163 if (a64 - b64 < -u) return -u & 0xFFFFFFFF;
164 return (a64 - b64) & 0xFFFFFFFF;
165}
166
167uint32_t _deal(uint32_t u) {
168 uint32_t u1, u0, k, k1, k0;
169 u1 = 0; u0 = 0;
170 k = 1; k0 = 1; k1 = 1 << 16;
171
172 for (int i = 0; i < 16; ++i, (k1 <<= 1), (k <<= 1)) {
173 if (u & k) u0 |= k0;
174 k0 = k0 << 1;
175 k = k << 1;
176
177 if (u & k) u1 |= k1;
178 }
179 return u1 | u0;
180}
181
184
185//uint32_t _hi(double d) { return (uint64_t)d >> 32; }
186//uint32_t _lo(double d) { return (uint64_t)d & 0xFFFFFFFF; }
187//
188//double _memd8(uint32_t* ptr) {
189// uint64_t u = *ptr++;
190// u = u << 32;
191// u |= *ptr++;
192// return (double)u;
193//}
194
195// ========== Some definitions from Compress.h (DSP code) ========== //
196
197#define sbits(u, n) (32 - 1 - (n) < _norm(u))
198#define mvbits(u, n, i) _extu(u, 32 - (n), 32 - (n + i))
199#define mvbits_ex(u, n, i, i0) mvbits(mvbits(u, n + i0, -(i0)), n, i)
200#define nonsat_ene(ene) ((0 < ene) && (ene < 0x7FFF))
201
202//#define _round(u, k) (_ext(u + _rotl(0x1, k - 1), 0, k))
203#define _round(u, k) (_ext(u + _sshl(0x1, k - 1), 0, k))
204
205#define ssatbits(u, n) _ext(_sshl(u, 32 - (n)), 0, 32 - (n))
206
207// does not work for abs(u) >= 0x20000000
208#define saturate(u, n) _ext(_sshl(u + _abs(u), 30 - (n)), 0, 31 - (n))
209
210int get_code(UINT32 reco) { return TileRawChannel2Bytes5::get_code(reco); }
211
212// ========== RarCompress.c (DSP code) ========== //
213
214inline int _roundf(float f) {
215 if (f > 0) return (int)(f + 0.5);
216 else return (int)(f - 0.5);
217}
218
219UINT32 get_uncalib(int unit, UINT32 calib)
220{
221 // uncalib = 1/calib
222 // 1.0 <= calib < 2.0
223 // 0.5 < uncalib <= 1.0
224 // 2^14 <= calib_coeff < 2^15, calib_scale = 14
225 // 2^13 < uncalib_coeff <= 2^14, uncalib_scale = 14
226
227 int FRACBITS_MINUS_11 = _sadd(OF_E_FRACBITS[unit], 11);
228 UINT16 calib_coeff = _extu(calib, 0, 16);
229 UINT16 calib_scale = _extu(calib, 16, 16) - FRACBITS_MINUS_11;
230 UINT16 uncalib_coeff = (int)((1.0/calib_coeff)*(1 << 14)*(1 << 14) + 0.5);
231 UINT16 uncalib_scale = 17 - calib_scale;
232 //UINT32 calib = _pack2(calib_coeff, calib_scale);
233 UINT32 uncalib = _pack2(uncalib_coeff, uncalib_scale);
234 return uncalib;
235}
236
237UINT32 repack_hg(UINT32 hg, UINT16 shift)
238{
239 return _packhl2(_extr(hg, shift), hg);
240}
241
242#if 0
243INT16 get_ampcorr_coeff(int time)
244{
245 // Time with 0.5 ns step
246 // time = t*2
247 // time [-32..31] <==> t [-16.0 .. 15.5]
248 double ampcorr = ((0.0000006467*time + 0.0002713687)*time + 0.0000365732)*time + 1;
249 return _roundf(ampcorr*(0x1 << 14));
250}
251
252
253void print_ampcorr_lookup() {
254 int time;
255 int k = 0;
256 printf("\n");
257 printf("// ampcorr lookup table, step = 0.5 ns\n");
258 printf("unsigned short ampcorr_lookup[64] = {");
259 for (time = -32; time < 32; time++) {
260 UINT16 ampcorr_coeff = get_ampcorr_coeff(time);
261 if (k % 8 == 0) printf("\n ");
262 k++;
263 printf(" 0x%04X,", ampcorr_coeff);
264 }
265 printf("}\n");
266}
267#endif
268
269
270#define unpack_diff(diff, nbits, d2, d3, d5, d6, d7) \
271{ \
272 UINT32 u = _deal(_deal((diff >> nbits))); \
273 d5 = _ext(diff, 32 - nbits, 32 - nbits); \
274 d7 = _ext(u, 8 - nbits, 32 - nbits); \
275 d6 = _ext(u, 16 - nbits, 32 - nbits); \
276 d3 = _ext(u, 24 - nbits, 32 - nbits); \
277 d2 = _ext(u, 32 - nbits, 32 - nbits); \
278}
279
280#define fill_samp(s1, s2, s3, s4, s5, s6, s7, s) \
281{ int i = 0; \
282 s[i++] = s1; \
283 s[i++] = s2; \
284 s[i++] = s3; \
285 s[i++] = s4; \
286 s[i++] = s5; \
287 s[i++] = s6; \
288 s[i++] = s7; \
289}
290
291int get_amp_reco(const UINT32* ofw, int unit, int chan, int gain, int ene0)
292{
293 const UINT32* ofc = (ofw + chan*NOFWORDS_WEIGHTS_7S +
295
296 UINT32 calib = ofc[4];
297 UINT32 uncalib = get_uncalib(unit, calib); // ofc[RECALIB_OFFSET + 1];
298 INT32 amp_reco = _extr(_mpyhl(uncalib, ene0), uncalib);
299 return amp_reco;
300}
301
302int get_s4(const UINT32* ofw, int unit, int chan, int gain, int ene,
303 int s1, int s2, int s3, int s5, int s6, int s7)
304{
305 const UINT32* ofc = (ofw + chan*NOFWORDS_WEIGHTS_7S +
307
308 UINT32 s1x, s32, s5x, s76;
309 UINT32 a1x, a32, a54, a76;
310 int amp, amp_reco, a4, s4;
311 float a4s4;
312
313 s1x = _pack2(s1, 0);
314 s32 = _pack2(s3, s2);
315 s5x = _pack2(s5, 0);
316 s76 = _pack2(s7, s6);
317
318 { // amp coeff
319 //double a1x32 = _memd8(ofc);
320 //double a5476 = _memd8(ofc + 2);
321 a1x = ofc[0]; //a1x = _hi(a1x32);
322 a32 = ofc[1]; //a32 = _lo(a1x32);
323 a54 = ofc[2]; //a54 = _hi(a5476);
324 a76 = ofc[3]; //a76 = _lo(a5476);
325 }
326 amp_reco = get_amp_reco(ofw, unit, chan, gain, ene);
327
328 amp = _mpyh (a1x, s1x)
329 + _dotp2(a32, s32)
330 + _dotp2(a54, s5x)
331 + _dotp2(a76, s76);
332
333 a4s4 = amp_reco - amp;
334 a4 = _ext(a54, 16, 16);
335 s4 = _roundf(a4s4/a4);
336
337 return s4;
338}
339
340inline UINT32 pop_buf(const unsigned char** pptr_buff, int size)
341{
342 UINT32 data = _mem4(*pptr_buff);
343 data = _extu(data, 0, 32 - size);
344 *pptr_buff += (size) >> 3;
345 return data;
346}
347
348int calc_ped_s4(const UINT32* ofw, int unit, int chan, int gain, int ene,
349 int s1, int s2, int s3, int s5, int s6, int s7)
350{
351 return get_s4(ofw, unit, chan, gain, ene, s1, s2, s3, s5, s6, s7);
352}
353
354void calc_amp(const UINT32* ofw, int unit, int chan, int gain, int ene, int time,
355 int s1, int d2, int d3, int d5, int d6, int d7, int s[])
356{
357 int s2, s3, s4, s5, s6, s7;
358 INT16 amp2, ampcorr, a_scale;
359 UINT32 amptime;
360 int amp_reco;
361 UINT32 wamptime;
362
363 const UINT32* ofc = (ofw + chan*NOFWORDS_WEIGHTS_7S +
365
366 a_scale = _extu(ofc[0], 16, 16); // a1x
367 amp_reco = get_amp_reco(ofw, unit, chan, gain, ene);
368 amp2 = (INT16) (amp_reco >> a_scale);
369
370 ampcorr = ampcorr_lookup[time + 32];
371 amp2 = _mpy(amp2, ampcorr) >> 14;
372 amptime = _sshl(_round(_mpy(amp2, time), 3), 16);
373 wamptime = _packhl2((~amptime) + 1, amp2);
374 {
375 // g_scale, h_scale
376 UINT16 g_scale = _extu(ofc[13], 16, 16);
377 UINT16 h_scale = _extu(ofc[13], 0, 16) - 1;
378 UINT16 shift = h_scale - g_scale;
379
380 // shape, derivative coeff
381 //UINT32 hg1 = ofc[14];
382 UINT32 hg2 = ofc[15];
383 UINT32 hg3 = ofc[16];
384 //UINT32 hg4 = ofc[17];
385 UINT32 hg5 = ofc[18];
386 UINT32 hg6 = ofc[19];
387 UINT32 hg7 = ofc[20];
388
389 int q2 = _extr(_dotp2(repack_hg(hg2, shift), wamptime), g_scale);
390 int q3 = _extr(_dotp2(repack_hg(hg3, shift), wamptime), g_scale);
391 int q5 = _extr(_dotp2(repack_hg(hg5, shift), wamptime), g_scale);
392 int q6 = _extr(_dotp2(repack_hg(hg6, shift), wamptime), g_scale);
393 int q7 = _extr(_dotp2(repack_hg(hg7, shift), wamptime), g_scale);
394
395 s2 = q2 + d2 + s1;
396 s3 = q3 + d3 + s1;
397 s5 = q5 + d5 + s1;
398 s6 = q6 + d6 + s1;
399 s7 = q7 + d7 + s1;
400 }
401 s4 = get_s4(ofw, unit, chan, gain, ene, s1, s2, s3, s5, s6, s7);
402 //cppcheck-suppress ctuArrayIndex
403 fill_samp(s1, s2, s3, s4, s5, s6, s7, s);
404}
405
406void calc_raw(const UINT32* ofw, int unit, int chan, int gain, int ene,
407 int s1, int s2, int s3, int s5, int s6, int s7, int s[])
408{
409 int s4 = get_s4(ofw, unit, chan, gain, ene, s1, s2, s3, s5, s6, s7);
410 //cppcheck-suppress ctuArrayIndex
411 fill_samp(s1, s2, s3, s4, s5, s6, s7, s);
412}
413
414int unpack_null(const UINT32* /* ofw */, int /* chan */, const UINT32** pptr_reco,
415 int* gain, int* ene, int* time, int s[])
416{
417 UINT32 reco = **pptr_reco;
418 UINT32 code = get_code(reco);
419 int i;
420 if (code != code_null) return 0;
421 (*pptr_reco)++;
422
423 *gain = reco & 0x1;
424 *ene = 0;
425 *time = 0;
426 for (i = 0; i < 7; i++)
427 s[i] = (reco >> 1) & 0x3FF;
428
429 return 32;
430}
431
432int unpack_ped(const UINT32* ofw, int unit, int chan,
433 const UINT32** pptr_reco, const unsigned char** pptr_buff,
434 int* gain, int* ene, int* time, int s[])
435{
436 int nbits;
437 int size = 0;
438 int s1, s2, s3, s4, s5, s6, s7, d2, d3, d5, d6, d7;
440 UINT32 reco = **pptr_reco;
441 UINT32 code = get_code(reco);
442 if (code != code_ped4 && code != code_ped5) return 0;
443 (*pptr_reco)++;
444
445 *gain = 1;
446 *ene = mvbits_ex(reco, 9, 0, 0) - 256;
447 *time = 0;
448
449 if (code == code_ped4) {
450 s1 = mvbits_ex(reco, 7, 0, 9);
451 nbits = 4;
452 diff = mvbits_ex(reco, 20 - 8, 0, 7 + 9);
453 data = pop_buf(pptr_buff, 8);
454 diff |= _extu(data, 20 - 8, 0);
455 size = 40;
456 } else {
457 s1 = mvbits_ex(reco, 10, 0, 9);
458 nbits = 5;
459 diff = mvbits_ex(reco, 25 - 16, 0, 10 + 9);
460 data = pop_buf(pptr_buff, 16);
461 diff |= _extu(data, 25 - 16, 0);
462 size = 48;
463 }
464
465 unpack_diff(diff, nbits, d2, d3, d5, d6, d7);
466 s2 = s1 + d2;
467 s3 = s1 + d3;
468 s5 = s1 + d5;
469 s6 = s1 + d6;
470 s7 = s1 + d7;
471
472 s4 = calc_ped_s4(ofw, unit, chan, *gain, *ene, s1, s2, s3, s5, s6, s7);
473 fill_samp(s1, s2, s3, s4, s5, s6, s7, s);
474 return size;
475}
476
477int unpack_amp(const UINT32* ofw, int unit, int chan,
478 const UINT32** pptr_reco, const unsigned char** pptr_buff,
479 int* gain, int* ene, int* time, int s[])
480{
481 int nbits = 0;
482 int size = 0;
483 int s1 = 0, d2, d3, d5, d6, d7;
484 UINT32 diff = 0;
485 UINT32 reco = **pptr_reco;
486 UINT32 code = get_code(reco);
487 if (code != code_amp5 && code != code_amp6) return 0;
488 (*pptr_reco)++;
489
490 *gain = mvbits_ex(reco, 1, 0, 31);
491 *ene = mvbits_ex(reco, 15, 0, 0) - ((*gain == 0) ? 512 : 2048);
492 *time = _ext(reco, 32 - 15 - 6, 32 - 6);
493
494 if (code == code_amp5) {
495 s1 = mvbits_ex(reco, 7, 0, 15 + 6);
496 diff = mvbits_ex(reco, 25 - 24, 0, 15 + 6 + 7);
497 diff = _extu(pop_buf(pptr_buff, 24), 1, 0) | diff;
498 nbits = 5;
499 size = 56;
500 } else
501 if (code == code_amp6) {
502 s1 = mvbits_ex(reco, 5, 0, 15 + 6);
503 diff = pop_buf(pptr_buff, 32);
504 s1 = _extu(diff, 32 - 2, 32 - 2 - 5) | s1;
505 diff = _extu(diff, 0, 2);
506 nbits = 6;
507 size = 64;
508 }
509 unpack_diff(diff, nbits, d2, d3, d5, d6, d7);
510 //cppcheck-suppress ctuArrayIndex
511 calc_amp(ofw, unit, chan, *gain, *ene, *time, s1, d2, d3, d5, d6, d7, s);
512 return size;
513}
514
515int unpack_raw(const UINT32* ofw, int unit, int chan,
516 const UINT32** pptr_reco, const unsigned char** pptr_buff,
517 int* gain, int* ene, int* time, int s[])
518{
519 int s1, s2, s3, s5, s6, s7;
520 UINT32 diff1, diff2;
521 UINT32 reco = **pptr_reco;
522 UINT32 code = get_code(reco);
523 int size = 0;
524 if (code != code_raws && code != code_rawf) return 0;
525 (*pptr_reco)++;
526
527 *gain = mvbits_ex(reco, 1, 0, 31);
528 *ene = mvbits_ex(reco, 15, 0, 0) - ((*gain == 0) ? 512 : 2048);
529 *time = 0;
530
531 if (code == code_raws) {
532 // code = code_raws
533 diff1 = pop_buf(pptr_buff, 32);
534 diff2 = pop_buf(pptr_buff, 8);
535 s1 = mvbits_ex(reco, 8, 0, 15);
536 s2 = mvbits_ex(diff1, 3, 6, 0) | mvbits_ex(reco, 6, 0, 15 + 8);
537 s3 = mvbits_ex(diff1, 10, 0, 3);
538 s5 = mvbits_ex(diff1, 10, 0, 10 + 3);
539 s6 = mvbits_ex(diff1, 9, 0, 10 + 10 + 3);
540 s7 = diff2;
541 size = 72;
542 } else {
543 // code = code_rawf
544 diff1 = pop_buf(pptr_buff, 32);
545 diff2 = pop_buf(pptr_buff, 16);
546 s1 = mvbits_ex(reco, 10, 0, 15);
547 s2 = mvbits_ex(diff1, 8, 2, 0) | mvbits_ex(reco, 2, 0, 15 + 10);
548 s3 = mvbits_ex(diff1, 10, 0, 8);
549 s5 = mvbits_ex(diff1, 10, 0, 8 + 10);
550 s6 = mvbits_ex(diff2, 6, 4, 0) | mvbits_ex(diff1, 4, 0, 8 + 10 + 10);
551 s7 = mvbits_ex(diff2, 10, 0, 6);
552 size = 80;
553 }
554 //cppcheck-suppress ctuArrayIndex
555 calc_raw(ofw, unit, chan, *gain, *ene, s1, s2, s3, s5, s6, s7, s);
556 return size;
557}
558
559int unpack_full(const UINT32* /* ofw */, int /* chan */,
560 const UINT32** pptr_reco, const unsigned char** pptr_buff,
561 int* gain, int* ene, int* time, int s[])
562{
563 UINT32 diff1, diff2;
564 UINT32 reco = **pptr_reco;
565 UINT32 code = get_code(reco);
566 int overflow;
567 if (code != code_full) return 0;
568 (*pptr_reco)++;
569
570 diff1 = pop_buf(pptr_buff, 32);
571 diff2 = pop_buf(pptr_buff, 16);
572
573 *gain = mvbits_ex(reco, 1, 0, 31);
574 overflow = mvbits_ex(reco, 1, 0, 23);
575 *ene = (overflow ? 0x7FFF : 0) - ((*gain == 0) ? 512 : 2048);
576 *time = 0;
577
578 s[1-1] = mvbits_ex(reco, 10, 0, 0);
579 s[2-1] = mvbits_ex(reco, 10, 0, 0 + 10);
580 s[3-1] = mvbits_ex(reco, 2, 0, 0 + 10 + 10) | mvbits_ex(diff1, 8, 2, 0);
581 s[4-1] = mvbits_ex(diff1, 10, 0, 8);
582 s[5-1] = mvbits_ex(diff1, 10, 0, 8 + 10);
583 s[6-1] = mvbits_ex(diff1, 4, 0, 8 + 10 + 10) | mvbits_ex(diff2, 6, 4, 0);
584 s[7-1] = mvbits_ex(diff2, 10, 0, 6);
585
586 return 80;
587}
588
589int unpack_dump(const UINT32* /* ofw */, int /* chan */,
590 const UINT32** pptr_reco, const unsigned char** pptr_buff,
591 int* gain, int* ene, int* time, int s[])
592{
593 UINT32 diff1, diff2;
594 UINT32 reco = **pptr_reco;
595 UINT32 code = get_code(reco);
596 if (code != code_dump) return 0;
597 (*pptr_reco)++;
598
599 diff1 = pop_buf(pptr_buff, 32);
600 diff2 = pop_buf(pptr_buff, 24);
601
602 *gain = mvbits_ex(reco, 1, 0, 31);
603 *ene = mvbits_ex(reco, 15, 0, 0) - ((*gain == 0) ? 512 : 2048);
604 *time = 0;
605
606 s[1-1] = mvbits_ex(reco, 10, 0, 15);
607 s[2-1] = mvbits_ex(diff1, 6, 4, 0) | mvbits_ex(reco, 4, 0, 15 + 10);
608 s[3-1] = mvbits_ex(diff1, 10, 0, 6);
609 s[4-1] = mvbits_ex(diff1, 10, 0, 6 + 10);
610 s[5-1] = mvbits_ex(diff2, 4, 6, 0) | mvbits_ex(diff1, 6, 0, 6 + 10 + 10);
611 s[6-1] = mvbits_ex(diff2, 10, 0, 4);
612 s[7-1] = mvbits_ex(diff2, 10, 0, 4 + 10);
613
614 return 88;
615}
616
617} // anonymous namespace
618
619
620// ========== DSP reconstruction of Amplitude (DSP code) ========== //
621
622
623int TileRawChannel2Bytes5::amplitude(const UINT32* ofw, int unit, int chan, int gain, int s[]) const
624{
625
626 UINT32 calib, calib_coeff;
627 INT16 calib_scale;
628 int amp, ene, ene0, ene_shift;
629 //INT16 amp2;
630 const UINT32* ofc;
631
632 int FRACBITS_MINUS_11 = _sadd(OF_E_FRACBITS[unit], 11);
633
634 int s1 = s[0], s2 = s[1], s3 = s[2], s4 = s[3], s5 = s[4], s6 = s[5], s7 = s[6];
635
636 // samples
637 UINT32 s1x = _pack2(s1, gain << 15);
638 UINT32 s32 = _pack2(s3, s2);
639 UINT32 s54 = _pack2(s5, s4);
640 UINT32 s76 = _pack2(s7, s6);
641
642 ene_shift = 512 + _mpy(gain, 2048 - 512);
643
644 ofc = ofw + chan*NOFWORDS_WEIGHTS_7S + gain*NOFWORDS_WEIGHTS_7S_1GAIN;
645
646 // amp coeff
647 UINT32 a1x = ofc[0];
648 UINT32 a32 = ofc[1];
649 UINT32 a54 = ofc[2];
650 UINT32 a76 = ofc[3];
651 //UINT16 a_scale = _extu(a1x, 16, 16);
652
653 amp = _mpyh (a1x, s1x)
654 + _dotp2(a32, s32)
655 + _dotp2(a54, s54)
656 + _dotp2(a76, s76);
657
658 // calib
659 calib = ofc[4];
660
661 calib_coeff = _ext(calib, 0, 16);
662 calib_scale = _ssub(_extu(calib, 16, 16) , FRACBITS_MINUS_11);
663 ene0 = _round(amp, 11);
664 ene0 = _round(ene0*calib_coeff, calib_scale);
665 ene = ene0 + ene_shift;
666
667 return ene;
668}
669
670
671void TileRawChannel2Bytes5::unpack(const UINT32* ofw, const UINT32* ptr_frag, TileChanData* ChanData) const
672{
673 int unit = _extu(ptr_frag[2], 0, 32 - 2); // frag_info = xx......
674 int size_L2 = _extu(ptr_frag[2], 2, 32 - 3); // frag_info = ..xxx...
675 int i, chan, code, size;
676 int gain(0), bad, ene(0), time(0), u[7];
677 const UINT32* ptr_reco = ptr_frag + 3; // + Header
678 const unsigned char* ptr_buff = reinterpret_cast<const unsigned char*> (ptr_frag + 3 + 48 + size_L2); // + Header + Reco + Size_L2
679 const UINT32* ptr = ptr_reco;
680 UINT16 bad_bits[3];
681 UINT16 bad16 = 0;
682
683 const unsigned char* ptr_ped4;
684 const unsigned char* ptr_ped5;
685 const unsigned char* ptr_amp5;
686 const unsigned char* ptr_amp6;
687 const unsigned char* ptr_raws;
688 const unsigned char* ptr_rawf;
689 const unsigned char* ptr_full;
690 const unsigned char* ptr_dump;
691
692 int cnt_ped4, cnt_ped5, cnt_amp5, cnt_amp6,
693 cnt_raws, cnt_rawf, cnt_full, cnt_null, cnt_dump;
694 cnt_ped4 = cnt_ped5 = cnt_amp5 = cnt_amp6 =
695 cnt_raws = cnt_rawf = cnt_full = cnt_null = cnt_dump = 0;
696
697 bad_bits[0] = pop_buf(&ptr_buff, 16);
698 bad_bits[1] = pop_buf(&ptr_buff, 16);
699 bad_bits[2] = pop_buf(&ptr_buff, 16);
700
701 for (chan = 0; chan < 48; ++chan) {
702 for (i = 0; i < 7; ++i) u[i] = 0;
703 code = get_code(ptr_reco[chan]);
704 if (code == code_ped4) cnt_ped4++; else
705 if (code == code_ped5) cnt_ped5++; else
706 if (code == code_amp5) cnt_amp5++; else
707 if (code == code_amp6) cnt_amp6++; else
708 if (code == code_raws) cnt_raws++; else
709 if (code == code_rawf) cnt_rawf++; else
710 if (code == code_full) cnt_full++; else
711 if (code == code_dump) cnt_dump++; else
712 if (code == code_null) cnt_null++;
713 }
714
715 ptr_ped4 = ptr_buff;
716 ptr_ped5 = ptr_ped4 + cnt_ped4*1; // 40 - ped4
717 ptr_amp5 = ptr_ped5 + cnt_ped5*2; // 48 - ped5
718 ptr_amp6 = ptr_amp5 + cnt_amp5*3; // 56 - amp5
719 ptr_raws = ptr_amp6 + cnt_amp6*4; // 64 - amp6
720 ptr_rawf = ptr_raws + cnt_raws*5; // 72 - raws
721 ptr_full = ptr_rawf + cnt_rawf*6; // 80 - rawf
722 ptr_dump = ptr_full + cnt_full*6; // 80 - full
723
724 for (chan = 0; chan < 48; ++chan) {
725 if (chan % 16 == 0) bad16 = ~bad_bits[chan/16]; // note inversion here
726 bad = (bad16 & 0x1); bad16 >>= 1;
727 code = get_code(ptr_reco[chan]);
728
729 size = 0;
730 if (code == code_ped4) size = unpack_ped (ofw, unit, chan, &ptr, &ptr_ped4, &gain, &ene, &time, u); else
731 if (code == code_ped5) size = unpack_ped (ofw, unit, chan, &ptr, &ptr_ped5, &gain, &ene, &time, u); else
732 if (code == code_amp5) size = unpack_amp (ofw, unit, chan, &ptr, &ptr_amp5, &gain, &ene, &time, u); else
733 if (code == code_amp6) size = unpack_amp (ofw, unit, chan, &ptr, &ptr_amp6, &gain, &ene, &time, u); else
734 if (code == code_raws) size = unpack_raw (ofw, unit, chan, &ptr, &ptr_raws, &gain, &ene, &time, u); else
735 if (code == code_rawf) size = unpack_raw (ofw, unit, chan, &ptr, &ptr_rawf, &gain, &ene, &time, u); else
736 if (code == code_full) size = unpack_full(ofw, chan, &ptr, &ptr_full, &gain, &ene, &time, u); else
737 if (code == code_dump) size = unpack_dump(ofw, chan, &ptr, &ptr_dump, &gain, &ene, &time, u); else
738 if (code == code_null) size = unpack_null(ofw, chan, &ptr, &gain, &ene, &time, u);
739 if (size == 0) printf("\nTileRawChannel2Bytes5::unpack ERROR size = 0\n");
740
741 // Fill ChanData
742 ChanData[chan].code = code;
743 ChanData[chan].gain = gain;
744 ChanData[chan].bad = bad;
745 ChanData[chan].ene_bin = ene;
746 ChanData[chan].time_bin = time;
747
748 ChanData[chan].ene = (gain) ? ene/AMPLITUDE_FACTOR5_HG[unit]
750 ChanData[chan].time = time/2.0;
751
752 for (i = 0; i < 7; ++i) ChanData[chan].s[i] = u[i];
753 }
754}
755
756bool TileRawChannel2Bytes5::check_raw(const uint32_t* feb, int of_energy[], TileChanData* Data) const
757{
758 bool OK = true;
759 int chan, i;
760 int gain, ene, u[7], s[7];
761 const UINT32* data = feb + 3;
762 for (chan = 0; chan < 48; ++chan) {
763 bool chOK = true;
764 //code = Data[chan].code;
765 //bad = Data[chan].bad;
766 gain = Data[chan].gain;
767 ene = Data[chan].ene_bin;
768 //time = Data[chan].time_bin;
769
770 for (i = 0; i < 7; ++i) u[i] = Data[chan].s[i];
771 {
772 //double s1x32 = _memd8(data + chan*4);
773 //double s5476 = _memd8(data + chan*4 + 2);
774 UINT32 s1x = data[chan*4 + 0]; //_hi(s1x32);
775 UINT32 s32 = data[chan*4 + 1]; //_lo(s1x32);
776 UINT32 s54 = data[chan*4 + 2]; //_hi(s5476);
777 UINT32 s76 = data[chan*4 + 3]; //_lo(s5476);
778 s[1-1] = _extu(s1x, 0, 16);
779 s[2-1] = _extu(s32, 16, 16);
780 s[3-1] = _extu(s32, 0, 16);
781 s[4-1] = _extu(s54, 16, 16);
782 s[5-1] = _extu(s54, 0, 16);
783 s[6-1] = _extu(s76, 16, 16);
784 s[7-1] = _extu(s76, 0, 16);
785 }
786
787 for (i = 0; i < 7; ++i) {
788 if (s[i] != u[i]) chOK = false;
789 }
790 if (!chOK) { printf("\n %d: Raw Data ERROR", chan); }
791
792 ene += (gain == 0 ? 512 : 2048);
793
794 if (of_energy[chan] != ene) {
795 OK = false;
796 printf("\n %d : amp error ene: %d e_t_amp: %d\n", chan, ene, of_energy[chan]);
797 }
798
799 if (!chOK) {
800 OK = false;
801 printf("\n %2d ERROR", chan);
802 }
803 }
804 printf("\nunpack_data");
805 if (OK) printf(" OK"); else printf(" ERROR");
806 printf(" ");
807 return OK;
808}
809
810bool TileRawChannel2Bytes5::check_reco(const UINT32* frag, int of_energy[]) const
811{
812 int chan;
813 bool OK = true;
814 int bad, gain, amp, ene, time;
815 const UINT32* reco = (frag + 3); // + Header
816 UINT32 w;
817
818 for (chan = 0; chan < 48; ++chan) {
819 w = reco[chan];
820
821 if (!unpack_reco_bin(w, bad, gain, amp, time)) {
822 printf("\nTileRawChannel2Bytes5::unpack_reco_bin ERROR\n");
823 OK = false;
824 }
825
826 ene = amp + AMPLITUDE_OFFSET5[gain];
827
828 if (of_energy[chan] != ene) {
829 OK = false;
830 //printf("\n "); print_code(code);
831 //printf(" amp error ene: %d e_t_amp: %d", amp, of_energy[chan]);
832 }
833 } // for
834
835 return OK;
836}
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
@ Data
Definition BaseObject.h:11
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t a
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
#define code_null
#define code_dump
#define code_ped5
#define _round(u, k)
#define code_raws
#define unpack_diff(diff, nbits, d2, d3, d5, d6, d7)
#define code_full
#define fill_samp(s1, s2, s3, s4, s5, s6, s7, s)
#define mvbits_ex(u, n, i, i0)
#define code_amp5
#define UINT32
#define code_ped4
#define INT32
#define UINT16
#define INT16
#define code_amp6
#define code_rawf
const double AMPLITUDE_FACTOR5_HG[4]
const double AMPLITUDE_FACTOR5_LG[4]
const int AMPLITUDE_OFFSET5[2]
const int NOFWORDS_WEIGHTS_7S
const int NOFWORDS_WEIGHTS_7S_1GAIN
static int get_code(uint32_t reco)
bool check_reco(const uint32_t *frag, int of_energy[]) const
bool unpack_reco_bin(unsigned int w, int &fmt, int &gain, int &amp, int &time) const
int amplitude(const uint32_t *ofw, int unit, int chan, int gain, int s[]) const
void unpack(const uint32_t *ofw, const uint32_t *ptr_frag, TileChanData *ChanData) const
bool check_raw(const uint32_t *feb, int of_energy[], TileChanData *ChanData) const
time(flags, cells_name, *args, **kw)