CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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) {
61  const reco::GenJetCollection& genJets = *m_genJets;
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  if (variation == 0)
136  else if (variation == 1)
138  else if (variation == -1)
140  else
141  throw edm::Exception(edm::errors::ConfigFileReadError, "Invalid value for 'variation' parameter. Only -1, 0 or 1 are supported.");
142  }
143 
144  produces<JetCollection>();
145  }
146 
149 
150  desc.add<edm::InputTag>("src");
151  desc.add<bool>("enabled");
152  desc.add<edm::InputTag>("rho");
153  desc.add<std::int32_t>("variation", 0);
154  desc.add<std::uint32_t>("seed", 37428479);
155  desc.add<bool>("skipGenMatching", false);
156  desc.addUntracked<bool>("debug", false);
157 
158  auto source =
160  (edm::ParameterDescription<edm::FileInPath>("resolutionFile", true) and edm::ParameterDescription<edm::FileInPath>("scaleFactorFile", true));
161  desc.addNode(source);
162 
164 
165  descriptions.addDefault(desc);
166  }
167 
168  virtual void produce(edm::Event& event, const edm::EventSetup& setup) override {
169 
170  edm::Handle<JetCollection> jets_collection;
171  event.getByToken(m_jets_token, jets_collection);
172 
173  // Disable the module when running on real data
174  if (m_enabled && event.isRealData()) {
175  m_enabled = false;
176  m_genJetMatcher.reset();
177  }
178 
180  if (m_enabled)
181  event.getByToken(m_rho_token, rho);
182 
184  JME::JetResolutionScaleFactor resolution_sf;
185 
186  if (m_enabled) {
187  if (m_use_txt_files) {
188  resolution = *m_resolution_from_file;
189  resolution_sf = *m_scale_factor_from_file;
190  } else {
191  resolution = JME::JetResolution::get(setup, m_jets_algo_pt);
192  resolution_sf = JME::JetResolutionScaleFactor::get(setup, m_jets_algo);
193  }
194  }
195 
196  const JetCollection& jets = *jets_collection;
197 
198  if (m_genJetMatcher)
199  m_genJetMatcher->getTokens(event);
200 
201  std::unique_ptr<JetCollection> smearedJets(new JetCollection());
202 
203  for (const auto& jet: jets) {
204 
205  if ((! m_enabled) || (jet.pt() == 0)) {
206  // Module disabled or invalid p4. Simply copy the input jet.
207  smearedJets->push_back(jet);
208 
209  continue;
210  }
211 
212  double jet_resolution = resolution.getResolution({{JME::Binning::JetPt, jet.pt()}, {JME::Binning::JetEta, jet.eta()}, {JME::Binning::Rho, *rho}});
213  double jer_sf = resolution_sf.getScaleFactor({{JME::Binning::JetEta, jet.eta()}}, m_systematic_variation);
214 
215  if (m_debug) {
216  std::cout << "jet: pt: " << jet.pt() << " eta: " << jet.eta() << " phi: " << jet.phi() << " e: " << jet.energy() << std::endl;
217  std::cout << "resolution: " << jet_resolution << std::endl;
218  std::cout << "resolution scale factor: " << jer_sf << std::endl;
219  }
220 
221  const reco::GenJet* genJet = nullptr;
222  if (m_genJetMatcher)
223  genJet = m_genJetMatcher->match(jet, jet.pt() * jet_resolution);
224 
225  double smearFactor = 1.;
226 
227  if (genJet) {
228  /*
229  * Case 1: we have a "good" gen jet matched to the reco jet
230  */
231 
232  if (m_debug) {
233  std::cout << "gen jet: pt: " << genJet->pt() << " eta: " << genJet->eta() << " phi: " << genJet->phi() << " e: " << genJet->energy() << std::endl;
234  }
235 
236  double dPt = jet.pt() - genJet->pt();
237  smearFactor = 1 + (jer_sf - 1.) * dPt / jet.pt();
238 
239  } else if (jer_sf > 1) {
240  /*
241  * Case 2: we don't have a gen jet. Smear jet pt using a random gaussian variation
242  */
243 
244  double sigma = jet_resolution * std::sqrt(jer_sf * jer_sf - 1);
245  if (m_debug) {
246  std::cout << "gaussian width: " << sigma << std::endl;
247  }
248 
249  std::normal_distribution<> d(0, sigma);
250  smearFactor = 1. + d(m_random_generator);
251  } else if (m_debug) {
252  std::cout << "Impossible to smear this jet" << std::endl;
253  }
254 
255  T smearedJet = jet;
256  smearedJet.scaleEnergy(smearFactor);
257 
258  if (m_debug) {
259  std::cout << "smeared jet (" << smearFactor << "): pt: " << smearedJet.pt() << " eta: " << smearedJet.eta() << " phi: " << smearedJet.phi() << " e: " << smearedJet.energy() << std::endl;
260  }
261 
262  smearedJets->push_back(smearedJet);
263  }
264 
265  // Sort jets by pt
266  std::sort(smearedJets->begin(), smearedJets->end(), jetPtComparator);
267 
268  event.put(std::move(smearedJets));
269  }
270 
271  private:
274  bool m_enabled;
278  bool m_debug;
279  std::shared_ptr<pat::GenJetMatcher> m_genJetMatcher;
280 
282  std::unique_ptr<JME::JetResolution> m_resolution_from_file;
283  std::unique_ptr<JME::JetResolutionScaleFactor> m_scale_factor_from_file;
284 
285  std::mt19937 m_random_generator;
286 
288 };
289 #endif
edm::EDGetTokenT< JetCollection > m_jets_token
T getParameter(std::string const &) const
float getResolution(const JetParameters &parameters) const
tuple cfg
Definition: looper.py:293
void getTokens(const edm::Event &event)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
virtual double energy() const final
energy
static const JetResolution get(const edm::EventSetup &, const std::string &)
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)
virtual double phi() const final
momentum azimuthal angle
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
bool isRealData() const
Definition: EventBase.h:63
GreaterByPt< T > jetPtComparator
const reco::GenJet * match(const T &jet, double resolution)
std::unique_ptr< JME::JetResolution > m_resolution_from_file
tuple d
Definition: ztail.py:151
static void fillDescriptions(edm::ParameterSetDescription &desc)
void addDefault(ParameterSetDescription const &psetDescription)
std::vector< T > JetCollection
ConsumesCollector consumesCollector()
Use a ConsumesCollector to gather consumes information from helper functions.
T sqrt(T t)
Definition: SSEVec.h:18
vector< PseudoJet > jets
def move
Definition: eostools.py:510
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)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
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
std::unique_ptr< JME::JetResolutionScaleFactor > m_scale_factor_from_file
tuple cout
Definition: gather_cfg.py:145
edm::EDGetTokenT< reco::GenJetCollection > m_genJetsToken
virtual double eta() const final
momentum pseudorapidity
volatile std::atomic< bool > shutdown_flag false
long double T
static std::string const source
Definition: EdmProvDump.cc:43
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
virtual double pt() const final
transverse momentum