00001
00009 #include "DQMOffline/Trigger/interface/HLTMuonMatchAndPlot.h"
00010
00011 #include "FWCore/Framework/interface/Run.h"
00012 #include "FWCore/Framework/interface/EventSetup.h"
00013
00014 #include "FWCore/ServiceRegistry/interface/Service.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 #include "DataFormats/Common/interface/Handle.h"
00017 #include "DataFormats/HLTReco/interface/TriggerEventWithRefs.h"
00018 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
00019 #include "DataFormats/Candidate/interface/CandMatchMap.h"
00020 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00021 #include "DataFormats/VertexReco/interface/Vertex.h"
00022 #include "DataFormats/Common/interface/TriggerResults.h"
00023
00024 #include <iostream>
00025
00028
00029 using namespace std;
00030 using namespace edm;
00031 using namespace reco;
00032 using namespace trigger;
00033 using namespace l1extra;
00034
00035 typedef std::vector<std::string> vstring;
00036
00037
00040
00042 HLTMuonMatchAndPlot::HLTMuonMatchAndPlot(const ParameterSet & pset,
00043 string hltPath,
00044 vector<string> moduleLabels) :
00045 hltProcessName_(pset.getParameter<string>("hltProcessName")),
00046 destination_(pset.getUntrackedParameter<string>("destination")),
00047 requiredTriggers_(pset.getUntrackedParameter<vstring>("requiredTriggers")),
00048 targetParams_(pset.getParameterSet("targetParams")),
00049 probeParams_(pset.getParameterSet("probeParams")),
00050 hltPath_(hltPath),
00051 moduleLabels_(moduleLabels),
00052 hasTargetRecoCuts(targetParams_.exists("recoCuts")),
00053 hasProbeRecoCuts(probeParams_.exists("recoCuts")),
00054 targetMuonSelector_(targetParams_.getUntrackedParameter<string>("recoCuts", "")),
00055 targetZ0Cut_(targetParams_.getUntrackedParameter<double>("z0Cut",0.)),
00056 targetD0Cut_(targetParams_.getUntrackedParameter<double>("d0Cut",0.)),
00057 probeMuonSelector_(probeParams_.getUntrackedParameter<string>("recoCuts", "")),
00058 probeZ0Cut_(probeParams_.getUntrackedParameter<double>("z0Cut",0.)),
00059 probeD0Cut_(probeParams_.getUntrackedParameter<double>("d0Cut",0.))
00060 {
00061
00062
00063 fillMapFromPSet(inputTags_, pset, "inputTags");
00064 fillMapFromPSet(binParams_, pset, "binParams");
00065 fillMapFromPSet(plotCuts_, pset, "plotCuts");
00066
00067
00068 InputTag & resTag = inputTags_["triggerResults"];
00069 resTag = InputTag(resTag.label(), resTag.instance(), hltProcessName_);
00070 InputTag & sumTag = inputTags_["triggerSummary"];
00071 sumTag = InputTag(sumTag.label(), sumTag.instance(), hltProcessName_);
00072
00073
00074 dbe_ = edm::Service<DQMStore>().operator->();
00075 dbe_->setVerbose(0);
00076
00077
00078 triggerLevel_ = "L3";
00079 TPRegexp levelRegexp("L[1-3]");
00080 size_t nModules = moduleLabels_.size();
00081 TObjArray * levelArray = levelRegexp.MatchS(moduleLabels_[nModules - 1]);
00082 if (levelArray->GetEntriesFast() > 0) {
00083 triggerLevel_ = ((TObjString *)levelArray->At(0))->GetString();
00084 }
00085 delete levelArray;
00086
00087
00088 cutMinPt_ = 3;
00089 TPRegexp ptRegexp("Mu([0-9]*)");
00090 TObjArray * objArray = ptRegexp.MatchS(hltPath_);
00091 if (objArray->GetEntriesFast() >= 2) {
00092 TObjString * ptCutString = (TObjString *)objArray->At(1);
00093 cutMinPt_ = atoi(ptCutString->GetString());
00094 cutMinPt_ = ceil(cutMinPt_ * plotCuts_["minPtFactor"]);
00095 }
00096 delete objArray;
00097 }
00098
00099 void HLTMuonMatchAndPlot::beginRun(const edm::Run& iRun,
00100 const edm::EventSetup& iSetup)
00101 {
00102
00103 TPRegexp suffixPtCut("Mu[0-9]+$");
00104
00105 string baseDir = destination_;
00106 if (baseDir[baseDir.size() - 1] != '/') baseDir += '/';
00107 string pathSansSuffix = hltPath_;
00108 if (hltPath_.rfind("_v") < hltPath_.length())
00109 pathSansSuffix = hltPath_.substr(0, hltPath_.rfind("_v"));
00110 dbe_->setCurrentFolder(baseDir + pathSansSuffix);
00111
00112
00113
00114 book1D("deltaR", "deltaR", ";#Deltar(reco, HLT);");
00115 book1D("hltPt", "pt", ";p_{T} of HLT object");
00116 book1D("hltEta", "eta", ";#eta of HLT object");
00117 book1D("hltPhi", "phi", ";#phi of HLT object");
00118 book1D("resolutionEta", "resolutionEta", ";#eta^{reco}-#eta^{HLT};");
00119 book1D("resolutionPhi", "resolutionPhi", ";#phi^{reco}-#phi^{HLT};");
00120 book1D("resolutionPt", "resolutionRel",
00121 ";(p_{T}^{reco}-p_{T}^{HLT})/|p_{T}^{reco}|;");
00122
00123 for (size_t i = 0; i < 2; i++) {
00124
00125 string suffix = EFFICIENCY_SUFFIXES[i];
00126
00127 book1D("efficiencyEta_" + suffix, "eta", ";#eta;");
00128 book1D("efficiencyPhi_" + suffix, "phi", ";#phi;");
00129 book1D("efficiencyTurnOn_" + suffix, "pt", ";p_{T};");
00130 book1D("efficiencyD0_" + suffix, "d0", ";d0;");
00131 book1D("efficiencyZ0_" + suffix, "z0", ";z0;");
00132 book1D("efficiencyCharge_" + suffix, "charge", ";charge;");
00133 book2D("efficiencyPhiVsEta_" + suffix, "etaCoarse", "phiCoarse",
00134 ";#eta;#phi");
00135
00136 book1D("fakerateEta_" + suffix, "eta", ";#eta;");
00137 book1D("fakeratePhi_" + suffix, "phi", ";#phi;");
00138 book1D("fakerateTurnOn_" + suffix, "pt", ";p_{T};");
00139
00140
00141
00142
00143 if (probeParams_.exists("recoCuts")) {
00144 book2D("massVsEtaZ_" + suffix, "zMass", "etaCoarse", ";m_{#mu#mu};#eta");
00145 book2D("massVsEtaJpsi_" + suffix, "jpsiMass", "etaCoarse", ";m_{#mu#mu};#eta");
00146 }
00147
00148 }
00149
00150 }
00151
00152
00153
00154 void HLTMuonMatchAndPlot::endRun(const edm::Run& iRun,
00155 const edm::EventSetup& iSetup)
00156 {
00157 }
00158
00159
00160
00161 void HLTMuonMatchAndPlot::analyze(const Event & iEvent,
00162 const edm::EventSetup& iSetup)
00163
00164 {
00165
00166
00167 Handle<MuonCollection> allMuons;
00168 iEvent.getByLabel(inputTags_["recoMuon"], allMuons);
00169 Handle<BeamSpot> beamSpot;
00170 iEvent.getByLabel(inputTags_["beamSpot"], beamSpot);
00171 Handle<TriggerEvent> triggerSummary;
00172 iEvent.getByLabel(inputTags_["triggerSummary"], triggerSummary);
00173 Handle<TriggerResults> triggerResults;
00174 if(!triggerSummary.isValid())
00175 {
00176 edm::LogError("HLTMuonMatchAndPlot")<<"Missing triggerSummary with label " << inputTags_["triggerSummary"] <<std::endl;
00177 return;
00178 }
00179 iEvent.getByLabel(inputTags_["triggerResults"], triggerResults);
00180 if(!triggerResults.isValid())
00181 {
00182 edm::LogError("HLTMuonMatchAndPlot")<<"Missing triggerResults with label " << inputTags_["triggerResults"] <<std::endl;
00183 return;
00184 }
00185
00186 for (size_t i = 0; i < requiredTriggers_.size(); i++) {
00187 unsigned int triggerIndex = triggerResults->find(requiredTriggers_[i]);
00188 if (triggerIndex < triggerResults->size() ||
00189 !triggerResults->accept(triggerIndex))
00190 return;
00191 }
00192
00193
00194 MuonCollection targetMuons = selectedMuons(* allMuons, * beamSpot, hasTargetRecoCuts, targetMuonSelector_, targetD0Cut_, targetZ0Cut_);
00195 MuonCollection probeMuons = selectedMuons(* allMuons, * beamSpot, hasProbeRecoCuts, probeMuonSelector_, probeD0Cut_, probeZ0Cut_);
00196 TriggerObjectCollection allTriggerObjects = triggerSummary->getObjects();
00197 TriggerObjectCollection hltMuons =
00198 selectedTriggerObjects(allTriggerObjects, * triggerSummary, targetParams_);
00199
00200
00201 for (size_t i = 0; i < hltMuons.size(); i++) {
00202 hists_["hltPt"]->Fill(hltMuons[i].pt());
00203 hists_["hltEta"]->Fill(hltMuons[i].eta());
00204 hists_["hltPhi"]->Fill(hltMuons[i].phi());
00205 }
00206
00207
00208 vector<size_t> matches = matchByDeltaR(targetMuons, hltMuons,
00209 plotCuts_[triggerLevel_ + "DeltaR"]);
00210
00211
00212 for (size_t i = 0; i < targetMuons.size(); i++) {
00213
00214 Muon & muon = targetMuons[i];
00215
00216
00217 if (matches[i] < targetMuons.size()) {
00218 TriggerObject & hltMuon = hltMuons[matches[i]];
00219 double ptRes = (muon.pt() - hltMuon.pt()) / muon.pt();
00220 double etaRes = muon.eta() - hltMuon.eta();
00221 double phiRes = muon.phi() - hltMuon.phi();
00222 hists_["resolutionEta"]->Fill(etaRes);
00223 hists_["resolutionPhi"]->Fill(phiRes);
00224 hists_["resolutionPt"]->Fill(ptRes);
00225 hists_["deltaR"]->Fill(deltaR(muon, hltMuon));
00226 }
00227
00228
00229 for (size_t j = 0; j < 2; j++) {
00230
00231 string suffix = EFFICIENCY_SUFFIXES[j];
00232
00233
00234 if (suffix == "numer" && matches[i] >= targetMuons.size()) continue;
00235
00236 if (muon.pt() > cutMinPt_) {
00237 hists_["efficiencyEta_" + suffix]->Fill(muon.eta());
00238 hists_["efficiencyPhiVsEta_" + suffix]->Fill(muon.eta(), muon.phi());
00239 }
00240
00241 if (fabs(muon.eta()) < plotCuts_["maxEta"]) {
00242 hists_["efficiencyTurnOn_" + suffix]->Fill(muon.pt());
00243 }
00244
00245 if (muon.pt() > cutMinPt_ && fabs(muon.eta()) < plotCuts_["maxEta"]) {
00246 const Track * track = 0;
00247 if (muon.isTrackerMuon()) track = & * muon.innerTrack();
00248 else if (muon.isStandAloneMuon()) track = & * muon.outerTrack();
00249 if (track) {
00250 double d0 = track->dxy(beamSpot->position());
00251 double z0 = track->dz(beamSpot->position());
00252 hists_["efficiencyPhi_" + suffix]->Fill(muon.phi());
00253 hists_["efficiencyD0_" + suffix]->Fill(d0);
00254 hists_["efficiencyZ0_" + suffix]->Fill(z0);
00255 hists_["efficiencyCharge_" + suffix]->Fill(muon.charge());
00256 }
00257 }
00258
00259
00260 for (size_t k = 0; k < probeMuons.size(); k++) {
00261 Muon & probe = targetMuons[k];
00262 if (muon.charge() != probe.charge()) {
00263 double mass = (muon.p4() + probe.p4()).M();
00264 hists_["massVsEtaZ_" + suffix]->Fill(mass, muon.eta());
00265 hists_["massVsEtaJpsi_" + suffix]->Fill(mass, muon.eta());
00266 }
00267 }
00268
00269 }
00270
00271 }
00272
00273
00274 vector<size_t> hltMatches = matchByDeltaR(hltMuons, targetMuons,
00275 plotCuts_[triggerLevel_ + "DeltaR"]);
00276 for (size_t i = 0; i < hltMuons.size(); i++) {
00277 TriggerObject & hltMuon = hltMuons[i];
00278 bool isFake = hltMatches[i] > hltMuons.size();
00279 for (size_t j = 0; j < 2; j++) {
00280 string suffix = EFFICIENCY_SUFFIXES[j];
00281
00282 if (suffix == "numer" && ! isFake) continue;
00283 hists_["fakerateEta_" + suffix]->Fill(hltMuon.eta());
00284 hists_["fakeratePhi_" + suffix]->Fill(hltMuon.phi());
00285 hists_["fakerateTurnOn_" + suffix]->Fill(hltMuon.pt());
00286 }
00287 }
00288
00289
00290 }
00291
00292
00293
00294
00295 void
00296 HLTMuonMatchAndPlot::fillEdges(size_t & nBins, float * & edges,
00297 vector<double> binning) {
00298
00299 if (binning.size() < 3) {
00300 LogWarning("HLTMuonVal") << "Invalid binning parameters!";
00301 return;
00302 }
00303
00304
00305 if (binning.size() == 3) {
00306 nBins = binning[0];
00307 edges = new float[nBins + 1];
00308 const double min = binning[1];
00309 const double binwidth = (binning[2] - binning[1]) / nBins;
00310 for (size_t i = 0; i <= nBins; i++) edges[i] = min + (binwidth * i);
00311 }
00312
00313
00314 else {
00315 nBins = binning.size() - 1;
00316 edges = new float[nBins + 1];
00317 for (size_t i = 0; i <= nBins; i++) edges[i] = binning[i];
00318 }
00319
00320 }
00321
00322
00323
00324
00325
00326
00327 template <class T>
00328 void
00329 HLTMuonMatchAndPlot::fillMapFromPSet(map<string, T> & m,
00330 ParameterSet pset, string target) {
00331
00332
00333 ParameterSet targetPset;
00334 if (pset.existsAs<ParameterSet>(target, true))
00335 targetPset = pset.getParameterSet(target);
00336 else if (pset.existsAs<ParameterSet>(target, false))
00337 targetPset = pset.getUntrackedParameterSet(target);
00338
00339
00340 vector<string> names = targetPset.getParameterNames();
00341 vector<string>::const_iterator iter;
00342
00343 for (iter = names.begin(); iter != names.end(); ++iter) {
00344 if (targetPset.existsAs<T>(* iter, true))
00345 m[* iter] = targetPset.getParameter<T>(* iter);
00346 else if (targetPset.existsAs<T>(* iter, false))
00347 m[* iter] = targetPset.getUntrackedParameter<T>(* iter);
00348 }
00349
00350 }
00351
00352
00353
00354
00355 template <class T1, class T2>
00356 vector<size_t>
00357 HLTMuonMatchAndPlot::matchByDeltaR(const vector<T1> & collection1,
00358 const vector<T2> & collection2,
00359 const double maxDeltaR) {
00360
00361 const size_t n1 = collection1.size();
00362 const size_t n2 = collection2.size();
00363
00364 vector<size_t> result(n1, -1);
00365 vector<vector<double> > deltaRMatrix(n1, vector<double>(n2, NOMATCH));
00366
00367 for (size_t i = 0; i < n1; i++)
00368 for (size_t j = 0; j < n2; j++) {
00369 deltaRMatrix[i][j] = deltaR(collection1[i], collection2[j]);
00370 }
00371
00372
00373 for (size_t k = 0; k < n1; k++) {
00374 size_t i_min = -1;
00375 size_t j_min = -1;
00376 double minDeltaR = maxDeltaR;
00377
00378 for (size_t i = 0; i < n1; i++)
00379 for (size_t j = 0; j < n2; j++)
00380 if (deltaRMatrix[i][j] < minDeltaR) {
00381 i_min = i;
00382 j_min = j;
00383 minDeltaR = deltaRMatrix[i][j];
00384 }
00385
00386 if (minDeltaR < maxDeltaR) {
00387 result[i_min] = j_min;
00388 deltaRMatrix[i_min] = vector<double>(n2, NOMATCH);
00389 for (size_t i = 0; i < n1; i++)
00390 deltaRMatrix[i][j_min] = NOMATCH;
00391 }
00392 }
00393
00394 return result;
00395
00396 }
00397
00398
00399
00400 MuonCollection
00401 HLTMuonMatchAndPlot::selectedMuons(const MuonCollection & allMuons,
00402 const BeamSpot & beamSpot,
00403 bool hasRecoCuts,
00404 const StringCutObjectSelector<reco::Muon> &selector,
00405 double d0Cut, double z0Cut)
00406 {
00407
00408 if (!hasRecoCuts)
00409 return MuonCollection();
00410
00411 MuonCollection reducedMuons(allMuons);
00412 MuonCollection::iterator iter = reducedMuons.begin();
00413 while (iter != reducedMuons.end()) {
00414 const Track * track = 0;
00415 if (iter->isTrackerMuon()) track = & * iter->innerTrack();
00416 else if (iter->isStandAloneMuon()) track = & * iter->outerTrack();
00417 if (track && selector(* iter) &&
00418 fabs(track->dxy(beamSpot.position())) < d0Cut &&
00419 fabs(track->dz(beamSpot.position())) < z0Cut)
00420 ++iter;
00421 else reducedMuons.erase(iter);
00422 }
00423
00424 return reducedMuons;
00425
00426 }
00427
00428
00429
00430 TriggerObjectCollection
00431 HLTMuonMatchAndPlot::selectedTriggerObjects(
00432 const TriggerObjectCollection & triggerObjects,
00433 const TriggerEvent & triggerSummary,
00434 const ParameterSet & pset)
00435 {
00436
00437
00438 if (!pset.exists("hltCuts"))
00439 return TriggerObjectCollection();
00440
00441 StringCutObjectSelector<TriggerObject> selector
00442 (pset.getUntrackedParameter<string>("hltCuts"));
00443
00444 InputTag filterTag(moduleLabels_[moduleLabels_.size() - 1], "",
00445 hltProcessName_);
00446 size_t filterIndex = triggerSummary.filterIndex(filterTag);
00447
00448 TriggerObjectCollection selectedObjects;
00449
00450 if (filterIndex < triggerSummary.sizeFilters()) {
00451 const Keys &keys = triggerSummary.filterKeys(filterIndex);
00452 for (size_t j = 0; j < keys.size(); j++ ){
00453 TriggerObject foundObject = triggerObjects[keys[j]];
00454 if (selector(foundObject))
00455 selectedObjects.push_back(foundObject);
00456 }
00457 }
00458
00459 return selectedObjects;
00460
00461 }
00462
00463
00464
00465 void HLTMuonMatchAndPlot::book1D(string name, string binningType, string title)
00466 {
00467
00468
00469
00470
00471
00472
00473 size_t nBins;
00474 float * edges = 0;
00475 fillEdges(nBins, edges, binParams_[binningType]);
00476
00477 hists_[name] = dbe_->book1D(name, title, nBins, edges);
00478 if (hists_[name])
00479 if (hists_[name]->getTH1F()->GetSumw2N())
00480 hists_[name]->getTH1F()->Sumw2();
00481
00482 if (edges)
00483 delete [] edges;
00484 }
00485
00486
00487
00488 void
00489 HLTMuonMatchAndPlot::book2D(string name, string binningTypeX,
00490 string binningTypeY, string title)
00491 {
00492
00493
00494
00495
00496
00497
00498
00499 size_t nBinsX;
00500 float * edgesX = 0;
00501 fillEdges(nBinsX, edgesX, binParams_[binningTypeX]);
00502
00503 size_t nBinsY;
00504 float * edgesY = 0;
00505 fillEdges(nBinsY, edgesY, binParams_[binningTypeY]);
00506
00507 hists_[name] = dbe_->book2D(name.c_str(), title.c_str(),
00508 nBinsX, edgesX, nBinsY, edgesY);
00509 if (hists_[name])
00510 if (hists_[name]->getTH2F()->GetSumw2N())
00511 hists_[name]->getTH2F()->Sumw2();
00512
00513 if (edgesX)
00514 delete [] edgesX;
00515 if (edgesY)
00516 delete [] edgesY;
00517 }
00518