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