Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:20:16

0001 #include <iostream>
0002 #include <iomanip>
0003 #include <string>
0004 #include <vector>
0005 #include <cmath>
0006 #include <cstdlib>
0007 #include <cstdint>
0008 
0009 #include "UCTTower.hh"
0010 #include "UCTLogging.hh"
0011 
0012 using namespace l1tcalo;
0013 
0014 bool UCTTower::process() {
0015   if (region >= NRegionsInCard) {
0016     return processHFTower();
0017   }
0018   if (ecalET > etInputMax)
0019     ecalET = etInputMax;
0020   if (hcalET > etInputMax)
0021     hcalET = etInputMax;
0022   uint32_t calibratedECALET = ecalET;
0023   uint32_t logECALET = (uint32_t)log2((double)ecalET);
0024   if (logECALET > erMaxV)
0025     logECALET = erMaxV;
0026   if (ecalLUT != nullptr) {
0027     uint32_t etaAddress = region * NEtaInRegion + iEta;
0028     uint32_t fbAddress = 0;
0029     if (ecalFG)
0030       fbAddress = 1;
0031     uint32_t value = (*ecalLUT)[etaAddress][fbAddress][ecalET];
0032     calibratedECALET = value & etInputMax;
0033     logECALET = (value & 0x7000) >> 12;
0034   }
0035   uint32_t calibratedHCALET = hcalET;
0036   uint32_t logHCALET = (uint32_t)log2((double)hcalET);
0037   if (logHCALET > erMaxV)
0038     logHCALET = erMaxV;
0039   if (hcalLUT != nullptr) {
0040     uint32_t etaAddress = region * NEtaInRegion + iEta;
0041     uint32_t fbAddress = 0;
0042     if ((hcalFB & 0x1) != 0)
0043       fbAddress = 1;
0044     uint32_t value = (*hcalLUT)[etaAddress][fbAddress][hcalET];
0045     calibratedHCALET = value & etInputMax;
0046     logHCALET = (value & 0x7000) >> 12;
0047   }
0048 
0049   // Saturation codes implemented in fwVersion 1
0050   if (fwVersion >= 1) {
0051     if (calibratedECALET == 0xFF && calibratedHCALET == 0xFF)
0052       towerData = 0x1FF;
0053     else if (calibratedECALET == 0xFF)
0054       towerData = 0x1FE;
0055     else if (calibratedHCALET == 0xFF)
0056       towerData = 0x1FD;
0057     else
0058       towerData = calibratedECALET + calibratedHCALET;
0059   } else {
0060     towerData = calibratedECALET + calibratedHCALET;
0061   }
0062 
0063   if (towerData > etMask)
0064     towerData = etMask;
0065   uint32_t er = 0;
0066   if (calibratedECALET == 0 || calibratedHCALET == 0) {
0067     er = 0;
0068     towerData |= zeroFlagMask;
0069     if (calibratedHCALET == 0 && calibratedECALET != 0)
0070       towerData |= eohrFlagMask;
0071   } else if (calibratedECALET == calibratedHCALET) {
0072     er = 0;
0073     towerData |= eohrFlagMask;
0074   } else if (calibratedECALET > calibratedHCALET) {
0075     er = logECALET - logHCALET;
0076     if (er > erMaxV)
0077       er = erMaxV;
0078     towerData |= eohrFlagMask;
0079   } else {
0080     er = logHCALET - logECALET;
0081     if (er > erMaxV)
0082       er = erMaxV;
0083   }
0084   towerData |= (er << erShift);
0085   // Unfortunately, hcalFlag is presently bogus :(
0086   // It has never been studied nor used in Run-1
0087   // The same status persists in Run-2, but it is available usage
0088   // Currently, summarize all hcalFeatureBits in one flag bit
0089   if ((hcalFB & 0x1) != 0)
0090     towerData |= hcalFlagMask;  // FIXME - ignore top bits if(hcalFB != 0)
0091   if (ecalFG)
0092     towerData |= ecalFlagMask;
0093   // Store ecal and hcal calibrated ET in unused upper bits
0094   towerData |= (calibratedECALET << ecalShift);
0095   towerData |= (calibratedHCALET << hcalShift);
0096   // All done!
0097   return true;
0098 }
0099 
0100 bool UCTTower::processHFTower() {
0101   if (fwVersion > 2) {
0102     uint32_t calibratedET = hcalET;
0103     if (hfLUT != nullptr) {
0104       uint32_t etaAddress = (region - NRegionsInCard) * NHFEtaInRegion + iEta;
0105       const std::array<uint32_t, 256>& a = hfLUT->at(etaAddress);
0106       calibratedET = a[hcalET] & 0x1FF;
0107     }
0108     towerData = calibratedET | zeroFlagMask;
0109     if ((hcalFB & 0x1) == 0x1)
0110       towerData |= ecalFlagMask;  // LSB defines short over long fiber ratio
0111     if ((hcalFB & 0x2) == 0x2)
0112       towerData |= hcalFlagMask;  // MSB defines minbias flag
0113   } else {
0114     uint32_t calibratedET = hcalET;
0115     if (hfLUT != nullptr) {
0116       uint32_t etaAddress = (region - NRegionsInCard) * NHFEtaInRegion + iEta;
0117       const std::array<uint32_t, 256>& a = hfLUT->at(etaAddress);
0118       calibratedET = a[hcalET] & 0xFF;
0119     }
0120     uint32_t absCaloEta = abs(caloEta());
0121     if (absCaloEta > 29 && absCaloEta < 40) {
0122       // Divide by two (since two duplicate towers are sent)
0123       calibratedET /= 2;
0124     } else if (absCaloEta == 40 || absCaloEta == 41) {
0125       // Divide by four
0126       calibratedET /= 4;
0127     }
0128     towerData = calibratedET | zeroFlagMask;
0129     if ((hcalFB & 0x1) == 0x1)
0130       towerData |= ecalFlagMask;  // LSB defines short over long fiber ratio
0131     if ((hcalFB & 0x2) == 0x2)
0132       towerData |= hcalFlagMask;  // MSB defines minbias flag
0133   }
0134   return true;
0135 }
0136 
0137 bool UCTTower::setECALData(bool eFG, uint32_t eET) {
0138   ecalFG = eFG;
0139   ecalET = eET;
0140   if (eET > etInputMax) {
0141     LOG_ERROR << "UCTTower::setData - ecalET too high " << eET << "; Pegged to etInputMax" << std::endl;
0142     ecalET = etInputMax;
0143   }
0144   return true;
0145 }
0146 
0147 bool UCTTower::setHCALData(uint32_t hFB, uint32_t hET) {
0148   hcalET = hET;
0149   hcalFB = hFB;
0150   if (hET > etInputMax) {
0151     LOG_ERROR << "UCTTower::setData - hcalET too high " << hET << "; Pegged to etInputMax" << std::endl;
0152     hcalET = etInputMax;
0153   }
0154   if (hFB > 0x3F) {
0155     LOG_ERROR << "UCTTower::setData - too many hcalFeatureBits " << std::hex << hFB << "; Used only bottom 6 bits"
0156               << std::endl;
0157     hcalFB &= 0x3F;
0158   }
0159   return true;
0160 }
0161 
0162 bool UCTTower::setHFData(uint32_t fbIn, uint32_t etIn) {
0163   ecalFG = false;  // HF has no separate ecal section
0164   ecalET = 0;
0165   hcalET = etIn;  // We reuse HCAL place as HF
0166   hcalFB = fbIn;
0167   if (etIn > etInputMax) {
0168     LOG_ERROR << "UCTTower::setData - HF ET too high " << etIn << "; Pegged to etInputMax" << std::endl;
0169     hcalET = etInputMax;
0170   }
0171   if (fbIn > 0x3) {
0172     LOG_ERROR << "UCTTower::setData - too many HF FeatureBits " << std::hex << fbIn << "; Used only bottom 2 bits"
0173               << std::endl;
0174     hcalFB &= 0x3;
0175   }
0176   return true;
0177 }
0178 
0179 const uint16_t UCTTower::location() const {
0180   uint16_t l = 0;
0181   if (negativeEta)
0182     l = 0x8000;        // Used top bit for +/- eta-side
0183   l |= iPhi;           // Max iPhi is 4, so bottom 2 bits for iPhi
0184   l |= (iEta << 2);    // Max iEta is 4, so 2 bits needed
0185   l |= (region << 4);  // Max region number 14, so 4 bits needed
0186   l |= (card << 8);    // Max card number is 6, so 3 bits needed
0187   l |= (crate << 11);  // Max crate number is 2, so 2 bits needed
0188   return l;
0189 }
0190 
0191 UCTTower::UCTTower(uint16_t location, int fwv) : fwVersion(fwv) {
0192   if ((location & 0x8000) != 0)
0193     negativeEta = true;
0194   crate = (location & 0x1800) >> 11;
0195   card = (location & 0x0700) >> 8;
0196   region = (location & 0x00F0) >> 4;
0197   iEta = (location & 0x000C) >> 2;
0198   iPhi = (location & 0x0003);
0199   towerData = 0;
0200 }
0201 
0202 const uint64_t UCTTower::extendedData() const {
0203   uint64_t d = rawData();
0204   uint64_t l = location();
0205   uint64_t r = (l << 48) + d;
0206   return r;
0207 }
0208 
0209 std::ostream& operator<<(std::ostream& os, const UCTTower& t) {
0210   //  if((t.ecalET + t.hcalET) == 0) return os;
0211 
0212   os << "Side Crt  Crd  Rgn  iEta iPhi cEta cPhi eET  eFG  hET  hFB  Summary" << std::endl;
0213 
0214   UCTGeometry g;
0215   std::string side = "+eta ";
0216   if (t.negativeEta)
0217     side = "-eta ";
0218   os << side << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.crate << " "
0219      << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.card << " "
0220      << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.region << " "
0221      << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.iEta << " "
0222      << std::showbase << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.iPhi << " " << std::setw(4)
0223      << std::setfill(' ') << std::dec << g.getCaloEtaIndex(t.negativeEta, t.region, t.iEta) << " " << std::setw(4)
0224      << std::setfill(' ') << std::dec << g.getCaloPhiIndex(t.crate, t.card, t.region, t.iPhi) << " " << std::showbase
0225      << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.ecalET << " " << std::showbase
0226      << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.ecalFG << " " << std::showbase
0227      << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.hcalET << " " << std::showbase
0228      << std::internal << std::setfill('0') << std::setw(4) << std::hex << t.hcalFB << " " << std::showbase
0229      << std::internal << std::setfill('0') << std::setw(10) << std::hex << t.towerData << std::endl;
0230   return os;
0231 }