File indexing completed on 2023-10-25 09:54:47
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(uint32_t crt, uint32_t crd, bool ne, uint32_t rgn, int fwv)
0072 : crate(crt), card(crd), region(rgn), negativeEta(ne), regionSummary(0), fwVersion(fwv) {
0073 UCTGeometry g;
0074 uint32_t nEta = g.getNEta(region);
0075 uint32_t nPhi = g.getNPhi(region);
0076 towers.clear();
0077 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0078 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0079 towers.push_back(new UCTTower(crate, card, ne, region, iEta, iPhi, fwVersion));
0080 }
0081 }
0082 }
0083
0084 UCTRegion::~UCTRegion() {
0085 for (uint32_t i = 0; i < towers.size(); i++) {
0086 if (towers[i] != nullptr)
0087 delete towers[i];
0088 }
0089 }
0090
0091 const UCTTower* UCTRegion::getTower(uint32_t caloEta, uint32_t caloPhi) const {
0092 UCTGeometry g;
0093 uint32_t nPhi = g.getNPhi(region);
0094 uint32_t iEta = g.getiEta(caloEta);
0095 uint32_t iPhi = g.getiPhi(caloPhi);
0096 UCTTower* tower = towers[iEta * nPhi + iPhi];
0097 return tower;
0098 }
0099
0100 bool UCTRegion::process() {
0101
0102 UCTGeometry g;
0103 uint32_t nEta = g.getNEta(region);
0104 uint32_t nPhi = g.getNPhi(region);
0105
0106
0107 uint32_t regionET = 0;
0108 uint32_t regionEcalET = 0;
0109 for (uint32_t twr = 0; twr < towers.size(); twr++) {
0110 if (!towers[twr]->process()) {
0111 LOG_ERROR << "Tower level processing failed. Bailing out :(" << std::endl;
0112 return false;
0113 }
0114 regionET += towers[twr]->et();
0115
0116 regionEcalET += towers[twr]->getEcalET();
0117 }
0118 if (regionET > RegionETMask) {
0119
0120
0121 regionET = RegionETMask;
0122 }
0123 regionSummary = (RegionETMask & regionET);
0124 if (regionEcalET > RegionETMask)
0125 regionEcalET = RegionETMask;
0126
0127
0128
0129 if (region < NRegionsInCard) {
0130
0131
0132 bool activeTower[nEta][nPhi];
0133 uint32_t activityLevel = ((uint32_t)((float)regionET) * activityFraction);
0134 uint32_t activeTowerET = 0;
0135 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0136 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0137 uint32_t towerET = towers[iEta * nPhi + iPhi]->et();
0138 if (towerET > activityLevel) {
0139 activeTower[iEta][iPhi] = true;
0140 activeTowerET += towers[iEta * nPhi + iPhi]->et();
0141 } else
0142 activeTower[iEta][iPhi] = false;
0143 }
0144 }
0145 if (activeTowerET > RegionETMask)
0146 activeTowerET = RegionETMask;
0147
0148 uint32_t sumETIEta[4] = {0, 0, 0, 0};
0149 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0150 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0151 uint32_t towerET = towers[iEta * nPhi + iPhi]->et();
0152 sumETIEta[iEta] += towerET;
0153 }
0154 }
0155 uint32_t hitIEta = getHitTowerLocation(sumETIEta);
0156 uint32_t sumETIPhi[4] = {0, 0, 0, 0};
0157 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0158 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0159 uint32_t towerET = towers[iEta * nPhi + iPhi]->et();
0160 sumETIPhi[iPhi] += towerET;
0161 }
0162 }
0163 uint32_t hitIPhi = getHitTowerLocation(sumETIPhi);
0164 uint32_t hitTowerLocation = hitIEta * nPhi + hitIPhi;
0165
0166 bitset<4> activeTowerEtaPattern = 0;
0167 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0168 bool activeStrip = false;
0169 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0170 if (activeTower[iEta][iPhi])
0171 activeStrip = true;
0172 }
0173 if (activeStrip)
0174 activeTowerEtaPattern |= (0x1 << iEta);
0175 }
0176 bitset<4> activeTowerPhiPattern = 0;
0177 for (uint32_t iPhi = 0; iPhi < nPhi; iPhi++) {
0178 bool activeStrip = false;
0179 for (uint32_t iEta = 0; iEta < nEta; iEta++) {
0180 if (activeTower[iEta][iPhi])
0181 activeStrip = true;
0182 }
0183 if (activeStrip)
0184 activeTowerPhiPattern |= (0x1 << iPhi);
0185 }
0186
0187 bool veto = vetoBit(activeTowerEtaPattern, activeTowerPhiPattern);
0188 bool egVeto = veto;
0189 bool tauVeto = veto;
0190 uint32_t maxMiscActivityLevelForEG = ((uint32_t)((float)regionET) * ecalActivityFraction);
0191 uint32_t maxMiscActivityLevelForTau = ((uint32_t)((float)regionET) * miscActivityFraction);
0192 if ((regionET - regionEcalET) > maxMiscActivityLevelForEG)
0193 egVeto = true;
0194 if ((regionET - activeTowerET) > maxMiscActivityLevelForTau)
0195 tauVeto = true;
0196
0197 if (egVeto)
0198 regionSummary |= RegionEGVeto;
0199 if (tauVeto)
0200 regionSummary |= RegionTauVeto;
0201
0202 regionSummary |= (hitTowerLocation << LocationShift);
0203
0204
0205
0206 if (negativeEta)
0207 regionSummary |= NegEtaBit;
0208 regionSummary |= (region << RegionNoShift);
0209 regionSummary |= (card << CardNoShift);
0210 regionSummary |= (crate << CrateNoShift);
0211 }
0212
0213 return true;
0214 }
0215
0216 bool UCTRegion::clearEvent() {
0217 regionSummary = 0;
0218 for (uint32_t i = 0; i < towers.size(); i++) {
0219 if (!towers[i]->clearEvent())
0220 return false;
0221 }
0222 return true;
0223 }
0224
0225 bool UCTRegion::setECALData(UCTTowerIndex t, bool ecalFG, uint32_t ecalET) {
0226 UCTGeometry g;
0227 uint32_t nPhi = g.getNPhi(region);
0228 uint32_t absCaloEta = abs(t.first);
0229 uint32_t absCaloPhi = abs(t.second);
0230 uint32_t iEta = g.getiEta(absCaloEta);
0231 uint32_t iPhi = g.getiPhi(absCaloPhi);
0232 UCTTower* tower = towers[iEta * nPhi + iPhi];
0233 return tower->setECALData(ecalFG, ecalET);
0234 }
0235
0236 bool UCTRegion::setHCALData(UCTTowerIndex t, uint32_t hcalFB, uint32_t hcalET) {
0237 UCTGeometry g;
0238 uint32_t nPhi = g.getNPhi(region);
0239 uint32_t absCaloEta = abs(t.first);
0240 uint32_t absCaloPhi = abs(t.second);
0241 uint32_t iEta = g.getiEta(absCaloEta);
0242 uint32_t iPhiStart = g.getiPhi(absCaloPhi);
0243 if (absCaloEta > 29 && absCaloEta < 40) {
0244
0245
0246 for (uint32_t iPhi = iPhiStart; iPhi < iPhiStart + 2; iPhi++) {
0247 UCTTower* tower = towers[iEta * nPhi + iPhi];
0248
0249 if (!tower->setHFData(hcalFB, hcalET))
0250 return false;
0251 }
0252 } else if (absCaloEta == 40 || absCaloEta == 41) {
0253
0254
0255 for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {
0256 UCTTower* tower = towers[iEta * nPhi + iPhi];
0257
0258 if (!tower->setHFData(hcalFB, hcalET))
0259 return false;
0260 }
0261 } else {
0262 uint32_t iPhi = g.getiPhi(absCaloPhi);
0263 UCTTower* tower = towers[iEta * nPhi + iPhi];
0264 return tower->setHCALData(hcalFB, hcalET);
0265 }
0266 return true;
0267 }
0268
0269 bool UCTRegion::setRegionSummary(uint16_t regionData) {
0270
0271 regionSummary = regionData;
0272 return true;
0273 }
0274
0275 std::ostream& operator<<(std::ostream& os, const UCTRegion& r) {
0276 if (r.negativeEta)
0277 os << "UCTRegion Summary for negative eta " << r.region << " HitTower (eta, phi) = (" << std::dec << r.hitCaloEta()
0278 << ", " << r.hitCaloPhi() << ")"
0279 << " summary = " << std::hex << r.regionSummary << std::endl;
0280 else
0281 os << "UCTRegion Summary for positive eta " << r.region << " HitTower (eta, phi) = (" << std::dec << r.hitCaloEta()
0282 << ", " << r.hitCaloPhi() << ")"
0283 << " summary = " << std::hex << r.regionSummary << std::endl;
0284
0285 return os;
0286 }