ATLAS Offline Software
Loading...
Searching...
No Matches
TrigMuonEFIdtpInvMassHypoTool.cxx
Go to the documentation of this file.
1/*
2# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include "GaudiKernel/SystemOfUnits.h"
12
13// --------------------------------------------------------------------------------
14// --------------------------------------------------------------------------------
15
16TrigMuonEFIdtpInvMassHypoTool::TrigMuonEFIdtpInvMassHypoTool(const std::string & type, const std::string & name, const IInterface* parent):
17 ComboHypoToolBase(type, name, parent) {
18}
19
20// --------------------------------------------------------------------------------
21// --------------------------------------------------------------------------------
22
24{
25 if( m_muonqualityCut ) {
26 if( m_muonSelTool.retrieve().isFailure() ) {
27 ATH_MSG_ERROR("Unable to retrieve " << m_muonSelTool);
28 return StatusCode::FAILURE;
29 }
30 } else m_muonSelTool.disable();
31
32 if( m_acceptAll ) {
33 ATH_MSG_DEBUG("Accepting all the events!");
34 } else {
35 if( m_invMassLow<0 && m_invMassHigh<0 ) {
36 ATH_MSG_ERROR("Both mass cuts are <0. This is probably a configuration mistake.");
37 return StatusCode::FAILURE;
38 }
39 }
40
41 if ( not m_monTool.name().empty() ) {
42 ATH_CHECK( m_monTool.retrieve() );
43 ATH_MSG_DEBUG("MonTool name: " << m_monTool);
44 }
45
46 ATH_MSG_DEBUG("Initialization completed successfully");
47 return StatusCode::SUCCESS;
48}
49
50// --------------------------------------------------------------------------------
51// --------------------------------------------------------------------------------
52
53bool TrigMuonEFIdtpInvMassHypoTool::executeAlg(const std::vector<Combo::LegDecision>& combination, const EventContext& /*ctx*/) const
54{
55 ATH_MSG_VERBOSE("in executeAlg");
56 bool result = false;
57
58 if( m_acceptAll ) {
59 ATH_MSG_DEBUG("Accept property is set: taking all the events");
60 return true;
61 }
62
63 // monitored variables
64 std::vector<float> mnt_invMass;
65 auto mon_invMass = Monitored::Collection("Mass", mnt_invMass);
66 auto monitorIt = Monitored::Group(m_monTool, mon_invMass);
67
68 // retrieve muon and tracks
69 std::vector<const xAOD::TrackParticle*> tracks_pt;
70 std::vector<const xAOD::TrackParticle*> tracks_ftf;
71 std::vector<const xAOD::Muon*> muons_cb;
72 std::vector<const xAOD::Muon*> muons_sa;
73 int i_leg_idperf = -1;
74 for(auto leg: combination) {
75 auto decision= (*(leg.second));
76 auto i_leg = TrigCompositeUtils::getIndexFromLeg(leg.first);
77 ATH_MSG_VERBOSE("i_leg="<<i_leg);
79 if( muonLinks.size() != 1 ) continue;
80 if( ! muonLinks.at(0).isValid() ) continue;
81 const xAOD::Muon *mu = *(muonLinks.at(0).link);
82 if( ! mu->primaryTrackParticle() ) continue;
83
84 bool is_idperf_muon = false;
85 ATH_MSG_VERBOSE("... selected: muonType="<<mu->muonType()<<", pT="<<mu->pt()/Gaudi::Units::GeV<<", eta="<<mu->eta()<<", phi="<<mu->phi()<<", author="<<mu->author());
86 if(mu->author()==xAOD::Muon::Author::MuidCo && mu->muonType()==xAOD::Muon::MuonType::Combined) {
87 muons_cb.push_back(mu);
88 }
89 else if(mu->author()==xAOD::Muon::Author::MuidSA && mu->muonType()==xAOD::Muon::MuonType::MuonStandAlone) {
90 muons_sa.push_back(mu);
91 is_idperf_muon = true;
92 if( i_leg_idperf == -1 ) { i_leg_idperf = i_leg; }
93 else if( i_leg_idperf != (int)i_leg ) {
94 ATH_MSG_ERROR("i_leg for idperf looks inconsistent: i_leg_idperf / i_leg="<<i_leg_idperf<<" / "<<i_leg);
95 return result;
96 }
97 }
98
99 // if this leg is idperf leg (muon is SA) get ID tracks
100 if( is_idperf_muon ) {
101 const std::vector< TrigCompositeUtils::LinkInfo<xAOD::TrackParticleContainer> > ptLinks = TrigCompositeUtils::findLinks< xAOD::TrackParticleContainer >( decision, "HLT_IDTrack_Muon_IDTrig", TrigDefs::lastFeatureOfType);
102 ATH_MSG_VERBOSE("PT TrackParticleContainer Links size = "<<ptLinks.size());
103 if( ptLinks.size() == 1 && ptLinks.at(0).isValid() ) {
104 const xAOD::TrackParticle* track = *(ptLinks.at(0).link);
105 tracks_pt.push_back(track);
106 float pt = track->pt();
107 float eta = track->eta();
108 float phi = track->phi();
109 ATH_MSG_VERBOSE("... pt / eta / phi = "<<pt/Gaudi::Units::GeV << " / " << eta << " / " << phi<<", fitter="<<track->trackFitter());
110 }
111 const std::vector< TrigCompositeUtils::LinkInfo<xAOD::TrackParticleContainer> > ftfLinks = TrigCompositeUtils::findLinks< xAOD::TrackParticleContainer >( decision, "HLT_IDTrack_Muon_FTF", TrigDefs::lastFeatureOfType);
112 ATH_MSG_VERBOSE("FTF TrackParticleContainer Links size = "<< ftfLinks.size());
113 if( ftfLinks.size() == 1 && ftfLinks.at(0).isValid() ) {
114 const xAOD::TrackParticle* track = *(ftfLinks.at(0).link);
115 tracks_ftf.push_back(track);
116 float pt = track->pt();
117 float eta = track->eta();
118 float phi = track->phi();
119 ATH_MSG_VERBOSE("... pt / eta / phi = "<<pt/Gaudi::Units::GeV << " / " << eta << " / " << phi<<", fitter="<<track->trackFitter());
120 }
121 }
122 } // end of combination loop
123
124 // mass between CB and SA
125 for(auto muon_cb : muons_cb) {
126 if( m_muonqualityCut && ! passedCBQualityCuts(muon_cb) ) continue;
127
128 for(auto muon_sa : muons_sa) {
129 if( m_muonqualityCut && ! passedSAQualityCuts(muon_sa) ) continue;
130
131 const xAOD::TrackParticle* tr_cb = muon_cb->trackParticle(xAOD::Muon::TrackParticleType::CombinedTrackParticle);
132 const xAOD::TrackParticle* tr_sa = muon_sa->trackParticle(xAOD::Muon::TrackParticleType::ExtrapolatedMuonSpectrometerTrackParticle);
133 if (!tr_cb || !tr_sa) {
134 ATH_MSG_ERROR("Either CB or SA TrackParticle not found.");
135 continue;
136 }
137
138 if( m_selOS && (muon_cb->charge()*muon_sa->charge() > 0) ) continue;
139
140 float diMuMass = (tr_cb->p4()+tr_sa->p4()).M()/Gaudi::Units::GeV;
141 mnt_invMass.push_back(diMuMass);
142 ATH_MSG_VERBOSE("pt CB / pt SA = " << (*tr_cb).pt()/Gaudi::Units::GeV << " / " << (*tr_sa).pt()/Gaudi::Units::GeV << ", mass =" << diMuMass);
143
144 if( ((m_invMassLow >=0 && diMuMass>m_invMassLow ) || m_invMassLow <0) &&
145 ((m_invMassHigh>=0 && diMuMass<m_invMassHigh) || m_invMassHigh<0) ) {
146 result = true;
147 StatusCode sc = doTPIdperf(tr_sa, tracks_pt, tracks_ftf);
148 if( sc != StatusCode::SUCCESS ) {
149 ATH_MSG_ERROR("doTPIdperf failed with StatuCode="<<sc);
150 }
151 }
152 }
153 }
154
155 //
156 ATH_MSG_VERBOSE("idperf TP overall result is: "<<(result?"true":"false"));
157 return result;
158}
159
160// --------------------------------------------------------------------------------
161// --------------------------------------------------------------------------------
162
163StatusCode TrigMuonEFIdtpInvMassHypoTool::doTPIdperf(const xAOD::TrackParticle* metrack, const std::vector<const xAOD::TrackParticle*>& tracks_pt, const std::vector<const xAOD::TrackParticle*>& tracks_ftf) const
164{
165 ATH_MSG_VERBOSE("----- doTPIdperf -----");
166
167 // monitored variables
168 std::vector<float> mnt_PT_dr, mnt_PT_qovp;
169 std::vector<float> mnt_FTF_dr, mnt_FTF_qovp;
170 auto mon_PT_dr = Monitored::Collection("PT_dr", mnt_PT_dr);
171 auto mon_PT_qovp = Monitored::Collection("PT_qovp", mnt_PT_qovp);
172 auto mon_FTF_dr = Monitored::Collection("FTF_dr", mnt_FTF_dr);
173 auto mon_FTF_qovp = Monitored::Collection("FTF_qovp", mnt_FTF_qovp);
174 auto mon_phi_effi = Monitored::Scalar<float>("probePhiEfficiency", -999.0);
175 auto mon_eta_effi = Monitored::Scalar<float>("probeEtaEfficiency", -999.0);
176 auto mon_pt_found = Monitored::Scalar<float>("PTfound", -1);
177 auto mon_ftf_found = Monitored::Scalar<float>("FTFfound", -1);
178 auto mon_pt_phi = Monitored::Scalar<float>("PTphi", -999.0);
179 auto mon_pt_pix = Monitored::Scalar<float>("PTpixelFound", -1);
180 auto mon_pt_pixnext= Monitored::Scalar<float>("PTpixelNextToFound", -1);
181 auto monitorIt = Monitored::Group(m_monTool, mon_PT_dr, mon_PT_qovp, mon_FTF_dr, mon_FTF_qovp, mon_phi_effi, mon_eta_effi, mon_pt_found, mon_ftf_found, mon_pt_phi, mon_pt_pix, mon_pt_pixnext);
182
183 // probe values
184 auto mnt_probe_pt = Monitored::Scalar<float>("probe_pt", 0);
185 auto mnt_probe_eta = Monitored::Scalar<float>("probe_eta", 0);
186 auto monProbe = Monitored::Group(m_monTool, mnt_probe_pt, mnt_probe_eta);
187 mnt_probe_pt = metrack->pt()/Gaudi::Units::GeV;
188 mnt_probe_eta = metrack->eta();
189
190 // PT
191 const float PT_DR_CUT = 0.1;
192 const float PT_QOVP_CUT = 2.0;
193 ATH_MSG_VERBOSE("PT: n size="<<tracks_pt.size());
194 int n_pt_matched = 0;
195 float min_dr_pt_matched = 999;
196 uint8_t pt_expectInnermost=0;
197 uint8_t pt_numberInnermost=0;
198 uint8_t pt_expectNextToInnermost=0;
199 uint8_t pt_numberNextToInnermost=0;
200 for(auto idtrack : tracks_pt) {
201 float dr_pt = xAOD::P4Helpers::deltaR(metrack,idtrack);
202 float qovp_pt = TrigMuonEFIdtpCommon::qOverPMatching(metrack,idtrack);
203 mnt_PT_dr.push_back(dr_pt);
204 mnt_PT_qovp.push_back(qovp_pt);
205 ATH_MSG_VERBOSE("... dr (ME-PT): "<<dr_pt);
206 ATH_MSG_VERBOSE("... Q/p match (ME-PT): "<<qovp_pt);
207 if( dr_pt > PT_DR_CUT ) continue;
208 if( qovp_pt > PT_QOVP_CUT ) continue;
209 ++n_pt_matched;
210 if( dr_pt < min_dr_pt_matched ) {
211 min_dr_pt_matched = dr_pt;
212 mon_pt_phi = idtrack->phi();
213 idtrack->summaryValue(pt_expectInnermost,xAOD::expectInnermostPixelLayerHit);
214 idtrack->summaryValue(pt_numberInnermost,xAOD::numberOfInnermostPixelLayerHits);
215 idtrack->summaryValue(pt_expectNextToInnermost,xAOD::expectNextToInnermostPixelLayerHit);
216 idtrack->summaryValue(pt_numberNextToInnermost,xAOD::numberOfNextToInnermostPixelLayerHits);
217 }
218 }
219 if( n_pt_matched > 1 ) n_pt_matched=1;
220
221 // FTF
222 const float FTF_DR_CUT = 0.2;
223 const float FTF_QOVP_CUT = 3.0;
224 ATH_MSG_VERBOSE("FTF: n size="<<tracks_ftf.size());
225 int n_ftf_matched = 0;
226 for(auto idtrack : tracks_ftf) {
227 float dr_pt = xAOD::P4Helpers::deltaR(metrack,idtrack);
228 float qovp_pt = TrigMuonEFIdtpCommon::qOverPMatching(metrack,idtrack);
229 mnt_FTF_dr.push_back(dr_pt);
230 mnt_FTF_qovp.push_back(qovp_pt);
231 ATH_MSG_VERBOSE("... dr (ME-FTF): "<<dr_pt);
232 ATH_MSG_VERBOSE("... Q/p match (ME-FTF): "<<qovp_pt);
233 if( dr_pt > FTF_DR_CUT ) continue;
234 if( qovp_pt > FTF_QOVP_CUT ) continue;
235 ++n_ftf_matched;
236 }
237 if( n_ftf_matched > 1 ) n_ftf_matched=1;
238
239 // efficiency
240 float me_eta = metrack->eta();
241 float me_phi = metrack->phi();
242 float me_pt_gev = metrack->pt()/Gaudi::Units::GeV;
243
244 int eta_nr = 0;
245 if( std::abs(me_eta) > 2.0 ) { eta_nr = 2; }
246 else if( std::abs(me_eta) > 1.0 ) { eta_nr = 1; }
247 int pt_nr = 0;
248 if( me_pt_gev > 20.0 ) { pt_nr = 1; }
249
250 std::stringstream ss;
251 ss << "PT_effi_pt" << pt_nr << "_eta" << eta_nr;
252 auto mnt_PT_effi = Monitored::Scalar<int>(ss.str(), 0);
253 ss.clear();
254 ss << "PT_effi_pt" << pt_nr << "_eta" << eta_nr;
255 auto mnt_FTF_effi = Monitored::Scalar<int>(ss.str(), 0);
256 auto monEffi = Monitored::Group(m_monTool, mnt_PT_effi, mnt_FTF_effi);
257 mnt_PT_effi = n_pt_matched;
258 mnt_FTF_effi = n_ftf_matched;
259
260 // TnP monitoring
261 mon_phi_effi = me_phi;
262 mon_eta_effi = me_eta;
263 mon_pt_found = n_pt_matched;
264 mon_ftf_found = n_ftf_matched;
265 if( n_pt_matched != 0 ) {
266 if( pt_expectInnermost == 1 ) {
267 if( pt_numberInnermost>0 ) {
268 mon_pt_pix=1;
269 } else {
270 mon_pt_pix=0;
271 }
272 }
273 if( pt_expectNextToInnermost == 1 ) {
274 if( pt_numberNextToInnermost>0 ) {
275 mon_pt_pixnext=1;
276 } else {
277 mon_pt_pixnext=0;
278 }
279 }
280 }
281
282 //
283 return StatusCode::SUCCESS;
284}
285
286// --------------------------------------------------------------------------------
287// --------------------------------------------------------------------------------
288
290{
291 bool passCut = false;
292
293 const xAOD::TrackParticle* idtrack = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
294 const xAOD::TrackParticle* metrack = muon->trackParticle( xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle );
295
296 const float CHI2_CUT = 8.0;
297 const float QOVP_CUT = 7.0;
298
299 if( idtrack && metrack ) {
300 float qOverPsignif = TrigMuonEFIdtpCommon::qOverPMatching(metrack,idtrack);
301 float reducedChi2 = muon->primaryTrackParticle()->chiSquared()/muon->primaryTrackParticle()->numberDoF();
302 // Selection criteria based on the requirements that are part of the muon quality working points (offline)
303 if(std::abs(reducedChi2) < CHI2_CUT && !m_muonSelTool->isBadMuon(*muon) && qOverPsignif<QOVP_CUT && muon->author()==xAOD::Muon::MuidCo) passCut = true;
304 }
305
306 return passCut;
307}
308
309
311{
312 bool passCut = false;
313
314 const xAOD::TrackParticle* metrack = muon->trackParticle( xAOD::Muon::ExtrapolatedMuonSpectrometerTrackParticle );
315
316 const float CHI2_CUT = 8.0;
317
318 if( metrack ) {
319 float reducedChi2 = muon->primaryTrackParticle()->chiSquared()/muon->primaryTrackParticle()->numberDoF();
320 if( std::abs(reducedChi2) < CHI2_CUT && !m_muonSelTool->isBadMuon(*muon) ) passCut = true;
321 }
322
323 return passCut;
324}
325
326// --------------------------------------------------------------------------------
327// --------------------------------------------------------------------------------
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
static Double_t ss
static Double_t sc
Header file to be included by clients of the Monitored infrastructure.
ComboHypoToolBase(const std::string &type, const std::string &name, const IInterface *parent)
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
bool executeAlg(const std::vector< Combo::LegDecision > &combinaiton, const EventContext &ctx) const override
Only a dummy implementation exists in ComboHypoToolBase.
ToolHandle< CP::IMuonSelectionTool > m_muonSelTool
StatusCode doTPIdperf(const xAOD::TrackParticle *metrack, const std::vector< const xAOD::TrackParticle * > &tracks_pt, const std::vector< const xAOD::TrackParticle * > &tracks_ftf) const
bool passedSAQualityCuts(const xAOD::Muon *muon) const
ToolHandle< GenericMonitoringTool > m_monTool
bool passedCBQualityCuts(const xAOD::Muon *muon) const
TrigMuonEFIdtpInvMassHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
virtual double phi() const override final
The azimuthal angle ( ) of the particle (has range to .)
virtual double pt() const override final
The transverse momentum ( ) of the particle.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
const std::string & featureString()
int32_t getIndexFromLeg(const HLT::Identifier &legIdentifier)
Extract the numeric index of a leg identifier.
void findLinks(const Decision *start, const std::string &linkName, std::vector< LinkInfo< T > > &links, unsigned int behaviour=TrigDefs::allFeaturesOfType, std::set< const xAOD::TrigComposite * > *fullyExploredFrom=nullptr)
search back the TC links for the object of type T linked to the one of TC (recursively) Populates pro...
static const unsigned int lastFeatureOfType
Run 3 "enum". Only return the final feature along each route through the navigation.
float qOverPMatching(const xAOD::TrackParticle *metrack, const xAOD::TrackParticle *idtrack)
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Muon_v1 Muon
Reference the current persistent version:
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfNextToInnermostPixelLayerHits
these are the hits in the 1st pixel barrel layer
@ expectNextToInnermostPixelLayerHit
Do we expect a 1st-layer barrel hit for this track?
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer