Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:49

0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "EventFilter/L1TRawToDigi/plugins/PackerFactory.h"
0003 
0004 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0005 
0006 #include "CaloLayer1Packer.h"
0007 
0008 namespace l1t {
0009   namespace stage2 {
0010 
0011     // max_iEta_HcalTP = 41; // barrel <= 16, endcap <= 28, hf <= 41
0012     // there are two TT29’s: one in HE readout in TT28 and another in HF readout in TT30
0013     // max_iPhi_HcalTP = 72;
0014 
0015     Blocks CaloLayer1Packer::pack(const edm::Event& event, const PackerTokens* toks) {
0016       edm::Handle<EcalTrigPrimDigiCollection> ecalDigis;
0017       event.getByToken(static_cast<const CaloLayer1Tokens*>(toks)->getEcalDigiToken(), ecalDigis);
0018       edm::Handle<HcalTrigPrimDigiCollection> hcalDigis;
0019       event.getByToken(static_cast<const CaloLayer1Tokens*>(toks)->getHcalDigiToken(), hcalDigis);
0020       edm::Handle<L1CaloRegionCollection> caloRegions;
0021       event.getByToken(static_cast<const CaloLayer1Tokens*>(toks)->getCaloRegionToken(), caloRegions);
0022 
0023       std::vector<uint32_t> load;
0024       load.resize(192, 0u);
0025 
0026       auto ctp7_phi = board();
0027       uint32_t* ptr = load.data();
0028       UCTCTP7RawData ctp7Data(ptr);
0029       makeECalTPGs(ctp7_phi, ctp7Data, ecalDigis.product());
0030       makeHCalTPGs(ctp7_phi, ctp7Data, hcalDigis.product());
0031       makeHFTPGs(ctp7_phi, ctp7Data, hcalDigis.product());
0032       makeRegions(ctp7_phi, ctp7Data, caloRegions.product());
0033 
0034       unsigned bx_per_l1a = 1;
0035       // CTP7 uses CMS scheme, starting at 0
0036       // TODO: expected +2, but +1 apparently?
0037       unsigned calo_bxid = (event.bunchCrossing() + 1) % 3564;
0038 
0039       // a la CTP7Payload::getHeader()
0040       unsigned blockId = 0;
0041       unsigned blockSize = 192;
0042       unsigned capId = 0;
0043       unsigned blockFlags = ((bx_per_l1a & 0xf) << 16) | (calo_bxid & 0xfff);
0044       BlockHeader hdr(blockId, blockSize, capId, blockFlags, CTP7);
0045       Block block(hdr, &*load.begin(), &*load.end());
0046 
0047       Blocks res;
0048       res.push_back(block);
0049       return res;
0050     }
0051 
0052     void CaloLayer1Packer::makeECalTPGs(uint32_t lPhi,
0053                                         UCTCTP7RawData& ctp7Data,
0054                                         const EcalTrigPrimDigiCollection* ecalTPGs) {
0055       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::EBEE;
0056       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0057         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0058         if (cPhi == 0)
0059           cPhi = 72;
0060         else if (cPhi == -1)
0061           cPhi = 71;
0062         else if (cPhi < -1) {
0063           edm::LogError("CaloLayer1Packer") << "Major error in makeECalTPGs" << std::endl;
0064           return;
0065         }
0066         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0067           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0068             bool negativeEta = false;
0069             if (cEta < 0)
0070               negativeEta = true;
0071             uint32_t iEta = abs(cEta);
0072 
0073             int zSide = cEta / ((int)iEta);
0074             const EcalSubdetector ecalTriggerTower =
0075                 (iEta > 17) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
0076             EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
0077             const auto& tp = ecalTPGs->find(id);
0078             if (tp != ecalTPGs->end()) {
0079               ctp7Data.setET(cType, negativeEta, iEta, iPhi, tp->compressedEt());
0080               ctp7Data.setFB(cType, negativeEta, iEta, iPhi, tp->fineGrain());
0081             }
0082           }
0083         }
0084       }
0085     }
0086 
0087     void CaloLayer1Packer::makeHCalTPGs(uint32_t lPhi,
0088                                         UCTCTP7RawData& ctp7Data,
0089                                         const HcalTrigPrimDigiCollection* hcalTPGs) {
0090       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::HBHE;
0091       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0092         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0093         if (cPhi == 0)
0094           cPhi = 72;
0095         else if (cPhi == -1)
0096           cPhi = 71;
0097         else if (cPhi < -1) {
0098           edm::LogError("CaloLayer1Packer") << "Major error in makeHCalTPGs" << std::endl;
0099           return;
0100         }
0101         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0102           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0103             bool negativeEta = false;
0104             if (cEta < 0)
0105               negativeEta = true;
0106             uint32_t iEta = abs(cEta);
0107 
0108             HcalTrigTowerDetId id(cEta, cPhi);
0109             const auto tp = hcalTPGs->find(id);
0110 
0111             if (tp != hcalTPGs->end()) {
0112               uint32_t fg_bits = 0;
0113               for (int index = 0; index < 6; index++)
0114                 fg_bits |= tp->SOI_fineGrain(index) << index;
0115 
0116               ctp7Data.setET(cType, negativeEta, iEta, iPhi, tp->SOI_compressedEt());
0117               ctp7Data.setFB(cType, negativeEta, iEta, iPhi, fg_bits);
0118             }
0119           }
0120         }
0121       }
0122     }
0123 
0124     void CaloLayer1Packer::makeHFTPGs(uint32_t lPhi,
0125                                       UCTCTP7RawData& ctp7Data,
0126                                       const HcalTrigPrimDigiCollection* hcalTPGs) {
0127       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::HF;
0128       for (uint32_t side = 0; side <= 1; side++) {
0129         bool negativeEta = false;
0130         if (side == 0)
0131           negativeEta = true;
0132         for (uint32_t iEta = 30; iEta <= 40; iEta++) {
0133           for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
0134             if (iPhi == 1 && iEta == 40)
0135               iEta = 41;
0136             int cPhi = 1 + lPhi * 4 + iPhi * 2;  // Calorimeter phi index: 1, 3, 5, ... 71
0137             if (iEta == 41)
0138               cPhi -= 2;                  // Last two HF are 3, 7, 11, ...
0139             cPhi = (cPhi + 69) % 72 + 1;  // cPhi -= 2 mod 72
0140             int cEta = iEta;
0141             if (negativeEta)
0142               cEta = -iEta;
0143 
0144             HcalTrigTowerDetId id(cEta, cPhi);
0145             id.setVersion(1);  // To not process these 1x1 HF TPGs with RCT
0146             const auto tp = hcalTPGs->find(id);
0147             if (tp != hcalTPGs->end()) {
0148               ctp7Data.setET(cType, negativeEta, iEta, iPhi, tp->SOI_compressedEt());
0149               ctp7Data.setFB(cType, negativeEta, iEta, iPhi, ((tp->SOI_fineGrain(1) << 1) | tp->SOI_fineGrain(0)));
0150             }
0151           }
0152         }
0153       }
0154     }
0155 
0156     void CaloLayer1Packer::makeRegions(uint32_t lPhi, UCTCTP7RawData& ctp7Data, const L1CaloRegionCollection* regions) {
0157       for (uint32_t side = 0; side <= 1; side++) {
0158         bool negativeEta = false;
0159         if (side == 0)
0160           negativeEta = true;
0161         for (uint32_t region = 0; region <= 6; region++) {
0162           uint32_t lEta = 10 - region;  // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0163           if (!negativeEta)
0164             lEta = region + 11;
0165 
0166           L1CaloRegionDetId id(lEta, lPhi);
0167           // Can't use find since not an edm::SortedCollection
0168           // const L1CaloRegion& rtp = *regions->find(id);
0169           for (const auto& rtp : *regions) {
0170             if (rtp.id() == id) {
0171               ctp7Data.setRegionSummary(negativeEta, region, rtp.raw());
0172               break;
0173             }
0174           }
0175         }
0176       }
0177     }
0178 
0179   }  // namespace stage2
0180 }  // namespace l1t
0181 
0182 DEFINE_L1T_PACKER(l1t::stage2::CaloLayer1Packer);