File indexing completed on 2024-11-01 06:11:54
0001 #include <iostream>
0002 #include <cstdlib>
0003 #include <cstdint>
0004
0005 #include <bitset>
0006 using std::bitset;
0007 #include <string>
0008 using std::string;
0009
0010 #include "UCTRegion.hh"
0011
0012 #include "UCTGeometry.hh"
0013 #include "UCTLogging.hh"
0014
0015 #include "UCTTower.hh"
0016
0017 using namespace l1tcalo;
0018
0019
0020
0021
0022
0023
0024
0025 const float activityFraction = 0.125;
0026 const float ecalActivityFraction = 0.25;
0027 const float miscActivityFraction = 0.25;
0028
0029 bool vetoBit(bitset<4> etaPattern, bitset<4> phiPattern) {
0030 bitset<4> badPattern5(string("0101"));
0031 bitset<4> badPattern7(string("0111"));
0032 bitset<4> badPattern9(string("1001"));
0033 bitset<4> badPattern10(string("1010"));
0034 bitset<4> badPattern11(string("1011"));
0035 bitset<4> badPattern13(string("1101"));
0036 bitset<4> badPattern14(string("1110"));
0037 bitset<4> badPattern15(string("1111"));
0038
0039 bool answer = true;
0040
0041 if (etaPattern != badPattern5 && etaPattern != badPattern7 && etaPattern != badPattern10 &&
0042 etaPattern != badPattern11 && etaPattern != badPattern13 && etaPattern != badPattern14 &&
0043 etaPattern != badPattern15 && phiPattern != badPattern5 &&
0044
0045 phiPattern != badPattern10 && phiPattern != badPattern11 && phiPattern != badPattern13 &&
0046
0047 etaPattern != badPattern9 && phiPattern != badPattern9) {
0048 answer = false;
0049 }
0050 return answer;
0051 }
0052
0053 uint32_t getHitTowerLocation(uint32_t* et) {
0054 uint32_t etSum = et[0] + et[1] + et[2] + et[3];
0055 uint32_t iEtSum = (et[0] >> 1) +
0056 (et[1] >> 1) + et[1] +
0057 (et[2] >> 1) + (et[2] << 1) +
0058 (et[3] << 2) - (et[3] >> 1);
0059 uint32_t iAve = 0xDEADBEEF;
0060 if (iEtSum <= etSum)
0061 iAve = 0;
0062 else if (iEtSum <= (etSum << 1))
0063 iAve = 1;
0064 else if (iEtSum <= (etSum + (etSum << 1)))
0065 iAve = 2;
0066 else
0067 iAve = 3;
0068 return iAve;
0069 }
0070
0071 UCTRegion::UCTRegion(const UCTRegion& otherRegion)
0072 : crate(otherRegion.crate),
0073 card(otherRegion.card),
0074 region(otherRegion.region),
0075 towers(otherRegion.towers),
0076 regionSummary(otherRegion.regionSummary),
0077 fwVersion(otherRegion.fwVersion) {}
0078
0079 UCTRegion::UCTRegion(uint32_t crt, uint32_t crd, bool ne, uint32_t rgn, int fwv)
0080 : crate(crt), card(crd), region(rgn), negativeEta(ne), regionSummary(0), fwVersion(fwv) {
0081 UCTGeometry g;
0082 uint32_t nEta = g.getNEta(region);
0083 uint32_t nPhi = g.getNPhi(region);
0084 towers.clear();
0085 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0086 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0087 towers.push_back(std::make_shared<UCTTower>(crate, card, ne, region, iEta, iPhi, fwVersion));
0088 }
0089 }
0090 }
0091
0092 const std::shared_ptr<UCTTower> UCTRegion::getTower(uint32_t caloEta, uint32_t caloPhi) const {
0093 UCTGeometry g;
0094 uint32_t nPhi = g.getNPhi(region);
0095 uint32_t iEta = g.getiEta(caloEta);
0096 uint32_t iPhi = g.getiPhi(caloPhi);
0097 std::shared_ptr<UCTTower> tower = towers[iEta * nPhi + iPhi];
0098 return tower;
0099 }
0100
0101 bool UCTRegion::process() {
0102
0103 UCTGeometry g;
0104 uint32_t nEta = g.getNEta(region);
0105 uint32_t nPhi = g.getNPhi(region);
0106
0107
0108 uint32_t regionET = 0;
0109 uint32_t regionEcalET = 0;
0110 for (uint32_t twr = 0; twr < towers.size(); twr++) {
0111 if (!towers[twr]->process()) {
0112 LOG_ERROR << "Tower level processing failed. Bailing out :(" << std::endl;
0113 return false;
0114 }
0115 regionET += towers[twr]->et();
0116
0117 regionEcalET += towers[twr]->getEcalET();
0118 }
0119 if (regionET > RegionETMask) {
0120
0121
0122 regionET = RegionETMask;
0123 }
0124 regionSummary = (RegionETMask & regionET);
0125 if (regionEcalET > RegionETMask)
0126 regionEcalET = RegionETMask;
0127
0128
0129
0130 if (region < NRegionsInCard) {
0131
0132
0133 bool activeTower[nEta][nPhi];
0134 uint32_t activityLevel = ((uint32_t)((float)regionET) * activityFraction);
0135 uint32_t activeTowerET = 0;
0136 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0137 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0138 uint32_t towerET = towers[iEta * nPhi + iPhi]->et();
0139 if (towerET > activityLevel) {
0140 activeTower[iEta][iPhi] = true;
0141 activeTowerET += towers[iEta * nPhi + iPhi]->et();
0142 } else
0143 activeTower[iEta][iPhi] = false;
0144 }
0145 }
0146 if (activeTowerET > RegionETMask)
0147 activeTowerET = RegionETMask;
0148
0149 uint32_t sumETIEta[4] = {0, 0, 0, 0};
0150 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0151 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0152 uint32_t towerET = towers[iEta * nPhi + iPhi]->et();
0153 sumETIEta[iEta] += towerET;
0154 }
0155 }
0156 uint32_t hitIEta = getHitTowerLocation(sumETIEta);
0157 uint32_t sumETIPhi[4] = {0, 0, 0, 0};
0158 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0159 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0160 uint32_t towerET = towers[iEta * nPhi + iPhi]->et();
0161 sumETIPhi[iPhi] += towerET;
0162 }
0163 }
0164 uint32_t hitIPhi = getHitTowerLocation(sumETIPhi);
0165 uint32_t hitTowerLocation = hitIEta * nPhi + hitIPhi;
0166
0167 bitset<4> activeTowerEtaPattern = 0;
0168 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0169 bool activeStrip = false;
0170 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0171 if (activeTower[iEta][iPhi])
0172 activeStrip = true;
0173 }
0174 if (activeStrip)
0175 activeTowerEtaPattern |= (0x1 << iEta);
0176 }
0177 bitset<4> activeTowerPhiPattern = 0;
0178 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0179 bool activeStrip = false;
0180 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0181 if (activeTower[iEta][iPhi])
0182 activeStrip = true;
0183 }
0184 if (activeStrip)
0185 activeTowerPhiPattern |= (0x1 << iPhi);
0186 }
0187
0188 bool veto = vetoBit(activeTowerEtaPattern, activeTowerPhiPattern);
0189 bool egVeto = veto;
0190 bool tauVeto = veto;
0191 uint32_t maxMiscActivityLevelForEG = ((uint32_t)((float)regionET) * ecalActivityFraction);
0192 uint32_t maxMiscActivityLevelForTau = ((uint32_t)((float)regionET) * miscActivityFraction);
0193 if ((regionET - regionEcalET) > maxMiscActivityLevelForEG)
0194 egVeto = true;
0195 if ((regionET - activeTowerET) > maxMiscActivityLevelForTau)
0196 tauVeto = true;
0197
0198 if (egVeto)
0199 regionSummary |= RegionEGVeto;
0200 if (tauVeto)
0201 regionSummary |= RegionTauVeto;
0202
0203 regionSummary |= (hitTowerLocation << LocationShift);
0204
0205
0206
0207 if (negativeEta)
0208 regionSummary |= NegEtaBit;
0209 regionSummary |= (region << RegionNoShift);
0210 regionSummary |= (card << CardNoShift);
0211 regionSummary |= (crate << CrateNoShift);
0212 }
0213
0214 return true;
0215 }
0216
0217 bool UCTRegion::clearEvent() {
0218 regionSummary = 0;
0219 for (uint32_t i = 0; i < towers.size(); i++) {
0220 if (!towers[i]->clearEvent())
0221 return false;
0222 }
0223 return true;
0224 }
0225
0226 bool UCTRegion::setECALData(UCTTowerIndex t, bool ecalFG, uint32_t ecalET) {
0227 UCTGeometry g;
0228 uint32_t nPhi = g.getNPhi(region);
0229 uint32_t absCaloEta = abs(t.first);
0230 uint32_t absCaloPhi = abs(t.second);
0231 uint32_t iEta = g.getiEta(absCaloEta);
0232 uint32_t iPhi = g.getiPhi(absCaloPhi);
0233 std::shared_ptr<UCTTower> tower = towers[iEta * nPhi + iPhi];
0234 return tower->setECALData(ecalFG, ecalET);
0235 }
0236
0237 bool UCTRegion::setHCALData(UCTTowerIndex t, uint32_t hcalFB, uint32_t hcalET) {
0238 UCTGeometry g;
0239 uint32_t nPhi = g.getNPhi(region);
0240 uint32_t absCaloEta = abs(t.first);
0241 uint32_t absCaloPhi = abs(t.second);
0242 uint32_t iEta = g.getiEta(absCaloEta);
0243 uint32_t iPhiStart = g.getiPhi(absCaloPhi);
0244 if (absCaloEta > 29 && absCaloEta < 40) {
0245
0246
0247 for (uint32_t iPhi = iPhiStart; iPhi < iPhiStart + 2; iPhi++) {
0248 std::shared_ptr<UCTTower> tower = towers[iEta * nPhi + iPhi];
0249
0250 if (!tower->setHFData(hcalFB, hcalET))
0251 return false;
0252 }
0253 } else if (absCaloEta == 40 || absCaloEta == 41) {
0254
0255
0256 for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {
0257 std::shared_ptr<UCTTower> tower = towers[iEta * nPhi + iPhi];
0258
0259 if (!tower->setHFData(hcalFB, hcalET))
0260 return false;
0261 }
0262 } else {
0263 uint32_t iPhi = g.getiPhi(absCaloPhi);
0264 std::shared_ptr<UCTTower> tower = towers[iEta * nPhi + iPhi];
0265 return tower->setHCALData(hcalFB, hcalET);
0266 }
0267 return true;
0268 }
0269
0270 bool UCTRegion::setRegionSummary(uint16_t regionData) {
0271
0272 regionSummary = regionData;
0273 return true;
0274 }
0275
0276 std::ostream& operator<<(std::ostream& os, const UCTRegion& r) {
0277 if (r.negativeEta)
0278 os << "UCTRegion Summary for negative eta " << r.region << " HitTower (eta, phi) = (" << std::dec << r.hitCaloEta()
0279 << ", " << r.hitCaloPhi() << ")"
0280 << " summary = " << std::hex << r.regionSummary << std::endl;
0281 else
0282 os << "UCTRegion Summary for positive eta " << r.region << " HitTower (eta, phi) = (" << std::dec << r.hitCaloEta()
0283 << ", " << r.hitCaloPhi() << ")"
0284 << " summary = " << std::hex << r.regionSummary << std::endl;
0285
0286 return os;
0287 }