CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
SmearedPFCandidateProducerForPFNoPUMEt.cc
Go to the documentation of this file.
2 
5 
14 
16 
17 
18 const double defJetPtThr = 0.01;
19 const double dR2Match = 0.01*0.01;
20 const double etaMaxBound = 9.9;
21 
22 
23 template <typename T, typename Textractor>
25  : genJetMatcher_(cfg,consumesCollector()),
26  jetResolutionExtractor_(cfg.getParameter<edm::ParameterSet>("jetResolutions")),
27  jetCorrLabel_(""),
28  skipJetSelection_(nullptr)
29 {
30 
31  srcPFCandidates_ = consumes<reco::PFCandidateCollection>(cfg.getParameter<edm::InputTag>("srcPFCandidates") );
32  srcJets_ = consumes<JetCollection>(cfg.getParameter<edm::InputTag>("srcJets"));
33 
35  std::string lutName = cfg.getParameter<std::string>("lutName");
36  if ( inputFileName.location() == edm::FileInPath::Unknown )
37  throw cms::Exception("SmearedPFCandidateProducerForPFNoPUMEt")
38  << " Failed to find File = " << inputFileName << " !!\n";
39 
40  inputFile_ = new TFile(inputFileName.fullPath().data());
41  lut_ = dynamic_cast<TH2*>(inputFile_->Get(lutName.data()));
42  if ( !lut_ )
43  throw cms::Exception("SmearedPFCandidateProducerForPFNoPUMEt")
44  << " Failed to load LUT = " << lutName.data() << " from file = " << inputFileName.fullPath().data() << " !!\n";
45 
46  if ( cfg.exists("jetCorrLabel") ) {
47  jetCorrLabel_ = cfg.getParameter<edm::InputTag>("jetCorrLabel");
48  jetCorrToken_ = consumes<reco::JetCorrector>(jetCorrLabel_);
49  }
50 
51  jetCorrEtaMax_ = ( cfg.exists("jetCorrEtaMax") ) ?
52  cfg.getParameter<double>("jetCorrEtaMax") : etaMaxBound;
53 
54  sigmaMaxGenJetMatch_ = cfg.getParameter<double>("sigmaMaxGenJetMatch");
55 
56  smearBy_ = ( cfg.exists("smearBy") ) ? cfg.getParameter<double>("smearBy") : 1.0;
57  //std::cout << "smearBy = " << smearBy_ << std::endl;
58 
59  shiftBy_ = ( cfg.exists("shiftBy") ) ? cfg.getParameter<double>("shiftBy") : 0.;
60  //std::cout << "shiftBy = " << shiftBy_ << std::endl;
61 
62  skipJetSel_ = cfg.exists("skipJetSelection");
63  if ( skipJetSel_ ) {
64  std::string skipJetSelection_string = cfg.getParameter<std::string>("skipJetSelection");
65  skipJetSelection_ = new StringCutObjectSelector<T>(skipJetSelection_string);
66  }
67 
68 
69  skipRawJetPtThreshold_ = ( cfg.exists("skipRawJetPtThreshold") ) ?
70  cfg.getParameter<double>("skipRawJetPtThreshold") : defJetPtThr;
71  skipCorrJetPtThreshold_ = ( cfg.exists("skipCorrJetPtThreshold") ) ?
72  cfg.getParameter<double>("skipCorrJetPtThreshold") : defJetPtThr;
73 
74  verbosity_ = ( cfg.exists("verbosity") ) ?
75  cfg.getParameter<int>("verbosity") : 0;
76 
77  produces<reco::PFCandidateCollection>();
78 }
79 
80 template <typename T, typename Textractor>
82 {
83  delete inputFile_;
84  if ( skipJetSel_ ) {
85  delete skipJetSelection_;
86  }
87 }
88 
89 template <typename T, typename Textractor>
91 {
92  edm::Handle<reco::PFCandidateCollection> originalPFCandidates;
93  evt.getByToken(srcPFCandidates_, originalPFCandidates);
94 
96  evt.getByToken(srcJets_, jets);
97 
98  std::auto_ptr<reco::PFCandidateCollection> smearedPFCandidates(new reco::PFCandidateCollection);
99 
100  for ( reco::PFCandidateCollection::const_iterator originalPFCandidate = originalPFCandidates->begin();
101  originalPFCandidate != originalPFCandidates->end(); ++originalPFCandidate ) {
102 
103  const T* jet_matched = nullptr;
104  for ( typename JetCollection::const_iterator jet = jets->begin();
105  jet != jets->end(); ++jet ) {
106  std::vector<reco::PFCandidatePtr> jetConstituents = jet->getPFConstituents();
107  for ( std::vector<reco::PFCandidatePtr>::const_iterator jetConstituent = jet->getPFConstituents().begin();
108  jetConstituent != jet->getPFConstituents().end() && jet_matched==nullptr; ++jetConstituent ) {
109  if ( deltaR2(originalPFCandidate->p4(), (*jetConstituent)->p4()) < dR2Match ) jet_matched = &(*jet);
110  }
111  }
112 
113  if ( jet_matched==nullptr ) continue;
114 
115  const static SmearedJetProducer_namespace::RawJetExtractorT<T> rawJetExtractor;
116  reco::Candidate::LorentzVector rawJetP4 = rawJetExtractor(*jet_matched);
117  // if ( verbosity_ ) {
118  // std::cout << "rawJet: Pt = " << rawJetP4.pt() << ", eta = " << rawJetP4.eta() << ", phi = " << rawJetP4.phi() << std::endl;
119  // }
120 
121  reco::Candidate::LorentzVector corrJetP4 = jet_matched->p4();
122  if ( !jetCorrLabel_.label().empty() ) {
124  evt.getByToken(jetCorrToken_, jetCorr);
125  corrJetP4 = jetCorrExtractor_(*jet_matched, jetCorr.product(), jetCorrEtaMax_, &rawJetP4);
126  }
127  // if ( verbosity_ ) {
128  // std::cout << "corrJet: Pt = " << corrJetP4.pt() << ", eta = " << corrJetP4.eta() << ", phi = " << corrJetP4.phi() << std::endl;
129  // }
130 
131  double smearFactor = 1.;
132  double x = std::abs(corrJetP4.eta());
133  double y = corrJetP4.pt();
134  if ( x > lut_->GetXaxis()->GetXmin() && x < lut_->GetXaxis()->GetXmax() &&
135  y > lut_->GetYaxis()->GetXmin() && y < lut_->GetYaxis()->GetXmax() ) {
136  int binIndex = lut_->FindBin(x, y);
137 
138  if ( smearBy_ > 0. ) smearFactor += smearBy_*(lut_->GetBinContent(binIndex) - 1.);
139  double smearFactorErr = lut_->GetBinError(binIndex);
140  //if ( verbosity_ ) std::cout << "smearFactor = " << smearFactor << " +/- " << smearFactorErr << std::endl;
141 
142  if ( shiftBy_ != 0. ) {
143  smearFactor += (shiftBy_*smearFactorErr);
144  //if ( verbosity_ ) std::cout << "smearFactor(shifted) = " << smearFactor << std::endl;
145  }
146  }
147 
148  double smearedJetEn = jet_matched->energy();
149 
150  T rawJet(*jet_matched);
151  rawJet.setP4(rawJetP4);
152  double jetResolution = jetResolutionExtractor_(rawJet);
153  double sigmaEn = jetResolution;
154 
155  const reco::GenJet* genJet = genJetMatcher_(*jet_matched, &evt);
156  bool isGenMatched = false;
157  if ( genJet!=nullptr ) {
158  // if ( verbosity_ ) {
159  // std::cout << "genJet: Pt = " << genJet->pt() << ", eta = " << genJet->eta() << ", phi = " << genJet->phi() << std::endl;
160  // }
161  double dEn = corrJetP4.E() - genJet->energy();
162  if ( std::abs(dEn) < (sigmaMaxGenJetMatch_*sigmaEn) ) {
163 //--- case 1: reconstructed jet matched to generator level jet,
164 // smear difference between reconstructed and "true" jet energy
165 
166  // if ( verbosity_ ) {
167  // std::cout << " successfully matched to genJet" << std::endl;
168  // std::cout << "corrJetEn = " << corrJetP4.E() << ", genJetEn = " << genJet->energy() << " --> dEn = " << dEn << std::endl;
169  // }
170 
171  //smearedJetEn = jet_matched->energy()*(1. + (smearFactor - 1.)*dEn/std::max(rawJetP4.E(), corrJetP4.E()));
172  smearedJetEn = jet_matched->energy() + (smearFactor - 1.)*dEn;
173  isGenMatched = true;
174  }
175  }
176  if ( !isGenMatched ) {
177 //--- case 2: reconstructed jet **not** matched to generator level jet,
178 // smear jet energy using MC resolution functions implemented in PFMEt significance algorithm (CMS AN-10/400)
179 
180  // if ( verbosity_ ) {
181  // std::cout << " not matched to genJet" << std::endl;
182  // std::cout << "corrJetEn = " << corrJetP4.E() << ", sigmaEn = " << sigmaEn << std::endl;
183  // }
184 
185  if ( smearFactor > 1. ) {
186  // CV: MC resolution already accounted for in reconstructed jet,
187  // add additional Gaussian smearing of width = sqrt(smearFactor^2 - 1)
188  // to account for Data/MC **difference** in jet resolutions.
189  // Take maximum(rawJetEn, corrJetEn) to avoid pathological cases
190  // (e.g. corrJetEn << rawJetEn, due to L1Fastjet corrections)
191 
192  double addSigmaEn = jetResolution*sqrt(smearFactor*smearFactor - 1.);
193  //smearedJetEn = jet_matched->energy()*(1. + rnd_.Gaus(0., addSigmaEn)/std::max(rawJetP4.E(), corrJetP4.E()));
194  smearedJetEn = jet_matched->energy() + rnd_.Gaus(0., addSigmaEn);
195  }
196  }
197 
198  // CV: keep minimum jet energy, in order not to loose direction information
199  const double minJetEn = 1.e-2;
200  if ( smearedJetEn < minJetEn ) smearedJetEn = minJetEn;
201 
202  // CV: skip smearing in case either "raw" or "corrected" jet energy is very low
203  // or jet passes selection configurable via python
204  // (allows for protection against "pathological cases",
205  // cf. PhysicsTools/PatUtils/python/tools/metUncertaintyTools.py)
206  reco::Candidate::LorentzVector smearedJetP4 = jet_matched->p4();
207  if ( !((skipJetSelection_ && (*skipJetSelection_)(*jet_matched)) ||
208  rawJetP4.pt() < skipRawJetPtThreshold_ ||
209  corrJetP4.pt() < skipCorrJetPtThreshold_ ) ) {
210  // if ( verbosity_ ) {
211  // std::cout << " multiplying jetP4 by factor = " << (smearedJetEn/jet_matched->energy()) << " --> smearedJetEn = " << smearedJetEn << std::endl;
212  // }
213  smearedJetP4 *= (smearedJetEn/jet_matched->energy());
214  }
215 
216  // if ( verbosity_ ) {
217  // std::cout << "smearedJet: Pt = " << smearedJetP4.pt() << ", eta = " << smearedJetP4.eta() << ", phi = " << smearedJetP4.phi() << std::endl;
218  // std::cout << " dPt = " << (smearedJetP4.pt() - jet_matched->pt())
219  // << " (dPx = " << (smearedJetP4.px() - jet_matched->px()) << ", dPy = " << (smearedJetP4.py() - jet_matched->py()) << ")" << std::endl;
220  // }
221 
222  double scaleFactor = ( jet_matched->p4().energy() > 0. ) ?
223  (smearedJetP4.energy()/jet_matched->p4().energy()) : 1.0;
224 
225  double smearedPx = scaleFactor*originalPFCandidate->px();
226  double smearedPy = scaleFactor*originalPFCandidate->py();
227  double smearedPz = scaleFactor*originalPFCandidate->pz();
228  double mass = originalPFCandidate->mass();
229  double smearedEn = sqrt(smearedPx*smearedPx + smearedPy*smearedPy + smearedPz*smearedPz + mass*mass);
230  reco::Candidate::LorentzVector smearedPFCandidateP4(smearedPx, smearedPy, smearedPz, smearedEn);
231 
232  reco::PFCandidate smearedPFCandidate(*originalPFCandidate);
233  smearedPFCandidate.setP4(smearedPFCandidateP4);
234 
235  smearedPFCandidates->push_back(smearedPFCandidate);
236  }
237 
238  evt.put(smearedPFCandidates);
239 }
240 
244 
245 namespace SmearedJetProducer_namespace
246 {
247  template <>
248  class JetResolutionExtractorT<reco::PFJet>
249  {
250  public:
251 
253  : jetResolutions_(cfg)
254  {}
256 
257  double operator()(const reco::PFJet& jet) const
258  {
259  metsig::SigInputObj pfJetResolution = jetResolutions_.evalPFJet(&jet);
260  if ( pfJetResolution.get_energy() > 0. ) {
261  return jet.energy()*(pfJetResolution.get_sigma_e()/pfJetResolution.get_energy());
262  } else {
263  return 0.;
264  }
265  }
266 
267  metsig::SignAlgoResolutions jetResolutions_;
268  };
269 }
270 
272 
274 
276 
T getParameter(std::string const &) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:446
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
SmearedPFCandidateProducerForPFNoPUMEtT< reco::PFJet, JetCorrExtractorT< reco::PFJet > > SmearedPFCandidateProducerForPFNoPUMEt
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual void setP4(const LorentzVector &p4)
set 4-momentum
#define nullptr
edm::EDGetTokenT< reco::PFCandidateCollection > srcPFCandidates_
Jets made from PFObjects.
Definition: PFJet.h:21
virtual double energy() const
energy
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:113
T sqrt(T t)
Definition: SSEVec.h:48
vector< PseudoJet > jets
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Jets made from MC generator particles.
Definition: GenJet.h:24
double deltaR2(const T1 &t1, const T2 &t2)
Definition: deltaR.h:36
void produce(edm::Event &, const edm::EventSetup &)
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
T const * product() const
Definition: Handle.h:81
LocationCode location() const
Where was the file found?
Definition: FileInPath.cc:159
double get_energy() const
Definition: SigInputObj.h:43
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:41
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
std::string fullPath() const
Definition: FileInPath.cc:165
Definition: DDAxes.h:10
long double T
double get_sigma_e() const
Definition: SigInputObj.h:45