ATLAS Offline Software
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>
11 #include <AsgTools/AsgToolConfig.h>
12 
13 namespace CP {
14 
16  asg::AsgTool(name)
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
CP::IMuonLRTOverlapRemovalTool::defaultStrategy
@ defaultStrategy
Definition: IMuonLRTOverlapRemovalTool.h:38
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
CP::MuonLRTOverlapRemovalTool::checkOverlapForDecor
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.
Definition: MuonLRTOverlapRemovalTool.cxx:176
CP::IMuonLRTOverlapRemovalTool::passThroughAndDecorate
@ passThroughAndDecorate
Definition: IMuonLRTOverlapRemovalTool.h:39
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
LikeEnum::VeryLoose
@ VeryLoose
Definition: LikelihoodEnums.h:11
xAOD::Muon_v1::trackParticle
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:504
xAOD::TrackParticle_v1::eta
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
Definition: TrackParticle_v1.cxx:77
xAOD::Muon_v1::phi
virtual double phi() const
The azimuthal angle ( ) of the particle.
CP::MuonLRTOverlapRemovalTool::m_strategy
Gaudi::Property< int > m_strategy
This allows to configure the OR strategy in the future, if more than one is supported by MCP.
Definition: MuonLRTOverlapRemovalTool.h:70
xAOD::Muon_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
asg
Definition: DataHandleTestTool.h:28
xAOD::Muon_v1::author
Author author() const
CP
Select isolated Photons, Electrons and Muons.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:48
CP::MuonLRTOverlapRemovalTool::resolveOverlap
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.
Definition: MuonLRTOverlapRemovalTool.cxx:135
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
CP::MuonLRTOverlapRemovalTool::hasOverlap
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.
Definition: MuonLRTOverlapRemovalTool.cxx:115
asg::AsgToolConfig
an object that can create a AsgTool
Definition: AsgToolConfig.h:22
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
CP::MuonLRTOverlapRemovalTool::m_muonSelectionTool
ToolHandle< CP::IMuonSelectionTool > m_muonSelectionTool
This is the muon selection tool. No particular configuration required, the loosest WP is used as a ti...
Definition: MuonLRTOverlapRemovalTool.h:74
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
AsgToolConfig.h
xAOD::Muon_v1::pt
virtual double pt() const
The transverse momentum ( ) of the particle.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
Trk::Combined
@ Combined
Definition: TrackSummaryTool.h:32
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
CP::MuonLRTOverlapRemovalTool::MuonLRTOverlapRemovalTool
MuonLRTOverlapRemovalTool(const std::string &name)
Standard Algotithm methods:
Definition: MuonLRTOverlapRemovalTool.cxx:15
CP::MuonLRTOverlapRemovalTool::getIDMEdEta
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...
Definition: MuonLRTOverlapRemovalTool.cxx:194
lumiFormat.fill
fill
Definition: lumiFormat.py:111
config
std::vector< std::string > config
Definition: fbtTestBasics.cxx:72
CP::MuonLRTOverlapRemovalTool::m_useRun3WP
Gaudi::Property< bool > m_useRun3WP
This allows to configure the geometry used for the muon selection tool (run 2 or run 3).
Definition: MuonLRTOverlapRemovalTool.h:72
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
CP::MuonLRTOverlapRemovalTool::initialize
virtual StatusCode initialize()
Dummy implementation of the initialisation function.
Definition: MuonLRTOverlapRemovalTool.cxx:25
MuonLRTOverlapRemovalTool.h
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
CP::MuonLRTOverlapRemovalTool::checkOverlap
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.
Definition: MuonLRTOverlapRemovalTool.cxx:42
xAOD::Muon_v1::muonType
MuonType muonType() const