ATLAS Offline Software
TauAODRunnerAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "TauAODRunnerAlg.h"
6 
7 TauAODRunnerAlg::TauAODRunnerAlg(const std::string &name, ISvcLocator *pSvcLocator) :
8  AthReentrantAlgorithm(name, pSvcLocator) {}
9 
10 
12  ATH_CHECK(m_tauContainer.initialize());
14  ATH_CHECK(m_tauOutContainer.initialize());
21 
22  ATH_CHECK(m_modificationTools.retrieve());
23  ATH_CHECK(m_officialTools.retrieve());
24 
25  if(!m_modificationTools.empty()) {
26  ATH_MSG_INFO("List of modification tools in execution sequence:");
27  ATH_MSG_INFO("------------------------------------");
28  for (const auto &tool : m_modificationTools) {
29  ATH_MSG_INFO(tool->type() << " - " << tool->name());
30  }
31  ATH_MSG_INFO("------------------------------------");
32  } else {
33  ATH_MSG_INFO("Running without modification tools");
34  }
35 
36  if(!m_officialTools.empty()) {
37  ATH_MSG_INFO("List of official tools in execution sequence:");
38  ATH_MSG_INFO("------------------------------------");
39  for (const auto &tool : m_officialTools) {
40  ATH_MSG_INFO(tool->type() << " - " << tool->name());
41 
42  if((tool->type() == "TauPi0ClusterCreator" && (m_neutralPFOOutputContainer.empty() || m_hadronicPFOOutputContainer.empty() || m_pi0ClusterInputContainer.empty()))
43  || (tool->type() == "TauVertexVariables" && m_vertexOutputContainer.empty())
44  || (tool->type() == "TauPi0ClusterScaler" && (m_neutralPFOOutputContainer.empty() || m_chargedPFOOutputContainer.empty()))
45  || (tool->type() == "TauPi0ScoreCalculator" && m_neutralPFOOutputContainer.empty())
46  || (tool->type() == "TauPi0Selector" && m_neutralPFOOutputContainer.empty())
47  || (tool->type() == "PanTau::PanTauProcessor" && (m_neutralPFOOutputContainer.empty() || m_pi0Container.empty()))
48  || (tool->type() == "tauRecTools::TauTrackRNNClassifier" && m_tauTrackOutputContainer.empty())) {
49  ATH_MSG_ERROR("Missing input/output containers required for tool " << tool->name() << " (" << tool->type() << ")");
50  return StatusCode::FAILURE;
51  }
52  }
53  ATH_MSG_INFO("------------------------------------");
54  } else {
55  ATH_MSG_INFO("Running without official tools");
56  }
57 
58  if(m_modificationTools.empty() && m_officialTools.empty()) {
59  ATH_MSG_ERROR("Could not allocate any tool!");
60  return StatusCode::FAILURE;
61  }
62 
63  return StatusCode::SUCCESS;
64 }
65 
66 
67 StatusCode TauAODRunnerAlg::execute (const EventContext& ctx) const {
68  // Input TauJets
70  if (!tauInputHandle.isValid()) {
71  ATH_MSG_ERROR("Could not retrieve TauJetContainer with key " << tauInputHandle.key());
72  return StatusCode::FAILURE;
73  }
74  const xAOD::TauJetContainer *pTauContainer = tauInputHandle.cptr();
75 
76 
77  // Output TauTracks
78  xAOD::TauTrackContainer* newTauTrkCon = nullptr;
79  SG::WriteHandle<xAOD::TauTrackContainer> outputTauTrackHandle;
80  if(!m_tauTrackOutputContainer.empty()) {
81  outputTauTrackHandle = SG::makeHandle(m_tauTrackOutputContainer, ctx);
82  ATH_CHECK(outputTauTrackHandle.record(std::make_unique<xAOD::TauTrackContainer>(), std::make_unique<xAOD::TauTrackAuxContainer>()));
83  newTauTrkCon = outputTauTrackHandle.ptr();
84  }
85 
86  // Output TauJets
88  ATH_CHECK(outputTauHandle.record(std::make_unique<xAOD::TauJetContainer>(), std::make_unique<xAOD::TauJetAuxContainer>()));
89  xAOD::TauJetContainer *newTauCon = outputTauHandle.ptr();
90 
91  static const SG::Accessor<ElementLink<xAOD::TauJetContainer>> acc_ori_tau_link("originalTauJet");
92  static const SG::Accessor<char> acc_modified("ModifiedInAOD");
93 
94  for (const xAOD::TauJet *tau : *pTauContainer) {
95  // Deep copy the tau container
96  xAOD::TauJet* newTau = newTauCon->push_back(std::make_unique<xAOD::TauJet>());
97  *newTau = *tau;
98 
99  // Link the original tau to the deepcopy
100  ElementLink<xAOD::TauJetContainer> link_to_ori_tau;
101  link_to_ori_tau.toContainedElement(*pTauContainer, tau);
102  acc_ori_tau_link(*newTau) = link_to_ori_tau;
103 
104  // If the output TauTrackContainer is declared, create a new copy of all existing TauTracks
105  // otherwise, reuse the same TauTracks (e.g. if only new TauID is being ran on a deep copy
106  // of the input TauJet container).
107  if(newTauTrkCon) {
108  // Clear the tautrack links to allow relinking.
109  newTau->clearTauTrackLinks();
110  for(const xAOD::TauTrack *tauTrk : tau->allTracks()) {
111  // Deep copy the tau track
112  xAOD::TauTrack* newTauTrk = newTauTrkCon->push_back(std::make_unique<xAOD::TauTrack>());
113  *newTauTrk = *tauTrk;
114 
115  // Relink the tautrack
117  linkToTauTrack.toContainedElement(*newTauTrkCon, newTauTrk);
118  newTau->addTauTrackLink(linkToTauTrack);
119  }
120  }
121 
122  // 'ModifiedInAOD' will be overriden by modification tools for relevant candidates
123  acc_modified(*newTau) = static_cast<char>(false);
124 
125  // Execute all the modification tools (if provided)
126  for(const ToolHandle<ITauToolBase> &tool : m_modificationTools) {
127  ATH_MSG_DEBUG("RunnerAlg Invoking tool " << tool->name());
128  if(tool->execute(*newTau).isFailure()) break;
129  }
130 
131  // If tau candidate was not modified and we ran modification tools, remove it from container
132  // The track cleanup is performed by the thinning algorithm downstream
133  if(!m_modificationTools.empty() && !acc_modified(*newTau)) {
134  newTauCon->pop_back();
135  }
136  }
137 
138 
139  // Read the CaloClusterContainer
140  const xAOD::CaloClusterContainer* pi0ClusterContainer = nullptr;
143  pi0ClusterInHandle = SG::makeHandle(m_pi0ClusterInputContainer, ctx);
144  if(!pi0ClusterInHandle.isValid()) {
145  ATH_MSG_ERROR ("Could not retrieve HiveDataObj with key " << pi0ClusterInHandle.key());
146  return StatusCode::FAILURE;
147  }
148  pi0ClusterContainer = pi0ClusterInHandle.cptr();
149  }
150 
151  // Write charged PFO container
152  xAOD::PFOContainer* chargedPFOContainer = nullptr;
153  SG::WriteHandle<xAOD::PFOContainer> chargedPFOHandle;
154  if(!m_chargedPFOOutputContainer.empty()) {
155  chargedPFOHandle = SG::makeHandle(m_chargedPFOOutputContainer, ctx);
156  ATH_CHECK(chargedPFOHandle.record(std::make_unique<xAOD::PFOContainer>(), std::make_unique<xAOD::PFOAuxContainer>()));
157  chargedPFOContainer = chargedPFOHandle.ptr();
158  }
159 
160  // Write neutral PFO container
161  xAOD::PFOContainer* neutralPFOContainer = nullptr;
162  SG::WriteHandle<xAOD::PFOContainer> neutralPFOHandle;
163  if(!m_neutralPFOOutputContainer.empty()) {
164  neutralPFOHandle = SG::makeHandle(m_neutralPFOOutputContainer, ctx);
165  ATH_CHECK(neutralPFOHandle.record(std::make_unique<xAOD::PFOContainer>(), std::make_unique<xAOD::PFOAuxContainer>()));
166  neutralPFOContainer = neutralPFOHandle.ptr();
167  }
168 
169  // Write pi0 container
170  xAOD::ParticleContainer* pi0Container = nullptr;
172  if(!m_pi0Container.empty()) {
173  pi0Handle = SG::makeHandle(m_pi0Container, ctx);
174  ATH_CHECK(pi0Handle.record(std::make_unique<xAOD::ParticleContainer>(), std::make_unique<xAOD::ParticleAuxContainer>()));
175  pi0Container = pi0Handle.ptr();
176  }
177 
178  // Write hadronic cluster PFO container
179  xAOD::PFOContainer* hadronicClusterPFOContainer = nullptr;
180  SG::WriteHandle<xAOD::PFOContainer> hadronicPFOHandle;
181  if(!m_hadronicPFOOutputContainer.empty()) {
182  hadronicPFOHandle = SG::makeHandle(m_hadronicPFOOutputContainer, ctx);
183  ATH_CHECK(hadronicPFOHandle.record(std::make_unique<xAOD::PFOContainer>(), std::make_unique<xAOD::PFOAuxContainer>()));
184  hadronicClusterPFOContainer = hadronicPFOHandle.ptr();
185  }
186 
187  // Write secondary vertices
188  xAOD::VertexContainer* pSecVtxContainer = nullptr;
190  if(!m_vertexOutputContainer.empty()) {
191  vertOutHandle = SG::makeHandle(m_vertexOutputContainer, ctx);
192  ATH_CHECK(vertOutHandle.record(std::make_unique<xAOD::VertexContainer>(), std::make_unique<xAOD::VertexAuxContainer>()));
193  pSecVtxContainer = vertOutHandle.ptr();
194  }
195 
196 
197  // Execute all post-modification (_official_) tools
198  for (xAOD::TauJet *pTau : *newTauCon) {
199  StatusCode sc = StatusCode::SUCCESS;
200  for (const ToolHandle<ITauToolBase> &tool : m_officialTools) {
201  ATH_MSG_DEBUG("RunnerAlg Invoking tool " << tool->name());
202  if (tool->type() == "TauPi0ClusterCreator")
203  sc = tool->executePi0ClusterCreator(*pTau, *neutralPFOContainer, *hadronicClusterPFOContainer, *pi0ClusterContainer);
204  else if (tool->type() == "TauVertexVariables")
205  sc = tool->executeVertexVariables(*pTau, *pSecVtxContainer);
206  else if (tool->type() == "TauPi0ClusterScaler")
207  sc = tool->executePi0ClusterScaler(*pTau, *neutralPFOContainer, *chargedPFOContainer);
208  else if (tool->type() == "TauPi0ScoreCalculator")
209  sc = tool->executePi0nPFO(*pTau, *neutralPFOContainer);
210  else if (tool->type() == "TauPi0Selector")
211  sc = tool->executePi0nPFO(*pTau, *neutralPFOContainer);
212  else if (tool->type() == "PanTau::PanTauProcessor")
213  sc = tool->executePanTau(*pTau, *pi0Container, *neutralPFOContainer);
214  else if (tool->type() == "tauRecTools::TauTrackRNNClassifier")
215  sc = tool->executeTrackClassifier(*pTau, *newTauTrkCon);
216  else
217  sc = tool->execute(*pTau);
218 
219  if (sc.isFailure()) break;
220  }
221  if (sc.isSuccess()) ATH_MSG_VERBOSE("The tau candidate has been modified successfully by the invoked official tools.");
222  }
223 
224  ATH_MSG_VERBOSE("The tau candidate container has been modified by the rest of the tools");
225  ATH_MSG_DEBUG(newTauCon->size() << " / " << pTauContainer->size() <<" taus were modified");
226 
227  return StatusCode::SUCCESS;
228 }
229 
230 
231 // Helper
233  static const SG::ConstAccessor<char> acc_modified("ModifiedInAOD");
234  return acc_modified(*newtau);
235 }
TauAODRunnerAlg::m_neutralPFOOutputContainer
SG::WriteHandleKey< xAOD::PFOContainer > m_neutralPFOOutputContainer
Definition: TauAODRunnerAlg.h:60
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TauAODRunnerAlg::m_chargedPFOOutputContainer
SG::WriteHandleKey< xAOD::PFOContainer > m_chargedPFOOutputContainer
Definition: TauAODRunnerAlg.h:61
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
TauAODRunnerAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: TauAODRunnerAlg.cxx:67
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
xAOD::TauJet_v3::clearTauTrackLinks
void clearTauTrackLinks()
Remove all tracks from the tau.
Definition: TauJet_v3.cxx:527
SG::ConstAccessor< char >
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
TauAODRunnerAlg::m_modificationTools
ToolHandleArray< ITauToolBase > m_modificationTools
Definition: TauAODRunnerAlg.h:52
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
TauAODRunnerAlg::m_hadronicPFOOutputContainer
SG::WriteHandleKey< xAOD::PFOContainer > m_hadronicPFOOutputContainer
Definition: TauAODRunnerAlg.h:62
TauAODRunnerAlg::m_vertexOutputContainer
SG::WriteHandleKey< xAOD::VertexContainer > m_vertexOutputContainer
Definition: TauAODRunnerAlg.h:64
TauAODRunnerAlg::m_tauTrackOutputContainer
SG::WriteHandleKey< xAOD::TauTrackContainer > m_tauTrackOutputContainer
Definition: TauAODRunnerAlg.h:63
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TauAODRunnerAlg::isTauModified
static bool isTauModified(const xAOD::TauJet *newtau)
Definition: TauAODRunnerAlg.cxx:232
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
TauAODRunnerAlg::m_pi0ClusterInputContainer
SG::ReadHandleKey< xAOD::CaloClusterContainer > m_pi0ClusterInputContainer
Definition: TauAODRunnerAlg.h:57
xAOD::TauJet_v3
Class describing a tau jet.
Definition: TauJet_v3.h:41
xAOD::TauJet_v3::addTauTrackLink
void addTauTrackLink(const ElementLink< TauTrackContainer > &tr)
add a TauTrack to the tau
Definition: TauJet_v3.cxx:523
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
TauAODRunnerAlg::m_tauOutContainer
SG::WriteHandleKey< xAOD::TauJetContainer > m_tauOutContainer
Definition: TauAODRunnerAlg.h:58
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:452
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
TauAODRunnerAlg.h
SG::VarHandleBase::key
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:64
TauAODRunnerAlg::m_officialTools
ToolHandleArray< ITauToolBase > m_officialTools
Definition: TauAODRunnerAlg.h:53
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
TauAODRunnerAlg::m_tauContainer
SG::ReadHandleKey< xAOD::TauJetContainer > m_tauContainer
Definition: TauAODRunnerAlg.h:56
TauAODRunnerAlg::initialize
virtual StatusCode initialize() override
Definition: TauAODRunnerAlg.cxx:11
TauAODRunnerAlg::m_pi0Container
SG::WriteHandleKey< xAOD::ParticleContainer > m_pi0Container
Definition: TauAODRunnerAlg.h:59
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
xAOD::TauTrack_v1
Definition: TauTrack_v1.h:27
DataVector::pop_back
void pop_back()
Remove the last element from the collection.
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
TauAODRunnerAlg::TauAODRunnerAlg
TauAODRunnerAlg(const std::string &name, ISvcLocator *)
Definition: TauAODRunnerAlg.cxx:7