CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/RecoMuon/MuonIdentification/plugins/CaloMuonMerger.cc

Go to the documentation of this file.
00001 //
00002 // $Id: CaloMuonMerger.cc,v 1.6 2011/01/06 13:26:53 gpetrucc Exp $
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     // copy reco::Muons, turning on the CaloCompatibility flag if enabled and possible
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         // copy reco::CaloMuon 
00088         for (std::vector<reco::CaloMuon>::const_iterator it = caloMuons->begin(), ed = caloMuons->end(); it != ed; ++it) {
00089             if(!caloMuonsCut_(*it)) continue;
00090             // make a reco::Muon
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             // fill info 
00097             mu.setCalEnergy( it->calEnergy() );
00098             mu.setCaloCompatibility( it->caloCompatibility() );
00099             mu.setInnerTrack( track );
00100             mu.setType( reco::Muon::CaloMuon );
00101         }
00102     }
00103 
00104     // merge reco::Track avoiding duplication of innerTracks
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             // check if it is a muon or calomuon
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             // make a reco::Muon
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             // fill info 
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);