578 const std::vector<size_t> &electron_indices,
579 const std::vector<size_t> &muon_indices,
580 const std::vector<size_t> &jet_indices) {
582 auto resultAuxContainer =
583 std::make_unique<xAOD::KLFitterResultAuxContainer>();
584 auto resultContainer = std::make_unique<xAOD::KLFitterResultContainer>();
585 resultContainer->setStore(resultAuxContainer.get());
589 const size_t selectionCode = std::hash<std::string>{}(sys.name());
592 const int nperm =
m_myFitter->Permutations()->NPermutations();
593 for (
int iperm = 0; iperm < nperm; ++iperm) {
598 resultContainer->push_back(std::make_unique<xAOD::KLFitterResult>());
600 result->setSelectionCode(selectionCode);
602 unsigned int ConvergenceStatusBitWord =
m_myFitter->ConvergenceStatus();
603 bool MinuitDidNotConverge =
604 (ConvergenceStatusBitWord &
m_myFitter->MinuitDidNotConvergeMask) != 0;
605 bool FitAbortedDueToNaN =
606 (ConvergenceStatusBitWord &
m_myFitter->FitAbortedDueToNaNMask) != 0;
607 bool AtLeastOneFitParameterAtItsLimit =
608 (ConvergenceStatusBitWord &
609 m_myFitter->AtLeastOneFitParameterAtItsLimitMask) != 0;
610 bool InvalidTransferFunctionAtConvergence =
611 (ConvergenceStatusBitWord &
612 m_myFitter->InvalidTransferFunctionAtConvergenceMask) != 0;
614 result->setMinuitDidNotConverge(((MinuitDidNotConverge) ? 1 : 0));
615 result->setFitAbortedDueToNaN(((FitAbortedDueToNaN) ? 1 : 0));
616 result->setAtLeastOneFitParameterAtItsLimit(
617 ((AtLeastOneFitParameterAtItsLimit) ? 1 : 0));
618 result->setInvalidTransferFunctionAtConvergence(
619 ((InvalidTransferFunctionAtConvergence) ? 1 : 0));
621 result->setLogLikelihood(
m_myFitter->Likelihood()->LogLikelihood(
622 m_myFitter->Likelihood()->GetBestFitParameters()));
623 result->setEventProbability(
624 std::exp(
m_myFitter->Likelihood()->LogEventProbability()));
625 result->setParameters(
m_myFitter->Likelihood()->GetBestFitParameters());
626 result->setParameterErrors(
627 m_myFitter->Likelihood()->GetBestFitParameterErrors());
629 KLFitter::Particles *myModelParticles =
631 KLFitter::Particles **myPermutedParticles =
632 m_myFitter->Likelihood()->PParticlesPermuted();
640 result->setModel_bhad_pt(myModelParticles->Parton(0)->Pt());
641 result->setModel_bhad_eta(myModelParticles->Parton(0)->Eta());
642 result->setModel_bhad_phi(myModelParticles->Parton(0)->Phi());
643 result->setModel_bhad_E(myModelParticles->Parton(0)->E());
644 result->setModel_bhad_jetIndex(
645 jet_indices.at((*myPermutedParticles)->JetIndex(0)));
647 result->setModel_blep_pt(myModelParticles->Parton(1)->Pt());
648 result->setModel_blep_eta(myModelParticles->Parton(1)->Eta());
649 result->setModel_blep_phi(myModelParticles->Parton(1)->Phi());
650 result->setModel_blep_E(myModelParticles->Parton(1)->E());
651 result->setModel_blep_jetIndex(
652 jet_indices.at((*myPermutedParticles)->JetIndex(1)));
654 result->setModel_lq1_pt(myModelParticles->Parton(2)->Pt());
655 result->setModel_lq1_eta(myModelParticles->Parton(2)->Eta());
656 result->setModel_lq1_phi(myModelParticles->Parton(2)->Phi());
657 result->setModel_lq1_E(myModelParticles->Parton(2)->E());
658 result->setModel_lq1_jetIndex(
659 jet_indices.at((*myPermutedParticles)->JetIndex(2)));
663 result->setModel_lq2_pt(myModelParticles->Parton(3)->Pt());
664 result->setModel_lq2_eta(myModelParticles->Parton(3)->Eta());
665 result->setModel_lq2_phi(myModelParticles->Parton(3)->Phi());
666 result->setModel_lq2_E(myModelParticles->Parton(3)->E());
667 result->setModel_lq2_jetIndex(
668 jet_indices.at((*myPermutedParticles)->JetIndex(3)));
671 result->setModel_Higgs_b1_pt(myModelParticles->Parton(4)->Pt());
672 result->setModel_Higgs_b1_eta(myModelParticles->Parton(4)->Eta());
673 result->setModel_Higgs_b1_phi(myModelParticles->Parton(4)->Phi());
674 result->setModel_Higgs_b1_E(myModelParticles->Parton(4)->E());
675 result->setModel_Higgs_b1_jetIndex(
676 jet_indices.at((*myPermutedParticles)->JetIndex(4)));
678 result->setModel_Higgs_b2_pt(myModelParticles->Parton(5)->Pt());
679 result->setModel_Higgs_b2_eta(myModelParticles->Parton(5)->Eta());
680 result->setModel_Higgs_b2_phi(myModelParticles->Parton(5)->Phi());
681 result->setModel_Higgs_b2_E(myModelParticles->Parton(5)->E());
682 result->setModel_Higgs_b2_jetIndex(
683 jet_indices.at((*myPermutedParticles)->JetIndex(5)));
689 result->setModel_lep_pt(myModelParticles->Electron(0)->Pt());
690 result->setModel_lep_eta(myModelParticles->Electron(0)->Eta());
691 result->setModel_lep_phi(myModelParticles->Electron(0)->Phi());
692 result->setModel_lep_E(myModelParticles->Electron(0)->E());
695 result->setModel_lep_index(
696 electron_indices.at((*myPermutedParticles)->ElectronIndex(0)));
698 result->setModel_lepZ1_pt(myModelParticles->Electron(1)->Pt());
699 result->setModel_lepZ1_eta(myModelParticles->Electron(1)->Eta());
700 result->setModel_lepZ1_phi(myModelParticles->Electron(1)->Phi());
701 result->setModel_lepZ1_E(myModelParticles->Electron(1)->E());
702 result->setModel_lepZ1_index(
703 electron_indices.at((*myPermutedParticles)->ElectronIndex(1)));
705 result->setModel_lepZ2_pt(myModelParticles->Electron(2)->Pt());
706 result->setModel_lepZ2_eta(myModelParticles->Electron(2)->Eta());
707 result->setModel_lepZ2_phi(myModelParticles->Electron(2)->Phi());
708 result->setModel_lepZ2_E(myModelParticles->Electron(2)->E());
709 result->setModel_lepZ2_index(
710 electron_indices.at((*myPermutedParticles)->ElectronIndex(2)));
716 result->setModel_lep_pt(myModelParticles->Muon(0)->Pt());
717 result->setModel_lep_eta(myModelParticles->Muon(0)->Eta());
718 result->setModel_lep_phi(myModelParticles->Muon(0)->Phi());
719 result->setModel_lep_E(myModelParticles->Muon(0)->E());
722 result->setModel_lep_index(
723 muon_indices.at((*myPermutedParticles)->MuonIndex(0)));
725 result->setModel_lepZ1_pt(myModelParticles->Muon(1)->Pt());
726 result->setModel_lepZ1_eta(myModelParticles->Muon(1)->Eta());
727 result->setModel_lepZ1_phi(myModelParticles->Muon(1)->Phi());
728 result->setModel_lepZ1_E(myModelParticles->Muon(1)->E());
729 result->setModel_lepZ1_index(
730 muon_indices.at((*myPermutedParticles)->MuonIndex(1)));
732 result->setModel_lepZ2_pt(myModelParticles->Muon(2)->Pt());
733 result->setModel_lepZ2_eta(myModelParticles->Muon(2)->Eta());
734 result->setModel_lepZ2_phi(myModelParticles->Muon(2)->Phi());
735 result->setModel_lepZ2_E(myModelParticles->Muon(2)->E());
736 result->setModel_lepZ2_index(
737 muon_indices.at((*myPermutedParticles)->MuonIndex(2)));
741 result->setModel_nu_pt(myModelParticles->Neutrino(0)->Pt());
742 result->setModel_nu_eta(myModelParticles->Neutrino(0)->Eta());
743 result->setModel_nu_phi(myModelParticles->Neutrino(0)->Phi());
744 result->setModel_nu_E(myModelParticles->Neutrino(0)->E());
746 result->setModel_b_from_top1_pt(myModelParticles->Parton(0)->Pt());
747 result->setModel_b_from_top1_eta(myModelParticles->Parton(0)->Eta());
748 result->setModel_b_from_top1_phi(myModelParticles->Parton(0)->Phi());
749 result->setModel_b_from_top1_E(myModelParticles->Parton(0)->E());
750 result->setModel_b_from_top1_jetIndex(
751 jet_indices.at((*myPermutedParticles)->JetIndex(0)));
753 result->setModel_b_from_top2_pt(myModelParticles->Parton(1)->Pt());
754 result->setModel_b_from_top2_eta(myModelParticles->Parton(1)->Eta());
755 result->setModel_b_from_top2_phi(myModelParticles->Parton(1)->Phi());
756 result->setModel_b_from_top2_E(myModelParticles->Parton(1)->E());
757 result->setModel_b_from_top2_jetIndex(
758 jet_indices.at((*myPermutedParticles)->JetIndex(1)));
760 result->setModel_lj1_from_top1_pt(myModelParticles->Parton(2)->Pt());
761 result->setModel_lj1_from_top1_eta(myModelParticles->Parton(2)->Eta());
762 result->setModel_lj1_from_top1_phi(myModelParticles->Parton(2)->Phi());
763 result->setModel_lj1_from_top1_E(myModelParticles->Parton(2)->E());
764 result->setModel_lj1_from_top1_jetIndex(
765 jet_indices.at((*myPermutedParticles)->JetIndex(2)));
767 result->setModel_lj2_from_top1_pt(myModelParticles->Parton(3)->Pt());
768 result->setModel_lj2_from_top1_eta(myModelParticles->Parton(3)->Eta());
769 result->setModel_lj2_from_top1_phi(myModelParticles->Parton(3)->Phi());
770 result->setModel_lj2_from_top1_E(myModelParticles->Parton(3)->E());
771 result->setModel_lj2_from_top1_jetIndex(
772 jet_indices.at((*myPermutedParticles)->JetIndex(3)));
774 result->setModel_lj1_from_top2_pt(myModelParticles->Parton(4)->Pt());
775 result->setModel_lj1_from_top2_eta(myModelParticles->Parton(4)->Eta());
776 result->setModel_lj1_from_top2_phi(myModelParticles->Parton(4)->Phi());
777 result->setModel_lj1_from_top2_E(myModelParticles->Parton(4)->E());
778 result->setModel_lj1_from_top2_jetIndex(
779 jet_indices.at((*myPermutedParticles)->JetIndex(4)));
781 result->setModel_lj2_from_top2_pt(myModelParticles->Parton(5)->Pt());
782 result->setModel_lj2_from_top2_eta(myModelParticles->Parton(5)->Eta());
783 result->setModel_lj2_from_top2_phi(myModelParticles->Parton(5)->Phi());
784 result->setModel_lj2_from_top2_E(myModelParticles->Parton(5)->E());
785 result->setModel_lj2_from_top2_jetIndex(
786 jet_indices.at((*myPermutedParticles)->JetIndex(5)));
792 float sumEventProbability(0.), bestEventProbability(0.);
793 std::optional<size_t> bestPermutation;
797 for (
auto x : *resultContainer) {
798 float prob =
x->eventProbability();
799 short minuitDidNotConverge =
x->minuitDidNotConverge();
800 short fitAbortedDueToNaN =
x->fitAbortedDueToNaN();
801 short atLeastOneFitParameterAtItsLimit =
802 x->atLeastOneFitParameterAtItsLimit();
803 short invalidTransferFunctionAtConvergence =
804 x->invalidTransferFunctionAtConvergence();
805 sumEventProbability += prob;
809 if (minuitDidNotConverge)
811 if (fitAbortedDueToNaN)
813 if (atLeastOneFitParameterAtItsLimit)
815 if (invalidTransferFunctionAtConvergence)
818 if (prob > bestEventProbability) {
819 bestEventProbability = prob;
821 bestPermutation = iPerm - 1;
825 if (!bestPermutation) {
826 ANA_MSG_DEBUG(
"No KLFitter permutation passed the convergence criteria");
828 if (!resultContainer->empty() && sumEventProbability == 0.) {
830 "Sum of KLFitter event probabilities is zero, event probabilities are "
836 for (
auto x : *resultContainer) {
837 if (sumEventProbability != 0.)
838 x->setEventProbability(
x->eventProbability() / sumEventProbability);
839 if (bestPermutation && iPerm == *bestPermutation) {
840 x->setBestPermutation(1);
842 x->setBestPermutation(0);
850 std::move(resultAuxContainer), sys, ctx));
853 auto bestContainer = std::make_unique<xAOD::KLFitterResultContainer>();
854 auto bestAuxContainer =
855 std::make_unique<xAOD::KLFitterResultAuxContainer>();
856 bestContainer->setStore(bestAuxContainer.get());
858 for (
auto x : *resultContainer) {
859 if (
x->bestPermutation() == 1) {
860 auto result = std::make_unique<xAOD::KLFitterResult>();
861 result->makePrivateStore(*
x);
862 bestContainer->push_back(std::move(result));
866 std::move(bestAuxContainer), sys, ctx));
869 return StatusCode::SUCCESS;