37 }
catch (std::out_of_range &) {
39 <<
m_LHType.value() <<
". Available options: "
41 return StatusCode::FAILURE;
45 ANA_MSG_ERROR(
"The ttbar_JetAngles likelihood is currently not supported!");
46 return StatusCode::FAILURE;
55 "If using ttbar_AllHad likelihood, please use leptonType = "
57 return StatusCode::FAILURE;
59 }
catch (std::out_of_range &) {
63 return StatusCode::FAILURE;
70 }
catch (std::out_of_range &) {
74 return StatusCode::FAILURE;
81 }
catch (std::out_of_range &) {
83 "Could not parse the number of required jets from KLFitter jet "
86 return StatusCode::FAILURE;
93 }
catch (std::out_of_range &) {
97 return StatusCode::FAILURE;
101 m_myFitter = std::make_unique<KLFitter::Fitter>();
102 const std::string transferFunctionAbsPath =
105 std::make_unique<KLFitter::DetectorAtlas_8TeV>(transferFunctionAbsPath);
108 "Failed to set KLFitter::Detector for KLFitter::Fitter instance.");
109 return StatusCode::FAILURE;
113 m_myLikelihood = std::make_unique<KLFitter::LikelihoodTopLeptonJets>();
116 std::make_unique<KLFitter::LikelihoodTopLeptonJets_JetAngles>();
118 std::make_unique<KLFitter::LikelihoodTopLeptonJets_Angular>();
121 std::make_unique<KLFitter::LikelihoodTopAllHadronic>();
123 std::make_unique<KLFitter::BoostedLikelihoodTopLeptonJets>();
156 " LeptonType kTriElectron is only defined for the ttZTrilepton "
158 return StatusCode::FAILURE;
173 " LeptonType kTriMuon is only defined for the ttZTrilepton "
175 return StatusCode::FAILURE;
188 ANA_MSG_ERROR(
" Please supply a valid LeptonType : kElectron or kMuon");
189 return StatusCode::FAILURE;
227 int klfitter_returncode = 0;
233 klfitter_returncode =
236 klfitter_returncode =
251 klfitter_returncode =
254 klfitter_returncode =
258 return StatusCode::FAILURE;
261 if (!klfitter_returncode) {
264 return StatusCode::FAILURE;
268 ANA_MSG_ERROR(
"KLFitter cannot run using Continuous b-tag working point!");
269 return StatusCode::FAILURE;
271 m_bTagDecoAcc = std::make_unique<SG::AuxElement::ConstAccessor<char>>(
275 KLFitter::LikelihoodBase::BtaggingMethod::kWorkingPoint) {
282 ANA_MSG_INFO(
" Using transfer functions with full path "
283 << transferFunctionAbsPath);
293 " Saving only the permutation with the highest event probability");
296 return StatusCode::SUCCESS;
303 return StatusCode::SUCCESS;
334 return StatusCode::SUCCESS;
348 std::vector<const xAOD::Electron *> selected_electrons;
349 std::vector<const xAOD::Muon *> selected_muons;
350 std::vector<const xAOD::Jet *> selected_jets;
355 selected_electrons.push_back(
el);
360 selected_muons.push_back(
mu);
365 selected_jets.push_back(
jet);
368 std::vector<size_t> electron_indices;
369 const std::vector<const xAOD::Electron *> selected_sorted_electrons =
370 sortPt(selected_electrons, electron_indices);
371 std::vector<size_t> muon_indices;
372 const std::vector<const xAOD::Muon *> selected_sorted_muons =
373 sortPt(selected_muons, muon_indices);
374 std::vector<size_t> jet_indices;
375 const std::vector<const xAOD::Jet *> selected_sorted_jets =
376 sortPt(selected_jets, jet_indices);
389 return StatusCode::FAILURE;
393 auto *met_finalTrk = (*met)[
m_METterm.value()];
397 return StatusCode::FAILURE;
399 if (!
m_myFitter->SetET_miss_XY_SumET(met_finalTrk->mpx() / 1.e3,
400 met_finalTrk->mpy() / 1.e3,
401 met_finalTrk->sumet())) {
403 return StatusCode::FAILURE;
411 return StatusCode::SUCCESS;
415 const std::vector<const xAOD::Electron *> &selected_electrons,
416 const std::vector<const xAOD::Muon *> &selected_muons,
424 if (selected_electrons.size() == 0) {
426 "For single-lepton kElectron KLFitter likelihoods, at least one "
427 "electron is required");
428 return StatusCode::FAILURE;
431 el.SetPtEtaPhiE(xaod_el->
pt() / 1.e3, xaod_el->
eta(), xaod_el->
phi(),
432 xaod_el->
e() / 1.e3);
437 if (selected_muons.size() == 0) {
439 "For single-lepton kMuon KLFitter likelihoods, at least one muon is "
441 return StatusCode::FAILURE;
443 const xAOD::Muon *xaod_mu = selected_muons.at(0);
444 mu.SetPtEtaPhiE(xaod_mu->
pt() / 1.e3, xaod_mu->
eta(), xaod_mu->
phi(),
445 xaod_mu->
e() / 1.e3);
449 if (selected_electrons.size() < 3) {
451 "For tri-lepton kTriElectron KLFitter likelihoods, at least 3 "
452 "electrons are required");
453 return StatusCode::FAILURE;
456 for (
size_t i = 0;
i < 3; ++
i) {
458 el.SetPtEtaPhiE(electron->pt() / 1.e3, electron->eta(), electron->phi(),
459 electron->e() / 1.e3);
460 myParticles->AddParticle(&
el, electron->caloCluster()->etaBE(2),
465 if (selected_muons.size() < 3) {
467 "For tr-lepton kTriMuons KLFitter likelihoods, at least 3 muons are "
469 return StatusCode::FAILURE;
472 for (
size_t i = 0;
i < 3; ++
i) {
474 mu.SetPtEtaPhiE(muon->pt() / 1.e3, muon->eta(), muon->phi(),
480 return StatusCode::SUCCESS;
490 return StatusCode::SUCCESS;
494 const std::vector<const xAOD::Jet *> &
jets,
499 if (
jets.size() < njets) {
500 ANA_MSG_ERROR(
"KLFitterTool::setJetskLeadingX: You required "
501 << njets <<
" jets. Event has " <<
jets.size() <<
" jets!");
502 return StatusCode::FAILURE;
509 if (
index > njets - 1)
512 TLorentzVector jet_p4;
513 jet_p4.SetPtEtaPhiE(
jet->pt() / 1.e3,
jet->eta(),
jet->phi(),
516 float eff(0), ineff(0);
519 ANA_MSG_ERROR(
"RunKLFitterAlg::setJetskLeadingX: jet does not have "
521 return StatusCode::FAILURE;
524 const bool isTagged = (*m_bTagDecoAcc)(*jet);
527 KLFitter::LikelihoodBase::BtaggingMethod::kWorkingPoint) {
530 inputParticles->AddParticle(
531 &jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton,
"",
index,
532 isTagged,
eff, 1. / ineff, KLFitter::Particles::kNone);
534 inputParticles->AddParticle(&jet_p4, jet_p4.Eta(),
535 KLFitter::Particles::kParton,
"",
index,
540 return StatusCode::SUCCESS;
544 float *
eff,
float *ineff) {
549 jets.setStore(&jetsAux);
551 jets.push_back(jet_copy);
555 jet_copy->
setAttribute(
"HadronConeExclTruthLabelID", 5);
558 jet_copy->
setAttribute(
"HadronConeExclTruthLabelID", 0);
560 return StatusCode::SUCCESS;
564 const std::vector<const xAOD::Jet *> &
jets,
571 if (
jets.size() < maxJets) {
572 ANA_MSG_ERROR(
"KLFitterTool::setJetskBtagPriority: You required "
573 << maxJets <<
" jets. Event has " <<
jets.size()
575 return StatusCode::FAILURE;
579 unsigned int totalJets(0);
582 unsigned int index(0);
584 if (totalJets >= maxJets)
588 ANA_MSG_ERROR(
"RunKLFitterAlg::setJetskLeadingX: jet does not have "
590 return StatusCode::FAILURE;
594 TLorentzVector jet_p4;
595 jet_p4.SetPtEtaPhiE(
jet->pt() / 1.e3,
jet->eta(),
jet->phi(),
599 KLFitter::LikelihoodBase::BtaggingMethod::kWorkingPoint) {
600 float eff(0), ineff(0);
603 inputParticles->AddParticle(
604 &jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton,
"",
index,
605 true,
eff, 1. / ineff, KLFitter::Particles::kNone);
607 inputParticles->AddParticle(&jet_p4, jet_p4.Eta(),
608 KLFitter::Particles::kParton,
"",
index,
620 if (totalJets >= maxJets)
623 TLorentzVector jet_p4;
624 jet_p4.SetPtEtaPhiE(
jet->pt() / 1.e3,
jet->eta(),
jet->phi(),
628 KLFitter::LikelihoodBase::BtaggingMethod::kWorkingPoint) {
629 float eff(0), ineff(0);
632 inputParticles->AddParticle(
633 &jet_p4, jet_p4.Eta(), KLFitter::Particles::kParton,
"",
index,
634 false,
eff, 1. / ineff, KLFitter::Particles::kNone);
636 inputParticles->AddParticle(&jet_p4, jet_p4.Eta(),
637 KLFitter::Particles::kParton,
"",
index,
645 return StatusCode::SUCCESS;
650 const std::vector<size_t> &muon_indices,
651 const std::vector<size_t> &jet_indices) {
653 auto resultAuxContainer =
654 std::make_unique<xAOD::KLFitterResultAuxContainer>();
655 auto resultContainer = std::make_unique<xAOD::KLFitterResultContainer>();
656 resultContainer->setStore(resultAuxContainer.get());
659 const int nperm =
m_myFitter->Permutations()->NPermutations();
660 for (
int iperm = 0; iperm < nperm; ++iperm) {
665 resultContainer->push_back(
result);
669 std::hash<std::string> hash_string;
670 result->setSelectionCode(hash_string(
sys.name()));
672 unsigned int ConvergenceStatusBitWord =
m_myFitter->ConvergenceStatus();
673 bool MinuitDidNotConverge =
674 (ConvergenceStatusBitWord &
m_myFitter->MinuitDidNotConvergeMask) != 0;
675 bool FitAbortedDueToNaN =
676 (ConvergenceStatusBitWord &
m_myFitter->FitAbortedDueToNaNMask) != 0;
677 bool AtLeastOneFitParameterAtItsLimit =
678 (ConvergenceStatusBitWord &
679 m_myFitter->AtLeastOneFitParameterAtItsLimitMask) != 0;
680 bool InvalidTransferFunctionAtConvergence =
681 (ConvergenceStatusBitWord &
682 m_myFitter->InvalidTransferFunctionAtConvergenceMask) != 0;
684 result->setMinuitDidNotConverge(((MinuitDidNotConverge) ? 1 : 0));
685 result->setFitAbortedDueToNaN(((FitAbortedDueToNaN) ? 1 : 0));
686 result->setAtLeastOneFitParameterAtItsLimit(
687 ((AtLeastOneFitParameterAtItsLimit) ? 1 : 0));
688 result->setInvalidTransferFunctionAtConvergence(
689 ((InvalidTransferFunctionAtConvergence) ? 1 : 0));
692 m_myFitter->Likelihood()->GetBestFitParameters()));
693 result->setEventProbability(
696 result->setParameterErrors(
697 m_myFitter->Likelihood()->GetBestFitParameterErrors());
702 m_myFitter->Likelihood()->PParticlesPermuted();
710 result->setModel_bhad_pt(myModelParticles->Parton(0)->Pt());
711 result->setModel_bhad_eta(myModelParticles->Parton(0)->Eta());
712 result->setModel_bhad_phi(myModelParticles->Parton(0)->Phi());
713 result->setModel_bhad_E(myModelParticles->Parton(0)->E());
714 result->setModel_bhad_jetIndex(
715 jet_indices.at((*myPermutedParticles)->JetIndex(0)));
717 result->setModel_blep_pt(myModelParticles->Parton(1)->Pt());
718 result->setModel_blep_eta(myModelParticles->Parton(1)->Eta());
719 result->setModel_blep_phi(myModelParticles->Parton(1)->Phi());
720 result->setModel_blep_E(myModelParticles->Parton(1)->E());
721 result->setModel_blep_jetIndex(
722 jet_indices.at((*myPermutedParticles)->JetIndex(1)));
724 result->setModel_lq1_pt(myModelParticles->Parton(2)->Pt());
725 result->setModel_lq1_eta(myModelParticles->Parton(2)->Eta());
726 result->setModel_lq1_phi(myModelParticles->Parton(2)->Phi());
727 result->setModel_lq1_E(myModelParticles->Parton(2)->E());
728 result->setModel_lq1_jetIndex(
729 jet_indices.at((*myPermutedParticles)->JetIndex(2)));
733 result->setModel_lq2_pt(myModelParticles->Parton(3)->Pt());
734 result->setModel_lq2_eta(myModelParticles->Parton(3)->Eta());
735 result->setModel_lq2_phi(myModelParticles->Parton(3)->Phi());
736 result->setModel_lq2_E(myModelParticles->Parton(3)->E());
737 result->setModel_lq2_jetIndex(
738 jet_indices.at((*myPermutedParticles)->JetIndex(3)));
741 result->setModel_Higgs_b1_pt(myModelParticles->Parton(4)->Pt());
742 result->setModel_Higgs_b1_eta(myModelParticles->Parton(4)->Eta());
743 result->setModel_Higgs_b1_phi(myModelParticles->Parton(4)->Phi());
744 result->setModel_Higgs_b1_E(myModelParticles->Parton(4)->E());
745 result->setModel_Higgs_b1_jetIndex(
746 jet_indices.at((*myPermutedParticles)->JetIndex(4)));
748 result->setModel_Higgs_b2_pt(myModelParticles->Parton(5)->Pt());
749 result->setModel_Higgs_b2_eta(myModelParticles->Parton(5)->Eta());
750 result->setModel_Higgs_b2_phi(myModelParticles->Parton(5)->Phi());
751 result->setModel_Higgs_b2_E(myModelParticles->Parton(5)->E());
752 result->setModel_Higgs_b2_jetIndex(
753 jet_indices.at((*myPermutedParticles)->JetIndex(5)));
759 result->setModel_lep_pt(myModelParticles->Electron(0)->Pt());
760 result->setModel_lep_eta(myModelParticles->Electron(0)->Eta());
761 result->setModel_lep_phi(myModelParticles->Electron(0)->Phi());
762 result->setModel_lep_E(myModelParticles->Electron(0)->E());
765 result->setModel_lep_index(
766 electron_indices.at((*myPermutedParticles)->ElectronIndex(0)));
768 result->setModel_lepZ1_pt(myModelParticles->Electron(1)->Pt());
769 result->setModel_lepZ1_eta(myModelParticles->Electron(1)->Eta());
770 result->setModel_lepZ1_phi(myModelParticles->Electron(1)->Phi());
771 result->setModel_lepZ1_E(myModelParticles->Electron(1)->E());
772 result->setModel_lepZ1_index(
773 electron_indices.at((*myPermutedParticles)->ElectronIndex(1)));
775 result->setModel_lepZ2_pt(myModelParticles->Electron(2)->Pt());
776 result->setModel_lepZ2_eta(myModelParticles->Electron(2)->Eta());
777 result->setModel_lepZ2_phi(myModelParticles->Electron(2)->Phi());
778 result->setModel_lepZ2_E(myModelParticles->Electron(2)->E());
779 result->setModel_lepZ2_index(
780 electron_indices.at((*myPermutedParticles)->ElectronIndex(2)));
786 result->setModel_lep_pt(myModelParticles->Muon(0)->Pt());
787 result->setModel_lep_eta(myModelParticles->Muon(0)->Eta());
788 result->setModel_lep_phi(myModelParticles->Muon(0)->Phi());
789 result->setModel_lep_E(myModelParticles->Muon(0)->E());
792 result->setModel_lep_index(
793 muon_indices.at((*myPermutedParticles)->MuonIndex(0)));
795 result->setModel_lepZ1_pt(myModelParticles->Muon(1)->Pt());
796 result->setModel_lepZ1_eta(myModelParticles->Muon(1)->Eta());
797 result->setModel_lepZ1_phi(myModelParticles->Muon(1)->Phi());
798 result->setModel_lepZ1_E(myModelParticles->Muon(1)->E());
799 result->setModel_lepZ1_index(
800 muon_indices.at((*myPermutedParticles)->MuonIndex(1)));
802 result->setModel_lepZ2_pt(myModelParticles->Muon(2)->Pt());
803 result->setModel_lepZ2_eta(myModelParticles->Muon(2)->Eta());
804 result->setModel_lepZ2_phi(myModelParticles->Muon(2)->Phi());
805 result->setModel_lepZ2_E(myModelParticles->Muon(2)->E());
806 result->setModel_lepZ2_index(
807 muon_indices.at((*myPermutedParticles)->MuonIndex(2)));
811 result->setModel_nu_pt(myModelParticles->Neutrino(0)->Pt());
812 result->setModel_nu_eta(myModelParticles->Neutrino(0)->Eta());
813 result->setModel_nu_phi(myModelParticles->Neutrino(0)->Phi());
814 result->setModel_nu_E(myModelParticles->Neutrino(0)->E());
816 result->setModel_b_from_top1_pt(myModelParticles->Parton(0)->Pt());
817 result->setModel_b_from_top1_eta(myModelParticles->Parton(0)->Eta());
818 result->setModel_b_from_top1_phi(myModelParticles->Parton(0)->Phi());
819 result->setModel_b_from_top1_E(myModelParticles->Parton(0)->E());
820 result->setModel_b_from_top1_jetIndex(
821 jet_indices.at((*myPermutedParticles)->JetIndex(0)));
823 result->setModel_b_from_top2_pt(myModelParticles->Parton(1)->Pt());
824 result->setModel_b_from_top2_eta(myModelParticles->Parton(1)->Eta());
825 result->setModel_b_from_top2_phi(myModelParticles->Parton(1)->Phi());
826 result->setModel_b_from_top2_E(myModelParticles->Parton(1)->E());
827 result->setModel_b_from_top2_jetIndex(
828 jet_indices.at((*myPermutedParticles)->JetIndex(1)));
830 result->setModel_lj1_from_top1_pt(myModelParticles->Parton(2)->Pt());
831 result->setModel_lj1_from_top1_eta(myModelParticles->Parton(2)->Eta());
832 result->setModel_lj1_from_top1_phi(myModelParticles->Parton(2)->Phi());
833 result->setModel_lj1_from_top1_E(myModelParticles->Parton(2)->E());
834 result->setModel_lj1_from_top1_jetIndex(
835 jet_indices.at((*myPermutedParticles)->JetIndex(2)));
837 result->setModel_lj2_from_top1_pt(myModelParticles->Parton(3)->Pt());
838 result->setModel_lj2_from_top1_eta(myModelParticles->Parton(3)->Eta());
839 result->setModel_lj2_from_top1_phi(myModelParticles->Parton(3)->Phi());
840 result->setModel_lj2_from_top1_E(myModelParticles->Parton(3)->E());
841 result->setModel_lj2_from_top1_jetIndex(
842 jet_indices.at((*myPermutedParticles)->JetIndex(3)));
844 result->setModel_lj1_from_top2_pt(myModelParticles->Parton(4)->Pt());
845 result->setModel_lj1_from_top2_eta(myModelParticles->Parton(4)->Eta());
846 result->setModel_lj1_from_top2_phi(myModelParticles->Parton(4)->Phi());
847 result->setModel_lj1_from_top2_E(myModelParticles->Parton(4)->E());
848 result->setModel_lj1_from_top2_jetIndex(
849 jet_indices.at((*myPermutedParticles)->JetIndex(4)));
851 result->setModel_lj2_from_top2_pt(myModelParticles->Parton(5)->Pt());
852 result->setModel_lj2_from_top2_eta(myModelParticles->Parton(5)->Eta());
853 result->setModel_lj2_from_top2_phi(myModelParticles->Parton(5)->Phi());
854 result->setModel_lj2_from_top2_E(myModelParticles->Parton(5)->E());
855 result->setModel_lj2_from_top2_jetIndex(
856 jet_indices.at((*myPermutedParticles)->JetIndex(5)));
862 float sumEventProbability(0.), bestEventProbability(0.);
866 for (
auto x : *resultContainer) {
867 float prob =
x->eventProbability();
869 short fitAbortedDueToNaN =
x->fitAbortedDueToNaN();
871 x->atLeastOneFitParameterAtItsLimit();
872 short invalidTransferFunctionAtConvergence =
873 x->invalidTransferFunctionAtConvergence();
874 sumEventProbability +=
prob;
880 if (fitAbortedDueToNaN)
884 if (invalidTransferFunctionAtConvergence)
887 if (
prob > bestEventProbability) {
888 bestEventProbability =
prob;
896 for (
auto x : *resultContainer) {
897 x->setEventProbability(
x->eventProbability() / sumEventProbability);
899 x->setBestPermutation(1);
901 x->setBestPermutation(0);
909 std::move(resultAuxContainer),
sys));
912 auto bestContainer = std::make_unique<xAOD::KLFitterResultContainer>();
913 auto bestAuxContainer =
914 std::make_unique<xAOD::KLFitterResultAuxContainer>();
915 bestContainer->setStore(bestAuxContainer.get());
917 for (
auto x : *resultContainer) {
918 if (
x->bestPermutation() == 1) {
921 bestContainer->push_back(
result);
925 std::move(bestAuxContainer),
sys));
928 return StatusCode::SUCCESS;