Go to the documentation of this file.00001
00002
00003
00004
00014 #include "FWCore/Framework/interface/EDProducer.h"
00015 #include "FWCore/Framework/interface/Event.h"
00016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00017 #include "FWCore/Utilities/interface/InputTag.h"
00018
00019 #include "DataFormats/MuonReco/interface/Muon.h"
00020 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00021 #include "DataFormats/MuonReco/interface/CaloMuon.h"
00022
00023 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
00024
00025 class CaloMuonMerger : public edm::EDProducer {
00026 public:
00027 explicit CaloMuonMerger(const edm::ParameterSet & iConfig);
00028 virtual ~CaloMuonMerger() { }
00029
00030 virtual void produce(edm::Event & iEvent, const edm::EventSetup & iSetup);
00031
00032 private:
00033 edm::InputTag muons_;
00034 StringCutObjectSelector<reco::Muon, false> muonsCut_;
00035 bool mergeCaloMuons_;
00036 edm::InputTag caloMuons_;
00037 StringCutObjectSelector<reco::CaloMuon, false> caloMuonsCut_;
00038 double minCaloCompatibility_;
00039 bool mergeTracks_;
00040 edm::InputTag tracks_;
00041 StringCutObjectSelector<reco::TrackRef, false> tracksCut_;
00042 };
00043
00044
00045 CaloMuonMerger::CaloMuonMerger(const edm::ParameterSet & iConfig) :
00046 muons_(iConfig.getParameter<edm::InputTag>("muons")),
00047 muonsCut_(iConfig.existsAs<std::string>("muonsCut") ? iConfig.getParameter<std::string>("muonsCut") : ""),
00048 mergeCaloMuons_(iConfig.existsAs<bool>("mergeCaloMuons") ? iConfig.getParameter<bool>("mergeCaloMuons") : true),
00049 caloMuons_(iConfig.getParameter<edm::InputTag>("caloMuons")),
00050 caloMuonsCut_(iConfig.existsAs<std::string>("caloMuonsCut") ? iConfig.getParameter<std::string>("caloMuonsCut") : ""),
00051 minCaloCompatibility_(mergeCaloMuons_ ? iConfig.getParameter<double>("minCaloCompatibility") : 0),
00052 mergeTracks_(iConfig.existsAs<bool>("mergeTracks") ? iConfig.getParameter<bool>("mergeTracks") : false),
00053 tracks_(mergeTracks_ ? iConfig.getParameter<edm::InputTag>("tracks") : edm::InputTag()),
00054 tracksCut_(iConfig.existsAs<std::string>("tracksCut") ? iConfig.getParameter<std::string>("tracksCut") : "")
00055 {
00056 produces<std::vector<reco::Muon> >();
00057 }
00058
00059 void
00060 CaloMuonMerger::produce(edm::Event & iEvent, const edm::EventSetup & iSetup) {
00061 edm::Handle<std::vector<reco::Muon> > muons;
00062 edm::Handle<std::vector<reco::CaloMuon> > caloMuons;
00063 edm::Handle<std::vector<reco::Track> > tracks;
00064
00065 iEvent.getByLabel(muons_, muons);
00066 if(mergeCaloMuons_) iEvent.getByLabel(caloMuons_, caloMuons);
00067 if(mergeTracks_) iEvent.getByLabel(tracks_, tracks);
00068
00069 std::auto_ptr<std::vector<reco::Muon> > out(new std::vector<reco::Muon>());
00070 out->reserve(muons->size() + (mergeTracks_?tracks->size():0));
00071
00072
00073 for (std::vector<reco::Muon>::const_iterator it = muons->begin(), ed = muons->end(); it != ed; ++it) {
00074 if(!muonsCut_(*it)) continue;
00075 out->push_back(*it);
00076 reco::Muon & mu = out->back();
00077 if (mergeCaloMuons_ && mu.track().isNonnull()) {
00078 if (mu.isCaloCompatibilityValid()) {
00079 if (mu.caloCompatibility() >= minCaloCompatibility_) {
00080 mu.setType(mu.type() | reco::Muon::CaloMuon);
00081 }
00082 } else throw cms::Exception("Boh") << "Muon with track and no CaloCompatibility; pt = " << mu.pt() << ", eta = " << mu.eta() << ", type = " << mu.type() << "\n";
00083 }
00084 }
00085
00086 if (mergeCaloMuons_) {
00087
00088 for (std::vector<reco::CaloMuon>::const_iterator it = caloMuons->begin(), ed = caloMuons->end(); it != ed; ++it) {
00089 if(!caloMuonsCut_(*it)) continue;
00090
00091 reco::TrackRef track = it->track();
00092 double energy = sqrt(track->p() * track->p() + 0.011163691);
00093 math::XYZTLorentzVector p4(track->px(), track->py(), track->pz(), energy);
00094 out->push_back(reco::Muon(track->charge(), p4, track->vertex()));
00095 reco::Muon & mu = out->back();
00096
00097 mu.setCalEnergy( it->calEnergy() );
00098 mu.setCaloCompatibility( it->caloCompatibility() );
00099 mu.setInnerTrack( track );
00100 mu.setType( reco::Muon::CaloMuon );
00101 }
00102 }
00103
00104
00105 if(mergeTracks_){
00106 for (size_t i = 0; i < tracks->size(); i++) {
00107 reco::TrackRef track(tracks, i);
00108 if(!tracksCut_(track)) continue;
00109
00110 bool isMuon = false;
00111 for(std::vector<reco::Muon>::const_iterator muon = muons->begin(); muon < muons->end(); muon++){
00112 if(muon->innerTrack() == track){
00113 isMuon = true;
00114 break;
00115 }
00116 }
00117 if(isMuon) continue;
00118 if (mergeCaloMuons_) {
00119 bool isCaloMuon = false;
00120 for(std::vector<reco::CaloMuon>::const_iterator muon = caloMuons->begin(); muon < caloMuons->end(); muon++){
00121 if(muon->innerTrack() == track){
00122 isCaloMuon = true;
00123 break;
00124 }
00125 }
00126 if(isCaloMuon) continue;
00127 }
00128
00129 double energy = sqrt(track->p() * track->p() + 0.011163691);
00130 math::XYZTLorentzVector p4(track->px(), track->py(), track->pz(), energy);
00131 out->push_back(reco::Muon(track->charge(), p4, track->vertex()));
00132 reco::Muon & mu = out->back();
00133
00134 mu.setInnerTrack( track );
00135 }
00136 }
00137
00138 iEvent.put(out);
00139 }
00140
00141 #include "FWCore/Framework/interface/MakerMacros.h"
00142 DEFINE_FWK_MODULE(CaloMuonMerger);