CMS 3D CMS Logo

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