CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/HLTriggerOffline/Muon/src/HLTMuonValidator.cc

Go to the documentation of this file.
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     // Add fake HLT path where we bypass all filters
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       // The L2 and L3 collections will be built manually later on
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     // Choose a pT cut for gen/rec muons based on the pT cut in the path
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     // We select a whole number min pT cut slightly above the path's final 
00150     // pt threshold, then subtract a bit to let through particle gun muons with
00151     // exact integer pT:
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       // Standardize the names that will be applied to each step
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       //     string l1Name = path + "_L1Quality";
00188       //     elements_[l1Name.c_str()] = 
00189       //       dbe_->book1D("L1Quality", "Quality of L1 Muons", 8, 0, 8);
00190       //     for (size_t i = 0; i < 8; i++)
00191       //       elements_[l1Name.c_str()]->setBinLabel(i + 1, Form("%i", i));
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     // If this is the first event, initialize selectors
00239     if (!genMuonSelector_) genMuonSelector_ =
00240       new StringCutObjectSelector<reco::GenParticle>(genMuonCut_);
00241     if (!recMuonSelector_) recMuonSelector_ =
00242       new StringCutObjectSelector<reco::Muon       >(recMuonCut_);
00243 
00244     // Make each good gen/rec muon into the base cand for a MatchStruct
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     // Sort the MatchStructs by pT for later filling of turn-on curve
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   } // End loop over sources
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   // Add trigger objects to the MatchStructs
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; // default value when step == 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       // TrajectoryStateOnSurface propagated;
00423       // float dR = 999., dPhi = 999.;
00424       // bool isValid = l1Matcher_.match(* cand, * candsL1[*it], 
00425       //                                 dR, dPhi, propagated);
00426       // if (isValid && dR < bestDeltaR) {
00427       //   bestMatch = *it;
00428       //   bestDeltaR = dR;
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 //     cout << "    Muon: " << cand->eta() << ", ";
00461 //     if (matches[i].candL1) cout << matches[i].candL1->eta() << ", ";
00462 //     else cout << "none, ";
00463 //     for (size_t j = 0; j < candsHlt.size(); j++) 
00464 //       if (matches[i].candHlt[j]) cout << matches[i].candHlt[j]->eta() << ", ";
00465 //       else cout << "none, ";
00466 //     cout << endl;
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);