File indexing completed on 2024-04-06 12:27:00
0001
0002
0003
0004
0005
0006
0007
0008
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
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
0095 for (std::vector<reco::CaloMuon>::const_iterator it = caloMuons->begin(), ed = caloMuons->end(); it != ed; ++it) {
0096 if (!caloMuonsCut_(*it))
0097 continue;
0098
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
0105 mu.setCalEnergy(it->calEnergy());
0106 mu.setCaloCompatibility(it->caloCompatibility());
0107 mu.setInnerTrack(track);
0108 mu.setType(reco::Muon::CaloMuon);
0109 }
0110 }
0111
0112
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
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
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
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);