Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:12:29

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1TMicroGMTInputProducerFromGen
0004 // Class:      L1TMicroGMTInputProducerFromGen
0005 //
0006 /**\class L1TMicroGMTInputProducerFromGen L1TMicroGMTInputProducerFromGen.cc L1Trigger/L1TGlobalMuon/plugins/L1TMicroGMTInputProducerFromGen.cc
0007 
0008  Description: takes generated muons and fills them in the expected collections for the MicroGMT
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Joschka Philip Lingemann,40 3-B01,+41227671598,
0015 //         Created:  Thu Oct  3 10:12:30 CEST 2013
0016 // $Id$
0017 //
0018 //
0019 
0020 // system include files
0021 #include <memory>
0022 #include <fstream>
0023 
0024 // user include files
0025 #include "FWCore/Framework/interface/Frameworkfwd.h"
0026 #include "FWCore/Framework/interface/stream/EDProducer.h"
0027 
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/Framework/interface/MakerMacros.h"
0030 
0031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0032 #include "FWCore/Utilities/interface/Exception.h"
0033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0034 
0035 #include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h"
0036 #include "DataFormats/L1TMuon/interface/RegionalMuonCand.h"
0037 #include "DataFormats/L1TMuon/interface/MuonCaloSumFwd.h"
0038 #include "DataFormats/L1TMuon/interface/MuonCaloSum.h"
0039 
0040 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0041 
0042 #include "TMath.h"
0043 #include "TRandom3.h"
0044 
0045 //
0046 // class declaration
0047 //
0048 using namespace l1t;
0049 
0050 class L1TMicroGMTInputProducerFromGen : public edm::stream::EDProducer<> {
0051 public:
0052   explicit L1TMicroGMTInputProducerFromGen(const edm::ParameterSet&);
0053   ~L1TMicroGMTInputProducerFromGen() override;
0054 
0055   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0056 
0057 private:
0058   void produce(edm::Event&, const edm::EventSetup&) override;
0059 
0060   void beginRun(const edm::Run&, edm::EventSetup const&) override;
0061   void endRun(const edm::Run&, edm::EventSetup const&) override;
0062   void beginLuminosityBlock(const edm::LuminosityBlock&, edm::EventSetup const&) override;
0063   void endLuminosityBlock(const edm::LuminosityBlock&, edm::EventSetup const&) override;
0064 
0065   static bool compareMuons(const RegionalMuonCand&, const RegionalMuonCand&);
0066 
0067   // ----------member data ---------------------------
0068   edm::EDGetTokenT<reco::GenParticleCollection> genParticlesToken;
0069   int m_currEvt;
0070   const static int m_maxMuons = 108;
0071   TRandom3 m_rnd;
0072 };
0073 
0074 //
0075 // constants, enums and typedefs
0076 //
0077 
0078 //
0079 // static data member definitions
0080 //
0081 
0082 //
0083 // constructors and destructor
0084 //
0085 L1TMicroGMTInputProducerFromGen::L1TMicroGMTInputProducerFromGen(const edm::ParameterSet& iConfig)
0086     : m_currEvt(0), m_rnd(0) {
0087   //register your inputs:
0088   genParticlesToken = consumes<reco::GenParticleCollection>(std::string("genParticles"));
0089   //register your products
0090   produces<RegionalMuonCandBxCollection>("BarrelTFMuons");
0091   produces<RegionalMuonCandBxCollection>("OverlapTFMuons");
0092   produces<RegionalMuonCandBxCollection>("ForwardTFMuons");
0093   produces<MuonCaloSumBxCollection>("TriggerTowerSums");
0094 }
0095 
0096 L1TMicroGMTInputProducerFromGen::~L1TMicroGMTInputProducerFromGen() {
0097   // do anything here that needs to be done at desctruction time
0098   // (e.g. close files, deallocate resources etc.)
0099 }
0100 
0101 //
0102 // member functions
0103 //
0104 
0105 bool L1TMicroGMTInputProducerFromGen::compareMuons(const RegionalMuonCand& mu1, const RegionalMuonCand& mu2) {
0106   return mu1.processor() < mu2.processor();
0107 }
0108 
0109 // ------------ method called to produce the data  ------------
0110 void L1TMicroGMTInputProducerFromGen::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0111   using namespace edm;
0112 
0113   std::unique_ptr<RegionalMuonCandBxCollection> barrelMuons(new RegionalMuonCandBxCollection());
0114   std::unique_ptr<RegionalMuonCandBxCollection> overlapMuons(new RegionalMuonCandBxCollection());
0115   std::unique_ptr<RegionalMuonCandBxCollection> endcapMuons(new RegionalMuonCandBxCollection());
0116   std::unique_ptr<MuonCaloSumBxCollection> towerSums(new MuonCaloSumBxCollection());
0117 
0118   std::vector<RegionalMuonCand> bmMuons;
0119   std::vector<RegionalMuonCand> omMuons;
0120   std::vector<RegionalMuonCand> emMuons;
0121 
0122   std::vector<int> muIndices;
0123   edm::Handle<reco::GenParticleCollection> genParticles;
0124   // Make sure that you can get genParticles
0125   if (iEvent.getByToken(genParticlesToken, genParticles)) {
0126     int cntr = 0;
0127     for (auto it = genParticles->cbegin(); it != genParticles->cend(); ++it) {
0128       const reco::Candidate& mcParticle = *it;
0129       if (abs(mcParticle.pdgId()) == 13 && mcParticle.status() == 1)
0130         muIndices.push_back(cntr);
0131       cntr++;
0132     }
0133   } else {
0134     LogTrace("GlobalMuon") << " GenParticleCollection not found." << std::endl;
0135   }
0136 
0137   RegionalMuonCand mu;
0138   MuonCaloSum tSum;
0139   // alternative scale (using full phi bit-width): 163.4521265553765f;
0140   const float phiToInt = 91.67324722093171f;
0141   // alternative scale: 100.0f;
0142   const float etaToInt = 90.9090909090f;
0143   const int maxPt = (1 << 9) - 1;
0144   int muCntr = 0;
0145 
0146   double twoPi = TMath::Pi() * 2.;
0147 
0148   for (auto it = muIndices.begin(); it != muIndices.end(); ++it) {
0149     // don't really care which muons are taken...
0150     // guess there ain't 108 generated anyways
0151     if (muCntr == m_maxMuons)
0152       break;
0153     int gen_idx = *it;
0154     const reco::Candidate& mcMuon = genParticles->at(gen_idx);
0155     double eta = mcMuon.eta();
0156     if (fabs(eta) > 2.45)
0157       continue;  // out of acceptance
0158     int hwPt = int(mcMuon.pt() * 2);
0159     hwPt = (hwPt < maxPt ? hwPt : maxPt);
0160     int hwEta = int(eta * etaToInt);
0161     double phi = mcMuon.phi();
0162     if (phi < 0)
0163       phi += twoPi;  // add 2*pi
0164     int hwPhi = (int(phi * phiToInt)) % 576;
0165     int hwQual = 8;
0166     int hwCharge = (mcMuon.charge() > 0) ? 0 : 1;
0167     int hwChargeValid = 1;
0168 
0169     mu.setHwPt(hwPt);
0170 
0171     tftype tf(tftype::bmtf);
0172     int globalWedgePhi = (hwPhi + 24) % 576;  // this sets CMS phi = 0 to -15 deg
0173     int localPhi = globalWedgePhi % 48;
0174     int processor = globalWedgePhi / 48 + 1;
0175     int globalSectorPhi = (hwPhi - 24);  // this sets CMS phi = 0 to +15 deg
0176     if (globalSectorPhi < 0) {
0177       globalSectorPhi += 576;
0178     }
0179 
0180     if (fabs(eta) > 0.8) {
0181       if (fabs(eta) < 1.2) {
0182         tf = (eta > 0 ? tftype::omtf_pos : tftype::omtf_neg);
0183         processor = globalSectorPhi / 96 + 1;
0184         localPhi = globalSectorPhi % 96;
0185       } else {
0186         tf = (eta > 0 ? tftype::emtf_pos : tftype::emtf_neg);
0187         processor = globalSectorPhi / 96 + 1;
0188         localPhi = globalSectorPhi % 96;
0189       }
0190     }
0191     mu.setHwPhi(localPhi);
0192     mu.setTFIdentifiers(processor, tf);
0193 
0194     mu.setHwEta(hwEta);
0195     mu.setHwSign(hwCharge);
0196     mu.setHwSignValid(hwChargeValid);
0197     mu.setHwQual(hwQual);
0198 
0199     if (fabs(eta) < 0.8 && bmMuons.size() < 36) {
0200       bmMuons.push_back(mu);
0201       muCntr++;
0202     } else if (fabs(eta) < 1.2 && omMuons.size() < 36) {
0203       omMuons.push_back(mu);
0204       muCntr++;
0205     } else if (emMuons.size() < 36) {
0206       emMuons.push_back(mu);
0207       muCntr++;
0208     }
0209   }
0210 
0211   std::sort(bmMuons.begin(), bmMuons.end(), L1TMicroGMTInputProducerFromGen::compareMuons);
0212   std::sort(omMuons.begin(), omMuons.end(), L1TMicroGMTInputProducerFromGen::compareMuons);
0213   std::sort(emMuons.begin(), emMuons.end(), L1TMicroGMTInputProducerFromGen::compareMuons);
0214 
0215   for (const auto& mu : bmMuons) {
0216     barrelMuons->push_back(0, mu);
0217   }
0218 
0219   for (const auto& mu : omMuons) {
0220     overlapMuons->push_back(0, mu);
0221   }
0222 
0223   for (const auto& mu : emMuons) {
0224     endcapMuons->push_back(0, mu);
0225   }
0226 
0227   for (int i = 0; i < 1008; ++i) {
0228     // from where could I take the tower energies?
0229     int energy = int(m_rnd.Gaus(12, 6));
0230     if (energy < 0)
0231       energy = 0;
0232     if (energy > 31)
0233       energy = 31;
0234     MuonCaloSum sum(energy, i / 28, i % 28, i);
0235     towerSums->push_back(0, sum);
0236   }
0237 
0238   iEvent.put(std::move(barrelMuons), "BarrelTFMuons");
0239   iEvent.put(std::move(overlapMuons), "OverlapTFMuons");
0240   iEvent.put(std::move(endcapMuons), "ForwardTFMuons");
0241   iEvent.put(std::move(towerSums), "TriggerTowerSums");
0242   m_currEvt++;
0243 }
0244 
0245 // ------------ method called when starting to processes a run  ------------
0246 void L1TMicroGMTInputProducerFromGen::beginRun(const edm::Run&, edm::EventSetup const&) {}
0247 
0248 // ------------ method called when ending the processing of a run  ------------
0249 void L1TMicroGMTInputProducerFromGen::endRun(const edm::Run&, edm::EventSetup const&) {}
0250 
0251 // ------------ method called when starting to processes a luminosity block  ------------
0252 void L1TMicroGMTInputProducerFromGen::beginLuminosityBlock(const edm::LuminosityBlock&, edm::EventSetup const&) {}
0253 
0254 // ------------ method called when ending the processing of a luminosity block  ------------
0255 void L1TMicroGMTInputProducerFromGen::endLuminosityBlock(const edm::LuminosityBlock&, edm::EventSetup const&) {}
0256 
0257 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0258 void L1TMicroGMTInputProducerFromGen::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0259   //The following says we do not know what parameters are allowed so do no validation
0260   // Please change this to state exactly what you do use, even if it is no parameters
0261   edm::ParameterSetDescription desc;
0262   desc.setUnknown();
0263   descriptions.addDefault(desc);
0264 }
0265 
0266 //define this as a plug-in
0267 DEFINE_FWK_MODULE(L1TMicroGMTInputProducerFromGen);