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("resolutionEta", "resolution",
00116 ";(#eta^{reco}-#eta^{HLT})/|#eta^{reco}|;");
00117 book1D("resolutionPhi", "resolution",
00118 ";(#phi^{reco}-#phi^{HLT})/|#phi^{reco}|;");
00119 book1D("resolutionPt", "resolution",
00120 ";(p_{T}^{reco}-p_{T}^{HLT})/|p_{T}^{reco}|;");
00121
00122 for (size_t i = 0; i < 2; i++) {
00123
00124 string suffix = EFFICIENCY_SUFFIXES[i];
00125
00126 book1D("efficiencyEta_" + suffix, "eta", ";#eta;");
00127 book1D("efficiencyPhi_" + suffix, "phi", ";#phi;");
00128 book1D("efficiencyTurnOn_" + suffix, "pt", ";p_{T};");
00129 book1D("efficiencyD0_" + suffix, "d0", ";d0;");
00130 book1D("efficiencyZ0_" + suffix, "z0", ";z0;");
00131 book1D("efficiencyCharge_" + suffix, "charge", ";charge;");
00132 book2D("efficiencyPhiVsEta_" + suffix, "etaCoarse", "phiCoarse",
00133 ";#eta;#phi");
00134
00135 book1D("fakerateEta_" + suffix, "eta", ";#eta;");
00136 book1D("fakeratePhi_" + suffix, "phi", ";#phi;");
00137 book1D("fakerateTurnOn_" + suffix, "pt", ";p_{T};");
00138
00139
00140
00141
00142 if (probeParams_.exists("recoCuts")) {
00143 book2D("massVsEta_" + suffix, "zMass", "etaCoarse", ";m_{#mu#mu};#eta");
00144 }
00145
00146 }
00147
00148 }
00149
00150
00151
00152 void HLTMuonMatchAndPlot::endRun(const edm::Run& iRun,
00153 const edm::EventSetup& iSetup)
00154 {
00155 }
00156
00157
00158
00159 void HLTMuonMatchAndPlot::analyze(const Event & iEvent,
00160 const edm::EventSetup& iSetup)
00161
00162 {
00163
00164
00165 Handle<MuonCollection> allMuons;
00166 iEvent.getByLabel(inputTags_["recoMuon"], allMuons);
00167 Handle<BeamSpot> beamSpot;
00168 iEvent.getByLabel(inputTags_["beamSpot"], beamSpot);
00169 Handle<TriggerEvent> triggerSummary;
00170 iEvent.getByLabel(inputTags_["triggerSummary"], triggerSummary);
00171 Handle<TriggerResults> triggerResults;
00172 iEvent.getByLabel(inputTags_["triggerResults"], triggerResults);
00173
00174
00175 for (size_t i = 0; i < requiredTriggers_.size(); i++) {
00176 unsigned int triggerIndex = triggerResults->find(requiredTriggers_[i]);
00177 if (triggerIndex < triggerResults->size() ||
00178 !triggerResults->accept(triggerIndex))
00179 return;
00180 }
00181
00182
00183 MuonCollection targetMuons = selectedMuons(* allMuons, * beamSpot, hasTargetRecoCuts, targetMuonSelector_, targetD0Cut_, targetZ0Cut_);
00184 MuonCollection probeMuons = selectedMuons(* allMuons, * beamSpot, hasProbeRecoCuts, probeMuonSelector_, probeD0Cut_, probeZ0Cut_);
00185 TriggerObjectCollection allTriggerObjects = triggerSummary->getObjects();
00186 TriggerObjectCollection hltMuons =
00187 selectedTriggerObjects(allTriggerObjects, * triggerSummary, targetParams_);
00188
00189
00190 vector<size_t> matches = matchByDeltaR(targetMuons, hltMuons,
00191 plotCuts_[triggerLevel_ + "DeltaR"]);
00192
00193
00194 for (size_t i = 0; i < targetMuons.size(); i++) {
00195
00196 Muon & muon = targetMuons[i];
00197
00198
00199 if (matches[i] < targetMuons.size()) {
00200 TriggerObject & hltMuon = hltMuons[matches[i]];
00201 double ptRes = (muon.pt() - hltMuon.pt()) / muon.pt();
00202 double etaRes = (muon.eta() - hltMuon.eta()) / fabs(muon.eta());
00203 double phiRes = (muon.phi() - hltMuon.phi()) / fabs(muon.phi());
00204 hists_["resolutionEta"]->Fill(etaRes);
00205 hists_["resolutionPhi"]->Fill(phiRes);
00206 hists_["resolutionPt"]->Fill(ptRes);
00207 hists_["deltaR"]->Fill(deltaR(muon, hltMuon));
00208 }
00209
00210
00211 for (size_t j = 0; j < 2; j++) {
00212
00213 string suffix = EFFICIENCY_SUFFIXES[j];
00214
00215
00216 if (suffix == "numer" && matches[i] >= targetMuons.size()) continue;
00217
00218 if (muon.pt() > cutMinPt_) {
00219 hists_["efficiencyEta_" + suffix]->Fill(muon.eta());
00220 hists_["efficiencyPhiVsEta_" + suffix]->Fill(muon.eta(), muon.phi());
00221 }
00222
00223 if (fabs(muon.eta()) < plotCuts_["maxEta"]) {
00224 hists_["efficiencyTurnOn_" + suffix]->Fill(muon.pt());
00225 }
00226
00227 if (muon.pt() > cutMinPt_ && fabs(muon.eta()) < plotCuts_["maxEta"]) {
00228 const Track * track = 0;
00229 if (muon.isTrackerMuon()) track = & * muon.innerTrack();
00230 else if (muon.isStandAloneMuon()) track = & * muon.outerTrack();
00231 if (track) {
00232 double d0 = track->dxy(beamSpot->position());
00233 double z0 = track->dz(beamSpot->position());
00234 hists_["efficiencyPhi_" + suffix]->Fill(muon.phi());
00235 hists_["efficiencyD0_" + suffix]->Fill(d0);
00236 hists_["efficiencyZ0_" + suffix]->Fill(z0);
00237 hists_["efficiencyCharge_" + suffix]->Fill(muon.charge());
00238 }
00239 }
00240
00241
00242 for (size_t k = 0; k < probeMuons.size(); k++) {
00243 Muon & probe = targetMuons[k];
00244 if (muon.charge() != probe.charge()) {
00245 double mass = (muon.p4() + probe.p4()).M();
00246 hists_["massVsEta_" + suffix]->Fill(mass, muon.eta());
00247 }
00248 }
00249
00250 }
00251
00252 }
00253
00254
00255 vector<size_t> hltMatches = matchByDeltaR(hltMuons, targetMuons,
00256 plotCuts_[triggerLevel_ + "DeltaR"]);
00257 for (size_t i = 0; i < hltMuons.size(); i++) {
00258 TriggerObject & hltMuon = hltMuons[i];
00259 bool isFake = hltMatches[i] > hltMuons.size();
00260 for (size_t j = 0; j < 2; j++) {
00261 string suffix = EFFICIENCY_SUFFIXES[j];
00262
00263 if (suffix == "numer" && ! isFake) continue;
00264 hists_["fakerateEta_" + suffix]->Fill(hltMuon.eta());
00265 hists_["fakeratePhi_" + suffix]->Fill(hltMuon.phi());
00266 hists_["fakerateTurnOn_" + suffix]->Fill(hltMuon.pt());
00267 }
00268 }
00269
00270
00271 }
00272
00273
00274
00275
00276 void
00277 HLTMuonMatchAndPlot::fillEdges(size_t & nBins, float * & edges,
00278 vector<double> binning) {
00279
00280 if (binning.size() < 3) {
00281 LogWarning("HLTMuonVal") << "Invalid binning parameters!";
00282 return;
00283 }
00284
00285
00286 if (binning.size() == 3) {
00287 nBins = binning[0];
00288 edges = new float[nBins + 1];
00289 const double min = binning[1];
00290 const double binwidth = (binning[2] - binning[1]) / nBins;
00291 for (size_t i = 0; i <= nBins; i++) edges[i] = min + (binwidth * i);
00292 }
00293
00294
00295 else {
00296 nBins = binning.size() - 1;
00297 edges = new float[nBins + 1];
00298 for (size_t i = 0; i <= nBins; i++) edges[i] = binning[i];
00299 }
00300
00301 }
00302
00303
00304
00305
00306
00307
00308 template <class T>
00309 void
00310 HLTMuonMatchAndPlot::fillMapFromPSet(map<string, T> & m,
00311 ParameterSet pset, string target) {
00312
00313
00314 ParameterSet targetPset;
00315 if (pset.existsAs<ParameterSet>(target, true))
00316 targetPset = pset.getParameterSet(target);
00317 else if (pset.existsAs<ParameterSet>(target, false))
00318 targetPset = pset.getUntrackedParameterSet(target);
00319
00320
00321 vector<string> names = targetPset.getParameterNames();
00322 vector<string>::const_iterator iter;
00323
00324 for (iter = names.begin(); iter != names.end(); ++iter) {
00325 if (targetPset.existsAs<T>(* iter, true))
00326 m[* iter] = targetPset.getParameter<T>(* iter);
00327 else if (targetPset.existsAs<T>(* iter, false))
00328 m[* iter] = targetPset.getUntrackedParameter<T>(* iter);
00329 }
00330
00331 }
00332
00333
00334
00335
00336 template <class T1, class T2>
00337 vector<size_t>
00338 HLTMuonMatchAndPlot::matchByDeltaR(const vector<T1> & collection1,
00339 const vector<T2> & collection2,
00340 const double maxDeltaR) {
00341
00342 const size_t n1 = collection1.size();
00343 const size_t n2 = collection2.size();
00344
00345 vector<size_t> result(n1, -1);
00346 vector<vector<double> > deltaRMatrix(n1, vector<double>(n2, NOMATCH));
00347
00348 for (size_t i = 0; i < n1; i++)
00349 for (size_t j = 0; j < n2; j++) {
00350 deltaRMatrix[i][j] = deltaR(collection1[i], collection2[j]);
00351 }
00352
00353
00354 for (size_t k = 0; k < n1; k++) {
00355 size_t i_min = -1;
00356 size_t j_min = -1;
00357 double minDeltaR = maxDeltaR;
00358
00359 for (size_t i = 0; i < n1; i++)
00360 for (size_t j = 0; j < n2; j++)
00361 if (deltaRMatrix[i][j] < minDeltaR) {
00362 i_min = i;
00363 j_min = j;
00364 minDeltaR = deltaRMatrix[i][j];
00365 }
00366
00367 if (minDeltaR < maxDeltaR) {
00368 result[i_min] = j_min;
00369 deltaRMatrix[i_min] = vector<double>(n2, NOMATCH);
00370 for (size_t i = 0; i < n1; i++)
00371 deltaRMatrix[i][j_min] = NOMATCH;
00372 }
00373 }
00374
00375 return result;
00376
00377 }
00378
00379
00380
00381 MuonCollection
00382 HLTMuonMatchAndPlot::selectedMuons(const MuonCollection & allMuons,
00383 const BeamSpot & beamSpot,
00384 bool hasRecoCuts,
00385 const StringCutObjectSelector<reco::Muon> &selector,
00386 double d0Cut, double z0Cut)
00387 {
00388
00389 if (!hasRecoCuts)
00390 return MuonCollection();
00391
00392 MuonCollection reducedMuons(allMuons);
00393 MuonCollection::iterator iter = reducedMuons.begin();
00394 while (iter != reducedMuons.end()) {
00395 const Track * track = 0;
00396 if (iter->isTrackerMuon()) track = & * iter->innerTrack();
00397 else if (iter->isStandAloneMuon()) track = & * iter->outerTrack();
00398 if (track && selector(* iter) &&
00399 fabs(track->dxy(beamSpot.position())) < d0Cut &&
00400 fabs(track->dz(beamSpot.position())) < z0Cut)
00401 ++iter;
00402 else reducedMuons.erase(iter);
00403 }
00404
00405 return reducedMuons;
00406
00407 }
00408
00409
00410
00411 TriggerObjectCollection
00412 HLTMuonMatchAndPlot::selectedTriggerObjects(
00413 const TriggerObjectCollection & triggerObjects,
00414 const TriggerEvent & triggerSummary,
00415 const ParameterSet & pset)
00416 {
00417
00418
00419 if (!pset.exists("hltCuts"))
00420 return TriggerObjectCollection();
00421
00422 StringCutObjectSelector<TriggerObject> selector
00423 (pset.getUntrackedParameter<string>("hltCuts"));
00424
00425 InputTag filterTag(moduleLabels_[moduleLabels_.size() - 1], "",
00426 hltProcessName_);
00427 size_t filterIndex = triggerSummary.filterIndex(filterTag);
00428
00429 TriggerObjectCollection selectedObjects;
00430
00431 if (filterIndex < triggerSummary.sizeFilters()) {
00432 const Keys &keys = triggerSummary.filterKeys(filterIndex);
00433 for (size_t j = 0; j < keys.size(); j++ ){
00434 TriggerObject foundObject = triggerObjects[keys[j]];
00435 if (selector(foundObject))
00436 selectedObjects.push_back(foundObject);
00437 }
00438 }
00439
00440 return selectedObjects;
00441
00442 }
00443
00444
00445
00446 void
00447 HLTMuonMatchAndPlot::book1D(string name, string binningType, string title) {
00448
00449 size_t nBins;
00450 float * edges;
00451 fillEdges(nBins, edges, binParams_[binningType]);
00452
00453 TH1F * h = new TH1F(name.c_str(), title.c_str(), nBins, edges);
00454 h->Sumw2();
00455 hists_[name] = dbe_->book1D(name, h);
00456 delete h;
00457
00458 }
00459
00460
00461
00462 void
00463 HLTMuonMatchAndPlot::book2D(string name, string binningTypeX,
00464 string binningTypeY, string title) {
00465
00466 size_t nBinsX;
00467 float * edgesX;
00468 fillEdges(nBinsX, edgesX, binParams_[binningTypeX]);
00469
00470 size_t nBinsY;
00471 float * edgesY;
00472 fillEdges(nBinsY, edgesY, binParams_[binningTypeY]);
00473
00474 TH2F * h = new TH2F(name.c_str(), title.c_str(),
00475 nBinsX, edgesX, nBinsY, edgesY);
00476 h->Sumw2();
00477 hists_[name] = dbe_->book2D(name, h);
00478 delete h;
00479
00480 }
00481