ATLAS Offline Software
Loading...
Searching...
No Matches
TrigJetHypoTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ********************************************************************
6//
7// NAME: TrigJetHypoTool.cxx
8// PACKAGE: Trigger/TrigHypothesis/TrigHLTJetHypo
9//
10//
11// ********************************************************************
12
13#include "TrigJetHypoTool.h"
14
15#include "GaudiKernel/StatusCode.h"
16
20#include "./xAODJetCollector.h"
21
23
25
26
27#include <sstream>
28
35
36
38 const std::string& name,
39 const IInterface* parent) :
40 AthAlgTool(type, name, parent),
41 m_decisionID(HLT::Identifier::fromToolName(name))
42{
43}
44
45
48
50
51 if (!(m_endLabelIndex > 0)){
52 ATH_MSG_ERROR("endLabelIndex must be > 0, is " + std::to_string(m_endLabelIndex));
53 return StatusCode::FAILURE;
54 }
55
56 if (m_endLabelIndex == 1u) {
57
58 // This is a single-leg jet chain.
59 m_decisionIDs.push_back(m_decisionID);
60
61 } else {
62
63 // This is a multi-leg chain with (m_endLabelIndex - m_startLabelIndex) jet legs contained within
64
65 if(not isLegId(m_decisionID)){
66 ATH_MSG_ERROR(name() << " is being configured to do jet selection for a multi-leg chain, from leg " << m_startLabelIndex <<
67 " to " << m_endLabelIndex << ", the HypoTool's name must therefore start with legXXX_ rather than HLT_");
68 return StatusCode::FAILURE;
69 }
70
71 HLT::Identifier noLegNameDecisionID = getIDFromLeg(m_decisionID);
72 for (std::size_t i = m_startLabelIndex; i != m_endLabelIndex; ++i){
73 m_decisionIDs.push_back(createLegName(noLegNameDecisionID, i));
74 ATH_MSG_DEBUG("Adding jet-leg " << m_decisionIDs.size()-1 << " for " << noLegNameDecisionID << ", this is leg " << i << " in the chain:" << m_decisionIDs.back());
75 }
76
77 }
78
79 if (m_visitDebug){
80 DebugInfoCollector collector(name() + "_init");
81 CHECK(m_helper->getDescription(collector));
82 auto s = collector.toString();
83
84 for(const auto& l : lineSplitter(s)){
85 ATH_MSG_INFO(l);
86 }
87 }
88
89 if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve());
90 return StatusCode::SUCCESS;
91}
92
93
95 return StatusCode::SUCCESS;
96}
97
98
99StatusCode
101 const TrigCompositeUtils::DecisionIDContainer& previousDecisionIDs,
102 std::vector<JetDecision>& jetHypoInputs) const {
103
104 // need only check against the decision ID corresponding to the name
105 // of this hypo. Leg indices are irrelevant at this point.
107 previousDecisionIDs)) {
108 return StatusCode::SUCCESS;
109 }
110
111 std::unique_ptr<ITrigJetHypoInfoCollector> infocollector(nullptr);
112 std::unique_ptr<ITrigJetHypoInfoCollector> jetdumper(nullptr);
113 if(m_visitDebug){
114 auto collectorName = name() + "_" + std::to_string(m_id++);
115 infocollector.reset(new DebugInfoCollector(collectorName));
116 auto jetdumperName =
117 name()+"_passingjets_" + std::to_string(m_id++);
118 jetdumper.reset(new DebugInfoCollector(jetdumperName));
119 }
120
121
122 HypoJetVector hypoJets(jets->size());
123
124 std::transform(jets -> begin(),
125 jets -> end(),
126 hypoJets.begin(),
128
129 /* apply cleaning and hypothesis alg */
130 ATH_MSG_DEBUG("hypo helper start... "
131 << " no of jets ... "
132 << jets->size()
133 << "...");
134
135 // steady_clock::time_point t = steady_clock::now();
136 // monitoring -- timing plots (filled for every call)
137 auto mon_NInputs = Monitored::Scalar("NJetsIn",jets->size());
138 auto mon_NOutputs = Monitored::Scalar("NJetsOut",-1);
139 auto tHypo = Monitored::Timer<std::chrono::milliseconds>("TIME_jetHypo");
140 auto monitor_group_multTime = Monitored::Group( m_monTool, tHypo, mon_NOutputs, mon_NInputs);
141
142 xAODJetCollector jetCollector;
143 bool pass;
144 try{
145 pass = m_helper->pass(hypoJets, jetCollector, infocollector);
146 } catch(std::exception& e){
147 ATH_MSG_ERROR("Exception raised by the TrigJetHypoToolHelper: "
148 << e.what());
149 return StatusCode::FAILURE;
150 }
151 tHypo.stop();
152
153 if (!pass) {
154
155 if (infocollector){
156
157 std::string msg =
158 "hypo testing done: no of input jets " + std::to_string(jets->size())
159 + " no of participating jets " + std::to_string(jetCollector.size())
160 + " pass: false ";
161
162 infocollector->collect("TrigJetHypoTool", msg);
163 }
164
165 return StatusCode::SUCCESS;
166 }
167
168 CHECK(checkPassingJets(jetCollector, infocollector));
169 CHECK(reportPassingJets(jetCollector, jetHypoInputs));
170
171 // accumulateTime(steady_clock::now() - t);
172
173
174 if (infocollector){
175
176 std::string msg =
177 "hypo testing done: no of input jets " + std::to_string(jets->size())
178 + " no of particlating jets " + std::to_string(jetCollector.size())
179 + " pass: true";
180
181
182 infocollector->collect("TrigJetHypoTool", msg);
183 infocollector->write();
184
185 std::stringstream ss;
186 ss << jetCollector.hypoJets();
187 jetdumper->collect("passed", ss.str());
188 }
189
190 //monitoring -- filled in passing events
191 HypoJetVector hjv = jetCollector.hypoJets();
192
193 mon_NOutputs = hjv.size();
194 for(const auto& j : hjv) {
195 auto mon_jetEt = Monitored::Scalar("Et", j->et()*0.001);
196 auto mon_jetEta = Monitored::Scalar("Eta", j->eta());
197 auto mon_jetPhi = Monitored::Scalar("Phi", j->phi());
198 auto mon_jetMass = Monitored::Scalar("Mass", j->m()*0.001);
199 float this_z = 999;
200 float this_negLogSigma2 = 999;
201 j->getAttribute("dipz20231122_z", this_z);
202 j->getAttribute("dipz20231122_negLogSigma2", this_negLogSigma2);
203 auto mon_dipz_z = Monitored::Scalar( "dipz_z", this_z);
204 auto mon_dipz_negLogSigma2 = Monitored::Scalar( "dipz_negLogSigma2", this_negLogSigma2);
205 float this_GN2X_phbb{999.}, this_GN2X_phcc{999.}, this_GN2X_pqcd{999.}, this_GN2X_ptop{999.};
206 j->getAttribute("GN2Xv01_phbb", this_GN2X_phbb);
207 j->getAttribute("GN2Xv01_phcc", this_GN2X_phcc);
208 j->getAttribute("GN2Xv01_ptop", this_GN2X_ptop);
209 j->getAttribute("GN2Xv01_pqcd", this_GN2X_pqcd);
210 auto mon_GN2X_phbb = Monitored::Scalar("GN2Xv01_phbb", this_GN2X_phbb);
211 auto mon_GN2X_phcc = Monitored::Scalar("GN2Xv01_phcc", this_GN2X_phcc);
212 auto mon_GN2X_ptop = Monitored::Scalar("GN2Xv01_ptop", this_GN2X_ptop);
213 auto mon_GN2X_pqcd = Monitored::Scalar("GN2Xv01_pqcd", this_GN2X_pqcd);
214 float this_GN2X_discriminant{999.};
215 if (this_GN2X_phbb > 0.){
216 float top_frac{0.25};
217 float denom = this_GN2X_pqcd*(1. - top_frac) + this_GN2X_ptop * top_frac;
218 if (denom > 0.){
219 this_GN2X_discriminant = log(this_GN2X_phbb/denom);
220 }
221 }
222 auto mon_GN2X_discriminant = Monitored::Scalar("GN2Xv01_discriminant", this_GN2X_discriminant);
223
224 float this_GN2XTrig_phbb{999.}, this_GN2XTrig_pqcd{999.}, this_GN2XTrig_ptop{999.};
225 j->getAttribute("GN2XTrig_phbb", this_GN2XTrig_phbb);
226 j->getAttribute("GN2XTrig_ptop", this_GN2XTrig_ptop);
227 j->getAttribute("GN2XTrig_pqcd", this_GN2XTrig_pqcd);
228 auto mon_GN2XTrig_phbb = Monitored::Scalar("GN2XTrig_phbb", this_GN2XTrig_phbb);
229 auto mon_GN2XTrig_ptop = Monitored::Scalar("GN2XTrig_ptop", this_GN2XTrig_ptop);
230 auto mon_GN2XTrig_pqcd = Monitored::Scalar("GN2XTrig_pqcd", this_GN2XTrig_pqcd);
231 float this_GN2XTrig_discriminant{999.};
232 if (this_GN2XTrig_phbb > 0.){
233 float top_frac{0.25};
234 float denom = this_GN2XTrig_pqcd*(1. - top_frac) + this_GN2XTrig_ptop * top_frac;
235 if (denom > 0.){
236 this_GN2XTrig_discriminant = log(this_GN2XTrig_phbb/denom);
237 }
238 }
239 auto mon_GN2XTrig_discriminant = Monitored::Scalar("GN2XTrig_discriminant", this_GN2XTrig_discriminant);
240
241 auto monitor_group_passingjets = Monitored::Group( m_monTool, mon_jetEt, mon_jetEta, mon_jetPhi , mon_dipz_z, mon_dipz_negLogSigma2, mon_jetMass, mon_GN2X_phbb, mon_GN2X_phcc, mon_GN2X_ptop, mon_GN2X_pqcd, mon_GN2X_discriminant, mon_GN2XTrig_phbb, mon_GN2XTrig_ptop, mon_GN2XTrig_pqcd, mon_GN2XTrig_discriminant);
242
243 }
244 //monitor the passing jets for each leg (there should only be one per chain!)
245 auto legInds = jetCollector.legInds();
246 for (const auto& label : legInds) {
247 auto jets = jetCollector.hypoJets(label);
248 auto monitor_nJt = Monitored::Scalar( "NJets", jets.size());
249 auto htsum = Monitored::Scalar("HT", std::accumulate(jets.begin(), jets.end(),0.0,
250 [](double sum, const HypoJetVector::value_type jptr){return sum + jptr->et()*0.001;} ));
251 auto monitor_group_passinght = Monitored::Group(m_monTool, monitor_nJt,htsum);
252 }
253
254 return StatusCode::SUCCESS;
255}
256
257
258const std::vector<HLT::Identifier>& TrigJetHypoTool::getIDs() const{
259 return m_decisionIDs;
260}
261
262
263const HLT::Identifier& TrigJetHypoTool::getID(std::size_t i) const{
264 return m_decisionIDs.at(i-m_startLabelIndex);
265}
266
267
268StatusCode
270 const std::unique_ptr<ITrigJetHypoInfoCollector>& infocollector) const {
271
272 if (jetCollector.empty()) {
273 ATH_MSG_ERROR("HypoTool passed the event for " <<
274 m_chainName << " ev " << m_id <<
275 ", but did not specify which jets participated");
276 return StatusCode::FAILURE;
277 }
278
279 auto legIndices = jetCollector.legInds();
280 if (!(legIndices.size() == (m_endLabelIndex - m_startLabelIndex))) {
281 ATH_MSG_ERROR("inconsistent number of leg indices");
282 return StatusCode::FAILURE;
283 }
284
285 ATH_MSG_DEBUG("check passing jets? does it work?");
286 ATH_MSG_DEBUG("There are some indices: " << legIndices.size());
287 for(size_t i = 0; i < legIndices.size(); i ++){
288 ATH_MSG_DEBUG(" -- leg " << i << " has index " << legIndices.at(i));
289 }
290
291 // jet hypo inputs:
292 // pairs of const xAOD::Jet* (first) and mutable Decision* (second)
293
294 auto participating_jets = jetCollector.xAODJets();
295 if (infocollector) {
296 infocollector->
297 collect(name(),
298 "no of xAODJets " + std::to_string(participating_jets.size()));
299
300 auto legInds = jetCollector.legInds();
301 std::stringstream ss;
302
303 for(const auto& label : legInds){
304 auto jets = jetCollector.xAODJets(label);
305 ss << label << " [\n";
306 for(const auto& j : jets){
308 }
309 ss << "]\n";
310 }
311 infocollector->collect(name(), ss.str());
312 }
313
314 return StatusCode::SUCCESS;
315}
316
317StatusCode
319 const std::vector<JetDecision>& jetHypoInputs) const {
320
321 auto legIndices = jetCollector.legInds();
322 for(const auto& legInd : legIndices){
323 auto participating_jets = jetCollector.xAODJets(legInd);
324 CHECK(reportLeg(participating_jets, jetHypoInputs, legInd));
325 }
326
327 return StatusCode::SUCCESS;
328}
329
330
331
332
333StatusCode
334TrigJetHypoTool::reportLeg(const std::vector<const xAOD::Jet*>& jets,
335 const std::vector<JetDecision>& jetHypoInputs,
336 int legInd) const {
337
338 // check if input jet is a participating jet. If so , add
339 // its Decision object.
340 for (auto& pair : jetHypoInputs) {
341 if (!inputJetParticipates(jets, pair)){continue;}
342
343 TrigCompositeUtils::DecisionIDContainer passingIDs; // set<uint32_t>
344
345 // Add the Leg DecisionID.
346 // Required by any downstream Steps which need to consume jets which
347 // are satisfying this leg's jet cuts and by the following ComboHypo
348 // Note that if the chain is single-leg, then the ID will be the chain-ID
349 // rathe than a leg-specific ID
350 passingIDs.insert(getID(legInd).numeric());
351
352 // Copy these passingIDs into the Decision Object
353 // This call also performs de-duplication
355 }
356
357 return StatusCode::SUCCESS;
358}
359
360
361bool
362TrigJetHypoTool::inputJetParticipates(const std::vector<const xAOD::Jet*>& jets,
363 const JetDecision& pair) const {
364
365 return std::find(jets.begin(), jets.end(), pair.first) != jets.end();
366}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
std::vector< pHypoJet > HypoJetVector
Definition HypoJetDefs.h:27
static Double_t ss
Header file to be included by clients of the Monitored infrastructure.
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
HLT::Identifier getIDFromLeg(const HLT::Identifier &legIdentifier)
Generate the HLT::Identifier which corresponds to the chain name from the leg name.
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
MsgStream & msg() const
virtual std::string toString() const override
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
A monitored timer.
StatusCode checkPassingJets(const xAODJetCollector &, const std::unique_ptr< ITrigJetHypoInfoCollector > &) const
std::vector< HLT::Identifier > m_decisionIDs
StatusCode finalize()
std::atomic< size_t > m_id
TrigJetHypoTool(const std::string &type, const std::string &name, const IInterface *parent)
StatusCode reportLeg(const std::vector< const xAOD::Jet * > &jets, const std::vector< JetDecision > &jetHypoInputs, int legInd) const
std::pair< const xAOD::Jet *, TrigCompositeUtils::Decision * > JetDecision
ToolHandle< ITrigJetHypoToolHelper > m_helper
Gaudi::Property< std::size_t > m_endLabelIndex
Gaudi::Property< bool > m_visitDebug
const std::vector< HLT::Identifier > & getIDs() const
Gaudi::Property< std::string > m_chainName
ToolHandle< GenericMonitoringTool > m_monTool
const HLT::Identifier & getID(std::size_t) const
StatusCode initialize()
Gaudi::Property< std::size_t > m_startLabelIndex
HLT::Identifier m_decisionID
StatusCode decide(const xAOD::JetContainer *jets, const TrigCompositeUtils::DecisionIDContainer &previousDecisionIDs, std::vector< JetDecision > &jetHypoInputs) const
bool inputJetParticipates(const std::vector< const xAOD::Jet * > &jets, const JetDecision &pair) const
StatusCode reportPassingJets(const xAODJetCollector &, const std::vector< JetDecision > &jetHypoInputs) const
STL class.
std::vector< const xAOD::Jet * > xAODJets() const
std::size_t size() const
HypoJetVector hypoJets() const
std::vector< int > legInds() const
std::string label(const std::string &format, int i)
Definition label.h:19
std::vector< std::string > lineSplitter(const std::string &s, char delimiter)
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
unsigned int DecisionID
void insertDecisionIDs(const Decision *src, Decision *dest)
Appends the decision IDs of src to the dest decision object.
HLT::Identifier getIDFromLeg(const HLT::Identifier &legIdentifier)
Generate the HLT::Identifier which corresponds to the chain name from the leg name.
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
std::set< DecisionID > DecisionIDContainer
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
JetContainer_v1 JetContainer
Definition of the current "jet container version".