ATLAS Offline Software
KLFitterTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 // Local include(s):
9 #include "TopEvent/Event.h"
10 #include "TopEvent/EventTools.h"
13 
14 #include <algorithm>
15 
16 namespace top {
17  KLFitterTool::KLFitterTool(const std::string& name) :
18  asg::AsgTool(name),
19  m_config(nullptr),
20  m_massTop(172.5), // This is the MC top mass in GeV - only change if you change the MC mass
21  // commented out variables are unused. experts please check and remove
22  // m_bTagCutValue(9999.9),
23  m_isWorkingPoint(false),
24  m_transferFunctionsPathPrefix("SetMe"),
25  m_transferFunctionsPath("SetMe"),
26  m_selectionName("SetMe"),
27  m_leptonType("SetMe"),
28  m_customParameters("SetMe"),
29  m_LHType("SetMe"),
30  m_myFitter(nullptr) {
31  declareProperty("config", m_config, "Set the configuration");
32  declareProperty("LeptonType", m_leptonType = "kUndefined", "Define the lepton type");
33  declareProperty("CustomParameters", m_customParameters = "", "Define the custom parameters");
34  declareProperty("SelectionName", m_selectionName = "kUndefined", "Define the name of the selection");
35  declareProperty("LHType", m_LHType = "kUndefined", "Define the Likelihood type");
36  }
37 
40  // Have you set the config??
41  if (m_config == nullptr) {
42  ATH_MSG_ERROR("Please set the top::TopConfig");
43  return StatusCode::FAILURE;
44  }
45  //Retrieving configuration from TopConfig
46  m_config->setKLFitter();
47  //Setting configuration, giving priority to the ones passed inside the selection
48  std::vector<std::string> custom_tokens;
49  tokenize(m_customParameters, custom_tokens, " ");
50  std::string temp_option = "";
51  // Setting event topology
52  if (findOption(custom_tokens, "KLFitterLH", temp_option)) m_LHType = temp_option;
53  else m_LHType = m_config->KLFitterLH();
54  // Find KLFitter ATLAS transfer functions. As of May '18, stored in
55  // AnalysisTop group data area on cvmfs.
56  m_transferFunctionsPathPrefix = PathResolverFindCalibDirectory("dev/AnalysisTop/KLFitterTFs/");
57  if (findOption(custom_tokens, "KLFitterTransferFunctionsPath", temp_option)) m_transferFunctionsPath = temp_option;
58  else m_transferFunctionsPath = m_config->KLFitterTransferFunctionsPath();
59  std::string transferFunctionAbsPath = m_transferFunctionsPathPrefix + m_transferFunctionsPath + "/";
60 
61  // 1) create an instance of the fitter
62  m_myFitter = std::unique_ptr<KLFitter::Fitter>(new KLFitter::Fitter {});
63 
64  // 2) create an instance of the detector, which holds the information on the resolutions (transfer functions);
65  // it takes as an argument the folder which contains the parameter files for the transfer functions
66  m_myDetector = std::make_unique<KLFitter::DetectorAtlas_8TeV>(transferFunctionAbsPath);
67 
68  // 3) tell the fitter which detector to use
69  top::check(m_myFitter->SetDetector(
70  m_myDetector.get()), "KLFitterTool::initialize() ERROR setting detector to fitter");
71 
72  // 4) create an instance of the likelihood for ttbar->l+jets channel and customize it according to your needs
73  m_myLikelihood = std::make_unique<KLFitter::LikelihoodTopLeptonJets>();
74 
75  // 4) create an instance of the likelihood for ttH -> l+jets channel and customize it according to your needs
76  m_myLikelihood_TTH = std::make_unique<KLFitter::LikelihoodTTHLeptonJets>();
77 
78  // 4) create an instance of the likelihood for ttbar->l+jets channel using jet angles channel and customize it
79  // according to your needs
80  m_myLikelihood_JetAngles = std::make_unique<KLFitter::LikelihoodTopLeptonJets_JetAngles>();
81 
82  // 4) create an instance of the likelihood for ttbar->l+jets channel using angular W-helicity info and
83  // customize it according to your needs
84  m_myLikelihood_Angular = std::make_unique<KLFitter::LikelihoodTopLeptonJets_Angular>();
85 
86  // 4) create an instance of the likelihood for ttZ -> trilepton channel and customize it according to your needs
87  m_myLikelihood_TTZ = std::make_unique<KLFitter::LikelihoodTTZTrilepton>();
88 
89  // 4) create an instance of the likelihood for ttbar -> allhadronic channel and customize it according to your needs
90  m_myLikelihood_AllHadronic = std::make_unique<KLFitter::LikelihoodTopAllHadronic>();
91 
92  // 4) create an instance of the likelihood for ttbar -> boosted ljets and customize it according to your needs
93  m_myLikelihood_BoostedLJets = std::make_unique<KLFitter::BoostedLikelihoodTopLeptonJets>();
94 
95  // 4.a) SetleptonType
96  if (m_LHType != "ttbar_AllHadronic") { // no lepton type for all hadronic
97  if (m_leptonType == "kElectron") {
104  } else if (m_leptonType == "kMuon") {
111  } else if (m_leptonType == "kTriElectron") {
112  if (m_LHType != "ttZTrilepton") {
113  ATH_MSG_ERROR(" LeptonType kTriElectron is only defined for the ttZTrilepton likelihood");
114  return StatusCode::FAILURE;
115  }
121  } else if (m_leptonType == "kTriMuon") {
122  if (m_LHType != "ttZTrilepton") {
123  ATH_MSG_ERROR(" LeptonType kTriMuon is only defined for the ttZTrilepton likelihood");
124  return StatusCode::FAILURE;
125  }
131  } else {
132  ATH_MSG_ERROR(" Please supply a valid LeptonType : kElectron or kMuon");
133  return StatusCode::FAILURE;
134  }
135 
142  }
143  // 4.b) Jet Selection Mode
144  std::string JetSelectionMode = "";
145  if (findOption(custom_tokens, "KLFitterJetSelectionMode", temp_option)) JetSelectionMode = temp_option;
146  else JetSelectionMode = m_config->KLFitterJetSelectionMode();
147 
149  else if (JetSelectionMode ==
151  else if (JetSelectionMode ==
154 
155  else if (JetSelectionMode ==
157  else if (JetSelectionMode ==
159  else if (JetSelectionMode ==
160  "kBtagPriorityThreeJets") m_jetSelectionModeKLFitterEnum =
162  else if (JetSelectionMode ==
164 
165  else if (JetSelectionMode ==
167 
168  else if (JetSelectionMode ==
170  else if (JetSelectionMode ==
171  "kBtagPrioritySevenJets") m_jetSelectionModeKLFitterEnum =
173  else if (JetSelectionMode ==
174  "kBtagPriorityEightJets") m_jetSelectionModeKLFitterEnum =
176  else {
178  "Please supply a valid JetSelectionMode : kLeadingFour , kLeadingFive , kLeadingSix , kLeadingSeven , kLeadingEight , kBtagPriorityFourJets , kBtagPriorityFiveJets , kBtagPrioritySixJets , kBtagPrioritySevenJets , kBtagPriorityEightJets");
179  return StatusCode::FAILURE;
180  }
181 
188  if (m_LHType == "ttH" || m_LHType == "ttbar_AllHadronic") {
190  "You want to run the ttH or ttbar_AllHadronic Likelihood, you need to use either : kLeadingSix , kBtagPrioritySixJets , kLeadingSeven , kBtagPrioritySevenJets , kLeadingEight , kBtagPriorityEightJets");
191  return StatusCode::FAILURE;
192  }
193  }
194 
195  // 4.c) SetBTagging method
196  std::string BTaggingMethod = "";
197  if (findOption(custom_tokens, "KLFitterBTaggingMethod", temp_option)) BTaggingMethod = temp_option;
198  else BTaggingMethod = m_config->KLFitterBTaggingMethod();
199 
200  if (BTaggingMethod == "kNotag") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kNotag;
201  else if (BTaggingMethod ==
202  "kVetoNoFit") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFit;
203  else if (BTaggingMethod ==
204  "kVetoNoFitLight") m_bTaggingMethodKLFitterEnum =
205  KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFitLight;
206  else if (BTaggingMethod ==
207  "kVetoNoFitBoth") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoNoFitBoth;
208  else if (BTaggingMethod ==
209  "kVetoHybridNoFit") m_bTaggingMethodKLFitterEnum =
210  KLFitter::LikelihoodBase::BtaggingMethod::kVetoHybridNoFit;
211  else if (BTaggingMethod == "kWorkingPoint") {
212  m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kWorkingPoint;
213  m_isWorkingPoint = true;
214  } else if (BTaggingMethod ==
215  "kVeto") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVeto;
216  else if (BTaggingMethod ==
217  "kVetoLight") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoLight;
218  else if (BTaggingMethod ==
219  "kVetoBoth") m_bTaggingMethodKLFitterEnum = KLFitter::LikelihoodBase::BtaggingMethod::kVetoBoth;
220  else {
222  "Please supply a valid BTaggingMethod : kNotag,kVetoNoFit,kVetoNoFitLight,kVetoNoFitBoth,kVetoHybridNoFit,kWorkingPoint,kVeto,kVetoLight or kVetoBoth");
223  return StatusCode::FAILURE;
224  }
232  // 4.d) SetTopMass
233  m_myLikelihood->PhysicsConstants()->SetMassTop(m_massTop);
234  m_myLikelihood_TTH->PhysicsConstants()->SetMassTop(m_massTop);
235  m_myLikelihood_JetAngles->PhysicsConstants()->SetMassTop(m_massTop);
236  m_myLikelihood_Angular->PhysicsConstants()->SetMassTop(m_massTop);
237  m_myLikelihood_TTZ->PhysicsConstants()->SetMassTop(m_massTop);
238  m_myLikelihood_AllHadronic->PhysicsConstants()->SetMassTop(m_massTop);
239  m_myLikelihood_BoostedLJets->PhysicsConstants()->SetMassTop(m_massTop);
240  // 4.e) TopMassFixed
241  bool FixTopMass = true;
242  if (findOption(custom_tokens, "KLFitterTopMassFixed", temp_option)) {
243  if (temp_option.compare("True") == 0) FixTopMass = true;
244  else if (temp_option.compare("False") == 0) FixTopMass = false;
245  else {
246  ATH_MSG_ERROR("Invalid KLFitterTopMassFixed custom option! Exiting.");
247  return StatusCode::FAILURE;
248  }
249  } else FixTopMass = m_config->KLFitterTopMassFixed();
250 
251  m_myLikelihood->SetFlagTopMassFixed(FixTopMass);
252  m_myLikelihood_TTH->SetFlagTopMassFixed(FixTopMass);
253  m_myLikelihood_JetAngles->SetFlagTopMassFixed(FixTopMass);
254  m_myLikelihood_Angular->SetFlagTopMassFixed(FixTopMass);
255  m_myLikelihood_TTZ->SetFlagTopMassFixed(FixTopMass);
256  m_myLikelihood_AllHadronic->SetFlagTopMassFixed(FixTopMass);
257  m_myLikelihood_BoostedLJets->SetFlagTopMassFixed(FixTopMass);
258 
259  // 5) tell the fitter which likelihood to use
260  if (m_LHType == "ttbar") top::check(m_myFitter->SetLikelihood(
261  m_myLikelihood.get()),
262  "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
263  else if (m_LHType == "ttH") top::check(m_myFitter->SetLikelihood(
264  m_myLikelihood_TTH.get()),
265  "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
266  else if (m_LHType == "ttbar_JetAngles") top::check(m_myFitter->SetLikelihood(
268  "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
269  else if (m_LHType == "ttbar_Angular") top::check(m_myFitter->SetLikelihood(
270  m_myLikelihood_Angular.get()),
271  "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
272  else if (m_LHType == "ttZTrilepton" && (m_leptonType == "kTriElectron" || m_leptonType == "kTriMuon")) {
273  // For ttZ->trilepton, we can have difficult combinations of leptons in the
274  // final state (3x same flavour, or mixed case). The latter is trivial, for
275  // which we can default back to the ljets likelihood. So we distinguish here:
276  // - kTriMuon, kTriElectron: dedicated TTZ->trilepton likelihood,
277  // - kMuon, kElectron: standard ttbar->l+jets likelihood.
278  top::check(m_myFitter->SetLikelihood(
279  m_myLikelihood_TTZ.get()), "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
280  } else if (m_LHType == "ttZTrilepton") {
281  top::check(m_myFitter->SetLikelihood(
282  m_myLikelihood.get()), "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
283  } else if (m_LHType == "ttbar_AllHadronic") {
284  top::check(m_myFitter->SetLikelihood(
286  "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
287  } else if (m_LHType == "ttbar_BoostedLJets") {
288  top::check(m_myFitter->SetLikelihood(
290  "KLFitterTool::initialize() ERROR setting likelihood for KLFitter");
291  } else {
292  ATH_MSG_ERROR("KLFitter: This likelihood is not defined...");
293  return StatusCode::FAILURE;
294  }
295 
296  // 6) Figure out the b tagging working point
297  // All the blame for this horrible code rests with the b-tagging people
298  std::string btagWP = "";
299  if (findOption(custom_tokens, "KLFitterBTaggingWP", temp_option)) btagWP = temp_option;
300  else {
301  if (m_config->bTagWP().size() != 1) {
303  m_config->bTagWP().size() <<
304  " b-tagging WP - cannot pick b-jets. Please select only 1 WP or specify the desired one in your selection!");
305  return StatusCode::FAILURE;
306  }
307  btagWP = m_config->bTagWP()[0];
308  }
309  if (btagWP.find("Continuous") != std::string::npos) {
311  "KLFitter is not able to run with (pseudo)continuous b-tagging! Please specify a different WP either in your configuration file or in your selection!");
312  return StatusCode::FAILURE;
313  }
314 
315  if (m_isWorkingPoint) {
316  m_btagging_eff_tool = "BTaggingEfficiencyTool_" + btagWP + "_" + m_config->sgKeyJets();
317  top::check(m_btagging_eff_tool.retrieve(), "KLFitterTool:: Failed to retrieve b-tagging Efficiency tool");
318  }
319 
320  ATH_MSG_INFO("++++++++++++++++++++++++++++++");
321  ATH_MSG_INFO("Configured KLFitter with name " << name());
322  ATH_MSG_INFO(" For selection " << m_selectionName);
323  ATH_MSG_INFO(" Using " << m_btagging_eff_tool);
324  ATH_MSG_INFO(" Using transfer functions with full path " << transferFunctionAbsPath);
325  ATH_MSG_INFO(" Using Lepton \t\t" << m_leptonType);
326  ATH_MSG_INFO(" Using JetSelectionMode \t" << JetSelectionMode);
327  ATH_MSG_INFO(" Using BTaggingMethod \t" << BTaggingMethod);
328  ATH_MSG_INFO(" Using TopMassFixed \t" << FixTopMass);
329 
330  if (m_config->KLFitterSaveAllPermutations()) ATH_MSG_INFO(" Saving All permutations");
331  else ATH_MSG_INFO(" Saving only the permutation with the highest event probability");
332  ATH_MSG_INFO("++++++++++++++++++++++++++++++");
333 
335  return StatusCode::SUCCESS;
336  }
337 
339  bool KLFitterTool::findOption(std::vector<std::string> full_options, std::string option, std::string& op_value) {
340  //Find option in full_options and put in op_value, then return true. Otherwise return false
341  for (unsigned int t = 0; t < full_options.size(); ++t) {
342  if (full_options.at(t).compare("") == 0) continue; //Skip void strings
343  top::check((full_options.at(t).find(
344  ":") != std::string::npos),
345  "KLFitterTool::findOption Error! You specified an invalid option: " + full_options.at(
346  t) + ". Expected format is A:a B:b C:c...");
347  std::string key = full_options.at(t).substr(0, full_options.at(t).find(":"));
348  std::string value = full_options.at(t).substr(full_options.at(t).find(":") + 1);
349  if (key.compare(option) == 0) {
350  op_value = value;
351  return true;
352  }
353  }
354  return false;
355  }
356 
359  // run KLFitter
360  // create an instance of the particles class filled with the particles to be fitted;
361  // here, you need to make sure that
362  // - the particles are in the range allowed by the transfer functions (eta and pt)
363  // - the energies and momenta are in GeV
364  // - be aware that *all* particles you're adding are considered in the fit
365  // (many particles lead to many permutations to be considered and hence a long
366  // running time and not necessarily good fitting results due to the many available
367  // permutations)
368  // the arguments taken py AddParticle() are
369  // - TLorentzVector of the physics 4-momentum
370  // - detector eta for the evaluation of the transfer functions (for muons: just use the physics eta)
371  // - type of particle
372  // - an optional name of the particle (pass empty string in case you don't want to give your particle a name)
373  // - index of the particle in your original collection (for convenience)
374  // - for jets:
375  // * bool isBtagged : mandatory only if you want to use b-tagging in the fit
376 
377 /*
378  FIXME: this may be useful to cache results, that's why I am not deleting this piece of commented code
379  maybe we could concatenate the full KLFitter selection and then calculate an hash...
380  if( (event.m_info->isAvailable< int >( "KLFitterHasRun" ) ) )
381  if( ( event.m_info->auxdata< int >("KLFitterHasRun") )!=0 ) return StatusCode::SUCCESS;
382  */
383  KLFitter::Particles* myParticles = new KLFitter::Particles {};
384 
385  if (m_LHType == "ttbar") {
387  TLorentzVector el;
388  el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at(
389  0)->phi(), event.m_electrons.at(0)->e() / 1.e3);
390  myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron);
391  }
393  TLorentzVector mu;
394  mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at(
395  0)->phi(), event.m_muons.at(0)->e() / 1.e3);
396  myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon);
397  }
398  }
399  if (m_LHType == "ttH") {
401  TLorentzVector el;
402  el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at(
403  0)->phi(), event.m_electrons.at(0)->e() / 1.e3);
404  myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron);
405  }
407  TLorentzVector mu;
408  mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at(
409  0)->phi(), event.m_muons.at(0)->e() / 1.e3);
410  myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon);
411  }
412  }
413  if (m_LHType == "ttbar_JetAngles") {
415  TLorentzVector el;
416  el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at(
417  0)->phi(), event.m_electrons.at(0)->e() / 1.e3);
418  myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron);
419  }
421  TLorentzVector mu;
422  mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at(
423  0)->phi(), event.m_muons.at(0)->e() / 1.e3);
424  myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon);
425  }
426  }
427  if (m_LHType == "ttbar_Angular") {
429  TLorentzVector el;
430  el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at(
431  0)->phi(), event.m_electrons.at(0)->e() / 1.e3);
432  myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron);
433  }
435  TLorentzVector mu;
436  mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at(
437  0)->phi(), event.m_muons.at(0)->e() / 1.e3);
438  myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon);
439  }
440  }
441  if (m_LHType == "ttZTrilepton") {
443  if (m_leptonType == "kTriElectron") {
444  // This is the "true" trilepton case with three leptons of the same flavour.
445  if (event.m_electrons.size() < 3) {
446  ATH_MSG_ERROR("KLFitter: kTriElectron requires three electrons...");
447  return StatusCode::FAILURE;
448  }
449  TLorentzVector el;
450  for (unsigned int i = 0; i < 3; ++i) {
451  const auto& electron = event.m_electrons.at(i);
452  el.SetPtEtaPhiE(electron->pt() / 1.e3, electron->eta(), electron->phi(), electron->e() / 1.e3);
453  myParticles->AddParticle(&el, electron->caloCluster()->etaBE(2), KLFitter::Particles::kElectron, "", i);
454  }
455  } else {
456  // Trivial case of mixed lepton flavours. Use ttbar->l+jets likelihood and only add the single lepton.
457  TLorentzVector el;
458  el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at(
459  0)->phi(), event.m_electrons.at(0)->e() / 1.e3);
460  myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2),
462  }
463  }
464 
466  if (m_leptonType == "kTriMuon") {
467  // This is the "true" trilepton case with three leptons of the same flavour.
468  if (event.m_muons.size() < 3) {
469  ATH_MSG_ERROR("KLFitter: kTriMuon requires three muons...");
470  return StatusCode::FAILURE;
471  }
472  TLorentzVector mu;
473  for (unsigned int i = 0; i < 3; ++i) {
474  const auto& muon = event.m_muons.at(i);
475  mu.SetPtEtaPhiE(muon->pt() / 1.e3, muon->eta(), muon->phi(), muon->e() / 1.e3);
476  myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon, "", i);
477  }
478  } else {
479  // Trivial case of mixed lepton flavours. Use ttbar->l+jets likelihood and only add the single lepton.
480  TLorentzVector mu;
481  mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at(
482  0)->phi(), event.m_muons.at(0)->e() / 1.e3);
483  myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon);
484  }
485  }
486  }
487  if (m_LHType == "ttbar_BoostedLJets") {
489  TLorentzVector el;
490  el.SetPtEtaPhiE(event.m_electrons.at(0)->pt() / 1.e3, event.m_electrons.at(0)->eta(), event.m_electrons.at(
491  0)->phi(), event.m_electrons.at(0)->e() / 1.e3);
492  myParticles->AddParticle(&el, event.m_electrons.at(0)->caloCluster()->etaBE(2), KLFitter::Particles::kElectron);
493  }
495  TLorentzVector mu;
496  mu.SetPtEtaPhiE(event.m_muons.at(0)->pt() / 1.e3, event.m_muons.at(0)->eta(), event.m_muons.at(
497  0)->phi(), event.m_muons.at(0)->e() / 1.e3);
498  myParticles->AddParticle(&mu, mu.Eta(), KLFitter::Particles::kMuon);
499  }
500  }
501 
502  // set the jets, depending on the Jet Selection Mode
503  if (!setJets(event, myParticles)) {
504  ATH_MSG_INFO(
505  "KLFitterTool::execute: error at event " << event.m_info->eventNumber() <<
506  ". It was not possible to properly fill the jets. Are you trying to use a KLeadingX Jet Selection mode with a signal region with less than X jets? Please check your configuration!");
507  return StatusCode::FAILURE;
508  }
509 
510  // add the particles to the fitter
511  if (!m_myFitter->SetParticles(myParticles)) {
512  ATH_MSG_ERROR("KLFitter: Error adding particles to fitter...");
513  return StatusCode::FAILURE;
514  }
515 
516  // add the MET x and y components as well as the SumET to the fitter
517  const double met_ex = event.m_met->mpx() / 1.e3;
518  const double met_ey = event.m_met->mpy() / 1.e3;
519  const double met_sumet = event.m_met->sumet() / 1.e3;
520 
521  if (!m_myFitter->SetET_miss_XY_SumET(met_ex, met_ey, met_sumet)) {
522  ATH_MSG_ERROR("KLFitter: Error adding MET to fitter...");
523  return StatusCode::FAILURE;
524  }
525  // define StoreGate names
526  std::string outputSGKey("SetMe");
527  if (!event.m_isLoose) {
528  outputSGKey = m_config->sgKeyKLFitter(event.m_hashValue);
529  }
530  if (event.m_isLoose) {
531  outputSGKey = m_config->sgKeyKLFitterLoose(event.m_hashValue);
532  }
533  std::string outputSGKeyAux = outputSGKey + "Aux.";
534  // create or retrieve (if existent) the xAOD::KLFitterResultContainer
535  xAOD::KLFitterResultAuxContainer* resultAuxContainer = nullptr;
536  xAOD::KLFitterResultContainer* resultContainer = nullptr;
537  if ((!m_config->KLFitterSaveAllPermutations()) ||
538  ((m_config->KLFitterSaveAllPermutations()) &&
539  (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)))) {
540  resultAuxContainer = new xAOD::KLFitterResultAuxContainer {};
541  resultContainer = new xAOD::KLFitterResultContainer {};
542  resultContainer->setStore(resultAuxContainer);
543  } else top::check(evtStore()->tds()->retrieve(resultContainer,
544  outputSGKey),
545  "KLFitterTools::execute(): can not retrieve xAOD::KLFitterResultContainer from evtStore()");
546 
547  // loop over all permutations
548  const int nperm = m_myFitter->Permutations()->NPermutations();
549  for (int iperm = 0; iperm < nperm; ++iperm) {
550  // Perform the fit
551  m_myFitter->Fit(iperm);
552  // create a result
554  resultContainer->push_back(result);
555 
556  //Set name hash. This is because it seems std::string is not supported by AuxContainers...
557  std::hash<std::string> hash_string;
558  result->setSelectionCode(hash_string(m_selectionName));
559 
560  unsigned int ConvergenceStatusBitWord = m_myFitter->ConvergenceStatus();
561  bool MinuitDidNotConverge = (ConvergenceStatusBitWord & m_myFitter->MinuitDidNotConvergeMask) != 0;
562  bool FitAbortedDueToNaN = (ConvergenceStatusBitWord & m_myFitter->FitAbortedDueToNaNMask) != 0;
563  bool AtLeastOneFitParameterAtItsLimit =
564  (ConvergenceStatusBitWord & m_myFitter->AtLeastOneFitParameterAtItsLimitMask) != 0;
565  bool InvalidTransferFunctionAtConvergence =
566  (ConvergenceStatusBitWord & m_myFitter->InvalidTransferFunctionAtConvergenceMask) != 0;
567 
568  result->setMinuitDidNotConverge(((MinuitDidNotConverge) ? 1 : 0));
569  result->setFitAbortedDueToNaN(((FitAbortedDueToNaN) ? 1 : 0));
570  result->setAtLeastOneFitParameterAtItsLimit(((AtLeastOneFitParameterAtItsLimit) ? 1 : 0));
571  result->setInvalidTransferFunctionAtConvergence(((InvalidTransferFunctionAtConvergence) ? 1 : 0));
572 
573  result->setLogLikelihood(m_myFitter->Likelihood()->LogLikelihood(m_myFitter->Likelihood()->GetBestFitParameters()));
574  result->setEventProbability(std::exp(m_myFitter->Likelihood()->LogEventProbability()));
575  result->setParameters(m_myFitter->Likelihood()->GetBestFitParameters());
576  result->setParameterErrors(m_myFitter->Likelihood()->GetBestFitParameterErrors());
577 
578  KLFitter::Particles* myModelParticles = m_myFitter->Likelihood()->ParticlesModel();
579  KLFitter::Particles** myPermutedParticles = m_myFitter->Likelihood()->PParticlesPermuted();
580 
581 
582  if (m_LHType == "ttbar" || m_LHType == "ttH" || m_LHType == "ttbar_JetAngles" || m_LHType == "ttbar_Angular" ||
583  m_LHType == "ttZTrilepton" || m_LHType == "ttbar_BoostedLJets") {
584  result->setModel_bhad_pt(myModelParticles->Parton(0)->Pt());
585  result->setModel_bhad_eta(myModelParticles->Parton(0)->Eta());
586  result->setModel_bhad_phi(myModelParticles->Parton(0)->Phi());
587  result->setModel_bhad_E(myModelParticles->Parton(0)->E());
588  result->setModel_bhad_jetIndex((*myPermutedParticles)->JetIndex(0));
589 
590  result->setModel_blep_pt(myModelParticles->Parton(1)->Pt());
591  result->setModel_blep_eta(myModelParticles->Parton(1)->Eta());
592  result->setModel_blep_phi(myModelParticles->Parton(1)->Phi());
593  result->setModel_blep_E(myModelParticles->Parton(1)->E());
594  result->setModel_blep_jetIndex((*myPermutedParticles)->JetIndex(1));
595 
596  result->setModel_lq1_pt(myModelParticles->Parton(2)->Pt());
597  result->setModel_lq1_eta(myModelParticles->Parton(2)->Eta());
598  result->setModel_lq1_phi(myModelParticles->Parton(2)->Phi());
599  result->setModel_lq1_E(myModelParticles->Parton(2)->E());
600  result->setModel_lq1_jetIndex((*myPermutedParticles)->JetIndex(2));
601 
602  // boosted likelihood has only one light jet
603  if (m_LHType != "ttbar_BoostedLJets") {
604  result->setModel_lq2_pt(myModelParticles->Parton(3)->Pt());
605  result->setModel_lq2_eta(myModelParticles->Parton(3)->Eta());
606  result->setModel_lq2_phi(myModelParticles->Parton(3)->Phi());
607  result->setModel_lq2_E(myModelParticles->Parton(3)->E());
608  result->setModel_lq2_jetIndex((*myPermutedParticles)->JetIndex(3));
609 
610  if (m_LHType == "ttH") {
611  result->setModel_Higgs_b1_pt(myModelParticles->Parton(4)->Pt());
612  result->setModel_Higgs_b1_eta(myModelParticles->Parton(4)->Eta());
613  result->setModel_Higgs_b1_phi(myModelParticles->Parton(4)->Phi());
614  result->setModel_Higgs_b1_E(myModelParticles->Parton(4)->E());
615  result->setModel_Higgs_b1_jetIndex((*myPermutedParticles)->JetIndex(4));
616 
617  result->setModel_Higgs_b2_pt(myModelParticles->Parton(5)->Pt());
618  result->setModel_Higgs_b2_eta(myModelParticles->Parton(5)->Eta());
619  result->setModel_Higgs_b2_phi(myModelParticles->Parton(5)->Phi());
620  result->setModel_Higgs_b2_E(myModelParticles->Parton(5)->E());
621  result->setModel_Higgs_b2_jetIndex((*myPermutedParticles)->JetIndex(5));
622  }
623  }
624 
631  result->setModel_lep_pt(myModelParticles->Electron(0)->Pt());
632  result->setModel_lep_eta(myModelParticles->Electron(0)->Eta());
633  result->setModel_lep_phi(myModelParticles->Electron(0)->Phi());
634  result->setModel_lep_E(myModelParticles->Electron(0)->E());
635 
636  if (m_leptonType == "kTriElectron") {
637  result->setModel_lep_index((*myPermutedParticles)->ElectronIndex(0));
638 
639  result->setModel_lepZ1_pt(myModelParticles->Electron(1)->Pt());
640  result->setModel_lepZ1_eta(myModelParticles->Electron(1)->Eta());
641  result->setModel_lepZ1_phi(myModelParticles->Electron(1)->Phi());
642  result->setModel_lepZ1_E(myModelParticles->Electron(1)->E());
643  result->setModel_lepZ1_index((*myPermutedParticles)->ElectronIndex(1));
644 
645  result->setModel_lepZ2_pt(myModelParticles->Electron(2)->Pt());
646  result->setModel_lepZ2_eta(myModelParticles->Electron(2)->Eta());
647  result->setModel_lepZ2_phi(myModelParticles->Electron(2)->Phi());
648  result->setModel_lepZ2_E(myModelParticles->Electron(2)->E());
649  result->setModel_lepZ2_index((*myPermutedParticles)->ElectronIndex(2));
650  }
651  }
652 
659  result->setModel_lep_pt(myModelParticles->Muon(0)->Pt());
660  result->setModel_lep_eta(myModelParticles->Muon(0)->Eta());
661  result->setModel_lep_phi(myModelParticles->Muon(0)->Phi());
662  result->setModel_lep_E(myModelParticles->Muon(0)->E());
663 
664  if (m_leptonType == "kTriMuon") {
665  result->setModel_lep_index((*myPermutedParticles)->MuonIndex(0));
666 
667  result->setModel_lepZ1_pt(myModelParticles->Muon(1)->Pt());
668  result->setModel_lepZ1_eta(myModelParticles->Muon(1)->Eta());
669  result->setModel_lepZ1_phi(myModelParticles->Muon(1)->Phi());
670  result->setModel_lepZ1_E(myModelParticles->Muon(1)->E());
671  result->setModel_lepZ1_index((*myPermutedParticles)->MuonIndex(1));
672 
673  result->setModel_lepZ2_pt(myModelParticles->Muon(2)->Pt());
674  result->setModel_lepZ2_eta(myModelParticles->Muon(2)->Eta());
675  result->setModel_lepZ2_phi(myModelParticles->Muon(2)->Phi());
676  result->setModel_lepZ2_E(myModelParticles->Muon(2)->E());
677  result->setModel_lepZ2_index((*myPermutedParticles)->MuonIndex(2));
678  }
679  }
680 
681  result->setModel_nu_pt(myModelParticles->Neutrino(0)->Pt());
682  result->setModel_nu_eta(myModelParticles->Neutrino(0)->Eta());
683  result->setModel_nu_phi(myModelParticles->Neutrino(0)->Phi());
684  result->setModel_nu_E(myModelParticles->Neutrino(0)->E());
685  } else if (m_LHType == "ttbar_AllHadronic") {
686  result->setModel_b_from_top1_pt(myModelParticles->Parton(0)->Pt());
687  result->setModel_b_from_top1_eta(myModelParticles->Parton(0)->Eta());
688  result->setModel_b_from_top1_phi(myModelParticles->Parton(0)->Phi());
689  result->setModel_b_from_top1_E(myModelParticles->Parton(0)->E());
690  result->setModel_b_from_top1_jetIndex((*myPermutedParticles)->JetIndex(0));
691 
692  result->setModel_b_from_top2_pt(myModelParticles->Parton(1)->Pt());
693  result->setModel_b_from_top2_eta(myModelParticles->Parton(1)->Eta());
694  result->setModel_b_from_top2_phi(myModelParticles->Parton(1)->Phi());
695  result->setModel_b_from_top2_E(myModelParticles->Parton(1)->E());
696  result->setModel_b_from_top2_jetIndex((*myPermutedParticles)->JetIndex(1));
697 
698  result->setModel_lj1_from_top1_pt(myModelParticles->Parton(2)->Pt());
699  result->setModel_lj1_from_top1_eta(myModelParticles->Parton(2)->Eta());
700  result->setModel_lj1_from_top1_phi(myModelParticles->Parton(2)->Phi());
701  result->setModel_lj1_from_top1_E(myModelParticles->Parton(2)->E());
702  result->setModel_lj1_from_top1_jetIndex((*myPermutedParticles)->JetIndex(2));
703 
704  result->setModel_lj2_from_top1_pt(myModelParticles->Parton(3)->Pt());
705  result->setModel_lj2_from_top1_eta(myModelParticles->Parton(3)->Eta());
706  result->setModel_lj2_from_top1_phi(myModelParticles->Parton(3)->Phi());
707  result->setModel_lj2_from_top1_E(myModelParticles->Parton(3)->E());
708  result->setModel_lj2_from_top1_jetIndex((*myPermutedParticles)->JetIndex(3));
709 
710  result->setModel_lj1_from_top2_pt(myModelParticles->Parton(4)->Pt());
711  result->setModel_lj1_from_top2_eta(myModelParticles->Parton(4)->Eta());
712  result->setModel_lj1_from_top2_phi(myModelParticles->Parton(4)->Phi());
713  result->setModel_lj1_from_top2_E(myModelParticles->Parton(4)->E());
714  result->setModel_lj1_from_top2_jetIndex((*myPermutedParticles)->JetIndex(4));
715 
716  result->setModel_lj2_from_top2_pt(myModelParticles->Parton(5)->Pt());
717  result->setModel_lj2_from_top2_eta(myModelParticles->Parton(5)->Eta());
718  result->setModel_lj2_from_top2_phi(myModelParticles->Parton(5)->Phi());
719  result->setModel_lj2_from_top2_E(myModelParticles->Parton(5)->E());
720  result->setModel_lj2_from_top2_jetIndex((*myPermutedParticles)->JetIndex(5));
721  }
722  } // Loop over permutations
723 
724  // Normalize event probability to unity
725  // work out best permutation
726  float sumEventProbability(0.), bestEventProbability(0.);
727  unsigned int bestPermutation(999), iPerm(0);
728 
729  // First loop
730  for (auto x : *resultContainer) {
731  float prob = x->eventProbability();
732  short minuitDidNotConverge = x->minuitDidNotConverge();
733  short fitAbortedDueToNaN = x->fitAbortedDueToNaN();
734  short atLeastOneFitParameterAtItsLimit = x->atLeastOneFitParameterAtItsLimit();
735  short invalidTransferFunctionAtConvergence = x->invalidTransferFunctionAtConvergence();
736  sumEventProbability += prob;
737  ++iPerm;
738 
739  // check if the best value has the highest event probability AND converged
740  if (minuitDidNotConverge) continue;
741  if (fitAbortedDueToNaN) continue;
742  if (atLeastOneFitParameterAtItsLimit) continue;
744 
745  if (prob > bestEventProbability) {
746  bestEventProbability = prob;
747  // Using iPerm -1 because it has already been incremented before
748  bestPermutation = iPerm - 1;
749  }
750  }
751 
752  // Second loop
753  iPerm = 0;
754  for (auto x : *resultContainer) {
755  x->setEventProbability(x->eventProbability() / sumEventProbability);
756  if (iPerm == bestPermutation) {
757  x->setBestPermutation(1);
758  } else {
759  x->setBestPermutation(0);
760  }
761  ++iPerm;
762  }
763 
764  // Save to StoreGate / TStore
765 
766  // Save all permutations or only the highest event probability?
767 
768  // Save all
769  if (m_config->KLFitterSaveAllPermutations()) {
770  if (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)) {
771  top::check(evtStore()->tds()->record(resultContainer,
772  outputSGKey),
773  "KLFitterTools: ERROR! Was not able to write KLFitterResultContainer");
774  top::check(evtStore()->tds()->record(resultAuxContainer,
775  outputSGKeyAux),
776  "KLFitterTools: ERROR! Was not able to write KLFitterResultAuxContainer");
777  }
778  }
779  // Save only the best
780  else {
781  // create ore retrieve the xAOD::KLFitterResultContainer
782  xAOD::KLFitterResultAuxContainer* bestAuxContainer = nullptr;
783  xAOD::KLFitterResultContainer* bestContainer = nullptr;
784  if (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)) {
785  bestAuxContainer = new xAOD::KLFitterResultAuxContainer {};
786  bestContainer = new xAOD::KLFitterResultContainer {};
787  bestContainer->setStore(bestAuxContainer);
788  } else top::check(evtStore()->tds()->retrieve(bestContainer,
789  outputSGKey),
790  "KLFitterTools::execute(): can not retrieve xAOD::KLFitterResultContainer from evtStore()");
791 
792  for (auto x : *resultContainer) {
793  if (x->bestPermutation() == 1) {
795  result->makePrivateStore(*x);
796  bestContainer->push_back(result);
797  }
798  }
799  if (!evtStore()->tds()->contains<xAOD::KLFitterResultContainer>(outputSGKey)) {
800  top::check(evtStore()->tds()->record(bestContainer,
801  outputSGKey),
802  "KLFitterTools: ERROR! Was not able to write KLFitterResultContainer with best permutation");
803  top::check(evtStore()->tds()->record(bestAuxContainer,
804  outputSGKeyAux),
805  "KLFitterTools: ERROR! Was not able to write KLFitterResultAuxContainer with best permutation");
806  }
807  // watch out for memory leaks!
808  // raw pointers have not been put into a DataVector
809  // we still actually own them
810  // AnalysisTop will actually do some memory management (which is very wierd and we don't like it)
811  delete resultContainer;
812  delete resultAuxContainer;
813  }
814 
815  // Pull the const result back out of StoreGate and attach to top::Event
816  top::check(evtStore()->retrieve(event.m_KLFitterResults, outputSGKey),
817  "Failed to add KLFitterResults to top::Event");
818 
819  delete myParticles;
820 
822  return StatusCode::SUCCESS;
823  }
824 
825  bool KLFitterTool::HasTag(const xAOD::Jet& jet, double& weight) const {
826  weight = -99.;
827 
828  for (const std::string& tagWP : m_config->bTagWP()) {
829  if (tagWP.find("Continuous") != std::string::npos) continue;
830  if (!jet.isAvailable<char>("isbtagged_" + tagWP)) {
831  ATH_MSG_ERROR("Failed to retrieve jet decoration isbtagged_" + tagWP);
832  break;
833  }
834  return jet.auxdataConst<char>("isbtagged_" + tagWP);
835  }
836  return false;
837  }
838 
839  void KLFitterTool::retrieveEfficiencies(const xAOD::Jet& jet, float* efficiency, float* inefficiency) {
840  *efficiency = .7725; // dummy values
841  *inefficiency = 1. / 125.93; // dummy values
842  //copy jet
844  xAOD::JetAuxContainer jetsAux;
845  jets.setStore(&jetsAux);
846  xAOD::Jet* jet_copy = new xAOD::Jet();
847  jets.push_back(jet_copy);
848  *jet_copy = jet;
849  jet_copy->setJetP4(jet.jetP4());
850  //treat jet as b-tagged
851  jet_copy->setAttribute("HadronConeExclTruthLabelID", 5);
852  top::check(m_btagging_eff_tool->getMCEfficiency(*jet_copy, *efficiency),
853  "Could not retrieve tagging efficiency for b-jet");
854  //treat jet as light
855  jet_copy->setAttribute("HadronConeExclTruthLabelID", 0);
856  top::check(m_btagging_eff_tool->getMCEfficiency(*jet_copy, *inefficiency),
857  "Could not retrieve tagging efficiency for light jet");
858  }
859 
862  inputParticles);
863 
864 
865 
867  inputParticles);
868 
869 
870 
872  inputParticles);
873 
874 
875 
877  inputParticles);
878 
879 
880 
882  inputParticles);
883 
884 
885 
887  inputParticles);
888 
889 
890 
893 
896 
899 
902 
905 
908 
909  return false;
910  }
911 
913  return setJetskLeadingX(event, inputParticles, 3);
914  }
915 
917  return setJetskLeadingX(event, inputParticles, 4);
918  }
919 
921  return setJetskLeadingX(event, inputParticles, 5);
922  }
923 
925  return setJetskLeadingX(event, inputParticles, 6);
926  }
927 
929  return setJetskLeadingX(event, inputParticles, 7);
930  }
931 
933  return setJetskLeadingX(event, inputParticles, 8);
934  }
935 
937  const unsigned int njets) {
938  unsigned int index(0);
939 
940  //If container has less jets than required, raise error
941  if (m_config->KLFitterFailOnLessThanXJets()) {
942  if (event.m_jets.size() < njets) {
943  ATH_MSG_INFO(
944  "KLFitterTool::setJetskLeadingX: You required " << njets << " jets. Event has " << event.m_jets.size() <<
945  " jets!");
946  return false;
947  }
948  }
949  for (const auto *jet : event.m_jets) {
950  if (index > njets - 1) break;
951 
952  TLorentzVector jet_p4;
953  jet_p4.SetPtEtaPhiE(jet->pt() / 1.e3, jet->eta(), jet->phi(), jet->e() / 1.e3);
954 
955  double weight(-99.);
956  float eff(0), ineff(0);
957 
958  const bool isTagged = HasTag(*jet, weight);
959 
960  if (m_isWorkingPoint) {
961  retrieveEfficiencies(*jet, &eff, &ineff);
962 
963  inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index,
964  isTagged, eff, 1. / ineff, KLFitter::Particles::kNone, weight);
965  } else {
966  inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index, isTagged);
967  }
968  ++index;
969  }
970  return true;
971  }
972 
974  return setJetskBtagPriority(event, inputParticles, 3);
975  }
976 
978  return setJetskBtagPriority(event, inputParticles, 4);
979  }
980 
982  return setJetskBtagPriority(event, inputParticles, 5);
983  }
984 
986  return setJetskBtagPriority(event, inputParticles, 6);
987  }
988 
990  return setJetskBtagPriority(event, inputParticles, 7);
991  }
992 
994  return setJetskBtagPriority(event, inputParticles, 8);
995  }
996 
998  const unsigned int maxJets) {
999  // kBtagPriority mode first adds the b jets, then the light jets
1000  // If your 6th or 7th jet is a b jet, then you probably want this option
1001 
1002  //If container has less jets than required, raise error
1003  if (m_config->KLFitterFailOnLessThanXJets()) {
1004  if (event.m_jets.size() < maxJets) {
1005  ATH_MSG_INFO(
1006  "KLFitterTool::setJetskBtagPriority: You required " << maxJets << " jets. Event has " << event.m_jets.size() <<
1007  " jets!");
1008  return false;
1009  }
1010  }
1011 
1012  unsigned int totalJets(0);
1013 
1014  // First find the b-jets
1015  unsigned int index(0);
1016  double weight(0);
1017  for (const auto *jet : event.m_jets) {
1018  if (totalJets >= maxJets) break;
1019  if (HasTag(*jet, weight)) {
1020  TLorentzVector jet_p4;
1021  jet_p4.SetPtEtaPhiE(jet->pt() / 1.e3, jet->eta(), jet->phi(), jet->e() / 1.e3);
1022 
1023  if (m_isWorkingPoint) {
1024  float eff(0), ineff(0);
1025  retrieveEfficiencies(*jet, &eff, &ineff);
1026 
1027  inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index,
1028  true, eff, 1. / ineff, KLFitter::Particles::kNone, weight);
1029  } else {
1030  inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index,
1031  true);
1032  }
1033  ++totalJets;
1034  } // HasTag
1035 
1036  ++index;
1037  } // for (jet)
1038 
1039 
1040  // Second, find the light jets
1041  index = 0;
1042  for (const auto *jet : event.m_jets) {
1043  if (totalJets >= maxJets) break;
1044  if (!HasTag(*jet, weight)) {
1045  TLorentzVector jet_p4;
1046  jet_p4.SetPtEtaPhiE(jet->pt() / 1.e3, jet->eta(), jet->phi(), jet->e() / 1.e3);
1047 
1048  if (m_isWorkingPoint) {
1049  float eff(0), ineff(0);
1050  retrieveEfficiencies(*jet, &eff, &ineff);
1051 
1052  inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index,
1053  false, eff, 1. / ineff, KLFitter::Particles::kNone, weight);
1054  } else {
1055  inputParticles->AddParticle(&jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton, "", index,
1056  false);
1057  }
1058  ++totalJets;
1059  } // !HasTag
1060 
1061  ++index;
1062  } // for (jet)
1063  return true;
1064  }
1065 
1069  return StatusCode::SUCCESS;
1070  }
1071 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
top::KLFitterTool::m_leptonTypeKLFitterEnum_JetAngles
KLFitter::LikelihoodTopLeptonJets_JetAngles::LeptonType m_leptonTypeKLFitterEnum_JetAngles
Definition: KLFitterTool.h:126
top::KLFitterTool::m_myFitter
std::unique_ptr< KLFitter::Fitter > m_myFitter
The KLFitter.
Definition: KLFitterTool.h:145
xAOD::KLFitterResult
KLFitterResult A simple xAOD class which we can persist into a mini-xAOD The xAOD EDM is way too comp...
Definition: KLFitterResult.h:26
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
top::KLFitterTool::m_leptonTypeKLFitterEnum_BoostedLJets
KLFitter::BoostedLikelihoodTopLeptonJets::LeptonType m_leptonTypeKLFitterEnum_BoostedLJets
Definition: KLFitterTool.h:129
KLFitterResultAuxContainer.h
get_generator_info.result
result
Definition: get_generator_info.py:21
top
TopConfig A simple configuration that is NOT a singleton.
Definition: AnalysisTrackingHelper.cxx:58
top::KLFitterJetSelection::kLeadingSix
@ kLeadingSix
Definition: KLFitterTool.h:60
KLFitterResultContainer.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
top::KLFitterTool::setJetskBtagPriorityThreeJets
bool setJetskBtagPriorityThreeJets(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:973
top::KLFitterTool::m_config
std::shared_ptr< top::TopConfig > m_config
Definition: KLFitterTool.h:104
top::KLFitterTool::m_myDetector
std::unique_ptr< KLFitter::DetectorAtlas_8TeV > m_myDetector
Definition: KLFitterTool.h:139
top::KLFitterTool::setJetskLeadingEight
bool setJetskLeadingEight(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:932
index
Definition: index.py:1
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
top::KLFitterTool::setJetskBtagPriorityFourJets
bool setJetskBtagPriorityFourJets(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:977
top::KLFitterTool::m_customParameters
std::string m_customParameters
Definition: KLFitterTool.h:122
top::KLFitterTool::m_leptonTypeKLFitterEnum_TTZ
KLFitter::LikelihoodTTZTrilepton::LeptonType m_leptonTypeKLFitterEnum_TTZ
Definition: KLFitterTool.h:128
top::tokenize
void tokenize(const std::string &input, Container &output, const std::string &delimiters=" ", bool trim_empty=false)
Tokenize an input string using a set of delimiters.
Definition: Tokenize.h:24
asg
Definition: DataHandleTestTool.h:28
top::KLFitterTool::setJetskBtagPriorityEightJets
bool setJetskBtagPriorityEightJets(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:993
xAOD::invalidTransferFunctionAtConvergence
invalidTransferFunctionAtConvergence
Definition: KLFitterResult.cxx:19
top::KLFitterTool::m_LHType
std::string m_LHType
Definition: KLFitterTool.h:123
athena.value
value
Definition: athena.py:122
top::KLFitterTool::m_transferFunctionsPathPrefix
std::string m_transferFunctionsPathPrefix
KLFitter parameters, to be set by input file.
Definition: KLFitterTool.h:117
top::KLFitterTool::setJetskLeadingSeven
bool setJetskLeadingSeven(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:928
top::KLFitterJetSelection::kBtagPrioritySevenJets
@ kBtagPrioritySevenJets
Definition: KLFitterTool.h:63
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
covarianceTool.prob
prob
Definition: covarianceTool.py:678
top::KLFitterTool::m_jetSelectionModeKLFitterEnum
top::KLFitterJetSelection::JetSelectionMode m_jetSelectionModeKLFitterEnum
Definition: KLFitterTool.h:141
x
#define x
top::KLFitterTool::m_selectionName
std::string m_selectionName
Definition: KLFitterTool.h:120
top::KLFitterTool::m_myLikelihood_AllHadronic
std::unique_ptr< KLFitter::LikelihoodTopAllHadronic > m_myLikelihood_AllHadronic
Definition: KLFitterTool.h:136
top::KLFitterTool::setJetskBtagPriorityFiveJets
bool setJetskBtagPriorityFiveJets(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:981
top::KLFitterTool::m_massTop
float m_massTop
Definition: KLFitterTool.h:105
top::KLFitterTool::setJetskLeadingSix
bool setJetskLeadingSix(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:924
top::KLFitterTool::m_isWorkingPoint
bool m_isWorkingPoint
Definition: KLFitterTool.h:108
EventTools.h
A few functions for doing operations on particles / events. Currently holds code for dR,...
top::KLFitterJetSelection::kBtagPriorityFourJets
@ kBtagPriorityFourJets
Definition: KLFitterTool.h:62
top::KLFitterTool::m_transferFunctionsPath
std::string m_transferFunctionsPath
Definition: KLFitterTool.h:118
PathResolverFindCalibDirectory
std::string PathResolverFindCalibDirectory(const std::string &logical_file_name)
Definition: PathResolver.cxx:432
top::kMuon
@ kMuon
Definition: PseudoTopReco.h:37
xAOD::Jet_v1::setJetP4
void setJetP4(const JetFourMom_t &p4)
Definition: Jet_v1.cxx:171
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
top::KLFitterTool::m_myLikelihood_TTZ
std::unique_ptr< KLFitter::LikelihoodTTZTrilepton > m_myLikelihood_TTZ
Definition: KLFitterTool.h:135
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
top::KLFitterTool::setJetskLeadingThree
bool setJetskLeadingThree(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:912
efficiency
void efficiency(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
Definition: dependence.cxx:128
xAOD::JetAuxContainer_v1
Temporary container used until we have I/O for AuxStoreInternal.
Definition: JetAuxContainer_v1.h:37
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
top::KLFitterJetSelection::kBtagPriorityEightJets
@ kBtagPriorityEightJets
Definition: KLFitterTool.h:63
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
lumiFormat.i
int i
Definition: lumiFormat.py:92
top::KLFitterTool::m_leptonTypeKLFitterEnum_TTH
KLFitter::LikelihoodTTHLeptonJets::LeptonType m_leptonTypeKLFitterEnum_TTH
Definition: KLFitterTool.h:125
top::KLFitterTool::m_leptonType
std::string m_leptonType
Definition: KLFitterTool.h:121
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
top::KLFitterTool::execute
virtual StatusCode execute(const top::Event &)
Function executing the tool.
Definition: KLFitterTool.cxx:358
top::KLFitterJetSelection::kLeadingThree
@ kLeadingThree
Definition: KLFitterTool.h:60
top::KLFitterTool::m_myLikelihood_TTH
std::unique_ptr< KLFitter::LikelihoodTTHLeptonJets > m_myLikelihood_TTH
Definition: KLFitterTool.h:132
makePlot.Particles
Particles
Definition: makePlot.py:25
top::kElectron
@ kElectron
Definition: PseudoTopReco.h:37
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
top::check
void check(bool thingToCheck, const std::string &usefulFailureMessage)
Print an error message and terminate if thingToCheck is false.
Definition: EventTools.cxx:15
top::KLFitterTool::m_leptonTypeKLFitterEnum
KLFitter::LikelihoodTopLeptonJets::LeptonType m_leptonTypeKLFitterEnum
Definition: KLFitterTool.h:124
top::KLFitterTool::setJetskBtagPrioritySixJets
bool setJetskBtagPrioritySixJets(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:985
Event.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
top::KLFitterTool::setJets
bool setJets(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:860
xAOD::Jet_v1::setAttribute
void setAttribute(const std::string &name, const T &v)
top::KLFitterTool::m_myLikelihood_JetAngles
std::unique_ptr< KLFitter::LikelihoodTopLeptonJets_JetAngles > m_myLikelihood_JetAngles
Definition: KLFitterTool.h:133
top::KLFitterJetSelection::kLeadingFive
@ kLeadingFive
Definition: KLFitterTool.h:60
top::KLFitterTool::HasTag
bool HasTag(const xAOD::Jet &jet, double &weight) const
Definition: KLFitterTool.cxx:825
top::KLFitterJetSelection::kBtagPriorityFiveJets
@ kBtagPriorityFiveJets
Definition: KLFitterTool.h:62
PathResolver.h
top::KLFitterTool::setJetskBtagPrioritySevenJets
bool setJetskBtagPrioritySevenJets(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:989
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
top::KLFitterTool::setJetskLeadingFive
bool setJetskLeadingFive(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:920
top::KLFitterTool::m_myLikelihood_Angular
std::unique_ptr< KLFitter::LikelihoodTopLeptonJets_Angular > m_myLikelihood_Angular
Definition: KLFitterTool.h:134
top::KLFitterTool::setJetskLeadingX
bool setJetskLeadingX(const top::Event &event, KLFitter::Particles *inputParticles, const unsigned int)
Definition: KLFitterTool.cxx:936
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
top::KLFitterTool::m_btagging_eff_tool
ToolHandle< IBTaggingEfficiencyTool > m_btagging_eff_tool
Definition: KLFitterTool.h:112
top::KLFitterJetSelection::kLeadingFour
@ kLeadingFour
Definition: KLFitterTool.h:60
TopConfig.h
top::KLFitterJetSelection::JetSelectionMode
JetSelectionMode
Definition: KLFitterTool.h:59
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
DeMoScan.index
string index
Definition: DeMoScan.py:362
top::KLFitterTool::m_bTaggingMethodKLFitterEnum
KLFitter::LikelihoodBase::BtaggingMethod m_bTaggingMethodKLFitterEnum
Definition: KLFitterTool.h:142
top::KLFitterTool::KLFitterTool
KLFitterTool(const std::string &name)
Constructor.
Definition: KLFitterTool.cxx:17
top::KLFitterJetSelection::kLeadingSeven
@ kLeadingSeven
Definition: KLFitterTool.h:61
top::KLFitterTool::findOption
bool findOption(std::vector< std::string > full_options, std::string option, std::string &op_value)
Config helpers.
Definition: KLFitterTool.cxx:339
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
top::KLFitterTool::initialize
virtual StatusCode initialize()
Function initialising the tool.
Definition: KLFitterTool.cxx:39
top::KLFitterTool::retrieveEfficiencies
void retrieveEfficiencies(const xAOD::Jet &jet, float *efficiency, float *inefficiency)
Definition: KLFitterTool.cxx:839
top::KLFitterTool::m_leptonTypeKLFitterEnum_Angular
KLFitter::LikelihoodTopLeptonJets_Angular::LeptonType m_leptonTypeKLFitterEnum_Angular
Definition: KLFitterTool.h:127
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
dqt_zlumi_alleff_HIST.eff
int eff
Definition: dqt_zlumi_alleff_HIST.py:113
top::KLFitterJetSelection::kBtagPriorityThreeJets
@ kBtagPriorityThreeJets
Definition: KLFitterTool.h:61
top::Event
Very simple class to hold event data after reading from a file.
Definition: Event.h:49
KLFitterTool.h
top::KLFitterTool::m_myLikelihood
std::unique_ptr< KLFitter::LikelihoodTopLeptonJets > m_myLikelihood
Definition: KLFitterTool.h:131
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
top::KLFitterTool::finalize
virtual StatusCode finalize()
Function finalizing the tool.
Definition: KLFitterTool.cxx:1067
top::KLFitterTool::setJetskBtagPriority
bool setJetskBtagPriority(const top::Event &, KLFitter::Particles *inputParticles, const unsigned int maxJets)
Definition: KLFitterTool.cxx:997
top::KLFitterTool::setJetskLeadingFour
bool setJetskLeadingFour(const top::Event &, KLFitter::Particles *inputParticles)
Definition: KLFitterTool.cxx:916
xAOD::Jet
Jet_v1 Jet
Definition of the current "jet version".
Definition: Event/xAOD/xAODJet/xAODJet/Jet.h:17
top::KLFitterJetSelection::kBtagPrioritySixJets
@ kBtagPrioritySixJets
Definition: KLFitterTool.h:62
top::KLFitterTool::m_myLikelihood_BoostedLJets
std::unique_ptr< KLFitter::BoostedLikelihoodTopLeptonJets > m_myLikelihood_BoostedLJets
Definition: KLFitterTool.h:137
xAOD::KLFitterResultAuxContainer
Auxiliary container for xAOD::KLFitterResultContainer.
Definition: KLFitterResultAuxContainer.h:18
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
top::KLFitterJetSelection::kLeadingEight
@ kLeadingEight
Definition: KLFitterTool.h:61