ATLAS Offline Software
Loading...
Searching...
No Matches
JetClustererByVertex.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <memory>
8#include "fastjet/PseudoJet.hh"
9#include "fastjet/ClusterSequence.hh"
10#include "fastjet/ClusterSequenceArea.hh"
11#include "fastjet/config.h"
12#include "fastjet/contrib/VariableRPlugin.hh"
13
17
18#include "JetEDM/FastJetUtils.h"
19
21
23#include "JetEDM/LabelIndex.h"
25
26JetClustererByVertex::JetClustererByVertex(const std::string &myname) : JetClusterer(myname) {}
27
36
37std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore>> JetClustererByVertex::getJets() const
38{
39 // Return this in case of any problems
40 auto nullreturn = std::make_pair(std::unique_ptr<xAOD::JetContainer>(nullptr), std::unique_ptr<SG::IAuxStore>(nullptr));
41
42 // -----------------------
43 // retrieve input
45 if (!pjContHandle.isValid())
46 {
47 ATH_MSG_ERROR("No valid PseudoJetContainer with key " << m_inputPseudoJets.key());
48 return nullreturn;
49 }
50
51 // Get reco vertices
53 const xAOD::VertexContainer *vertices = vertexHandle.cptr();
54 unsigned numVertices = vertices->size();
55 ATH_MSG_DEBUG("Retrieved vertex container for by-vertex clustering");
56
57 // Build the container to be returned
58 // Avoid memory leaks with unique_ptr
59 auto jets = std::make_unique<xAOD::JetContainer>();
60 auto auxCont = std::make_unique<xAOD::JetAuxContainer>();
61 jets->setStore(auxCont.get());
62
63 // Create a copy of the PseudoJet container that we modify for each vertex
64 // There is no valid copy constructor, but can use the `append` method instead
65 PseudoJetContainer pjContCopy;
66 pjContCopy.append(pjContHandle.cptr());
67
68 // The pointer to the PseudoJetVector (non-const) that we can modify for each iteration
69 PseudoJetVector *inputPseudoJetVector = pjContCopy.casVectorPseudoJet();
70 // We need to keep a copy of the original vector, otherwise we will lose information
71 const PseudoJetVector cachedPseudoJetVector(*inputPseudoJetVector);
72
73 ATH_MSG_DEBUG("Pseudojet input container has size " << inputPseudoJetVector->size());
74
75 std::unique_ptr<fastjet::ClusterSequence> clSequence = std::make_unique<fastjet::ClusterSequence>();
76
77 std::unique_ptr<PseudoJetVector> outputPseudoJetVector = std::make_unique<PseudoJetVector>();
78
79 for (unsigned int iVertex{0}; iVertex < numVertices; iVertex++)
80 {
81 const xAOD::Vertex *vertex = vertices->at(iVertex);
82
83 for (unsigned int iJet{0}; iJet < inputPseudoJetVector->size(); iJet++)
84 {
85 fastjet::PseudoJet &pseudoJet = inputPseudoJetVector->at(iJet);
86 // Check if pseudoJet has VertexIndexedConstituentUserInfo
87 if (pseudoJet.has_user_info<jet::VertexIndexedConstituentUserInfo>())
88 {
90 const xAOD::Vertex *originVertex = userInfo.vertex();
91 // Reset state
92 pseudoJet = cachedPseudoJetVector.at(iJet);
93 if (originVertex != vertex)
94 {
95 // pseudoJet should not affect this vertex iteration
96 // nullify its four-momentum
97 pseudoJet *= 1e-12;
98 }
99 else
100 {
101 // Do nothing -- this is the correct vertex
102 ATH_MSG_VERBOSE("Constituent found with pT = " << pseudoJet.pt() << " belonging to vertex index: " << userInfo.vertex()->index());
103 }
104 }
105 // Else we expect this to be a ghost, so do nothing
106 }
107 std::unique_ptr<fastjet::ClusterSequence> clSequenceByVertex = buildClusterSequence(inputPseudoJetVector);
108 if (!clSequenceByVertex)
109 return nullreturn;
110
111 // -----------------------
112 // Build a new pointer to a PseudoJetVector containing the final PseudoJet
113 // This allows us to own the vector of PseudoJet which we will put in the evt store.
114 // Thus the contained PseudoJet will be kept frozen there and we can safely use pointer to them from the xAOD::Jet objects
115
116 auto outputPseudoJetVectorByVertex = std::make_unique<PseudoJetVector>(fastjet::sorted_by_pt(clSequenceByVertex->inclusive_jets(m_ptmin)));
117 if (msgLvl(MSG::VERBOSE))
118 {
119 for (const auto &pj : *outputPseudoJetVectorByVertex)
120 {
121 msg() << " Pseudojet with pt " << std::setprecision(4) << pj.Et() * 1e-3 << " has " << pj.constituents().size() << " constituents" << endmsg;
122 }
123 }
124
125 // No PseudoJets, so there's nothing else to do
126 // Delete the cluster sequence before we go
127 if (!outputPseudoJetVectorByVertex->empty())
128 {
129 for (const fastjet::PseudoJet &pj : *outputPseudoJetVectorByVertex)
130 {
131 processPseudoJet(pj, pjContCopy, jets.get(), vertex);
132 //Mario we need to add jetRank for btagging
133 // we want the rank to start with zero, but this is after the
134 // jet has been added, thus the "size() - 1" here.
135 m_jetRankAccessor(*jets.get()->back()) = jets->size() - 1;
136 }
137 }
138 ATH_MSG_DEBUG("For vertex index " << iVertex << ", total reconstructed jet count so far: " << jets->size() << " clusterseq=" << clSequenceByVertex.get());
139
140 // Copy the contents of pjVectorByVertex into pjVector
141 for (const fastjet::PseudoJet &pj : *outputPseudoJetVectorByVertex)
142 {
143 outputPseudoJetVector->emplace_back(pj);
144 }
145
146 // We want to add the clSequence from this vertex to the total one
147 // TODO: how to best achieve this?
148 // Looks like this will simply delete the old sequence..
149 // clSequence->transfer_from_sequence(*clSequenceByVertex);
150 }
151
152 if (!outputPseudoJetVector->empty())
153 {
154 // -------------------------------------
155 // record final PseudoJetVector
157 if (!pjVectorHandle.record(std::move(outputPseudoJetVector)))
158 {
159 ATH_MSG_ERROR("Can't record PseudoJetVector under key " << m_finalPseudoJets);
160 return nullreturn;
161 }
162 // -------------------------------------
163 // record ClusterSequences vector
165 if (!clusterSeqHandle.record(std::move(clSequence)))
166 {
167 ATH_MSG_ERROR("Can't record ClusterSequence under key " << m_clusterSequence);
168 return nullreturn;
169 }
170 }
171
172 // Return the jet container and aux, use move to transfer
173 // ownership of pointers to caller
174 return std::make_pair(std::move(jets), std::move(auxCont));
175}
#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)
Handle class for reading from StoreGate.
std::vector< fastjet::PseudoJet > PseudoJetVector
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.
StatusCode initialize() override
Dummy implementation of the initialisation function.
JetClustererByVertex(const std::string &name)
std::pair< std::unique_ptr< xAOD::JetContainer >, std::unique_ptr< SG::IAuxStore > > getJets() const override
Return the final jets with their aux store.
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainer_key
SG::WriteHandleKey< jet::ClusterSequence > m_clusterSequence
Gaudi::Property< float > m_ptmin
Gaudi::Property< std::string > m_jetRank
StatusCode initialize() override
Dummy implementation of the initialisation function.
void processPseudoJet(const fastjet::PseudoJet &pj, const PseudoJetContainer &pjCont, xAOD::JetContainer *jets, const xAOD::Vertex *vertex) const
translate to xAOD::Jet
SG::AuxElement::Accessor< int > m_jetRankAccessor
std::unique_ptr< fastjet::ClusterSequence > buildClusterSequence(const PseudoJetVector *pseudoJetvector) const
Used to create the cluster sequence.
SG::ReadHandleKey< PseudoJetContainer > m_inputPseudoJets
Handle Input PseudoJetContainer.
SG::WriteHandleKey< PseudoJetVector > m_finalPseudoJets
used to build the key under which the final PJ will be stored in evtStore()
JetClusterer(const std::string &name)
const std::vector< PseudoJet > * casVectorPseudoJet() const
void append(const PseudoJetContainer *)
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
size_t index() const
Return the index of this element within its container.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
const xAOD::Vertex * vertex() const
Returns the associated vertex if this constit is a track. Else returns null. *‍/.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
MsgStream & msg
Definition testRead.cxx:32