Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TowerInfoDefs.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TowerInfoDefs.cc
1 #include "TowerInfoDefs.h"
2 #include "RawTowerDefs.h"
3 
4 #include <bitset>
5 #include <climits>
6 #include <cstdlib>
7 #include <iostream>
8 #include <string>
9 
10 #pragma GCC diagnostic push
11 #pragma GCC diagnostic ignored "-Wunused-function"
12 static const int emcadc[8][8] = {
13  {62, 60, 46, 44, 30, 28, 14, 12},
14  {63, 61, 47, 45, 31, 29, 15, 13},
15  {58, 56, 42, 40, 26, 24, 10, 8},
16  {59, 57, 43, 41, 27, 25, 11, 9},
17  {54, 52, 38, 36, 22, 20, 6, 4},
18  {55, 53, 39, 37, 23, 21, 7, 5},
19  {50, 48, 34, 32, 18, 16, 2, 0},
20  {51, 49, 35, 33, 19, 17, 3, 1}};
21 
22 static const int hcaladc[8][2] = {
23  {0, 1},
24  {2, 3},
25  {4, 5},
26  {6, 7},
27  {8, 9},
28  {10, 11},
29  {12, 13},
30  {14, 15}};
31 static const int epdchnlmap[16][2] = {
32  {0, 0},
33  {1, 2},
34  {3, 4},
35  {5, 6},
36  {7, 8},
37  {9, 10},
38  {11, 12},
39  {13, 14},
40  {15, 16},
41  {17, 18},
42  {19, 20},
43  {21, 22},
44  {23, 24},
45  {25, 26},
46  {27, 28},
47  {29, 30}};
48 
49 static const int epd_phimap[31] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
50 static const int epd_rmap[31] = {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
51 
52 unsigned int TowerInfoDefs::encode_emcal(const unsigned int towerIndex)
53 {
54  static int phimap[64];
55  static int etamap[64];
56  static int etabinoffset[4];
57  static int ifirst = 1;
58  if (ifirst == 1)
59  {
60  for (int j = 0; j < 8; j++)
61  {
62  for (int k = 0; k < 8; k++)
63  {
64  etamap[emcadc[j][k]] = j;
65  phimap[emcadc[j][k]] = k;
66  }
67  }
68  etabinoffset[0] = 24;
69  etabinoffset[1] = 0;
70  etabinoffset[2] = 48;
71  etabinoffset[3] = 72;
72  ifirst = 0;
73  }
74  const int channels_per_sector = 64;
75  const int supersector = 64 * 12;
76  const int nchannelsperpacket = 64 * 3;
77  const int maxphibin = 7;
78  const int maxetabin = 23;
79  int supersectornumber = towerIndex / supersector;
80  int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta|
81  if (packet < 0 || packet > 3)
82  {
83  std::cout << "Attempting to access channel with invalid value in EMCal " << packet << std::endl;
84  exit(1);
85  }
86  int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector;
87  int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector;
88  int localphibin = phimap[interfaceboard_channel];
89  if (packet == 0 || packet == 1)
90  {
91  localphibin = maxphibin - localphibin;
92  }
93  int localetabin = etamap[interfaceboard_channel];
94  int packet_etabin = localetabin + 8 * interfaceboard;
95  if (packet == 0 || packet == 1)
96  {
97  packet_etabin = maxetabin - packet_etabin;
98  }
99  unsigned int globaletabin = packet_etabin + etabinoffset[packet];
100  unsigned int globalphibin = localphibin + supersectornumber * 8;
101  unsigned int key = globalphibin + (globaletabin << 16U);
102  return key;
103 }
104 
105 unsigned int TowerInfoDefs::encode_emcal(const unsigned int etabin, const unsigned int phibin)
106 {
107  unsigned int key = phibin + (etabin << 16U);
108  return key;
109 }
110 
111 unsigned int TowerInfoDefs::decode_emcal(const unsigned int tower_key)
112 {
113  const int etabinoffset[4] = {24, 0, 48, 72};
114  const int etabinmap[4] = {1, 0, 2, 3};
115  const int channels_per_sector = 64;
116  const int supersector = 64 * 12;
117  const int nchannelsperpacket = 64 * 3;
118  const int maxphibin = 7;
119  const int maxetabin = 23;
120 
121  unsigned int etabin = tower_key >> 16U;
122  unsigned int phibin = tower_key - (etabin << 16U);
123  int packet = etabinmap[(int) etabin / 24];
124  int localetabin = etabin - etabinoffset[packet];
125  int localphibin = phibin % 8;
126  int supersectornumber = phibin / 8;
127  int ib = 0;
128  if (packet == 0 || packet == 1)
129  {
130  localetabin = maxetabin - localetabin;
131  }
132  ib = localetabin / 8;
133  unsigned int index = 0;
134  if (packet == 0 || packet == 1)
135  {
136  localphibin = maxphibin - localphibin;
137  }
138  localetabin = localetabin % 8;
139  unsigned int localindex = emcadc[localetabin][localphibin];
140  index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber;
141  return index;
142 }
143 
144 unsigned int TowerInfoDefs::encode_hcal(const unsigned int towerIndex)
145 {
146  static int phimap[64];
147  static int etamap[64];
148  static int etabinoffset[4];
149  static int phibinoffset[4];
150  static int ifirst = 1;
151  if (ifirst == 1)
152  {
153  for (int j = 0; j < 8; j++)
154  {
155  for (int k = 0; k < 2; k++)
156  {
157  etamap[hcaladc[j][k]] = j;
158  phimap[hcaladc[j][k]] = k;
159  }
160  }
161  etabinoffset[0] = 0;
162  etabinoffset[1] = 8;
163  etabinoffset[2] = 16;
164  etabinoffset[3] = 0;
165 
166  phibinoffset[0] = 0;
167  phibinoffset[1] = 2;
168  phibinoffset[2] = 4;
169  phibinoffset[3] = 6;
170  ifirst = 0;
171  }
172 
173  const int channels_per_sector = 16;
174  const int supersector = 16 * 4 * 3;
175  const int nchannelsperpacket = channels_per_sector * 4;
176  // const int etabinoffset[4] = {0,8,16,0};
177  // const int phibinoffset[4] = {0,2,4,6};
178  int supersectornumber = towerIndex / supersector;
179  int packet = (towerIndex % supersector) / nchannelsperpacket; // 0 = S small |eta|, 1 == S big |eta|, 2 == N small |eta|, 3 == N big |eta|
180  if (packet < 0 || packet > 3)
181  {
182  std::cout << "Attempting to access channel with invalid value ih HCAL " << packet << std::endl;
183  exit(1);
184  }
185  int interfaceboard = ((towerIndex % supersector) % nchannelsperpacket) / channels_per_sector;
186  int interfaceboard_channel = ((towerIndex % supersector) % nchannelsperpacket) % channels_per_sector;
187  int localphibin = phimap[interfaceboard_channel] + phibinoffset[interfaceboard];
188  int localetabin = etamap[interfaceboard_channel];
189  int packet_etabin = localetabin;
190  unsigned int globaletabin = packet_etabin + etabinoffset[packet];
191  unsigned int globalphibin = localphibin + supersectornumber * 8;
192  unsigned int key = globalphibin + (globaletabin << 16U);
193  return key;
194 }
195 
196 // convert from etabin-phibin to key
197 unsigned int TowerInfoDefs::encode_hcal(const unsigned int etabin, const unsigned int phibin)
198 {
199  unsigned int key = phibin + (etabin << 16U);
200  return key;
201 }
202 
203 unsigned int TowerInfoDefs::decode_hcal(const unsigned int tower_key)
204 {
205  int channels_per_sector = 16;
206  int supersector = 16 * 4 * 3;
207  int nchannelsperpacket = channels_per_sector * 4;
208  int etabinoffset[3] = {0, 8, 16};
209  int phibinoffset[4] = {0, 2, 4, 6};
210  unsigned int etabin = tower_key >> 16U;
211  unsigned int phibin = tower_key - (etabin << 16U);
212  int packet = etabin / 8;
213  int localetabin = etabin - etabinoffset[packet];
214  int localphibin = phibin % 8;
215  int supersectornumber = phibin / 8;
216  int ib = localphibin / 2;
217  unsigned int index = 0;
218  localphibin = localphibin - phibinoffset[ib];
219  unsigned int localindex = hcaladc[localetabin][localphibin];
220  index = localindex + channels_per_sector * ib + packet * nchannelsperpacket + supersector * supersectornumber;
221  return index;
222 }
223 
224 // convert from calorimeter key to phi bin
225 unsigned int TowerInfoDefs::getCaloTowerPhiBin(const unsigned int key)
226 {
227  unsigned int etabin = key >> 16U;
228  unsigned int phibin = key - (etabin << 16U);
229  return phibin;
230 }
231 
232 // convert from calorimeter key to eta bin
233 unsigned int TowerInfoDefs::getCaloTowerEtaBin(const unsigned int key)
234 {
235  unsigned int etabin = key >> 16U;
236  return etabin;
237 }
238 
239 unsigned int TowerInfoDefs::encode_epd(const unsigned int towerIndex) // convert from tower index to key
240 {
241  int channels_per_sector = 31;
242  int supersector = channels_per_sector * 12;
243  unsigned int supersectornumber = towerIndex / supersector;
244  int sector = ((towerIndex % supersector)) / channels_per_sector;
245  int channel = ((towerIndex % supersector)) % channels_per_sector;
246  unsigned int key = channel + (sector << 5U) + (supersectornumber << 9U);
247  return key;
248 }
249 
250 // convert from arm-rbin-phibin to key
251 unsigned int TowerInfoDefs::encode_epd(const unsigned int arm, const unsigned int rbin, const unsigned int phibin)
252 {
253  if (rbin == 0 && phibin > 11)
254  {
255  std::cout << __PRETTY_FUNCTION__ << " encode_epd invalid phibin value: " << phibin << " where max valid phibin is 11" << std::endl;
256  exit(1);
257  }
258 
259  unsigned int sector = phibin / 2;
260  if (rbin == 0)
261  {
262  sector = phibin;
263  }
264 
265  int channel = 0;
266  if (rbin != 0)
267  {
268  channel = epdchnlmap[rbin][phibin - 2 * sector];
269  }
270 
271  unsigned int key = channel + (sector << 5U) + (arm << 9U);
272  return key;
273 }
274 
275 unsigned int TowerInfoDefs::decode_epd(const unsigned int tower_key)
276 {
277  int channels_per_sector = 31;
278  int supersector = channels_per_sector * 12;
279  unsigned int ns_sector = tower_key >> 9U;
280  unsigned int sector = (tower_key - (ns_sector << 9U)) >> 5U;
281  unsigned int channel = tower_key - (ns_sector << 9U) - (sector << 5U);
282  unsigned int index = ns_sector * supersector + sector * channels_per_sector + channel;
283  return index;
284 }
285 
286 // convert from epd key to arm bin
287 unsigned int TowerInfoDefs::get_epd_arm(unsigned int key)
288 {
289  unsigned int arm = key >> 9U;
290  return arm;
291 }
292 // convert from epd key to sector number
293 unsigned int TowerInfoDefs::get_epd_sector(unsigned int key)
294 {
295  unsigned int arm = get_epd_arm(key);
296  unsigned int sector = (key - (arm << 9U)) >> 5U;
297  return sector;
298 }
299 // convert from epd key to r bin
300 unsigned int TowerInfoDefs::get_epd_rbin(unsigned int key)
301 {
302  unsigned int arm = get_epd_arm(key);
303  unsigned int sector = get_epd_sector(key);
304  unsigned int channel = key - (sector << 5U) - (arm << 9U);
305  unsigned int rbin = epd_rmap[channel];
306  return rbin;
307 }
308 // convert from epd key to phi bin
309 unsigned int TowerInfoDefs::get_epd_phibin(unsigned int key)
310 {
311  unsigned int arm = get_epd_arm(key);
312  unsigned int rbin = get_epd_rbin(key);
313  unsigned int sector = get_epd_sector(key);
314  unsigned int channel = key - (sector << 5U) - (arm << 9U);
315  unsigned int phibin = epd_phimap[channel] + 2 * sector;
316  if (rbin == 0)
317  {
318  phibin = sector;
319  }
320 
321  return phibin;
322 }
323 
324 unsigned int TowerInfoDefs::encode_zdc(const unsigned int towerIndex)
325 {
326  if (towerIndex > 15)
327  {
328  std::cout << "Attempting to access zdc channel with invalid number " << towerIndex << std::endl;
329  exit(1);
330  }
331  unsigned int key = towerIndex;
332  /*
333  // 3 bits: one for pos/neg z and 2 for the 3 modules
334  unsigned int key;
335  if (towerIndex == 0) key = 0;
336  if (towerIndex == 1) key = 1;
337  if (towerIndex == 2) key = 2;
338  // negative side
339  if (towerIndex == 3)
340  {
341  key = 1 << 2;
342  key += 0;
343  }
344  if (towerIndex == 4)
345  {
346  key = 1 << 2;
347  key += 1;
348  }
349  if (towerIndex == 5)
350  {
351  key = 1 << 2;
352  key += 2;
353  }
354  */
355  return key;
356 }
357 
358 // convert from channel number to smd tower key
359 unsigned int TowerInfoDefs::encode_smd(const unsigned int towerIndex)
360 {
361  // 3 bits: one for pos/neg z and 2 for the 3 modules
362  if (towerIndex > 29)
363  {
364  std::cout << "Attempting to access smd channel with invalid number " << towerIndex << std::endl;
365  exit(1);
366  }
367  unsigned int Xpos[2] = {0, 6};
368  unsigned int Ypos[2] = {7, 14};
369  unsigned int Xneg[2] = {15, 23};
370  unsigned int Yneg[2] = {22, 29};
371  unsigned int xyBit = 0;
372  unsigned int fingerIndex = UINT_MAX;
373  unsigned int sideBit = 0;
374  if (towerIndex >= Xpos[0] && towerIndex <= Xpos[1])
375  {
376  xyBit = 0;
377  fingerIndex = towerIndex - Xpos[0];
378  sideBit = 1;
379  }
380  if (towerIndex >= Ypos[0] && towerIndex <= Ypos[1])
381  {
382  xyBit = 1;
383  fingerIndex = towerIndex - Ypos[0];
384  sideBit = 1;
385  }
386  if (towerIndex >= Xneg[0] && towerIndex <= Xneg[1])
387  {
388  xyBit = 0;
389  fingerIndex = towerIndex - Xneg[0];
390  sideBit = 0;
391  }
392  if (towerIndex >= Yneg[0] && towerIndex <= Yneg[1])
393  {
394  xyBit = 1;
395  fingerIndex = towerIndex - Yneg[0];
396  sideBit = 0;
397  }
398  unsigned int key = (sideBit << 4) + (xyBit << 3) + fingerIndex;
399  // key += (sideBit << 4) + (xyBit << 3) + fingerIndex;
400  return key;
401 }
402 
403 unsigned int TowerInfoDefs::decode_smd(const unsigned int key)
404 {
405  unsigned int index = 999;
406  for (unsigned int i = 0; i < 30; i++)
407  {
408  if (encode_smd(i) == key)
409  {
410  index = i;
411  break;
412  }
413  }
414  return index;
415 }
416 
417 // convert from zdc tower key to channel number
418 unsigned int TowerInfoDefs::decode_zdc(const unsigned int key)
419 {
420  unsigned int index = 999;
421  for (unsigned int i = 0; i < 16; i++)
422  {
423  if (encode_zdc(i) == key)
424  {
425  index = i;
426  break;
427  }
428  }
429  return index;
430 }
431 
432 // get zdc side, 0 = south, 1 = north
433 int TowerInfoDefs::get_zdc_side(const unsigned int key)
434 {
435  if (key & 8) return 1;
436  return 0;
437 }
438 
439 // convert from calorimeter key to smd side
440 int TowerInfoDefs::get_smd_side(const unsigned int key)
441 {
442  if (key & (1 << 4)) return 1;
443  return -1;
444 }
445 // convert from calorimeter key to smd xy bin
446 int TowerInfoDefs::get_smd_xy(const unsigned int key)
447 {
448  if (key & (1 << 3)) return 0;
449  return 1;
450 }
451 // convert from calorimeter key to smd finger
452 int TowerInfoDefs::get_smd_finger_index(const unsigned int key)
453 {
454  return key & 7;
455 }
456 
457 // 128 channels per side, goes 8 times and 8 charges and so on
458 unsigned int TowerInfoDefs::encode_mbd(const unsigned int pmtIndex)
459 {
460  unsigned int arm = pmtIndex / 128;
461  unsigned int type = (pmtIndex % 16) / 8;
462  unsigned int channel = (pmtIndex % 8) + ((pmtIndex / 16) * 8);
463  if (channel > 63) channel -= 64;
464 
465  unsigned int key = (arm << 7) | (type << 6) | channel;
466 
467  return key;
468 }
469 
470 unsigned int TowerInfoDefs::decode_mbd(const unsigned int key)
471 {
472  unsigned int arm = (key >> 7) & 0x1;
473  unsigned int type = (key >> 6) & 0x1;
474  unsigned int channel = key & 0x3f;
475 
476  unsigned int index = (arm * 128) + (type * 8) + (channel % 8) + (channel / 8) * 16;
477 
478  return index;
479 }
480 
481 unsigned int TowerInfoDefs::get_mbd_arm(const unsigned int key)
482 {
483  return (key >> 7) & 0x1;
484 }
485 
486 unsigned int TowerInfoDefs::get_mbd_side(const unsigned int key)
487 {
488  return get_mbd_arm(key);
489 }
490 
491 unsigned int TowerInfoDefs::get_mbd_type(const unsigned int key)
492 {
493  return (key >> 6) & 0x1;
494 }
495 
496 unsigned int TowerInfoDefs::get_mbd_channel(const unsigned int key)
497 {
498  return key & 0x3f;
499 }
500 
501 // convienent for interface to geometry class
503 {
504  unsigned int towerkey = encode_emcal(towerIndex);
505  unsigned int etabin = getCaloTowerEtaBin(towerkey);
506  unsigned int phibin = getCaloTowerPhiBin(towerkey);
508  return key;
509 }
510 
511 // convienent for interface to geometry class
513 {
514  unsigned int towerkey = encode_hcal(towerIndex);
515  unsigned int etabin = getCaloTowerEtaBin(towerkey);
516  unsigned int phibin = getCaloTowerPhiBin(towerkey);
518  return key;
519 }
520 
521 // convienent for interface to geometry class
523 {
524  unsigned int towerkey = encode_hcal(towerIndex);
525  unsigned int etabin = getCaloTowerEtaBin(towerkey);
526  unsigned int phibin = getCaloTowerPhiBin(towerkey);
528  return key;
529 }
530 
531 #pragma GCC diagnostic pop