Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:25:53

0001 //
0002 //
0003 
0004 /**
0005   \class    CaloMuonMerger "RecoMuon/MuonIdentification/plugins/CaloMuonMerger.cc"
0006   \brief    Merges reco::CaloMuons, reco::Muons and optionally reco::Tracks avoiding innerTrack duplications in a single reco::Muon collection
0007             
0008   \author   Giovanni Petrucciani
0009 */
0010 
0011 #include "FWCore/Framework/interface/stream/EDProducer.h"
0012 #include "FWCore/Framework/interface/Event.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/Utilities/interface/InputTag.h"
0015 
0016 #include "DataFormats/MuonReco/interface/Muon.h"
0017 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0018 #include "DataFormats/MuonReco/interface/CaloMuon.h"
0019 
0020 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0021 
0022 class CaloMuonMerger : public edm::stream::EDProducer<> {
0023 public:
0024   explicit CaloMuonMerger(const edm::ParameterSet& iConfig);
0025   ~CaloMuonMerger() override {}
0026 
0027   void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0028 
0029 private:
0030   edm::InputTag muons_;
0031   StringCutObjectSelector<reco::Muon, false> muonsCut_;
0032   bool mergeCaloMuons_;
0033   edm::InputTag caloMuons_;
0034   StringCutObjectSelector<reco::CaloMuon, false> caloMuonsCut_;
0035   double minCaloCompatibility_;
0036   bool mergeTracks_;
0037   edm::InputTag tracks_;
0038   StringCutObjectSelector<reco::TrackRef, false> tracksCut_;
0039 
0040   edm::EDGetTokenT<std::vector<reco::Muon>> muonToken_;
0041   edm::EDGetTokenT<std::vector<reco::CaloMuon>> caloMuonToken_;
0042   edm::EDGetTokenT<std::vector<reco::Track>> trackToken_;
0043 };
0044 
0045 CaloMuonMerger::CaloMuonMerger(const edm::ParameterSet& iConfig)
0046     : muons_(iConfig.getParameter<edm::InputTag>("muons")),
0047       muonsCut_(iConfig.existsAs<std::string>("muonsCut") ? iConfig.getParameter<std::string>("muonsCut") : ""),
0048       mergeCaloMuons_(iConfig.existsAs<bool>("mergeCaloMuons") ? iConfig.getParameter<bool>("mergeCaloMuons") : true),
0049       caloMuons_(iConfig.getParameter<edm::InputTag>("caloMuons")),
0050       caloMuonsCut_(iConfig.existsAs<std::string>("caloMuonsCut") ? iConfig.getParameter<std::string>("caloMuonsCut")
0051                                                                   : ""),
0052       minCaloCompatibility_(mergeCaloMuons_ ? iConfig.getParameter<double>("minCaloCompatibility") : 0),
0053       mergeTracks_(iConfig.existsAs<bool>("mergeTracks") ? iConfig.getParameter<bool>("mergeTracks") : false),
0054       tracks_(mergeTracks_ ? iConfig.getParameter<edm::InputTag>("tracks") : edm::InputTag()),
0055       tracksCut_(iConfig.existsAs<std::string>("tracksCut") ? iConfig.getParameter<std::string>("tracksCut") : "") {
0056   muonToken_ = consumes<std::vector<reco::Muon>>(muons_);
0057   caloMuonToken_ = consumes<std::vector<reco::CaloMuon>>(caloMuons_);
0058   trackToken_ = consumes<std::vector<reco::Track>>(tracks_);
0059   produces<std::vector<reco::Muon>>();
0060 }
0061 
0062 void CaloMuonMerger::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0063   edm::Handle<std::vector<reco::Muon>> muons;
0064   edm::Handle<std::vector<reco::CaloMuon>> caloMuons;
0065   edm::Handle<std::vector<reco::Track>> tracks;
0066 
0067   iEvent.getByToken(muonToken_, muons);
0068   if (mergeCaloMuons_)
0069     iEvent.getByToken(caloMuonToken_, caloMuons);
0070   if (mergeTracks_)
0071     iEvent.getByToken(trackToken_, tracks);
0072 
0073   auto out = std::make_unique<std::vector<reco::Muon>>();
0074   out->reserve(muons->size() + (mergeTracks_ ? tracks->size() : 0));
0075 
0076   // copy reco::Muons, turning on the CaloCompatibility flag if enabled and possible
0077   for (std::vector<reco::Muon>::const_iterator it = muons->begin(), ed = muons->end(); it != ed; ++it) {
0078     if (!muonsCut_(*it))
0079       continue;
0080     out->push_back(*it);
0081     reco::Muon& mu = out->back();
0082     if (mergeCaloMuons_ && mu.track().isNonnull()) {
0083       if (mu.isCaloCompatibilityValid()) {
0084         if (mu.caloCompatibility() >= minCaloCompatibility_) {
0085           mu.setType(mu.type() | reco::Muon::CaloMuon);
0086         }
0087       } else
0088         throw cms::Exception("Boh") << "Muon with track and no CaloCompatibility; pt = " << mu.pt()
0089                                     << ", eta = " << mu.eta() << ", type = " << mu.type() << "\n";
0090     }
0091   }
0092 
0093   if (mergeCaloMuons_) {
0094     // copy reco::CaloMuon
0095     for (std::vector<reco::CaloMuon>::const_iterator it = caloMuons->begin(), ed = caloMuons->end(); it != ed; ++it) {
0096       if (!caloMuonsCut_(*it))
0097         continue;
0098       // make a reco::Muon
0099       reco::TrackRef track = it->track();
0100       double energy = sqrt(track->p() * track->p() + 0.011163691);
0101       math::XYZTLorentzVector p4(track->px(), track->py(), track->pz(), energy);
0102       out->push_back(reco::Muon(track->charge(), p4, track->vertex()));
0103       reco::Muon& mu = out->back();
0104       // fill info
0105       mu.setCalEnergy(it->calEnergy());
0106       mu.setCaloCompatibility(it->caloCompatibility());
0107       mu.setInnerTrack(track);
0108       mu.setType(reco::Muon::CaloMuon);
0109     }
0110   }
0111 
0112   // merge reco::Track avoiding duplication of innerTracks
0113   if (mergeTracks_) {
0114     for (size_t i = 0; i < tracks->size(); i++) {
0115       reco::TrackRef track(tracks, i);
0116       if (!tracksCut_(track))
0117         continue;
0118       // check if it is a muon or calomuon
0119       bool isMuon = false;
0120       for (std::vector<reco::Muon>::const_iterator muon = muons->begin(); muon < muons->end(); muon++) {
0121         if (muon->innerTrack() == track) {
0122           isMuon = true;
0123           break;
0124         }
0125       }
0126       if (isMuon)
0127         continue;
0128       if (mergeCaloMuons_) {
0129         bool isCaloMuon = false;
0130         for (std::vector<reco::CaloMuon>::const_iterator muon = caloMuons->begin(); muon < caloMuons->end(); muon++) {
0131           if (muon->innerTrack() == track) {
0132             isCaloMuon = true;
0133             break;
0134           }
0135         }
0136         if (isCaloMuon)
0137           continue;
0138       }
0139       // make a reco::Muon
0140       double energy = sqrt(track->p() * track->p() + 0.011163691);
0141       math::XYZTLorentzVector p4(track->px(), track->py(), track->pz(), energy);
0142       out->push_back(reco::Muon(track->charge(), p4, track->vertex()));
0143       reco::Muon& mu = out->back();
0144       // fill info
0145       mu.setInnerTrack(track);
0146     }
0147   }
0148 
0149   iEvent.put(std::move(out));
0150 }
0151 
0152 #include "FWCore/Framework/interface/MakerMacros.h"
0153 DEFINE_FWK_MODULE(CaloMuonMerger);