CMS 3D CMS Logo

HLTMuonPlotter.cc
Go to the documentation of this file.
1 
14 
19 
20 using namespace std;
21 using namespace edm;
22 using namespace reco;
23 using namespace trigger;
24 
25 namespace {
26  const unsigned int kNull = (unsigned int)-1;
27 }
28 
29 typedef vector<ParameterSet> Parameters;
30 
32  string hltPath,
33  const std::vector<string> &moduleLabels,
34  const std::vector<string> &stepLabels,
35  const edm::EDGetTokenT<trigger::TriggerEventWithRefs> &triggerEventToken,
36  const edm::EDGetTokenT<reco::GenParticleCollection> &genParticlesToken,
37  const edm::EDGetTokenT<reco::MuonCollection> &recoMuonsToken,
38  const L1MuonMatcherAlgoForDQM &l1Matcher)
39  : l1Matcher_(l1Matcher) {
40  hltPath_ = hltPath;
41  moduleLabels_ = moduleLabels;
42  stepLabels_ = stepLabels;
43  hltProcessName_ = pset.getParameter<string>("hltProcessName");
44 
45  cutsDr_ = pset.getParameter<vector<double>>("cutsDr");
46 
47  parametersEta_ = pset.getParameter<vector<double>>("parametersEta");
48  parametersPhi_ = pset.getParameter<vector<double>>("parametersPhi");
49  parametersTurnOn_ = pset.getParameter<vector<double>>("parametersTurnOn");
50 
51  genMuonCut_ = pset.getParameter<string>("genMuonCut");
52  recMuonCut_ = pset.getParameter<string>("recMuonCut");
53 
54  genMuonSelector_ = nullptr;
55  recMuonSelector_ = nullptr;
56 
57  hltTriggerSummaryRAW_ = triggerEventToken;
58  genParticleLabel_ = genParticlesToken;
59  recMuonLabel_ = recoMuonsToken;
60 }
61 
63 
64 void HLTMuonPlotter::beginRun(DQMStore::IBooker &iBooker, const Run &iRun, const EventSetup &iSetup) {
65  l1Matcher_.init(iSetup);
66 
67  cutMaxEta_ = 2.4;
68  if (hltPath_.find("eta2p1") != string::npos)
69  cutMaxEta_ = 2.1;
70 
71  // Choose a pT cut for gen/rec muons based on the pT cut in the hltPath_
72  unsigned int threshold = 0;
73  TPRegexp ptRegexp("Mu([0-9]+)");
74  TObjArray *regexArray = ptRegexp.MatchS(hltPath_);
75  if (regexArray->GetEntriesFast() == 2) {
76  threshold = atoi(((TObjString *)regexArray->At(1))->GetString());
77  }
78  delete regexArray;
79  // We select a whole number min pT cut slightly above the hltPath_'s final
80  // pt threshold, then subtract a bit to let through particle gun muons with
81  // exact integer pT:
82  cutMinPt_ = ceil(threshold * 1.1) - 0.01;
83  if (cutMinPt_ < 0.)
84  cutMinPt_ = 0.;
85 
86  string baseDir = "HLT/Muon/Distributions/";
88 
89  vector<string> sources(2);
90  sources[0] = "gen";
91  sources[1] = "rec";
92 
93  elements_["CutMinPt"] = iBooker.bookFloat("CutMinPt");
94  elements_["CutMaxEta"] = iBooker.bookFloat("CutMaxEta");
95  elements_["CutMinPt"]->Fill(cutMinPt_);
96  elements_["CutMaxEta"]->Fill(cutMaxEta_);
97 
98  for (size_t i = 0; i < sources.size(); i++) {
99  string source = sources[i];
100  for (size_t j = 0; j < stepLabels_.size(); j++) {
101  bookHist(iBooker, hltPath_, stepLabels_[j], source, "Eta");
102  bookHist(iBooker, hltPath_, stepLabels_[j], source, "Phi");
103  bookHist(iBooker, hltPath_, stepLabels_[j], source, "MaxPt1");
104  bookHist(iBooker, hltPath_, stepLabels_[j], source, "MaxPt2");
105  }
106  }
107 }
108 
109 void HLTMuonPlotter::analyze(const Event &iEvent, const EventSetup &iSetup) {
110  LogTrace("HLTMuonVal") << "In HLTMuonPlotter::analyze, "
111  << "Event: " << iEvent.id();
112 
113  // cout << hltPath_ << endl;
114  // for (size_t i = 0; i < moduleLabels_.size(); i++)
115  // cout << " " << moduleLabels_[i] << endl;
116 
117  Handle<TriggerEventWithRefs> rawTriggerEvent;
118  Handle<MuonCollection> recMuons;
120 
121  iEvent.getByToken(hltTriggerSummaryRAW_, rawTriggerEvent);
122  if (rawTriggerEvent.failedToGet()) {
123  LogError("HLTMuonVal") << "No trigger summary found";
124  return;
125  }
126  iEvent.getByToken(recMuonLabel_, recMuons);
128 
129  vector<string> sources;
130  if (genParticles.isValid())
131  sources.push_back("gen");
132  if (recMuons.isValid())
133  sources.push_back("rec");
134 
135  for (size_t sourceNo = 0; sourceNo < sources.size(); sourceNo++) {
136  string source = sources[sourceNo];
137 
138  // If this is the first event, initialize selectors
139  if (!genMuonSelector_)
141  if (!recMuonSelector_)
143 
144  // Make each good gen/rec muon into the base cand for a MatchStruct
145  vector<MatchStruct> matches;
146  if (source == "gen" && genParticles.isValid())
147  for (size_t i = 0; i < genParticles->size(); i++)
148  if ((*genMuonSelector_)(genParticles->at(i)))
149  matches.push_back(MatchStruct(&genParticles->at(i)));
150  if (source == "rec" && recMuons.isValid())
151  for (size_t i = 0; i < recMuons->size(); i++)
152  if ((*recMuonSelector_)(recMuons->at(i)))
153  matches.push_back(MatchStruct(&recMuons->at(i)));
154 
155  // Sort the MatchStructs by pT for later filling of turn-on curve
156  sort(matches.begin(), matches.end(), matchesByDescendingPt());
157 
158  const bool isDoubleMuonPath = (hltPath_.find("Double") != string::npos);
159  const size_t nFilters = moduleLabels_.size();
160  const size_t nSteps = stepLabels_.size();
161  const size_t nStepsHlt = nSteps - 2;
162  const int nObjectsToPassPath = (isDoubleMuonPath) ? 2 : 1;
163  l1t::MuonVectorRef candsL1;
164  vector<vector<RecoChargedCandidateRef>> refsHlt(nStepsHlt);
165  vector<vector<const RecoChargedCandidate *>> candsHlt(nStepsHlt);
166 
167  for (size_t i = 0; i < nFilters; i++) {
168  const int hltStep = i - 1;
170  size_t iFilter = rawTriggerEvent->filterIndex(tag);
171  if (iFilter < rawTriggerEvent->size()) {
172  if (i == 0)
173  rawTriggerEvent->getObjects(iFilter, TriggerL1Mu, candsL1);
174  else
175  rawTriggerEvent->getObjects(iFilter, TriggerMuon, refsHlt[hltStep]);
176  } else
177  LogTrace("HLTMuonVal") << "No collection with label " << tag;
178  }
179  for (size_t i = 0; i < nStepsHlt; i++)
180  for (size_t j = 0; j < refsHlt[i].size(); j++)
181  if (refsHlt[i][j].isAvailable()) {
182  candsHlt[i].push_back(&*refsHlt[i][j]);
183  } else {
184  LogWarning("HLTMuonPlotter") << "Ref refsHlt[i][j]: product not available " << i << " " << j;
185  }
186 
187  // Add trigger objects to the MatchStructs
188  findMatches(matches, candsL1, candsHlt);
189 
190  vector<size_t> matchesInEtaRange;
191  vector<bool> hasMatch(matches.size(), true);
192 
193  for (size_t step = 0; step < nSteps; step++) {
194  size_t hltStep = (step >= 2) ? step - 2 : 0;
195  if (nSteps == 6)
196  hltStep = hltStep - 1; // case of the tracker muon (it has no L2)
197  size_t level = 0;
198  if ((stepLabels_[step].find("L3TkIso") != string::npos) || (stepLabels_[step].find("TkTkIso") != string::npos))
199  level = 6;
200  else if ((stepLabels_[step].find("L3HcalIso") != string::npos) ||
201  (stepLabels_[step].find("TkEcalIso") != string::npos))
202  level = 5;
203  else if ((stepLabels_[step].find("L3EcalIso") != string::npos) ||
204  (stepLabels_[step].find("TkEcalIso") != string::npos))
205  level = 4;
206  else if ((stepLabels_[step].find("L3") != string::npos) || (stepLabels_[step].find("Tk") != string::npos))
207  level = 3;
208  else if (stepLabels_[step].find("L2") != string::npos)
209  level = 2;
210  else if (stepLabels_[step].find("L1") != string::npos)
211  level = 1;
212 
213  for (size_t j = 0; j < matches.size(); j++) {
214  if (level == 0) {
215  if (fabs(matches[j].candBase->eta()) < cutMaxEta_)
216  matchesInEtaRange.push_back(j);
217  } else if (level == 1) {
218  if (matches[j].candL1 == nullptr)
219  hasMatch[j] = false;
220  } else if (level >= 2) {
221  if (matches[j].candHlt[hltStep] == nullptr)
222  hasMatch[j] = false;
223  else if (!hasMatch[j]) {
224  LogTrace("HLTMuonVal") << "Match found for HLT step " << hltStep << " of " << nStepsHlt
225  << " without previous match!";
226  break;
227  }
228  }
229  }
230 
231  if (std::count(hasMatch.begin(), hasMatch.end(), true) < nObjectsToPassPath)
232  break;
233 
234  string pre = source + "Pass";
235  string post = "_" + stepLabels_[step];
236 
237  for (size_t j = 0; j < matches.size(); j++) {
238  float pt = matches[j].candBase->pt();
239  float eta = matches[j].candBase->eta();
240  float phi = matches[j].candBase->phi();
241  if (hasMatch[j]) {
242  if (!matchesInEtaRange.empty() && j == matchesInEtaRange[0])
243  elements_[pre + "MaxPt1" + post]->Fill(pt);
244  if (matchesInEtaRange.size() >= 2 && j == matchesInEtaRange[1])
245  elements_[pre + "MaxPt2" + post]->Fill(pt);
246  if (pt > cutMinPt_) {
247  elements_[pre + "Eta" + post]->Fill(eta);
248  if (fabs(eta) < cutMaxEta_)
249  elements_[pre + "Phi" + post]->Fill(phi);
250  }
251  }
252  }
253  }
254 
255  } // End loop over sources
256 }
257 
258 void HLTMuonPlotter::findMatches(vector<MatchStruct> &matches,
259  const l1t::MuonVectorRef &candsL1,
260  const std::vector<vector<const RecoChargedCandidate *>> &candsHlt) {
261  set<size_t>::iterator it;
262 
263  set<size_t> indicesL1;
264  for (size_t i = 0; i < candsL1.size(); i++)
265  indicesL1.insert(i);
266 
267  vector<set<size_t>> indicesHlt(candsHlt.size());
268  for (size_t i = 0; i < candsHlt.size(); i++)
269  for (size_t j = 0; j < candsHlt[i].size(); j++)
270  indicesHlt[i].insert(j);
271 
272  for (size_t i = 0; i < matches.size(); i++) {
273  const Candidate *cand = matches[i].candBase;
274 
275  double bestDeltaR = cutsDr_[0];
276  size_t bestMatch = kNull;
277  for (it = indicesL1.begin(); it != indicesL1.end(); it++) {
278  if (candsL1[*it].isAvailable()) {
279  double dR = deltaR(cand->eta(), cand->phi(), candsL1[*it]->eta(), candsL1[*it]->phi());
280  if (dR < bestDeltaR) {
281  bestMatch = *it;
282  bestDeltaR = dR;
283  }
284  // TrajectoryStateOnSurface propagated;
285  // float dR = 999., dPhi = 999.;
286  // bool isValid = l1Matcher_.match(* cand, * candsL1[*it],
287  // dR, dPhi, propagated);
288  // if (isValid && dR < bestDeltaR) {
289  // bestMatch = *it;
290  // bestDeltaR = dR;
291  // }
292  } else {
293  LogWarning("HLTMuonPlotter") << "Ref candsL1[*it]: product not available " << *it;
294  }
295  }
296 
297  if (bestMatch != kNull)
298  matches[i].candL1 = &*candsL1[bestMatch];
299  indicesL1.erase(bestMatch);
300 
301  matches[i].candHlt.assign(candsHlt.size(), nullptr);
302  for (size_t j = 0; j < candsHlt.size(); j++) {
303  size_t level = (candsHlt.size() == 4) ? (j < 2) ? 2 : 3 : (candsHlt.size() == 2) ? (j < 1) ? 2 : 3 : 2;
304  bestDeltaR = cutsDr_[level - 2];
305  bestMatch = kNull;
306  for (it = indicesHlt[j].begin(); it != indicesHlt[j].end(); it++) {
307  double dR = deltaR(cand->eta(), cand->phi(), candsHlt[j][*it]->eta(), candsHlt[j][*it]->phi());
308  if (dR < bestDeltaR) {
309  bestMatch = *it;
310  bestDeltaR = dR;
311  }
312  }
313  if (bestMatch != kNull)
314  matches[i].candHlt[j] = candsHlt[j][bestMatch];
315  indicesHlt[j].erase(bestMatch);
316  }
317 
318  // cout << " Muon: " << cand->eta() << ", ";
319  // if (matches[i].candL1) cout << matches[i].candL1->eta() << ", ";
320  // else cout << "none, ";
321  // for (size_t j = 0; j < candsHlt.size(); j++)
322  // if (matches[i].candHlt[j]) cout << matches[i].candHlt[j]->eta() <<
323  // ", "; else cout << "none, ";
324  // cout << endl;
325  }
326 }
327 
328 void HLTMuonPlotter::bookHist(DQMStore::IBooker &iBooker, string path, string label, string source, string type) {
329  string sourceUpper = source;
330  sourceUpper[0] = toupper(sourceUpper[0]);
331  string name = source + "Pass" + type + "_" + label;
332  TH1F *h;
333 
334  if (type.find("MaxPt") != string::npos) {
335  string desc = (type == "MaxPt1") ? "Leading" : "Next-to-Leading";
336  string title = "pT of " + desc + " " + sourceUpper + " Muon " + "matched to " + label;
337  const size_t nBins = parametersTurnOn_.size() - 1;
338  float *edges = new float[nBins + 1];
339  for (size_t i = 0; i < nBins + 1; i++)
341  h = new TH1F(name.c_str(), title.c_str(), nBins, edges);
342  }
343 
344  else {
345  string symbol = (type == "Eta") ? "#eta" : "#phi";
346  string title = symbol + " of " + sourceUpper + " Muons " + "matched to " + label;
347  vector<double> params = (type == "Eta") ? parametersEta_ : parametersPhi_;
348  int nBins = (int)params[0];
349  double min = params[1];
350  double max = params[2];
351  h = new TH1F(name.c_str(), title.c_str(), nBins, min, max);
352  }
353 
354  h->Sumw2();
355  elements_[name] = iBooker.book1D(name, h);
356  delete h;
357 }
size
Write out results.
constexpr int32_t ceil(float num)
MonitorElement * bookFloat(TString const &name, FUNC onbooking=NOOP())
Definition: DQMStore.h:80
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
enum start value shifted to 81 so as to avoid clashes with PDG codes
void beginRun(DQMStore::IBooker &, const edm::Run &, const edm::EventSetup &)
std::string hltPath_
std::vector< double > parametersEta_
Log< level::Error, false > LogError
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
std::string genMuonCut_
HLTMuonPlotter(const edm::ParameterSet &, std::string, const std::vector< std::string > &, const std::vector< std::string > &, const edm::EDGetTokenT< trigger::TriggerEventWithRefs > &, const edm::EDGetTokenT< reco::GenParticleCollection > &, const edm::EDGetTokenT< reco::MuonCollection > &, const L1MuonMatcherAlgoForDQM &)
void init(const edm::EventSetup &iSetup)
Call this method at the beginning of each run, to initialize geometry, magnetic field and propagators...
std::vector< std::string > moduleLabels_
#define LogTrace(id)
void findMatches(std::vector< MatchStruct > &, const l1t::MuonVectorRef &candsL1, const std::vector< std::vector< const reco::RecoChargedCandidate *>> &)
std::vector< MuonRef > MuonVectorRef
Definition: Muon.h:15
bool failedToGet() const
Definition: HandleBase.h:72
char const * label
std::string recMuonCut_
int iEvent
Definition: GenABIO.cc:224
vector< ParameterSet > Parameters
size_type filterIndex(const edm::InputTag &filterTag) const
index from tag
std::vector< double > cutsDr_
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
edm::EDGetTokenT< reco::MuonCollection > recMuonLabel_
void analyze(const edm::Event &, const edm::EventSetup &)
bool insert(Storage &iStorage, ItemType *iItem, const IdTag &iIdTag)
Definition: HCMethods.h:50
StringCutObjectSelector< reco::GenParticle > * genMuonSelector_
std::vector< std::string > stepLabels_
void bookHist(DQMStore::IBooker &, std::string, std::string, std::string, std::string)
def bestMatch(object, matchCollection)
Definition: deltar.py:138
L1MuonMatcherAlgoForDQM l1Matcher_
bool isValid() const
Definition: HandleBase.h:70
StringCutObjectSelector< reco::Muon > * recMuonSelector_
fixed size matrix
HLT enums.
std::vector< double > parametersPhi_
step
Definition: StallMonitor.cc:98
std::map< std::string, MonitorElement * > elements_
std::string hltProcessName_
Log< level::Warning, false > LogWarning
edm::EDGetTokenT< reco::GenParticleCollection > genParticleLabel_
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
edm::EDGetTokenT< trigger::TriggerEventWithRefs > hltTriggerSummaryRAW_
std::vector< double > parametersTurnOn_
static std::string const source
Definition: EdmProvDump.cc:46
Definition: Run.h:45
void getObjects(size_type filter, Vids &ids, VRphoton &photons) const
extract Ref<C>s for a specific filter and of specific physics type