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