Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-05-05 02:47:49

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/Phase2L1GMT
0004 // Class:      Phase2L1TGMTSAMuonProducer
0005 //
0006 /**\class Phase2L1TGMTSAMuonProducer Phase2L1TGMTSAMuonProducer.cc L1Trigger/Phase2L1GMT/plugins/Phase2L1TGMTSAMuonProducer.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Zhenbin Wu
0015 //         Created:  Fri, 30 Apr 2021 19:10:59 GMT
0016 //
0017 //
0018 
0019 #ifndef PHASE2GMT_SAMUONPRODUCER
0020 #define PHASE2GMT_SAMUONPRODUCER
0021 
0022 // system include files
0023 #include <memory>
0024 #include <sstream>
0025 
0026 // user include files
0027 #include "FWCore/Framework/interface/Frameworkfwd.h"
0028 #include "FWCore/Framework/interface/stream/EDProducer.h"
0029 
0030 #include "FWCore/Framework/interface/Event.h"
0031 #include "FWCore/Framework/interface/MakerMacros.h"
0032 
0033 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0034 #include "FWCore/Utilities/interface/StreamID.h"
0035 
0036 #include "DataFormats/L1Trigger/interface/Muon.h"
0037 #include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h"
0038 #include "DataFormats/L1Trigger/interface/L1MuonParticle.h"
0039 
0040 #include "DataFormats/L1TMuonPhase2/interface/Constants.h"
0041 #include "DataFormats/L1TMuonPhase2/interface/SAMuon.h"
0042 //
0043 // class declaration
0044 //
0045 using namespace Phase2L1GMT;
0046 using namespace l1t;
0047 
0048 class Phase2L1TGMTSAMuonProducer : public edm::stream::EDProducer<> {
0049 public:
0050   explicit Phase2L1TGMTSAMuonProducer(const edm::ParameterSet&);
0051   ~Phase2L1TGMTSAMuonProducer() override = default;
0052 
0053   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0054 
0055 private:
0056   void beginStream(edm::StreamID) override;
0057   void produce(edm::Event&, const edm::EventSetup&) override;
0058   void endStream() override;
0059 
0060   l1t::SAMuon Convertl1tMuon(const l1t::Muon& mu, const int bx_);
0061 
0062   // ----------member data ---------------------------
0063   edm::EDGetTokenT<BXVector<l1t::Muon> > muonToken_;
0064   unsigned int Nprompt;
0065   unsigned int Ndisplaced;
0066 };
0067 
0068 Phase2L1TGMTSAMuonProducer::Phase2L1TGMTSAMuonProducer(const edm::ParameterSet& iConfig)
0069     : muonToken_(consumes<l1t::MuonBxCollection>(iConfig.getParameter<edm::InputTag>("muonToken"))),
0070       Nprompt(iConfig.getParameter<uint>("Nprompt")),
0071       Ndisplaced(iConfig.getParameter<uint>("Ndisplaced")) {
0072   produces<std::vector<l1t::SAMuon> >("promptSAMuons").setBranchAlias("prompt");
0073   produces<std::vector<l1t::SAMuon> >("displacedSAMuons").setBranchAlias("displaced");
0074 }
0075 
0076 //
0077 // member functions
0078 //
0079 
0080 // ------------ method called to produce the data  ------------
0081 void Phase2L1TGMTSAMuonProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0082   using namespace edm;
0083   edm::Handle<l1t::MuonBxCollection> muon;
0084   iEvent.getByToken(muonToken_, muon);
0085 
0086   // Output
0087   std::vector<SAMuon> prompt;
0088   std::vector<SAMuon> displaced;
0089 
0090   for (int bx = muon->getFirstBX(); bx <= muon->getLastBX(); ++bx) {
0091     //TODO: We are expecting to send all BX. Using bx0 for now
0092     if (bx != 0) {
0093       continue;
0094     }
0095 
0096     for (uint i = 0; i < muon->size(bx); ++i) {
0097       const l1t::Muon& mu = muon->at(bx, i);
0098 
0099       //TODO: Still looking for a way to get displaced muon
0100       if (abs(mu.hwDXY()) > 0)
0101         displaced.push_back(Convertl1tMuon(mu, bx));
0102       else
0103         prompt.push_back(Convertl1tMuon(mu, bx));
0104     }
0105 
0106     // Sort by hwPt
0107     std::sort(prompt.begin(), prompt.end(), std::greater<>());
0108     std::sort(displaced.begin(), displaced.end(), std::greater<>());
0109 
0110     // Store into output, allow up to 18 prompt + 18 displayed
0111     if (prompt.size() > Nprompt) {
0112       prompt.resize(Nprompt);
0113     }
0114     if (displaced.size() > Ndisplaced) {
0115       displaced.resize(Ndisplaced);
0116     }
0117   }
0118 
0119   std::unique_ptr<std::vector<l1t::SAMuon> > prompt_ptr = std::make_unique<std::vector<l1t::SAMuon> >(prompt);
0120   std::unique_ptr<std::vector<l1t::SAMuon> > displaced_ptr = std::make_unique<std::vector<l1t::SAMuon> >(displaced);
0121   iEvent.put(std::move(prompt_ptr), "promptSAMuons");
0122   iEvent.put(std::move(displaced_ptr), "displacedSAMuons");
0123 }
0124 
0125 // ===  FUNCTION  ============================================================
0126 //         Name:  Phase2L1TGMTSAMuonProducer::Convertl1tMuon
0127 //  Description:
0128 // ===========================================================================
0129 SAMuon Phase2L1TGMTSAMuonProducer::Convertl1tMuon(const l1t::Muon& mu, const int bx_) {
0130   qual_sa_t qual = mu.hwQual();
0131   int charge = mu.charge() > 0 ? 0 : 1;
0132 
0133   pt_sa_t pt = round(mu.pt() / LSBpt);
0134   phi_sa_t phi = round(mu.phi() / LSBphi);
0135   eta_sa_t eta = round(mu.eta() / LSBeta);
0136   // FIXME: Below are not well defined in phase1 GMT
0137   // Using the version from Correlator for now
0138   z0_sa_t z0 = 0;  // No tracks info in Phase 1
0139   // Use 2 bits with LSB = 30cm for BMTF and 25cm for EMTF currently, but subjet to change
0140   d0_sa_t d0 = mu.hwDXY();
0141 
0142   int bstart = 0;
0143   wordtype word(0);
0144   bstart = wordconcat<wordtype>(word, bstart, pt > 0, 1);
0145   bstart = wordconcat<wordtype>(word, bstart, pt, BITSGTPT);
0146   bstart = wordconcat<wordtype>(word, bstart, phi, BITSGTPHI);
0147   bstart = wordconcat<wordtype>(word, bstart, eta, BITSGTETA);
0148   bstart = wordconcat<wordtype>(word, bstart, z0, BITSSAZ0);
0149   bstart = wordconcat<wordtype>(word, bstart, d0, BITSSAD0);
0150   bstart = wordconcat<wordtype>(word, bstart, charge, 1);
0151   bstart = wordconcat<wordtype>(word, bstart, qual, BITSSAQUAL);
0152 
0153   SAMuon samuon(mu, charge, pt.to_uint(), eta.to_int(), phi.to_int(), z0.to_int(), d0.to_int(), qual.to_uint());
0154   samuon.setWord(word);
0155   return samuon;
0156 }  // -----  end of function Phase2L1TGMTSAMuonProducer::Convertl1tMuon  -----
0157 
0158 // ------------ method called once each stream before processing any runs, lumis or events  ------------
0159 void Phase2L1TGMTSAMuonProducer::beginStream(edm::StreamID) {
0160   // please remove this method if not needed
0161 }
0162 
0163 // ------------ method called once each stream after processing all runs, lumis and events  ------------
0164 void Phase2L1TGMTSAMuonProducer::endStream() {
0165   // please remove this method if not needed
0166 }
0167 
0168 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0169 void Phase2L1TGMTSAMuonProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0170   edm::ParameterSetDescription desc;
0171   desc.add<edm::InputTag>("muonToken", edm::InputTag("simGmtStage2Digis"));
0172   desc.add<unsigned int>("Nprompt", 12);
0173   desc.add<unsigned int>("Ndisplaced", 12);
0174   descriptions.add("standaloneMuons", desc);
0175 }
0176 
0177 //define this as a plug-in
0178 DEFINE_FWK_MODULE(Phase2L1TGMTSAMuonProducer);
0179 #endif