ATLAS Offline Software
Loading...
Searching...
No Matches
TrigJetHypoAlg.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#include <algorithm>
6#include "TrigJetHypoAlg.h"
10
11using namespace TrigCompositeUtils;
12
14
15TrigJetHypoAlg::TrigJetHypoAlg( const std::string& name,
16 ISvcLocator* pSvcLocator ) :
17 ::HypoBase( name, pSvcLocator ) {}
18
19
21
22 // Jet special case: only one jet HypoTool is provided per chain, even if the chain has multiple jet legs.
23 // Suppose HLT_e5_2e10_j10_j20_mu40. Only the leg002 jet HypoTool will be provided, and this will
24 // compute the result for both the leg002 and leg003 here.
25 for (auto& tool : m_hypoTools) {
26 if (not tool.empty()) {
27 ATH_CHECK(tool.retrieve());
28 }
29 }
30 CHECK( m_jetsKey.initialize() );
31 return StatusCode::SUCCESS;
32}
33
34
35StatusCode TrigJetHypoAlg::execute( const EventContext& context ) const {
36 ATH_MSG_DEBUG ( "Executing " << name() << "..." );
37
38
39 // read in the previous Decisions made before running this hypo Alg.
40 // The container should have only one such Decision (for L1) as deciding
41 // on jets is a one step process.
42
43 ATH_MSG_DEBUG("Retrieving L1 decision \"" << decisionInput().key() << "\"");
44 auto h_prevDecisions = SG::makeHandle(decisionInput(), context );
45
46 if( not h_prevDecisions.isValid() || h_prevDecisions->size() ==0) {//implicit
47 ATH_MSG_DEBUG( "No implicit RH for previous decisions "<< decisionInput().key()<<": is this expected?" );
48 return StatusCode::SUCCESS;
49 }
50
51 if(h_prevDecisions->size() != 1){
52 ATH_MSG_ERROR(" Expected one previous decisions in " << decisionInput().key()
53 << " (L1 RoIs not used), found " << h_prevDecisions->size());
54 return StatusCode::FAILURE;
55 }
56
57 const DecisionContainer* prevDecisions = h_prevDecisions.get();
58 const Decision* previousDecision = prevDecisions->at(0);
59
60 // previousDecision contains all active jet chains (i.e. seeded by L1,
61 // passed prescale)
62
63 // Create container to write output Decision objects - there will be one per
64 // jet
67
68 DecisionContainer* outputDecisions = outputHandle.ptr();
69
70 // read in a jets collection, and obtain a bare pointer to it
71
72 auto h_jets = SG::makeHandle(m_jetsKey, context );
73 ATH_MSG_DEBUG("Retrieving jets from: " << h_jets.key());
74 ATH_CHECK(h_jets.isValid());
75
76 const JetContainer* jets = h_jets.get();
77
78 CHECK(decide(jets, previousDecision, outputDecisions, context));
79
80 // Common debug printing and output checking
82
83 return StatusCode::SUCCESS;
84}
85
86StatusCode
88 const Decision* previousDecision,
89 DecisionContainer* outputDecisions,
90 const EventContext& context) const{
91
92 // Pair to associate each jet with its corresponding Decision object -
93 // this will record the chains which the jet passes.
94
95 std::vector<std::pair<const xAOD::Jet*,Decision*>> jetHypoInputs;
96 jetHypoInputs.reserve(jets->size());
97
98 if(m_doPresel) {
99 // In the preselection case, we create only one DecisionObject, which links
100 // all jets -- this is so as to avoid making spurious DecisionObject
101 // chains where the objects in one step have no unambiguous relationship
102 // with those in the preceding step.
103 Decision* newDecision = nullptr;
104 newDecision = TrigCompositeUtils::newDecisionIn(outputDecisions, previousDecision, TrigCompositeUtils::hypoAlgNodeName(), context);
105 // Needs a dummy feature link -- we will specify the input RoI which triggers special behaviour in the ComboHypo, equivilant to the "noCombo" below
109 }
110 // We need to fill the jetHypoInputs vector, pairing each jet with
111 // the same newDecision object, such that it is updated if the hypo
112 // tool passes the jet.
113 // In the opposite direction, we link the jets from the object for
114 // retrieval subsequently.
115 // *Linked jets are not implied to be responsible for a passing decision*
116 //
117 bool first=true;
118 for (const xAOD::Jet* jet : *jets) {
119 jetHypoInputs.push_back( std::make_pair(jet, newDecision) );
120 if(first) {
121 // We receive a VIEW container with filtered jets, so need to retrieve the original
122 const xAOD::JetContainer* jetCont = static_cast<const xAOD::JetContainer*>(jet->container());
123 ATH_MSG_VERBOSE("Creating element link to presel jet " << jet->index() << " of " << jetCont->size());
124 newDecision->setObjectLink<xAOD::JetContainer>("LeadingPreselJet",ElementLink<xAOD::JetContainer>(*jetCont, jet->index()));
125 }
126 }
127
128 ATH_MSG_DEBUG("Output decision object:");
129 ATH_MSG_DEBUG( *newDecision );
130
131 } else {
132 // When operating as a terminal hypo selection, we create one DecisionObject
133 // per jet, which is later used to identify which jets contributed to an
134 // event passing.
135 for (const xAOD::Jet* jet : *jets) {
136
137 Decision* newDecision = nullptr;
138 // Create a new Decision object to mirror this Jet.
139 // Link it to its parent Decision object and attach the jet as a "feature"
140 newDecision = TrigCompositeUtils::newDecisionIn(outputDecisions, previousDecision, TrigCompositeUtils::hypoAlgNodeName(), context);
141
142 // We receive a VIEW container with filtered jets, so need to retrieve the original
143 const xAOD::JetContainer* jetCont = static_cast<const xAOD::JetContainer*>(jet->container());
145 ElementLink<xAOD::JetContainer>(*jetCont, jet->index());
146
147 // Create a decoration. This is used to comminicate to the following ComboHypo that the
148 // DecisionObject should be excluded from downstream multiplicity checks.
149 newDecision->setDetail<int32_t>("noCombo", 1);
150
152 jetHypoInputs.push_back( std::make_pair(jet, newDecision) );
153 }
154 }
155
156 // Extract the IDs of the jet chains which are active.
157 // previousDecisionIDs is a std::set<uint32_t>.
158
159 TrigCompositeUtils::DecisionIDContainer previousDecisionIDs{
160 TrigCompositeUtils::decisionIDs(previousDecision).begin(),
161 TrigCompositeUtils::decisionIDs(previousDecision).end()
162 };
163
164 if (msgLvl(MSG::DEBUG)) {
165 msg() << "IDs of active legs:" << endmsg;
166 for(auto decisionID: previousDecisionIDs) {
167 msg() << " " << decisionID << endmsg;
168 }
169 }
170 // Some of these may be leg IDs, convert those to the chain ID
171 TrigCompositeUtils::DecisionIDContainer leglessPreviousDecisionIDs;
172 std::transform(previousDecisionIDs.begin(), previousDecisionIDs.end(),
173 std::inserter(leglessPreviousDecisionIDs,leglessPreviousDecisionIDs.begin()),
175 {return TrigCompositeUtils::getIDFromLeg(HLT::Identifier(id)).numeric();}
176 );
177 if (msgLvl(MSG::DEBUG)) {
178 msg() << "IDs of active chains:" << endmsg;
179 for(auto decisionID: leglessPreviousDecisionIDs) {
180 msg() << " " << decisionID << endmsg;
181 }
182 }
183
184 // If this is a jet-only chain use the chain IDs
185 // Otherwise, we need to keep the leg
186 // The two options are combined into a single list to make this simpler
187
188 previousDecisionIDs.insert(leglessPreviousDecisionIDs.begin(), leglessPreviousDecisionIDs.end());
189
190 for (const auto& tool: m_hypoTools) {
191 if (tool.empty()) {
192 continue;
193 }
194 ATH_MSG_DEBUG("Now computing decision for " << tool->name());
195 CHECK(tool->decide(jets, previousDecisionIDs, jetHypoInputs));
196 }
197
198 return StatusCode::SUCCESS;
199}
200
#define endmsg
#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)
#define CHECK(...)
Evaluate an expression and check for errors.
bool msgLvl(const MSG::Level lvl) const
const T * at(size_type n) const
Access an element, as an rvalue.
size_type size() const noexcept
Returns the number of elements in the collection.
const SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > & decisionInput() const
methods for derived classes to access handles of the base class input other read/write handles may be...
Definition HypoBase.cxx:18
const SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > & decisionOutput() const
methods for derived classes to access handles of the base class output other read/write handles may b...
Definition HypoBase.cxx:22
StatusCode hypoBaseOutputProcessing(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MSG::Level lvl=MSG::DEBUG) const
Base class function to be called once slice specific code has finished. Handles debug printing and va...
Definition HypoBase.cxx:35
HypoBase(const std::string &name, ISvcLocator *pSvcLocator)
constructor, to be called by sub-class constructors
Definition HypoBase.cxx:12
pointer_type ptr()
Dereference the pointer.
Gaudi::Property< bool > m_doPresel
TrigJetHypoAlg(const std::string &name, ISvcLocator *pSvcLocator)
virtual StatusCode initialize() override
StatusCode decide(const xAOD::JetContainer *jets, const TrigCompositeUtils::Decision *previousDecision, TrigCompositeUtils::DecisionContainer *outputDecisions, const EventContext &context) const
Populate outputDecisions and run all HypoTools over the jet collection.
SG::ReadHandleKey< xAOD::JetContainer > m_jetsKey
virtual StatusCode execute(const EventContext &context) const override
ToolHandleArray< TrigJetHypoTool > m_hypoTools
bool setObjectLink(const std::string &name, const ElementLink< CONTAINER > &link)
Set the link to an object.
bool hasObjectLink(const std::string &name, const CLID clid=CLID_NULL) const
Check if a link to an object with a given name and type exists. CLID_NULL to not check type.
bool setDetail(const std::string &name, const TYPE &value)
Set an TYPE detail on the object.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
unsigned int DecisionID
Decision * newDecisionIn(DecisionContainer *dc, const std::string &name)
Helper method to create a Decision object, place it in the container and return a pointer to it.
const std::string & featureString()
std::set< DecisionID > DecisionIDContainer
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
const std::string & hypoAlgNodeName()
LinkInfo< T > findLink(const Decision *start, const std::string &linkName, const bool suppressMultipleLinksWarning=false)
Perform a recursive search for ElementLinks of type T and name 'linkName', starting from Decision obj...
const std::string & initialRoIString()
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
Jet_v1 Jet
Definition of the current "jet version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".