Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-06 03:13:01

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/L1TCaloLayer1
0004 // Class:      L1TCaloLayer1
0005 //
0006 /**\class L1TCaloLayer1 L1TCaloLayer1.cc L1Trigger/L1TCaloLayer1/plugins/L1TCaloLayer1.cc
0007 
0008    Description: [one line class summary]
0009 
0010    Implementation:
0011    [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Sridhara Rao Dasu
0015 //         Created:  Thu, 08 Oct 2015 09:20:16 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 
0022 // user include files
0023 #include "FWCore/Framework/interface/Frameworkfwd.h"
0024 #include "FWCore/Framework/interface/stream/EDProducer.h"
0025 
0026 #include "FWCore/Framework/interface/Event.h"
0027 #include "FWCore/Framework/interface/MakerMacros.h"
0028 
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030 
0031 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
0032 #include "DataFormats/HcalDigi/interface/HcalDigiCollections.h"
0033 
0034 #include "L1Trigger/L1TCaloLayer1/src/UCTLayer1.hh"
0035 #include "L1Trigger/L1TCaloLayer1/src/UCTCrate.hh"
0036 #include "L1Trigger/L1TCaloLayer1/src/UCTCard.hh"
0037 #include "L1Trigger/L1TCaloLayer1/src/UCTRegion.hh"
0038 #include "L1Trigger/L1TCaloLayer1/src/UCTTower.hh"
0039 
0040 #include "L1Trigger/L1TCaloLayer1/src/UCTGeometry.hh"
0041 #include "L1Trigger/L1TCaloLayer1/src/UCTLogging.hh"
0042 
0043 #include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
0044 #include "DataFormats/L1CaloTrigger/interface/L1CaloCollections.h"
0045 #include "DataFormats/L1CaloTrigger/interface/L1CaloRegion.h"
0046 
0047 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0048 
0049 #include "L1Trigger/L1TCaloLayer1/src/L1TCaloLayer1FetchLUTs.hh"
0050 
0051 using namespace l1t;
0052 using namespace l1tcalo;
0053 
0054 //
0055 // class declaration
0056 //
0057 
0058 class L1TCaloLayer1 : public edm::stream::EDProducer<> {
0059 public:
0060   explicit L1TCaloLayer1(const edm::ParameterSet&);
0061 
0062   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0063 
0064 private:
0065   void produce(edm::Event&, const edm::EventSetup&) override;
0066 
0067   void beginRun(edm::Run const&, edm::EventSetup const&) override;
0068 
0069   //virtual void endRun(edm::Run const&, edm::EventSetup const&) override;
0070   //virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0071   //virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0072 
0073   // ----------member data ---------------------------
0074 
0075   edm::EDGetTokenT<EcalTrigPrimDigiCollection> ecalTPSource;
0076   edm::EDGetTokenT<HcalTrigPrimDigiCollection> hcalTPSource;
0077   edm::EDPutTokenT<CaloTowerBxCollection> towerPutToken;
0078   edm::EDPutTokenT<L1CaloRegionCollection> regionPutToken;
0079   const L1TCaloLayer1FetchLUTsTokens lutsTokens;
0080 
0081   std::vector<std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> > ecalLUT;
0082   std::vector<std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> > hcalLUT;
0083   std::vector<std::array<std::array<uint32_t, nEtBins>, nHfEtaBins> > hfLUT;
0084 
0085   std::vector<unsigned int> ePhiMap;
0086   std::vector<unsigned int> hPhiMap;
0087   std::vector<unsigned int> hfPhiMap;
0088 
0089   std::vector<UCTTower*> twrList;
0090 
0091   bool useLSB;
0092   bool useCalib;
0093   bool useECALLUT;
0094   bool useHCALLUT;
0095   bool useHFLUT;
0096   bool verbose;
0097   bool unpackHcalMask;
0098   bool unpackEcalMask;
0099   int fwVersion;
0100 
0101   std::unique_ptr<UCTLayer1> layer1;
0102 };
0103 
0104 //
0105 // constants, enums and typedefs
0106 //
0107 
0108 //
0109 // static data member definitions
0110 //
0111 
0112 //
0113 // constructors and destructor
0114 //
0115 L1TCaloLayer1::L1TCaloLayer1(const edm::ParameterSet& iConfig)
0116     : ecalTPSource(consumes<EcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalToken"))),
0117       hcalTPSource(consumes<HcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("hcalToken"))),
0118       towerPutToken{produces<CaloTowerBxCollection>()},
0119       regionPutToken{produces<L1CaloRegionCollection>()},
0120       lutsTokens{esConsumes<edm::Transition::BeginRun>(),
0121                  esConsumes<edm::Transition::BeginRun>(),
0122                  esConsumes<edm::Transition::BeginRun>()},
0123       ePhiMap(72 * 2, 0),
0124       hPhiMap(72 * 2, 0),
0125       hfPhiMap(72 * 2, 0),
0126       useLSB(iConfig.getParameter<bool>("useLSB")),
0127       useCalib(iConfig.getParameter<bool>("useCalib")),
0128       useECALLUT(iConfig.getParameter<bool>("useECALLUT")),
0129       useHCALLUT(iConfig.getParameter<bool>("useHCALLUT")),
0130       useHFLUT(iConfig.getParameter<bool>("useHFLUT")),
0131       verbose(iConfig.getParameter<bool>("verbose")),
0132       unpackHcalMask(iConfig.getParameter<bool>("unpackHcalMask")),
0133       unpackEcalMask(iConfig.getParameter<bool>("unpackEcalMask")),
0134       fwVersion(iConfig.getParameter<int>("firmwareVersion")) {
0135   // See UCTLayer1.hh for firmware version definitions
0136   layer1 = std::make_unique<UCTLayer1>(fwVersion);
0137 
0138   vector<UCTCrate*> crates = layer1->getCrates();
0139   for (uint32_t crt = 0; crt < crates.size(); crt++) {
0140     vector<UCTCard*> cards = crates[crt]->getCards();
0141     for (uint32_t crd = 0; crd < cards.size(); crd++) {
0142       vector<UCTRegion*> regions = cards[crd]->getRegions();
0143       for (uint32_t rgn = 0; rgn < regions.size(); rgn++) {
0144         vector<UCTTower*> towers = regions[rgn]->getTowers();
0145         for (uint32_t twr = 0; twr < towers.size(); twr++) {
0146           twrList.push_back(towers[twr]);
0147         }
0148       }
0149     }
0150   }
0151 
0152   // This sort corresponds to the sort condition on
0153   // the output CaloTowerBxCollection
0154   std::sort(twrList.begin(), twrList.end(), [](UCTTower* a, UCTTower* b) {
0155     return CaloTools::caloTowerHash(a->caloEta(), a->caloPhi()) < CaloTools::caloTowerHash(b->caloEta(), b->caloPhi());
0156   });
0157 }
0158 
0159 //
0160 // member functions
0161 //
0162 
0163 // ------------ method called to produce the data  ------------
0164 void L1TCaloLayer1::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0165   using namespace edm;
0166 
0167   edm::Handle<EcalTrigPrimDigiCollection> ecalTPs;
0168   iEvent.getByToken(ecalTPSource, ecalTPs);
0169   edm::Handle<HcalTrigPrimDigiCollection> hcalTPs;
0170   iEvent.getByToken(hcalTPSource, hcalTPs);
0171 
0172   CaloTowerBxCollection towersColl;
0173   L1CaloRegionCollection rgnCollection;
0174 
0175   uint32_t expectedTotalET = 0;
0176   if (!layer1->clearEvent()) {
0177     LOG_ERROR << "UCT: Failed to clear event" << std::endl;
0178     return;
0179   }
0180 
0181   for (const auto& ecalTp : *ecalTPs) {
0182     if (unpackEcalMask && ((ecalTp.sample(0).raw() >> 13) & 0x1))
0183       continue;
0184     int caloEta = ecalTp.id().ieta();
0185     int caloPhi = ecalTp.id().iphi();
0186     int et = ecalTp.compressedEt();
0187     bool fgVeto = ecalTp.fineGrain();
0188     UCTTowerIndex t = UCTTowerIndex(caloEta, caloPhi);
0189     if (!layer1->setECALData(t, fgVeto, et)) {
0190       LOG_ERROR << "UCT: Failed loading an ECAL tower" << std::endl;
0191       return;
0192     }
0193     expectedTotalET += et;
0194   }
0195 
0196   if (hcalTPs.isValid()) {
0197     for (const auto& hcalTp : *hcalTPs) {
0198       if (unpackHcalMask && ((hcalTp.sample(0).raw() >> 13) & 0x1))
0199         continue;
0200       int caloEta = hcalTp.id().ieta();
0201       uint32_t absCaloEta = std::abs(caloEta);
0202       // Tower 29 is not used by Layer-1
0203       if (absCaloEta == 29) {
0204         continue;
0205       }
0206       // Prevent usage of HF TPs with Layer-1 emulator if HCAL TPs are old style
0207       else if (hcalTp.id().version() == 0 && absCaloEta > 29) {
0208         continue;
0209       } else if (absCaloEta <= 41) {
0210         int caloPhi = hcalTp.id().iphi();
0211         int et = hcalTp.SOI_compressedEt();
0212         bool fg = hcalTp.t0().fineGrain(0);   // depth
0213         bool fg2 = hcalTp.t0().fineGrain(1);  // prompt
0214         bool fg3 = hcalTp.t0().fineGrain(2);  // delay 1
0215         bool fg4 = hcalTp.t0().fineGrain(3);  // delay 2
0216         // note that hcalTp.t0().fineGrain(4) and hcalTp.t0().fineGrain(5) are the reserved MIP bits (not used for LLP logic)
0217         if (caloPhi <= 72) {
0218           UCTTowerIndex t = UCTTowerIndex(caloEta, caloPhi);
0219           uint32_t featureBits = 0;
0220           if (absCaloEta > 29) {
0221             if (fg)
0222               featureBits |= 0b01;
0223             // fg2 should only be set for HF
0224             if (fg2)
0225               featureBits |= 0b10;
0226           } else if (absCaloEta < 16)
0227             featureBits |= (fg | ((!fg2) & (fg3 | fg4)));  // depth | (!prompt & (delay1 | delay2))
0228           if (!layer1->setHCALData(t, featureBits, et)) {
0229             LOG_ERROR << "caloEta = " << caloEta << "; caloPhi =" << caloPhi << std::endl;
0230             LOG_ERROR << "UCT: Failed loading an HCAL tower" << std::endl;
0231             return;
0232           }
0233           expectedTotalET += et;
0234         } else {
0235           LOG_ERROR << "Illegal Tower: caloEta = " << caloEta << "; caloPhi =" << caloPhi << "; et = " << et
0236                     << std::endl;
0237         }
0238       } else {
0239         LOG_ERROR << "Illegal Tower: caloEta = " << caloEta << std::endl;
0240       }
0241     }
0242   }
0243 
0244   //Process
0245   if (!layer1->process()) {
0246     LOG_ERROR << "UCT: Failed to process layer 1" << std::endl;
0247   }
0248 
0249   int theBX = 0;  // Currently we only read and process the "hit" BX only
0250 
0251   for (uint32_t twr = 0; twr < twrList.size(); twr++) {
0252     CaloTower caloTower;
0253     caloTower.setHwPt(twrList[twr]->et());          // Bits 0-8 of the 16-bit word per the interface protocol document
0254     caloTower.setHwEtRatio(twrList[twr]->er());     // Bits 9-11 of the 16-bit word per the interface protocol document
0255     caloTower.setHwQual(twrList[twr]->miscBits());  // Bits 12-15 of the 16-bit word per the interface protocol document
0256     caloTower.setHwEta(twrList[twr]->caloEta());    // caloEta = 1-28 and 30-41
0257     caloTower.setHwPhi(twrList[twr]->caloPhi());    // caloPhi = 1-72
0258     caloTower.setHwEtEm(twrList[twr]->getEcalET());   // This is provided as a courtesy - not available to hardware
0259     caloTower.setHwEtHad(twrList[twr]->getHcalET());  // This is provided as a courtesy - not available to hardware
0260     towersColl.push_back(theBX, caloTower);
0261   }
0262 
0263   iEvent.emplace(towerPutToken, std::move(towersColl));
0264 
0265   UCTGeometry g;
0266   vector<UCTCrate*> crates = layer1->getCrates();
0267   for (uint32_t crt = 0; crt < crates.size(); crt++) {
0268     vector<UCTCard*> cards = crates[crt]->getCards();
0269     for (uint32_t crd = 0; crd < cards.size(); crd++) {
0270       vector<UCTRegion*> regions = cards[crd]->getRegions();
0271       for (uint32_t rgn = 0; rgn < regions.size(); rgn++) {
0272         uint32_t rawData = regions[rgn]->rawData();
0273         uint32_t regionData = rawData & 0x0000FFFF;
0274         uint32_t crate = regions[rgn]->getCrate();
0275         uint32_t card = regions[rgn]->getCard();
0276         uint32_t region = regions[rgn]->getRegion();
0277         bool negativeEta = regions[rgn]->isNegativeEta();
0278         uint32_t rPhi = g.getUCTRegionPhiIndex(crate, card);
0279         if (region < NRegionsInCard) {  // We only store the Barrel and Endcap - HF has changed in the upgrade
0280           uint32_t rEta =
0281               10 -
0282               region;  // UCT region is 0-6 for B/E but GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0283           if (!negativeEta)
0284             rEta = 11 + region;  // Positive eta portion is offset by 11
0285           rgnCollection.push_back(L1CaloRegion((uint16_t)regionData, (unsigned)rEta, (unsigned)rPhi, (int16_t)0));
0286         }
0287       }
0288     }
0289   }
0290   iEvent.emplace(regionPutToken, std::move(rgnCollection));
0291 }
0292 
0293 // ------------ method called when starting to processes a run  ------------
0294 void L1TCaloLayer1::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
0295   if (!L1TCaloLayer1FetchLUTs(lutsTokens,
0296                               iSetup,
0297                               ecalLUT,
0298                               hcalLUT,
0299                               hfLUT,
0300                               ePhiMap,
0301                               hPhiMap,
0302                               hfPhiMap,
0303                               useLSB,
0304                               useCalib,
0305                               useECALLUT,
0306                               useHCALLUT,
0307                               useHFLUT,
0308                               fwVersion)) {
0309     LOG_ERROR << "L1TCaloLayer1::beginRun: failed to fetch LUTS - using unity" << std::endl;
0310     std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> eCalLayer1EtaSideEtArray;
0311     std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> hCalLayer1EtaSideEtArray;
0312     std::array<std::array<uint32_t, nEtBins>, nHfEtaBins> hfLayer1EtaEtArray;
0313     ecalLUT.push_back(eCalLayer1EtaSideEtArray);
0314     hcalLUT.push_back(hCalLayer1EtaSideEtArray);
0315     hfLUT.push_back(hfLayer1EtaEtArray);
0316   }
0317   for (uint32_t twr = 0; twr < twrList.size(); twr++) {
0318     // Map goes minus 1 .. 72 plus 1 .. 72 -> 0 .. 143
0319     int iphi = twrList[twr]->caloPhi();
0320     int ieta = twrList[twr]->caloEta();
0321     if (ieta < 0) {
0322       iphi -= 1;
0323     } else {
0324       iphi += 71;
0325     }
0326     twrList[twr]->setECALLUT(&ecalLUT[ePhiMap[iphi]]);
0327     twrList[twr]->setHCALLUT(&hcalLUT[hPhiMap[iphi]]);
0328     twrList[twr]->setHFLUT(&hfLUT[hfPhiMap[iphi]]);
0329   }
0330 }
0331 
0332 // ------------ method called when ending the processing of a run  ------------
0333 /*
0334   void
0335   L1TCaloLayer1::endRun(edm::Run const&, edm::EventSetup const&)
0336   {
0337   }
0338 */
0339 
0340 // ------------ method called when starting to processes a luminosity block  ------------
0341 /*
0342   void
0343   L1TCaloLayer1::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0344   {
0345   }
0346 */
0347 
0348 // ------------ method called when ending the processing of a luminosity block  ------------
0349 /*
0350   void
0351   L1TCaloLayer1::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0352   {
0353   }
0354 */
0355 
0356 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0357 void L1TCaloLayer1::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0358   //The following says we do not know what parameters are allowed so do no validation
0359   // Please change this to state exactly what you do use, even if it is no parameters
0360   edm::ParameterSetDescription desc;
0361   desc.setUnknown();
0362   descriptions.addDefault(desc);
0363 }
0364 
0365 //define this as a plug-in
0366 DEFINE_FWK_MODULE(L1TCaloLayer1);
0367 /* vim: set ts=8 sw=2 tw=0 et :*/