00001
00008 #include "HLTriggerOffline/Muon/interface/HLTMuonValidator.h"
00009 #include "FWCore/ServiceRegistry/interface/Service.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "DataFormats/Common/interface/Handle.h"
00012 #include "DataFormats/Candidate/interface/CandMatchMap.h"
00013 #include "DataFormats/Math/interface/deltaPhi.h"
00014 #include "DataFormats/Math/interface/deltaR.h"
00015 #include "DataFormats/MuonReco/interface/Muon.h"
00016 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00017
00018 #include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeed.h"
00019 #include "DataFormats/MuonSeed/interface/L2MuonTrajectorySeedCollection.h"
00020 #include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h"
00021 #include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeedCollection.h"
00022
00023
00024
00025 using namespace std;
00026 using namespace edm;
00027 using namespace reco;
00028 using namespace trigger;
00029 using namespace l1extra;
00030
00031
00032
00033 typedef vector<ParameterSet> Parameters;
00034
00035
00036
00037 HLTMuonValidator::HLTMuonValidator(const ParameterSet & pset) :
00038 l1Matcher_(pset)
00039 {
00040
00041 hltProcessName_ = pset.getParameter< string >("hltProcessName");
00042 hltPathsToCheck_ = pset.getParameter< vector<string> >("hltPathsToCheck");
00043
00044 genParticleLabel_ = pset.getParameter<string>("genParticleLabel");
00045 recMuonLabel_ = pset.getParameter<string>( "recMuonLabel");
00046 l1CandLabel_ = pset.getParameter<string>( "l1CandLabel");
00047 l2CandLabel_ = pset.getParameter<string>( "l2CandLabel");
00048 l3CandLabel_ = pset.getParameter<string>( "l3CandLabel");
00049
00050 cutsDr_ = pset.getParameter< vector<double> >("cutsDr" );
00051
00052 parametersEta_ = pset.getParameter< vector<double> >("parametersEta");
00053 parametersPhi_ = pset.getParameter< vector<double> >("parametersPhi");
00054 parametersTurnOn_ = pset.getParameter< vector<double> >("parametersTurnOn");
00055
00056 genMuonCut_ = pset.getParameter<string>("genMuonCut");
00057 recMuonCut_ = pset.getParameter<string>("recMuonCut");
00058
00059 genMuonSelector_ = 0;
00060 recMuonSelector_ = 0;
00061
00062 dbe_ = Service<DQMStore>().operator->();
00063 dbe_->setVerbose(0);
00064
00065 }
00066
00067
00068
00069 void
00070 HLTMuonValidator::beginJob()
00071 {
00072 }
00073
00074
00075
00076 void
00077 HLTMuonValidator::beginRun(const Run & iRun, const EventSetup & iSetup)
00078 {
00079
00080 static int runNumber = 0;
00081 runNumber++;
00082
00083 l1Matcher_.init(iSetup);
00084
00085 bool changedConfig;
00086 if (!hltConfig_.init(iRun, iSetup, hltProcessName_, changedConfig)) {
00087 LogError("HLTMuonVal") << "Initialization of HLTConfigProvider failed!!";
00088 return;
00089 }
00090
00091 hltPaths_.clear();
00092 filterLabels_.clear();
00093 vector<string> validTriggerNames = hltConfig_.triggerNames();
00094 for (size_t i = 0; i < hltPathsToCheck_.size(); i++) {
00095 TPRegexp pattern(hltPathsToCheck_[i]);
00096 for (size_t j = 0; j < validTriggerNames.size(); j++)
00097 if (TString(validTriggerNames[j]).Contains(pattern))
00098 hltPaths_.insert(validTriggerNames[j]);
00099
00100 if (TString("NoFilters").Contains(pattern))
00101 hltPaths_.insert("NoFilters");
00102 }
00103
00104 initializeHists();
00105
00106 }
00107
00108
00109
00110 void
00111 HLTMuonValidator::initializeHists()
00112 {
00113
00114 vector<string> sources(2);
00115 sources[0] = "gen";
00116 sources[1] = "rec";
00117
00118 set<string>::iterator iPath;
00119
00120 for (iPath = hltPaths_.begin(); iPath != hltPaths_.end(); iPath++) {
00121
00122 string path = * iPath;
00123
00124 if (path == "NoFilters") {
00125 filterLabels_[path].push_back("hltL1sL1SingleMuOpenL1SingleMu0");
00126
00127 filterLabels_[path].push_back("");
00128 filterLabels_[path].push_back("");
00129 }
00130
00131 vector<string> moduleLabels;
00132 if (path != "NoFilters") moduleLabels = hltConfig_.moduleLabels(path);
00133
00134 for (size_t i = 0; i < moduleLabels.size(); i++)
00135 if (moduleLabels[i].find("Filtered") != string::npos)
00136 filterLabels_[path].push_back(moduleLabels[i]);
00137
00138 double cutMaxEta = 2.4;
00139
00140
00141
00142 unsigned int threshold = 3;
00143 TPRegexp ptRegexp("Mu([0-9]*)");
00144 TObjArray * regexArray = ptRegexp.MatchS(path);
00145 if (regexArray->GetEntriesFast() == 2) {
00146 threshold = atoi(((TObjString *)regexArray->At(1))->GetString());
00147 }
00148 delete regexArray;
00149
00150
00151
00152 double cutMinPt = ceil(threshold * 1.1) - 0.01;
00153 if (cutMinPt < 0. || path == "NoFilters") cutMinPt = 0.;
00154 cutsMinPt_[path] = cutMinPt;
00155
00156 string baseDir = "HLT/Muon/Distributions/";
00157 string pathSansSuffix = path;
00158 if (path.rfind("_v") < path.length())
00159 pathSansSuffix = path.substr(0, path.rfind("_v"));
00160 dbe_->setCurrentFolder(baseDir + pathSansSuffix);
00161
00162 if (dbe_->get(baseDir + path + "/CutMinPt") == 0) {
00163
00164 elements_[path + "_" + "CutMinPt" ] = dbe_->bookFloat("CutMinPt" );
00165 elements_[path + "_" + "CutMaxEta"] = dbe_->bookFloat("CutMaxEta");
00166 elements_[path + "_" + "CutMinPt" ]->Fill(cutMinPt);
00167 elements_[path + "_" + "CutMaxEta"]->Fill(cutMaxEta);
00168
00169
00170 const int nFilters = filterLabels_[path].size();
00171 stepLabels_[path].push_back("All");
00172 stepLabels_[path].push_back("L1");
00173 if (nFilters == 2) {
00174 stepLabels_[path].push_back("L2");
00175 }
00176 if (nFilters == 3) {
00177 stepLabels_[path].push_back("L2");
00178 stepLabels_[path].push_back("L3");
00179 }
00180 if (nFilters == 5) {
00181 stepLabels_[path].push_back("L2");
00182 stepLabels_[path].push_back("L2Iso");
00183 stepLabels_[path].push_back("L3");
00184 stepLabels_[path].push_back("L3Iso");
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 for (size_t i = 0; i < sources.size(); i++) {
00194 string source = sources[i];
00195 for (size_t j = 0; j < stepLabels_[path].size(); j++) {
00196 bookHist(path, stepLabels_[path][j], source, "Eta");
00197 bookHist(path, stepLabels_[path][j], source, "Phi");
00198 bookHist(path, stepLabels_[path][j], source, "MaxPt1");
00199 bookHist(path, stepLabels_[path][j], source, "MaxPt2");
00200 }
00201 }
00202
00203 }
00204
00205 }
00206
00207 }
00208
00209
00210
00211 void
00212 HLTMuonValidator::analyze(const Event & iEvent, const EventSetup & iSetup)
00213 {
00214
00215 static int eventNumber = 0;
00216 eventNumber++;
00217 LogTrace("HLTMuonVal") << "In HLTMuonValidator::analyze, "
00218 << "Event: " << eventNumber;
00219
00220 Handle< TriggerEventWithRefs> rawTriggerEvent;
00221 Handle< MuonCollection> recMuons;
00222 Handle< GenParticleCollection> genParticles;
00223
00224 iEvent.getByLabel("hltTriggerSummaryRAW", rawTriggerEvent);
00225 if (rawTriggerEvent.failedToGet())
00226 {LogError("HLTMuonVal") << "No trigger summary found"; return;}
00227 iEvent.getByLabel( recMuonLabel_, recMuons );
00228 iEvent.getByLabel(genParticleLabel_, genParticles );
00229
00230 vector<string> sources;
00231 if (genParticles.isValid()) sources.push_back("gen");
00232 if ( recMuons.isValid()) sources.push_back("rec");
00233
00234 for (size_t sourceNo = 0; sourceNo < sources.size(); sourceNo++) {
00235
00236 string source = sources[sourceNo];
00237
00238
00239 if (!genMuonSelector_) genMuonSelector_ =
00240 new StringCutObjectSelector<reco::GenParticle>(genMuonCut_);
00241 if (!recMuonSelector_) recMuonSelector_ =
00242 new StringCutObjectSelector<reco::Muon >(recMuonCut_);
00243
00244
00245 vector<MatchStruct> matches;
00246 if (source == "gen" && genParticles.isValid())
00247 for (size_t i = 0; i < genParticles->size(); i++)
00248 if ((*genMuonSelector_)(genParticles->at(i)))
00249 matches.push_back(MatchStruct(& genParticles->at(i)));
00250 if (source == "rec" && recMuons.isValid())
00251 for (size_t i = 0; i < recMuons->size(); i++)
00252 if ((*recMuonSelector_)(recMuons->at(i)))
00253 matches.push_back(MatchStruct(& recMuons->at(i)));
00254
00255
00256 sort(matches.begin(), matches.end(), matchesByDescendingPt());
00257
00258 set<string>::iterator iPath;
00259 for (iPath = hltPaths_.begin(); iPath != hltPaths_.end(); iPath++)
00260 analyzePath(iEvent, * iPath, source, matches, rawTriggerEvent);
00261
00262 }
00263
00264 }
00265
00266
00267
00268 void
00269 HLTMuonValidator::analyzePath(const Event & iEvent,
00270 const string & path,
00271 const string & source,
00272 vector<MatchStruct> matches,
00273 Handle<TriggerEventWithRefs> rawTriggerEvent)
00274 {
00275
00276 const bool skipFilters = (path == "NoFilters");
00277
00278 const float maxEta = elements_[path + "_" + "CutMaxEta"]->getFloatValue();
00279 const bool isDoubleMuonPath = (path.find("Double") != string::npos);
00280 const size_t nFilters = filterLabels_[path].size();
00281 const size_t nSteps = stepLabels_[path].size();
00282 const size_t nStepsHlt = nSteps - 2;
00283 const int nObjectsToPassPath = (isDoubleMuonPath) ? 2 : 1;
00284 vector< L1MuonParticleRef > candsL1;
00285 vector< vector< RecoChargedCandidateRef > > refsHlt(nStepsHlt);
00286 vector< vector< const RecoChargedCandidate * > > candsHlt(nStepsHlt);
00287
00288 for (size_t i = 0; i < nFilters; i++) {
00289 const int hltStep = i - 1;
00290 InputTag tag = InputTag(filterLabels_[path][i], "", hltProcessName_);
00291 size_t iFilter = rawTriggerEvent->filterIndex(tag);
00292 if (iFilter < rawTriggerEvent->size()) {
00293 if (i == 0)
00294 rawTriggerEvent->getObjects(iFilter, TriggerL1Mu, candsL1);
00295 else
00296 rawTriggerEvent->getObjects(iFilter, TriggerMuon,
00297 refsHlt[hltStep]);
00298 }
00299 else if (!skipFilters)
00300 LogTrace("HLTMuonVal") << "No collection with label " << tag;
00301 }
00302 if (skipFilters) {
00303 Handle<RecoChargedCandidateCollection> handleCandsL2;
00304 Handle<RecoChargedCandidateCollection> handleCandsL3;
00305 iEvent.getByLabel(l2CandLabel_, handleCandsL2);
00306 iEvent.getByLabel(l3CandLabel_, handleCandsL3);
00307 if (handleCandsL2.isValid())
00308 for (size_t i = 0; i < handleCandsL2->size(); i++)
00309 candsHlt[0].push_back(& handleCandsL2->at(i));
00310 if (handleCandsL3.isValid())
00311 for (size_t i = 0; i < handleCandsL3->size(); i++)
00312 candsHlt[1].push_back(& handleCandsL3->at(i));
00313 }
00314 else for (size_t i = 0; i < nStepsHlt; i++)
00315 for (size_t j = 0; j < refsHlt[i].size(); j++)
00316 if (refsHlt[i][j].isAvailable()) {
00317 candsHlt[i].push_back(& * refsHlt[i][j]);
00318 } else {
00319 LogWarning("HLTMuonValidator")
00320 << "Ref refsHlt[i][j]: product not available "
00321 << i << " " << j;
00322 }
00323
00324
00325 findMatches(matches, candsL1, candsHlt);
00326
00327 vector<size_t> matchesInEtaRange;
00328 vector<bool> hasMatch(matches.size(), true);
00329
00330 for (size_t step = 0; step < nSteps; step++) {
00331
00332 const size_t hltStep = (step >= 2) ? step - 2 : 0;
00333 const size_t level = (step == 1) ? 1 :
00334 (step == 2) ? 2 :
00335 (step == 3) ? ((nStepsHlt == 4) ? 2 : 3) :
00336 (step >= 4) ? 3 :
00337 0;
00338
00339 for (size_t j = 0; j < matches.size(); j++) {
00340 if (level == 0) {
00341 if (fabs(matches[j].candBase->eta()) < maxEta)
00342 matchesInEtaRange.push_back(j);
00343 }
00344 else if (level == 1) {
00345 if (matches[j].candL1 == 0)
00346 hasMatch[j] = false;
00347 }
00348 else if (level >= 2) {
00349 if (matches[j].candHlt[hltStep] == 0)
00350 hasMatch[j] = false;
00351 else if (!hasMatch[j]) {
00352 LogTrace("HLTMuonVal") << "Match found for HLT step " << hltStep
00353 << " of " << nStepsHlt
00354 << " without previous match!";
00355 break;
00356 }
00357 }
00358 }
00359
00360 if (std::count(hasMatch.begin(), hasMatch.end(), true) <
00361 nObjectsToPassPath)
00362 break;
00363
00364 string pre = path + "_" + source + "Pass";
00365 string post = "_" + stepLabels_[path][step];
00366
00367 for (size_t j = 0; j < matches.size(); j++) {
00368 float pt = matches[j].candBase->pt();
00369 float eta = matches[j].candBase->eta();
00370 float phi = matches[j].candBase->phi();
00371 if (hasMatch[j]) {
00372 if (matchesInEtaRange.size() >= 1 && j == matchesInEtaRange[0])
00373 elements_[pre + "MaxPt1" + post]->Fill(pt);
00374 if (matchesInEtaRange.size() >= 2 && j == matchesInEtaRange[1])
00375 elements_[pre + "MaxPt2" + post]->Fill(pt);
00376 if (pt > cutsMinPt_[path]) {
00377 elements_[pre + "Eta" + post]->Fill(eta);
00378 if (fabs(eta) < maxEta)
00379 elements_[pre + "Phi" + post]->Fill(phi);
00380 }
00381 }
00382 }
00383
00384 }
00385
00386 }
00387
00388
00389
00390 void
00391 HLTMuonValidator::findMatches(
00392 vector<MatchStruct> & matches,
00393 vector<L1MuonParticleRef> candsL1,
00394 vector< vector< const RecoChargedCandidate *> > candsHlt)
00395 {
00396
00397 set<size_t>::iterator it;
00398
00399 set<size_t> indicesL1;
00400 for (size_t i = 0; i < candsL1.size(); i++)
00401 indicesL1.insert(i);
00402
00403 vector< set<size_t> > indicesHlt(candsHlt.size());
00404 for (size_t i = 0; i < candsHlt.size(); i++)
00405 for (size_t j = 0; j < candsHlt[i].size(); j++)
00406 indicesHlt[i].insert(j);
00407
00408 for (size_t i = 0; i < matches.size(); i++) {
00409
00410 const Candidate * cand = matches[i].candBase;
00411
00412 double bestDeltaR = cutsDr_[0];
00413 size_t bestMatch = kNull;
00414 for (it = indicesL1.begin(); it != indicesL1.end(); it++) {
00415 if (candsL1[*it].isAvailable()) {
00416 double dR = deltaR(cand->eta(), cand->phi(),
00417 candsL1[*it]->eta(), candsL1[*it]->phi());
00418 if (dR < bestDeltaR) {
00419 bestMatch = *it;
00420 bestDeltaR = dR;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430 } else {
00431 LogWarning("HLTMuonValidator")
00432 << "Ref candsL1[*it]: product not available "
00433 << *it;
00434 }
00435 }
00436 if (bestMatch != kNull)
00437 matches[i].candL1 = & * candsL1[bestMatch];
00438 indicesL1.erase(bestMatch);
00439
00440 matches[i].candHlt.assign(candsHlt.size(), 0);
00441 for (size_t j = 0; j < candsHlt.size(); j++) {
00442 size_t level = (candsHlt.size() == 4) ? (j < 2) ? 2 : 3 :
00443 (candsHlt.size() == 2) ? (j < 1) ? 2 : 3 :
00444 2;
00445 bestDeltaR = cutsDr_[level - 2];
00446 bestMatch = kNull;
00447 for (it = indicesHlt[j].begin(); it != indicesHlt[j].end(); it++) {
00448 double dR = deltaR(cand->eta(), cand->phi(),
00449 candsHlt[j][*it]->eta(), candsHlt[j][*it]->phi());
00450 if (dR < bestDeltaR) {
00451 bestMatch = *it;
00452 bestDeltaR = dR;
00453 }
00454 }
00455 if (bestMatch != kNull)
00456 matches[i].candHlt[j] = candsHlt[j][bestMatch];
00457 indicesHlt[j].erase(bestMatch);
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468 }
00469
00470 }
00471
00472
00473
00474
00475 void
00476 HLTMuonValidator::bookHist(string path, string label,
00477 string source, string type)
00478 {
00479
00480 string sourceUpper = source;
00481 sourceUpper[0] = toupper(sourceUpper[0]);
00482 string name = source + "Pass" + type + "_" + label;
00483 string rootName = path + "_" + name;
00484 TH1F * h;
00485
00486 if (type.find("MaxPt") != string::npos) {
00487 string desc = (type == "MaxPt1") ? "Leading" : "Next-to-Leading";
00488 string title = "pT of " + desc + " " + sourceUpper + " Muon "+
00489 "matched to " + label;
00490 const size_t nBins = parametersTurnOn_.size() - 1;
00491 float * edges = new float[nBins + 1];
00492 for (size_t i = 0; i < nBins + 1; i++) edges[i] = parametersTurnOn_[i];
00493 h = new TH1F(rootName.c_str(), title.c_str(), nBins, edges);
00494 }
00495
00496 else {
00497 string symbol = (type == "Eta") ? "#eta" : "#phi";
00498 string title = symbol + " of " + sourceUpper + " Muons " +
00499 "matched to " + label;
00500 vector<double> params = (type == "Eta") ? parametersEta_ : parametersPhi_;
00501 int nBins = (int)params[0];
00502 double min = params[1];
00503 double max = params[2];
00504 h = new TH1F(rootName.c_str(), title.c_str(), nBins, min, max);
00505 }
00506
00507 h->Sumw2();
00508 elements_[rootName] = dbe_->book1D(name, h);
00509 delete h;
00510
00511 }
00512
00513
00514
00515 DEFINE_FWK_MODULE(HLTMuonValidator);