CMS 3D CMS Logo

SmearedJetProducerT.h
Go to the documentation of this file.
1 #ifndef PAT_SMEAREDJETPRODUCERT_H
2 #define PAT_SMEAREDJETPRODUCERT_H
3 
16 
25 
29 
31 
32 #include <TFile.h>
33 #include <TH1.h>
34 #include <TH1F.h>
35 
36 #include <memory>
37 #include <random>
38 
39 namespace pat {
40  class GenJetMatcher {
41  public:
43  m_genJetsToken(collector.consumes<reco::GenJetCollection>(cfg.getParameter<edm::InputTag>("genJets"))),
44  m_dR_max(cfg.getParameter<double>("dRMax")),
45  m_dPt_max_factor(cfg.getParameter<double>("dPtMaxFactor")) {
46  // Empty
47  }
48 
50  desc.add<edm::InputTag>("genJets");
51  desc.add<double>("dRMax");
52  desc.add<double>("dPtMaxFactor");
53  }
54 
55  void getTokens(const edm::Event& event) {
56  event.getByToken(m_genJetsToken, m_genJets);
57  }
58 
59  template<class T>
60  const reco::GenJet* match(const T& jet, double resolution) {
62 
63  // Try to find a gen jet matching
64  // dR < m_dR_max
65  // dPt < m_dPt_max_factor * resolution
66 
67  double min_dR = std::numeric_limits<double>::infinity();
68  const reco::GenJet* matched_genJet = nullptr;
69 
70  for (const auto& genJet: genJets) {
71  double dR = deltaR(genJet, jet);
72 
73  if (dR > min_dR)
74  continue;
75 
76  if (dR < m_dR_max) {
77  double dPt = std::abs(genJet.pt() - jet.pt());
78  if (dPt > m_dPt_max_factor * resolution)
79  continue;
80 
81  min_dR = dR;
82  matched_genJet = &genJet;
83  }
84  }
85 
86  return matched_genJet;
87  }
88 
89  private:
92 
93  double m_dR_max;
95  };
96 };
97 
98 template <typename T>
100 
101  using JetCollection = std::vector<T>;
102 
103  public:
105  m_enabled(cfg.getParameter<bool>("enabled")),
106  m_debug(cfg.getUntrackedParameter<bool>("debug", false)) {
107 
108  m_jets_token = consumes<JetCollection>(cfg.getParameter<edm::InputTag>("src"));
109 
110  if (m_enabled) {
111  m_rho_token = consumes<double>(cfg.getParameter<edm::InputTag>("rho"));
112 
113  m_use_txt_files = cfg.exists("resolutionFile") && cfg.exists("scaleFactorFile");
114 
115  if (m_use_txt_files) {
116  std::string resolutionFile = cfg.getParameter<edm::FileInPath>("resolutionFile").fullPath();
117  std::string scaleFactorFile = cfg.getParameter<edm::FileInPath>("scaleFactorFile").fullPath();
118 
119  m_resolution_from_file.reset(new JME::JetResolution(resolutionFile));
120  m_scale_factor_from_file.reset(new JME::JetResolutionScaleFactor(scaleFactorFile));
121  } else {
122  m_jets_algo = cfg.getParameter<std::string>("algo");
123  m_jets_algo_pt = cfg.getParameter<std::string>("algopt");
124  }
125 
126  std::uint32_t seed = cfg.getParameter<std::uint32_t>("seed");
127  m_random_generator = std::mt19937(seed);
128 
129  bool skipGenMatching = cfg.getParameter<bool>("skipGenMatching");
130  if (! skipGenMatching)
131  m_genJetMatcher = std::make_shared<pat::GenJetMatcher>(cfg, consumesCollector());
132 
133  std::int32_t variation = cfg.getParameter<std::int32_t>("variation");
134  m_nomVar=1;
135  if (variation == 0)
136  m_systematic_variation = Variation::NOMINAL;
137  else if (variation == 1)
138  m_systematic_variation = Variation::UP;
139  else if (variation == -1)
140  m_systematic_variation = Variation::DOWN;
141  else if (variation == 101) {
142  m_systematic_variation = Variation::NOMINAL;
143  m_nomVar=1;
144  }
145  else if (variation == -101) {
146  m_systematic_variation = Variation::NOMINAL;
147  m_nomVar=-1;
148  }
149  else
150  throw edm::Exception(edm::errors::ConfigFileReadError, "Invalid value for 'variation' parameter. Only -1, 0, 1 or 101, -101 are supported.");
151  }
152 
153  produces<JetCollection>();
154  }
155 
158 
159  desc.add<edm::InputTag>("src");
160  desc.add<bool>("enabled");
161  desc.add<edm::InputTag>("rho");
162  desc.add<std::int32_t>("variation", 0);
163  desc.add<std::uint32_t>("seed", 37428479);
164  desc.add<bool>("skipGenMatching", false);
165  desc.addUntracked<bool>("debug", false);
166 
167  auto source =
169  (edm::ParameterDescription<edm::FileInPath>("resolutionFile", true) and edm::ParameterDescription<edm::FileInPath>("scaleFactorFile", true));
170  desc.addNode(std::move(source));
171 
173 
174  descriptions.addDefault(desc);
175  }
176 
177  virtual void produce(edm::Event& event, const edm::EventSetup& setup) override {
178 
179  edm::Handle<JetCollection> jets_collection;
180  event.getByToken(m_jets_token, jets_collection);
181 
182  // Disable the module when running on real data
183  if (m_enabled && event.isRealData()) {
184  m_enabled = false;
185  m_genJetMatcher.reset();
186  }
187 
189  if (m_enabled)
190  event.getByToken(m_rho_token, rho);
191 
193  JME::JetResolutionScaleFactor resolution_sf;
194 
195  if (m_enabled) {
196  if (m_use_txt_files) {
197  resolution = *m_resolution_from_file;
198  resolution_sf = *m_scale_factor_from_file;
199  } else {
200  resolution = JME::JetResolution::get(setup, m_jets_algo_pt);
201  resolution_sf = JME::JetResolutionScaleFactor::get(setup, m_jets_algo);
202  }
203  }
204 
205  const JetCollection& jets = *jets_collection;
206 
207  if (m_genJetMatcher)
208  m_genJetMatcher->getTokens(event);
209 
210  auto smearedJets = std::make_unique<JetCollection>();
211 
212  for (const auto& jet: jets) {
213 
214  if ((! m_enabled) || (jet.pt() == 0)) {
215  // Module disabled or invalid p4. Simply copy the input jet.
216  smearedJets->push_back(jet);
217 
218  continue;
219  }
220 
221  double jet_resolution = resolution.getResolution({{JME::Binning::JetPt, jet.pt()}, {JME::Binning::JetEta, jet.eta()}, {JME::Binning::Rho, *rho}});
222  double jer_sf = resolution_sf.getScaleFactor({{JME::Binning::JetEta, jet.eta()}}, m_systematic_variation);
223 
224  if (m_debug) {
225  std::cout << "jet: pt: " << jet.pt() << " eta: " << jet.eta() << " phi: " << jet.phi() << " e: " << jet.energy() << std::endl;
226  std::cout << "resolution: " << jet_resolution << std::endl;
227  std::cout << "resolution scale factor: " << jer_sf << std::endl;
228  }
229 
230  const reco::GenJet* genJet = nullptr;
231  if (m_genJetMatcher)
232  genJet = m_genJetMatcher->match(jet, jet.pt() * jet_resolution);
233 
234  double smearFactor = 1.;
235 
236  if (genJet) {
237  /*
238  * Case 1: we have a "good" gen jet matched to the reco jet
239  */
240 
241  if (m_debug) {
242  std::cout << "gen jet: pt: " << genJet->pt() << " eta: " << genJet->eta() << " phi: " << genJet->phi() << " e: " << genJet->energy() << std::endl;
243  }
244 
245  double dPt = jet.pt() - genJet->pt();
246  smearFactor = 1 + m_nomVar*(jer_sf - 1.) * dPt / jet.pt();
247 
248  } else if (jer_sf > 1) {
249  /*
250  * Case 2: we don't have a gen jet. Smear jet pt using a random gaussian variation
251  */
252 
253  double sigma = jet_resolution * std::sqrt(jer_sf * jer_sf - 1);
254  if (m_debug) {
255  std::cout << "gaussian width: " << sigma << std::endl;
256  }
257 
258  std::normal_distribution<> d(0, sigma);
259  smearFactor = 1. + m_nomVar*d(m_random_generator);
260  } else if (m_debug) {
261  std::cout << "Impossible to smear this jet" << std::endl;
262  }
263 
264  if (jet.energy() * smearFactor < MIN_JET_ENERGY) {
265  // Negative or too small smearFactor. We would change direction of the jet
266  // and this is not what we want.
267  // Recompute the smearing factor in order to have jet.energy() == MIN_JET_ENERGY
268  double newSmearFactor = MIN_JET_ENERGY / jet.energy();
269  if (m_debug) {
270  std::cout << "The smearing factor (" << smearFactor << ") is either negative or too small. Fixing it to " << newSmearFactor << " to avoid change of direction." << std::endl;
271  }
272  smearFactor = newSmearFactor;
273  }
274 
275  T smearedJet = jet;
276  smearedJet.scaleEnergy(smearFactor);
277 
278  if (m_debug) {
279  std::cout << "smeared jet (" << smearFactor << "): pt: " << smearedJet.pt() << " eta: " << smearedJet.eta() << " phi: " << smearedJet.phi() << " e: " << smearedJet.energy() << std::endl;
280  }
281 
282  smearedJets->push_back(smearedJet);
283  }
284 
285  // Sort jets by pt
286  std::sort(smearedJets->begin(), smearedJets->end(), jetPtComparator);
287 
288  event.put(std::move(smearedJets));
289  }
290 
291  private:
292  static constexpr const double MIN_JET_ENERGY = 1e-2;
293 
296  bool m_enabled;
300  bool m_debug;
301  std::shared_ptr<pat::GenJetMatcher> m_genJetMatcher;
302 
304  std::unique_ptr<JME::JetResolution> m_resolution_from_file;
305  std::unique_ptr<JME::JetResolutionScaleFactor> m_scale_factor_from_file;
306 
307  std::mt19937 m_random_generator;
308 
310 
311  int m_nomVar;
312 };
313 #endif
edm::EDGetTokenT< JetCollection > m_jets_token
T getParameter(std::string const &) const
virtual double pt() const final
transverse momentum
float getResolution(const JetParameters &parameters) const
void getTokens(const edm::Event &event)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
static const JetResolution get(const edm::EventSetup &, const std::string &)
virtual double eta() const final
momentum pseudorapidity
edm::Handle< reco::GenJetCollection > m_genJets
std::vector< GenJet > GenJetCollection
collection of GenJet objects
virtual void produce(edm::Event &event, const edm::EventSetup &setup) override
GenJetMatcher(const edm::ParameterSet &cfg, edm::ConsumesCollector &&collector)
bool exists(std::string const &parameterName) const
checks if a parameter exists
SmearedJetProducerT(const edm::ParameterSet &cfg)
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:1
bool isRealData() const
Definition: EventBase.h:62
#define constexpr
Definition: HeavyIon.h:7
GreaterByPt< T > jetPtComparator
const reco::GenJet * match(const T &jet, double resolution)
virtual double phi() const final
momentum azimuthal angle
std::unique_ptr< JME::JetResolution > m_resolution_from_file
static void fillDescriptions(edm::ParameterSetDescription &desc)
void addDefault(ParameterSetDescription const &psetDescription)
std::vector< T > JetCollection
T sqrt(T t)
Definition: SSEVec.h:18
vector< PseudoJet > jets
virtual double energy() const final
energy
const double infinity
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Jets made from MC generator particles.
Definition: GenJet.h:24
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::EDGetTokenT< double > m_rho_token
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
std::mt19937 m_random_generator
float getScaleFactor(const JetParameters &parameters, Variation variation=Variation::NOMINAL) const
static const JetResolutionScaleFactor get(const edm::EventSetup &, const std::string &)
std::shared_ptr< pat::GenJetMatcher > m_genJetMatcher
fixed size matrix
HLT enums.
std::unique_ptr< JME::JetResolutionScaleFactor > m_scale_factor_from_file
edm::EDGetTokenT< reco::GenJetCollection > m_genJetsToken
long double T
static std::string const source
Definition: EdmProvDump.cc:43
def move(src, dest)
Definition: eostools.py:510
Definition: event.py:1