Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-15 22:20:44

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   for (unsigned int i = 0; i < srcMuons->size(); i++) {
0162     const reco::Muon& muon(srcMuons->at(i));
0163 
0164     if (muon.isStandAloneMuon()) {
0165       if (muon.innerTrack().isNonnull()) {
0166         // Discard STA + GL/TR muons that are below pt threshold
0167         if (muon.innerTrack()->pt() < minPtTK_ && muon.standAloneMuon()->pt() < minPtSTA_) {
0168           filteredmuons[i] = false;
0169           oMuons = oMuons - 1;
0170           continue;
0171         }
0172       } else {
0173         // Discard STA-only muons with less than minMatches_ segments and below pt threshold
0174         if (!muon.isMatchesValid() || muon.numberOfMatches() < minMatches_ || muon.standAloneMuon()->pt() < minPtSTA_) {
0175           filteredmuons[i] = false;
0176           oMuons = oMuons - 1;
0177           continue;
0178         }
0179       }
0180     } else {
0181       if (muon.innerTrack().isNonnull()) {
0182         if (muon.innerTrack()->pt() < minPtTK_ || !muon.isTrackerMuon()) {
0183           filteredmuons[i] = false;
0184           oMuons = oMuons - 1;
0185           continue;
0186         }
0187       } else {  // Should never happen
0188         edm::LogWarning("muonBadTracks") << "Muon that has not standalone nor tracker track."
0189                                          << "There should be no such object. Muon is skipped.";
0190         filteredmuons[i] = false;
0191         oMuons = oMuons - 1;
0192         continue;
0193       }
0194     }
0195   }
0196 
0197   // timing information
0198   edm::Handle<reco::MuonTimeExtraMap> timeMapCmb;
0199   edm::Handle<reco::MuonTimeExtraMap> timeMapDT;
0200   edm::Handle<reco::MuonTimeExtraMap> timeMapCSC;
0201 
0202   std::vector<reco::MuonTimeExtra> dtTimeColl(oMuons);
0203   std::vector<reco::MuonTimeExtra> cscTimeColl(oMuons);
0204   std::vector<reco::MuonTimeExtra> combinedTimeColl(oMuons);
0205 
0206   if (fillTimingInfo_) {
0207     iEvent.getByToken(timeMapCmbToken_, timeMapCmb);
0208     iEvent.getByToken(timeMapDTToken_, timeMapDT);
0209     iEvent.getByToken(timeMapCSCToken_, timeMapCSC);
0210   }
0211 
0212   // detector based isolation
0213   std::vector<reco::IsoDeposit> trackDepColl(oMuons);
0214   std::vector<reco::IsoDeposit> ecalDepColl(oMuons);
0215   std::vector<reco::IsoDeposit> hcalDepColl(oMuons);
0216   std::vector<reco::IsoDeposit> hoDepColl(oMuons);
0217   std::vector<reco::IsoDeposit> jetDepColl(oMuons);
0218 
0219   edm::Handle<reco::IsoDepositMap> trackIsoDepMap;
0220   edm::Handle<reco::IsoDepositMap> ecalIsoDepMap;
0221   edm::Handle<reco::IsoDepositMap> hcalIsoDepMap;
0222   edm::Handle<reco::IsoDepositMap> hoIsoDepMap;
0223   edm::Handle<reco::IsoDepositMap> jetIsoDepMap;
0224 
0225   if (fillDetectorBasedIsolation_) {
0226     iEvent.getByToken(theTrackDepositToken_, trackIsoDepMap);
0227     iEvent.getByToken(theEcalDepositToken_, ecalIsoDepMap);
0228     iEvent.getByToken(theHcalDepositToken_, hcalIsoDepMap);
0229     iEvent.getByToken(theHoDepositToken_, hoIsoDepMap);
0230     iEvent.getByToken(theJetDepositToken_, jetIsoDepMap);
0231   }
0232 
0233   // save filtered muons
0234   unsigned int k = 0;
0235   for (unsigned int i = 0; i < srcMuons->size(); i++) {
0236     if (filteredmuons[i]) {
0237       const reco::Muon& inMuon(srcMuons->at(i));
0238       reco::MuonRef muRef(srcMuons, i);
0239 
0240       // Copy the muon
0241       reco::Muon outMuon = inMuon;
0242 
0243       // Fill timing information
0244       if (fillTimingInfo_) {
0245         combinedTimeColl[k] = (*timeMapCmb)[muRef];
0246         dtTimeColl[k] = (*timeMapDT)[muRef];
0247         cscTimeColl[k] = (*timeMapCSC)[muRef];
0248       }
0249 
0250       // Fill detector based isolation
0251       if (fillDetectorBasedIsolation_) {
0252         trackDepColl[k] = (*trackIsoDepMap)[muRef];
0253         ecalDepColl[k] = (*ecalIsoDepMap)[muRef];
0254         hcalDepColl[k] = (*hcalIsoDepMap)[muRef];
0255         hoDepColl[k] = (*hoIsoDepMap)[muRef];
0256         jetDepColl[k] = (*jetIsoDepMap)[muRef];
0257       }
0258 
0259       output->push_back(outMuon);
0260       k++;
0261     }
0262   }
0263 
0264   // fill information
0265   edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(std::move(output));
0266 
0267   if (fillTimingInfo_) {
0268     fillMuonMap<reco::MuonTimeExtra>(iEvent, muonHandle, combinedTimeColl, "combined");
0269     fillMuonMap<reco::MuonTimeExtra>(iEvent, muonHandle, dtTimeColl, "dt");
0270     fillMuonMap<reco::MuonTimeExtra>(iEvent, muonHandle, cscTimeColl, "csc");
0271   }
0272 
0273   if (fillDetectorBasedIsolation_) {
0274     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, trackDepColl, "tracker");
0275     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, jetDepColl, "jets");
0276     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, ecalDepColl, "ecal");
0277     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, hcalDepColl, "hcal");
0278     fillMuonMap<reco::IsoDeposit>(iEvent, muonHandle, hoDepColl, "ho");
0279   }
0280 }
0281 
0282 template <typename TYPE>
0283 void pat::DisplacedMuonFilterProducer::fillMuonMap(edm::Event& event,
0284                                                    const edm::OrphanHandle<reco::MuonCollection>& muonHandle,
0285                                                    const std::vector<TYPE>& muonExtra,
0286                                                    const std::string& label) {
0287   typedef typename edm::ValueMap<TYPE>::Filler FILLER;
0288 
0289   auto muonMap = std::make_unique<edm::ValueMap<TYPE>>();
0290   if (!muonExtra.empty()) {
0291     FILLER filler(*muonMap);
0292     filler.insert(muonHandle, muonExtra.begin(), muonExtra.end());
0293     filler.fill();
0294   }
0295   event.put(std::move(muonMap), label);
0296 }
0297 
0298 #include "FWCore/Framework/interface/MakerMacros.h"
0299 using pat::DisplacedMuonFilterProducer;
0300 DEFINE_FWK_MODULE(DisplacedMuonFilterProducer);