CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_10_patch2/src/ElectroWeakAnalysis/Utilities/src/DistortedMuonProducer.cc

Go to the documentation of this file.
00001 #include <memory>
00002 #include "FWCore/Framework/interface/Frameworkfwd.h"
00003 #include "FWCore/Framework/interface/MakerMacros.h"
00004 #include "FWCore/Framework/interface/EDProducer.h"
00005 #include "FWCore/Framework/interface/Event.h"
00006 
00007 #include "MuonAnalysis/MomentumScaleCalibration/interface/MomentumScaleCorrector.h"
00008 #include "MuonAnalysis/MomentumScaleCalibration/interface/ResolutionFunction.h"
00009 
00010 //
00011 // class declaration
00012 //
00013 class DistortedMuonProducer : public edm::EDProducer {
00014    public:
00015       explicit DistortedMuonProducer(const edm::ParameterSet&);
00016       ~DistortedMuonProducer();
00017 
00018    private:
00019       virtual void beginJob() ;
00020       virtual void produce(edm::Event&, const edm::EventSetup&);
00021       virtual void endJob() ;
00022 
00023       edm::InputTag muonTag_;
00024       edm::InputTag genMatchMapTag_;
00025       std::vector<double> etaBinEdges_;
00026 
00027       std::vector<double> shiftOnOneOverPt_; // in [1/GeV]
00028       std::vector<double> relativeShiftOnPt_;
00029       std::vector<double> uncertaintyOnOneOverPt_; // in [1/GeV]
00030       std::vector<double> relativeUncertaintyOnPt_;
00031 
00032       std::vector<double> efficiencyRatioOverMC_;
00033 };
00034 
00035 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00036 #include "DataFormats/Common/interface/Handle.h"
00037 #include "DataFormats/Common/interface/View.h"
00038 #include "DataFormats/MuonReco/interface/Muon.h"
00039 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00040 #include "DataFormats/TrackReco/interface/Track.h"
00041 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00042 
00043 #include <CLHEP/Random/RandFlat.h>
00044 #include <CLHEP/Random/RandGauss.h>
00045 
00047 DistortedMuonProducer::DistortedMuonProducer(const edm::ParameterSet& pset) {
00048 
00049   // What is being produced
00050       produces<std::vector<reco::Muon> >();
00051 
00052   // Input products
00053       muonTag_ = pset.getUntrackedParameter<edm::InputTag> ("MuonTag", edm::InputTag("muons"));
00054       genMatchMapTag_ = pset.getUntrackedParameter<edm::InputTag> ("GenMatchMapTag", edm::InputTag("genMatchMap"));
00055 
00056   // Eta edges
00057       std::vector<double> defEtaEdges;
00058       defEtaEdges.push_back(-999999.);
00059       defEtaEdges.push_back(999999.);
00060       etaBinEdges_ = pset.getUntrackedParameter<std::vector<double> > ("EtaBinEdges",defEtaEdges);
00061       unsigned int ninputs_expected = etaBinEdges_.size()-1;
00062 
00063   // Distortions in muon momentum
00064       std::vector<double> defDistortion;
00065       defDistortion.push_back(0.);
00066 
00067       shiftOnOneOverPt_ = pset.getUntrackedParameter<std::vector<double> > ("ShiftOnOneOverPt",defDistortion); // in [1/GeV]
00068       if (shiftOnOneOverPt_.size()==1 && ninputs_expected>1) {
00069             for (unsigned int i=1; i<ninputs_expected; i++){ shiftOnOneOverPt_.push_back(shiftOnOneOverPt_[0]);}
00070       }
00071 
00072       relativeShiftOnPt_ = pset.getUntrackedParameter<std::vector<double> > ("RelativeShiftOnPt",defDistortion);
00073       if (relativeShiftOnPt_.size()==1 && ninputs_expected>1) {
00074             for (unsigned int i=1; i<ninputs_expected; i++){ relativeShiftOnPt_.push_back(relativeShiftOnPt_[0]);}
00075       }
00076 
00077       uncertaintyOnOneOverPt_ = pset.getUntrackedParameter<std::vector<double> > ("UncertaintyOnOneOverPt",defDistortion); // in [1/GeV]
00078       if (uncertaintyOnOneOverPt_.size()==1 && ninputs_expected>1) {
00079             for (unsigned int i=1; i<ninputs_expected; i++){ uncertaintyOnOneOverPt_.push_back(uncertaintyOnOneOverPt_[0]);}
00080       }
00081 
00082       relativeUncertaintyOnPt_ = pset.getUntrackedParameter<std::vector<double> > ("RelativeUncertaintyOnPt",defDistortion);
00083       if (relativeUncertaintyOnPt_.size()==1 && ninputs_expected>1) {
00084             for (unsigned int i=1; i<ninputs_expected; i++){ relativeUncertaintyOnPt_.push_back(relativeUncertaintyOnPt_[0]);}
00085       }
00086 
00087   // Data/MC efficiency ratios
00088       std::vector<double> defEfficiencyRatio;
00089       defEfficiencyRatio.push_back(1.);
00090       efficiencyRatioOverMC_ = pset.getUntrackedParameter<std::vector<double> > ("EfficiencyRatioOverMC",defEfficiencyRatio);
00091       if (efficiencyRatioOverMC_.size()==1 && ninputs_expected>1) {
00092             for (unsigned int i=1; i<ninputs_expected; i++){ efficiencyRatioOverMC_.push_back(efficiencyRatioOverMC_[0]);}
00093       }
00094 
00095   // Send a warning if there are inconsistencies in vector sizes !!
00096       bool effWrong = efficiencyRatioOverMC_.size()!=ninputs_expected;
00097       bool momWrong =    shiftOnOneOverPt_.size()!=ninputs_expected 
00098                       || relativeShiftOnPt_.size()!=ninputs_expected 
00099                       || uncertaintyOnOneOverPt_.size()!=ninputs_expected 
00100                       || relativeUncertaintyOnPt_.size()!=ninputs_expected;
00101       if ( effWrong and momWrong) {
00102            edm::LogError("") << "WARNING: DistortedMuonProducer : Size of some parameters do not match the EtaBinEdges vector!!";
00103       }
00104 
00105 } 
00106 
00108 DistortedMuonProducer::~DistortedMuonProducer(){
00109 }
00110 
00112 void DistortedMuonProducer::beginJob() {
00113 }
00114 
00116 void DistortedMuonProducer::endJob(){
00117 }
00118 
00120 void DistortedMuonProducer::produce(edm::Event& ev, const edm::EventSetup& iSetup) {
00121 
00122       if (ev.isRealData()) return;
00123 
00124       // Muon collection
00125       edm::Handle<edm::View<reco::Muon> > muonCollection;
00126       if (!ev.getByLabel(muonTag_, muonCollection)) {
00127             edm::LogError("") << ">>> Muon collection does not exist !!!";
00128             return;
00129       }
00130 
00131       edm::Handle<reco::GenParticleMatch> genMatchMap;
00132       if (!ev.getByLabel(genMatchMapTag_, genMatchMap)) {
00133             edm::LogError("") << ">>> Muon-GenParticle match map does not exist !!!";
00134             return;
00135       }
00136   
00137       unsigned int muonCollectionSize = muonCollection->size();
00138 
00139       std::auto_ptr<reco::MuonCollection> newmuons (new reco::MuonCollection);
00140 
00141       for (unsigned int i=0; i<muonCollectionSize; i++) {
00142             edm::RefToBase<reco::Muon> mu = muonCollection->refAt(i);
00143 
00144             double ptgen = mu->pt();
00145             double etagen = mu->eta();
00146             reco::GenParticleRef gen = (*genMatchMap)[mu];
00147             if( !gen.isNull()) {
00148                   ptgen = gen->pt();
00149                   etagen = gen->eta();
00150                   LogTrace("") << ">>> Muon-GenParticle match found; ptmu= " << mu->pt() << ", ptgen= " << ptgen;
00151             } else {
00152                   LogTrace("") << ">>> MUON-GENPARTICLE MATCH NOT FOUND!!!";
00153             }
00154 
00155             // Initialize parameters
00156             double effRatio = 0.;
00157             double shift1 = 0.;
00158             double shift2 = 0.;
00159             double sigma1 = 0.;
00160             double sigma2 = 0.;
00161 
00162             // Find out which eta bin should be used
00163             unsigned int nbins = etaBinEdges_.size()-1;
00164             unsigned int etaBin = nbins;
00165             if (etagen>etaBinEdges_[0] && etagen<etaBinEdges_[nbins]) {
00166                   for (unsigned int j=1; j<=nbins; ++j) {
00167                         if (etagen>etaBinEdges_[j]) continue;
00168                         etaBin = j-1;
00169                         break;
00170                   }
00171             }
00172             if (etaBin<nbins) {
00173                   LogTrace("") << ">>> etaBin: " << etaBin << ", for etagen =" << etagen;
00174             } else {
00175                   // Muon is rejected if outside the considered eta range
00176                   LogTrace("") << ">>> Muon outside eta range: reject it; etagen = " << etagen;
00177                   continue;
00178             }
00179 
00180             // Set shifts
00181             shift1 = shiftOnOneOverPt_[etaBin];
00182             shift2 = relativeShiftOnPt_[etaBin];
00183             LogTrace("") << "\tshiftOnOneOverPt= " << shift1*100 << " [%]"; 
00184             LogTrace("") << "\trelativeShiftOnPt= " << shift2*100 << " [%]"; 
00185 
00186             // Set resolutions
00187             sigma1 = uncertaintyOnOneOverPt_[etaBin];
00188             sigma2 = relativeUncertaintyOnPt_[etaBin];
00189             LogTrace("") << "\tuncertaintyOnOneOverPt= " << sigma1 << " [1/GeV]"; 
00190             LogTrace("") << "\trelativeUncertaintyOnPt= " << sigma2*100 << " [%]"; 
00191 
00192             // Set efficiency ratio
00193             effRatio = efficiencyRatioOverMC_[etaBin];
00194             LogTrace("") << "\tefficiencyRatioOverMC= " << effRatio;
00195 
00196             // Reject muons according to efficiency ratio
00197             double rndf = CLHEP::RandFlat::shoot();
00198             if (rndf>effRatio) continue;
00199 
00200             // Gaussian Random numbers for smearing
00201             double rndg1 = CLHEP::RandGauss::shoot();
00202             double rndg2 = CLHEP::RandGauss::shoot();
00203             
00204             // New muon
00205             double ptmu = mu->pt();
00206             ptmu += ptgen * ( shift1*ptgen + shift2 + sigma1*rndg1*ptgen + sigma2*rndg2);
00207             reco::Muon* newmu = mu->clone();
00208             newmu->setP4 (
00209                   reco::Particle::PolarLorentzVector (
00210                         ptmu, mu->eta(), mu->phi(), mu->mass()
00211                   )
00212             );
00213             newmuons->push_back(*newmu);
00214 
00215       }
00216 
00217       ev.put(newmuons);
00218 }
00219 
00220 DEFINE_FWK_MODULE(DistortedMuonProducer);