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