ATLAS Offline Software
Loading...
Searching...
No Matches
MuonLRTOverlapRemovalTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6// MuonLRTOverlapRemovalTool
7// Author: Max Goblirsch, goblirsc@SPAMNOT_CERN.ch
8
10#include <algorithm>
12
13namespace CP {
14
17 {
18 // nothing to do here
19 }
20
22 // Initialisation
24
26 {
27 if(m_muonSelectionTool.empty()){
28 asg::AsgToolConfig config("CP::MuonSelectionTool/MuonSelectionTool");
29 ATH_CHECK(config.setProperty("TurnOffMomCorr",true));
30 ATH_CHECK(config.setProperty("IsRun3Geo",m_useRun3WP.value()));
31 ATH_CHECK(config.makePrivateTool(m_muonSelectionTool));
32 }
33
34 ATH_MSG_DEBUG("retrieving Muon selection tool");
35 ATH_CHECK( m_muonSelectionTool.retrieve() );
36 return StatusCode::SUCCESS;
37 }
38
40 // Check overlap between the muon collections and decorate duplicates
43 const xAOD::MuonContainer & LRTMuonCol,
44 std::vector<bool>& promptMuonsSelectedToKeep,
45 std::vector<bool>& lrtMuonsSelectedToKeep ) const
46 {
47
49 promptMuonsSelectedToKeep.resize(promptMuonCol.size(), true);
50 lrtMuonsSelectedToKeep.resize(LRTMuonCol.size(), true);
51 std::fill(promptMuonsSelectedToKeep.begin(), promptMuonsSelectedToKeep.end(), true);
52 std::fill(lrtMuonsSelectedToKeep.begin(), lrtMuonsSelectedToKeep.end(), true);
53
55 std::vector<int> promptMuonsOverlapDecision, lrtMuonsOverlapDecision;
56 promptMuonsOverlapDecision.resize(promptMuonCol.size(), 0);
57 lrtMuonsOverlapDecision.resize(LRTMuonCol.size(), 0);
58
59 // loop over prompt muons
60 u_int promptMuonIndex = 0;
61 for (const xAOD::Muon* promptMuon : promptMuonCol){
62
63 // loop over LRT muons
64 u_int lrtMuonIndex = 0;
65 for( const xAOD::Muon* lrtMuon : LRTMuonCol){
66 // check for overlap
67 std::pair<bool,bool> writeDecision = {true,true};
68 switch(m_strategy){
71 if(hasOverlap(promptMuon,lrtMuon)) { writeDecision = resolveOverlap(promptMuon, lrtMuon); }
72 break;
75 if ( (promptMuonsOverlapDecision.at(promptMuonIndex) == 0) && (lrtMuonsOverlapDecision.at(lrtMuonIndex) == 0) ) {
76 // overwrite the decision only if no overlaps have been found yet. Do not check again if either of the leptons have found overlaps previously.
77 std::tie(promptMuonsOverlapDecision.at(promptMuonIndex), lrtMuonsOverlapDecision.at(lrtMuonIndex)) = checkOverlapForDecor(promptMuon, lrtMuon);
78 }
79 break;
80 default:
81 ATH_MSG_FATAL("Unsupported overlap removal strategy type. Choose from 0 (`defaultStrategy`) or 1 (`passThroughAndDecorate`)");
82 break;
83 }
84 // write decision into vectors
85 if(!writeDecision.first){
86 promptMuonsSelectedToKeep.at(promptMuon->index()) = false;
87 }
88 if(!writeDecision.second){
89 lrtMuonsSelectedToKeep.at(lrtMuon->index()) = false;
90 }
91 ++lrtMuonIndex;
92 } // LRT muon loop ends
93 ++promptMuonIndex;
94 } // prompt muon loop ends
95
97 // if the passThroughAndDecorate strategy is selected, run a final loop over the collections to decorate the muons with the overlap resolution result.
98 static const SG::AuxElement::Decorator<int> MuonLRTOverlapDecision("MuonLRTOverlapDecision"); //0 if no overlap, 1 if overlaps and rejected, 2 if overlaps and retained
99 //final loop over prompt muons
100 u_int promptMuonIndex = 0;
101 for (const xAOD::Muon* promptMuon : promptMuonCol){
102 MuonLRTOverlapDecision(*promptMuon) = promptMuonsOverlapDecision.at(promptMuonIndex);
103 ++promptMuonIndex;
104 }
105 //final loop over LRT muons
106 u_int lrtMuonIndex = 0;
107 for (const xAOD::Muon* lrtMuon : LRTMuonCol){
108 MuonLRTOverlapDecision(*lrtMuon) = lrtMuonsOverlapDecision.at(lrtMuonIndex);
109 ++lrtMuonIndex;
110 }
111 }
112
113 }
114
116 const xAOD::Muon* lrtMuon) const{
117
118 // we compare based on MS track information to detect re-use of the same track
119 const xAOD::TrackParticle* lrtMsTrack = lrtMuon->trackParticle( xAOD::Muon::MuonSpectrometerTrackParticle );
120 const xAOD::TrackParticle* promptMsTrack = promptMuon->trackParticle( xAOD::Muon::MuonSpectrometerTrackParticle );
121
122 // baseline case: if no two MS tracks or two different MS tracks, no overlap possible
123 if ( (!promptMsTrack && !lrtMsTrack) || (promptMsTrack != lrtMsTrack)){
124 return false;
125 }
126
127 else {
128 ATH_MSG_DEBUG("Found an overlap, solving");
129 ATH_MSG_DEBUG(" Prompt muon has author "<< promptMuon->author()<<", type "<<promptMuon->muonType()<<", pT "<<promptMuon->pt()<<", eta "<<promptMuon->eta()<<", phi "<<promptMuon->phi());
130 ATH_MSG_DEBUG(" LRT muon has author "<< lrtMuon->author()<<", type "<<lrtMuon->muonType()<<", pT "<<lrtMuon->pt()<<", eta "<<lrtMuon->eta()<<", phi "<<lrtMuon->phi());
131 return true;
132 }
133 }
134
135 std::pair<bool, bool> MuonLRTOverlapRemovalTool::resolveOverlap(const xAOD::Muon* promptMuon,
136 const xAOD::Muon* lrtMuon) const{
137
138 // apply the loosest available ID to resolve most overlaps using existing MCP recommendations
139 bool promptPassQuality = (m_muonSelectionTool->getQuality(*promptMuon) < xAOD::Muon::VeryLoose);
140 bool lrtPassQuality = (m_muonSelectionTool->getQuality(*lrtMuon) < xAOD::Muon::VeryLoose);
141
142 if (promptPassQuality && !lrtPassQuality) {
143 return {true,false};
144 }
145 else if (!promptPassQuality && lrtPassQuality) {
146 return {false,true};
147 }
148
149 // still here? Next prefer combined muons over others
150 bool promptIsCombined = promptMuon->muonType() == xAOD::Muon::Combined;
151 bool lrtIsCombined = lrtMuon->muonType() == xAOD::Muon::Combined;
152
153 if (promptIsCombined && !lrtIsCombined) {
154 return {true,false};
155 }
156 else if (!promptIsCombined && lrtIsCombined) {
157 return {false,true};
158 }
159
160 // still here? Next choose the muon with a lower ID-ME delta eta value
161 float promptIDMEdEta = getIDMEdEta(promptMuon);
162 float lrtIDMEdEta = getIDMEdEta(lrtMuon);
163
164 if (promptIDMEdEta <= lrtIDMEdEta) {
165 return {true,false};
166 }
167 else {
168 return {false,true};
169 }
170
171 // fail-safe case: choose prompt over LRT.
172 ATH_MSG_DEBUG("Resolution reached the fail-safe point. Why?");
173 return {true,false};
174 }
175
176 std::tuple<int, int> MuonLRTOverlapRemovalTool::checkOverlapForDecor(const xAOD::Muon* promptMuon,
177 const xAOD::Muon* lrtMuon) const{
178 //return values: 0 if no overlap, 1 if overlaps and rejected, 2 if overlaps and retained.
179
180 if (!hasOverlap(promptMuon, lrtMuon)){
181 return std::make_tuple(0, 0);
182 }
183 else {
184 std::pair<bool, bool> overlapDecision = resolveOverlap(promptMuon, lrtMuon);
185 if (overlapDecision.first && !overlapDecision.second) {
186 return std::make_tuple(2, 1);
187 }
188 else {
189 return std::make_tuple(1, 2);
190 }
191 }
192 }
193
195 const xAOD::TrackParticle* ID_track = muon->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
196 const xAOD::TrackParticle* ME_track = muon->trackParticle(xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle);
197 if (!ID_track || !ME_track) return FLT_MAX;
198 return ( std::abs( ID_track->eta() - ME_track->eta() ) );
199 }
200
201} // end namespace CP
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_DEBUG(x)
virtual float getIDMEdEta(const xAOD::Muon *muon) const
checks the eta difference between the ID and ME track particles which is used for the final overlap r...
virtual bool hasOverlap(const xAOD::Muon *promptMuon, const xAOD::Muon *lrtMuon) const
checks the overlap between a pair of muons, one from the prompt and one from the LRT pass.
Gaudi::Property< bool > m_useRun3WP
This allows to configure the geometry used for the muon selection tool (run 2 or run 3).
Gaudi::Property< int > m_strategy
This allows to configure the OR strategy in the future, if more than one is supported by MCP.
virtual void checkOverlap(const xAOD::MuonContainer &promptCollection, const xAOD::MuonContainer &lrtCollection, std::vector< bool > &promptMuonsSelectedToKeep, std::vector< bool > &lrtMuonsSelectedToKeep) const
check the overlap between the prompt and LRT muon collections.
virtual std::pair< bool, bool > resolveOverlap(const xAOD::Muon *promptMuon, const xAOD::Muon *lrtMuon) const
resolve the overlap between a pair of muons, one from the prompt and one from the LRT pass.
virtual StatusCode initialize()
Dummy implementation of the initialisation function.
ToolHandle< CP::IMuonSelectionTool > m_muonSelectionTool
This is the muon selection tool. No particular configuration required, the loosest WP is used as a ti...
MuonLRTOverlapRemovalTool(const std::string &name)
Standard Algotithm methods:
virtual std::tuple< int, int > checkOverlapForDecor(const xAOD::Muon *promptMuon, const xAOD::Muon *lrtMuon) const
checks for overlap between a pair of muons, one from the prompt and one from the LRT pass.
size_type size() const noexcept
Returns the number of elements in the collection.
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
an object that can create a AsgTool
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
virtual double pt() const
The transverse momentum ( ) of the particle.
Author author() const
MuonType muonType() const
const TrackParticle * trackParticle(TrackParticleType type) const
Returns a pointer (which can be NULL) to the TrackParticle used in identification of this muon.
Definition Muon_v1.cxx:482
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Select isolated Photons, Electrons and Muons.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".