ATLAS Offline Software
Loading...
Searching...
No Matches
SubjetBuilderAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "SubjetBuilderAlg.h"
6
11
12#include "xAODJet/Jet.h"
13#include "xAODBase/IParticle.h"
14
15#include "fastjet/PseudoJet.hh"
16#include "fastjet/ClusterSequence.hh"
17#include "fastjet/JetDefinition.hh"
18
19namespace ftag {
20
22 ATH_CHECK(m_targetJetsKey.initialize());
23 ATH_CHECK(m_ghostKey.initialize());
24 ATH_CHECK(m_outputKey.initialize());
25 ATH_CHECK(m_linkKey.initialize());
26 ATH_CHECK(m_countKey.initialize());
27 return StatusCode::SUCCESS;
28 }
29
30 StatusCode SubjetBuilderAlg::execute(const EventContext& ctx) const {
31
33 if (!targetJetsH.isValid()) {
34 ATH_MSG_ERROR("Failed to retrieve jet container: "
35 << m_targetJetsKey.key());
36 return StatusCode::FAILURE;
37 }
38
39 // Recorded up front so the event always gets a container, and subjets are
40 // only created inside one that owns them.
42 ATH_CHECK(outputH.record(std::make_unique<xAOD::JetContainer>(),
43 std::make_unique<xAOD::JetAuxContainer>()));
44
48
49 const fastjet::JetDefinition jetdef(fastjet::antikt_algorithm, m_radius);
50
51 for (const xAOD::Jet* jet : *targetJetsH) {
52
53 const IPLV& constituents = ghosts(*jet);
54 std::vector<fastjet::PseudoJet> inputs;
55 inputs.reserve(constituents.size());
56 for (const ElementLink<xAOD::IParticleContainer>& link : constituents) {
57 if (!link.isValid()) {
58 ATH_MSG_ERROR("Invalid link in ghost association '"
59 << m_ghostKey.key()
60 << "'; the constituent was thinned away.");
61 return StatusCode::FAILURE;
62 }
63 const xAOD::IParticle& part = **link;
64 const auto p4 = part.p4();
65 inputs.emplace_back(p4.Px(), p4.Py(), p4.Pz(), p4.E());
66 }
67
68 if (inputs.empty()) {
69 linkDec(*jet) = {};
70 countDec(*jet) = 0;
71 continue;
72 }
73
74 const fastjet::ClusterSequence cs(inputs, jetdef);
75 const auto subjetsPj = fastjet::sorted_by_pt(cs.inclusive_jets(m_ptMin));
76
77 IPLV links;
78 links.reserve(subjetsPj.size());
79 for (const auto& pj : subjetsPj) {
80 // Owned from the moment it exists.
81 xAOD::Jet& subjet = *outputH->emplace_back(new xAOD::Jet());
83 p4.SetPxPyPzE(pj.px(), pj.py(), pj.pz(), pj.e());
84 subjet.setJetP4(p4);
85
86 links.emplace_back(*outputH, outputH->size() - 1, ctx);
87 }
88
89 countDec(*jet) = static_cast<int>(links.size());
90 linkDec(*jet) = std::move(links);
91 }
92
93 return StatusCode::SUCCESS;
94 }
95
96} // end namespace ftag
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x,...)
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for adding a decoration to an object.
Handle class for recording to StoreGate.
Handle class for reading a decoration on an object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
SG::WriteHandleKey< xAOD::JetContainer > m_outputKey
virtual StatusCode initialize() override
std::vector< ElementLink< xAOD::IParticleContainer > > IPLV
Gaudi::Property< float > m_ptMin
virtual StatusCode execute(const EventContext &) const override
SG::ReadHandleKey< xAOD::JetContainer > m_targetJetsKey
SG::ReadDecorHandleKey< xAOD::JetContainer > m_ghostKey
Gaudi::Property< float > m_radius
SG::WriteDecorHandleKey< xAOD::JetContainer > m_countKey
SG::WriteDecorHandleKey< xAOD::JetContainer > m_linkKey
Class providing the definition of the 4-vector interface.
Jet_v1 Jet
Definition of the current "jet version".
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition JetTypes.h:17