CMS 3D CMS Logo

UCTRegion.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <cstdlib>
3 #include <cstdint>
4 
5 #include <bitset>
6 using std::bitset;
7 #include <string>
8 using std::string;
9 
10 #include "UCTRegion.hh"
11 
12 #include "UCTGeometry.hh"
13 #include "UCTLogging.hh"
14 
15 #include "UCTTower.hh"
16 
17 using namespace l1tcalo;
18 
19 // Activity fraction to determine how active a tower compared to a region is
20 // To avoid ratio calculation, one can use comparison to bit-shifted RegionET
21 // (activityLevelShift, %) = (1, 50%), (2, 25%), (3, 12.5%), (4, 6.125%), (5, 3.0625%)
22 // Cutting any tighter is rather dangerous
23 // For the moment we use floating point arithmetic
24 
25 const float activityFraction = 0.125;
26 const float ecalActivityFraction = 0.25;
27 const float miscActivityFraction = 0.25;
28 
29 bool vetoBit(bitset<4> etaPattern, bitset<4> phiPattern) {
30 
31  bitset<4> badPattern5(string("0101"));
32  bitset<4> badPattern7(string("0111"));
33  bitset<4> badPattern9(string("1001"));
34  bitset<4> badPattern10(string("1010"));
35  bitset<4> badPattern11(string("1011"));
36  bitset<4> badPattern13(string("1101"));
37  bitset<4> badPattern14(string("1110"));
38  bitset<4> badPattern15(string("1111"));
39 
40  bool answer = true;
41 
42  if(etaPattern != badPattern5 && etaPattern != badPattern7 &&
43  etaPattern != badPattern10 && etaPattern != badPattern11 &&
44  etaPattern != badPattern13 && etaPattern != badPattern14 &&
45  etaPattern != badPattern15 && phiPattern != badPattern5 &&
46  // phiPattern != badPattern7 && phiPattern != badPattern10 &&
47  phiPattern != badPattern10 &&
48  phiPattern != badPattern11 && phiPattern != badPattern13 &&
49  //phiPattern != badPattern14 && phiPattern != badPattern15 &&
50  etaPattern != badPattern9 && phiPattern != badPattern9){
51  answer = false;
52  }
53  return answer;
54 
55 }
56 
57 uint32_t getHitTowerLocation(uint32_t *et) {
58  uint32_t etSum = et[0] + et[1] + et[2] + et[3];
59  uint32_t iEtSum =
60  (et[0] >> 1) + // 0.5xet[0]
61  (et[1] >> 1) + et[1] + // 1.5xet[1]
62  (et[2] >> 1) + (et[2] << 1) + // 2.5xet[2]
63  (et[3] << 2) - (et[3] >> 1) ; // 3.5xet[3]
64  uint32_t iAve = 0xDEADBEEF;
65  if( iEtSum <= etSum) iAve = 0;
66  else if(iEtSum <= (etSum << 1)) iAve = 1;
67  else if(iEtSum <= (etSum + (etSum << 1))) iAve = 2;
68  else iAve = 3;
69  return iAve;
70 }
71 
72 UCTRegion::UCTRegion(uint32_t crt, uint32_t crd, bool ne, uint32_t rgn, int fwv) :
73  crate(crt),
74  card(crd),
75  region(rgn),
76  negativeEta(ne),
77  regionSummary(0),
78  fwVersion(fwv) {
79  UCTGeometry g;
80  uint32_t nEta = g.getNEta(region);
81  uint32_t nPhi = g.getNPhi(region);
82  towers.clear();
83  for(uint32_t iEta = 0; iEta < nEta; iEta++) {
84  for(uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
85  towers.push_back(new UCTTower(crate, card, ne, region, iEta, iPhi, fwVersion));
86  }
87  }
88 }
89 
90 UCTRegion::~UCTRegion() {
91  for(uint32_t i = 0; i < towers.size(); i++) {
92  if(towers[i] != nullptr) delete towers[i];
93  }
94 }
95 
96 const UCTTower* UCTRegion::getTower(uint32_t caloEta, uint32_t caloPhi) const {
97  UCTGeometry g;
98  uint32_t nPhi = g.getNPhi(region);
99  uint32_t iEta = g.getiEta(caloEta);
100  uint32_t iPhi = g.getiPhi(caloPhi);
101  UCTTower* tower = towers[iEta*nPhi+iPhi];
102  return tower;
103 }
104 
105 bool UCTRegion::process() {
106 
107  // Determine region dimension
108  UCTGeometry g;
109  uint32_t nEta = g.getNEta(region);
110  uint32_t nPhi = g.getNPhi(region);
111 
112  // Process towers and calculate total ET for the region
113  uint32_t regionET = 0;
114  uint32_t regionEcalET = 0;
115  for(uint32_t twr = 0; twr < towers.size(); twr++) {
116  if(!towers[twr]->process()) {
117  LOG_ERROR << "Tower level processing failed. Bailing out :(" << std::endl;
118  return false;
119  }
120  regionET += towers[twr]->et();
121  // Calculate regionEcalET
122  regionEcalET += towers[twr]->getEcalET();
123  }
124  if(regionET > RegionETMask) {
125  // Region ET can easily saturate, suppress error spam
126  // LOG_ERROR << "L1TCaloLayer1::UCTRegion::Pegging RegionET" << std::endl;
127  regionET = RegionETMask;
128  }
129  regionSummary = (RegionETMask & regionET);
130  if(regionEcalET > RegionETMask) regionEcalET = RegionETMask;
131 
132  // For central regions determine extra bits
133 
134  if(region < NRegionsInCard) {
135  // Identify active towers
136  // Tower ET must be a decent fraction of RegionET
137  bool activeTower[nEta][nPhi];
138  uint32_t activityLevel = ((uint32_t) ((float) regionET) * activityFraction);
139  uint32_t nActiveTowers = 0;
140  uint32_t activeTowerET = 0;
141  for(uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
142  for(uint32_t iEta = 0; iEta < nEta; iEta++) {
143  uint32_t towerET = towers[iEta*nPhi+iPhi]->et();
144  if(towerET > activityLevel) {
145  activeTower[iEta][iPhi] = true;
146  nActiveTowers++;
147  activeTowerET += towers[iEta*nPhi+iPhi]->et();
148  }
149  else
150  activeTower[iEta][iPhi] = false;
151  }
152  }
153  if(activeTowerET > RegionETMask) activeTowerET = RegionETMask;
154  // Determine "hit" tower as weighted position of ET
155  uint32_t sumETIEta[4] = {0, 0, 0, 0};
156  for(uint32_t iEta = 0; iEta < nEta; iEta++) {
157  for(uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
158  uint32_t towerET = towers[iEta*nPhi+iPhi]->et();
159  sumETIEta[iEta] += towerET;
160  }
161  }
162  uint32_t hitIEta = getHitTowerLocation(sumETIEta);
163  uint32_t sumETIPhi[4] = {0, 0, 0, 0};
164  for(uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
165  for(uint32_t iEta = 0; iEta < nEta; iEta++) {
166  uint32_t towerET = towers[iEta*nPhi+iPhi]->et();
167  sumETIPhi[iPhi] += towerET;
168  }
169  }
170  uint32_t hitIPhi = getHitTowerLocation(sumETIPhi);
171  uint32_t hitTowerLocation = hitIEta * nPhi + hitIPhi;
172  // Calculate (energy deposition) active tower pattern
173  bitset<4> activeTowerEtaPattern = 0;
174  for(uint32_t iEta = 0; iEta < nEta; iEta++) {
175  bool activeStrip = false;
176  for(uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
177  if(activeTower[iEta][iPhi]) activeStrip = true;
178  }
179  if(activeStrip) activeTowerEtaPattern |= (0x1 << iEta);
180  }
181  bitset<4> activeTowerPhiPattern = 0;
182  for(uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
183  bool activeStrip = false;
184  for(uint32_t iEta = 0; iEta < nEta; iEta++) {
185  if(activeTower[iEta][iPhi]) activeStrip = true;
186  }
187  if(activeStrip) activeTowerPhiPattern |= (0x1 << iPhi);
188  }
189  // Calculate veto bits for eg and tau patterns
190  bool veto = vetoBit(activeTowerEtaPattern, activeTowerPhiPattern);
191  bool egVeto = veto;
192  bool tauVeto = veto;
193  uint32_t maxMiscActivityLevelForEG = ((uint32_t) ((float) regionET) * ecalActivityFraction);
194  uint32_t maxMiscActivityLevelForTau = ((uint32_t) ((float) regionET) * miscActivityFraction);
195  if((regionET - regionEcalET) > maxMiscActivityLevelForEG) egVeto = true;
196  if((regionET - activeTowerET) > maxMiscActivityLevelForTau) tauVeto = true;
197 
198  if(egVeto) regionSummary |= RegionEGVeto;
199  if(tauVeto) regionSummary |= RegionTauVeto;
200 
201  regionSummary |= (hitTowerLocation << LocationShift);
202 
203  // Extra bits, not in readout, but implicit from their location in data packet for full location information
204 
205  if(negativeEta) regionSummary |= NegEtaBit; // Used top bit for +/- eta-side
206  regionSummary |= (region << RegionNoShift); // Max region number 14, so 4 bits needed
207  regionSummary |= (card << CardNoShift); // Max card number is 6, so 3 bits needed
208  regionSummary |= (crate << CrateNoShift); // Max crate number is 2, so 2 bits needed
209 
210  }
211 
212  return true;
213 
214 }
215 
216 bool UCTRegion::clearEvent() {
217  regionSummary = 0;
218  for(uint32_t i = 0; i < towers.size(); i++) {
219  if(!towers[i]->clearEvent()) return false;
220  }
221  return true;
222 }
223 
224 bool UCTRegion::setECALData(UCTTowerIndex t, bool ecalFG, uint32_t ecalET) {
225  UCTGeometry g;
226  uint32_t nPhi = g.getNPhi(region);
227  uint32_t absCaloEta = abs(t.first);
228  uint32_t absCaloPhi = abs(t.second);
229  uint32_t iEta = g.getiEta(absCaloEta);
230  uint32_t iPhi = g.getiPhi(absCaloPhi);
231  UCTTower* tower = towers[iEta*nPhi+iPhi];
232  return tower->setECALData(ecalFG, ecalET);
233 }
234 
235 bool UCTRegion::setHCALData(UCTTowerIndex t, uint32_t hcalFB, uint32_t hcalET) {
236  UCTGeometry g;
237  uint32_t nPhi = g.getNPhi(region);
238  uint32_t absCaloEta = abs(t.first);
239  uint32_t absCaloPhi = abs(t.second);
240  uint32_t iEta = g.getiEta(absCaloEta);
241  uint32_t iPhiStart = g.getiPhi(absCaloPhi);
242  if(absCaloEta > 29 && absCaloEta < 40) {
243  // Valid data are:
244  // absCaloEta = 30-39, 1 < absCaloPhi <= 72 (every second value)
245  for(uint32_t iPhi = iPhiStart; iPhi < iPhiStart + 2; iPhi++) { // For artificial splitting in half
246  UCTTower* tower = towers[iEta*nPhi + iPhi];
247  // We divide by 2 in output section, after LUT
248  if(!tower->setHFData(hcalFB, hcalET)) return false;
249  }
250  }
251  else if(absCaloEta == 40 || absCaloEta == 41) {
252  // Valid data are:
253  // absCaloEta = 40,41, 1 < absCaloPhi <= 72 (every fourth value)
254  for(uint32_t iPhi = 0; iPhi < 4; iPhi++) { // For artificial splitting in quarter
255  UCTTower* tower = towers[iEta * nPhi + iPhi];
256  // We divide by 4 in output section, after LUT
257  if(!tower->setHFData(hcalFB, hcalET)) return false;
258  }
259  }
260  else {
261  uint32_t iPhi = g.getiPhi(absCaloPhi);
262  UCTTower* tower = towers[iEta*nPhi+iPhi];
263  return tower->setHCALData(hcalFB, hcalET);
264  }
265  return true;
266 }
267 
268 std::ostream& operator<<(std::ostream& os, const UCTRegion& r) {
269  if(r.negativeEta)
270  os << "UCTRegion Summary for negative eta " << r.region
271  << " HitTower (eta, phi) = (" << std::dec << r.hitCaloEta() << ", " << r.hitCaloPhi() << ")"
272  << " summary = "<< std::hex << r.regionSummary << std::endl;
273  else
274  os << "UCTRegion Summary for positive eta " << r.region
275  << " HitTower (eta, phi) = (" << std::dec << r.hitCaloEta() << ", " << r.hitCaloPhi() << ")"
276  << " summary = "<< std::hex << r.regionSummary << std::endl;
277 
278  return os;
279 }
bool vetoBit(bitset< 4 > etaPattern, bitset< 4 > phiPattern)
Definition: UCTRegion.cc:29
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
const float miscActivityFraction
Definition: UCTRegion.cc:27
const float ecalActivityFraction
Definition: UCTRegion.cc:26
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::ostream & operator<<(std::ostream &os, const UCTRegion &r)
Definition: UCTRegion.cc:268
const float activityFraction
Definition: UCTRegion.cc:25
et
define resolution functions of each parameter
uint32_t getHitTowerLocation(uint32_t *et)
Definition: UCTRegion.cc:57
answer
Definition: submit.py:44
#define LOG_ERROR
Definition: CSCDQM_Logger.h:41