CMS 3D CMS Logo

UCTTower.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <iomanip>
3 #include <string>
4 #include <vector>
5 #include <cmath>
6 #include <cstdlib>
7 #include <cstdint>
8 
9 #include "UCTTower.hh"
10 #include "UCTLogging.hh"
11 
12 using namespace l1tcalo;
13 
14 bool UCTTower::process() {
15  if (region >= NRegionsInCard) {
16  return processHFTower();
17  }
18  if (ecalET > etInputMax)
19  ecalET = etInputMax;
20  if (hcalET > etInputMax)
21  hcalET = etInputMax;
22  uint32_t calibratedECALET = ecalET;
23  uint32_t logECALET = (uint32_t)log2((double)ecalET);
24  if (logECALET > erMaxV)
25  logECALET = erMaxV;
26  if (ecalLUT != nullptr) {
27  uint32_t etaAddress = region * NEtaInRegion + iEta;
28  uint32_t fbAddress = 0;
29  if (ecalFG)
30  fbAddress = 1;
31  uint32_t value = (*ecalLUT)[etaAddress][fbAddress][ecalET];
32  calibratedECALET = value & etInputMax;
33  logECALET = (value & 0x7000) >> 12;
34  }
35  uint32_t calibratedHCALET = hcalET;
36  uint32_t logHCALET = (uint32_t)log2((double)hcalET);
37  if (logHCALET > erMaxV)
38  logHCALET = erMaxV;
39  if (hcalLUT != nullptr) {
40  uint32_t etaAddress = region * NEtaInRegion + iEta;
41  uint32_t fbAddress = 0;
42  if ((hcalFB & 0x1) != 0)
43  fbAddress = 1;
44  uint32_t value = (*hcalLUT)[etaAddress][fbAddress][hcalET];
45  calibratedHCALET = value & etInputMax;
46  logHCALET = (value & 0x7000) >> 12;
47  }
48 
49  // Saturation codes implemented in fwVersion 1
50  if (fwVersion >= 1) {
51  if (calibratedECALET == 0xFF && calibratedHCALET == 0xFF)
52  towerData = 0x1FF;
53  else if (calibratedECALET == 0xFF)
54  towerData = 0x1FE;
55  else if (calibratedHCALET == 0xFF)
56  towerData = 0x1FD;
57  else
58  towerData = calibratedECALET + calibratedHCALET;
59  } else {
60  towerData = calibratedECALET + calibratedHCALET;
61  }
62 
63  if (towerData > etMask)
64  towerData = etMask;
65  uint32_t er = 0;
66  if (calibratedECALET == 0 || calibratedHCALET == 0) {
67  er = 0;
68  towerData |= zeroFlagMask;
69  if (calibratedHCALET == 0 && calibratedECALET != 0)
70  towerData |= eohrFlagMask;
71  } else if (calibratedECALET == calibratedHCALET) {
72  er = 0;
73  towerData |= eohrFlagMask;
74  } else if (calibratedECALET > calibratedHCALET) {
75  er = logECALET - logHCALET;
76  if (er > erMaxV)
77  er = erMaxV;
78  towerData |= eohrFlagMask;
79  } else {
80  er = logHCALET - logECALET;
81  if (er > erMaxV)
82  er = erMaxV;
83  }
84  towerData |= (er << erShift);
85  // Unfortunately, hcalFlag is presently bogus :(
86  // It has never been studied nor used in Run-1
87  // The same status persists in Run-2, but it is available usage
88  // Currently, summarize all hcalFeatureBits in one flag bit
89  if ((hcalFB & 0x1) != 0)
90  towerData |= hcalFlagMask; // FIXME - ignore top bits if(hcalFB != 0)
91  if (ecalFG)
92  towerData |= ecalFlagMask;
93  // Store ecal and hcal calibrated ET in unused upper bits
94  towerData |= (calibratedECALET << ecalShift);
95  towerData |= (calibratedHCALET << hcalShift);
96  // All done!
97  return true;
98 }
99 
100 bool UCTTower::processHFTower() {
101  if (fwVersion > 2) {
102  uint32_t calibratedET = hcalET;
103  if (hfLUT != nullptr) {
104  uint32_t etaAddress = (region - NRegionsInCard) * NHFEtaInRegion + iEta;
105  const std::array<uint32_t, 256>& a = hfLUT->at(etaAddress);
106  calibratedET = a[hcalET] & 0x1FF;
107  }
108  towerData = calibratedET | zeroFlagMask;
109  if ((hcalFB & 0x1) == 0x1)
110  towerData |= ecalFlagMask; // LSB defines short over long fiber ratio
111  if ((hcalFB & 0x2) == 0x2)
112  towerData |= hcalFlagMask; // MSB defines minbias flag
113  } else {
114  uint32_t calibratedET = hcalET;
115  if (hfLUT != nullptr) {
116  uint32_t etaAddress = (region - NRegionsInCard) * NHFEtaInRegion + iEta;
117  const std::array<uint32_t, 256>& a = hfLUT->at(etaAddress);
118  calibratedET = a[hcalET] & 0xFF;
119  }
120  uint32_t absCaloEta = abs(caloEta());
121  if (absCaloEta > 29 && absCaloEta < 40) {
122  // Divide by two (since two duplicate towers are sent)
123  calibratedET /= 2;
124  } else if (absCaloEta == 40 || absCaloEta == 41) {
125  // Divide by four
126  calibratedET /= 4;
127  }
128  towerData = calibratedET | zeroFlagMask;
129  if ((hcalFB & 0x1) == 0x1)
130  towerData |= ecalFlagMask; // LSB defines short over long fiber ratio
131  if ((hcalFB & 0x2) == 0x2)
132  towerData |= hcalFlagMask; // MSB defines minbias flag
133  }
134  return true;
135 }
136 
137 bool UCTTower::setECALData(bool eFG, uint32_t eET) {
138  ecalFG = eFG;
139  ecalET = eET;
140  if (eET > etInputMax) {
141  LOG_ERROR << "UCTTower::setData - ecalET too high " << eET << "; Pegged to etInputMax" << std::endl;
142  ecalET = etInputMax;
143  }
144  return true;
145 }
146 
147 bool UCTTower::setHCALData(uint32_t hFB, uint32_t hET) {
148  hcalET = hET;
149  hcalFB = hFB;
150  if (hET > etInputMax) {
151  LOG_ERROR << "UCTTower::setData - hcalET too high " << hET << "; Pegged to etInputMax" << std::endl;
152  hcalET = etInputMax;
153  }
154  if (hFB > 0x3F) {
155  LOG_ERROR << "UCTTower::setData - too many hcalFeatureBits " << std::hex << hFB << "; Used only bottom 6 bits"
156  << std::endl;
157  hcalFB &= 0x3F;
158  }
159  return true;
160 }
161 
162 bool UCTTower::setHFData(uint32_t fbIn, uint32_t etIn) {
163  ecalFG = false; // HF has no separate ecal section
164  ecalET = 0;
165  hcalET = etIn; // We reuse HCAL place as HF
166  hcalFB = fbIn;
167  if (etIn > etInputMax) {
168  LOG_ERROR << "UCTTower::setData - HF ET too high " << etIn << "; Pegged to etInputMax" << std::endl;
169  hcalET = etInputMax;
170  }
171  if (fbIn > 0x3) {
172  LOG_ERROR << "UCTTower::setData - too many HF FeatureBits " << std::hex << fbIn << "; Used only bottom 2 bits"
173  << std::endl;
174  hcalFB &= 0x3;
175  }
176  return true;
177 }
178 
179 const uint16_t UCTTower::location() const {
180  uint16_t l = 0;
181  if (negativeEta)
182  l = 0x8000; // Used top bit for +/- eta-side
183  l |= iPhi; // Max iPhi is 4, so bottom 2 bits for iPhi
184  l |= (iEta << 2); // Max iEta is 4, so 2 bits needed
185  l |= (region << 4); // Max region number 14, so 4 bits needed
186  l |= (card << 8); // Max card number is 6, so 3 bits needed
187  l |= (crate << 11); // Max crate number is 2, so 2 bits needed
188  return l;
189 }
190 
191 UCTTower::UCTTower(uint16_t location, int fwv) : fwVersion(fwv) {
192  if ((location & 0x8000) != 0)
193  negativeEta = true;
194  crate = (location & 0x1800) >> 11;
195  card = (location & 0x0700) >> 8;
196  region = (location & 0x00F0) >> 4;
197  iEta = (location & 0x000C) >> 2;
198  iPhi = (location & 0x0003);
199  towerData = 0;
200 }
201 
202 const uint64_t UCTTower::extendedData() const {
203  uint64_t d = rawData();
204  uint64_t l = location();
205  uint64_t r = (l << 48) + d;
206  return r;
207 }
208 
209 std::ostream& operator<<(std::ostream& os, const UCTTower& t) {
210  // if((t.ecalET + t.hcalET) == 0) return os;
211 
212  os << "Side Crt Crd Rgn iEta iPhi cEta cPhi eET eFG hET hFB Summary" << std::endl;
213 
214  UCTGeometry g;
215  std::string side = "+eta ";
216  if (t.negativeEta)
217  side = "-eta ";
218  os << side << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.crate << " "
219  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.card << " "
220  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.region << " "
221  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.iEta << " "
222  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.iPhi << " " << std::setw(4)
223  << std::setfill(' ') << std::dec << g.getCaloEtaIndex(t.negativeEta, t.region, t.iEta) << " " << std::setw(4)
224  << std::setfill(' ') << std::dec << g.getCaloPhiIndex(t.crate, t.card, t.region, t.iPhi) << " " << std::showbase
225  << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.ecalET << " " << std::showbase
226  << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.ecalFG << " " << std::showbase
227  << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.hcalET << " " << std::showbase
228  << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.hcalFB << " " << std::showbase
229  << std::internal << std::setfill('0') << std::setw(10) << std::hex << t.towerData << std::endl;
230  return os;
231 }
std::ostream & operator<<(std::ostream &os, const UCTTower &t)
Definition: UCTTower.cc:209
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Definition: value.py:1
d
Definition: ztail.py:151
unsigned long long uint64_t
Definition: Time.h:13
double a
Definition: hdecay.h:121
#define LOG_ERROR
Definition: CSCDQM_Logger.h:40