ATLAS Offline Software
Loading...
Searching...
No Matches
TrigTauMonitorDiTauAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#if __GNUC__ >= 16
6// Suppress false-positive warning seen with gcc16.
7# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
8#endif
9
12
13
14TrigTauMonitorDiTauAlgorithm::TrigTauMonitorDiTauAlgorithm(const std::string& name, ISvcLocator* pSvcLocator)
15 : TrigTauMonitorBaseAlgorithm(name, pSvcLocator)
16{}
17
18
19StatusCode TrigTauMonitorDiTauAlgorithm::processEvent(const EventContext& ctx) const
20{
21 constexpr float threshold_offset = 10.0;
22
23 // Offline taus
24 auto offline_taus_all = getOfflineTausAll(ctx, 0.0);
25 if(m_requireOfflineTaus && offline_taus_all.empty()) return StatusCode::SUCCESS;
26
27 for(const std::string& trigger : m_triggers) {
28 const TrigTauInfo& info = getTrigInfo(trigger);
29
30 if(!info.isHLTDiTau()) {
31 ATH_MSG_WARNING("Chain \"" << trigger << "\" is not a di-tau trigger. Skipping...");
32 continue;
33 }
34
35 const auto passBits = m_trigDecTool->isPassedBits(trigger);
36 const bool l1_accept_flag = passBits & TrigDefs::L1_isPassedAfterVeto;
37 const bool hlt_not_prescaled_flag = (passBits & TrigDefs::EF_prescaled) == 0;
38
39 // Offline tau requirement check
40 std::vector<const xAOD::TauJet*> offline_taus_with_id = classifyTausAll(ctx, offline_taus_all, 0, static_cast<TauID>(m_offline_tau_id.value()));
41 if(m_requireOfflineTaus && offline_taus_with_id.empty()) continue;
42
43 // Filter offline taus
44 std::vector<const xAOD::TauJet*> offline_taus = classifyTausAll(ctx, offline_taus_with_id, info.getHLTTauThreshold() - threshold_offset);
45
46 // Online taus
47 std::vector<const xAOD::TauJet*> hlt_taus = getOnlineTausAll(trigger, true, info.isBootstrappedTauTrigger());
48
49 if(m_do_variable_plots) fillDiTauVars(trigger, hlt_taus);
50 if(m_do_efficiency_plots && hlt_not_prescaled_flag) fillDiTauHLTEfficiencies(ctx, trigger, l1_accept_flag, offline_taus, hlt_taus);
51 }
52
53 return StatusCode::SUCCESS;
54}
55
56
57void TrigTauMonitorDiTauAlgorithm::fillDiTauHLTEfficiencies(const EventContext& ctx, const std::string& trigger, const bool l1_accept_flag, const std::vector<const xAOD::TauJet*>& offline_tau_vec, const std::vector<const xAOD::TauJet*>& online_tau_vec) const
58{
59 ATH_MSG_DEBUG("Fill DiTau HLT efficiencies: " << trigger);
60
61 const TrigTauInfo& info = getTrigInfo(trigger);
62
63 // Require 2 offline taus
64 if(offline_tau_vec.size() != 2) return;
65
66 auto monGroup = getGroup(trigger+"_DiTauHLT_Efficiency");
67
68 auto dR = Monitored::Scalar<float>("dR", 0.0);
69 auto dEta = Monitored::Scalar<float>("dEta", 0.0);
70 auto dPhi = Monitored::Scalar<float>("dPhi", 0.0);
71 auto averageMu = Monitored::Scalar<float>("averageMu", 0.0);
72 auto HLT_match = Monitored::Scalar<bool>("HLT_pass", false);
73 auto HLT_match_highPt = Monitored::Scalar<bool>("HLT_pass_highPt", false);
74 auto Total_match = Monitored::Scalar<bool>("Total_pass", false);
75 auto Total_match_highPt = Monitored::Scalar<bool>("Total_pass_highPt", false);
76
77 // efficiency denominator : two offline taus and two online taus (this guarantees that the event passed L1), not necesarily matched
78 // efficiency numerator : hlt fires + two offline taus matched with online taus
79 bool hlt_fires = m_trigDecTool->isPassed(trigger, TrigDefs::Physics);
80 bool tau0_match = matchObjects(offline_tau_vec.at(0), online_tau_vec, 0.2);
81 bool tau1_match = matchObjects(offline_tau_vec.at(1), online_tau_vec, 0.2);
82
83 dR = offline_tau_vec.at(0)->p4().DeltaR(offline_tau_vec.at(1)->p4());
84 dEta = std::abs(offline_tau_vec.at(0)->p4().Eta() - offline_tau_vec.at(1)->p4().Eta());
85 dPhi = offline_tau_vec.at(0)->p4().DeltaPhi(offline_tau_vec.at(1)->p4());
86 averageMu = lbAverageInteractionsPerCrossing(ctx);
87 HLT_match = hlt_fires && tau0_match && tau1_match;
88
89 float tau0_pT = offline_tau_vec.at(0)->pt()/Gaudi::Units::GeV;
90 float tau1_pT = offline_tau_vec.at(1)->pt()/Gaudi::Units::GeV;
91 bool is_highPt = tau0_pT > info.getHLTTauThresholds().at(0) + 20.0 && tau1_pT > info.getHLTTauThresholds().at(1) + 20.0;
92
93 // Total efficiency (without L1 matching)
95 Total_match = static_cast<bool>(HLT_match);
96 fill(monGroup, dR, dEta, dPhi, Total_match);
97
98 if(is_highPt) {
99 Total_match_highPt = static_cast<bool>(HLT_match);
100 fill(monGroup, dR, dEta, dPhi, Total_match_highPt);
101 }
102 }
103
104 // Require also 2 online tau candidates (thus, the efficiency is with respect to L1)
105 if(l1_accept_flag && online_tau_vec.size() == 2) {
106 fill(monGroup, dR, dEta, dPhi, averageMu, HLT_match);
107
108 if(is_highPt) {
109 HLT_match_highPt = static_cast<bool>(HLT_match);
110 fill(monGroup, dR, dEta, dPhi, HLT_match_highPt);
111 }
112 }
113
114 ATH_MSG_DEBUG("After fill DiTau HLT efficiencies: " << trigger);
115}
116
117
118void TrigTauMonitorDiTauAlgorithm::fillDiTauVars(const std::string& trigger, const std::vector<const xAOD::TauJet*>& tau_vec) const
119{
120 ATH_MSG_DEBUG("Fill DiTau Variables: " << trigger);
121
122 auto monGroup = getGroup(trigger+"_DiTauVars");
123
124 if(tau_vec.size() != 2) return;
125
126 auto leadHLTEt = Monitored::Scalar<float>("leadHLTEt", 0.0);
127 auto subleadHLTEt = Monitored::Scalar<float>("subleadHLTEt", 0.0);
128 auto leadHLTEta = Monitored::Scalar<float>("leadHLTEta", 0.0);
129 auto subleadHLTEta = Monitored::Scalar<float>("subleadHLTEta", 0.0);
130 auto leadHLTPhi = Monitored::Scalar<float>("leadHLTPhi", 0.0);
131 auto subleadHLTPhi = Monitored::Scalar<float>("subleadHLTPhi", 0.0);
132 auto dR = Monitored::Scalar<float>("dR", 0.0);
133 auto dEta = Monitored::Scalar<float>("dEta", 0.0);
134 auto dPhi = Monitored::Scalar<float>("dPhi", 0.0);
135
136 auto Pt = Monitored::Scalar<float>("Pt", 0.0);
137 auto Eta = Monitored::Scalar<float>("Eta", 0.0);
138 auto Phi = Monitored::Scalar<float>("Phi", 0.0);
139 auto M = Monitored::Scalar<float>("M", 0.0);
140 auto dPt = Monitored::Scalar<float>("dPt", 0.0);
141
142 // Get the index of the leading and the subleading tau
143 unsigned int index0 = 0, index1 = 1;
144 if(tau_vec.at(1)->p4().Pt() > tau_vec.at(0)->p4().Pt()) {
145 index0 = 1;
146 index1 = 0;
147 }
148
149 TLorentzVector leadTau4V, subleadTau4V, diTau4V;
150 leadTau4V.SetPtEtaPhiM(0,0,0,0);
151 subleadTau4V.SetPtEtaPhiM(0,0,0,0);
152
153 leadTau4V = tau_vec.at(index0)->p4();
154 subleadTau4V = tau_vec.at(index1)->p4();
155 diTau4V = leadTau4V + subleadTau4V;
156
157 leadHLTEt = leadTau4V.Pt()/Gaudi::Units::GeV;
158 subleadHLTEt = subleadTau4V.Pt()/Gaudi::Units::GeV;
159 leadHLTEta = leadTau4V.Eta();
160 subleadHLTEta = subleadTau4V.Eta();
161 leadHLTPhi = leadTau4V.Phi();
162 subleadHLTPhi = subleadTau4V.Phi();
163 dR = leadTau4V.DeltaR(subleadTau4V);
164 dEta = std::abs(leadTau4V.Eta() - subleadTau4V.Eta());
165 dPhi = leadTau4V.DeltaPhi(subleadTau4V);
166
167 dPt = std::abs((leadTau4V.Pt() - subleadTau4V.Pt())/Gaudi::Units::GeV);
168 Pt = diTau4V.Pt()/Gaudi::Units::GeV;
169 Eta = diTau4V.Eta();
170 Phi = diTau4V.Phi();
171 M = diTau4V.M()/Gaudi::Units::GeV;
172
173 fill(monGroup, leadHLTEt, subleadHLTEt, leadHLTEta, subleadHLTEta, leadHLTPhi, subleadHLTPhi, dR, dEta, dPhi, dPt, Pt, Eta, Phi, M);
174
175 ATH_MSG_DEBUG("After fill DiTau variables: " << trigger);
176}
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
PublicToolHandle< Trig::TrigDecisionTool > m_trigDecTool
Tool to tell whether a specific trigger is passed.
Declare a monitored scalar variable.
Gaudi::Property< bool > m_do_efficiency_plots
double dR(const double eta1, const double phi1, const double eta2, const double phi2) const
TrigTauMonitorBaseAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< const xAOD::TauJet * > getOfflineTausAll(const EventContext &ctx, const float threshold=20.0) const
bool matchObjects(const T1 *tau, const std::vector< const T2 * > &tau_vec, float threshold) const
Gaudi::Property< std::vector< std::string > > m_triggers
const TrigTauInfo & getTrigInfo(const std::string &trigger) const
std::vector< const xAOD::TauJet * > classifyTausAll(const EventContext &ctx, const std::vector< const xAOD::TauJet * > &taus, const float threshold=0.0, const TauID tau_id=TauID::None) const
std::vector< const xAOD::TauJet * > getOnlineTausAll(const std::string &trigger, bool include_0P=true, bool filter_legs=false) const
Gaudi::Property< bool > m_do_variable_plots
void fillDiTauVars(const std::string &trigger, const std::vector< const xAOD::TauJet * > &tau_vec) const
TrigTauMonitorDiTauAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
void fillDiTauHLTEfficiencies(const EventContext &ctx, const std::string &trigger, const bool l1_accept_flag, const std::vector< const xAOD::TauJet * > &offline_tau_vec, const std::vector< const xAOD::TauJet * > &online_tau_vec) const
Gaudi::Property< unsigned int > m_offline_tau_id
virtual StatusCode processEvent(const EventContext &ctx) const override
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > &&variables) const
Fills a vector of variables to a group by reference.
virtual float lbAverageInteractionsPerCrossing(const EventContext &ctx) const
Calculate the average mu, i.e.