Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:23:47

0001 /** \class DisplacedMuonFilterProducer
0002  *
0003  * The filter takes a reco::Muon collection as an input and preselects
0004  * the muons that will be processed by the next sequences.
0005  *
0006  * 1) StandAlone muons matched to an inner track (either as Tracker or Global muons)
0007  *    are preselected if the StandAlone track has pt > minPtSTA_ or the tracker track 
0008  *    has pt > minPtTK_
0009  *
0010  *    (Global muon are contained in this subset)
0011  *
0012  * 2) StandAlone-only muons are preselected if they have number of segments > minMatches_
0013  *    and they have pt > minPtSTA_
0014  *
0015  * 3) Tracker muons without an StandAlone track are preselected if they have pt > minPtTK_
0016  *    and they are labelled as isTrackerMuon() i.e. not RPC/GEM muons.
0017  *
0018  * \author C. Fernandez Madrazo <celia.fernandez.madrazo@cern.ch>
0019  *
0020  */
0021 
0022 // system include files
0023 #include <memory>
0024 
0025 // user include files
0026 #include "FWCore/Framework/interface/Frameworkfwd.h"
0027 #include "FWCore/Framework/interface/stream/EDProducer.h"
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/Framework/interface/EventSetup.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0032 
0033 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0034 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0035 #include "FWCore/Utilities/interface/InputTag.h"
0036 
0037 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0038 #include "DataFormats/MuonReco/interface/Muon.h"
0039 #include "DataFormats/MuonReco/interface/MuonTimeExtra.h"
0040 #include "DataFormats/MuonReco/interface/MuonTimeExtraMap.h"
0041 
0042 #include "DataFormats/Common/interface/ValueMap.h"
0043 #include "DataFormats/RecoCandidate/interface/IsoDepositFwd.h"
0044 #include "DataFormats/RecoCandidate/interface/IsoDeposit.h"
0045 
0046 #include "DataFormats/Common/interface/Handle.h"
0047 
0048 namespace pat {
0049   class DisplacedMuonFilterProducer : public edm::stream::EDProducer<> {
0050   public:
0051     explicit DisplacedMuonFilterProducer(const edm::ParameterSet&);
0052 
0053     ~DisplacedMuonFilterProducer() override;
0054 
0055     void produce(edm::Event&, const edm::EventSetup&) override;
0056     /// description of config file parameters
0057     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0058 
0059   private:
0060     template <typename TYPE>
0061     void fillMuonMap(edm::Event& event,
0062                      const edm::OrphanHandle<reco::MuonCollection>& muonHandle,
0063                      const std::vector<TYPE>& muonExtra,
0064                      const std::string& label);
0065 
0066     // muon collections
0067     const edm::InputTag srcMuons_;
0068     const edm::EDGetTokenT<reco::MuonCollection> srcMuonToken_;
0069 
0070     // filter criteria and selection
0071     const double minPtTK_;     // Minimum pt of inner tracks
0072     const double minPtSTA_;    // Minimum pt of standalone tracks
0073     const double minMatches_;  // Minimum number of matches of standalone-only muons
0074 
0075     // what information to fill
0076     bool fillDetectorBasedIsolation_;
0077     bool fillTimingInfo_;
0078 
0079     // timing info
0080     edm::EDGetTokenT<reco::MuonTimeExtraMap> timeMapCmbToken_;
0081     edm::EDGetTokenT<reco::MuonTimeExtraMap> timeMapDTToken_;
0082     edm::EDGetTokenT<reco::MuonTimeExtraMap> timeMapCSCToken_;
0083 
0084     // detector based isolation
0085     edm::EDGetTokenT<reco::IsoDepositMap> theTrackDepositToken_;
0086     edm::EDGetTokenT<reco::IsoDepositMap> theEcalDepositToken_;
0087     edm::EDGetTokenT<reco::IsoDepositMap> theHcalDepositToken_;
0088     edm::EDGetTokenT<reco::IsoDepositMap> theHoDepositToken_;
0089     edm::EDGetTokenT<reco::IsoDepositMap> theJetDepositToken_;
0090   };
0091 }  // namespace pat
0092 
0093 pat::DisplacedMuonFilterProducer::DisplacedMuonFilterProducer(const edm::ParameterSet& iConfig)
0094     : srcMuons_(iConfig.getParameter<edm::InputTag>("srcMuons")),
0095       srcMuonToken_(consumes<reco::MuonCollection>(srcMuons_)),
0096       minPtTK_(iConfig.getParameter<double>("minPtTK")),
0097       minPtSTA_(iConfig.getParameter<double>("minPtSTA")),
0098       minMatches_(iConfig.getParameter<double>("minMatches")),
0099       fillDetectorBasedIsolation_(iConfig.getParameter<bool>("FillDetectorBasedIsolation")),
0100       fillTimingInfo_(iConfig.getParameter<bool>("FillTimingInfo")) {
0101   produces<reco::MuonCollection>();
0102 
0103   if (fillTimingInfo_) {
0104     timeMapCmbToken_ = consumes<reco::MuonTimeExtraMap>(edm::InputTag(srcMuons_.label(), "combined"));
0105     timeMapDTToken_ = consumes<reco::MuonTimeExtraMap>(edm::InputTag(srcMuons_.label(), "dt"));
0106     timeMapCSCToken_ = consumes<reco::MuonTimeExtraMap>(edm::InputTag(srcMuons_.label(), "csc"));
0107 
0108     produces<reco::MuonTimeExtraMap>("combined");
0109     produces<reco::MuonTimeExtraMap>("dt");
0110     produces<reco::MuonTimeExtraMap>("csc");
0111   }
0112 
0113   if (fillDetectorBasedIsolation_) {
0114     theTrackDepositToken_ = consumes<reco::IsoDepositMap>(iConfig.getParameter<edm::InputTag>("TrackIsoDeposits"));
0115     theJetDepositToken_ = consumes<reco::IsoDepositMap>(iConfig.getParameter<edm::InputTag>("JetIsoDeposits"));
0116     theEcalDepositToken_ = consumes<reco::IsoDepositMap>(iConfig.getParameter<edm::InputTag>("EcalIsoDeposits"));
0117     theHcalDepositToken_ = consumes<reco::IsoDepositMap>(iConfig.getParameter<edm::InputTag>("HcalIsoDeposits"));
0118     theHoDepositToken_ = consumes<reco::IsoDepositMap>(iConfig.getParameter<edm::InputTag>("HoIsoDeposits"));
0119     produces<reco::IsoDepositMap>("tracker");
0120     produces<reco::IsoDepositMap>("ecal");
0121     produces<reco::IsoDepositMap>("hcal");
0122     produces<reco::IsoDepositMap>("ho");
0123     produces<reco::IsoDepositMap>("jets");
0124   }
0125 }
0126 
0127 pat::DisplacedMuonFilterProducer::~DisplacedMuonFilterProducer() {}
0128 
0129 void pat::DisplacedMuonFilterProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0130   // filteredDisplacedMuons
0131   edm::ParameterSetDescription desc;
0132   desc.add<edm::InputTag>("srcMuons", edm::InputTag("displacedMuons"));
0133   desc.add<bool>("FillTimingInfo", true);
0134   desc.add<bool>("FillDetectorBasedIsolation", false);
0135   desc.add<edm::InputTag>("TrackIsoDeposits", edm::InputTag("displacedMuons", "tracker"));
0136   desc.add<edm::InputTag>("JetIsoDeposits", edm::InputTag("displacedMuons", "jets"));
0137   desc.add<edm::InputTag>("EcalIsoDeposits", edm::InputTag("displacedMuons", "ecal"));
0138   desc.add<edm::InputTag>("HcalIsoDeposits", edm::InputTag("displacedMuons", "hcal"));
0139   desc.add<edm::InputTag>("HoIsoDeposits", edm::InputTag("displacedMuons", "ho"));
0140   desc.add<double>("minPtSTA", 3.5);
0141   desc.add<double>("minPtTK", 3.5);
0142   desc.add<double>("minMatches", 2);
0143   descriptions.add("filteredDisplacedMuons", desc);
0144 }
0145 
0146 // Filter muons
0147 
0148 void pat::DisplacedMuonFilterProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0149   auto output = std::make_unique<reco::MuonCollection>();
0150 
0151   // muon collections
0152   edm::Handle<reco::MuonCollection> srcMuons;
0153   iEvent.getByToken(srcMuonToken_, srcMuons);
0154 
0155   int nMuons = srcMuons->size();
0156 
0157   // filter the muons
0158   std::vector<bool> filteredmuons(nMuons, true);
0159   int oMuons = nMuons;
0160 
0161   unsigned int nsegments = 0;
0162   for (unsigned int i = 0; i < srcMuons->size(); i++) {
0163     const reco::Muon& muon(srcMuons->at(i));
0164 
0165     if (muon.isStandAloneMuon()) {
0166       if (muon.innerTrack().isNonnull()) {
0167         // Discard STA + GL/TR muons that are below pt threshold
0168         if (muon.innerTrack()->pt() < minPtTK_ && muon.standAloneMuon()->pt() < minPtSTA_) {
0169           filteredmuons[i] = false;
0170           oMuons = oMuons - 1;
0171           continue;
0172         }
0173         // Discard STA-only muons below pt threshold
0174       } else if (muon.standAloneMuon()->pt() < minPtSTA_) {
0175         filteredmuons[i] = false;
0176         oMuons = oMuons - 1;
0177         continue;
0178       } else {
0179         // Compute number of DT+CSC segments and discard those that have less than the minimum required
0180         nsegments = 0;
0181         for (trackingRecHit_iterator hit = muon.standAloneMuon()->recHitsBegin();
0182              hit != muon.standAloneMuon()->recHitsEnd();
0183              ++hit) {
0184           if (!(*hit)->isValid())
0185             continue;
0186           DetId id = (*hit)->geographicalId();
0187           if (id.det() != DetId::Muon)
0188             continue;
0189           if (id.subdetId() == MuonSubdetId::DT || id.subdetId() == MuonSubdetId::CSC) {
0190             nsegments++;
0191           }
0192         }
0193         // Discard STA-only muons with less than minMatches_ segments
0194         if (nsegments < minMatches_) {
0195           filteredmuons[i] = false;
0196           oMuons = oMuons - 1;
0197           continue;
0198         }
0199       }
0200     } else {
0201       if (muon.innerTrack().isNonnull()) {
0202         if (muon.innerTrack()->pt() < minPtTK_ || !muon.isTrackerMuon()) {
0203           filteredmuons[i] = false;
0204           oMuons = oMuons - 1;
0205           continue;
0206         }
0207       } else {  // Should never happen
0208         edm::LogWarning("muonBadTracks") << "Muon that has not standalone nor tracker track."
0209                                          << "There should be no such object. Muon is skipped.";
0210         filteredmuons[i] = false;
0211         oMuons = oMuons - 1;
0212         continue;
0213       }
0214     }
0215   }
0216 
0217   // timing information
0218   edm::Handle<reco::MuonTimeExtraMap> timeMapCmb;
0219   edm::Handle<reco::MuonTimeExtraMap> timeMapDT;
0220   edm::Handle<reco::MuonTimeExtraMap> timeMapCSC;
0221 
0222   std::vector<reco::MuonTimeExtra> dtTimeColl(oMuons);
0223   std::vector<reco::MuonTimeExtra> cscTimeColl(oMuons);
0224   std::vector<reco::MuonTimeExtra> combinedTimeColl(oMuons);
0225 
0226   if (fillTimingInfo_) {
0227     iEvent.getByToken(timeMapCmbToken_, timeMapCmb);
0228     iEvent.getByToken(timeMapDTToken_, timeMapDT);
0229     iEvent.getByToken(timeMapCSCToken_, timeMapCSC);
0230   }
0231 
0232   // detector based isolation
0233   std::vector<reco::IsoDeposit> trackDepColl(oMuons);
0234   std::vector<reco::IsoDeposit> ecalDepColl(oMuons);
0235   std::vector<reco::IsoDeposit> hcalDepColl(oMuons);
0236   std::vector<reco::IsoDeposit> hoDepColl(oMuons);
0237   std::vector<reco::IsoDeposit> jetDepColl(oMuons);
0238 
0239   edm::Handle<reco::IsoDepositMap> trackIsoDepMap;
0240   edm::Handle<reco::IsoDepositMap> ecalIsoDepMap;
0241   edm::Handle<reco::IsoDepositMap> hcalIsoDepMap;
0242   edm::Handle<reco::IsoDepositMap> hoIsoDepMap;
0243   edm::Handle<reco::IsoDepositMap> jetIsoDepMap;
0244 
0245   if (fillDetectorBasedIsolation_) {
0246     iEvent.getByToken(theTrackDepositToken_, trackIsoDepMap);
0247     iEvent.getByToken(theEcalDepositToken_, ecalIsoDepMap);
0248     iEvent.getByToken(theHcalDepositToken_, hcalIsoDepMap);
0249     iEvent.getByToken(theHoDepositToken_, hoIsoDepMap);
0250     iEvent.getByToken(theJetDepositToken_, jetIsoDepMap);
0251   }
0252 
0253   // save filtered muons
0254   unsigned int k = 0;
0255   for (unsigned int i = 0; i < srcMuons->size(); i++) {
0256     if (filteredmuons[i]) {
0257       const reco::Muon& inMuon(srcMuons->at(i));
0258       reco::MuonRef muRef(srcMuons, i);
0259 
0260       // Copy the muon
0261       reco::Muon outMuon = inMuon;
0262 
0263       // Fill timing information
0264       if (fillTimingInfo_) {
0265         combinedTimeColl[k] = (*timeMapCmb)[muRef];
0266         dtTimeColl[k] = (*timeMapDT)[muRef];
0267         cscTimeColl[k] = (*timeMapCSC)[muRef];
0268       }
0269 
0270       // Fill detector based isolation
0271       if (fillDetectorBasedIsolation_) {
0272         trackDepColl[k] = (*trackIsoDepMap)[muRef];
0273         ecalDepColl[k] = (*ecalIsoDepMap)[muRef];
0274         hcalDepColl[k] = (*hcalIsoDepMap)[muRef];
0275         hoDepColl[k] = (*hoIsoDepMap)[muRef];
0276         jetDepColl[k] = (*jetIsoDepMap)[muRef];
0277       }
0278 
0279       output->push_back(outMuon);
0280       k++;
0281     }
0282   }
0283 
0284   // fill information
0285   edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(std::move(output));
0286 
0287   if (fillTimingInfo_) {
0288     fillMuonMap<reco::MuonTimeExtra>(iEvent, muonHandle, combinedTimeColl, "combined");
0289     fillMuonMap<reco::MuonTimeExtra>(iEvent, muonHandle, dtTimeColl, "dt");
0290     fillMuonMap<reco::MuonTimeExtra>(iEvent, muonHandle, cscTimeColl, "csc");
0291   }
0292 
0293   if (fillDetectorBasedIsolation_) {
0294     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, trackDepColl, "tracker");
0295     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, jetDepColl, "jets");
0296     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, ecalDepColl, "ecal");
0297     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, hcalDepColl, "hcal");
0298     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, hoDepColl, "ho");
0299   }
0300 }
0301 
0302 template <typename TYPE>
0303 void pat::DisplacedMuonFilterProducer::fillMuonMap(edm::Event& event,
0304                                                    const edm::OrphanHandle<reco::MuonCollection>& muonHandle,
0305                                                    const std::vector<TYPE>& muonExtra,
0306                                                    const std::string& label) {
0307   typedef typename edm::ValueMap<TYPE>::Filler FILLER;
0308 
0309   auto muonMap = std::make_unique<edm::ValueMap<TYPE>>();
0310   if (!muonExtra.empty()) {
0311     FILLER filler(*muonMap);
0312     filler.insert(muonHandle, muonExtra.begin(), muonExtra.end());
0313     filler.fill();
0314   }
0315   event.put(std::move(muonMap), label);
0316 }
0317 
0318 #include "FWCore/Framework/interface/MakerMacros.h"
0319 using pat::DisplacedMuonFilterProducer;
0320 DEFINE_FWK_MODULE(DisplacedMuonFilterProducer);