CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TtSemiLepHitFitProducer.h
Go to the documentation of this file.
1 #ifndef TtSemiLepHitFitProducer_h
2 #define TtSemiLepHitFitProducer_h
3 
7 
12 
18 
19 template <typename LeptonCollection>
21 public:
23  ~TtSemiLepHitFitProducer() override;
24 
25 private:
26  // produce
27  void produce(edm::Event&, const edm::EventSetup&) override;
28 
32 
34  int maxNJets_;
36  int maxNComb_;
37 
39  double maxEtaMu_;
41  double maxEtaEle_;
43  double maxEtaJet_;
44 
52  bool useBTag_;
53 
55  double mW_;
56  double mTop_;
57 
60 
62  double jes_;
63  double jesB_;
64 
65  struct FitResult {
66  int Status;
67  double Chi2;
68  double Prob;
69  double MT;
70  double SigMT;
77  std::vector<int> JetCombi;
78  bool operator<(const FitResult& rhs) { return Chi2 < rhs.Chi2; };
79  };
80 
82 
89 
94 
96 };
97 
98 template <typename LeptonCollection>
100  : jetsToken_(consumes<std::vector<pat::Jet> >(cfg.getParameter<edm::InputTag>("jets"))),
101  lepsToken_(consumes<LeptonCollection>(cfg.getParameter<edm::InputTag>("leps"))),
102  metsToken_(consumes<std::vector<pat::MET> >(cfg.getParameter<edm::InputTag>("mets"))),
103  maxNJets_(cfg.getParameter<int>("maxNJets")),
104  maxNComb_(cfg.getParameter<int>("maxNComb")),
105  bTagAlgo_(cfg.getParameter<std::string>("bTagAlgo")),
106  minBTagValueBJet_(cfg.getParameter<double>("minBDiscBJets")),
107  maxBTagValueNonBJet_(cfg.getParameter<double>("maxBDiscLightJets")),
108  useBTag_(cfg.getParameter<bool>("useBTagging")),
109  mW_(cfg.getParameter<double>("mW")),
110  mTop_(cfg.getParameter<double>("mTop")),
111  jetCorrectionLevel_(cfg.getParameter<std::string>("jetCorrectionLevel")),
112  jes_(cfg.getParameter<double>("jes")),
113  jesB_(cfg.getParameter<double>("jesB")),
114 
115  // The following five initializers read the config parameters for the
116  // ASCII text files which contains the physics object resolutions.
117  hitfitDefault_(cfg.getUntrackedParameter<edm::FileInPath>(
118  std::string("hitfitDefault"),
119  edm::FileInPath(std::string("TopQuarkAnalysis/TopHitFit/data/setting/RunHitFitConfiguration.txt")))),
120  hitfitElectronResolution_(cfg.getUntrackedParameter<edm::FileInPath>(
121  std::string("hitfitElectronResolution"),
122  edm::FileInPath(std::string("TopQuarkAnalysis/TopHitFit/data/resolution/tqafElectronResolution.txt")))),
123  hitfitMuonResolution_(cfg.getUntrackedParameter<edm::FileInPath>(
124  std::string("hitfitMuonResolution"),
125  edm::FileInPath(std::string("TopQuarkAnalysis/TopHitFit/data/resolution/tqafMuonResolution.txt")))),
126  hitfitUdscJetResolution_(cfg.getUntrackedParameter<edm::FileInPath>(
127  std::string("hitfitUdscJetResolution"),
128  edm::FileInPath(std::string("TopQuarkAnalysis/TopHitFit/data/resolution/tqafUdscJetResolution.txt")))),
129  hitfitBJetResolution_(cfg.getUntrackedParameter<edm::FileInPath>(
130  std::string("hitfitBJetResolution"),
131  edm::FileInPath(std::string("TopQuarkAnalysis/TopHitFit/data/resolution/tqafBJetResolution.txt")))),
132  hitfitMETResolution_(cfg.getUntrackedParameter<edm::FileInPath>(
133  std::string("hitfitMETResolution"),
134  edm::FileInPath(std::string("TopQuarkAnalysis/TopHitFit/data/resolution/tqafKtResolution.txt")))),
135 
136  // The following four initializers instantiate the translator between PAT objects
137  // and HitFit objects using the ASCII text files which contains the resolutions.
138  electronTranslator_(hitfitElectronResolution_.fullPath()),
139  muonTranslator_(hitfitMuonResolution_.fullPath()),
140  jetTranslator_(
141  hitfitUdscJetResolution_.fullPath(), hitfitBJetResolution_.fullPath(), jetCorrectionLevel_, jes_, jesB_),
142  metTranslator_(hitfitMETResolution_.fullPath())
143 
144 {
145  // Create an instance of RunHitFit and initialize it.
146  HitFit = new PatHitFit(
148 
149  maxEtaMu_ = 2.4;
150  maxEtaEle_ = 2.5;
151  maxEtaJet_ = 2.5;
152 
153  edm::LogVerbatim("TopHitFit") << "\n"
154  << "+++++++++++ TtSemiLepHitFitProducer ++++++++++++ \n"
155  << " Due to the eta ranges for which resolutions \n"
156  << " are provided in \n"
157  << " TopQuarkAnalysis/TopHitFit/data/resolution/ \n"
158  << " so far, the following cuts are currently \n"
159  << " implemented in the TtSemiLepHitFitProducer: \n"
160  << " |eta(muons )| <= " << maxEtaMu_ << " \n"
161  << " |eta(electrons)| <= " << maxEtaEle_ << " \n"
162  << " |eta(jets )| <= " << maxEtaJet_ << " \n"
163  << "++++++++++++++++++++++++++++++++++++++++++++++++ \n";
164 
165  produces<std::vector<pat::Particle> >("PartonsHadP");
166  produces<std::vector<pat::Particle> >("PartonsHadQ");
167  produces<std::vector<pat::Particle> >("PartonsHadB");
168  produces<std::vector<pat::Particle> >("PartonsLepB");
169  produces<std::vector<pat::Particle> >("Leptons");
170  produces<std::vector<pat::Particle> >("Neutrinos");
171 
172  produces<std::vector<std::vector<int> > >();
173  produces<std::vector<double> >("Chi2");
174  produces<std::vector<double> >("Prob");
175  produces<std::vector<double> >("MT");
176  produces<std::vector<double> >("SigMT");
177  produces<std::vector<int> >("Status");
178  produces<int>("NumberOfConsideredJets");
179 }
180 
181 template <typename LeptonCollection>
183  delete HitFit;
184 }
185 
186 template <typename LeptonCollection>
188  std::unique_ptr<std::vector<pat::Particle> > pPartonsHadP(new std::vector<pat::Particle>);
189  std::unique_ptr<std::vector<pat::Particle> > pPartonsHadQ(new std::vector<pat::Particle>);
190  std::unique_ptr<std::vector<pat::Particle> > pPartonsHadB(new std::vector<pat::Particle>);
191  std::unique_ptr<std::vector<pat::Particle> > pPartonsLepB(new std::vector<pat::Particle>);
192  std::unique_ptr<std::vector<pat::Particle> > pLeptons(new std::vector<pat::Particle>);
193  std::unique_ptr<std::vector<pat::Particle> > pNeutrinos(new std::vector<pat::Particle>);
194 
195  std::unique_ptr<std::vector<std::vector<int> > > pCombi(new std::vector<std::vector<int> >);
196  std::unique_ptr<std::vector<double> > pChi2(new std::vector<double>);
197  std::unique_ptr<std::vector<double> > pProb(new std::vector<double>);
198  std::unique_ptr<std::vector<double> > pMT(new std::vector<double>);
199  std::unique_ptr<std::vector<double> > pSigMT(new std::vector<double>);
200  std::unique_ptr<std::vector<int> > pStatus(new std::vector<int>);
201  std::unique_ptr<int> pJetsConsidered(new int);
202 
204  evt.getByToken(jetsToken_, jets);
205 
207  evt.getByToken(metsToken_, mets);
208 
210  evt.getByToken(lepsToken_, leps);
211 
212  // -----------------------------------------------------
213  // skip events with no appropriate lepton candidate in
214  // or empty MET or less jets than partons
215  // -----------------------------------------------------
216 
217  const unsigned int nPartons = 4;
218 
219  // Clear the internal state
220  HitFit->clear();
221 
222  // Add lepton into HitFit
223  bool foundLepton = false;
224  if (!leps->empty()) {
225  double maxEtaLep = maxEtaMu_;
226  if (!dynamic_cast<const reco::Muon*>(&((*leps)[0]))) // assume electron if it is not a muon
227  maxEtaLep = maxEtaEle_;
228  for (unsigned iLep = 0; iLep < (*leps).size() && !foundLepton; ++iLep) {
229  if (std::abs((*leps)[iLep].eta()) <= maxEtaLep) {
230  HitFit->AddLepton((*leps)[iLep]);
231  foundLepton = true;
232  }
233  }
234  }
235 
236  // Add jets into HitFit
237  unsigned int nJetsFound = 0;
238  for (unsigned iJet = 0; iJet < (*jets).size() && (int)nJetsFound != maxNJets_; ++iJet) {
239  double jet_eta = (*jets)[iJet].eta();
240  if ((*jets)[iJet].isCaloJet()) {
241  jet_eta = ((reco::CaloJet*)((*jets)[iJet]).originalObject())->detectorP4().eta();
242  }
243  if (std::abs(jet_eta) <= maxEtaJet_) {
244  HitFit->AddJet((*jets)[iJet]);
245  nJetsFound++;
246  }
247  }
248  *pJetsConsidered = nJetsFound;
249 
250  // Add missing transverse energy into HitFit
251  if (!mets->empty())
252  HitFit->SetMet((*mets)[0]);
253 
254  if (!foundLepton || mets->empty() || nJetsFound < nPartons) {
255  // the kinFit getters return empty objects here
256  pPartonsHadP->push_back(pat::Particle());
257  pPartonsHadQ->push_back(pat::Particle());
258  pPartonsHadB->push_back(pat::Particle());
259  pPartonsLepB->push_back(pat::Particle());
260  pLeptons->push_back(pat::Particle());
261  pNeutrinos->push_back(pat::Particle());
262  // indices referring to the jet combination
263  std::vector<int> invalidCombi;
264  for (unsigned int i = 0; i < nPartons; ++i)
265  invalidCombi.push_back(-1);
266  pCombi->push_back(invalidCombi);
267  // chi2
268  pChi2->push_back(-1.);
269  // chi2 probability
270  pProb->push_back(-1.);
271  // fitted top mass
272  pMT->push_back(-1.);
273  pSigMT->push_back(-1.);
274  // status of the fitter
275  pStatus->push_back(-1);
276  // feed out all products
277  evt.put(std::move(pCombi));
278  evt.put(std::move(pPartonsHadP), "PartonsHadP");
279  evt.put(std::move(pPartonsHadQ), "PartonsHadQ");
280  evt.put(std::move(pPartonsHadB), "PartonsHadB");
281  evt.put(std::move(pPartonsLepB), "PartonsLepB");
282  evt.put(std::move(pLeptons), "Leptons");
283  evt.put(std::move(pNeutrinos), "Neutrinos");
284  evt.put(std::move(pChi2), "Chi2");
285  evt.put(std::move(pProb), "Prob");
286  evt.put(std::move(pMT), "MT");
287  evt.put(std::move(pSigMT), "SigMT");
288  evt.put(std::move(pStatus), "Status");
289  evt.put(std::move(pJetsConsidered), "NumberOfConsideredJets");
290  return;
291  }
292 
293  std::list<FitResult> FitResultList;
294 
295  //
296  // BEGIN DECLARATION OF VARIABLES FROM KINEMATIC FIT
297  //
298 
299  // In this part are variables from the
300  // kinematic fit procedure
301 
302  // Number of all permutations of the event
303  size_t nHitFit = 0;
304 
305  // Number of jets in the event
306  size_t nHitFitJet = 0;
307 
308  // Results of the fit for all jet permutations of the event
309  std::vector<hitfit::Fit_Result> hitFitResult;
310 
311  //
312  // R U N H I T F I T
313  //
314  // Run the kinematic fit and get how many permutations are possible
315  // in the fit
316 
317  nHitFit = HitFit->FitAllPermutation();
318 
319  //
320  // BEGIN PART WHICH EXTRACTS INFORMATION FROM HITFIT
321  //
322 
323  // Get the number of jets
324  nHitFitJet = HitFit->GetUnfittedEvent()[0].njets();
325 
326  // Get the fit results for all permutations
327  hitFitResult = HitFit->GetFitAllPermutation();
328 
329  // Loop over all permutations and extract the information
330  for (size_t fit = 0; fit != nHitFit; ++fit) {
331  // Get the event after the fit
332  hitfit::Lepjets_Event fittedEvent = hitFitResult[fit].ev();
333 
334  /*
335  Get jet permutation according to TQAF convention
336  11 : leptonic b
337  12 : hadronic b
338  13 : hadronic W
339  14 : hadronic W
340  */
341  std::vector<int> hitCombi(4);
342  for (size_t jet = 0; jet != nHitFitJet; ++jet) {
343  int jet_type = fittedEvent.jet(jet).type();
344 
345  switch (jet_type) {
346  case 11:
347  hitCombi[TtSemiLepEvtPartons::LepB] = jet;
348  break;
349  case 12:
350  hitCombi[TtSemiLepEvtPartons::HadB] = jet;
351  break;
352  case 13:
353  hitCombi[TtSemiLepEvtPartons::LightQ] = jet;
354  break;
355  case 14:
357  break;
358  }
359  }
360 
361  // Store the kinematic quantities in the corresponding containers.
362 
363  hitfit::Lepjets_Event_Jet hadP_ = fittedEvent.jet(hitCombi[TtSemiLepEvtPartons::LightQ]);
364  hitfit::Lepjets_Event_Jet hadQ_ = fittedEvent.jet(hitCombi[TtSemiLepEvtPartons::LightQBar]);
365  hitfit::Lepjets_Event_Jet hadB_ = fittedEvent.jet(hitCombi[TtSemiLepEvtPartons::HadB]);
366  hitfit::Lepjets_Event_Jet lepB_ = fittedEvent.jet(hitCombi[TtSemiLepEvtPartons::LepB]);
367  hitfit::Lepjets_Event_Lep lepL_ = fittedEvent.lep(0);
368 
369  /*
371  std::string bTagAlgo_;
373  double minBTagValueBJet_;
375  double maxBTagValueNonBJet_;
377  bool useBTag_;
378  */
379 
380  if (hitFitResult[fit].chisq() > 0 // only take into account converged fits
381  && (!useBTag_ ||
382  (useBTag_ // use btag information if chosen
383  && jets->at(hitCombi[TtSemiLepEvtPartons::LightQ]).bDiscriminator(bTagAlgo_) < maxBTagValueNonBJet_ &&
384  jets->at(hitCombi[TtSemiLepEvtPartons::LightQBar]).bDiscriminator(bTagAlgo_) < maxBTagValueNonBJet_ &&
385  jets->at(hitCombi[TtSemiLepEvtPartons::HadB]).bDiscriminator(bTagAlgo_) > minBTagValueBJet_ &&
386  jets->at(hitCombi[TtSemiLepEvtPartons::LepB]).bDiscriminator(bTagAlgo_) > minBTagValueBJet_))) {
388  result.Status = 0;
389  result.Chi2 = hitFitResult[fit].chisq();
390  result.Prob = exp(-1.0 * (hitFitResult[fit].chisq()) / 2.0);
391  result.MT = hitFitResult[fit].mt();
392  result.SigMT = hitFitResult[fit].sigmt();
394  0, math::XYZTLorentzVector(hadB_.p().x(), hadB_.p().y(), hadB_.p().z(), hadB_.p().t()), math::XYZPoint()));
396  0, math::XYZTLorentzVector(hadP_.p().x(), hadP_.p().y(), hadP_.p().z(), hadP_.p().t()), math::XYZPoint()));
398  0, math::XYZTLorentzVector(hadQ_.p().x(), hadQ_.p().y(), hadQ_.p().z(), hadQ_.p().t()), math::XYZPoint()));
400  0, math::XYZTLorentzVector(lepB_.p().x(), lepB_.p().y(), lepB_.p().z(), lepB_.p().t()), math::XYZPoint()));
402  0, math::XYZTLorentzVector(lepL_.p().x(), lepL_.p().y(), lepL_.p().z(), lepL_.p().t()), math::XYZPoint()));
404  0,
406  fittedEvent.met().x(), fittedEvent.met().y(), fittedEvent.met().z(), fittedEvent.met().t()),
407  math::XYZPoint()));
408  result.JetCombi = hitCombi;
409 
410  FitResultList.push_back(result);
411  }
412  }
413 
414  // sort results w.r.t. chi2 values
415  FitResultList.sort();
416 
417  // -----------------------------------------------------
418  // feed out result
419  // starting with the JetComb having the smallest chi2
420  // -----------------------------------------------------
421 
422  if (((unsigned)FitResultList.size()) < 1) { // in case no fit results were stored in the list (all fits aborted)
423  pPartonsHadP->push_back(pat::Particle());
424  pPartonsHadQ->push_back(pat::Particle());
425  pPartonsHadB->push_back(pat::Particle());
426  pPartonsLepB->push_back(pat::Particle());
427  pLeptons->push_back(pat::Particle());
428  pNeutrinos->push_back(pat::Particle());
429  // indices referring to the jet combination
430  std::vector<int> invalidCombi;
431  for (unsigned int i = 0; i < nPartons; ++i)
432  invalidCombi.push_back(-1);
433  pCombi->push_back(invalidCombi);
434  // chi2
435  pChi2->push_back(-1.);
436  // chi2 probability
437  pProb->push_back(-1.);
438  // fitted top mass
439  pMT->push_back(-1.);
440  pSigMT->push_back(-1.);
441  // status of the fitter
442  pStatus->push_back(-1);
443  } else {
444  unsigned int iComb = 0;
445  for (typename std::list<FitResult>::const_iterator result = FitResultList.begin(); result != FitResultList.end();
446  ++result) {
447  if (maxNComb_ >= 1 && iComb == (unsigned int)maxNComb_)
448  break;
449  iComb++;
450  // partons
451  pPartonsHadP->push_back(result->HadP);
452  pPartonsHadQ->push_back(result->HadQ);
453  pPartonsHadB->push_back(result->HadB);
454  pPartonsLepB->push_back(result->LepB);
455  // lepton
456  pLeptons->push_back(result->LepL);
457  // neutrino
458  pNeutrinos->push_back(result->LepN);
459  // indices referring to the jet combination
460  pCombi->push_back(result->JetCombi);
461  // chi2
462  pChi2->push_back(result->Chi2);
463  // chi2 probability
464  pProb->push_back(result->Prob);
465  // fitted top mass
466  pMT->push_back(result->MT);
467  pSigMT->push_back(result->SigMT);
468  // status of the fitter
469  pStatus->push_back(result->Status);
470  }
471  }
472  evt.put(std::move(pCombi));
473  evt.put(std::move(pPartonsHadP), "PartonsHadP");
474  evt.put(std::move(pPartonsHadQ), "PartonsHadQ");
475  evt.put(std::move(pPartonsHadB), "PartonsHadB");
476  evt.put(std::move(pPartonsLepB), "PartonsLepB");
477  evt.put(std::move(pLeptons), "Leptons");
478  evt.put(std::move(pNeutrinos), "Neutrinos");
479  evt.put(std::move(pChi2), "Chi2");
480  evt.put(std::move(pProb), "Prob");
481  evt.put(std::move(pMT), "MT");
482  evt.put(std::move(pSigMT), "SigMT");
483  evt.put(std::move(pStatus), "Status");
484  evt.put(std::move(pJetsConsidered), "NumberOfConsideredJets");
485 }
486 
487 #endif
Log< level::Info, true > LogVerbatim
int maxNComb_
maximal number of combinations to be written to the event
double maxEtaEle_
maximum eta value for electrons, needed to limited range in which resolutions are provided ...
double maxBTagValueNonBJet_
max value of bTag for a non-b-jet
static const unsigned int nPartons
hitfit::JetTranslatorBase< pat::Jet > jetTranslator_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
tuple cfg
Definition: looper.py:296
Jets made from CaloTowers.
Definition: CaloJet.h:27
Represent a lepton in an instance of Lepjets_Event class. This class hold the following information: ...
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
hitfit::LeptonTranslatorBase< pat::Electron > electronTranslator_
TtSemiLepHitFitProducer(const edm::ParameterSet &)
edm::EDGetTokenT< std::vector< pat::MET > > metsToken_
Exp< T >::type exp(const T &t)
Definition: Exp.h:22
hitfit::LeptonTranslatorBase< pat::Muon > muonTranslator_
Lepjets_Event_Jet & jet(std::vector< Lepjets_Event_Jet >::size_type i)
Return a reference to jet at index position i.
double maxEtaJet_
maximum eta value for jets, needed to limited range in which resolutions are provided ...
tuple result
Definition: mps_fire.py:311
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
int & type()
Return a reference to the type code.
edm::FileInPath hitfitUdscJetResolution_
void produce(edm::Event &, const edm::EventSetup &) override
auto const & fit
A class to hold functions to calculate kinematic quantities of interest in events.
bool useBTag_
switch to tell whether to use b-tagging or not
vector< PseudoJet > jets
Represent a simple event consisting of lepton(s) and jet(s). An instance of this class holds a list o...
Definition: Lepjets_Event.h:62
def move
Definition: eostools.py:511
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Template class of function object to translate missing transverse energy object to HitFit&#39;s Fourvec o...
A class to represent a jet in an instance of Lepjets_Event class. The class is derived from the Lepje...
int maxNJets_
maximal number of jets (-1 possible to indicate &#39;all&#39;)
Template class of experiment-independent interface to HitFit.
edm::EDGetTokenT< std::vector< pat::Jet > > jetsToken_
Template class of experiment-independent interface to HitFit. This class is intended to be used insid...
Definition: RunHitFit.h:153
hitfit::METTranslatorBase< pat::MET > metTranslator_
Template class of function object to translate jet physics object to HitFit&#39;s Lepjets_Event_Jet objec...
Fourvec & met()
Return a reference to the missing transverse energy.
Lepjets_Event_Lep & lep(std::vector< Lepjets_Event_Lep >::size_type i)
Return a reference to lepton at index position i.
edm::EDGetTokenT< LeptonCollection > lepsToken_
Template class of function object to translate lepton physics object to HitFit&#39;s Lepjets_Event_Lep ob...
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
edm::FileInPath hitfitElectronResolution_
Analysis-level particle class.
Definition: Particle.h:30
std::string jetCorrectionLevel_
jet correction level
Fourvec & p()
Return a reference to the four-momentum.
constexpr char Jet[]
Definition: modules.cc:9
hitfit::RunHitFit< pat::Electron, pat::Muon, pat::Jet, pat::MET > PatHitFit
std::string fullPath() const
Definition: FileInPath.cc:161
double maxEtaMu_
maximum eta value for muons, needed to limited range in which resolutions are provided ...
Definition: Chi2.h:15
double minBTagValueBJet_
min value of bTag for a b-jet
std::string bTagAlgo_
input tag for b-tagging algorithm
double jes_
jet energy scale