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 <math.h>
6 #include <stdlib.h>
7 #include <stdint.h>
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 != 0) {
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 != 0) {
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  uint32_t calibratedET = hcalET;
94  if(hfLUT != 0) {
95  const std::vector< uint32_t > a = hfLUT->at((region - NRegionsInCard) * NHFEtaInRegion + iEta);
96  calibratedET = a[hcalET] & 0xFF;
97  }
98  uint32_t absCaloEta = abs(caloEta());
99  if(absCaloEta > 29 && absCaloEta < 40) {
100  // Divide by two (since two duplicate towers are sent)
101  calibratedET /= 2;
102  }
103  else if(absCaloEta == 40 || absCaloEta == 41) {
104  // Divide by four
105  calibratedET /= 4;
106  }
107  towerData = calibratedET | zeroFlagMask;
108  if((hcalFB & 0x1) == 0x1) towerData |= ecalFlagMask; // LSB defines short over long fiber ratio
109  if((hcalFB & 0x2) == 0x2) towerData |= hcalFlagMask; // MSB defines minbias flag
110  return true;
111 }
112 
113 bool UCTTower::setECALData(bool eFG, uint32_t eET) {
114  ecalFG = eFG;
115  ecalET = eET;
116  if(eET > etInputMax) {
117  LOG_ERROR << "UCTTower::setData - ecalET too high " << eET << "; Pegged to etInputMax" << std::endl;
118  ecalET = etInputMax;
119  }
120  return true;
121 }
122 
123 bool UCTTower::setHCALData(uint32_t hFB, uint32_t hET) {
124  hcalET = hET;
125  hcalFB = hFB;
126  if(hET > etInputMax) {
127  LOG_ERROR << "UCTTower::setData - hcalET too high " << hET << "; Pegged to etInputMax" << std::endl;
128  hcalET = etInputMax;
129  }
130  if(hFB > 0x3F) {
131  LOG_ERROR << "UCTTower::setData - too many hcalFeatureBits " << std::hex << hFB
132  << "; Used only bottom 6 bits" << std::endl;
133  hcalFB &= 0x3F;
134  }
135  return true;
136 }
137 
138 bool UCTTower::setHFData(uint32_t fbIn, uint32_t etIn) {
139  ecalFG = false; // HF has no separate ecal section
140  ecalET = 0;
141  hcalET = etIn; // We reuse HCAL place as HF
142  hcalFB = fbIn;
143  if(etIn > etInputMax) {
144  LOG_ERROR << "UCTTower::setData - HF ET too high " << etIn << "; Pegged to etInputMax" << std::endl;
145  hcalET = etInputMax;
146  }
147  if(fbIn > 0x3) {
148  LOG_ERROR << "UCTTower::setData - too many HF FeatureBits " << std::hex << fbIn
149  << "; Used only bottom 2 bits" << std::endl;
150  hcalFB &= 0x3;
151  }
152  return true;
153 }
154 
155 const uint16_t UCTTower::location() const {
156  uint16_t l = 0;
157  if(negativeEta) l = 0x8000; // Used top bit for +/- eta-side
158  l |= iPhi; // Max iPhi is 4, so bottom 2 bits for iPhi
159  l |= (iEta << 2); // Max iEta is 4, so 2 bits needed
160  l |= (region << 4); // Max region number 14, so 4 bits needed
161  l |= (card << 8); // Max card number is 6, so 3 bits needed
162  l |= (crate << 11); // Max crate number is 2, so 2 bits needed
163  return l;
164 }
165 
166 UCTTower::UCTTower(uint16_t location, int fwv) :
167  fwVersion(fwv) {
168  if((location & 0x8000) != 0) negativeEta = true;
169  crate = (location & 0x1800) >> 11;
170  card = (location & 0x0700) >> 8;
171  region = (location & 0x00F0) >> 4;
172  iEta = (location & 0x000C) >> 2;
173  iPhi = (location & 0x0003);
174  towerData = 0;
175 }
176 
177 const uint64_t UCTTower::extendedData() const {
178  uint64_t d = rawData();
179  uint64_t l = location();
180  uint64_t r = (l << 48) + d;
181  return r;
182 }
183 
184 std::ostream& operator<<(std::ostream& os, const UCTTower& t) {
185  // if((t.ecalET + t.hcalET) == 0) return os;
186 
187  os << "Side Crt Crd Rgn iEta iPhi cEta cPhi eET eFG hET hFB Summary" << std::endl;
188 
189  UCTGeometry g;
190  std::string side = "+eta ";
191  if(t.negativeEta) side = "-eta ";
192  os << side
193  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
194  << t.crate << " "
195  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
196  << t.card << " "
197  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
198  << t.region << " "
199  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
200  << t.iEta << " "
201  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
202  << t.iPhi << " "
203  << std::setw(4) << std::setfill(' ') << std::dec
204  << g.getCaloEtaIndex(t.negativeEta, t.region, t.iEta) << " "
205  << std::setw(4) << std::setfill(' ') << std::dec
206  << g.getCaloPhiIndex(t.crate, t.card, t.region, t.iPhi) << " "
207  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
208  << t.ecalET << " "
209  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
210  << t.ecalFG << " "
211  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
212  << t.hcalET << " "
213  << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex
214  << t.hcalFB << " "
215  << std::showbase << std::internal << std::setfill('0') << std::setw(10) << std::hex
216  << t.towerData
217  << std::endl;
218  return os;
219 
220 }
std::ostream & operator<<(std::ostream &os, const UCTTower &t)
Definition: UCTTower.cc:184
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