ATLAS Offline Software
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 
11 using namespace TrigCompositeUtils;
12 
13 using xAOD::JetContainer;
14 
15 TrigJetHypoAlg::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 
35 StatusCode 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
66  createAndStore(decisionOutput(), context);
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
81  ATH_CHECK(hypoBaseOutputProcessing(outputHandle));
82 
83  return StatusCode::SUCCESS;
84 }
85 
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
106  if(!newDecision->hasObjectLink(TrigCompositeUtils::featureString())) {
108  TrigCompositeUtils::findLink<TrigRoiDescriptorCollection>(newDecision, TrigCompositeUtils::initialRoIString()).link);
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 
TrigJetHypoAlg.h
xAOD::TrigComposite_v1::setDetail
bool setDetail(const std::string &name, const TYPE &value)
Set an TYPE detail on the object.
TrigCompositeUtils::DecisionID
unsigned int DecisionID
Definition: TrigComposite_v1.h:27
TrigJetHypoAlg::m_jetsKey
SG::ReadHandleKey< xAOD::JetContainer > m_jetsKey
Definition: TrigJetHypoAlg.h:49
TrigCompositeUtils::newDecisionIn
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.
Definition: TrigCompositeUtilsRoot.cxx:46
TrigCompositeUtils::hypoAlgNodeName
const std::string & hypoAlgNodeName()
Definition: TrigCompositeUtilsRoot.cxx:904
xAOD::TrigComposite_v1::hasObjectLink
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.
Definition: TrigComposite_v1.cxx:246
DataVector::get
const T * get(size_type n) const
Access an element, as an rvalue.
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
HypoBase::decisionInput
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:16
TrigJetHypoAlg::decide
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.
Definition: TrigJetHypoAlg.cxx:87
TrigCompositeUtils::createAndStore
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
Definition: TrigCompositeUtilsRoot.cxx:30
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
TrigJetHypoAlg::initialize
virtual StatusCode initialize() override
Definition: TrigJetHypoAlg.cxx:20
HypoBase::decisionOutput
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:20
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:270
TrigCompositeUtils.h
TrigJetHypoAlg::m_doPresel
Gaudi::Property< bool > m_doPresel
Definition: TrigJetHypoAlg.h:54
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
xAOD::TrigComposite_v1::setObjectLink
bool setObjectLink(const std::string &name, const ElementLink< CONTAINER > &link)
Set the link to an object.
TrigCompositeUtils::initialRoIString
const std::string & initialRoIString()
Definition: TrigCompositeUtilsRoot.cxx:868
HypoBase::hypoBaseOutputProcessing
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:33
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
xAOD::TrigComposite_v1
Class used to describe composite objects in the HLT.
Definition: TrigComposite_v1.h:52
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtilsRoot.cxx:884
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
TrigJetHypoAlg::m_hypoTools
ToolHandleArray< TrigJetHypoTool > m_hypoTools
Definition: TrigJetHypoAlg.h:46
TrigCompositeUtils::DecisionIDContainer
std::set< DecisionID > DecisionIDContainer
Definition: TrigComposite_v1.h:28
TrigJetHypoAlg::TrigJetHypoAlg
TrigJetHypoAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: TrigJetHypoAlg.cxx:15
TrigRoiDescriptorCollection
Definition: TrigRoiDescriptorCollection.h:21
TrigJetHypoAlg::execute
virtual StatusCode execute(const EventContext &context) const override
Definition: TrigJetHypoAlg.cxx:35
DeMoScan.first
bool first
Definition: DeMoScan.py:536
DEBUG
#define DEBUG
Definition: page_access.h:11
HLTIdentifier.h
AthCommonMsg< Gaudi::Algorithm >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
TrigCompositeUtils::decisionIDs
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
Definition: TrigCompositeUtilsRoot.cxx:67
TrigCompositeUtils
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:19
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
xAOD::JetContainer
JetContainer_v1 JetContainer
Definition of the current "jet container version".
Definition: JetContainer.h:17
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
TrigRoiDescriptorCollection.h
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37