590 {
591 if(!metJet || !jets) {
593 << "MET (" << metJet << ") or "
594 << "jet collection (" << jets << ").");
595 return StatusCode::FAILURE;
596 }
598 if(!map){
599 ATH_MSG_ERROR(
"MET Association Helper isn't associated with a MissingETAssociationMap!");
600 return StatusCode::FAILURE;
601 }
603 ATH_MSG_WARNING(
"Requested soft track element links, but no track selection tool supplied.");
604 }
606
608 ATH_MSG_WARNING(
"Incomplete association map received. Cannot rebuild MET.");
609 ATH_MSG_WARNING(
"Note: METMaker should only be run on events containing at least one PV");
610 return StatusCode::SUCCESS;
611 }
612
613 if(doJetJVT &&
m_JvtWP ==
"None"){
615 doJetJVT = false;
616 }
617
619 if(!metSoftClus && !metSoftTrk) {
620 ATH_MSG_WARNING(
"Neither soft cluster nor soft track term has been supplied!");
621 return StatusCode::SUCCESS;
622 }
623 static const SG::AuxElement::ConstAccessor<std::vector<ElementLink<IParticleContainer> > > acc_softConst("softConstituents");
624 if(metSoftClus) {
626 if(!coreSoftClus) {
627 ATH_MSG_ERROR(
"Soft cluster term provided without a core term!");
628 return StatusCode::FAILURE;
629 }
632 <<
", mpy " << coreSoftClus->
mpy()
633 <<
" sumet " << coreSoftClus->
sumet());
634 *metSoftClus += *coreSoftClus;
635
636
637
638 if(softConst && acc_softConst.isAvailable(*coreSoftClus)) {
639 for(const auto& constit : acc_softConst(*coreSoftClus)) {
640 softConst->push_back(*constit);
641 }
642 ATH_MSG_DEBUG(softConst->size() <<
" soft constituents from core term");
643 }
644 }
645 if(metSoftTrk) {
647 if(!coreSoftTrk) {
648 ATH_MSG_ERROR(
"Soft track term provided without a core term!");
649 return StatusCode::FAILURE;
650 }
653 <<
", mpy " << coreSoftTrk->
mpy()
654 <<
" sumet " << coreSoftTrk->
sumet());
655 *metSoftTrk += *coreSoftTrk;
657 for(const auto& constit : acc_softConst(*coreSoftTrk)) {
658 softConst->push_back(*constit);
659 }
660 ATH_MSG_DEBUG(softConst->size() <<
" soft constituents from trk core term");
661 }
662 }
663
668 uniqueLinks.reserve(
jets->size());
669 uniqueWeights.reserve(
jets->size());
670 std::vector<iplink_t> softJetLinks;
671 std::vector<float> softJetWeights;
673
674
675
676
677
678
679
683 if(jetsSgKey == 0) {
684 ATH_MSG_ERROR(
"Could not find the jets with pointer: " << jets);
685 return StatusCode::FAILURE;
686 }
687 }
688
691 if(originalInputs) {
693 } else {
696 }
697 if(!assoc || assoc->isMisc()){
699 continue;
700 }
701
703
707
708 }
709 else
710 ATH_MSG_ERROR(
"No nominal calibrated jet available for jet " << jet->index() <<
". Cannot simplify overlap removal!");
711 }
713
715 bool JVT_reject(false);
716 bool isMuFSRJet(false);
717
718
720 JVT_reject = true;
721
722 if(doJetJVT) {
723
725 ATH_MSG_VERBOSE(
"Jet " << (JVT_reject ?
"fails" :
"passes") <<
" JVT selection");
726 }
727
728
730 bool hardJet(false);
732 bool caloverlap = false;
733 caloverlap = calvec.
ce()>0;
734 ATH_MSG_DEBUG(
"Jet " << jet->index() <<
" is " << ( caloverlap ?
"" :
"non-") <<
"overlapping");
735
737 for(const auto& object : assoc->objects()) {
738
740 }
741 }
742
744 double constSF(1);
746 constjet = assoc->getAlternateConstVec();
747 } else {
749 double denom = (assoc->hasAlternateConstVec() ? assoc->getAlternateConstVec() : jet->jetP4(
"JetConstitScaleMomentum")).E();
752 calvec *= constSF;
753 }
754 double jpx = constjet.Px();
755 double jpy = constjet.Py();
756 double jpt = constjet.Pt();
757 double opx = jpx - calvec.
cpx();
758 double opy = jpy - calvec.
cpy();
759
762
764 met_muonEloss = (*metCont)["MuonEloss"];
765 if(!met_muonEloss) {
766 ATH_MSG_WARNING(
"Attempted to apply muon Eloss correction, but corresponding MET term does not exist!");
767 return StatusCode::FAILURE;
768 }
769 }
770
771 float total_eloss(0);
773 std::vector<const xAOD::Muon*> muons_in_jet;
774 std::vector<const xAOD::Electron*> electrons_in_jet;
775 bool passJetForEl=false;
779 return StatusCode::FAILURE;
780 }
783 ATH_MSG_ERROR(
"Invalid element link to ghost muon! Quitting.");
784 return StatusCode::FAILURE;
785 }
786 muons_in_jet.push_back(
static_cast<const xAOD::Muon*
>(*el));
787 }
788 }
789 for(const auto& obj : assoc->objects()) {
790 if(!obj) continue;
793 ATH_MSG_VERBOSE(
"Muon " << mu_test->index() <<
" found in jet " << jet->index());
797 muons_in_jet.push_back(mu_test);
799 }
800 }
803 ATH_MSG_VERBOSE(
"Electron " << el_test->index() <<
" found in jet " << jet->index());
805 if(
helper.objSelected(assoc,el_test)){
806 if(el_test->pt()>90.0e3) {
807 electrons_in_jet.push_back(el_test);
809 }
810 }
811 }
812 }
815 float jet_ORtrk_sumpt = assoc->overlapTrkVec(helper).
sumpt();
816 float jet_all_trk_pt = initialTrkMom.
sumpt();
817 float jet_unique_trk_pt = jet_all_trk_pt - jet_ORtrk_sumpt;
820 for(const auto& elec : electrons_in_jet) {
821 el_calvec += assoc->calVec(elec);
822 el_trkvec += assoc->trkVec(elec);
823 }
824 float el_cal_pt = el_calvec.
cpt();
825 float el_trk_pt = el_trkvec.
cpt();
827 << " jetalltrk: " << jet_all_trk_pt
828 << " jetORtrk: " << jet_ORtrk_sumpt
829 << " electrk-jetORtrk: " << (el_trk_pt-jet_ORtrk_sumpt)
830 << " elec cal: " << el_cal_pt
831 << " jetalltrk-electrk: " << (jet_all_trk_pt-el_trk_pt)
832 << " jetalltrk-jetORtrk: " << (jet_all_trk_pt-jet_ORtrk_sumpt) );
833
834
835
836 if(el_trk_pt>1
e-9 && jet_unique_trk_pt>10.0e3) passJetForEl=
true;
837 }
838
839 for(
const xAOD::Muon* mu_in_jet : muons_in_jet) {
840 if (!mu_in_jet) continue;
842
843 if(!JVT_reject) {
845
846 float mu_id_pt = mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) ? mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle)->pt() : 0.;
848
849
850 if(0.9999*mu_id_pt>jet_trk_sumpt)
851 jet_trk_sumpt+=mu_id_pt;
854 ATH_MSG_VERBOSE(
"Jet has pt " << jet->pt() <<
", trk sumpt " << jet_trk_sumpt <<
", trk N " << jet_trk_N);
855 bool jet_from_muon = mu_id_pt>1
e-9 && jet_trk_sumpt>1
e-9 && (jet->pt()/mu_id_pt < m_muIDPTJetPtRatioMuOlap && mu_id_pt/jet_trk_sumpt>
m_jetTrkPtMuPt) && jet_trk_N<
m_jetTrkNMuOlap;
856 if(jet_from_muon) {
858 JVT_reject = true;
859 }
860 }
861
863
864 float mu_id_pt = mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) ? mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle)->pt() : 0.;
866
867 if(0.9999*mu_id_pt>jet_trk_sumpt)
868 jet_trk_sumpt+=mu_id_pt;
870
871 float jet_psE = 0.;
872 if (
acc_psf.isAvailable(*jet)){
876 } else {
877 ATH_MSG_ERROR(
"Jet PS fraction or sampling energy must be available to calculate MET with doSetMuonJetEMScale");
878 return StatusCode::FAILURE;
879 }
880
883 ATH_MSG_VERBOSE(
"Jet has trk sumpt " << jet_trk_sumpt <<
", trk N " << jet_trk_N <<
", PS E " << jet_psE <<
", width " <<
acc_width(*jet) <<
", emfrac " <<
acc_emf(*jet));
884
885 if(jet_from_muon) {
886 ATH_MSG_VERBOSE(
"Jet is from muon -- set to EM scale and subtract Eloss.");
887
888
889 ATH_MSG_VERBOSE(
"Jet e: " << constjet.E() <<
", mu Eloss: " << mu_Eloss);
890 float elosscorr = mu_Eloss >= constjet.e() ? 0. : 1.-mu_Eloss/constjet.e();
891
892
893 opx *= elosscorr;
894 opy *= elosscorr;
895 ATH_MSG_VERBOSE(
" Jet eloss factor " << elosscorr <<
", final pt: " << sqrt(opx*opx+opy*opy));
896
897 isMuFSRJet = true;
898 }
899 }
900 }
901
902 switch(mu_in_jet->energyLossType()) {
903 using enum xAOD::Muon::EnergyLossType;
904 case Parametrized:
905 case MOP:
906 case Tail:
907 case FSRcandidate:
908 case NotIsolated:
909
910
911
912 total_eloss += mu_Eloss;
913 muons_selflags |= (1<<assoc->findIndex(mu_in_jet));
914 }
915 }
918
920
921 for(size_t iKey = 0; iKey < assoc->sizeCal(); iKey++) {
922 bool selector = (muons_selflags & assoc->calkey()[iKey]);
923 if(selector) mu_calovec += assoc->calVec(iKey);
924 ATH_MSG_VERBOSE(
"This key: " << assoc->calkey()[iKey] <<
", selector: " << selector);
925 }
927 if(
m_muEloss) mu_calovec *= std::max<float>(0.,1-(total_eloss/mu_calovec.
ce()));
929
930
931 ATH_MSG_VERBOSE(
"Jet " << jet->index() <<
" const pT before OR " << jpt);
932 ATH_MSG_VERBOSE(
"Jet " << jet->index() <<
" const pT after OR " << sqrt(opx*opx+opy*opy));
933 opx += mu_calovec.
cpx();
934 opy += mu_calovec.
cpy();
935 double opt = sqrt( opx*opx+opy*opy );
936 ATH_MSG_VERBOSE(
"Jet " << jet->index() <<
" const pT diff after OR readding muon clusters " << opt-jpt);
937 double uniquefrac = 1. - (calvec.
ce() - mu_calovec.
ce()) / constjet.E();
938 ATH_MSG_VERBOSE(
"Jet constscale px, py, pt, E = " << jpx <<
", " << jpy <<
", " << jpt <<
", " << constjet.E() );
940 ATH_MSG_VERBOSE(
"Jet OR px, py, pt, E = " << opx <<
", " << opy <<
", " << opt <<
", " << constjet.E() - calvec.
ce() );
941
942 if(isMuFSRJet) {
943 if(!met_muonEloss){
944 ATH_MSG_ERROR(
"Attempted to apply muon Eloss correction, but corresponding MET term does not exist!");
945 return StatusCode::FAILURE;
946 }
947 met_muonEloss->add(opx,opy,opt);
948 continue;
949 }
950
951 if(selected && !JVT_reject) {
952 if(!caloverlap) {
953
954 hardJet = true;
955 if (!tracksForHardJets) {
957 metJet->
add(jpx,jpy,jpt);
958 else
959 *metJet += jet;
960 }
961 }
963
964 hardJet = true;
965 if(!tracksForHardJets) {
968 metJet->
add(opx,opy,opt);
969 else {
970 double jesF = jet->pt() / jpt;
971 metJet->
add(opx*jesF,opy*jesF,opt*jesF);
972 }
973 } else {
975 metJet->
add(uniquefrac*jpx,uniquefrac*jpy,uniquefrac*jpt);
976 else{
978 metJet->
add(opx,opy,opt);
979 else
980 metJet->
add(uniquefrac*jet->px(),uniquefrac*jet->py(),uniquefrac*jet->pt());
981 }
982 }
983 }
984 }
985 }
986
987
989 if(jetsSgKey == 0) {
992 jetLink =
iplink_t(*ipc, jet->index());
993 } else {
994 jetLink =
iplink_t(jetsSgKey, jet->index());
995 }
996
997 if(hardJet){
999 uniqueLinks.push_back( jetLink );
1000 uniqueWeights.push_back( uniquefrac );
1001 } else {
1002 if(metSoftClus && !JVT_reject) {
1003
1006 softJetLinks.push_back( jetLink );
1007 softJetWeights.push_back( uniquefrac );
1008 metSoftClus->
add(opx,opy,opt);
1009 }
1010
1011
1012
1013
1014
1015
1016 if(softConst) {
1017 for(size_t iConst=0; iConst<jet->numConstituents(); ++iConst) {
1018 const IParticle* constit = jet->rawConstituent(iConst);
1019 softConst->push_back(constit);
1020 }
1021 }
1022 }
1023 }
1024
1025 if(!metSoftTrk || (hardJet && !tracksForHardJets)) continue;
1026
1027
1028
1031 if(jettrkvec.
ce()>1
e-9) {
1032 jpx = jettrkvec.
cpx();
1033 jpy = jettrkvec.
cpy();
1034 jpt = jettrkvec.
sumpt();
1035 jettrkvec -= trkvec;
1036 opx = jettrkvec.
cpx();
1037 opy = jettrkvec.
cpy();
1039 ATH_MSG_VERBOSE(
"Jet track px, py, sumpt = " << jpx <<
", " << jpy <<
", " << jpt );
1040 ATH_MSG_VERBOSE(
"Jet OR px, py, sumpt = " << opx <<
", " << opy <<
", " << opt );
1041 } else {
1042 opx = opy =
opt = 0;
1044 }
1045 if (hardJet) metJet->
add(opx,opy,opt);
1047 metSoftTrk->
add(opx,opy,opt);
1048
1049 if(!metSoftClus) {
1050 softJetLinks.push_back( jetLink );
1051 softJetWeights.push_back( uniquefrac );
1052 }
1053
1054
1055
1056
1057
1058
1060 std::vector<const IParticle*> jettracks;
1062 for(size_t iConst=0; iConst<jettracks.size(); ++iConst) {
1064 if (
acceptTrack(pTrk,pv)) softConst->push_back(pTrk);
1065 }
1066 }
1067 }
1068 }
1069
1071
1072 if(metSoftTrk) {
1075 }
1076
1077 if(metSoftClus) {
1080 }
1081
1082 if(softConst)
ATH_MSG_DEBUG(softConst->size() <<
" soft constituents from core term + jets");
1083
1085 if(!assoc) return StatusCode::SUCCESS;
1086
1087 if(metSoftTrk) {
1088
1089
1091 double opx = trkvec.
cpx();
1092 double opy = trkvec.
cpy();
1093 double osumpt = trkvec.
sumpt();
1094 ATH_MSG_VERBOSE(
"Misc track px, py, sumpt = " << opx <<
", " << opy <<
", " << osumpt );
1095 metSoftTrk->
add(opx,opy,osumpt);
1097 <<
", mpy " << metSoftTrk->
mpy()
1098 <<
" sumet " << metSoftTrk->
sumet());
1099 }
1100
1101 if(metSoftClus) {
1102
1103
1104 float total_eloss(0.);
1107 double opx = calvec.
cpx();
1108 double opy = calvec.
cpy();
1109 double osumpt = calvec.
sumpt();
1110 for(const auto& obj : assoc->objects()) {
1116 switch(mu_test->energyLossType()) {
1117 using enum xAOD::Muon::EnergyLossType;
1118 case Parametrized:
1119 case MOP:
1120 case Tail:
1121 case FSRcandidate:
1122 case NotIsolated:
1123
1124
1125
1126 total_eloss += mu_Eloss;
1127 muons_selflags |= (1<<assoc->findIndex(mu_test));
1128 }
1130 }
1131 }
1134
1136
1137 for(size_t iKey = 0; iKey < assoc->sizeCal(); iKey++) {
1138 bool selector = (muons_selflags & assoc->calkey()[iKey]);
1139 ATH_MSG_VERBOSE(
"This key: " << assoc->calkey()[iKey] <<
", selector: " << selector
1140 << " this calvec E: " << assoc->calVec(iKey).ce());
1141 if(selector) mu_calovec += assoc->calVec(iKey);
1142 }
1144 mu_calovec *= std::max<float>(0.,1-(total_eloss/mu_calovec.
ce()));
1145 opx += mu_calovec.
cpx();
1146 opy += mu_calovec.
cpy();
1147 osumpt += mu_calovec.
sumpt();
1148 }
1150
1151 ATH_MSG_VERBOSE(
"Misc cluster px, py, sumpt = " << opx <<
", " << opy <<
", " << osumpt );
1152 metSoftClus->
add(opx,opy,osumpt);
1154 <<
", mpy " << metSoftClus->
mpy()
1155 <<
" sumet " << metSoftClus->
sumet());
1156 }
1157
1158 return StatusCode::SUCCESS;
1159 }
bool empty() const noexcept
Returns true if the collection is empty.
bool acceptTrack(const xAOD::TrackParticle *trk, const xAOD::Vertex *vx) const
const xAOD::Vertex * getPV() const
const MissingETAssociation_v1 * getMiscAssociation() const
Get an association for miscellaneous objects not associated to jets.
float ce() const
Returns .
float sumpt() const
Returns sum of component pt.
float cpt() const
Returns .
float cpx() const
Returns .
float cpy() const
Returns .
float sumet() const
Returns.
void add(const IParticle *particle)
Add particle kinematics to MET.
MissingETBase::Types::bitmask_t source() const
MET object source tag.
const std::string & name() const
Identifier getters.
float mpx() const
Returns .
float mpy() const
Returns .
xAOD::MissingETAssociation_v1::ConstVec constvec_t
Type for constituent vector.
uint64_t bitmask_t
Type for status word bit mask.
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
@ OWN_ELEMENTS
this data object owns its elements
ElementLink< xAOD::IParticleContainer > iplink_t
static const SG::AuxElement::ConstAccessor< float > acc_emf("EMFrac")
static const SG::AuxElement::Accessor< std::vector< float > > dec_constitObjWeights("ConstitObjectWeights")
static const SG::AuxElement::ConstAccessor< float > acc_Eloss("EnergyLoss")
static const SG::AuxElement::ConstAccessor< float > acc_width("Width")
static const SG::AuxElement::ConstAccessor< iplink_t > acc_nominalObject("nominalObjectLink")
static const SG::AuxElement::Accessor< std::vector< iplink_t > > dec_constitObjLinks("ConstitObjectLinks")
static const SG::AuxElement::ConstAccessor< float > acc_psf("PSFrac")
static const SG::AuxElement::ConstAccessor< std::vector< int > > acc_trkN("NumTrkPt500")
static const SG::AuxElement::ConstAccessor< std::vector< float > > acc_sampleE("EnergyPerSampling")
static const SG::AuxElement::ConstAccessor< iplink_t > acc_originalObject("originalObjectLink")
static const SG::AuxElement::ConstAccessor< std::vector< iplink_t > > acc_ghostMuons("GhostMuon")
static const SG::AuxElement::ConstAccessor< std::vector< float > > acc_trksumpt("SumPtTrkPt500")
@ Photon
The object is a photon.
@ Muon
The object is a muon.
@ Electron
The object is an electron.
Jet_v1 Jet
Definition of the current "jet version".
MissingETAssociation_v1 MissingETAssociation
Version control by type definition.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
MissingETContainer_v1 MissingETContainer
Muon_v1 Muon
Reference the current persistent version:
setBGCode setTAP setLVL2ErrorBits bool
MissingETAssociationMap_v1 MissingETAssociationMap
Version control by type defintion.
Electron_v1 Electron
Definition of the current "egamma version".
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
@ Central
Indicator for MET contribution from the central region.
static bool objSelected(const MissingETAssociationHelper &helper, const IParticle *obj)
static const MissingETAssociation * getAssociation(const MissingETAssociationMap *pMap, const Jet *pJet)