CMS 3D CMS Logo

PFJetAnalyzerDQM.cc
Go to the documentation of this file.
13 
14 #include <algorithm>
15 #include <numeric>
16 #include <regex>
17 #include <sstream>
18 #include <vector>
19 #include <memory>
20 
22 public:
24  void analyze(const edm::Event&, const edm::EventSetup&) override;
25 
26 protected:
27  //Book histograms
28  void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
29 
30 private:
31  class Plot1DInBin {
32  public:
34  const uint32_t nbins;
35  const float min, max;
38 
39  Plot1DInBin(const std::string _name,
40  const std::string _title,
41  const uint32_t _nbins,
42  const float _min,
43  const float _max,
44  float _ptbin_low,
45  float _ptbin_high,
46  float _etabin_low,
47  float _etabin_high)
48  : name(_name),
49  title(_title),
50  nbins(_nbins),
51  min(_min),
52  max(_max),
53  ptbin_low(_ptbin_low),
54  ptbin_high(_ptbin_high),
55  etabin_low(_etabin_low),
56  etabin_high(_etabin_high) {}
57 
58  void book(DQMStore::IBooker& booker) { plot_ = booker.book1D(name, title, nbins, min, max); }
59 
60  void fill(float value) {
61  assert(plot_ != nullptr);
62  plot_->Fill(value);
63  }
64 
65  //Check if a jet with a value v would be in the bin that applies to this plot
66  bool isInBin(float v, float low, float high) { return v >= low && v < high; }
67 
68  bool isInPtBin(float pt) { return isInBin(pt, ptbin_low, ptbin_high); }
69 
70  bool isInEtaBin(float eta) { return isInBin(eta, etabin_low, etabin_high); }
71 
72  bool isInPtEtaBin(float pt, float eta) { return isInPtBin(pt) && isInEtaBin(eta); }
73  };
74 
76  public:
78  std::unique_ptr<TH1F> base_hist;
81 
83  const std::string _title,
84  std::unique_ptr<TH1F> _base_hist,
85  float _ptbin_low,
86  float _ptbin_high,
87  float _etabin_low,
88  float _etabin_high)
89  : name(_name),
90  title(_title),
91  base_hist(std::move(_base_hist)),
92  ptbin_low(_ptbin_low),
93  ptbin_high(_ptbin_high),
94  etabin_low(_etabin_low),
95  etabin_high(_etabin_high) {}
96 
97  void book(DQMStore::IBooker& booker) { plot_ = booker.book1D(name.c_str(), base_hist.get()); }
98 
99  void fill(float value) {
100  assert(plot_ != nullptr);
101  plot_->Fill(value);
102  }
103 
104  //Check if a jet with a value v would be in the bin that applies to this plot
105  bool isInBin(float v, float low, float high) { return v >= low && v < high; }
106 
107  bool isInPtBin(float pt) { return isInBin(pt, ptbin_low, ptbin_high); }
108 
109  bool isInEtaBin(float eta) { return isInBin(eta, etabin_low, etabin_high); }
110 
111  bool isInPtEtaBin(float pt, float eta) { return isInPtBin(pt) && isInEtaBin(eta); }
112  };
113 
114  std::vector<Plot1DInBin> jetResponsePlots;
115  std::vector<Plot1DInBin> jetResponsePlots_noJEC;
116  std::vector<Plot1DInBinVariable> genJetPlots;
117  std::vector<Plot1DInBinVariable> genJetPlots_matched;
118  std::vector<Plot1DInBinVariable> genJetPlots_unmatched;
119  std::vector<Plot1DInBinVariable> recoJetPlots;
120  std::vector<Plot1DInBinVariable> recoJetPlots_matched;
121  std::vector<Plot1DInBinVariable> recoJetPlots_unmatched;
122  // Is this data or MC?
123  bool isMC;
124 
125  float jetDeltaR;
126 
128 
130 
136 
138  void prepareJetResponsePlots(const std::vector<edm::ParameterSet>& genjet_plots_pset);
139  void prepareGenJetPlots(const std::vector<edm::ParameterSet>& genjet_plots_pset);
140  void prepareGenJetMatchedPlots(const std::vector<edm::ParameterSet>& genjet_plots_pset);
141  void prepareGenJetUnmatchedPlots(const std::vector<edm::ParameterSet>& genjet_plots_pset);
142  void prepareRecoJetPlots(const std::vector<edm::ParameterSet>& recojet_plots_pset);
143  void prepareRecoJetMatchedPlots(const std::vector<edm::ParameterSet>& recojet_plots_pset);
144  void prepareRecoJetUnmatchedPlots(const std::vector<edm::ParameterSet>& recojet_plots_pset);
145 };
146 
147 void PFJetAnalyzerDQM::prepareJetResponsePlots(const std::vector<edm::ParameterSet>& response_plots) {
148  for (auto& pset : response_plots) {
149  //Low and high edges of the pt and eta bins for jets to pass to be filled into this histogram
150  const auto ptbin_low = pset.getParameter<double>("ptBinLow");
151  const auto ptbin_high = pset.getParameter<double>("ptBinHigh");
152  const auto etabin_low = pset.getParameter<double>("etaBinLow");
153  const auto etabin_high = pset.getParameter<double>("etaBinHigh");
154 
155  const auto response_nbins = pset.getParameter<uint32_t>("responseNbins");
156  const auto response_low = pset.getParameter<double>("responseLow");
157  const auto response_high = pset.getParameter<double>("responseHigh");
158 
159  const auto name = pset.getParameter<std::string>("name");
160  const auto title = pset.getParameter<std::string>("title");
161 
162  // for title of raw jet response histograms
163  auto rawTitle = title;
164  rawTitle = rawTitle.replace(rawTitle.begin(), rawTitle.begin(), "Raw ");
165 
166  jetResponsePlots.push_back(Plot1DInBin(
167  name, title, response_nbins, response_low, response_high, ptbin_low, ptbin_high, etabin_low, etabin_high));
168 
170  name, rawTitle, response_nbins, response_low, response_high, ptbin_low, ptbin_high, etabin_low, etabin_high));
171  }
172  if (jetResponsePlots.size() > 200) {
173  throw std::runtime_error("Requested too many jet response plots, aborting as this seems unusual.");
174  }
175 }
176 
177 void PFJetAnalyzerDQM::prepareGenJetPlots(const std::vector<edm::ParameterSet>& genjet_plots_pset) {
178  for (auto& pset : genjet_plots_pset) {
179  const auto name = pset.getParameter<std::string>("name");
180  const auto title = pset.getParameter<std::string>("title");
181 
182  //Low and high edges of the eta bins for jets to pass to be filled into this histogram
183  const auto ptbins_d = pset.getParameter<std::vector<double>>("ptBins");
184  std::vector<float> ptbins(ptbins_d.begin(), ptbins_d.end());
185 
186  const auto etabin_low = pset.getParameter<double>("etaBinLow");
187  const auto etabin_high = pset.getParameter<double>("etaBinHigh");
188 
190  name,
191  title,
192  std::make_unique<TH1F>(name.c_str(), title.c_str(), static_cast<int>(ptbins.size()) - 1, ptbins.data()),
193  0.0,
194  0.0,
195  etabin_low,
196  etabin_high));
197  }
198 }
199 
200 void PFJetAnalyzerDQM::prepareGenJetMatchedPlots(const std::vector<edm::ParameterSet>& genjet_plots_pset) {
201  for (auto& pset : genjet_plots_pset) {
202  const auto name = pset.getParameter<std::string>("name") + "_matched";
203  const auto title = "Matched " + pset.getParameter<std::string>("title");
204 
205  //Low and high edges of the eta bins for jets to pass to be filled into this histogram
206  const auto ptbins_d = pset.getParameter<std::vector<double>>("ptBins");
207  std::vector<float> ptbins(ptbins_d.begin(), ptbins_d.end());
208 
209  const auto etabin_low = pset.getParameter<double>("etaBinLow");
210  const auto etabin_high = pset.getParameter<double>("etaBinHigh");
211 
213  name,
214  title,
215  std::make_unique<TH1F>(name.c_str(), title.c_str(), static_cast<int>(ptbins.size()) - 1, ptbins.data()),
216  0.0,
217  0.0,
218  etabin_low,
219  etabin_high));
220  }
221 }
222 
223 void PFJetAnalyzerDQM::prepareGenJetUnmatchedPlots(const std::vector<edm::ParameterSet>& genjet_plots_pset) {
224  for (auto& pset : genjet_plots_pset) {
225  const auto name = pset.getParameter<std::string>("name") + "_unmatched";
226  const auto title = "Unmatched " + pset.getParameter<std::string>("title");
227 
228  //Low and high edges of the eta bins for jets to pass to be filled into this histogram
229  const auto ptbins_d = pset.getParameter<std::vector<double>>("ptBins");
230  std::vector<float> ptbins(ptbins_d.begin(), ptbins_d.end());
231 
232  const auto etabin_low = pset.getParameter<double>("etaBinLow");
233  const auto etabin_high = pset.getParameter<double>("etaBinHigh");
234 
236  name,
237  title,
238  std::make_unique<TH1F>(name.c_str(), title.c_str(), static_cast<int>(ptbins.size()) - 1, ptbins.data()),
239  0.0,
240  0.0,
241  etabin_low,
242  etabin_high));
243  }
244 }
245 
246 void PFJetAnalyzerDQM::prepareRecoJetPlots(const std::vector<edm::ParameterSet>& recojet_plots_pset) {
247  for (auto& pset : recojet_plots_pset) {
248  const auto name = pset.getParameter<std::string>("name");
249  const auto title = pset.getParameter<std::string>("title");
250 
251  //Low and high edges of the eta bins for jets to pass to be filled into this histogram
252  const auto ptbins_d = pset.getParameter<std::vector<double>>("ptBins");
253  std::vector<float> ptbins(ptbins_d.begin(), ptbins_d.end());
254 
255  const auto etabin_low = pset.getParameter<double>("etaBinLow");
256  const auto etabin_high = pset.getParameter<double>("etaBinHigh");
257 
259  name,
260  title,
261  std::make_unique<TH1F>(name.c_str(), title.c_str(), static_cast<int>(ptbins.size()) - 1, ptbins.data()),
262  0.0,
263  0.0,
264  etabin_low,
265  etabin_high));
266  }
267 }
268 
269 void PFJetAnalyzerDQM::prepareRecoJetMatchedPlots(const std::vector<edm::ParameterSet>& recojet_plots_pset) {
270  for (auto& pset : recojet_plots_pset) {
271  const auto name = pset.getParameter<std::string>("name") + "_matched";
272  const auto title = "Matched " + pset.getParameter<std::string>("title");
273 
274  //Low and high edges of the eta bins for jets to pass to be filled into this histogram
275  const auto ptbins_d = pset.getParameter<std::vector<double>>("ptBins");
276  std::vector<float> ptbins(ptbins_d.begin(), ptbins_d.end());
277 
278  const auto etabin_low = pset.getParameter<double>("etaBinLow");
279  const auto etabin_high = pset.getParameter<double>("etaBinHigh");
280 
282  name,
283  title,
284  std::make_unique<TH1F>(name.c_str(), title.c_str(), static_cast<int>(ptbins.size()) - 1, ptbins.data()),
285  0.0,
286  0.0,
287  etabin_low,
288  etabin_high));
289  }
290 }
291 
292 void PFJetAnalyzerDQM::prepareRecoJetUnmatchedPlots(const std::vector<edm::ParameterSet>& recojet_plots_pset) {
293  for (auto& pset : recojet_plots_pset) {
294  const auto name = pset.getParameter<std::string>("name") + "_unmatched";
295  const auto title = "Unmatched " + pset.getParameter<std::string>("title");
296 
297  //Low and high edges of the eta bins for jets to pass to be filled into this histogram
298  const auto ptbins_d = pset.getParameter<std::vector<double>>("ptBins");
299  std::vector<float> ptbins(ptbins_d.begin(), ptbins_d.end());
300 
301  const auto etabin_low = pset.getParameter<double>("etaBinLow");
302  const auto etabin_high = pset.getParameter<double>("etaBinHigh");
303 
305  name,
306  title,
307  std::make_unique<TH1F>(name.c_str(), title.c_str(), static_cast<int>(ptbins.size()) - 1, ptbins.data()),
308  0.0,
309  0.0,
310  etabin_low,
311  etabin_high));
312  }
313 }
314 
316  recoJetsLabel = iConfig.getParameter<edm::InputTag>("recoJetCollection");
317  genJetsLabel = iConfig.getParameter<edm::InputTag>("genJetCollection");
318 
319  //label for making new folder
321 
322  //DeltaR for reco to gen jet matching
323  jetDeltaR = iConfig.getParameter<double>("jetDeltaR");
324 
325  //for turn genJet on/off
326  genJetsOn = iConfig.getParameter<bool>("genJetsOn");
327  recoJetsOn = iConfig.getParameter<bool>("recoJetsOn");
328 
329  //Create all jet response plots in bins of genjet pt and eta
330  const auto& response_plots = iConfig.getParameter<std::vector<edm::ParameterSet>>("responsePlots");
331  prepareJetResponsePlots(response_plots);
332 
333  const auto& genjet_plots = iConfig.getParameter<std::vector<edm::ParameterSet>>("genJetPlots");
334  prepareGenJetPlots(genjet_plots);
335  prepareGenJetMatchedPlots(genjet_plots);
336  prepareGenJetUnmatchedPlots(genjet_plots);
337 
338  const auto& recojet_plots = iConfig.getParameter<std::vector<edm::ParameterSet>>("recoJetPlots");
339  prepareRecoJetPlots(recojet_plots);
340  prepareRecoJetMatchedPlots(recojet_plots);
341  prepareRecoJetUnmatchedPlots(recojet_plots);
342 
343  recoJetsToken = consumes<edm::View<pat::Jet>>(recoJetsLabel);
344  genJetsToken = consumes<edm::View<reco::Jet>>(genJetsLabel);
345 }
346 
348  //match gen jets to reco jets, require minimum jetDeltaR, choose closest, do not try to match charge
349  std::vector<int> matchIndices;
350  std::vector<int> matchIndicesReco;
351  PFB::match(genJetCollection, recoJetCollection, matchIndices, false, jetDeltaR);
352  PFB::match(recoJetCollection, genJetCollection, matchIndicesReco, false, jetDeltaR);
353 
354  //Fill recojet pt if recoJetOn
355  for (unsigned int i = 0; i < recoJetCollection.size(); i++) {
356  const auto& recoJet = recoJetCollection.at(i);
357  const auto pt_reco = recoJet.pt();
358  const auto eta_reco = abs(recoJet.eta());
359  const int iMatch_reco = matchIndicesReco[i];
360  if (recoJetsOn) {
361  for (auto& plot : recoJetPlots) {
362  if (plot.isInEtaBin(eta_reco)) {
363  plot.fill(pt_reco);
364  }
365  }
366  if (iMatch_reco != -1) {
367  for (auto& plot : recoJetPlots_matched) {
368  if (plot.isInEtaBin(eta_reco)) {
369  plot.fill(pt_reco);
370  }
371  }
372  } else {
373  for (auto& plot : recoJetPlots_unmatched) {
374  if (plot.isInEtaBin(eta_reco)) {
375  plot.fill(pt_reco);
376  }
377  }
378  }
379  }
380  }
381 
382  for (unsigned int i = 0; i < genJetCollection.size(); i++) {
383  const auto& genJet = genJetCollection.at(i);
384  const auto pt_gen = genJet.pt();
385  const auto eta_gen = abs(genJet.eta());
386  const int iMatch = matchIndices[i];
387 
388  //Fill genjet pt if genJetOn
389  if (genJetsOn) {
390  for (auto& plot : genJetPlots) {
391  if (plot.isInEtaBin(eta_gen)) {
392  plot.fill(pt_gen);
393  }
394  }
395  }
396  if (recoJetsOn) {
397  if (iMatch != -1) {
398  for (auto& plot : genJetPlots_matched) {
399  if (plot.isInEtaBin(eta_gen)) {
400  plot.fill(pt_gen);
401  }
402  }
403  } else {
404  for (auto& plot : genJetPlots_unmatched) {
405  if (plot.isInEtaBin(eta_gen)) {
406  plot.fill(pt_gen);
407  }
408  }
409  }
410  }
411 
412  //If gen jet had a matched reco jet
413  if (iMatch != -1) {
414  const auto& recoJet = recoJetCollection[iMatch];
415  auto pt_reco = recoJet.pt();
416 
417  const auto response = pt_reco / pt_gen;
418  const auto response_raw = pt_reco * recoJet.jecFactor("Uncorrected") / pt_gen;
419 
420  //Loop linearly through all plots and check if they match the pt and eta bin
421  //this is not algorithmically optimal but we don't expect to more than a few hundred plots
422  //If this turns out to be a problem, can easily make a 2D-map for indices
423  for (auto& plot : jetResponsePlots) {
424  if (plot.isInPtEtaBin(pt_gen, eta_gen)) {
425  plot.fill(response);
426  }
427  }
428  // this loop should be for NoJEC plots
429  for (auto& plot : jetResponsePlots_noJEC) {
430  if (plot.isInPtEtaBin(pt_gen, eta_gen)) {
431  plot.fill(response_raw);
432  }
433  }
434  }
435  }
436 }
437 
439  booker.setCurrentFolder("ParticleFlow/JetResponse/" + jetCollectionName + "/JEC/");
440  for (auto& plot : jetResponsePlots) {
441  plot.book(booker);
442  }
443  //Book plots for noJEC
444  booker.setCurrentFolder("ParticleFlow/JetResponse/" + jetCollectionName + "/noJEC/");
445  for (auto& plot : jetResponsePlots_noJEC) {
446  plot.book(booker);
447  }
448 
449  if (recoJetsOn) {
450  booker.setCurrentFolder("ParticleFlow/JetResponse/" + jetCollectionName + "/noJEC/");
451  for (auto& plot : genJetPlots_matched) {
452  plot.book(booker);
453  }
454  for (auto& plot : genJetPlots_unmatched) {
455  plot.book(booker);
456  }
457  booker.setCurrentFolder("ParticleFlow/JetResponse/" + jetCollectionName + "/JEC/");
458  for (auto& plot : recoJetPlots) {
459  plot.book(booker);
460  }
461  for (auto& plot : recoJetPlots_matched) {
462  plot.book(booker);
463  }
464  for (auto& plot : recoJetPlots_unmatched) {
465  plot.book(booker);
466  }
467  }
468 
469  //Book plots for gen-jet pt spectra
470  if (genJetsOn) {
471  booker.setCurrentFolder("ParticleFlow/GenJets/");
472  for (auto& plot : genJetPlots) {
473  plot.book(booker);
474  }
475  }
476 }
477 
479  edm::Handle<edm::View<pat::Jet>> recoJetCollectionHandle;
480  iEvent.getByToken(recoJetsToken, recoJetCollectionHandle);
481  auto recoJetCollection = *recoJetCollectionHandle;
482 
483  isMC = !iEvent.isRealData();
484 
485  if (isMC) {
486  edm::Handle<edm::View<reco::Jet>> genJetCollectionHandle;
487  iEvent.getByToken(genJetsToken, genJetCollectionHandle);
488  auto genJetCollection = *genJetCollectionHandle;
489 
491  }
492 }
493 
edm::EDGetTokenT< edm::View< pat::Jet > > recoJetsToken
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
Plot1DInBin(const std::string _name, const std::string _title, const uint32_t _nbins, const float _min, const float _max, float _ptbin_low, float _ptbin_high, float _etabin_low, float _etabin_high)
void book(DQMStore::IBooker &booker)
void prepareJetResponsePlots(const std::vector< edm::ParameterSet > &genjet_plots_pset)
void match(const C &candCollection, const M &matchedCandCollection, std::vector< int > &matchIndices, bool matchCharge=false, float dRMax=-1)
Definition: Matchers.h:17
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
std::vector< Plot1DInBin > jetResponsePlots
bool isInBin(float v, float low, float high)
std::vector< Plot1DInBinVariable > recoJetPlots
void fillJetResponse(edm::View< pat::Jet > &recoJetCollection, edm::View< reco::Jet > &genJetCollection)
std::string const & label() const
Definition: InputTag.h:36
void prepareGenJetMatchedPlots(const std::vector< edm::ParameterSet > &genjet_plots_pset)
assert(be >=bs)
edm::EDGetTokenT< edm::View< reco::Jet > > genJetsToken
PFJetAnalyzerDQM(const edm::ParameterSet &)
bool isInBin(float v, float low, float high)
void prepareRecoJetMatchedPlots(const std::vector< edm::ParameterSet > &recojet_plots_pset)
bool isInPtEtaBin(float pt, float eta)
void prepareRecoJetUnmatchedPlots(const std::vector< edm::ParameterSet > &recojet_plots_pset)
edm::InputTag genJetsLabel
void Fill(long long x)
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
std::vector< Plot1DInBinVariable > recoJetPlots_matched
int iEvent
Definition: GenABIO.cc:224
std::vector< Plot1DInBinVariable > recoJetPlots_unmatched
void book(DQMStore::IBooker &booker)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::string jetCollectionName
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Definition: value.py:1
edm::InputTag recoJetsLabel
edm::EDGetTokenT< reco::CandViewMatchMap > srcRefToJetMap
std::vector< Plot1DInBinVariable > genJetPlots
std::vector< Plot1DInBinVariable > genJetPlots_matched
std::vector< Plot1DInBinVariable > genJetPlots_unmatched
void prepareGenJetUnmatchedPlots(const std::vector< edm::ParameterSet > &genjet_plots_pset)
void prepareRecoJetPlots(const std::vector< edm::ParameterSet > &recojet_plots_pset)
void analyze(const edm::Event &, const edm::EventSetup &) override
void prepareGenJetPlots(const std::vector< edm::ParameterSet > &genjet_plots_pset)
Plot1DInBinVariable(const std::string _name, const std::string _title, std::unique_ptr< TH1F > _base_hist, float _ptbin_low, float _ptbin_high, float _etabin_low, float _etabin_high)
bool isInPtEtaBin(float pt, float eta)
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
std::vector< Plot1DInBin > jetResponsePlots_noJEC
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45