ATLAS Offline Software
MuonMatchingTool.icc
Go to the documentation of this file.
1 /* -*- mode:c++ -*-
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 template<class T> std::tuple<bool,double,double> MuonMatchingTool :: trigPosForMatch(const T *trig) {
7  return std::forward_as_tuple(true, trig->eta(), trig->phi());
8 }
9 
10 
11 template<class T, class OFFL>
12 const T* MuonMatchingTool :: matchReadHandle(const OFFL* offl, float reqdR,
13  SG::ReadHandleKey<DataVector<T> > ReadHandleKey, const EventContext& ctx,
14  std::tuple<bool,double,double> (*trigPosForMatchFunc)(const T*)) const {
15 
16  ATH_MSG_DEBUG("MuonMonitoring::matchReadHandle<T>");
17 
18  using CONTAINER = DataVector<T>;
19  const T* ptr = nullptr;
20 
21  SG::ReadHandle<CONTAINER> trigmuons(ReadHandleKey, ctx);
22  if (! trigmuons.isValid() ) {
23  ATH_MSG_ERROR("evtStore() does not contain collection with name " << ReadHandleKey);
24  return ptr;
25  }
26 
27  double offlEta = offl->eta();
28  double offlPhi = offl->phi();
29 
30  for(const auto& trigmu : *trigmuons){
31  const auto [status, trigEta, trigPhi] = trigPosForMatchFunc(trigmu);
32  if(!status) continue;
33  double deta = offlEta - trigEta;
34  double dphi = xAOD::P4Helpers::deltaPhi(offlPhi, trigPhi);
35  double dR = sqrt(deta*deta + dphi*dphi);
36 
37  ATH_MSG_VERBOSE("Trigger muon candidate eta=" << trigEta << " phi=" << trigPhi << " pt=" << trigmu->pt() << " dR=" << dR);
38  if( dR<reqdR ){
39  reqdR = dR;
40  ATH_MSG_DEBUG("* Trigger muon eta=" << trigEta << " phi=" << trigPhi << " pt=" << trigmu->pt() << " dR=" << dR);
41  ptr = trigmu;
42  }
43  }
44 
45  return ptr;
46 
47 }
48 
49 
50 template<class T, class OFFL>
51 const T* MuonMatchingTool :: match(const OFFL* offl, std::string trig, float reqdR, bool &pass,
52  const std::string& containerSGKey,
53  std::tuple<bool,double,double> (*trigPosForMatchFunc)(const T*)) const {
54 
55  ATH_MSG_DEBUG("MuonMonitoring::match<T>");
56 
57  using CONTAINER = DataVector<T>;
58  const T* ptr = nullptr;
59 
60  const TrigCompositeUtils::LinkInfo<CONTAINER> featureLinkInfo = matchLinkInfo<T>(offl, trig, reqdR, pass, containerSGKey, trigPosForMatchFunc);
61  if( featureLinkInfo.isValid() ){
62  const ElementLink<CONTAINER> link = featureLinkInfo.link;
63  ptr = *link;
64  }
65 
66  return ptr;
67 
68 }
69 
70 
71 template<class T, class OFFL>
72 const TrigCompositeUtils::LinkInfo<DataVector<T> > MuonMatchingTool :: matchLinkInfo(const OFFL* offl, std::string trig, float reqdR, bool &pass,
73  const std::string& containerSGKey,
74  std::tuple<bool,double,double> (*trigPosForMatchFunc)(const T*)) const {
75 
76  ATH_MSG_DEBUG("MuonMonitoring::matchLinkInfo<T>");
77 
78  using CONTAINER = DataVector<T>;
79 
80  double offlEta = offl->eta();
81  double offlPhi = offl->phi();
82 
83  std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > featureCont = m_trigDec->features<CONTAINER>( trig, TrigDefs::includeFailedDecisions, containerSGKey );
84  TrigCompositeUtils::LinkInfo<CONTAINER> muonLinkInfo;
85  for(const TrigCompositeUtils::LinkInfo<CONTAINER>& featureLinkInfo : featureCont){
86  if ( !featureLinkInfo.isValid() ) continue;
87  const ElementLink<CONTAINER> link = featureLinkInfo.link;
88  const auto [status, trigEta, trigPhi] = trigPosForMatchFunc(*link);
89  if(!status) continue;
90  double deta = offlEta - trigEta;
91  double dphi = xAOD::P4Helpers::deltaPhi(offlPhi, trigPhi);
92  double dR = sqrt(deta*deta + dphi*dphi);
93 
94  ATH_MSG_VERBOSE("Trigger muon candidate eta=" << trigEta << " phi=" << trigPhi << " pt=" << (*link)->pt() << " dR=" << dR);
95  if( dR<reqdR ){
96  reqdR = dR;
97  muonLinkInfo = featureLinkInfo;
98  pass = ( featureLinkInfo.state == TrigCompositeUtils::ActiveState::ACTIVE );
99  ATH_MSG_DEBUG("* Trigger muon eta=" << trigEta << " phi=" << trigPhi << " pt=" << (*link)->pt() << " dR=" << dR << " isPassed=" << pass);
100  }
101  }
102 
103  return muonLinkInfo;
104 
105 }
106 
107 
108 template<class T>
109 const xAOD::Muon* MuonMatchingTool :: matchOff(const EventContext& ctx, const T* trig, float reqdR,
110  std::tuple<bool,double,double> (*offlinePosForMatchFunc)(const xAOD::Muon*), std::tuple<bool,double,double> (*trigPosForMatchFunc)(const T*)) const {
111 
112  ATH_MSG_DEBUG("MuonMonitoring::matchOff<T>");
113 
114  const xAOD::Muon *muon = nullptr;
115 
116  SG::ReadHandle<xAOD::MuonContainer> muons(m_MuonContainerKey, ctx);
117  if (! muons.isValid() ) {
118  ATH_MSG_ERROR("evtStore() does not contain muon Collection with name "<< m_MuonContainerKey);
119  return muon;
120  }
121 
122  const auto [trigstatus, trigEta, trigPhi] = trigPosForMatchFunc(trig);
123  if(!trigstatus) return muon;
124 
125  for(const auto mu : *muons){
126  const auto [offstatus, offEta, offPhi] = offlinePosForMatchFunc(mu);
127  if(!offstatus) continue;
128  float deta = offEta - trigEta;
129  float dphi = xAOD::P4Helpers::deltaPhi(offPhi, trigPhi);
130  double dR = sqrt(deta*deta + dphi*dphi);
131 
132  if(dR < reqdR){
133  reqdR = dR;
134  muon = mu;
135  ATH_MSG_DEBUG("* Trigger muon eta=" << trigEta << " phi=" << trigPhi << " offEta=" << offEta << " offPhi=" << offPhi << " dR=" << dR);
136  }
137  }
138 
139  return muon;
140 }