ATLAS Offline Software
Loading...
Searching...
No Matches
JetTriggerDecoratorAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include <algorithm>
10
11namespace CP
12{
14 ISvcLocator *svcLoc)
15 : EL::AnaAlgorithm(name, svcLoc),
16 m_trigDecisionTool("Trig::TrigDecisionTool/TrigDecisionTool")
17 {
18 declareProperty("TrigDecisionTool", m_trigDecisionTool, "trigger decision tool");
19 }
20
49
50
51
56 ANA_CHECK(l1Jets.isValid());
57 }
58 std::regex l1NameParser("(\\d*)(J)(\\d*)((p|\\.)(\\d*)ETA(\\d*))?");
59
61 if (m_doHLTMatching) {
63 ANA_MSG_DEBUG(m_trigger << " isPassed "<<m_emulationTool->isPassed(m_trigger));
64 else {
65 hltJetsFromCont = SG::makeHandle(m_HLTJetsInKey);
66 ANA_CHECK(hltJetsFromCont.isValid());
67 }
68 }
69
72 // prepare Run2 emulation results
73 std::unordered_map<std::string, std::vector<std::pair<const xAOD::Jet*, bool>>> emulatedJets = {};
75 emulatedJets = m_emulationTool->getEmulatedJets(m_trigger);
76 bool isTrigPassed = m_trigDecisionTool->isPassed(m_trigger);
77 const TrigConf::HLTChain* hltChain = m_trigDecisionTool->ExperimentalAndExpertMethods().getChainConfigurationDetails(m_trigger);
78 const std::string& l1Name = hltChain->lower_chain_name();
79
80 for (const auto& sys : m_systematicsList.systematicsVector())
81 {
82 const xAOD::JetContainer *jets = nullptr;
83 ANA_CHECK(m_jetsHandle.retrieve(jets, sys));
84
85 for (const xAOD::Jet *jet : *jets)
86 {
90
91 if (m_doL1Matching){
92 const xAOD::JetRoI* bestL1 = nullptr;
93 float minDRL1 = m_dR.value();
94 std::set<int> L1Thresholds = {};
95
96 if (isTrigPassed) {
97
98 for (const auto l1_jet : *l1Jets) {
99 TLorentzVector l1_jet_p4;
100 l1_jet_p4.SetPtEtaPhiM(l1_jet->et8x8(), l1_jet->eta(), l1_jet->phi(), 0.);
101 float dR = jet->p4().DeltaR(l1_jet_p4);
102 if (dR < minDRL1) {
103 minDRL1 = dR;
104 bestL1 = l1_jet;
105
106 std::vector<std::string> thrNames = l1_jet->thrNames();
107 std::stringstream ss(std::regex_replace(l1Name, std::regex("-"), "_"));
108 std::string legName;
109 std::smatch match;
110 // loop over legs
111 while (getline(ss, legName, '_')) {
112 if (std::regex_match(legName, match, l1NameParser)) {
113 std::string legName_noMultiplicity = match[2].str() + match[3].str() + match[4].str();
114 int threshold = match[3].str()=="" ? 1 : std::stoi(match[3].str());
115 // compare with passed thresholds
116 for (const auto &thr : thrNames) {
117 if (thr == legName_noMultiplicity)
118 L1Thresholds.insert(threshold);
119 }
120 } // end of regex match
121 } // loop over legs
122 }
123 } // loop over L1 jets
124 }
125
126 m_L1Et_decor.set(*jet, bestL1 ? bestL1->et8x8() : -99., sys);
127 m_L1Eta_decor.set(*jet, bestL1 ? bestL1->eta() : -99., sys);
128 m_L1Phi_decor.set(*jet, bestL1 ? bestL1->phi() : -99., sys);
129 m_L1DR_decor.set(*jet, minDRL1, sys);
130
131 std::vector<int> l1Thresh;
132 if(bestL1) l1Thresh = std::vector<int>(L1Thresholds.begin(), L1Thresholds.end());
133 m_L1Threshold_decor.set(*jet, l1Thresh, sys);
134 } // end L1 matching
135
139
140 if (m_doHLTMatching){
141 const xAOD::IParticle* bestHLT = nullptr;
142 float minDRHLT = m_dR.value();
143 std::set<int> HLTThresholds = {};
144
145 if (isTrigPassed) {
146 int ileg = 0;
147 for (const ChainNameParser::LegInfo &legInfo :
149 if (legInfo.signature == "j") {
150 ANA_MSG_VERBOSE(" Leg" << ileg << ": "
151 << " " << legInfo.legName() << " "
152 << legInfo.type() << " " << legInfo.signature
153 << " " << legInfo.threshold);
154
155 int legThreshold = legInfo.threshold;
156
157 if (legInfo.legName().find("gsc") != std::string::npos)
158 {
159 for (auto part : legInfo.legParts)
160 {
161 if (part.find("gsc") != std::string::npos)
162 {
163 legThreshold = std::stoi(part.substr(3));
164 ATH_MSG_DEBUG("GSC leg found. Using threshold " << legThreshold);
165 break;
166 }
167 }
168 }
169
170
174
175 if (m_useEmulationTool) {
176 auto hlt_emulated_jets = emulatedJets[legInfo.legName()]; // use pre-fetched emulation results
177 ANA_MSG_DEBUG(" Emulated jets for " << legInfo.legName() << ": " << hlt_emulated_jets.size());
178
179 for (const auto& [hlt_jet, passBtag]: hlt_emulated_jets) {
180 float dR = jet->p4().DeltaR(hlt_jet->p4());
181 ANA_MSG_VERBOSE(" pt: " << hlt_jet->pt()
182 << " eta: " << hlt_jet->eta()
183 << " phi: " << hlt_jet->phi()
184 << " dR: " << dR);
185
186 if (bestHLT && isSameJet(bestHLT, hlt_jet))
187 HLTThresholds.insert(legThreshold);
188 else if (dR < minDRHLT) {
189 minDRHLT = dR;
190 bestHLT = hlt_jet;
191 HLTThresholds.clear();
192 HLTThresholds.insert(legThreshold);
193 }
194 }
195 }
196
200
201 else {
202 frd.setRestrictRequestToLeg(ileg);
203 auto hlt_jetsFromtrigDec = m_trigDecisionTool->features<xAOD::IParticleContainer>(frd);
204 std::vector<const xAOD::IParticle*> allHLTJets;
205
206 for (const auto& hlt_jet_link : hlt_jetsFromtrigDec) {
207 const xAOD::IParticle *hlt_jetFromtrigDec = *hlt_jet_link.link;
208 if (!hlt_jetFromtrigDec) continue;
209 allHLTJets.push_back(hlt_jetFromtrigDec);
210 }
211
212 // Start adding missing HLT jets -- only for buggy triggers
213 if (std::find(m_triggerNavBug.begin(),
214 m_triggerNavBug.end(),
215 m_trigger) != m_triggerNavBug.end()) {
216 for (const xAOD::Jet* jetFromCont : *hltJetsFromCont) {
217 bool alreadyIn = false;
218 for (const xAOD::IParticle* seenJet : allHLTJets) {
219 if (isSameJet(seenJet, jetFromCont)) {
220 alreadyIn = true;
221 break;
222 }
223 }
224 if (alreadyIn) continue;
225
226 allHLTJets.push_back(jetFromCont);
227 ANA_MSG_DEBUG("Added missing HLT jet from container: pt="
228 << jetFromCont->pt() << " eta=" << jetFromCont->eta()
229 << " phi=" << jetFromCont->phi());
230 }
231 }
232
233 for (const xAOD::IParticle* hlt_jet : allHLTJets) {
234 float dR = jet->p4().DeltaR(hlt_jet->p4());
235 bool fromtrigDec = false;
236 for (const auto& hlt_jet_link : hlt_jetsFromtrigDec) {
237 if (*hlt_jet_link.link == hlt_jet) {
238 fromtrigDec = true;
239 break;
240 }
241 }
242
243 ANA_MSG_VERBOSE(" pt: "
244 << hlt_jet->pt() << " eta: " << hlt_jet->eta()
245 << " phi: " << hlt_jet->phi() << " dR: " << dR
246 << " (fromContainer=" << !fromtrigDec << ")");
247
248 if (bestHLT && isSameJet(bestHLT, hlt_jet))
249 HLTThresholds.insert(legThreshold);
250 else if (dR < minDRHLT)
251 {
252 minDRHLT = dR;
253 bestHLT = hlt_jet;
254 HLTThresholds.clear();
255 HLTThresholds.insert(legThreshold);
256 }
257 } // Loop over allHLTJets
258 } // end Run 3 access
259 }
260 ileg++;
261 }
262 }
263
264 m_HLTPt_decor.set(*jet, bestHLT ? bestHLT->pt() : -99., sys);
265 m_HLTEta_decor.set(*jet, bestHLT ? bestHLT->eta() : -99., sys);
266 m_HLTPhi_decor.set(*jet, bestHLT ? bestHLT->phi() : -99., sys);
267 m_HLTDR_decor.set(*jet, minDRHLT, sys);
268
269 std::vector<int> hltThresh;
270 if(bestHLT) hltThresh = std::vector<int>(HLTThresholds.begin(), HLTThresholds.end());
271 m_HLTThreshold_decor.set(*jet, hltThresh, sys);
272
273 ANA_MSG_VERBOSE("Summary " << " Trigger: " << m_trigger << " bestHLT pT: "
274 << (bestHLT ? bestHLT->pt() : -99.));
275
276 }
277 }
278 };
279 return StatusCode::SUCCESS;
280 }
281
282
284 {
285 // Need this function because jet1 == jet2 would return false when comparing b-jet to untagged jet
286 return (jet1->p4().DeltaR(jet2->p4()) < 0.01) && (std::abs(jet1->pt() - jet2->pt()) < 100);
287 }
288
289}
#define ATH_MSG_DEBUG(x)
#define ANA_MSG_VERBOSE(xmsg)
Macro printing verbose messages.
#define ANA_MSG_DEBUG(xmsg)
Macro printing debug messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
static Double_t ss
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
SysListHandle m_systematicsList
the systematics list we run
Gaudi::Property< bool > m_doHLTMatching
JetTriggerDecoratorAlg(const std::string &name, ISvcLocator *svcLoc=nullptr)
Gaudi::Property< bool > m_useEmulationTool
CP::SysWriteDecorHandle< std::vector< int > > m_L1Threshold_decor
CP::SysWriteDecorHandle< float > m_HLTPt_decor
CP::SysWriteDecorHandle< float > m_HLTPhi_decor
CP::SysWriteDecorHandle< std::vector< int > > m_HLTThreshold_decor
ToolHandle< Trig::ITrigBtagEmulationTool > m_emulationTool
bool isSameJet(const xAOD::IParticle *jet1, const xAOD::IParticle *jet2) const
Gaudi::Property< std::vector< std::string > > m_triggerNavBug
CP::SysWriteDecorHandle< float > m_L1Eta_decor
CP::SysWriteDecorHandle< float > m_L1DR_decor
CP::SysReadHandle< xAOD::JetContainer > m_jetsHandle
SG::ReadHandleKey< xAOD::JetContainer > m_HLTJetsInKey
CP::SysWriteDecorHandle< float > m_HLTEta_decor
Gaudi::Property< std::string > m_trigger
Gaudi::Property< float > m_dR
ToolHandle< Trig::TrigDecisionTool > m_trigDecisionTool
CP::SysWriteDecorHandle< float > m_HLTDR_decor
CP::SysWriteDecorHandle< float > m_L1Et_decor
SG::ReadHandleKey< xAOD::JetRoIContainer > m_L1JetsInKey
Gaudi::Property< bool > m_doL1Matching
CP::SysWriteDecorHandle< float > m_L1Phi_decor
Helper class that provides access to information about individual legs.
AnaAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
constructor with parameters
virtual bool isValid() override final
Can the handle be successfully dereferenced?
HLT chain configuration information.
const std::string & lower_chain_name() const
FeatureRequestDescriptor & setChainGroup(const std::string &chainGroupName)
Set the desired Chain or Chain Group.
FeatureRequestDescriptor & setRestrictRequestToLeg(const int restrictToLegIndex)
Set to -1 by default, indicating that all legs of multi-leg chains are searched.
Class providing the definition of the 4-vector interface.
virtual double eta() const =0
The pseudorapidity ( ) of the particle.
virtual FourMom_t p4() const =0
The full 4-momentum of the particle.
virtual double pt() const =0
The transverse momentum ( ) of the particle.
virtual double phi() const =0
The azimuthal angle ( ) of the particle.
float et8x8() const
The energy deposited in a 0.8x0.8 area around the RoI.
const std::vector< std::string > & thrNames() const
The names of the thresholds passed by jet candidate.
float eta() const
The pseudorapidity ( ) of the jet candidate.
float phi() const
The azimuthal angle ( ) of the jet candidate.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:359
Select isolated Photons, Electrons and Muons.
This module defines the arguments passed from the BATCH driver to the BATCH worker.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Jet_v1 Jet
Definition of the current "jet version".
JetRoI_v2 JetRoI
Definition JetRoI.h:16
JetContainer_v1 JetContainer
Definition of the current "jet container version".
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
Struct containing information on each leg of a chain.