CP3-llbb Framework
CorrectedMuonProducerT.h
1 #pragma once
2 
11 #include "CommonTools/Utils/interface/PtComparator.h"
12 
13 #include "DataFormats/Common/interface/ValueMap.h"
14 #include "DataFormats/Math/interface/LorentzVector.h"
15 
16 #include "FWCore/Framework/interface/Frameworkfwd.h"
17 #include "FWCore/Framework/interface/stream/EDProducer.h"
18 #include "FWCore/Framework/interface/Event.h"
19 #include "FWCore/Framework/interface/ConsumesCollector.h"
20 #include "FWCore/ParameterSet/interface/ParameterSet.h"
21 #include "FWCore/Utilities/interface/InputTag.h"
22 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
23 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
24 
25 #include <cp3_llbb/Framework/interface/Rochester.h>
26 #include <KaMuCa/Calibration/interface/KalmanMuonCalibrator.h>
27 
28 #include <memory>
29 #include <random>
30 #include <boost/filesystem.hpp>
31 
32 namespace cp3 {
33 
35  public:
36  explicit KaMuCaCorrector(const edm::ParameterSet& cfg) {
37  std::string tag = cfg.getParameter<std::string>("tag");
38  corrector.reset(new KalmanMuonCalibrator(tag));
39  }
40 
41  template<typename T>
42  T correct(const edm::Event& event, const T& muon) {
43  auto corrected_pt = corrector->getCorrectedPt(muon.pt(), muon.eta(), muon.phi(), muon.charge());
44  if (! event.isRealData())
45  corrected_pt = corrector->smear(corrected_pt, muon.eta());
46 
47  double ratio = corrected_pt / muon.pt();
48 
49  T corrected_muon = muon;
50  corrected_muon.setP4(corrected_muon.p4() * ratio);
51 
52  return corrected_muon;
53  }
54 
55  private:
56  std::unique_ptr<KalmanMuonCalibrator> corrector;
57  };
58 
60  public:
61  explicit RochesterCorrector(const edm::ParameterSet& cfg):
62  random_generator(42), random_distribution(0, 1) {
63  auto tag = cfg.getParameter<edm::FileInPath>("input");
64 
65  // Constructor expect a path to the directory, but edm::FileInPath does not support folders
66  // Extract the path from the tag file
67 
68  boost::filesystem::path p(tag.fullPath());
69  corrector.reset(new RoccoR(p.parent_path().native()));
70  }
71 
72  template<typename T>
73  T correct(const edm::Event& event, const T& muon) {
74 
75  float scale_factor = 1.;
76 
77  if (event.isRealData()) {
78  scale_factor = corrector->kScaleDT(muon.charge(), muon.pt(), muon.eta(), muon.phi(), 0 /* set */, 0 /* param */);
79  } else {
80  int n_tracks = 0;
81  if (!muon.innerTrack().isNull())
82  n_tracks = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement();
83 
84  auto gen_particle = muon.genParticle();
85  if (gen_particle)
86  scale_factor = corrector->kScaleFromGenMC(muon.charge(), muon.pt(), muon.eta(), muon.phi(), n_tracks, gen_particle->pt(), random_distribution(random_generator), 0 /* set */, 0 /* param */);
87  else
88  scale_factor = corrector->kScaleAndSmearMC(muon.charge(), muon.pt(), muon.eta(), muon.phi(), n_tracks, random_distribution(random_generator), random_distribution(random_generator), 0 /* set */, 0 /* param */);
89  }
90 
91  if (std::isnan(scale_factor)) {
92  scale_factor = 1.;
93  }
94 
95  T corrected_muon = muon;
96  corrected_muon.setP4(muon.p4() * scale_factor);
97 
98  return corrected_muon;
99  }
100 
101  private:
102  std::unique_ptr<RoccoR> corrector;
103  std::mt19937 random_generator;
104  std::uniform_real_distribution<double> random_distribution;
105  };
106 }
107 
108 template <typename T, class C>
109 class CorrectedMuonProducerT : public edm::stream::EDProducer<> {
110 
111  using MuonCollection = std::vector<T>;
112 
113  public:
114  explicit CorrectedMuonProducerT(const edm::ParameterSet& cfg) {
115 
116  enabled = cfg.getParameter<bool>("enabled");
117  muons_token = consumes<MuonCollection>(cfg.getParameter<edm::InputTag>("src"));
118 
119  if (enabled) {
120  corrector.reset(new C(cfg));
121  }
122 
123  produces<MuonCollection>();
124  produces<edm::ValueMap<float>>("correctionFactors");
125  }
126 
127  virtual void produce(edm::Event& event, const edm::EventSetup& setup) override {
128 
129  edm::Handle<MuonCollection> muons_collection;
130  event.getByToken(muons_token, muons_collection);
131 
132  const MuonCollection& muons = *muons_collection;
133 
134  std::unique_ptr<MuonCollection> corrected_muons(new MuonCollection());
135  std::vector<float> correction_factors;
136 
137  for (const auto& muon: muons) {
138  if ((! enabled) || muon.pt() == 0) {
139  corrected_muons->push_back(muon);
140  correction_factors.push_back(1);
141  continue;
142  }
143 
144  // Correct muon
145  T corrected_muon = corrector->template correct<T>(event, muon);
146 
147  double ratio = corrected_muon.pt() / muon.pt();
148 
149  corrected_muons->push_back(corrected_muon);
150  correction_factors.push_back(ratio);
151  }
152 
153  std::unique_ptr<edm::ValueMap<float>> correction_factors_map(new edm::ValueMap<float>());
154  edm::ValueMap<float>::Filler filler(*correction_factors_map);
155  filler.insert(muons_collection, correction_factors.begin(), correction_factors.end());
156  filler.fill();
157 
158  std::sort(corrected_muons->begin(), corrected_muons->end(), muon_pt_comparator);
159 
160  event.put(std::move(corrected_muons));
161  event.put(std::move(correction_factors_map), "correctionFactors");
162  }
163 
164  private:
165  edm::EDGetTokenT<MuonCollection> muons_token;
166  bool enabled;
167 
168  std::unique_ptr<C> corrector;
169 
170  GreaterByPt<T> muon_pt_comparator;
171 };
Definition: CorrectedMuonProducerT.h:109
Definition: Rochester.h:197
Definition: CorrectedMuonProducerT.h:34
Definition: CorrectedMuonProducerT.h:59