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
00006 #include "MuonAnalysis/MomentumScaleCalibration/interface/MomentumScaleCorrector.h"
00007 #include "MuonAnalysis/MomentumScaleCalibration/interface/ResolutionFunction.h"
00008
00009
00010
00011
00012 class DistortedPFCandProducer : public edm::EDProducer {
00013 public:
00014 explicit DistortedPFCandProducer(const edm::ParameterSet&);
00015 ~DistortedPFCandProducer();
00016
00017 private:
00018 virtual void beginJob() ;
00019 virtual void produce(edm::Event&, const edm::EventSetup&);
00020 virtual void endJob() ;
00021
00022 edm::InputTag muonTag_;
00023 edm::InputTag pfTag_;
00024 edm::InputTag genMatchMapTag_;
00025 std::vector<double> etaBinEdges_;
00026
00027 std::vector<double> shiftOnOneOverPt_;
00028 std::vector<double> relativeShiftOnPt_;
00029 std::vector<double> uncertaintyOnOneOverPt_;
00030 std::vector<double> relativeUncertaintyOnPt_;
00031
00032 std::vector<double> efficiencyRatioOverMC_;
00033 };
00034
00035 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00036 #include "FWCore/Framework/interface/Event.h"
00037 #include "DataFormats/Common/interface/Handle.h"
00038 #include "DataFormats/Common/interface/View.h"
00039 #include "DataFormats/MuonReco/interface/Muon.h"
00040 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00041 #include "DataFormats/TrackReco/interface/Track.h"
00042 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00043 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00044 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
00045
00046 #include <CLHEP/Random/RandFlat.h>
00047 #include <CLHEP/Random/RandGauss.h>
00048
00050 DistortedPFCandProducer::DistortedPFCandProducer(const edm::ParameterSet& pset) {
00051
00052
00053 produces<std::vector<reco::PFCandidate> >();
00054
00055
00056 muonTag_ = pset.getUntrackedParameter<edm::InputTag> ("MuonTag", edm::InputTag("muons"));
00057 pfTag_ = pset.getUntrackedParameter<edm::InputTag> ("PFTag", edm::InputTag("particleFlow"));
00058 genMatchMapTag_ = pset.getUntrackedParameter<edm::InputTag> ("GenMatchMapTag", edm::InputTag("genMatchMap"));
00059
00060
00061 std::vector<double> defEtaEdges;
00062 defEtaEdges.push_back(-999999.);
00063 defEtaEdges.push_back(999999.);
00064 etaBinEdges_ = pset.getUntrackedParameter<std::vector<double> > ("EtaBinEdges",defEtaEdges);
00065 unsigned int ninputs_expected = etaBinEdges_.size()-1;
00066
00067
00068 std::vector<double> defDistortion;
00069 defDistortion.push_back(0.);
00070
00071 shiftOnOneOverPt_ = pset.getUntrackedParameter<std::vector<double> > ("ShiftOnOneOverPt",defDistortion);
00072 if (shiftOnOneOverPt_.size()==1 && ninputs_expected>1) {
00073 for (unsigned int i=1; i<ninputs_expected; i++){ shiftOnOneOverPt_.push_back(shiftOnOneOverPt_[0]);}
00074 }
00075
00076 relativeShiftOnPt_ = pset.getUntrackedParameter<std::vector<double> > ("RelativeShiftOnPt",defDistortion);
00077 if (relativeShiftOnPt_.size()==1 && ninputs_expected>1) {
00078 for (unsigned int i=1; i<ninputs_expected; i++){ relativeShiftOnPt_.push_back(relativeShiftOnPt_[0]);}
00079 }
00080
00081 uncertaintyOnOneOverPt_ = pset.getUntrackedParameter<std::vector<double> > ("UncertaintyOnOneOverPt",defDistortion);
00082 if (uncertaintyOnOneOverPt_.size()==1 && ninputs_expected>1) {
00083 for (unsigned int i=1; i<ninputs_expected; i++){ uncertaintyOnOneOverPt_.push_back(uncertaintyOnOneOverPt_[0]);}
00084 }
00085
00086 relativeUncertaintyOnPt_ = pset.getUntrackedParameter<std::vector<double> > ("RelativeUncertaintyOnPt",defDistortion);
00087 if (relativeUncertaintyOnPt_.size()==1 && ninputs_expected>1) {
00088 for (unsigned int i=1; i<ninputs_expected; i++){ relativeUncertaintyOnPt_.push_back(relativeUncertaintyOnPt_[0]);}
00089 }
00090
00091
00092 std::vector<double> defEfficiencyRatio;
00093 defEfficiencyRatio.push_back(1.);
00094 efficiencyRatioOverMC_ = pset.getUntrackedParameter<std::vector<double> > ("EfficiencyRatioOverMC",defEfficiencyRatio);
00095 if (efficiencyRatioOverMC_.size()==1 && ninputs_expected>1) {
00096 for (unsigned int i=1; i<ninputs_expected; i++){ efficiencyRatioOverMC_.push_back(efficiencyRatioOverMC_[0]);}
00097 }
00098
00099
00100 bool effWrong = efficiencyRatioOverMC_.size()!=ninputs_expected;
00101 bool momWrong = shiftOnOneOverPt_.size()!=ninputs_expected
00102 || relativeShiftOnPt_.size()!=ninputs_expected
00103 || uncertaintyOnOneOverPt_.size()!=ninputs_expected
00104 || relativeUncertaintyOnPt_.size()!=ninputs_expected;
00105 if ( effWrong and momWrong) {
00106 edm::LogError("") << "WARNING: DistortedPFCandProducer : Size of some parameters do not match the EtaBinEdges vector!!";
00107 }
00108
00109 }
00110
00112 DistortedPFCandProducer::~DistortedPFCandProducer(){
00113 }
00114
00116 void DistortedPFCandProducer::beginJob() {
00117 }
00118
00120 void DistortedPFCandProducer::endJob(){
00121 }
00122
00124 void DistortedPFCandProducer::produce(edm::Event& ev, const edm::EventSetup& iSetup) {
00125
00126 if (ev.isRealData()) return;
00127
00128
00129 edm::Handle<edm::View<reco::Muon> > muonCollection;
00130 if (!ev.getByLabel(muonTag_, muonCollection)) {
00131 edm::LogError("") << ">>> Muon collection does not exist !!!";
00132 return;
00133 }
00134
00135 edm::Handle<reco::GenParticleMatch> genMatchMap;
00136 if (!ev.getByLabel(genMatchMapTag_, genMatchMap)) {
00137 edm::LogError("") << ">>> Muon-GenParticle match map does not exist !!!";
00138 return;
00139 }
00140
00141
00142
00143 edm::Handle<edm::View<reco::PFCandidate> > pfCollection;
00144 if (!ev.getByLabel(pfTag_, pfCollection)) {
00145 edm::LogError("") << ">>> PFCandidate collection does not exist !!!";
00146 return;
00147 }
00148
00149 unsigned int muonCollectionSize = muonCollection->size();
00150 unsigned int pfCollectionSize = pfCollection->size();
00151
00152 if (pfCollectionSize<1) return;
00153
00154
00155
00156 bool pfMuonFound = false;
00157
00158
00159
00160 std::auto_ptr<reco::PFCandidateCollection> newmuons (new reco::PFCandidateCollection);
00161
00162
00163
00164 for (unsigned int j=0; j<pfCollectionSize; j++) {
00165 edm::RefToBase<reco::PFCandidate> pf = pfCollection->refAt(j);
00166
00167
00168
00169 double ptmu = pf->pt();
00170
00171
00172 for (unsigned int i=0; i<muonCollectionSize; i++) {
00173 edm::RefToBase<reco::Muon> mu = muonCollection->refAt(i);
00174
00175
00176
00177 if (pf->particleId()==reco::PFCandidate::mu) {
00178 reco::MuonRef muref = pf->muonRef();
00179 if (muref.isNonnull()) {
00180 if (muref.key()==mu.key()) {
00181 if ( mu->isStandAloneMuon() && ptmu == muref->standAloneMuon()->pt() && (
00182 ( !mu->isGlobalMuon() || ( mu->isGlobalMuon() && ptmu != muref->combinedMuon()->pt() ) ) &&
00183 ( !mu->isTrackerMuon() || ( mu->isTrackerMuon() && ptmu != mu->track()->pt() ) ) )
00184 ) {
00185 pfMuonFound = false;
00186 }
00187 else if ( !mu->isTrackerMuon() ){
00188 pfMuonFound = false;
00189 }
00190 else{
00191 pfMuonFound = true;}
00192 }
00193 else {pfMuonFound = false; }
00194
00195 }
00196 }
00197
00198
00199
00200
00201 if ( !pfMuonFound) continue;
00202
00203 double ptgen = pf->pt();
00204 double etagen = pf->eta();
00205
00206
00207 reco::GenParticleRef gen = (*genMatchMap)[mu];
00208 if( !gen.isNull()) {
00209 ptgen = gen->pt();
00210 etagen = gen->eta();
00211 LogTrace("") << ">>> Muon-GenParticle match found; ptmu= " << pf->pt() << ", ptgen= " << ptgen;
00212 } else {
00213 LogTrace("") << ">>> MUON-GENPARTICLE MATCH NOT FOUND!!!";
00214 }
00215
00216
00217
00218 double effRatio = 0.;
00219 double shift1 = 0.;
00220 double shift2 = 0.;
00221 double sigma1 = 0.;
00222 double sigma2 = 0.;
00223
00224
00225 unsigned int nbins = etaBinEdges_.size()-1;
00226 unsigned int etaBin = nbins;
00227 if (etagen>etaBinEdges_[0] && etagen<etaBinEdges_[nbins]) {
00228 for (unsigned int j=1; j<=nbins; ++j) {
00229 if (etagen>etaBinEdges_[j]) continue;
00230 etaBin = j-1;
00231 break;
00232 }
00233 }
00234 if (etaBin<nbins) {
00235 LogTrace("") << ">>> etaBin: " << etaBin << ", for etagen =" << etagen;
00236 } else {
00237
00238 LogTrace("") << ">>> Muon outside eta range: reject it; etagen = " << etagen;
00239 pfMuonFound = false;
00240 continue;
00241 }
00242
00243 if (!pfMuonFound) continue;
00244
00245
00246 shift1 = shiftOnOneOverPt_[etaBin];
00247 shift2 = relativeShiftOnPt_[etaBin];
00248 LogTrace("") << "\tshiftOnOneOverPt= " << shift1*100 << " [%]";
00249 LogTrace("") << "\trelativeShiftOnPt= " << shift2*100 << " [%]";
00250
00251
00252 sigma1 = uncertaintyOnOneOverPt_[etaBin];
00253 sigma2 = relativeUncertaintyOnPt_[etaBin];
00254 LogTrace("") << "\tuncertaintyOnOneOverPt= " << sigma1 << " [1/GeV]";
00255 LogTrace("") << "\trelativeUncertaintyOnPt= " << sigma2*100 << " [%]";
00256
00257
00258 effRatio = efficiencyRatioOverMC_[etaBin];
00259 LogTrace("") << "\tefficiencyRatioOverMC= " << effRatio;
00260
00261
00262 double rndf = CLHEP::RandFlat::shoot();
00263 if (rndf>effRatio) continue;
00264
00265
00266 double rndg1 = CLHEP::RandGauss::shoot();
00267 double rndg2 = CLHEP::RandGauss::shoot();
00268
00269
00270
00271
00272 ptmu += ptgen * ( shift1*ptgen + shift2 + sigma1*rndg1*ptgen + sigma2*rndg2);
00273 pfMuonFound = false ;
00274
00275 }
00276
00277 reco::PFCandidate* newmu = pf->clone();
00278 newmu->setP4 (
00279 reco::Particle::PolarLorentzVector (
00280 ptmu, pf->eta(), pf->phi(), pf->mass()
00281 )
00282 );
00283
00284 newmuons->push_back(*newmu);
00285 }
00286
00287
00288 ev.put(newmuons);
00289
00290
00291 }
00292
00293 DEFINE_FWK_MODULE(DistortedPFCandProducer);