Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:22:39

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