00001
00009
00010 #include "FWCore/Framework/interface/EDAnalyzer.h"
00011 #include "DQMOffline/Muon/interface/MuonPFAnalyzer.h"
00012
00013 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
00014
00015 #include "DataFormats/GeometryVector/interface/Pi.h"
00016 #include "DataFormats/Math/interface/deltaR.h"
00017
00018
00019 #include <memory>
00020 #include <string>
00021 #include <typeinfo>
00022 #include <utility>
00023
00024
00025 #include "TH1.h"
00026 #include "TH2.h"
00027 #include "TProfile.h"
00028
00029
00030
00031 #include "FWCore/Framework/interface/MakerMacros.h"
00032 #include "FWCore/Framework/interface/Event.h"
00033 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00034
00035 #include "FWCore/Utilities/interface/InputTag.h"
00036 #include "DQMServices/Core/interface/DQMStore.h"
00037 #include "DQMServices/Core/interface/MonitorElement.h"
00038 #include "FWCore/ServiceRegistry/interface/Service.h"
00039
00040 using namespace edm;
00041 using namespace std;
00042 using namespace reco;
00043
00044
00045 MuonPFAnalyzer::MuonPFAnalyzer(const ParameterSet& pSet)
00046
00047 {
00048
00049 LogTrace("MuonPFAnalyzer") <<
00050 "[MuonPFAnalyzer] Initializing configuration from parameterset.\n";
00051
00052 theGenLabel = pSet.getParameter<InputTag>("inputTagGenParticles");
00053 theRecoLabel = pSet.getParameter<InputTag>("inputTagMuonReco");
00054 theBeamSpotLabel = pSet.getParameter<InputTag>("inputTagBeamSpot");
00055 theVertexLabel = pSet.getParameter<InputTag>("inputTagVertex");
00056
00057 theHighPtTh = pSet.getParameter<double>("highPtThreshold");
00058 theRecoGenR = pSet.getParameter<double>("recoGenDeltaR");
00059 theIsoCut = pSet.getParameter<double>("relCombIsoCut");
00060 theRunOnMC = pSet.getParameter<bool>("runOnMC");
00061
00062 theFolder = pSet.getParameter<string>("folder");
00063
00064 theMuonKinds.push_back("");
00065 theMuonKinds.push_back("Tight");
00066 theMuonKinds.push_back("TightIso");
00067
00068
00069 }
00070
00071
00072 MuonPFAnalyzer::~MuonPFAnalyzer()
00073 {
00074
00075 LogTrace("MuonPFAnalyzer") <<
00076 "[MuonPFAnalyzer] Destructor called.\n";
00077
00078 }
00079
00080
00081
00082
00083
00084 void MuonPFAnalyzer::beginRun(edm::Run const &, edm::EventSetup const &) {
00085
00086 LogTrace("MuonPFAnalyzer") <<
00087 "[MuonPFAnalyzer] Booking histograms.\n";
00088
00089
00090 theDbe = 0;
00091 theDbe = edm::Service<DQMStore>().operator->();
00092 theDbe->cd();
00093
00094 if(theRunOnMC)
00095 {
00096 bookHistos("PF");
00097 bookHistos("PFTight");
00098 bookHistos("PFTightIso");
00099 bookHistos("TUNEP");
00100 bookHistos("TUNEPTight");
00101 bookHistos("TUNEPTightIso");
00102 }
00103
00104 bookHistos("PFvsTUNEP");
00105 bookHistos("PFvsTUNEPTight");
00106 bookHistos("PFvsTUNEPTightIso");
00107
00108
00109 }
00110
00111 void MuonPFAnalyzer::analyze(const Event& event,
00112 const EventSetup& context)
00113 {
00114
00115 Handle<reco::MuonCollection> muons;
00116 event.getByLabel(theRecoLabel, muons);
00117
00118 Handle<GenParticleCollection> genMuons;
00119 event.getByLabel(theGenLabel, genMuons);
00120
00121 Handle<BeamSpot> beamSpot;
00122 event.getByLabel(theBeamSpotLabel, beamSpot);
00123
00124 Handle<VertexCollection> vertex;
00125 event.getByLabel(theVertexLabel, vertex);
00126
00127 const Vertex primaryVertex = getPrimaryVertex(vertex, beamSpot);
00128
00129 recoToGenMatch(muons, genMuons);
00130
00131 RecoGenCollection::const_iterator recoGenIt = theRecoGen.begin();
00132 RecoGenCollection::const_iterator recoGenEnd = theRecoGen.end();
00133
00134 for (;recoGenIt!=recoGenEnd;++recoGenIt)
00135 {
00136
00137 const Muon *muon = recoGenIt->first;
00138 TrackRef tunePTrack = muon->tunePMuonBestTrack();
00139
00140 const GenParticle *genMuon = recoGenIt->second;
00141
00142 vector<string>::const_iterator kindIt = theMuonKinds.begin();
00143 vector<string>::const_iterator kindEnd = theMuonKinds.end();
00144
00145 for (;kindIt!=kindEnd;++kindIt)
00146 {
00147
00148 const string & kind = (*kindIt);
00149
00150 if (kind.find("Tight") != string::npos &&
00151 !muon::isTightMuon((*muon), primaryVertex)) continue;
00152
00153 if (kind.find("Iso") != string::npos &&
00154 combRelIso(muon) > theIsoCut) continue;
00155
00156 if (theRunOnMC && genMuon && !muon->innerTrack().isNull() )
00157 {
00158
00159 if (!tunePTrack.isNull())
00160 {
00161
00162 string group = "TUNEP" + kind;
00163
00164 float pt = tunePTrack->pt();
00165 float phi = tunePTrack->phi();
00166 float eta = tunePTrack->eta();
00167
00168 float genPt = genMuon->pt();
00169 float genPhi = genMuon->p4().phi();
00170 float genEta = genMuon->p4().eta();
00171
00172 float dPtOverPt = (pt / genPt) - 1;
00173
00174 if (pt < theHighPtTh)
00175 {
00176
00177 fillInRange(getPlot(group,"code"),1,muonTrackType(muon, false));
00178 fillInRange(getPlot(group,"deltaPtOverPt"),1,dPtOverPt);
00179 }
00180 else
00181 {
00182 fillInRange(getPlot(group,"codeHighPt"),1,muonTrackType(muon, false));
00183 fillInRange(getPlot(group,"deltaPtOverPtHighPt"),1,dPtOverPt);
00184 }
00185
00186 fillInRange(getPlot(group,"deltaPt"),1,(pt - genPt));
00187 fillInRange(getPlot(group,"deltaPhi"),1,fDeltaPhi(genPhi,phi));
00188 fillInRange(getPlot(group,"deltaEta"),1,genEta - eta);
00189
00190 }
00191
00192 if (muon->isPFMuon())
00193 {
00194
00195 string group = "PF" + kind;
00196
00197
00198 float pt = muon->pt();
00199 float phi = muon->p4().phi();
00200 float eta = muon->p4().eta();
00201
00202 float genPt = genMuon->pt();
00203 float genPhi = genMuon->p4().phi();
00204 float genEta = genMuon->p4().eta();
00205
00206 float dPtOverPt = (pt / genPt) - 1;
00207
00208 if (pt < theHighPtTh)
00209 {
00210 fillInRange(getPlot(group,"code"),1,muonTrackType(muon, true));
00211 fillInRange(getPlot(group,"deltaPtOverPt"),1,dPtOverPt);
00212 }
00213 else
00214 {
00215 fillInRange(getPlot(group,"codeHighPt"),1,muonTrackType(muon, true));
00216 fillInRange(getPlot(group,"deltaPtOverPtHighPt"),1,dPtOverPt);
00217 }
00218
00219
00220 fillInRange(getPlot(group,"deltaPt"),1,pt - genPt);
00221 fillInRange(getPlot(group,"deltaPhi"),1,fDeltaPhi(genPhi,phi));
00222 fillInRange(getPlot(group,"deltaEta"),1,genEta - eta);
00223
00224 }
00225
00226 }
00227
00228
00229
00230 if (muon->isPFMuon() && !tunePTrack.isNull() &&
00231 !muon->innerTrack().isNull())
00232 {
00233
00234 string group = "PFvsTUNEP" + kind;
00235
00236 float pt = tunePTrack->pt();
00237 float phi = tunePTrack->phi();
00238 float eta = tunePTrack->eta();
00239
00240
00241 float pfPt = muon->pt();
00242 float pfPhi = muon->p4().phi();
00243 float pfEta = muon->p4().eta();
00244 float dPtOverPt = (pfPt / pt) - 1;
00245
00246
00247 if (pt < theHighPtTh)
00248 {
00249 fillInRange(getPlot(group,"code"),2,
00250 muonTrackType(muon, false),muonTrackType(muon, true));
00251 fillInRange(getPlot(group,"deltaPtOverPt"),1,dPtOverPt);
00252 }
00253 else
00254 {
00255 fillInRange(getPlot(group,"codeHighPt"),
00256 2,muonTrackType(muon, false),muonTrackType(muon, true));
00257 fillInRange(getPlot(group,"deltaPtOverPtHighPt"),1,dPtOverPt);
00258 }
00259
00260 fillInRange(getPlot(group,"deltaPt"),1,pfPt - pt);
00261 fillInRange(getPlot(group,"deltaPhi"),1,fDeltaPhi(pfPhi,phi));
00262 fillInRange(getPlot(group,"deltaEta"),1,pfEta - eta);
00263
00264
00265 if (theRunOnMC && genMuon)
00266
00267 {
00268
00269 float genPt = genMuon->pt();
00270 float dPtOverPtGen = (pt / genPt) - 1;
00271 float dPtOverPtGenPF = (pfPt / genPt) - 1;
00272
00273 if (pt < theHighPtTh)
00274 {
00275 fillInRange(getPlot(group,"deltaPtOverPtPFvsTUNEP"),
00276 2,dPtOverPtGen,dPtOverPtGenPF);
00277 }
00278 else
00279 {
00280 fillInRange(getPlot(group,"deltaPtOverPtHighPtPFvsTUNEP"),
00281 2,dPtOverPtGen,dPtOverPtGenPF);
00282 }
00283 }
00284
00285 }
00286
00287 }
00288
00289 }
00290
00291 }
00292
00293
00294
00295
00296 void MuonPFAnalyzer::bookHistos(const string & group) {
00297
00298
00299
00300 LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] Booking histos for group :"
00301 << group << "\n";
00302
00303 theDbe->setCurrentFolder(string(theFolder) + group);
00304
00305
00306 bool isPFvsTUNEP = group.find("PFvsTUNEP") != string::npos;
00307
00308 string hName;
00309
00310
00311 hName = "deltaPtOverPt" + group;
00312 thePlots[group]["deltaPtOverPt"] = theDbe->book1D(hName.c_str(),hName.c_str(),101,-1.01,1.01);
00313
00314 hName = "deltaPtOverPtHighPt" + group;
00315 thePlots[group]["deltaPtOverPtHighPt"] = theDbe->book1D(hName.c_str(),hName.c_str(),101,-1.01,1.01);
00316
00317 hName = "deltaPt" + group;
00318 thePlots[group]["deltaPt"] = theDbe->book1D(hName.c_str(),hName.c_str(),201.,-10.25,10.25);
00319
00320 hName = "deltaPhi"+group;
00321 thePlots[group]["deltaPhi"] = theDbe->book1D(hName.c_str(),hName.c_str(),51.,0,.0102);
00322
00323 hName = "deltaEta"+group;
00324 thePlots[group]["deltaEta"] = theDbe->book1D(hName.c_str(),hName.c_str(),101.,-.00505,.00505);
00325
00326
00327
00328 if (isPFvsTUNEP) {
00329
00330
00331 hName = "code"+group;
00332 MonitorElement * plot = theDbe->book2D(hName.c_str(),hName.c_str(),7,-.5,6.5,7,-.5,6.5);
00333 thePlots[group]["code"] = plot;
00334 setCodeLabels(plot,1);
00335 setCodeLabels(plot,2);
00336
00337 hName = "codeHighPt"+group;
00338 plot = theDbe->book2D(hName.c_str(),hName.c_str(),7,-.5,6.5,7,-.5,6.5);
00339 thePlots[group]["codeHighPt"] = plot;
00340 setCodeLabels(plot,1);
00341 setCodeLabels(plot,2);
00342
00343
00344 if (theRunOnMC)
00345 {
00346 hName = "deltaPtOverPtPFvsTUNEP" + group;
00347 thePlots[group]["deltaPtOverPtPFvsTUNEP"] =
00348 theDbe->book2D(hName.c_str(),hName.c_str(),
00349 101,-1.01,1.01,101,-1.01,1.01);
00350
00351 hName = "deltaPtOverPtHighPtPFvsTUNEP" + group;
00352 thePlots[group]["deltaPtOverPtHighPtPFvsTUNEP"] =
00353 theDbe->book2D(hName.c_str(),hName.c_str(),
00354 101,-1.01,1.01,101,-1.01,1.01);
00355 }
00356 } else {
00357 hName = "code"+group;
00358 MonitorElement * plot = theDbe->book1D(hName.c_str(),hName.c_str(),7,-.5,6.5);
00359 thePlots[group]["code"] = plot;
00360 setCodeLabels(plot,1);
00361
00362 hName = "codeHighPt"+group;
00363 plot = theDbe->book1D(hName.c_str(),hName.c_str(),7,-.5,6.5);
00364 thePlots[group]["codeHighPt"] = plot;
00365 setCodeLabels(plot,1);
00366 }
00367
00368 }
00369
00370
00371 MonitorElement * MuonPFAnalyzer::getPlot(const string & group,
00372 const string & type) {
00373
00374 map<string,map<string,MonitorElement *> >::iterator groupIt = thePlots.find(group);
00375 if (groupIt == thePlots.end()) {
00376 LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] GROUP : " << group
00377 << " is not a valid plot group. Returning 0.\n";
00378 return 0;
00379 }
00380
00381 map<string,MonitorElement *>::iterator typeIt = groupIt->second.find(type);
00382 if (typeIt == groupIt->second.end()) {
00383 LogTrace("MuonPFAnalyzer") << "[MuonPFAnalyzer] TYPE : " << type
00384 << " is not a valid type for GROUP : " << group
00385 << ". Returning 0.\n";
00386 return 0;
00387 }
00388
00389 return typeIt->second;
00390
00391 }
00392
00393
00394 inline float MuonPFAnalyzer::combRelIso(const reco::Muon * muon)
00395 {
00396
00397 MuonIsolation iso = muon->isolationR03();
00398 float combRelIso = (iso.emEt + iso.hadEt + iso.sumPt) / muon->pt();
00399
00400 return combRelIso;
00401
00402 }
00403
00404
00405 inline float MuonPFAnalyzer::fDeltaPhi(float phi1, float phi2) {
00406
00407 float fPhiDiff = fabs(acos(cos(phi1-phi2)));
00408 return fPhiDiff;
00409
00410 }
00411
00412
00413 void MuonPFAnalyzer::setCodeLabels(MonitorElement *plot, int nAxis)
00414 {
00415
00416 TAxis *axis = 0;
00417
00418 TH1 * histo = plot->getTH1();
00419 if(!histo) return;
00420
00421 if (nAxis==1)
00422 axis =histo->GetXaxis();
00423 else if (nAxis == 2)
00424 axis =histo->GetYaxis();
00425
00426 if(!axis) return;
00427
00428 axis->SetBinLabel(1,"Inner Track");
00429 axis->SetBinLabel(2,"Outer Track");
00430 axis->SetBinLabel(3,"Combined");
00431 axis->SetBinLabel(4,"TPFMS");
00432 axis->SetBinLabel(5,"Picky");
00433 axis->SetBinLabel(6,"DYT");
00434 axis->SetBinLabel(7,"None");
00435
00436 }
00437
00438
00439 void MuonPFAnalyzer::fillInRange(MonitorElement *plot, int nAxis, double x, double y)
00440 {
00441
00442 TH1 * histo = plot->getTH1();
00443
00444 TAxis *axis[2] = {0, 0};
00445 axis[0] = histo->GetXaxis();
00446 if (nAxis == 2)
00447 axis[1] = histo->GetYaxis();
00448
00449 double value[2] = {0, 0};
00450 value[0] = x;
00451 value[1] = y;
00452
00453 for (int i = 0;i<nAxis;++i)
00454 {
00455 double min = axis[i]->GetXmin();
00456 double max = axis[i]->GetXmax();
00457
00458 if (value[i] <= min)
00459 value[i] = axis[i]->GetBinCenter(1);
00460
00461 if (value[i] >= max)
00462 value[i] = axis[i]->GetBinCenter(axis[i]->GetNbins());
00463 }
00464
00465 if (nAxis == 2)
00466 plot->Fill(value[0],value[1]);
00467 else
00468 plot->Fill(value[0]);
00469
00470 }
00471
00472
00473 int MuonPFAnalyzer::muonTrackType(const Muon * muon, bool usePF) {
00474
00475 switch ( usePF ? muon->muonBestTrackType() : muon->tunePMuonBestTrackType() ) {
00476 case Muon::InnerTrack :
00477 return 0;
00478 case Muon::OuterTrack :
00479 return 1;
00480 case Muon::CombinedTrack :
00481 return 2;
00482 case Muon::TPFMS :
00483 return 3;
00484 case Muon::Picky :
00485 return 4;
00486 case Muon::DYT :
00487 return 5;
00488 case Muon::None :
00489 return 6;
00490 }
00491
00492 return 6;
00493
00494 }
00495
00496
00497 void MuonPFAnalyzer::recoToGenMatch( Handle<MuonCollection> & muons,
00498 Handle<GenParticleCollection> & gens )
00499 {
00500
00501 theRecoGen.clear();
00502
00503 if (muons.isValid())
00504 {
00505
00506 MuonCollection::const_iterator muonIt = muons->begin();
00507 MuonCollection::const_iterator muonEnd = muons->end();
00508
00509 for(; muonIt!=muonEnd; ++muonIt)
00510 {
00511
00512 float bestDR = 999.;
00513 const GenParticle *bestGen = 0;
00514
00515 if (theRunOnMC && gens.isValid())
00516 {
00517
00518 GenParticleCollection::const_iterator genIt = gens->begin();
00519 GenParticleCollection::const_iterator genEnd = gens->end();
00520
00521 for(; genIt!=genEnd; ++genIt)
00522 {
00523
00524 if (abs(genIt->pdgId()) == 13 )
00525 {
00526
00527 float muonPhi = muonIt->phi();
00528 float muonEta = muonIt->eta();
00529
00530 float genPhi = genIt->phi();
00531 float genEta = genIt->eta();
00532
00533 float dR = deltaR(muonEta,muonPhi,
00534 genEta,genPhi);
00535
00536 if (dR < theRecoGenR && dR < bestDR)
00537 {
00538 bestDR = dR;
00539 bestGen = &(*genIt);
00540 }
00541
00542 }
00543
00544 }
00545 }
00546
00547 theRecoGen.push_back(RecoGenPair(&(*muonIt), bestGen));
00548
00549 }
00550 }
00551
00552 }
00553
00554 const reco::Vertex MuonPFAnalyzer::getPrimaryVertex( Handle<VertexCollection> &vertex,
00555 Handle<BeamSpot> &beamSpot )
00556 {
00557
00558 Vertex::Point posVtx;
00559 Vertex::Error errVtx;
00560
00561 bool hasPrimaryVertex = false;
00562
00563 if (vertex.isValid())
00564 {
00565
00566 vector<Vertex>::const_iterator vertexIt = vertex->begin();
00567 vector<Vertex>::const_iterator vertexEnd = vertex->end();
00568
00569 for (;vertexIt!=vertexEnd;++vertexIt)
00570 {
00571 if (vertexIt->isValid() &&
00572 !vertexIt->isFake())
00573 {
00574 posVtx = vertexIt->position();
00575 errVtx = vertexIt->error();
00576 hasPrimaryVertex = true;
00577 break;
00578 }
00579 }
00580 }
00581
00582 if ( !hasPrimaryVertex ) {
00583
00584 LogInfo("MuonPFAnalyzer") <<
00585 "[MuonPFAnalyzer] PrimaryVertex not found, use BeamSpot position instead.\n";
00586
00587 posVtx = beamSpot->position();
00588 errVtx(0,0) = beamSpot->BeamWidthX();
00589 errVtx(1,1) = beamSpot->BeamWidthY();
00590 errVtx(2,2) = beamSpot->sigmaZ();
00591
00592 }
00593
00594 const Vertex primaryVertex(posVtx,errVtx);
00595
00596 return primaryVertex;
00597
00598 }
00599
00600
00601
00602 DEFINE_FWK_MODULE(MuonPFAnalyzer);