Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/skeleton
0004 // Class:      skeleton
0005 //
0006 /**\class skeleton skeleton.cc L1Trigger/skeleton/plugins/skeleton.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  James Brooke
0015 //         Created:  Thu, 05 Dec 2013 17:39:27 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 
0022 // user include files
0023 
0024 #include "FWCore/Framework/interface/EventSetup.h"
0025 #include "FWCore/Framework/interface/Frameworkfwd.h"
0026 #include "FWCore/Framework/interface/stream/EDProducer.h"
0027 #include "FWCore/Framework/interface/ESHandle.h"
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/Framework/interface/MakerMacros.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 #include "FWCore/Utilities/interface/EDGetToken.h"
0032 #include "FWCore/Utilities/interface/EDPutToken.h"
0033 #include "FWCore/Utilities/interface/InputTag.h"
0034 #include "FWCore/Utilities/interface/ESGetToken.h"
0035 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0036 
0037 #include "L1Trigger/L1TCalorimeter/interface/Stage2Layer2FirmwareFactory.h"
0038 #include "L1Trigger/L1TCalorimeter/interface/Stage2MainProcessor.h"
0039 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0040 
0041 #include "L1Trigger/L1TCalorimeter/interface/CaloParamsHelper.h"
0042 #include "CondFormats/DataRecord/interface/L1TCaloParamsRcd.h"
0043 #include "CondFormats/DataRecord/interface/L1TCaloParamsO2ORcd.h"
0044 
0045 #include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
0046 #include "DataFormats/L1Trigger/interface/EGamma.h"
0047 #include "DataFormats/L1Trigger/interface/Tau.h"
0048 #include "DataFormats/L1Trigger/interface/Jet.h"
0049 #include "DataFormats/L1Trigger/interface/EtSum.h"
0050 
0051 //
0052 // class declaration
0053 //
0054 
0055 using namespace l1t;
0056 
0057 class L1TStage2Layer2Producer : public edm::stream::EDProducer<> {
0058 public:
0059   explicit L1TStage2Layer2Producer(const edm::ParameterSet& ps);
0060   ~L1TStage2Layer2Producer() override;
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   // ----------member data ---------------------------
0070 
0071   // input tokens
0072   edm::EDGetTokenT<CaloTowerBxCollection> m_towerToken;
0073   edm::ESGetToken<CaloParams, L1TCaloParamsRcd> m_candidateToken;
0074   edm::ESGetToken<CaloParams, L1TCaloParamsO2ORcd> m_o2oProtoToken;
0075 
0076   // put tokens
0077   edm::EDPutTokenT<CaloTowerBxCollection> m_towerMPToken;
0078   edm::EDPutTokenT<CaloClusterBxCollection> m_clusterMPToken;
0079   edm::EDPutTokenT<EGammaBxCollection> m_egammaMPToken;
0080   edm::EDPutTokenT<TauBxCollection> m_tauMPToken;
0081   edm::EDPutTokenT<JetBxCollection> m_jetMPToken;
0082   edm::EDPutTokenT<EtSumBxCollection> m_etMPToken;
0083   edm::EDPutTokenT<EGammaBxCollection> m_egammaToken;
0084   edm::EDPutTokenT<TauBxCollection> m_tauToken;
0085   edm::EDPutTokenT<JetBxCollection> m_jetToken;
0086   edm::EDPutTokenT<EtSumBxCollection> m_etToken;
0087 
0088   // parameters
0089   unsigned long long m_paramsCacheId;
0090   unsigned m_fwv;
0091   CaloParamsHelper* m_params;
0092 
0093   // the processor
0094   std::shared_ptr<Stage2MainProcessor> m_processor;
0095 
0096   // use static config for fw testing
0097   bool m_useStaticConfig;
0098 };
0099 
0100 L1TStage2Layer2Producer::L1TStage2Layer2Producer(const edm::ParameterSet& ps) {
0101   // register what you produce
0102   m_towerMPToken = produces<CaloTowerBxCollection>("MP");
0103   m_clusterMPToken = produces<CaloClusterBxCollection>("MP");
0104   m_egammaMPToken = produces<EGammaBxCollection>("MP");
0105   m_tauMPToken = produces<TauBxCollection>("MP");
0106   m_jetMPToken = produces<JetBxCollection>("MP");
0107   m_etMPToken = produces<EtSumBxCollection>("MP");
0108   m_egammaToken = produces<EGammaBxCollection>();
0109   m_tauToken = produces<TauBxCollection>();
0110   m_jetToken = produces<JetBxCollection>();
0111   m_etToken = produces<EtSumBxCollection>();
0112 
0113   // register what you consume and keep token for later access:
0114   m_towerToken = consumes<CaloTowerBxCollection>(ps.getParameter<edm::InputTag>("towerToken"));
0115   m_candidateToken = esConsumes<CaloParams, L1TCaloParamsRcd, edm::Transition::BeginRun>();
0116 
0117   // placeholder for the parameters
0118   m_params = new CaloParamsHelper;
0119 
0120   // set firmware version from python config for now
0121   m_fwv = ps.getParameter<int>("firmware");
0122 
0123   // get static config flag
0124   m_useStaticConfig = ps.getParameter<bool>("useStaticConfig");
0125   if (!m_useStaticConfig) {
0126     m_o2oProtoToken = esConsumes<CaloParams, L1TCaloParamsO2ORcd, edm::Transition::BeginRun>();
0127   }
0128 
0129   //initialize
0130   m_paramsCacheId = 0;
0131 }
0132 
0133 L1TStage2Layer2Producer::~L1TStage2Layer2Producer() { delete m_params; }
0134 
0135 // ------------ method called to produce the data  ------------
0136 void L1TStage2Layer2Producer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0137   using namespace edm;
0138 
0139   using namespace l1t;
0140 
0141   LogDebug("l1t|stage 2") << "L1TStage2Layer2Producer::produce function called..." << std::endl;
0142 
0143   //inputs
0144   Handle<BXVector<CaloTower> > towers;
0145   iEvent.getByToken(m_towerToken, towers);
0146 
0147   int bxFirst = towers->getFirstBX();
0148   int bxLast = towers->getLastBX();
0149 
0150   LogDebug("L1TDebug") << "First BX=" << bxFirst << ", last BX=" << bxLast << std::endl;
0151 
0152   //outputs
0153   CaloTowerBxCollection outTowers(0, bxFirst, bxLast);
0154   CaloClusterBxCollection clusters(0, bxFirst, bxLast);
0155   EGammaBxCollection mpegammas(0, bxFirst, bxLast);
0156   TauBxCollection mptaus(0, bxFirst, bxLast);
0157   JetBxCollection mpjets(0, bxFirst, bxLast);
0158   EtSumBxCollection mpsums(0, bxFirst, bxLast);
0159   EGammaBxCollection egammas(0, bxFirst, bxLast);
0160   TauBxCollection taus(0, bxFirst, bxLast);
0161   JetBxCollection jets(0, bxFirst, bxLast);
0162   EtSumBxCollection etsums(0, bxFirst, bxLast);
0163 
0164   // loop over BX
0165   for (int ibx = bxFirst; ibx < bxLast + 1; ++ibx) {
0166     std::vector<CaloTower> localTowers(CaloTools::caloTowerHashMax() + 1);
0167     std::vector<CaloTower> localOutTowers;
0168     std::vector<CaloCluster> localClusters;
0169     std::vector<EGamma> localMPEGammas;
0170     std::vector<Tau> localMPTaus;
0171     std::vector<Jet> localMPJets;
0172     std::vector<EtSum> localMPEtSums;
0173     std::vector<EGamma> localEGammas;
0174     std::vector<Tau> localTaus;
0175     std::vector<Jet> localJets;
0176     std::vector<EtSum> localEtSums;
0177 
0178     LogDebug("L1TDebug") << "BX=" << ibx << ", N(Towers)=" << towers->size(ibx) << std::endl;
0179 
0180     for (std::vector<CaloTower>::const_iterator tower = towers->begin(ibx); tower != towers->end(ibx); ++tower) {
0181       CaloTower tow(tower->p4(),
0182                     tower->etEm(),
0183                     tower->etHad(),
0184                     tower->hwPt(),
0185                     tower->hwEta(),
0186                     tower->hwPhi(),
0187                     tower->hwQual(),
0188                     tower->hwEtEm(),
0189                     tower->hwEtHad(),
0190                     tower->hwEtRatio());
0191 
0192       localTowers.at(CaloTools::caloTowerHash(tow.hwEta(), tow.hwPhi())) = tow;
0193     }
0194 
0195     LogDebug("L1TDebug") << "BX=" << ibx << ", N(Towers)=" << localTowers.size() << std::endl;
0196 
0197     m_processor->processEvent(localTowers,
0198                               localOutTowers,
0199                               localClusters,
0200                               localMPEGammas,
0201                               localMPTaus,
0202                               localMPJets,
0203                               localMPEtSums,
0204                               localEGammas,
0205                               localTaus,
0206                               localJets,
0207                               localEtSums);
0208 
0209     for (auto tow = localOutTowers.begin(); tow != localOutTowers.end(); ++tow)
0210       outTowers.push_back(ibx, *tow);
0211     for (auto clus = localClusters.begin(); clus != localClusters.end(); ++clus)
0212       clusters.push_back(ibx, *clus);
0213     for (auto eg = localMPEGammas.begin(); eg != localMPEGammas.end(); ++eg)
0214       mpegammas.push_back(ibx, CaloTools::egP4MP(*eg));
0215     for (auto tau = localMPTaus.begin(); tau != localMPTaus.end(); ++tau)
0216       mptaus.push_back(ibx, CaloTools::tauP4MP(*tau));
0217     for (auto jet = localMPJets.begin(); jet != localMPJets.end(); ++jet)
0218       mpjets.push_back(ibx, CaloTools::jetP4MP(*jet));
0219     for (auto etsum = localMPEtSums.begin(); etsum != localMPEtSums.end(); ++etsum)
0220       mpsums.push_back(ibx, CaloTools::etSumP4MP(*etsum));
0221     for (auto eg = localEGammas.begin(); eg != localEGammas.end(); ++eg)
0222       egammas.push_back(ibx, CaloTools::egP4Demux(*eg));
0223     for (auto tau = localTaus.begin(); tau != localTaus.end(); ++tau)
0224       taus.push_back(ibx, CaloTools::tauP4Demux(*tau));
0225     for (auto jet = localJets.begin(); jet != localJets.end(); ++jet)
0226       jets.push_back(ibx, CaloTools::jetP4Demux(*jet));
0227     for (auto etsum = localEtSums.begin(); etsum != localEtSums.end(); ++etsum)
0228       etsums.push_back(ibx, CaloTools::etSumP4Demux(*etsum));
0229 
0230     LogDebug("L1TDebug") << "BX=" << ibx << ", N(Cluster)=" << localClusters.size() << ", N(EG)=" << localEGammas.size()
0231                          << ", N(Tau)=" << localTaus.size() << ", N(Jet)=" << localJets.size()
0232                          << ", N(Sums)=" << localEtSums.size() << std::endl;
0233   }
0234 
0235   iEvent.emplace(m_towerMPToken, std::move(outTowers));
0236   iEvent.emplace(m_clusterMPToken, std::move(clusters));
0237   iEvent.emplace(m_egammaMPToken, std::move(mpegammas));
0238   iEvent.emplace(m_tauMPToken, std::move(mptaus));
0239   iEvent.emplace(m_jetMPToken, std::move(mpjets));
0240   iEvent.emplace(m_etMPToken, std::move(mpsums));
0241   iEvent.emplace(m_egammaToken, std::move(egammas));
0242   iEvent.emplace(m_tauToken, std::move(taus));
0243   iEvent.emplace(m_jetToken, std::move(jets));
0244   iEvent.emplace(m_etToken, std::move(etsums));
0245 }
0246 
0247 // ------------ method called when starting to processes a run  ------------
0248 void L1TStage2Layer2Producer::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) {
0249   // update parameters and algorithms at run start, if they have changed
0250   // update params first because the firmware factory relies on pointer to params
0251 
0252   // parameters
0253 
0254   unsigned long long id = iSetup.get<L1TCaloParamsRcd>().cacheIdentifier();
0255 
0256   if (id != m_paramsCacheId) {
0257     m_paramsCacheId = id;
0258 
0259     // fetch payload corresponding to the current run from the CondDB
0260     edm::ESHandle<CaloParams> candidateHandle = iSetup.getHandle(m_candidateToken);
0261     std::unique_ptr<l1t::CaloParams> candidate(new l1t::CaloParams(*candidateHandle.product()));
0262 
0263     if (!m_useStaticConfig) {
0264       // fetch the latest greatest prototype (equivalent of static payload)
0265       edm::ESHandle<CaloParams> o2oProtoHandle = iSetup.getHandle(m_o2oProtoToken);
0266       std::unique_ptr<l1t::CaloParams> prototype(new l1t::CaloParams(*o2oProtoHandle.product()));
0267 
0268       // prepare to set the emulator's configuration
0269       //  and then replace our local copy of the parameters with a new one using placement new
0270       m_params->~CaloParamsHelper();
0271 
0272       // compare the candidate payload misses some of the pnodes compared to the prototype,
0273       // if this is the case - the candidate is an old payload that'll crash the Stage2 emulator
0274       // and we better use the prototype for the emulator's configuration
0275       if (((CaloParamsHelper*)candidate.get())->getNodes().size() <
0276           ((CaloParamsHelper*)prototype.get())->getNodes().size())
0277         m_params = new (m_params) CaloParamsHelper(*o2oProtoHandle.product());
0278       else
0279         m_params = new (m_params) CaloParamsHelper(*candidateHandle.product());
0280       // KK: the nifty tricks above (placement new) work as long as current definition of
0281       //     CaloParams takes more space than the one obtained from the record
0282 
0283     } else {
0284       m_params->~CaloParamsHelper();
0285       m_params = new (m_params) CaloParamsHelper(*candidateHandle.product());
0286     }
0287 
0288     LogDebug("L1TDebug") << *m_params << std::endl;
0289 
0290     if (!m_params) {
0291       edm::LogError("l1t|caloStage2") << "Could not retrieve params from Event Setup" << std::endl;
0292     }
0293   }
0294 
0295   // firmware
0296 
0297   if (!m_processor) {  // in future, also check if the firmware cache ID has changed !
0298 
0299     //     m_fwv = ; // get new firmware version in future
0300 
0301     // Set the current algorithm version based on DB pars from database:
0302     Stage2Layer2FirmwareFactory m_factory;
0303     m_processor = m_factory.create(m_fwv, m_params);
0304 
0305     if (!m_processor) {
0306       // we complain here once per run
0307       edm::LogError("l1t|caloStage2") << "Firmware could not be configured.\n";
0308     }
0309 
0310     LogDebug("L1TDebug") << "Processor object : " << (m_processor ? 1 : 0) << std::endl;
0311   }
0312 }
0313 
0314 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0315 void L1TStage2Layer2Producer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0316   //The following says we do not know what parameters are allowed so do no validation
0317   // Please change this to state exactly what you do use, even if it is no parameters
0318   edm::ParameterSetDescription desc;
0319   desc.setUnknown();
0320   descriptions.addDefault(desc);
0321 }
0322 
0323 //define this as a plug-in
0324 DEFINE_FWK_MODULE(L1TStage2Layer2Producer);