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