Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-01-16 23:37:02

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   if (!layer1->clearEvent()) {
0176     LOG_ERROR << "UCT: Failed to clear event" << std::endl;
0177     return;
0178   }
0179 
0180   for (const auto& ecalTp : *ecalTPs) {
0181     if (unpackEcalMask && ((ecalTp.sample(0).raw() >> 13) & 0x1))
0182       continue;
0183     int caloEta = ecalTp.id().ieta();
0184     int caloPhi = ecalTp.id().iphi();
0185     int et = ecalTp.compressedEt();
0186     bool fgVeto = ecalTp.fineGrain();
0187     UCTTowerIndex t = UCTTowerIndex(caloEta, caloPhi);
0188     if (!layer1->setECALData(t, fgVeto, et)) {
0189       LOG_ERROR << "UCT: Failed loading an ECAL tower" << std::endl;
0190       return;
0191     }
0192   }
0193 
0194   if (hcalTPs.isValid()) {
0195     for (const auto& hcalTp : *hcalTPs) {
0196       if (unpackHcalMask && ((hcalTp.sample(0).raw() >> 13) & 0x1))
0197         continue;
0198       int caloEta = hcalTp.id().ieta();
0199       uint32_t absCaloEta = std::abs(caloEta);
0200       // Tower 29 is not used by Layer-1
0201       if (absCaloEta == 29) {
0202         continue;
0203       }
0204       // Prevent usage of HF TPs with Layer-1 emulator if HCAL TPs are old style
0205       else if (hcalTp.id().version() == 0 && absCaloEta > 29) {
0206         continue;
0207       } else if (absCaloEta <= 41) {
0208         int caloPhi = hcalTp.id().iphi();
0209         int et = hcalTp.SOI_compressedEt();
0210         bool fg = hcalTp.t0().fineGrain(0);   // depth
0211         bool fg2 = hcalTp.t0().fineGrain(1);  // prompt
0212         bool fg3 = hcalTp.t0().fineGrain(2);  // delay 1
0213         bool fg4 = hcalTp.t0().fineGrain(3);  // delay 2
0214         // note that hcalTp.t0().fineGrain(4) and hcalTp.t0().fineGrain(5) are the reserved MIP bits (not used for LLP logic)
0215         if (caloPhi <= 72) {
0216           UCTTowerIndex t = UCTTowerIndex(caloEta, caloPhi);
0217           uint32_t featureBits = 0;
0218           if (absCaloEta > 29) {
0219             if (fg)
0220               featureBits |= 0b01;
0221             // fg2 should only be set for HF
0222             if (fg2)
0223               featureBits |= 0b10;
0224           } else if (absCaloEta < 16)
0225             featureBits |= (fg | ((!fg2) & (fg3 | fg4)));  // depth | (!prompt & (delay1 | delay2))
0226           if (!layer1->setHCALData(t, featureBits, et)) {
0227             LOG_ERROR << "caloEta = " << caloEta << "; caloPhi =" << caloPhi << std::endl;
0228             LOG_ERROR << "UCT: Failed loading an HCAL tower" << std::endl;
0229             return;
0230           }
0231         } else {
0232           LOG_ERROR << "Illegal Tower: caloEta = " << caloEta << "; caloPhi =" << caloPhi << "; et = " << et
0233                     << std::endl;
0234         }
0235       } else {
0236         LOG_ERROR << "Illegal Tower: caloEta = " << caloEta << std::endl;
0237       }
0238     }
0239   }
0240 
0241   //Process
0242   if (!layer1->process()) {
0243     LOG_ERROR << "UCT: Failed to process layer 1" << std::endl;
0244   }
0245 
0246   int theBX = 0;  // Currently we only read and process the "hit" BX only
0247 
0248   for (uint32_t twr = 0; twr < twrList.size(); twr++) {
0249     CaloTower caloTower;
0250     caloTower.setHwPt(twrList[twr]->et());          // Bits 0-8 of the 16-bit word per the interface protocol document
0251     caloTower.setHwEtRatio(twrList[twr]->er());     // Bits 9-11 of the 16-bit word per the interface protocol document
0252     caloTower.setHwQual(twrList[twr]->miscBits());  // Bits 12-15 of the 16-bit word per the interface protocol document
0253     caloTower.setHwEta(twrList[twr]->caloEta());    // caloEta = 1-28 and 30-41
0254     caloTower.setHwPhi(twrList[twr]->caloPhi());    // caloPhi = 1-72
0255     caloTower.setHwEtEm(twrList[twr]->getEcalET());   // This is provided as a courtesy - not available to hardware
0256     caloTower.setHwEtHad(twrList[twr]->getHcalET());  // This is provided as a courtesy - not available to hardware
0257     towersColl.push_back(theBX, caloTower);
0258   }
0259 
0260   iEvent.emplace(towerPutToken, std::move(towersColl));
0261 
0262   UCTGeometry g;
0263   vector<UCTCrate*> crates = layer1->getCrates();
0264   for (uint32_t crt = 0; crt < crates.size(); crt++) {
0265     vector<UCTCard*> cards = crates[crt]->getCards();
0266     for (uint32_t crd = 0; crd < cards.size(); crd++) {
0267       vector<UCTRegion*> regions = cards[crd]->getRegions();
0268       for (uint32_t rgn = 0; rgn < regions.size(); rgn++) {
0269         uint32_t rawData = regions[rgn]->rawData();
0270         uint32_t regionData = rawData & 0x0000FFFF;
0271         uint32_t crate = regions[rgn]->getCrate();
0272         uint32_t card = regions[rgn]->getCard();
0273         uint32_t region = regions[rgn]->getRegion();
0274         bool negativeEta = regions[rgn]->isNegativeEta();
0275         uint32_t rPhi = g.getUCTRegionPhiIndex(crate, card);
0276         if (region < NRegionsInCard) {  // We only store the Barrel and Endcap - HF has changed in the upgrade
0277           uint32_t rEta =
0278               10 -
0279               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
0280           if (!negativeEta)
0281             rEta = 11 + region;  // Positive eta portion is offset by 11
0282           rgnCollection.push_back(L1CaloRegion((uint16_t)regionData, (unsigned)rEta, (unsigned)rPhi, (int16_t)0));
0283         }
0284       }
0285     }
0286   }
0287   iEvent.emplace(regionPutToken, std::move(rgnCollection));
0288 }
0289 
0290 // ------------ method called when starting to processes a run  ------------
0291 void L1TCaloLayer1::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
0292   if (!L1TCaloLayer1FetchLUTs(lutsTokens,
0293                               iSetup,
0294                               ecalLUT,
0295                               hcalLUT,
0296                               hfLUT,
0297                               ePhiMap,
0298                               hPhiMap,
0299                               hfPhiMap,
0300                               useLSB,
0301                               useCalib,
0302                               useECALLUT,
0303                               useHCALLUT,
0304                               useHFLUT,
0305                               fwVersion)) {
0306     LOG_ERROR << "L1TCaloLayer1::beginRun: failed to fetch LUTS - using unity" << std::endl;
0307     std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> eCalLayer1EtaSideEtArray;
0308     std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> hCalLayer1EtaSideEtArray;
0309     std::array<std::array<uint32_t, nEtBins>, nHfEtaBins> hfLayer1EtaEtArray;
0310     ecalLUT.push_back(eCalLayer1EtaSideEtArray);
0311     hcalLUT.push_back(hCalLayer1EtaSideEtArray);
0312     hfLUT.push_back(hfLayer1EtaEtArray);
0313   }
0314   for (uint32_t twr = 0; twr < twrList.size(); twr++) {
0315     // Map goes minus 1 .. 72 plus 1 .. 72 -> 0 .. 143
0316     int iphi = twrList[twr]->caloPhi();
0317     int ieta = twrList[twr]->caloEta();
0318     if (ieta < 0) {
0319       iphi -= 1;
0320     } else {
0321       iphi += 71;
0322     }
0323     twrList[twr]->setECALLUT(&ecalLUT[ePhiMap[iphi]]);
0324     twrList[twr]->setHCALLUT(&hcalLUT[hPhiMap[iphi]]);
0325     twrList[twr]->setHFLUT(&hfLUT[hfPhiMap[iphi]]);
0326   }
0327 }
0328 
0329 // ------------ method called when ending the processing of a run  ------------
0330 /*
0331   void
0332   L1TCaloLayer1::endRun(edm::Run const&, edm::EventSetup const&)
0333   {
0334   }
0335 */
0336 
0337 // ------------ method called when starting to processes a luminosity block  ------------
0338 /*
0339   void
0340   L1TCaloLayer1::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0341   {
0342   }
0343 */
0344 
0345 // ------------ method called when ending the processing of a luminosity block  ------------
0346 /*
0347   void
0348   L1TCaloLayer1::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0349   {
0350   }
0351 */
0352 
0353 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0354 void L1TCaloLayer1::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0355   //The following says we do not know what parameters are allowed so do no validation
0356   // Please change this to state exactly what you do use, even if it is no parameters
0357   edm::ParameterSetDescription desc;
0358   desc.setUnknown();
0359   descriptions.addDefault(desc);
0360 }
0361 
0362 //define this as a plug-in
0363 DEFINE_FWK_MODULE(L1TCaloLayer1);
0364 /* vim: set ts=8 sw=2 tw=0 et :*/