ATLAS Offline Software
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>
7 #include "JetRec/JetClusterer.h"
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 
15 #include "xAODJet/JetContainer.h"
17 
18 #include "JetEDM/FastJetUtils.h"
19 
21 
23 #include "JetEDM/LabelIndex.h"
25 
26 JetClustererByVertex::JetClustererByVertex(const std::string &myname) : JetClusterer(myname) {}
27 
29 {
31  ATH_CHECK(m_vertexContainer_key.initialize());
33 
34  return StatusCode::SUCCESS;
35 }
36 
37 std::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 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
VertexIndexedConstituentUserInfo.h
jet::VertexIndexedConstituentUserInfo::vertex
const xAOD::Vertex * vertex() const
Returns the associated vertex if this constit is a track. Else returns null. *‍/.
Definition: VertexIndexedConstituentUserInfo.h:28
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
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
JetClustererByVertex::m_vertexContainer_key
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainer_key
Definition: JetClustererByVertex.h:69
defineDB.jets
jets
Definition: JetTagCalibration/share/defineDB.py:24
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
JetClusterer::m_clusterSequence
SG::WriteHandleKey< jet::ClusterSequence > m_clusterSequence
Definition: JetClusterer.h:91
PseudoJetContainer
Definition: PseudoJetContainer.h:48
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
JetClusterer::initialize
StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: JetClusterer.cxx:44
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
JetClusterer::m_inputPseudoJets
SG::ReadHandleKey< PseudoJetContainer > m_inputPseudoJets
Handle Input PseudoJetContainer.
Definition: JetClusterer.h:87
PseudoJetTranslator.h
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
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
JetClusterer::buildClusterSequence
std::unique_ptr< fastjet::ClusterSequence > buildClusterSequence(const PseudoJetVector *pseudoJetvector) const
Used to create the cluster sequence.
Definition: JetClusterer.cxx:91
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
JetClusterer
Definition: JetClusterer.h:45
jet::VertexIndexedConstituentUserInfo
Definition: VertexIndexedConstituentUserInfo.h:16
SG::AuxElement::index
size_t index() const
Return the index of this element within its container.
PseudoJetContainer::append
void append(const PseudoJetContainer *)
Definition: PseudoJetContainer.cxx:145
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
ReadHandle.h
Handle class for reading from StoreGate.
JetClusterer.h
JetClusterer::m_jetRankAccessor
SG::AuxElement::Accessor< int > m_jetRankAccessor
Definition: JetClusterer.h:113
JetClustererByVertex::getJets
std::pair< std::unique_ptr< xAOD::JetContainer >, std::unique_ptr< SG::IAuxStore > > getJets() const override
Return the final jets with their aux store.
Definition: JetClustererByVertex.cxx:37
JetClustererByVertex::initialize
StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: JetClustererByVertex.cxx:28
EventInfo.h
LabelIndex.h
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
PseudoJetVector
std::vector< fastjet::PseudoJet > PseudoJetVector
Definition: JetConstituentFiller.cxx:17
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
JetContainer.h
JetClusterer::m_finalPseudoJets
SG::WriteHandleKey< PseudoJetVector > m_finalPseudoJets
used to build the key under which the final PJ will be stored in evtStore()
Definition: JetClusterer.h:90
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
JetClustererByVertex::JetClustererByVertex
JetClustererByVertex(const std::string &name)
Definition: JetClustererByVertex.cxx:26
JetAuxContainer.h
JetClusterer::m_ptmin
Gaudi::Property< float > m_ptmin
Definition: JetClusterer.h:97
PseudoJetContainer::casVectorPseudoJet
const std::vector< PseudoJet > * casVectorPseudoJet() const
Definition: PseudoJetContainer.cxx:135
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
FastJetUtils.h
JetClusterer::m_jetRank
Gaudi::Property< std::string > m_jetRank
Definition: JetClusterer.h:92
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
JetClustererByVertex.h
JetClusterer::processPseudoJet
void processPseudoJet(const fastjet::PseudoJet &pj, const PseudoJetContainer &pjCont, xAOD::JetContainer *jets, const xAOD::Vertex *vertex) const
translate to xAOD::Jet
Definition: JetClusterer.cxx:151