589 {
590 if(!metJet || !jets) {
592 << "MET (" << metJet << ") or "
593 << "jet collection (" << jets << ").");
594 return StatusCode::FAILURE;
595 }
597 if(!map){
598 ATH_MSG_ERROR(
"MET Association Helper isn't associated with a MissingETAssociationMap!");
599 return StatusCode::FAILURE;
600 }
602 ATH_MSG_WARNING(
"Requested soft track element links, but no track selection tool supplied.");
603 }
605
607 ATH_MSG_WARNING(
"Incomplete association map received. Cannot rebuild MET.");
608 ATH_MSG_WARNING(
"Note: METMaker should only be run on events containing at least one PV");
609 return StatusCode::SUCCESS;
610 }
611
612 if(doJetJVT &&
m_JvtWP ==
"None"){
614 doJetJVT = false;
615 }
616
618 if(!metSoftClus && !metSoftTrk) {
619 ATH_MSG_WARNING(
"Neither soft cluster nor soft track term has been supplied!");
620 return StatusCode::SUCCESS;
621 }
623 if(metSoftClus) {
625 if(!coreSoftClus) {
626 ATH_MSG_ERROR(
"Soft cluster term provided without a core term!");
627 return StatusCode::FAILURE;
628 }
631 <<
", mpy " << coreSoftClus->
mpy()
632 <<
" sumet " << coreSoftClus->
sumet());
633 *metSoftClus += *coreSoftClus;
634
635
636
637 if(softConst && acc_softConst.isAvailable(*coreSoftClus)) {
638 for(const auto& constit : acc_softConst(*coreSoftClus)) {
639 softConst->push_back(*constit);
640 }
641 ATH_MSG_DEBUG(softConst->size() <<
" soft constituents from core term");
642 }
643 }
644 if(metSoftTrk) {
646 if(!coreSoftTrk) {
647 ATH_MSG_ERROR(
"Soft track term provided without a core term!");
648 return StatusCode::FAILURE;
649 }
652 <<
", mpy " << coreSoftTrk->
mpy()
653 <<
" sumet " << coreSoftTrk->
sumet());
654 *metSoftTrk += *coreSoftTrk;
656 for(const auto& constit : acc_softConst(*coreSoftTrk)) {
657 softConst->push_back(*constit);
658 }
659 ATH_MSG_DEBUG(softConst->size() <<
" soft constituents from trk core term");
660 }
661 }
662
667 uniqueLinks.reserve(
jets->size());
668 uniqueWeights.reserve(
jets->size());
669 std::vector<iplink_t> softJetLinks;
670 std::vector<float> softJetWeights;
672
673
674
675
676
677
678
682 if(jetsSgKey == 0) {
683 ATH_MSG_ERROR(
"Could not find the jets with pointer: " << jets);
684 return StatusCode::FAILURE;
685 }
686 }
687
690 if(originalInputs) {
692 } else {
695 }
696 if(!assoc || assoc->isMisc()){
698 continue;
699 }
700
702
706
707 }
708 else
709 ATH_MSG_ERROR(
"No nominal calibrated jet available for jet " << jet->index() <<
". Cannot simplify overlap removal!");
710 }
712
714 bool JVT_reject(false);
715 bool isMuFSRJet(false);
716
717
719 JVT_reject = true;
720
721 if(doJetJVT) {
722
724 ATH_MSG_VERBOSE(
"Jet " << (JVT_reject ?
"fails" :
"passes") <<
" JVT selection");
725 }
726
727
729 bool hardJet(false);
731 bool caloverlap = false;
732 caloverlap = calvec.
ce()>0;
733 ATH_MSG_DEBUG(
"Jet " << jet->index() <<
" is " << ( caloverlap ?
"" :
"non-") <<
"overlapping");
734
736 for(const auto& object : assoc->objects()) {
737
739 }
740 }
741
743 double constSF(1);
745 constjet = assoc->getAlternateConstVec();
746 } else {
748 double denom = (assoc->hasAlternateConstVec() ? assoc->getAlternateConstVec() : jet->jetP4(
"JetConstitScaleMomentum")).E();
751 calvec *= constSF;
752 }
753 double jpx = constjet.Px();
754 double jpy = constjet.Py();
755 double jpt = constjet.Pt();
756 double opx = jpx - calvec.
cpx();
757 double opy = jpy - calvec.
cpy();
758
761
763 met_muonEloss = (*metCont)["MuonEloss"];
764 if(!met_muonEloss) {
765 ATH_MSG_WARNING(
"Attempted to apply muon Eloss correction, but corresponding MET term does not exist!");
766 return StatusCode::FAILURE;
767 }
768 }
769
770 float total_eloss(0);
772 std::vector<const xAOD::Muon*> muons_in_jet;
773 std::vector<const xAOD::Electron*> electrons_in_jet;
774 bool passJetForEl=false;
778 return StatusCode::FAILURE;
779 }
782 ATH_MSG_ERROR(
"Invalid element link to ghost muon! Quitting.");
783 return StatusCode::FAILURE;
784 }
785 muons_in_jet.push_back(
static_cast<const xAOD::Muon*
>(*el));
786 }
787 }
788 for(const auto& obj : assoc->objects()) {
789 if(!obj) continue;
792 ATH_MSG_VERBOSE(
"Muon " << mu_test->index() <<
" found in jet " << jet->index());
796 muons_in_jet.push_back(mu_test);
798 }
799 }
802 ATH_MSG_VERBOSE(
"Electron " << el_test->index() <<
" found in jet " << jet->index());
804 if(
helper.objSelected(assoc,el_test)){
805 if(el_test->pt()>90.0e3) {
806 electrons_in_jet.push_back(el_test);
808 }
809 }
810 }
811 }
814 float jet_ORtrk_sumpt = assoc->overlapTrkVec(helper).
sumpt();
815 float jet_all_trk_pt = initialTrkMom.
sumpt();
816 float jet_unique_trk_pt = jet_all_trk_pt - jet_ORtrk_sumpt;
819 for(const auto& elec : electrons_in_jet) {
820 el_calvec += assoc->calVec(elec);
821 el_trkvec += assoc->trkVec(elec);
822 }
823 float el_cal_pt = el_calvec.
cpt();
824 float el_trk_pt = el_trkvec.
cpt();
826 << " jetalltrk: " << jet_all_trk_pt
827 << " jetORtrk: " << jet_ORtrk_sumpt
828 << " electrk-jetORtrk: " << (el_trk_pt-jet_ORtrk_sumpt)
829 << " elec cal: " << el_cal_pt
830 << " jetalltrk-electrk: " << (jet_all_trk_pt-el_trk_pt)
831 << " jetalltrk-jetORtrk: " << (jet_all_trk_pt-jet_ORtrk_sumpt) );
832
833
834
835 if(el_trk_pt>1
e-9 && jet_unique_trk_pt>10.0e3) passJetForEl=
true;
836 }
837
838 for(
const xAOD::Muon* mu_in_jet : muons_in_jet) {
839 if (!mu_in_jet) continue;
841
842 if(!JVT_reject) {
844
845 float mu_id_pt = mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) ? mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle)->pt() : 0.;
847
848
849 if(0.9999*mu_id_pt>jet_trk_sumpt)
850 jet_trk_sumpt+=mu_id_pt;
853 ATH_MSG_VERBOSE(
"Jet has pt " << jet->pt() <<
", trk sumpt " << jet_trk_sumpt <<
", trk N " << jet_trk_N);
854 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;
855 if(jet_from_muon) {
857 JVT_reject = true;
858 }
859 }
860
862
863 float mu_id_pt = mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle) ? mu_in_jet->trackParticle(xAOD::Muon::InnerDetectorTrackParticle)->pt() : 0.;
865
866 if(0.9999*mu_id_pt>jet_trk_sumpt)
867 jet_trk_sumpt+=mu_id_pt;
869
870 float jet_psE = 0.;
871 if (
acc_psf.isAvailable(*jet)){
875 } else {
876 ATH_MSG_ERROR(
"Jet PS fraction or sampling energy must be available to calculate MET with doSetMuonJetEMScale");
877 return StatusCode::FAILURE;
878 }
879
882 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));
883
884 if(jet_from_muon) {
885 ATH_MSG_VERBOSE(
"Jet is from muon -- set to EM scale and subtract Eloss.");
886
887
888 ATH_MSG_VERBOSE(
"Jet e: " << constjet.E() <<
", mu Eloss: " << mu_Eloss);
889 float elosscorr = mu_Eloss >= constjet.e() ? 0. : 1.-mu_Eloss/constjet.e();
890
891
892 opx *= elosscorr;
893 opy *= elosscorr;
894 ATH_MSG_VERBOSE(
" Jet eloss factor " << elosscorr <<
", final pt: " << sqrt(opx*opx+opy*opy));
895
896 isMuFSRJet = true;
897 }
898 }
899 }
900
901 switch(mu_in_jet->energyLossType()) {
902 case xAOD::Muon::Parametrized:
903 case xAOD::Muon::MOP:
904 case xAOD::Muon::Tail:
905 case xAOD::Muon::FSRcandidate:
906 case xAOD::Muon::NotIsolated:
907
908
909
910 total_eloss += mu_Eloss;
911 muons_selflags |= (1<<assoc->findIndex(mu_in_jet));
912 }
913 }
916
918
919 for(size_t iKey = 0; iKey < assoc->sizeCal(); iKey++) {
920 bool selector = (muons_selflags & assoc->calkey()[iKey]);
921 if(selector) mu_calovec += assoc->calVec(iKey);
922 ATH_MSG_VERBOSE(
"This key: " << assoc->calkey()[iKey] <<
", selector: " << selector);
923 }
925 if(
m_muEloss) mu_calovec *= std::max<float>(0.,1-(total_eloss/mu_calovec.
ce()));
927
928
929 ATH_MSG_VERBOSE(
"Jet " << jet->index() <<
" const pT before OR " << jpt);
930 ATH_MSG_VERBOSE(
"Jet " << jet->index() <<
" const pT after OR " << sqrt(opx*opx+opy*opy));
931 opx += mu_calovec.
cpx();
932 opy += mu_calovec.
cpy();
933 double opt = sqrt( opx*opx+opy*opy );
934 ATH_MSG_VERBOSE(
"Jet " << jet->index() <<
" const pT diff after OR readding muon clusters " << opt-jpt);
935 double uniquefrac = 1. - (calvec.
ce() - mu_calovec.
ce()) / constjet.E();
936 ATH_MSG_VERBOSE(
"Jet constscale px, py, pt, E = " << jpx <<
", " << jpy <<
", " << jpt <<
", " << constjet.E() );
938 ATH_MSG_VERBOSE(
"Jet OR px, py, pt, E = " << opx <<
", " << opy <<
", " << opt <<
", " << constjet.E() - calvec.
ce() );
939
940 if(isMuFSRJet) {
941 if(!met_muonEloss){
942 ATH_MSG_ERROR(
"Attempted to apply muon Eloss correction, but corresponding MET term does not exist!");
943 return StatusCode::FAILURE;
944 }
945 met_muonEloss->add(opx,opy,opt);
946 continue;
947 }
948
949 if(selected && !JVT_reject) {
950 if(!caloverlap) {
951
952 hardJet = true;
953 if (!tracksForHardJets) {
955 metJet->
add(jpx,jpy,jpt);
956 else
957 *metJet += jet;
958 }
959 }
961
962 hardJet = true;
963 if(!tracksForHardJets) {
966 metJet->
add(opx,opy,opt);
967 else {
968 double jesF = jet->pt() / jpt;
969 metJet->
add(opx*jesF,opy*jesF,opt*jesF);
970 }
971 } else {
973 metJet->
add(uniquefrac*jpx,uniquefrac*jpy,uniquefrac*jpt);
974 else{
976 metJet->
add(opx,opy,opt);
977 else
978 metJet->
add(uniquefrac*jet->px(),uniquefrac*jet->py(),uniquefrac*jet->pt());
979 }
980 }
981 }
982 }
983 }
984
985
987 if(jetsSgKey == 0) {
990 jetLink =
iplink_t(*ipc, jet->index());
991 } else {
992 jetLink =
iplink_t(jetsSgKey, jet->index());
993 }
994
995 if(hardJet){
997 uniqueLinks.push_back( jetLink );
998 uniqueWeights.push_back( uniquefrac );
999 } else {
1000 if(metSoftClus && !JVT_reject) {
1001
1004 softJetLinks.push_back( jetLink );
1005 softJetWeights.push_back( uniquefrac );
1006 metSoftClus->
add(opx,opy,opt);
1007 }
1008
1009
1010
1011
1012
1013
1014 if(softConst) {
1015 for(size_t iConst=0; iConst<jet->numConstituents(); ++iConst) {
1016 const IParticle* constit = jet->rawConstituent(iConst);
1017 softConst->push_back(constit);
1018 }
1019 }
1020 }
1021 }
1022
1023 if(!metSoftTrk || (hardJet && !tracksForHardJets)) continue;
1024
1025
1026
1029 if(jettrkvec.
ce()>1
e-9) {
1030 jpx = jettrkvec.
cpx();
1031 jpy = jettrkvec.
cpy();
1032 jpt = jettrkvec.
sumpt();
1033 jettrkvec -= trkvec;
1034 opx = jettrkvec.
cpx();
1035 opy = jettrkvec.
cpy();
1037 ATH_MSG_VERBOSE(
"Jet track px, py, sumpt = " << jpx <<
", " << jpy <<
", " << jpt );
1038 ATH_MSG_VERBOSE(
"Jet OR px, py, sumpt = " << opx <<
", " << opy <<
", " << opt );
1039 } else {
1040 opx = opy =
opt = 0;
1042 }
1043 if (hardJet) metJet->
add(opx,opy,opt);
1045 metSoftTrk->
add(opx,opy,opt);
1046
1047 if(!metSoftClus) {
1048 softJetLinks.push_back( jetLink );
1049 softJetWeights.push_back( uniquefrac );
1050 }
1051
1052
1053
1054
1055
1056
1058 std::vector<const IParticle*> jettracks;
1060 for(size_t iConst=0; iConst<jettracks.size(); ++iConst) {
1062 if (
acceptTrack(pTrk,pv)) softConst->push_back(pTrk);
1063 }
1064 }
1065 }
1066 }
1067
1069
1070 if(metSoftTrk) {
1073 }
1074
1075 if(metSoftClus) {
1078 }
1079
1080 if(softConst)
ATH_MSG_DEBUG(softConst->size() <<
" soft constituents from core term + jets");
1081
1083 if(!assoc) return StatusCode::SUCCESS;
1084
1085 if(metSoftTrk) {
1086
1087
1089 double opx = trkvec.
cpx();
1090 double opy = trkvec.
cpy();
1091 double osumpt = trkvec.
sumpt();
1092 ATH_MSG_VERBOSE(
"Misc track px, py, sumpt = " << opx <<
", " << opy <<
", " << osumpt );
1093 metSoftTrk->
add(opx,opy,osumpt);
1095 <<
", mpy " << metSoftTrk->
mpy()
1096 <<
" sumet " << metSoftTrk->
sumet());
1097 }
1098
1099 if(metSoftClus) {
1100
1101
1102 float total_eloss(0.);
1105 double opx = calvec.
cpx();
1106 double opy = calvec.
cpy();
1107 double osumpt = calvec.
sumpt();
1108 for(const auto& obj : assoc->objects()) {
1114 switch(mu_test->energyLossType()) {
1115 case xAOD::Muon::Parametrized:
1116 case xAOD::Muon::MOP:
1117 case xAOD::Muon::Tail:
1118 case xAOD::Muon::FSRcandidate:
1119 case xAOD::Muon::NotIsolated:
1120
1121
1122
1123 total_eloss += mu_Eloss;
1124 muons_selflags |= (1<<assoc->findIndex(mu_test));
1125 }
1127 }
1128 }
1131
1133
1134 for(size_t iKey = 0; iKey < assoc->sizeCal(); iKey++) {
1135 bool selector = (muons_selflags & assoc->calkey()[iKey]);
1136 ATH_MSG_VERBOSE(
"This key: " << assoc->calkey()[iKey] <<
", selector: " << selector
1137 << " this calvec E: " << assoc->calVec(iKey).ce());
1138 if(selector) mu_calovec += assoc->calVec(iKey);
1139 }
1141 mu_calovec *= std::max<float>(0.,1-(total_eloss/mu_calovec.
ce()));
1142 opx += mu_calovec.
cpx();
1143 opy += mu_calovec.
cpy();
1144 osumpt += mu_calovec.
sumpt();
1145 }
1147
1148 ATH_MSG_VERBOSE(
"Misc cluster px, py, sumpt = " << opx <<
", " << opy <<
", " << osumpt );
1149 metSoftClus->
add(opx,opy,osumpt);
1151 <<
", mpy " << metSoftClus->
mpy()
1152 <<
" sumet " << metSoftClus->
sumet());
1153 }
1154
1155 return StatusCode::SUCCESS;
1156 }
bool empty() const noexcept
Returns true if the collection is empty.
SG::ConstAccessor< T, ALLOC > ConstAccessor
XAOD_AUXDATA_DEPRECATED bool isAvailable(const std::string &name, const std::string &clsname="") const
Check if an aux variable is available for reading.
const SG::AuxVectorData * container() const
Return the container holding this element.
size_t index() const
Return the index of this element within its container.
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
static const SG::AuxElement::ConstAccessor< iplink_t > acc_nominalObject("nominalObjectLink")
ElementLink< xAOD::IParticleContainer > iplink_t
static const SG::AuxElement::ConstAccessor< float > acc_width("Width")
static const SG::AuxElement::ConstAccessor< std::vector< int > > acc_trkN("NumTrkPt500")
static const SG::AuxElement::ConstAccessor< iplink_t > acc_originalObject("originalObjectLink")
static const SG::AuxElement::ConstAccessor< float > acc_Eloss("EnergyLoss")
static const SG::AuxElement::Accessor< std::vector< iplink_t > > dec_constitObjLinks("ConstitObjectLinks")
static const SG::AuxElement::Accessor< std::vector< float > > dec_constitObjWeights("ConstitObjectWeights")
static const SG::AuxElement::ConstAccessor< std::vector< iplink_t > > acc_ghostMuons("GhostMuon")
static const SG::AuxElement::ConstAccessor< float > acc_emf("EMFrac")
static const SG::AuxElement::ConstAccessor< std::vector< float > > acc_trksumpt("SumPtTrkPt500")
static const SG::AuxElement::ConstAccessor< float > acc_psf("PSFrac")
static const SG::AuxElement::ConstAccessor< std::vector< float > > acc_sampleE("EnergyPerSampling")
@ 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)