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());
32 
33  return StatusCode::SUCCESS;
34 }
35 
36 std::pair<std::unique_ptr<xAOD::JetContainer>, std::unique_ptr<SG::IAuxStore>> JetClustererByVertex::getJets() const
37 {
38  // Return this in case of any problems
39  auto nullreturn = std::make_pair(std::unique_ptr<xAOD::JetContainer>(nullptr), std::unique_ptr<SG::IAuxStore>(nullptr));
40 
41  // -----------------------
42  // retrieve input
44  if (!pjContHandle.isValid())
45  {
46  ATH_MSG_ERROR("No valid PseudoJetContainer with key " << m_inputPseudoJets.key());
47  return nullreturn;
48  }
49 
50  // Get reco vertices
52  const xAOD::VertexContainer *vertices = vertexHandle.cptr();
53  unsigned numVertices = vertices->size();
54  ATH_MSG_DEBUG("Retrieved vertex container for by-vertex clustering");
55 
56  // Build the container to be returned
57  // Avoid memory leaks with unique_ptr
58  auto jets = std::make_unique<xAOD::JetContainer>();
59  auto auxCont = std::make_unique<xAOD::JetAuxContainer>();
60  jets->setStore(auxCont.get());
61 
62  // Create a copy of the PseudoJet container that we modify for each vertex
63  // There is no valid copy constructor, but can use the `append` method instead
64  PseudoJetContainer pjContCopy;
65  pjContCopy.append(pjContHandle.cptr());
66 
67  // The pointer to the PseudoJetVector (non-const) that we can modify for each iteration
68  PseudoJetVector *inputPseudoJetVector = pjContCopy.casVectorPseudoJet();
69  // We need to keep a copy of the original vector, otherwise we will lose information
70  const PseudoJetVector cachedPseudoJetVector(*inputPseudoJetVector);
71 
72  ATH_MSG_DEBUG("Pseudojet input container has size " << inputPseudoJetVector->size());
73 
74  std::unique_ptr<fastjet::ClusterSequence> clSequence = std::make_unique<fastjet::ClusterSequence>();
75 
76  std::unique_ptr<PseudoJetVector> outputPseudoJetVector = std::make_unique<PseudoJetVector>();
77 
78  for (unsigned int iVertex{0}; iVertex < numVertices; iVertex++)
79  {
80  const xAOD::Vertex *vertex = vertices->at(iVertex);
81 
82  for (unsigned int iJet{0}; iJet < inputPseudoJetVector->size(); iJet++)
83  {
84  fastjet::PseudoJet &pseudoJet = inputPseudoJetVector->at(iJet);
85  // Check if pseudoJet has VertexIndexedConstituentUserInfo
86  if (pseudoJet.has_user_info<jet::VertexIndexedConstituentUserInfo>())
87  {
89  const xAOD::Vertex *originVertex = userInfo.vertex();
90  // Reset state
91  pseudoJet = cachedPseudoJetVector.at(iJet);
92  if (originVertex != vertex)
93  {
94  // pseudoJet should not affect this vertex iteration
95  // nullify its four-momentum
96  pseudoJet *= 1e-12;
97  }
98  else
99  {
100  // Do nothing -- this is the correct vertex
101  ATH_MSG_VERBOSE("Constituent found with pT = " << pseudoJet.pt() << " belonging to vertex index: " << userInfo.vertex()->index());
102  }
103  }
104  // Else we expect this to be a ghost, so do nothing
105  }
106  std::unique_ptr<fastjet::ClusterSequence> clSequenceByVertex = buildClusterSequence(inputPseudoJetVector);
107  if (!clSequenceByVertex)
108  return nullreturn;
109 
110  // -----------------------
111  // Build a new pointer to a PseudoJetVector containing the final PseudoJet
112  // This allows us to own the vector of PseudoJet which we will put in the evt store.
113  // Thus the contained PseudoJet will be kept frozen there and we can safely use pointer to them from the xAOD::Jet objects
114 
115  auto outputPseudoJetVectorByVertex = std::make_unique<PseudoJetVector>(fastjet::sorted_by_pt(clSequenceByVertex->inclusive_jets(m_ptmin)));
116  if (msgLvl(MSG::VERBOSE))
117  {
118  for (const auto &pj : *outputPseudoJetVectorByVertex)
119  {
120  msg() << " Pseudojet with pt " << std::setprecision(4) << pj.Et() * 1e-3 << " has " << pj.constituents().size() << " constituents" << endmsg;
121  }
122  }
123 
124  // No PseudoJets, so there's nothing else to do
125  // Delete the cluster sequence before we go
126  if (!outputPseudoJetVectorByVertex->empty())
127  {
128  for (const fastjet::PseudoJet &pj : *outputPseudoJetVectorByVertex)
129  {
130  processPseudoJet(pj, pjContCopy, jets.get(), vertex);
131  }
132  }
133  ATH_MSG_DEBUG("For vertex index " << iVertex << ", total reconstructed jet count so far: " << jets->size() << " clusterseq=" << clSequenceByVertex.get());
134 
135  // Copy the contents of pjVectorByVertex into pjVector
136  for (const fastjet::PseudoJet &pj : *outputPseudoJetVectorByVertex)
137  {
138  outputPseudoJetVector->emplace_back(pj);
139  }
140 
141  // We want to add the clSequence from this vertex to the total one
142  // TODO: how to best achieve this?
143  // Looks like this will simply delete the old sequence..
144  // clSequence->transfer_from_sequence(*clSequenceByVertex);
145  }
146 
147  if (!outputPseudoJetVector->empty())
148  {
149  // -------------------------------------
150  // record final PseudoJetVector
152  if (!pjVectorHandle.record(std::move(outputPseudoJetVector)))
153  {
154  ATH_MSG_ERROR("Can't record PseudoJetVector under key " << m_finalPseudoJets);
155  return nullreturn;
156  }
157  // -------------------------------------
158  // record ClusterSequences vector
160  if (!clusterSeqHandle.record(std::move(clSequence)))
161  {
162  ATH_MSG_ERROR("Can't record ClusterSequence under key " << m_clusterSequence);
163  return nullreturn;
164  }
165  }
166 
167  // Return the jet container and aux, use move to transfer
168  // ownership of pointers to caller
169  return std::make_pair(std::move(jets), std::move(auxCont));
170 }
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::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
JetClustererByVertex::m_vertexContainer_key
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainer_key
Definition: JetClustererByVertex.h:69
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:269
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:581
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
ReadHandle.h
Handle class for reading from StoreGate.
JetClusterer.h
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:36
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:76
PseudoJetVector
std::vector< fastjet::PseudoJet > PseudoJetVector
Definition: JetConstituentFiller.cxx:17
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
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
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
FastJetUtils.h
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